| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- package exchange
- import (
- "encoding/json"
- "fmt"
- "sort"
- "sync"
- "bet24.com/log"
- "bet24.com/servers/common"
- "bet24.com/servers/coreservice/bet"
- "bet24.com/servers/coreservice/client"
- "bet24.com/servers/coreservice/serviceconfig"
- "bet24.com/servers/coreservice/teacher"
- inventory "bet24.com/servers/micros/item_inventory/proto"
- item "bet24.com/servers/micros/item_inventory/proto"
- cash "bet24.com/servers/micros/money/proto"
- vip "bet24.com/servers/micros/userservices/proto"
- )
- func newExchangeManager() *exchangemgr {
- em := new(exchangemgr)
- em.lock = &sync.RWMutex{}
- go em.loadInfo()
- log.Debug("exchange.Run")
- return em
- }
- type exchangemgr struct {
- exchangeList map[int]ExchangeInfo
- lock *sync.RWMutex
- }
- func (em *exchangemgr) loadInfo() {
- em.exchangeList = make(map[int]ExchangeInfo)
- // 去数据库读取可兑换列表
- list := trans_loadExchangeList()
- for _, v := range list {
- em.exchangeList[v.Id] = v
- }
- }
- func (em *exchangemgr) getExchangeType() []ExchangeType {
- var ret []ExchangeType
- for _, v := range em.exchangeList {
- ret = append(ret, ExchangeType{
- Id: v.Id,
- ExchangeType: v.ExchangeType,
- Price: v.Price,
- Memo: v.Memo,
- })
- }
- sort.SliceStable(ret, func(i, j int) bool {
- return ret[i].Memo < ret[j].Memo
- })
- sort.SliceStable(ret, func(i, j int) bool {
- return ret[i].Price < ret[j].Price
- })
- return ret
- }
- func (em *exchangemgr) getExchangeList(userId int) []ExchangeInfo {
- var ret []ExchangeInfo
- // 这里用户ID待过滤
- // 需要从数据库中查询兑换记录,去除已兑换过的选项
- _, history := trans_getExchangeHistory(userId, 0, 1, 1000000)
- removeList := make(map[int]int)
- for _, v := range history {
- e := em.getExchange(v.ExchangeId)
- // 兑换数据不存在
- if e.Id <= 0 {
- removeList[v.ExchangeId] = 1
- continue
- }
- // 只兑换一次
- if e.LimitOnce {
- removeList[v.ExchangeId] = 1
- continue
- }
- }
- gameCount := 0
- // 获取游戏局数
- list := bet.GetGameCount(userId, 0)
- for _, v := range list {
- gameCount += v.TotalCount
- }
- // 判断vip
- userVip := vip.GetUserVipInfo(userId)
- vipLevel := 0
- if userVip != nil && userVip.IsVip() {
- vipLevel = userVip.Level
- }
- for _, v := range em.exchangeList {
- if _, ok := removeList[v.Id]; ok {
- continue
- }
- if vipLevel < v.VipShow {
- continue
- }
- // 判断局数
- if gameCount < v.GameCountShow {
- continue
- }
- ret = append(ret, v)
- }
- sort.SliceStable(ret, func(i, j int) bool {
- return ret[i].Id < ret[j].Id
- })
- return ret
- }
- // 获取收益类型 (1=绑码 2=充值 3=兑换 4=提现)
- func (em *exchangemgr) getProfitType(exchangeType int) int {
- profitType := 0
- switch exchangeType {
- case EXCHANGE_TYPE_FUKA:
- // 什么都不做
- case EXCHANGE_TYPE_TEACHER_CASH:
- fallthrough
- case EXCHANGE_TYPE_TEACHER_TEL:
- profitType = 3 // 兑换
- case EXCHANGE_TYPE_TEACHER_CHIP:
- profitType = 4 // 提现
- }
- return profitType
- }
- func (em *exchangemgr) getExchange(exchangeId int) ExchangeInfo {
- em.lock.RLock()
- defer em.lock.RUnlock()
- e, ok := em.exchangeList[exchangeId]
- if !ok {
- return ExchangeInfo{}
- }
- return e
- }
- func (em *exchangemgr) userExchange(userId, exchangeId, num int, remark string) (int, string) {
- e := em.getExchange(exchangeId)
- if e.Id <= 0 {
- log.Debug("exchangemgr.userExchange %d not found", exchangeId)
- return -3, ""
- }
- //先判断vip
- userVip := vip.GetUserVipInfo(userId)
- vipLevel := 0
- if userVip != nil && userVip.IsVip() {
- vipLevel = userVip.Level
- }
- if vipLevel < e.VipNeed {
- return -5, "Vip等级不够"
- }
- //限制购买1次
- if e.LimitOnce {
- if _, history := trans_getExchangeHistory(userId, exchangeId, 1, 1000000); len(history) > 0 {
- return -6, "已经购买过"
- }
- }
- //剩余数量
- if e.LeftCount <= 0 {
- return -7, "库存不足"
- }
- //道具无效
- if len(e.Items) <= 0 {
- log.Error("exchangemgr.userExchange UserId=%d exchangeId=%d num=%d info=%+v",
- userId, exchangeId, num, e)
- return -3, ""
- }
- price := e.Price * num
- if price <= 0 {
- log.Error("exchangemgr.userExchange UserId=%d exchangeId=%d num=%d info=%+v",
- userId, exchangeId, num, e)
- return -3, ""
- }
- // 提现需要判断最低提现金额
- if e.ExchangeType == EXCHANGE_TYPE_TEACHER_CASH && price < serviceconfig.Server.MinWithdraw {
- return -4, fmt.Sprintf("提取金额必须大于%d", serviceconfig.Server.MinWithdraw)
- }
- success, msg := false, ""
- //获取道具
- tool := item.GetItem(e.Items[0].ItemId)
- if tool == nil {
- log.Error("exchangemgr.userExchange UserId=%d exchangeId=%d num=%d info=%+v",
- userId, exchangeId, num, e)
- return -1, "无效道具"
- }
- // 物品*数量
- if num > 1 {
- for i := 0; i < len(e.Items); i++ {
- e.Items[i].Count = e.Items[i].Count * num
- }
- }
- switch e.ExchangeType {
- case EXCHANGE_TYPE_FUKA: // 扣减奖券
- logType := 0
- switch tool.Type {
- case item.Item_Gold: // 兑换金币
- logType = common.LOGTYPE_EXCHANGE_TOGOLD
- case item.Item_Addminutes: // 兑换话费
- logType = common.LOGTYPE_EXCHANGE_TOTEL
- case item.Item_Cash: // 兑换cash
- logType = common.LOGTYPE_EXCHANGE_TOCASH
- }
- success, msg = inventory.Consume(userId, 620100, logType, price, 0)
- if !success {
- log.Debug("exchangemgr.userExchange UserId=%d exchangeId=%d success=%v num=%d msg=%s info=%+v",
- userId, exchangeId, success, num, msg, e)
- return -1, "扣减福卡失败"
- }
- case EXCHANGE_TYPE_TEACHER_CHIP: // 代理收益兑元宝
- fallthrough
- case EXCHANGE_TYPE_TEACHER_TEL: // 代理收益兑话费
- fallthrough
- case EXCHANGE_TYPE_TEACHER_CASH: // 代理收益兑RP
- profitType := em.getProfitType(e.ExchangeType)
- if retCode := teacher.ReduceProfit(userId, price, profitType); retCode != 1 {
- log.Debug("exchangemgr.userExchange UserId=%d exchangeType=%d exchangeId=%d num=%d retCode=%v msg=%s info=%+v",
- userId, e.ExchangeType, exchangeId, num, retCode, msg, e)
- return retCode, "扣减收益失败"
- }
- case EXCHANGE_TYPE_GOLD: // 金币提现
- // 判断提现金额足购
- /*if !vip.TryWithdraw(userId, price, true) {
- log.Debug("exchangemgr.userExchange UserId=%d exchangeType=%d exchangeId=%d num=%d msg=%s info=%+v",
- userId, e.ExchangeType, exchangeId, num, msg, e)
- return -8, "不满足条件"
- }*/
- if !cash.ReduceMoney(userId, price, common.LOGTYPE_GOLD_EXCHANGE, "金币提现", "金币提现", "") {
- log.Debug("exchangemgr.userExchange UserId=%d exchangeType=%d exchangeId=%d price=%d num=%d info=%+v",
- userId, e.ExchangeType, exchangeId, price, num, e)
- return -1, "扣减金币失败"
- }
- //vip.TryWithdraw(userId, price, false)
- case EXCHANGE_TYPE_CASH: // 现金卡提现
- success, msg = inventory.Consume(userId, 14001, common.LOGTYPE_CASHCARD_TOCASH, price, 0)
- if !success {
- log.Debug("exchangemgr.userExchange UserId=%d exchangeId=%d success=%v num=%d msg=%s info=%+v",
- userId, exchangeId, success, num, msg, e)
- return -1, "扣减现金卡失败"
- }
- default:
- log.Error("exchange.userExchange UserId=%d exchangeId=%d exchangeType=%d num=%d info=%+v",
- userId, exchangeId, e.ExchangeType, num, e)
- return -3, ""
- }
- //剩余数量-1
- if e.LeftCount != 999999999 {
- e.LeftCount--
- em.lock.Lock()
- em.exchangeList[e.Id] = e
- em.lock.Unlock()
- //数据库更新数量
- if retCode := trans_updateExchange(e.Id, e.LeftCount); retCode != 1 {
- return -1, "兑换失败,请重试"
- }
- }
- //待发货
- status := 0
- msg = "兑换成功,客服将于3个工作日之内处理发货,详情请查阅兑换记录"
- if tool.Type != item.Item_Addminutes && tool.Type != item.Item_Physical && tool.Type != item.Item_GiftCard &&
- tool.Type != item.Item_Cash {
- //已发货
- status = 1
- msg = "兑换成功"
- }
- //物品
- items, _ := json.Marshal(e.Items)
- //兑换
- ret := trans_userExchange(userId, exchangeId, e.ExchangeType, price, status, string(items), remark)
- if !ret {
- return -2, "兑换失败,请联系客服"
- }
- //加道具
- inventory.AddItems(userId, e.Items, fmt.Sprintf("兑换[%d]", exchangeId), common.LOGTYPE_EXCHANGE)
- return 1, msg
- }
- func (em *exchangemgr) getExchangeHistory(userId, pageIndex, pageSize int) (int, []client.ExchangeHistory) {
- return trans_getExchangeHistory(userId, 0, pageIndex, pageSize)
- }
|