fruitslot.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package service
  2. import (
  3. "fmt"
  4. "strconv"
  5. "crazy-fox-backend-api/config"
  6. "crazy-fox-backend-api/model"
  7. "crazy-fox-backend-api/repo"
  8. "crazy-fox-backend-api/repo/okeys"
  9. "crazy-fox-backend-api/utils"
  10. jsoniter "github.com/json-iterator/go"
  11. "github.com/pkg/errors"
  12. "github.com/xuri/excelize/v2"
  13. )
  14. // fruitSlotService 水果机模块服务
  15. type fruitSlotService struct{}
  16. const (
  17. fruitSlotGameBaseCfg = "gameBaseCfg"
  18. fruitSlotGameProNew = "gameProNew"
  19. fruitSlotGameProNewPay = "gameProNewPay"
  20. fruitSlotGoodsListNew = "goodsListNew"
  21. fruitSlotBaseCoins = "baseCoins"
  22. )
  23. func (This *fruitSlotService) BasicConf() (model.FruitSlotBasicConf, error) {
  24. conf := repo.FruitSlot.GetConfByType(fruitSlotGameBaseCfg)
  25. var showConf model.FruitSlotBasicConf
  26. if err := jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil {
  27. return showConf, errors.WithStack(err)
  28. }
  29. return showConf, nil
  30. }
  31. func (This *fruitSlotService) BasicConfEdit(req *model.FruitSlotBasicConf) error {
  32. repoConf, err := jsoniter.MarshalToString(req)
  33. if err != nil {
  34. return errors.WithStack(err)
  35. }
  36. if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotGameBaseCfg, Config: repoConf}); err != nil {
  37. return errors.WithStack(err)
  38. }
  39. toMap, err := utils.StructToMap(req, "json", false)
  40. if err != nil {
  41. return errors.WithStack(err)
  42. }
  43. repo.HMSetCache(okeys.FruitGameBaseConfig(), toMap)
  44. return nil
  45. }
  46. func (This *fruitSlotService) WeightConf(typ string) ([]model.FruitSlotWeight, error) {
  47. if !utils.InSlice(typ, []string{fruitSlotGameProNew, fruitSlotGameProNewPay}) {
  48. return nil, errors.New("type error :" + typ)
  49. }
  50. conf := repo.FruitSlot.GetConfByType(typ)
  51. var showConf []model.FruitSlotWeight
  52. if err := jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil {
  53. return showConf, errors.WithStack(err)
  54. }
  55. for i, weight := range showConf {
  56. if utils.IsEmpty(weight.Ext) {
  57. showConf[i].Ext = model.PropPrizes{}
  58. }
  59. }
  60. return showConf, nil
  61. }
  62. func (This *fruitSlotService) WeightConfEdit(req *model.FruitSlotWeightUpdate) error {
  63. if !utils.InSlice(req.Type, []string{fruitSlotGameProNew, fruitSlotGameProNewPay}) {
  64. return errors.New("type error :" + req.Type)
  65. }
  66. for _, weight := range req.Conf {
  67. propsIds := utils.SliceColumn[model.PropPrize, int64](weight.Ext, "propsId")
  68. if weight.Id != 4 && utils.InSlice(config.PropSkinChest, propsIds) {
  69. return errors.New("Id为4的行才可以配置小丑宝箱")
  70. }
  71. if weight.Id != 4 && len(propsIds) == 1 && !utils.InSlice(config.PropCoin, propsIds) {
  72. return errors.New(fmt.Sprintf("Id为%d的行 只能配置金币", weight.Id))
  73. }
  74. }
  75. repoConf, err := jsoniter.MarshalToString(req.Conf)
  76. if err != nil {
  77. return errors.WithStack(err)
  78. }
  79. if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: req.Type, Config: repoConf}); err != nil {
  80. return errors.WithStack(err)
  81. }
  82. // 更新缓存
  83. repo.SetCache(okeys.FruitGameProCfg(utils.Ternary(req.Type == fruitSlotGameProNew, "", ":PAY")), repoConf)
  84. return nil
  85. }
  86. func (This *fruitSlotService) GoodsConf() (goodsConf model.FruitSlotGoodsConf, err error) {
  87. conf := repo.FruitSlot.GetConfByType(fruitSlotGoodsListNew)
  88. var showConf []model.FruitSlotGoodsConf
  89. if err = jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil {
  90. return goodsConf, errors.WithStack(err)
  91. }
  92. return showConf[0], err
  93. }
  94. func (This *fruitSlotService) GoodsConfEdit(req *model.FruitSlotGoodsConf) error {
  95. req.Gtype = 113
  96. goodsConf := []model.FruitSlotGoodsConf{*req}
  97. repoConf, err := jsoniter.MarshalToString(goodsConf)
  98. if err != nil {
  99. return errors.WithStack(err)
  100. }
  101. if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotGoodsListNew, Config: repoConf}); err != nil {
  102. return errors.WithStack(err)
  103. }
  104. // 更新缓存
  105. repo.SetCache(okeys.FruitGameGoodsListCfg(), repoConf)
  106. return nil
  107. }
  108. func (This *fruitSlotService) LevelCoins() (list []model.FruitSlotBaseCoinShow) {
  109. conf := repo.FruitSlot.GetConfByType(fruitSlotBaseCoins)
  110. var confList []model.FruitSlotBaseCoin
  111. if err := jsoniter.UnmarshalFromString(conf.Config, &confList); err != nil {
  112. return list
  113. }
  114. lastLimit := model.FruitSlotBaseCoinShow{
  115. LvRange: model.LvRange{LvStart: confList[0].Lv, LvEnd: confList[0].Lv},
  116. Coins: confList[0].Coins,
  117. }
  118. for _, limit := range confList {
  119. if limit.Coins == lastLimit.Coins {
  120. lastLimit.LvEnd = limit.Lv
  121. } else {
  122. list = append(list, lastLimit)
  123. lastLimit = model.FruitSlotBaseCoinShow{
  124. LvRange: model.LvRange{LvStart: limit.Lv, LvEnd: limit.Lv},
  125. Coins: limit.Coins,
  126. }
  127. }
  128. }
  129. list = append(list, lastLimit)
  130. return
  131. }
  132. func (This *fruitSlotService) LevelCoinsEdit(req []model.FruitSlotBaseCoinShow) error {
  133. lvLen := req[len(req)-1].LvEnd
  134. cacheMap := make(map[string]any, lvLen)
  135. confList := make([]model.FruitSlotBaseCoin, 0, lvLen)
  136. for _, show := range req {
  137. for i := show.LvStart; i <= show.LvEnd; i++ {
  138. confList = append(confList, model.FruitSlotBaseCoin{Lv: i, Coins: show.Coins})
  139. cacheMap[strconv.FormatInt(i, 10)] = show.Coins
  140. }
  141. }
  142. if lvLen != int64(len(confList)) {
  143. return errors.New("等级需要从1开始连续配置")
  144. }
  145. repoConf, err := jsoniter.MarshalToString(confList)
  146. if err != nil {
  147. return errors.WithStack(err)
  148. }
  149. if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotBaseCoins, Config: repoConf}); err != nil {
  150. return errors.WithStack(err)
  151. }
  152. // 更新缓存
  153. repo.ClearAndHMSetCache(okeys.FruitGameBaseCoinsCfg(), cacheMap)
  154. return nil
  155. }
  156. func (This *fruitSlotService) handleLevelCoinImport(excelInfo [][][]string) (err error) {
  157. excelData := excelInfo[0]
  158. confList := make([]model.FruitSlotBaseCoinShow, 0, len(excelData))
  159. for i := 1; i < len(excelData); i++ {
  160. var one model.FruitSlotBaseCoinShow
  161. if err = utils.DestructAssign(excelData[i], &one); err != nil {
  162. return errors.WithStack(err)
  163. }
  164. confList = append(confList, one)
  165. }
  166. if err = This.LevelCoinsEdit(confList); err != nil {
  167. return errors.WithStack(err)
  168. }
  169. return err
  170. }
  171. func (This *fruitSlotService) handleLevelCoinExport(xlsx *excelize.File, fileName *string) (err error) {
  172. list := This.LevelCoins()
  173. // 工作表1
  174. sheetName := "基础配置"
  175. if err = xlsx.SetSheetName("Sheet1", sheetName); err != nil {
  176. return errors.WithStack(err)
  177. }
  178. titles := []string{"等级下限", "等级上限", "金币"}
  179. if err = xlsx.SetSheetRow(sheetName, "A1", &titles); err != nil {
  180. return errors.WithStack(err)
  181. }
  182. for i, oneInfo := range list {
  183. rowSlice := []any{oneInfo.LvStart, oneInfo.LvEnd, oneInfo.Coins}
  184. if err = xlsx.SetSheetRow(sheetName, fmt.Sprintf("A%d", i+2), &rowSlice); err != nil {
  185. return errors.WithStack(err)
  186. }
  187. }
  188. *fileName = "水果机等级金币配置"
  189. return err
  190. }