From 8aa5f0e094e6ff51aa7c47d5b4e8331a16eb09ff Mon Sep 17 00:00:00 2001
From: leiqunqing <zhengqifeng@hnkhzn.com>
Date: 星期五, 06 二月 2026 15:19:05 +0800
Subject: [PATCH] 提交ddl

---
 代码管理/WIDESEAWCS_Client/src/views/Home.vue |  675 ++++++++++++++++++-------------------------------------
 1 files changed, 222 insertions(+), 453 deletions(-)

diff --git "a/\344\273\243\347\240\201\347\256\241\347\220\206/WIDESEAWCS_Client/src/views/Home.vue" "b/\344\273\243\347\240\201\347\256\241\347\220\206/WIDESEAWCS_Client/src/views/Home.vue"
index b82d2f2..9a69c91 100644
--- "a/\344\273\243\347\240\201\347\256\241\347\220\206/WIDESEAWCS_Client/src/views/Home.vue"
+++ "b/\344\273\243\347\240\201\347\256\241\347\220\206/WIDESEAWCS_Client/src/views/Home.vue"
@@ -1,42 +1,17 @@
 <template>
   <div class="container">
-    <!-- 宸︿晶鍖哄煙 - 鏃犱换浣曟爣棰樻爣娉� -->
+    <!-- 宸︿晶鍖哄煙 - 浠呬繚鐣欎俊鍙风伅+鎴愬搧/闆朵欢鍖哄煙 -->
     <div class="left-area">
       <div class="left-top">
-        <!-- 鎸夐挳+淇″彿 妯悜鎺掑垪瀹瑰櫒 -->
-        <div class="btn-signal-group">
-          <!-- 鎸夐挳缁� - 淇敼涓轰笂涓嬫帓鍒� -->
-          <div class="btn-group">
-            <button
-              class="btn"
-              :class="isPLCStarted ? 'stop-btn' : 'start-btn'"
-              @click="handleToggle"
+        <div class="signal-status">
+          <div class="signal-item" v-for="(signal, index) in signalStates" :key="index">
+            <div
+              class="signal-light"
+              :class="signal ? 'signal-active' : 'signal-inactive'"
             >
-              <i class="icon" :class="isPLCStarted ? 'icon-stop' : 'icon-start'"></i>
-              {{ isPLCStarted ? "鍏抽棴" : "鍚姩" }}
-            </button>
-            <button
-              class="btn"
-              :class="isPLCPaused ? 'resume-btn' : 'pause-btn'"
-              @click="handlePauseToggle"
-              :disabled="!isPLCStarted"
-            >
-              <i class="icon" :class="isPLCPaused ? 'icon-resume' : 'icon-pause'"></i>
-              {{ isPLCPaused ? "鎭㈠" : "鏆傚仠" }}
-            </button>
-          </div>
-
-          <!-- 淇″彿鐏粍 鍗犱袱涓寜閽搴� + 鏁翠綋鏀惧ぇ -->
-          <div class="signal-status">
-            <div class="signal-item" v-for="(signal, index) in signalStates" :key="index">
-              <div
-                class="signal-light"
-                :class="signal ? 'signal-active' : 'signal-inactive'"
-              >
-                <div class="signal-light-inner"></div>
-              </div>
-              <span class="signal-label">{{ signalLabels[index] }}</span>
+              <div class="signal-light-inner"></div>
             </div>
+            <span class="signal-label">{{ signalLabels[index] }}</span>
           </div>
         </div>
       </div>
@@ -65,6 +40,7 @@
                 class="part-checkbox"
                 v-model="leftPartChecked[index]"
                 @change="handlePartCheck(index)"
