@@ -12,3 +12,10 @@ func SecondGetAllPriceTypeList(Db *xorm.Engine) ([]model.SecondNewcomersFreePric | |||
} | |||
return priceType, nil | |||
} | |||
func MoreGetAllPriceTypeList(Db *xorm.Engine) ([]model.MoreNewcomersFreePriceType, error) { | |||
var priceType []model.MoreNewcomersFreePriceType | |||
if err := Db.Find(&priceType); err != nil { | |||
return nil, err | |||
} | |||
return priceType, nil | |||
} |
@@ -26,4 +26,5 @@ type FinUserFlow struct { | |||
AliOrdId string `json:"ali_ord_id" xorm:"default '' comment('支付宝订单号') VARCHAR(128)"` | |||
CreateAt time.Time `json:"create_at" xorm:"created not null default CURRENT_TIMESTAMP comment('创建时间') TIMESTAMP"` | |||
UpdateAt time.Time `json:"update_at" xorm:"updated not null default CURRENT_TIMESTAMP comment('更新时间') TIMESTAMP"` | |||
Date string `json:"date" xorm:"comment('2023-12-01') VARCHAR(255)"` | |||
} |
@@ -0,0 +1,17 @@ | |||
package model | |||
type MoreNewcomersFreePriceType struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(10)"` | |||
PriceName string `json:"price_name" xorm:"not null comment('价格类型') VARCHAR(255)"` | |||
NeedQuan int `json:"need_quan" xorm:"not null default 0 comment('需要的福利券') INT(11)"` | |||
CreatedAt int `json:"created_at" xorm:"not null default 0 INT(11)"` | |||
UpdatedAt int `json:"updated_at" xorm:"not null default 0 INT(11)"` | |||
IsShow int `json:"is_show" xorm:"not null default 1 comment('是否开启') TINYINT(1)"` | |||
IsDel int `json:"is_del" xorm:"not null default 0 INT(11)"` | |||
NeedUseQuan int `json:"need_use_quan" xorm:"not null default 1 INT(1)"` | |||
NeedLimitBuy int `json:"need_limit_buy" xorm:"not null default 0 INT(1)"` | |||
Auth string `json:"auth" xorm:"not null comment('权限') TEXT"` | |||
LimitBuyCondition string `json:"limit_buy_condition" xorm:"not null comment('限购条件') TEXT"` | |||
CommissionId string `json:"commission_id" xorm:"default '' VARCHAR(255)"` | |||
CommissionData string `json:"commission_data" xorm:"default '' VARCHAR(500)"` | |||
} |
@@ -10,4 +10,5 @@ type SubsidyWithUserFlow struct { | |||
Kind int `json:"kind" xorm:"default 1 comment('类型(1:消费补贴 2:体验补贴)') INT(1)"` | |||
Month int `json:"month" xorm:"default 0 comment('202312') INT(11)"` | |||
Uid int `json:"uid" xorm:"default 0 INT(11)"` | |||
Date string `json:"date" xorm:"comment('2023-12-01') VARCHAR(255)"` | |||
} |
@@ -46,4 +46,5 @@ type DealUserAmount struct { | |||
OrdId string `json:"ord_id"` | |||
Uid int `json:"uid"` | |||
Amount float64 `json:"amount"` | |||
Num string `json:"num"` | |||
} |
@@ -24,6 +24,7 @@ type InsertRegionalAgentOrdBelongData struct { | |||
ProvinceId string `json:"province_id"` | |||
CityId string `json:"city_id"` | |||
CountyId string `json:"county_id"` | |||
RegionRate float64 `json:"region_rate"` | |||
SiteId string `json:"site_id"` | |||
BelongType string `json:"belong_type"` | |||
} | |||
@@ -94,6 +94,8 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
return | |||
} | |||
var consumeTotalMap = make(map[int]decimal.Decimal) | |||
var consumeTotalCountMap = make(map[int]int) | |||
if hasConsumeTotal > 0 { | |||
consumeValue, err = calcNowEverydayConsumeIntegral(subsidyBase, hasConsumeTotal) | |||
if err != nil { | |||
@@ -102,6 +104,8 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
for _, v := range subsidyWithUserForConsumeList { | |||
consumeTotalMap[v.Uid] = consumeTotalMap[v.Uid].Add(decimal.NewFromFloat(consumeValue)) | |||
consumeTotalCountMap[v.Uid]++ | |||
consumeValueTotal = consumeValueTotal.Add(decimal.NewFromFloat(consumeValue)) | |||
err1 := DealUserConsumeIntegral(session, &v, consumeValue, mid) | |||
if err1 != nil { | |||
@@ -110,7 +114,16 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
} | |||
} | |||
//加余额流水 | |||
if len(consumeTotalMap) > 0 { | |||
for k, v := range consumeTotalMap { | |||
err1 := DealUserConsumeAmountFlow(session, k, zhios_order_relate_utils.StrToFloat64(v.String()), mid, zhios_order_relate_utils.IntToStr(consumeTotalCountMap[k])) | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1 | |||
} | |||
} | |||
} | |||
//2、统计当前拥有多少份体验补贴 | |||
var subsidyWithUserForExperienceList []model.SubsidyWithUser | |||
hasExperienceTotal, err := session.Where("date <= ?", startAt).And("kind = ? and is_can_subsidy=?", 2, 1).FindAndCount(&subsidyWithUserForExperienceList) | |||
@@ -118,13 +131,17 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
_ = session.Rollback() | |||
return | |||
} | |||
if hasExperienceTotal > 0 { | |||
var experienceTotalMap = make(map[int]decimal.Decimal) | |||
var experienceTotalCountMap = make(map[int]int) | |||
if hasExperienceTotal > 0 && consumeValue > 0 { | |||
experienceValue, err = calcNowEverydayExperienceIntegral(consumeValue) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return err | |||
} | |||
for _, v := range subsidyWithUserForExperienceList { | |||
experienceTotalCountMap[v.Uid]++ | |||
experienceTotalMap[v.Uid] = experienceTotalMap[v.Uid].Add(decimal.NewFromFloat(experienceValue)) | |||
experienceValueTotal = experienceValueTotal.Add(decimal.NewFromFloat(experienceValue)) | |||
err1 := DealUserExperienceIntegral(session, &v, experienceValue, mid) | |||
if err1 != nil { | |||
@@ -133,7 +150,16 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
} | |||
} | |||
//加余额流水 | |||
if len(experienceTotalMap) > 0 { | |||
for k, v := range experienceTotalMap { | |||
err1 := DealUserExperienceAmountFlow(session, k, zhios_order_relate_utils.StrToFloat64(v.String()), mid, zhios_order_relate_utils.IntToStr(experienceTotalCountMap[k])) | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1 | |||
} | |||
} | |||
} | |||
//3、修改 subsidy_base 中 consumption_money、experience_money | |||
consumeTotal, _ := consumeValueTotal.Float64() | |||
experienceTotal, _ := experienceValueTotal.Float64() | |||
@@ -177,7 +203,7 @@ func calcNowEverydayConsumeIntegral(subsidyBase *model.SubsidyBase, hasConsumeTo | |||
//计算当前体验积分价值(当前消费积分价值 * 10%) | |||
func calcNowEverydayExperienceIntegral(consumeValue float64) (value float64, err error) { | |||
value = consumeValue * 0.1 | |||
value, _ = decimal.NewFromFloat(consumeValue * 0.1).RoundFloor(2).Float64() | |||
////2、通过公式计算 "((资金池的金额 * 浮动比例) / 体验补贴总数) + 基础补贴" | |||
//experienceMoney, _ := decimal.NewFromString(subsidyBase.ExperienceTotalMoney) | |||
//baseSubsidyMoney, _ := decimal.NewFromString(subsidyBase.BaseSubsidyMoney) | |||
@@ -220,6 +246,7 @@ func DealUserConsumeIntegral(session *xorm.Session, subsidyWithUser *model.Subsi | |||
BalanceAmount: zhios_order_relate_utils.Float64ToStr(afterAmount), | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
Date: now.Format("2006-01-02"), | |||
Uid: subsidyWithUser.Uid, | |||
Kind: subsidyWithUser.Kind, | |||
Month: zhios_order_relate_utils.StrToInt(now.Format("200601")), | |||
@@ -255,7 +282,7 @@ func DealUserConsumeIntegral(session *xorm.Session, subsidyWithUser *model.Subsi | |||
Uid: subsidyWithUser.Uid, | |||
Amount: consumeIntegralValue, | |||
} | |||
err = svc.DealUserAmount(session, dealUserAmount) | |||
err = svc.DealUserAmountNew(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
@@ -293,6 +320,7 @@ func DealUserExperienceIntegral(session *xorm.Session, subsidyWithUser *model.Su | |||
Amount: zhios_order_relate_utils.Float64ToStr(experienceIntegralValue), | |||
BalanceAmount: zhios_order_relate_utils.Float64ToStr(afterAmount), | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
Date: now.Format("2006-01-02"), | |||
Month: zhios_order_relate_utils.StrToInt(now.Format("200601")), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
} | |||
@@ -327,7 +355,50 @@ func DealUserExperienceIntegral(session *xorm.Session, subsidyWithUser *model.Su | |||
Uid: subsidyWithUser.Uid, | |||
Amount: experienceIntegralValue, | |||
} | |||
err = svc.DealUserAmount(session, dealUserAmount) | |||
err = svc.DealUserAmountNew(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
return nil | |||
} | |||
// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 流水 | |||
func DealUserConsumeAmountFlow(session *xorm.Session, uid int, consumeIntegralValue float64, mid, num string) (err error) { | |||
//4、给用户添加余额流水 | |||
orderType := enum.FinUserFlowOrderActionString(md.ConsumeSubsidyOrdActionForFinUserFlow) | |||
var dealUserAmount = md.DealUserAmount{ | |||
Kind: "add", | |||
Mid: mid, | |||
Title: md.ConsumeSubsidyTitleForFinUserFlow, | |||
OrderType: orderType, | |||
OrdAction: md.ConsumeSubsidyOrdActionForFinUserFlow, | |||
Uid: uid, | |||
Amount: consumeIntegralValue, | |||
Num: num, | |||
} | |||
err = svc.DealUserAmountFlow(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
return nil | |||
} | |||
// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 | |||
func DealUserExperienceAmountFlow(session *xorm.Session, uid int, experienceIntegralValue float64, mid, num string) (err error) { | |||
//4、给用户添加余额 | |||
orderType := enum.FinUserFlowOrderActionString(md.ExperienceSubsidyOrdActionForFinUserFlow) | |||
var dealUserAmount = md.DealUserAmount{ | |||
Kind: "add", | |||
Mid: mid, | |||
Title: md.ExperienceSubsidyTitleForFinUserFlow, | |||
OrderType: orderType, | |||
OrdAction: md.ExperienceSubsidyOrdActionForFinUserFlow, | |||
Uid: uid, | |||
Amount: experienceIntegralValue, | |||
Num: num, | |||
} | |||
err = svc.DealUserAmountFlow(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
@@ -60,7 +60,31 @@ func GetAllPlan(eg *xorm.Engine, dbName string) (map[string]*model.PlanReward, m | |||
plan[tmp.Pvd] = tmp | |||
} | |||
} | |||
moreList, _ := db.MoreGetAllPriceTypeList(eg) | |||
for _, v := range moreList { | |||
var oneRewardPlan map[string]string | |||
err := json.Unmarshal([]byte(v.CommissionData), &oneRewardPlan) | |||
if err == nil { | |||
var tmp = &model.PlanReward{ | |||
Id: 0, | |||
Pvd: "moreFree_" + zhios_order_relate_utils.IntToStr(v.Id), | |||
PvdRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["pvd_rate"]) / 100, | |||
SysRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["sys_rate"]) / 100, | |||
RegionRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["region_rate"]) / 100, | |||
GlobalRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["global_rate"]) / 100, | |||
SettleMode: zhios_order_relate_utils.StrToInt(oneRewardPlan["settle_mode"]), | |||
PlanCommissionId: zhios_order_relate_utils.StrToInt(oneRewardPlan["plan_commission_id"]), | |||
PlanSettleId: zhios_order_relate_utils.StrToInt(oneRewardPlan["plan_settle_id"]), | |||
State: 1, | |||
Source: 1, | |||
IntegralOpen: zhios_order_relate_utils.StrToInt(oneRewardPlan["integral_open"]), | |||
MerchantRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["merchant_rate"]) / 100, | |||
PushHandRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["push_hand_rate"]) / 100, | |||
OrderBeforeRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["order_before_rate"]) / 100, | |||
} | |||
plan[tmp.Pvd] = tmp | |||
} | |||
} | |||
commission := make(map[int]*model.PlanCommission, 0) | |||
commissions := db.DbsPlanCommissionByIds(eg) | |||
for _, v := range commissions { | |||
@@ -74,7 +98,7 @@ func GetPlanCfg(eg *xorm.Engine, pvd, masterId string, rewardOpts map[string]*mo | |||
opt := &comm_plan.PlanOpt{} | |||
// 根据供应商 | |||
rewardOpt := rewardOpts[pvd] | |||
if strings.Contains(pvd, "seFree") == false { | |||
if strings.Contains(pvd, "seFree") == false && strings.Contains(pvd, "moreFree") == false { | |||
if pvd == "tikTok" && rmd.IsTikTokTeamOrder == "1" && rewardOpts["tikTokTeam"] != nil && rewardOpts["tikTokTeam"].PlanCommissionId > 0 { | |||
rewardOpt = rewardOpts["tikTokTeam"] | |||
} | |||
@@ -271,6 +295,31 @@ func PlanOpts(eg *xorm.Engine) map[string]*comm_plan.PlanOpt { | |||
allRewardPlan = append(allRewardPlan, tmp) | |||
} | |||
} | |||
moreList, _ := db.MoreGetAllPriceTypeList(eg) | |||
for _, v := range moreList { | |||
var oneRewardPlan map[string]string | |||
err := json.Unmarshal([]byte(v.CommissionData), &oneRewardPlan) | |||
if err == nil { | |||
var tmp = &model.PlanReward{ | |||
Id: 0, | |||
Pvd: "moreFree_" + zhios_order_relate_utils.IntToStr(v.Id), | |||
PvdRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["pvd_rate"]) / 100, | |||
SysRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["sys_rate"]) / 100, | |||
RegionRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["region_rate"]) / 100, | |||
GlobalRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["global_rate"]) / 100, | |||
SettleMode: zhios_order_relate_utils.StrToInt(oneRewardPlan["settle_mode"]), | |||
PlanCommissionId: zhios_order_relate_utils.StrToInt(oneRewardPlan["plan_commission_id"]), | |||
PlanSettleId: zhios_order_relate_utils.StrToInt(oneRewardPlan["plan_settle_id"]), | |||
State: 1, | |||
Source: 1, | |||
IntegralOpen: zhios_order_relate_utils.StrToInt(oneRewardPlan["integral_open"]), | |||
MerchantRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["merchant_rate"]) / 100, | |||
PushHandRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["push_hand_rate"]) / 100, | |||
OrderBeforeRate: zhios_order_relate_utils.StrToFloat32(oneRewardPlan["order_before_rate"]) / 100, | |||
} | |||
allRewardPlan = append(allRewardPlan, tmp) | |||
} | |||
} | |||
opts := map[string]*comm_plan.PlanOpt{} | |||
for _, v := range allRewardPlan { | |||
if _, ok := commissionPlans[v.PlanCommissionId]; ok && v.State == 1 && v.PlanCommissionId > 0 { | |||
@@ -51,6 +51,7 @@ func DealUserAmount(session *xorm.Session, req md.DealUserAmount) (err error) { | |||
State: 1, | |||
CreateAt: now, | |||
UpdateAt: now, | |||
Date: now.Format("2006-01-02"), | |||
} | |||
if req.Kind == "add" { | |||
finUserFlow.Type = 0 | |||
@@ -88,6 +89,93 @@ func DealUserAmount(session *xorm.Session, req md.DealUserAmount) (err error) { | |||
return nil | |||
} | |||
func DealUserAmountNew(session *xorm.Session, req md.DealUserAmount) (err error) { | |||
if req.Amount < 0 { | |||
req.Amount = 0 | |||
} | |||
//1、分布式锁阻拦 | |||
requestIdPrefix := fmt.Sprintf(md.DealUserAmountRequestIdPrefix, req.Mid, req.Uid) | |||
cb, err := HandleBalanceDistributedLockForAmount(req.Mid, strconv.Itoa(req.Uid), requestIdPrefix) | |||
if err != nil { | |||
return err | |||
} | |||
if cb != nil { | |||
defer cb() // 释放锁 | |||
} | |||
//2、计算&&组装数据 | |||
userAmount, err := GetUserAmount(session, req.Mid, req.Uid) | |||
if err != nil { | |||
return err | |||
} | |||
userAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount)) | |||
amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(8) | |||
AfterAmount := "" | |||
if req.Kind == "add" { | |||
AfterAmount = userAmountValue.Add(amountValue).RoundFloor(8).String() | |||
} else if req.Kind == "sub" { | |||
AfterAmount = userAmountValue.Sub(amountValue).RoundFloor(8).String() | |||
} else { | |||
err = errors.New("错误的kind类型") | |||
return err | |||
} | |||
//4、修改 `user_profile`的fin_valid值 && 及缓存 | |||
err = SetCacheUserAmount(session, req.Mid, AfterAmount, req.Uid, true) | |||
if err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func DealUserAmountFlow(session *xorm.Session, req md.DealUserAmount) (err error) { | |||
if req.Amount < 0 { | |||
req.Amount = 0 | |||
} | |||
//2、计算&&组装数据 | |||
now := time.Now() | |||
userAmount, err := GetUserAmount(session, req.Mid, req.Uid) | |||
if err != nil { | |||
return err | |||
} | |||
userAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount)) | |||
amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(8) | |||
var finUserFlow = model.FinUserFlow{ | |||
Uid: req.Uid, | |||
Amount: amountValue.String(), | |||
AfterAmount: userAmount, | |||
OrdType: req.OrderType, | |||
OrdId: req.OrdId, | |||
OrdTitle: req.Title, | |||
OrdAction: req.OrdAction, | |||
OrdTime: int(now.Unix()), | |||
State: 1, | |||
CreateAt: now, | |||
UpdateAt: now, | |||
Memo: req.Num, | |||
Date: now.Format("2006-01-02"), | |||
} | |||
finUserFlow.Type = 0 | |||
finUserFlow.BeforeAmount = userAmountValue.Sub(amountValue).RoundFloor(8).String() | |||
if zhios_order_relate_utils.StrToFloat64(finUserFlow.AfterAmount) < 0 { | |||
zhios_order_relate_utils.FilePutContents("user_amount_not", zhios_order_relate_utils.SerializeStr(map[string]interface{}{ | |||
"uid": finUserFlow.Uid, | |||
"amount": finUserFlow.Amount, | |||
"before_amount": finUserFlow.BeforeAmount, | |||
"title": finUserFlow.OrdTitle, | |||
"mid": req.Mid, | |||
})) | |||
return errors.New("用户余额不足") | |||
} | |||
//3、插入 `fin_user_flow` 记录 | |||
affected, err := session.Insert(&finUserFlow) | |||
if affected == 0 || err != nil { | |||
_ = zhios_order_relate_logx.Warn(err) | |||
return err | |||
} | |||
return nil | |||
} | |||
// GetUserAmount 获取用户余额 | |||
func GetUserAmount(session *xorm.Session, masterId string, uid int) (amount string, err error) { | |||