actor.go 4.1 KB

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