package handler import ( "encoding/json" "fmt" "os" "strconv" "time" "bet24.com/log" "bet24.com/servers/common" platformconfig "bet24.com/servers/micros/platformconfig/proto" "bet24.com/servers/micros/userservices/handler/mail" userservices "bet24.com/servers/micros/userservices/proto" ) var transMgr *transferManager const config_key = "money_transferconfig" const refresh_config_sec = 1800 func getTransferManager() *transferManager { if transMgr == nil { transMgr = new(transferManager) transMgr.ctor() } return transMgr } type transferManager struct { GoldConfig GoldTransferConfig configString string } func (tm *transferManager) ctor() { log.Debug("transferManager.ctor") tm.readConf() } func (tm *transferManager) readConf() { time.AfterFunc(time.Second*refresh_config_sec, tm.readConf) configString := platformconfig.GetConfig(config_key) if configString == "" { data, err := os.ReadFile(fmt.Sprintf("serviceconf/%s.json", config_key)) if err != nil { log.Release("transferManager.loadData read config failed") return } configString = string(data) if configString != "" { platformconfig.SetConfig(config_key, configString) } } if configString == tm.configString { return } tm.configString = configString // 读取配置 err := json.Unmarshal([]byte(configString), &tm) if err != nil { log.Release("transferManager.loadData Unmarshal failed %s", configString) } } func (tm *transferManager) dump(param1, param2 string) { log.Release("-------------------------------") log.Release("transferManager.dump %s,%s", param1, param2) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() if param1 == "count" { getTransferCountMgr().dump(param2) return } if param1 == "user" { var userId int var err error userId, err = strconv.Atoi(param2) if err != nil { log.Release("invalid userId") return } log.Release(tm.getGoldTransferConfig(userId)) return } log.Release(tm.configString) } func (tm *transferManager) transferGold(userId int, toUserId int, amount int, ipAddress string) (ok bool, errorMsg string) { // 不能赠送给自己 if userId == toUserId { errorMsg = "Can't give it to yourself" return } if tm.GoldConfig.DailyTransferCount == 0 { errorMsg = "Transfer not open" log.Release("transferManager.transferGold Transfer not open") return } // 用户是否存在 usr := userservices.GetUserInfo(userId) if usr == nil { errorMsg = "User not exist" log.Release("transferManager.transferGold userId[%d] not exist", userId) return } if userservices.IsBlackList(userId) { log.Release("transferManager.transferGold userId[%d] blacklist", userId) return } // 接收用户 toUsr := userservices.GetUserInfo(toUserId) if toUsr == nil { errorMsg = "Target User not exist" log.Release("transferManager.transferGold toUserId[%d] not exist", toUserId) return } if amount < tm.GoldConfig.MinAmount { ok = false errorMsg = "Invalid Amount" log.Release("transferManager.transferGold userId[%d] amount[%d]%d]>Gold[%d]Reserved[%d]", userId, amount, reduceAmount, usr.Gold, tm.GoldConfig.ReservedAmount) return } // 判断我的次数 if !tm.checkGoldTransferCount(userId) { ok = false errorMsg = "Daily Transfer Limited" return } // 先扣减金币 retCode := cash.reduceMoney(userId, reduceAmount, common.LOGTYPE_TRANSFER_CONSUME, "cash", "transfer", ipAddress) if retCode != 1 { ok = false errorMsg = "Failed to deduct gold coins" return } // 加金币 cash.giveMoney(toUserId, amount, common.LOGTYPE_TRANSFER_ADD, "cash", "transfer", ipAddress) // 添加转账记录 cash.addTransferLog(usr.UserId, usr.NickName, toUsr.UserId, toUsr.NickName, amount, reduceAmount-amount, ipAddress) // TODO:发送邮件通知 go mail.SendSysMail(toUserId, &userservices.SysMail{ Id: 0, Title: tm.GoldConfig.MailTitle, Content: fmt.Sprintf(tm.GoldConfig.MailContent, amount, usr.NickName, userId), Status: 0, SourceName: tm.GoldConfig.MailSource, Crdate: common.GetTimeStamp(), Tools: nil, }) // 转账成功,增加当日次数 getTransferCountMgr().addTransferCount(userId) go userservices.UpdateUserInfo(userId) ok = true return } func (tm *transferManager) checkGoldTransferCount(userId int) bool { if tm.GoldConfig.DailyTransferCount < 0 || userservices.IsWhiteList(userId) { return true } totalCount := tm.GoldConfig.DailyTransferCount + userservices.GetUserPrivilegeValue(userId, userservices.VipPrivilege_ExtraGoldTransferCount) if totalCount <= 0 { return false } return getTransferCountMgr().getTransferCount(userId) < totalCount } func (tm *transferManager) getGoldTransferLog(userId int) string { type transferLog struct { UserId int // 对方用户ID NickName string // 对方昵称 FaceUrl string FaceId int Amount int // 大于0接收,小于0赠送 Crdate string } var ret []transferLog logs := cashTransferLog(userId, 30) for _, v := range logs { var tl transferLog if v.UserID == userId { // 赠送 tl.Amount = -v.Amount tl.UserId = v.AcceptUserID tl.NickName = v.AcceptNickName } else { // 接收 tl.Amount = v.Amount tl.UserId = v.UserID tl.NickName = v.NickName } toUser := userservices.GetUserInfo(tl.UserId) if toUser == nil { log.Debug("transferManager.getGoldTransferLog userId[%d] not exist", tl.UserId) } else { tl.NickName = toUser.NickName tl.FaceId = toUser.FaceId tl.FaceUrl = toUser.FaceUrl } tl.Crdate = v.Crdate ret = append(ret, tl) } d, _ := json.Marshal(ret) return string(d) } func (tm *transferManager) getGoldTransferConfig(userId int) string { if tm.GoldConfig.DailyTransferCount == 0 { return "" } // 用户是否存在 usr := userservices.GetUserInfo(userId) if usr == nil { log.Release("transferManager.transferGold userId[%d] not exist", userId) return "" } if userservices.IsBlackList(userId) { log.Release("transferManager.transferGold userId[%d] blacklist", userId) return "" } var info UserGoldTransferConfig info.MinAmount = tm.GoldConfig.MinAmount info.TaxRate = tm.GoldConfig.TaxRate info.MaxAmount = (usr.Gold - tm.GoldConfig.ReservedAmount) * 100 / (100 + tm.GoldConfig.TaxRate) if info.MaxAmount < info.MinAmount { info.MaxAmount = 0 } if tm.GoldConfig.DailyTransferCount > 0 { if userservices.IsWhiteList(userId) { info.TotalCount = 999 } else { info.TotalCount = tm.GoldConfig.DailyTransferCount + userservices.GetUserPrivilegeValue(userId, userservices.VipPrivilege_ExtraGoldTransferCount) info.UsedCount = getTransferCountMgr().getTransferCount(userId) } } else { info.TotalCount = 999 } d, _ := json.Marshal(info) return string(d) }