package service import ( "fmt" "sort" config2 "crazy-fox-backend-api/config" "crazy-fox-backend-api/model" "crazy-fox-backend-api/utils" "crazy-fox-backend-api/utils/uniqid" "github.com/jmoiron/sqlx/types" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" ) type actMayaWheel struct{} // 展示数据处理 func (This *actMayaWheel) handleActShow(confInfo *model.ActConfInfo) (json types.JSONText, err error) { // 奖励配置 var rewardMap map[int64]model.MayaWheelRewardRepoConf if err = jsoniter.Unmarshal(confInfo.RewardConf, &rewardMap); err != nil { return nil, errors.Wrap(err, "玛雅转盘 奖励Json解析失败") } // 转盘基础配置 var wheelConf model.MayaWheelBaseConf if err = jsoniter.Unmarshal(confInfo.ExtraData, &wheelConf); err != nil { return nil, errors.Wrap(err, "玛雅转盘 基础配置Json解析失败") } // 代币商品 var tokenGoodsRepoConf map[string]model.TokenGoods if err = jsoniter.Unmarshal(confInfo.ExtraReward, &tokenGoodsRepoConf); err != nil { return nil, errors.Wrap(err, "玛雅转盘 代币商品Json解析失败") } // 数据转换 showConf := This.convertIntoShowConf(rewardMap, wheelConf, tokenGoodsRepoConf) if json, err = jsoniter.Marshal(showConf); err != nil { return nil, errors.Wrap(err, "玛雅转盘 奖励序列化失败") } return } // 保存数据处理 func (This *actMayaWheel) handleActSave(confInfo *model.ActConfInfo) (err error) { var showConf model.MayaWheelShowConf if err = jsoniter.Unmarshal(confInfo.ActShowConf, &showConf); err != nil { return errors.Wrap(err, "玛雅转盘 奖励Json解析失败") } // 数据转换 repoConf := This.convertIntoRepoConf(showConf.RewardConf) if confInfo.RewardConf, err = jsoniter.Marshal(repoConf); err != nil { return errors.Wrap(err, "玛雅转盘 奖励数据序列化失败") } showConf.WheelConf.MayaWheelTotalCnt = 12 // 固定为12 if confInfo.ExtraData, err = jsoniter.Marshal(showConf.WheelConf); err != nil { return errors.Wrap(err, "玛雅转盘 基础配置数据序列化失败") } if confInfo.RewardConf, err = jsoniter.Marshal(repoConf); err != nil { return errors.Wrap(err, "玛雅转盘 奖励数据序列化失败") } // 数据转换 if confInfo.ExtraReward, err = This.convertIntoTokenGoodsRepoConf(showConf.RewardConf); err != nil { return errors.Wrap(err, "玛雅转盘 代币商品序列化失败") } return } // 分层数据处理 func (This *actMayaWheel) handleActRewardSection(confInfo *model.ActConfInfo, maps ...map[string]any) error { var repoConfMap map[int64]model.MayaWheelRewardRepoConf if err := jsoniter.Unmarshal(confInfo.RewardConf, &repoConfMap); err != nil { return errors.Wrap(err, "玛雅转盘 奖励解析失败") } var baseConf model.MayaWheelBaseConf if err := jsoniter.Unmarshal(confInfo.ExtraData, &baseConf); err != nil { return errors.Wrap(err, "玛雅转盘 基础配置解析失败") } var extraReward map[string]model.TokenGoods if err := jsoniter.Unmarshal(confInfo.ExtraReward, &extraReward); err != nil { return errors.Wrap(err, "玛雅转盘 基础配置解析失败") } conditionMap, rewardMap, extraRewardMap := maps[0], maps[1], maps[2] for idx1, item1 := range repoConfMap { for idx2, item2 := range item1.Stages { for idx3, item3 := range item2.Stages { stageKey := fmt.Sprintf("%d_%d_%d", idx1, idx2, idx3) conditionMap[stageKey] = Activity.buildStageCondition(item1.LvRange, item2.SpinsRange, item3.SsGroup) rewardMap[stageKey] = model.MayaWheelStageCache{ DiceConf: This.buildDiceCacheMap(item3.Rewards.DiceConf, baseConf), ProgressConf: utils.MapValues(item3.Rewards.ProgressConf, true), } extraRewardMap[stageKey] = model.StageExtraRepoConf{ TokenGoods: extraReward[stageKey], } } } } return nil } // 导入数据处理 func (This *actMayaWheel) handleActImport(_ *model.ActDetailInfo, excelInfo [][][]string) (json types.JSONText, err error) { if len(excelInfo) < 5 { return json, errors.New("工作表数量不匹配") } showConf, err := This.sheetResolver(excelInfo) if err != nil { return json, errors.Wrap(err, "玛雅转盘 工作表解析失败") } if json, err = jsoniter.Marshal(showConf); err != nil { return json, errors.Wrap(err, "玛雅转盘 配置序列化失败") } return } func (This *actMayaWheel) convertIntoShowConf(repoConfMap map[int64]model.MayaWheelRewardRepoConf, wheelConf model.MayaWheelBaseConf, tokenGoodsInfo map[string]model.TokenGoods) (showConf model.MayaWheelShowConf) { var rewardArr []model.MayaWheelRewardShowConf for lvId, lvStageReward := range repoConfMap { for spinsId, spinsStageReward := range lvStageReward.Stages { for ssId, ssStageReward := range spinsStageReward.Stages { multiIdx := fmt.Sprintf("%d_%d_%d", lvId, spinsId, ssId) tokenGoods, ok := tokenGoodsInfo[multiIdx] if !ok { tokenGoods = model.TokenGoods{} } rewardArr = append(rewardArr, model.MayaWheelRewardShowConf{ ThreeLayer: model.ThreeLayer{ Id: Activity.buildLayerOrderId(lvId, spinsId, ssId), LvRange: lvStageReward.LvRange, SpinsRange: spinsStageReward.SpinsRange, SsGroup: ssStageReward.SsGroup, }, Reward: model.MayaWheelReward{ StageConf: This.buildStageShowConf(ssStageReward.Rewards.DiceConf), ProgressConf: utils.MapValues(ssStageReward.Rewards.ProgressConf, true), }, TokenGoods: tokenGoods, }) } } } sort.SliceStable(rewardArr, func(i, j int) bool { return rewardArr[i].Id < rewardArr[j].Id }) return model.MayaWheelShowConf{RewardConf: rewardArr, WheelConf: wheelConf} } func (This *actMayaWheel) buildStageShowConf(diceConfMap map[int64]model.MayaWheelDiceConf) []model.MayaWheelStageShowReward { rewardArr := make([]model.MayaWheelStageShowReward, 0, len(diceConfMap)*12) for layer, diceConf := range diceConfMap { for seq, oneReward := range diceConf.List { rewardArr = append(rewardArr, model.MayaWheelStageShowReward{ Layer: layer, Seq: seq, MayaWheelDiceRewardConf: oneReward, }) } } sort.SliceStable(rewardArr, func(i, j int) bool { if rewardArr[i].Layer == rewardArr[j].Layer { return rewardArr[i].Seq < rewardArr[j].Seq } return rewardArr[i].Layer < rewardArr[j].Layer }) return rewardArr } func (This *actMayaWheel) convertIntoRepoConf(rewardInfo []model.MayaWheelRewardShowConf) map[int64]model.MayaWheelRewardRepoConf { var ( repoConfMap = map[int64]model.MayaWheelRewardRepoConf{} unique = uniqid.GetUniqId() ) defer uniqid.DelMapByUniqId(unique) for _, oneRowInfo := range rewardInfo { idxes := uniqid.GetStageIdx(unique, oneRowInfo.LvRange, oneRowInfo.SpinsRange, oneRowInfo.SsGroup) lvIdx, spinIdx, ssIdx := idxes[0], idxes[1], idxes[2] if _, Ok := repoConfMap[lvIdx]; !Ok { repoConfMap[lvIdx] = model.MayaWheelRewardRepoConf{ LvRange: oneRowInfo.LvRange, Stages: map[int64]model.MayaWheelSpinsStage{}, } } if _, Ok := repoConfMap[lvIdx].Stages[spinIdx]; !Ok { repoConfMap[lvIdx].Stages[spinIdx] = model.MayaWheelSpinsStage{ SpinsRange: oneRowInfo.SpinsRange, Stages: map[int64]model.MayaWheelSsStage{}, } } // 构建阶段奖励二维数组 stageRewardList := func() map[int64]model.MayaWheelDiceConf { stageRewardMap := map[int64]model.MayaWheelDiceConf{} for _, reward := range oneRowInfo.Reward.StageConf { if _, Ok := stageRewardMap[reward.Layer]; !Ok { stageRewardMap[reward.Layer] = model.MayaWheelDiceConf{ List: map[int64]model.MayaWheelDiceRewardConf{}, } } stageRewardMap[reward.Layer].List[reward.Seq] = reward.MayaWheelDiceRewardConf } return stageRewardMap }() // 构建进度奖励Map progressReward := func() map[int64]model.MayaWheelProgressConf { rewardMap := make(map[int64]model.MayaWheelProgressConf, len(oneRowInfo.Reward.ProgressConf)) for idx, reward := range oneRowInfo.Reward.ProgressConf { reward.Stage = int64(idx + 1) rewardMap[reward.Stage] = reward } return rewardMap }() repoConfMap[lvIdx].Stages[spinIdx].Stages[ssIdx] = model.MayaWheelSsStage{ SsGroup: oneRowInfo.SsGroup, Rewards: model.MayaWheelStageReward{ DiceConf: stageRewardList, ProgressConf: progressReward, }, } } return repoConfMap } func (This *actMayaWheel) convertIntoTokenGoodsRepoConf(rewardInfo []model.MayaWheelRewardShowConf) (types.JSONText, error) { var ( repoConfMap = map[string]model.TokenGoods{} unique = uniqid.GetUniqId() ) defer uniqid.DelMapByUniqId(unique) for _, oneRowInfo := range rewardInfo { idxes := uniqid.GetStageIdx(unique, oneRowInfo.LvRange, oneRowInfo.SpinsRange, oneRowInfo.SsGroup) stageKey := fmt.Sprintf("%d_%d_%d", idxes[0], idxes[1], idxes[2]) repoConfMap[stageKey] = oneRowInfo.TokenGoods } return jsoniter.Marshal(repoConfMap) } func (This *actMayaWheel) buildDiceCacheMap(diceConf map[int64]model.MayaWheelDiceConf, baseConf model.MayaWheelBaseConf) map[int64]model.MayaWheelDiceConfCache { confCache := make(map[int64]model.MayaWheelDiceConfCache, len(diceConf)) for i, conf := range diceConf { confCache[i] = model.MayaWheelDiceConfCache{ TotalCnt: baseConf.MayaWheelTotalCnt, SpendConfig: baseConf.MayaWheelSpend, RewardConfig: utils.MapValues(conf.List, true), } } return confCache } func (This *actMayaWheel) sheetResolver(excelInfo [][][]string) (model.MayaWheelShowConf, error) { sheet2Array, sheet3Array, sheet4Array, sheet5Array, sheet6Array := excelInfo[1], excelInfo[2], excelInfo[3], excelInfo[4], excelInfo[5] // 解析转盘基础配置 showConf, err := This.parseBaseConf(sheet2Array) // 解析分组ID配置项 stageConfArr, err := Activity.parseThreeLayerConf(sheet3Array) if err != nil { return showConf, errors.WithStack(err) } // 解析奖励配置项 stageRewardMap, err := This.parseRewardSheet(sheet4Array) if err != nil { return showConf, errors.WithStack(err) } // 解析进度奖励配置项 progressRewardMap, err := This.parseProgressRewardSheet(sheet5Array) if err != nil { return showConf, errors.WithStack(err) } // 解析进度奖励配置项 tokenGoodsMap, err := Activity.ParseTokenGoodsSheet(sheet6Array, config2.ActMayaWheel) if err != nil { return showConf, errors.WithStack(err) } if err = This.packageShowConf(&showConf, stageConfArr, stageRewardMap, progressRewardMap, tokenGoodsMap); err != nil { return showConf, errors.WithStack(err) } return showConf, nil } func (This *actMayaWheel) parseBaseConf(sheet [][]string) (showConf model.MayaWheelShowConf, err error) { spends := make([]int64, 0, len(sheet)) for i := 1; i < len(sheet); i++ { var ignore string var spendNum int64 if err = utils.DestructAssign(sheet[i], &ignore, &spendNum); err != nil { return showConf, errors.WithStack(err) } spends = append(spends, spendNum) } if len(spends) != 12 { return showConf, errors.WithMessage(err, "转盘转动次数固定为12") } showConf.WheelConf = model.MayaWheelBaseConf{ MayaWheelTotalCnt: int64(len(spends)), MayaWheelSpend: spends, } return showConf, err } func (This *actMayaWheel) parseRewardSheet(rewardsSheet [][]string) (map[int64][]model.MayaWheelStageShowReward, error) { var err error stageRewardArrMap := map[int64][]model.MayaWheelStageShowReward{} for rowIdx := 1; rowIdx < len(rewardsSheet); rowIdx++ { var ( id int64 one model.MayaWheelStageShowReward rewards = make([]model.ExcelPrize, 1) ) // 解析行配置 if err = utils.DestructAssign(rewardsSheet[rowIdx], &id, &one.Layer, &one.Seq, &one.Weight, &one.LastCnt, &rewards); err != nil { return nil, errors.WithStack(err) } // 转换奖励格式 if one.Prize, err = Props.MultiParseActPrize(rewards); err != nil { return nil, errors.WithStack(err) } stageRewardArrMap[id] = append(stageRewardArrMap[id], one) } return stageRewardArrMap, nil } func (This *actMayaWheel) parseProgressRewardSheet(sheet [][]string) (map[int64][]model.MayaWheelProgressConf, error) { var err error progressRewardArrMap := make(map[int64][]model.MayaWheelProgressConf, len(sheet)) for rowIdx := 1; rowIdx < len(sheet); rowIdx++ { var ( id int64 one model.MayaWheelProgressConf rewards = make([]model.ExcelPrize, 1) ) // 解析行配置 if err = utils.DestructAssign(sheet[rowIdx], &id, &one.Stage, &one.Target, &rewards); err != nil { return nil, errors.WithStack(err) } // 转换奖励格式 if one.Prize, err = Props.MultiParseActPrize(rewards); err != nil { return nil, errors.WithStack(err) } progressRewardArrMap[id] = append(progressRewardArrMap[id], one) } return progressRewardArrMap, nil } func (This *actMayaWheel) packageShowConf(showConf *model.MayaWheelShowConf, layers []model.ThreeLayer, stageRewardMap map[int64][]model.MayaWheelStageShowReward, progressRewardMap map[int64][]model.MayaWheelProgressConf, TokenGoodsMap map[int64]model.TokenGoods) error { rewardArr := make([]model.MayaWheelRewardShowConf, 0, len(layers)) for _, layer := range layers { stageReward, Ok := stageRewardMap[layer.Id] if !Ok { return errors.New("未配置阶段奖励项") } progressReward, Ok := progressRewardMap[layer.Id] if !Ok { return errors.New("未配置进度奖励项") } tokenGoods, Ok := TokenGoodsMap[layer.Id] if !Ok { return errors.New("未配置代币商品奖励项") } rewardArr = append(rewardArr, model.MayaWheelRewardShowConf{ ThreeLayer: layer, Reward: model.MayaWheelReward{ StageConf: stageReward, ProgressConf: progressReward, }, TokenGoods: tokenGoods, }) } showConf.RewardConf = rewardArr return nil }