+                :disabled="checkLoading[index]"
               />
               <span class="checkmark"></span>
               <span class="checkbox-label">{{
@@ -76,32 +52,19 @@
       </div>
     </div>
 
-    <!-- 鍙充晶鍖哄煙 - 鏃犱换浣曟爣棰樻爣娉� 銆愬凡鍒犻櫎娓呯┖+淇濆瓨鎸夐挳銆� -->
+    <!-- 鍙充晶鍖哄煙 - 淇濈暀鍘熸湁褰曞叆+鎻愪氦+娓呴櫎鍔熻兘 -->
     <div class="right-area">
       <div class="right-top">
-        <div class="form-row">
+        <div class="form-row input-submit-row">
           <span class="label">褰曞叆妗嗭細</span>
-          <!-- 鉁� 鍙繚鐣欑函褰曞叆妗嗭紝娓呯┖/淇濆瓨鎸夐挳宸插垹闄� -->
           <input type="text" class="input-box" v-model="rightTopInput" />
+          <button class="btn save-btn submit-input-btn" @click="saveData">
+            <i class="icon icon-submit"></i>鎻愪氦
+          </button>
         </div>
       </div>
 
       <div class="right-bottom">
-        <div class="form-row tooling-board-row">
-          <span class="short-label">宸ヨ鏉跨紪鍙凤細</span>
-          <input
-            type="text"
-            class="input-box short-input"
-            v-model="toolingBoardNo"
-            placeholder="璇疯緭鍏ュ伐瑁呮澘缂栧彿"
-          />
-          <button class="btn clear-btn" @click="clearToolingBoardNo">
-            <i class="icon icon-clear"></i>娓呴櫎
-          </button>
-          <button class="btn save-btn" @click="saveToolingBoardNo">
-            <i class="icon icon-submit"></i>鎻愪氦
-          </button>
-        </div>
         <div class="parts-list">
           <div class="form-row part-item finished-product-row">
             <span class="label">鎴愬搧缂栧彿锛�</span>
@@ -143,23 +106,19 @@
 
 export default {
   setup() {
-    // 鍩虹鏁版嵁瀹氫箟 - 1:1绮惧噯瀵规帴鍚庣 鎴愬搧缂栧彿+闆朵欢缂栧彿 鏃犲啑浣欏吋瀹�
-    const finishedProduct = ref(""); // 宸︿晶鎴愬搧缂栧彿锛圙etLeftInitialData鎺ュ彛杩斿洖锛�
-    const finishedProductId = ref("");
-    const rightTopInput = ref("");
+    // 鍩虹鏁版嵁瀹氫箟
+    const finishedProduct = ref(""); // 宸︿晶鎴愬搧缂栧彿锛堟帴鍙h繑鍥烇級
+    const finishedProductId = ref(""); // 宸︿晶鎴愬搧ID锛堟帴鍙h繑鍥烇級
+    const rightTopInput = ref(""); // 鍙充晶鏍稿績褰曞叆妗�
     const leftPartCodes = ref(Array(10).fill("")); // 宸︿晶闆朵欢缂栧彿鏁扮粍
     const rightPartCodes = ref(Array(10).fill("")); // 鍙充晶闆朵欢缂栧彿鏁扮粍
-    const leftPartChecked = ref(Array(10).fill(false));
-    const toolingBoardNo = ref("");
-    const fillIndex = ref(-1);
-    const leftPartIds = ref(Array(10).fill(""));
-    const finishedProductCode = ref(""); // 鍙充晶鎴愬搧缂栧彿锛堝伐瑁呮澘鎺ュ彛杩斿洖锛�
+    const leftPartChecked = ref(Array(10).fill(false)); // 宸︿晶闆朵欢鍕鹃�夌姸鎬�
+    const leftPartIds = ref(Array(10).fill("")); // 宸︿晶闆朵欢ID锛堟帴鍙h繑鍥烇級
+    const finishedProductCode = ref(""); // 鍙充晶鎴愬搧缂栧彿杈撳叆妗�
+    const fillIndex = ref(-1); // 褰曞叆妗嗚嚜鍔ㄥ~鍏呯储寮�
+    const checkLoading = ref(Array(10).fill(false)); // 闆朵欢鍕鹃�夊姞杞介攣
 
-    // PLC鐘舵��
-    const isPLCStarted = ref(false);
-    const isPLCPaused = ref(false);
-
-    // 淇″彿鐩稿叧
+    // 淇″彿鐏浉鍏�
     const signalStates = ref([false, false, false, false, false]);
     const signalLabels = ref([
       "蹇冭烦淇″彿",
@@ -169,34 +128,27 @@
       "鏁呴殰淇″彿",
     ]);
 
-    // 瀹氭椂杞鏍稿績閰嶇疆
+    // 瀹氭椂/闃叉姈鐩稿叧鍙橀噺
     let pollingTimer = null;
-    const pollingInterval = 5000;
+    const pollingInterval = 5000; // 淇″彿鐏疆璇㈤棿闅�5绉�
     let checkDebounceTimer = null;
     let destroyDelayTimer = null;
-    const destroyDelayTime = 500; // 鉁� 鏍稿績锛氬~鍏�+娓呯┖ 閮藉欢杩�500姣
-    let boardCodeDebounceTimer = null;
-    // 鉁� 鏂板锛氳嚜鍔ㄦ彁浜ら槻鎶栧畾鏃跺櫒锛岄槻姝㈤噸澶嶆彁浜�
+    const destroyDelayTime = 500; // 褰曞叆妗嗗~鍏呭欢杩�500ms
     let autoSubmitDebounceTimer = null;
-    // 鉁� 鏂板锛氭彁浜ら攣锛岄槻姝㈡棤鍕鹃�夋椂閲嶅瑙﹀彂鎻愪氦
-    let submitLock = ref(false);
+    let submitLock = ref(false); // 鎻愪氦閿侊紝闃叉閲嶅鎻愪氦
 
-    // 鉁� 鉁� 鉁� 鏍稿績鏂板1锛氳绠楀睘鎬� - 瀹炴椂缁熻宸︿晶鍕鹃�夌殑澶嶉�夋鏁伴噺 (鑷姩鏇存柊)
+    // 璁$畻灞炴�� - 缁熻鏈夋晥鍕鹃��/濉厖鏁伴噺锛堣繃婊ょ┖鍊硷級
     const checkedCount = computed(() => {
-      // 缁熻leftPartChecked鏁扮粍涓负true鐨勬暟閲�
       return leftPartChecked.value.filter((checked) => checked === true).length;
     });
-
-    // 鉁� 鉁� 鉁� 鏍稿績鏂板2锛氳绠楀睘鎬� - 瀹炴椂缁熻鍙充晶宸插~鍏呯殑闆朵欢鏁伴噺 (鑷姩鏇存柊)
     const filledPartCount = computed(() => {
-      // 缁熻rightPartCodes鏁扮粍涓湁鍊�(闈炵┖)鐨勯浂浠舵暟閲�
       return rightPartCodes.value.filter((code) => code.trim() !== "").length;
     });
 
-    // 鉁� 鑾峰彇宸︿晶鍒濆鏁版嵁 - 瀵规帴 /api/scanStation/GetLeftInitialData
+    // 鑾峰彇宸︿晶鍒濆鏁版嵁锛堟垚鍝�+闆朵欢+鍕鹃�夌姸鎬侊級
     const fetchLeftInitialData = async () => {
       try {
-        console.log("姝e湪鑾峰彇宸︿晶鍒濆鏁版嵁锛堟垚鍝佺紪鍙�+闆朵欢缂栧彿+鍕鹃�夌姸鎬�+闆朵欢ID锛�...");
+        console.log("姝e湪鑾峰彇宸︿晶鍒濆鏁版嵁...");
         const response = await axios.get("/api/scanStation/GetLeftInitialData", {
           timeout: 5000,
         });
@@ -206,14 +158,12 @@
           const data = resData.Data || resData.data || {};
           if (data.finishedProductId) finishedProductId.value = data.finishedProductId;
           if (data.finishedProduct) finishedProduct.value = data.finishedProduct;
-          // 璧嬪�煎乏渚ч浂浠剁紪鍙�
           if (Array.isArray(data.leftPartCodes) && data.leftPartCodes.length >= 10) {
             for (let i = 0; i < 10; i++) {
               leftPartCodes.value[i] = data.leftPartCodes[i] || "";
               leftPartIds.value[i] = data.leftPartIds?.[i] || "";
             }
           }
-          // 璧嬪�煎嬀閫夌姸鎬�
           if (Array.isArray(data.leftPartChecked) && data.leftPartChecked.length >= 10) {
             for (let i = 0; i < 10; i++) {
               leftPartChecked.value[i] = !!data.leftPartChecked[i];
@@ -225,7 +175,7 @@
       }
     };
 
-    // 鉁� 鑾峰彇淇″彿+PLC鐘舵��
+    // 鑾峰彇淇″彿鐏姸鎬侊紙瀹氭椂杞锛�
     const fetchSignalAndPLCStates = async () => {
       try {
         const response = await axios.get("/api/scanStation/GetSignalStates", {
@@ -237,63 +187,13 @@
           const data = resData.Data || resData.data || {};
           const newSignalStates = data.signalStates || [];
           for (let i = 0; i < 5; i++) signalStates.value[i] = newSignalStates[i] ?? false;
-          const plcStatus = data.plcStatus || data.plc_status || {};
-          isPLCStarted.value = plcStatus.isStarted ?? isPLCStarted.value;
-          // 鉁� 淇BUG锛氬師浠g爜鏄� isPLCStarted.value 瀵艰嚧鏆傚仠鐘舵�佽祴鍊奸敊璇�
-          isPLCPaused.value = plcStatus.isPaused ?? isPLCPaused.value;
         }
       } catch (error) {
-        console.error("鑾峰彇淇″彿鍜孭LC鐘舵�佸け璐ワ細", error);
+        console.error("鑾峰彇淇″彿鐘舵�佸け璐ワ細", error);
       }
     };
 
-    // 鉁� 銆愭牳蹇冧慨鏀广�戝伐瑁呮澘鏌ヨ鎺ュ彛 - 鏈夋暟鎹氨濉厖锛屾棤鏁版嵁/澶辫触 瀹屽叏淇濈暀鍘熸湁鍐呭锛屼笉鍋氫换浣曟竻绌烘搷浣�
-    const fetchProductAndPartsByBoardCode = async (boardCode) => {
-      if (!boardCode.trim()) return;
-      try {
-        console.log(`宸ヨ鏉跨紪鍙峰彉鏇达紝璇锋眰鏁版嵁锛�${boardCode}`);
-        const response = await axios.get(
-          "/api/boxingDetail/GetProductAndPartsByBoardNo",
-          {
-            params: { palletCode: boardCode.trim() },
-            timeout: 5000,
-          }
-        );
-        const resData = response.data;
-        const isSuccess = resData.Status === true || resData.status === true;
-        // 鉁� 鍙湁銆愭帴鍙f垚鍔�+鏈夎繑鍥炴暟鎹�戠殑鏃跺�欙紝鎵嶆墽琛岃祴鍊艰鐩�
-        if (isSuccess) {
-          const data = resData.Data || resData.data || {};
-          // 鏈夋垚鍝佺紪鍙峰氨璧嬪�硷紝娌℃湁灏变笉鎿嶄綔
-          if (data.finishedProductCode) {
-            finishedProductCode.value = data.finishedProductCode;
-          }
-          // 鏈夐浂浠跺垪琛ㄥ氨濉厖锛屾病鏈夊氨涓嶆搷浣�
-          const partsList = Array.isArray(data.partsList) ? data.partsList : [];
-          if (partsList.length > 0) {
-            for (let i = 0; i < 10; i++) {
-              if (partsList[i]) {
-                rightPartCodes.value[i] = partsList[i];
-              }
-            }
-          }
-          console.log("鉁� 宸ヨ鏉挎煡璇㈡垚鍔燂紝鎴愬搧缂栧彿+闆朵欢缂栧彿濉厖瀹屾垚");
-        } else {
-          // 鉁� 鏃犲搴旀暟鎹細鍙脊鎻愮ず锛屼笉娓呯┖浠讳綍鍐呭
-          alert(
-            "鑾峰彇鏁版嵁澶辫触锛�" + (resData.Message || resData.message || "鏃犲搴斿伐瑁呮澘鏁版嵁")
-          );
-        }
-      } catch (error) {
-        // 鉁� 璇锋眰澶辫触锛氬彧寮规彁绀猴紝涓嶆竻绌轰换浣曞唴瀹�
-        alert("宸ヨ鏉挎暟鎹姹傚け璐ワ紝璇锋鏌ョ綉缁滄垨鎺ュ彛锛�");
-        console.error("宸ヨ鏉挎帴鍙h姹傚け璐ワ細", error);
-      } finally {
-        boardCodeDebounceTimer = null;
-      }
-    };
-
-    // 鍚姩/鍋滄瀹氭椂杞
+    // 鍚姩/鍋滄淇″彿鐏疆璇�
     const startPolling = () => {
       if (pollingTimer) clearInterval(pollingTimer);
       fetchSignalAndPLCStates();
@@ -304,63 +204,13 @@
       pollingTimer = null;
     };
 
-    // PLC鍚姩/鍏抽棴閫昏緫
-    const handleToggle = async () => {
-      try {
-        const response = await axios.get("/api/scanStation/StartPLC", {
-          params: { isStop: isPLCStarted.value },
-          timeout: 5000,
-        });
-        const resData = response.data;
-        const isSuccess = resData.Status === true || resData.status === true;
-        if (isSuccess) {
-          isPLCStarted.value = !isPLCStarted.value;
-          isPLCPaused.value = false;
-          fetchSignalAndPLCStates();
-        } else {
-          alert(
-            resData.Message ||
-              resData.message ||
-              (isPLCStarted.value ? "鍏抽棴澶辫触" : "鍚姩澶辫触")
-          );
-        }
-      } catch (error) {
-        alert(isPLCStarted.value ? "鍏抽棴PLC澶辫触" : "鍚姩PLC澶辫触");
-        console.error("PLC鍚仠澶辫触锛�", error);
-      }
-    };
-
-    // PLC鏆傚仠/鎭㈠閫昏緫
-    const handlePauseToggle = async () => {
-      try {
-        const response = await axios.get("/api/scanStation/PausePLC", {
-          params: { isPause: !isPLCPaused.value },
-          timeout: 5000,
-        });
-        const resData = response.data;
-        const isSuccess = resData.Status === true || resData.status === true;
-        if (isSuccess) {
-          isPLCPaused.value = !isPLCPaused.value;
-          fetchSignalAndPLCStates();
-        } else {
-          alert(
-            resData.Message ||
-              resData.message ||
-              (isPLCPaused.value ? "鎭㈠澶辫触" : "鏆傚仠澶辫触")
-          );
-        }
-      } catch (error) {
-        alert(isPLCPaused.value ? "鎭㈠PLC澶辫触" : "鏆傚仠PLC澶辫触");
-        console.error("PLC鏆傚仠鎭㈠澶辫触锛�", error);
-      }
-    };
-
-    // 闆朵欢鍕鹃�夌姸鎬佸彉鏇村鐞�
+    // 宸︿晶闆朵欢鍕鹃�夌姸鎬佸彉鏇村鐞嗭紙鏇存柊鍚庣鐘舵�侊級
     const handlePartCheck = async (index) => {
       const isChecked = leftPartChecked.value[index];
       const partCode = leftPartCodes.value[index];
       const partId = leftPartIds.value[index];
 
+      // 鍓嶇疆鏍¢獙
       if (!finishedProductId.value) {
         alert("鎴愬搧ID涓嶅瓨鍦紝鏃犳硶鏇存柊闆朵欢鎵爜鐘舵�侊紒");
         leftPartChecked.value[index] = !isChecked;
@@ -377,67 +227,60 @@
         return;
       }
 
-      if (checkDebounceTimer) clearTimeout(checkDebounceTimer);
-      checkDebounceTimer = setTimeout(async () => {
-        try {
-          const response = await axios.post(
-            "/api/scanStation/UpdatePartScannedStatus",
-            { Id: partId, IsScanned: isChecked ? 1 : 0 },
-            { timeout: 5000 }
-          );
-          const resData = response.data;
-          const isSuccess = resData.Status === true || resData.status === true;
-          if (isSuccess) {
-            console.log(`闆朵欢${index + 1}鎵爜鐘舵�佹洿鏂版垚鍔焋);
-            // 鉁� 鍕鹃�夌姸鎬佸彉鍖栨椂锛岄噸缃彁浜ら攣
-            submitLock.value = false;
-          } else {
-            leftPartChecked.value[index] = !isChecked;
-            alert(
-              `闆朵欢${index + 1}鐘舵�佹洿鏂板け璐ワ細${
-                resData.Message || resData.message || "鏈煡閿欒"
-              }`
-            );
-          }
-        } catch (error) {
+      checkLoading.value[index] = true;
+      try {
+        const response = await axios.post(
+          "/api/scanStation/UpdatePartScannedStatus",
+          { Id: partId, IsScanned: isChecked ? 1 : 0 },
+          { timeout: 5000 }
+        );
+        const resData = response.data;
+        const isSuccess = resData.Status === true || resData.status === true;
+        if (isSuccess) {
+          console.log(`闆朵欢${index + 1}鎵爜鐘舵�佹洿鏂版垚鍔焋);
+        } else {
           leftPartChecked.value[index] = !isChecked;
-          alert(`闆朵欢${index + 1}鐘舵�佹洿鏂拌姹傚け璐ワ紝璇锋鏌ョ綉缁滄垨鎺ュ彛锛乣);
-          console.error(`鏇存柊闆朵欢${index + 1}鎵爜鐘舵�佸け璐ワ細`, error);
-        } finally {
-          checkDebounceTimer = null;
+          alert(
+            `闆朵欢${index + 1}鐘舵�佹洿鏂板け璐ワ細${
+              resData.Message || resData.message || "鏈煡閿欒"
+            }`
+          );
         }
-      }, 500);
+      } catch (error) {
+        leftPartChecked.value[index] = !isChecked;
+        alert(`闆朵欢${index + 1}鐘舵�佹洿鏂拌姹傚け璐ワ紝璇锋鏌ョ綉缁滄垨鎺ュ彛锛乣);
+        console.error(`鏇存柊闆朵欢${index + 1}鎵爜鐘舵�佸け璐ワ細`, error);
+      } finally {
+        checkLoading.value[index] = false;
+        if (checkDebounceTimer) clearTimeout(checkDebounceTimer);
+        checkDebounceTimer = null;
+      }
     };
 
-    // 鉁� 鏍稿績淇敼锛氬欢杩�0.5绉掑~鍏� + 寤惰繜0.5绉掓竻绌� 鍚屾鎵ц 鏃犻渶鎵嬪姩鎸夐挳
+    // 鍙充晶褰曞叆妗嗗欢杩熷~鍏呴�昏緫锛堟垚鍝佲啋闆朵欢渚濇濉厖锛�
     const fillContent = () => {
       if (!rightTopInput.value.trim()) return;
       const inputValue = rightTopInput.value.trim();
 
-      // 娓呴櫎鏃у畾鏃跺櫒锛岄槻姝㈤噸澶嶆墽琛�
       if (destroyDelayTimer) clearTimeout(destroyDelayTimer);
-      // 缁熶竴寤惰繜500ms鎵ц銆愬~鍏�+娓呯┖銆�
       destroyDelayTimer = setTimeout(() => {
-        if (!toolingBoardNo.value.trim()) {
-          toolingBoardNo.value = inputValue;
-        } else if (!finishedProductCode.value.trim()) {
+        if (!finishedProductCode.value.trim()) {
           finishedProductCode.value = inputValue;
         } else if (fillIndex.value < 10) {
           rightPartCodes.value[fillIndex.value] = inputValue;
           fillIndex.value++;
         } else {
-          alert("宸ヨ鏉跨紪鍙枫�佹垚鍝佺紪鍙峰拰闆朵欢1-10宸插叏閮ㄥ~鍏呭畬鎴�,鏃犳硶缁х画褰曞叆!");
+          alert("鎴愬搧缂栧彿鍜岄浂浠�1-10宸插叏閮ㄥ~鍏呭畬鎴�,鏃犳硶缁х画褰曞叆!");
           rightTopInput.value = "";
           destroyDelayTimer = null;
           return;
         }
-        // 濉厖瀹屾垚鍚� 鑷姩娓呯┖褰曞叆妗�
         rightTopInput.value = "";
         destroyDelayTimer = null;
       }, destroyDelayTime);
     };
 
-    // 鉁� 鐩戝惉褰曞叆妗嗗唴瀹瑰彉鍖栬嚜鍔ㄨЕ鍙戝~鍏呴�昏緫
+    // 鐩戝惉鍙充晶褰曞叆妗嗚緭鍏ワ紝瑙﹀彂鑷姩濉厖
     watch(
       rightTopInput,
       (newVal) => {
@@ -446,116 +289,119 @@
       { immediate: false }
     );
 
-    // 鐩戝惉宸ヨ鏉跨紪鍙峰彉鍖栨煡璇㈡暟鎹�
-    watch(
-      toolingBoardNo,
-      (newVal) => {
-        const boardCode = newVal.trim();
-        if (boardCode) {
-          if (boardCodeDebounceTimer) clearTimeout(boardCodeDebounceTimer);
-          boardCodeDebounceTimer = setTimeout(
-            () => fetchProductAndPartsByBoardCode(boardCode),
-            300
-          );
-        } else {
-          if (boardCodeDebounceTimer) clearTimeout(boardCodeDebounceTimer);
-        }
-      },
-      { immediate: false }
-    );
-
-    // 鍙充晶椤甸潰鎿嶄綔鏂规硶 (宸插垹闄ゆ竻绌�/淇濆瓨褰曞叆妗嗙殑鏂规硶锛屾棤鍐椾綑)
-    const clearToolingBoardNo = () => (toolingBoardNo.value = "");
+    // 鍙充晶杈撳叆妗嗘竻闄ゆ柟娉�
     const clearRightPart = (index) => (rightPartCodes.value[index] = "");
     const clearFinishedProductCode = () => (finishedProductCode.value = "");
 
-    // 鎻愪氦宸ヨ鏉挎暟鎹埌鍚庣
-    const saveToolingBoardNo = async () => {
-      if (!toolingBoardNo.value.trim()) {
-        alert("宸ヨ鏉跨紪鍙蜂笉鑳戒负绌猴紝璇疯緭鍏ュ悗鍐嶆彁浜わ紒");
+    // 鏍稿績淇敼锛氭仮澶嶆垚鍝佺紪鍙峰繀濉牎楠岋紝鏈~鍐欑洿鎺ユ彁绀哄苟缁堟鎻愪氦
+    const saveData = async () => {
+      // 1. 鎴愬搧缂栧彿蹇呭~鏍¢獙銆愭牳蹇冩柊澧炪��
+      const productCode = finishedProductCode.value.trim();
+      if (!productCode) {
+        alert("璇峰厛濉啓鎴愬搧缂栧彿锛屾垚鍝佺紪鍙蜂负蹇呭~椤癸紒");
         return;
       }
-      if (!finishedProductCode.value.trim()) {
-        alert("鎴愬搧缂栧彿涓嶈兘涓虹┖锛岃杈撳叆鍚庡啀鎻愪氦锛�");
-        return;
-      }
+      // 2. 鎻愪氦閿侊細闃叉閲嶅鐐瑰嚮
+      if (submitLock.value) return;
+      submitLock.value = true;
+
       try {
+        // 3. 浼犲弬閫傞厤锛氬悗绔疍to鏄ぇ椹煎嘲瀛楁锛佸繀椤讳弗鏍煎尮閰嶏紙FinishedProductCode/PartsList锛�
         const submitData = {
-          toolingBoardNo: toolingBoardNo.value.trim(),
-          finishedProductCode: finishedProductCode.value.trim(),
-          partsList: rightPartCodes.value.map((item) => item.trim()),
+          FinishedProductCode: productCode, // 鐩存帴浣跨敤宸叉牎楠岀殑闈炵┖鍊�
+          PartsList: rightPartCodes.value.map((item) => item.trim()),
         };
-        console.log("鉁� 鎻愪氦宸ヨ鏉挎暟鎹細", submitData);
+        console.log("馃摛 鎻愪氦鍒癝aveToolingBoardNo鐨勫弬鏁帮紙鍖归厤鍚庣Dto锛夛細", submitData);
+
+        // 4. 璋冪敤鍚庣鎺ュ彛锛屽欢闀胯秴鏃舵椂闂达紙鍚庣鏈塒LC浜や簰锛�500ms浼戠湢锛岃涓�10绉掞級
         const response = await axios.post(
           "/api/boxingDetail/SaveToolingBoardNo",
           submitData,
-          { timeout: 5000 }
+          { timeout: 10000 }
         );
         const resData = response.data;
-        const isSuccess = resData.Status === true || resData.status === true;
-        if (isSuccess) {
-          alert("鉁� 鎻愪氦鎴愬姛锛�");
-          toolingBoardNo.value = "";
+        console.log("馃摜 SaveToolingBoardNo鎺ュ彛杩斿洖锛�", resData);
+
+        // 5. 閫傞厤鍚庣杩斿洖鏍煎紡锛歴tatus涓簍rue琛ㄧず鎴愬姛锛屽惁鍒欏彇message閿欒淇℃伅
+        if (resData.status === true) {
           finishedProductCode.value = "";
           rightPartCodes.value = Array(10).fill("");
           rightTopInput.value = "";
           fillIndex.value = -1;
-          // 鉁� 鎻愪氦鎴愬姛鍚庯紝閲嶇疆鎻愪氦閿�
-          submitLock.value = false;
         } else {
-          alert("鎻愪氦澶辫触锛�" + (resData.Message || resData.message || "鏈煡閿欒"));
+          // 涓氬姟閿欒锛氱洿鎺ュ睍绀哄悗绔繑鍥炵殑message锛堝鐗╂枡閿欒銆佹棤閰嶆柟锛�
+          const errorMsg = resData.message || "鎻愪氦澶辫触锛屾湭鐭ヤ笟鍔¢敊璇�";
+          alert(`鎻愪氦澶辫触锛�${errorMsg}`);
         }
       } catch (error) {
-        alert("鎻愪氦璇锋眰澶辫触锛岃妫�鏌ョ綉缁滄垨鎺ュ彛锛�");
-        console.error("鎻愪氦鎺ュ彛澶辫触锛�", error);
-        // 鉁� 璇锋眰澶辫触涔熼噸缃攣
+        // 6. 寮傚父鎹曡幏锛氬吋瀹瑰悗绔湭鎹曡幏寮傚父锛堝PLC閫氳寮傚父銆佹暟缁勮秺鐣屻��500閿欒锛�
+        let errorMsg = "鎻愪氦璇锋眰寮傚父锛�";
+        if (error.code === "ECONNABORTED") {
+          errorMsg = "鎻愪氦璇锋眰瓒呮椂锛佸悗绔疨LC浜や簰/鏁版嵁搴撴搷浣滆�楁椂杩囬暱";
+        } else if (error.response) {
+          // 鏈嶅姟鍣�500閿欒锛氬悗绔姏鍑烘湭鎹曡幏寮傚父锛堝PLC鏈繛鎺ャ�侀浂浠朵笉鍖归厤锛�
+          errorMsg = `鏈嶅姟鍣ㄩ敊璇細${error.response.status} - ${error.response.statusText}锛岃妫�鏌LC閫氳鎴栭厤鏂归厤缃甡;
+          console.error("鉂� 鍚庣鏈嶅姟鍣ㄩ敊璇鎯咃細", error.response.data);
+        } else if (error.request) {
+          errorMsg = "缃戠粶寮傚父锛佹湭鏀跺埌鍚庣鍝嶅簲锛岃妫�鏌ユ帴鍙e湴鍧�鍜岀綉缁�";
+        } else {
+          errorMsg = `璇锋眰閿欒锛�${error.message}`;
+        }
+        alert(errorMsg);
+        console.error("鉂� 鎻愪氦鎺ュ彛寮傚父璇︽儏锛�", error);
+      } finally {
+        // 7. 閲婃斁鎻愪氦閿侊細鏃犺鎴愬姛/澶辫触閮借閲婃斁
         submitLock.value = false;
       }
     };
 
-    // 鉁� 鉁� 鉁� 鏍稿績鍗囩骇锛氳嚜鍔ㄦ彁浜ゅ垽鏂�昏緫 - 鏂板鏃犲嬀閫夋椂鎴愬搧缂栧彿濉厖鍗虫彁浜�
+    // 鏍稿績淇敼锛氳嚜鍔ㄦ彁浜ら�昏緫鍚屾澧炲姞鎴愬搧缂栧彿蹇呭~鏍¢獙锛堟棤鎴愬搧缂栧彿涓嶈Е鍙戣嚜鍔ㄦ彁浜わ級
     const checkAutoSubmit = () => {
-      // 闃叉姈锛氶槻姝㈢煭鏃堕棿鍐呭娆¤Е鍙戞彁浜�
       if (autoSubmitDebounceTimer) clearTimeout(autoSubmitDebounceTimer);
       autoSubmitDebounceTimer = setTimeout(() => {
-        const needCheckNum = checkedCount.value; // 宸︿晶鍕鹃�夌殑鏁伴噺
-        const filledNum = filledPartCount.value; // 鍙充晶濉厖鐨勯浂浠舵暟閲�
-        const hasBoardNo = toolingBoardNo.value.trim() !== ""; // 宸ヨ鏉挎湁鍊�
-        const hasProductCode = finishedProductCode.value.trim() !== ""; // 鎴愬搧鏈夊��
+        const needCheckNum = checkedCount.value; // 宸︿晶鍕鹃�夐浂浠舵暟
+        const filledNum = filledPartCount.value; // 鍙充晶鏈夋晥濉厖闆朵欢鏁�
+        const productCode = finishedProductCode.value.trim(); // 鎴愬搧缂栧彿锛堝幓绌烘牸锛�
+        const hasProductCode = !!productCode; // 鎴愬搧缂栧彿鏄惁鏈夋晥銆愪繚鐣欏師閫昏緫锛屽疄闄呮槸蹇呭~鏍¢獙銆�
 
-        console.log(`鉁� 鑷姩鎻愪氦鏍¢獙锛氬乏渚у嬀閫�${needCheckNum}涓紝鍙充晶濉厖${filledNum}涓猔);
+        console.log(
+          `鉁� 鑷姩鎻愪氦鏍¢獙锛氬嬀閫�${needCheckNum}涓� | 濉厖${filledNum}涓� | 鎴愬搧宸插~${hasProductCode}`
+        );
 
-        // 鍒嗘敮1锛氬乏渚ф湁鍕鹃�� 鈫� 鍘熸湁閫昏緫锛氶浂浠跺~鍏呮暟鈮ュ嬀閫夋暟 鎵嶆彁浜�
-        if (needCheckNum > 0) {
-          if (hasBoardNo && hasProductCode && filledNum >= needCheckNum) {
-            console.log("鉁� 婊¤冻鍕鹃�夋暟閲忔潯浠讹紝鎵ц鑷姩鎻愪氦锛�");
-            saveToolingBoardNo();
+        // 鍓嶇疆鎬绘牎楠岋細鎴愬搧缂栧彿鏈~鍐欙紝鐩存帴涓嶈Е鍙戜换浣曡嚜鍔ㄦ彁浜ゃ�愭牳蹇冨己鍖栥��
+        if (!hasProductCode) {
+          console.log("鈿狅笍 鎴愬搧缂栧彿鏈~鍐欙紝璺宠繃鑷姩鎻愪氦");
+          autoSubmitDebounceTimer = null;
+          return;
+        }
+
+        // 鍦烘櫙1锛氬乏渚ф棤鍕鹃�� 鈫� 浠呮垚鍝佺紪鍙锋湁鏁堝嵆鎻愪氦锛堝凡婊¤冻hasProductCode锛�
+        if (needCheckNum === 0) {
+          if (!submitLock.value) {
+            console.log("鉁� 鏃犻浂浠跺嬀閫夛紝鎴愬搧宸插~锛屾墽琛岃嚜鍔ㄦ彁浜わ紒");
+            saveData();
           }
         }
-        // 鍒嗘敮2锛氬乏渚ф棤鍕鹃�� 鈫� 鏂板閫昏緫锛氬伐瑁呮澘+鎴愬搧閮芥湁鍊� 灏辨彁浜� (鍔犻攣闃查噸澶�)
+        // 鍦烘櫙2锛氬乏渚ф湁鍕鹃�� 鈫� 鎴愬搧鏈夋晥 + 濉厖鏁�=鍕鹃�夋暟 鎵嶆彁浜わ紙宸叉弧瓒砲asProductCode锛�
         else {
-          if (hasBoardNo && hasProductCode && !submitLock.value) {
-            console.log("鉁� 宸︿晶鏃犲嬀閫夛紝鎴愬搧缂栧彿濉厖瀹屾垚锛屾墽琛岃嚜鍔ㄦ彁浜わ紒");
-            submitLock.value = true; // 鍔犻攣闃叉閲嶅鎻愪氦
-            saveToolingBoardNo();
+          if (filledNum === needCheckNum && !submitLock.value) {
+            console.log("鉁� 闆朵欢鏁伴噺鍖归厤锛屾垚鍝佸凡濉紝鎵ц鑷姩鎻愪氦锛�");
+            saveData();
           }
         }
         autoSubmitDebounceTimer = null;
-      }, 300);
+      }, 300); // 300ms闃叉姈锛岄伩鍏嶈緭鍏ラ绻佽Е鍙�
     };
 
-    // 鉁� 鉁� 鉁� 鏍稿績鏂板4锛氱洃鍚叧閿暟鎹彉鍖栵紝瑙﹀彂鑷姩鎻愪氦鏍¢獙
-    watch(
-      [checkedCount, filledPartCount, toolingBoardNo, finishedProductCode],
-      () => {
-        checkAutoSubmit();
-      },
-      { deep: true, immediate: false }
-    );
+    // 鐩戝惉鑷姩鎻愪氦鐩稿叧鏁版嵁鍙樺寲锛岃Е鍙戞牎楠�
+    watch([checkedCount, filledPartCount, finishedProductCode], () => checkAutoSubmit(), {
+      deep: true,
+      immediate: false,
+    });
 
-    // 鑷姩妫�娴嬪~鍏呯储寮曢�昏緫
+    // 鑷姩妫�娴嬪~鍏呯储寮曪紙鎴愬搧濉畬鍚庯紝鎸囧悜绗竴涓┖闆朵欢妗嗭級
     const detectFillIndex = () => {
-      if (!toolingBoardNo.value.trim() || !finishedProductCode.value.trim()) {
+      if (!finishedProductCode.value.trim()) {
         fillIndex.value = -1;
         return;
       }
@@ -568,49 +414,40 @@
       fillIndex.value = 10;
     };
 
-    watch(
-      [toolingBoardNo, finishedProductCode, () => [...rightPartCodes.value]],
-      detectFillIndex,
-      {
-        immediate: true,
-        deep: true,
-      }
-    );
+    // 鐩戝惉鎴愬搧/闆朵欢杈撳叆锛屾洿鏂板~鍏呯储寮�
+    watch([finishedProductCode, () => [...rightPartCodes.value]], detectFillIndex, {
+      immediate: true,
+      deep: true,
+    });
 
-    // 椤甸潰鎸傝浇/鍗歌浇鐢熷懡鍛ㄦ湡
+    // 鐢熷懡鍛ㄦ湡锛氭寕杞芥椂鍔犺浇鍒濆鏁版嵁+鍚姩杞
     onMounted(async () => {
       await fetchLeftInitialData();
       startPolling();
       detectFillIndex();
     });
 
+    // 鐢熷懡鍛ㄦ湡锛氬嵏杞芥椂娓呴櫎鎵�鏈夊畾鏃跺櫒/闃叉姈锛岄槻姝㈠唴瀛樻硠婕�
     onUnmounted(() => {
       stopPolling();
-      if (checkDebounceTimer) clearTimeout(checkDebounceTimer);
-      if (destroyDelayTimer) clearTimeout(destroyDelayTimer);
-      if (boardCodeDebounceTimer) clearTimeout(boardCodeDebounceTimer);
-      if (autoSubmitDebounceTimer) clearTimeout(autoSubmitDebounceTimer);
+      [checkDebounceTimer, destroyDelayTimer, autoSubmitDebounceTimer].forEach(
+        (t) => t && clearTimeout(t)
+      );
     });
 
+    // 鏆撮湶妯℃澘鎵�闇�灞炴��/鏂规硶
     return {
       finishedProduct,
-      finishedProductId,
       rightTopInput,
       leftPartCodes,
       rightPartCodes,
       leftPartChecked,
-      leftPartIds,
-      toolingBoardNo,
-      isPLCStarted,
-      isPLCPaused,
       signalStates,
       signalLabels,
       finishedProductCode,
-      handleToggle,
-      handlePauseToggle,
+      checkLoading,
       handlePartCheck,
-      clearToolingBoardNo,
-      saveToolingBoardNo,
+      saveData,
       clearRightPart,
       clearFinishedProductCode,
     };
@@ -619,12 +456,12 @@
 </script>
 
 <style scoped>
-/* 鍩虹鏍峰紡閲嶇疆涓庡叏灞�鏍峰紡 */
+/* 鍩虹鏍峰紡閲嶇疆 */
 * {
   margin: 0;
   padding: 0;
   box-sizing: border-box;
-  font-family: "Microsoft Yahei", "PingFang SC", "Inter", sans-serif;
+  font-family: "Microsoft Yahei", "PingFang SC", sans-serif;
   scrollbar-width: none;
   -ms-overflow-style: none;
 }
@@ -639,18 +476,17 @@
   font-size: 14px;
 }
 
-/* 瀹瑰櫒鏍峰紡 - 鏀惧ぇ 闂磋窛鍔犲 */
+/* 涓诲鍣� */
 .container {
   display: flex;
   width: 100%;
   height: 100vh;
-  margin: 0;
   gap: 15px;
   padding: 15px;
   overflow: hidden;
 }
 
-/* 闈㈡澘閫氱敤鏍峰紡 - 缁熶竴鍐呰竟璺� 纭繚宸﹀彸瀵归綈 */
+/* 宸﹀彸鍖哄煙閫氱敤鏍峰紡 */
 .left-area,
 .right-area {
   flex: 1;
@@ -666,36 +502,26 @@
   transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
 }
 
-/* 鎸夐挳+淇″彿 妯悜鎺掑垪瀹瑰櫒 - 鏍稿績甯冨眬 */
-.btn-signal-group {
+/* 宸︿晶椤堕儴-淇″彿鐏尯鍩� */
+.left-top {
+  background: #f8fafc;
+  padding: 20px 15px;
+  border-radius: 12px;
+  flex-shrink: 0;
   display: flex;
   align-items: center;
-  gap: 20px;
-  width: 100%;
-}
-.btn-group {
-  display: flex;
-  flex-direction: column;
-  gap: 10px;
-  flex-shrink: 0;
+  justify-content: center;
 }
 .signal-status {
   display: flex;
-  justify-content: flex-start;
+  justify-content: center;
   align-items: center;
-  gap: 18px;
-  flex-shrink: 0;
-  padding: 0;
-}
-
-.left-top {
-  background: #f8fafc;
-  padding: 15px;
-  border-radius: 12px;
+  gap: 25px;
   flex-shrink: 0;
   width: 100%;
 }
 
+/* 涓婁笅鍖哄煙閫氱敤 */
 .left-bottom,
 .right-bottom {
   display: flex;
@@ -704,7 +530,6 @@
   flex: 1;
   overflow: hidden !important;
 }
-
 .right-top {
   padding: 15px;
   background: #f8fafc;
@@ -712,7 +537,7 @@
   flex-shrink: 0;
 }
 
-/* 琛ㄥ崟琛屾牱寮� - 缁熶竴楂樺害鍜岄棿璺� 纭繚宸﹀彸瀵归綈 */
+/* 琛ㄥ崟琛岄�氱敤鏍峰紡 */
 .form-row {
   display: flex;
   align-items: center;
@@ -726,31 +551,46 @@
   flex-shrink: 0;
   width: 100%;
 }
-
+.input-submit-row {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  flex-wrap: nowrap;
+  padding: 6px 10px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  height: 48px;
+  line-height: 48px;
+  flex-shrink: 0;
+  width: 100%;
+}
 .form-row:hover {
   background: #f8fafc;
 }
 
-.finished-product-row {
+/* 鎴愬搧缂栧彿琛屾牱寮� */
+.right-bottom .finished-product-row {
+  margin-top: 16px;
+  background: #eff6ff;
+  border-left: 4px solid #3b82f6;
+  padding-top: 2px;
+  padding-bottom: 2px;
+}
+.left-bottom .finished-product-row {
   background: #eff6ff;
   border-left: 4px solid #3b82f6;
 }
 
-.tooling-board-row {
-  background: #f0fdf4;
-  border-left: 4px solid #22c55e;
-}
-
+/* 闆朵欢椤规牱寮� */
 .part-item {
   border-bottom: 1px solid #f1f5f9;
   margin-bottom: 3px;
 }
-
 .part-item:last-child {
   border-bottom: none;
 }
 
-/* 鏍囩鏍峰紡 - 缁熶竴瀹藉害 纭繚宸﹀彸瀵归綈 */
+/* 鏍囩鏍峰紡 */
 .label {
   width: 90px;
   text-align: right;
@@ -760,16 +600,7 @@
   flex-shrink: 0;
 }
 
-.short-label {
-  width: 110px;
-  text-align: right;
-  color: #334155;
-  font-size: 15px;
-  font-weight: 600;
-  flex-shrink: 0;
-}
-
-/* 杈撳叆妗嗘牱寮� - 缁熶竴灏哄 纭繚宸﹀彸瀵归綈 */
+/* 杈撳叆妗嗘牱寮� */
 .input-box {
   flex: 1;
   min-width: 100px;
@@ -782,29 +613,21 @@
   transition: all 0.2s ease;
   background-color: #ffffff;
 }
-
-.short-input {
-  width: 150px !important;
-  flex: none !important;
-}
-
 .input-box:focus {
   border-color: #3b82f6;
   box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
 }
-
 .input-box:disabled {
   background-color: #f1f5f9;
   color: #64748b;
   cursor: not-allowed;
 }
-
 .input-box::placeholder {
   color: #94a3b8;
   font-size: 14px;
 }
 
-/* 鎸夐挳鏍峰紡 - 鍥哄畾瀹藉害 涓嶅彉 */
+/* 鎸夐挳閫氱敤鏍峰紡 */
 .btn {
   width: 120px;
   height: 42px;
@@ -823,14 +646,23 @@
   position: relative;
   overflow: hidden;
 }
-
+.submit-input-btn {
+  width: 110px !important;
+  height: 42px !important;
+  flex: none !important;
+  padding: 0 15px !important;
+  font-size: 15px !important;
+}
+.submit-input-btn .icon {
+  width: 20px !important;
+  height: 20px !important;
+}
 .btn:disabled {
   opacity: 0.6;
   cursor: not-allowed;
   transform: none !important;
   box-shadow: none !important;
 }
-
 .btn::after {
   content: "";
   position: absolute;
@@ -841,12 +673,11 @@
   background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
   transition: all 0.5s ease;
 }
-
 .btn:hover::after {
   left: 100%;
 }
 
-/* 鍥炬爣鏍峰紡 - 鍥炬爣鏀惧ぇ */
+/* 鍥炬爣鏍峰紡 */
 .icon {
   display: inline-block;
   width: 18px;
@@ -855,68 +686,14 @@
   background-repeat: no-repeat;
   background-position: center;
 }
-
-.icon-start {
-  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E");
-}
-
-.icon-stop {
-  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M6 6h12v12H6z'/%3E%3C/svg%3E");
-}
-
-.icon-pause {
-  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M6 19h4V5H6v14zm8-14v14h4V5h-4z'/%3E%3C/svg%3E");
-}
-
-.icon-resume {
-  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M11 5L6 9H2v6h4l5 4V5zm7 0v14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2z'/%3E%3C/svg%3E");
-}
-
 .icon-clear {
   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E");
 }
-
 .icon-submit {
   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M2.01 21L15 13.4 23 21V5H2.01V21zM17 15l-5-5-5 5V7h10v8z'/%3E%3C/svg%3E");
 }
 
-/* 鎸夐挳绫诲瀷鏍峰紡 - 涓嶅彉 */
-.start-btn {
-  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
-  color: #fff;
-}
-.start-btn:hover:not(:disabled) {
-  transform: translateY(-1px);
-  box-shadow: 0 4px 8px rgba(16, 185, 129, 0.2);
-}
-
-.stop-btn {
-  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
-  color: #fff;
-}
-.stop-btn:hover:not(:disabled) {
-  transform: translateY(-1px);
-  box-shadow: 0 4px 8px rgba(239, 68, 68, 0.2);
-}
-
-.pause-btn {
-  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
-  color: #fff;
-}
-.pause-btn:hover:not(:disabled) {
-  transform: translateY(-1px);
-  box-shadow: 0 4px 8px rgba(245, 158, 11, 0.2);
-}
-
-.resume-btn {
-  background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
-  color: #fff;
-}
-.resume-btn:hover:not(:disabled) {
-  transform: translateY(-1px);
-  box-shadow: 0 4px 8px rgba(139, 92, 246, 0.2);
-}
-
+/* 鎸夐挳涓婚鏍峰紡 */
 .clear-btn {
   background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
   color: #fff;
@@ -926,7 +703,6 @@
   transform: translateY(-1px);
   box-shadow: 0 4px 8px rgba(239, 68, 68, 0.15);
 }
-
 .save-btn {
   background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
   color: #fff;
@@ -937,7 +713,7 @@
   box-shadow: 0 4px 8px rgba(59, 130, 246, 0.15);
 }
 
-/* 淇″彿鐏牱寮� 閱掔洰鏀惧ぇ */
+/* 淇″彿鐏牱寮� */
 .signal-item {
   display: flex;
   flex-direction: column;
@@ -949,9 +725,6 @@
   font-size: 14px;
   color: #334155;
   white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  width: 100%;
   text-align: center;
   font-weight: 600;
 }
@@ -994,7 +767,7 @@
   }
 }
 
-/* 鑷畾涔夊閫夋鏍峰紡 - 鏀惧ぇ 鐐瑰嚮鍖哄煙鏇村ぇ */
+/* 鑷畾涔夊閫夋鏍峰紡 */
 .checkbox-container {
   display: flex;
   align-items: center;
@@ -1006,6 +779,10 @@
 }
 .part-checkbox {
   display: none;
+}
+.checkbox-container:has(.part-checkbox:disabled) {
+  opacity: 0.6;
+  cursor: not-allowed;
 }
 .checkmark {
   width: 22px;
@@ -1052,25 +829,21 @@
     width: 100%;
     flex: none;
   }
-  .btn-signal-group {
-    flex-direction: column;
-    align-items: flex-start;
-  }
   .signal-status {
-    width: 100%;
-    justify-content: flex-start;
+    flex-wrap: wrap;
+    justify-content: center;
   }
 }
 
 @media (max-width: 768px) {
-  .form-row {
+  .form-row,
+  .input-submit-row {
     flex-direction: column;
     align-items: flex-start;
     height: auto;
     line-height: normal;
   }
-  .label,
-  .short-label {
+  .label {
     width: 100%;
     text-align: left;
     margin-bottom: 6px;
@@ -1078,17 +851,13 @@
   .input-box {
     width: 100%;
   }
-  .short-input {
+  .btn,
+  .submit-input-btn {
     width: 100% !important;
-  }
-  .btn {
-    width: 100%;
     margin-top: 6px;
   }
-  .btn-group {
-    flex-direction: column;
-    gap: 10px;
-    width: 100%;
+  .right-bottom .finished-product-row {
+    margin-top: 0 !important;
   }
 }
 </style>

--
Gitblit v1.9.3