From e8152d0f31f54c816bebca216985caf913037273 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 18 五月 2026 14:09:17 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro

---
 src/views/equipmentManagement/upkeep/index.vue                             |   24 ++++----
 src/views/productionManagement/productStructure/Detail/index.vue           |   69 ++++++++++++++++++++++
 src/views/qualityManagement/nonconformingManagement/components/formDia.vue |   22 +++++--
 src/assets/styles/sidebar.scss                                             |    9 --
 src/layout/components/Sidebar/index.vue                                    |   15 +++++
 src/views/equipmentManagement/inspectionManagement/index.vue               |   18 +++++
 6 files changed, 126 insertions(+), 31 deletions(-)

diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index be7b7a7..15d8078 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -225,14 +225,7 @@
             width: 0;
             overflow: hidden;
             visibility: hidden;
-            display: inline-block;
-          }
-          & > i {
-            height: 0;
-            width: 0;
-            overflow: hidden;
-            visibility: hidden;
-            display: inline-block;
+            display: inline-block;
           }
         }
       }
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 0692dda..d1d60b3 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -82,6 +82,7 @@
         margin-bottom: 6px;
         border-radius: 14px;
         color: v-bind(getMenuTextColor);
+        font-size: 13px;
 
         &:hover {
           background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
@@ -99,6 +100,19 @@
 
       .el-sub-menu__title {
         color: v-bind(getMenuTextColor);
+      }
+
+      :deep(.el-sub-menu__icon-arrow) {
+        display: inline-flex !important;
+        align-items: center;
+        justify-content: center;
+        width: 14px;
+        height: 14px;
+        margin-top: -7px;
+        right: 12px;
+        font-size: 14px !important;
+        color: currentColor !important;
+        opacity: 0.72;
       }
 
       :deep(.el-sub-menu.is-active > .el-sub-menu__title) {
@@ -128,6 +142,7 @@
 
       :deep(.el-sub-menu.is-active > .el-sub-menu__title .menu-title),
       :deep(.el-sub-menu.is-active > .el-sub-menu__title .svg-icon),
+      :deep(.el-sub-menu.is-active > .el-sub-menu__title .el-sub-menu__icon-arrow),
       :deep(.el-menu-item.is-active .menu-title),
       :deep(.el-menu-item.is-active .svg-icon) {
         color: v-bind(theme) !important;
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
index 44103ac..809fd4f 100644
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ b/src/views/equipmentManagement/inspectionManagement/index.vue
@@ -71,7 +71,8 @@
             </div>
           </template>
           <template #isEnabled="{ row }">
-            <el-tag :type="row.isEnabled === 1 ? 'success' : 'danger'" size="small">
+            <el-tag :type="row.isEnabled === 1 ? 'success' : 'danger'"
+                    size="small">
               {{ row.isEnabled == 1 ? '鏄�' : '鍚�' }}
             </el-tag>
           </template>
@@ -139,7 +140,7 @@
       label: "鏄惁鍚敤",
       minWidth: 100,
       dataType: "slot",
-      slot: "isEnabled"
+      slot: "isEnabled",
     },
     {
       prop: "frequencyType",
@@ -189,6 +190,19 @@
     },
     { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
     { prop: "createTime", label: "鐧昏鏃ユ湡", minWidth: 100 },
+    {
+      prop: "inspectionResult",
+      label: "宸℃缁撴灉",
+      minWidth: 100,
+      dataType: "tag",
+      formatData: val => {
+        return val == 1 ? "姝e父" : "寮傚父";
+      },
+      formatType: val => {
+        return val == 1 ? "success" : "danger";
+      },
+    },
+    { prop: "abnormalDescription", label: "寮傚父鎻忚堪", minWidth: 100 },
   ]);
 
   // 鎿嶄綔鍒楅厤缃�
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 6bdbc8f..c22ebcc 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -2,8 +2,8 @@
   <div class="app-container">
     <el-tabs v-model="activeTab"
              @tab-change="handleTabChange">
-      <!-- 瀹氭椂浠诲姟绠$悊tab -->
-      <el-tab-pane label="瀹氭椂浠诲姟绠$悊"
+      <!-- 淇濆吇浠诲姟tab -->
+      <el-tab-pane label="淇濆吇浠诲姟"
                    name="scheduled">
         <div class="search_form">
           <el-form :model="scheduledFilters"
@@ -37,7 +37,7 @@
         <div class="table_list">
           <div class="actions">
             <el-text class="mx-1"
-                     size="large">瀹氭椂浠诲姟绠$悊</el-text>
+                     size="large">淇濆吇浠诲姟</el-text>
             <div>
               <el-button type="primary"
                          icon="Plus"
@@ -84,8 +84,8 @@
           </PIMTable>
         </div>
       </el-tab-pane>
-      <!-- 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛� -->
-      <el-tab-pane label="浠诲姟璁板綍"
+      <!-- 淇濆吇璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛� -->
+      <el-tab-pane label="淇濆吇璁板綍"
                    name="record">
         <div class="search_form">
           <el-form :model="filters"
@@ -130,7 +130,7 @@
         <div class="table_list">
           <div class="actions">
             <el-text class="mx-1"
-                     size="large">浠诲姟璁板綍</el-text>
+                     size="large">淇濆吇璁板綍</el-text>
             <div>
               <el-button type="success"
                          icon="Van"
@@ -262,7 +262,7 @@
   const fileDialogVisible = ref(false);
   const currentMaintenanceTaskId = ref(null);
 
-  // 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
+  // 淇濆吇璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
   const filters = reactive({
     deviceName: "",
     maintenancePlanTime: "",
@@ -278,7 +278,7 @@
   });
   const multipleList = ref([]);
 
-  // 瀹氭椂浠诲姟绠$悊tab鐩稿叧鍙橀噺
+  // 淇濆吇浠诲姟tab鐩稿叧鍙橀噺
   const scheduledFilters = reactive({
     taskName: "",
     status: "",
@@ -292,7 +292,7 @@
   });
   const scheduledMultipleList = ref([]);
 
-  // 瀹氭椂浠诲姟绠$悊琛ㄦ牸鍒楅厤缃�
+  // 淇濆吇浠诲姟琛ㄦ牸鍒楅厤缃�
   const scheduledColumns = ref([
     { prop: "taskName", label: "璁惧鍚嶇О" },
     {
@@ -355,7 +355,7 @@
     },
   ]);
 
-  // 浠诲姟璁板綍琛ㄦ牸鍒楅厤缃紙鍘熻澶囦繚鍏昏〃鏍煎垪锛�
+  // 淇濆吇璁板綍琛ㄦ牸鍒楅厤缃紙鍘熻澶囦繚鍏昏〃鏍煎垪锛�
   const columns = ref([
     {
       label: "璁惧鍚嶇О",
@@ -436,7 +436,7 @@
     }
   };
 
-  // 瀹氭椂浠诲姟绠$悊鐩稿叧鏂规硶
+  // 淇濆吇浠诲姟鐩稿叧鏂规硶
   const getScheduledTableData = async () => {
     try {
       const params = {
@@ -503,7 +503,7 @@
     ElMessage.info("瀵煎嚭瀹氭椂浠诲姟鍔熻兘寰呭疄鐜�");
   };
 
-  // 浠诲姟璁板綍鐩稿叧鏂规硶锛堝師璁惧淇濆吇椤甸潰鏂规硶锛�
+  // 淇濆吇璁板綍鐩稿叧鏂规硶锛堝師璁惧淇濆吇椤甸潰鏂规硶锛�
   const getTableData = async () => {
     try {
       const params = {
diff --git a/src/views/productionManagement/productStructure/Detail/index.vue b/src/views/productionManagement/productStructure/Detail/index.vue
index a7f6b6b..0c326cc 100644
--- a/src/views/productionManagement/productStructure/Detail/index.vue
+++ b/src/views/productionManagement/productStructure/Detail/index.vue
@@ -316,7 +316,39 @@
     });
   };
 
+  const findSiblings = (items: any[], tempId: string): any[] | null => {
+    if (!items || items.length === 0) return null;
+    // 妫�鏌ュ綋鍓嶅眰绾�
+    if (items.some(item => item.tempId === tempId)) {
+      return items;
+    }
+    // 閫掑綊鏌ユ壘瀛愮骇
+    for (const item of items) {
+      if (item.children && item.children.length > 0) {
+        const result = findSiblings(item.children, tempId);
+        if (result) return result;
+      }
+    }
+    return null;
+  };
+
   const handleProcessChange = (row: any, value: any) => {
+    if (value) {
+      const siblings = findSiblings(dataValue.dataList, row.tempId);
+      if (siblings) {
+        const isDuplicate = siblings.some(
+          s => s.tempId !== row.tempId && s.processId === value
+        );
+        if (isDuplicate) {
+          const option = getProcessOptionById(value);
+          const processName = option?.name || "璇ュ伐搴�";
+          ElMessage.warning(`鍚屼竴灞傜骇涓嬩笉鑳介�夋嫨閲嶅鐨勬秷鑰楀伐搴忥細${processName}`);
+          row.processId = "";
+          syncProcessOperationFields(row);
+          return;
+        }
+      }
+    }
     row.processId = value || "";
     syncProcessOperationFields(row);
   };
@@ -431,8 +463,37 @@
   const validateAll = () => {
     let isValid = true;
 
+    // 鏍¢獙涓�缁勫厔寮熻妭鐐圭殑宸ュ簭鏄惁鍞竴
+    const checkProcessUniqueness = (items: any[]) => {
+      if (!items || items.length === 0 || !isValid) return;
+
+      const processIds = new Set();
+      for (const item of items) {
+        if (item.processId) {
+          if (processIds.has(item.processId)) {
+            const option = getProcessOptionById(item.processId);
+            const processName = option?.name || item.processName || "鏈煡宸ュ簭";
+            ElMessage.error(
+              `浜у搧銆�${item.productName}銆嶇殑娑堣�楀伐搴忋��${processName}銆嶅湪褰撳墠灞傜骇宸插瓨鍦紝璇峰嬁閲嶅璁剧疆`
+            );
+            isValid = false;
+            return;
+          }
+          processIds.add(item.processId);
+        }
+      }
+
+      // 閫掑綊鏍¢獙瀛愮骇鐨勫厔寮熻妭鐐�
+      for (const item of items) {
+        if (item.children && item.children.length > 0) {
+          checkProcessUniqueness(item.children);
+        }
+      }
+    };
+
     // 鏍¢獙鍑芥暟
     const validateItem = (item: any, isTopLevel = false) => {
+      if (!isValid) return;
       // 鏍¢獙褰撳墠椤圭殑蹇呭~瀛楁
       if (!item.model) {
         ElMessage.error("璇烽�夋嫨瑙勬牸");
@@ -460,7 +521,7 @@
       //   return;
       // }
 
-      // 閫掑綊鏍¢獙瀛愰」
+      // 閫掑綊鏍¢獙瀛愰」瀛楁
       if (item.children && item.children.length > 0) {
         item.children.forEach(child => {
           validateItem(child, false);
@@ -468,7 +529,11 @@
       }
     };
 
-    // 閬嶅巻鎵�鏈夐《灞傞」
+    // 1. 棣栧厛鏍¢獙鍚屼竴鐖剁骇涓嬬殑鍚屽眰娑堣�楀伐搴忔槸鍚﹀敮涓�
+    checkProcessUniqueness(dataValue.dataList);
+    if (!isValid) return false;
+
+    // 2. 鐒跺悗閬嶅巻鏍¢獙鎵�鏈夐《灞傞」鐨勫瓧娈靛繀濉儏鍐�
     dataValue.dataList.forEach(item => {
       validateItem(item, true);
     });
diff --git a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
index 0c6562c..e747d04 100644
--- a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
+++ b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -35,10 +35,10 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
-              <el-select v-model="form.model" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'edit'"
-                          filterable readonly @change="handleChangeModel">
-              <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
-            </el-select>
+              <el-select v-model="form.productModelId" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'edit'"
+                         filterable readonly @change="handleChangeModel">
+                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -149,7 +149,7 @@
     productId: "",
     model: "",
     unit: "",
-    quantity: "",
+    quantity: undefined,
     checkCompany: "",
     checkResult: "",
     inspectType: '',
@@ -157,6 +157,7 @@
     dealResult: '',
     dealName: '',
     dealTime: '',
+    productModelId: undefined,
   },
   rules: {
     checkTime: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -199,8 +200,9 @@
       productId: '',
       model: '',
       unit: '',
-      quantity: '',
+      quantity: undefined,
       productName: '',
+      productModelId: undefined,
     };
   } else {
     form.value = {};
@@ -223,6 +225,12 @@
   modelList({ id: value }).then((res) => {
     modelOptions.value = res;
   })
+};
+const handleChangeModel = (value) => {
+  const selectedModel = modelOptions.value.find(item => item.id === value);
+  if (selectedModel) {
+    form.value.model = selectedModel.model;
+  }
 };
 const findNodeById = (nodes, productId) => {
   for (let i = 0; i < nodes.length; i++) {
@@ -285,4 +293,4 @@
 
 <style scoped>
 
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3