feat(outbound): 退回弹窗增加「补发给谁」选择器
· 勾选「需要补发」后出现「补发给谁」下拉(filterable + clearable), 并自动带上补发数量。 · 预填策略:按原领用人 consumer_name **唯一命中**才预选;重名一律留空让现场 自己选 —— 与借用人回填同口径,宁可多一步也不猜错人(补发单会挂到错的人名下)。 · 留空时后端回退为当前操作人,文案已写明。 · 人员名单**勾选补发时才加载**(多数退回不需要补,避免无谓请求),加载后缓存。 · 新增 api/common/users.ts 的 getActiveUsers():走中性的 /v1/common/active-users,而不是复用借库专用路径。
This commit is contained in:
20
inventory-web/src/api/common/users.ts
Normal file
20
inventory-web/src/api/common/users.ts
Normal file
@ -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'
|
||||
})
|
||||
}
|
||||
@ -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',
|
||||
|
||||
@ -295,6 +295,21 @@
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="补发给谁" v-if="returnDialog.form.need_reissue">
|
||||
<el-select
|
||||
v-model="returnDialog.form.reissue_applicant_id"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="默认取原领用人;找不到时留空"
|
||||
style="width: 260px"
|
||||
>
|
||||
<el-option v-for="u in reissueUsers" :key="u.id" :label="u.name" :value="u.id" />
|
||||
</el-select>
|
||||
<div style="color:#909399; font-size:12px; margin-top:4px;">
|
||||
补发单会挂在此人名下,出现在他的「我的申请」里。<strong>留空</strong>则挂当前操作人。
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@ -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<Array<{ id: number; name: string }>>([])
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user