From 54e49e24267cea247f0f10234c98b919523cb0d7 Mon Sep 17 00:00:00 2001
From: ouyangxq <775153912@qq.com>
Date: Thu, 22 Oct 2026 23:06:06 +0800
Subject: [PATCH] fix: complete October 22 workflow feedback and request
failure recovery
---
docs/business-index.md | 2 +-
src/api/dispatch-loading-documents.js | 1 -
src/api/overseas.js | 14 +-
src/components/DispatchLoadingDocuments.vue | 75 +++-----
src/components/RelabelPalletWork.vue | 6 +-
src/components/ReturnBoxMergeWork.vue | 7 +-
src/components/ReturnRelabelPackWork.vue | 4 +-
src/pages/dispatch/dispatch.vue | 150 +++++++++++----
src/pages/move/move.vue | 4 +-
src/pages/outbound/outbound.vue | 8 +-
src/pages/pallet/pallet.vue | 2 +-
src/pages/relabel/relabel.vue | 20 +-
src/pages/return-packing/return-packing.vue | 4 +-
src/pages/return-receipt/return-receipt.vue | 78 ++++----
src/pages/stocktake/stocktake.vue | 10 +-
.../warehouse-transfer/warehouse-transfer.vue | 12 +-
src/stores/fulfillment.js | 58 +-----
src/stores/warehouse-work.js | 33 ++--
tests/dispatch-loading-documents.test.mjs | 79 ++++----
tests/dispatch-presentation.test.mjs | 30 +++
tests/dispatch-workflow.test.mjs | 174 +++++++-----------
tests/fulfillment-workflows.test.mjs | 13 +-
tests/overseas-request.test.mjs | 43 +++++
tests/project-contract.test.mjs | 4 +-
tests/return-box-merge-work.test.mjs | 35 +++-
tests/return-receipt-api.test.mjs | 2 +-
tests/return-receipt-page.test.mjs | 68 ++++++-
tests/warehouse-workflows.test.mjs | 7 +-
28 files changed, 530 insertions(+), 413 deletions(-)
create mode 100644 tests/dispatch-presentation.test.mjs
diff --git a/docs/business-index.md b/docs/business-index.md
index 419844c..aff014f 100644
--- a/docs/business-index.md
+++ b/docs/business-index.md
@@ -17,7 +17,7 @@
| 海外仓工作台与作业入口 | `src/pages/home/home.vue` | `src/data/overseas-workbench.js` 是分组与作业可用性入口;首页直接进入各作业,页面刷新后返回首页;首页通过 `/api/pda/v1/last-leg/receiving-containers/warehouse-profile` 读取 Token 绑定仓的中文主档名称 |
| 中英西语言设置 | `src/i18n/index.js`、`src/i18n/locales/`、`src/pages/profile/profile.vue` | 个人中心可选择并持久化 `zh-CN`、`en`、`es`;当前业务翻译资源仍为空,页面业务文案继续使用中文,不得把语言选择入口误报为全量翻译完成 |
| 柜号签收、照片与入仓真实作业 | `src/pages/operation/operation.vue`、`src/components/ReceivingSessionSummary.vue`、`src/api/inbound.js`、`src/api/receiving-adapter.js`、`src/api/overseas.js`、`src/stores/receiving.js` | 签收前展开显示国内空仓、半仓、满仓、锁仓和带锁码五类整柜只读照片,收货中折叠查看,单图加载失败只允许重试且不阻断拆柜;海外三个固定照片角色各一张,支持现场拍照、鉴权预览及更换失败保留原图;多计划同柜直接展示服务端 `assigned/mergeAllowed/urgent/mergeHint`,合托明确为现场可选而非完成门禁;扫码实收确认计划生成阶段已预留的真实托盘和库位,校验卡展示预留库位编码及 `A0` 共享溢出位提示,不在设备端重新分配。Backend `lastleg-service/inboundplan/pda/controller/ReceivingContainerController.java`、`ReceivingContainerService.java`,公网前缀 `/api/pda/v1/last-leg/receiving-containers/**` |
-| 退货入库签收与合箱 | `src/pages/return-receipt/return-receipt.vue`、`src/pages/return-packing/return-packing.vue`、`src/api/return-receipt.js`、`src/api/return-packing.js`、`src/stores/warehouse-work.js` | 签收优先扫描退货单号,也可扫描 SKU 后选择候选退货单,按本包实际 SKU 数量生成退货箱与计费批次;合箱只选择同客户已完成退货单的可用库存并录入新箱箱规;公网前缀 `/api/pda/v1/last-leg/return-receipts/**`、`/api/pda/v1/last-leg/return-inventory/**` |
+| 退货入库签收与合箱 | `src/pages/return-receipt/return-receipt.vue`、`src/pages/return-packing/return-packing.vue`、`src/api/return-receipt.js`、`src/api/return-packing.js`、`src/stores/warehouse-work.js` | 签收优先扫描退货单号,也可扫描 SKU 后选择候选退货单,按本包实际 SKU 数量生成退货箱与计费批次;刷新时服务端实收已变化须清空旧实物输入,未变化保留可编辑草稿;合箱只选择同客户已完成退货单的可用库存并录入新箱箱规;公网前缀 `/api/pda/v1/last-leg/return-receipts/**`、`/api/pda/v1/last-leg/return-inventory/**` |
| 退货箱内清点 | `src/pages/return-counting/return-counting.vue`、`src/api/return-counting.js` | 扫描箱号或托盘号定位清点任务;各箱 SKU 汇总与签收数量核平,支持恢复当前任务;页面注册见 `src/pages.json` |
| 仓储转运测量、打托与标签 | `src/pages/warehouse-transfer/warehouse-transfer.vue`、`src/api/warehouse-transfers.js` | 工作台键 `warehouseTransfer`;候选→详情→逐托测量草稿→生成新托盘号→扫码绑定→照片与完成打托。API 模块路径 `/pda/v1/last-leg/warehouse-transfers` 经统一海外请求层处理;不是 Admin 转运审核或排车转派送。回归 `tests/warehouse-transfer-api.test.mjs` |
| 托盘管理真实作业 | `src/pages/pallet/pallet.vue`、`src/api/pallet.js` | 扫码查询托盘内容,按服务端返回的托盘/库存版本执行组托、拆托、换托和解绑;公网前缀 `/api/pda/v1/last-leg/pallet-operations/**` |
diff --git a/src/api/dispatch-loading-documents.js b/src/api/dispatch-loading-documents.js
index f355e9d..07b188d 100644
--- a/src/api/dispatch-loading-documents.js
+++ b/src/api/dispatch-loading-documents.js
@@ -21,6 +21,5 @@ export function normalizeLoadingDocuments(value, no) {
}
export async function getLoadingDocuments(no) { return normalizeLoadingDocuments(await overseasRequest('GET', path(no)), no) }
export function uploadLoadingPhoto(no, slot, filePath, key) { return overseasUpload(`${slotPath(no, slot)}/uploads?idempotencyKey=${encodeURIComponent(key)}`, filePath) }
-export function recoverLoadingPhoto(no, key) { return overseasRequest('GET', `${path(no)}/uploads/${encodeURIComponent(key)}`) }
export async function bindLoadingPhoto(no, slot, body) { return normalizeLoadingDocuments(await overseasRequest('PUT', slotPath(no, slot), body), no) }
export function readLoadingPhoto(no, photo) { return overseasDownload(`${slotPath(no, photo.slot)}/files/${encodeURIComponent(photo.fileId)}/content`, { expectedContentTypePrefix: 'image/' }) }
diff --git a/src/api/overseas.js b/src/api/overseas.js
index 3966a6f..1f618eb 100644
--- a/src/api/overseas.js
+++ b/src/api/overseas.js
@@ -135,12 +135,22 @@ function rawUpload(path, filePath, name, token) {
const request = new XMLHttpRequest()
request.open('POST', url)
request.setRequestHeader('Authorization', `Bearer ${token}`)
+ request.timeout = 60000
request.onload = () => resolve({ statusCode: request.status, data: request.responseText, header: {} })
request.onerror = () => reject(new Error('海外作业文件上传失败'))
+ request.ontimeout = () => reject(new Error('照片上传超时,请重试'))
+ request.onabort = () => reject(new Error('照片上传已中断,请重试'))
request.send(form)
})
- const response = await fetch(url, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form })
- return { statusCode: response.status, data: await response.text(), header: Object.fromEntries(response.headers.entries()) }
+ const controller = new AbortController()
+ const timeout = setTimeout(() => controller.abort(), 60000)
+ try {
+ const response = await fetch(url, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form, signal: controller.signal })
+ return { statusCode: response.status, data: await response.text(), header: Object.fromEntries(response.headers.entries()) }
+ } catch (cause) {
+ if (controller.signal.aborted) throw new Error('照片上传超时,请重试')
+ throw cause
+ } finally { clearTimeout(timeout) }
})
.catch((cause) => { throw Object.assign(new Error(cause.message || '海外作业文件上传失败'), { network: true, uploadUrl: url }) })
}
diff --git a/src/components/DispatchLoadingDocuments.vue b/src/components/DispatchLoadingDocuments.vue
index b77428f..3db4448 100644
--- a/src/components/DispatchLoadingDocuments.vue
+++ b/src/components/DispatchLoadingDocuments.vue
@@ -8,21 +8,20 @@
可边装车边上传;确认装车完成且照片齐全后自动进入派送中。
上传并保存 5 张装车照片后,本车自动进入派送中。
{{ error.message }}requestId:{{ error.requestId }}traceId:{{ error.traceId }}
- 有装车照片尚未确认保存。
-
-
- 查看大图
+
+
+ 查看大图
@@ -32,28 +31,18 @@