Commit dbc068363ddbc7b6a32d3886ee013b0328663b0a

Authored by 王家文
1 parent ff742c87
Exists in master and in 1 other branch dev-wjw

feat✨:星星商店兑换

controllers/cardholder.go
@@ -45,3 +45,15 @@ func (c *CardHolderController) Open() { @@ -45,3 +45,15 @@ func (c *CardHolderController) Open() {
45 45
46 c.RetRspCodeData(code, rsp) 46 c.RetRspCodeData(code, rsp)
47 } 47 }
  48 +
  49 +// ShopExchange 星星商店兑换
  50 +func (c *CardHolderController) ShopExchange() {
  51 + req := new(models.ReqStarShopExchange)
  52 + if !c.GetPostData(req) {
  53 + return
  54 + }
  55 +
  56 + code, rsp := cardholder.HandleShopExchange(req)
  57 +
  58 + c.RetRspCodeData(code, rsp)
  59 +}
models/cardholder.go
@@ -65,27 +65,17 @@ type RspCardHolderOpen struct { @@ -65,27 +65,17 @@ type RspCardHolderOpen struct {
65 AwardRound string `form:"award_round" json:"award_round"` // 触发的轮次奖励列表 空字符串未触发 65 AwardRound string `form:"award_round" json:"award_round"` // 触发的轮次奖励列表 空字符串未触发
66 } 66 }
67 67
68 -// ReqCardHolderGetRewardAlbum 请求 领取卡组奖励  
69 -type ReqCardHolderGetRewardAlbum struct { 68 +// ReqStarShopExchange 请求 星星商店兑换
  69 +type ReqStarShopExchange struct {
70 BaseLoginInfo 70 BaseLoginInfo
71 BaseSign 71 BaseSign
72 - Id int `form:"id" json:"id" valid:"Required"` // 卡组ID 72 + Id int `form:"id" json:"id" valid:"Required"` // 星星商店ID
73 } 73 }
74 74
75 -// RspCardHolderGetRewardAlbum 返回 领取卡组奖励  
76 -type RspCardHolderGetRewardAlbum struct { 75 +// RspStarShopExchange 返回 星星商店兑换
  76 +type RspStarShopExchange struct {
77 CardHolderInfo 77 CardHolderInfo
78 - Award string `form:"award" json:"award"` // 奖励字符串  
79 -}  
80 -  
81 -// ReqCardHolderGetRewardRound 请求 领取轮次奖励  
82 -type ReqCardHolderGetRewardRound struct {  
83 - BaseLoginInfo  
84 - BaseSign  
85 -}  
86 -  
87 -// RspCardHolderGetRewardRound 返回 领取轮次奖励  
88 -type RspCardHolderGetRewardRound struct {  
89 - CardHolderInfo  
90 - Award string `form:"award" json:"award"` // 奖励字符串 78 + NewCards []int `form:"new_cards" json:"new_cards"` // 新获得的卡牌列表
  79 + AwardAlbum map[int]string `form:"award_album" json:"award_album"` // 触发的卡组奖励列表 k=出发的卡组ID v=对应奖励
  80 + AwardRound string `form:"award_round" json:"award_round"` // 触发的轮次奖励列表 空字符串未触发
91 } 81 }
routers/router.go
@@ -17,6 +17,8 @@ func init() { @@ -17,6 +17,8 @@ func init() {
17 beego.Router(prefix+"/cardholder/info", &controllers.CardHolderController{}, "post:Info") 17 beego.Router(prefix+"/cardholder/info", &controllers.CardHolderController{}, "post:Info")
18 // 卡包打开 18 // 卡包打开
19 beego.Router(prefix+"/cardholder/open", &controllers.CardHolderController{}, "post:Open") 19 beego.Router(prefix+"/cardholder/open", &controllers.CardHolderController{}, "post:Open")
  20 + // 卡包打开
  21 + beego.Router(prefix+"/cardholder/shopexchange", &controllers.CardHolderController{}, "post:ShopExchange")
20 22
21 beego.ErrorController(&controllers.ErrorController{}) 23 beego.ErrorController(&controllers.ErrorController{})
22 } 24 }
service/cardholder/config.go
@@ -117,6 +117,6 @@ type CardSequenceConfig struct { @@ -117,6 +117,6 @@ type CardSequenceConfig struct {
117 type StarShopConfig struct { 117 type StarShopConfig struct {
118 Id int `json:"id"` // ID 118 Id int `json:"id"` // ID
119 StarNumber int `json:"star_number"` // 需求星星数 119 StarNumber int `json:"star_number"` // 需求星星数
120 - CardholderId []int `json:"cardholder_id"` // 可换取的卡包ID // todo 要重命名 120 + CardholderId []int `json:"cardholder_id"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量} // todo 要重命名
121 AlbumId int `json:"album_id"` // 对应卡册活动ID // todo 要重命名 121 AlbumId int `json:"album_id"` // 对应卡册活动ID // todo 要重命名
122 } 122 }
service/cardholder/handle.go
@@ -3,6 +3,7 @@ package cardholder @@ -3,6 +3,7 @@ package cardholder
3 import ( 3 import (
4 "apigame/models" 4 "apigame/models"
5 "apigame/service/constd" 5 "apigame/service/constd"
  6 + "apigame/util/util-lx/lxalilog"
6 "apigame/util/util-lx/lxtime" 7 "apigame/util/util-lx/lxtime"
7 "apigame/util/uttype" 8 "apigame/util/uttype"
8 "strconv" 9 "strconv"
@@ -89,18 +90,130 @@ func HandleOpen(req *models.ReqCardHolderOpen) (code string, rsp models.RspCardH @@ -89,18 +90,130 @@ func HandleOpen(req *models.ReqCardHolderOpen) (code string, rsp models.RspCardH
89 } 90 }
90 91
91 // 开始处理抽卡 92 // 开始处理抽卡
  93 + openMode := 0
92 sequenceId, cohort := GetUserSequenceIdAndCohort(req.UID) 94 sequenceId, cohort := GetUserSequenceIdAndCohort(req.UID)
93 - newCards, awardAlbum, awardRound := DoOpen(req.GameID,  
94 - gameData, config, confCardholder, 95 + newCards := DoOpen(req.GameID,
  96 + gameData, config,
  97 + confCardholder,
95 sequenceId, cohort, 98 sequenceId, cohort,
96 - 0) 99 + openMode)
97 rsp.NewCards = newCards 100 rsp.NewCards = newCards
  101 + awardAlbum, awardRound := DoOpenCheckAward(req.GameID,
  102 + gameData, config,
  103 + sequenceId, cohort,
  104 + rsp.NewCards,
  105 + openMode)
  106 + rsp.AwardAlbum = awardAlbum
  107 + rsp.AwardRound = awardRound
  108 +
  109 + // 计算星星点数
  110 + CalculateStarCount(gameData, config)
  111 +
  112 + // 存档
  113 + SaveData(req.GameID, gameData)
  114 +
  115 + uttype.Shuffle(rsp.NewCards)
  116 +
  117 + // 返回信息
  118 + rsp.CardHolderInfo = GetInfo(gameData, config)
  119 +
  120 + return
  121 +}
  122 +
  123 +// HandleShopExchange 星星商店兑换
  124 +func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp models.RspStarShopExchange) {
  125 + rsp = models.RspStarShopExchange{
  126 + NewCards: make([]int, 0),
  127 + AwardAlbum: make(map[int]string),
  128 + }
  129 + code = constd.RECODE_OK
  130 +
  131 + // 尝试更新配置
  132 + config, hasConfig := TryUpdateConfig(req.GameID)
  133 + if !hasConfig {
  134 + code = constd.RECODE_MERGE_CARDHOLDER_NOTOPEN_ERROR
  135 + return
  136 + }
  137 +
  138 + // 检查活动状态
  139 + code = CheckStatus(config)
  140 + if code != constd.RECODE_OK {
  141 + return
  142 + }
  143 + // 检查星星商店ID
  144 + confStarShop, okStarShopConfig := config.StarShopConfig[req.Id]
  145 + if !okStarShopConfig {
  146 + code = constd.RECODE_MERGE_CARDHOLDER_STARSHOPID_ERROR
  147 + return
  148 + }
  149 +
  150 + // 读取游戏数据
  151 + gameData := LoadData(req.GameID, req.UID, config.Id)
  152 + // 检查游戏数据 轮次等
  153 + code = CheckGameData(gameData, config)
  154 + if code != constd.RECODE_OK {
  155 + return
  156 + }
  157 +
  158 + // 判断星星数是否足够
  159 + if gameData.Details.StarCount < confStarShop.StarNumber {
  160 + code = constd.RECODE_MERGE_CARDHOLDER_STAR_NOTENOUGH_ERROR
  161 + return
  162 + }
  163 +
  164 + // 判断配置
  165 + if len(confStarShop.CardholderId) < 3 {
  166 + lxalilog.Errors("StarShopConfig.CardholderId error", confStarShop.Id)
  167 + code = constd.RECODE_MERGE_CONFIG_ERROR
  168 + return
  169 + }
  170 + cardholderId := confStarShop.CardholderId[1]
  171 + cardholderCount := confStarShop.CardholderId[2]
  172 + if cardholderCount < 1 {
  173 + lxalilog.Errors("StarShopConfig.CardholderId error", confStarShop.Id)
  174 + code = constd.RECODE_MERGE_CONFIG_ERROR
  175 + return
  176 + }
  177 + confCardholder, okCardholderConfig := config.CardholderConfig[strconv.Itoa(cardholderId)]
  178 + if !okCardholderConfig {
  179 + code = constd.RECODE_MERGE_CONFIG_ERROR
  180 + return
  181 + }
  182 +
  183 + // 按照规则扣除星星
  184 + enough, cardList := GetStarCardList(gameData, config, confStarShop.StarNumber)
  185 + if !enough {
  186 + code = constd.RECODE_MERGE_CARDHOLDER_STAR_NOTENOUGH_ERROR
  187 + return
  188 + }
  189 + for i, i2 := range cardList {
  190 + gameData.Details.Cards[i] -= i2
  191 + }
  192 +
  193 + // 开始处理抽卡
  194 + openMode := 1
  195 + sequenceId, cohort := GetUserSequenceIdAndCohort(req.UID)
  196 + for i := 0; i < cardholderCount; i++ {
  197 + newCards := DoOpen(req.GameID,
  198 + gameData, config,
  199 + confCardholder,
  200 + sequenceId, cohort,
  201 + openMode)
  202 + for _, i3 := range newCards {
  203 + rsp.NewCards = append(rsp.NewCards, i3)
  204 + }
  205 + }
  206 + awardAlbum, awardRound := DoOpenCheckAward(req.GameID,
  207 + gameData, config,
  208 + sequenceId, cohort,
  209 + rsp.NewCards,
  210 + openMode)
98 rsp.AwardAlbum = awardAlbum 211 rsp.AwardAlbum = awardAlbum
99 rsp.AwardRound = awardRound 212 rsp.AwardRound = awardRound
100 213
101 // 计算星星点数 214 // 计算星星点数
102 CalculateStarCount(gameData, config) 215 CalculateStarCount(gameData, config)
103 - 216 +
104 // 存档 217 // 存档
105 SaveData(req.GameID, gameData) 218 SaveData(req.GameID, gameData)
106 219
service/cardholder/logic.go
@@ -177,11 +177,9 @@ func DoOpen(gameId string, @@ -177,11 +177,9 @@ func DoOpen(gameId string,
177 config *CardActivityConfig, 177 config *CardActivityConfig,
178 confCardholder OpenCardholderConfig, 178 confCardholder OpenCardholderConfig,
179 sequenceId, cohort string, 179 sequenceId, cohort string,
180 - openMode int) (newCards []int, awardAlbum map[int]string, awardRound string) { 180 + openMode int) (newCards []int) {
181 181
182 newCards = make([]int, 0) 182 newCards = make([]int, 0)
183 - awardAlbum = make(map[int]string)  
184 - awardRound = ""  
185 183
186 if confCardholder.IsNew != 0 { 184 if confCardholder.IsNew != 0 {
187 // 如果是新卡包 按顺序查找数目最少的一张卡抽取 185 // 如果是新卡包 按顺序查找数目最少的一张卡抽取
@@ -233,6 +231,20 @@ func DoOpen(gameId string, @@ -233,6 +231,20 @@ func DoOpen(gameId string,
233 openMode, uttype.StringToInt(confCardholder.Id), utjson.JsonString(newCards))) 231 openMode, uttype.StringToInt(confCardholder.Id), utjson.JsonString(newCards)))
234 } 232 }
235 233
  234 + return
  235 +}
  236 +
  237 +// DoOpenCheckAward 封装的新卡判断是否出发卡组和轮次奖励的逻辑
  238 +func DoOpenCheckAward(gameId string,
  239 + gameData *dto.CardHolderData,
  240 + config *CardActivityConfig,
  241 + sequenceId, cohort string,
  242 + newCards []int,
  243 + openMode int) (awardAlbum map[int]string, awardRound string) {
  244 +
  245 + awardAlbum = make(map[int]string)
  246 + awardRound = ""
  247 +
236 if openMode == 0 || openMode == 1 { 248 if openMode == 0 || openMode == 1 {
237 // 根据新获得卡牌列表 判断 触发的卡组奖励列表 249 // 根据新获得卡牌列表 判断 触发的卡组奖励列表
238 for _, cardId := range newCards { 250 for _, cardId := range newCards {
@@ -298,7 +310,7 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig @@ -298,7 +310,7 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig
298 } 310 }
299 // 1. 普卡 :卡的等级数=可累计 的星星数 311 // 1. 普卡 :卡的等级数=可累计 的星星数
300 // 2. 金币: 卡的等级数+1=可累计 的星星数 312 // 2. 金币: 卡的等级数+1=可累计 的星星数
301 - if confCard.IsGold != 0 { 313 + if confCard.IsGold == 1 {
302 starCount += (cardCount - 1) * (confCard.Star + 1) 314 starCount += (cardCount - 1) * (confCard.Star + 1)
303 } else { 315 } else {
304 starCount += (cardCount - 1) * confCard.Star 316 starCount += (cardCount - 1) * confCard.Star
@@ -306,3 +318,72 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig @@ -306,3 +318,72 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig
306 } 318 }
307 gameData.Details.StarCount = starCount 319 gameData.Details.StarCount = starCount
308 } 320 }
  321 +
  322 +// GetStarCardList 按照规则扣除星星数找到需要扣除的卡牌列表
  323 +func GetStarCardList(gameData *dto.CardHolderData, config *CardActivityConfig, needStar int) (enough bool, cardList map[int]int) {
  324 + enough = false
  325 + cardList = make(map[int]int)
  326 + starAmount := 0
  327 + levelMax := 5
  328 + // 等级依次从低到高
  329 + // 先普卡
  330 + for i := 1; i <= levelMax; i++ {
  331 + for cardId, cardCount := range gameData.Details.Cards {
  332 + if starAmount >= needStar {
  333 + enough = true
  334 + return
  335 + }
  336 + if cardCount <= 1 {
  337 + continue
  338 + }
  339 + confCard, hasConfCard := config.CardConfig[cardId]
  340 + if !hasConfCard {
  341 + continue
  342 + }
  343 + if confCard.IsGold == 1 {
  344 + continue
  345 + }
  346 + star := confCard.Star
  347 + need := needStar - starAmount
  348 + needCardCount := need / star
  349 + if cardCount-1 < needCardCount {
  350 + needCardCount = cardCount - 1
  351 + }
  352 + cardList[cardId] = needCardCount
  353 + starAmount += needCardCount * star
  354 + }
  355 + }
  356 + // 金卡
  357 + for i := 1; i <= levelMax; i++ {
  358 + for cardId, cardCount := range gameData.Details.Cards {
  359 + if starAmount >= needStar {
  360 + enough = true
  361 + return
  362 + }
  363 + if cardCount <= 1 {
  364 + continue
  365 + }
  366 + confCard, hasConfCard := config.CardConfig[cardId]
  367 + if !hasConfCard {
  368 + continue
  369 + }
  370 + if confCard.IsGold != 1 {
  371 + continue
  372 + }
  373 + star := confCard.Star + 1
  374 + need := needStar - starAmount
  375 + needCardCount := need / star
  376 + if cardCount-1 < needCardCount {
  377 + needCardCount = cardCount - 1
  378 + }
  379 + cardList[cardId] = needCardCount
  380 + starAmount += needCardCount * star
  381 + }
  382 + }
  383 + if starAmount >= needStar {
  384 + enough = true
  385 + return
  386 + }
  387 +
  388 + return
  389 +}
service/constd/code-msg.go
@@ -40,17 +40,13 @@ const ( @@ -40,17 +40,13 @@ const (
40 RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR = "2051" 40 RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR = "2051"
41 RECODE_MERGE_QINGXIANGMTXZ_ERROR = "2052" 41 RECODE_MERGE_QINGXIANGMTXZ_ERROR = "2052"
42 42
43 - RECODE_MERGE_CARDHOLDER_NOTOPEN_ERROR = "2100"  
44 - RECODE_MERGE_CARDHOLDER_NOTOPEN1_ERROR = "2101"  
45 - RECODE_MERGE_CARDHOLDER_NOTOPEN2_ERROR = "2102"  
46 - RECODE_MERGE_CARDHOLDER_ROUNDFINISH_ERROR = "2103"  
47 - RECODE_MERGE_CARDHOLDER_CARDHOLDERID_ERROR = "2104"  
48 - RECODE_MERGE_CARDHOLDER_COUNTILLEGAL_ERROR = "2105"  
49 - RECODE_MERGE_CARDHOLDER_CARDHOLDER_NOTENOUGH_ERROR = "2106"  
50 - RECODE_MERGE_CARDHOLDER_ALBUMID_ERROR = "2107"  
51 - RECODE_MERGE_CARDHOLDER_ALBUM_HASGOT_ERROR = "2108"  
52 - RECODE_MERGE_CARDHOLDER_ALBUM_NOTFINISH_ERROR = "2109"  
53 - RECODE_MERGE_CARDHOLDER_ROUND_NOTFINISH_ERROR = "2110" 43 + RECODE_MERGE_CARDHOLDER_NOTOPEN_ERROR = "2100"
  44 + RECODE_MERGE_CARDHOLDER_NOTOPEN1_ERROR = "2101"
  45 + RECODE_MERGE_CARDHOLDER_NOTOPEN2_ERROR = "2102"
  46 + RECODE_MERGE_CARDHOLDER_ROUNDFINISH_ERROR = "2103"
  47 + RECODE_MERGE_CARDHOLDER_CARDHOLDERID_ERROR = "2104"
  48 + RECODE_MERGE_CARDHOLDER_STARSHOPID_ERROR = "2105"
  49 + RECODE_MERGE_CARDHOLDER_STAR_NOTENOUGH_ERROR = "2106"
54 ) 50 )
55 51
56 var recodeText = map[string]string{ 52 var recodeText = map[string]string{
@@ -91,17 +87,13 @@ var recodeText = map[string]string{ @@ -91,17 +87,13 @@ var recodeText = map[string]string{
91 RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR: "通行证不存在", 87 RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR: "通行证不存在",
92 RECODE_MERGE_QINGXIANGMTXZ_ERROR: "请先购买通行证", 88 RECODE_MERGE_QINGXIANGMTXZ_ERROR: "请先购买通行证",
93 89
94 - RECODE_MERGE_CARDHOLDER_NOTOPEN_ERROR: "活动未开放",  
95 - RECODE_MERGE_CARDHOLDER_NOTOPEN1_ERROR: "活动未开始",  
96 - RECODE_MERGE_CARDHOLDER_NOTOPEN2_ERROR: "活动已结束",  
97 - RECODE_MERGE_CARDHOLDER_ROUNDFINISH_ERROR: "活动轮次已全部完成",  
98 - RECODE_MERGE_CARDHOLDER_CARDHOLDERID_ERROR: "卡包ID错误",  
99 - RECODE_MERGE_CARDHOLDER_COUNTILLEGAL_ERROR: "数目不合法",  
100 - RECODE_MERGE_CARDHOLDER_CARDHOLDER_NOTENOUGH_ERROR: "卡包不足",  
101 - RECODE_MERGE_CARDHOLDER_ALBUMID_ERROR: "卡组ID错误",  
102 - RECODE_MERGE_CARDHOLDER_ALBUM_HASGOT_ERROR: "卡组奖励已领取",  
103 - RECODE_MERGE_CARDHOLDER_ALBUM_NOTFINISH_ERROR: "卡组卡牌未集齐",  
104 - RECODE_MERGE_CARDHOLDER_ROUND_NOTFINISH_ERROR: "卡册未集齐", 90 + RECODE_MERGE_CARDHOLDER_NOTOPEN_ERROR: "活动未开放",
  91 + RECODE_MERGE_CARDHOLDER_NOTOPEN1_ERROR: "活动未开始",
  92 + RECODE_MERGE_CARDHOLDER_NOTOPEN2_ERROR: "活动已结束",
  93 + RECODE_MERGE_CARDHOLDER_ROUNDFINISH_ERROR: "活动轮次已全部完成",
  94 + RECODE_MERGE_CARDHOLDER_CARDHOLDERID_ERROR: "卡包ID错误",
  95 + RECODE_MERGE_CARDHOLDER_STARSHOPID_ERROR: "商店ID错误",
  96 + RECODE_MERGE_CARDHOLDER_STAR_NOTENOUGH_ERROR: "星星商店星星不足",
105 } 97 }
106 98
107 func RecodeText(code string) string { 99 func RecodeText(code string) string {