From 94ee31388ed0012d2c65437bd164e6878f4c635d Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 10 四月 2026 13:31:48 +0800
Subject: [PATCH] 新疆大罗素 1.设备保养、设备维修、设备巡检新增时可以多选设备 2.设备台账添加区域维护字段 3.添加环境页面实时展示设备数据

---
 src/views/equipmentManagement/inspectionManagement/components/formDia.vue |  595 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 379 insertions(+), 216 deletions(-)

diff --git a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue b/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
index 9f509b1..6432617 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
@@ -1,26 +1,73 @@
 <template>
   <div>
-    <el-dialog :title="operationType === 'add' ? '鏂板宸℃浠诲姟' : '缂栬緫宸℃浠诲姟'"
-               v-model="dialogVisitable" width="800px" @close="cancel">
+    <el-dialog
+      v-model="dialogVisitable"
+      :title="operationType === 'add' ? '鏂板宸℃浠诲姟' : '缂栬緫宸℃浠诲姟'"
+      width="800px"
+      @close="cancel"
+    >
       <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
         <el-row>
           <el-col :span="12">
-            <el-form-item label="璁惧鍚嶇О" prop="taskId">
-              <el-select v-model="form.taskId" @change="setDeviceModel">
+            <el-form-item label="鎵�灞炲尯鍩�" prop="areaId">
+              <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-col>
+          <el-col :span="12">
+            <el-form-item label="璁惧鍚嶇О" prop="deviceLedgerIds">
+              <el-select
+                v-model="form.deviceLedgerIds"
+                multiple
+                collapse-tags
+                collapse-tags-tooltip
+                clearable
+                filterable
+                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-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="宸℃浜�" prop="inspector">
+              <el-select v-model="form.inspector" placeholder="璇烽�夋嫨" multiple clearable>
+                <el-option
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId"
+                />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="宸℃浜�" prop="inspector">
-              <el-select v-model="form.inspector" placeholder="璇烽�夋嫨" multiple clearable>
-                <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/>
-              </el-select>
+            <el-form-item label="瑙勬牸鍨嬪彿">
+              <el-input
+                v-model="form.deviceModel"
+                placeholder="鑷姩甯﹀嚭瑙勬牸鍨嬪彿"
+                disabled
+              />
             </el-form-item>
           </el-col>
         </el-row>
@@ -35,55 +82,51 @@
           <el-col :span="12">
             <el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
               <el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
-                <el-option label="姣忔棩" value="DAILY"/>
-                <el-option label="姣忓懆" value="WEEKLY"/>
-                <el-option label="姣忔湀" value="MONTHLY"/>
-                <!-- <el-option label="瀛e害" value="QUARTERLY"/> -->
+                <el-option label="姣忔棩" value="DAILY" />
+                <el-option label="姣忓懆" value="WEEKLY" />
+                <el-option label="姣忔湀" value="MONTHLY" />
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+          <el-col :span="12" v-if="form.frequencyType === 'DAILY'">
             <el-form-item label="鏃ユ湡" prop="frequencyDetail">
-              <el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-                              value-format="HH:mm" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
-            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
-              <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
-                <el-option label="鍛ㄤ竴" value="MON"/>
-                <el-option label="鍛ㄤ簩" value="TUE"/>
-                <el-option label="鍛ㄤ笁" value="WED"/>
-                <el-option label="鍛ㄥ洓" value="THU"/>
-                <el-option label="鍛ㄤ簲" value="FRI"/>
-                <el-option label="鍛ㄥ叚" value="SAT"/>
-                <el-option label="鍛ㄦ棩" value="SUN"/>
-              </el-select>
-              <el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-                              value-format="HH:mm"  style="width: 50%"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
-            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
-              <el-date-picker
-                  v-model="form.frequencyDetail"
-                  type="datetime"
-                  clearable
-                  placeholder="閫夋嫨寮�濮嬫棩鏈�"
-                  format="DD,HH:mm"
-                  value-format="DD,HH:mm"
+              <el-time-picker
+                v-model="form.frequencyDetail"
+                placeholder="閫夋嫨鏃堕棿"
+                format="HH:mm"
+                value-format="HH:mm"
               />
             </el-form-item>
           </el-col>
