act_serial_pack.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. package service
  2. import (
  3. "fmt"
  4. "sort"
  5. "crazy-fox-backend-api/config"
  6. "crazy-fox-backend-api/model"
  7. "crazy-fox-backend-api/utils"
  8. "crazy-fox-backend-api/utils/uniqid"
  9. "github.com/jmoiron/sqlx/types"
  10. jsoniter "github.com/json-iterator/go"
  11. "github.com/pkg/errors"
  12. )
  13. type actSerialPack struct{}
  14. const (
  15. mTypeCoins = 1 // 金币
  16. mTypeDollar = 2 // 美元
  17. )
  18. // 展示数据处理
  19. func (This *actSerialPack) handleActShow(confInfo *model.ActConfInfo) (json types.JSONText, err error) {
  20. var repoConfMap map[int64]model.SerialPackRepoConf
  21. if err = jsoniter.Unmarshal(confInfo.ExtraReward, &repoConfMap); err != nil {
  22. return json, errors.Wrap(err, "连环礼包 奖励Json解析失败")
  23. }
  24. // 数据转换
  25. showConf := This.convertIntoShowConf(repoConfMap)
  26. if json, err = jsoniter.Marshal(showConf); err != nil {
  27. return json, errors.Wrap(err, "连环礼包 奖励序列化失败")
  28. }
  29. return
  30. }
  31. // 保存数据处理
  32. func (This *actSerialPack) handleActSave(confInfo *model.ActConfInfo) (err error) {
  33. var showConfArr []model.SerialPackShowConf
  34. if err = jsoniter.Unmarshal(confInfo.ActShowConf, &showConfArr); err != nil {
  35. return errors.Wrap(err, "连环礼包的奖励Json解析失败")
  36. }
  37. if len(showConfArr) == 0 {
  38. return errors.New("保存失败,未配置等级层级")
  39. }
  40. // 数据合法性验证
  41. if err = This.verifyConf(showConfArr); err != nil {
  42. return errors.WithStack(err)
  43. }
  44. // 数据转换
  45. rewardMap := This.convertIntoRepoConf(showConfArr)
  46. if confInfo.ExtraReward, err = jsoniter.Marshal(rewardMap); err != nil {
  47. return errors.Wrap(err, "连环礼包 奖励数据序列化失败")
  48. }
  49. rewardTypeMap := map[string]int64{"scoreCGType": 3}
  50. if confInfo.Reward, err = jsoniter.Marshal(rewardTypeMap); err != nil {
  51. return errors.Wrap(err, "连环礼包 奖励类型数据序列化失败")
  52. }
  53. return
  54. }
  55. // 分层数据处理
  56. func (This *actSerialPack) handleActRewardSection(confInfo *model.ActConfInfo, maps ...map[string]any) error {
  57. var repoConfMap map[int64]model.SerialPackRepoConf
  58. if err := jsoniter.Unmarshal(confInfo.ExtraReward, &repoConfMap); err != nil {
  59. return errors.Wrap(err, "连环礼包奖励解析失败")
  60. }
  61. conditionMap, rewardMap := maps[0], maps[1]
  62. for idx1, item1 := range repoConfMap {
  63. for idx2, item2 := range item1.Stages {
  64. stageKey := fmt.Sprintf("%d_%d", idx1, idx2)
  65. conditionMap[stageKey] = Activity.buildStageConditionOld(item1.StartEnd, item2.SsGroup)
  66. rewardMap[stageKey] = item2.List
  67. }
  68. }
  69. return nil
  70. }
  71. // 导入数据处理
  72. func (This *actSerialPack) handleActImport(_ *model.ActDetailInfo, excelInfo [][][]string) (json types.JSONText, err error) {
  73. if len(excelInfo) < 3 {
  74. return json, errors.New("工作表数量不匹配")
  75. }
  76. var showConfArr []model.SerialPackShowConf
  77. if showConfArr, err = This.sheetResolver(excelInfo); err != nil {
  78. return json, errors.Wrap(err, "连环礼包 工作表解析失败")
  79. }
  80. if json, err = jsoniter.Marshal(showConfArr); err != nil {
  81. return json, errors.Wrap(err, "连环礼包 配置序列化失败")
  82. }
  83. return
  84. }
  85. func (This *actSerialPack) convertIntoShowConf(repoConfMap map[int64]model.SerialPackRepoConf) []model.SerialPackShowConf {
  86. var showConfArr []model.SerialPackShowConf
  87. for lvId, lvStageReward := range repoConfMap {
  88. for spinsId, ssStageReward := range lvStageReward.Stages {
  89. showConfArr = append(showConfArr, model.SerialPackShowConf{
  90. TwoLayerLvSsGroup: model.TwoLayerLvSsGroup{
  91. Id: Activity.buildLayerOrderId(lvId, spinsId),
  92. LvRange: model.LvRange{LvStart: lvStageReward.Start, LvEnd: lvStageReward.End},
  93. SsGroup: ssStageReward.SsGroup,
  94. },
  95. Reward: utils.MapValues(ssStageReward.List, true),
  96. })
  97. }
  98. }
  99. sort.SliceStable(showConfArr, func(i, j int) bool { return showConfArr[i].Id < showConfArr[j].Id })
  100. return showConfArr
  101. }
  102. func (This *actSerialPack) convertIntoRepoConf(rewardInfo []model.SerialPackShowConf) map[int64]model.SerialPackRepoConf {
  103. var (
  104. repoConfMap = map[int64]model.SerialPackRepoConf{}
  105. unique = uniqid.GetUniqId()
  106. )
  107. defer uniqid.DelMapByUniqId(unique)
  108. for i := 0; i < len(rewardInfo); i++ {
  109. oneRowInfo := rewardInfo[i]
  110. idxes := uniqid.GetStageIdx(unique, oneRowInfo.LvRange, oneRowInfo.SsGroup)
  111. lvIdx, ssIdx := idxes[0], idxes[1]
  112. if _, Ok := repoConfMap[lvIdx]; !Ok {
  113. repoConfMap[lvIdx] = model.SerialPackRepoConf{
  114. StartEnd: model.StartEnd{Start: oneRowInfo.LvRange.LvStart, End: oneRowInfo.LvRange.LvEnd},
  115. Stages: map[int64]model.SerialPackSsGroupStage{},
  116. }
  117. }
  118. if _, Ok := repoConfMap[lvIdx].Stages[ssIdx]; !Ok {
  119. repoConfMap[lvIdx].Stages[ssIdx] = model.SerialPackSsGroupStage{
  120. SsGroup: oneRowInfo.SsGroup,
  121. List: utils.Slice2Map(oneRowInfo.Reward),
  122. }
  123. }
  124. }
  125. return repoConfMap
  126. }
  127. func (This *actSerialPack) sheetResolver(excelInfo [][][]string) ([]model.SerialPackShowConf, error) {
  128. sheet2Array, sheet3Array := excelInfo[1], excelInfo[2]
  129. // 解析分组ID配置项
  130. stageConfArr, err := Activity.parseTwoLayerLvSsGroupConf(sheet2Array)
  131. if err != nil {
  132. return nil, errors.WithStack(err)
  133. }
  134. // 解析奖励配置项
  135. rewardMap, err := This.parseRewardSheet(sheet3Array)
  136. if err != nil {
  137. return nil, errors.WithStack(err)
  138. }
  139. // 匹配 分组ID和奖励项
  140. showConf, err := This.packageShowConf(stageConfArr, rewardMap)
  141. if err != nil {
  142. return nil, errors.WithStack(err)
  143. }
  144. return showConf, nil
  145. }
  146. func (This *actSerialPack) parseRewardSheet(rewardsSheet [][]string) (map[int64][]model.SerialPackStageReward, error) {
  147. var err error
  148. stageRewardArrMap := map[int64][]model.SerialPackStageReward{}
  149. mTypeMap := map[string]int64{"金币": mTypeCoins, "美元": mTypeDollar}
  150. for rowIdx := 1; rowIdx < len(rewardsSheet); rowIdx++ {
  151. var (
  152. id int64
  153. mType string
  154. reward = make([]model.ExcelPrize, 5)
  155. one model.SerialPackStageReward
  156. )
  157. // 解析行配置
  158. if err = utils.DestructAssign(rewardsSheet[rowIdx], &id, &one.Stage, &one.GMax, &mType, &one.Price, &one.Bet, &reward); err != nil {
  159. return nil, errors.WithStack(err)
  160. }
  161. if one.Prize, err = Props.MultiParseActPrize(reward); err != nil {
  162. return nil, errors.WithStack(err)
  163. }
  164. if one.MType = mTypeMap[mType]; utils.IsEmpty(one.MType) {
  165. return nil, errors.New(fmt.Sprintf("第%d行,购买货币类型不存在: %s", rowIdx, mType))
  166. }
  167. // 美元类型
  168. if one.MType == mTypeDollar {
  169. if one.Sku = config.PriceSkuMap[one.Price]; utils.IsEmpty(one.Sku) {
  170. return nil, errors.New(fmt.Sprintf("第%d行,购买价格:%.2f 无对应sku", rowIdx, one.Price))
  171. }
  172. } else {
  173. one.Coin = "coins01"
  174. }
  175. one.Name = fmt.Sprintf("serialPack-%d", one.Stage)
  176. stageRewardArrMap[id] = append(stageRewardArrMap[id], one)
  177. }
  178. return stageRewardArrMap, nil
  179. }
  180. func (This *actSerialPack) packageShowConf(layers []model.TwoLayerLvSsGroup, rewardMap map[int64][]model.SerialPackStageReward) ([]model.SerialPackShowConf, error) {
  181. showConfArr := make([]model.SerialPackShowConf, 0, len(layers))
  182. for _, layer := range layers {
  183. reward, Ok := rewardMap[layer.Id]
  184. if !Ok {
  185. return nil, errors.New("未配置奖励项")
  186. }
  187. showConfArr = append(showConfArr, model.SerialPackShowConf{
  188. TwoLayerLvSsGroup: layer,
  189. Reward: reward,
  190. })
  191. }
  192. return showConfArr, nil
  193. }
  194. func (This *actSerialPack) verifyConf(showConfArr []model.SerialPackShowConf) error {
  195. for i := 0; i < len(showConfArr); i++ {
  196. for j := 0; j < len(showConfArr[i].Reward); j++ {
  197. oneRewardInfo := &showConfArr[i].Reward[j]
  198. if oneRewardInfo.MType == mTypeDollar && (utils.IsEmpty(oneRewardInfo.Price) || utils.IsEmpty(oneRewardInfo.Sku)) {
  199. return Activity.jointError("美元商品价格不能为空", i+1, j+1)
  200. }
  201. if utils.IsEmpty(oneRewardInfo.GMax) {
  202. return Activity.jointError("限量不能为空", i+1, j+1)
  203. }
  204. oneRewardInfo.Stage = int64(j + 1)
  205. oneRewardInfo.Name = fmt.Sprintf("serialPack-%d", j+1)
  206. }
  207. }
  208. return nil
  209. }