This commit is contained in:
2026-09-09 09:52:46 +08:00
parent 68a5612598
commit 4379b721bc
9 changed files with 195 additions and 46 deletions
+76 -13
View File
@@ -128,11 +128,13 @@ Assert-Contains $testTaskRegistry 'projectId `c64729ff-6710-43c6-8ef2-d84e9666cc
Assert-Contains $testTaskRegistry 'C:\Users\BY-OY\Desktop\code\chongchong-global`' '测试登记工作目录'
Assert-Contains $testTaskRegistry '已重新启用测试环境总控调度' '测试登记启用状态'
Assert-Contains $testTaskRegistry '`01a05b10-a5fc-7d51-8203-c671f3a823ad`' '测试环境全流程总控'
Assert-Contains $testTaskRegistry '`01a046ea-cfc4-73a1-85f0-c69c714bff22`' '测试环境海外接柜仓总控'
Assert-Contains $testTaskRegistry '| 海外接柜后端 |' '测试环境海外接柜后端专项'
Assert-Contains $testTaskRegistry '| 海外接柜Admin前端 |' '测试环境海外接柜 Admin 专项'
Assert-Contains $testTaskRegistry '| 海外接柜Client前端 |' '测试环境海外接柜 Client 专项'
Assert-Contains $testTaskRegistry '| 海外接柜PDA前端 |' '测试环境海外接柜 PDA 专项'
Assert-Contains $testTaskRegistry '| 【总控】测试环境全流程 |' '测试环境唯一总控名称'
Assert-Contains $testTaskRegistry '`01a046ea-cfc4-73a1-85f0-c69c714bff22`' '测试环境海外仓全流程测试专项'
Assert-Contains $testTaskRegistry '| 【测试】海外仓全流程 |' '测试环境海外仓全流程测试专项名称'
Assert-Contains $testTaskRegistry '| 【前端】Admin全流程 |' '测试环境 Admin 前端专项'
Assert-Contains $testTaskRegistry '| 【前端】Client全流程 |' '测试环境 Client 前端专项'
Assert-Contains $testTaskRegistry '| 【前端】海外PDA |' '测试环境海外 PDA 专项'
Assert-Contains $testTaskRegistry '| 【后端4】海外接柜 |' '测试环境海外接柜后端专项'
Assert-NotContains $testTaskRegistry '01a0194a-259c-7171-8967-074731a27618' '测试登记历史总控'
Assert-NotContains $testTaskRegistry '01a06c0b-0515-7c60-b329-77342b54e666' '测试登记当前开发总控'
Assert-NotContains $testTaskRegistry '6f874ec3-d3b2-49bd-8625-327f4d685f98' '测试登记开发 projectId'
@@ -172,7 +174,7 @@ Assert-Contains $rootAgents '尾程订单控制与柜级入仓计划转换' '根
Assert-Contains $adminAgents '目的港码头拖车与还空预警' 'Admin 目的港码头拖车路由'
Assert-Contains $adminAgents '尾程订单控制与柜级入仓计划转换' 'Admin 尾程订单控制路由'
Assert-Contains $backendAgents '目的港码头拖车与还空预警' '后端目的港码头拖车路由'
Assert-Contains $backendAgents '尾程订单控制与柜级入仓计划转换' '后端尾程订单控制路由'
Assert-Contains $backendAgents '尾程订单控制、柜级预览与入仓计划转换' '后端尾程订单控制路由'
$testTaskIds = @([regex]::Matches($testTaskRegistry, '(?m)^\|\s*`([0-9a-f-]{36})`\s*\|') | ForEach-Object { $_.Groups[1].Value })
$devTaskIds = @([regex]::Matches($devTaskRegistry, '(?m)^\|\s*`([0-9a-f-]{36})`\s*\|') | ForEach-Object { $_.Groups[1].Value })
foreach ($sharedTaskId in @($testTaskIds | Where-Object { $devTaskIds -contains $_ } | Select-Object -Unique)) {
@@ -263,6 +265,48 @@ Assert-Contains $unifiedOrderQueryService 'order.getStatus() == OrderStatus.SUBM
Assert-Contains $unifiedOrderQueryService 'pendingReview ? "PENDING_REVIEW" : summary.mainStatus()' 'Order 待审核主状态优先'
Assert-Contains $unifiedOrderQueryService 'pendingReview ? "APPROVE_ORDER" : summary.nextAction()' 'Order 待审核动作优先'
# 批量审核、客户专属价格簿和柜级阶梯计价已经成为稳定跨端能力,必须从根表直达且锁住服务端权威规则。
$batchReviewPreviewService = Read-RequiredText (Join-Path $backendRoot 'order/src/main/java/com/baiyue/order/service/BatchOrderReviewPreviewService.java')
$fbaPricingOpenApi = Read-RequiredText (Join-Path $backendRoot 'firstleg/src/main/resources/openapi/fba-pricing-v1.yaml')
$fbaPricingService = Read-RequiredText (Join-Path $backendRoot 'firstleg/src/main/java/com/baiyue/firstleg/service/FbaPricingService.java')
$inboundFeeDetailService = Read-RequiredText (Join-Path $backendRoot 'firstleg/src/main/java/com/baiyue/firstleg/service/InboundFeeDetailService.java')
$adminUnifiedOrdersApi = Read-RequiredText (Join-Path $workspaceRoot 'apps/admin-web/src/modules/unified-orders/api/unifiedOrders.ts')
$adminCarrierRatesView = Read-RequiredText (Join-Path $workspaceRoot 'apps/admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRatesView.vue')
Assert-Contains $rootAgents '头程订单、批量审核预览与入仓码关系' '根批量审核预览路由'
Assert-Contains $adminAgents '订单列表、批量审核预览、详情、商品图片与入库费用' 'Admin 批量审核预览路由'
Assert-Contains $backendAgents '平台订单批量审核预览' '后端批量审核预览路由'
Assert-Contains $orderAgents '平台批量审核预览' 'Order 批量审核预览入口'
Assert-Contains $orderOpenApi '/api/platform/v1/orders/first-leg/batch-review-preview:' 'Order 批量审核预览 OpenAPI'
Assert-Contains $batchReviewPreviewService '固定两次批量查询生成审核弹窗快照' 'Order 批量审核禁止逐票查询'
Assert-Contains $adminUnifiedOrdersApi '/platform/v1/orders/first-leg/batch-review-preview' 'Admin 批量审核预览 API'
Assert-Contains $rootAgents '客户专属报价、柜级阶梯运费与费用调整' '根客户专属报价路由'
Assert-Contains $adminAgents '客户专属价格簿、柜级阶梯运费与受控调价' 'Admin 客户专属报价路由'
Assert-Contains $backendAgents '客户专属价格簿、柜级阶梯运费与受控调价' '后端客户专属报价路由'
Assert-Contains $firstlegAgents '客户专属价格簿、柜级阶梯运费与调价边界' 'Firstleg 客户专属报价入口'
Assert-Contains $fbaPricingOpenApi '计价时优先使用客户专属 ACTIVE 版本,不存在时回退公共 ACTIVE 版本' '价格簿作用域优先级'
Assert-Contains $fbaPricingOpenApi '计费量只能在系统原计费量上下10%范围内(含边界)' '计费量调整边界'
Assert-Contains $fbaPricingService 'recalculateUnlockedContainerCustomerFees' '柜级阶梯费用重算入口'
Assert-Contains $firstlegAgents '一件代发 `WAIT_PALLETIZE` 可在预装确认前试算' 'Firstleg 一件代发预装前计价边界'
Assert-Contains $fbaPricingService '"WAIT_PALLETIZE"' '一件代发托盘化状态可计价'
Assert-Contains $fbaPricingService 'preserveProcessStatusDuringPricing' '计价保留履约状态入口'
Assert-Contains $inboundFeeDetailService 'PRIVATE_LAST_MILE_DELIVERY_FEE_CODE' '私人仓尾程派送费稳定代码'
Assert-Contains $adminCarrierRatesView 'customerId' 'Admin 价格簿客户作用域'
Assert-Path 'baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/pricing/ContainerTierAmountAllocator.java'
# 海外异常处理必须贯通证据、原出库来源和库存恢复,不能退化为仅修改派送状态。
$exceptionOrderService = Read-RequiredText (Join-Path $backendRoot 'lastleg-service/src/main/java/com/baiyue/lastleg/exceptionorder/service/ExceptionOrderService.java')
$inventoryCommandService = Read-RequiredText (Join-Path $backendRoot 'lastleg-service/src/main/java/com/baiyue/lastleg/inventory/command/service/InventoryCommandService.java')
Assert-Contains $rootAgents '退回海外仓时先把实收恢复到指定真实托盘/库位' '根海外异常库存恢复路由'
Assert-Contains $adminAgents '库存恢复、异常完成与派送 `RETURNED` 由服务端原子推进' 'Admin 海外异常原子边界'
Assert-Contains $backendAgents '海外异常退回、库存恢复与客户回访' '后端海外异常库存恢复路由'
Assert-Contains $lastlegAgents 'ExceptionEvidenceFileGateway.java' 'Lastleg 异常证据入口'
Assert-Contains $lastlegAgents '`RETURN_STOCK_IN` 流水' 'Lastleg 退回库存流水边界'
Assert-Contains $fileAgents 'businessType=OVERSEAS_EXCEPTION_EVIDENCE' 'File 海外异常证据归属'
Assert-Contains $exceptionOrderService 'restoreReturnedInventory' '海外异常退回库存恢复调用'
Assert-Contains $exceptionOrderService 'delivery.setStatus("RETURNED")' '海外异常完成派送状态'
Assert-Contains $inventoryCommandService 'ReturnedInventoryRestoreRequest' '海外退回库存命令入口'
Assert-Path 'baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/exceptionorder/gateway/ExceptionEvidenceFileGateway.java'
# 智能装柜已扩展到四态候选、Order 待审核补齐、提前占位与未拣整批移除;费用确认和会话恢复也必须可定向命中。
$pendingReviewOrderService = Read-RequiredText (Join-Path $backendRoot 'order/src/main/java/com/baiyue/order/service/PendingReviewOrderQueryService.java')
$merchantInboundBillingService = Read-RequiredText (Join-Path $backendRoot 'firstleg/src/main/java/com/baiyue/firstleg/service/MerchantInboundBillingService.java')
@@ -391,7 +435,7 @@ Assert-Contains $firstlegAgents '按卸柜完成时间加 72 小时' 'Firstleg
Assert-Contains $terminalDrayageOpenApi '/api/platform/v1/terminal-drayages/{containerBookingId}/fleet:' '码头拖车车队命令 OpenAPI'
Assert-Contains $terminalDrayageOpenApi '/api/platform/v1/terminal-drayages/{containerBookingId}/empty-return:' '码头拖车还柜命令 OpenAPI'
Assert-Contains $terminalDrayageService 'EMPTY_RETURN_WARNING_HOURS = 72' '码头拖车 72 小时预警实现'
Assert-Contains $terminalDrayageService 'context.unloadingCompletedAt().plusHours(EMPTY_RETURN_WARNING_HOURS)' '码头拖车权威截止时间实现'
Assert-Contains $terminalDrayageService 'context.base().unloadingCompletedAt().plusHours(EMPTY_RETURN_WARNING_HOURS)' '码头拖车权威截止时间实现'
Assert-Contains $adminTerminalDrayages 'allowedActions' 'Admin 码头拖车服务端动作消费'
Assert-Contains $lastlegOrderCommandService '必须提交完整8行人工时间快照' '尾程人工节点完整快照实现'
Assert-Contains $lastlegOrderCommandService '尾程订单已进入出库流程,不能新增暂扣' '尾程暂扣出库门禁实现'
@@ -675,28 +719,47 @@ Assert-Contains $productImageController "hasAuthority('platform:order:list')" '
Assert-Contains $receivingController '/current/unload-photos/files/{fileId}/download' '海外 PDA 签收照片预览'
Assert-Contains $receivingController 'CacheControl.noStore()' '海外 PDA 签收照片缓存边界'
# 尾程订单按来源柜展示服务端计划进度,整柜转换每票独立计划且整批原子。
# 尾程订单按来源柜展示服务端计划进度;整柜确认必须绑定预览快照并编排真实托盘批次。
$lastlegBusinessOpenApi = Read-RequiredText (Join-Path $backendRoot 'lastleg-service/src/main/resources/openapi/overseas-business-v1.yaml')
$lastlegAgents = Read-RequiredText (Join-Path $backendRoot 'lastleg-service/AGENTS.md')
$adminLastMileApi = Read-RequiredText (Join-Path $workspaceRoot 'apps/admin-web/src/modules/overseas-warehouse/api/lastMileOrders.ts')
$containerConversionCoordinator = Read-RequiredText (Join-Path $backendRoot 'lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/ContainerInboundPlanConversionCoordinator.java')
$warehousePalletBatchService = Read-RequiredText (Join-Path $backendRoot 'warehouse-overseas-service/src/main/java/com/baiyue/warehouse/service/WarehousePalletBatchService.java')
$overseasWarehouseAgents = Read-RequiredText (Join-Path $backendRoot 'warehouse-overseas-service/AGENTS.md')
$overseasPdaReceivingAdapter = Read-RequiredText (Join-Path $workspaceRoot 'apps/pda-overseas-uniapp/src/api/receiving-adapter.js')
Assert-Contains $lastlegBusinessOpenApi '/api/platform/v1/last-leg/orders/container-summaries:' 'Lastleg 柜级摘要契约'
Assert-Contains $lastlegBusinessOpenApi '/api/platform/v1/last-leg/inbound-plans/convert-container:' 'Lastleg 整柜计划转换契约'
Assert-Contains $lastlegBusinessOpenApi '/api/platform/v1/last-leg/inbound-plans/container-preview:' 'Lastleg 整柜计划预览契约'
Assert-Contains $lastlegBusinessOpenApi 'snapshotVersion' 'Lastleg 整柜计划快照版本'
Assert-Contains $lastlegBusinessOpenApi 'snapshotHash' 'Lastleg 整柜计划快照哈希'
Assert-Contains $lastlegBusinessOpenApi 'sourceContainerBookingId' 'Lastleg 稳定来源柜身份'
Assert-Contains $adminAgents '/orders/container-summaries' 'Admin 柜级摘要目标入口'
Assert-Contains $rootAgents '尾程订单控制与柜级入仓计划转换' '根柜级计划入口'
Assert-Contains $backendAgents '分页前排除全部入仓码均已生成有效独立计划的柜' '后端柜级计划待处理筛选'
Assert-Contains $adminAgents '返回仍有待生成计划入仓码的柜' 'Admin 柜级计划待处理筛选'
Assert-Contains $lastlegAgents '分页前排除全部入仓码均已生成有效独立计划的柜' 'Lastleg 柜级计划待处理筛选'
Assert-Contains $lastlegBusinessOpenApi '仅返回仍有入仓码待生成有效独立计划的柜' 'Lastleg 柜级计划待处理 OpenAPI'
Assert-Contains $backendAgents '分页返回全部稳定来源柜' '后端全柜工作台范围'
Assert-Contains $adminAgents '服务端分页返回全部稳定来源柜' 'Admin 全柜工作台范围'
Assert-Contains $lastlegAgents '分页返回全部稳定来源柜' 'Lastleg 全柜工作台范围'
Assert-Contains $lastlegBusinessOpenApi '返回全部稳定来源柜' 'Lastleg 全柜工作台 OpenAPI'
Assert-Contains $adminAgents 'ACTIVE + FBA' 'Admin FBA 权威仓候选'
Assert-Contains $adminAgents '/inbound-plans/convert-container' 'Admin 整柜转换目标入口'
Assert-Contains $adminAgents '/inbound-plans/container-preview' 'Admin 整柜预览目标入口'
Assert-Contains $adminAgents '同一 `snapshotVersion/snapshotHash` 原样提交' 'Admin 整柜快照确认边界'
Assert-Contains $adminLastMileApi '/orders/container-summaries' 'Admin 柜级摘要真实调用'
Assert-Contains $adminLastMileApi '/platform/v1/last-leg/inbound-plans/container-preview' 'Admin 柜级预览真实调用'
Assert-NotContains $adminLastMileApi '/orders/pending-containers' 'Admin 旧柜级摘要调用'
Assert-Contains $lastlegBusinessOpenApi 'ContainerPlanProgressSummary' 'Lastleg 柜级计划进度摘要模型'
Assert-Contains $lastlegBusinessOpenApi 'ContainerPlanProgressDetail' 'Lastleg 柜级计划进度详情模型'
Assert-Contains $lastlegBusinessOpenApi 'allPlansReady' 'Lastleg 全柜计划就绪事实'
Assert-Contains $lastlegBusinessOpenApi 'plannedArrivalAt' 'Lastleg 计划到仓冻结事实'
Assert-Contains $lastlegAgents 'service/FbaWarehouseValidator.java' 'Lastleg FBA 权威仓校验入口'
Assert-Contains $lastlegAgents 'ContainerInboundPlanConversionCoordinator.java' 'Lastleg 柜级计划 Saga 入口'
Assert-Contains $containerConversionCoordinator 'warehouse.ensurePalletBatch' 'Lastleg 托盘批次预留'
Assert-Contains $containerConversionCoordinator 'warehouse.confirmPalletBatch' 'Lastleg 托盘批次确认'
Assert-Contains $containerConversionCoordinator 'warehouse.compensatePalletBatch' 'Lastleg 托盘批次补偿'
Assert-Contains $warehousePalletBatchService 'Only a RESERVED pallet batch can be confirmed' '海外资源批次确认状态门禁'
Assert-Contains $overseasWarehouseAgents '同柜重放不得产生第二批资源' '海外资源批次幂等边界'
Assert-Contains $overseasPdaAgents 'assigned/mergeAllowed/urgent/mergeHint' '海外 PDA 计划标志索引'
Assert-Contains $overseasPdaAgents '不在设备端重新分配' '海外 PDA 预留托盘边界'
Assert-Contains $overseasPdaReceivingAdapter 'mergeAllowed: value.mergeAllowed === true' '海外 PDA 合托可选事实适配'
# 国内 PDA 当前以页面、API 和作业状态合同覆盖部分拣货及库位不足反馈。
Assert-Contains $pdaAgents 'tests/page-contract.test.mjs' '国内 PDA 页面合同'
@@ -1079,5 +1142,5 @@ if ($failures.Count -gt 0) {
exit 1
}
Write-Host "AGENTS 索引合同通过:$checked 项检查,覆盖快速表唯一性、部署单元、开发/测试任务登记隔离、前端模块、Client active 路由、客户中文批量下单、箱规算法与测量计费、称重整票库位块与暂估箱数校准、全局智能装柜组分页、客户账单入仓码联查、导出退避任务重试、脚本目录治理、Finance 扩展 HTTP 模块、柜费跨客户原子分摊、海外费用跨区入池与直接已付隔离、企业联系信息与登录标识解耦、选填法人身份证独立上传、待审核订单状态优先、订单申报版本同步与渠道门禁、装柜证据内容哈希重放、业务编号与内部 ID 隔离、装柜清单生命周期与真实柜号后补、订舱级拖车与柜级证据、海外仓全流程范围、柜级待处理计划筛选与范围漂移、仓库主档唯一权威、订舱候选与柜量语义、整柜出仓与船节点单调性、Gateway 覆盖、PDA 页面/运行配置/独立更新/语言预留/能力开关、人工分段验收链、Maven 模块、Lastleg 海外安全投影、同步 Trace、关键入口和排除目录。" -ForegroundColor Green
Write-Host "AGENTS 索引合同通过:$checked 项检查,覆盖快速表唯一性、部署单元、开发/测试任务登记隔离、前端模块、Client active 路由、客户中文批量下单、箱规算法与测量计费、一件代发预装前计价、称重整票库位块与暂估箱数校准、全局智能装柜组分页、客户账单入仓码联查、导出退避任务重试、脚本目录治理、Finance 扩展 HTTP 模块、柜费跨客户原子分摊、海外费用跨区入池与直接已付隔离、企业联系信息与登录标识解耦、选填法人身份证独立上传、待审核订单状态优先、订单申报版本同步与渠道门禁、装柜证据内容哈希重放、业务编号与内部 ID 隔离、装柜清单生命周期与真实柜号后补、订舱级拖车与柜级证据、海外仓全流程范围、柜级全柜工作台、计划快照与托盘 Saga、海外 PDA 多计划标志及范围漂移、仓库主档唯一权威、订舱候选与柜量语义、整柜出仓与船节点单调性、Gateway 覆盖、PDA 页面/运行配置/独立更新/语言预留/能力开关、人工分段验收链、Maven 模块、Lastleg 海外安全投影、同步 Trace、关键入口和排除目录。" -ForegroundColor Green
exit 0
@@ -60,6 +60,7 @@ test('builds an order payload owned by the fixed profile', () => {
senderLocation: { province: '浙江省', city: '义乌市', district: '稠城街道', postalCode: '322000' },
},
productImageFileId: '33',
pickupAddressId: '55',
})
assert.equal(payload.receivingWarehouseId, '11')
assert.equal(payload.destinationWarehouseId, '22')
@@ -67,11 +68,14 @@ test('builds an order payload owned by the fixed profile', () => {
assert.equal(payload.customerName, '固定测试客户')
assert.equal(payload.cargoes.length, 1)
assert.equal(payload.cargoes[0].productImageFileId, '33')
assert.equal(payload.cargoes[0].woodenProduct, false)
assert.equal(payload.tradeTerm, 'EXW')
assert.equal(payload.pickupMethod, 'SELF_TRUCK')
assert.equal(payload.taxMode, 'TAX_REFUND')
assert.equal(payload.customsInspection, true)
assert.equal(payload.sender, null)
assert.equal(payload.senderAddressId, null)
assert.equal(payload.requestedPickupAt, null)
assert.equal(payload.cargoes[0].cargoName, PRODUCT_CATALOG[0].cargoName)
assert.equal(payload.cargoes[0].packageCount, 7)
assert.equal(payload.cargoes[0].totalQuantity, PRODUCT_CATALOG[0].unitsPerPackage * 7)
@@ -79,6 +83,27 @@ test('builds an order payload owned by the fixed profile', () => {
assert.equal(payload.cargoes[0].declaredValue, PRODUCT_CATALOG[0].unitDeclaredValue * PRODUCT_CATALOG[0].unitsPerPackage * 7)
})
test('uses the selected customer pickup address and appointment for pickup orders', () => {
const payload = buildOrderPayload({
marker: 'PENDING-PICKUP', index: 1,
profile: { id: '44', tenantName: '固定测试客户' },
master: {
receiving: { id: '11', warehouseName: '国内仓' },
destination: { id: '22', warehouseName: 'ONT8', warehouseCode: 'ONT8', countryCode: 'US' },
channel: { channelCode: 'SEA-US', channelName: '美西海运' }, pricingTaxMode: 'TAX_INCLUDED',
},
product: PRODUCT_CATALOG[0], packageCount: 1, productImageFileId: '33', pickupAddressId: '55',
options: {
tradeTerm: 'FOB', pickupMethod: 'PICKUP', taxMode: 'BUY_DECLARATION',
customsInspection: false, expectedShipDays: 7,
senderLocation: { province: '广东省', city: '深圳市', district: '南山区', postalCode: '518000' },
},
})
assert.equal(payload.sender, null)
assert.equal(payload.senderAddressId, '55')
assert.match(payload.requestedPickupAt, /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/)
})
test('randomizes only supported basic-order fields', () => {
for (let index = 0; index < 100; index += 1) {
const options = randomOrderOptions()
+40 -14
View File
@@ -247,7 +247,39 @@ async function uploadProductImage(gateway, timeoutMs, token, marker) {
return data.fileId
}
export function buildOrderPayload({ marker, index, profile, master, product, packageCount, options = randomOrderOptions(), productImageFileId }) {
async function ensurePickupAddress(gateway, timeoutMs, token, profile, marker) {
const listResponse = await request(gateway, timeoutMs, 'GET',
'/api/merchant/v1/orders/first-leg/addresses?addressType=PICKUP', { token })
const existing = items(requireSuccess(listResponse, 'Query pickup addresses'))
.find((address) => address?.id)
if (existing) return String(existing.id)
const location = pickRandom(SENDER_LOCATIONS)
const createResponse = await request(gateway, timeoutMs, 'POST',
'/api/merchant/v1/orders/first-leg/addresses', {
token,
body: {
addressType: 'PICKUP',
addressName: '待审核订单测试取货地址',
companyName: profile.tenantName || `固定客户-${marker}`,
contactName: '订单测试联系人',
phone: '13800138000',
email: 'pending-order@example.com',
countryCode: 'CN',
province: location.province,
city: location.city,
district: location.district,
addressLine: `${marker} 固定客户测试地址`,
postalCode: location.postalCode,
defaultAddress: true,
},
})
const addressId = String(requireSuccess(createResponse, 'Create pickup address') ?? '')
if (!addressId) throw new Error('Create pickup address did not return address ID')
return addressId
}
export function buildOrderPayload({ marker, index, profile, master, product, packageCount, options = randomOrderOptions(), productImageFileId, pickupAddressId }) {
const sequence = String(index).padStart(3, '0')
const shipmentId = `SHIP-${sequence}-${marker}`.slice(0, 64)
const referenceId = `REF-${sequence}-${marker}`.slice(0, 64)
@@ -282,18 +314,10 @@ export function buildOrderPayload({ marker, index, profile, master, product, pac
amazonWarehouseCode: master.destination.warehouseCode,
shipmentId,
referenceId,
sender: options.pickupMethod === 'PICKUP' ? {
companyName,
contactName: '订单测试联系人',
phone: '13800138000',
email: 'pending-order@example.com',
countryCode: 'CN',
province: options.senderLocation.province,
city: options.senderLocation.city,
district: options.senderLocation.district,
addressLine: `${marker} 固定客户测试地址`,
postalCode: options.senderLocation.postalCode,
} : null,
requestedPickupAt: options.pickupMethod === 'PICKUP'
? new Date(Date.now() + 7 * 86_400_000).toISOString().slice(0, 19) : null,
senderAddressId: options.pickupMethod === 'PICKUP' ? pickupAddressId : null,
sender: null,
receiver: null,
cargoes: [{
skuNo: `SKU-${sequence}-${marker}`.slice(0, 64),
@@ -325,6 +349,7 @@ export function buildOrderPayload({ marker, index, profile, master, product, pac
referenceId,
upcNo: `${Date.now()}${sequence}`.slice(-12),
productImageFileId,
woodenProduct: false,
dangerousGoods: false,
cargoRemark: `待审核订单货物 ${sequence} ${marker}`,
}],
@@ -383,6 +408,7 @@ export async function main(argv = process.argv.slice(2)) {
const routePool = await loadPricedRoutes(gateway, timeoutMs, token)
const productImageFileId = await uploadProductImage(gateway, timeoutMs, token, marker)
const pickupAddressId = await ensurePickupAddress(gateway, timeoutMs, token, profile, marker)
const randomizedProducts = shuffled(PRODUCT_CATALOG)
const sameChannel = args['same-channel'] === true
const randomizedRoutes = sameChannel ? selectSameChannelRoutes(routePool) : diversifyRoutes(routePool)
@@ -392,7 +418,7 @@ export async function main(argv = process.argv.slice(2)) {
const product = randomizedProducts[(index - 1) % randomizedProducts.length]
const packageCount = randomInt(1, 31)
const options = randomOrderOptions()
const payload = buildOrderPayload({ marker, index, profile, master, product, packageCount, options, productImageFileId })
const payload = buildOrderPayload({ marker, index, profile, master, product, packageCount, options, productImageFileId, pickupAddressId })
const createResponse = await request(gateway, timeoutMs, 'POST',
'/api/merchant/v1/orders/first-leg', {
token,