<!-- 设备交接单详情 --> <script lang="ts" setup name="ReceiptList"> import type { Ref } from 'vue' import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import dayjs from 'dayjs' import type { IReceiptDetail, ISampleList, dictType } from './receiptList-interface' import selectOrder from './selectOrder.vue' import selectCustomer from '@/views/customer/sample/list/selectCustomer.vue' import selectSample from '@/views/business/schedule/interchangeReceipt/selectSample.vue' import userStore from '@/store/modules/user' import { getDictByCode } from '@/api/system/dict' import type { ICustomer } from '@/views/customer/customerInfo/customer_interface' import type { IOrderList } from '@/views/business/schedule/order/orderList_interface' import BarCodeBind from '@/components/BarCodeBind/index.vue' import type { queryType, typeofSign } from '@/views/system/tool/tool_interface' import { listPageApi } from '@/api/system/tool' import showPhoto from '@/views/system/tool/showPhoto.vue' import type { userType } from '@/views/system/user/user-interface' import { getUserList } from '@/api/system/user' import { addInterchangeReceipt, getInterchangeReceiptDetail, getStream, updateInterchangeReceipt } from '@/api/business/schedule/interchangeReceipt' import { getOrderDetail, updateOrder } from '@/api/business/schedule/order' import SelectOrderSamplesDialog from '@/views/business/lab/components/selectOrderSamplesDialog.vue' import useCheckList from '@/utils/useCheckList' import { exportFile } from '@/utils/exportUtils' const user = userStore() const pageType = ref('add') // 页面类型: add, edit, detail const infoId = ref('') // id const usePersonList = ref<userType[]>([]) // 申请人列表(用户) const usePersonOptions = ref<userType[]>([]) // 申请人列表(用户)--模糊搜索数据 const applyPersonLoading = ref(false) const customerVisible = ref(false) // 控制选择委托方对话框显隐 const orderVisible = ref(false) // 控制委托单对话框显隐 const customerInfoMap = ref<dictType[]>([]) // 系统字典--航天计量检测技术(江苏)有限公司基本信息 const mesureCategoryList = ref<dictType[]>([]) // 校检类别 const secrecyList = ref<dictType[]>([]) // 保密要求 const minioFileNameSignature = ref() // 签章图片 const minioFileNameAutograph = ref() // 签名图片 const ruleFormRef = ref() // 表单ref const createUser = ref('') // 创建人 // 表单 const dataForm = ref({ interchangeCode: '', // 交接单编号 orderNo: '', // 委托单编号 orderId: '', // 委托单id customerNo: '', // 委托方代码 customerId: '', // 委托方id customerName: '', // 委托方名称 customerAddress: '', // 委托方地址 certificationCompany: '', // 证书单位名称 certificationCompanyAddress: '', // 证书单位地址 reciever: '', // 收发员 recieverSignFile: '', // 收发员签名文件 recieverSignTime: '', // 收发员签名时间 signee: '', // 签收人 signeeSignFile: '', // 签收人签名文件 deliverer: '', // 客户联系人 delivererTel: '', // 送电话样人联系方式 }) // 表单验证规则 const rules = reactive<FormRules>({ orderNo: [{ required: true, message: '要求委托单号必填', trigger: 'blur,change' }], // reciever: [{ required: true, message: '收发员必填', trigger: 'change' }], // signee: [{ required: true, message: '签收人必填', trigger: 'change' }], }) // 签章查询数据 const searchQuerySignature = reactive<queryType>({ signNo: 'qmqz202212050009', // 编号 signName: '', // 名称 signDirector: '', // 负责人 createEndTime: '', createStartTime: '', ids: [], limit: 20, offset: 1, signType: '', // 1签名、2签章 }) // 签名查询数据 const searchQueryAutograph = reactive<queryType>({ signNo: '', // 编号 signName: '', // 名称 signDirector: '', // 负责人 signUserId: '', // 用户id createStartTime: '', createEndTime: '', limit: 20, offset: 1, signType: '', ids: [], }) // 获取字典值 async function getDict() { // 系统字典 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 }) // 获取类型(签名、签章) const res = await getDictByCode('signType') searchQuerySignature.signType = res.data.filter((item: typeofSign) => item.name === '签章')[0].value searchQueryAutograph.signType = res.data.filter((item: typeofSign) => item.name === '签名')[0].value console.log(res.data.filter((item: typeofSign) => item.name === '签章')[0].value) console.log(searchQuerySignature.signType) console.log(searchQueryAutograph.signType) } // 获取签章数据 const getSignatureList = () => { listPageApi(searchQuerySignature).then((res) => { if (res.code === 200) { minioFileNameSignature.value = res.data.rows[0].minioFileName } }) } // 获取签名数据 const getAutographList = () => { listPageApi(searchQueryAutograph).then((res) => { if (res.code === 200) { if (res.data.rows.length) { minioFileNameAutograph.value = res.data.rows[0].minioFileName dataForm.value.recieverSignFile = res.data.rows[0].minioFileName // 接收人/收发员签字文件 } else { minioFileNameAutograph.value = '' dataForm.value.recieverSignFile = '' } } }) } // 从路由中获取页面类型参数 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 selectOrderSamplesDialogRef = ref() // 选择委托单下的样品清单组件ref const sampleList = ref<ISampleList[]>([])// 表格数据 const checkoutSampleList = ref<ISampleList[]>([])// 多选样品列表 // 表头 const columns = ref([ { text: '样品名称', value: 'sampleName', align: 'center', required: true }, { text: '型号规格', value: 'sampleModel', align: 'center', required: true }, { text: '仪器编号', value: 'manufacturingNo', align: 'center', required: true }, { text: '外观状态', value: 'appearanceStatus', align: 'center', required: true }, { text: '备注', value: 'interchangeRemark', align: 'center' }, ]) // 点击批量增加 const multiAdd = () => { if (!dataForm.value.orderId) { ElMessage.warning('请先选择委托单') return } if (!dataForm.value.customerNo) { ElMessage.warning('没有委托方代码,请检查') return } selectOrderSamplesDialogRef.value.initDialog(dataForm.value.orderId, true, 'needFilterByInterchangeId') } // 选好样品 const confirmSelectSample = (val: any) => { val.forEach((item: any) => { // 只添加列表里不存在的 const index = sampleList.value.findIndex((i: ISampleList) => item.sampleNo === i.sampleNo) if (index === -1) { sampleList.value.push({ ...item, appearanceStatus: item.appearanceStatus, // 外观状态 interchangeRemark: item.remark, // 备注 manufacturingNo: item.manufacturingNo, // 出厂编号/仪器编号 orderId: dataForm.value.orderId, // 委托单id sampleId: item.id, // 样品id sampleModel: item.sampleModel, // 样品型号 sampleName: item.sampleName, // 样品名称 sampleNo: item.sampleNo, // 样品编号 }) } }) } // 多选发生改变时 function handleSelectionChange(e: any) { checkoutSampleList.value = e } // 删除样品 const delSample = () => { if (!checkoutSampleList.value.length) { ElMessage.warning('请选中要删除的样品') return false } checkoutSampleList.value.forEach((item: ISampleList) => { sampleList.value.forEach((element, index) => { if (element.sampleId === item.sampleId) { sampleList.value.splice(index, 1) } }) }) } // ----------------------------委托单---------------------------------------------------- // 点击选择委托单编号 const handleClickOrder = () => { orderVisible.value = true } // 修改委托单对话框显隐 const changeOrderVisible = (val: boolean) => { orderVisible.value = val } // 选好委托单 const confirmCheckoutOrder = (val: Array<IOrderList>) => { if (val && val.length) { // 更换委托单需要清空样品列表 if (dataForm.value.orderId !== val[0].id) { sampleList.value = [] } dataForm.value.orderNo = val[0].orderCode // 委托单编号 dataForm.value.orderId = val[0].id // 委托单id dataForm.value.customerNo = val[0].customerNo // 委托方代码 dataForm.value.customerId = val[0].customerId // 委托方id dataForm.value.customerName = val[0].customerName // 委托方名称 dataForm.value.customerAddress = val[0].customerAddress // 委托方地址 dataForm.value.deliverer = val[0].deliverer // 客户联系人 dataForm.value.delivererTel = val[0].delivererTel // 电话 dataForm.value.certificationCompany = val[0].certificationCompany! // 证书单位名称 dataForm.value.certificationCompanyAddress = val[0].certificationCompanyAddress! // 证书单位地址 } } // ------------------------------------------------------------------------------------------------- // 点击保存 const saveForm = (formEl: FormInstance | undefined) => { // if (!dataForm.value.recieverSignFile) { // ElMessage({ // message: '此接收人没有对应签名,请前往系统设置-常用工具-签名管理添加', // type: 'warning', // duration: 5000, // }) // return // } if (!sampleList.value.length) { ElMessage({ message: '交接清单不能为空', type: 'warning', duration: 2000, }) return } if (!useCheckList(sampleList.value, columns.value)) { return } if (!formEl) { return } formEl.validate((valid) => { if (valid) { ElMessageBox.confirm( '确认保存吗?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }, ).then(() => { const params = { ...dataForm.value, // 表单 id: infoId.value, customerSampleList: sampleList.value, // 表格 recieverSignTime: dayjs().format('YYYY-MM-DD'), } if (pageType.value === 'edit') { // 编辑 updateInterchangeReceipt(params).then(() => { ElMessage.success('已保存') pageType.value = 'detail' }) } if (pageType.value === 'add') { // 新建 addInterchangeReceipt(params).then((res: any) => { ElMessage.success('已保存') infoId.value = res.data pageType.value = 'detail' }) } }) } }) } /** * 选好接收人/收发员 * @param userId 用户id */ const changeSelectReceiver = (userId: string) => { // 在用户列表里找到选择的接收人的名字 const name = usePersonList.value.find(item => item.id === userId)!.name // dataForm.value.reciever = name searchQueryAutograph.signUserId = userId // 通过接收人的用户id查询签名 getAutographList() // 调对应接收人的签名 } // 获取用户列表--(是否有不分页接口?) const fetchUserList = () => { getUserList({ offset: 1, limit: 999999 }).then((res: any) => { usePersonList.value = res.data.rows usePersonOptions.value = res.data.rows }) } // 选择器模糊查询 const remoteMethod = (query: string) => { if (query) { applyPersonLoading.value = true setTimeout(() => { applyPersonLoading.value = false usePersonOptions.value = usePersonList.value.filter((item) => { return item.name.toLowerCase().includes(query.toLowerCase()) }) }, 200) } else { usePersonOptions.value = usePersonList.value } } // 获取详情信息 const fetchInterchangeReceiptDetail = () => { const loading = ElLoading.service({ lock: true, text: '加载中...', background: 'rgba(255, 255, 255, 0.8)', }) getInterchangeReceiptDetail({ id: infoId.value }).then((res) => { dataForm.value = res.data // 表单 sampleList.value = res.data.customerSampleList // 样品列表 dataForm.value.orderId = res.data.orderId // orderId minioFileNameAutograph.value = res.data.recieverSignFile // 签名图片 loading.close() }) } const exportExcel = () => { const loading = ElLoading.service({ lock: true, text: '加载中...', background: 'rgba(255, 255, 255, 0.6)', }) getStream({ id: infoId.value }).then((res) => { exportFile(res.data, '样品交接单.xlsx') loading.close() }) } onMounted(async () => { await getDict() // 获取字典 nextTick(() => { if (pageType.value === 'add') { dataForm.value.reciever = user.name // 收发员 createUser.value = user.id // 创建人 } else { fetchInterchangeReceiptDetail() // 获取详情信息 createUser.value = $route.query.createUser as string // 创建人 } getSignatureList() // 获取签章数据 fetchUserList() // 获取用户列表 searchQueryAutograph.signUserId = user.id getAutographList() }) }) </script> <template> <app-container> <div id="main"> <detail-page title="设备交接单"> <template #btns> <el-button v-if="pageType === 'detail'" type="primary" @click="exportExcel"> 导出 </el-button> <el-button v-if="pageType === 'detail' && createUser === user.id" type="primary" @click="pageType = 'edit'"> 编辑 </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 class="customer-title"> <!-- <img src="@/assets/images/logo.png" class="img"> --> <div class="title"> 航天计量检测技术(江苏)有限公司 </div> </div> <div class="interchangeReceipt-subtitle"> 样品交接单 </div> <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="orderNo"> <el-input v-model="dataForm.orderNo" :placeholder="pageType === 'detail' ? '' : '请选择委托单号'" :class="{ 'detail-input': pageType === 'detail' }" disabled > <template v-if="pageType !== 'detail'" #append> <el-button size="small" @click="handleClickOrder"> 选择 </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="12"> <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="客户联系人" prop="deliverer"> <el-input v-model="dataForm.deliverer" :placeholder="pageType === 'detail' ? '' : '客户联系人'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="证书单位名称:" prop="certificationCompany"> <el-input v-model="dataForm.certificationCompany" :class="{ 'detail-input': pageType === 'detail' }" disabled :placeholder="pageType === 'detail' ? '' : '证书单位名称'" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="证书单位地址:" prop="certificationCompanyAddress"> <el-input v-model="dataForm.certificationCompanyAddress" type="textarea" autosize :class="{ 'detail-input': pageType === 'detail' }" :placeholder="pageType === 'detail' ? '' : '证书单位地址'" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="电话" prop="delivererTel"> <el-input v-model="dataForm.delivererTel" :placeholder="pageType === 'detail' ? '' : '电话'" :class="{ 'detail-input': pageType === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="收发员:" prop="reciever"> <el-select v-model="dataForm.reciever" :disabled="pageType === 'detail'" placeholder="请选择收发员" style="width: 100%;" filterable remote remote-show-suffix :remote-method="remoteMethod" :loading="applyPersonLoading" @change="changeSelectReceiver" > <el-option v-for="item in usePersonOptions" :key="item.id" :label="item.name" :value="item.name" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="签收人:" prop="signee"> <el-input v-model="dataForm.signee" :placeholder="pageType === 'detail' ? '' : '请输入签收人'" :class="{ 'detail-input': pageType === 'detail' }" :disabled="pageType === 'detail'" /> </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="info" @click="delSample"> 删除行 </el-button> </template> <el-table :data="sampleList" 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" show-overflow-tooltip align="center" > <template #header> <span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span> </template> <template #default="scope"> <el-input v-if="pageType !== 'detail' && item.value !== 'sampleName'" v-model="scope.row[item.value]" :placeholder="pageType === 'detail' ? ' ' : item.text" :class="{ 'detail-input': pageType === 'detail' }" /> <span v-if="pageType === 'detail' && item.value !== 'sampleName'">{{ scope.row[item.value] }}</span> </template> </el-table-column> </el-table> </detail-block> </div> <!-- 选择委托单下的样品清单 --> <select-order-samples-dialog ref="selectOrderSamplesDialogRef" @confirm="(val: any) => confirmSelectSample(val)" /> <!-- 选择委托单组件 --> <select-order v-model:visible="orderVisible" @confirmCheckout="confirmCheckoutOrder" @changeVisible="changeOrderVisible" /> </app-container> </template> <style lang="scss" scoped> .orderNo-title { font-size: 13px; color: #606266; } .interchangeReceipt-subtitle { text-align: center; margin: 10px 0 32px; font-size: 18px; font-weight: 600; } .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; } } } .receipt-signature { display: flex; justify-content: space-around; // padding: 50px 250px 50px 150px; padding: 50px; font-size: 28px; color: #000; font-weight: 600; .content { display: flex; position: relative; .img { position: absolute; right: 0; top: 0; z-index: 2; } .img-name { position: absolute; left: 220px; top: -30px; z-index: 1; } .title { margin-right: 32px; letter-spacing: 6px; } .deliverer-time { display: flex; flex-direction: column; .text-title { letter-spacing: 2px; } .time { margin-top: 30px; letter-spacing: 2px; } .text { font-size: 24px; font-weight: 500; margin-left: 10px; } } } } </style>