-          <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+          <el-col :span="12" v-if="form.frequencyType === 'WEEKLY'">
+            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+              <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+                <el-option label="鍛ㄤ竴" value="MON" />
+                <el-option label="鍛ㄤ簩" value="TUE" />
+                <el-option label="鍛ㄤ笁" value="WED" />
+                <el-option label="鍛ㄥ洓" value="THU" />
+                <el-option label="鍛ㄤ簲" value="FRI" />
+                <el-option label="鍛ㄥ叚" value="SAT" />
+                <el-option label="鍛ㄦ棩" value="SUN" />
+              </el-select>
+              <el-time-picker
+                v-model="form.time"
+                placeholder="閫夋嫨鏃堕棿"
+                format="HH:mm"
+                value-format="HH:mm"
+                style="width: 50%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.frequencyType === 'MONTHLY'">
             <el-form-item label="鏃ユ湡" prop="frequencyDetail">
               <el-date-picker
-                  v-model="form.frequencyDetail"
-                  type="datetime"
-                  clearable
-                  placeholder="閫夋嫨寮�濮嬫棩鏈�"
-                  format="MM,DD,HH:mm"
-                  value-format="MM,DD,HH:mm"
+                v-model="form.frequencyDetail"
+                type="datetime"
+                clearable
+                placeholder="閫夋嫨寮�濮嬫棩鏈�"
+                format="DD,HH:mm"
+                value-format="DD,HH:mm"
               />
             </el-form-item>
           </el-col>
@@ -100,188 +143,308 @@
 </template>
 
 <script setup>
-import {reactive, ref, getCurrentInstance, toRefs} from "vue";
-import useUserStore from '@/store/modules/user'
-import {addOrEditTimingTask} from "@/api/inspectionManagement/index.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { getCurrentInstance, reactive, ref, toRefs } from "vue";
+import useUserStore from "@/store/modules/user";
+import { addOrEditTimingTask } from "@/api/inspectionManagement/index.js";
+import { userListNoPageByTenantId } from "@/api/system/user.js";
+import {
+  getDeviceAreaTree,
+  getDeviceAreaTreeWithDevices,
+} from "@/api/equipmentManagement/deviceArea";
 
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const emit = defineEmits(["closeDia"]);
+const userStore = useUserStore();
 const dialogVisitable = ref(false);
-const operationType = ref('add');
+const operationType = ref("add");
+const areaOptions = ref([]);
 const deviceOptions = ref([]);
