| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="现场照片"> |
| | | <div class="repair-upload-area"> |
| | | <el-upload |
| | | v-model:file-list="uploadFileList" |
| | | :action="uploadUrl" |
| | | :headers="uploadHeaders" |
| | | accept="image/*" |
| | | list-type="picture-card" |
| | | :limit="uploadLimit" |
| | | :on-success="handleUploadSuccess" |
| | | :on-remove="handleRemoveFile" |
| | | :before-upload="beforeUpload" |
| | | > |
| | | <el-icon><Plus /></el-icon> |
| | | </el-upload> |
| | | <div v-if="repairFileList.length === 0" class="upload-tip">请上传现场照片,最多 {{ uploadLimit }} 张</div> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | |
| | | getRepairById, |
| | | } from "@/api/equipmentManagement/repair"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { Plus } from "@element-plus/icons-vue"; |
| | | import dayjs from "dayjs"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | defineOptions({ |
| | | name: "设备报修弹窗", |
| | |
| | | const userStore = useUserStore(); |
| | | const deviceOptions = ref([]); |
| | | |
| | | // 现场照片上传(与 APP 字段一致:fileList / commonFileList) |
| | | const uploadUrl = import.meta.env.VITE_APP_BASE_API + "/file/upload"; |
| | | const uploadLimit = 10; |
| | | const uploadFileList = ref([]); |
| | | const repairFileList = ref([]); |
| | | const uploadHeaders = { Authorization: "Bearer " + getToken() }; |
| | | const baseApi = import.meta.env.VITE_APP_BASE_API || ""; |
| | | |
| | | const formatFileUrl = (url) => { |
| | | if (!url) return ""; |
| | | if (url.startsWith("http://") || url.startsWith("https://")) return url; |
| | | const path = url.replace(/^\/+/, ""); |
| | | return path ? baseApi + "/" + path : baseApi; |
| | | }; |
| | | |
| | | const loadDeviceName = async () => { |
| | | const { data } = await getDeviceLedger(); |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设备Id |
| | | deviceName: undefined, // 设备名称 |
| | | deviceModel: undefined, // 规格型号 |
| | | repairTime: dayjs().format("YYYY-MM-DD"), // 报修日期,默认当天 |
| | | repairName: userStore.nickName, // 报修人 |
| | | remark: undefined, // 故障现象 |
| | | status: 0, // 报修状态 |
| | | deviceLedgerId: undefined, |
| | | deviceName: undefined, |
| | | deviceModel: undefined, |
| | | repairTime: dayjs().format("YYYY-MM-DD"), |
| | | repairName: userStore.nickName, |
| | | remark: undefined, |
| | | status: 0, |
| | | }); |
| | | |
| | | const setDeviceModel = (deviceId) => { |
| | | const option = deviceOptions.value.find((item) => item.id === deviceId); |
| | | form.deviceModel = option.deviceModel; |
| | | }; |
| | | |
| | | const beforeUpload = (file) => { |
| | | const isImage = file.type.startsWith("image/"); |
| | | if (!isImage) { |
| | | ElMessage.warning("只能上传图片"); |
| | | return false; |
| | | } |
| | | if (repairFileList.value.length >= uploadLimit) { |
| | | ElMessage.warning(`最多上传 ${uploadLimit} 张图片`); |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | const handleUploadSuccess = (res, file) => { |
| | | if (res?.code !== 200 && res?.code !== 0) { |
| | | ElMessage.error(res?.msg || "上传失败"); |
| | | const idx = uploadFileList.value.findIndex((f) => f.uid === file.uid); |
| | | if (idx > -1) uploadFileList.value.splice(idx, 1); |
| | | return; |
| | | } |
| | | const d = res?.data !== undefined ? res.data : res; |
| | | if (!d) return; |
| | | const item = { |
| | | uid: file.uid, |
| | | id: d.id, |
| | | url: d.url || d.downloadUrl || d.tempPath, |
| | | downloadUrl: d.downloadUrl || d.url, |
| | | bucketFilename: d.bucketFilename || d.originalFilename || file.name, |
| | | originalFilename: d.originalFilename || d.bucketFilename || file.name, |
| | | name: d.bucketFilename || d.originalFilename || file.name, |
| | | size: d.size ?? d.byteSize ?? file.size, |
| | | byteSize: d.byteSize ?? d.size ?? file.size, |
| | | uploadResponse: res, |
| | | }; |
| | | repairFileList.value.push(item); |
| | | }; |
| | | |
| | | const handleRemoveFile = (file) => { |
| | | const targetUrl = file.url || file.response?.data?.url || file.response?.data?.downloadUrl; |
| | | repairFileList.value = repairFileList.value.filter( |
| | | (f) => f.uid !== file.uid && (f.url || f.downloadUrl) !== targetUrl |
| | | ); |
| | | }; |
| | | |
| | | const setForm = (data) => { |
| | |
| | | form.repairName = data.repairName; |
| | | form.remark = data.remark; |
| | | form.status = data.status; |
| | | const list = data.fileList || data.commonFileList || []; |
| | | repairFileList.value = (Array.isArray(list) ? list : []).map((f, i) => ({ |
| | | uid: f.id || "existing-" + i, |
| | | id: f.id, |
| | | url: f.url || f.downloadUrl, |
| | | downloadUrl: f.downloadUrl || f.url, |
| | | bucketFilename: f.bucketFilename || f.originalFilename || f.name, |
| | | originalFilename: f.originalFilename || f.bucketFilename || f.name, |
| | | name: f.bucketFilename || f.originalFilename || f.name || "图片", |
| | | size: f.size ?? f.byteSize, |
| | | byteSize: f.byteSize ?? f.size, |
| | | ...f, |
| | | })); |
| | | uploadFileList.value = repairFileList.value.map((f, i) => ({ |
| | | uid: f.uid || "existing-" + i, |
| | | name: f.name || f.bucketFilename || "图片", |
| | | url: formatFileUrl(f.url || f.downloadUrl), |
| | | status: "success", |
| | | })); |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | try { |
| | | const fileList = repairFileList.value.map((f) => { |
| | | const d = f.uploadResponse?.data !== undefined ? f.uploadResponse.data : f.uploadResponse; |
| | | return d ? { ...d } : (f.id || f.url ? { ...f } : null); |
| | | }).filter(Boolean); |
| | | const submitData = { ...form }; |
| | | if (fileList.length) submitData.fileList = fileList; |
| | | const { code } = id.value |
| | | ? await editRepair({ id: unref(id), ...form }) |
| | | : await addRepair(form); |
| | | ? await editRepair({ id: unref(id), ...submitData }) |
| | | : await addRepair(submitData); |
| | | if (code == 200) { |
| | | ElMessage.success(`${id.value ? "编辑" : "新增"}报修成功`); |
| | | visible.value = false; |
| | |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | repairFileList.value = []; |
| | | uploadFileList.value = []; |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | repairFileList.value = []; |
| | | uploadFileList.value = []; |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const openAdd = async () => { |
| | | id.value = undefined; |
| | | repairFileList.value = []; |
| | | uploadFileList.value = []; |
| | | visible.value = true; |
| | | await nextTick(); |
| | | await loadDeviceName(); |
| | |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | | <style lang="scss" scoped> |
| | | .repair-upload-area { |
| | | :deep(.el-upload-list--picture-card) { |
| | | --el-upload-list-picture-card-size: 100px; |
| | | } |
| | | } |
| | | .upload-tip { |
| | | font-size: 12px; |
| | | color: var(--el-text-color-secondary); |
| | | margin-top: 8px; |
| | | } |
| | | </style> |