smart-bid-web/src/views/enterpriseLibrary/personnel/components/child/QualificationInfoDetail.vue

310 lines
11 KiB
Vue
Raw Normal View History

2025-10-21 15:06:03 +08:00
<template>
2025-10-27 09:06:42 +08:00
<div class="basic-info-detail">
2025-10-21 15:06:03 +08:00
<div class="basic-info-title">
<img src="@/assets/enterpriseLibrary/basic-info.png" alt="资质信息">
<span>资质信息</span>
</div>
2025-10-21 15:21:49 +08:00
2025-10-27 09:06:42 +08:00
<div class="detail-content">
<template v-if="isProjectManager">
2025-11-17 15:25:52 +08:00
<el-row :gutter="24">
<el-col :span="8">
<!-- 建造师证书 -->
<FileOrImageDisplay label="建造师证书" :file="form.fileList[0]" :image-url="form.url" />
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<!-- 专业类型 -->
<DetailItem label="专业类型" :value="form.professionalType" />
</el-col>
<el-col :span="8">
<!-- 证书编号 -->
<DetailItem label="证书编号" :value="form.certificateCode" />
</el-col>
<el-col :span="8">
<!-- 级别 -->
<DetailItem label="级别" :value="form.certificateLevel" />
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<!-- 证书有效期 -->
<DetailItem label="证书有效期" :value="form.certificateValidityPeriod" />
</el-col>
<el-col :span="8">
<!-- 使用有效期 -->
<DetailItem label="使用有效期" :value="form.useValidityPeriod" />
</el-col>
</el-row>
2025-10-27 09:06:42 +08:00
</template>
<template>
<!-- 安全考核B证安全考核C证其他人员证书 -->
2025-11-17 15:25:52 +08:00
<el-row :gutter="24">
<el-col :span="8">
<FileOrImageDisplay :label="certificateName" :file="form.fileList2[0]" :image-url="form.url2" />
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<!-- 证书编号 -->
<DetailItem label="证书编号" :value="form.certificateCode2" />
</el-col>
<el-col :span="8">
<!-- 证书有效期 -->
<DetailItem label="证书有效期" :value="form.certificateValidityPeriod2" />
</el-col>
<el-col :span="8">
<!-- 注册专业 -->
<DetailItem label="注册专业" :value="form.registerProfessional" />
</el-col>
</el-row>
2025-10-21 15:06:03 +08:00
</template>
2025-10-21 15:21:49 +08:00
</div>
2025-10-21 15:06:03 +08:00
</div>
</template>
<script>
2025-10-27 09:06:42 +08:00
import FileOrImageDisplay from '@/views/common/FileOrImageDisplay.vue';
import DetailItem from '@/views/common/DetailItem.vue';
// 建造师证书识别规则
const CONSTRUCTOR_CERTIFICATE = {
fields_json: "专业类型,证书编号,级别",
fileUploadType: "constructor_certificate",
suffix: "personnel_database",
}
2025-10-21 15:06:03 +08:00
export default {
name: 'QualificationInfoPersonnelDetail',
2025-10-27 09:06:42 +08:00
components: {
FileOrImageDisplay,
DetailItem
},
2025-10-21 15:06:03 +08:00
props: {
2025-10-27 09:06:42 +08:00
detailData: {
type: Object,
default: () => { }
},
2025-10-21 15:06:03 +08:00
personnelPosition: {
type: Object,
default: () => ({
label: '项目经理',
value: 'project_manager',
qualification: '建造师证书、安全考核B证'
})
},
},
2025-10-27 09:06:42 +08:00
dicts: ['personnel_position', 'identification_tag'],
2025-10-21 15:06:03 +08:00
data() {
return {
form: {
professionalType: '',
certificateCode: '',
certificateLevel: '',
certificateValidityPeriod: '',
useValidityPeriod: '',
certificateCode2: '',
certificateValidityPeriod2: '',
registerProfessional: '',
2025-10-27 09:06:42 +08:00
url: null,
url2: null,
fileList: [],
fileList2: [],
2025-10-21 15:06:03 +08:00
},
2025-10-27 09:06:42 +08:00
// 其他类型
otherType: '',
// OCR 识别规则
ocrRuleList: ['constructor_certificate', 'safety_assessment_certificate_b'],
fileUploadList: [],
2025-10-21 15:06:03 +08:00
}
},
methods: {
2025-10-27 09:06:42 +08:00
// ocr文件识别规则
ocrRule(type) {
const item = this.getRuleItem(type);
this.fileUploadList.push(item)
},
// 获取ocr识别规则
getRuleItem(type) {
const foundItem = this.dict.type.identification_tag.find(item => item.value === type);
const item = foundItem ? {
fileUploadType: foundItem.value,
fields_json: foundItem.raw.remark,
suffix: 'personnel_database'
} : null;
return item;
},
// 添加ocr文件识别规则
addOcrRule() {
this.ocrRuleList.forEach(item => {
this.ocrRule(item)
})
},
setDetailData() {
this.fileUploadList.forEach((item, index) => {
if (Object.keys(item).length > 0 && index === 0) {
this.form.fileList = this.getFileList(item.fileUploadType);
this.form.professionalType = this.getFormData(item.fileUploadType, 'professionalType');
this.form.certificateCode = this.getFormData(item.fileUploadType, 'certificateCode');
this.form.certificateLevel = this.getFormData(item.fileUploadType, 'certificateLevel');
this.form.certificateValidityPeriod = this.getFormData(item.fileUploadType, 'certificateValidityPeriod');
this.form.useValidityPeriod = this.getFormData(item.fileUploadType, 'useValidityPeriod');
this.form.url = this.getFileList(item.fileUploadType)[0]?.fileType === '1' ? this.getFileList(item.fileUploadType)[0]?.lsFilePath : null;
this.form.fileList = this.getFileList(item.fileUploadType);
} else if (Object.keys(item).length > 0 && index === 1) {
this.form.fileList2 = this.getFileList(item.fileUploadType);
this.form.registerProfessional = this.getFormData(item.fileUploadType, 'registerProfessional');
this.form.certificateCode2 = this.getFormData(item.fileUploadType, 'certificateCode');
this.form.certificateValidityPeriod2 = this.getFormData(item.fileUploadType, 'certificateValidityPeriod');
this.form.url2 = this.getFileList(item.fileUploadType)[0]?.fileType === '1' ? this.getFileList(item.fileUploadType)[0]?.lsFilePath : null;
this.form.fileList2 = this.getFileList(item.fileUploadType);
2025-10-21 15:06:03 +08:00
}
2025-10-27 09:06:42 +08:00
})
},
getFileList(businessType) {
if (this.detailData?.certificateDetailList) {
for (const certificateDetail of this.detailData.certificateDetailList) {
if (certificateDetail.certificate?.certificateType === businessType &&
certificateDetail.fileVoList) {
return certificateDetail.fileVoList.map(item => ({
name: item.fileName,
filePath: item.filePath,
lsFilePath: item.lsFilePath,
fileType: item.fileType,
businessType: item.businessType
}));
}
2025-10-21 15:06:03 +08:00
}
}
2025-10-27 09:06:42 +08:00
return [];
2025-10-21 15:06:03 +08:00
},
2025-10-27 09:06:42 +08:00
getFormData(businessType, key) {
if (!this.detailData?.certificateDetailList) {
return '';
}
const certificates = this.detailData.certificateDetailList
.map(certificateDetail => certificateDetail.certificate)
.filter(certificate =>
certificate &&
certificate.certificateType === businessType
);
if (certificates.length > 0) {
const value = certificates[0][key];
return value != null ? value : '';
}
return '';
},
getOtherType() {
const result = this.personnelPosition.qualification.split('、').filter(item => !item.includes('建造师证书'));
const firstMatch = this.dict.type.identification_tag.find(item =>
result.includes(item.label)
);
this.otherType = firstMatch ? firstMatch.value : '';
const ruleItem = this.getRuleItem(this.otherType);
const baseItems = this.isProjectManager
? [{ ...CONSTRUCTOR_CERTIFICATE }, { ...ruleItem }]
: [{}, { ...ruleItem }];
this.fileUploadList = baseItems;
2025-10-21 15:06:03 +08:00
},
},
watch: {
2025-10-27 09:06:42 +08:00
// 监听字典数据加载完成
'dict.type.identification_tag': {
handler(newVal) {
if (newVal && newVal.length > 0) {
this.addOcrRule();
}
},
},
2025-10-21 15:06:03 +08:00
personnelPosition: {
handler(newVal) {
2025-10-27 09:06:42 +08:00
this.getOtherType();
2025-10-21 15:06:03 +08:00
},
2025-10-27 09:06:42 +08:00
},
detailData: {
handler(newVal) {
if (Object.keys(newVal).length > 0) {
this.setDetailData();
}
},
deep: true
2025-10-21 15:06:03 +08:00
},
},
computed: {
// 是否是项目经理
isProjectManager() {
return this.personnelPosition.value === 'project_manager';
},
// 证书名称
certificateName() {
const result = this.personnelPosition.qualification.split('、').filter(item => !item.includes('建造师证书'));
return result[0];
},
2025-10-27 09:06:42 +08:00
},
2025-10-21 15:06:03 +08:00
}
</script>
<style scoped lang="scss">
.basic-info-title {
display: flex;
align-items: center;
2025-10-27 09:06:42 +08:00
margin: 10px 0;
2025-10-21 15:06:03 +08:00
span {
2025-10-27 09:06:42 +08:00
margin: 0 5px;
font-size: 20px;
2025-10-21 15:21:49 +08:00
}
}
2025-10-27 09:06:42 +08:00
.detail-content {
.detail-item {
margin-bottom: 16px;
2025-10-21 15:21:49 +08:00
2025-10-27 09:06:42 +08:00
.item-label {
color: #424242;
font-size: 18px;
font-weight: 500;
margin-bottom: 8px;
}
2025-10-21 15:21:49 +08:00
2025-10-27 09:06:42 +08:00
.item-value {
color: #424242;
font-size: 16px;
line-height: 1.5;
2025-10-21 15:21:49 +08:00
2025-10-27 09:06:42 +08:00
.license-image {
width: 350px;
height: 220px;
display: block;
margin: 0 auto;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
object-fit: cover;
cursor: pointer;
transition: transform 0.3s ease;
2025-10-21 15:21:49 +08:00
2025-10-27 09:06:42 +08:00
&:hover {
transform: scale(1.02);
}
}
2025-10-21 15:21:49 +08:00
}
2025-10-21 15:06:03 +08:00
}
}
</style>