-const data = reactive({
-  form: {
-    taskId: undefined,
-    taskName: undefined,
-    inspector: '',
-    inspectorIds: '',
-    remarks: '',
-    frequencyType: '',
-    frequencyDetail: '',
-    week: '',
-    time: ''
-  },
-	rules: {
-		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
-		inspector: [{ required: true, message: "璇疯緭鍏ュ贰妫�浜�", trigger: "blur" },],
-		dateStr: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }],
-		frequencyType: [{ required: true, message: "璇烽�夋嫨浠诲姟棰戠巼", trigger: "change" }],
-		frequencyDetail: [
-			{
-				required: true,
-				message: "璇烽�夋嫨鏃ユ湡",
-				trigger: "change",
-				validator: (rule, value, callback) => {
-					if (!form.value.frequencyType) {
-						callback()
-						return
-					}
-					if (form.value.frequencyType === 'WEEKLY') {
-						if (!form.value.week || !form.value.time) {
-							callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"))
-						} else {
-							callback()
-						}
-					} else {
-						if (!value) {
-							callback(new Error("璇烽�夋嫨鏃ユ湡"))
-						} else {
-							callback()
-						}
-					}
-				}
-			}
-		],
-		week: [
-			{
-				required: true,
-				message: "璇烽�夋嫨鏄熸湡",
-				trigger: "change",
-				validator: (rule, value, callback) => {
-					if (form.value.frequencyType === 'WEEKLY' && !value) {
-						callback(new Error("璇烽�夋嫨鏄熸湡"))
-					} else {
-						callback()
-					}
-				}
-			}
-		],
-		time: [
-			{
-				required: true,
-				message: "璇烽�夋嫨鏃堕棿",
-				trigger: "change",
-				validator: (rule, value, callback) => {
-					if (form.value.frequencyType === 'WEEKLY' && !value) {
-						callback(new Error("璇烽�夋嫨鏃堕棿"))
-					} else {
-						callback()
-					}
-				}
-			}
-		]
-	}
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
+const userList = ref([]);
+const areaTreeProps = {
+  label: "areaName",
+  children: "children",
 };
 
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  if (option) {
-    form.value.taskName = option.deviceName;
-  }
-}
+const data = reactive({
+  form: {
+    areaId: undefined,
+    taskId: undefined,
+    taskIds: [],
+    taskIdsStr: undefined,
+    deviceLedgerIds: [],
+    deviceLedgerIdsStr: undefined,
+    taskName: undefined,
+    deviceModel: undefined,
+    inspector: [],
+    inspectorIds: "",
+    remarks: "",
+    frequencyType: "",
+    frequencyDetail: "",
+    week: "",
+    time: "",
+  },
+  rules: {
+    areaId: [{ required: true, message: "璇烽�夋嫨鎵�灞炲尯鍩�", trigger: "change" }],
+    deviceLedgerIds: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" }],
+    inspector: [{ required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }],
+    frequencyType: [{ required: true, message: "璇烽�夋嫨浠诲姟棰戠巼", trigger: "change" }],
+    frequencyDetail: [
+      {
+        required: true,
+        trigger: "change",
+        validator: (rule, value, callback) => {
+          if (!form.value.frequencyType) {
+            callback();
+            return;
+          }
+          if (form.value.frequencyType === "WEEKLY") {
+            if (!form.value.week || !form.value.time) {
+              callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"));
+            } else {
+              callback();
+            }
+            return;
+          }
+          if (!value) {
+            callback(new Error("璇烽�夋嫨鏃ユ湡"));
+            return;
+          }
+          callback();
+        },
+      },
+    ],
+  },
+});
 
