act_one_plus.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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/dablelv/go-huge-util/conv"
  10. "github.com/jmoiron/sqlx/types"
  11. jsoniter "github.com/json-iterator/go"
  12. "github.com/pkg/errors"
  13. )
  14. type actOnePlus struct{}
  15. // 展示数据处理
  16. func (This *actOnePlus) handleActShow(confInfo *model.ActConfInfo) (json types.JSONText, err error) {
  17. var confMap map[int64]model.OnePlusRewardConf
  18. if err = jsoniter.Unmarshal(confInfo.Reward, &confMap); err != nil {
  19. return json, errors.Wrap(err, "1+1礼包 奖励Json解析失败")
  20. }
  21. var baseConf model.OnePlusBaseConf
  22. if err = jsoniter.Unmarshal(confInfo.RewardConf, &baseConf); err != nil {
  23. return json, errors.Wrap(err, "1+1礼包 基础配置Json解析失败")
  24. }
  25. // 数据转换
  26. showConf := This.convertIntoShowConf(confMap, baseConf, confInfo.Type)
  27. if json, err = jsoniter.Marshal(showConf); err != nil {
  28. return json, errors.Wrap(err, "1+1礼包 奖励序列化失败")
  29. }
  30. return
  31. }
  32. // 保存数据处理
  33. func (This *actOnePlus) handleActSave(confInfo *model.ActConfInfo) (err error) {
  34. var showConf model.OnePlusShowConf
  35. if err = jsoniter.Unmarshal(confInfo.ActShowConf, &showConf); err != nil {
  36. return errors.Wrap(err, "1+1礼包 奖励Json解析失败")
  37. }
  38. // 数据转换
  39. rewardMap := This.convertIntoRepoConf(showConf.RewardConf, confInfo.Type)
  40. if confInfo.Reward, err = jsoniter.Marshal(rewardMap); err != nil {
  41. return errors.Wrap(err, "1+1礼包 奖励数据序列化失败")
  42. }
  43. baseConf := map[string]int64{"maxNum": showConf.BaseConf.MaxNum}
  44. if confInfo.RewardConf, err = jsoniter.Marshal(baseConf); err != nil {
  45. return errors.Wrap(err, "1+1礼包 基础配置序列化失败")
  46. }
  47. return
  48. }
  49. // 分层数据处理
  50. func (This *actOnePlus) handleActRewardSection(confInfo *model.ActConfInfo, maps ...map[string]any) error {
  51. var rewardConfMap map[int64]model.OnePlusRewardConf
  52. if err := jsoniter.Unmarshal(confInfo.Reward, &rewardConfMap); err != nil {
  53. return errors.Wrap(err, "1+1礼包 奖励解析失败")
  54. }
  55. conditionMap, rewardMap := maps[0], maps[1]
  56. for idx1, item1 := range rewardConfMap {
  57. for idx2, item2 := range item1.Data {
  58. stageKey := fmt.Sprintf("%d_%d", idx1, idx2)
  59. conditionMap[stageKey] = Activity.buildStageConditionOld(item1.StartEnd, item2.SsGroup)
  60. rewardMap[stageKey] = item2.Data
  61. }
  62. }
  63. return nil
  64. }
  65. // 导入数据处理
  66. func (This *actOnePlus) handleActImport(detailInfo *model.ActDetailInfo, excelInfo [][][]string) (json types.JSONText, err error) {
  67. if len(excelInfo) < 3 {
  68. return json, errors.New("工作表数量不匹配")
  69. }
  70. var showConf model.OnePlusShowConf
  71. if showConf, err = This.sheetResolver(excelInfo, detailInfo.Type); err != nil {
  72. return json, errors.Wrap(err, "1+1礼包 工作表解析失败")
  73. }
  74. if json, err = jsoniter.Marshal(showConf); err != nil {
  75. return json, errors.Wrap(err, "1+1礼包 配置序列化失败")
  76. }
  77. return
  78. }
  79. func (This *actOnePlus) convertIntoShowConf(confMap map[int64]model.OnePlusRewardConf, baseConf model.OnePlusBaseConf, actType string) (showConf model.OnePlusShowConf) {
  80. for lvId, lvStageReward := range confMap {
  81. for ssId, ssStageReward := range lvStageReward.Data {
  82. formatStageReward := func() []model.OnePlusShowStageReward {
  83. rewardArr := utils.MapValues(ssStageReward.Data, true)
  84. formatRewards := make([]model.OnePlusShowStageReward, 0, len(rewardArr))
  85. for i, reward := range rewardArr {
  86. formatRewards = append(formatRewards, model.OnePlusShowStageReward{
  87. OnePlusStageReward: reward,
  88. IsFree: utils.Ternary(0 == i, false, true),
  89. })
  90. }
  91. return formatRewards
  92. }()
  93. showConf.RewardConf = append(showConf.RewardConf, model.OnePlusRewardShowConf{
  94. TwoLayerLvSsGroup: model.TwoLayerLvSsGroup{
  95. Id: Activity.buildLayerOrderId(lvId, ssId),
  96. LvRange: model.LvRange{LvStart: lvStageReward.Start, LvEnd: lvStageReward.End},
  97. SsGroup: ssStageReward.SsGroup,
  98. },
  99. Reward: formatStageReward,
  100. })
  101. }
  102. }
  103. sort.SliceStable(showConf.RewardConf, func(i, j int) bool { return showConf.RewardConf[i].Id < showConf.RewardConf[j].Id })
  104. baseConf.PlusCnt = This.buildPlusCnt(actType)
  105. showConf.BaseConf = baseConf
  106. return showConf
  107. }
  108. func (This *actOnePlus) convertIntoRepoConf(rewardConfArr []model.OnePlusRewardShowConf, actType string) map[int64]model.OnePlusRewardConf {
  109. repoConfMap := map[int64]model.OnePlusRewardConf{}
  110. var unique = uniqid.GetUniqId()
  111. defer uniqid.DelMapByUniqId(unique)
  112. startGid := This.getStartGid(actType)
  113. for i := 0; i < len(rewardConfArr); i++ {
  114. oneRowInfo := rewardConfArr[i]
  115. idxes := uniqid.GetStageIdx(unique, oneRowInfo.LvRange, oneRowInfo.SsGroup)
  116. lvIdx, ssIdx := idxes[0], idxes[1]
  117. if _, Ok := repoConfMap[lvIdx]; !Ok {
  118. repoConfMap[lvIdx] = model.OnePlusRewardConf{
  119. StartEnd: model.StartEnd{Start: oneRowInfo.LvRange.LvStart, End: oneRowInfo.LvRange.LvEnd},
  120. Data: map[int64]model.OnePlusSsGroupStage{},
  121. }
  122. }
  123. rewardMap := make(map[int64]model.OnePlusStageReward, len(oneRowInfo.Reward))
  124. paidReward := oneRowInfo.Reward[0].OnePlusStageReward
  125. for idx, reward := range oneRowInfo.Reward {
  126. one := model.OnePlusStageReward{
  127. Price: paidReward.Price,
  128. Sku: paidReward.Sku,
  129. Discount: 1,
  130. Gid: int64(idx) + startGid,
  131. Prizes: reward.Prizes,
  132. }
  133. rewardMap[one.Gid] = one
  134. }
  135. if _, Ok := repoConfMap[lvIdx].Data[ssIdx]; !Ok {
  136. repoConfMap[lvIdx].Data[ssIdx] = model.OnePlusSsGroupStage{
  137. SsGroup: oneRowInfo.SsGroup,
  138. Data: rewardMap,
  139. }
  140. }
  141. }
  142. return repoConfMap
  143. }
  144. func (This *actOnePlus) sheetResolver(excelInfo [][][]string, actType string) (model.OnePlusShowConf, error) {
  145. sheet1Array, sheet2Array, sheet3Array := excelInfo[0], excelInfo[1], excelInfo[2]
  146. // 基础配置
  147. showConf, err := This.parseBaseConf(sheet1Array, actType)
  148. if err != nil {
  149. return showConf, errors.WithStack(err)
  150. }
  151. // 解析分组ID配置项
  152. stageConfArr, err := Activity.parseTwoLayerLvSsGroupConf(sheet2Array)
  153. if err != nil {
  154. return showConf, errors.WithStack(err)
  155. }
  156. // 解析奖励配置项
  157. rewardMap, err := This.parseRewardSheet(sheet3Array)
  158. if err != nil {
  159. return showConf, errors.WithStack(err)
  160. }
  161. if err = This.packageShowConf(&showConf, stageConfArr, rewardMap); err != nil {
  162. return showConf, errors.WithStack(err)
  163. }
  164. return showConf, nil
  165. }
  166. func (This *actOnePlus) parseRewardSheet(sheet [][]string) (rewardMap map[int64][]model.OnePlusShowStageReward, err error) {
  167. rewardMap = map[int64][]model.OnePlusShowStageReward{}
  168. for rowIdx := 1; rowIdx < len(sheet); rowIdx++ {
  169. var (
  170. id int64
  171. ignore string
  172. one model.OnePlusShowStageReward
  173. reward = make([]model.ExcelPrize, 3)
  174. )
  175. // 解析行配置
  176. if err = utils.DestructAssign(sheet[rowIdx], &id, &ignore, &one.Price, &reward); err != nil {
  177. return nil, errors.WithStack(err)
  178. }
  179. if one.Prizes, err = Props.MultiParseActPrize(reward); err != nil {
  180. return nil, errors.WithStack(err)
  181. }
  182. if one.Sku = config.PriceSkuMap[one.Price]; utils.IsEmpty(one.Sku) {
  183. return nil, errors.New(fmt.Sprintf("第%d行,购买价格:%.2f 无对应sku", rowIdx, one.Price))
  184. }
  185. one.IsFree = utils.Ternary(len(rewardMap[id]) == 0, false, true)
  186. rewardMap[id] = append(rewardMap[id], one)
  187. }
  188. return rewardMap, err
  189. }
  190. func (This *actOnePlus) packageShowConf(showConf *model.OnePlusShowConf, layers []model.TwoLayerLvSsGroup, rewardMap map[int64][]model.OnePlusShowStageReward) error {
  191. showRewardArr := make([]model.OnePlusRewardShowConf, 0, len(layers))
  192. for _, layer := range layers {
  193. reward, Ok := rewardMap[layer.Id]
  194. if !Ok {
  195. return errors.New("未配置奖励项")
  196. }
  197. showRewardArr = append(showRewardArr, model.OnePlusRewardShowConf{
  198. TwoLayerLvSsGroup: layer,
  199. Reward: reward,
  200. })
  201. }
  202. showConf.RewardConf = showRewardArr
  203. return nil
  204. }
  205. func (This *actOnePlus) parseBaseConf(sheet [][]string, actType string) (showConf model.OnePlusShowConf, err error) {
  206. var maxNum int64
  207. for i := 0; i < len(sheet); i++ {
  208. if len(sheet[i]) == 0 || sheet[i][0] != "最大购买次数" {
  209. continue
  210. }
  211. if maxNum, err = conv.ToAnyE[int64](sheet[i][1]); err != nil {
  212. return showConf, errors.WithStack(err)
  213. }
  214. }
  215. showConf.BaseConf = model.OnePlusBaseConf{
  216. MaxNum: maxNum,
  217. PlusCnt: This.buildPlusCnt(actType),
  218. }
  219. return showConf, err
  220. }
  221. func (This *actOnePlus) buildPlusCnt(actType string) int64 {
  222. var plusCnt int64
  223. switch actType {
  224. case config.ActOnePlusGift:
  225. plusCnt = 1
  226. case config.ActOnePlusTwo:
  227. plusCnt = 2
  228. case config.ActOnePlusThree:
  229. plusCnt = 3
  230. }
  231. return plusCnt
  232. }
  233. func (This *actOnePlus) getStartGid(actType string) int64 {
  234. var gid int64
  235. switch actType {
  236. case config.ActOnePlusGift:
  237. gid = 1837
  238. case config.ActOnePlusTwo:
  239. gid = 1230001
  240. case config.ActOnePlusThree:
  241. gid = 1240001
  242. }
  243. return gid
  244. }