package service import ( "context" "affiliate_dash/internal/model" "gorm.io/gorm" ) type FulfillmentService struct { db *gorm.DB callbacks *CallbackService upstreamCancel func(order *model.FulfillmentOrder) error upstreamSync func(ctx context.Context, order *model.FulfillmentOrder) (bool, error) } func NewFulfillmentService(db *gorm.DB, callbacks *CallbackService) *FulfillmentService { return &FulfillmentService{db: db, callbacks: callbacks} } // SetUpstreamCancel 注册取消订单时同步取消上游履约单的钩子(如乐玩 CancelOrder)。 func (s *FulfillmentService) SetUpstreamCancel(fn func(order *model.FulfillmentOrder) error) { s.upstreamCancel = fn } // SetUpstreamSync 注册主动查单同步上游状态的钩子(如乐玩订单补偿)。 func (s *FulfillmentService) SetUpstreamSync(fn func(ctx context.Context, order *model.FulfillmentOrder) (bool, error)) { s.upstreamSync = fn } func CanFulfill(order *model.FulfillmentOrder) (bool, string) { switch normalizeOrderStatus(order) { case model.OrderStatusPaid: return true, "" case model.OrderStatusShipFailed: if deliverySubmittedUpstream(order) { return false, "订单已提交上游,为避免重复发货请先确认上游状态" } return true, "" case model.OrderStatusDelivering: return false, "订单发货中" case model.OrderStatusDelivered: return false, "订单已交付" case model.OrderStatusCancelled: return false, "订单已取消" default: return false, "订单状态不可发货" } } func orderCallbackData(order *model.FulfillmentOrder) map[string]interface{} { canShip, cannotShipReason := CanFulfill(order) data := map[string]interface{}{ "order_no": order.OrderNo, "client_order_no": order.ClientOrderNo, "product_sku": order.ProductSKU, "quantity": order.Quantity, "base_amount": order.BaseAmount, "fee_type": order.FeeType, "service_fee_amount": order.ServiceFeeAmount, "amount": order.Amount, "currency": order.Currency, "order_status": normalizeOrderStatus(order), "order_source": order.OrderSource, "can_ship": canShip, "cannot_ship_reason": cannotShipReason, "provider_order_no": order.ProviderOrderNo, "failure_reason": order.FailureReason, } if requestData := requestDataMap(order.RequestData); len(requestData) > 0 { data["data"] = requestData } return data } // ----- 仪表盘统计 ----- // DashboardStats 仪表盘聚合指标。