package activity import ( "context" "encoding/hex" "encoding/json" "bindbox-game/internal/repository/mysql/dao" "bindbox-game/internal/repository/mysql/model" ) // BatchDrawForUsers 批量为用户执行抽奖并写入日志与收据 // 参数: issueID 期ID, userIDs 用户ID数组 // 返回: 抽奖结果集合与错误 func (s *service) BatchDrawForUsers(ctx context.Context, issueID int64, userIDs []int64) ([]BatchDrawItem, error) { rewards, err := s.readDB.ActivityRewardSettings.WithContext(ctx). Where(s.readDB.ActivityRewardSettings.IssueID.Eq(issueID)). Order(s.readDB.ActivityRewardSettings.Sort). Find() if err != nil { return nil, err } rewardMap := make(map[int64]string, len(rewards)) for _, r := range rewards { rewardMap[r.ID] = r.Name } draws := make([]BatchDrawItem, 0, len(userIDs)) err = s.writeDB.Transaction(func(tx *dao.Query) error { for _, uid := range userIDs { rec, err := s.ExecuteDrawWithEffects(ctx, issueID, uid) if err != nil { return err } isWinner := int32(0) if rec.SelectedItemId > 0 { isWinner = 1 } drawLog := &model.ActivityDrawLogs{ UserID: uid, IssueID: issueID, RewardID: rec.SelectedItemId, IsWinner: isWinner, Level: 1, } if err := tx.ActivityDrawLogs.WithContext(ctx).Create(drawLog); err != nil { return err } itemsSnapshot, _ := json.Marshal(rec.Items) receipt := &model.ActivityDrawReceipts{ DrawLogID: drawLog.ID, AlgoVersion: rec.AlgoVersion, RoundID: rec.RoundId, DrawID: rec.DrawId, ClientID: rec.ClientId, Timestamp: rec.Timestamp, ServerSeedHash: hex.EncodeToString(rec.ServerSeedHash), ServerSubSeed: hex.EncodeToString(rec.ServerSubSeed), ClientSeed: hex.EncodeToString(rec.ClientSeed), Nonce: int64(rec.Nonce), ItemsRoot: hex.EncodeToString(rec.ItemsRoot), WeightsTotal: int64(rec.WeightsTotal), SelectedIndex: int32(rec.SelectedIndex), RandProof: hex.EncodeToString(rec.RandProof), Signature: "", ItemsSnapshot: string(itemsSnapshot), } if err := tx.ActivityDrawReceipts.WithContext(ctx).Create(receipt); err != nil { return err } name := "" if rec.SelectedItemId > 0 { name = rewardMap[rec.SelectedItemId] } draws = append(draws, BatchDrawItem{ UserID: uid, DrawID: rec.DrawId, RewardID: rec.SelectedItemId, RewardName: name, IsWinner: rec.SelectedItemId > 0, Receipt: rec, }) } return nil }) if err != nil { return nil, err } return draws, nil }