gongchunyi
8 天以前 b95a00bf7ec7c667e16032bcabc4d97ef42909fc
src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -2,12 +2,12 @@
  <FormDialog
    v-model="visible"
    :title="id ? '编辑设备保养计划' : '新增设备保养计划'"
    width="500px"
    width="640px"
    @confirm="sendForm"
    @cancel="handleCancel"
    @close="handleClose"
  >
    <el-form :model="form" label-width="100px">
    <el-form :model="form" :rules="rules" label-width="100px">
      <el-form-item label="设备名称">
        <el-select
          v-model="form.deviceLedgerId"
@@ -33,21 +33,36 @@
        />
      </el-form-item>
      <el-form-item label="录入人">
        <el-input
          :model-value="registrantDisplayName"
          disabled
          placeholder="当前登录用户"
        />
      </el-form-item>
      <el-form-item label="保养人" prop="maintenancePerson">
        <el-select
          v-model="form.createUser"
          placeholder="请选择"
          v-model="form.maintenancePerson"
          filterable
          default-first-option
          :reserve-keyword="false"
          clearable
          placeholder="请选择保养人"
          style="width: 100%"
        >
          <el-option
            v-for="item in userList"
            :key="item.userId"
            :key="'mp-' + item.userId"
            :label="item.nickName"
            :value="item.userId"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="保养项目">
        <el-input
          v-model="form.maintenanceLocation"
          type="textarea"
          :rows="3"
          placeholder="请输入保养项目"
        />
      </el-form-item>
      <el-form-item v-if="id" label="保修状态">
        <el-select v-model="form.status">
@@ -67,6 +82,18 @@
          clearable
        />
      </el-form-item>
      <el-form-item label="附件">
        <el-upload
          :http-request="handlePlanFileUpload"
          :file-list="planFileList"
          :on-remove="handlePlanFileRemove"
          multiple
          list-type="picture-card"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <span v-if="!id" class="upload-tip">可先选择附件,保存计划后自动关联到本计划</span>
      </el-form-item>
    </el-form>
  </FormDialog>
