From c65127f90e9d03d12b683661ad2911cd11486f24 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 15 一月 2026 17:55:20 +0800
Subject: [PATCH] fix: 生产订单重构90%

---
 src/views/productionManagement/processRoute/processRouteItem/index.vue  |   63 +++++++---
 src/views/productionManagement/productionOrder/index.vue                |  170 +++++++++++++++++++++++++++-
 src/views/productionManagement/productionOrder/ProcessRouteItemForm.vue |    6 
 src/api/productionManagement/productionOrder.js                         |   19 +++
 src/api/productionManagement/productProcessRoute.js                     |   54 +++++---
 5 files changed, 258 insertions(+), 54 deletions(-)

diff --git a/src/api/productionManagement/productProcessRoute.js b/src/api/productionManagement/productProcessRoute.js
index 8934b79..517172e 100644
--- a/src/api/productionManagement/productProcessRoute.js
+++ b/src/api/productionManagement/productProcessRoute.js
@@ -3,35 +3,43 @@
 
 // 鍒楄〃鏌ヨ
 export function findProductProcessRouteItemList(query) {
-    return request({
-        url: "/productProcessRoute/list",
-        method: "get",
-        params: query,
-    });
+  return request({
+    url: "/productProcessRoute/list",
+    method: "get",
+    params: query,
+  });
 }
 
 export function addOrUpdateProductProcessRouteItem(data) {
-    return request({
-        url: "/productProcessRoute/updateRouteItem",
-        method: "post",
-        data: data,
-    });
+  return request({
+    url: "/productProcessRoute/updateRouteItem",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鐢熶骇璁㈠崟涓嬶細鏂板宸ヨ壓璺嚎椤圭洰
+export function addRouteItem(data) {
+  return request({
+    url: "/productProcessRoute/addRouteItem",
+    method: "post",
+    data,
+  });
 }
 
 // 鑾峰彇鐢熶骇璁㈠崟鍏宠仈鐨勫伐鑹鸿矾绾夸富淇℃伅
 export function listMain(orderId) {
-    return request({
-        url: "/productProcessRoute/listMain",
-        method: "get",
-        params: { orderId },
-    });
+  return request({
+    url: "/productProcessRoute/listMain",
+    method: "get",
+    params: { orderId },
+  });
 }
 
-// 鍒犻櫎瀹㈡埛妗f
-export function deleteRouteItem(ids) {
-    return request({
-        url: '/productProcessRoute/deleteRouteItem',
-        method: 'delete',
-        data: ids
-    })
-}
\ No newline at end of file
+// 鍒犻櫎宸ヨ壓璺嚎椤圭洰锛堣矾鐢卞悗鎷兼帴 id锛�
+export function deleteRouteItem(id) {
+  return request({
+    url: `/productProcessRoute/deleteRouteItem/${id}`,
+    method: "delete",
+  });
+}
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index 0c37be1..241baa5 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -10,7 +10,6 @@
   });
 }
 
-
 export function productOrderListPage(query) {
   return request({
     url: "/productOrder/page",
@@ -19,6 +18,24 @@
   });
 }
 
