统一订单单状态模型

This commit is contained in:
yml2213
2026-07-31 17:02:19 +08:00
parent 677bdbbc1c
commit 04130e5ec8
19 changed files with 300 additions and 345 deletions
+46 -29
View File
@@ -63,60 +63,77 @@ func ensureSameIdempotentOrder(existing *model.FulfillmentOrder, fingerprint str
return nil
}
func validateFulfillmentTransition(order *model.FulfillmentOrder, next string, kind fulfillmentTransitionKind) error {
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("订单不存在")
}
if order.PaymentStatus != model.PaymentStatusPaid {
return errors.New("订单未支付,不能履约")
}
if order.FulfillmentStatus == next {
current := normalizeOrderStatus(order)
if current == next {
return nil
}
switch order.FulfillmentStatus {
case model.FulfillmentStatusCancelled:
return errors.New("订单已取消,不能更新履约状态")
case model.FulfillmentStatusSucceeded:
switch current {
case model.OrderStatusPending:
if next == model.OrderStatusPaid || next == model.OrderStatusCancelled {
return nil
}
return errors.New("订单未支付,不能履约")
case model.OrderStatusCancelled:
return errors.New("订单已取消,不能更新状态")
case model.OrderStatusDelivered:
return errors.New("订单已履约成功,不能回退状态")
}
switch next {
case model.FulfillmentStatusProcessing:
if order.FulfillmentStatus == model.FulfillmentStatusPending || order.FulfillmentStatus == model.FulfillmentStatusFailed {
case model.OrderStatusDelivering:
if current == model.OrderStatusPaid || current == model.OrderStatusShipFailed {
return nil
}
case model.FulfillmentStatusSucceeded:
if order.FulfillmentStatus == model.FulfillmentStatusPending ||
order.FulfillmentStatus == model.FulfillmentStatusFailed ||
order.FulfillmentStatus == model.FulfillmentStatusProcessing {
case model.OrderStatusDelivered:
if current == model.OrderStatusPaid ||
current == model.OrderStatusShipFailed ||
current == model.OrderStatusDelivering {
return nil
}
case model.FulfillmentStatusFailed:
if kind == fulfillmentTransitionTimeout && order.FulfillmentStatus != model.FulfillmentStatusProcessing {
case model.OrderStatusShipFailed:
if kind == fulfillmentTransitionTimeout && current != model.OrderStatusDelivering {
return errors.New("只有履约中的订单可以标记超时")
}
if order.FulfillmentStatus == model.FulfillmentStatusPending ||
order.FulfillmentStatus == model.FulfillmentStatusFailed ||
order.FulfillmentStatus == model.FulfillmentStatusProcessing {
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("订单当前状态不允许该履约变更")
return errors.New("订单当前状态不允许该状态变更")
}
func canCancelOrder(order *model.FulfillmentOrder) error {
if order == nil {
return errors.New("订单不存在")
}
if order.FulfillmentStatus == model.FulfillmentStatusCancelled {
status := normalizeOrderStatus(order)
if status == model.OrderStatusCancelled {
return nil
}
if order.PaymentStatus != model.PaymentStatusPaid {
return errors.New("订单未支付或已退款,不能取消")
}
switch order.FulfillmentStatus {
case model.FulfillmentStatusPending, model.FulfillmentStatusFailed:
switch status {
case model.OrderStatusPaid, model.OrderStatusShipFailed:
return nil
case model.FulfillmentStatusProcessing, model.FulfillmentStatusSucceeded:
case model.OrderStatusPending:
return errors.New("订单未支付,不能取消")
case model.OrderStatusDelivering, model.OrderStatusDelivered:
return errors.New("订单已进入履约流程,不能取消")
default:
return errors.New("订单当前状态不能取消")
@@ -127,5 +144,5 @@ func processingTimedOut(order *model.FulfillmentOrder, timeout time.Duration, no
if order == nil || timeout <= 0 {
return false
}
return order.FulfillmentStatus == model.FulfillmentStatusProcessing && order.UpdatedAt.Before(now.Add(-timeout))
return normalizeOrderStatus(order) == model.OrderStatusDelivering && order.UpdatedAt.Before(now.Add(-timeout))
}