fix: align merchant delivery contract
This commit is contained in:
@@ -63,6 +63,30 @@ export interface DeliveryOrderDetail extends DeliveryRow {
|
||||
updatedAt?: string | null
|
||||
}
|
||||
|
||||
interface DeliveryOrderDetailResponse {
|
||||
order: Omit<DeliveryOrderDetail, 'fees' | 'items' | 'updatedAt'>
|
||||
skus: DeliveryOrderItem[]
|
||||
fees: DeliveryOrderFee[]
|
||||
operations: Array<{
|
||||
id: string
|
||||
operatedAt: string
|
||||
operationNode: string
|
||||
operatorName: string
|
||||
result: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface DeliveryTransferResult {
|
||||
dispatchNo: string
|
||||
outboundNo: string
|
||||
outboundStatus: string
|
||||
deliveryNo: string
|
||||
deliveryStatus: string
|
||||
palletCount: number
|
||||
packageCount: number
|
||||
replayed: boolean
|
||||
}
|
||||
|
||||
export interface DeliveryQuery {
|
||||
page: number
|
||||
size: number
|
||||
@@ -107,16 +131,20 @@ export function listDeliveryOrders(params: DeliveryQuery) {
|
||||
}
|
||||
|
||||
export function getDeliveryOrder(deliveryNo: string) {
|
||||
return overseasApiRequest<DeliveryOrderDetail>({
|
||||
return overseasApiRequest<DeliveryOrderDetailResponse>({
|
||||
method: 'GET',
|
||||
url: `/merchant/v1/last-leg/delivery-orders/${encodeURIComponent(deliveryNo)}`,
|
||||
params: { page: 1, size: 200 },
|
||||
})
|
||||
}).then(({ order, skus, fees }) => ({
|
||||
...order,
|
||||
fees,
|
||||
items: skus,
|
||||
}))
|
||||
}
|
||||
|
||||
export function createDeliveryOrder(payload: DeliveryTransferPayload) {
|
||||
const { dispatchNo, ...request } = payload
|
||||
return overseasApiRequest<DeliveryOrderDetail>({
|
||||
return overseasApiRequest<DeliveryTransferResult>({
|
||||
method: 'POST',
|
||||
url: '/merchant/v1/last-leg/delivery-orders',
|
||||
params: { dispatchNo },
|
||||
|
||||
@@ -23,7 +23,9 @@ test('uses only authenticated merchant delivery endpoints without customer scope
|
||||
assert.match(apiSource, /method: 'POST'[\s\S]*url: '\/merchant\/v1\/last-leg\/delivery-orders'/)
|
||||
assert.match(apiSource, /const \{ dispatchNo, \.\.\.request \} = payload/)
|
||||
assert.match(apiSource, /params: \{ dispatchNo \}/)
|
||||
assert.match(apiSource, /overseasApiRequest<DeliveryOrderDetail>/)
|
||||
assert.match(apiSource, /overseasApiRequest<DeliveryOrderDetailResponse>/)
|
||||
assert.match(apiSource, /\.then\(\(\{ order, skus, fees \}\) => \(\{[\s\S]*\.\.\.order,[\s\S]*fees,[\s\S]*items: skus/)
|
||||
assert.match(apiSource, /overseasApiRequest<DeliveryTransferResult>/)
|
||||
assert.doesNotMatch(apiSource, /customerId|tenantId|Record<string, unknown>|mock|fallback/i)
|
||||
})
|
||||
|
||||
@@ -69,6 +71,15 @@ test('submits the complete create contract with stable retry idempotency and rec
|
||||
assert.match(createSource, /if \(!pendingIdempotencyKey\) pendingIdempotencyKey = crypto\.randomUUID\(\)/)
|
||||
assert.match(createSource, /createDeliveryOrder\(requestPayload\(\)\)/)
|
||||
assert.match(createSource, /fees: form\.fees\.map/)
|
||||
assert.match(createSource, /if \(form\.fees\.length === 0\)/)
|
||||
assert.match(createSource, /请至少添加一条费用明细/)
|
||||
for (const value of ['FBA_PICKUP', 'CUSTOMER_PICKUP', 'TRUCK_PALLET', 'TRUCK_FLOOR', 'EXPRESS', 'OUTSOURCED', 'DEDICATED_TRUCK', 'LTL']) {
|
||||
assert.match(createSource, new RegExp(`value="${value}"`))
|
||||
}
|
||||
for (const value of ['ONE_PICKUP_ONE_DROP', 'ONE_PICKUP_MULTI_DROP', 'MULTI_PICKUP_ONE_DROP', 'MULTI_PICKUP_MULTI_DROP', 'WAREHOUSE_PICKUP', 'PALLET', 'FLOOR', 'MIXED']) {
|
||||
assert.match(createSource, new RegExp(`value="${value}"`))
|
||||
}
|
||||
assert.doesNotMatch(createSource, /value="(?:TRUCK|COURIER|SELF_PICKUP|DOOR_PICKUP|LOOSE_CARTON)"/)
|
||||
assert.match(createSource, /submitError\.value = error instanceof Error/)
|
||||
assert.match(createSource, /useUnsavedWorkRegistration/)
|
||||
assert.doesNotMatch(createSource, /customerId|tenantId|mock|fallback/i)
|
||||
|
||||
@@ -71,6 +71,10 @@ function removeFee(index: number) {
|
||||
}
|
||||
|
||||
function validateFees() {
|
||||
if (form.fees.length === 0) {
|
||||
ElMessage.warning('请至少添加一条费用明细')
|
||||
return false
|
||||
}
|
||||
const invalidIndex = form.fees.findIndex((fee) => !fee.feeType.trim() || !fee.currency.trim() || fee.amount <= 0)
|
||||
if (invalidIndex < 0) return true
|
||||
ElMessage.warning(`请完整填写第 ${invalidIndex + 1} 条费用的类型、币种和大于 0 的金额`)
|
||||
@@ -154,9 +158,9 @@ async function cancel() {
|
||||
<div class="delivery-form-grid">
|
||||
<el-form-item label="排车单号" prop="dispatchNo" required><el-input v-model="form.dispatchNo" maxlength="64" placeholder="请输入排车单号" /></el-form-item>
|
||||
<el-form-item label="计划派送时间" prop="plannedDeliveryAt" required><el-date-picker v-model="form.plannedDeliveryAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择计划派送时间" /></el-form-item>
|
||||
<el-form-item label="派送方式" prop="deliveryMethod" required><el-select v-model="form.deliveryMethod" placeholder="请选择派送方式"><el-option label="卡车派送" value="TRUCK" /><el-option label="快递派送" value="COURIER" /><el-option label="客户自提" value="SELF_PICKUP" /></el-select></el-form-item>
|
||||
<el-form-item label="提货方式" prop="pickupMethod" required><el-select v-model="form.pickupMethod" placeholder="请选择提货方式"><el-option label="仓库提货" value="WAREHOUSE_PICKUP" /><el-option label="上门提货" value="DOOR_PICKUP" /></el-select></el-form-item>
|
||||
<el-form-item label="装载类型" prop="loadingType" required><el-select v-model="form.loadingType" placeholder="请选择装载类型"><el-option label="托盘" value="PALLET" /><el-option label="散箱" value="LOOSE_CARTON" /><el-option label="混合装载" value="MIXED" /></el-select></el-form-item>
|
||||
<el-form-item label="派送方式" prop="deliveryMethod" required><el-select v-model="form.deliveryMethod" placeholder="请选择派送方式"><el-option label="FBA自提" value="FBA_PICKUP" /><el-option label="客户自提" value="CUSTOMER_PICKUP" /><el-option label="卡派打托" value="TRUCK_PALLET" /><el-option label="卡派地板" value="TRUCK_FLOOR" /><el-option label="快递" value="EXPRESS" /><el-option label="外配" value="OUTSOURCED" /><el-option label="专车直送" value="DEDICATED_TRUCK" /><el-option label="零担派送" value="LTL" /></el-select></el-form-item>
|
||||
<el-form-item label="提货方式" prop="pickupMethod" required><el-select v-model="form.pickupMethod" placeholder="请选择提货方式"><el-option label="一提一卸" value="ONE_PICKUP_ONE_DROP" /><el-option label="一提多卸" value="ONE_PICKUP_MULTI_DROP" /><el-option label="多提一卸" value="MULTI_PICKUP_ONE_DROP" /><el-option label="多提多卸" value="MULTI_PICKUP_MULTI_DROP" /><el-option label="仓库自提" value="WAREHOUSE_PICKUP" /></el-select></el-form-item>
|
||||
<el-form-item label="装载类型" prop="loadingType" required><el-select v-model="form.loadingType" placeholder="请选择装载类型"><el-option label="托盘" value="PALLET" /><el-option label="地板" value="FLOOR" /><el-option label="混装" value="MIXED" /></el-select></el-form-item>
|
||||
<el-form-item label="运单号"><el-input v-model="form.waybillNo" maxlength="64" placeholder="选填" /></el-form-item>
|
||||
</div>
|
||||
</section>
|
||||
@@ -185,7 +189,7 @@ async function cancel() {
|
||||
<el-table-column label="金额" width="180"><template #default="{ row }"><el-input-number v-model="row.amount" :min="0" :precision="2" :step="1" controls-position="right" /></template></el-table-column>
|
||||
<el-table-column label="备注" min-width="220"><template #default="{ row }"><el-input v-model="row.remark" maxlength="200" placeholder="选填" /></template></el-table-column>
|
||||
</el-table>
|
||||
<div v-else class="delivery-fee-empty">暂无费用明细,可按实际情况添加。</div>
|
||||
<div v-else class="delivery-fee-empty">请至少添加一条费用明细后再提交。</div>
|
||||
</section>
|
||||
|
||||
<div class="delivery-form-actions"><el-button :disabled="submitting" @click="cancel">取消</el-button><el-button type="primary" native-type="submit" :loading="submitting">提交创建</el-button></div>
|
||||
|
||||
Reference in New Issue
Block a user