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:
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 = []
|
||||
|
||||
Reference in new issue
Block a user