diff --git a/db/db_subsidy_base.go b/db/db_subsidy_base.go new file mode 100644 index 0000000..7eea279 --- /dev/null +++ b/db/db_subsidy_base.go @@ -0,0 +1,147 @@ +package db + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "errors" + "fmt" + "reflect" + "xorm.io/xorm" +) + +// SubsidyBaseInsert 插入单条数据 +func SubsidyBaseInsert(Db *xorm.Engine, SubsidyBase *model.SubsidyBase) (int, error) { + _, err := Db.InsertOne(SubsidyBase) + if err != nil { + return 0, err + } + return SubsidyBase.Id, nil +} + +// BatchAddSubsidyBases 批量新增数据 +func BatchAddSubsidyBases(Db *xorm.Engine, SubsidyBaseData []*model.SubsidyBase) (int64, error) { + affected, err := Db.Insert(SubsidyBaseData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetSubsidyBaseCount(Db *xorm.Engine) int { + var SubsidyBase model.SubsidyBase + session := Db.Where("") + count, err := session.Count(&SubsidyBase) + if err != nil { + return 0 + } + return int(count) +} + +// SubsidyBaseDelete 删除记录 +func SubsidyBaseDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.SubsidyBase{}) + } else { + return Db.Where("id = ?", id).Delete(model.SubsidyBase{}) + } +} + +// SubsidyBaseUpdate 更新记录 +func SubsidyBaseUpdate(session *xorm.Session, id interface{}, SubsidyBase *model.SubsidyBase, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(SubsidyBase) + } else { + affected, err = session.Where("id=?", id).Update(SubsidyBase) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// SubsidyBaseGetOneByParams 通过传入的参数查询数据(单条) +func SubsidyBaseGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.SubsidyBase, error) { + var m model.SubsidyBase + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := session.Where(query, params["value"]).Get(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + if has == false { + return nil, errors.New("未查询到相应的 block_star_chain 记录") + } + return &m, nil +} + +// SubsidyBaseFindByParams 通过传入的参数查询数据(多条) +func SubsidyBaseFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.SubsidyBase, error) { + var m []model.SubsidyBase + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} + +func SubsidyBaseFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.SubsidyBase, error) { + var m []model.SubsidyBase + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if page == 0 && pageSize == 0 { + page = 1 + pageSize = 10 + } + + if params["key"] == nil { + //查询全部数据 + err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} diff --git a/db/db_subsidy_with_user.go b/db/db_subsidy_with_user.go new file mode 100644 index 0000000..3da3572 --- /dev/null +++ b/db/db_subsidy_with_user.go @@ -0,0 +1,147 @@ +package db + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "errors" + "fmt" + "reflect" + "xorm.io/xorm" +) + +// SubsidyWithUserInsert 插入单条数据 +func SubsidyWithUserInsert(Db *xorm.Engine, SubsidyWithUser *model.SubsidyWithUser) (int, error) { + _, err := Db.InsertOne(SubsidyWithUser) + if err != nil { + return 0, err + } + return SubsidyWithUser.Id, nil +} + +// BatchAddSubsidyWithUsers 批量新增数据 +func BatchAddSubsidyWithUsers(Db *xorm.Engine, SubsidyWithUserData []*model.SubsidyWithUser) (int64, error) { + affected, err := Db.Insert(SubsidyWithUserData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetSubsidyWithUserCount(Db *xorm.Engine) int { + var SubsidyWithUser model.SubsidyWithUser + session := Db.Where("") + count, err := session.Count(&SubsidyWithUser) + if err != nil { + return 0 + } + return int(count) +} + +// SubsidyWithUserDelete 删除记录 +func SubsidyWithUserDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.SubsidyWithUser{}) + } else { + return Db.Where("id = ?", id).Delete(model.SubsidyWithUser{}) + } +} + +// SubsidyWithUserUpdate 更新记录 +func SubsidyWithUserUpdate(session *xorm.Session, id interface{}, SubsidyWithUser *model.SubsidyWithUser, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(SubsidyWithUser) + } else { + affected, err = session.Where("id=?", id).Update(SubsidyWithUser) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// SubsidyWithUserGetOneByParams 通过传入的参数查询数据(单条) +func SubsidyWithUserGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.SubsidyWithUser, error) { + var m model.SubsidyWithUser + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := session.Where(query, params["value"]).Get(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + if has == false { + return nil, errors.New("未查询到相应的 block_star_chain 记录") + } + return &m, nil +} + +// SubsidyWithUserFindByParams 通过传入的参数查询数据(多条) +func SubsidyWithUserFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.SubsidyWithUser, error) { + var m []model.SubsidyWithUser + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} + +func SubsidyWithUserFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.SubsidyWithUser, error) { + var m []model.SubsidyWithUser + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if page == 0 && pageSize == 0 { + page = 1 + pageSize = 10 + } + + if params["key"] == nil { + //查询全部数据 + err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} diff --git a/db/db_subsidy_with_user_flow.go b/db/db_subsidy_with_user_flow.go new file mode 100644 index 0000000..5c343dc --- /dev/null +++ b/db/db_subsidy_with_user_flow.go @@ -0,0 +1,147 @@ +package db + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "errors" + "fmt" + "reflect" + "xorm.io/xorm" +) + +// SubsidyWithUserFlowInsert 插入单条数据 +func SubsidyWithUserFlowInsert(session *xorm.Session, SubsidyWithUserFlow *model.SubsidyWithUserFlow) (int, error) { + _, err := session.InsertOne(SubsidyWithUserFlow) + if err != nil { + return 0, err + } + return SubsidyWithUserFlow.Id, nil +} + +// BatchAddSubsidyWithUserFlows 批量新增数据 +func BatchAddSubsidyWithUserFlows(Db *xorm.Engine, SubsidyWithUserFlowData []*model.SubsidyWithUserFlow) (int64, error) { + affected, err := Db.Insert(SubsidyWithUserFlowData) + if err != nil { + return 0, err + } + return affected, nil +} + +func GetSubsidyWithUserFlowCount(Db *xorm.Engine) int { + var SubsidyWithUserFlow model.SubsidyWithUserFlow + session := Db.Where("") + count, err := session.Count(&SubsidyWithUserFlow) + if err != nil { + return 0 + } + return int(count) +} + +// SubsidyWithUserFlowDelete 删除记录 +func SubsidyWithUserFlowDelete(Db *xorm.Engine, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.SubsidyWithUserFlow{}) + } else { + return Db.Where("id = ?", id).Delete(model.SubsidyWithUserFlow{}) + } +} + +// SubsidyWithUserFlowUpdate 更新记录 +func SubsidyWithUserFlowUpdate(session *xorm.Session, id interface{}, SubsidyWithUserFlow *model.SubsidyWithUserFlow, forceColums ...string) (int64, error) { + var ( + affected int64 + err error + ) + if forceColums != nil { + affected, err = session.Where("id=?", id).Cols(forceColums...).Update(SubsidyWithUserFlow) + } else { + affected, err = session.Where("id=?", id).Update(SubsidyWithUserFlow) + } + if err != nil { + return 0, err + } + return affected, nil +} + +// SubsidyWithUserFlowGetOneByParams 通过传入的参数查询数据(单条) +func SubsidyWithUserFlowGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.SubsidyWithUserFlow, error) { + var m model.SubsidyWithUserFlow + var query = fmt.Sprintf("%s =?", params["key"]) + has, err := session.Where(query, params["value"]).Get(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + if has == false { + return nil, errors.New("未查询到相应的 block_star_chain 记录") + } + return &m, nil +} + +// SubsidyWithUserFlowFindByParams 通过传入的参数查询数据(多条) +func SubsidyWithUserFlowFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.SubsidyWithUserFlow, error) { + var m []model.SubsidyWithUserFlow + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} + +func SubsidyWithUserFlowFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.SubsidyWithUserFlow, error) { + var m []model.SubsidyWithUserFlow + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if page == 0 && pageSize == 0 { + page = 1 + pageSize = 10 + } + + if params["key"] == nil { + //查询全部数据 + err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil { + return nil, zhios_order_relate_logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m) + if err != nil { + return nil, zhios_order_relate_logx.Error(err) + } + return &m, nil + } + + } +} diff --git a/db/model/subsidy_base.go b/db/model/subsidy_base.go new file mode 100644 index 0000000..dba8852 --- /dev/null +++ b/db/model/subsidy_base.go @@ -0,0 +1,18 @@ +package model + +type SubsidyBase struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + IsOpen int `json:"is_open" xorm:"default 0 comment('功能开关:') INT(1)"` + LvList string `json:"lv_list" xorm:"comment('json [] 兑换等级:') VARCHAR(255)"` + FloatSubsidyOpen int `json:"float_subsidy_open" xorm:"default 0 comment('浮动补贴比例:') INT(1)"` + BaseSubsidyMoney string `json:"base_subsidy_money" xorm:"default 0.00 comment('补贴基础金额设置:') DECIMAL(20,2)"` + ConsumptionIntegral string `json:"consumption_integral" xorm:"not null default 0.00 comment('消费积分数量') DECIMAL(20,2)"` + ConsumptionMoney string `json:"consumption_money" xorm:"default 0.00 comment('消费补贴') DECIMAL(20,2)"` + ExperienceIntegral string `json:"experience_integral" xorm:"default 0.00 comment('体验积分数量') DECIMAL(20,2)"` + ExperienceMoney string `json:"experience_money" xorm:"default 0.00 comment('体验补贴') DECIMAL(20,2)"` + ConsumptionDay int `json:"consumption_day" xorm:"default 0 comment('消费补贴兑换后第X天') INT(11)"` + ExperienceDay int `json:"experience_day" xorm:"comment('体贴补贴兑换后第X天') VARCHAR(255)"` + 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)"` +} diff --git a/db/model/subsidy_with_user.go b/db/model/subsidy_with_user.go new file mode 100644 index 0000000..8d19f37 --- /dev/null +++ b/db/model/subsidy_with_user.go @@ -0,0 +1,14 @@ +package model + +type SubsidyWithUser struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Kind int `json:"kind" xorm:"not null default 1 comment('类型(1:消费补贴 2:体验补贴)') TINYINT(1)"` + Uid int `json:"uid" xorm:"not null default 0 comment('uid') INT(11)"` + IntegralNum string `json:"integral_num" xorm:"not null default 0.00 comment('积分数量') DECIMAL(6,2)"` + Amount string `json:"amount" xorm:"not null default 0.00 comment('金额') DECIMAL(6,2)"` + BalanceAmount string `json:"balance_amount" xorm:"not null default 0.00 comment('余额') DECIMAL(6,2)"` + State int `json:"state" xorm:"not null default 1 comment('状态(1:待补贴 2:补贴中 3:补贴完)') TINYINT(1)"` + Date string `json:"date" xorm:"not null default '0000-00-00' comment('购入日期') CHAR(50)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` +} diff --git a/db/model/subsidy_with_user_flow.go b/db/model/subsidy_with_user_flow.go new file mode 100644 index 0000000..554f674 --- /dev/null +++ b/db/model/subsidy_with_user_flow.go @@ -0,0 +1,10 @@ +package model + +type SubsidyWithUserFlow struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + RecordsId int `json:"records_id" xorm:"not null default 0 comment('记录id') INT(11)"` + Amount string `json:"amount" xorm:"not null default 0.00 comment('金额') DECIMAL(6,2)"` + BalanceAmount string `json:"balance_amount" xorm:"not null default 0.00 comment('余额') DECIMAL(6,2)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` +} diff --git a/enum/fin_user_flow.go b/enum/fin_user_flow.go index 02f211b..c4cd901 100644 --- a/enum/fin_user_flow.go +++ b/enum/fin_user_flow.go @@ -6,6 +6,10 @@ func FinUserFlowOrderActionString(kind int) string { switch kind { case md.IntegralReleaseServiceRevenueOrderTypeForFinUserFlow: return "integral_release_service_revenue" + case md.ConsumeSubsidyOrdActionForFinUserFlow: + return "consume_subsidy" + case md.ExperienceSubsidyOrdActionForFinUserFlow: + return "experience_subsidy" default: return "unknown" } diff --git a/md/block_star_chain.go b/md/block_star_chain.go index cc638b9..ac8cd0a 100644 --- a/md/block_star_chain.go +++ b/md/block_star_chain.go @@ -118,6 +118,7 @@ const ( const DealUserCoinRequestIdPrefix = "%s:block_star_chain_deal_user_coin:%d:uid:%d" const DealUserCoinForGreenRequestIdPrefix = "%s:block_star_chain_deal_user_coin_for_green:%d:uid:%d" +const DealConsumeIntegralRequestIdPrefix = "consume_integral:%s:uid:%d" const RewardBaseMultiple = 10 //区块星链-打赏倍数 const RewardBaseMultipleForMerchant = 2 //区块星链-打赏倍数(商家) diff --git a/md/fin_user_flow.go b/md/fin_user_flow.go index 21f5dc2..9bb0c26 100644 --- a/md/fin_user_flow.go +++ b/md/fin_user_flow.go @@ -13,11 +13,15 @@ const ( const ( IntegralReleaseServiceRevenueTitleForFinUserFlow = "积分释放-服务收益" IntegralReleaseServiceRevenueRefundTitleForFinUserFlow = "订单退款-服务收益扣除" + ConsumeSubsidyTitleForFinUserFlow = "消费补贴-收益" + ExperienceSubsidyTitleForFinUserFlow = "体验补贴-收益" ) const ( - IntegralReleaseServiceRevenueOrderTypeForFinUserFlow = 50 // 积分释放-服务收益 - IntegralReleaseServiceRevenueOrderRefundTypeForFinUserFlow = 51 // 积分释放-服务收益退款 + IntegralReleaseServiceRevenueOrderTypeForFinUserFlow = 50 // 积分释放-服务收益 + IntegralReleaseServiceRevenueOrderRefundTypeForFinUserFlow = 51 // 积分释放-服务收益退款 + ConsumeSubsidyOrdActionForFinUserFlow = 110 // 消费补贴-收益 + ExperienceSubsidyOrdActionForFinUserFlow = 111 // 体验补贴-收益 ) const DealUserAmountRequestIdPrefix = "%s:deal_user_amount:%d" diff --git a/rule/consume_integral_settlement.go b/rule/consume_integral_settlement.go new file mode 100644 index 0000000..d9dfb5d --- /dev/null +++ b/rule/consume_integral_settlement.go @@ -0,0 +1,260 @@ +package rule + +import ( + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/enum" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/svc" + zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils" + "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/cache" + zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx" + "errors" + "fmt" + "github.com/shopspring/decimal" + "strconv" + "time" + "xorm.io/xorm" +) + +func InitForConsumeIntegral(redisAddr string) (err error) { + if redisAddr != "" { + cache.NewRedis(redisAddr) + } + _, err = cache.SelectDb(md.RedisDataBase) + return +} + +const PessimismLockKeyForConsumeIntegral = "daily_settlement_consume_integral_lock_key" +const PessimismLockValueForConsumeIntegral = "running" + +// DailySettlementBlockConsumeIntegral 每日结算“消费积分” +func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask bool) (err error) { + session := engine.NewSession() + defer func() { + session.Close() + if err := recover(); err != nil { + _ = zhios_order_relate_logx.Error(err) + } + }() + session.Begin() + now := time.Now() + today := now.Format("2006-01-02") + + //1、查找 `subsidy_base` 基础设置 + subsidyBase, err := db.SubsidyBaseGetOneByParams(session, map[string]interface{}{ + "key": "is_open", + "value": 1, + }) + + fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", now.Hour()) + settleTime, err := time.ParseInLocation("2006-01-02 15:04:05", today+subsidyBase.SettleTime, time.Local) + if err != nil { + return + } + if isTask && (now.Hour() > 8) && now.After(settleTime) { + //TODO::结算时间 ~ 凌晨 8 点运行 + return errors.New("非运行时间") + } + + if err != nil { + _ = session.Rollback() + return err + } + if subsidyBase.SettlementDate == today { + _ = session.Rollback() + return errors.New("今日“消费计费”已结算") + } + + //TODO::增加“悲观锁”防止串行 + getString, _ := cache.GetString(PessimismLockKeyForConsumeIntegral) + //if err != nil { + // return err + //} + if getString == PessimismLockValueForConsumeIntegral { + fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "上一次结算未执行完") + return errors.New("上一次结算未执行完") + } + cache.SetEx(PessimismLockKeyForConsumeIntegral, PessimismLockValueForConsumeIntegral, 3600*8) //8小时 + //1、统计当前拥有多少份消费补贴 + startAt := time.Now().Add(time.Duration(subsidyBase.ConsumptionDay) * -24 * time.Hour).Format("2006-01-02") //起始时间 + var subsidyWithUserForConsumeList []model.SubsidyWithUser + hasConsumeTotal, err := session.Where("date <= ?", startAt).And("kind = ?", 1).FindAndCount(&subsidyWithUserForConsumeList) + if err != nil { + return + } + consumeValue, err := calcNowEverydayConsumeIntegral(subsidyBase, hasConsumeTotal) + if err != nil { + _ = session.Rollback() + return err + } + for _, v := range subsidyWithUserForConsumeList { + err1 := DealUserConsumeIntegral(session, &v, consumeValue, mid) + if err1 != nil { + _ = session.Rollback() + return err1 + } + } + + //2、统计当前拥有多少份体验补贴 + var subsidyWithUserForExperienceList []model.SubsidyWithUser + hasExperienceTotal, err := session.Where("date <= ?", startAt).And("kind = ?", 2).FindAndCount(&subsidyWithUserForExperienceList) + if err != nil { + return + } + experienceValue, err := calcNowEverydayExperienceIntegral(subsidyBase, hasExperienceTotal) + if err != nil { + _ = session.Rollback() + return err + } + for _, v := range subsidyWithUserForConsumeList { + err1 := DealUserExperienceIntegral(session, &v, experienceValue, mid) + if err1 != nil { + _ = session.Rollback() + return err1 + } + } + + cache.Del(PessimismLockKeyForConsumeIntegral) + fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>消费积分结束<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") + return nil +} + +//计算当前消费积分价值(公式 "((资金池的金额 * 浮动比例) / 消费补贴总数) + 基础补贴") +func calcNowEverydayConsumeIntegral(subsidyBase *model.SubsidyBase, hasConsumeTotal int64) (value float64, err error) { + consumptionMoney, _ := decimal.NewFromString(subsidyBase.ConsumptionMoney) + baseSubsidyMoney, _ := decimal.NewFromString(subsidyBase.BaseSubsidyMoney) + floatSubsidyOpen := decimal.NewFromInt(int64(subsidyBase.FloatSubsidyOpen) / 10000) + consumeTotal := decimal.NewFromInt(hasConsumeTotal) + value, _ = consumptionMoney.Mul(floatSubsidyOpen).Div(consumeTotal).Add(baseSubsidyMoney).Float64() + return +} + +//计算当前体验积分价值 +func calcNowEverydayExperienceIntegral(subsidyBase *model.SubsidyBase, hasExperienceTotal int64) (value float64, err error) { + //2、通过公式计算 "((资金池的金额 * 浮动比例) / 体验补贴总数) + 基础补贴" + experienceMoney, _ := decimal.NewFromString(subsidyBase.ExperienceMoney) + baseSubsidyMoney, _ := decimal.NewFromString(subsidyBase.BaseSubsidyMoney) + floatSubsidyOpen := decimal.NewFromInt(int64(subsidyBase.FloatSubsidyOpen) / 10000) + consumeTotal := decimal.NewFromInt(hasExperienceTotal) + value, _ = experienceMoney.Mul(floatSubsidyOpen).Div(consumeTotal).Add(baseSubsidyMoney).Float64() + return +} + +// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 +func DealUserConsumeIntegral(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, consumeIntegralValue 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(consumeIntegralValue)).Float64() + if afterAmount <= 0 { + afterAmount = 0 + consumeIntegralValue = 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, + Amount: zhios_order_relate_utils.Float64ToStr(consumeIntegralValue), + 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"), + } + insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) + if err != nil { + return err + } + if insertAffected <= 0 { + return errors.New("新增 subsidy_with_user_flow 记录失败") + } + + //3、给用户添加余额 + orderType := enum.FinUserFlowOrderActionString(md.ConsumeSubsidyOrdActionForFinUserFlow) + var dealUserAmount = md.DealUserAmount{ + Kind: "add", + Mid: mid, + Title: md.ConsumeSubsidyTitleForFinUserFlow, + OrderType: orderType, + OrdAction: md.ConsumeSubsidyOrdActionForFinUserFlow, + OrdId: strconv.Itoa(subsidyWithUser.Id), + Uid: subsidyWithUser.Uid, + Amount: consumeIntegralValue, + } + err = svc.DealUserAmount(session, dealUserAmount) + if err != nil { + return + } + return nil +} + +// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 +func DealUserExperienceIntegral(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, + Amount: zhios_order_relate_utils.Float64ToStr(experienceIntegralValue), + 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"), + } + insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) + if err != nil { + return err + } + if insertAffected <= 0 { + return errors.New("新增 subsidy_with_user_flow 记录失败") + } + + //3、给用户添加余额 + orderType := enum.FinUserFlowOrderActionString(md.ExperienceSubsidyOrdActionForFinUserFlow) + var dealUserAmount = md.DealUserAmount{ + Kind: "add", + Mid: mid, + Title: md.ExperienceSubsidyTitleForFinUserFlow, + OrderType: orderType, + OrdAction: md.ExperienceSubsidyOrdActionForFinUserFlow, + OrdId: strconv.Itoa(subsidyWithUser.Id), + Uid: subsidyWithUser.Uid, + Amount: experienceIntegralValue, + } + err = svc.DealUserAmount(session, dealUserAmount) + if err != nil { + return + } + return nil + + return nil +} diff --git a/svc/svc_deal_user_amount.go b/svc/svc_deal_user_amount.go index 14ba0ce..826c385 100644 --- a/svc/svc_deal_user_amount.go +++ b/svc/svc_deal_user_amount.go @@ -73,7 +73,7 @@ func DealUserAmount(session *xorm.Session, req md.DealUserAmount) (err error) { return errors.New("用户余额不足") } - //3、插入 `user_virtual_coin_flow` 记录 + //3、插入 `fin_user_flow` 记录 affected, err := session.Insert(&finUserFlow) if affected == 0 || err != nil { _ = zhios_order_relate_logx.Warn(err)