| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package period_profit
- import (
- "app/commons/constant"
- "app/commons/core"
- "app/commons/model/entity"
- "app/commons/utils"
- "fmt"
- "github.com/shopspring/decimal"
- )
- // 计算等级奖励
- // 根据等级配置 计算每个等级可获得比例
- // 统计各等级人数
- // 平均分配计算 -- 生成待发放奖励记录
- // 加权分配计算 -- 生成待发放奖励记录 -- 以真实小区业绩加权
- func (s *Service) calLevelProfit(periodNo string) error {
- levelMap, err := s.LevelConfigMapFromCache()
- if err != nil {
- return err
- }
- nowPeriodJob, err := s.FirstStakePeriodJob(s.DB().
- Where("job_state", entity.PeriodJobStateRunning).
- Where("period_no", periodNo).
- Where("level_profit_is_cal", false))
- if err != nil {
- return err
- }
- if nowPeriodJob.StaticSymbolProfit.LessThanOrEqual(decimal.Zero) {
- core.JobLog.Errorf("期:%s 静态收益为:%s", periodNo, nowPeriodJob.StaticSymbolProfit)
- return nil
- }
- periodProfit := nowPeriodJob.StaticSymbolProfit
- periodUsdProfit := nowPeriodJob.StaticUsdProfit
- price := nowPeriodJob.Price
- profitRecords := make([]*entity.UserProfitRecord, 0)
- for k, v := range levelMap {
- core.JobLog.Infof("计算等级:%d 收益", k)
- records, err := s.avgWeightedLevelProfit(periodNo, v, periodUsdProfit, price, periodProfit)
- if err != nil {
- return err
- }
- if len(records) > 0 {
- profitRecords = append(profitRecords, records...)
- }
- }
- if len(profitRecords) > 0 {
- txDb := s.DB().Begin()
- err = txDb.CreateInBatches(profitRecords, 200).Error
- if err != nil {
- txDb.Rollback()
- return err
- }
- txDb.Commit()
- }
- return nil
- }
- // 根据等级计算均分收益
- func (s *Service) avgWeightedLevelProfit(periodNo string, levelConfig *entity.SysLevelConfig, usdProfit, symbolProfit, price decimal.Decimal) ([]*entity.UserProfitRecord, error) {
- dailyJobDate, err := utils.PeriodNoToDailyDate(periodNo) // 期任务格式转化为 日任务格式
- if err != nil {
- return nil, err
- }
- profitRecords := make([]*entity.UserProfitRecord, 0)
- levelSymbolProfit := symbolProfit.Mul(levelConfig.StaticRatio) // 当期该等级可分配总数量
- levelUsdAmount := usdProfit.Mul(levelConfig.StaticRatio) // 当期该等级可分配总U数
- // 等级均分总数
- totalAvgProfit := levelSymbolProfit.Mul(levelConfig.AvgRatio)
- totalAvgUsdProfit := levelUsdAmount.Mul(levelConfig.AvgRatio)
- // 加权分配总数
- totalWeightedProfit := levelSymbolProfit.Mul(levelConfig.WeightedRatio)
- totalWeightedUsdProfit := levelUsdAmount.Mul(levelConfig.WeightedRatio)
- allLevelUserQuota, err := s.BatchUserQuota(s.DB().Where("level", levelConfig.Level))
- if err != nil {
- return profitRecords, err
- }
- // 均分计算
- countUser := len(allLevelUserQuota)
- core.JobLog.Infof("等级:%d 用户数:%d", levelConfig.Level, countUser)
- if countUser == 0 {
- return profitRecords, nil
- }
- avgRatio := decimal.NewFromFloat(1).Div(decimal.NewFromInt(int64(countUser))) // 每人可获得均分比例
- avgPerUserSymbolProfit := totalAvgProfit.Mul(avgRatio) // 当前等级每人可获得SYMBOL数量 == 拆分为 均分与加权
- avgPerUserUsdProfit := totalAvgUsdProfit.Mul(avgRatio) // 当前等级每人可获得USD数量 == 拆分为 均分与加权
- // 计算加权分配数量
- allFewAc := decimal.Zero // 等级达标总小区业绩
- for _, quota := range allLevelUserQuota {
- allFewAc = allFewAc.Add(quota.FewTeamAchievement)
- }
- weightedPerAcSymbolRatio := totalWeightedProfit.Mul(allFewAc) // 1U 业绩可获得 加权奖励比例
- weightedPerAcUsdRatio := totalWeightedUsdProfit.Mul(allFewAc) // 1U 业绩可获得 加权奖励比例
- for _, userQuota := range allLevelUserQuota {
- // 均分记录
- avgBs := constant.BsById(constant.BsDynamicLevelAvgProfit)
- avgBs.ContextValue = fmt.Sprintf("%d", userQuota.UserId)
- avgBs.ContextName = userQuota.TableName()
- avgBs.Desc = fmt.Sprintf("%s-期:%s-Level:%d-perUserSymbolProfit:%s", avgBs.BusinessName, periodNo, levelConfig.Level, avgPerUserSymbolProfit)
- profitInfo := &entity.ProfitInfo{
- RawUserId: userQuota.UserId,
- RawUserUid: userQuota.Uid,
- RewardUserId: userQuota.UserId,
- RewardUserUid: userQuota.Uid,
- RewardSymbol: constant.CoinSymbolTD,
- SymbolUsdPrice: price,
- CapitalUsd: totalAvgUsdProfit,
- RewardRatio: avgRatio,
- RewardUsdValue: avgPerUserUsdProfit,
- RewardQuantity: avgPerUserSymbolProfit,
- RewardPeriod: periodNo,
- RewardDate: dailyJobDate,
- }
- profitRecord := s.BuildUserProfitRecord(profitInfo, avgBs)
- profitRecords = append(profitRecords, profitRecord)
- // 加权分配
- weightedBs := constant.BsById(constant.BsDynamicLevelWeightedProfit)
- weightedBs.ContextValue = fmt.Sprintf("%d", userQuota.UserId)
- weightedBs.ContextName = userQuota.TableName()
- userWeightedProfit := userQuota.FewTeamAchievement.Mul(weightedPerAcSymbolRatio)
- userWeightedUsdProfit := userQuota.FewTeamAchievement.Mul(weightedPerAcUsdRatio)
- weightedBs.Desc = fmt.Sprintf("%s-期:%s-Level:%d-userWeightedProfit:%s", avgBs.BusinessName, periodNo, levelConfig.Level, userWeightedProfit)
- weightedProfitInfo := &entity.ProfitInfo{
- RawUserId: userQuota.UserId,
- RawUserUid: userQuota.Uid,
- RewardUserId: userQuota.UserId,
- RewardUserUid: userQuota.Uid,
- RewardSymbol: constant.CoinSymbolTD,
- SymbolUsdPrice: price,
- CapitalUsd: userQuota.FewTeamAchievement,
- RewardRatio: weightedPerAcUsdRatio,
- RewardUsdValue: userWeightedUsdProfit,
- RewardQuantity: userWeightedProfit,
- RewardPeriod: periodNo,
- RewardDate: dailyJobDate,
- }
- weightedProfitRecord := s.BuildUserProfitRecord(weightedProfitInfo, weightedBs)
- profitRecords = append(profitRecords, weightedProfitRecord)
- }
- return profitRecords, nil
- }
|