package egg_energy import ( "code.fnuoos.com/EggPlanet/egg_models.git/src/implement" "code.fnuoos.com/EggPlanet/egg_models.git/src/model" "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/enum" md2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/md" "code.fnuoos.com/EggPlanet/egg_system_rules.git/rule/egg_energy/svc" egg_system_rules "code.fnuoos.com/EggPlanet/egg_system_rules.git/utils" "code.fnuoos.com/EggPlanet/egg_system_rules.git/utils/cache" zhios_order_relate_logx "code.fnuoos.com/EggPlanet/egg_system_rules.git/utils/logx" "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" "encoding/json" "errors" "fmt" "github.com/shopspring/decimal" "time" "xorm.io/xorm" ) const SettlementStarLevelDividendsLockKey = "settlement_star_level_dividends_lock_key" // SettlementStarLevelDividends 蛋蛋能量星级分红 func SettlementStarLevelDividends(engine *xorm.Engine, masterId string, ch *rabbit.Channel) (err error) { now := time.Now() fmt.Println(now.Hour()) if !(now.Hour() > 2 && now.Hour() < 8) { //TODO::只在凌晨一点 ~ 凌晨 8 点运行 return errors.New("非运行时间") } //TODO::增加“悲观锁”防止串行 getString, _ := cache.GetString(SettlementStarLevelDividendsLockKey) if getString != "" { fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "上一次结算未执行完") return errors.New("上一次结算未执行完") } cache.SetEx(SettlementStarLevelDividendsLockKey, "running", 3600*8) //8小时 //1、查找 `egg_energy_basic_setting` 基础设置 eggEnergyBasicSettingDb := implement.NewEggEnergyBasicSettingDb(engine) eggEnergyBasicSetting, err := eggEnergyBasicSettingDb.EggEnergyBasicSettingGetOneByParams(map[string]interface{}{ "key": "is_open", "value": 1, }) if err != nil { return } isLimitDividend := eggEnergyBasicSetting.IsLimitDividend if isLimitDividend != 1 { return errors.New("必须开启限制分红!") } startDate := now.AddDate(0, 0, -1).Format("2006-01-02") + " 00:00:00" endDate := now.Format("2006-01-02") + " 00:00:00" var list []model.EggSignIn err = engine.Where("start_time >= ?", startDate).And("start_time <=?", endDate).Find(&list) if err != nil { fmt.Println("err:::::1111", err) return } if len(list) <= 0 { return errors.New("无须参与星级分红用户!") } var vipEquitySetting []*md2.VipEquitySettingStruct err = json.Unmarshal([]byte(eggEnergyBasicSetting.VipEquitySetting), &vipEquitySetting) if err != nil { fmt.Println("err:::::22222", err) return } userLevelDb := implement.NewUserLevelDb(engine) allUserLevel, err := userLevelDb.UserLevelAllByAsc() if err != nil { return err } var allUserLevelMap = map[int]model.UserLevel{} for _, v := range allUserLevel { allUserLevelMap[v.Id] = *v } session := engine.NewSession() defer func() { session.Close() if err := recover(); err != nil { _ = zhios_order_relate_logx.Error(err) } }() session.Begin() //2、查找 `egg_star_level_dividends_records` 基础设置 eggStarLevelDividendsRecordsDb := implement.NewEggStarLevelDividendsRecordsDb(engine) eggStarLevelDividendsRecords, err := eggStarLevelDividendsRecordsDb.EggStarLevelDividendsRecordsGetOneByParamsBySession(session, map[string]interface{}{ "key": "date", "value": now.AddDate(0, 0, -1).Format("2006-01-02"), }) if err != nil { fmt.Println("err:::::33333", err) return } if eggStarLevelDividendsRecords == nil { return errors.New("今日无分红积分!") } //3、统计各等级人数 dividendAmountValue, _ := decimal.NewFromString(eggStarLevelDividendsRecords.Amount) decimalRate := decimal.NewFromInt(100) //百分比 var vipLevelUserTotalMap = map[string]map[string]int64{} var vipEquitySettingMap = map[string]string{} for _, v := range vipEquitySetting { dividendRatioValue, _ := decimal.NewFromString(v.DividendRatio) dividendRatioValue = dividendRatioValue.Div(decimalRate) //分红比例 vipEquitySettingMap[v.VipLevelId] = dividendAmountValue.Mul(dividendRatioValue).String() //TODO::计算各会员等级能得到多少分红 userLevel, err1 := userLevelDb.UserLevelByID(v.VipLevelId) if err1 != nil { fmt.Println("err:::::444444", err1) return err1 } var ms []*model.UserLevel err1 = session.Where("is_use=1").Where("level_weight > ?", userLevel.LevelWeight).Find(&ms) if err1 != nil { fmt.Println("err:::::55555", err1) return err1 } var tmpVipLevelId = []string{v.VipLevelId} for _, m := range ms { tmpVipLevelId = append(tmpVipLevelId, egg_system_rules.IntToStr(m.Id)) } var users model.User count, err1 := session.In("level", tmpVipLevelId).Count(&users) if err1 != nil { fmt.Println("err:::::66666", err1) return err1 } vipLevelUserTotalMap[v.VipLevelId] = map[string]int64{} vipLevelUserTotalMap[v.VipLevelId]["count"] = count vipLevelUserTotalMap[v.VipLevelId]["weight"] = int64(userLevel.LevelWeight) } //4、处理分红 var userSignInArr []int64 var totalDividendValue = decimal.Decimal{} userRelateDb := implement.NewUserRelateDb(engine) for _, l := range list { userSignInArr = append(userSignInArr, l.Uid) if len(userSignInArr) >= 10000 { var users []*model.User err = session.In("uid", userSignInArr).Find(&users) if err != nil { fmt.Println("err:::::7777777", err) return err } for _, item := range users { var siginDividendValue = decimal.Decimal{} for k, v := range vipLevelUserTotalMap { if int(v["weight"]) > allUserLevelMap[item.Level].LevelWeight { continue } if vipEquitySettingMap[k] != "" && vipLevelUserTotalMap[k]["count"] > 0 { dividendValue, _ := decimal.NewFromString(vipEquitySettingMap[k]) userTotal := decimal.NewFromInt(vipLevelUserTotalMap[k]["count"]) siginDividendValue = siginDividendValue.Add(dividendValue.Div(userTotal)) } } if siginDividendValue.GreaterThan(decimal.NewFromInt(0)) { //TODO::统计当前有多少直推用户昨天签到了 userRelates, err1 := userRelateDb.FindUserRelateByParentUid(item.Id, 1) if err1 != nil { fmt.Println("err:::::88888888", err1) return err } var userRelatesUids []int64 if userRelates != nil { for _, userRelate := range *userRelates { userRelatesUids = append(userRelatesUids, userRelate.Uid) } } if len(userRelatesUids) > 0 { var eggEnergySignIns []*model.EggSignIn err = engine.Where("start_time >= ?", startDate).And("start_time <=?", endDate).In("uid", userRelatesUids).And("is_completed =?", 0).Find(&eggEnergySignIns) if err != nil { fmt.Println("err:::::999999999", err) return } if len(eggEnergySignIns) > 0 { userRelatesUidsValue := decimal.NewFromInt(int64(len(userRelatesUids))) eggEnergySignInsValue := decimal.NewFromInt(int64(len(eggEnergySignIns))) siginDividendValue = siginDividendValue.Mul(eggEnergySignInsValue.Div(userRelatesUidsValue)) } else { siginDividendValue = decimal.NewFromFloat(0) } } else { siginDividendValue = decimal.NewFromFloat(0) } siginDividend, _ := siginDividendValue.Float64() if siginDividend > 0 { //TODO::推入rabbitmq 异步处理 ch.Publish(md2.EggEnergyExchange, md2.EggEnergyStructForStarLevelDividends{ Uid: item.Id, SignDividend: siginDividend, }, md2.EggEnergyRoutKeyForStarLevelDividend) totalDividendValue = totalDividendValue.Add(siginDividendValue) } } } userSignInArr = []int64{} } } if len(userSignInArr) > 0 { var users []*model.User err = session.In("uid", userSignInArr).Find(&users) if err != nil { fmt.Println("err:::::7777777", err) return err } for _, item := range users { var siginDividendValue = decimal.Decimal{} for k, v := range vipLevelUserTotalMap { if int(v["weight"]) > allUserLevelMap[item.Level].LevelWeight { continue } if vipEquitySettingMap[k] != "" && vipLevelUserTotalMap[k]["count"] > 0 { dividendValue, _ := decimal.NewFromString(vipEquitySettingMap[k]) userTotal := decimal.NewFromInt(vipLevelUserTotalMap[k]["count"]) siginDividendValue = siginDividendValue.Add(dividendValue.Div(userTotal)) } } if siginDividendValue.GreaterThan(decimal.NewFromInt(0)) { //TODO::统计当前有多少直推用户昨天签到了 userRelates, err1 := userRelateDb.FindUserRelateByParentUid(item.Id, 1) if err1 != nil { fmt.Println("err:::::88888888", err1) return err } var userRelatesUids []int64 if userRelates != nil { for _, userRelate := range *userRelates { userRelatesUids = append(userRelatesUids, userRelate.Uid) } } if len(userRelatesUids) > 0 { var eggEnergySignIns []*model.EggSignIn err = engine.Where("start_time >= ?", startDate).And("start_time <=?", endDate).In("uid", userRelatesUids).And("is_completed =?", 0).Find(&eggEnergySignIns) if err != nil { fmt.Println("err:::::999999999", err) return } if len(eggEnergySignIns) > 0 { userRelatesUidsValue := decimal.NewFromInt(int64(len(userRelatesUids))) eggEnergySignInsValue := decimal.NewFromInt(int64(len(eggEnergySignIns))) siginDividendValue = siginDividendValue.Mul(eggEnergySignInsValue.Div(userRelatesUidsValue)) } else { siginDividendValue = decimal.NewFromFloat(0) } } else { siginDividendValue = decimal.NewFromFloat(0) } siginDividend, _ := siginDividendValue.Float64() if siginDividend > 0 { //TODO::推入rabbitmq 异步处理 ch.Publish(md2.EggEnergyExchange, md2.EggEnergyStructForStarLevelDividends{ Uid: item.Id, SignDividend: siginDividend, }, md2.EggEnergyRoutKeyForStarLevelDividend) totalDividendValue = totalDividendValue.Add(siginDividendValue) } } } } //5、更新 egg_star_level_dividends_records 记录 eggStarLevelDividendsRecords.AlreadyDividendsAmount = totalDividendValue.String() eggStarLevelDividendsRecords.NotDividendsAmount = dividendAmountValue.Sub(totalDividendValue).String() _, err = eggStarLevelDividendsRecordsDb.EggStarLevelDividendsRecordsUpdateBySession(session, eggStarLevelDividendsRecords.Id, eggStarLevelDividendsRecords, "already_dividends_amount", "not_dividends_amount") if err != nil { _ = session.Rollback() fmt.Println("err:::::8888888", err) return err } //6、 减少“星级分红”中的绿色能量 totalDividend := totalDividendValue.String() eggEnergyCoreData, cb, err := svc.GetEggEnergyCoreData(engine) if err != nil { return err } if cb != nil { defer cb() // 释放锁 } err = DealAvailableEggEnergyCoin(session, int(enum.SettlementStarLevelDividends), eggEnergyCoreData, md2.DealAvailableEggEnergyCoinReq{ Amount: totalDividend, AmountFee: "", BeforePrice: eggEnergyCoreData.NowPrice, AfterPrice: eggEnergyCoreData.NowPrice, BeforePlanetTotalValue: eggEnergyCoreData.PlanetTotalValue, AfterPlanetTotalValue: eggEnergyCoreData.PlanetTotalValue, BeforeEnergyTotalNums: eggEnergyCoreData.NowEnergyTotalNums, AfterEnergyTotalNums: eggEnergyCoreData.NowEnergyTotalNums, }) if err != nil { _ = session.Rollback() fmt.Println("err:::::9999999", err) return err } err = session.Commit() if err != nil { _ = session.Rollback() return errors.New("事务提交失败") } return }