gongchunyi
8 天以前 d846993ab3a04772fe3c80b0c877fa59f881f7f9
src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -2,12 +2,12 @@
  <FormDialog
    v-model="visible"
    :title="id ? '编辑设备保养计划' : '新增设备保养计划'"
    width="640px"
    width="680px"
    @confirm="sendForm"
    @cancel="handleCancel"
    @close="handleClose"
  >
    <el-form :model="form" :rules="rules" label-width="100px">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
      <el-form-item label="设备名称">
        <el-select
          v-model="form.deviceLedgerId"
@@ -56,9 +56,17 @@
          />
        </el-select>
      </el-form-item>
      <el-form-item label="保养项目">
      <el-form-item label="保养部位" prop="maintenanceLocation">
        <el-input
          v-model="form.maintenanceLocation"
          type="textarea"
          :rows="3"
          placeholder="请输入保养部位"
        />
      </el-form-item>
      <el-form-item label="保养项目" prop="maintenanceItems">
        <el-input
          v-model="form.maintenanceItems"
          type="textarea"
          :rows="3"
          placeholder="请输入保养项目"
@@ -107,8 +115,6 @@
} from "@/api/equipmentManagement/upkeep";
import {
  listMaintenanceTaskFiles,
  bindMaintenanceTaskFile,
  uploadMaintenanceTaskFile,
  delMaintenanceTaskFile,
} from "@/api/equipmentManagement/maintenanceTaskFile";
import { ElMessage } from "element-plus";
@@ -132,13 +138,19 @@
const pendingTempFiles = ref([]);
const planFileList = ref([]);
// 编辑模式下已保存但待删除的文件列表
const pendingDeleteFiles = ref([]);
const registrantDisplayName = computed(
  () => userStore.nickName || userStore.name || "当前登录用户"
);
const formRef = ref();
const rules = {
  maintenancePerson: [{ required: true, message: "请选择保养人", trigger: "change" }],
  maintenanceLocation: [{ required: true, message: "请输入保养部位", trigger: "blur" }],
  maintenanceItems: [{ required: true, message: "请输入保养项目", trigger: "blur" }],
};
const syncCreateUserFromLogin = () => {
@@ -169,6 +181,7 @@
  deviceName: undefined,
  deviceModel: undefined,
  maintenanceLocation: undefined,
  maintenanceItems: undefined,
  maintenancePlanTime: undefined,
  maintenancePerson: undefined,
  createUser: undefined,
@@ -185,6 +198,7 @@
const resetAttachmentState = () => {
  pendingTempFiles.value = [];
  planFileList.value = [];
  pendingDeleteFiles.value = [];
};
const normalizeFilePreviewUrl = (url = "") => {
@@ -208,6 +222,8 @@
    status: "success",
    uid: `saved-${item.id}`,
    fileId: item.id,
    // 标记为已保存的文件,不是新上传的
    isNew: false,
  }));
};
@@ -226,38 +242,33 @@
const handlePlanFileUpload = async (options) => {
  const { file, onSuccess, onError } = options;
  try {
    if (id.value) {
      const fd = new FormData();
      fd.append("file", file);
      fd.append("deviceMaintenanceId", String(id.value));
      const res = await uploadMaintenanceTaskFile(fd);
      if (res.code === 200) {
        await loadPlanFiles(id.value);
        onSuccess(res);
        ElMessage.success("附件上传成功");
      } else {
        onError(new Error(res.msg || "上传失败"));
      }
      return;
    }
    // 无论新增还是编辑,都先上传到临时目录
    const res = await uploadTempFile(file);
    if (res.code !== 200) {
      onError(new Error(res.msg || "上传失败"));
      return;
    }
    const data = res.data || {};
    const tempId = data.tempId;
    // 记录临时文件信息
    pendingTempFiles.value.push({
      tempId: data.tempId,
      tempId: tempId,
      name: data.originalName || file.name,
      fileId: id.value ? tempId : undefined,
    });
    onSuccess(res);
    planFileList.value.push({
      name: data.originalName || file.name,
      url: "",
      status: "success",
      uid: data.tempId,
      tempId: data.tempId,
      uid: tempId,
      tempId: tempId,
      // 标记为新上传的临时文件
      isNew: true,
    });
    ElMessage.success("附件上传成功");
  } catch (e) {
    onError(e);
    ElMessage.error("附件上传失败");
@@ -265,28 +276,29 @@
};
const handlePlanFileRemove = async (file) => {
  if (file.fileId) {
    try {
      await delMaintenanceTaskFile(file.fileId);
      await loadPlanFiles(id.value);
    } catch (e) {
      ElMessage.error("删除附件失败");
    }
  // 从显示列表中移除
  planFileList.value = planFileList.value.filter((f) => f.uid !== file.uid);
  const tempId = file.tempId || file.uid;
  if (file.isNew) {
    // 新上传的临时文件,直接从待上传列表移除
    pendingTempFiles.value = pendingTempFiles.value.filter((f) => f.tempId !== tempId);
    return;
  }
  const tempId = file.tempId || file.uid;
  pendingTempFiles.value = pendingTempFiles.value.filter((f) => f.tempId !== tempId);
  planFileList.value = planFileList.value.filter((f) => (f.tempId || f.uid) !== tempId);
  if (file.fileId) {
    pendingDeleteFiles.value.push({
      fileId: file.fileId,
      name: file.name,
    });
  }
};
const bindPendingFiles = async (planId) => {
  if (!pendingTempFiles.value.length) return;
  for (const item of pendingTempFiles.value) {
    await bindMaintenanceTaskFile({
      tempId: item.tempId,
      name: item.name,
      deviceMaintenanceId: planId,
    });
// 处理编辑模式下待删除的文件
const processPendingDeletes = async () => {
  if (!pendingDeleteFiles.value.length) return;
  for (const file of pendingDeleteFiles.value) {
    await delMaintenanceTaskFile(file.fileId);
  }
};
@@ -295,6 +307,7 @@
  form.deviceName = data.deviceName;
  form.deviceModel = data.deviceModel;
  form.maintenanceLocation = data.maintenanceLocation;
  form.maintenanceItems = data.maintenanceItems;
  form.status = data.status;
  syncCreateUserFromLogin();
  if (data.maintenancePersonId) {
@@ -324,6 +337,10 @@
      payload.maintenancePerson = maintainer.nickName;
    }
  }
  // 传递临时文件ID列表,由后端统一处理
  if (pendingTempFiles.value.length > 0) {
    payload.tempFileIds = pendingTempFiles.value.map((f) => f.tempId);
  }
  return payload;
};
@@ -347,10 +364,14 @@
const sendForm = async () => {
  syncCreateUserFromLogin();
  const valid = await formRef.value?.validate().catch(() => false);
  if (!valid) return;
  loading.value = true;
  try {
    const payload = buildSubmitPayload();
    if (id.value) {
      // 编辑模式:先处理待删除的文件,再保存表单
      await processPendingDeletes();
      const { code } = await editUpkeep({ id: unref(id), ...payload });
      if (code == 200) {
        ElMessage.success("编辑计划成功");
@@ -358,12 +379,9 @@
        emits("ok");
      }
    } else {
      // 新增模式:tempFileIds 会随 payload 一起传到后端,由后端处理临时文件的关联
      const res = await addUpkeep(payload);
      if (res.code == 200) {
        const planId = res.data?.id;
        if (planId) {
          await bindPendingFiles(planId);
        }
        ElMessage.success("新增计划成功");
        visible.value = false;
        emits("ok");