actor.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package order
  2. import (
  3. "f1-game/internal/code"
  4. "f1-game/internal/component/redis"
  5. "f1-game/internal/data"
  6. "f1-game/internal/enum"
  7. nameActor "f1-game/internal/name/actor"
  8. nameRemote "f1-game/internal/name/remote"
  9. "f1-game/internal/pb"
  10. "f1-game/nodes/pay/internal/db"
  11. "sync/atomic"
  12. "time"
  13. cherryString "github.com/cherry-game/cherry/extend/string"
  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. "github.com/cherry-game/cherry/net/parser/pomelo"
  18. )
  19. type actor struct {
  20. pomelo.ActorBase
  21. size int64 //
  22. isLoading int32 //
  23. autoPay bool // 读取settings配置,是否自动充值
  24. }
  25. func NewActor(size int) *actor {
  26. return &actor{
  27. size: int64(size),
  28. }
  29. }
  30. func (p *actor) AliasID() string {
  31. return nameActor.Order
  32. }
  33. func (p *actor) OnInit() {
  34. p.autoPay = p.App().Settings().GetBool("auto_pay", false)
  35. p.Remote().Register(nameRemote.Order_Create, p.create)
  36. p.Remote().Register(nameRemote.Order_Payment, p.payment)
  37. p.Timer().Add(10*time.Minute, func() {
  38. p.loadPaymentOrders()
  39. }, true)
  40. // create child deliver actor
  41. for i := int64(0); i < p.size; i++ {
  42. p.Child().Create(cstring.ToString(i), &actorDeliver{})
  43. }
  44. p.loadPaymentOrders()
  45. }
  46. // create 创建订单 pay-1.order.create
  47. func (p *actor) create(req *pb.CreateOrder) (*pb.I64, int32) {
  48. rsp := &pb.I64{}
  49. if req.Extra == nil {
  50. req.Extra = make(map[string]string)
  51. }
  52. sdkRow := data.SDK.Get(req.PID)
  53. if sdkRow == nil {
  54. return rsp, code.PIDError
  55. }
  56. if cherryString.ToInt32D(req.GameNodeID, 0) < 1 {
  57. return rsp, code.PlayerOrderCreateFail
  58. }
  59. if req.UID < 1 || req.PlayerID < 1 || req.ChargeID < 1 || req.Amount < 1 {
  60. return rsp, code.PlayerOrderCreateFail
  61. }
  62. //TODO RechargeId/Money 读取配表判断是否正确
  63. rsp.Value = redis.GUID.NewGUID()
  64. table := &db.OrderTable{
  65. OrderID: rsp.Value,
  66. PID: req.PID,
  67. SdkOrderID: "",
  68. UID: req.UID,
  69. GameNodeID: req.GameNodeID,
  70. PlayerID: req.PlayerID,
  71. ChargeID: req.ChargeID,
  72. Money: req.Amount,
  73. Status: enum.OrderStatusCreate,
  74. ClientOS: req.ClientOS,
  75. CreateTime: ctime.Now().ToMillisecond(),
  76. CreateIP: req.Ip,
  77. DayTotal: ctime.Now().ToShortIntDateFormat(),
  78. PaymentTime: 0,
  79. DeliverTime: 0,
  80. PayNodeID: p.App().NodeID(), //记录当前节点id
  81. Origin: 0,
  82. Extra: req.Extra,
  83. }
  84. db.OrderCreate(table)
  85. if p.autoPay {
  86. // 如果开启自动充值, 则订单状态设置为[已支付],并自动发货
  87. table.Status = enum.OrderStatusPayment
  88. table.Save2Queue()
  89. p.deliver2Child(table)
  90. }
  91. clog.Infof("[create] orderID = %d, playerID = %d, gameNodeID = %d, status = %d, amount =%v, chargeID =%d, extra = %v",
  92. table.OrderID,
  93. table.PlayerID,
  94. table.GameNodeID,
  95. table.Status,
  96. table.Money,
  97. table.ChargeID,
  98. table.Extra,
  99. )
  100. return rsp, code.OK
  101. }
  102. // payment 更新支付订单 pay.order.payment
  103. func (p *actor) payment(req *pb.UpdateOrder) int32 {
  104. if req.OrderID < 1 {
  105. return code.DataNotFound
  106. }
  107. table := db.GetOrderWithID(req.OrderID)
  108. if table == nil {
  109. clog.Warnf("order not found. req = %s", req)
  110. return code.DataNotFound
  111. }
  112. if table.Status >= enum.OrderStatusPayment {
  113. clog.Warnf("duplicate pay request. req = %s", req)
  114. return code.OK
  115. }
  116. if req.CheckAmount && table.Money != req.Amount {
  117. clog.Warnf("amount error. money = %v, req = %s", table.Money, req)
  118. return code.DataNotFound
  119. }
  120. table.SdkOrderID = req.SdkOrderID
  121. table.PaymentTime = ctime.Now().ToMillisecond()
  122. table.Status = enum.OrderStatusPayment
  123. table.Origin = req.Origin
  124. table.Save2Queue()
  125. // 订单转发到订单派发actor
  126. p.deliver2Child(table)
  127. return code.OK
  128. }
  129. // deliver
  130. func (p *actor) deliver2Child(table *db.OrderTable) {
  131. if table == nil {
  132. return
  133. }
  134. childID := table.OrderID % p.size
  135. targetPath := p.NewMyChildPath(childID)
  136. p.Call(targetPath, nameRemote.Order_Deliver, table)
  137. }
  138. // loadPaymentOrders 加载7天内已支付未发货的订单
  139. func (p *actor) loadPaymentOrders() {
  140. if p.isLoading > 0 {
  141. return
  142. }
  143. atomic.StoreInt32(&p.isLoading, 1)
  144. orderIDList := db.PaymentOrderIDList(p.App().NodeID(), 7)
  145. for _, orderID := range orderIDList {
  146. orderTable := db.GetOrderWithID(orderID)
  147. p.deliver2Child(orderTable)
  148. }
  149. atomic.StoreInt32(&p.isLoading, 0)
  150. }