fix(web): limit protocol managers to active region leaders

Provide tenant-scoped leader options for the Web protocol form, exclude ordinary members and retain historical names only for display. Default only to a leader of the selected region and prevent delayed requests from replacing manual choices.

Refs #1. Add backend option isolation and Web cascade regression coverage.
This commit is contained in:
zlwu committed 2026-10-30 17:47:43 +08:00
1 parent f6cfce3315
commit d1347e8cea
6 files changed
+300 -61

No files matched your search

@@ -154,10 +154,21 @@
clearable
reserve-keyword
:remote-method="remoteSearchManagerUsers"
@visible-change="(visible: boolean) => visible && remoteSearchManagerUsers('')"
:loading="managerLoading"
placeholder="默认取地区负责人,可修改"
@change="onManagerUserChange"
>
<el-option
v-if="
managerSnapshot &&
!managerUserOptions.some((u) => u.id === managerSnapshot?.id)
"
v-show="false"
:label="managerSnapshot.nickName"
:value="managerSnapshot.id"
disabled
/>
<el-option
v-for="u in managerUserOptions"
:key="u.id"
@@ -1162,6 +1173,7 @@
} from '@element-plus/icons-vue'
import {
fetchCollectionProtocolDetail,
fetchProtocolRegionManagers,
fetchCreateCollectionProtocol,
fetchUpdateCollectionProtocol,
fetchSubmitReceiptFinance,
@@ -1188,7 +1200,6 @@
fetchItemUnitList,
fetchCollectionRegionList,
fetchHospitalList,
fetchRegionStaffList,
fetchRegionsByStaffUser,
fetchSampleCodeList,
fetchExpressCompanyList,
@@ -1308,7 +1319,9 @@
const salesSnapshot = ref<Api.User.UserItem | null>(null)
const regionManagerUserId = ref<string | null>(null)
const managerUserOptions = ref<Api.User.UserItem[]>([])
const managerUserOptions = ref<Array<Api.User.UserItem & { regionIds: string[] }>>([])
let managerSearchVersion = 0
let managerDefaultVersion = 0
const managerLoading = ref(false)
const managerSnapshot = ref<Api.User.UserItem | null>(null)
const linkedRegionMode = ref(false)
@@ -1607,6 +1620,9 @@
}
function resetForm() {
managerSearchVersion++
managerDefaultVersion++
managerLoading.value = false
Object.assign(formData, {
protocolNo: '',
protocolNoId: '',
@@ -2729,7 +2745,6 @@
(user) => {
managerSnapshot.value = { ...user }
regionManagerUserId.value = user.id
managerUserOptions.value = [{ ...user }]
formData.regionManagerUserId = user.id
},
() => {
@@ -2739,6 +2754,7 @@
formData.regionManagerUserId = ''
}
)
await remoteSearchManagerUsers('')
}
function makeManagerUserStub(id: string, name: string): Api.User.UserItem {
@@ -2974,28 +2990,29 @@
}
async function remoteSearchManagerUsers(query: string) {
const version = ++managerSearchVersion
managerLoading.value = true
try {
const res = await fetchUserList({
page: 1,
pageSize: 50,
keyword: (query || '').trim() || undefined,
status: '1'
})
let list = [...(res.list || [])]
const cur = regionManagerUserId.value
if (cur && !list.some((x) => x.id === cur)) {
const keep =
managerSnapshot.value?.id === cur
? managerSnapshot.value
: managerUserOptions.value.find((x) => x.id === cur)
if (keep) list = [keep, ...list]
const res = await fetchProtocolRegionManagers()
const keyword = (query || '').trim().toLowerCase()
const list = (res.list || []).map((item) => ({
...makeManagerUserStub(item.id, item.nickName),
regionIds: item.regionIds
}))
if (version === managerSearchVersion) {
managerUserOptions.value = list.filter((item) =>
item.nickName.toLowerCase().includes(keyword)
)
}
managerUserOptions.value = list
return list
} catch {
managerUserOptions.value = []
if (version === managerSearchVersion) {
managerUserOptions.value = []
ElMessage.error('地区负责人加载失败,请重试')
}
return []
} finally {
managerLoading.value = false
if (version === managerSearchVersion) managerLoading.value = false
}
}
@@ -3016,53 +3033,34 @@
}
function onManagerUserChange(val: string | null | undefined) {
managerDefaultVersion++
if (!val) {
regionManagerUserId.value = null
managerSnapshot.value = null
formData.regionManagerUserId = ''
return
}
const u = managerUserOptions.value.find((x) => x.id === val) || managerSnapshot.value
if (!u) {
regionManagerUserId.value = val
formData.regionManagerUserId = val
return
}
const u = managerUserOptions.value.find((x) => x.id === val)
if (!u) return
managerSnapshot.value = { ...u }
regionManagerUserId.value = u.id
formData.regionManagerUserId = u.id
}
async function applyDefaultRegionManager(regionId: string) {
if (!regionId) {
regionManagerUserId.value = null
formData.regionManagerUserId = ''
managerUserOptions.value = []
managerSnapshot.value = null
return
}
try {
const res: any = await fetchRegionStaffList(regionId, { page: 1, pageSize: 100 })
const list = (res?.list || []) as Array<Record<string, any>>
const leader = list.find((x) => x.isLeader) || list[0]
if (!leader?.userId) {
regionManagerUserId.value = null
formData.regionManagerUserId = ''
return
}
const stub = makeManagerUserStub(
String(leader.userId),
String(leader.nickName || leader.userName || '')
)
regionManagerUserId.value = stub.id
formData.regionManagerUserId = stub.id
managerSnapshot.value = { ...stub }
if (!managerUserOptions.value.some((x) => x.id === stub.id)) {
managerUserOptions.value = [stub, ...managerUserOptions.value]
}
} catch {
/* 地区无人员配置时留空,可手工选择 */
}
if (formData.regionId !== regionId) return
const version = ++managerDefaultVersion
regionManagerUserId.value = null
formData.regionManagerUserId = ''
managerSnapshot.value = null
if (!regionId) return
const list = await remoteSearchManagerUsers('')
if (version !== managerDefaultVersion || formData.regionId !== regionId) return
const leader = list.find((item) => item.regionIds.includes(regionId))
if (!leader) return
regionManagerUserId.value = leader.id
formData.regionManagerUserId = leader.id
managerSnapshot.value = { ...leader }
}
async function applyRegionsForSalesUser(
@@ -3112,10 +3110,10 @@
if (regionChanged) {
formData.hospitalId = ''
hospitalOptions.value = []
await loadHospitalsByRegion(nextId, '')
if (!opts?.skipManagerDefault) {
await applyDefaultRegionManager(nextId)
}
await Promise.all([
loadHospitalsByRegion(nextId, ''),
...(opts?.skipManagerDefault ? [] : [applyDefaultRegionManager(nextId)])
])
} else if (!opts?.skipManagerDefault && !formData.regionManagerUserId) {
await applyDefaultRegionManager(nextId)
}
@@ -3246,6 +3244,7 @@
}
async function onRegionChange(val: string | null | undefined) {
managerDefaultVersion++
if (!val) {
formData.regionId = ''
hospitalOptions.value = []
@@ -3259,11 +3258,11 @@
formData.regionId = val
formData.hospitalId = ''
hospitalOptions.value = []
await loadHospitalsByRegion(val)
await applyDefaultRegionManager(val)
await Promise.all([loadHospitalsByRegion(val), applyDefaultRegionManager(val)])
}
function onRegionClear() {
managerDefaultVersion++
formData.regionId = ''
formData.hospitalId = ''
hospitalOptions.value = []