feat(web-admin): link system user on personnel form
Allow binding a login account on driver/escort personnel so miniprogram driver-plan visibility can resolve by sys_user_id. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
26b096ae38
commit
3dc71788d4
3 files changed
+149
-7
No files matched your search
@@ -30,6 +30,24 @@
|
||||
<el-form-item label="手机号" prop="phoneNo">
|
||||
<el-input v-model="formData.phoneNo" placeholder="请输入手机号(选填)" maxlength="32" />
|
||||
</el-form-item>
|
||||
<el-form-item label="关联用户账号" prop="sysUserId">
|
||||
<el-select
|
||||
v-model="formData.sysUserId"
|
||||
placeholder="可选,绑定小程序登录账号"
|
||||
filterable
|
||||
clearable
|
||||
:loading="userSelectLoading"
|
||||
style="width: 100%"
|
||||
@focus="ensureUserOptions"
|
||||
>
|
||||
<el-option
|
||||
v-for="user in userOptions"
|
||||
:key="user.userId"
|
||||
:label="user.displayName"
|
||||
:value="user.userId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input-number
|
||||
v-model="formData.age"
|
||||
@@ -110,6 +128,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Check, Close } from '@element-plus/icons-vue'
|
||||
import { fetchUserOptions } from '@/api/admin'
|
||||
import { personnelApi, type CertRow, type PersonnelDetail } from '@/api/pl'
|
||||
import AttachmentUploadField from '@/components/business/attachment-upload-field/index.vue'
|
||||
import PlCertFormList from '@/components/business/pl-cert-form-list/index.vue'
|
||||
@@ -185,9 +204,38 @@
|
||||
personnelAffiliation: props.affiliation,
|
||||
status: '1',
|
||||
remark: '',
|
||||
photoUrls: ''
|
||||
photoUrls: '',
|
||||
sysUserId: '' as string
|
||||
})
|
||||
|
||||
const userSelectLoading = ref(false)
|
||||
const userOptions = ref<Array<{ userId: string; nickName: string; displayName: string }>>([])
|
||||
|
||||
async function ensureUserOptions() {
|
||||
if (userOptions.value.length || userSelectLoading.value) return
|
||||
userSelectLoading.value = true
|
||||
try {
|
||||
const res = await fetchUserOptions()
|
||||
const data = (res as any)?.data ?? res
|
||||
userOptions.value = (Array.isArray(data) ? data : [])
|
||||
.map((u: Record<string, unknown>) => {
|
||||
const userId = String(u.value ?? u.id ?? u.userId ?? '')
|
||||
const name = String(u.label ?? u.nickName ?? u.userName ?? userId)
|
||||
const account = String(u.userName ?? u.account ?? '').trim()
|
||||
return {
|
||||
userId,
|
||||
nickName: name,
|
||||
displayName: account && account !== name ? `${name}(${account})` : name
|
||||
}
|
||||
})
|
||||
.filter((u) => u.userId)
|
||||
} catch {
|
||||
userOptions.value = []
|
||||
} finally {
|
||||
userSelectLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const requiredPersonnelCertNames = computed(() =>
|
||||
isCarrierPersonnel.value
|
||||
? []
|
||||
@@ -227,7 +275,8 @@
|
||||
personnelAffiliation: props.affiliation,
|
||||
status: '1',
|
||||
remark: '',
|
||||
photoUrls: ''
|
||||
photoUrls: '',
|
||||
sysUserId: ''
|
||||
})
|
||||
resetCertList()
|
||||
}
|
||||
@@ -286,7 +335,8 @@
|
||||
personnelAffiliation: props.affiliation,
|
||||
status: detail.status,
|
||||
remark: detail.remark || '',
|
||||
photoUrls: detail.photoUrls || ''
|
||||
photoUrls: detail.photoUrls || '',
|
||||
sysUserId: detail.sysUserId || ''
|
||||
})
|
||||
certList.value = mergePersonnelCertSlots(
|
||||
(detail.certList || []).map((c) => ({
|
||||
@@ -310,6 +360,7 @@
|
||||
|
||||
async function openDialog() {
|
||||
resetForm()
|
||||
void ensureUserOptions()
|
||||
if (props.personnelId) {
|
||||
await loadDetail(props.personnelId)
|
||||
} else if (props.initialPersonnelType) {
|
||||
@@ -341,6 +392,7 @@
|
||||
status: formData.status,
|
||||
remark: formData.remark || undefined,
|
||||
photoUrls: formData.photoUrls ?? '',
|
||||
sysUserId: (formData.sysUserId || '').trim() || null,
|
||||
certList: certList.value.map((c) => ({
|
||||
certId: c.certId,
|
||||
certName: c.certName.trim(),
|
||||
@@ -372,6 +424,11 @@
|
||||
emit('saved', { mode: 'create', personnel: detail })
|
||||
}
|
||||
visible.value = false
|
||||
} catch (e: any) {
|
||||
const msg = e?.response?.data?.detail || e?.response?.data?.message || e?.message || ''
|
||||
if (typeof msg === 'string' && msg) {
|
||||
ElMessage.error(msg)
|
||||
}
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user