diff --git a/inventory-web/src/api/common/users.ts b/inventory-web/src/api/common/users.ts new file mode 100644 index 0000000..56077c3 --- /dev/null +++ b/inventory-web/src/api/common/users.ts @@ -0,0 +1,20 @@ +import request from '@/utils/request' + +/** + * 在职人员名单(id + 姓名)—— 「选择某人」类下拉框的共用数据源。 + * + * 使用场景:借出/转交/归还的借用人选择、出库退回补发的「补发给谁」等。 + * + * ★ 为什么不复用 transaction.ts 里的 getBorrowUsers: + * 那条路径(/transactions/borrow/users)在语义上属于借库模块,出库补发直接 + * 复用会让后人困惑「出库为什么在调借库的接口」。后端两者共用同一份实现, + * 前端各走各的中性/专用入口。 + * + * ★ 公司隔离与服务端同口径;只返回 id 与姓名,不含邮箱/角色/部门。 + */ +export function getActiveUsers() { + return request({ + url: '/v1/common/active-users', + method: 'get' + }) +} diff --git a/inventory-web/src/api/inbound/return.ts b/inventory-web/src/api/inbound/return.ts index 54678f7..81a511c 100644 --- a/inventory-web/src/api/inbound/return.ts +++ b/inventory-web/src/api/inbound/return.ts @@ -20,11 +20,13 @@ import request from '@/utils/request' * reason: string 可选,退回原因 * need_reissue: boolean 可选,退回后是否自动生成补发单(默认 false) * reissue_qty: number 可选,补发数量,默认 = return_qty + * reissue_applicant_id: number 可选,**补发给谁**;不传则回退为当前操作人 * } * - * ★ 补发(need_reissue=true):后端直接生成一张**免审批**出库单并关联回本笔退回, - * 申请人取**当前操作人**(trans_outbound 没有申请人字段,也无指回原审批单的 - * 关联,无法可靠判定原申请人;原领用人写入备注)。 + * ★ 补发(need_reissue=true):后端直接生成一张**免审批**出库单并关联回本笔退回。 + * 申请人优先取 reissue_applicant_id(前端选择的「补发给谁」),未传则回退为 + * 当前操作人 —— trans_outbound 没有申请人字段,也无指回原审批单的关联, + * 无法可靠推断原申请人(按姓名反查会重名错绑),故把选择权交给现场。 * ★ 补发库存不足时**整笔退回一并回滚**并返回明确提示 —— 取消勾选即可只做退回过账。 * * @returns data.reissue 为 { id, request_no, quantity } 或 null @@ -36,6 +38,7 @@ export function returnFromOutbound(data: { reason?: string need_reissue?: boolean reissue_qty?: number + reissue_applicant_id?: number }) { return request({ url: '/inbound/stock/return-from-outbound', diff --git a/inventory-web/src/views/outbound/index.vue b/inventory-web/src/views/outbound/index.vue index b19ef36..cf20a93 100644 --- a/inventory-web/src/views/outbound/index.vue +++ b/inventory-web/src/views/outbound/index.vue @@ -295,6 +295,21 @@ style="width: 200px" /> + + + + + + + 补发单会挂在此人名下,出现在他的「我的申请」里。留空则挂当前操作人。 + + @@ -313,6 +328,7 @@ import { ref, computed, onMounted, reactive, onBeforeUnmount } from 'vue' import { ElMessage } from 'element-plus' import { getOutboundList } from '@/api/outbound' import { returnFromOutbound } from '@/api/inbound/return' +import { getActiveUsers } from '@/api/common/users' import { formatQty, normalizeQty } from '@/utils/format' import { Picture } from '@element-plus/icons-vue' import { useUserStore } from '@/stores/user' @@ -530,12 +546,40 @@ const returnDialog = reactive({ // 补发:默认**不勾选** —— 有些退回是项目结束退还,根本不需要补 need_reissue: false, reissue_qty: 1, + // 补发给谁:留空则由后端回退为当前操作人 + reissue_applicant_id: null as number | null, }, }) -// 勾选补发时,默认补发量 = 本次退回量(最常见的情况),用户可再调小 -const handleNeedReissueChange = (val: boolean) => { - if (val) returnDialog.form.reissue_qty = normalizeQty(returnDialog.form.return_qty) || 1 +// 补发人员名单:勾选补发时才加载(多数退回不需要补,避免无谓请求) +const reissueUsers = ref>([]) +let reissueUsersLoaded = false + +const loadReissueUsers = async () => { + if (reissueUsersLoaded) return + try { + const res: any = await getActiveUsers() + reissueUsers.value = res?.data || [] + reissueUsersLoaded = true + } catch { + reissueUsers.value = [] + } +} + +// 勾选补发时:默认补发量 = 本次退回量,并尝试按**原领用人**预选「补发给谁」 +const handleNeedReissueChange = async (val: boolean) => { + if (!val) return + returnDialog.form.reissue_qty = normalizeQty(returnDialog.form.return_qty) || 1 + await loadReissueUsers() + if (returnDialog.form.reissue_applicant_id) return + // 按姓名唯一命中才预填;重名一律留空让现场自己选 —— 与借用人回填同口径, + // 宁可多一步,也不猜错人(补发单会挂到错的人名下)。 + const want = String(returnDialog.row?.consumer_name || '').split('/')[0].trim() + if (!want) return + const hits = reissueUsers.value.filter( + (u) => String(u.name || '').split('/')[0].trim() === want, + ) + if (hits.length === 1) returnDialog.form.reissue_applicant_id = hits[0].id } const openReturnDialog = (row: any) => { @@ -547,6 +591,7 @@ const openReturnDialog = (row: any) => { returnDialog.form.reason = '' returnDialog.form.need_reissue = false returnDialog.form.reissue_qty = 1 + returnDialog.form.reissue_applicant_id = null returnDialog.visible = true } @@ -558,6 +603,7 @@ const resetReturnDialog = () => { returnDialog.form.reason = '' returnDialog.form.need_reissue = false returnDialog.form.reissue_qty = 1 + returnDialog.form.reissue_applicant_id = null } const submitReturn = async () => { @@ -603,6 +649,10 @@ const submitReturn = async () => { reason, need_reissue: needReissue, reissue_qty: needReissue ? reissueQty : undefined, + // 留空则由后端回退为当前操作人 + reissue_applicant_id: needReissue + ? (returnDialog.form.reissue_applicant_id ?? undefined) + : undefined, }) ElMessage.success(res?.msg || '退回成功') returnDialog.visible = false