| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- 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
- }
|