package period_profit import ( "app/commons/constant" "app/commons/core" "app/commons/model/entity" "app/commons/utils" "fmt" "github.com/shopspring/decimal" "gorm.io/gorm" ) func (s *Service) DisProfit() error { allRewards, err := s.BatchUserProfitRecord(s.DB().Where("state", entity.ProfitSendStateWaiting)) if err != nil { return err } count := len(allRewards) for i, item := range allRewards { if i%10000 == 0 && i > 0 { core.JobLog.Infof("发放进度:%d/%d", i, count) } txDb := s.DB().Begin() bs := constant.BsById(item.BusinessNumber) bs.ContextName = item.TableName() bs.ContextValue = fmt.Sprintf("%d", item.Id) state := entity.ProfitSendStateSuccess // 根据业务场景 // 1 静态写入订单池 // 2 动态直接发放到资产钱包 // todo:发放到待领取 -- 需计算上一轮发放时间 并计算出是否可继续发放 if bs.BusinessNumber == constant.BsCurrentStaticProfit { // 检查是否满池 currentOrder, err := s.CheckUserCurrentStakeUserOrder(txDb, item.RewardUserId, item.RewardUserUid) if err != nil { txDb.Rollback() core.JobLog.Errorf(err.Error()) continue } if currentOrder.LastClaimPeriod == "" { currentOrder.LastClaimPeriod = utils.NowPeriodNo() } n := utils.CalPeriodNosSpan(currentOrder.LastClaimPeriod, item.RewardPeriod) core.JobLog.Infof("剩余%d期 未领取", n) if n >= 12 { state = entity.ProfitSendStateOverflow // 溢出 } else { // LastProfitPeriod string `json:"lastProfitPeriod" gorm:"type:varchar(32);comment:最近产出期号"` // AvailableQuantity decimal.Decimal `json:"availableQuantity" gorm:"type:decimal(25,8);default:0;comment:待领取数量"` // AvailableUsdAmount decimal.Decimal `json:"availableUsdAmount" gorm:"type:decimal(25,8);default:0;comment:待领取价值"` updateStm := txDb. Debug(). Model(&entity.StakeUserCurrentOrder{}). Where("id", currentOrder.Id). Where("version", currentOrder.Version). Updates(map[string]interface{}{ "available_quantity": gorm.Expr("available_quantity + ?", item.RewardQuantity), "available_usd_amount": gorm.Expr("available_usd_amount + ?", item.RewardUsdValue), "last_profit_period": item.RewardPeriod, "version": gorm.Expr("version + 1"), }) if updateStm.RowsAffected != 1 || updateStm.Error != nil { txDb.Rollback() core.JobLog.Errorf("update fail RowsAffected:%d err:%+v", updateStm.RowsAffected, updateStm.Error) continue } } } else { // 其他类型全部发放到资产钱包 if err = s.GenBillAndActionAsset(txDb, item.RewardUserId, constant.CoinSymbolTD, item.RewardQuantity, decimal.Zero, bs); err != nil { txDb.Rollback() core.JobLog.Errorf(err.Error()) continue } } // 发放记录状态修改 err = txDb.Model(&entity.UserProfitRecord{}). Where("id", item.Id). Update("state", state).Error if err != nil { txDb.Rollback() core.JobLog.Errorf(err.Error()) continue } txDb.Commit() } return nil }