<!-- 受检设备信息列表 --> <script lang="ts" setup name="ReviewDeviceTable"> // import { ElMessage, ElMessageBox } from 'element-plus' import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import { uploadApi } from '@/api/system/notice' import { useCheckList } from '@/utils/useCheckList' import subpackageDialog from '@/views/tested/subpackage/task/components/subpackageDialog.vue' import { uniqueMultiArray } from '@/utils/Array' import showPhoto from '@/views/tested/device/info/components/showPhotoSinge.vue' const $props = defineProps({ data: { type: Array, default: () => ([]), }, }) const $route = useRoute() const $router = useRouter() // 表头显示标题 const columns = ref([ { text: '设备名称', value: 'equipmentName', required: false, type: 'text', width: 180, }, { text: '规格型号', value: 'equipmentModel', required: false, type: 'text', width: 180, }, { text: '辅助字段', value: 'helpInstruction', required: false, type: 'text', width: 180, }, { text: '出厂编号', value: 'manufactureNo', required: false, type: 'text', width: 180, }, { text: '生产厂家', value: 'manufacturer', required: false, type: 'text', width: 180, }, { text: '计量标识', value: 'meterIdentifyName', required: false, type: 'text', width: 120, }, // { // text: '限用说明', // value: 'limitInstruction', // required: false, // type: 'input', // width: 180 // }, { text: '上次送检单位', value: 'checkOrganization', required: false, type: 'text', width: 180, }, { text: '证书编号', value: 'certificateNo', required: true, type: 'input', width: 180, }, { text: '证书名称', value: 'certificateName', required: true, type: 'input', width: 180, }, { text: '证书有效期', value: 'certificateValid', required: true, type: 'date', width: 180, }, { text: '检定(校准)机构', value: 'subcontractorName', required: true, type: 'input', width: 180, }, { text: '检定(校准)日期', value: 'checkDate', required: true, type: 'date', width: 180, }, { text: '证书附件', value: 'certificateReport', required: false, type: 'upload', width: 300, }, ]) const list = ref<any[]>([]) // 检查数据列表 function checkCertificateList() { return useCheckList(list.value, columns.value as any, '设备清单') } // 将列表置为不可编辑状态 function setAllRowReadable() { for (const item of list.value) { item.editable = false } } // 双击行显示输入框 const dblclickRow = (row: any) => { if ($route.path.includes('detail')) { return } setAllRowReadable() row.editable = true } const SelectionList = ref() // 表格选中 const handleSelectionChange = (e: any[]) => { SelectionList.value = e } watch(() => $props.data, (newVal) => { if (newVal) { list.value = newVal fetchTogetherData() } }) const initDialog = () => { list.value = $props.data } initDialog() defineExpose({ list, checkCertificateList, }) // 选择设备 const deviceRef = ref() const confirm = (device: any) => { // 多选 device.forEach((item: any) => { list.value.push({ ...item, equipmentId: item.id, id: null, groupId: null, editable: true, }) }) } // --------------------------------------------表格操作-------------------------------------------- // 表格标识 const tableFlag = ref('normal')// normal普通表格 together聚合表格 // 切换表格 const changeTable = () => { if (tableFlag.value === 'normal') { tableFlag.value = 'together' } else { tableFlag.value = 'normal' } } const togetherColumns = ref([ { text: '', value: '', align: 'center', width: '38', }, { text: '设备名称', value: 'equipmentName', align: 'center', }, { text: '总计', value: 'deviceNum', align: 'center', }, ]) const togetherList = ref<any>([]) const expandList = ref<any>([]) function fetchTogetherData() { togetherList.value = [] const equipmentNames = uniqueMultiArray(list.value, 'equipmentName') equipmentNames.forEach((element: any) => { togetherList.value.push({ equipmentName: element.equipmentName, deviceNum: list.value.filter((citem: any) => citem.equipmentName === element.equipmentName).length, }) }) } const getRowKeys = (row: any) => { // 获取当前行id return row.equipmentName // 这里看这一行中需要根据哪个属性值是id } // 控制展开行 const expands = ref<any[]>([]) const expandChange = (row: any, expandedRows: any) => { if (expandedRows.length) { expands.value = [] if (row) { expands.value.push(row.equipmentName) } } else { expands.value = [] } } watch(() => expands.value, (newVal) => { expandList.value = list.value.filter((item: any) => item.equipmentName === newVal[0]) }, { deep: true, }) // 选择分包方 const subcontractorsRef = ref() const $index = ref(-1) const selectSubcontractors = (text: string, index: number) => { if (text !== '检定(校准)机构') { return } subcontractorsRef.value.initDialog() $index.value = index } const confirmSubcontractors = (subcontractors: any) => { list.value[$index.value].subcontractorNo = subcontractors.subcontractorNo list.value[$index.value].subcontractorName = subcontractors.companyName list.value[$index.value].subcontractorId = subcontractors.id } const fileRef = ref() // 文件上传input,获取input的引用 const uploadIndex = ref(-1) const upload = (index: number) => { uploadIndex.value = index fileRef.value.click() } const onFileChange = (event: any) => { // 原生上传 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)', }) uploadApi(fd).then((res) => { if (res.code === 200) { list.value[uploadIndex.value].certificateReport = res.data[0] ElMessage.success('文件上传成功') fileRef.value.value = '' loading.close() } else { fileRef.value.value = '' ElMessage.error(res.message) loading.close() } }).catch(() => { fileRef.value.value = '' loading.close() }) } } </script> <template> <detail-block-switch title="设备清单"> <!-- 分包方弹窗 --> <subpackage-dialog ref="subcontractorsRef" @add="confirmSubcontractors" /> <template #btns> <template v-if="$route.path.includes('detail')"> <icon-button icon="icon-change" title="切换列表状态" @click="changeTable" /> </template> </template> <!-- 普通表格 --> <el-table v-show="tableFlag === 'normal'" ref="multipleTableRef" :data="list" style="width: 100%;" border :height="list.length > 8 ? 500 : null" @selection-change="handleSelectionChange" > <el-table-column align="center" label="#" width="55" type="index" /> <el-table-column v-for="item in columns" :key="item.value" :width="item.width" :prop="item.value" :label="item.text" align="center" > <template #header> <span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span> </template> <template #default="scope"> <span v-if="!scope.row.editable" class="cur">{{ scope.row[item.value] }}</span> <span v-if="scope.row.editable && item.type === 'text'" class="cur">{{ scope.row[item.value] }}</span> <el-input v-if="scope.row.editable && item.type === 'input'" v-model="scope.row[item.value]" :placeholder="`${item.text}`" class="input" style="width: 100%;" @focus="selectSubcontractors(item.text, scope.$index)" /> <el-date-picker v-if="scope.row.editable && item.type === 'date'" v-model="scope.row[item.value]" type="date" :placeholder="`${item.text}`" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%;" /> <span v-if="scope.row.editable && item.type === 'upload'" style="display: flex;"> <show-photo :minio-file-name="scope.row[item.value]" /> <el-button type="primary" @click="upload(scope.$index)"> {{ scope.row[item.value] ? '更换' : '上传' }} </el-button> </span> </template> </el-table-column> </el-table> <input ref="fileRef" style="display: none;" type="file" accept=".doc,.docx,.pdf" @change="onFileChange"> <!-- 头部 --> <normal-table v-show="tableFlag === 'together'" class="nortable-header" :data="[]" :total="0" :columns="togetherColumns as any" :options="{ needIndex: false, // 是否需要序号列 border: true, // 是否需要上方边框 } " :pagination="false" :is-showmulti-select="false" :query="{}" /> <!-- 身体 --> <el-table v-show="tableFlag === 'together'" ref="togetherTableRef" :data="togetherList" border style="width: 100%;" :row-key="getRowKeys" :expand-row-keys="expands" :show-header="false" @expand-change="expandChange" > <el-table-column type="expand" width="38"> <template #default> <el-table ref="expandTableRef" :data="expandList" border style="width: 100%;"> <el-table-column v-for="item in columns" :key="item.value" :label="item.text" :prop="item.value" align="center" /> </el-table> </template> </el-table-column> <el-table-column label="设备名称" prop="equipmentName" align="center" /> <el-table-column label="数量" align="center"> <template #default="scope"> 共计{{ scope.row.deviceNum }}台 </template> </el-table-column> </el-table> </detail-block-switch> </template> <style lang="scss" scoped> .el-dialog { width: 700px; } .el-select { width: 100%; } .cur { &:hover { cursor: pointer; } } .nortable-header { ::v-deep(.el-table__body-wrapper) { display: none; } } ::v-deep(.el-table__expanded-cell) { padding: 0; } </style>