<template>
|
<FormDialog
|
v-model="visible"
|
:title="id ? '编辑设备报修' : '新增设备报修'"
|
width="800px"
|
@confirm="sendForm"
|
@cancel="handleCancel"
|
@close="handleClose"
|
>
|
<el-form :model="form" label-width="100px">
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="设备名称">
|
<el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
|
<el-option
|
v-for="(item, index) in deviceOptions"
|
:key="index"
|
:label="item.deviceName"
|
:value="item.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="规格型号">
|
<el-input
|
v-model="form.deviceModel"
|
placeholder="请输入规格型号"
|
disabled
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="报修日期">
|
<el-date-picker
|
v-model="form.repairTime"
|
placeholder="请选择报修日期"
|
format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
type="date"
|
clearable
|
style="width: 100%"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="报修人">
|
<el-input v-model="form.repairName" placeholder="请输入报修人" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row v-if="id">
|
<el-col :span="12">
|
<el-form-item label="报修状态">
|
<el-select v-model="form.status">
|
<el-option label="待维修" :value="0"></el-option>
|
<el-option label="完结" :value="1"></el-option>
|
<el-option label="失败" :value="2"></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-col :span="24">
|
<el-form-item label="故障现象">
|
<el-input
|
v-model="form.remark"
|
:rows="2"
|
type="textarea"
|
placeholder="请输入故障现象"
|
/>
|
</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>
|
|
<script setup>
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import {
|
addRepair,
|
editRepair,
|
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 emits = defineEmits(["ok"]);
|
|
const id = ref();
|
const visible = ref(false);
|
const loading = ref(false);
|
|
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,
|
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.deviceLedgerId = data.deviceLedgerId;
|
form.deviceName = data.deviceName;
|
form.deviceModel = data.deviceModel;
|
form.repairTime = data.repairTime;
|
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), ...submitData })
|
: await addRepair(submitData);
|
if (code == 200) {
|
ElMessage.success(`${id.value ? "编辑" : "新增"}报修成功`);
|
visible.value = false;
|
emits("ok");
|
}
|
} finally {
|
loading.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();
|
};
|
|
const openEdit = async (editId) => {
|
const { data } = await getRepairById(editId);
|
id.value = editId;
|
visible.value = true;
|
await nextTick();
|
await loadDeviceName();
|
setForm(data);
|
};
|
|
defineExpose({
|
openAdd,
|
openEdit,
|
});
|
</script>
|
|
<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>
|