package order import ( "f1-game/internal/code" "f1-game/internal/component/redis" "f1-game/internal/data" "f1-game/internal/enum" nameActor "f1-game/internal/name/actor" nameRemote "f1-game/internal/name/remote" "f1-game/internal/pb" "f1-game/nodes/game/internal/db" "sync/atomic" "time" cstring "github.com/cherry-game/cherry/extend/string" ctime "github.com/cherry-game/cherry/extend/time" clog "github.com/cherry-game/cherry/logger" "github.com/cherry-game/cherry/net/parser/pomelo" ) type actor struct { pomelo.ActorBase size int64 // isLoading int32 // autoPay bool // 读取settings配置,是否自动充值 } func NewActor(size int) *actor { return &actor{ size: int64(size), } } func (p *actor) AliasID() string { return nameActor.Order } func (p *actor) OnInit() { p.autoPay = p.App().Settings().GetBool("auto_pay", false) p.Remote().Register(nameRemote.Order_Create, p.create) p.Remote().Register(nameRemote.Order_Payment, p.payment) p.Timer().Add(10*time.Minute, func() { p.loadPaymentOrders() }, true) // create child deliver actor for i := int64(0); i < p.size; i++ { p.Child().Create(cstring.ToString(i), &actorDeliver{}) } p.loadPaymentOrders() } // create 创建订单 pay-1.order.create func (p *actor) create(req *pb.CreateOrder) (*pb.I64, int32) { rsp := &pb.I64{} if req.Extra == nil { req.Extra = make(map[string]string) } sdkRow := data.SDK.Get(req.PID) if sdkRow == nil { return rsp, code.PIDError } if cstring.ToInt32D(req.GameNodeID, 0) < 1 { return rsp, code.PlayerOrderCreateFail } if req.UID < 1 || req.PlayerID < 1 || req.ChargeID < 1 || req.Amount < 1 { return rsp, code.PlayerOrderCreateFail } //TODO RechargeId/Money 读取配表判断是否正确 rsp.Value = redis.GUID.NewGUID() table := &db.OrderTable{ OrderID: rsp.Value, PID: req.PID, SdkOrderID: "", UID: req.UID, GameNodeID: req.GameNodeID, PlayerID: req.PlayerID, ChargeID: req.ChargeID, Money: req.Amount, Status: enum.OrderStatusCreate, ClientOS: req.ClientOS, CreateTime: ctime.Now().ToMillisecond(), CreateIP: req.Ip, DayTotal: ctime.Now().ToShortIntDateFormat(), PaymentTime: 0, DeliverTime: 0, Origin: 0, Extra: req.Extra, } db.OrderCreate(table) if p.autoPay { // 如果开启自动充值, 则订单状态设置为[已支付],并自动发货 table.Status = enum.OrderStatusPayment table.Save2Queue() p.deliver2Child(table) } clog.Infof("[create] orderID = %d, playerID = %d, gameNodeID = %s, status = %d, amount =%v, chargeID =%d, extra = %v", table.OrderID, table.PlayerID, table.GameNodeID, table.Status, table.Money, table.ChargeID, table.Extra, ) return rsp, code.OK } // payment 更新支付订单 pay.order.payment func (p *actor) payment(req *pb.UpdateOrder) int32 { if req.OrderID < 1 { return code.DataNotFound } table := db.GetOrderWithID(req.OrderID) if table == nil { clog.Warnf("order not found. req = %s", req) return code.DataNotFound } if table.Status >= enum.OrderStatusPayment { clog.Warnf("duplicate pay request. req = %s", req) return code.OK } if req.CheckAmount && table.Money != req.Amount { clog.Warnf("amount error. money = %v, req = %s", table.Money, req) return code.DataNotFound } table.SdkOrderID = req.SdkOrderID table.PaymentTime = ctime.Now().ToMillisecond() table.Status = enum.OrderStatusPayment table.Origin = req.Origin table.Save2Queue() // 订单转发到订单派发actor p.deliver2Child(table) return code.OK } // deliver func (p *actor) deliver2Child(table *db.OrderTable) { if table == nil { return } childID := table.OrderID % p.size targetPath := p.NewMyChildPath(childID) p.Call(targetPath, nameRemote.Order_Deliver, table) } // loadPaymentOrders 加载7天内已支付未发货的订单 func (p *actor) loadPaymentOrders() { if p.isLoading > 0 { return } atomic.StoreInt32(&p.isLoading, 1) orderIDList := db.PaymentOrderIDList(p.App().NodeID(), 7) for _, orderID := range orderIDList { orderTable := db.GetOrderWithID(orderID) p.deliver2Child(orderTable) } atomic.StoreInt32(&p.isLoading, 0) }