From fd99d33a0dff39458faf756fd769137f3bd54264 Mon Sep 17 00:00:00 2001 From: yueli Date: Wed, 16 Sep 2026 15:45:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(return):=20=E5=89=8D=E7=AB=AF=E9=80=80?= =?UTF-8?q?=E5=9B=9E=E5=85=A5=E5=8F=A3=E4=B8=8E=E4=B8=8D=E8=89=AF=E5=93=81?= =?UTF-8?q?=E5=9C=A8=E7=AE=A1=E5=8F=B0=E8=B4=A6=E7=9C=8B=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 出库记录页(views/outbound/index.vue): - 明细行新增「退回」列,returnable_quantity <= 0 时按钮置灰,行内显示「已退 N」 - 对话框展示 原出库数量 / 已退回数量 / 本次可退最大,默认带入可退最大值 - 退回类型用下拉单选:良品(加回库存)/ 不良品(转入异常待处理) - 退回原因必填,提交前三重校验;按钮 :loading + 函数内 submitting 双保险防抖 - 成功后刷新列表。错误提示不重复弹——request 拦截器对 HTTP 400 已取 data.msg 展示,对话框 catch 只收尾 配套后端(services/outbound_service.py): - get_grouped_list 的出库明细补 id / returned_quantity / returnable_quantity。 原先明细不带 id,退回接口无从指定 outbound_id 新增页面(views/stock/defective/index.vue,路由 /inventory/defective): - 展示 物料名称/规格/SKU/退回时间/操作人/退回总数/剩余待处理/状态 - 顶部 alert 提示在管总量,并明确「这批实物不在库存表中,盘点请以本台账 为准」——在管坏件对盘点不可见是本方案的固有盲区,必须在页面上主动提醒 - 仅对 remaining_qty > 0 的行提供「修复回库」「报废销毁」,终态行显示已结案 - 两个弹窗均带数量上限约束与 loading 防抖,成功后刷新 新增 api/inbound/return.ts 承载四个逆向物流接口。 侧边栏由 router/index.ts 驱动,加路由即入菜单;注意侧边栏只过滤 meta.hidden、不看 meta.permission,故菜单对所有角色可见,访问控制由后端 接口负责(与既有「维修管理」一致)。 --- inventory-web/src/api/inbound/return.ts | 86 ++++ inventory-web/src/router/index.ts | 8 + inventory-web/src/views/outbound/index.vue | 189 +++++++- .../src/views/stock/defective/index.vue | 448 ++++++++++++++++++ 4 files changed, 730 insertions(+), 1 deletion(-) create mode 100644 inventory-web/src/api/inbound/return.ts create mode 100644 inventory-web/src/views/stock/defective/index.vue diff --git a/inventory-web/src/api/inbound/return.ts b/inventory-web/src/api/inbound/return.ts new file mode 100644 index 0000000..9d7b6f5 --- /dev/null +++ b/inventory-web/src/api/inbound/return.ts @@ -0,0 +1,86 @@ +import request from '@/utils/request' + +// ============================================================================ +// 逆向物流(原单退回 + 不良品在管台账) +// +// 后端路由见 inventory-backend/app/api/v1/inbound/stock.py +// 设计要点: +// · 良品退回 → 直接加回原库存行 +// · 不良品退回 → 不进库存表,转入 trans_defective_goods 在管台账, +// 修好后回库 / 无法维修则报废销毁 +// ============================================================================ + +/** + * 原单退回。 + * + * @param data { + * outbound_id: number 必填,trans_outbound.id(出库**明细行**主键,非单号) + * return_qty: number 必填,本次退回数量(>0) + * is_defective: boolean 必填,true=不良品转在管台账,false=良品加回库存 + * reason: string 可选,退回原因 + * } + */ +export function returnFromOutbound(data: { + outbound_id: number + return_qty: number + is_defective: boolean + reason?: string +}) { + return request({ + url: '/inbound/stock/return-from-outbound', + method: 'post', + data + }) +} + +/** + * 不良品在管台账分页查询。 + * + * @param params { page, page_size, status?, keyword?, start_date?, end_date? } + * status 传 '全部' 或留空表示不过滤 + */ +export function getDefectiveList(params: { + page?: number + page_size?: number + status?: string + keyword?: string + start_date?: string + end_date?: string + company_name?: string +}) { + return request({ + url: '/inbound/stock/defective', + method: 'get', + params + }) +} + +/** + * 修复回库:把修好的数量加回原库存行。 + * + * @param id 在管台账 id + * @param data { restock_qty?: number, remark?: string } + * restock_qty 缺省 = 全部剩余在管量 + */ +export function restockDefective(id: number, data: { restock_qty?: number; remark?: string }) { + return request({ + url: `/inbound/stock/defective/${id}/restock`, + method: 'post', + data + }) +} + +/** + * 报废销毁:在管坏件确认无法维修时销毁。 + * + * @param id 在管台账 id + * @param data { scrap_qty?: number, reason: string } + * reason 必填;scrap_qty 缺省 = 全部剩余在管量 + */ +export function scrapDefective(id: number, data: { scrap_qty?: number; reason: string }) { + return request({ + url: `/inbound/stock/defective/${id}/scrap`, + method: 'post', + data + }) +} diff --git a/inventory-web/src/router/index.ts b/inventory-web/src/router/index.ts index 87de087..382d5a1 100644 --- a/inventory-web/src/router/index.ts +++ b/inventory-web/src/router/index.ts @@ -106,6 +106,14 @@ const routes: Array = [ name: 'RepairManagement', component: () => import('@/views/stock/inbound/repair.vue'), meta: { title: '维修管理', permission: 'inbound_repair' } + }, + // ★ 不良品在管台账(逆向物流):退回的坏件不入库存表, + // 实物在仓但不在库存行中,故单独成页承载其去向与处置。 + { + path: 'defective', + name: 'DefectiveGoods', + component: () => import('@/views/stock/defective/index.vue'), + meta: { title: '不良品在管台账', permission: 'inventory_stocktake' } } ] }, diff --git a/inventory-web/src/views/outbound/index.vue b/inventory-web/src/views/outbound/index.vue index 9f09a7e..8c9c88e 100644 --- a/inventory-web/src/views/outbound/index.vue +++ b/inventory-web/src/views/outbound/index.vue @@ -120,6 +120,28 @@ ¥{{ row.subtotal.toFixed(2) }} + + + + + @@ -183,18 +205,94 @@ @current-change="handlePageChange" /> + + + + + + + {{ returnDialog.row?.name || '-' }} + / {{ returnDialog.row?.sku || '-' }} + + + + {{ returnDialog.row?.quantity ?? 0 }} + + + {{ returnDialog.row?.returned_quantity ?? 0 }} + + + + {{ returnDialog.row?.returnable_quantity ?? 0 }} + + + + + + + + + + + + + + + + + + + + + + +