gaoluyang
2026-04-13 9d1ba481cb3c061c7fe46a52776e6171d5595bdd
src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -8,27 +8,45 @@
    @close="handleClose"
  >
    <el-form :model="form" label-width="100px">
      <el-form-item label="所属区域">
        <el-tree-select
          v-model="form.areaId"
          :data="areaOptions"
          :props="areaTreeProps"
          node-key="id"
          value-key="id"
          check-strictly
          clearable
          filterable
          placeholder="请选择所属区域"
          style="width: 100%"
          @change="handleAreaChange"
        />
      </el-form-item>
      <el-form-item label="设备名称">
        <el-select
          v-model="form.deviceLedgerId"
          @change="setDeviceModel"
          placeholder="请选择设备"
          v-model="form.deviceLedgerIds"
          filterable
          default-first-option
          :reserve-keyword="false"
          clearable
          multiple
          collapse-tags
          collapse-tags-tooltip
          placeholder="请选择设备"
          style="width: 100%"
          @change="setDeviceModels"
        >
          <el-option
            v-for="(item, index) in deviceOptions"
            :key="index"
            v-for="item in deviceOptions"
            :key="item.id"
            :label="item.deviceName"
            :value="item.id"
          ></el-option>
          />
        </el-select>
      </el-form-item>
      <el-form-item label="规格型号">
        <el-input
          v-model="form.deviceModel"
          placeholder="请输入规格型号"
          placeholder="自动带出规格型号"
          disabled
        />
      </el-form-item>
@@ -51,19 +69,19 @@
      </el-form-item>
      <el-form-item v-if="id" 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-option label="待保修" :value="0" />
          <el-option label="完结" :value="1" />
          <el-option label="失败" :value="2" />
        </el-select>
      </el-form-item>
      <el-form-item label="计划保养日期">
        <el-date-picker
          style="width: 100%"
          v-model="form.maintenancePlanTime"
          style="width: 100%"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="date"
          placeholder="请选择计划保养日期日期"
          placeholder="请选择计划保养日期"
          clearable
        />
      </el-form-item>
