| | |
| | | <template> |
| | | <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr"> |
| | | <MaintainForm ref="maintainFormRef" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | </template> |
| | | </el-drawer> |
| | | <FormDialog |
| | | v-model="visible" |
| | | title="设备维修" |
| | | width="640px" |
| | | :loading="loading" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="90px"> |
| | | <el-form-item label="维修人" prop="maintenanceName"> |
| | | <el-input |
| | | v-model="form.maintenanceName" |
| | | :placeholder="isEditableMaintenanceName ? '请输入维修人姓名' : '报修时指定的维修人'" |
| | | :disabled="!isEditableMaintenanceName" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="维修结果" prop="maintenanceResult"> |
| | | <el-input |
| | | v-model="form.maintenanceResult" |
| | | type="textarea" |
| | | :autosize="{ minRows: 2, maxRows: 6 }" |
| | | placeholder="请输入维修结果" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="维修状态" prop="status"> |
| | | <el-select v-model="form.status" style="width: 100%"> |
| | | <el-option label="待验收" :value="3" /> |
| | | <el-option label="维修失败" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="维修日期" prop="maintenanceTime"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceTime" |
| | | placeholder="请选择维修日期" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="附件"> |
| | | <el-upload |
| | | class="repair-attachment-upload" |
| | | v-model:file-list="attachmentFileList" |
| | | drag |
| | | multiple |
| | | :auto-upload="false" |
| | | :limit="9" |
| | | accept="image/png,image/jpeg,image/jpg" |
| | | :before-upload="beforeAttachmentUpload" |
| | | > |
| | | <el-icon class="repair-upload-icon"><UploadFilled /></el-icon> |
| | | <div class="el-upload__text">将文件拖到此处,或 <em>点击选择文件</em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip"> |
| | | 支持 png / jpg / jpeg,单个不超过 50MB,保存后与列表「附件」同步 |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import MaintainForm from "../Form/MaintainForm.vue"; |
| | | import { addMaintain } from "@/api/equipmentManagement/repair"; |
| | | import { computed } from "vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintain, uploadRepairFile } from "@/api/equipmentManagement/repair"; |
| | | import { REPAIR_FILE_TYPE_MAINTAIN } from "@/api/equipmentManagement/repairFileType.js"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import dayjs from "dayjs"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { UploadFilled } from "@element-plus/icons-vue"; |
| | | |
| | | defineOptions({ |
| | | name: "维修模态框", |
| | | }); |
| | | |
| | | const maintainFormRef = ref(); |
| | | const emits = defineEmits(["ok"]); |
| | | |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "设备维修" }); |
| | | const repairId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const formRef = ref(); |
| | | const attachmentFileList = ref([]); |
| | | const ATTACH_MAX_MB = 50; |
| | | |
| | | const userStore = useUserStore(); |
| | | const systemUserNames = ref([]); |
| | | |
| | | const isSystemUser = (name) => { |
| | | return systemUserNames.value.includes(name); |
| | | }; |
| | | |
| | | // 维修人是否可编辑:外部人员时可以编辑修改 |
| | | const isEditableMaintenanceName = computed(() => { |
| | | const name = form.maintenanceName; |
| | | if (!name) return false; |
| | | return !isSystemUser(name); |
| | | }); |
| | | |
| | | const loadSystemUsers = async () => { |
| | | const res = await userListNoPage(); |
| | | systemUserNames.value = (res?.data || []).map((u) => u.nickName); |
| | | }; |
| | | |
| | | const rules = { |
| | | maintenanceName: [{ required: true, message: "请选择维修人", trigger: "change" }], |
| | | maintenanceResult: [{ required: true, message: "请输入维修结果", trigger: "blur" }], |
| | | maintenanceTime: [{ required: true, message: "请选择维修日期", trigger: "change" }], |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceName: undefined, |
| | | maintenanceResult: undefined, |
| | | maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
| | | status: 3, |
| | | }); |
| | | |
| | | const syncMaintenanceNameFromRow = (row) => { |
| | | form.maintenanceName = row?.maintenanceName || ""; |
| | | }; |
| | | |
| | | const beforeAttachmentUpload = (rawFile) => { |
| | | const okType = ["image/jpeg", "image/jpg", "image/png"].includes(rawFile.type); |
| | | if (!okType) { |
| | | ElMessage.error("只能上传 png / jpg / jpeg 图片"); |
| | | return false; |
| | | } |
| | | if (rawFile.size > ATTACH_MAX_MB * 1024 * 1024) { |
| | | ElMessage.error(`单个文件不能超过 ${ATTACH_MAX_MB}MB`); |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | const clearAttachmentQueue = () => { |
| | | attachmentFileList.value = []; |
| | | }; |
| | | |
| | | const uploadQueuedImages = async (id) => { |
| | | const files = (attachmentFileList.value || []).map((f) => f.raw).filter(Boolean); |
| | | for (const file of files) { |
| | | const fd = new FormData(); |
| | | fd.append("file", file); |
| | | fd.append("deviceRepairId", String(id)); |
| | | fd.append("fileType", String(REPAIR_FILE_TYPE_MAINTAIN)); |
| | | const res = await uploadRepairFile(fd); |
| | | if (res.code !== 200) { |
| | | throw new Error(res.msg || "附件上传失败"); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | | syncMaintenanceNameFromRow(data); |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.maintenanceTime = data.maintenanceTime |
| | | ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.status = 3; |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | const form = await maintainFormRef.value.getForm(); |
| | | const { code } = await addMaintain({ id: id.value, ...form }); |
| | | if (code == 200) { |
| | | emits("ok"); |
| | | maintainFormRef.value.resetForm(); |
| | | closeModal(); |
| | | const valid = await formRef.value?.validate().catch(() => false); |
| | | if (!valid) return; |
| | | const maintenanceName = form.maintenanceName; |
| | | // 如果维修人是系统用户且非当前用户,禁止提交 |
| | | if (isSystemUser(maintenanceName) && maintenanceName !== userStore.nickName) { |
| | | ElMessage.warning("仅指定的维修人可进行维修"); |
| | | return; |
| | | } |
| | | loading.value = false; |
| | | loading.value = true; |
| | | try { |
| | | const { code, msg } = await addMaintain({ id: repairId.value, ...form }); |
| | | if (code !== 200) { |
| | | if (msg) ElMessage.error(msg); |
| | | return; |
| | | } |
| | | if (attachmentFileList.value.length) { |
| | | await uploadQueuedImages(repairId.value); |
| | | } |
| | | ElMessage.success("维修成功"); |
| | | clearAttachmentQueue(); |
| | | visible.value = false; |
| | | emits("ok"); |
| | | } catch (e) { |
| | | ElMessage.error(e?.message || "保存或上传附件失败"); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | clearAttachmentQueue(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | clearAttachmentQueue(); |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | openModal(id); |
| | | repairId.value = id; |
| | | clearAttachmentQueue(); |
| | | visible.value = true; |
| | | await nextTick(); |
| | | maintainFormRef.value.setForm(row); |
| | | await loadSystemUsers(); |
| | | setForm(row); |
| | | const maintenanceName = row?.maintenanceName; |
| | | // 如果维修人是系统用户且非当前用户,禁止操作 |
| | | if (isSystemUser(maintenanceName) && maintenanceName !== userStore.nickName) { |
| | | ElMessage.warning("仅指定的维修人可进行维修"); |
| | | visible.value = false; |
| | | } |
| | | }; |
| | | |
| | | defineExpose({ |
| | |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | | <style lang="scss" scoped> |
| | | .repair-attachment-upload { |
| | | width: 100%; |
| | | :deep(.el-upload) { |
| | | width: 100%; |
| | | } |
| | | :deep(.el-upload-dragger) { |
| | | width: 100%; |
| | | padding: 20px 16px; |
| | | } |
| | | } |
| | | .repair-upload-icon { |
| | | font-size: 42px; |
| | | color: var(--el-color-primary); |
| | | margin-bottom: 8px; |
| | | } |
| | | </style> |