</template>
@@ -78,12 +105,21 @@
  editUpkeep,
  getUpkeepById,
} from "@/api/equipmentManagement/upkeep";
import {
  listMaintenanceTaskFiles,
  bindMaintenanceTaskFile,
  uploadMaintenanceTaskFile,
  delMaintenanceTaskFile,
} from "@/api/equipmentManagement/maintenanceTaskFile";
import { ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import useFormData from "@/hooks/useFormData";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { onMounted } from "vue";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { computed, nextTick, onMounted, ref, unref } from "vue";
import dayjs from "dayjs";
import { userListNoPage } from "@/api/system/user.js";
import useUserStore from "@/store/modules/user.js";
import request from "@/utils/request";
defineOptions({
  name: "设备保养新增计划",
@@ -91,73 +127,247 @@
const emits = defineEmits(["ok"]);
const userStore = useUserStore();
const javaApi = import.meta.env.VITE_APP_BASE_API;
const pendingTempFiles = ref([]);
const planFileList = ref([]);
const registrantDisplayName = computed(
  () => userStore.nickName || userStore.name || "当前登录用户"
);
const rules = {
  maintenancePerson: [{ required: true, message: "请选择保养人", trigger: "change" }],
};
const syncCreateUserFromLogin = () => {
  if (userStore.id != null && userStore.id !== "") {
    form.createUser = userStore.id;
  }
};
const id = ref();
const visible = ref(false);
const loading = ref(false);
const deviceOptions = ref([]);
const userList = ref([]);
const loadDeviceName = async () => {
  const { data } = await getDeviceLedger();
  deviceOptions.value = data;
};
const loadUserList = async () => {
  const res = await userListNoPageByTenantId();
  userList.value = res.data || [];
};
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // 设备Id
  deviceName: undefined, // 设备名称
  deviceModel: undefined, // 规格型号
  maintenancePlanTime: undefined, // 计划保养日期
  createUser: undefined, // 录入人
  status: 0, //保修状态
  deviceLedgerId: undefined,
  deviceName: undefined,
  deviceModel: undefined,
  maintenanceLocation: undefined,
  maintenancePlanTime: undefined,
  maintenancePerson: undefined,
  createUser: undefined,
  status: 0,
});
const setDeviceModel = (deviceId) => {
  const option = deviceOptions.value.find((item) => item.id === deviceId);
  form.deviceModel = option.deviceModel;
  if (option) {
    form.deviceModel = option.deviceModel;
  }
};
/**
 * @desc 设置表单内容
 * @param data 设备信息
 */
const resetAttachmentState = () => {
  pendingTempFiles.value = [];
  planFileList.value = [];
};
const normalizeFilePreviewUrl = (url = "") => {
  if (!url) return "";
  if (url.startsWith("http")) return url;
  if (url.startsWith("/profile")) return javaApi + url;
  return url;
};
const loadPlanFiles = async (planId) => {
  if (!planId) return;
  const res = await listMaintenanceTaskFiles({
    current: 1,
    size: 100,
    deviceMaintenanceId: planId,
  });
  const records = res?.data?.records || [];
  planFileList.value = records.map((item) => ({
    name: item.name,
    url: normalizeFilePreviewUrl(item.url),
    status: "success",
    uid: `saved-${item.id}`,
    fileId: item.id,
  }));
};
const uploadTempFile = (file) => {
  const fd = new FormData();
  fd.append("file", file);
  fd.append("type", "16");
  return request({
    url: "/file/upload",
    method: "post",
    data: fd,
    headers: { "Content-Type": "multipart/form-data" },
  });
};
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 || {};
    pendingTempFiles.value.push({
      tempId: data.tempId,
      name: data.originalName || file.name,
    });
    onSuccess(res);
    planFileList.value.push({
      name: data.originalName || file.name,
      url: "",
      status: "success",
      uid: data.tempId,
      tempId: data.tempId,
    });
  } catch (e) {
    onError(e);
    ElMessage.error("附件上传失败");
  }
};
const handlePlanFileRemove = async (file) => {
  if (file.fileId) {
    try {
      await delMaintenanceTaskFile(file.fileId);
      await loadPlanFiles(id.value);
    } catch (e) {
      ElMessage.error("删除附件失败");
    }
    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);
};
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 setForm = (data) => {
  form.deviceLedgerId = data.deviceLedgerId;
  form.deviceName = data.deviceName;
  form.deviceModel = data.deviceModel;
  form.createUser = Number(data.createUser);
  form.maintenanceLocation = data.maintenanceLocation;
  form.status = data.status;
  syncCreateUserFromLogin();
  if (data.maintenancePersonId) {
    form.maintenancePerson = data.maintenancePersonId;
  } else if (data.maintenancePerson) {
    const matched = userList.value.find(
      (u) => u.nickName === data.maintenancePerson
    );
    if (matched) {
      form.maintenancePerson = matched.userId;
    }
  }
  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
    "YYYY-MM-DD HH:mm:ss"
  );
};
// 用户列表
const userList = ref([]);
const buildSubmitPayload = () => {
  const payload = { ...form };
  const maintenancePersonUserId = form.maintenancePerson;
  if (maintenancePersonUserId) {
    const maintainer = userList.value.find(
      (u) => String(u.userId) === String(maintenancePersonUserId)
    );
    if (maintainer) {
      payload.maintenancePersonId = maintainer.userId;
      payload.maintenancePerson = maintainer.nickName;
    }
  }
  return payload;
};
onMounted(() => {
  loadDeviceName();
  userListNoPage().then((res) => {
    userList.value = res.data;
  });
  loadUserList();
});
const openEdit = async (editId) => {
  resetAttachmentState();
  if (!userList.value.length) {
    await loadUserList();
  }
  const { data } = await getUpkeepById(editId);
  id.value = editId;
  visible.value = true;
  await nextTick();
  setForm(data);
  await loadPlanFiles(editId);
};
const sendForm = async () => {
  syncCreateUserFromLogin();
  loading.value = true;
  try {
    const { code } = id.value
      ? await editUpkeep({ id: unref(id), ...form })
      : await addUpkeep(form);
    if (code == 200) {
      ElMessage.success(`${id.value ? "编辑" : "新增"}计划成功`);
      visible.value = false;
      emits("ok");
    const payload = buildSubmitPayload();
    if (id.value) {
      const { code } = await editUpkeep({ id: unref(id), ...payload });
      if (code == 200) {
        ElMessage.success("编辑计划成功");
        visible.value = false;
        emits("ok");
      }
    } else {
      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");
      }
    }
  } finally {
    loading.value = false;
@@ -166,16 +376,24 @@
const handleCancel = () => {
  resetForm();
  resetAttachmentState();
  visible.value = false;
};
const handleClose = () => {
  resetForm();
  resetAttachmentState();
  visible.value = false;
};
const openModal = () => {
  id.value = undefined;
  resetForm();
  resetAttachmentState();
  syncCreateUserFromLogin();
  if (userStore.id != null && userStore.id !== "") {
    form.maintenancePerson = userStore.id;
  }
  visible.value = true;
};
@@ -185,4 +403,12 @@
});
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.upload-tip {
  display: block;
  font-size: 12px;
  color: #999;
  margin-top: 8px;
  line-height: 1.4;
}
</style>