transfermanager.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package handler
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "time"
  8. "bet24.com/log"
  9. "bet24.com/servers/common"
  10. platformconfig "bet24.com/servers/micros/platformconfig/proto"
  11. "bet24.com/servers/micros/userservices/handler/mail"
  12. userservices "bet24.com/servers/micros/userservices/proto"
  13. )
  14. var transMgr *transferManager
  15. const config_key = "money_transferconfig"
  16. const refresh_config_sec = 1800
  17. func getTransferManager() *transferManager {
  18. if transMgr == nil {
  19. transMgr = new(transferManager)
  20. transMgr.ctor()
  21. }
  22. return transMgr
  23. }
  24. type transferManager struct {
  25. GoldConfig GoldTransferConfig
  26. configString string
  27. }
  28. func (tm *transferManager) ctor() {
  29. log.Debug("transferManager.ctor")
  30. tm.readConf()
  31. }
  32. func (tm *transferManager) readConf() {
  33. time.AfterFunc(time.Second*refresh_config_sec, tm.readConf)
  34. configString := platformconfig.GetConfig(config_key)
  35. if configString == "" {
  36. data, err := os.ReadFile(fmt.Sprintf("serviceconf/%s.json", config_key))
  37. if err != nil {
  38. log.Release("transferManager.loadData read config failed")
  39. return
  40. }
  41. configString = string(data)
  42. if configString != "" {
  43. platformconfig.SetConfig(config_key, configString)
  44. }
  45. }
  46. if configString == tm.configString {
  47. return
  48. }
  49. tm.configString = configString
  50. // 读取配置
  51. err := json.Unmarshal([]byte(configString), &tm)
  52. if err != nil {
  53. log.Release("transferManager.loadData Unmarshal failed %s", configString)
  54. }
  55. }
  56. func (tm *transferManager) dump(param1, param2 string) {
  57. log.Release("-------------------------------")
  58. log.Release("transferManager.dump %s,%s", param1, param2)
  59. defer func() {
  60. log.Release("+++++++++++++++++++++++++++++++")
  61. log.Release("")
  62. }()
  63. if param1 == "count" {
  64. getTransferCountMgr().dump(param2)
  65. return
  66. }
  67. if param1 == "user" {
  68. var userId int
  69. var err error
  70. userId, err = strconv.Atoi(param2)
  71. if err != nil {
  72. log.Release("invalid userId")
  73. return
  74. }
  75. log.Release(tm.getGoldTransferConfig(userId))
  76. return
  77. }
  78. log.Release(tm.configString)
  79. }
  80. func (tm *transferManager) transferGold(userId int, toUserId int, amount int, ipAddress string) (ok bool, errorMsg string) {
  81. // 不能赠送给自己
  82. if userId == toUserId {
  83. errorMsg = "Can't give it to yourself"
  84. return
  85. }
  86. if tm.GoldConfig.DailyTransferCount == 0 {
  87. errorMsg = "Transfer not open"
  88. log.Release("transferManager.transferGold Transfer not open")
  89. return
  90. }
  91. // 用户是否存在
  92. usr := userservices.GetUserInfo(userId)
  93. if usr == nil {
  94. errorMsg = "User not exist"
  95. log.Release("transferManager.transferGold userId[%d] not exist", userId)
  96. return
  97. }
  98. if userservices.IsBlackList(userId) {
  99. log.Release("transferManager.transferGold userId[%d] blacklist", userId)
  100. return
  101. }
  102. // 接收用户
  103. toUsr := userservices.GetUserInfo(toUserId)
  104. if toUsr == nil {
  105. errorMsg = "Target User not exist"
  106. log.Release("transferManager.transferGold toUserId[%d] not exist", toUserId)
  107. return
  108. }
  109. if amount < tm.GoldConfig.MinAmount {
  110. ok = false
  111. errorMsg = "Invalid Amount"
  112. log.Release("transferManager.transferGold userId[%d] amount[%d]<MinAmount[%d]",
  113. userId, amount, tm.GoldConfig.MinAmount)
  114. return
  115. }
  116. reduceAmount := amount * (100 + tm.GoldConfig.TaxRate) / 100
  117. // 判断金额
  118. if usr.Gold-tm.GoldConfig.ReservedAmount < reduceAmount {
  119. ok = false
  120. errorMsg = "Not Enough Amount"
  121. log.Release("transferManager.transferGold userId[%d] amount[%d->%d]>Gold[%d]Reserved[%d]",
  122. userId, amount, reduceAmount, usr.Gold, tm.GoldConfig.ReservedAmount)
  123. return
  124. }
  125. // 判断我的次数
  126. if !tm.checkGoldTransferCount(userId) {
  127. ok = false
  128. errorMsg = "Daily Transfer Limited"
  129. return
  130. }
  131. // 先扣减金币
  132. retCode := cash.reduceMoney(userId, reduceAmount, common.LOGTYPE_TRANSFER_CONSUME, "cash", "transfer", ipAddress)
  133. if retCode != 1 {
  134. ok = false
  135. errorMsg = "Failed to deduct gold coins"
  136. return
  137. }
  138. // 加金币
  139. cash.giveMoney(toUserId, amount, common.LOGTYPE_TRANSFER_ADD, "cash", "transfer", ipAddress)
  140. // 添加转账记录
  141. cash.addTransferLog(usr.UserId, usr.NickName,
  142. toUsr.UserId, toUsr.NickName,
  143. amount, reduceAmount-amount,
  144. ipAddress)
  145. // TODO:发送邮件通知
  146. go mail.SendSysMail(toUserId, &userservices.SysMail{
  147. Id: 0,
  148. Title: tm.GoldConfig.MailTitle,
  149. Content: fmt.Sprintf(tm.GoldConfig.MailContent, amount, usr.NickName, userId),
  150. Status: 0,
  151. SourceName: tm.GoldConfig.MailSource,
  152. Crdate: common.GetTimeStamp(),
  153. Tools: nil,
  154. })
  155. // 转账成功,增加当日次数
  156. getTransferCountMgr().addTransferCount(userId)
  157. go userservices.UpdateUserInfo(userId)
  158. ok = true
  159. return
  160. }
  161. func (tm *transferManager) checkGoldTransferCount(userId int) bool {
  162. if tm.GoldConfig.DailyTransferCount < 0 || userservices.IsWhiteList(userId) {
  163. return true
  164. }
  165. totalCount := tm.GoldConfig.DailyTransferCount + userservices.GetUserPrivilegeValue(userId, userservices.VipPrivilege_ExtraGoldTransferCount)
  166. if totalCount <= 0 {
  167. return false
  168. }
  169. return getTransferCountMgr().getTransferCount(userId) < totalCount
  170. }
  171. func (tm *transferManager) getGoldTransferLog(userId int) string {
  172. type transferLog struct {
  173. UserId int // 对方用户ID
  174. NickName string // 对方昵称
  175. FaceUrl string
  176. FaceId int
  177. Amount int // 大于0接收,小于0赠送
  178. Crdate string
  179. }
  180. var ret []transferLog
  181. logs := cashTransferLog(userId, 30)
  182. for _, v := range logs {
  183. var tl transferLog
  184. if v.UserID == userId { // 赠送
  185. tl.Amount = -v.Amount
  186. tl.UserId = v.AcceptUserID
  187. tl.NickName = v.AcceptNickName
  188. } else { // 接收
  189. tl.Amount = v.Amount
  190. tl.UserId = v.UserID
  191. tl.NickName = v.NickName
  192. }
  193. toUser := userservices.GetUserInfo(tl.UserId)
  194. if toUser == nil {
  195. log.Debug("transferManager.getGoldTransferLog userId[%d] not exist", tl.UserId)
  196. } else {
  197. tl.NickName = toUser.NickName
  198. tl.FaceId = toUser.FaceId
  199. tl.FaceUrl = toUser.FaceUrl
  200. }
  201. tl.Crdate = v.Crdate
  202. ret = append(ret, tl)
  203. }
  204. d, _ := json.Marshal(ret)
  205. return string(d)
  206. }
  207. func (tm *transferManager) getGoldTransferConfig(userId int) string {
  208. if tm.GoldConfig.DailyTransferCount == 0 {
  209. return ""
  210. }
  211. // 用户是否存在
  212. usr := userservices.GetUserInfo(userId)
  213. if usr == nil {
  214. log.Release("transferManager.transferGold userId[%d] not exist", userId)
  215. return ""
  216. }
  217. if userservices.IsBlackList(userId) {
  218. log.Release("transferManager.transferGold userId[%d] blacklist", userId)
  219. return ""
  220. }
  221. var info UserGoldTransferConfig
  222. info.MinAmount = tm.GoldConfig.MinAmount
  223. info.TaxRate = tm.GoldConfig.TaxRate
  224. info.MaxAmount = (usr.Gold - tm.GoldConfig.ReservedAmount) * 100 / (100 + tm.GoldConfig.TaxRate)
  225. if info.MaxAmount < info.MinAmount {
  226. info.MaxAmount = 0
  227. }
  228. if tm.GoldConfig.DailyTransferCount > 0 {
  229. if userservices.IsWhiteList(userId) {
  230. info.TotalCount = 999
  231. } else {
  232. info.TotalCount = tm.GoldConfig.DailyTransferCount + userservices.GetUserPrivilegeValue(userId, userservices.VipPrivilege_ExtraGoldTransferCount)
  233. info.UsedCount = getTransferCountMgr().getTransferCount(userId)
  234. }
  235. } else {
  236. info.TotalCount = 999
  237. }
  238. d, _ := json.Marshal(info)
  239. return string(d)
  240. }