package quota import ( "app/commons/core" "app/commons/model/entity" "fmt" "github.com/shopspring/decimal" "strings" "time" ) // todo:团队业绩计算 // 获取指标信息 // 内存中计算完成 一一修改到数据库中 func (s *Service) resetTeamTodayAchievement() error { err := s.DB().Model(&entity.UserQuota{}). Where("1=1"). Updates(map[string]interface{}{ "invite_count": 0, "team_count": 0, "team_achievement": 0, "large_region_achievement": 0, "few_team_achievement": 0, }).Error if err != nil { return err } return nil } func (s *Service) teamAchievementHandler() error { // 更新用户缓存 -- 保证PATH为最新 if err := s.RefreshUserMap(); err != nil { return err } userQuotas, err := s.BatchUserQuota(s.DB().Where("1=1")) if err != nil { return err } userQuotaMap := make(map[int64]*entity.UserQuota) for _, item := range userQuotas { item.InviteCount = 0 item.TeamCount = 0 item.TeamAchievement = decimal.Zero item.LargeRegionUserId = 0 item.LargeRegionAchievement = decimal.Zero item.FewTeamAchievement = decimal.Zero userQuotaMap[item.UserId] = item } type LargeRegionTeam struct { LargeRegionUserId int64 `json:"largeRegionUserId" gorm:"default:0;comment:大区用户ID"` LargeRegionAchievement decimal.Decimal `json:"largeRegionAchievement" gorm:"type:decimal(25,8);default:0;comment:大区业绩"` } // 计算数据 for _, quota := range userQuotas { // 通过USER_ID // 获取用户信息 user, err := s.UserInfoFromCache(quota.UserId) if err != nil { continue } // 大区业绩信息 -- 当前 largeRegionTeam := LargeRegionTeam{ LargeRegionUserId: user.Id, LargeRegionAchievement: quota.TeamAchievement.Add(quota.PersonAchievement), } for i, pid := range user.ParentIds { parentUserQuota, ok := userQuotaMap[pid] if !ok { break } if i == 0 { parentUserQuota.InviteCount += 1 // 直推人数 } parentUserQuota.TeamCount += 1 // 团队人数 parentUserQuota.TeamAchievement = parentUserQuota.TeamAchievement.Add(quota.PersonAchievement) // 团队业绩 // 替换当期大区业绩 -- 如果当前区业绩大于 当期指标最大业绩 则替换 if parentUserQuota.LargeRegionAchievement.LessThanOrEqual(largeRegionTeam.LargeRegionAchievement) { parentUserQuota.LargeRegionAchievement = largeRegionTeam.LargeRegionAchievement parentUserQuota.LargeRegionUserId = largeRegionTeam.LargeRegionUserId } // 小区业绩 = 总业绩 - 大区业绩 parentUserQuota.FewTeamAchievement = parentUserQuota.TeamAchievement.Sub(parentUserQuota.LargeRegionAchievement) // 更新当前团队业绩信息 -- 假设为大区 largeRegionTeam = LargeRegionTeam{ LargeRegionUserId: parentUserQuota.UserId, LargeRegionAchievement: parentUserQuota.TeamAchievement.Add(parentUserQuota.PersonAchievement), } } } // 使用临时表 err = s.batchUpdateQuotas(userQuotas) if err != nil { core.JobLog.Errorf("批量更新失败:%s", err) return err } return nil } // 批量更新方法 func (s *Service) batchUpdateQuotas(updates []*entity.UserQuota) error { // 1. 确保删除已存在的临时表(避免冲突)temp_user_quota_updates var err error tempTableName := fmt.Sprintf("user_quota_team_ac_updates_%d", time.Now().Unix()) defer func() { if err := s.DB().Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s", tempTableName)).Error; err != nil { core.JobLog.Errorf("删除临时表失败: %v", err) } }() createSQL := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s ( user_id VARCHAR(32), invite_delta INT, team_delta INT, large_region_user_id INT, large_region_achievement DECIMAL(25,8), few_team_achievement DECIMAL(25,8), team_achievement DECIMAL(25,8) )ENGINE=InnoDB`, tempTableName) if err := s.DB().Exec(createSQL).Error; err != nil { return fmt.Errorf("创建临时表失败: %v", err) } // 2. 批量插入数据到临时表 batchSize := 1000 // 每批处理1000条 for i := 0; i < len(updates); i += batchSize { end := i + batchSize if end > len(updates) { end = len(updates) } batch := updates[i:end] var valueStrings []string var valueArgs []interface{} for _, item := range batch { valueStrings = append(valueStrings, "(?, ?, ?, ?, ?, ?, ?)") valueArgs = append(valueArgs, item.UserId, item.InviteCount, item.TeamCount, item.LargeRegionUserId, item.LargeRegionAchievement, item.FewTeamAchievement, item.TeamAchievement, ) } stmt := fmt.Sprintf( "INSERT INTO %s "+ "(user_id, invite_delta, team_delta, "+ "large_region_user_id,large_region_achievement,few_team_achievement, team_achievement)"+ "VALUES %s", tempTableName, strings.Join(valueStrings, ",")) if err := s.DB().Exec(stmt, valueArgs...).Error; err != nil { return fmt.Errorf("批量插入临时表失败: %v", err) } } // 3. 执行JOIN更新 err = s.DB().Exec(fmt.Sprintf(` UPDATE %s q JOIN %s t ON q.user_id = t.user_id SET q.invite_count = t.invite_delta, q.team_count = t.team_delta, q.large_region_user_id = t.large_region_user_id, q.large_region_achievement = t.large_region_achievement, q.few_team_achievement = t.few_team_achievement, q.team_achievement = t.team_achievement `, entity.NewUserQuota().TableName(), tempTableName)).Error if err != nil { return fmt.Errorf("执行批量更新失败: %v", err) } return nil }