package service import ( "fmt" "sort" "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 actSerialPack struct{} const ( mTypeCoins = 1 // 金币 mTypeDollar = 2 // 美元 ) // 展示数据处理 func (This *actSerialPack) handleActShow(confInfo *model.ActConfInfo) (json types.JSONText, err error) { var repoConfMap map[int64]model.SerialPackRepoConf if err = jsoniter.Unmarshal(confInfo.ExtraReward, &repoConfMap); err != nil { return json, errors.Wrap(err, "连环礼包 奖励Json解析失败") } // 数据转换 showConf := This.convertIntoShowConf(repoConfMap) if json, err = jsoniter.Marshal(showConf); err != nil { return json, errors.Wrap(err, "连环礼包 奖励序列化失败") } return } // 保存数据处理 func (This *actSerialPack) handleActSave(confInfo *model.ActConfInfo) (err error) { var showConfArr []model.SerialPackShowConf if err = jsoniter.Unmarshal(confInfo.ActShowConf, &showConfArr); err != nil { return errors.Wrap(err, "连环礼包的奖励Json解析失败") } if len(showConfArr) == 0 { return errors.New("保存失败,未配置等级层级") } // 数据合法性验证 if err = This.verifyConf(showConfArr); err != nil { return errors.WithStack(err) } // 数据转换 rewardMap := This.convertIntoRepoConf(showConfArr) if confInfo.ExtraReward, err = jsoniter.Marshal(rewardMap); err != nil { return errors.Wrap(err, "连环礼包 奖励数据序列化失败") } rewardTypeMap := map[string]int64{"scoreCGType": 3} if confInfo.Reward, err = jsoniter.Marshal(rewardTypeMap); err != nil { return errors.Wrap(err, "连环礼包 奖励类型数据序列化失败") } return } // 分层数据处理 func (This *actSerialPack) handleActRewardSection(confInfo *model.ActConfInfo, maps ...map[string]any) error { var repoConfMap map[int64]model.SerialPackRepoConf if err := jsoniter.Unmarshal(confInfo.ExtraReward, &repoConfMap); err != nil { return errors.Wrap(err, "连环礼包奖励解析失败") } conditionMap, rewardMap := maps[0], maps[1] for idx1, item1 := range repoConfMap { for idx2, item2 := range item1.Stages { stageKey := fmt.Sprintf("%d_%d", idx1, idx2) conditionMap[stageKey] = Activity.buildStageConditionOld(item1.StartEnd, item2.SsGroup) rewardMap[stageKey] = item2.List } } return nil } // 导入数据处理 func (This *actSerialPack) handleActImport(_ *model.ActDetailInfo, excelInfo [][][]string) (json types.JSONText, err error) { if len(excelInfo) < 3 { return json, errors.New("工作表数量不匹配") } var showConfArr []model.SerialPackShowConf if showConfArr, err = This.sheetResolver(excelInfo); err != nil { return json, errors.Wrap(err, "连环礼包 工作表解析失败") } if json, err = jsoniter.Marshal(showConfArr); err != nil { return json, errors.Wrap(err, "连环礼包 配置序列化失败") } return } func (This *actSerialPack) convertIntoShowConf(repoConfMap map[int64]model.SerialPackRepoConf) []model.SerialPackShowConf { var showConfArr []model.SerialPackShowConf for lvId, lvStageReward := range repoConfMap { for spinsId, ssStageReward := range lvStageReward.Stages { showConfArr = append(showConfArr, model.SerialPackShowConf{ TwoLayerLvSsGroup: model.TwoLayerLvSsGroup{ Id: Activity.buildLayerOrderId(lvId, spinsId), LvRange: model.LvRange{LvStart: lvStageReward.Start, LvEnd: lvStageReward.End}, SsGroup: ssStageReward.SsGroup, }, Reward: utils.MapValues(ssStageReward.List, true), }) } } sort.SliceStable(showConfArr, func(i, j int) bool { return showConfArr[i].Id < showConfArr[j].Id }) return showConfArr } func (This *actSerialPack) convertIntoRepoConf(rewardInfo []model.SerialPackShowConf) map[int64]model.SerialPackRepoConf { var ( repoConfMap = map[int64]model.SerialPackRepoConf{} unique = uniqid.GetUniqId() ) defer uniqid.DelMapByUniqId(unique) for i := 0; i < len(rewardInfo); i++ { oneRowInfo := rewardInfo[i] idxes := uniqid.GetStageIdx(unique, oneRowInfo.LvRange, oneRowInfo.SsGroup) lvIdx, ssIdx := idxes[0], idxes[1] if _, Ok := repoConfMap[lvIdx]; !Ok { repoConfMap[lvIdx] = model.SerialPackRepoConf{ StartEnd: model.StartEnd{Start: oneRowInfo.LvRange.LvStart, End: oneRowInfo.LvRange.LvEnd}, Stages: map[int64]model.SerialPackSsGroupStage{}, } } if _, Ok := repoConfMap[lvIdx].Stages[ssIdx]; !Ok { repoConfMap[lvIdx].Stages[ssIdx] = model.SerialPackSsGroupStage{ SsGroup: oneRowInfo.SsGroup, List: utils.Slice2Map(oneRowInfo.Reward), } } } return repoConfMap } func (This *actSerialPack) sheetResolver(excelInfo [][][]string) ([]model.SerialPackShowConf, error) { sheet2Array, sheet3Array := excelInfo[1], excelInfo[2] // 解析分组ID配置项 stageConfArr, err := Activity.parseTwoLayerLvSsGroupConf(sheet2Array) if err != nil { return nil, errors.WithStack(err) } // 解析奖励配置项 rewardMap, err := This.parseRewardSheet(sheet3Array) if err != nil { return nil, errors.WithStack(err) } // 匹配 分组ID和奖励项 showConf, err := This.packageShowConf(stageConfArr, rewardMap) if err != nil { return nil, errors.WithStack(err) } return showConf, nil } func (This *actSerialPack) parseRewardSheet(rewardsSheet [][]string) (map[int64][]model.SerialPackStageReward, error) { var err error stageRewardArrMap := map[int64][]model.SerialPackStageReward{} mTypeMap := map[string]int64{"金币": mTypeCoins, "美元": mTypeDollar} for rowIdx := 1; rowIdx < len(rewardsSheet); rowIdx++ { var ( id int64 mType string reward = make([]model.ExcelPrize, 5) one model.SerialPackStageReward ) // 解析行配置 if err = utils.DestructAssign(rewardsSheet[rowIdx], &id, &one.Stage, &one.GMax, &mType, &one.Price, &one.Bet, &reward); err != nil { return nil, errors.WithStack(err) } if one.Prize, err = Props.MultiParseActPrize(reward); err != nil { return nil, errors.WithStack(err) } if one.MType = mTypeMap[mType]; utils.IsEmpty(one.MType) { return nil, errors.New(fmt.Sprintf("第%d行,购买货币类型不存在: %s", rowIdx, mType)) } // 美元类型 if one.MType == mTypeDollar { if one.Sku = config.PriceSkuMap[one.Price]; utils.IsEmpty(one.Sku) { return nil, errors.New(fmt.Sprintf("第%d行,购买价格:%.2f 无对应sku", rowIdx, one.Price)) } } else { one.Coin = "coins01" } one.Name = fmt.Sprintf("serialPack-%d", one.Stage) stageRewardArrMap[id] = append(stageRewardArrMap[id], one) } return stageRewardArrMap, nil } func (This *actSerialPack) packageShowConf(layers []model.TwoLayerLvSsGroup, rewardMap map[int64][]model.SerialPackStageReward) ([]model.SerialPackShowConf, error) { showConfArr := make([]model.SerialPackShowConf, 0, len(layers)) for _, layer := range layers { reward, Ok := rewardMap[layer.Id] if !Ok { return nil, errors.New("未配置奖励项") } showConfArr = append(showConfArr, model.SerialPackShowConf{ TwoLayerLvSsGroup: layer, Reward: reward, }) } return showConfArr, nil } func (This *actSerialPack) verifyConf(showConfArr []model.SerialPackShowConf) error { for i := 0; i < len(showConfArr); i++ { for j := 0; j < len(showConfArr[i].Reward); j++ { oneRewardInfo := &showConfArr[i].Reward[j] if oneRewardInfo.MType == mTypeDollar && (utils.IsEmpty(oneRewardInfo.Price) || utils.IsEmpty(oneRewardInfo.Sku)) { return Activity.jointError("美元商品价格不能为空", i+1, j+1) } if utils.IsEmpty(oneRewardInfo.GMax) { return Activity.jointError("限量不能为空", i+1, j+1) } oneRewardInfo.Stage = int64(j + 1) oneRewardInfo.Name = fmt.Sprintf("serialPack-%d", j+1) } } return nil }