移除履约任务表
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
-- 当前履约流程由上游通过 URL 获取订单号后主动查单和回传结果,不再维护独立任务表。
|
||||
DROP TABLE IF EXISTS fulfillment_jobs;
|
||||
@@ -45,11 +45,6 @@ const (
|
||||
FulfillmentStatusFailed = "failed"
|
||||
FulfillmentStatusCancelled = "cancelled"
|
||||
|
||||
FulfillmentJobStatusPending = "pending"
|
||||
FulfillmentJobStatusProcessing = "processing"
|
||||
FulfillmentJobStatusSucceeded = "succeeded"
|
||||
FulfillmentJobStatusFailed = "failed"
|
||||
|
||||
WalletLedgerCredit = "credit"
|
||||
WalletLedgerDebit = "debit"
|
||||
WalletLedgerRefund = "refund"
|
||||
@@ -228,23 +223,6 @@ type FulfillmentOrder struct {
|
||||
MerchantProduct *MerchantProduct `gorm:"foreignKey:MerchantProductID" json:"merchant_product,omitempty"`
|
||||
}
|
||||
|
||||
// FulfillmentJob 为后续履约器保留可重试的持久化任务边界。
|
||||
type FulfillmentJob struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
MerchantID uint `gorm:"not null;index" json:"merchant_id"`
|
||||
OrderID uint `gorm:"not null;uniqueIndex" json:"order_id"`
|
||||
Status string `gorm:"size:16;not null;default:pending;index" json:"status"`
|
||||
Attempts int `gorm:"not null;default:0" json:"attempts"`
|
||||
NextRunAt time.Time `gorm:"not null;index" json:"next_run_at"`
|
||||
ProviderOrderNo string `gorm:"size:96;index" json:"provider_order_no"`
|
||||
RequestPayload string `gorm:"type:text" json:"request_payload"`
|
||||
ResultPayload string `gorm:"type:text" json:"result_payload"`
|
||||
LastError string `gorm:"size:512" json:"last_error"`
|
||||
}
|
||||
|
||||
// CallbackSubscription 为商户提供独立、可禁用的事件订阅。
|
||||
type CallbackSubscription struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
|
||||
@@ -181,14 +181,6 @@ func (s *FulfillmentService) CreateOrder(in CreateFulfillmentOrderInput) (*Creat
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.Create(&model.FulfillmentJob{
|
||||
MerchantID: in.MerchantID,
|
||||
OrderID: order.ID,
|
||||
Status: model.FulfillmentJobStatusPending,
|
||||
NextRunAt: time.Now(),
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeAudit(tx, &in.MerchantID, nil, &in.APIClientID, "open_order.create", "fulfillment_order", order.OrderNo, map[string]interface{}{"client_order_no": in.ClientOrderNo, "sku": in.SKU}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -415,20 +407,6 @@ func (s *FulfillmentService) UpdateFulfillment(in FulfillmentUpdateInput) (*mode
|
||||
if err := tx.Model(&order).Updates(updates).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
jobStatus := model.FulfillmentJobStatusProcessing
|
||||
if in.Status == model.FulfillmentStatusSucceeded {
|
||||
jobStatus = model.FulfillmentJobStatusSucceeded
|
||||
} else if in.Status == model.FulfillmentStatusFailed {
|
||||
jobStatus = model.FulfillmentJobStatusFailed
|
||||
}
|
||||
if err := tx.Model(&model.FulfillmentJob{}).Where("order_id = ?", order.ID).Updates(map[string]interface{}{
|
||||
"status": jobStatus,
|
||||
"provider_order_no": in.ProviderOrderNo,
|
||||
"result_payload": resultData,
|
||||
"last_error": in.FailureReason,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.First(&out, order.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -509,12 +487,6 @@ func (s *FulfillmentService) CancelOrder(merchantID, apiClientID uint, orderNo,
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.Model(&model.FulfillmentJob{}).Where("order_id = ?", order.ID).Updates(map[string]interface{}{
|
||||
"status": model.FulfillmentJobStatusFailed,
|
||||
"last_error": "订单已取消",
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.First(&out, order.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -941,22 +913,6 @@ func (s *FulfillmentService) HandleShipNotify(in ShipNotifyInput) (*ShipNotifyRe
|
||||
return err
|
||||
}
|
||||
|
||||
jobStatus := model.FulfillmentJobStatusFailed
|
||||
if nextStatus == model.FulfillmentStatusSucceeded {
|
||||
jobStatus = model.FulfillmentJobStatusSucceeded
|
||||
}
|
||||
jobUpdates := map[string]interface{}{
|
||||
"status": jobStatus,
|
||||
"result_payload": resultData,
|
||||
"last_error": in.FailReason,
|
||||
}
|
||||
if in.ProviderOrderNo != "" {
|
||||
jobUpdates["provider_order_no"] = in.ProviderOrderNo
|
||||
}
|
||||
if err := tx.Model(&model.FulfillmentJob{}).Where("order_id = ?", order.ID).Updates(jobUpdates).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeAudit(tx, &order.MerchantID, nil, nil, "ship.notify", "fulfillment_order", order.OrderNo,
|
||||
shipNotifyAuditMetadata(in, nextStatus, message)); err != nil {
|
||||
return err
|
||||
|
||||
@@ -19,7 +19,6 @@ func newServiceTestDB(t *testing.T) *gorm.DB {
|
||||
&model.WalletAccount{},
|
||||
&model.WalletLedgerEntry{},
|
||||
&model.FulfillmentOrder{},
|
||||
&model.FulfillmentJob{},
|
||||
&model.CallbackSubscription{},
|
||||
&model.CallbackDelivery{},
|
||||
&model.AuditLog{},
|
||||
@@ -458,7 +457,7 @@ func TestCreateTestOrderSupportsFailedFulfillableStatus(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleShipNotifyUpdatesOrderJobAndEnqueuesMerchantCallback(t *testing.T) {
|
||||
func TestHandleShipNotifyUpdatesOrderAndEnqueuesMerchantCallback(t *testing.T) {
|
||||
db := newServiceTestDB(t)
|
||||
merchantID, product := seedFulfillmentMerchant(t, db, "merchant-source-notify", 1000, 2, 100)
|
||||
codec, err := NewSecretCodec("test-master-key")
|
||||
@@ -504,13 +503,6 @@ func TestHandleShipNotifyUpdatesOrderJobAndEnqueuesMerchantCallback(t *testing.T
|
||||
if order.FulfillmentStatus != model.FulfillmentStatusSucceeded || order.ProviderOrderNo != "SRC-10001" || order.DeliveredAt == nil {
|
||||
t.Fatalf("unexpected order after source notify: %+v", order)
|
||||
}
|
||||
var job model.FulfillmentJob
|
||||
if err := db.Where("order_id = ?", created.Order.ID).First(&job).Error; err != nil {
|
||||
t.Fatalf("query fulfillment job: %v", err)
|
||||
}
|
||||
if job.Status != model.FulfillmentJobStatusSucceeded || job.ProviderOrderNo != "SRC-10001" {
|
||||
t.Fatalf("unexpected job after source notify: %+v", job)
|
||||
}
|
||||
var delivery model.CallbackDelivery
|
||||
if err := db.Where("merchant_id = ? AND event = ?", merchantID, "order.fulfillment.updated").First(&delivery).Error; err != nil {
|
||||
t.Fatalf("query callback delivery: %v", err)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
商户回调 / 商户查询订单
|
||||
```
|
||||
|
||||
当前流程不再维护独立的 `fulfillment_jobs` 任务表;履约事实以订单表里的 `fulfillment_status`、上游单号、发货时间和失败原因等字段为准。
|
||||
|
||||
## 3. 鉴权不要混用
|
||||
|
||||
| 项 | 商户侧 `/api/client/v1` | 源头侧 `/api/open/v1` |
|
||||
|
||||
Reference in New Issue
Block a user