-// 鎵撳紑寮规
+const { form, rules } = toRefs(data);
+
+const loadAreaTree = async () => {
+  const { data } = await getDeviceAreaTree();
+  areaOptions.value = Array.isArray(data) ? 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.value.deviceLedgerIds = selectedIds;
+  form.value.deviceLedgerIdsStr = selectedIds.join(",");
+  form.value.taskIds = [...selectedIds];
+  form.value.taskIdsStr = selectedIds.join(",");
+  form.value.taskId = selectedIds[0];
+  form.value.taskName = selectedDevices
+    .map((item) => item.deviceName)
+    .filter(Boolean)
+    .join(",");
+  form.value.deviceModel = selectedDevices
+    .map((item) => item.deviceModel || "-")
+    .join(",");
+};
+
+const setDeviceModels = (deviceIds) => {
+  syncDeviceFields(deviceIds);
+};
+
+const handleAreaChange = async (areaId) => {
+  form.value.taskId = undefined;
+  form.value.taskIds = [];
+  form.value.taskIdsStr = undefined;
+  form.value.deviceLedgerIds = [];
+  form.value.deviceLedgerIdsStr = undefined;
+  form.value.taskName = undefined;
+  form.value.deviceModel = undefined;
+  await loadDevicesByArea(areaId);
+};
+
+const resetForm = () => {
+  if (proxy.$refs.formRef) {
+    proxy.$refs.formRef.resetFields();
+  }
+  form.value = {
+    areaId: undefined,
+    taskId: undefined,
+    taskIds: [],
+    taskIdsStr: undefined,
+    deviceLedgerIds: [],
+    deviceLedgerIdsStr: undefined,
+    taskName: undefined,
+    deviceModel: undefined,
+    inspector: [],
+    inspectorIds: "",
+    remarks: "",
+    frequencyType: "",
+    frequencyDetail: "",
+    week: "",
+    time: "",
+  };
+};
+
 const openDialog = async (type, row) => {
-  dialogVisitable.value = true
-  operationType.value = type
-  
-  // 閲嶇疆琛ㄥ崟
+  dialogVisitable.value = true;
+  operationType.value = type;
   resetForm();
-  
-  // 鍔犺浇鐢ㄦ埛鍒楄〃
+
   userListNoPageByTenantId().then((res) => {
     userList.value = res.data;
   });
-  
-  // 鍔犺浇璁惧鍒楄〃
-  await loadDeviceName();
-  
-  if (type === 'edit' && row) {
-    form.value = {...row}
-    form.value.inspector = form.value.inspectorIds.split(',').map(Number)
-    
-    // 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
-    if (form.value.taskId) {
-      setDeviceModel(form.value.taskId);
+
+  await loadAreaTree();
+
+  if (type === "edit" && row) {
+    form.value = {
+      ...form.value,
+      ...row,
+      inspector: row.inspectorIds
+        ? String(row.inspectorIds)
+            .split(",")
+            .map((item) => Number(item))
+            .filter((item) => Number.isFinite(item))
+        : [],
+    };
+
+    form.value.deviceLedgerIds = normalizeIdList(
+      row.deviceLedgerIds ??
+        row.deviceLedgerIdsStr ??
+        row.taskIds ??
+        row.taskIdsStr ??
+        row.taskId
+    );
+    form.value.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
+    form.value.taskIds = [...form.value.deviceLedgerIds];
+    form.value.taskIdsStr = form.value.deviceLedgerIds.join(",");
+    form.value.taskId = form.value.deviceLedgerIds[0];
+
+    if (form.value.areaId) {
+      await loadDevicesByArea(form.value.areaId);
+      syncDeviceFields(form.value.deviceLedgerIds);
     }
   }
-}
+};
 
-// 鍏抽棴瀵硅瘽妗�
 const cancel = () => {
-  resetForm()
-  dialogVisitable.value = false
-  emit('closeDia')
-}
+  resetForm();
+  dialogVisitable.value = false;
+  emit("closeDia");
+};
 
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
-  if (proxy.$refs.formRef) {
-    proxy.$refs.formRef.resetFields()
-  }
-  // 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
-  form.value = {
-    taskId: undefined,
-    taskName: undefined,
-    inspector: '',
-    inspectorIds: '',
-    remarks: '',
-    frequencyType: '',
-    frequencyDetail: '',
-    week: '',
-    time: ''
-  }
-}
-
-// 鎻愪氦琛ㄥ崟
 const submitForm = () => {
-  proxy.$refs["formRef"].validate(async valid => {
-    if (valid) {
-      try {
-        form.value.inspectorIds = form.value.inspector.join(',')
-        delete form.value.inspector
-        
-        if (form.value.frequencyType === 'WEEKLY') {
-          let frequencyDetail = ''
-          frequencyDetail = form.value.week + ',' + form.value.time
-          form.value.frequencyDetail = frequencyDetail
-        }
-        
-        let res = await userStore.getInfo()
-        form.value.registrantId = res.user.userId
-        
-        await addOrEditTimingTask(form.value)
-        cancel()
-        proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
-      } catch (error) {
-        proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
-      }
+  proxy.$refs.formRef.validate(async (valid) => {
+    if (!valid) {
+      return;
     }
-  })
-}
-defineExpose({ openDialog })
+    try {
+      syncDeviceFields(form.value.deviceLedgerIds);
+      const payload = { ...form.value };
+
+      payload.inspectorIds = Array.isArray(form.value.inspector)
+        ? form.value.inspector.join(",")
+        : "";
+      delete payload.inspector;
+
+      if (payload.frequencyType === "WEEKLY") {
+        payload.frequencyDetail = `${payload.week},${payload.time}`;
+      }
+
+      const userInfo = await userStore.getInfo();
+      payload.registrantId = userInfo.user.userId;
+      payload.taskId = form.value.deviceLedgerIds[0];
+      payload.taskIds = [...form.value.deviceLedgerIds];
+      payload.taskIdsStr = form.value.deviceLedgerIds.join(",");
+      payload.deviceLedgerIds = [...form.value.deviceLedgerIds];
+      payload.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
+      payload.taskName = form.value.taskName;
+      payload.deviceModel = form.value.deviceModel || "-";
+
+      await addOrEditTimingTask(payload);
+      cancel();
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+    } catch (error) {
+      proxy.$modal.msgError("鎻愪氦澶辫触锛岃閲嶈瘯");
+    }
+  });
+};
+
+defineExpose({ openDialog });
 </script>
 
-<style scoped>
-
-</style>
\ No newline at end of file
+<style scoped></style>

--
Gitblit v1.9.3