Commit dbc068363ddbc7b6a32d3886ee013b0328663b0a
1 parent
ff742c87
Exists in
master
and in
1 other branch
feat✨:星星商店兑换
Showing
7 changed files
with
239 additions
and
49 deletions
Show diff stats
controllers/cardholder.go
| ... | ... | @@ -45,3 +45,15 @@ func (c *CardHolderController) Open() { |
| 45 | 45 | |
| 46 | 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 | 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 | 70 | BaseLoginInfo |
| 71 | 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 | 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 | 17 | beego.Router(prefix+"/cardholder/info", &controllers.CardHolderController{}, "post:Info") |
| 18 | 18 | // 卡包打开 |
| 19 | 19 | beego.Router(prefix+"/cardholder/open", &controllers.CardHolderController{}, "post:Open") |
| 20 | + // 卡包打开 | |
| 21 | + beego.Router(prefix+"/cardholder/shopexchange", &controllers.CardHolderController{}, "post:ShopExchange") | |
| 20 | 22 | |
| 21 | 23 | beego.ErrorController(&controllers.ErrorController{}) |
| 22 | 24 | } | ... | ... |
service/cardholder/config.go
| ... | ... | @@ -117,6 +117,6 @@ type CardSequenceConfig struct { |
| 117 | 117 | type StarShopConfig struct { |
| 118 | 118 | Id int `json:"id"` // ID |
| 119 | 119 | StarNumber int `json:"star_number"` // 需求星星数 |
| 120 | - CardholderId []int `json:"cardholder_id"` // 可换取的卡包ID // todo 要重命名 | |
| 120 | + CardholderId []int `json:"cardholder_id"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量} // todo 要重命名 | |
| 121 | 121 | AlbumId int `json:"album_id"` // 对应卡册活动ID // todo 要重命名 |
| 122 | 122 | } | ... | ... |
service/cardholder/handle.go
| ... | ... | @@ -3,6 +3,7 @@ package cardholder |
| 3 | 3 | import ( |
| 4 | 4 | "apigame/models" |
| 5 | 5 | "apigame/service/constd" |
| 6 | + "apigame/util/util-lx/lxalilog" | |
| 6 | 7 | "apigame/util/util-lx/lxtime" |
| 7 | 8 | "apigame/util/uttype" |
| 8 | 9 | "strconv" |
| ... | ... | @@ -89,18 +90,130 @@ func HandleOpen(req *models.ReqCardHolderOpen) (code string, rsp models.RspCardH |
| 89 | 90 | } |
| 90 | 91 | |
| 91 | 92 | // 开始处理抽卡 |
| 93 | + openMode := 0 | |
| 92 | 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 | 98 | sequenceId, cohort, |
| 96 | - 0) | |
| 99 | + openMode) | |
| 97 | 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 | 211 | rsp.AwardAlbum = awardAlbum |
| 99 | 212 | rsp.AwardRound = awardRound |
| 100 | 213 | |
| 101 | 214 | // 计算星星点数 |
| 102 | 215 | CalculateStarCount(gameData, config) |
| 103 | - | |
| 216 | + | |
| 104 | 217 | // 存档 |
| 105 | 218 | SaveData(req.GameID, gameData) |
| 106 | 219 | ... | ... |
service/cardholder/logic.go
| ... | ... | @@ -177,11 +177,9 @@ func DoOpen(gameId string, |
| 177 | 177 | config *CardActivityConfig, |
| 178 | 178 | confCardholder OpenCardholderConfig, |
| 179 | 179 | sequenceId, cohort string, |
| 180 | - openMode int) (newCards []int, awardAlbum map[int]string, awardRound string) { | |
| 180 | + openMode int) (newCards []int) { | |
| 181 | 181 | |
| 182 | 182 | newCards = make([]int, 0) |
| 183 | - awardAlbum = make(map[int]string) | |
| 184 | - awardRound = "" | |
| 185 | 183 | |
| 186 | 184 | if confCardholder.IsNew != 0 { |
| 187 | 185 | // 如果是新卡包 按顺序查找数目最少的一张卡抽取 |
| ... | ... | @@ -233,6 +231,20 @@ func DoOpen(gameId string, |
| 233 | 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 | 248 | if openMode == 0 || openMode == 1 { |
| 237 | 249 | // 根据新获得卡牌列表 判断 触发的卡组奖励列表 |
| 238 | 250 | for _, cardId := range newCards { |
| ... | ... | @@ -298,7 +310,7 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig |
| 298 | 310 | } |
| 299 | 311 | // 1. 普卡 :卡的等级数=可累计 的星星数 |
| 300 | 312 | // 2. 金币: 卡的等级数+1=可累计 的星星数 |
| 301 | - if confCard.IsGold != 0 { | |
| 313 | + if confCard.IsGold == 1 { | |
| 302 | 314 | starCount += (cardCount - 1) * (confCard.Star + 1) |
| 303 | 315 | } else { |
| 304 | 316 | starCount += (cardCount - 1) * confCard.Star |
| ... | ... | @@ -306,3 +318,72 @@ func CalculateStarCount(gameData *dto.CardHolderData, config *CardActivityConfig |
| 306 | 318 | } |
| 307 | 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 | 40 | RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR = "2051" |
| 41 | 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 | 52 | var recodeText = map[string]string{ |
| ... | ... | @@ -91,17 +87,13 @@ var recodeText = map[string]string{ |
| 91 | 87 | RECODE_MERGE_TONGXINGZHENGBUCUNZAI_ERROR: "通行证不存在", |
| 92 | 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 | 99 | func RecodeText(code string) string { | ... | ... |