feat(web-admin): add personnel photo on driver/escort pages
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
9089e455e9
commit
8d9f5777e0
1 file changed
+90
-4
@@ -105,6 +105,23 @@
|
||||
header-align="center"
|
||||
:index="(index) => (pagination.page - 1) * pagination.pageSize + index + 1"
|
||||
/>
|
||||
<el-table-column
|
||||
v-if="isColumnVisible('photoUrls')"
|
||||
label="照片"
|
||||
min-width="80"
|
||||
align="center"
|
||||
header-align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="firstPhotoUrl(row.photoUrls)"
|
||||
class="pl-photo-thumb"
|
||||
:src="resolvePhotoDisplayUrl(firstPhotoUrl(row.photoUrls))"
|
||||
alt="人员照片"
|
||||
/>
|
||||
<span v-else class="pl-photo-thumb pl-photo-thumb--empty">未上传</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="personnelName"
|
||||
label="姓名"
|
||||
@@ -122,6 +139,17 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="isColumnVisible('certAttachments')"
|
||||
label="证书附件"
|
||||
min-width="340"
|
||||
align="left"
|
||||
header-align="left"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<PlCertListAttachmentCell :cert-list="row.certList" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="isColumnVisible('personnelAffiliation')"
|
||||
label="人员归属"
|
||||
@@ -289,6 +317,15 @@
|
||||
maxlength="512"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="人员照片" style="grid-column: 1 / -1">
|
||||
<AttachmentUploadField
|
||||
ref="photoUploadRef"
|
||||
v-model="formData.photoUrls"
|
||||
:limit="1"
|
||||
accept="image/*"
|
||||
upload-folder="pl/personnel-photo"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- 人员证书(列表) -->
|
||||
@@ -341,6 +378,16 @@
|
||||
<el-icon><Delete /></el-icon>删除
|
||||
</el-button>
|
||||
</template>
|
||||
<template #photo>
|
||||
<AttachmentUploadField
|
||||
v-if="viewDetail?.photoUrls"
|
||||
:model-value="viewDetail.photoUrls"
|
||||
disabled
|
||||
:limit="1"
|
||||
accept="image/*"
|
||||
/>
|
||||
<span v-else>—</span>
|
||||
</template>
|
||||
<template #certs>
|
||||
<PlCertViewList :cert-list="viewDetail?.certList || []" layout="table" />
|
||||
</template>
|
||||
@@ -362,6 +409,8 @@ import PlCertFormList from '@/components/business/pl-cert-form-list/index.vue'
|
||||
import PlPasteRecognizeDialog from '@/components/business/pl-paste-recognize-dialog/index.vue'
|
||||
import PlCertViewList from '@/components/business/pl-cert-view-list/index.vue'
|
||||
import PlPersonnelCertBadges from '@/components/business/pl-personnel-cert-badges/index.vue'
|
||||
import PlCertListAttachmentCell from '@/components/business/pl-cert-list-attachment-cell/index.vue'
|
||||
import AttachmentUploadField from '@/components/business/attachment-upload-field/index.vue'
|
||||
import SystemViewDialog, {
|
||||
type ViewSection
|
||||
} from '@/components/business/system-view-dialog/index.vue'
|
||||
@@ -372,6 +421,7 @@ import { useDbInstantSearch } from '@/composables/useDbInstantSearch'
|
||||
import { pickBxPageResult } from '@/utils/http/bx'
|
||||
import { DEFAULT_LIST_PAGE_SIZE } from '@/utils/table/tableConfig'
|
||||
import { formatDateTime } from '@/utils/format'
|
||||
import { firstPhotoUrl, resolvePhotoDisplayUrl } from '@/utils/pl-photo'
|
||||
import { canDeleteByCreator, filterDeletableByCreator, allRowsDeletableByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
|
||||
import {
|
||||
collectRequiredCertSlotErrors,
|
||||
@@ -401,6 +451,8 @@ const isCarrierPersonnel = computed(() => affiliationMode.value === 'carrier')
|
||||
const loading = ref(false)
|
||||
|
||||
const listColumnDefs = [
|
||||
{ prop: 'photoUrls', label: '照片' },
|
||||
{ prop: 'certAttachments', label: '证书附件' },
|
||||
{ prop: 'personnelAffiliation', label: '人员归属' },
|
||||
{ prop: 'personnelType', label: '人员类型' },
|
||||
{ prop: 'phoneNo', label: '手机号' },
|
||||
@@ -417,7 +469,7 @@ const {
|
||||
isIndeterminate,
|
||||
isColumnVisible,
|
||||
resetToDefault
|
||||
} = usePersistedListColumns('pl-personnel-list-columns', listColumnDefs)
|
||||
} = usePersistedListColumns('pl-personnel-list-columns-v3', listColumnDefs)
|
||||
|
||||
const submitLoading = ref(false)
|
||||
const personnelRows = ref<Personnel[]>([])
|
||||
@@ -429,6 +481,7 @@ const formRef = ref()
|
||||
const isEdit = ref(false)
|
||||
const certList = ref<CertListItem[]>([])
|
||||
const certFormListRef = ref<CertFormListRef>()
|
||||
const photoUploadRef = ref<InstanceType<typeof AttachmentUploadField>>()
|
||||
const viewVisible = ref(false)
|
||||
const viewLoading = ref(false)
|
||||
const viewDetail = ref<PersonnelDetail | null>(null)
|
||||
@@ -463,7 +516,8 @@ const formData = reactive({
|
||||
personnelType: '',
|
||||
personnelAffiliation: 'self',
|
||||
status: '1',
|
||||
remark: ''
|
||||
remark: '',
|
||||
photoUrls: ''
|
||||
})
|
||||
|
||||
const requiredPersonnelCertNames = computed(() =>
|
||||
@@ -559,6 +613,11 @@ const viewSections = computed<ViewSection[]>(() => {
|
||||
fieldLayout: 'table',
|
||||
tableMode: 'triple'
|
||||
},
|
||||
{
|
||||
title: '人员照片',
|
||||
fields: [],
|
||||
slot: 'photo'
|
||||
},
|
||||
{
|
||||
title: `人员证书${
|
||||
viewDetail.value && !isCarrierPersonnel.value
|
||||
@@ -697,7 +756,8 @@ function handleAdd() {
|
||||
personnelType: '',
|
||||
personnelAffiliation: affiliationMode.value,
|
||||
status: '1',
|
||||
remark: ''
|
||||
remark: '',
|
||||
photoUrls: ''
|
||||
})
|
||||
resetCertList()
|
||||
dialogVisible.value = true
|
||||
@@ -740,7 +800,8 @@ async function handleEdit(row: Personnel) {
|
||||
personnelType: detail.personnelType || 'both',
|
||||
personnelAffiliation: affiliationMode.value,
|
||||
status: detail.status,
|
||||
remark: detail.remark || ''
|
||||
remark: detail.remark || '',
|
||||
photoUrls: detail.photoUrls || ''
|
||||
})
|
||||
certList.value = mergePersonnelCertSlots(
|
||||
|
||||
@@ -767,6 +828,10 @@ async function handleSubmit() {
|
||||
ElMessage.warning('证书附件上传中,请稍候')
|
||||
return
|
||||
}
|
||||
if (photoUploadRef.value?.hasUploading?.()) {
|
||||
ElMessage.warning('附件上传中,请稍候')
|
||||
return
|
||||
}
|
||||
|
||||
submitLoading.value = true
|
||||
try {
|
||||
@@ -779,6 +844,7 @@ async function handleSubmit() {
|
||||
personnelAffiliation: formData.personnelAffiliation,
|
||||
status: formData.status,
|
||||
remark: formData.remark || undefined,
|
||||
photoUrls: formData.photoUrls || undefined,
|
||||
certList: certList.value.map(c => ({
|
||||
certId: c.certId,
|
||||
certName: c.certName.trim(),
|
||||
@@ -866,4 +932,24 @@ onMounted(() => {
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.pl-photo-thumb {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
border: 1px solid var(--el-border-color, #d9e8e2);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
.pl-photo-thumb--empty {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user