<!-- 委托书详情 --> <script lang="ts" setup name="OrderListEdit"> import type { Ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import type { FormInstance, FormRules, UploadUserFile } from 'element-plus' import type { IOrderDetail, ISampleList, dictType } from './orderList_interface' import selectSample from './selectSample.vue' import { UploadFile } from '@/api/measure/file' import selectCustomer from '@/views/customer/sample/list/selectCustomer.vue' import type { ICustomer } from '@/views/customer/customerInfo/customer_interface' import showPhoto from '@/views/system/tool/showPhoto.vue' import { getDictByCode } from '@/api/system/dict' import { getUid } from '@/utils/getUid' import { addOrder, getOrderDetail, updateOrder } from '@/api/business/schedule/order' const pageType = ref('add') // 页面类型: add, edit, detail const infoId = ref('') // id const visible = ref(false) // 控制选择委托方对话框显隐 const sampleVisible = ref(false) // 控制选择样品对话框显隐 const ruleFormRef = ref() // 表单 const dataForm: Ref<IOrderDetail> = ref({ id: '', orderCode: '', // 委托书编号 deliverer: '', // 送检人 delivererTel: '', // 送样人联系方式 orderTime: '', // 委托日期 planDeliverTime: '', // 预计送达时间 requireOverTime: '', // 要求检完时间 customerNo: '', // 委托方代码 customerId: '', // 委托方id customerName: '', // 委托方名称 phone: '', // 委托方电话 customerAddress: '', // 委托方地址 remark: '', // 备注 minioFileName: '', // 附件 isUrgent: 0, // 是否加急 0否 1是 certifications: '', // 证书类别 }) const certificationsMap = ref<dictType[]>([]) // 证书类别 const powerVoltageMap = ref<dictType[]>([]) // 电源电压 const isUrgentMap = ref<dictType[]>([]) // 是否加急 const customerInfoMap = ref<dictType[]>([]) // 系统字典--航天计量检测技术(江苏)有限公司基本信息 const list = ref<ISampleList[]>([])// 表格数据 // 选中的内容 const checkoutList = ref([]) // 表头 const columns = ref([ { text: '样品编号', value: 'sampleNo', align: 'center', width: '170', disabled: true }, { text: '样品名称', value: 'sampleName', align: 'center', required: true }, { text: '型号', value: 'sampleModel', align: 'center', required: true }, { text: '出厂编号', value: 'manufacturingNo', align: 'center', required: true }, { text: '电源电压', value: 'powerVoltage', align: 'center', required: true }, { text: '检定项目', value: 'mesureContent', align: 'center', required: true }, { text: '备注', value: 'remark', align: 'center' }, { text: '附件说明', value: 'appendixDescn', align: 'center' }, ]) // 自定义校验规则--要求检完时间不能比预计送达时间大 const requireOverTimeValid = (rule: any, value: any, callback: any) => { if (!value) { return callback(new Error('要求检完时间不能为空')) } if (new Date(dataForm.value.planDeliverTime).getTime() >= new Date(dataForm.value.requireOverTime).getTime()) { return callback(new Error('要求检完时间应大于预计送达时间')) } callback() } // 校验规则 const rules = reactive<FormRules>({ deliverer: [{ required: true, message: '要求送样人不能为空', trigger: 'blur' }], delivererTel: [{ required: true, message: '要求送样人联系方式不能为空', trigger: 'blur' }], customerNo: [{ required: true, message: '要求委托方代码不能为空', trigger: 'change' }], customerName: [{ required: true, message: '要求委托方名称不能为空', trigger: 'change' }], phone: [{ required: true, message: '要求委托方电话不能为空', trigger: 'change' }], customerAddress: [{ required: true, message: '要求委托方地址不能为空', trigger: 'change' }], orderTime: [{ type: 'date', required: true, message: '要求委托日期不能为空', trigger: 'change' }], planDeliverTime: [{ type: 'date', required: true, message: '要求预计送达时间不能为空', trigger: 'change' }], requireOverTime: [{ type: 'date', validator: requireOverTimeValid, trigger: 'change' }], certifications: [{ required: true, message: '要求证书类别不能为空', trigger: 'change' }], isUrgent: [{ required: true, message: '要求是否加急不能为空', trigger: 'change' }], }) // 表单验证规则 // 从路由中获取页面类型参数 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 } } // 获取字典值 function getDict() { // 证书类别 getDictByCode('certificationType').then((response) => { certificationsMap.value = response.data }) // 电源电压 getDictByCode('powerVoltage').then((response) => { powerVoltageMap.value = response.data }) // 是否加急 getDictByCode('isUrgent').then((response) => { isUrgentMap.value = response.data.map((item: dictType) => { return { ...item, value: parseInt(item.value as string), } }) }) // 系统字典 getDictByCode('systemDict').then((response) => { const tempMap = response.data.map((item: dictType) => { if (item.value === 'address') { item.label = '通信地址' } else if (item.value === 'postalCode') { item.label = '邮编' } else if (item.value === 'tel') { item.label = '电话' } else if (item.value === 'fax') { item.label = '传真' } return item }) // 删除除上述四项的其他基本信息 tempMap.forEach((item: dictType, index: number) => { if (item.value !== 'address' && item.value !== 'postalCode' && item.value !== 'tel' && item.value !== 'fax') { tempMap.splice(index, 1) } }) customerInfoMap.value = tempMap }) } getDict() // 点击选择 const customerNoFocus = () => { visible.value = true } // 点击从样品库添加 const multiAdd = () => { if (!dataForm.value.customerNo) { ElMessage.warning('请先选择委托方') return } sampleVisible.value = true } // 选好委托方 const confirmCheckout = (val: Array<ICustomer>) => { if (val && val.length) { list.value = [] // 切换委托方时把样品清单置空 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.customerAddress = getValue.fullAddress // 委托方地址 } } // 选择好样品 const clickConfirmSample = (val: Array<ISampleList>) => { val.forEach((item: ISampleList) => { // 只添加列表里不存在的 const index = list.value.findIndex((i: ISampleList) => item.sampleNo === i.sampleNo) if (index === -1) { list.value.push({ ...item, isExistSample: '1', // 是否存在样品库中 1存在、0不存在 }) } }) } // 控制选择委托方对话框显隐 const changeVisible = (val: boolean) => { visible.value = val } // 控制选择样品对话框显隐 const changeSampleVisible = (val: boolean) => { sampleVisible.value = val } // 多选发生改变时 const handleSelectionChange = (e: any) => { checkoutList.value = e } // 增加行 const addRow = () => { const index = list.value.findIndex(item => !item.sampleNo) if (index !== -1) { ElMessage.warning('请完善上一条样品信息') return } list.value.push({ sampleNo: '', // 样品编号 sampleName: '', // 样品名称 sampleModel: '', // 样品型号 manufacturingNo: '', // 出厂编号 powerVoltage: '', // 电源电压 appendixDescn: '', // 附件说明 mesureContent: '', // 检定项目 remark: '', // 备注 isEdit: true, // 是否可编辑 isExistSample: '0', // 是否存在样品库中 1存在、0不存在 delId: getUid(), }) } // 删除行 const delRow = () => { if (checkoutList.value.length <= 0) { ElMessage({ message: '请选中要删除的行', type: 'warning', }) } else { checkoutList.value.forEach((item: ISampleList) => { list.value.forEach((element, index) => { if (!item.sampleNo) { // 点击增加行--手动增加的项目需要判断前端添加的delID if (element.delId === item.delId) { list.value.splice(index, 1) } } else { // 从样品库中选择的项目 if (element.sampleNo === item.sampleNo) { list.value.splice(index, 1) } } }) }) } } const fileRef = ref() // 文件上传input const onFileChange = (event: any) => { // 原生上传 if (event.target.files?.length !== 0) { // 创建formdata对象 const fd = new FormData() fd.append('multipartFile', event.target.files[0]) UploadFile(fd).then((res) => { if (res.code === 200) { dataForm.value.minioFileName = res.data[0] // 重置当前验证 ElMessage.success('文件上传成功') } else { ElMessage.error(res.message) } }) } } const upload = () => { fileRef.value.click() } const $router = useRouter() // 关闭新增页面的回调 const close = () => { $router.back() } // 点击保存 const saveForm = (formEl: FormInstance | undefined) => { // 检查表格是否存在增加行信息没有完善的情况 const index = list.value.findIndex(item => !item.sampleNo) if (index !== -1 && (!list.value[index].sampleName || !list.value[index].sampleModel || !list.value[index].manufacturingNo || !list.value[index].powerVoltage || !list.value[index].mesureContent)) { ElMessage.warning(`表格第${index + 1}行信息未完善`) return } if (!formEl) { return } formEl.validate((valid) => { if (valid) { ElMessageBox.confirm( '确认保存吗?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }, ).then(() => { const params = { ...dataForm.value, customerPhone: dataForm.value.phone, // 委托方电话 customerSampleInfoList: list.value, } if (pageType.value === 'edit') { // 编辑 updateOrder(params).then(() => { ElMessage.success('已保存') $router.go(-1) }) } if (pageType.value === 'add') { // 新建 addOrder(params).then(() => { ElMessage.success('已保存') $router.go(-1) }) } }) } }) } // 点击打印 const printObj = ref({ id: 'main', // 需要打印元素的id popTitle: '委托书详情', // 打印配置页上方的标题 extraHead: '<div style="display: flex;flex-direction: column;text-align: center"><h3></h3></div>', // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分割 preview: false, // 是否启动预览模式,默认是false standard: '', extarCss: '', }) // 获取详细信息 const getInfo = () => { getOrderDetail({ id: infoId.value }).then((res) => { dataForm.value = res.data dataForm.value.phone = res.data.customerPhone list.value = res.data.customerSampleInfoList }) } // 非添加页面获取详情 if (pageType.value !== 'add') { getInfo() } </script> <template> <app-container> <div id="main"> <div class="customer-title"> <img src="@/assets/images/logo.png" class="img"> <div class="title"> 航天计量检测技术(江苏)有限公司 </div> </div> <detail-page title="检测/校准委托单"> <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="8"> <el-form-item label="委托书编号:" prop="orderCode"> <el-input v-model="dataForm.orderCode" :placeholder="pageType === 'detail' ? '' : '系统自动生成'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="送样人:" prop="deliverer"> <el-input v-model="dataForm.deliverer" :placeholder="pageType === 'detail' ? '' : '请输入送样人'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </el-form-item> </el-col><el-col :span="8"> <el-form-item label="联系方式:" prop="delivererTel"> <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="8"> <el-form-item label="委托日期:" prop="orderTime"> <el-date-picker v-model="dataForm.orderTime" 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 :span="8"> <el-form-item label="预计送达时间:" prop="planDeliverTime"> <el-date-picker v-model="dataForm.planDeliverTime" type="datetime" class="full-width-input" :placeholder="pageType === 'detail' ? '' : '请输入预计送达时间'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="要求检完时间:" prop="requireOverTime"> <el-date-picker v-model="dataForm.requireOverTime" type="datetime" class="full-width-input" :placeholder="pageType === 'detail' ? '' : '请输入要求检完时间'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" /> </el-form-item> </el-col> <el-col :span="8"> <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 !== 'detail'" #append> <el-button size="small" @click="customerNoFocus"> 选择 </el-button> </template> </el-input> </el-form-item> </el-col> <el-col :span="8"> <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="8"> <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="16"> <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-row> <el-row :gutter="24"> <el-col :span="8"> <el-form-item label="证书类别:" prop="certifications"> <el-select v-model="dataForm.certifications" :placeholder="pageType === 'detail' ? '' : '请选择证书类别'" :disabled="pageType === 'detail'" class="full-width-input"> <el-option v-for="i in certificationsMap" :key="i.value" :label="i.name" :value="i.value" /> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="是否加急:" prop="isUrgent"> <el-select v-model="dataForm.isUrgent" :placeholder="pageType === 'detail' ? '' : '请选择是否加急'" :disabled="pageType === 'detail'" class="full-width-input"> <el-option v-for="i in isUrgentMap" :key="i.value" :label="i.name" :value="i.value" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="24" class="marg"> <el-col :span="16"> <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 :gutter="24" class="marg"> <el-col :span="16"> <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 title="样品清单"> <template #btns> <el-button v-if="pageType !== 'detail'" type="primary" @click="multiAdd"> 从样品库中添加 </el-button> <el-button v-if="pageType !== 'detail'" type="primary" @click="addRow"> 增加行 </el-button> <el-button v-if="pageType !== 'detail'" type="info" @click="delRow"> 删除行 </el-button> </template> <el-table :data="list" border style="width: 100%;" max-height="600" @selection-change="handleSelectionChange" > <el-table-column v-if="pageType !== 'detail'" type="selection" width="38" /> <el-table-column align="center" label="序号" width="80" type="index" /> <el-table-column v-for="item in columns" :key="item.value" :prop="item.value" :label="item.text" :width="item.width" show-overflow-tooltip align="center" > <template #header> <span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span> </template> <template v-if="(pageType === 'add' || pageType === 'edit')" #default="scope"> <el-input v-if="item.value !== 'powerVoltage' && scope.row.isEdit" v-model="scope.row[item.value]" :placeholder="item.value === 'sampleNo' ? '系统自动生成' : `请输入${item.text}`" :disabled="item.disabled" class="input" /> <span v-if="item.value !== 'powerVoltage' && !scope.row.isEdit">{{ scope.row[item.value] }}</span> <el-select v-if="item.value === 'powerVoltage' && scope.row.isEdit" v-model="scope.row[item.value]" :placeholder="`请选择${item.text}`"> <el-option v-for="i in powerVoltageMap" :key="i.value" :label="i.name" :value="i.value" /> </el-select> <span v-if="item.value === 'powerVoltage' && !scope.row.isEdit">{{ scope.row[item.value] }}</span> </template> </el-table-column> </el-table> </detail-block> <!-- 公司信息 --> <div class="customer-info"> <div v-for="item in customerInfoMap" :key="item.value" class="content"> <div v-if="item.value === 'address' || item.value === 'postalCode' || item.value === 'tel' || item.value === 'fax'" class="title"> {{ item.label }}: </div> <div v-if="item.value === 'address' || item.value === 'postalCode' || item.value === 'tel' || item.value === 'fax'" class="value"> {{ item.name }} </div> </div> </div> </div> <!-- 选择委托方组件 --> <select-customer v-model:visible="visible" @confirmCheckout="confirmCheckout" @changeVisible="changeVisible" /> <!-- 选择样品组件 --> <select-sample v-model:visible="sampleVisible" :customer-no="dataForm.customerNo" @clickConfirmSample="clickConfirmSample" @changeVisible="changeSampleVisible" /> </app-container> </template> <style lang="scss" scoped> .customer-title { display: flex; justify-content: center; align-items: center; font-size: 24px; font-weight: 700; margin: 24px 0; .img { width: 32px; height: 32px; margin-right: 14px; vertical-align: middle; } } .customer-info { display: flex; justify-content: space-around; align-items: center; flex-wrap: nowrap; margin: 40px 0; .content { display: flex; font-size: 14px; .title { font-weight: 600; color: #000; } .value { margin-left: 10px; } } } </style>