@@ -72,18 +90,21 @@
</template>
<script setup>
import { nextTick, onMounted, ref, unref } from "vue";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import useFormData from "@/hooks/useFormData";
import { userListNoPage } from "@/api/system/user.js";
import {
  addUpkeep,
  editUpkeep,
  getUpkeepById,
} from "@/api/equipmentManagement/upkeep";
import { ElMessage } from "element-plus";
import useFormData from "@/hooks/useFormData";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { onMounted } from "vue";
import dayjs from "dayjs";
import { userListNoPage } from "@/api/system/user.js";
import {
  getDeviceAreaTree,
  getDeviceAreaTreeWithDevices,
} from "@/api/equipmentManagement/deviceArea";
defineOptions({
  name: "设备保养新增计划",
@@ -94,47 +115,159 @@
const id = ref();
const visible = ref(false);
const loading = ref(false);
const areaOptions = ref([]);
const deviceOptions = ref([]);
const loadDeviceName = async () => {
  const { data } = await getDeviceLedger();
  deviceOptions.value = data;
const userList = ref([]);
const areaTreeProps = {
  label: "areaName",
  children: "children",
};
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // 设备Id
  deviceName: undefined, // 设备名称
  deviceModel: undefined, // 规格型号
  maintenancePlanTime: undefined, // 计划保养日期
  createUser: undefined, // 录入人
  status: 0, //保修状态
  areaId: undefined,
  deviceLedgerId: undefined,
  deviceLedgerIds: [],
  deviceLedgerIdsStr: undefined,
  deviceName: undefined,
  deviceModel: undefined,
  maintenancePlanTime: undefined,
  createUser: undefined,
  status: 0,
});
const setDeviceModel = (deviceId) => {
  const option = deviceOptions.value.find((item) => item.id === deviceId);
  form.deviceModel = option.deviceModel;
const loadAreaTree = async () => {
  const { data } = await getDeviceAreaTree();
  areaOptions.value = Array.isArray(data) ? data : [];
};
/**
 * @desc 设置表单内容
 * @param data 设备信息
 */
const normalizeIdList = (value) => {
  if (Array.isArray(value)) {
    return value
      .map((item) => Number(item))
      .filter((item) => Number.isFinite(item));
  }
  if (typeof value === "string") {
    return value
      .split(",")
      .map((item) => Number(item.trim()))
      .filter((item) => Number.isFinite(item));
  }
  if (value !== undefined && value !== null && value !== "") {
    const numericValue = Number(value);
    return Number.isFinite(numericValue) ? [numericValue] : [];
  }
  return [];
};
const getNodeDevices = (node) => {
  const candidates = [
    node?.deviceList,
    node?.devices,
    node?.deviceLedgerList,
    node?.deviceLedgers,
    node?.ledgerList,
    node?.ledgers,
  ];
  return candidates.find((item) => Array.isArray(item)) || [];
};
const normalizeDevice = (item) => ({
  ...item,
  id: item.id ?? item.deviceLedgerId,
  deviceName: item.deviceName ?? item.name,
  deviceModel: item.deviceModel ?? item.model,
});
const collectDevices = (node) => {
  const currentDevices = getNodeDevices(node).map(normalizeDevice);
  const childDevices = (node?.children || []).flatMap((child) =>
    collectDevices(child)
  );
  const deviceMap = new Map();
  [...currentDevices, ...childDevices].forEach((item) => {
    if (item?.id !== undefined && item?.id !== null) {
      deviceMap.set(Number(item.id), item);
    }
  });
  return Array.from(deviceMap.values());
};
const findAreaNode = (nodes, areaId) => {
  for (const node of nodes || []) {
    if (Number(node.id) === Number(areaId)) {
      return node;
    }
    const target = findAreaNode(node.children, areaId);
    if (target) {
      return target;
    }
  }
  return null;
};
const loadDevicesByArea = async (areaId) => {
  if (!areaId) {
    deviceOptions.value = [];
    return;
  }
  const { data } = await getDeviceAreaTreeWithDevices();
  const treeData = Array.isArray(data) ? data : [];
  const currentNode = findAreaNode(treeData, areaId);
  deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
};
const syncDeviceFields = (deviceIds) => {
  const selectedIds = normalizeIdList(deviceIds);
  const selectedDevices = selectedIds
    .map((deviceId) =>
      deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
    )
    .filter(Boolean);
  form.deviceLedgerIds = selectedIds;
  form.deviceLedgerId = selectedIds[0];
  form.deviceLedgerIdsStr = selectedIds.join(",");
  form.deviceName = selectedDevices
    .map((item) => item.deviceName)
    .filter(Boolean)
    .join(",");
  form.deviceModel = selectedDevices
    .map((item) => item.deviceModel || "-")
    .join(",");
};
const setDeviceModels = (deviceIds) => {
  syncDeviceFields(deviceIds);
};
const handleAreaChange = async (areaId) => {
  form.deviceLedgerId = undefined;
  form.deviceLedgerIds = [];
  form.deviceLedgerIdsStr = undefined;
  form.deviceName = undefined;
  form.deviceModel = undefined;
  await loadDevicesByArea(areaId);
};
const setForm = (data) => {
  form.deviceLedgerId = data.deviceLedgerId;
  form.areaId = data.areaId;
  form.deviceLedgerIds = normalizeIdList(
    data.deviceLedgerIds ?? data.deviceLedgerIdsStr ?? data.deviceLedgerId
  );
  form.deviceLedgerId = form.deviceLedgerIds[0];
  form.deviceLedgerIdsStr =
    data.deviceLedgerIdsStr ?? form.deviceLedgerIds.join(",");
  form.deviceName = data.deviceName;
  form.deviceModel = data.deviceModel;
  form.createUser = Number(data.createUser);
  form.status = data.status;
  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
    "YYYY-MM-DD HH:mm:ss"
  );
  form.maintenancePlanTime = data.maintenancePlanTime
    ? dayjs(data.maintenancePlanTime).format("YYYY-MM-DD HH:mm:ss")
    : undefined;
};
// 用户列表
const userList = ref([]);
onMounted(() => {
  loadDeviceName();
  loadAreaTree();
  userListNoPage().then((res) => {
    userList.value = res.data;
  });
@@ -145,16 +278,27 @@
  id.value = editId;
  visible.value = true;
  await nextTick();
  await loadAreaTree();
  setForm(data);
  await loadDevicesByArea(form.areaId);
  syncDeviceFields(form.deviceLedgerIds);
};
const sendForm = async () => {
  loading.value = true;
  try {
    syncDeviceFields(form.deviceLedgerIds);
    const payload = {
      ...form,
      deviceLedgerId: form.deviceLedgerIds[0],
      deviceLedgerIds: [...form.deviceLedgerIds],
      deviceLedgerIdsStr: form.deviceLedgerIds.join(","),
      deviceModel: form.deviceModel || "-",
    };
    const { code } = id.value
      ? await editUpkeep({ id: unref(id), ...form })
      : await addUpkeep(form);
    if (code == 200) {
      ? await editUpkeep({ id: unref(id), ...payload })
      : await addUpkeep(payload);
    if (code === 200) {
      ElMessage.success(`${id.value ? "编辑" : "新增"}计划成功`);
      visible.value = false;
      emits("ok");
@@ -174,9 +318,12 @@
  visible.value = false;
};
const openModal = () => {
const openModal = async () => {
  id.value = undefined;
  visible.value = true;
  await nextTick();
  await loadAreaTree();
  deviceOptions.value = [];
};
defineExpose({