@@ -42,6 +42,14 @@ func UserProfileFindByIDWithSession(sess *xorm.Session, id interface{}) (*model. | |||
} | |||
return &m, nil | |||
} | |||
func O2oMerchantFindByIDWithSession(sess *xorm.Session, id interface{}) (*model.O2oMerchant, error) { | |||
var m model.O2oMerchant | |||
if has, err := sess.Where("id = ?", id). | |||
Get(&m); err != nil || has == false { | |||
return nil, zhios_order_relate_logx.Warn(err) | |||
} | |||
return &m, nil | |||
} | |||
func UserProfileUpdateWithSession(session *xorm.Session, uid interface{}, userProfile *model.UserProfile, forceCols ...string) (int64, error) { | |||
var ( | |||
affected int64 | |||
@@ -0,0 +1,32 @@ | |||
package model | |||
import ( | |||
"time" | |||
) | |||
type O2oFinUserFlow struct { | |||
Id int64 `json:"id" xorm:"pk autoincr comment('流水编号') BIGINT(20)"` | |||
Uid int `json:"uid" xorm:"not null default 0 comment('用户id') INT(11)"` | |||
MerchantId int `json:"merchant_id" xorm:"default 0 comment('商家id') INT(11)"` | |||
StoreId int `json:"store_id" xorm:"default 0 comment('店铺id') INT(11)"` | |||
Type int `json:"type" xorm:"not null default 0 comment('0收入,1支出') TINYINT(1)"` | |||
Amount string `json:"amount" xorm:"not null default 0.0000 comment('变动金额') DECIMAL(11,4)"` | |||
BeforeAmount string `json:"before_amount" xorm:"not null default 0.0000 comment('变动前金额') DECIMAL(11,4)"` | |||
AfterAmount string `json:"after_amount" xorm:"not null default 0.0000 comment('变动后金额') DECIMAL(11,4)"` | |||
SysFee string `json:"sys_fee" xorm:"not null default 0.0000 comment('手续费') DECIMAL(11,4)"` | |||
PaymentType int `json:"payment_type" xorm:"not null default 1 comment('1支付宝,2微信.3手动转账') TINYINT(1)"` | |||
OrdType string `json:"ord_type" xorm:"not null default '' comment('订单类型 o2o_goods(小店), o2o_hotel(酒店) withdraw(提现)') VARCHAR(255)"` | |||
OrdId string `json:"ord_id" xorm:"not null default '' comment('对应订单编号') VARCHAR(50)"` | |||
OrdTitle string `json:"ord_title" xorm:"not null default '' comment('订单标题') VARCHAR(50)"` | |||
OrdAction int `json:"ord_action" xorm:"not null default 0 comment('10自购,11推广,12团队,13免单,20提现,21消费,22退款,23拼团返佣,24区域代理,25重置虚拟币 26充值') TINYINT(2)"` | |||
OrdTime int `json:"ord_time" xorm:"not null default 0 comment('下单时间or提现时间') INT(11)"` | |||
OrdDetail string `json:"ord_detail" xorm:"not null default '' comment('记录商品ID或提现账号') VARCHAR(50)"` | |||
ExpectedTime string `json:"expected_time" xorm:"not null default '0' comment('预期到账时间,字符串用于直接显示,结算后清除内容') VARCHAR(30)"` | |||
Date string `json:"date" xorm:"not null default 1 comment('1未到账,2已到账') VARCHAR(50)"` | |||
State int `json:"state" xorm:"not null default 1 comment('1未到账,2已到账') TINYINT(1)"` | |||
Memo string `json:"memo" xorm:"not null default '' comment('备注') VARCHAR(2000)"` | |||
OtherId int64 `json:"other_id" xorm:"not null default 0 comment('其他关联订单,具体根据订单类型判断') index BIGINT(20)"` | |||
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"` | |||
} |
@@ -0,0 +1,49 @@ | |||
package model | |||
import ( | |||
"time" | |||
) | |||
type O2oMerchant struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
Pid int `json:"pid" xorm:"comment('主账号id') INT(11)"` | |||
AvatarUrl string `json:"avatar_url" xorm:"comment('用户头像') VARCHAR(255)"` | |||
Type string `json:"type" xorm:"not null comment('商家类型,可多个') VARCHAR(255)"` | |||
Phone string `json:"phone" xorm:"not null comment('商家手机号') VARCHAR(255)"` | |||
Email string `json:"email" xorm:"not null comment('商家邮箱') VARCHAR(255)"` | |||
Wechat string `json:"wechat" xorm:"comment('微信号') VARCHAR(255)"` | |||
AccountAlipay string `json:"account_alipay" xorm:"comment('支付宝账户') VARCHAR(50)"` | |||
AccountAlipayRealName string `json:"account_alipay_real_name" xorm:"comment('支付宝持有人姓名') VARCHAR(255)"` | |||
Password string `json:"password" xorm:"not null comment('密码') VARCHAR(255)"` | |||
Name string `json:"name" xorm:"not null comment('名称') VARCHAR(255)"` | |||
FunctionalAuthority string `json:"functional_authority" xorm:"not null comment('功能权限角色id') VARCHAR(255)"` | |||
State int `json:"state" xorm:"default 1 comment('商家状态') TINYINT(1)"` | |||
Token string `json:"token" xorm:"comment('token') VARCHAR(520)"` | |||
Amount float64 `json:"amount" xorm:"comment('商家余额') DOUBLE(10,2)"` | |||
FrozenAmount float64 `json:"frozen_amount" xorm:"comment('商家冻结余额') DOUBLE(16,4)"` | |||
AuthWay int `json:"auth_way" xorm:"default 1 comment('1:统一授权模式,2:普通授权') TINYINT(1)"` | |||
CreateTime time.Time `json:"create_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') DATETIME"` | |||
UpdateTime time.Time `json:"update_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') DATETIME"` | |||
DeletedTime time.Time `json:"deleted_time" xorm:"comment('删除时间') DATETIME"` | |||
Gender int `json:"gender" xorm:"default 0 comment('0女,1:男,其他为未知性别') TINYINT(1)"` | |||
Birthday *time.Time `json:"birthday" xorm:"comment('生日') DATE"` | |||
NotificationSetting string `json:"notification_setting" xorm:"comment('通知设置 json格式') TEXT"` | |||
Info string `json:"info" xorm:"comment('补充信息') LONGTEXT"` | |||
BelongStore string `json:"belong_store" xorm:"comment('归属店铺(只有员工才有)') VARCHAR(255)"` | |||
RealName string `json:"real_name" xorm:"comment('真实姓名') VARCHAR(255)"` | |||
IdNumber string `json:"Id_number" xorm:"comment('身份证号') VARCHAR(255)"` | |||
InviteCode string `json:"invite_code" xorm:"comment('邀请码(唯一)') VARCHAR(255)"` | |||
IsvTicket string `json:"isv_ticket" xorm:"comment('支付宝isv_ticket(唯一)') VARCHAR(255)"` | |||
PushHandId int `json:"push_hand_id" xorm:"comment('推手id(推送分享出去后注册的商家绑定)') INT(11)"` | |||
Uid string `json:"uid" xorm:"comment('智莺生活用户id') VARCHAR(50)"` | |||
FreezeAmount float64 `json:"freeze_amount" xorm:"comment('商家冻结余额(B2C中用户支付后,商家的钱先流去冻结余额,完成订单才会流去余额)') DOUBLE(10,2)"` | |||
B2cAmount float64 `json:"b2c_amount" xorm:"comment('b2c商家余额') DOUBLE(16,4)"` | |||
B2cBindAlipay string `json:"b2c_bind_alipay" xorm:"comment('b2c绑定的支付宝账户') VARCHAR(50)"` | |||
B2cBindAlipayName string `json:"b2c_bind_alipay_name" xorm:"comment('b2c绑定的支付宝账户姓名') VARCHAR(255)"` | |||
AccountWx string `json:"account_wx" xorm:"comment('微信账号(o2o用)') VARCHAR(255)"` | |||
AccountWxRealName string `json:"account_wx_real_name" xorm:"comment('微信账号持有人姓名(o2o用)') VARCHAR(255)"` | |||
AccountWxOpenId string `json:"account_wx_open_id" xorm:"comment('微信账号持有人的OpenId(o2o用)') VARCHAR(255)"` | |||
B2cBindWx string `json:"b2c_bind_wx" xorm:"comment('b2c绑定的微信账户') VARCHAR(255)"` | |||
B2cBindWxName string `json:"b2c_bind_wx_name" xorm:"comment('b2c绑定的微信账户姓名') VARCHAR(255)"` | |||
Zone string `json:"zone" xorm:" default '86' comment('区号') VARCHAR(10)"` | |||
} |
@@ -18,4 +18,7 @@ type SubsidyBase struct { | |||
SettleTime string `json:"settle_time" xorm:"comment('每天 XX:xx') VARCHAR(255)"` | |||
HolidaySettleOpen int `json:"holiday_settle_open" xorm:"default 0 comment('节假日是否结算') INT(1)"` | |||
SettlementDate string `json:"settlement_date" xorm:"not null default '0000-00' comment('结算日期(0000-00)') CHAR(50)"` | |||
StoreOpen int `json:"store_open" xorm:"default 0 comment('节假日是否结算') INT(1)"` | |||
StoreIntegral string `json:"store_integral" xorm:"default 0.00 comment('消费补贴') DECIMAL(20,2)"` | |||
StoreMoney string `json:"store_money" xorm:"default 0.00 comment('消费补贴') DECIMAL(20,2)"` | |||
} |
@@ -6,4 +6,5 @@ type SubsidyWithUserMonth struct { | |||
Date string `json:"date" xorm:"comment('2023-12') VARCHAR(255)"` | |||
ConsumeAmount string `json:"consume_amount" xorm:"default 0.00 DECIMAL(20,2)"` | |||
ExperienceAmount string `json:"experience_amount" xorm:"default 0.00 DECIMAL(20,2)"` | |||
StoreAmount string `json:"store_amount" xorm:"default 0.00 DECIMAL(20,2)"` | |||
} |
@@ -15,6 +15,7 @@ const ( | |||
IntegralReleaseServiceRevenueRefundTitleForFinUserFlow = "订单退款-服务收益扣除" | |||
ConsumeSubsidyTitleForFinUserFlow = "消费补贴-收益" | |||
ExperienceSubsidyTitleForFinUserFlow = "体验补贴-收益" | |||
StoreSubsidyTitleForFinUserFlow = "门店补贴-收益" | |||
GreenEnergyExchangeForBalanceTitleForFinUserFlow = "兑换账户余额" | |||
BalanceExchangeForGreenEnergyTitleForFinUserFlow = "账户余额兑换" | |||
GreenCoinDoubleChainExchangeForBalanceTitleForFinUserFlow = "绿色积分双链兑换账户余额" | |||
@@ -25,6 +26,7 @@ const ( | |||
IntegralReleaseServiceRevenueOrderRefundTypeForFinUserFlow = 51 // 积分释放-服务收益退款 | |||
ConsumeSubsidyOrdActionForFinUserFlow = 110 // 消费补贴-收益 | |||
ExperienceSubsidyOrdActionForFinUserFlow = 111 // 体验补贴-收益 | |||
StoreSubsidyOrdActionForFinUserFlow = 115 // 体验补贴-收益 | |||
GreenEnergyExchangeForBalanceForFinUserFlow = 112 // 兑换账户余额 | |||
BalanceExchangeForGreenEnergyForFinUserFlow = 113 // 账户余额兑换 | |||
GreenCoinDoubleChainExchangeForBalanceForFinUserFlow = 114 // 绿色积分双链兑换账户余额 | |||
@@ -32,6 +34,7 @@ const ( | |||
const DealUserAmountRequestIdPrefix = "%s:deal_user_amount:%d" | |||
const UserAmountRedisKey = "%s:rule_user_amount:%d" | |||
const StoreUserAmountRedisKey = "%s:rule_store_user_amount:%d" | |||
type DealIntegralReleaseInterpositionUserAmountReq struct { | |||
Kind string `json:"kind"` | |||
@@ -83,8 +83,8 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
cache.SetEx(key, PessimismLockValueForConsumeIntegral, 3600*8) //8小时 | |||
var consumeValueTotal, experienceValueTotal = decimal.NewFromInt(0), decimal.NewFromInt(0) | |||
var consumeValue, experienceValue float64 | |||
var consumeValueTotal, experienceValueTotal, storeValueTotal = decimal.NewFromInt(0), decimal.NewFromInt(0), decimal.NewFromInt(0) | |||
var consumeValue, experienceValue, storeValue float64 | |||
//1、统计当前拥有多少份消费补贴 | |||
startAt := time.Now().Add(time.Duration(subsidyBase.ConsumptionDay) * -24 * time.Hour).Format("2006-01-02") //起始时间 | |||
var subsidyWithUserForConsumeList []model.SubsidyWithUser | |||
@@ -94,15 +94,30 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
return | |||
} | |||
var subsidyWithUserForExperienceList []model.SubsidyWithUser | |||
hasExperienceTotal, err := session.Where("date <= ?", startAt).And("kind = ? and is_can_subsidy=?", 2, 1).FindAndCount(&subsidyWithUserForExperienceList) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
var subsidyWithUserForStoreList []model.SubsidyWithUser | |||
hasStoreTotal, err := session.Where("date <= ?", startAt).And("kind = ? and is_can_subsidy=?", 3, 1).FindAndCount(&subsidyWithUserForStoreList) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
var consumeTotalMap = make(map[int]decimal.Decimal) | |||
var consumeTotalCountMap = make(map[int]int) | |||
total := hasConsumeTotal + hasExperienceTotal | |||
if subsidyBase.StoreOpen == 1 { | |||
total += hasStoreTotal | |||
} | |||
consumeValue, err = calcNowEverydayConsumeIntegral(subsidyBase, total) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return err | |||
} | |||
if hasConsumeTotal > 0 { | |||
consumeValue, err = calcNowEverydayConsumeIntegral(subsidyBase, hasConsumeTotal) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return err | |||
} | |||
for _, v := range subsidyWithUserForConsumeList { | |||
consumeTotalMap[v.Uid] = consumeTotalMap[v.Uid].Add(decimal.NewFromFloat(consumeValue)) | |||
consumeTotalCountMap[v.Uid]++ | |||
@@ -125,12 +140,7 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
} | |||
//2、统计当前拥有多少份体验补贴 | |||
var subsidyWithUserForExperienceList []model.SubsidyWithUser | |||
hasExperienceTotal, err := session.Where("date <= ?", startAt).And("kind = ? and is_can_subsidy=?", 2, 1).FindAndCount(&subsidyWithUserForExperienceList) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
var experienceTotalMap = make(map[int]decimal.Decimal) | |||
var experienceTotalCountMap = make(map[int]int) | |||
if hasExperienceTotal > 0 && consumeValue > 0 { | |||
@@ -160,6 +170,41 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
} | |||
} | |||
} | |||
//2、统计当前拥有多少份门店补贴 | |||
if subsidyBase.StoreOpen == 1 { | |||
var storeTotalMap = make(map[int]decimal.Decimal) | |||
var storeTotalCountMap = make(map[int]int) | |||
if hasStoreTotal > 0 && consumeValue > 0 { | |||
experienceValue, err = calcNowEverydayStoreIntegral(consumeValue, zhios_order_relate_utils.StrToFloat64(subsidyBase.StoreIntegral)/zhios_order_relate_utils.StrToFloat64(subsidyBase.ConsumptionIntegral)) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return err | |||
} | |||
for _, v := range subsidyWithUserForStoreList { | |||
storeTotalCountMap[v.Uid]++ | |||
storeTotalMap[v.Uid] = storeTotalMap[v.Uid].Add(decimal.NewFromFloat(storeValue)) | |||
storeValueTotal = storeValueTotal.Add(decimal.NewFromFloat(storeValue)) | |||
err1 := DealUserStoreIntegral(session, &v, storeValue, mid) | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1 | |||
} | |||
} | |||
} | |||
//加余额流水 | |||
if len(storeTotalMap) > 0 { | |||
for k, v := range storeTotalMap { | |||
err1 := DealUserStoreAmountFlow(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() | |||
@@ -215,6 +260,19 @@ func calcNowEverydayExperienceIntegral(consumeValue float64) (value float64, err | |||
//value, _ = experienceMoney.Mul(floatSubsidyBili).Div(consumeTotal).Add(baseSubsidyMoney).RoundFloor(2).Float64() | |||
return | |||
} | |||
func calcNowEverydayStoreIntegral(consumeValue, bili float64) (value float64, err error) { | |||
value, _ = decimal.NewFromFloat(consumeValue * bili).RoundFloor(2).Float64() | |||
////2、通过公式计算 "((资金池的金额 * 浮动比例) / 体验补贴总数) + 基础补贴" | |||
//experienceMoney, _ := decimal.NewFromString(subsidyBase.ExperienceTotalMoney) | |||
//baseSubsidyMoney, _ := decimal.NewFromString(subsidyBase.BaseSubsidyMoney) | |||
//if subsidyBase.FloatSubsidyOpen == 0 { //没有浮动补贴情况 | |||
// subsidyBase.FloatSubsidyBili = 0 | |||
//} | |||
//floatSubsidyBili := decimal.NewFromFloat(float64(subsidyBase.FloatSubsidyBili) / 10000) | |||
//consumeTotal := decimal.NewFromInt(hasExperienceTotal) | |||
//value, _ = experienceMoney.Mul(floatSubsidyBili).Div(consumeTotal).Add(baseSubsidyMoney).RoundFloor(2).Float64() | |||
return | |||
} | |||
// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 | |||
func DealUserConsumeIntegral(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, consumeIntegralValue float64, mid string) (err error) { | |||
@@ -363,6 +421,80 @@ func DealUserExperienceIntegral(session *xorm.Session, subsidyWithUser *model.Su | |||
} | |||
// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 | |||
func DealUserStoreIntegral(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, experienceIntegralValue float64, mid string) (err error) { | |||
now := time.Now() | |||
//1、扣除 subsidy_with_user 的 balance_amount、state | |||
if subsidyWithUser.Amount == subsidyWithUser.BalanceAmount { | |||
subsidyWithUser.State = 2 //补贴中 | |||
} | |||
balanceAmount, _ := decimal.NewFromString(subsidyWithUser.BalanceAmount) | |||
afterAmount, _ := balanceAmount.Sub(decimal.NewFromFloat(experienceIntegralValue)).Float64() | |||
if afterAmount <= 0 { | |||
afterAmount = 0 | |||
experienceIntegralValue = zhios_order_relate_utils.StrToFloat64(subsidyWithUser.BalanceAmount) | |||
subsidyWithUser.State = 3 //补贴完 | |||
} | |||
subsidyWithUser.BalanceAmount = zhios_order_relate_utils.Float64ToStr(afterAmount) | |||
updateAffected, err := db.SubsidyWithUserUpdate(session, subsidyWithUser.Id, subsidyWithUser, "balance_amount", "state") | |||
if err != nil { | |||
return err | |||
} | |||
if updateAffected <= 0 { | |||
return errors.New("修改 subsidy_with_user 记录失败") | |||
} | |||
//2、新增 subsidy_with_user_flow 记录 | |||
var subsidyWitUserFlow = &model.SubsidyWithUserFlow{ | |||
RecordsId: subsidyWithUser.Id, | |||
Uid: subsidyWithUser.Uid, | |||
Kind: subsidyWithUser.Kind, | |||
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"), | |||
} | |||
insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) | |||
if err != nil { | |||
return err | |||
} | |||
if insertAffected <= 0 { | |||
return errors.New("新增 subsidy_with_user_flow 记录失败") | |||
} | |||
//3、加入每月统计 | |||
if experienceIntegralValue > 0 { | |||
var subsidyWitUserMonth = &model.SubsidyWithUserMonth{ | |||
Uid: subsidyWithUser.Uid, | |||
StoreAmount: zhios_order_relate_utils.Float64ToStr(experienceIntegralValue), | |||
Date: now.Format("2006-01"), | |||
} | |||
_, err1 := db.SubsidyWithMonthInsert(session, subsidyWitUserMonth) | |||
if err1 != nil { | |||
return err | |||
} | |||
} | |||
//4、给用户添加余额 | |||
orderType := enum.FinUserFlowOrderActionString(md.StoreSubsidyOrdActionForFinUserFlow) | |||
var dealUserAmount = md.DealUserAmount{ | |||
Kind: "add", | |||
Mid: mid, | |||
Title: md.StoreSubsidyTitleForFinUserFlow, | |||
OrderType: orderType, | |||
OrdAction: md.StoreSubsidyOrdActionForFinUserFlow, | |||
OrdId: strconv.Itoa(subsidyWithUser.Id), | |||
Uid: subsidyWithUser.Uid, | |||
Amount: experienceIntegralValue, | |||
} | |||
err = svc.DealStoreUserAmountNew(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
return nil | |||
} | |||
// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 流水 | |||
func DealUserConsumeAmountFlow(session *xorm.Session, uid int, consumeIntegralValue float64, mid, num string) (err error) { | |||
//4、给用户添加余额流水 | |||
@@ -405,3 +537,25 @@ func DealUserExperienceAmountFlow(session *xorm.Session, uid int, experienceInte | |||
return nil | |||
} | |||
// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 | |||
func DealUserStoreAmountFlow(session *xorm.Session, uid int, experienceIntegralValue float64, mid, num string) (err error) { | |||
//4、给用户添加余额 | |||
orderType := enum.FinUserFlowOrderActionString(md.StoreSubsidyOrdActionForFinUserFlow) | |||
var dealUserAmount = md.DealUserAmount{ | |||
Kind: "add", | |||
Mid: mid, | |||
Title: md.StoreSubsidyTitleForFinUserFlow, | |||
OrderType: orderType, | |||
OrdAction: md.StoreSubsidyOrdActionForFinUserFlow, | |||
Uid: uid, | |||
Amount: experienceIntegralValue, | |||
Num: num, | |||
} | |||
err = svc.DealUserStoreAmountFlow(session, dealUserAmount) | |||
if err != nil { | |||
return | |||
} | |||
return nil | |||
} |
@@ -127,6 +127,44 @@ func DealUserAmountNew(session *xorm.Session, req md.DealUserAmount) (err error) | |||
return nil | |||
} | |||
func DealStoreUserAmountNew(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 := GetStoreUserAmount(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 = SetCacheStoreUserAmount(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 | |||
@@ -176,6 +214,55 @@ func DealUserAmountFlow(session *xorm.Session, req md.DealUserAmount) (err error | |||
} | |||
return nil | |||
} | |||
func DealUserStoreAmountFlow(session *xorm.Session, req md.DealUserAmount) (err error) { | |||
if req.Amount < 0 { | |||
req.Amount = 0 | |||
} | |||
//2、计算&&组装数据 | |||
now := time.Now() | |||
userAmount, err := GetStoreUserAmount(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.O2oFinUserFlow{ | |||
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) { | |||
@@ -221,3 +308,31 @@ func SetCacheUserAmount(session *xorm.Session, masterId, amount string, uid int, | |||
} | |||
return nil | |||
} | |||
// GetUserAmount 获取用户余额 | |||
func GetStoreUserAmount(session *xorm.Session, masterId string, uid int) (amount string, err error) { | |||
userAmount, err := db.O2oMerchantFindByIDWithSession(session, uid) | |||
if err != nil { | |||
return amount, err | |||
} | |||
if userAmount == nil { | |||
amount = "0" | |||
} else { | |||
amount = zhios_order_relate_utils.Float64ToStrByPrec(userAmount.Amount, 8) | |||
} | |||
return amount, nil | |||
} | |||
// SetCacheUserAmount 设置缓存的用户余额 | |||
func SetCacheStoreUserAmount(session *xorm.Session, masterId, amount string, uid int, isUpdateDb bool) error { | |||
_, err := session.Where("id=?", uid).Update(model.O2oMerchant{ | |||
Id: uid, | |||
Amount: zhios_order_relate_utils.StrToFloat64(amount), | |||
}) | |||
if err != nil { | |||
return err | |||
} | |||
return nil | |||
} |