package service import ( "fmt" "strconv" "crazy-fox-backend-api/config" "crazy-fox-backend-api/model" "crazy-fox-backend-api/repo" "crazy-fox-backend-api/repo/okeys" "crazy-fox-backend-api/utils" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" "github.com/xuri/excelize/v2" ) // fruitSlotService 水果机模块服务 type fruitSlotService struct{} const ( fruitSlotGameBaseCfg = "gameBaseCfg" fruitSlotGameProNew = "gameProNew" fruitSlotGameProNewPay = "gameProNewPay" fruitSlotGoodsListNew = "goodsListNew" fruitSlotBaseCoins = "baseCoins" ) func (This *fruitSlotService) BasicConf() (model.FruitSlotBasicConf, error) { conf := repo.FruitSlot.GetConfByType(fruitSlotGameBaseCfg) var showConf model.FruitSlotBasicConf if err := jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil { return showConf, errors.WithStack(err) } return showConf, nil } func (This *fruitSlotService) BasicConfEdit(req *model.FruitSlotBasicConf) error { repoConf, err := jsoniter.MarshalToString(req) if err != nil { return errors.WithStack(err) } if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotGameBaseCfg, Config: repoConf}); err != nil { return errors.WithStack(err) } toMap, err := utils.StructToMap(req, "json", false) if err != nil { return errors.WithStack(err) } repo.HMSetCache(okeys.FruitGameBaseConfig(), toMap) return nil } func (This *fruitSlotService) WeightConf(typ string) ([]model.FruitSlotWeight, error) { if !utils.InSlice(typ, []string{fruitSlotGameProNew, fruitSlotGameProNewPay}) { return nil, errors.New("type error :" + typ) } conf := repo.FruitSlot.GetConfByType(typ) var showConf []model.FruitSlotWeight if err := jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil { return showConf, errors.WithStack(err) } for i, weight := range showConf { if utils.IsEmpty(weight.Ext) { showConf[i].Ext = model.PropPrizes{} } } return showConf, nil } func (This *fruitSlotService) WeightConfEdit(req *model.FruitSlotWeightUpdate) error { if !utils.InSlice(req.Type, []string{fruitSlotGameProNew, fruitSlotGameProNewPay}) { return errors.New("type error :" + req.Type) } for _, weight := range req.Conf { propsIds := utils.SliceColumn[model.PropPrize, int64](weight.Ext, "propsId") if weight.Id != 4 && utils.InSlice(config.PropSkinChest, propsIds) { return errors.New("Id为4的行才可以配置小丑宝箱") } if weight.Id != 4 && len(propsIds) == 1 && !utils.InSlice(config.PropCoin, propsIds) { return errors.New(fmt.Sprintf("Id为%d的行 只能配置金币", weight.Id)) } } repoConf, err := jsoniter.MarshalToString(req.Conf) if err != nil { return errors.WithStack(err) } if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: req.Type, Config: repoConf}); err != nil { return errors.WithStack(err) } // 更新缓存 repo.SetCache(okeys.FruitGameProCfg(utils.Ternary(req.Type == fruitSlotGameProNew, "", ":PAY")), repoConf) return nil } func (This *fruitSlotService) GoodsConf() (goodsConf model.FruitSlotGoodsConf, err error) { conf := repo.FruitSlot.GetConfByType(fruitSlotGoodsListNew) var showConf []model.FruitSlotGoodsConf if err = jsoniter.UnmarshalFromString(conf.Config, &showConf); err != nil { return goodsConf, errors.WithStack(err) } return showConf[0], err } func (This *fruitSlotService) GoodsConfEdit(req *model.FruitSlotGoodsConf) error { req.Gtype = 113 goodsConf := []model.FruitSlotGoodsConf{*req} repoConf, err := jsoniter.MarshalToString(goodsConf) if err != nil { return errors.WithStack(err) } if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotGoodsListNew, Config: repoConf}); err != nil { return errors.WithStack(err) } // 更新缓存 repo.SetCache(okeys.FruitGameGoodsListCfg(), repoConf) return nil } func (This *fruitSlotService) LevelCoins() (list []model.FruitSlotBaseCoinShow) { conf := repo.FruitSlot.GetConfByType(fruitSlotBaseCoins) var confList []model.FruitSlotBaseCoin if err := jsoniter.UnmarshalFromString(conf.Config, &confList); err != nil { return list } lastLimit := model.FruitSlotBaseCoinShow{ LvRange: model.LvRange{LvStart: confList[0].Lv, LvEnd: confList[0].Lv}, Coins: confList[0].Coins, } for _, limit := range confList { if limit.Coins == lastLimit.Coins { lastLimit.LvEnd = limit.Lv } else { list = append(list, lastLimit) lastLimit = model.FruitSlotBaseCoinShow{ LvRange: model.LvRange{LvStart: limit.Lv, LvEnd: limit.Lv}, Coins: limit.Coins, } } } list = append(list, lastLimit) return } func (This *fruitSlotService) LevelCoinsEdit(req []model.FruitSlotBaseCoinShow) error { lvLen := req[len(req)-1].LvEnd cacheMap := make(map[string]any, lvLen) confList := make([]model.FruitSlotBaseCoin, 0, lvLen) for _, show := range req { for i := show.LvStart; i <= show.LvEnd; i++ { confList = append(confList, model.FruitSlotBaseCoin{Lv: i, Coins: show.Coins}) cacheMap[strconv.FormatInt(i, 10)] = show.Coins } } if lvLen != int64(len(confList)) { return errors.New("等级需要从1开始连续配置") } repoConf, err := jsoniter.MarshalToString(confList) if err != nil { return errors.WithStack(err) } if err = repo.FruitSlot.UpdateConfByType(model.TFruitBaseConfig{Type: fruitSlotBaseCoins, Config: repoConf}); err != nil { return errors.WithStack(err) } // 更新缓存 repo.ClearAndHMSetCache(okeys.FruitGameBaseCoinsCfg(), cacheMap) return nil } func (This *fruitSlotService) handleLevelCoinImport(excelInfo [][][]string) (err error) { excelData := excelInfo[0] confList := make([]model.FruitSlotBaseCoinShow, 0, len(excelData)) for i := 1; i < len(excelData); i++ { var one model.FruitSlotBaseCoinShow if err = utils.DestructAssign(excelData[i], &one); err != nil { return errors.WithStack(err) } confList = append(confList, one) } if err = This.LevelCoinsEdit(confList); err != nil { return errors.WithStack(err) } return err } func (This *fruitSlotService) handleLevelCoinExport(xlsx *excelize.File, fileName *string) (err error) { list := This.LevelCoins() // 工作表1 sheetName := "基础配置" if err = xlsx.SetSheetName("Sheet1", sheetName); err != nil { return errors.WithStack(err) } titles := []string{"等级下限", "等级上限", "金币"} if err = xlsx.SetSheetRow(sheetName, "A1", &titles); err != nil { return errors.WithStack(err) } for i, oneInfo := range list { rowSlice := []any{oneInfo.LvStart, oneInfo.LvEnd, oneInfo.Coins} if err = xlsx.SetSheetRow(sheetName, fmt.Sprintf("A%d", i+2), &rowSlice); err != nil { return errors.WithStack(err) } } *fileName = "水果机等级金币配置" return err }