<!-- 新建、编辑、详情 --> <script lang="ts" setup name="SampleEdit"> import type { Ref } from 'vue' import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import type { FormInstance, UploadUserFile } from 'element-plus' import { ref } from 'vue' import dayjs from 'dayjs' import type { ISampleEdit, Menu, SimpleCertification, SimpleMeasureRecord, dictType } from './sample_list_interface' import selectCustomer from './selectCustomer.vue' import { tagBinding } from '@/api/reader' import showPhoto from '@/views/system/tool/showPhoto.vue' import TemplateTable from '@/views/customer/customerInfo/templateTable.vue' import { addSample, getCertification, getMesureRecords, getSapmleDetail, updateSample } from '@/api/customer/sampleList' import countries from '@/components/AddressSelect/country-code.json' import { UploadFile } from '@/api/measure/file' import type { ICustomer } from '@/views/customer/customerInfo/customer_interface' import { getDictByCode } from '@/api/system/dict' import type { IRecord } from '@/views/business/schedule/interchange/interchange_interface' const textMap: { [key: string]: string } = { edit: '编辑', add: '新建', detail: '详情', }// 字典 const scanSampleRef = ref() // 标签绑定弹窗ref const pageType = ref('add') // 页面类型: add, edit, detail const countryList = ref(countries) // 国家列表 const loading = ref(false) // 表单加载状态 const infoId = ref('') // id const visible = ref(false) // 控制对话框显隐 const mesureCategoryList = ref<dictType[]>([]) // 校检类别 const measureTypeList = ref<dictType[]>([]) // 检定方式 const powerVoltageList = ref<dictType[]>([]) // 电源电压 const ABCList = ref<dictType[]>([]) // ABC const dataForm: Ref<ISampleEdit> = ref({ id: '', sampleNo: '', // 样品编号 sampleName: '', // 样品名称 sampleModel: '', // 样品型号 manufacturingNo: '', // 出厂编号 customerId: '', // 委托方id customerNo: '', // 委托方代码 customerName: '', // 委托方名称 phone: '', // 委托方电话 postalCode: '', // 委托方邮编 customerAddress: '', // 委托方地址 measureCategory: '', // 检校类别 manufacturer: '', // 生产厂家 manufacturerCountry: '', // 厂家国别 manufacturingDate: '', // 出厂年月 ABC: '', // ABC // deliverer: '', // 送检人 // delivererTel: '', // 送检人联系方式 measureContent: '', // 检定项目 measurePeriod: '', // 检定周期 remark: '', // 备注 minioFileName: '', // 说明书 labelBind: '', // 标签绑定 measureType: '1', // 检定方式 1自检、2外包、3外检 measureLastTime: '', // 检定日期 validDeadline: '', // 有效日期 powerVoltage: '', // 电源电压 })// 表单 const ruleFormRef = ref<FormInstance>() // 自定义校验规则--检定周期为正整数 const validateMesurePeriod = (rule: any, value: string, callback: Function) => { if (value === '') { callback() } else if (!(/(^[1-9]\d*$)/.test(value))) { callback(new Error('请输入一个正整数')) } else { callback() } } // 校验规则 const rules = ref({ sampleName: [{ required: true, message: '样品名称必填', trigger: 'blur' }], sampleModel: [{ required: true, message: '样品型号必填', trigger: 'blur' }], manufacturingNo: [{ required: true, message: '出厂编号必填', trigger: 'blur' }], customerNo: [{ required: true, message: '委托方代码必填', trigger: 'change' }], customerName: [{ required: true, message: '委托方名称必填', trigger: 'change' }], // phone: [{ required: true, message: '委托方电话必填', trigger: 'change' }], // postalCode: [{ required: true, message: '委托方邮编必填', trigger: 'change' }], // customerAddress: [{ required: true, message: '委托方地址必填', trigger: 'change' }], // measureContent: [{ required: true, message: '检定项目必填', trigger: 'blur' }], measurePeriod: [{ validator: validateMesurePeriod, trigger: 'blur' }], // powerVoltage: [{ required: true, message: '电源电压必填', trigger: 'change' }], }) // 表单验证规则 // 其他关联数据列表 const dataList = ref({ measureRecords: [] as SimpleMeasureRecord[], certificationRecords: [] as SimpleCertification[], }) // 获取字典值 function getDict() { // 校检类别 getDictByCode('measureCategory').then((response) => { mesureCategoryList.value = response.data }) // ABC getDictByCode('ABC').then((response) => { ABCList.value = response.data }) // 检定方式 getDictByCode('measureType').then((response) => { measureTypeList.value = response.data }) // 电源电压 getDictByCode('powerVoltage').then((response) => { powerVoltageList.value = response.data }) } getDict() // 检定记录、检定证书请求参数 const listQuery = ref<IRecord>({ sampleId: infoId.value, // 样品id customerId: '', // 客户id offset: 1, limit: 10, }) const totalRecords = ref(0) // 检定记录 const totalCertifications = ref(0) // 检定证书 // 获取检定记录 const fetchMeasureRecords = (query = null) => { if (pageType.value === 'detail') { getMesureRecords(listQuery.value).then((res) => { dataList.value.measureRecords = res.data.rows.map((item: { orderTime: string; deliverTime: string }) => { return { ...item, orderTime: item.orderTime ? dayjs(item.orderTime).format('YYYY-MM-DD') : '', deliverTime: item.deliverTime ? dayjs(item.deliverTime).format('YYYY-MM-DD') : '', } }) totalRecords.value = parseInt(res.data.total) }) } } // 获取检定证书 const fetchCertifications = (query = null) => { if (pageType.value === 'detail') { getCertification(listQuery.value).then((res) => { dataList.value.certificationRecords = res.data.rows.map((item: { effectiveDate: string; expirationDate: string }) => { return { ...item, effectiveDate: item.effectiveDate ? dayjs(item.effectiveDate).format('YYYY-MM-DD') : '', expirationDate: item.expirationDate ? dayjs(item.expirationDate).format('YYYY-MM-DD') : '', } }) totalCertifications.value = parseInt(res.data.total) }) } } // 菜单 const menu: Menu[] = [ { name: '检定记录', columns: [ { text: '委托单编号', value: 'orderCode', align: 'center' }, { text: '委托单日期', value: 'orderTime', align: 'center', width: '120' }, { text: '委托方代码', value: 'customerCode', align: 'center' }, { text: '委托方名称', value: 'customerName', align: 'center' }, { text: '送检人', value: 'deliverer', align: 'center' }, { text: '送检日期', value: 'deliverTime', align: 'center', width: '120' }, ], list: 'measureRecords', pagination: true, searchFunc: fetchMeasureRecords, }, { name: '检定证书', columns: [ { text: '证书编号', value: 'certificationCode', align: 'center' }, { text: '证书名称', value: 'certificationName', align: 'center' }, { text: '证书类型', value: 'certificationClassName', align: 'center' }, { text: '证书出具日期', value: 'effectiveDate', align: 'center', width: '120' }, { text: '证书有效期', value: 'expirationDate', align: 'center', width: '120' }, ], list: 'certificationRecords', pagination: true, searchFunc: fetchCertifications, }, ] const currentMenu = ref('检定记录') const currentMenuObj = computed(() => { return menu.find(item => item.name === currentMenu.value) }) watch(currentMenuObj, () => { listQuery.value.offset = 1 currentMenuObj.value?.searchFunc() }, { deep: true, immediate: true, }) // 监听检定记录和证书报告页数变化 const changePage = (val: any) => { if (val.value && currentMenuObj) { listQuery.value.offset = val.value.offset listQuery.value.limit = val.value.limit currentMenuObj.value?.searchFunc() } } // 从路由中获取页面类型参数 const $route = useRoute() if ($route.params && $route.params.type) { pageType.value = $route.params.type as string if ($route.params.id) { infoId.value = $route.params.id as string } } const $router = useRouter() // 关闭新增页面的回调 const close = () => { $router.back() } // 打印表单 const printObj = ref({ id: 'form', // 需要打印元素的id popTitle: '样品详情', // 打印配置页上方的标题 extraHead: '<div style="display: flex;flex-direction: column;text-align: center"><h3>样品详情</h3></div>', // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分割 preview: false, // 是否启动预览模式,默认是false standard: '', extarCss: '', }) const fileRef = ref() // 文件上传input const onFileChange = (event: any) => { // 原生上传 console.log(event.target.files) if (event.target.files?.length !== 0) { // 创建formdata对象 const fd = new FormData() fd.append('multipartFile', event.target.files[0]) const loading = ElLoading.service({ lock: true, background: 'rgba(255, 255, 255, 0.8)', }) UploadFile(fd).then((res) => { if (res.code === 200) { dataForm.value.minioFileName = res.data[0] // 重置当前验证 ElMessage.success('文件上传成功') loading.close() } else { ElMessage.error(res.message) loading.close() } }) } } const upload = () => { fileRef.value.click() } // 委托方代码获取焦点 const customerNoFocus = () => { visible.value = true } // 选好委托方 const confirmCheckout = (val: Array<ICustomer>) => { if (val && val.length) { const getValue = val[0] dataForm.value.customerNo = getValue.customerNo // 委托方代码 dataForm.value.customerId = getValue.id // 委托方id dataForm.value.customerName = getValue.customerName // 委托方名称 dataForm.value.phone = getValue.phone // 电话 dataForm.value.postalCode = getValue.postalCode || '' // 邮编 dataForm.value.customerAddress = getValue.fullAddress // 委托方地址 } } // 控制选择委托方对话框显隐 const changeVisible = (val: boolean) => { visible.value = val } // 保存 function saveForm(formEl: FormInstance | undefined) { if (!formEl) { return } formEl.validate((valid, fields) => { if (valid) { ElMessageBox.confirm( '确认保存吗?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }, ).then(() => { if (dataForm.value.id) { updateSample(dataForm.value).then((res) => { if (res.code === 200) { dataForm.value.id = res.data.id dataForm.value.customerNo = res.data.customerNo ElMessage.success('已保存') $router.go(-1) } }) } else { addSample(dataForm.value).then((res) => { if (res.code === 200) { dataForm.value.id = res.data.id dataForm.value.customerNo = res.data.customerNo ElMessage.success('已保存') $router.go(-1) } }) } }) } }) } // 获取详细信息 const getInfo = () => { getSapmleDetail({ id: infoId.value }).then((res) => { res.data.customerAddress = res.data.customerAddress.replace(/null/g, '') dataForm.value = res.data dataForm.value.ABC = res.data.abc listQuery.value.sampleId = infoId.value for (const item of menu) { item.searchFunc() } }) } // --------------------------------------------扫描------------------------------------- // 点击标签绑定 const scan = () => { scanSampleRef.value.initDialog(true) } // 扫描结束 const scanOver = (value: any) => { const label = value.labelBind // dataForm.value.labelBind = label if (pageType.value === 'edit') { tagBinding({ label, sampleId: infoId.value }).then((res) => { ElMessage.success(' 绑定成功') scanSampleRef.value.closeDialog() dataForm.value.labelBind = label }) } } // ---------------------------------------------------------------------------------- // 非添加页面获取详情 if (pageType.value !== 'add') { getInfo() } </script> <template> <app-container> <detail-page :title="`样品-${textMap[pageType]}`"> <template #btns> <el-button v-if="pageType === 'detail'" v-print="printObj" type="primary"> 打印 </el-button> <el-button v-if="pageType !== 'detail'" type="primary" @click="saveForm(ruleFormRef)"> 保存 </el-button> <el-button type="info" @click="close"> 关闭 </el-button> </template> <div id="form"> <el-form ref="ruleFormRef" :model="dataForm" :label-width="120" label-position="right" :rules="rules" > <el-row :gutter="24"> <el-col :span="6"> <el-form-item label="样品编号:" prop="sampleNo"> <el-input v-model="dataForm.sampleNo" :placeholder="pageType === 'detail' ? '' : '系统自动生成'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="样品名称:" prop="sampleName"> <el-input v-model="dataForm.sampleName" :placeholder="pageType === 'detail' ? '' : '请输入样品名称'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col><el-col :span="6"> <el-form-item label="样品型号:" prop="sampleModel"> <el-input v-model="dataForm.sampleModel" :placeholder="pageType === 'detail' ? '' : '请输入样品型号'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="出厂编号:" prop="manufacturingNo"> <el-input v-model="dataForm.manufacturingNo" :placeholder="pageType === 'detail' ? '' : '请输入出厂编号'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="委托方代码" prop="customerNo"> <el-input v-model="dataForm.customerNo" :placeholder="pageType === 'detail' ? '' : '请选择委托方代码'" :class="{ 'detail-input': pageType === 'detail' }" disabled > <template v-if="pageType === 'add' || (pageType === 'edit' && !dataForm.customerNo)" #append> <el-button size="small" @click="customerNoFocus"> 选择 </el-button> </template> </el-input> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="委托方名称" prop="customerName"> <el-input v-model="dataForm.customerName" :placeholder="pageType === 'detail' ? '' : '请输入委托方名称'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="委托方电话" prop="phone"> <el-input v-model="dataForm.phone" :placeholder="pageType === 'detail' ? '' : '请输入委托方电话'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="委托方邮编" prop="postalCode"> <el-input v-model="dataForm.postalCode" :placeholder="pageType === 'detail' ? '' : '请输入委托方邮编'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="18"> <el-form-item label="委托方地址:" prop="customerAddress"> <el-input v-model="dataForm.customerAddress" type="textarea" autosize :placeholder="pageType === 'detail' ? '' : '请输入委托方地址'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="校检类别:"> <el-select v-model="dataForm.measureCategory" :placeholder="pageType === 'detail' ? ' ' : '请选择校检类别'" :disabled="pageType === 'detail'" class="full-width-input" > <el-option v-for="item of mesureCategoryList" :key="item.value" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="生产厂家:"> <el-input v-model="dataForm.manufacturer" :placeholder="pageType === 'detail' ? '' : '请输入生产厂家'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="厂家国别:"> <el-select v-model="dataForm.manufacturerCountry" :placeholder="pageType === 'detail' ? ' ' : '请选择厂家国别'" :disabled="pageType === 'detail'" class="full-width-input" > <el-option v-for="country of countryList" :key="country.code" :label="country.CNName" :value="country.code" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="出厂年月:"> <el-date-picker v-model="dataForm.manufacturingDate" type="month" format="YYYY-MM" value-format="YYYY-MM" class="full-width-input" :placeholder="pageType === 'detail' ? '' : '请输入出厂年月'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="ABC:"> <el-select v-model="dataForm.ABC" :placeholder="pageType === 'detail' ? ' ' : '请选择ABC'" :disabled="pageType === 'detail'" class="full-width-input" > <el-option v-for="item of ABCList" :key="item.value" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="电源电压:" prop="powerVoltage"> <el-select v-model="dataForm.powerVoltage" :placeholder="pageType === 'detail' ? '' : '请选择电源电压'" :disabled="pageType === 'detail'" class="full-width-input" > <el-option v-for="item of powerVoltageList" :key="item.value" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="检定周期(月):" prop="measurePeriod"> <el-input v-model="dataForm.measurePeriod" :placeholder="pageType === 'detail' ? '' : '请输入检定周期'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col v-if="pageType === 'detail'" :span="6"> <el-form-item label="检定日期:"> <el-date-picker v-model="dataForm.measureLastTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="full-width-input" :placeholder="pageType === 'detail' ? '' : '请输入检定日期'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col v-if="pageType === 'detail'" :span="6"> <el-form-item label="有效日期:"> <el-date-picker v-model="dataForm.validDeadline" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" class="full-width-input" :placeholder="pageType === 'detail' ? '' : '请输入有效日期'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col v-if="pageType === 'detail'" :span="6"> <el-form-item label="送检人:"> <el-input v-model="dataForm.deliverer" :placeholder="pageType === 'detail' ? '' : '请输入送检人'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col v-if="pageType === 'detail'" :span="6"> <el-form-item label="联系方式:"> <el-input v-model="dataForm.delivererTel" :placeholder="pageType === 'detail' ? '' : '请输入联系方式'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="检定方式:"> <el-select v-model="dataForm.measureType" :placeholder="pageType === 'detail' ? ' ' : '请选择检定方式'" disabled class="full-width-input" > <el-option v-for="item of measureTypeList" :key="item.value" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="24" class="marg"> <el-col :span="12"> <el-form-item label="检定项目:" prop="measureContent"> <el-input v-model="dataForm.measureContent" :placeholder="pageType === 'detail' ? '' : '请输入检定项目'" :disabled="pageType === 'detail'" :class="{ 'detail-input': pageType === 'detail' }" /> </el-form-item> </el-col> </el-row> <el-row :gutter="24" class="marg"> <el-col :span="12"> <el-form-item label="备注:"> <el-input v-model="dataForm.remark" type="textarea" autosize :placeholder="pageType === 'detail' ? '' : '请输入备注'" :disabled="pageType === 'detail'" :class="{ 'detail-input': pageType === 'detail' }" /> </el-form-item> </el-col> </el-row> <el-row v-if="pageType !== 'add'" :gutter="24" class="marg"> <el-col :span="12"> <el-form-item label="标签绑定" prop="labelBind"> <el-input v-model.trim="dataForm.labelBind" disabled :placeholder="pageType === 'detail' ? ' ' : '请点击扫描'" clearable> <template v-if="pageType !== 'detail'" #append> <el-button type="primary" size="small" @click="scan"> 扫描 </el-button> </template> </el-input> </el-form-item> </el-col> </el-row> <el-row :gutter="24" class="marg"> <el-col :span="12"> <el-form-item label="说明书:"> <show-photo v-if="dataForm.minioFileName" :minio-file-name="dataForm.minioFileName" /> <span v-else-if="pageType === 'detail'">无</span> <input v-show="pageType === ''" ref="fileRef" type="file" @change="onFileChange"> <el-button v-if="pageType !== 'detail'" id="file" type="primary" :disabled="pageType === 'detail'" :style="{ 'margin-left': dataForm.minioFileName === '' ? '0px' : '20px' }" @click="upload"> {{ dataForm.minioFileName === '' ? '上传' : '更换附件' }} </el-button> </el-form-item> </el-col> </el-row> </el-form> </div> </detail-page> <!-- 使用记录、维护记录、 --> <detail-block-switch v-if="pageType === 'detail'" :title="currentMenu"> <template #menu> <el-radio-group v-model="currentMenu"> <el-radio-button v-for="item in menu" :key="item.name" :label="item.name"> {{ item.name }} </el-radio-button> </el-radio-group> </template> <!-- <template-table v-if="currentMenuObj" :columns="currentMenuObj.columns" :list="dataList[currentMenuObj.list]" :loading="false" :pagination="currentMenuObj.pagination" @change-page="currentMenuObj?.searchFunc" /> --> <template-table v-if="currentMenuObj" :columns="currentMenuObj.columns" :total="currentMenu === '检定记录' ? totalRecords : totalCertifications" :list="dataList[currentMenuObj.list]" :loading="false" :pagination="currentMenuObj.pagination" @change-page="changePage" /> </detail-block-switch> <!-- 选择委托方组件 --> <select-customer v-model:visible="visible" @confirmCheckout="confirmCheckout" @changeVisible="changeVisible" /> <scan-sample-dialog ref="scanSampleRef" title="标签绑定" @confirm="scanOver" /> </app-container> </template> <style lang="scss" scoped> // 样式 </style>