test(acceptance): reuse fixed customers and align native fulfillment flows

This commit is contained in:
2026-10-23 04:48:02 +08:00
parent b92f7fe991
commit 139f6b1932
51 changed files with 1076 additions and 228 deletions
@@ -51,7 +51,7 @@ async function discoverTrip(context, module, proof) {
for (let page = 1; ; page++) {
const query = new URLSearchParams({ page: String(page), size: '200', keyword: vehiclePlate, warehouseId: proof.warehouseId })
const data = await command(context, module, 'GET', `${BASE}/trips?${query}`, undefined, '按实际车牌读取自动资源记录')
if (!Array.isArray(data.records) || !Number.isSafeInteger(Number(data.total)) || Number(data.total) < 0
if (!Array.isArray(data.records) || data.total == null || data.total === '' || !Number.isSafeInteger(Number(data.total)) || Number(data.total) < 0
|| Number(data.page) !== page || Number(data.size) !== 200) throw new Error('车次分页不完整,不能证明唯一关联')
total ??= Number(data.total)
if (Number(data.total) !== total || data.records.length > 200 || (!data.records.length && rows.length < total)) throw new Error('车次分页变化或缺页')
@@ -83,9 +83,28 @@ export async function reuseFleetResources(context, module, proof, arrival) {
const pairs = context.options.fixedFleetResources
const busy = (context.createdResources.fleetTrips || []).filter(item => item !== proof
&& item.closure?.status !== 'CARGO_COMPLETED_AND_RESOURCES_RELEASED')
const pair = Array.isArray(pairs) && pairs.find(item => /^[1-9][0-9]*$/.test(id(item?.vehicleId))
const localPairs = Array.isArray(pairs) ? pairs.filter(item => /^[1-9][0-9]*$/.test(id(item?.vehicleId))
&& /^[1-9][0-9]*$/.test(id(item?.driverId))
&& !busy.some(trip => id(trip.vehicleId) === id(item.vehicleId) || id(trip.driverId) === id(item.driverId)))
&& !busy.some(trip => id(trip.vehicleId) === id(item.vehicleId) || id(trip.driverId) === id(item.driverId))) : []
if (!localPairs.length) throw Error('缺少本轮可用的固定车辆司机组合;禁止自动新建主档或证照')
const trips = [], seen = new Set(); let total
for (let page = 1; page <= 100; page++) {
const data = await command(context, module, 'GET', `${BASE}/trips?page=${page}&size=200`, undefined, '核对共享环境车辆司机占用')
if (!Array.isArray(data.records) || !Number.isSafeInteger(Number(data.total)) || Number(data.total) < 0
|| Number(data.page) !== page || Number(data.size) !== 200) throw Error('固定车辆司机占用分页无效')
total ??= Number(data.total)
if (Number(data.total) !== total || data.records.length > 200 || (!data.records.length && trips.length < total))
throw Error('固定车辆司机占用分页变化或缺页')
for (const row of data.records) {
if (!row.tripNo || seen.has(row.tripNo)) throw Error('固定车辆司机占用车次重复或缺少业务号')
seen.add(row.tripNo); trips.push(row)
}
if (trips.length >= total) break
}
if (trips.length !== total) throw Error('固定车辆司机占用分页不完整')
const pair = localPairs.find(item => !trips.some(trip => trip.status !== 'CANCELLED'
&& ((id(trip.vehicleId) === id(item.vehicleId) && !trip.vehicleRelease?.actualEndAt)
|| (id(trip.driverId) === id(item.driverId) && !trip.driverRelease?.actualEndAt))))
if (!pair) throw Error('缺少本轮可用的固定车辆司机组合;禁止自动新建主档或证照')
proof.expectedDriverEndAt = new Date(Math.max(Date.now() + 48 * 3600000, arrival ? Date.parse(arrival) + 6 * 3600000 : 0)).toISOString()
const vehicle = await command(context, module, 'GET', `/api/platform/v1/last-leg/master-data/vehicles/${id(pair.vehicleId)}`, undefined, '核对固定车辆状态')
@@ -145,7 +164,17 @@ export async function prepareFleetTrip(context, module, dispatchNo, warehouseId)
upload.fileId = id(file.fileId)
await context.checkpoint?.()
}
const maintenance = structuredClone(before.vehicleInfo?.maintenance || {})
const appointments = new Map((maintenance.destinationAppointments || []).map(row => [row.destinationKey, row]))
for (const row of before.dispatchInfo?.fbaAppointments || []) {
if (!row.destinationKey || !row.destinationWarehouseCode) continue
const existing = row.appointmentNo || appointments.get(row.destinationKey)?.appointmentNo
appointments.set(row.destinationKey, { destinationKey: row.destinationKey,
appointmentNo: existing || `TEST-${proof.marker}-${row.destinationWarehouseCode}`.slice(0, 128) })
}
maintenance.destinationAppointments = [...appointments.values()]
proof.updateRequest = { recordVersion: before.recordVersion, idempotencyKey: key(proof, 'EDIT'),
maintenance,
publishLooseboardDemand: before.publishLooseboardDemand,
vehicle: { mode: 'MASTER', vehicleId: proof.vehicleId, evidenceFileIds: [proof.reviewPhotos.VEHICLE.fileId] },
driver: { mode: 'MASTER', driverId: proof.driverId, evidence: { expectedTaskEndAt: proof.expectedDriverEndAt,