service.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package exchange
  2. import (
  3. actorRemote "f1-game/internal/actor_remote"
  4. "f1-game/internal/component/redis"
  5. "f1-game/internal/constant"
  6. "f1-game/internal/data"
  7. "f1-game/internal/enum"
  8. "f1-game/internal/extend/math"
  9. facade "f1-game/internal/facade"
  10. "f1-game/internal/pb"
  11. "f1-game/internal/types"
  12. "f1-game/nodes/map/internal/db"
  13. csnowflake "github.com/cherry-game/cherry/extend/snowflake"
  14. cstring "github.com/cherry-game/cherry/extend/string"
  15. ctime "github.com/cherry-game/cherry/extend/time"
  16. clog "github.com/cherry-game/cherry/logger"
  17. )
  18. var srv = &service{}
  19. func Service() *service {
  20. return srv
  21. }
  22. type service struct {
  23. facade.PlayerServiceBase[*db.MapPlayerTable]
  24. }
  25. func (p *service) OnReset(playerTable *db.MapPlayerTable, time *ctime.CherryTime, byLogin bool) {
  26. playerTable.Exchange.Reset()
  27. playerTable.Save2Queue()
  28. }
  29. // 给买方发货
  30. func (p *service) DeliverToBuyer(playerID int64, req *pb.PlayerExchangeItemDeliver) {
  31. var (
  32. transID = req.TransID // 流水号
  33. goodsID = req.GoodsID // 商品ID
  34. buyCount = req.Count // 购买数量
  35. itemPrice = req.Price // 物品单价
  36. wishPrice = req.WishPrice // 求购单价
  37. mapPlayerTable = db.GetMapPlayerTable(playerID)
  38. exchangeGoodsRow, _ = data.ExchangeGoods.GetByID(goodsID)
  39. )
  40. // 总价
  41. sumPrice := buyCount * int64(itemPrice)
  42. // 交易物品ID
  43. itemID := exchangeGoodsRow.ItemID
  44. // 以邮件的方式发货
  45. buyAssets := types.Assets{}
  46. // 如果是需要转成绑定资源就转成绑定资源
  47. bindingItemID, ok := enum.UnBindingResourceMap[goodsID]
  48. if ok {
  49. goodsID = bindingItemID
  50. }
  51. buyAsset := types.NewAsset(goodsID, buyCount*int64(exchangeGoodsRow.UnitQty))
  52. buyAssets.AddAsset(&buyAsset)
  53. // 求购差价
  54. sumWishDiffPrice := int64(0)
  55. mailID := constant.MailID_MapExchangeBuySuccess
  56. mailParams := []string{
  57. cstring.ToString(itemID),
  58. cstring.ToString(sumPrice),
  59. cstring.ToString(buyAsset.ID),
  60. cstring.ToString(buyAsset.Num),
  61. }
  62. // 求购购买的方式
  63. if wishPrice > 0 {
  64. // 记录求购成功的次数
  65. mapPlayerTable.Exchange.DailyWishCount++
  66. mapPlayerTable.Save2Queue()
  67. // 单个单位的差价
  68. wishDiffPrice := wishPrice - itemPrice
  69. if wishDiffPrice > 0 {
  70. sumWishDiffPrice = buyCount * int64(wishDiffPrice)
  71. // 返还求购差价
  72. buyAssets.Add(itemID, sumWishDiffPrice)
  73. }
  74. mailID = constant.MailID_MapExchangeWishSuccess
  75. mailParams = []string{
  76. cstring.ToString(itemID),
  77. cstring.ToString(sumPrice),
  78. cstring.ToString(buyAsset.ID),
  79. cstring.ToString(buyAsset.Num),
  80. cstring.ToString(sumWishDiffPrice),
  81. }
  82. }
  83. actorRemote.GameMail.SendMail(mapPlayerTable.GameNodeID, playerID, mailID, buyAssets, mailParams)
  84. // 交易的商品信息
  85. buyGoodsAsset := types.NewAsset(goodsID, buyCount)
  86. exchangeLog := &pb.ExchangeLog{
  87. LogID: csnowflake.NextID(),
  88. LogType: int32(enum.ExchangeLogType_Buy),
  89. Asset: buyGoodsAsset.ToProto(),
  90. Price: itemPrice,
  91. Time: ctime.Now().ToMillisecond(),
  92. }
  93. redis.Game.AddMapExchangeLog(mapPlayerTable.NodeID, playerID, enum.ExchangeLogType_Buy, int64(data.Const.ExchangeBuyLogSaveLimit), exchangeLog)
  94. clog.Infof("DeliverToBuyer success. playerID [%d], transID [%s], goodsID [%d], buyGoodsID [%d], itemID [%d], itemPrice [%d], sumPrice [%d], buyAssets [%+v], buyCount [%d], wishPrice [%d], sumWishDiffPrice [%d]",
  95. playerID, transID, exchangeGoodsRow.ID, goodsID, itemID, itemPrice, sumPrice, buyAssets, buyCount, wishPrice, sumWishDiffPrice)
  96. }
  97. // 给卖方发货
  98. func (p *service) DeliverToSeller(playerID int64, req *pb.PlayerExchangeItemDeliver) {
  99. var (
  100. transID = req.TransID
  101. goodsID = req.GoodsID
  102. mapPlayerTable = db.GetMapPlayerTable(playerID)
  103. sellCount = req.Count // 出售数量
  104. itemPrice = req.Price // 物品单价
  105. exchangeGoodsRow, _ = data.ExchangeGoods.GetByID(goodsID)
  106. )
  107. // 交易物品ID
  108. itemID := exchangeGoodsRow.ItemID
  109. // 最低手续费
  110. minFee := exchangeGoodsRow.MinFee
  111. // 总价
  112. sumPrice := int32(sellCount) * itemPrice
  113. // 单价手续费 %
  114. feeRate := float32(exchangeGoodsRow.FeeRate)
  115. // 按照公式计算手续费
  116. fee := math.Floor[float32, int32](float32(itemPrice) * feeRate / constant.PctBase * float32(sellCount))
  117. fee = math.Max(fee, minFee)
  118. // 剩余的交易收益
  119. remain := max(sumPrice-fee, 0)
  120. if remain < 1 {
  121. clog.Warnf("DeliverToSeller failed. playerID [%d], transID [%s], goodsID [%d], sumPrice [%d], fee [%d], remain [%d]",
  122. playerID, transID, goodsID, sumPrice, fee, remain)
  123. return
  124. }
  125. // 以邮件的方式发货
  126. sellAssets := types.Assets{}
  127. sellAssets.Add(itemID, int64(remain))
  128. // 总资源数量
  129. sumSellCount := sellCount * int64(exchangeGoodsRow.UnitQty)
  130. mailParams := []string{
  131. cstring.ToString(goodsID),
  132. cstring.ToString(sumSellCount),
  133. cstring.ToString(itemID),
  134. cstring.ToString(remain),
  135. }
  136. actorRemote.GameMail.SendMail(mapPlayerTable.GameNodeID, playerID, constant.MailID_MapExchangeSellSuccess, sellAssets, mailParams)
  137. // 交易的商品信息
  138. sellGoodsAsset := types.NewAsset(goodsID, sellCount)
  139. exchangeLog := &pb.ExchangeLog{
  140. LogID: csnowflake.NextID(),
  141. LogType: int32(enum.ExchangeLogType_Sell),
  142. Asset: sellGoodsAsset.ToProto(),
  143. Price: itemPrice,
  144. Fee: fee,
  145. Time: ctime.Now().ToMillisecond(),
  146. }
  147. redis.Game.AddMapExchangeLog(mapPlayerTable.NodeID, playerID, enum.ExchangeLogType_Sell, int64(data.Const.ExchangeSellLogSaveLimit), exchangeLog)
  148. clog.Infof("DeliverToSeller success. playerID [%d], transID [%s], goodsID [%d], itemID [%d], itemPrice [%d], sumPrice [%d], sellAssets [%+v], buyCount [%d], fee [%d]",
  149. playerID, transID, goodsID, itemID, itemPrice, sumPrice, sellAssets, sellCount, fee)
  150. }