+// 鐢熶骇璁㈠崟-鎸変骇鍝佸瀷鍙锋煡璇㈠彲鐢ㄥ伐鑹鸿矾绾垮垪琛�
+export function listProcessRoute(query) {
+  return request({
+    url: "/productOrder/listProcessRoute",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鐢熶骇璁㈠崟-缁戝畾宸ヨ壓璺嚎
+export function bindingRoute(data) {
+  return request({
+    url: "/productOrder/bindingRoute",
+    method: "post",
+    data,
+  });
+}
+
 // 鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
 export function schedulingList(query) {
   return request({
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index d4ad249..c3af4a7 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -3,7 +3,6 @@
     <PageHeader content="宸ヨ壓璺嚎椤圭洰" />
     
     <!-- 宸ヨ壓璺嚎淇℃伅灞曠ず -->
-    <div v-if="routeInfo.processRouteCode" class="section-title" style="margin-bottom: 12px;">宸ヨ壓璺嚎淇℃伅</div>
     <el-card v-if="routeInfo.processRouteCode" class="route-info-card" shadow="hover">
       <div class="route-info">
         <div class="info-item">
@@ -211,7 +210,7 @@
 import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick } from "vue";
 import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
 import { findProcessRouteItemList, addOrUpdateProcessRouteItem, sortProcessRouteItem, batchDeleteProcessRouteItem } from "@/api/productionManagement/processRouteItem.js";
-import { findProductProcessRouteItemList } from "@/api/productionManagement/productProcessRoute.js";
+import { findProductProcessRouteItemList, deleteRouteItem, addRouteItem, addOrUpdateProductProcessRouteItem } from "@/api/productionManagement/productProcessRoute.js";
 import { processList } from "@/api/productionManagement/productionProcess.js";
 import { useRoute } from 'vue-router'
 import { ElMessageBox } from 'element-plus'
@@ -353,8 +352,13 @@
     type: 'warning'
   })
     .then(() => {
-      // 璋冪敤鎵归噺鍒犻櫎鎺ュ彛锛屼紶閫抜d鏁扮粍
-      batchDeleteProcessRouteItem([row.id])
+      // 鐢熶骇璁㈠崟涓嬩娇鐢� productProcessRoute 鐨勫垹闄ゆ帴鍙o紙璺敱鍚庢嫾鎺� id锛夛紝鍏跺畠鎯呭喌浣跨敤宸ヨ壓璺嚎椤圭洰鎵归噺鍒犻櫎鎺ュ彛
+      const deletePromise =
+        pageType.value === 'order'
+          ? deleteRouteItem(row.id)
+          : batchDeleteProcessRouteItem([row.id]);
+
+      deletePromise
         .then(() => {
           proxy?.$modal?.msgSuccess('鍒犻櫎鎴愬姛');
           getList();
@@ -386,21 +390,28 @@
     if (valid) {
       submitLoading.value = true;
       
-      // 鏋勫缓鎻愪氦鏁版嵁瀵硅薄锛堝崟涓璞″舰寮忥級
-      const submitData = {
-        routeId: routeId.value,
-        processId: form.value.processId,
-        productModelId: form.value.productModelId,
-      };
-
       if (operationType.value === 'add') {
         // 鏂板锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玠ragSort瀛楁
         // dragSort = 褰撳墠鍒楄〃闀垮害 + 1锛岃〃绀烘柊澧炶褰曟帓鍦ㄦ渶鍚�
         const dragSort = tableData.value.length + 1;
-        addOrUpdateProcessRouteItem({
-          ...submitData,
-          dragSort: dragSort
-        })
+        const isOrderPage = pageType.value === 'order';
+
+        const addPromise = isOrderPage
+          ? addRouteItem({
+              productOrderId: orderId.value,
+              productRouteId: routeId.value,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+              dragSort,
+            })
+          : addOrUpdateProcessRouteItem({
+              routeId: routeId.value,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+              dragSort,
+            });
+
+        addPromise
           .then(() => {
             proxy?.$modal?.msgSuccess('鏂板鎴愬姛');
             closeDialog();
@@ -413,11 +424,23 @@
             submitLoading.value = false;
           });
       } else {
-        // 缂栬緫锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玦d
-        addOrUpdateProcessRouteItem({
-          ...submitData,
-          id: form.value.id,
-        })
+        // 缂栬緫锛氱敓浜ц鍗曚笅浣跨敤 productProcessRoute/updateRouteItem锛屽叾瀹冩儏鍐典娇鐢ㄥ伐鑹鸿矾绾块」鐩洿鏂版帴鍙�
+        const isOrderPage = pageType.value === 'order';
+        
+        const updatePromise = isOrderPage
+          ? addOrUpdateProductProcessRouteItem({
+              id: form.value.id,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+            })
+          : addOrUpdateProcessRouteItem({
+              routeId: routeId.value,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+              id: form.value.id,
+            });
+
+        updatePromise
           .then(() => {
             proxy?.$modal?.msgSuccess('淇敼鎴愬姛');
             closeDialog();
diff --git a/src/views/productionManagement/productionOrder/ProcessRouteItemForm.vue b/src/views/productionManagement/productionOrder/ProcessRouteItemForm.vue
index 354f9de..d202536 100644
--- a/src/views/productionManagement/productionOrder/ProcessRouteItemForm.vue
+++ b/src/views/productionManagement/productionOrder/ProcessRouteItemForm.vue
@@ -197,7 +197,7 @@
             const idx = routeItems.value.findIndex(item => item.id === row.id);
             console.log(idx, "idx");
             if (row.id) {
-              deleteRouteItemByIds({ id: row.id }, idx);
+              deleteRouteItemByIds(row.id, idx);
             } else {
               removeItem(dragSortx);
             }
@@ -224,8 +224,8 @@
     }
   };
 
-  const deleteRouteItemByIds = (ids, index) => {
-    deleteRouteItem(ids).then(res => {
+  const deleteRouteItemByIds = (id, index) => {
+    deleteRouteItem(id).then(res => {
       routeItems.value.splice(index, 1);
       updateDragSort();
       nextTick(() => initSortable());
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index d38bfcd..f6a5d08 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -8,7 +8,7 @@
                     placeholder="璇疯緭鍏�"
                     clearable
                     prefix-icon="Search"
-                    style="width: 200px;"
+                    style="width: 160px;"
                     @change="handleQuery" />
         </el-form-item>
         <el-form-item label="鍚堝悓鍙�:">
@@ -16,7 +16,7 @@
                     placeholder="璇疯緭鍏�"
                     clearable
                     prefix-icon="Search"
-                    style="width: 200px;"
+                    style="width: 160px;"
                     @change="handleQuery" />
         </el-form-item>
         <el-form-item label="浜у搧鍚嶇О:">
@@ -24,7 +24,7 @@
                     placeholder="璇疯緭鍏�"
                     clearable
                     prefix-icon="Search"
-                    style="width: 200px;"
+                    style="width: 160px;"
                     @change="handleQuery" />
         </el-form-item>
         <el-form-item label="瑙勬牸:">
@@ -32,7 +32,7 @@
                     placeholder="璇疯緭鍏�"
                     clearable
                     prefix-icon="Search"
-                    style="width: 200px;"
+                    style="width: 160px;"
                     @change="handleQuery" />
         </el-form-item>
         <el-form-item>
@@ -50,12 +50,45 @@
                 :tableData="tableData"
                 :page="page"
                 :tableLoading="tableLoading"
-                @pagination="pagination"></PIMTable>
+                @pagination="pagination">
+        <template #completionStatus="{ row }">
+          <el-progress
+            :percentage="toProgressPercentage(row?.completionStatus)"
+            :color="progressColor(toProgressPercentage(row?.completionStatus))"
+            :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
+          />
+        </template>
+      </PIMTable>
     </div>
     <process-route-item-form v-if="isShowItemModal"
                              v-model:visible="isShowItemModal"
                              :record="record"
                              @completed="getList" />
+    <el-dialog v-model="bindRouteDialogVisible"
+               title="缁戝畾宸ヨ壓璺嚎"
+               width="500px">
+      <el-form label-width="90px">
+        <el-form-item label="宸ヨ壓璺嚎">
+          <el-select v-model="bindForm.routeId"
+                     placeholder="璇烽�夋嫨宸ヨ壓璺嚎"
+                     style="width: 100%;"
+                     :loading="bindRouteLoading">
+            <el-option v-for="item in routeOptions"
+                       :key="item.id"
+                       :label="`${item.processRouteCode || ''}`"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="bindRouteDialogVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary"
+                     :loading="bindRouteSaving"
+                     @click="handleBindRouteConfirm">纭� 璁�</el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -64,7 +97,11 @@
   import { ElMessageBox } from "element-plus";
   import dayjs from "dayjs";
   import { useRouter } from "vue-router";
-  import { productOrderListPage } from "@/api/productionManagement/productionOrder.js";
+  import {
+    productOrderListPage,
+    listProcessRoute,
+    bindingRoute,
+  } from "@/api/productionManagement/productionOrder.js";
   import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
   const { proxy } = getCurrentInstance();
   import ProcessRouteItemForm from "@/views/productionManagement/productionOrder/ProcessRouteItemForm.vue";
@@ -75,22 +112,59 @@
     {
       label: "鐢熶骇璁㈠崟鍙�",
       prop: "npsNo",
+      width: '120px',
     },
     {
       label: "閿�鍞悎鍚屽彿",
       prop: "salesContractNo",
+      width: '150px',
     },
     {
       label: "瀹㈡埛鍚嶇О",
       prop: "customerName",
+      width: '200px',
     },
     {
       label: "浜у搧鍚嶇О",
       prop: "productCategory",
+      width: '120px',
     },
     {
       label: "瑙勬牸",
       prop: "specificationModel",
+      width: '120px',
+    },
+    {
+      label: "宸ヨ壓璺嚎缂栧彿",
+      prop: "processRouteCode",
+      width: '140px',
+    },
+    {
+      label: "闇�姹傛暟閲�",
+      prop: "quantity",
+    },
+    {
+      label: "瀹屾垚鏁伴噺",
+      prop: "completeQuantity",
+    },
+    {
+      dataType: "slot",
+      label: "瀹屾垚杩涘害",
+      prop: "completionStatus",
+      slot: "completionStatus",
+      width: 180,
+    },
+    {
+      label: "寮�濮嬫棩鏈�",
+      prop: "startTime",
+      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
+      width: 120,
+    },
+    {
+      label: "缁撴潫鏃ユ湡",
+      prop: "endTime",
+      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
+      width: 120,
     },
     {
       dataType: "action",
@@ -104,6 +178,14 @@
           type: "text",
           clickFun: row => {
             showRouteItemModal(row);
+          },
+        },
+        {
+          name: "缁戝畾宸ヨ壓璺嚎",
+          type: "text",
+          showHide: row => !row.processRouteCode,
+          clickFun: row => {
+            openBindRouteDialog(row);
           },
         },
       ],
@@ -127,6 +209,77 @@
     },
   });
   const { searchForm } = toRefs(data);
+
+  const toProgressPercentage = val => {
+    const n = Number(val);
+    if (!Number.isFinite(n)) return 0;
+    if (n <= 0) return 0;
+    if (n >= 100) return 100;
+    return Math.round(n);
+  };
+
+  // 30/50/80/100 鍒嗘棰滆壊锛氱孩/姗�/钃�/缁�
+  const progressColor = percentage => {
+    const p = toProgressPercentage(percentage);
+    if (p < 30) return "#f56c6c";
+    if (p < 50) return "#e6a23c";
+    if (p < 80) return "#409eff";
+    return "#67c23a";
+  };
+
+  // 缁戝畾宸ヨ壓璺嚎寮规
+  const bindRouteDialogVisible = ref(false);
+  const bindRouteLoading = ref(false);
+  const bindRouteSaving = ref(false);
+  const routeOptions = ref([]);
+  const bindForm = reactive({
+    orderId: null,
+    routeId: null,
+  });
+
+  const openBindRouteDialog = async row => {
+    bindForm.orderId = row.id;
+    bindForm.routeId = null;
+    bindRouteDialogVisible.value = true;
+    routeOptions.value = [];
+    if (!row.productModelId) {
+      proxy.$modal.msgWarning("褰撳墠璁㈠崟缂哄皯浜у搧鍨嬪彿锛屾棤娉曟煡璇㈠伐鑹鸿矾绾�");
+      bindRouteDialogVisible.value = false;
+      return;
+    }
+    bindRouteLoading.value = true;
+    try {
+      const res = await listProcessRoute({ productModelId: row.productModelId });
+      routeOptions.value = res.data || [];
+    } catch (e) {
+      console.error("鑾峰彇宸ヨ壓璺嚎鍒楄〃澶辫触锛�", e);
+      proxy.$modal.msgError("鑾峰彇宸ヨ壓璺嚎鍒楄〃澶辫触");
+    } finally {
+      bindRouteLoading.value = false;
+    }
+  };
+
+  const handleBindRouteConfirm = async () => {
+    if (!bindForm.routeId) {
+      proxy.$modal.msgWarning("璇烽�夋嫨宸ヨ壓璺嚎");
+      return;
+    }
+    bindRouteSaving.value = true;
+    try {
+      await bindingRoute({
+        id: bindForm.orderId,
+        routeId: bindForm.routeId,
+      });
+      proxy.$modal.msgSuccess("缁戝畾鎴愬姛");
+      bindRouteDialogVisible.value = false;
+      getList();
+    } catch (e) {
+      console.error("缁戝畾宸ヨ壓璺嚎澶辫触锛�", e);
+      proxy.$modal.msgError("缁戝畾宸ヨ壓璺嚎澶辫触");
+    } finally {
+      bindRouteSaving.value = false;
+    }
+  };
 
   // 鏌ヨ鍒楄〃
   /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -217,4 +370,7 @@
   });
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.search_form{
+  align-items: start;
+}</style>

--
Gitblit v1.9.3