| | |
| | | <div class="actions"> |
| | | <el-text class="mx-1" size="large">设备报修</el-text> |
| | | <div> |
| | | <el-button |
| | | type="primary" |
| | | icon="Plus" |
| | | :disabled="multipleList.length !== 1" |
| | | @click="addMaintain" |
| | | > |
| | | 新增维修 |
| | | </el-button> |
| | | <el-button type="success" icon="Van" @click="addRepair"> |
| | | 新增报修 |
| | | </el-button> |
| | | <el-button @click="handleOut"> |
| | | 导出 |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | icon="Delete" |
| | | :disabled="multipleList.length <= 0" |
| | | :disabled="multipleList.length <= 0 || hasFinishedStatus" |
| | | @click="delRepairByIds(multipleList.map((item) => item.id))" |
| | | > |
| | | 批量删除 |
| | |
| | | </div> |
| | | </div> |
| | | <PIMTable |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :page="{ |
| | | rowKey="id" |
| | | isSelection |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | total: pagination.total, |
| | | }" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="changePage" |
| | | @selection-change="handleSelectionChange" |
| | | @pagination="changePage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 1" type="success">完结</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">待维修</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">待维修</el-tag> |
| | | <el-tag v-else-if="row.status === 3" type="info">待验收</el-tag> |
| | | <el-tag v-else-if="row.status === 1" type="success">完成</el-tag> |
| | | <el-tag v-else-if="row.status === 2" type="danger">维修失败</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="editPen" |
| | | @click="editRepair(row.id)" |
| | | > |
| | | <el-button type="info" link @click="openRepairDetail(row.id)"> |
| | | 详情 |
| | | </el-button> |
| | | <el-button type="primary" link :disabled="!canEdit(row)" @click="editRepair(row.id)"> |
| | | 编辑 |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | icon="delete" |
| | | @click="delRepairByIds(row.id)" |
| | | > |
| | | <el-button type="success" link :disabled="!canMaintain(row)" @click="addMaintain(row)"> |
| | | 维修 |
| | | </el-button> |
| | | <el-button type="warning" link :disabled="!canAccept(row)" @click="openAcceptance(row)"> |
| | | 验收 |
| | | </el-button> |
| | | <el-button type="danger" link :disabled="!canDelete(row)" @click="delRepairByIds(row.id)"> |
| | | 删除 |
| | | </el-button> |
| | | <el-button type="primary" link @click="openAttachment(row)"> |
| | | 附件 |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <RepairModal ref="repairModalRef" @ok="getTableData" /> |
| | | <MaintainModal ref="maintainModalRef" @ok="getTableData" /> |
| | | <RepairModal ref="repairModalRef" @ok="getTableData"/> |
| | | <MaintainModal ref="maintainModalRef" @ok="getTableData"/> |
| | | <AcceptanceModal ref="acceptanceModalRef" @ok="getTableData"/> |
| | | <RepairDetailModal ref="repairDetailModalRef" :java-api="javaApi" /> |
| | | |
| | | <el-dialog v-model="attachment.visible" title="附件" width="900px" @closed="onAttachmentClosed"> |
| | | <div v-loading="attachment.loading" class="attachment-wrap"> |
| | | <p v-if="attachmentReadOnly" class="attachment-readonly-tip"> |
| | | 已开始维修,此处仅可查看;设备问题图请在报修「待维修」时于「编辑」中维护;维修完成图请在「维修」时上传。 |
| | | </p> |
| | | <div class="attachment-section"> |
| | | <div class="attachment-section-title">设备问题图片</div> |
| | | <template v-if="attachmentReadOnly"> |
| | | <div v-if="attachment.problemFileList.length" class="attachment-readonly-grid"> |
| | | <div |
| | | v-for="f in attachment.problemFileList" |
| | | :key="f.id" |
| | | class="attachment-readonly-item" |
| | | @click="handleAttachmentPreview(f)" |
| | | > |
| | | <el-image :src="f.url" fit="cover" class="attachment-readonly-img" /> |
| | | </div> |
| | | </div> |
| | | <el-empty |
| | | v-else |
| | | description="暂无设备问题图片" |
| | | :image-size="60" |
| | | /> |
| | | </template> |
| | | <template v-else> |
| | | <el-upload |
| | | v-model:file-list="attachment.problemFileList" |
| | | :action="upload.url" |
| | | multiple |
| | | auto-upload |
| | | :headers="upload.headers" |
| | | :data="uploadDataProblem" |
| | | :before-upload="handleAttachmentBeforeUpload" |
| | | :on-error="handleAttachmentUploadError" |
| | | :on-success="() => handleAttachmentUploadSuccess('problem')" |
| | | :on-preview="handleAttachmentPreview" |
| | | :on-remove="(file) => handleAttachmentRemove(file, 'problem')" |
| | | list-type="picture-card" |
| | | :limit="9" |
| | | accept="image/png,image/jpeg,image/jpg" |
| | | > |
| | | + |
| | | </el-upload> |
| | | <el-empty |
| | | v-if="!attachment.loading && attachment.problemFileList.length === 0" |
| | | description="暂无设备问题图片" |
| | | :image-size="60" |
| | | /> |
| | | </template> |
| | | </div> |
| | | <div class="attachment-section"> |
| | | <div class="attachment-section-title">维修完成图片</div> |
| | | <p v-if="!attachmentReadOnly" class="attachment-readonly-tip" style="margin-top: 0"> |
| | | 维修完成图请在列表「维修」操作中上传,此处仅查看。 |
| | | </p> |
| | | <div v-if="attachment.maintainFileList.length" class="attachment-readonly-grid"> |
| | | <div |
| | | v-for="f in attachment.maintainFileList" |
| | | :key="f.id" |
| | | class="attachment-readonly-item" |
| | | @click="handleAttachmentPreview(f)" |
| | | > |
| | | <el-image :src="f.url" fit="cover" class="attachment-readonly-img" /> |
| | | </div> |
| | | </div> |
| | | <el-empty |
| | | v-else |
| | | description="暂无维修完成图片" |
| | | :image-size="60" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <el-button @click="attachment.visible = false">关闭</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog |
| | | v-model="attachment.previewVisible" |
| | | title="图片预览" |
| | | width="70%" |
| | | append-to-body |
| | | > |
| | | <div class="attachment-preview-wrap"> |
| | | <img |
| | | v-if="attachment.previewUrl" |
| | | :src="attachment.previewUrl" |
| | | alt="preview" |
| | | class="attachment-preview-img" |
| | | /> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { usePaginationApi } from "@/hooks/usePaginationApi"; |
| | | import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair"; |
| | | import { onMounted } from "vue"; |
| | | import { onMounted, getCurrentInstance, computed } from "vue"; |
| | | import {usePaginationApi} from "@/hooks/usePaginationApi"; |
| | | import { |
| | | getRepairPage, |
| | | delRepair, |
| | | getRepairFileList, |
| | | deleteRepairFile, |
| | | } from "@/api/equipmentManagement/repair"; |
| | | import RepairModal from "./Modal/RepairModal.vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import {ElMessageBox, ElMessage} from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import MaintainModal from "./Modal/MaintainModal.vue"; |
| | | import AcceptanceModal from "./Modal/AcceptanceModal.vue"; |
| | | import RepairDetailModal from "./Modal/RepairDetailModal.vue"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import { |
| | | REPAIR_FILE_TYPE_PROBLEM, |
| | | isProblemRepairFile, |
| | | isMaintainRepairFile, |
| | | } from "@/api/equipmentManagement/repairFileType.js"; |
| | | |
| | | defineOptions({ |
| | | name: "设备报修", |
| | | }); |
| | | |
| | | const {proxy} = getCurrentInstance(); |
| | | const javaApi = proxy?.javaApi || ""; |
| | | |
| | | // 模态框实例 |
| | | const repairModalRef = ref(); |
| | | const maintainModalRef = ref(); |
| | | const acceptanceModalRef = ref(); |
| | | const repairDetailModalRef = ref(); |
| | | const userStore = useUserStore(); |
| | | const systemUserNames = ref([]); |
| | | |
| | | const loadSystemUsers = async () => { |
| | | const res = await userListNoPage(); |
| | | systemUserNames.value = (res?.data || []).map((u) => u.nickName); |
| | | }; |
| | | |
| | | const isSystemUser = (name) => systemUserNames.value.includes(name); |
| | | |
| | | // 表格多选框选中项 |
| | | const multipleList = ref([]); |
| | | |
| | | const attachment = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | deviceRepairId: undefined, |
| | | /** 报修单状态:非待维修(0)时附件弹窗只读 */ |
| | | repairStatus: undefined, |
| | | files: [], |
| | | problemFileList: [], |
| | | maintainFileList: [], |
| | | previewVisible: false, |
| | | previewUrl: "", |
| | | }); |
| | | |
| | | /** 已开始维修后:列表「附件」仅查看,不可增删 */ |
| | | const attachmentReadOnly = computed( |
| | | () => attachment.repairStatus != null && attachment.repairStatus !== 0 |
| | | ); |
| | | |
| | | const uploadDataProblem = computed(() => ({ |
| | | deviceRepairId: attachment.deviceRepairId, |
| | | fileType: REPAIR_FILE_TYPE_PROBLEM, |
| | | })); |
| | | |
| | | const toUploadFileItem = (item) => ({ |
| | | id: item.id, |
| | | name: item.name, |
| | | url: getFileAccessUrl(item), |
| | | fileType: item.type, |
| | | }); |
| | | |
| | | const getFileAccessUrl = (file = {}) => { |
| | | if (file?.link) { |
| | | if (String(file.link).startsWith('http')) return file.link; |
| | | return normalizeFileUrl(file.link); |
| | | } |
| | | return normalizeFileUrl(file?.url || ''); |
| | | }; |
| | | |
| | | const normalizeFileUrl = (rawUrl = '') => { |
| | | let fileUrl = rawUrl || ''; |
| | | |
| | | if (fileUrl && fileUrl.indexOf('\\') > -1) { |
| | | const lowerPath = fileUrl.toLowerCase(); |
| | | const uploadPathIndex = lowerPath.indexOf('uploadpath'); |
| | | |
| | | if (uploadPathIndex > -1) { |
| | | fileUrl = fileUrl |
| | | .substring(uploadPathIndex) |
| | | .replace(/\\/g, '/'); |
| | | } else { |
| | | fileUrl = fileUrl.replace(/\\/g, '/'); |
| | | } |
| | | } |
| | | fileUrl = fileUrl.replace(/^\/?uploadPath/, '/profile'); |
| | | |
| | | if (!fileUrl.startsWith('http')) { |
| | | if (!fileUrl.startsWith('/')) fileUrl = '/' + fileUrl; |
| | | fileUrl = javaApi + fileUrl; |
| | | } |
| | | |
| | | return fileUrl; |
| | | }; |
| | | |
| | | const attachmentUploadAction = "/device/repair/uploadFile"; |
| | | const upload = reactive({ |
| | | url: import.meta.env.VITE_APP_BASE_API + attachmentUploadAction, |
| | | headers: { |
| | | Authorization: "Bearer " + getToken(), |
| | | }, |
| | | }); |
| | | |
| | | // 表格钩子 |
| | | const { |
| | |
| | | resetFilters, |
| | | onCurrentChange, |
| | | } = usePaginationApi( |
| | | getRepairPage, |
| | | { |
| | | searchText: undefined, |
| | | }, |
| | | [ |
| | | getRepairPage, |
| | | { |
| | | label: "设备名称", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | remark: undefined, |
| | | maintenanceName: undefined, |
| | | repairTimeStr: undefined, |
| | | maintenanceTimeStr: undefined, |
| | | }, |
| | | { |
| | | label: "规格型号", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "报修日期", |
| | | align: "center", |
| | | prop: "repairTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "报修人", |
| | | align: "center", |
| | | prop: "repairName", |
| | | }, |
| | | { |
| | | label: "故障现象", |
| | | align: "center", |
| | | prop: "remark", |
| | | }, |
| | | { |
| | | label: "维修人", |
| | | align: "center", |
| | | prop: "maintenanceName", |
| | | }, |
| | | { |
| | | label: "维修结果", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | }, |
| | | { |
| | | label: "维修日期", |
| | | align: "center", |
| | | prop: "maintenanceTime", |
| | | formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""), |
| | | }, |
| | | { |
| | | label: "状态", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "操作", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "200px", |
| | | }, |
| | | ] |
| | | [ |
| | | { |
| | | label: "设备名称", |
| | | align: "center", |
| | | prop: "deviceName", |
| | | }, |
| | | { |
| | | label: "规格型号", |
| | | align: "center", |
| | | prop: "deviceModel", |
| | | }, |
| | | { |
| | | label: "报修日期", |
| | | align: "center", |
| | | prop: "repairTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"), |
| | | }, |
| | | { |
| | | label: "报修人", |
| | | align: "center", |
| | | prop: "repairName", |
| | | }, |
| | | { |
| | | label: "验收人", |
| | | align: "center", |
| | | prop: "acceptanceName", |
| | | }, |
| | | { |
| | | label: "故障现象", |
| | | align: "center", |
| | | prop: "remark", |
| | | }, |
| | | { |
| | | label: "维修人", |
| | | align: "center", |
| | | prop: "maintenanceName", |
| | | }, |
| | | { |
| | | label: "维修结果", |
| | | align: "center", |
| | | prop: "maintenanceResult", |
| | | }, |
| | | { |
| | | label: "维修日期", |
| | | align: "center", |
| | | prop: "maintenanceTime", |
| | | formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""), |
| | | }, |
| | | { |
| | | label: "状态", |
| | | align: "center", |
| | | prop: "status", |
| | | dataType: "slot", |
| | | slot: "statusRef", |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "操作", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | | align: "center", |
| | | width: "420px", |
| | | }, |
| | | ] |
| | | ); |
| | | |
| | | const isCurrentUser = (name) => !!name && name === userStore.nickName; |
| | | |
| | | const canEdit = (row) => row.status === 0; |
| | | // 仅报修时指定的维修人或外部人员时由报修人提交维修 |
| | | const canMaintain = (row) => { |
| | | if (row.status !== 0) return false; |
| | | if (!row.maintenanceName) return false; |
| | | if (isSystemUser(row.maintenanceName)) { |
| | | return isCurrentUser(row.maintenanceName); |
| | | } |
| | | return true; |
| | | }; |
| | | const canDelete = (row) => row.status === 0; |
| | | /** 仅报修时指定的验收人可验收 */ |
| | | const canAccept = (row) => { |
| | | if (row.status !== 3) return false; |
| | | if (!row.acceptanceName) return false; |
| | | return isCurrentUser(row.acceptanceName); |
| | | }; |
| | | |
| | | // type === 1 维修 2报修间 |
| | | const handleDateChange = (value,type) => { |
| | | const handleDateChange = (value, type) => { |
| | | filters.maintenanceTimeStr = null |
| | | filters.c = null |
| | | if(type === 1){ |
| | | if (type === 1) { |
| | | if (value) { |
| | | filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | | }else{ |
| | | } else { |
| | | if (value) { |
| | | filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD"); |
| | | } |
| | |
| | | multipleList.value = selectionList; |
| | | }; |
| | | |
| | | // 批量删除:仅允许待维修 |
| | | const hasFinishedStatus = computed(() => { |
| | | return multipleList.value.some((item) => item.status !== 0); |
| | | }); |
| | | |
| | | const openRepairDetail = (id) => { |
| | | repairDetailModalRef.value?.open(id); |
| | | }; |
| | | |
| | | // 新增报修 |
| | | const addRepair = () => { |
| | | repairModalRef.value.openAdd(); |
| | |
| | | repairModalRef.value.openEdit(id); |
| | | }; |
| | | |
| | | // 新增维修 |
| | | const addMaintain = () => { |
| | | const row = multipleList.value[0]; |
| | | // 维修(仅指定维修人) |
| | | const addMaintain = (row) => { |
| | | if (!canMaintain(row)) { |
| | | ElMessage.warning("仅指定的维修人可进行维修"); |
| | | return; |
| | | } |
| | | maintainModalRef.value.open(row.id, row); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | onCurrentChange(page); |
| | | // 验收(仅报修时指定的验收人、且待验收状态可点) |
| | | const openAcceptance = (row) => { |
| | | if (!canAccept(row)) { |
| | | ElMessage.warning("仅指定的验收人可进行验收"); |
| | | return; |
| | | } |
| | | acceptanceModalRef.value.open(row.id, row); |
| | | }; |
| | | |
| | | const changePage = ({page, limit}) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | onCurrentChange(page); |
| | | }; |
| | | |
| | | // 单行删除 |
| | | const delRepairByIds = async (ids) => { |
| | | // 检查是否有完结状态的记录 |
| | | const idsArray = Array.isArray(ids) ? ids : [ids]; |
| | | const cannotDelete = idsArray.some((id) => { |
| | | const record = dataList.value.find((item) => item.id === id); |
| | | return record && record.status !== 0; |
| | | }); |
| | | |
| | | if (cannotDelete) { |
| | | ElMessage.warning("仅待维修状态可删除"); |
| | | return; |
| | | } |
| | | |
| | | ElMessageBox.confirm("确认删除报修数据, 此操作不可逆?", "警告", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }).then(async () => { |
| | | const { code } = await delRepair(ids); |
| | | const {code} = await delRepair(ids); |
| | | if (code === 200) { |
| | | ElMessage.success("删除成功"); |
| | | getTableData(); |
| | |
| | | }); |
| | | }; |
| | | |
| | | // 导出 |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/device/repair/export", {}, "设备报修.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.info("已取消"); |
| | | }); |
| | | }; |
| | | |
| | | const openAttachment = async (row) => { |
| | | attachment.problemFileList = []; |
| | | attachment.maintainFileList = []; |
| | | attachment.repairStatus = row?.status; |
| | | attachment.visible = true; |
| | | attachment.deviceRepairId = row?.id; |
| | | await refreshAttachmentList(); |
| | | }; |
| | | |
| | | const refreshAttachmentList = async () => { |
| | | if (!attachment.deviceRepairId) return; |
| | | attachment.loading = true; |
| | | try { |
| | | const res = await getRepairFileList(attachment.deviceRepairId); |
| | | attachment.files = Array.isArray(res?.data) ? res.data : []; |
| | | attachment.problemFileList = attachment.files |
| | | .filter((item) => isProblemRepairFile(item.type)) |
| | | .map(toUploadFileItem); |
| | | attachment.maintainFileList = attachment.files |
| | | .filter((item) => isMaintainRepairFile(item.type)) |
| | | .map(toUploadFileItem); |
| | | } finally { |
| | | attachment.loading = false; |
| | | } |
| | | }; |
| | | |
| | | const onAttachmentClosed = () => { |
| | | attachment.loading = false; |
| | | attachment.deviceRepairId = undefined; |
| | | attachment.repairStatus = undefined; |
| | | attachment.files = []; |
| | | attachment.problemFileList = []; |
| | | attachment.maintainFileList = []; |
| | | attachment.previewVisible = false; |
| | | attachment.previewUrl = ""; |
| | | }; |
| | | |
| | | const handleAttachmentBeforeUpload = (file) => { |
| | | if (attachmentReadOnly.value) { |
| | | return false; |
| | | } |
| | | const isImage = ["image/png", "image/jpeg", "image/jpg"].includes(file.type); |
| | | if (!isImage) { |
| | | ElMessage.error("只能上传 png/jpg/jpeg 图片"); |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | const handleAttachmentUploadSuccess = async () => { |
| | | ElMessage.success("上传成功"); |
| | | await refreshAttachmentList(); |
| | | }; |
| | | |
| | | const handleAttachmentUploadError = () => { |
| | | ElMessage.error("上传失败"); |
| | | }; |
| | | |
| | | const handleAttachmentPreview = (file) => { |
| | | const rawUrl = file?.url || file?.response?.data?.link || file?.response?.data?.url || ""; |
| | | if (!rawUrl) { |
| | | ElMessage.warning("图片地址无效,无法预览"); |
| | | return; |
| | | } |
| | | attachment.previewUrl = normalizeFileUrl(rawUrl); |
| | | attachment.previewVisible = true; |
| | | }; |
| | | |
| | | const handleAttachmentRemove = async (file, category) => { |
| | | if (attachmentReadOnly.value) { |
| | | return false; |
| | | } |
| | | const matched = attachment.files.find((item) => item.id === file?.id) |
| | | || attachment.files.find((item) => item.name === file?.name); |
| | | if (!matched) return; |
| | | const expectProblem = category === "problem"; |
| | | if (expectProblem && !isProblemRepairFile(matched.type)) return; |
| | | if (!expectProblem && !isMaintainRepairFile(matched.type)) return; |
| | | try { |
| | | await confirmDeleteAttachment(matched); |
| | | } finally { |
| | | await refreshAttachmentList(); |
| | | } |
| | | }; |
| | | |
| | | const confirmDeleteAttachment = (fileRow) => { |
| | | return ElMessageBox.confirm("确认删除该附件?", "警告", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }).then(async () => { |
| | | const { code } = await deleteRepairFile(fileRow.id); |
| | | if (code === 200) { |
| | | ElMessage.success("删除成功"); |
| | | await refreshAttachmentList(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getTableData(); |
| | | loadSystemUsers(); |
| | | }); |
| | | </script> |
| | | |
| | |
| | | .table_list { |
| | | margin-top: unset; |
| | | } |
| | | |
| | | .actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .attachment-wrap { |
| | | min-height: 240px; |
| | | } |
| | | |
| | | .attachment-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | .attachment-section-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 12px; |
| | | padding-left: 8px; |
| | | border-left: 3px solid var(--el-color-primary); |
| | | } |
| | | |
| | | .attachment-readonly-tip { |
| | | font-size: 13px; |
| | | color: var(--el-text-color-secondary); |
| | | margin-bottom: 16px; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | .attachment-readonly-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .attachment-readonly-item { |
| | | width: 100px; |
| | | height: 100px; |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | cursor: pointer; |
| | | border: 1px solid var(--el-border-color); |
| | | } |
| | | |
| | | .attachment-readonly-img { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .attachment-preview-wrap { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | min-height: 360px; |
| | | } |
| | | |
| | | .attachment-preview-img { |
| | | max-width: 100%; |
| | | max-height: 70vh; |
| | | object-fit: contain; |
| | | } |
| | | |
| | | </style> |