service.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. buyAsset := types.NewAsset(goodsID, buyCount*int64(exchangeGoodsRow.UnitQty))
  47. buyAssets.AddAsset(&buyAsset)
  48. // 求购差价
  49. sumWishDiffPrice := int64(0)
  50. mailID := constant.MailID_MapExchangeBuySuccess
  51. mailParams := []string{
  52. cstring.ToString(itemID),
  53. cstring.ToString(sumPrice),
  54. cstring.ToString(buyAsset.ID),
  55. cstring.ToString(buyAsset.Num),
  56. }
  57. // 求购购买的方式
  58. if wishPrice > 0 {
  59. // 记录求购成功的次数
  60. mapPlayerTable.Exchange.DailyWishCount++
  61. mapPlayerTable.Save2Queue()
  62. // 单个单位的差价
  63. wishDiffPrice := wishPrice - itemPrice
  64. if wishDiffPrice > 0 {
  65. sumWishDiffPrice = buyCount * int64(wishDiffPrice)
  66. // 返还求购差价
  67. buyAssets.Add(itemID, sumWishDiffPrice)
  68. }
  69. mailID = constant.MailID_MapExchangeWishSuccess
  70. mailParams = []string{
  71. cstring.ToString(itemID),
  72. cstring.ToString(sumPrice),
  73. cstring.ToString(buyAsset.ID),
  74. cstring.ToString(buyAsset.Num),
  75. cstring.ToString(sumWishDiffPrice),
  76. }
  77. }
  78. actorRemote.GameMail.SendMail(mapPlayerTable.GameNodeID, playerID, mailID, buyAssets, mailParams)
  79. // 交易的商品信息
  80. buyGoodsAsset := types.NewAsset(goodsID, buyCount)
  81. exchangeLog := &pb.ExchangeLog{
  82. LogID: csnowflake.NextID(),
  83. LogType: int32(enum.ExchangeLogType_Buy),
  84. Asset: buyGoodsAsset.ToProto(),
  85. Price: itemPrice,
  86. Time: ctime.Now().ToMillisecond(),
  87. }
  88. redis.Game.AddMapExchangeLog(mapPlayerTable.NodeID, playerID, enum.ExchangeLogType_Buy, int64(data.Const.ExchangeBuyLogSaveLimit), exchangeLog)
  89. clog.Infof("DeliverToBuyer success. playerID [%d], transID [%s], goodsID [%d], itemID [%d], itemPrice [%d], sumPrice [%d], buyAssets [%+v], buyCount [%d], wishPrice [%d], sumWishDiffPrice [%d]",
  90. playerID, transID, goodsID, itemID, itemPrice, sumPrice, buyAssets, buyCount, wishPrice, sumWishDiffPrice)
  91. }
  92. // 给卖方发货
  93. func (p *service) DeliverToSeller(playerID int64, req *pb.PlayerExchangeItemDeliver) {
  94. var (
  95. transID = req.TransID
  96. goodsID = req.GoodsID
  97. mapPlayerTable = db.GetMapPlayerTable(playerID)
  98. sellCount = req.Count // 出售数量
  99. itemPrice = req.Price // 物品单价
  100. exchangeGoodsRow, _ = data.ExchangeGoods.GetByID(goodsID)
  101. )
  102. // 交易物品ID
  103. itemID := exchangeGoodsRow.ItemID
  104. // 最低手续费
  105. minFee := exchangeGoodsRow.MinFee
  106. // 总价
  107. sumPrice := int32(sellCount) * itemPrice
  108. // 单价手续费 %
  109. feeRate := float32(exchangeGoodsRow.FeeRate)
  110. // 按照公式计算手续费
  111. fee := math.Floor[float32, int32](float32(itemPrice) * feeRate / constant.PctBase * float32(sellCount))
  112. fee = math.Max(fee, minFee)
  113. // 剩余的交易收益
  114. remain := max(sumPrice-fee, 0)
  115. if remain < 1 {
  116. clog.Warnf("DeliverToSeller failed. playerID [%d], transID [%s], goodsID [%d], sumPrice [%d], fee [%d], remain [%d]",
  117. playerID, transID, goodsID, sumPrice, fee, remain)
  118. return
  119. }
  120. // 以邮件的方式发货
  121. sellAssets := types.Assets{}
  122. sellAssets.Add(itemID, int64(remain))
  123. // 总资源数量
  124. sumSellCount := sellCount * int64(exchangeGoodsRow.UnitQty)
  125. mailParams := []string{
  126. cstring.ToString(goodsID),
  127. cstring.ToString(sumSellCount),
  128. cstring.ToString(itemID),
  129. cstring.ToString(remain),
  130. }
  131. actorRemote.GameMail.SendMail(mapPlayerTable.GameNodeID, playerID, constant.MailID_MapExchangeSellSuccess, sellAssets, mailParams)
  132. // 交易的商品信息
  133. sellGoodsAsset := types.NewAsset(goodsID, sellCount)
  134. exchangeLog := &pb.ExchangeLog{
  135. LogID: csnowflake.NextID(),
  136. LogType: int32(enum.ExchangeLogType_Sell),
  137. Asset: sellGoodsAsset.ToProto(),
  138. Price: itemPrice,
  139. Fee: fee,
  140. Time: ctime.Now().ToMillisecond(),
  141. }
  142. redis.Game.AddMapExchangeLog(mapPlayerTable.NodeID, playerID, enum.ExchangeLogType_Sell, int64(data.Const.ExchangeSellLogSaveLimit), exchangeLog)
  143. clog.Infof("DeliverToSeller success. playerID [%d], transID [%s], goodsID [%d], itemID [%d], itemPrice [%d], sumPrice [%d], sellAssets [%+v], buyCount [%d], fee [%d]",
  144. playerID, transID, goodsID, itemID, itemPrice, sumPrice, sellAssets, sellCount, fee)
  145. }