加强发货提交可靠性并统一契约口径

- 发货提交记录阶段推进与失败分类,失败不再清空 result_data
- 超时巡检区分已提交上游与提交中断两类卡单,避免误判
- 已提交上游的失败订单禁止自动重发,防止重复发货
- ship_attempts 仅在 claim 时计数,失败阶段只记录分类信息
- CanFulfill 对已提交上游的失败单返回不可发货
- 删除预留的 pending 订单状态,统一订单状态模型
- 契约改名:order.fulfillment.updated -> order.shipping.updated,fulfillment:read -> shipping:read
- 文档修正 scope 为或关系
This commit is contained in:
yml2213
2026-07-31 18:42:52 +08:00
parent 4aa5258c2d
commit eac025c92f
15 changed files with 401 additions and 86 deletions
+2 -3
View File
@@ -18,7 +18,6 @@ export const errorCodes: ParamSpec[] = [
// 订单状态与可发货说明。
export const orderStatusTable: ParamSpec[] = [
{ name: 'pending', type: 'order_status', desc: '待支付(当前无真实支付流程,仅预留)', example: 'can_ship=false' },
{ name: 'paid', type: 'order_status', desc: '已支付/已扣款,可发货', example: 'can_ship=true' },
{ name: 'delivering', type: 'order_status', desc: '发货中', example: 'can_ship=false' },
{ name: 'delivered', type: 'order_status', desc: '已交付', example: 'can_ship=false' },
@@ -263,7 +262,7 @@ export const endpoints: EndpointSpec[] = [
path: '/api/client/v1/orders/{order_no}/delivery-link',
title: '获取发货链接',
summary: '获取签名发货链接,适合直接跳转平台 Web 发货页',
scope: 'orders:read + fulfillment:read',
scope: 'orders:read 或 shipping:read',
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
responseExample: deliveryLinkResponseExample,
responseFields: [
@@ -284,7 +283,7 @@ export const endpoints: EndpointSpec[] = [
path: '/api/client/v1/orders/{order_no}/delivery',
title: '查询发货数据',
summary: '查询发货页结构化数据,适合商户自建发货界面',
scope: 'orders:read + fulfillment:read',
scope: 'orders:read 或 shipping:read',
pathParams: [{ name: 'order_no', type: 'string', required: true, desc: '平台订单号', example: 'FO20260730000123' }],
responseExample: deliveryOrderResponseExample,
responseFields: [
-6
View File
@@ -161,12 +161,6 @@ export default function Dashboard() {
<Col xs={24} lg={14}>
<Card title="订单状态">
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
<StatusLine
label="待支付"
value={stats?.pending_order_count ?? 0}
total={stats?.order_count ?? 0}
color="#faad14"
/>
<StatusLine
label="待发货"
value={stats?.paid_order_count ?? 0}
+3 -4
View File
@@ -42,7 +42,6 @@ import type {
} from '../types'
const orderStatusMap: Record<string, { color: string; text: string }> = {
pending: { color: 'orange', text: '待支付' },
paid: { color: 'blue', text: '待发货' },
delivering: { color: 'cyan', text: '发货中' },
delivered: { color: 'green', text: '已交付' },
@@ -61,13 +60,13 @@ const scopeOptions = [
{ value: 'products:read', label: '商品读取' },
{ value: 'orders:read', label: '订单读取' },
{ value: 'orders:write', label: '订单写入' },
{ value: 'fulfillment:read', label: '发货读取' },
{ value: 'shipping:read', label: '发货读取' },
{ value: 'wallet:read', label: '钱包读取' },
]
const eventOptions = [
{ value: 'order.created', label: '订单创建' },
{ value: 'order.fulfillment.updated', label: '发货更新' },
{ value: 'order.shipping.updated', label: '发货更新' },
{ value: 'order.cancelled', label: '订单取消' },
]
@@ -665,7 +664,7 @@ export default function MerchantCenter({ fixedTab, title = '商户中心' }: Mer
<Typography.Text type="secondary"> outbox </Typography.Text>
{canManage && <Button type="primary" icon={<PlusOutlined />} onClick={() => {
callbackForm.resetFields()
callbackForm.setFieldsValue({ events: ['order.fulfillment.updated'] })
callbackForm.setFieldsValue({ events: ['order.shipping.updated'] })
setCallbackOpen(true)
}}></Button>}
</Space>
+1 -1
View File
@@ -489,7 +489,7 @@ POST /orders 下单(client_order_no 幂等)
发货平台通过上游回调更新 order_status
GET /orders/{order_no} 轮询,或接收 order.fulfillment.updated 回调`}</pre>
GET /orders/{order_no} 轮询,或接收 order.shipping.updated 回调`}</pre>
}
/>
</SectionWrap>
-1
View File
@@ -220,7 +220,6 @@ export interface DashboardStats {
today_sales: number
total_fees: number
today_fees: number
pending_order_count: number
paid_order_count: number
delivering_order_count: number
delivered_order_count: number