package service import ( "crypto/sha256" "encoding/hex" "encoding/json" "errors" "time" "affiliate_dash/internal/model" ) type fulfillmentTransitionKind string const ( fulfillmentTransitionUpdate fulfillmentTransitionKind = "update" fulfillmentTransitionShipNotify fulfillmentTransitionKind = "ship_notify" fulfillmentTransitionTimeout fulfillmentTransitionKind = "timeout" ) type orderRequestFingerprintPayload struct { ClientOrderNo string `json:"client_order_no"` SKU string `json:"sku"` Quantity int64 `json:"quantity"` BuyerReference string `json:"buyer_reference"` RequestData string `json:"request_data"` } func orderRequestFingerprint(in CreateFulfillmentOrderInput, requestData string) string { raw, _ := json.Marshal(orderRequestFingerprintPayload{ ClientOrderNo: in.ClientOrderNo, SKU: in.SKU, Quantity: in.Quantity, BuyerReference: in.BuyerReference, RequestData: requestData, }) sum := sha256.Sum256(raw) return hex.EncodeToString(sum[:]) } func storedOrderRequestFingerprint(order *model.FulfillmentOrder) string { if order == nil { return "" } if order.RequestFingerprint != "" { return order.RequestFingerprint } return orderRequestFingerprint(CreateFulfillmentOrderInput{ ClientOrderNo: order.ClientOrderNo, SKU: order.ProductSKU, Quantity: order.Quantity, BuyerReference: order.BuyerReference, }, order.RequestData) } func ensureSameIdempotentOrder(existing *model.FulfillmentOrder, fingerprint string) error { if existing == nil { return errors.New("订单不存在") } if storedOrderRequestFingerprint(existing) != fingerprint { return errors.New("client_order_no 已存在,但本次请求参数与原订单不一致") } return nil } func normalizeOrderStatus(order *model.FulfillmentOrder) string { if order == nil { return "" } if order.OrderStatus != "" { return order.OrderStatus } return model.OrderStatusPaid } func validateOrderStatusTransition(order *model.FulfillmentOrder, next string, kind fulfillmentTransitionKind) error { if order == nil { return errors.New("订单不存在") } current := normalizeOrderStatus(order) if current == next { return nil } switch current { case model.OrderStatusCancelled: return errors.New("订单已取消,不能更新状态") case model.OrderStatusDelivered: return errors.New("订单已交付,不能回退状态") } switch next { case model.OrderStatusDelivering: if current == model.OrderStatusPaid || current == model.OrderStatusShipFailed { return nil } case model.OrderStatusDelivered: if current == model.OrderStatusPaid || current == model.OrderStatusShipFailed || current == model.OrderStatusDelivering { return nil } case model.OrderStatusShipFailed: if kind == fulfillmentTransitionTimeout && current != model.OrderStatusDelivering { return errors.New("只有发货中的订单可以标记超时") } if current == model.OrderStatusPaid || current == model.OrderStatusShipFailed || current == model.OrderStatusDelivering { return nil } case model.OrderStatusCancelled: if current == model.OrderStatusPaid || current == model.OrderStatusShipFailed { return nil } } return errors.New("订单当前状态不允许该状态变更") } func canCancelOrder(order *model.FulfillmentOrder) error { if order == nil { return errors.New("订单不存在") } status := normalizeOrderStatus(order) if status == model.OrderStatusCancelled { return nil } switch status { case model.OrderStatusPaid, model.OrderStatusShipFailed: return nil case model.OrderStatusDelivering, model.OrderStatusDelivered: return errors.New("订单已进入发货流程,不能取消") default: return errors.New("订单当前状态不能取消") } } func processingTimedOut(order *model.FulfillmentOrder, timeout time.Duration, now time.Time) bool { if order == nil || timeout <= 0 { return false } return normalizeOrderStatus(order) == model.OrderStatusDelivering && order.UpdatedAt.Before(now.Add(-timeout)) }