From f12d684876ffbe90fa95c3113b1e6c4308ae4615 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期一, 20 四月 2026 16:55:33 +0800
Subject: [PATCH] 参数和工序部分

---
 src/views/productionManagement/productionProcess/index.vue             | 1277 ++++++++++--
 /dev/null                                                              |  121 -
 src/api/productionManagement/processRouteItem.js                       |   31 
 src/api/productionManagement/productStructure.js                       |   28 
 src/api/productionManagement/productionProcess.js                      |   64 
 src/views/productionManagement/processRoute/processRouteItem/index.vue | 2031 +++++++++++++-------
 src/api/basicData/parameterMaintenance.js                              |   81 
 src/components/ProcessParamListDialog.vue                              |  656 ++++++
 src/views/basicData/parameterMaintenance/index.vue                     |  790 +++++++
 src/components/PIMTable/PIMTable.vue                                   |  854 ++++----
 src/api/productionManagement/productProcessRoute.js                    |   31 
 11 files changed, 4,416 insertions(+), 1,548 deletions(-)

diff --git a/src/api/basicData/parameterMaintenance.js b/src/api/basicData/parameterMaintenance.js
new file mode 100644
index 0000000..86d889e
--- /dev/null
+++ b/src/api/basicData/parameterMaintenance.js
@@ -0,0 +1,81 @@
+// 鍙傛暟缁存姢椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鏌ヨ鍙傛暟鍒楄〃
+export function parameterListPage(query) {
+  return request({
+    url: "/basic/parameter/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板鍙傛暟
+export function addParameter(data) {
+  return request({
+    url: "/basic/parameter/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 缂栬緫鍙傛暟
+export function updateParameter(data) {
+  return request({
+    url: "/basic/parameter/update",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鍒犻櫎鍙傛暟
+export function delParameter(ids) {
+  return request({
+    url: "/basic/parameter/del",
+    method: "delete",
+    data: Array.isArray(ids) ? ids : [ids],
+  });
+}
+
+// 鑾峰彇浜у搧绫诲瀷鍒楄〃
+export function getProductTypes() {
+  return request({
+    url: "/basic/product/typeList",
+    method: "get",
+  });
+}
+
+// 鏂板鍩虹鍙傛暟
+export function addBaseParam(data) {
+  return request({
+    url: "/technologyParam/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 缂栬緫鍩虹鍙傛暟
+export function editBaseParam(data) {
+  return request({
+    url: "/technologyParam/edit",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鏌ヨ鍩虹鍙傛暟鍒楄〃
+export function getBaseParamList(query) {
+  return request({
+    url: "/technologyParam/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍒犻櫎鍩虹鍙傛暟
+export function removeBaseParam(ids) {
+  return request({
+    url: `/technologyParam/remove/` + ids,
+    method: "delete",
+  });
+}
diff --git a/src/api/productionManagement/processRouteItem.js b/src/api/productionManagement/processRouteItem.js
index 9e81406..7b66f8f 100644
--- a/src/api/productionManagement/processRouteItem.js
+++ b/src/api/productionManagement/processRouteItem.js
@@ -36,3 +36,34 @@
     method: "delete",
   });
 }
+// 鑾峰彇宸ュ簭鍙傛暟鍒楄〃
+export function getProcessParamList(query) {
+  return request({
+    url: `/ProcessRouteItemParam/pageList`,
+    method: "get",
+    params: query,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟鏂板
+export function addProcessRouteItemParam(data) {
+  return request({
+    url: "/ProcessRouteItemParam/save",
+    method: "post",
+    data: data,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟淇敼
+export function editProcessRouteItemParam(data) {
+  return request({
+    url: "/ProcessRouteItemParam/edit",
+    method: "put",
+    data: data,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟鍒犻櫎
+export function delProcessRouteItemParam(id) {
+  return request({
+    url: `/ProcessRouteItemParam/remove/${id}`,
+    method: "delete",
+  });
+}
diff --git a/src/api/productionManagement/productProcessRoute.js b/src/api/productionManagement/productProcessRoute.js
index e8d5da5..9d13c61 100644
--- a/src/api/productionManagement/productProcessRoute.js
+++ b/src/api/productionManagement/productProcessRoute.js
@@ -52,3 +52,34 @@
     data,
   });
 }
+// 鑾峰彇宸ュ簭鍙傛暟鍒楄〃-鐢熶骇璁㈠崟
+export function findProcessParamListOrder(query) {
+  return request({
+    url: `/productionOrderRouteItemParam/list`,
+    method: "get",
+    params: query,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟鏂板-鐢熶骇璁㈠崟
+export function addProcessRouteItemParamOrder(data) {
+  return request({
+    url: "/productionOrderRouteItemParam/add",
+    method: "post",
+    data: data,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟淇敼-鐢熶骇璁㈠崟
+export function editProcessRouteItemParamOrder(data) {
+  return request({
+    url: "/productionOrderRouteItemParam/update",
+    method: "put",
+    data: data,
+  });
+}
+// 宸ヨ壓璺嚎鍙傛暟鍒犻櫎-鐢熶骇璁㈠崟
+export function delProcessRouteItemParamOrder(id) {
+  return request({
+    url: `/productionOrderRouteItemParam/delete/${id}`,
+    method: "delete",
+  });
+}
diff --git a/src/api/productionManagement/productStructure.js b/src/api/productionManagement/productStructure.js
index e69e14a..5062e04 100644
--- a/src/api/productionManagement/productStructure.js
+++ b/src/api/productionManagement/productStructure.js
@@ -8,11 +8,33 @@
     method: "get",
   });
 }
-
 export function add(data) {
   return request({
-    url: "/productStructure",
+    url: "/productStructure/" + data.bomId,
     method: "post",
-    data: data,
+    data: data.children,
+  });
+}
+
+// export function add(data) {
+//   return request({
+//     url: "/productStructure",
+//     method: "post",
+//     data: data,
+//   });
+// }
+// 鍒嗛〉鏌ヨ-浜у搧璁㈠崟
+export function queryList2(id) {
+  return request({
+    url: "/productionOrderStructure/getBomStructs/" + id,
+    method: "get",
+  });
+}
+
+export function add2(data) {
+  return request({
+    url: "/productionOrderStructure/addOrUpdateBomStructs/" + data.orderId,
+    method: "put",
+    data: data.children,
   });
 }
diff --git a/src/api/productionManagement/productionProcess.js b/src/api/productionManagement/productionProcess.js
index d3a453c..50f756e 100644
--- a/src/api/productionManagement/productionProcess.js
+++ b/src/api/productionManagement/productionProcess.js
@@ -12,7 +12,7 @@
 
 export function processList(query) {
   return request({
-    url: "/productProcess/list",
+    url: "/technologyOperation/listPage",
     method: "get",
     params: query,
   });
@@ -20,7 +20,7 @@
 
 export function add(data) {
   return request({
-    url: "/productProcess",
+    url: "/technologyOperation/",
     method: "post",
     data: data,
   });
@@ -28,26 +28,27 @@
 
 export function del(data) {
   return request({
-    url: '/productProcess/batchDelete',
-    method: 'delete',
+    url: "/technologyOperation/batchDelete",
+    method: "delete",
     data: data,
-  })
+  });
 }
 
 export function update(data) {
   return request({
-    url: '/productProcess/update',
-    method: 'put',
+    url: "/technologyOperation/update",
+    method: "put",
     data: data,
-  })
+  });
 }
 
 // 宸ュ簭鏌ヨ
-export function list() {
-    return request({
-        url: "/productProcess/list",
-        method: "get",
-    });
+export function list(query) {
+  return request({
+    url: "/technologyOperation/listPage",
+    method: "get",
+    params: query,
+  });
 }
 
 // 瀵煎叆鏁版嵁
@@ -66,4 +67,39 @@
     method: "post",
     responseType: "blob",
   });
-}
\ No newline at end of file
+}
+
+// 鑾峰彇宸ュ簭鍙傛暟鍒楄〃
+export function getProcessParamList(processId, params) {
+  return request({
+    url: `/productProcessParam/list/${processId}`,
+    method: "get",
+    params,
+  });
+}
+
+// 娣诲姞宸ュ簭鍙傛暟
+export function addProcessParam(data) {
+  return request({
+    url: "/productProcessParam/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 缂栬緫宸ュ簭鍙傛暟
+export function editProcessParam(data) {
+  return request({
+    url: "/productProcessParam/edit",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鍒犻櫎宸ュ簭鍙傛暟
+export function deleteProcessParam(id) {
+  return request({
+    url: `/productProcessParam/${id}`,
+    method: "delete",
+  });
+}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 2b65817..61df179 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -1,83 +1,75 @@
 <template>
-  <el-table
-    ref="multipleTable"
-    v-loading="tableLoading"
-    :border="border"
-    :data="tableData"
-    :header-cell-style="mergedHeaderCellStyle"
-    :height="height"
-    :highlight-current-row="highlightCurrentRow"
-    :row-class-name="rowClassName"
-    :row-style="rowStyle"
-    :row-key="rowKey"
-    :style="tableStyle"
-    tooltip-effect="dark"
-    :expand-row-keys="expandRowKeys"
-    :show-summary="isShowSummary"
-    :summary-method="summaryMethod"
-    @row-click="rowClick"
-    @current-change="currentChange"
-    @selection-change="handleSelectionChange"
-    @expand-change="expandChange"
-    class="lims-table"
-  >
-    <el-table-column
-      align="center"
-      type="selection"
-      width="55"
-      v-if="isSelection"
-    />
-    <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-
-    <el-table-column
-      v-for="(item, index) in column"
-      :key="index"
-      :column-key="item.columnKey"
-      :filter-method="item.filterHandler"
-      :filter-multiple="item.filterMultiple"
-      :filtered-value="item.filteredValue"
-      :filters="item.filters"
-      :fixed="item.fixed"
-      :label="item.label"
-      :prop="item.prop"
-      :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'"
-      :align="item.align"
-      :sortable="!!item.sortable"
-      :type="item.type"
-      :width="item.width"
-      :minWidth="item.minWidth"
-    >
+  <el-table ref="multipleTable"
+            v-loading="tableLoading"
+            :border="border"
+            :data="tableData"
+            :header-cell-style="mergedHeaderCellStyle"
+            :height="height"
+            :highlight-current-row="highlightCurrentRow"
+            :row-class-name="rowClassName"
+            :row-style="rowStyle"
+            :row-key="rowKey"
+            :style="tableStyle"
+            tooltip-effect="dark"
+            :expand-row-keys="expandRowKeys"
+            :show-summary="isShowSummary"
+            :summary-method="summaryMethod"
+            @row-click="rowClick"
+            @current-change="currentChange"
+            @selection-change="handleSelectionChange"
+            @expand-change="expandChange"
+            class="lims-table">
+    <el-table-column align="center"
+                     type="selection"
+                     width="55"
+                     v-if="isSelection" />
+    <el-table-column align="center"
+                     label="搴忓彿"
+                     type="index"
+                     width="60" />
+    <el-table-column v-for="(item, index) in column"
+                     :key="index"
+                     :column-key="item.columnKey"
+                     :filter-method="item.filterHandler"
+                     :filter-multiple="item.filterMultiple"
+                     :filtered-value="item.filteredValue"
+                     :filters="item.filters"
+                     :fixed="item.fixed"
+                     :label="item.label"
+                     :prop="item.prop"
+                     :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'"
+                     :align="item.align"
+                     :sortable="!!item.sortable"
+                     :type="item.type"
+                     :width="item.width"
+                     :minWidth="item.minWidth">
       <template #header="scope">
-        <div class="pim-table-header-cell" :class="{ 'has-extra': item.headerSlot }">
+        <div class="pim-table-header-cell"
+             :class="{ 'has-extra': item.headerSlot }">
           <div class="pim-table-header-title">
             {{ item.label }}
           </div>
-          <div v-if="item.headerSlot" class="pim-table-header-extra">
-            <slot :name="item.headerSlot" :column="scope.column" />
+          <div v-if="item.headerSlot"
+               class="pim-table-header-extra">
+            <slot :name="item.headerSlot"
+                  :column="scope.column" />
           </div>
         </div>
       </template>
-      <template
-        v-if="item.hasOwnProperty('colunmTemplate')"
-        #[item.colunmTemplate]="scope"
-      >
-        <slot
-          v-if="item.theadSlot"
-          :name="item.theadSlot"
-          :index="scope.$index"
-          :row="scope.row"
-        />
+      <template v-if="item.hasOwnProperty('colunmTemplate')"
+                #[item.colunmTemplate]="scope">
+        <slot v-if="item.theadSlot"
+              :name="item.theadSlot"
+              :index="scope.$index"
+              :row="scope.row" />
       </template>
-
       <template #default="scope">
         <!-- 鎻掓Ы -->
         <div v-if="item.dataType == 'slot'">
-          <slot
-            v-if="item.slot"
-            :index="scope.$index"
-            :name="item.slot"
-            :row="scope.row"
-          />
+          <slot v-if="item.slot"
+                :index="scope.$index"
+                :name="item.slot"
+                :row="scope.row" />
         </div>
         <!-- 杩涘害鏉� -->
         <div v-else-if="item.dataType == 'progress'">
@@ -85,128 +77,111 @@
         </div>
         <!-- 鍥剧墖 -->
         <div v-else-if="item.dataType == 'image'">
-          <img
-            :src="javaApi + '/img/' + scope.row[item.prop]"
-            alt=""
-            style="width: 40px; height: 40px; margin-top: 10px"
-          />
+          <img :src="javaApi + '/img/' + scope.row[item.prop]"
+               alt=""
+               style="width: 40px; height: 40px; margin-top: 10px" />
         </div>
-
         <!-- tag -->
         <div v-else-if="item.dataType == 'tag'">
-          <el-tag
-            v-if="
+          <el-tag v-if="
               typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
               'string'
             "
-            :title="formatters(scope.row[item.prop], item.formatData)"
-            :type="formatType(scope.row[item.prop], item.formatType)"
-          >
+                  :title="formatters(scope.row[item.prop], item.formatData)"
+                  :type="formatType(scope.row[item.prop], item.formatType)">
             {{ formatters(scope.row[item.prop], item.formatData) }}
           </el-tag>
-
-          <el-tag
-            v-for="(tag, index) in dataTypeFn(
+          <el-tag v-for="(tag, index) in dataTypeFn(
               scope.row[item.prop],
               item.formatData
             )"
-            v-else-if="
+                  v-else-if="
               typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
               'object'
             "
-            :key="index"
-            :title="formatters(scope.row[item.prop], item.formatData)"
-            :type="formatType(tag, item.formatType)"
-          >
+                  :key="index"
+                  :title="formatters(scope.row[item.prop], item.formatData)"
+                  :type="formatType(tag, item.formatType)">
             {{ item.tagGroup ? tag[item.tagGroup.label] ?? tag : tag }}
           </el-tag>
-
-          <el-tag
-            v-else
-            :title="formatters(scope.row[item.prop], item.formatData)"
-            :type="formatType(scope.row[item.prop], item.formatType)"
-          >
+          <el-tag v-else
+                  :title="formatters(scope.row[item.prop], item.formatData)"
+                  :type="formatType(scope.row[item.prop], item.formatType)">
             {{ formatters(scope.row[item.prop], item.formatData) }}
           </el-tag>
         </div>
-
         <!-- 鎸夐挳 -->
-        <div v-else-if="item.dataType == 'action'" @click.stop>
-          <template v-for="(o, key) in item.operation" :key="key">
-            <el-button
-              v-show="o.type != 'upload'"
-              v-if="o.showHide ? o.showHide(scope.row) : true"
-              :disabled="isOperationDisabled(o, scope.row)"
-              :plain="o.plain"
-              type="primary"
-              :style="{
+        <div v-else-if="item.dataType == 'action'"
+             @click.stop>
+          <template v-for="(o, key) in item.operation"
+                    :key="key">
+            <el-button v-show="o.type != 'upload'"
+                       v-if="o.showHide ? o.showHide(scope.row) : true"
+                       :disabled="isOperationDisabled(o, scope.row)"
+                       :plain="o.plain"
+                       type="primary"
+                       :style="{
                 color: getOperationColor(o, scope.row),
                 fontWeight: 'bold',
               }"
-              link
-              @click.stop="o.clickFun(scope.row)"
-              :key="key"
-            >
+                       link
+                       @click.stop="o.clickFun(scope.row)"
+                       :key="key">
               {{ o.name }}
             </el-button>
-            <el-upload
-              :action="
+            <el-upload :action="
                 javaApi +
                 o.url +
                 '?id=' +
                 (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)
               "
-              ref="uploadRef"
-              :multiple="o.multiple ? o.multiple : false"
-              :limit="1"
-              :disabled="isOperationDisabled(o, scope.row)"
-              :accept="
+                       ref="uploadRef"
+                       :multiple="o.multiple ? o.multiple : false"
+                       :limit="1"
+                       :disabled="isOperationDisabled(o, scope.row)"
+                       :accept="
                 o.accept
                   ? o.accept
                   : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
               "
-              v-if="o.type == 'upload'"
-              style="display: inline-block; width: 50px"
-              v-show="o.showHide ? o.showHide(scope.row) : true"
-              :headers="uploadHeader"
-              :before-upload="(file) => beforeUpload(file, scope.$index)"
-              :on-change="
+                       v-if="o.type == 'upload'"
+                       style="display: inline-block; width: 50px"
+                       v-show="o.showHide ? o.showHide(scope.row) : true"
+                       :headers="uploadHeader"
+                       :before-upload="(file) => beforeUpload(file, scope.$index)"
+                       :on-change="
                 (file, fileList) => handleChange(file, fileList, scope.$index)
               "
-              :on-error="
+                       :on-error="
                 (error, file, fileList) =>
                   onError(error, file, fileList, scope.$index)
               "
-              :on-success="
+                       :on-success="
                 (response, file, fileList) =>
                   handleSuccessUp(response, file, fileList, scope.$index)
               "
-              :on-exceed="onExceed"
-              :show-file-list="false"
-            >
-              <el-button
-                link
-                type="primary"
-                :disabled="isOperationDisabled(o, scope.row)"
-                :style="{
+                       :on-exceed="onExceed"
+                       :show-file-list="false">
+              <el-button link
+                         type="primary"
+                         :disabled="isOperationDisabled(o, scope.row)"
+                         :style="{
                   color: getOperationColor(o, scope.row),
-                }"
-                >{{ o.name }}</el-button
-              >
+                }">{{ o.name }}</el-button>
             </el-upload>
           </template>
         </div>
         <!-- 鍙偣鍑荤殑鏂囧瓧 -->
-        <div
-          v-else-if="item.dataType == 'link'"
-          class="cell link"
-          style="width: 100%"
-          @click="goLink(scope.row, item.linkMethod)"
-        >
+        <div v-else-if="item.dataType == 'link'"
+             class="cell link"
+             style="width: 100%"
+             @click="goLink(scope.row, item.linkMethod)">
           <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
         </div>
         <!-- 榛樿绾睍绀烘暟鎹� -->
-        <div v-else class="cell" style="width: 100%">
+        <div v-else
+             class="cell"
+             style="width: 100%">
           <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
           <span v-else>{{
             formatters(scope.row[item.prop], item.formatData)
@@ -215,326 +190,333 @@
       </template>
     </el-table-column>
   </el-table>
-  <pagination
-		v-if="isShowPagination"
-    :total="page.total"
-    :layout="page.layout"
-    :page="page.current"
-    :limit="page.size"
-    @pagination="paginationSearch"
-  />
+  <pagination v-if="isShowPagination"
+              :total="page.total"
+              :layout="page.layout"
+              :page="page.current"
+              :limit="page.size"
+              @pagination="paginationSearch" />
 </template>
 
 <script setup>
-import pagination from "./Pagination.vue";
-import { computed, ref, inject, getCurrentInstance } from "vue";
-import { ElMessage } from "element-plus";
+  import pagination from "./Pagination.vue";
+  import { computed, ref, inject, getCurrentInstance } from "vue";
+  import { ElMessage } from "element-plus";
 
-// 鑾峰彇鍏ㄥ眬鐨� uploadHeader
-const { proxy } = getCurrentInstance();
-const uploadHeader = proxy.uploadHeader;
-const javaApi = proxy.javaApi;
+  // 鑾峰彇鍏ㄥ眬鐨� uploadHeader
+  const { proxy } = getCurrentInstance();
+  const uploadHeader = proxy.uploadHeader;
+  const javaApi = proxy.javaApi;
 
-const emit = defineEmits(["pagination", "expand-change", "selection-change", "row-click"]);
+  const emit = defineEmits([
+    "pagination",
+    "expand-change",
+    "selection-change",
+    "row-click",
+  ]);
 
-// Filters
-const typeFn = (val, row) => {
-  return typeof val === "function" ? val(row) : val;
-};
+  // Filters
+  const typeFn = (val, row) => {
+    return typeof val === "function" ? val(row) : val;
+  };
 
-const formatters = (val, format) => {
-  return typeof format === "function" ? format(val) : val;
-};
+  const formatters = (val, format) => {
+    return typeof format === "function" ? format(val) : val;
+  };
 
-// Props锛堜娇鐢� defineProps 鐨勯潪 TS 褰㈠紡锛�
-const props = defineProps({
-  tableLoading: {
-    type: Boolean,
-    default: false,
-  },
-  height: {
-    type: [Number, String],
-    default: "calc(100vh - 22em)",
-  },
-  expandRowKeys: {
-    type: Array,
-    default: () => [],
-  },
-  summaryMethod: {
-    type: Function,
-    default: () => {},
-  },
-  rowClick: {
-    type: Function,
-    default: () => {},
-  },
-  currentChange: {
-    type: Function,
-    default: () => {},
-  },
-  border: {
-    type: Boolean,
-    default: true,
-  },
-  isSelection: {
-    type: Boolean,
-    default: false,
-  },
-	isShowPagination: {
-    type: Boolean,
-    default: true,
-  },
-  isShowSummary: {
-    type: Boolean,
-    default: false,
-  },
-  highlightCurrentRow: {
-    type: Boolean,
-    default: false,
-  },
-  headerCellStyle: {
-    type: Object,
-    default: () => ({}),
-  },
-  column: {
-    type: Array,
-    default: () => [],
-  },
-  rowClassName: {
-    type: Function,
-    default: () => "",
-  },
-  rowStyle: {
-    type: [Object, Function],
-    default: () => ({}),
-  },
-  tableData: {
-    type: Array,
-    default: () => [],
-  },
-  rowKey: {
-    type: String,
-    default: 'id',
-  },
-  page: {
-    type: Object,
-    default: () => ({
-      total: 0,
-      current: 0,
-      size: 10,
-      layout: "total, sizes, prev, pager, next, jumper",
-    }),
-  },
-  total: {
-    type: Number,
-    default: 0,
-  },
-  tableStyle: {
-    type: [String, Object],
-    default: () => ({ width: "100%" }),
-  },
-});
+  // Props锛堜娇鐢� defineProps 鐨勯潪 TS 褰㈠紡锛�
+  const props = defineProps({
+    tableLoading: {
+      type: Boolean,
+      default: false,
+    },
+    height: {
+      type: [Number, String],
+      default: "calc(100vh - 22em)",
+    },
+    expandRowKeys: {
+      type: Array,
+      default: () => [],
+    },
+    summaryMethod: {
+      type: Function,
+      default: () => {},
+    },
+    rowClick: {
+      type: Function,
+      default: () => {},
+    },
+    currentChange: {
+      type: Function,
+      default: () => {},
+    },
+    border: {
+      type: Boolean,
+      default: true,
+    },
+    isSelection: {
+      type: Boolean,
+      default: false,
+    },
+    isShowPagination: {
+      type: Boolean,
+      default: true,
+    },
+    isShowSummary: {
+      type: Boolean,
+      default: false,
+    },
+    highlightCurrentRow: {
+      type: Boolean,
+      default: false,
+    },
+    headerCellStyle: {
+      type: Object,
+      default: () => ({}),
+    },
+    column: {
+      type: Array,
+      default: () => [],
+    },
+    rowClassName: {
+      type: Function,
+      default: () => "",
+    },
+    rowStyle: {
+      type: [Object, Function],
+      default: () => ({}),
+    },
+    tableData: {
+      type: Array,
+      default: () => [],
+    },
+    rowKey: {
+      type: String,
+      default: "id",
+    },
+    page: {
+      type: Object,
+      default: () => ({
+        total: 0,
+        current: 0,
+        size: 10,
+        layout: "total, sizes, prev, pager, next, jumper",
+      }),
+    },
+    total: {
+      type: Number,
+      default: 0,
+    },
+    tableStyle: {
+      type: [String, Object],
+      default: () => ({ width: "100%" }),
+    },
+  });
 
-const mergedHeaderCellStyle = computed(() => ({
-  background: "var(--surface-soft)",
-  color: "var(--text-secondary)",
-  fontWeight: 600,
-  ...props.headerCellStyle,
-}));
+  const mergedHeaderCellStyle = computed(() => ({
+    background: "var(--surface-soft)",
+    color: "var(--text-secondary)",
+    fontWeight: 600,
+    ...props.headerCellStyle,
+  }));
 
-// Data
-const uploadRefs = ref([]);
-const currentFiles = ref({});
-const uploadKeys = ref({});
+  // Data
+  const uploadRefs = ref([]);
+  const currentFiles = ref({});
+  const uploadKeys = ref({});
 
-const indexMethod = (index) => {
-  return (props.page.current - 1) * props.page.size + index + 1;
-};
+  const indexMethod = index => {
+    return (props.page.current - 1) * props.page.size + index + 1;
+  };
 
-// 鐐瑰嚮 link 浜嬩欢
-const goLink = (row, linkMethod) => {
-  if (!linkMethod) {
-    return ElMessage.warning("璇烽厤缃� link 浜嬩欢");
-  }
-  const parentMethod = getParentMethod(linkMethod);
-  if (typeof parentMethod === "function") {
-    parentMethod(row);
-  } else {
-    console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`);
-  }
-};
-
-// 鑾峰彇鐖剁粍浠舵柟娉曪紙绀轰緥瀹炵幇锛�
-const getParentMethod = (methodName) => {
-  const parentMethods = inject("parentMethods", {});
-  return parentMethods[methodName];
-};
-
-const dataTypeFn = (val, format) => {
-  if (typeof format === "function") {
-    return format(val);
-  } else return val;
-};
-const validTagTypes = ["primary", "success", "info", "warning", "danger"];
-
-const formatType = (val, format) => {
-  const type = typeof format === "function" ? format(val) : undefined;
-  return validTagTypes.includes(type) ? type : undefined;
-};
-
-const isOperationDisabled = (operation, row) => {
-  if (!operation?.disabled) return false;
-  return typeof operation.disabled === "function"
-    ? !!operation.disabled(row)
-    : !!operation.disabled;
-};
-
-const parseHexToRgb = (hex) => {
-  const normalized = String(hex || "").trim().replace("#", "");
-  if (normalized.length === 3) {
-    const r = parseInt(normalized[0] + normalized[0], 16);
-    const g = parseInt(normalized[1] + normalized[1], 16);
-    const b = parseInt(normalized[2] + normalized[2], 16);
-    if ([r, g, b].some((n) => Number.isNaN(n))) return null;
-    return { r, g, b };
-  }
-  if (normalized.length === 6 || normalized.length === 8) {
-    const r = parseInt(normalized.slice(0, 2), 16);
-    const g = parseInt(normalized.slice(2, 4), 16);
-    const b = parseInt(normalized.slice(4, 6), 16);
-    if ([r, g, b].some((n) => Number.isNaN(n))) return null;
-    return { r, g, b };
-  }
-  return null;
-};
-
-const fadeColor = (color, alpha = 0.35) => {
-  const c = String(color || "").trim();
-  if (!c) return undefined;
-  if (c.startsWith("#")) {
-    const rgb = parseHexToRgb(c);
-    if (!rgb) return c;
-    return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
-  }
-  const rgbMatch = c.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*[\d.]+\s*)?\)$/i);
-  if (rgbMatch) {
-    const r = Number(rgbMatch[1]);
-    const g = Number(rgbMatch[2]);
-    const b = Number(rgbMatch[3]);
-    if ([r, g, b].some((n) => Number.isNaN(n))) return c;
-    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
-  }
-  if (c.includes("--el-color-primary")) {
-    return "var(--el-color-primary-light-5)";
-  }
-  if (c.includes("--el-color-danger")) {
-    return "var(--el-color-danger-light-5)";
-  }
-  return "var(--el-text-color-disabled)";
-};
-
-const getOperationColor = (operation, row) => {
-  const baseColor =
-    operation?.name === "鍒犻櫎" || operation?.name === "delete"
-      ? "#D93025"
-      : operation?.name === "璇︽儏"
-      ? "#67C23A"
-      : operation?.color || "var(--el-color-primary)";
-
-  if (isOperationDisabled(operation, row)) {
-    return fadeColor(baseColor, 0.35);
-  }
-  return baseColor;
-};
-
-// 鏂囦欢鍙樺寲澶勭悊
-const handleChange = (file, fileList, index) => {
-  if (fileList.length > 1) {
-    const earliestFile = fileList[0];
-    uploadRefs.value[index]?.handleRemove(earliestFile);
-  }
-  currentFiles.value[index] = file;
-};
-
-// 鏂囦欢涓婁紶鍓嶆牎楠�
-const beforeUpload = (rawFile, index) => {
-  currentFiles.value[index] = {};
-  if (rawfile.size > 1024 * 1024 * 10 * 10) {
-    ElMessage.error("涓婁紶鏂囦欢涓嶈秴杩�10M");
-    return false;
-  }
-  return true;
-};
-
-// 涓婁紶鎴愬姛
-const handleSuccessUp = (response, file, fileList, index) => {
-  if (response.code == 200) {
-    if (uploadRefs[index]) {
-      uploadRefs[index].clearFiles();
+  // 鐐瑰嚮 link 浜嬩欢
+  const goLink = (row, linkMethod) => {
+    if (!linkMethod) {
+      return ElMessage.warning("璇烽厤缃� link 浜嬩欢");
     }
-    currentFiles[index] = file;
-    ElMessage.success("涓婁紶鎴愬姛");
-    resetUploadComponent(index);
-  } else {
-    ElMessage.error(response.message);
-  }
-};
+    const parentMethod = getParentMethod(linkMethod);
+    if (typeof parentMethod === "function") {
+      parentMethod(row);
+    } else {
+      console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`);
+    }
+  };
 
-const resetUploadComponent = (index) => {
-  uploadKeys[index] = Date.now();
-};
+  // 鑾峰彇鐖剁粍浠舵柟娉曪紙绀轰緥瀹炵幇锛�
+  const getParentMethod = methodName => {
+    const parentMethods = inject("parentMethods", {});
+    return parentMethods[methodName];
+  };
 
-// 涓婁紶澶辫触
-const onError = (error, file, fileList, index) => {
-  ElMessage.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
-  if (uploadRefs.value[index]) {
-    uploadRefs.value[index].clearFiles();
-  }
-};
+  const dataTypeFn = (val, format) => {
+    if (typeof format === "function") {
+      return format(val);
+    } else return val;
+  };
+  const validTagTypes = ["primary", "success", "info", "warning", "danger"];
 
-// 鏂囦欢鏁伴噺瓒呴檺鎻愮ず
-const onExceed = () => {
-  ElMessage.warning("瓒呭嚭鏂囦欢涓暟");
-};
+  const formatType = (val, format) => {
+    const type = typeof format === "function" ? format(val) : undefined;
+    return validTagTypes.includes(type) ? type : undefined;
+  };
 
-const paginationSearch = ({ page, limit }) => {
-  emit("pagination", { page: page, limit: limit });
-};
+  const isOperationDisabled = (operation, row) => {
+    if (!operation?.disabled) return false;
+    return typeof operation.disabled === "function"
+      ? !!operation.disabled(row)
+      : !!operation.disabled;
+  };
 
-const rowClick = (row) => {
-  emit("row-click", row);
-};
+  const parseHexToRgb = hex => {
+    const normalized = String(hex || "")
+      .trim()
+      .replace("#", "");
+    if (normalized.length === 3) {
+      const r = parseInt(normalized[0] + normalized[0], 16);
+      const g = parseInt(normalized[1] + normalized[1], 16);
+      const b = parseInt(normalized[2] + normalized[2], 16);
+      if ([r, g, b].some(n => Number.isNaN(n))) return null;
+      return { r, g, b };
+    }
+    if (normalized.length === 6 || normalized.length === 8) {
+      const r = parseInt(normalized.slice(0, 2), 16);
+      const g = parseInt(normalized.slice(2, 4), 16);
+      const b = parseInt(normalized.slice(4, 6), 16);
+      if ([r, g, b].some(n => Number.isNaN(n))) return null;
+      return { r, g, b };
+    }
+    return null;
+  };
 
-const expandChange = (row, expandedRows) => {
-  emit("expand-change", row, expandedRows);
-};
+  const fadeColor = (color, alpha = 0.35) => {
+    const c = String(color || "").trim();
+    if (!c) return undefined;
+    if (c.startsWith("#")) {
+      const rgb = parseHexToRgb(c);
+      if (!rgb) return c;
+      return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
+    }
+    const rgbMatch = c.match(
+      /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*[\d.]+\s*)?\)$/i
+    );
+    if (rgbMatch) {
+      const r = Number(rgbMatch[1]);
+      const g = Number(rgbMatch[2]);
+      const b = Number(rgbMatch[3]);
+      if ([r, g, b].some(n => Number.isNaN(n))) return c;
+      return `rgba(${r}, ${g}, ${b}, ${alpha})`;
+    }
+    if (c.includes("--el-color-primary")) {
+      return "var(--el-color-primary-light-5)";
+    }
+    if (c.includes("--el-color-danger")) {
+      return "var(--el-color-danger-light-5)";
+    }
+    return "var(--el-text-color-disabled)";
+  };
 
-const handleSelectionChange = (newSelection) => {
-  emit("selection-change", newSelection);
-};
+  const getOperationColor = (operation, row) => {
+    const baseColor =
+      operation?.name === "鍒犻櫎" || operation?.name === "delete"
+        ? "#D93025"
+        : operation?.name === "璇︽儏"
+        ? "#67C23A"
+        : operation?.color || "var(--el-color-primary)";
+
+    if (isOperationDisabled(operation, row)) {
+      return fadeColor(baseColor, 0.35);
+    }
+    return baseColor;
+  };
+
+  // 鏂囦欢鍙樺寲澶勭悊
+  const handleChange = (file, fileList, index) => {
+    if (fileList.length > 1) {
+      const earliestFile = fileList[0];
+      uploadRefs.value[index]?.handleRemove(earliestFile);
+    }
+    currentFiles.value[index] = file;
+  };
+
+  // 鏂囦欢涓婁紶鍓嶆牎楠�
+  const beforeUpload = (rawFile, index) => {
+    currentFiles.value[index] = {};
+    if (rawfile.size > 1024 * 1024 * 10 * 10) {
+      ElMessage.error("涓婁紶鏂囦欢涓嶈秴杩�10M");
+      return false;
+    }
+    return true;
+  };
+
+  // 涓婁紶鎴愬姛
+  const handleSuccessUp = (response, file, fileList, index) => {
+    if (response.code == 200) {
+      if (uploadRefs[index]) {
+        uploadRefs[index].clearFiles();
+      }
+      currentFiles[index] = file;
+      ElMessage.success("涓婁紶鎴愬姛");
+      resetUploadComponent(index);
+    } else {
+      ElMessage.error(response.message);
+    }
+  };
+
+  const resetUploadComponent = index => {
+    uploadKeys[index] = Date.now();
+  };
+
+  // 涓婁紶澶辫触
+  const onError = (error, file, fileList, index) => {
+    ElMessage.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+    if (uploadRefs.value[index]) {
+      uploadRefs.value[index].clearFiles();
+    }
+  };
+
+  // 鏂囦欢鏁伴噺瓒呴檺鎻愮ず
+  const onExceed = () => {
+    ElMessage.warning("瓒呭嚭鏂囦欢涓暟");
+  };
+
+  const paginationSearch = ({ page, limit }) => {
+    emit("pagination", { page: page, limit: limit });
+  };
+
+  const rowClick = row => {
+    emit("row-click", row);
+  };
+
+  const expandChange = (row, expandedRows) => {
+    emit("expand-change", row, expandedRows);
+  };
+
+  const handleSelectionChange = newSelection => {
+    emit("selection-change", newSelection);
+  };
 </script>
 
 <style scoped lang="scss">
-.lims-table {
-  border: 1px solid var(--surface-border);
-  border-radius: 18px;
-  background: rgba(255, 255, 255, 0.9);
-}
+  .lims-table {
+    border: 1px solid var(--surface-border);
+    border-radius: 18px;
+    background: rgba(255, 255, 255, 0.9);
+  }
 
-.cell {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  padding-right: 0 !important;
-  padding-left: 0 !important;
-}
+  .cell {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    padding-right: 0 !important;
+    padding-left: 0 !important;
+  }
 
-.pim-table-header-extra :deep(.el-input),
-.pim-table-header-extra :deep(.el-select) {
-  width: 100%;
-}
+  .pim-table-header-extra :deep(.el-input),
+  .pim-table-header-extra :deep(.el-select) {
+    width: 100%;
+  }
 
-.pim-table-header-title {
-  font-weight: 600;
-}
+  .pim-table-header-title {
+    font-weight: 600;
+  }
 </style>
diff --git a/src/components/ProcessParamListDialog.vue b/src/components/ProcessParamListDialog.vue
new file mode 100644
index 0000000..c835f29
--- /dev/null
+++ b/src/components/ProcessParamListDialog.vue
@@ -0,0 +1,656 @@
+<template>
+  <el-dialog v-model="visible"
+             :title="title"
+             width="800px"
+             destroy-on-close>
+    <div class="param-list-container">
+      <div class="params-header">
+        <span>鍙傛暟鍒楄〃</span>
+        <el-button v-if="editable"
+                   type="primary"
+                   link
+                   size="small"
+                   @click="handleAddParam">
+          <el-icon>
+            <Plus />
+          </el-icon>鏂板
+        </el-button>
+      </div>
+      <div class="params-list">
+        <div v-for="param in paramList"
+             :key="param.id"
+             class="param-item">
+          <div class="param-info">
+            <span class="param-code">{{ param.paramName }}</span>
+            <span class="param-value">
+              鏍囧噯鍊硷細{{ param.standardValue || "-" }} {{ param.unit }}
+            </span>
+          </div>
+          <div class="param-actions">
+            <el-button v-if="editable"
+                       link
+                       type="primary"
+                       size="small"
+                       @click="handleEditParam(param)">
+              缂栬緫
+            </el-button>
+            <el-button v-if="editable"
+                       link
+                       type="danger"
+                       size="small"
+                       @click="handleDeleteParam(param)">
+              鍒犻櫎
+            </el-button>
+          </div>
+        </div>
+        <el-empty v-if="!paramList || paramList.length === 0"
+                  description="鏆傛棤鍙傛暟"
+                  :image-size="50" />
+      </div>
+    </div>
+    <!-- 閫夋嫨鍙傛暟瀵硅瘽妗� -->
+    <el-dialog v-model="selectParamDialogVisible"
+               title="閫夋嫨鍙傛暟"
+               width="1000px">
+      <div class="param-select-container">
+        <!-- 宸︿晶鍙傛暟鍒楄〃 -->
+        <div class="param-list-area">
+          <div class="area-title">鍙�夊弬鏁�</div>
+          <div class="search-box">
+            <el-input v-model="paramSearchKeyword"
+                      placeholder="璇疯緭鍏ュ弬鏁板悕绉版悳绱�"
+                      clearable
+                      size="small"
+                      @input="getBaseParamListData">
+              <template #prefix>
+                <el-icon>
+                  <Search />
+                </el-icon>
+              </template>
+            </el-input>
+          </div>
+          <el-table :data="filteredParamList"
+                    height="400"
+                    border
+                    highlight-current-row
+                    @current-change="handleSelectParam">
+            <el-table-column prop="paramName"
+                             label="鍙傛暟鍚嶇О" />
+            <el-table-column prop="paramType"
+                             label="鍙傛暟绫诲瀷">
+              <template #default="scope">
+                <el-tag size="small"
+                        :type="getParamTypeTag(scope.row.paramType)">{{ getParamTypeText(scope.row.paramType) }}</el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- 鍒嗛〉鎺т欢 -->
+          <div class="pagination-container"
+               style="margin-top: 10px;">
+            <el-pagination v-model:current-page="paramPage.current"
+                           v-model:page-size="paramPage.size"
+                           :page-sizes="[10, 20, 50, 100]"
+                           layout="total, sizes, prev, pager, next, jumper"
+                           :total="paramPage.total"
+                           @size-change="getBaseParamListData"
+                           @current-change="getBaseParamListData"
+                           size="small" />
+          </div>
+        </div>
+        <!-- 鍙充晶鍙傛暟璇︽儏 -->
+        <div class="param-detail-area">
+          <div class="area-title">鍙傛暟璇︽儏</div>
+          <el-form v-if="selectedParam"
+                   :model="selectedParam"
+                   label-width="100px"
+                   class="param-detail-form">
+            <el-form-item label="鍙傛暟鍚嶇О">
+              <span class="detail-text">{{ selectedParam.paramName }}</span>
+            </el-form-item>
+            <el-form-item label="鍙傛暟绫诲瀷">
+              <el-tag size="small"
+                      :type="getParamTypeTag(selectedParam.paramType)">{{ getParamTypeText(selectedParam.paramType) }}</el-tag>
+            </el-form-item>
+            <el-form-item label="鍙傛暟鏍煎紡">
+              <span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span>
+            </el-form-item>
+            <el-form-item label="鍗曚綅">
+              <span class="detail-text">{{ selectedParam.unit || '-' }}</span>
+            </el-form-item>
+            <el-form-item label="鏍囧噯鍊�"
+                          v-if="selectedParam.paramType == '1'">
+              <el-input v-model="selectedParam.standardValue"
+                        type="number"
+                        placeholder="璇疯緭鍏ラ粯璁ゅ��" />
+            </el-form-item>
+            <el-form-item label="鎺掑簭">
+              <el-input v-model="selectedParam.sort"
+                        type="number"
+                        placeholder="璇疯緭鍏ユ帓搴�" />
+            </el-form-item>
+            <el-form-item label="鏄惁蹇呭~">
+              <el-switch :active-value="true"
+                         :inactive-value="false"
+                         v-model="selectedParam.isRequired" />
+            </el-form-item>
+          </el-form>
+          <el-empty v-else
+                    description="璇蜂粠宸︿晶閫夋嫨鍙傛暟"
+                    :image-size="100" />
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="selectParamDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary"
+                   @click="handleParamSelectSubmit">纭畾</el-button>
+      </template>
+    </el-dialog>
+    <!-- 缂栬緫鍙傛暟瀵硅瘽妗� -->
+    <el-dialog v-model="editParamDialogVisible"
+               title="缂栬緫鍙傛暟"
+               width="600px">
+      <el-form :model="editParamForm"
+               :rules="editParamRules"
+               ref="editParamFormRef"
+               label-width="120px">
+        <el-form-item label="鍙傛暟鍚嶇О">
+          <span class="detail-text">{{ editParamForm.paramName }}</span>
+        </el-form-item>
+        <el-form-item label="鍙傛暟绫诲瀷">
+          <el-tag size="small"
+                  :type="getParamTypeTag(editParamForm.paramType)">
+            {{ getParamTypeText(editParamForm.paramType) }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="鍙傛暟鏍煎紡">
+          <span class="detail-text">{{ editParamForm.paramFormat || '-' }}</span>
+        </el-form-item>
+        <el-form-item label="鍗曚綅">
+          <span class="detail-text">{{ editParamForm.unit || '-' }}</span>
+        </el-form-item>
+        <el-form-item label="鏍囧噯鍊�"
+                      v-if="editParamForm.paramType == '1'"
+                      prop="standardValue">
+          <el-input v-model="editParamForm.standardValue"
+                    type="number"
+                    placeholder="璇疯緭鍏ユ爣鍑嗗��" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="editParamDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary"
+                   @click="handleEditParamSubmit">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </el-dialog>
+</template>
+
+<script setup>
+  import { ref, computed, watch } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Plus, Search } from "@element-plus/icons-vue";
+  import {
+    delProcessRouteItemParam,
+    editProcessRouteItemParam,
+    addProcessRouteItemParam,
+  } from "@/api/productionManagement/processRouteItem.js";
+  import {
+    addProcessRouteItemParamOrder,
+    delProcessRouteItemParamOrder,
+    editProcessRouteItemParamOrder,
+  } from "@/api/productionManagement/productProcessRoute.js";
+
+  import { getBaseParamList } from "@/api/basicData/parameterMaintenance.js";
+
+  const props = defineProps({
+    modelValue: {
+      type: Boolean,
+      default: false,
+    },
+    title: {
+      type: String,
+      default: "鍙傛暟鍒楄〃",
+    },
+    routeId: {
+      type: Number,
+      default: 0,
+    },
+    process: {
+      type: Object,
+      default: () => ({}),
+    },
+    paramList: {
+      type: Array,
+      default: () => [],
+    },
+    editable: {
+      type: Boolean,
+      default: true,
+    },
+    orderId: {
+      type: Number,
+      default: 0,
+    },
+    pageType: {
+      type: String,
+      default: "route",
+    },
+  });
+
+  const emit = defineEmits(["update:modelValue", "refresh"]);
+
+  const visible = computed({
+    get: () => props.modelValue,
+    set: value => emit("update:modelValue", value),
+  });
+
+  // 鍝嶅簲寮忔暟鎹�
+  const selectParamDialogVisible = ref(false);
+  const editParamDialogVisible = ref(false);
+  const paramSearchKeyword = ref("");
+  const selectedParam = ref(null);
+  const filteredParamList = ref([]);
+  const paramPage = ref({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  const editParamForm = ref({
+    id: null,
+    processId: null,
+    paramId: null,
+    paramName: "",
+    standardValue: null,
+    sort: 1,
+    isRequired: false,
+    paramType: null,
+    paramFormat: "",
+    unit: "",
+  });
+  const editParamRules = ref({
+    standardValue: [{ required: true, message: "璇疯緭鍏ユ爣鍑嗗��", trigger: "blur" }],
+  });
+  const editParamFormRef = ref(null);
+
+  // 鏂板鍙傛暟
+  const handleAddParam = () => {
+    selectedParam.value = null;
+    paramSearchKeyword.value = "";
+    paramPage.current = 1;
+    // 鑾峰彇鍙�夊弬鏁板垪琛�
+    getBaseParamListData();
+    selectParamDialogVisible.value = true;
+  };
+
+  // 缂栬緫鍙傛暟
+  const handleEditParam = param => {
+    editParamForm.value = {
+      id: param.id,
+      processId: props.process.id,
+      paramId: param.paramId,
+      paramName: param.parameterName || param.paramName,
+      standardValue: param.standardValue,
+      sort: param.sort || 1,
+      isRequired: param.isRequired || false,
+      paramType: param.parameterType || param.paramType,
+      paramFormat: param.parameterFormat || param.paramFormat,
+      unit: param.unit || param.unit,
+    };
+    editParamDialogVisible.value = true;
+  };
+
+  // 鍒犻櫎鍙傛暟
+  const handleDeleteParam = param => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ鍙傛暟鍚楋紵", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        // 璋冪敤API鍒犻櫎鍙傛暟
+        if (props.pageType === "order") {
+          delProcessRouteItemParamOrder(param.id)
+            .then(res => {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              emit("refresh");
+            })
+            .catch(err => {
+              ElMessage.error("鍒犻櫎鍙傛暟澶辫触");
+              console.error("鍒犻櫎鍙傛暟澶辫触锛�", err);
+            });
+        } else {
+          delProcessRouteItemParam(param.id)
+            .then(res => {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              emit("refresh");
+            })
+            .catch(err => {
+              ElMessage.error("鍒犻櫎鍙傛暟澶辫触");
+              console.error("鍒犻櫎鍙傛暟澶辫触锛�", err);
+            });
+        }
+      })
+      .catch(() => {});
+  };
+
+  // 鑾峰彇鍙�夊弬鏁板垪琛�
+  const getBaseParamListData = () => {
+    getBaseParamList({
+      paramName: paramSearchKeyword.value,
+      current: paramPage.current,
+      size: paramPage.size,
+    }).then(res => {
+      if (res.code === 200) {
+        filteredParamList.value = res.data?.records || [];
+        paramPage.total = res.data?.total || 0;
+      } else {
+        ElMessage.error(res.msg || "鏌ヨ澶辫触");
+      }
+    });
+  };
+
+  // 閫夋嫨鍙傛暟
+  const handleSelectParam = param => {
+    selectedParam.value = param;
+  };
+
+  // 鎻愪氦閫夋嫨鍙傛暟
+  const handleParamSelectSubmit = () => {
+    if (!selectedParam.value) {
+      ElMessage.warning("璇峰厛閫夋嫨涓�涓弬鏁�");
+      return;
+    }
+
+    if (!props.process || !props.process.id) {
+      ElMessage.error("宸ヨ壓璺嚎椤圭洰淇℃伅涓嶅畬鏁�");
+      return;
+    }
+
+    // 鍒ゆ柇鍙傛暟绫诲瀷锛屽彧鏈夋暟鍊肩被鍨嬫墠浼犳爣鍑嗗�笺�佹渶澶у�煎拰鏈�灏忓��
+    const isNumericMode = selectedParam.value.paramType == 1;
+    console.log(isNumericMode, "isNumericMode");
+    // 璋冪敤API鏂板鍙傛暟
+    if (props.pageType === "order") {
+      addProcessRouteItemParamOrder({
+        orderId: Number(props.orderId),
+        // processId: props.process.id,
+        routeItemId: props.process.id,
+        // routeItemId: Number(props.routeId),
+        paramId: selectedParam.value.id,
+        standardValue: isNumericMode
+          ? selectedParam.value.standardValue || ""
+          : "",
+        isRequired: selectedParam.value.isRequired || false,
+        sort: selectedParam.value.sort || 1,
+      })
+        .then(res => {
+          if (res.code === 200) {
+            ElMessage.success("娣诲姞鍙傛暟鎴愬姛");
+            selectParamDialogVisible.value = false;
+            emit("refresh");
+          } else {
+            ElMessage.error(res.msg || "娣诲姞鍙傛暟澶辫触");
+          }
+        })
+        .catch(err => {
+          ElMessage.error("娣诲姞鍙傛暟澶辫触");
+          console.error("娣诲姞鍙傛暟澶辫触锛�", err);
+        });
+    } else {
+      addProcessRouteItemParam({
+        routeItemId: props.process.id,
+        paramId: selectedParam.value.id,
+        standardValue: isNumericMode
+          ? selectedParam.value.standardValue || ""
+          : "",
+        isRequired: selectedParam.value.isRequired || false,
+        sort: selectedParam.value.sort || 1,
+      })
+        .then(res => {
+          if (res.code === 200) {
+            ElMessage.success("娣诲姞鍙傛暟鎴愬姛");
+            selectParamDialogVisible.value = false;
+            emit("refresh");
+          } else {
+            ElMessage.error(res.msg || "娣诲姞鍙傛暟澶辫触");
+          }
+        })
+        .catch(err => {
+          ElMessage.error("娣诲姞鍙傛暟澶辫触");
+          console.error("娣诲姞鍙傛暟澶辫触锛�", err);
+        });
+    }
+  };
+
+  // 鎻愪氦缂栬緫鍙傛暟
+  const handleEditParamSubmit = () => {
+    if (!editParamFormRef.value) return;
+    editParamFormRef.value.validate(valid => {
+      if (valid) {
+        // 鍒ゆ柇鍙傛暟绫诲瀷锛屽彧鏈夋暟鍊肩被鍨嬫墠浼犳爣鍑嗗�笺�佹渶澶у�煎拰鏈�灏忓��
+        const isNumericMode = editParamForm.value.paramType == 1;
+        console.log(isNumericMode, "isNumericMode");
+        if (props.pageType === "order") {
+          editProcessRouteItemParamOrder({
+            id: editParamForm.value.id,
+            // routeItemId: props.process.id,
+            // paramId: editParamForm.value.paramId,
+            standardValue: isNumericMode
+              ? editParamForm.value.standardValue || ""
+              : "",
+            isRequired: editParamForm.value.isRequired || false,
+          })
+            .then(res => {
+              if (res.code === 200) {
+                ElMessage.success("缂栬緫鎴愬姛");
+                editParamDialogVisible.value = false;
+                emit("refresh");
+              } else {
+                ElMessage.error(res.msg || "缂栬緫澶辫触");
+              }
+            })
+            .catch(err => {
+              ElMessage.error("缂栬緫鍙傛暟澶辫触");
+              console.error("缂栬緫鍙傛暟澶辫触锛�", err);
+            });
+        } else {
+          // 璋冪敤API淇敼鍙傛暟
+          editProcessRouteItemParam({
+            id: editParamForm.value.id,
+            routeItemId: props.process.id,
+            paramId: editParamForm.value.paramId,
+            standardValue: isNumericMode
+              ? editParamForm.value.standardValue || ""
+              : "",
+            isRequired: editParamForm.value.isRequired || false,
+          })
+            .then(res => {
+              if (res.code === 200) {
+                ElMessage.success("缂栬緫鎴愬姛");
+                editParamDialogVisible.value = false;
+                emit("refresh");
+              } else {
+                ElMessage.error(res.msg || "缂栬緫澶辫触");
+              }
+            })
+            .catch(err => {
+              ElMessage.error("缂栬緫鍙傛暟澶辫触");
+              console.error("缂栬緫鍙傛暟澶辫触锛�", err);
+            });
+        }
+      }
+    });
+  };
+
+  // 鑾峰彇鍙傛暟绫诲瀷鏍囩
+  const getParamTypeTag = type => {
+    const typeMap = {
+      1: "primary",
+      2: "info",
+      3: "warning",
+      4: "success",
+    };
+    return typeMap[type] || "default";
+  };
+
+  // 鑾峰彇鍙傛暟绫诲瀷鏂囨湰
+  const getParamTypeText = type => {
+    const typeMap = {
+      1: "鏁板�兼牸寮�",
+      2: "鏂囨湰鏍煎紡",
+      3: "涓嬫媺閫夐」",
+      4: "鏃堕棿鏍煎紡",
+    };
+    return typeMap[type] || type;
+  };
+
+  watch(
+    () => props.modelValue,
+    newVal => {
+      if (!newVal) {
+        // 寮圭獥鍏抽棴鏃堕噸缃暟鎹�
+        selectParamDialogVisible.value = false;
+        editParamDialogVisible.value = false;
+        selectedParam.value = null;
+        paramSearchKeyword.value = "";
+        paramPage.current = 1;
+        filteredParamList.value = [];
+        editParamForm.value = {
+          id: null,
+          processId: null,
+          paramId: null,
+          paramName: "",
+          standardValue: null,
+          sort: 1,
+          isRequired: false,
+          paramType: null,
+          paramFormat: "",
+          unit: "",
+        };
+      }
+    }
+  );
+</script>
+
+<style scoped>
+  .param-list-container {
+    padding: 10px 0;
+  }
+
+  .params-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+    padding-bottom: 10px;
+    border-bottom: 1px solid #e4e7ed;
+  }
+
+  .params-header span {
+    font-size: 16px;
+    font-weight: 500;
+    color: #303133;
+  }
+
+  .params-list {
+    max-height: 400px;
+    overflow-y: auto;
+  }
+
+  .param-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 12px 16px;
+    margin-bottom: 8px;
+    background-color: #f9f9f9;
+    border-radius: 4px;
+    transition: all 0.3s ease;
+  }
+
+  .param-item:hover {
+    background-color: #ecf5ff;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  }
+
+  .param-info {
+    display: flex;
+    align-items: center;
+    gap: 20px;
+    flex: 1;
+  }
+
+  .param-code {
+    font-weight: 500;
+    color: #303133;
+    min-width: 120px;
+  }
+
+  .param-value {
+    color: #606266;
+    font-size: 14px;
+  }
+
+  .param-actions {
+    display: flex;
+    gap: 10px;
+  }
+
+  /* 婊氬姩鏉℃牱寮� */
+  .params-list::-webkit-scrollbar {
+    width: 6px;
+  }
+
+  .params-list::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 3px;
+  }
+
+  .params-list::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 3px;
+  }
+
+  .params-list::-webkit-scrollbar-thumb:hover {
+    background: #a8a8a8;
+  }
+
+  /* 閫夋嫨鍙傛暟瀵硅瘽妗嗘牱寮� */
+  .param-select-container {
+    display: flex;
+    gap: 20px;
+  }
+
+  .param-list-area {
+    flex: 1;
+    min-width: 400px;
+  }
+
+  .param-detail-area {
+    flex: 1;
+    min-width: 300px;
+  }
+
+  .area-title {
+    font-size: 14px;
+    font-weight: 500;
+    margin-bottom: 10px;
+    color: #303133;
+  }
+
+  .search-box {
+    display: flex;
+    gap: 10px;
+    margin-bottom: 10px;
+  }
+
+  .param-detail-form {
+    background: #f9f9f9;
+    padding: 15px;
+    border-radius: 4px;
+  }
+
+  .detail-text {
+    font-weight: 500;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/basicData/parameterMaintenance/index.vue b/src/views/basicData/parameterMaintenance/index.vue
new file mode 100644
index 0000000..63b52e9
--- /dev/null
+++ b/src/views/basicData/parameterMaintenance/index.vue
@@ -0,0 +1,790 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title ml10">鍙傛暟鍚嶇О锛�</span>
+        <el-input v-model="searchForm.paramName"
+                  style="width: 200px"
+                  placeholder="璇疯緭鍏ュ弬鏁板悕绉�"
+                  clearable />
+        <!-- 鍏宠仈浜у搧绫诲瀷鎼滅储 -->
+        <!-- <span class="search_title ml10">鍏宠仈浜у搧绫诲瀷锛�</span>
+        <el-input v-model="searchForm.productName"
+                  style="width: 200px"d
+                  placeholder="璇疯緭鍏ュ叧鑱斾骇鍝佺被鍨�"
+                  clearable /> -->
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储</el-button>
+        <el-button @click="handleReset">閲嶇疆</el-button>
+        <el-button type="primary"
+                   @click="handleAdd"
+                   style="margin-left: 10px">鏂板鍙傛暟</el-button>
+        <!-- 浜у搧绫诲瀷缁存姢鎸夐挳 -->
+        <!-- <el-button type="primary"
+                   @click="handleProductTypeMaintenance"
+                   style="margin-left: 10px">浜у搧绫诲瀷缁存姢</el-button> -->
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable rowKey="paramName"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                height="calc(100vh - 320px)"
+                :tableLoading="tableLoading"
+                :isSelection="false"
+                :isShowPagination="true"
+                @pagination="pagination">
+      </PIMTable>
+    </div>
+    <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="500px">
+      <el-form :model="formData"
+               :rules="rules"
+               ref="formRef"
+               label-width="120px">
+        <el-form-item label="鍙傛暟缂栫爜"
+                      prop="paramCode">
+          <el-input v-model="formData.paramCode"
+                    disabled
+                    placeholder="鑷姩鐢熸垚" />
+        </el-form-item>
+        <el-form-item label="鍙傛暟鍚嶇О"
+                      prop="paramName">
+          <el-input v-model="formData.paramName"
+                    placeholder="璇疯緭鍏ュ弬鏁板悕绉�" />
+        </el-form-item>
+        <el-form-item label="鍙傛暟绫诲瀷"
+                      prop="paramType">
+          <el-select v-model="formData.paramType"
+                     @change="handleParamTypeChange"
+                     placeholder="璇烽�夋嫨鍙傛暟绫诲瀷">
+            <el-option label="鏁板�兼牸寮�"
+                       :value="1" />
+            <el-option label="鏂囨湰鏍煎紡"
+                       :value="2" />
+            <el-option label="涓嬫媺閫夐」"
+                       :value="3" />
+            <el-option label="鏃堕棿鏍煎紡"
+                       :value="4" />
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="鍙栧�兼ā寮�"
+                      prop="valueMode">
+          <el-select v-model="formData.valueMode"
+                     placeholder="璇烽�夋嫨鍙栧�兼ā寮�">
+            <el-option label="鍗曞��"
+                       value="1" />
+            <el-option label="鍖洪棿"
+                       value="2" />
+          </el-select>
+        </el-form-item> -->
+        <el-form-item label="鍗曚綅"
+                      prop="unit">
+          <el-input v-model="formData.unit"
+                    placeholder="璇疯緭鍏ュ崟浣�" />
+        </el-form-item>
+        <el-form-item label="鍙栧�兼牸寮�"
+                      v-if="formData.paramType == 1 || formData.paramType == 2"
+                      prop="paramFormat">
+          <el-input v-model="formData.paramFormat"
+                    placeholder="璇疯緭鍏ュ彇鍊兼牸寮�" />
+          <!-- <el-select v-model="formData.paramFormat"
+                     placeholder="璇烽�夋嫨鍙栧�兼ā寮�">
+            <el-option label="#.00000"
+                       value="#.00000" />
+            <el-option label="#.0000"
+                       value="#.0000" />
+            <el-option label="#.000"
+                       value="#.000" />
+            <el-option label="#.00"
+                       value="#.00" />
+          </el-select> -->
+        </el-form-item>
+        <el-form-item label="涓嬫媺瀛楀吀"
+                      v-else-if="formData.paramType == 3"
+                      prop="paramFormat">
+          <el-select v-model="formData.paramFormat"
+                     placeholder="璇烽�夋嫨鍙栧�兼ā寮�">
+            <el-option v-for="item in dictTypes"
+                       :key="item.dictType"
+                       :label="item.dictName"
+                       :value="item.dictType" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏃堕棿鏍煎紡"
+                      v-else-if="formData.paramType == 4"
+                      prop="paramFormat">
+          <el-select v-model="formData.paramFormat"
+                     placeholder="璇烽�夋嫨鍙栧�兼ā寮�">
+            <el-option label="YYYY-MM-DD"
+                       value="YYYY-MM-DD" />
+            <el-option label="YYYY-MM-DD HH:mm:ss"
+                       value="YYYY-MM-DD HH:mm:ss" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏄惁蹇呭~"
+                      prop="isRequired">
+          <el-switch v-model="formData.isRequired"
+                     :active-value="1"
+                     :inactive-value="0" />
+        </el-form-item>
+        <el-form-item label="澶囨敞"
+                      prop="remark">
+          <el-input v-model="formData.remark"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- 浜у搧绫诲瀷缁存姢瀵硅瘽妗� -->
+    <!-- <el-dialog v-model="productTypeDialogVisible"
+               title="浜у搧绫诲瀷缁存姢"
+               width="600px">
+      <div class="product-type-header">
+        <el-button type="primary"
+                   @click="handleAddProductType">鏂板浜у搧绫诲瀷</el-button>
+      </div>
+      <el-table :data="productTypeList"
+                border
+                style="width: 100%; margin-top: 10px; margin-bottom: 20px">
+        <el-table-column prop="typeCode"
+                         label="绫诲瀷缂栫爜"
+                         width="150" />
+        <el-table-column prop="typeName"
+                         label="绫诲瀷鍚嶇О" />
+        <el-table-column label="鎿嶄綔"
+                         width="150">
+          <template #default="scope">
+            <el-button link
+                       type="primary"
+                       @click="handleEditProductType(scope.row)">缂栬緫</el-button>
+            <el-button link
+                       type="danger"
+                       @click="handleDeleteProductType(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog> -->
+    <!-- 鏂板/缂栬緫浜у搧绫诲瀷瀵硅瘽妗� -->
+    <!-- <el-dialog v-model="productTypeFormVisible"
+               :title="productTypeDialogTitle"
+               width="400px">
+      <el-form :model="productTypeForm"
+               :rules="productTypeRules"
+               ref="productTypeFormRef"
+               label-width="100px">
+        <el-form-item label="绫诲瀷缂栫爜"
+                      prop="typeCode">
+          <el-input v-model="productTypeForm.typeCode"
+                    placeholder="璇疯緭鍏ョ被鍨嬬紪鐮�" />
+        </el-form-item>
+        <el-form-item label="绫诲瀷鍚嶇О"
+                      prop="typeName">
+          <el-input v-model="productTypeForm.typeName"
+                    placeholder="璇疯緭鍏ョ被鍨嬪悕绉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="productTypeFormVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleProductTypeSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog> -->
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref, reactive } from "vue";
+  import {
+    parameterListPage,
+    addParameter,
+    updateParameter,
+    delParameter,
+    addBaseParam,
+    editBaseParam,
+    getBaseParamList,
+    removeBaseParam,
+    // getProductTypes as getProductTypesApi,
+  } from "@/api/basicData/parameterMaintenance.js";
+  import { listType } from "@/api/system/dict/type";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import PIMTable from "@/components/PIMTable/PIMTable.vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+
+  const tableColumn = ref([
+    {
+      label: "鍙傛暟缂栫爜",
+      prop: "paramCode",
+    },
+    {
+      label: "鍙傛暟鍚嶇О",
+      prop: "paramName",
+    },
+    {
+      label: "鍙傛暟绫诲瀷",
+      prop: "paramType",
+      dataType: "tag",
+      formatType: params => {
+        const typeMap = {
+          1: "primary",
+          2: "info",
+          3: "warning",
+          4: "success",
+        };
+        return typeMap[params] || "default";
+      },
+      formatData: val => {
+        const labelMap = {
+          1: "鏁板�兼牸寮�",
+          2: "鏂囨湰鏍煎紡",
+          3: "涓嬫媺閫夐」",
+          4: "鏃堕棿鏍煎紡",
+        };
+        return labelMap[val] || val;
+      },
+    },
+    // {
+    //   label: "鍙栧�兼ā寮�",
+    //   prop: "valueMode",
+    //   dataType: "tag",
+    //   formatType: params => {
+    //     return params === 2 ? "warning" : "success";
+    //   },
+    //   formatData: val => {
+    //     return val === 2 ? "鍖洪棿" : "鍗曞��";
+    //   },
+    // },
+    {
+      label: "鍗曚綅",
+      prop: "unit",
+    },
+    {
+      label: "鍙栧�兼牸寮�",
+      prop: "paramFormat",
+    },
+    {
+      label: "鏄惁蹇呭~",
+      prop: "isRequired",
+      dataType: "tag",
+      formatType: val => {
+        return val === 1 ? "success" : "info";
+      },
+      formatData: val => {
+        return val === 1 ? "鏄�" : "鍚�";
+      },
+    },
+    {
+      label: "澶囨敞",
+      prop: "remark",
+    },
+    {
+      label: "鍒涘缓鏃堕棿",
+      prop: "createTime",
+    },
+    {
+      label: "鎿嶄綔",
+      dataType: "action",
+      width: "150",
+      operation: [
+        {
+          name: "缂栬緫",
+          clickFun: row => {
+            handleEdit(row);
+          },
+        },
+        {
+          name: "鍒犻櫎",
+          clickFun: row => {
+            handleDelete(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    paramName: "",
+    productName: "",
+  });
+
+  // 瀵硅瘽妗嗙浉鍏�
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("");
+  const formRef = ref(null);
+  const formData = reactive({
+    id: null,
+    paramCode: "",
+    paramName: "",
+    paramType: "",
+    // valueMode: "1",
+    unit: "",
+    remark: "",
+    isRequired: 0,
+    paramFormat: "",
+  });
+  const rules = reactive({
+    paramName: [{ required: true, message: "璇疯緭鍏ュ弬鏁板悕绉�", trigger: "blur" }],
+    paramType: [{ required: true, message: "璇烽�夋嫨鍙傛暟绫诲瀷", trigger: "change" }],
+    // valueMode: [{ required: true, message: "璇烽�夋嫨鍙栧�兼ā寮�", trigger: "change" }],
+    unit: [
+      {
+        required: false,
+        message: "璇疯緭鍏ュ崟浣�",
+        trigger: "blur",
+        validator: (rule, value, callback) => {
+          if (formData.paramType === 1 && !value) {
+            callback(new Error("鏁板�肩被鍨嬪繀椤诲~鍐欏崟浣�"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+  });
+  // const productTypes = ref([]);
+  const isEdit = ref(false);
+
+  // 浜у搧绫诲瀷缁存姢鐩稿叧 - 宸叉敞閲�
+  // const productTypeDialogVisible = ref(false);
+  // const productTypeFormVisible = ref(false);
+  // const productTypeDialogTitle = ref("");
+  // const productTypeFormRef = ref(null);
+  // const productTypeList = ref([]);
+  // const productTypeForm = reactive({
+  //   id: null,
+  //   typeCode: "",
+  //   typeName: "",
+  // });
+  // const productTypeRules = reactive({
+  //   typeCode: [{ required: true, message: "璇疯緭鍏ョ被鍨嬬紪鐮�", trigger: "blur" }],
+  //   typeName: [{ required: true, message: "璇疯緭鍏ョ被鍨嬪悕绉�", trigger: "blur" }],
+  // });
+  // const isProductTypeEdit = ref(false);
+  const handleParamTypeChange = () => {
+    if (formData.paramType === 1) {
+      formData.paramFormat = "#.00000";
+    } else if (formData.paramType === 4) {
+      formData.paramFormat = "YYYY-MM-DD HH:mm:ss";
+    } else {
+      formData.paramFormat = "";
+    }
+    // 瑙﹀彂鍗曚綅瀛楁楠岃瘉
+    if (formRef.value) {
+      formRef.value.validateField("unit");
+    }
+  };
+  // 浜у搧绫诲瀷缁存姢鎸夐挳鐐瑰嚮浜嬩欢 - 宸叉敞閲�
+  // const handleProductTypeMaintenance = () => {
+  //   productTypeDialogVisible.value = true;
+  //   getProductTypeList();
+  // };
+
+  // 鑾峰彇浜у搧绫诲瀷鍒楄〃 - 宸叉敞閲�
+  // const getProductTypeList = () => {
+  //   productTypeList.value = [
+  //     { id: 1, typeCode: "TYPE001", typeName: "3.5鐮屽潡" },
+  //     { id: 2, typeCode: "TYPE002", typeName: "5.0鐮屽潡" },
+  //     { id: 3, typeCode: "TYPE003", typeName: "鏉挎潗" },
+  //   ];
+  // };
+
+  // 鏂板浜у搧绫诲瀷 - 宸叉敞閲�
+  // const handleAddProductType = () => {
+  //   isProductTypeEdit.value = false;
+  //   productTypeDialogTitle.value = "鏂板浜у搧绫诲瀷";
+  //   productTypeForm.id = null;
+  //   productTypeForm.typeCode = "";
+  //   productTypeForm.typeName = "";
+  //   productTypeFormVisible.value = true;
+  // };
+
+  // 缂栬緫浜у搧绫诲瀷 - 宸叉敞閲�
+  // const handleEditProductType = row => {
+  //   isProductTypeEdit.value = true;
+  //   productTypeDialogTitle.value = "缂栬緫浜у搧绫诲瀷";
+  //   productTypeForm.id = row.id;
+  //   productTypeForm.typeCode = row.typeCode;
+  //   productTypeForm.typeName = row.typeName;
+  //   productTypeFormVisible.value = true;
+  // };
+
+  // 鍒犻櫎浜у搧绫诲瀷 - 宸叉敞閲�
+  // const handleDeleteProductType = row => {
+  //   ElMessageBox.confirm("纭畾瑕佸垹闄よ浜у搧绫诲瀷鍚楋紵", "鎻愮ず", {
+  //     confirmButtonText: "纭畾",
+  //     cancelButtonText: "鍙栨秷",
+  //     type: "warning",
+  //   })
+  //     .then(() => {
+  //       ElMessage.success("鍒犻櫎鎴愬姛");
+  //       getProductTypeList();
+  //     })
+  //     .catch(() => {});
+  // };
+
+  // 鎻愪氦浜у搧绫诲瀷琛ㄥ崟 - 宸叉敞閲�
+  // const handleProductTypeSubmit = () => {
+  //   productTypeFormRef.value.validate(valid => {
+  //     if (valid) {
+  //       ElMessage.success(isProductTypeEdit.value ? "缂栬緫鎴愬姛" : "鏂板鎴愬姛");
+  //       productTypeFormVisible.value = false;
+  //       getProductTypeList();
+  //     }
+  //   });
+  // };
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+
+  /** 閲嶇疆鎸夐挳鎿嶄綔 */
+  const handleReset = () => {
+    searchForm.paramName = "";
+    searchForm.productName = "";
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+
+  const getList = () => {
+    tableLoading.value = true;
+    // 璋冪敤鏂版帴鍙� /baseParam/list
+    getBaseParamList({
+      paramName: searchForm.paramName,
+      current: page.current,
+      size: page.size,
+    })
+      .then(res => {
+        tableLoading.value = false;
+        if (res.code === 200) {
+          tableData.value = res.data.records || [];
+          page.total = res.data.total || 0;
+          console.log(tableData.value, "tableData.value");
+        } else {
+          ElMessage.error(res.msg || "鏌ヨ澶辫触");
+        }
+      })
+      .catch(() => {
+        tableLoading.value = false;
+        ElMessage.error("鏌ヨ澶辫触");
+      });
+  };
+
+  // 鑾峰彇浜у搧绫诲瀷鍒楄〃 - 宸叉敞閲�
+  // const getProductTypes = () => {
+  //   productTypes.value = [
+  //     { label: "3.5鐮屽潡", value: "type1" },
+  //     { label: "5.0鐮屽潡", value: "type2" },
+  //     { label: "鏉挎潗", value: "type3" },
+  //   ];
+  // };
+
+  // 鏂板鎸夐挳鐐瑰嚮浜嬩欢
+  const handleAdd = () => {
+    isEdit.value = false;
+    dialogTitle.value = "鏂板鍙傛暟";
+    // 閲嶇疆琛ㄥ崟
+    formData.id = null;
+    formData.paramCode = "";
+    formData.paramName = "";
+    formData.paramType = "";
+    // formData.valueMode = "1";
+    formData.unit = "";
+    formData.remark = "";
+    formData.isRequired = 0;
+    dialogVisible.value = true;
+  };
+
+  // 缂栬緫鎸夐挳鐐瑰嚮浜嬩欢
+  const handleEdit = row => {
+    isEdit.value = true;
+    dialogTitle.value = "缂栬緫鍙傛暟";
+    // 濉厖琛ㄥ崟鏁版嵁
+    formData.id = row.id;
+    formData.paramCode = row.paramCode || "";
+    formData.paramName = row.paramName || "";
+    formData.paramType = row.paramType !== undefined ? row.paramType : null;
+    // formData.valueMode =
+    //   row.valueMode !== undefined ? String(row.valueMode) : "1";
+    formData.unit = row.unit || "";
+    formData.remark = row.remark || "";
+    formData.paramFormat = row.paramFormat || "";
+    formData.isRequired = row.isRequired || 0;
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎鎸夐挳鐐瑰嚮浜嬩欢
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ繖鏉℃暟鎹悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        // 璋冪敤鏂版帴鍙� /baseParam/remove/{id}
+        removeBaseParam([row.id])
+          .then(res => {
+            ElMessage.success("鍒犻櫎鎴愬姛");
+            getList();
+          })
+          .catch(() => {
+            ElMessage.error("鍒犻櫎澶辫触");
+          });
+      })
+      .catch(() => {
+        // 鍙栨秷鍒犻櫎
+      });
+  };
+
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        if (formData.id) {
+          // 缂栬緫浣跨敤鏂版帴鍙� /technologyParam/edit
+          editBaseParam(formData)
+            .then(res => {
+              ElMessage.success("缂栬緫鎴愬姛");
+              dialogVisible.value = false;
+              getList();
+            })
+            .catch(() => {
+              // ElMessage.error("缂栬緫澶辫触");
+            });
+        } else {
+          // 鏂板浣跨敤鏂版帴鍙� /technologyParam/add
+          addBaseParam(formData)
+            .then(res => {
+              ElMessage.success("鏂板鎴愬姛");
+              dialogVisible.value = false;
+              getList();
+            })
+            .catch(() => {
+              ElMessage.error("鏂板澶辫触");
+            });
+        }
+      } else {
+        return false;
+      }
+    });
+  };
+  const dictTypes = ref([]);
+  const getDictTypes = () => {
+    listType({ pageNum: 1, pageSize: 1000 }).then(res => {
+      dictTypes.value = res.rows || [];
+    });
+  };
+
+  onMounted(() => {
+    getDictTypes();
+    getList();
+    // getProductTypes();
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 24px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 48px);
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
+    }
+
+    .search_title {
+      color: #606266;
+      font-size: 14px;
+      font-weight: 500;
+    }
+
+    .ml10 {
+      margin-left: 10px;
+    }
+  }
+
+  .table_list {
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    overflow: hidden;
+    height: calc(100vh - 230px);
+  }
+
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.1);
+
+    .el-table__header-wrapper {
+      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+
+      th {
+        background: transparent;
+        font-weight: 600;
+        // color: #ffffff;
+        border-bottom: none;
+        padding: 16px 0;
+        letter-spacing: 0.5px;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background: linear-gradient(
+            90deg,
+            rgba(102, 126, 234, 0.05) 0%,
+            rgba(118, 75, 162, 0.05) 100%
+          );
+          transform: scale(1.002);
+          box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1);
+        }
+
+        td {
+          border-bottom: 1px solid #f0f0f0;
+          padding: 14px 0;
+          color: #303133;
+        }
+      }
+
+      tr.current-row {
+        background: linear-gradient(
+          90deg,
+          rgba(102, 126, 234, 0.08) 0%,
+          rgba(118, 75, 162, 0.08) 100%
+        );
+      }
+
+      // 鏁板�煎瓧娈垫牱寮�
+      .quantity-cell,
+      .volume-cell,
+      .dimension-cell {
+        font-weight: 600;
+        color: #409eff;
+        font-family: "Courier New", monospace;
+        text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
+      }
+
+      // 瑙勬牸瀛楁鏍峰紡
+      .spec-cell {
+        color: #67c23a;
+        font-weight: 500;
+        padding: 4px 8px;
+        border-radius: 4px;
+      }
+
+      // 缂栫爜瀛楁鏍峰紡
+      .code-cell {
+        color: #e6a23c;
+        font-family: "Courier New", monospace;
+        font-weight: 500;
+        padding: 4px 8px;
+        border-radius: 4px;
+      }
+
+      // 鏃ユ湡瀛楁鏍峰紡
+      .date-cell {
+        color: #909399;
+        font-style: italic;
+      }
+    }
+
+    .el-table__empty-block {
+      padding: 60px 0;
+      background-color: #fafafa;
+    }
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+    padding: 16px 20px;
+    background-color: #ffffff;
+    border-top: 1px solid #ebeef5;
+    border-radius: 0 0 12px 12px;
+  }
+
+  :deep(.el-button) {
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-1px);
+    }
+  }
+
+  @media (max-width: 768px) {
+    .app-container {
+      padding: 16px;
+    }
+
+    .search_form {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 12px;
+
+      .el-form {
+        width: 100%;
+
+        .el-form-item {
+          width: 100%;
+        }
+      }
+
+      .el-button {
+        margin-right: 12px;
+      }
+    }
+
+    :deep(.el-table) {
+      th,
+      td {
+        padding: 10px 0;
+        font-size: 12px;
+      }
+    }
+  }
+</style>
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index c1c490c..be7138d 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -1,9 +1,10 @@
 <template>
   <div class="app-container">
     <PageHeader content="宸ヨ壓璺嚎椤圭洰" />
-    
     <!-- 宸ヨ壓璺嚎淇℃伅灞曠ず -->
-    <el-card v-if="routeInfo.processRouteCode" class="route-info-card" shadow="hover">
+    <el-card v-if="routeInfo.processRouteCode"
+             class="route-info-card"
+             shadow="hover">
       <div class="route-info">
         <div class="info-item">
           <div class="info-label-wrapper">
@@ -37,7 +38,8 @@
             <span class="info-value">{{ routeInfo.bomNo || '-' }}</span>
           </div>
         </div>
-        <div class="info-item full-width" v-if="routeInfo.description">
+        <div class="info-item full-width"
+             v-if="routeInfo.description">
           <div class="info-label-wrapper">
             <span class="info-label">鎻忚堪</span>
           </div>
@@ -47,435 +49,469 @@
         </div>
       </div>
     </el-card>
-    
     <!-- 琛ㄦ牸瑙嗗浘 -->
-    <div v-if="viewMode === 'table'" class="section-header">
+    <div v-if="viewMode === 'table'"
+         class="section-header">
       <div class="section-title">宸ヨ壓璺嚎椤圭洰鍒楄〃</div>
       <div class="section-actions">
-        <el-button 
-            icon="Grid" 
-            @click="toggleView"
-            style="margin-right: 10px;"
-        >
+        <el-button icon="Grid"
+                   @click="toggleView"
+                   style="margin-right: 10px;">
           鍗$墖瑙嗗浘
         </el-button>
-        <el-button type="primary" @click="handleAdd">鏂板</el-button>
+        <el-button type="primary"
+                   @click="handleAdd">鏂板</el-button>
       </div>
     </div>
-    <el-table
-        v-if="viewMode === 'table'"
-        ref="tableRef"
-        v-loading="tableLoading"
-        border
-        :data="tableData"
-        :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
-        row-key="id"
-        tooltip-effect="dark"
-        class="lims-table"
-    >
-      <el-table-column align="center" label="搴忓彿" width="60" type="index" />
-      <el-table-column label="宸ュ簭鍚嶇О" prop="processId" width="200">
+    <el-table v-if="viewMode === 'table'"
+              ref="tableRef"
+              v-loading="tableLoading"
+              border
+              :data="tableData"
+              :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+              row-key="id"
+              tooltip-effect="dark"
+              class="lims-table">
+      <el-table-column align="center"
+                       label="搴忓彿"
+                       width="60"
+                       type="index" />
+      <el-table-column label="宸ュ簭鍚嶇О"
+                       prop="processId"
+                       width="200">
         <template #default="scope">
           {{ getProcessName(scope.row.processId) || '-' }}
         </template>
       </el-table-column>
-      <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="160" />
-      <el-table-column label="瑙勬牸鍚嶇О" prop="model" min-width="140" />
-      <el-table-column label="鍗曚綅" prop="unit" width="100" />
-      <el-table-column label="鏄惁璐ㄦ" prop="isQuality" width="100">
+      <el-table-column label="鍙傛暟鍒楄〃"
+                       min-width="160">
+        <template #default="scope">
+          <el-button type="primary"
+                     link
+                     size="small"
+                     @click="handleViewParams(scope.row)">鍙傛暟鍒楄〃</el-button>
+        </template>
+      </el-table-column>
+      <el-table-column label="浜у搧鍚嶇О"
+                       prop="productName"
+                       min-width="160" />
+      <el-table-column label="瑙勬牸鍚嶇О"
+                       prop="model"
+                       min-width="140" />
+      <el-table-column label="鍗曚綅"
+                       prop="unit"
+                       width="100" />
+      <el-table-column label="鏄惁璐ㄦ"
+                       prop="isQuality"
+                       width="100">
         <template #default="scope">
           {{scope.row.isQuality ? "鏄�" : "鍚�"}}
         </template>
       </el-table-column>
-      <el-table-column label="鎿嶄綔" align="center" fixed="right" width="150">
+      <el-table-column label="鎿嶄綔"
+                       align="center"
+                       fixed="right"
+                       width="150">
         <template #default="scope">
-          <el-button type="primary" link size="small" @click="handleEdit(scope.row)" :disabled="scope.row.isComplete">缂栬緫</el-button>
-          <el-button type="danger" link size="small" @click="handleDelete(scope.row)" :disabled="scope.row.isComplete">鍒犻櫎</el-button>
+          <el-button type="primary"
+                     link
+                     size="small"
+                     @click="handleEdit(scope.row)"
+                     :disabled="scope.row.isComplete">缂栬緫</el-button>
+          <el-button type="danger"
+                     link
+                     size="small"
+                     @click="handleDelete(scope.row)"
+                     :disabled="scope.row.isComplete">鍒犻櫎</el-button>
         </template>
       </el-table-column>
     </el-table>
-    
     <!-- 鍗$墖瑙嗗浘 -->
     <template v-else>
       <div class="section-header">
         <div class="section-title">宸ヨ壓璺嚎椤圭洰鍒楄〃</div>
         <div class="section-actions">
-          <el-button 
-              icon="Menu" 
-              @click="toggleView"
-              style="margin-right: 10px;"
-          >
+          <el-button icon="Menu"
+                     @click="toggleView"
+                     style="margin-right: 10px;">
             琛ㄦ牸瑙嗗浘
           </el-button>
-          <el-button type="primary" @click="handleAdd">鏂板</el-button>
+          <el-button type="primary"
+                     @click="handleAdd">鏂板</el-button>
         </div>
       </div>
-      <div v-loading="tableLoading" class="card-container">
-        <div 
-            ref="cardsContainer" 
-            class="cards-wrapper"
-        >
-        <div
-            v-for="(item, index) in tableData"
-            :key="item.id || index"
-            class="process-card"
-            :data-index="index"
-        >
-          <!-- 搴忓彿鍦嗗湀 -->
-          <div class="card-header">
-            <div class="card-number">{{ index + 1 }}</div>
-            <div class="card-process-name">{{ getProcessName(item.processId) || '-' }}</div>
-          </div>
-          
-          <!-- 浜у搧淇℃伅 -->
-          <div class="card-content">
-            <div v-if="item.productName" class="product-info">
-              <div class="product-name">{{ item.productName }}</div>
-              <div v-if="item.model" class="product-model">
-                {{ item.model }}
-                <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
-              </div>
-              <el-tag type="primary" class="product-tag" v-if="item.isQuality">璐ㄦ</el-tag>
+      <div v-loading="tableLoading"
+           class="card-container">
+        <div ref="cardsContainer"
+             class="cards-wrapper">
+          <div v-for="(item, index) in tableData"
+               :key="item.id || index"
+               class="process-card"
+               :data-index="index">
+            <!-- 搴忓彿鍦嗗湀 -->
+            <div class="card-header">
+              <div class="card-number">{{ index + 1 }}</div>
+              <div class="card-process-name">{{ getProcessName(item.processId) || '-' }}</div>
             </div>
-            <div v-else class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
-          </div>
-          
-          <!-- 鎿嶄綔鎸夐挳 -->
-          <div class="card-footer">
-            <el-button type="primary" link size="small" @click="handleEdit(item)" :disabled="item.isComplete">缂栬緫</el-button>
-            <el-button type="danger" link size="small" @click="handleDelete(item)" :disabled="item.isComplete">鍒犻櫎</el-button>
+            <!-- 浜у搧淇℃伅 -->
+            <div class="card-content">
+              <div v-if="item.productName"
+                   class="product-info">
+                <div class="product-name">{{ item.productName }}</div>
+                <div v-if="item.model"
+                     class="product-model">
+                  {{ item.model }}
+                  <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
+                </div>
+                <el-tag type="primary"
+                        class="product-tag"
+                        v-if="item.isQuality">璐ㄦ</el-tag>
+              </div>
+              <div v-else
+                   class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
+            </div>
+            <!-- 鎿嶄綔鎸夐挳 -->
+            <div class="card-footer">
+              <el-button type="primary"
+                         link
+                         size="small"
+                         @click="handleEdit(item)"
+                         :disabled="item.isComplete">缂栬緫</el-button>
+              <el-button type="info"
+                         link
+                         size="small"
+                         @click="handleViewParams(item)">鍙傛暟鍒楄〃</el-button>
+              <el-button type="danger"
+                         link
+                         size="small"
+                         @click="handleDelete(item)"
+                         :disabled="item.isComplete">鍒犻櫎</el-button>
+            </div>
           </div>
         </div>
-      </div>
       </div>
     </template>
-
+    <div class="section-BOM">
+      <div class="section-header">
+        <div class="section-title">BOM</div>
+        <div class="section-actions">
+          <el-button type="primary"
+                     @click="toggleBomEdit">
+            {{ bomDataValue.isEdit ? '鍙栨秷' : '缂栬緫' }}
+          </el-button>
+          <el-button v-if=" bomDataValue.isEdit"
+                     type="success"
+                     @click="saveBomChanges">淇濆瓨</el-button>
+        </div>
+      </div>
+      <div>
+        <!-- BOM琛ㄦ牸 -->
+        <el-table :data="bomTableData"
+                  border
+                  :preserve-expanded-content="false"
+                  :default-expand-all="true"
+                  style="width: 100%">
+          <el-table-column type="expand">
+            <template #default="props">
+              <el-form ref="bomFormRef"
+                       :model="bomDataValue">
+                <el-table :data="props.row.bomList"
+                          row-key="tempId"
+                          default-expand-all
+                          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+                          style="width: 100%">
+                  <el-table-column prop="productName"
+                                   label="浜у搧" />
+                  <el-table-column prop="model"
+                                   label="瑙勬牸">
+                    <template #default="{ row }">
+                      <el-form-item v-if="bomDataValue.isEdit"
+                                    :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+                                    style="margin: 0">
+                        <el-select v-model="row.model"
+                                   placeholder="璇烽�夋嫨瑙勬牸"
+                                   clearable
+                                   :disabled="!bomDataValue.isEdit"
+                                   style="width: 100%"
+                                   @visible-change="(v) => { if (v) openBomProductDialog(row.tempId) }">
+                          <el-option v-if="row.model"
+                                     :label="row.model"
+                                     :value="row.model" />
+                        </el-select>
+                      </el-form-item>
+                      <span v-else>{{ row.model }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="processName"
+                                   label="娑堣�楀伐搴�">
+                    <template #default="{ row }">
+                      <el-form-item v-if="bomDataValue.isEdit"
+                                    :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+                                    style="margin: 0">
+                        <el-select v-model="row.processId"
+                                   placeholder="璇烽�夋嫨"
+                                   filterable
+                                   clearable
+                                   :disabled="!bomDataValue.isEdit"
+                                   style="width: 100%">
+                          <el-option v-for="process in processOptions"
+                                     :key="process.id"
+                                     :label="process.name"
+                                     :value="process.id" />
+                        </el-select>
+                      </el-form-item>
+                      <span v-else>{{ row.processName }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="unitQuantity"
+                                   label="鍗曚綅浜у嚭鎵�闇�鏁伴噺">
+                    <template #default="{ row }">
+                      <el-form-item v-if="bomDataValue.isEdit"
+                                    :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣嶄骇鍑烘墍闇�鏁伴噺', trigger: ['blur','change'] }]"
+                                    style="margin: 0">
+                        <el-input-number v-model="row.unitQuantity"
+                                         :min="0"
+                                         :precision="2"
+                                         :step="1"
+                                         controls-position="right"
+                                         style="width: 100%"
+                                         :disabled="!bomDataValue.isEdit" />
+                      </el-form-item>
+                      <span v-else>{{ row.unitQuantity }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column v-if="pageType === 'order'"
+                                   prop="demandedQuantity"
+                                   label="闇�姹傛�婚噺">
+                    <template #default="{ row }">
+                      <el-form-item v-if="bomDataValue.isEdit"
+                                    :rules="[{ required: true, message: '璇疯緭鍏ラ渶姹傛�婚噺', trigger: ['blur','change'] }]"
+                                    style="margin: 0">
+                        <el-input-number v-model="row.demandedQuantity"
+                                         :min="0"
+                                         :precision="2"
+                                         :step="1"
+                                         controls-position="right"
+                                         style="width: 100%"
+                                         :disabled="!bomDataValue.isEdit" />
+                      </el-form-item>
+                      <span v-else>{{ row.demandedQuantity }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="unit"
+                                   label="鍗曚綅">
+                    <template #default="{ row }">
+                      <el-form-item v-if="bomDataValue.isEdit"
+                                    :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
+                                    style="margin: 0">
+                        <el-input v-model="row.unit"
+                                  placeholder="璇疯緭鍏ュ崟浣�"
+                                  clearable
+                                  :disabled="!bomDataValue.isEdit" />
+                      </el-form-item>
+                      <span v-else>{{ row.unit }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="鎿嶄綔"
+                                   fixed="right"
+                                   width="180">
+                    <template #default="{ row }">
+                      <el-button v-if="bomDataValue.isEdit"
+                                 type="danger"
+                                 text
+                                 size="small"
+                                 @click="removeBomItem(row.tempId)">鍒犻櫎</el-button>
+                      <el-button v-if="bomDataValue.isEdit"
+                                 type="primary"
+                                 text
+                                 size="small"
+                                 @click="addBomItem2(row.tempId)">娣诲姞瀛愰」</el-button>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-form>
+            </template>
+          </el-table-column>
+          <el-table-column label="BOM缂栧彿"
+                           prop="bomNo" />
+          <el-table-column label="浜у搧鍚嶇О"
+                           prop="productName" />
+          <el-table-column label="瑙勬牸鍨嬪彿"
+                           prop="model" />
+        </el-table>
+        <!-- <div v-if="bomDataValue.isEdit"
+             style="text-align: center;border: 1px solid #e4e7ed;padding: 10px;transition: all 0.3s ease;cursor: pointer;"
+             :class="{'hover-effect': bomDataValue.isEdit}">
+          <el-button type="primary"
+                     text
+                     @click="addBomItem">
+            <el-icon style="vertical-align: middle;margin-right: 5px;">
+              <Plus />
+            </el-icon>
+            娣诲姞
+          </el-button>
+        </div> -->
+      </div>
+    </div>
     <!-- 鏂板/缂栬緫寮圭獥 -->
-    <el-dialog
-        v-model="dialogVisible"
-        :title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
-        width="500px"
-        @close="closeDialog"
-    >
-      <el-form
-          ref="formRef"
-          :model="form"
-          :rules="rules"
-          label-width="120px"
-      >
-        <el-form-item label="宸ュ簭" prop="processId">
-          <el-select
-              v-model="form.processId"
-              placeholder="璇烽�夋嫨宸ュ簭"
-              clearable
-              style="width: 100%"
-          >
-            <el-option
-                v-for="process in processOptions"
-                :key="process.id"
-                :label="process.name"
-                :value="process.id"
-            />
+    <el-dialog v-model="dialogVisible"
+               :title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
+               width="500px"
+               @close="closeDialog">
+      <el-form ref="formRef"
+               :model="form"
+               :rules="rules"
+               label-width="120px">
+        <el-form-item label="宸ュ簭"
+                      prop="processId">
+          <el-select v-model="form.processId"
+                     placeholder="璇烽�夋嫨宸ュ簭"
+                     clearable
+                     style="width: 100%">
+            <el-option v-for="process in processOptions"
+                       :key="process.id"
+                       :label="process.name"
+                       :value="process.id" />
           </el-select>
         </el-form-item>
-
-        <el-form-item label="浜у搧鍚嶇О" prop="productModelId">
-          <el-button type="primary" @click="showProductSelectDialog = true">
+        <el-form-item label="浜у搧鍚嶇О"
+                      prop="productModelId">
+          <el-button type="primary"
+                     @click="showProductSelectDialog = true">
             {{ form.productName && form.model 
               ? `${form.productName} - ${form.model}` 
               : '閫夋嫨浜у搧' }}
           </el-button>
         </el-form-item>
-
-        <el-form-item label="鍗曚綅" prop="unit">
-          <el-input 
-              v-model="form.unit" 
-              :placeholder="form.productModelId ? '鏍规嵁閫夋嫨鐨勪骇鍝佽嚜鍔ㄥ甫鍑�' : '璇峰厛閫夋嫨浜у搧'" 
-              clearable 
-              :disabled="true" 
-          />
+        <el-form-item label="鍗曚綅"
+                      prop="unit">
+          <el-input v-model="form.unit"
+                    :placeholder="form.productModelId ? '鏍规嵁閫夋嫨鐨勪骇鍝佽嚜鍔ㄥ甫鍑�' : '璇峰厛閫夋嫨浜у搧'"
+                    clearable
+                    :disabled="true" />
         </el-form-item>
-
-        <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
-          <el-switch v-model="form.isQuality" :active-value="true" inactive-value="false"/>
+        <el-form-item label="鏄惁璐ㄦ"
+                      prop="isQuality">
+          <el-switch v-model="form.isQuality"
+                     :active-value="true"
+                     inactive-value="false" />
         </el-form-item>
       </el-form>
-
       <template #footer>
-        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+        <el-button type="primary"
+                   @click="handleSubmit"
+                   :loading="submitLoading">纭畾</el-button>
         <el-button @click="closeDialog">鍙栨秷</el-button>
       </template>
     </el-dialog>
-
     <!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
-    <ProductSelectDialog
-        v-model="showProductSelectDialog"
-        @confirm="handleProductSelect"
-        single
-    />
+    <ProductSelectDialog v-model="showProductSelectDialog"
+                         @confirm="handleProductSelect"
+                         single />
+    <!-- BOM浜у搧閫夋嫨瀵硅瘽妗� -->
+    <ProductSelectDialog v-model="bomDataValue.showProductDialog"
+                         @confirm="handleBomProductSelect"
+                         single />
+    <!-- 鍙傛暟鍒楄〃瀵硅瘽妗� -->
+    <!-- :editable="!routeInfo.status" -->
+    <ProcessParamListDialog v-model="showParamListDialog"
+                            :title="`${currentProcess ? (currentProcess.processName || getProcessName(currentProcess.processId)) : ''} - 鍙傛暟鍒楄〃`"
+                            :route-id="routeId"
+                            :order-id="orderId"
+                            :process="currentProcess"
+                            :page-type="pageType"
+                            :param-list="paramList"
+                            @refresh="refreshParamList" />
   </div>
 </template>
 
 <script setup>
-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, deleteRouteItem, addRouteItem, addOrUpdateProductProcessRouteItem, sortRouteItem } from "@/api/productionManagement/productProcessRoute.js";
-import { processList } from "@/api/productionManagement/productionProcess.js";
-import { useRoute } from 'vue-router'
-import { ElMessageBox } from 'element-plus'
-import Sortable from 'sortablejs'
+  import {
+    ref,
+    computed,
+    getCurrentInstance,
+    onMounted,
+    onUnmounted,
+    nextTick,
+  } from "vue";
+  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+  import ProcessParamListDialog from "@/components/ProcessParamListDialog.vue";
+  import {
+    findProcessRouteItemList,
+    addOrUpdateProcessRouteItem,
+    sortProcessRouteItem,
+    batchDeleteProcessRouteItem,
+    getProcessParamList,
+  } from "@/api/productionManagement/processRouteItem.js";
+  import {
+    findProductProcessRouteItemList,
+    deleteRouteItem,
+    addRouteItem,
+    findProcessParamListOrder,
+    addOrUpdateProductProcessRouteItem,
+    sortRouteItem,
+  } from "@/api/productionManagement/productProcessRoute.js";
+  import { processList } from "@/api/productionManagement/productionProcess.js";
+  import {
+    queryList2,
+    queryList,
+    add2,
+  } from "@/api/productionManagement/productStructure.js";
+  import { useRoute } from "vue-router";
+  import { ElMessageBox, ElMessage } from "element-plus";
+  import Sortable from "sortablejs";
 
-const route = useRoute()
-const { proxy } = getCurrentInstance() || {};
+  const route = useRoute();
+  const { proxy } = getCurrentInstance() || {};
 
-const routeId = computed(() => route.query.id);
-const orderId = computed(() => route.query.orderId);
-const pageType = computed(() => route.query.type);
+  const routeId = computed(() => route.query.id);
+  const orderId = computed(() => route.query.orderId);
+  const pageType = computed(() => route.query.type);
 
-const tableLoading = ref(false);
-const tableData = ref([]);
-const dialogVisible = ref(false);
-const operationType = ref('add'); // add | edit
-const formRef = ref(null);
-const submitLoading = ref(false);
-const cardsContainer = ref(null);
-const tableRef = ref(null);
-const viewMode = ref('table'); // table | card
-const routeInfo = ref({
-  processRouteCode: '',
-  productName: '',
-  model: '',
-  bomNo: '',
-  description: ''
-});
-
-const processOptions = ref([]);
-const showProductSelectDialog = ref(false);
-let tableSortable = null;
-let cardSortable = null;
-
-// 鍒囨崲瑙嗗浘
-const toggleView = () => {
-  viewMode.value = viewMode.value === 'table' ? 'card' : 'table';
-  // 鍒囨崲瑙嗗浘鍚庨噸鏂板垵濮嬪寲鎷栨嫿鎺掑簭
-  nextTick(() => {
-    initSortable();
+  const tableLoading = ref(false);
+  const tableData = ref([]);
+  const dialogVisible = ref(false);
+  const operationType = ref("add"); // add | edit
+  const formRef = ref(null);
+  const submitLoading = ref(false);
+  const cardsContainer = ref(null);
+  const tableRef = ref(null);
+  const viewMode = ref("card"); // table | card
+  const routeInfo = ref({
+    processRouteCode: "",
+    productName: "",
+    model: "",
+    bomNo: "",
+    description: "",
   });
-};
 
-const form = ref({
-  id: undefined,
-  routeId: routeId.value,
-  processId: undefined,
-  productModelId: undefined,
-  productName: "",
-  model: "",
-  unit: "",
-  isQuality: false,
-});
-
-const rules = {
-  processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }],
-  productModelId: [{ required: true, message: '璇烽�夋嫨浜у搧', trigger: 'change' }],
-};
-
-// 鏍规嵁宸ュ簭ID鑾峰彇宸ュ簭鍚嶇О
-const getProcessName = (processId) => {
-  if (!processId) return '';
-  const process = processOptions.value.find(p => p.id === processId);
-  return process ? process.name : '';
-};
-
-// 鑾峰彇鍒楄〃
-const getList = () => {
-  tableLoading.value = true;
-  const listPromise =
-    pageType.value === "order"
-      ? findProductProcessRouteItemList({ orderId: orderId.value })
-      : findProcessRouteItemList({ routeId: routeId.value });
-
-  listPromise
-    .then(res => {
-      tableData.value = res.data || [];
-      tableLoading.value = false;
-      // 鍒楄〃鍔犺浇瀹屾垚鍚庡垵濮嬪寲鎷栨嫿鎺掑簭
-      nextTick(() => {
-        initSortable();
-      });
-    })
-    .catch(err => {
-      tableLoading.value = false;
-      console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
-      proxy?.$modal?.msgError("鑾峰彇鍒楄〃澶辫触");
-    });
-};
-
-// 鑾峰彇宸ュ簭鍒楄〃
-const getProcessList = () => {
-  processList({})
-    .then(res => {
-      processOptions.value = res.data || [];
-    })
-    .catch(err => {
-      console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
-    });
-};
-
-// 鑾峰彇宸ヨ壓璺嚎璇︽儏锛堜粠璺敱鍙傛暟鑾峰彇锛�
-const getRouteInfo = () => {
-  routeInfo.value = {
-    processRouteCode: route.query.processRouteCode || '',
-    productName: route.query.productName || '',
-    model: route.query.model || '',
-    bomNo: route.query.bomNo || '',
-    description: route.query.description || ''
-  };
-};
-
-// 鏂板
-const handleAdd = () => {
-  operationType.value = 'add';
-  resetForm();
-  dialogVisible.value = true;
-};
-
-// 缂栬緫
-const handleEdit = (row) => {
-  operationType.value = 'edit';
-  form.value = {
-    id: row.id,
-    routeId: routeId.value,
-    processId: row.processId,
-    productModelId: row.productModelId,
-    productName: row.productName || "",
-    model: row.model || "",
-    unit: row.unit || "",
-    isQuality: row.isQuality,
-  };
-  dialogVisible.value = true;
-};
-
-// 鍒犻櫎
-const handleDelete = (row) => {
-  ElMessageBox.confirm('纭鍒犻櫎璇ュ伐鑹鸿矾绾块」鐩紵', '鎻愮ず', {
-    confirmButtonText: '纭',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning'
-  })
-    .then(() => {
-      // 鐢熶骇璁㈠崟涓嬩娇鐢� productProcessRoute 鐨勫垹闄ゆ帴鍙o紙璺敱鍚庢嫾鎺� id锛夛紝鍏跺畠鎯呭喌浣跨敤宸ヨ壓璺嚎椤圭洰鎵归噺鍒犻櫎鎺ュ彛
-      const deletePromise =
-        pageType.value === 'order'
-          ? deleteRouteItem(row.id)
-          : batchDeleteProcessRouteItem([row.id]);
-
-      deletePromise
-        .then(() => {
-          proxy?.$modal?.msgSuccess('鍒犻櫎鎴愬姛');
-          getList();
-        })
-        .catch(() => {
-          proxy?.$modal?.msgError('鍒犻櫎澶辫触');
-        });
-    })
-    .catch(() => {});
-};
-
-// 浜у搧閫夋嫨
-const handleProductSelect = (products) => {
-  if (products && products.length > 0) {
-    const product = products[0];
-    form.value.productModelId = product.id;
-    form.value.productName = product.productName;
-    form.value.model = product.model;
-    form.value.unit = product.unit || "";
-    showProductSelectDialog.value = false;
-    // 瑙﹀彂琛ㄥ崟楠岃瘉
-    formRef.value?.validateField('productModelId');
-  }
-};
-
-// 鎻愪氦
-const handleSubmit = () => {
-  formRef.value.validate((valid) => {
-    if (valid) {
-      submitLoading.value = true;
-      
-      if (operationType.value === 'add') {
-        // 鏂板锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玠ragSort瀛楁
-        // dragSort = 褰撳墠鍒楄〃闀垮害 + 1锛岃〃绀烘柊澧炶褰曟帓鍦ㄦ渶鍚�
-        const dragSort = tableData.value.length + 1;
-        const isOrderPage = pageType.value === 'order';
-
-        const addPromise = isOrderPage
-          ? addRouteItem({
-              productOrderId: orderId.value,
-              productRouteId: routeId.value,
-              processId: form.value.processId,
-              productModelId: form.value.productModelId,
-              isQuality: form.value.isQuality,
-              dragSort,
-            })
-          : addOrUpdateProcessRouteItem({
-              routeId: routeId.value,
-              processId: form.value.processId,
-              productModelId: form.value.productModelId,
-              isQuality: form.value.isQuality,
-              dragSort,
-            });
-
-        addPromise
-          .then(() => {
-            proxy?.$modal?.msgSuccess('鏂板鎴愬姛');
-            closeDialog();
-            getList();
-          })
-          .catch(() => {
-            proxy?.$modal?.msgError('鏂板澶辫触');
-          })
-          .finally(() => {
-            submitLoading.value = false;
-          });
-      } else {
-        // 缂栬緫锛氱敓浜ц鍗曚笅浣跨敤 productProcessRoute/updateRouteItem锛屽叾瀹冩儏鍐典娇鐢ㄥ伐鑹鸿矾绾块」鐩洿鏂版帴鍙�
-        const isOrderPage = pageType.value === 'order';
-        
-        const updatePromise = isOrderPage
-          ? addOrUpdateProductProcessRouteItem({
-              id: form.value.id,
-              processId: form.value.processId,
-              productModelId: form.value.productModelId,
-              isQuality: form.value.isQuality,
-            })
-          : addOrUpdateProcessRouteItem({
-              routeId: routeId.value,
-              processId: form.value.processId,
-              productModelId: form.value.productModelId,
-              id: form.value.id,
-              isQuality: form.value.isQuality,
-            });
-
-        updatePromise
-          .then(() => {
-            proxy?.$modal?.msgSuccess('淇敼鎴愬姛');
-            closeDialog();
-            getList();
-          })
-          .catch(() => {
-            proxy?.$modal?.msgError('淇敼澶辫触');
-          })
-          .finally(() => {
-            submitLoading.value = false;
-          });
-      }
-    }
+  const processOptions = ref([]);
+  const showProductSelectDialog = ref(false);
+  const showParamListDialog = ref(false);
+  const currentProcess = ref(null);
+  const paramList = ref([]);
+  const bomTableData = ref([]);
+  const bomFormRef = ref(null);
+  const bomDataValue = ref({
+    dataList: [],
+    showProductDialog: false,
+    currentRowName: null,
+    loading: false,
+    isEdit: false,
   });
-};
+  let tableSortable = null;
+  let cardSortable = null;
 
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
-  form.value = {
+  // 鍒囨崲瑙嗗浘
+  const toggleView = () => {
+    viewMode.value = viewMode.value === "table" ? "card" : "table";
+    // 鍒囨崲瑙嗗浘鍚庨噸鏂板垵濮嬪寲鎷栨嫿鎺掑簭
+    nextTick(() => {
+      initSortable();
+    });
+  };
+
+  const form = ref({
     id: undefined,
     routeId: routeId.value,
     processId: undefined,
@@ -483,414 +519,967 @@
     productName: "",
     model: "",
     unit: "",
+    isQuality: false,
+  });
+
+  const rules = {
+    processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
+    productModelId: [
+      { required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
+    ],
   };
-  formRef.value?.resetFields();
-};
 
-// 鍏抽棴寮圭獥
-const closeDialog = () => {
-  dialogVisible.value = false;
-  resetForm();
-};
+  // 鏍规嵁宸ュ簭ID鑾峰彇宸ュ簭鍚嶇О
+  const getProcessName = processId => {
+    if (!processId) return "";
+    const process = processOptions.value.find(p => p.id === processId);
+    return process ? process.name : "";
+  };
 
-// 鍒濆鍖栨嫋鎷芥帓搴�
-const initSortable = () => {
-  destroySortable();
-  
-  if (viewMode.value === 'table') {
-    // 琛ㄦ牸瑙嗗浘鐨勬嫋鎷芥帓搴�
-    if (!tableRef.value) return;
-    
-    const tbody = tableRef.value.$el.querySelector('.el-table__body tbody') ||
-        tableRef.value.$el.querySelector('.el-table__body-wrapper > table > tbody');
-    
-    if (!tbody) return;
+  // 鑾峰彇鍒楄〃
+  const getList = () => {
+    tableLoading.value = true;
+    const listPromise =
+      pageType.value === "order"
+        ? findProductProcessRouteItemList({ orderId: orderId.value })
+        : findProcessRouteItemList({ routeId: routeId.value });
 
-    tableSortable = new Sortable(tbody, {
-      animation: 150,
-      ghostClass: 'sortable-ghost',
-      handle: '.el-table__row',
-      filter: '.el-button, .el-select',
-      onEnd: (evt) => {
-        if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex]) return;
+    listPromise
+      .then(res => {
+        tableData.value = res.data || [];
+        tableLoading.value = false;
+        // 鍒楄〃鍔犺浇瀹屾垚鍚庡垵濮嬪寲鎷栨嫿鎺掑簭
+        nextTick(() => {
+          initSortable();
+        });
+      })
+      .catch(err => {
+        tableLoading.value = false;
+        console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
+        proxy?.$modal?.msgError("鑾峰彇鍒楄〃澶辫触");
+      });
+  };
 
-        // 閲嶆柊鎺掑簭鏁扮粍
-        const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
-        tableData.value.splice(evt.newIndex, 0, moveItem);
-        
-        // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
-        const newIndex = evt.newIndex;
-        const dragSort = newIndex + 1;
-        
-        // 璋冪敤鎺掑簭鎺ュ彛
-        if (moveItem.id) {
-          const isOrderPage = pageType.value === 'order';
-          const sortPromise = isOrderPage
-            ? sortRouteItem({
-                id: moveItem.id,
-                dragSort: dragSort
-              })
-            : sortProcessRouteItem({
-                id: moveItem.id,
-                dragSort: dragSort
-              });
+  // 鑾峰彇宸ュ簭鍒楄〃
+  const getProcessList = () => {
+    processList({})
+      .then(res => {
+        processOptions.value = res.data || [];
+      })
+      .catch(err => {
+        console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
+      });
+  };
 
-          sortPromise
-            .then(() => {
-              // 鏇存柊鎵�鏈夎鐨刣ragSort
-              tableData.value.forEach((item, index) => {
-                if (item.id) {
-                  item.dragSort = index + 1;
+  // 鑾峰彇宸ヨ壓璺嚎璇︽儏锛堜粠璺敱鍙傛暟鑾峰彇锛�
+  const getRouteInfo = () => {
+    routeInfo.value = {
+      processRouteCode: route.query.processRouteCode || "",
+      productName: route.query.productName || "",
+      model: route.query.model || "",
+      bomNo: route.query.bomNo || "",
+      description: route.query.description || "",
+      status: !(route.query.status == 1 || route.query.status === "false"),
+    };
+    if (pageType.value === "order") {
+      queryList2(route.query.orderId)
+        .then(res => {
+          if (res.data) {
+            // 涓築OM鏁版嵁璁剧疆tempId
+            const setTempIdRecursively = items => {
+              items.forEach(item => {
+                item.tempId = item.id || new Date().getTime();
+                if (item.children && item.children.length > 0) {
+                  setTempIdRecursively(item.children);
                 }
               });
-              proxy?.$modal?.msgSuccess('鎺掑簭鎴愬姛');
+            };
+            setTempIdRecursively(res.data);
+
+            bomTableData.value = [
+              {
+                bomNo: routeInfo.value.bomNo,
+                dictLabel: routeInfo.value.dictLabel,
+                productCode: "",
+                productName: routeInfo.value.productName,
+                model: routeInfo.value.model,
+                bomList: res.data,
+              },
+            ];
+
+            // 淇濆瓨鍘熷BOM鏁版嵁
+            bomDataValue.value.dataList = res.data;
+          }
+        })
+        .catch(err => {
+          console.error("鑾峰彇BOM鏁版嵁澶辫触锛�", err);
+        });
+    } else {
+      queryList(Number(route.query.bomId))
+        .then(res => {
+          if (res.data) {
+            // 涓築OM鏁版嵁璁剧疆tempId
+            const setTempIdRecursively = items => {
+              items.forEach(item => {
+                item.tempId = item.id || new Date().getTime();
+                if (item.children && item.children.length > 0) {
+                  setTempIdRecursively(item.children);
+                }
+              });
+            };
+            setTempIdRecursively(res.data);
+
+            bomTableData.value = [
+              {
+                bomNo: routeInfo.value.bomNo,
+                dictLabel: routeInfo.value.dictLabel,
+                productCode: "",
+                productName: routeInfo.value.productName,
+                model: routeInfo.value.model,
+                bomList: res.data,
+              },
+            ];
+
+            // 淇濆瓨鍘熷BOM鏁版嵁
+            bomDataValue.value.dataList = res.data;
+          }
+        })
+        .catch(err => {
+          console.error("鑾峰彇BOM鏁版嵁澶辫触锛�", err);
+        });
+    }
+  };
+
+  // 鏂板
+  const handleAdd = () => {
+    operationType.value = "add";
+    resetForm();
+    dialogVisible.value = true;
+  };
+
+  // 缂栬緫
+  const handleEdit = row => {
+    operationType.value = "edit";
+    form.value = {
+      id: row.id,
+      routeId: routeId.value,
+      processId: row.processId,
+      productModelId: row.productModelId,
+      productName: row.productName || "",
+      model: row.model || "",
+      unit: row.unit || "",
+      isQuality: row.isQuality,
+    };
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭鍒犻櫎璇ュ伐鑹鸿矾绾块」鐩紵", "鎻愮ず", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        // 鐢熶骇璁㈠崟涓嬩娇鐢� productProcessRoute 鐨勫垹闄ゆ帴鍙o紙璺敱鍚庢嫾鎺� id锛夛紝鍏跺畠鎯呭喌浣跨敤宸ヨ壓璺嚎椤圭洰鎵归噺鍒犻櫎鎺ュ彛
+        const deletePromise =
+          pageType.value === "order"
+            ? deleteRouteItem(row.id)
+            : batchDeleteProcessRouteItem([row.id]);
+
+        deletePromise
+          .then(() => {
+            proxy?.$modal?.msgSuccess("鍒犻櫎鎴愬姛");
+            getList();
+          })
+          .catch(() => {
+            proxy?.$modal?.msgError("鍒犻櫎澶辫触");
+          });
+      })
+      .catch(() => {});
+  };
+
+  // 浜у搧閫夋嫨
+  const handleProductSelect = products => {
+    if (products && products.length > 0) {
+      const product = products[0];
+      form.value.productModelId = product.id;
+      form.value.productName = product.productName;
+      form.value.model = product.model;
+      form.value.unit = product.unit || "";
+      showProductSelectDialog.value = false;
+      // 瑙﹀彂琛ㄥ崟楠岃瘉
+      formRef.value?.validateField("productModelId");
+    }
+  };
+
+  // 鎻愪氦
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        submitLoading.value = true;
+
+        if (operationType.value === "add") {
+          // 鏂板锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玠ragSort瀛楁
+          // dragSort = 褰撳墠鍒楄〃闀垮害 + 1锛岃〃绀烘柊澧炶褰曟帓鍦ㄦ渶鍚�
+          const dragSort = tableData.value.length + 1;
+          const isOrderPage = pageType.value === "order";
+
+          const addPromise = isOrderPage
+            ? addRouteItem({
+                productOrderId: orderId.value,
+                productRouteId: routeId.value,
+                processId: form.value.processId,
+                productModelId: form.value.productModelId,
+                isQuality: form.value.isQuality,
+                dragSort,
+              })
+            : addOrUpdateProcessRouteItem({
+                routeId: routeId.value,
+                processId: form.value.processId,
+                productModelId: form.value.productModelId,
+                isQuality: form.value.isQuality,
+                dragSort,
+              });
+
+          addPromise
+            .then(() => {
+              proxy?.$modal?.msgSuccess("鏂板鎴愬姛");
+              closeDialog();
+              getList();
             })
-            .catch((err) => {
-              // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
-              tableData.value.splice(newIndex, 1);
-              tableData.value.splice(evt.oldIndex, 0, moveItem);
-              proxy?.$modal?.msgError('鎺掑簭澶辫触');
-              console.error("鎺掑簭澶辫触锛�", err);
+            .catch(() => {
+              proxy?.$modal?.msgError("鏂板澶辫触");
+            })
+            .finally(() => {
+              submitLoading.value = false;
+            });
+        } else {
+          // 缂栬緫锛氱敓浜ц鍗曚笅浣跨敤 productProcessRoute/updateRouteItem锛屽叾瀹冩儏鍐典娇鐢ㄥ伐鑹鸿矾绾块」鐩洿鏂版帴鍙�
+          const isOrderPage = pageType.value === "order";
+
+          const updatePromise = isOrderPage
+            ? addOrUpdateProductProcessRouteItem({
+                id: form.value.id,
+                processId: form.value.processId,
+                productModelId: form.value.productModelId,
+                isQuality: form.value.isQuality,
+              })
+            : addOrUpdateProcessRouteItem({
+                routeId: routeId.value,
+                processId: form.value.processId,
+                productModelId: form.value.productModelId,
+                id: form.value.id,
+                isQuality: form.value.isQuality,
+              });
+
+          updatePromise
+            .then(() => {
+              proxy?.$modal?.msgSuccess("淇敼鎴愬姛");
+              closeDialog();
+              getList();
+            })
+            .catch(() => {
+              proxy?.$modal?.msgError("淇敼澶辫触");
+            })
+            .finally(() => {
+              submitLoading.value = false;
             });
         }
       }
     });
-  } else {
-    // 鍗$墖瑙嗗浘鐨勬嫋鎷芥帓搴�
-    if (!cardsContainer.value) return;
+  };
 
-    cardSortable = new Sortable(cardsContainer.value, {
-      animation: 150,
-      ghostClass: 'sortable-ghost',
-      handle: '.process-card',
-      filter: '.el-button',
-      onEnd: (evt) => {
-        if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex]) return;
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    form.value = {
+      id: undefined,
+      routeId: routeId.value,
+      processId: undefined,
+      productModelId: undefined,
+      productName: "",
+      model: "",
+      unit: "",
+    };
+    formRef.value?.resetFields();
+  };
 
-        // 閲嶆柊鎺掑簭鏁扮粍
-        const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
-        tableData.value.splice(evt.newIndex, 0, moveItem);
-        
-        // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
-        const newIndex = evt.newIndex;
-        const dragSort = newIndex + 1;
-        
-        // 璋冪敤鎺掑簭鎺ュ彛
-        if (moveItem.id) {
-          const isOrderPage = pageType.value === 'order';
-          const sortPromise = isOrderPage
-            ? sortRouteItem({
-                id: moveItem.id,
-                dragSort: dragSort
-              })
-            : sortProcessRouteItem({
-                id: moveItem.id,
-                dragSort: dragSort
-              });
+  // 鍏抽棴寮圭獥
+  const closeDialog = () => {
+    dialogVisible.value = false;
+    resetForm();
+  };
 
-          sortPromise
-            .then(() => {
-              // 鏇存柊鎵�鏈夎鐨刣ragSort
-              tableData.value.forEach((item, index) => {
-                if (item.id) {
-                  item.dragSort = index + 1;
-                }
-              });
-              proxy?.$modal?.msgSuccess('鎺掑簭鎴愬姛');
-            })
-            .catch((err) => {
-              // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
-              tableData.value.splice(newIndex, 1);
-              tableData.value.splice(evt.oldIndex, 0, moveItem);
-              proxy?.$modal?.msgError('鎺掑簭澶辫触');
-              console.error("鎺掑簭澶辫触锛�", err);
-            });
+  // 鏌ョ湅鍙傛暟鍒楄〃
+  const handleViewParams = row => {
+    currentProcess.value = row;
+    const query = {
+      routeItemId: row.id,
+      orderId: orderId.value,
+    };
+
+    const apiPromise =
+      pageType.value === "order"
+        ? findProcessParamListOrder(query)
+        : getProcessParamList(query);
+
+    apiPromise
+      .then(res => {
+        paramList.value = res.data || [];
+        showParamListDialog.value = true;
+      })
+      .catch(err => {
+        console.error("鑾峰彇鍙傛暟鍒楄〃澶辫触锛�", err);
+        proxy?.$modal?.msgError("鑾峰彇鍙傛暟鍒楄〃澶辫触");
+      });
+  };
+
+  // 鍒锋柊鍙傛暟鍒楄〃
+  const refreshParamList = () => {
+    if (currentProcess.value) {
+      handleViewParams(currentProcess.value);
+    }
+  };
+
+  // BOM鐩稿叧鏂规硶
+  // 鍒囨崲BOM缂栬緫妯″紡
+  const toggleBomEdit = () => {
+    bomDataValue.value.isEdit = !bomDataValue.value.isEdit;
+    if (!bomDataValue.value.isEdit) {
+      // 鍙栨秷缂栬緫鏃堕噸鏂板姞杞芥暟鎹�
+      getRouteInfo();
+    }
+  };
+
+  // 娣诲姞BOM椤�
+  const addBomItem = () => {
+    if (bomTableData.value.length > 0) {
+      const newItem = {
+        parentId: "",
+        parentTempId: "",
+        productName: "",
+        productId: "",
+        model: undefined,
+        productModelId: undefined,
+        processId: "",
+        processName: "",
+        unitQuantity: 0,
+        demandedQuantity: 0,
+        unit: "",
+        children: [],
+        tempId: new Date().getTime(),
+      };
+      bomTableData.value[0].bomList.push(newItem);
+    }
+  };
+
+  // 娣诲姞BOM瀛愰」
+  const addBomItem2 = tempId => {
+    const addChildItem = (items, tempId) => {
+      for (let i = 0; i < items.length; i++) {
+        const item = items[i];
+        if (item.tempId === tempId) {
+          if (!item.children) {
+            item.children = [];
+          }
+          item.children.push({
+            parentId: item.id || "",
+            parentTempId: item.tempId || "",
+            productName: "",
+            productId: "",
+            model: undefined,
+            productModelId: undefined,
+            processId: "",
+            processName: "",
+            unitQuantity: 0,
+            demandedQuantity: 0,
+            unit: "",
+            children: [],
+            tempId: new Date().getTime(),
+          });
+          return true;
+        }
+        if (item.children && item.children.length > 0) {
+          if (addChildItem(item.children, tempId)) {
+            return true;
+          }
         }
       }
-    });
-  }
-};
+      return false;
+    };
 
-// 閿�姣佹嫋鎷芥帓搴�
-const destroySortable = () => {
-  if (tableSortable) {
-    tableSortable.destroy();
-    tableSortable = null;
-  }
-  if (cardSortable) {
-    cardSortable.destroy();
-    cardSortable = null;
-  }
-};
+    if (bomTableData.value.length > 0) {
+      addChildItem(bomTableData.value[0].bomList, tempId);
+    }
+  };
 
-onMounted(() => {
-  getRouteInfo();
-  getList();
-  getProcessList();
-});
+  // 鍒犻櫎BOM椤�
+  const removeBomItem = tempId => {
+    if (bomTableData.value.length > 0) {
+      const removeFromList = (items, tempId) => {
+        for (let i = 0; i < items.length; i++) {
+          const item = items[i];
+          if (item.tempId === tempId) {
+            items.splice(i, 1);
+            return true;
+          }
+          if (item.children && item.children.length > 0) {
+            if (removeFromList(item.children, tempId)) {
+              return true;
+            }
+          }
+        }
+        return false;
+      };
+      removeFromList(bomTableData.value[0].bomList, tempId);
+    }
+  };
 
-onUnmounted(() => {
-  destroySortable();
-});
+  // 鎵撳紑BOM浜у搧閫夋嫨瀵硅瘽妗�
+  const openBomProductDialog = tempId => {
+    bomDataValue.value.currentRowName = tempId;
+    bomDataValue.value.showProductDialog = true;
+  };
+
+  // 澶勭悊BOM浜у搧閫夋嫨
+  const handleBomProductSelect = products => {
+    if (products && products.length > 0) {
+      const product = products[0];
+      const updateProductInfo = (items, tempId, productData) => {
+        for (let i = 0; i < items.length; i++) {
+          const item = items[i];
+          if (item.tempId === tempId) {
+            item.productName = productData.productName;
+            item.model = productData.model;
+            item.productModelId = productData.id;
+            item.unit = productData.unit || "";
+            return true;
+          }
+          if (item.children && item.children.length > 0) {
+            if (updateProductInfo(item.children, tempId, productData)) {
+              return true;
+            }
+          }
+        }
+        return false;
+      };
+
+      if (bomTableData.value.length > 0) {
+        updateProductInfo(
+          bomTableData.value[0].bomList,
+          bomDataValue.value.currentRowName,
+          product
+        );
+      }
+      bomDataValue.value.showProductDialog = false;
+    }
+  };
+
+  // 淇濆瓨BOM鏇存敼
+  const saveBomChanges = () => {
+    const validateBomData = (items, isTopLevel = false) => {
+      for (let i = 0; i < items.length; i++) {
+        const item = items[i];
+        if (!item.productModelId) {
+          ElMessage.error("璇烽�夋嫨浜у搧");
+          return false;
+        }
+        if (!isTopLevel && !item.processId) {
+          ElMessage.error("璇烽�夋嫨娑堣�楀伐搴�");
+          return false;
+        }
+        if (
+          item.unitQuantity === undefined ||
+          item.unitQuantity === null ||
+          item.unitQuantity === 0
+        ) {
+          ElMessage.error("璇峰~鍐欏崟浣嶄骇鍑烘墍闇�鏁伴噺");
+          return false;
+        }
+        if (
+          pageType.value === "order" &&
+          (item.demandedQuantity === undefined ||
+            item.demandedQuantity === null ||
+            item.demandedQuantity === 0)
+        ) {
+          ElMessage.error("璇疯緭鍏ラ渶姹傛�婚噺");
+          return false;
+        }
+        if (item.children && item.children.length > 0) {
+          if (!validateBomData(item.children, false)) {
+            return false;
+          }
+        }
+      }
+      return true;
+    };
+
+    if (bomTableData.value.length > 0) {
+      if (!validateBomData(bomTableData.value[0].bomList, true)) {
+        return;
+      }
+    }
+
+    const processBomItem = (item, parentId = null, parentTempId = null) => {
+      const cleanItem = {
+        id: item.id || null,
+        orderId: Number(orderId.value) || null,
+        parentId: parentId,
+        parentTempId: parentTempId || null,
+        productModelId: item.productModelId || null,
+        processId: item.processId || null,
+        unitQuantity: item.unitQuantity || 0,
+        demandedQuantity: item.demandedQuantity || 0,
+        unit: item.unit || "",
+        tempId: item.tempId || new Date().getTime(),
+        bomId: Number(route.query.bomId) || null,
+        children: [],
+      };
+
+      if (item.children && item.children.length > 0) {
+        cleanItem.children = item.children.map(child =>
+          processBomItem(child, item.id, item.tempId)
+        );
+      }
+
+      return cleanItem;
+    };
+
+    const saveData = {
+      orderId: Number(orderId.value),
+      bomId: Number(route.query.bomId),
+      children: bomTableData.value[0].bomList.map(item => processBomItem(item)),
+    };
+
+    const savePromise =
+      pageType.value === "order" ? add2(saveData) : add(saveData);
+
+    savePromise
+      .then(() => {
+        proxy?.$modal?.msgSuccess("淇濆瓨鎴愬姛");
+        bomDataValue.value.isEdit = false;
+        getRouteInfo();
+      })
+      .catch(err => {
+        console.error("淇濆瓨BOM澶辫触锛�", err);
+        proxy?.$modal?.msgError("淇濆瓨澶辫触");
+      });
+  };
+
+  // 鍒濆鍖栨嫋鎷芥帓搴�
+  const initSortable = () => {
+    destroySortable();
+
+    if (viewMode.value === "table") {
+      // 琛ㄦ牸瑙嗗浘鐨勬嫋鎷芥帓搴�
+      if (!tableRef.value) return;
+
+      const tbody =
+        tableRef.value.$el.querySelector(".el-table__body tbody") ||
+        tableRef.value.$el.querySelector(
+          ".el-table__body-wrapper > table > tbody"
+        );
+
+      if (!tbody) return;
+
+      tableSortable = new Sortable(tbody, {
+        animation: 150,
+        ghostClass: "sortable-ghost",
+        handle: ".el-table__row",
+        filter: ".el-button, .el-select",
+        onEnd: evt => {
+          if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex])
+            return;
+
+          // 閲嶆柊鎺掑簭鏁扮粍
+          const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
+          tableData.value.splice(evt.newIndex, 0, moveItem);
+
+          // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
+          const newIndex = evt.newIndex;
+          const dragSort = newIndex + 1;
+
+          // 璋冪敤鎺掑簭鎺ュ彛
+          if (moveItem.id) {
+            const isOrderPage = pageType.value === "order";
+            const sortPromise = isOrderPage
+              ? sortRouteItem({
+                  id: moveItem.id,
+                  dragSort: dragSort,
+                })
+              : sortProcessRouteItem({
+                  id: moveItem.id,
+                  dragSort: dragSort,
+                });
+
+            sortPromise
+              .then(() => {
+                // 鏇存柊鎵�鏈夎鐨刣ragSort
+                tableData.value.forEach((item, index) => {
+                  if (item.id) {
+                    item.dragSort = index + 1;
+                  }
+                });
+                proxy?.$modal?.msgSuccess("鎺掑簭鎴愬姛");
+              })
+              .catch(err => {
+                // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
+                tableData.value.splice(newIndex, 1);
+                tableData.value.splice(evt.oldIndex, 0, moveItem);
+                proxy?.$modal?.msgError("鎺掑簭澶辫触");
+                console.error("鎺掑簭澶辫触锛�", err);
+              });
+          }
+        },
+      });
+    } else {
+      // 鍗$墖瑙嗗浘鐨勬嫋鎷芥帓搴�
+      if (!cardsContainer.value) return;
+
+      cardSortable = new Sortable(cardsContainer.value, {
+        animation: 150,
+        ghostClass: "sortable-ghost",
+        handle: ".process-card",
+        filter: ".el-button",
+        onEnd: evt => {
+          if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex])
+            return;
+
+          // 閲嶆柊鎺掑簭鏁扮粍
+          const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
+          tableData.value.splice(evt.newIndex, 0, moveItem);
+
+          // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
+          const newIndex = evt.newIndex;
+          const dragSort = newIndex + 1;
+
+          // 璋冪敤鎺掑簭鎺ュ彛
+          if (moveItem.id) {
+            const isOrderPage = pageType.value === "order";
+            const sortPromise = isOrderPage
+              ? sortRouteItem({
+                  id: moveItem.id,
+                  dragSort: dragSort,
+                })
+              : sortProcessRouteItem({
+                  id: moveItem.id,
+                  dragSort: dragSort,
+                });
+
+            sortPromise
+              .then(() => {
+                // 鏇存柊鎵�鏈夎鐨刣ragSort
+                tableData.value.forEach((item, index) => {
+                  if (item.id) {
+                    item.dragSort = index + 1;
+                  }
+                });
+                proxy?.$modal?.msgSuccess("鎺掑簭鎴愬姛");
+              })
+              .catch(err => {
+                // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
+                tableData.value.splice(newIndex, 1);
+                tableData.value.splice(evt.oldIndex, 0, moveItem);
+                proxy?.$modal?.msgError("鎺掑簭澶辫触");
+                console.error("鎺掑簭澶辫触锛�", err);
+              });
+          }
+        },
+      });
+    }
+  };
+
+  // 閿�姣佹嫋鎷芥帓搴�
+  const destroySortable = () => {
+    if (tableSortable) {
+      tableSortable.destroy();
+      tableSortable = null;
+    }
+    if (cardSortable) {
+      cardSortable.destroy();
+      cardSortable = null;
+    }
+  };
+
+  onMounted(() => {
+    getRouteInfo();
+    getList();
+    getProcessList();
+  });
+
+  onUnmounted(() => {
+    destroySortable();
+  });
 </script>
 
 <style scoped>
-.card-container {
-  padding: 20px 0;
-}
+  .card-container {
+    padding: 20px 0;
+  }
 
-.cards-wrapper {
-  display: flex;
-  gap: 16px;
-  overflow-x: auto;
-  padding: 10px 0;
-  min-height: 200px;
-}
+  .cards-wrapper {
+    display: flex;
+    gap: 16px;
+    overflow-x: auto;
+    padding: 10px 0;
+    min-height: 200px;
+  }
 
-.cards-wrapper::-webkit-scrollbar {
-  height: 8px;
-}
+  .cards-wrapper::-webkit-scrollbar {
+    height: 8px;
+  }
 
-.cards-wrapper::-webkit-scrollbar-track {
-  background: #f1f1f1;
-  border-radius: 4px;
-}
+  .cards-wrapper::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 4px;
+  }
 
-.cards-wrapper::-webkit-scrollbar-thumb {
-  background: #c1c1c1;
-  border-radius: 4px;
-}
+  .cards-wrapper::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 4px;
+  }
 
-.cards-wrapper::-webkit-scrollbar-thumb:hover {
-  background: #a8a8a8;
-}
+  .cards-wrapper::-webkit-scrollbar-thumb:hover {
+    background: #a8a8a8;
+  }
 
-.process-card {
-  flex-shrink: 0;
-  width: 220px;
-  background: #fff;
-  border-radius: 8px;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  padding: 16px;
-  display: flex;
-  flex-direction: column;
-  cursor: move;
-  transition: all 0.3s;
-}
+  .process-card {
+    flex-shrink: 0;
+    width: 220px;
+    background: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+    padding: 16px;
+    display: flex;
+    flex-direction: column;
+    cursor: move;
+    transition: all 0.3s;
+  }
 
-.process-card:hover {
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
-  transform: translateY(-2px);
-}
+  .process-card:hover {
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+    transform: translateY(-2px);
+  }
 
-.card-header {
-  text-align: center;
-  margin-bottom: 12px;
-}
+  .card-header {
+    text-align: center;
+    margin-bottom: 12px;
+  }
 
-.card-number {
-  width: 36px;
-  height: 36px;
-  line-height: 36px;
-  border-radius: 50%;
-  background: #409eff;
-  color: #fff;
-  font-weight: bold;
-  font-size: 16px;
-  margin: 0 auto 8px;
-}
+  .card-number {
+    width: 36px;
+    height: 36px;
+    line-height: 36px;
+    border-radius: 50%;
+    background: #409eff;
+    color: #fff;
+    font-weight: bold;
+    font-size: 16px;
+    margin: 0 auto 8px;
+  }
 
-.card-process-name {
-  font-size: 14px;
-  color: #333;
-  font-weight: 500;
-  word-break: break-all;
-}
+  .card-process-name {
+    font-size: 14px;
+    color: #333;
+    font-weight: 500;
+    word-break: break-all;
+  }
 
-.card-content {
-  flex: 1;
-  margin-bottom: 12px;
-  min-height: 60px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
+  .card-content {
+    flex: 1;
+    margin-bottom: 12px;
+    min-height: 60px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
 
-.product-info {
-  font-size: 13px;
-  color: #666;
-  text-align: center;
-  width: 100%;
-}
+  .product-info {
+    font-size: 13px;
+    color: #666;
+    text-align: center;
+    width: 100%;
+  }
 
-.product-info.empty {
-  color: #999;
-  text-align: center;
-  padding: 20px 0;
-}
+  .product-info.empty {
+    color: #999;
+    text-align: center;
+    padding: 20px 0;
+  }
 
-.product-name {
-  margin-bottom: 6px;
-  word-break: break-all;
-  line-height: 1.5;
-  text-align: center;
-}
+  .product-name {
+    margin-bottom: 6px;
+    word-break: break-all;
+    line-height: 1.5;
+    text-align: center;
+  }
 
-.product-model {
-  color: #909399;
-  font-size: 12px;
-  word-break: break-all;
-  line-height: 1.5;
-  text-align: center;
-}
+  .product-model {
+    color: #909399;
+    font-size: 12px;
+    word-break: break-all;
+    line-height: 1.5;
+    text-align: center;
+  }
 
-.product-unit {
-  margin-left: 4px;
-  color: #409eff;
-}
+  .product-unit {
+    margin-left: 4px;
+    color: #409eff;
+  }
 
-.product-tag {
-  margin: 10px 0;
-}
+  .product-tag {
+    margin: 10px 0;
+  }
 
-.card-footer {
-  display: flex;
-  justify-content: space-around;
-  padding-top: 12px;
-  border-top: 1px solid #f0f0f0;
-}
+  .card-footer {
+    display: flex;
+    justify-content: space-around;
+    padding-top: 12px;
+    border-top: 1px solid #f0f0f0;
+  }
 
-.card-footer .el-button {
-  padding: 0;
-  font-size: 12px;
-}
+  .card-footer .el-button {
+    padding: 0;
+    font-size: 12px;
+  }
 
-:deep(.sortable-ghost) {
-  opacity: 0.5;
-  background-color: #f5f7fa !important;
-}
+  :deep(.sortable-ghost) {
+    opacity: 0.5;
+    background-color: #f5f7fa !important;
+  }
 
-:deep(.sortable-drag) {
-  opacity: 0.8;
-}
+  :deep(.sortable-drag) {
+    opacity: 0.8;
+  }
 
-/* 琛ㄦ牸瑙嗗浘鏍峰紡 */
-:deep(.el-table__row) {
-  transition: background-color 0.2s;
-  cursor: move;
-}
+  /* 琛ㄦ牸瑙嗗浘鏍峰紡 */
+  :deep(.el-table__row) {
+    transition: background-color 0.2s;
+    cursor: move;
+  }
 
-:deep(.el-table__row:hover) {
-  background-color: #f9fafc !important;
-}
+  :deep(.el-table__row:hover) {
+    background-color: #f9fafc !important;
+  }
 
-/* 鍖哄煙鏍囬鏍峰紡 */
-.section-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 12px;
-}
+  /* 鍖哄煙鏍囬鏍峰紡 */
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 12px;
+  }
 
-.section-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #303133;
-  padding-left: 12px;
-  position: relative;
-  margin-bottom: 0;
-}
+  .section-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
+    padding-left: 12px;
+    position: relative;
+    margin-bottom: 0;
+  }
 
-.section-title::before {
-  content: '';
-  position: absolute;
-  left: 0;
-  top: 50%;
-  transform: translateY(-50%);
-  width: 3px;
-  height: 16px;
-  background: #409eff;
-  border-radius: 2px;
-}
+  .section-title::before {
+    content: "";
+    position: absolute;
+    left: 0;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 3px;
+    height: 16px;
+    background: #409eff;
+    border-radius: 2px;
+  }
 
-.section-actions {
-  display: flex;
-  align-items: center;
-}
+  .section-actions {
+    display: flex;
+    align-items: center;
+  }
 
-/* 宸ヨ壓璺嚎淇℃伅鍗$墖鏍峰紡 */
-.route-info-card {
-  margin-bottom: 20px;
-  border: 1px solid #e4e7ed;
-  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
-  border-radius: 8px;
-  overflow: hidden;
-}
+  /* 宸ヨ壓璺嚎淇℃伅鍗$墖鏍峰紡 */
+  .route-info-card {
+    margin-bottom: 20px;
+    border: 1px solid #e4e7ed;
+    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+    border-radius: 8px;
+    overflow: hidden;
+  }
 
-.route-info {
-  display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
-  gap: 16px;
-  padding: 4px;
-}
+  .route-info {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+    gap: 16px;
+    padding: 4px;
+  }
 
-.info-item {
-  display: flex;
-  flex-direction: column;
-  background: #ffffff;
-  border-radius: 6px;
-  padding: 14px 16px;
-  border: 1px solid #f0f2f5;
-  transition: all 0.3s ease;
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
-}
+  .info-item {
+    display: flex;
+    flex-direction: column;
+    background: #ffffff;
+    border-radius: 6px;
+    padding: 14px 16px;
+    border: 1px solid #f0f2f5;
+    transition: all 0.3s ease;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+  }
 
-.info-item:hover {
-  border-color: #409eff;
-  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
-  transform: translateY(-1px);
-}
+  .info-item:hover {
+    border-color: #409eff;
+    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
+    transform: translateY(-1px);
+  }
 
-.info-item.full-width {
-  grid-column: 1 / -1;
-}
+  .info-item.full-width {
+    grid-column: 1 / -1;
+  }
 
-.info-label-wrapper {
-  margin-bottom: 8px;
-}
+  .info-label-wrapper {
+    margin-bottom: 8px;
+  }
 
-.info-label {
-  display: inline-block;
-  color: #909399;
-  font-size: 12px;
-  font-weight: 500;
-  text-transform: uppercase;
-  letter-spacing: 0.5px;
-  padding: 2px 0;
-  position: relative;
-}
+  .info-label {
+    display: inline-block;
+    color: #909399;
+    font-size: 12px;
+    font-weight: 500;
+    text-transform: uppercase;
+    letter-spacing: 0.5px;
+    padding: 2px 0;
+    position: relative;
+  }
 
-.info-label::after {
-  content: '';
-  position: absolute;
-  left: 0;
-  bottom: 0;
-  width: 20px;
-  height: 2px;
-  background: linear-gradient(90deg, #409eff, transparent);
-  border-radius: 1px;
-}
+  .info-label::after {
+    content: "";
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    width: 20px;
+    height: 2px;
+    background: linear-gradient(90deg, #409eff, transparent);
+    border-radius: 1px;
+  }
 
-.info-value-wrapper {
-  flex: 1;
-}
+  .info-value-wrapper {
+    flex: 1;
+  }
 
-.info-value {
-  display: block;
-  color: #303133;
-  font-size: 15px;
-  font-weight: 500;
-  line-height: 1.5;
-  word-break: break-all;
-}
+  .info-value {
+    display: block;
+    color: #303133;
+    font-size: 15px;
+    font-weight: 500;
+    line-height: 1.5;
+    word-break: break-all;
+  }
+
+  .section-BOM {
+    margin-top: 20px;
+  }
+
+  .hover-effect:hover {
+    border-color: #409eff;
+    background-color: #ecf5ff;
+    transform: translateY(-2px);
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  }
 </style>
diff --git a/src/views/productionManagement/productionProcess/Edit.vue b/src/views/productionManagement/productionProcess/Edit.vue
deleted file mode 100644
index fb0ee74..0000000
--- a/src/views/productionManagement/productionProcess/Edit.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="isShow"
-        title="缂栬緫宸ュ簭"
-        width="400"
-        @close="closeModal"
-    >
-      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
-        <el-form-item
-            label="宸ュ簭鍚嶇О锛�"
-            prop="name"
-            :rules="[
-                {
-                required: true,
-                message: '璇疯緭鍏ュ伐搴忓悕绉�',
-              },
-              {
-                max: 100,
-                message: '鏈�澶�100涓瓧绗�',
-              }
-            ]">
-          <el-input v-model="formState.name" />
-        </el-form-item>
-        <el-form-item label="宸ュ簭缂栧彿" prop="no">
-          <el-input v-model="formState.no"  />
-        </el-form-item>
-        <el-form-item
-            label="宸ュ簭绫诲瀷"
-            prop="type"
-            :rules="[
-                {
-                required: true,
-                message: '璇烽�夋嫨宸ュ簭绫诲瀷',
-              }
-            ]"
-        >
-          <el-select v-model="formState.type" placeholder="璇烽�夋嫨宸ュ簭绫诲瀷">
-            <el-option label="璁℃椂" :value="0" />
-            <el-option label="璁′欢" :value="1" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="宸ヨ祫瀹氶" prop="salaryQuota">
-          <el-input v-model="formState.salaryQuota" type="number" :step="0.001" />
-        </el-form-item>
-        <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
-          <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="remark">
-          <el-input v-model="formState.remark" type="textarea" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="handleSubmit">纭</el-button>
-          <el-button @click="closeModal">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import { ref, computed, getCurrentInstance, watch } from "vue";
-import {update} from "@/api/productionManagement/productionProcess.js";
-
-const props = defineProps({
-  visible: {
-    type: Boolean,
-    required: true,
-  },
-
-  record: {
-    type: Object,
-    required: true,
-  }
-});
-
-const emit = defineEmits(['update:visible', 'completed']);
-
-// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
-const formState = ref({
-  id: props.record.id,
-  name: props.record.name,
-  type: props.record.type,
-  no: props.record.no,
-  remark: props.record.remark,
-  salaryQuota: props.record.salaryQuota,
-  isQuality: props.record.isQuality,
-});
-
-const isShow = computed({
-  get() {
-    return props.visible;
-  },
-  set(val) {
-    emit('update:visible', val);
-  },
-});
-
-// 鐩戝惉 record 鍙樺寲锛屾洿鏂拌〃鍗曟暟鎹�
-watch(() => props.record, (newRecord) => {
-  if (newRecord && isShow.value) {
-    formState.value = {
-      id: newRecord.id,
-      name: newRecord.name || '',
-      no: newRecord.no || '',
-      type: newRecord.type,
-      remark: newRecord.remark || '',
-      salaryQuota: newRecord.salaryQuota || '',
-      isQuality: props.record.isQuality,
-    };
-  }
-}, { immediate: true, deep: true });
-
-// 鐩戝惉寮圭獥鎵撳紑锛岄噸鏂板垵濮嬪寲琛ㄥ崟鏁版嵁
-watch(() => props.visible, (visible) => {
-  if (visible && props.record) {
-    formState.value = {
-      id: props.record.id,
-      name: props.record.name || '',
-      no: props.record.no || '',
-      type: props.record.type,
-      remark: props.record.remark || '',
-      salaryQuota: props.record.salaryQuota || '',
-      isQuality: props.record.isQuality,
-    };
-  }
-});
-
-let { proxy } = getCurrentInstance()
-
-const closeModal = () => {
-  isShow.value = false;
-};
-
-const handleSubmit = () => {
-  proxy.$refs["formRef"].validate(valid => {
-    if (valid) {
-      update(formState.value).then(res => {
-        // 鍏抽棴妯℃�佹
-        isShow.value = false;
-        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
-        emit('completed');
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      })
-    }
-  })
-};
-
-defineExpose({
-  closeModal,
-  handleSubmit,
-  isShow,
-});
-</script>
diff --git a/src/views/productionManagement/productionProcess/New.vue b/src/views/productionManagement/productionProcess/New.vue
deleted file mode 100644
index a5f00aa..0000000
--- a/src/views/productionManagement/productionProcess/New.vue
+++ /dev/null
@@ -1,121 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="isShow"
-        title="鏂板宸ュ簭"
-        width="400"
-        @close="closeModal"
-    >
-      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
-        <el-form-item
-            label="宸ュ簭鍚嶇О锛�"
-            prop="name"
-            :rules="[
-                {
-                required: true,
-                message: '璇疯緭鍏ュ伐搴忓悕绉�',
-              },
-              {
-                max: 100,
-                message: '鏈�澶�100涓瓧绗�',
-              }
-            ]">
-          <el-input v-model="formState.name" />
-        </el-form-item>
-        <el-form-item label="宸ュ簭缂栧彿" prop="no">
-          <el-input v-model="formState.no"  />
-        </el-form-item>
-        <el-form-item
-            label="宸ュ簭绫诲瀷"
-            prop="type"
-            :rules="[
-                {
-                required: true,
-                message: '璇烽�夋嫨宸ュ簭绫诲瀷',
-              }
-            ]"
-        >
-          <el-select v-model="formState.type" placeholder="璇烽�夋嫨宸ュ簭绫诲瀷">
-            <el-option label="璁℃椂" :value="0" />
-            <el-option label="璁′欢" :value="1" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="宸ヨ祫瀹氶" prop="salaryQuota">
-          <el-input v-model="formState.salaryQuota" type="number" :step="0.001">
-            <template #append>鍏�</template>
-          </el-input>
-        </el-form-item>
-        <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
-          <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="remark">
-          <el-input v-model="formState.remark" type="textarea" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="handleSubmit">纭</el-button>
-          <el-button @click="closeModal">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import { ref, computed, getCurrentInstance } from "vue";
-import {add} from "@/api/productionManagement/productionProcess.js";
-
-const props = defineProps({
-  visible: {
-    type: Boolean,
-    required: true,
-  },
-});
-
-const emit = defineEmits(['update:visible', 'completed']);
-
-// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
-const formState = ref({
-  name: '',
-  type: undefined,
-  remark: '',
-  salaryQuota:  '',
-  isQuality: false,
-});
-
-const isShow = computed({
-  get() {
-    return props.visible;
-  },
-  set(val) {
-    emit('update:visible', val);
-  },
-});
-
-let { proxy } = getCurrentInstance()
-
-const closeModal = () => {
-  isShow.value = false;
-};
-
-const handleSubmit = () => {
-  proxy.$refs["formRef"].validate(valid => {
-    if (valid) {
-      add(formState.value).then(res => {
-        // 鍏抽棴妯℃�佹
-        isShow.value = false;
-        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
-        emit('completed');
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      })
-    }
-  })
-};
-
-defineExpose({
-  closeModal,
-  handleSubmit,
-  isShow,
-});
-</script>
diff --git a/src/views/productionManagement/productionProcess/index.vue b/src/views/productionManagement/productionProcess/index.vue
index ffe13fc..c52fa65 100644
--- a/src/views/productionManagement/productionProcess/index.vue
+++ b/src/views/productionManagement/productionProcess/index.vue
@@ -1,319 +1,1090 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
-      <el-form :model="searchForm"
-               :inline="true">
-        <el-form-item label="宸ュ簭鍚嶇О:">
-          <el-input v-model="searchForm.name"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    prefix-icon="Search"
-                    style="width: 200px;"
-                    @change="handleQuery" />
-        </el-form-item>
-        <el-form-item label="宸ュ簭缂栧彿:">
-          <el-input v-model="searchForm.no"
-                    placeholder="璇疯緭鍏�"
-                    clearable
-                    prefix-icon="Search"
-                    style="width: 200px;"
-                    @change="handleQuery" />
-        </el-form-item>
-        <el-form-item>
+    <div class="process-config-container">
+      <!-- 宸︿晶宸ュ簭鍒楄〃 -->
+      <div class="process-list-section">
+        <div class="section-header">
+          <h3 class="section-title">宸ュ簭鍒楄〃</h3>
           <el-button type="primary"
-                     @click="handleQuery">鎼滅储</el-button>
+                     size="small"
+                     @click="handleAddProcess">
+            <el-icon>
+              <Plus />
+            </el-icon>鏂板宸ュ簭
+          </el-button>
+        </div>
+        <div class="process-card-list"
+             v-loading="processLoading">
+          <div v-for="process in processValueList"
+               :key="process.id"
+               class="process-card"
+               :class="{ active: selectedProcess?.id === process.id }"
+               @click="selectProcess(process)">
+            <div class="card-header">
+              <div class="process-name">{{ process.name }} <span class="process-code">{{ process.no }}</span></div>
+              <div class="card-actions">
+                <el-button link
+                           type="primary"
+                           @click.stop="handleEditProcess(process)">
+                  <el-icon>
+                    <Edit />
+                  </el-icon>
+                  缂栬緫
+                </el-button>
+                <el-button link
+                           type="danger"
+                           @click.stop="handleDeleteProcess(process)">
+                  <el-icon>
+                    <Delete />
+                  </el-icon>
+                  鍒犻櫎
+                </el-button>
+              </div>
+            </div>
+            <div class="card-body">
+              <!-- <div class="process-name">{{ process.name }}</div> -->
+              <div class="process-desc">{{ process.remark || '鏆傛棤鎻忚堪' }}</div>
+              <div class="process-device">鍏宠仈璁惧: {{ process.deviceName || '鏈叧鑱�' }}</div>
+            </div>
+            <div class="card-footer">
+              <div class="status-tag"> <el-tag size="small"
+                        :type="process.status ? 'success' : 'info'">
+                  {{ process.status ? '鍚敤' : '鍋滅敤' }}
+                </el-tag>
+                <el-tag size="small"
+                        :type="process.isQuality ? 'warning' : 'info'"
+                        style="margin-left: 8px">
+                  {{ process.isQuality ? '璐ㄦ' : '闈炶川妫�' }}
+                </el-tag>
+                <el-tag v-if="process.type !== null && process.type !== undefined"
+                        size="small"
+                        :type="process.type == 1 ? 'primary' : 'success'"
+                        style="margin-left: 8px">
+                  {{ process.type == 0 ? '璁℃椂' : '璁′欢' }}
+                </el-tag>
+              </div>
+              <span class="param-count">宸ヨ祫瀹氶: 楼{{ process.salaryQuota || 0 }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 鍙充晶鍙傛暟鍒楄〃 -->
+      <div class="param-list-section">
+        <div class="section-header">
+          <h3 class="section-title">
+            {{ selectedProcess ? selectedProcess.name + ' - 鍙傛暟閰嶇疆' : '璇烽�夋嫨宸ュ簭' }}
+          </h3>
+          <el-button type="primary"
+                     size="small"
+                     :disabled="!selectedProcess"
+                     @click="openParamDialog">
+            <el-icon>
+              <Plus />
+            </el-icon>閫夋嫨鍙傛暟
+          </el-button>
+        </div>
+        <div class="param-table-wrapper">
+          <PIMTable v-if="selectedProcess"
+                    rowKey="id"
+                    :column="paramColumn"
+                    :tableData="paramList"
+                    :page="paramPage2"
+                    height="calc(100vh - 280px)"
+                    :isSelection="false"
+                    @pagination="handleParamPagination" />
+          <div v-else
+               class="empty-tip">
+            <el-empty description="璇蜂粠宸︿晶閫夋嫨涓�涓伐搴�" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 宸ュ簭鏂板/缂栬緫瀵硅瘽妗� -->
+    <el-dialog v-model="processDialogVisible"
+               :title="isProcessEdit ? '缂栬緫宸ュ簭' : '鏂板宸ュ簭'"
+               width="500px">
+      <el-form :model="processForm"
+               :rules="processRules"
+               ref="processFormRef"
+               label-width="100px">
+        <el-form-item label="宸ュ簭缂栫爜"
+                      prop="no">
+          <el-input v-model="processForm.no"
+                    placeholder="璇疯緭鍏ュ伐搴忕紪鐮�" />
+        </el-form-item>
+        <el-form-item label="宸ュ簭鍚嶇О"
+                      prop="name">
+          <el-input v-model="processForm.name"
+                    placeholder="璇疯緭鍏ュ伐搴忓悕绉�" />
+        </el-form-item>
+        <el-form-item label="宸ヨ祫瀹氶"
+                      prop="salaryQuota">
+          <el-input v-model="processForm.salaryQuota"
+                    type="number"
+                    :step="0.001" />
+        </el-form-item>
+        <el-form-item label="鏄惁璐ㄦ"
+                      prop="isQuality">
+          <el-switch v-model="processForm.isQuality" />
+        </el-form-item>
+        <el-form-item label="璁¤垂绫诲瀷"
+                      prop="type">
+          <el-radio-group v-model="processForm.type">
+            <el-radio :label="0">璁℃椂</el-radio>
+            <el-radio :label="1">璁′欢</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鍏宠仈璁惧"
+                      prop="deviceLedgerId">
+          <el-select v-model="processForm.deviceLedgerId"
+                     placeholder="璇烽�夋嫨璁惧"
+                     clearable
+                     filterable
+                     style="width: 100%">
+            <el-option v-for="item in deviceOptions"
+                       :key="item.id"
+                       :label="item.deviceName"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="宸ュ簭鎻忚堪"
+                      prop="remark">
+          <el-input v-model="processForm.remark"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="璇疯緭鍏ュ伐搴忔弿杩�" />
+        </el-form-item>
+        <el-form-item label="鐘舵��"
+                      prop="status">
+          <el-radio-group v-model="processForm.status">
+            <el-radio :label="true">鍚敤</el-radio>
+            <el-radio :label="false">鍋滅敤</el-radio>
+          </el-radio-group>
         </el-form-item>
       </el-form>
-    </div>
-    <div class="table_list">
-      <div style="text-align: right"
-           class="mb10">
-        <el-button type="primary"
-                   @click="showNewModal">鏂板宸ュ簭</el-button>
-        <el-button type="info"
-                   plain
-                   @click="handleImport">瀵煎叆</el-button>
-        <el-button type="danger"
-                   @click="handleDelete"
-                   :disabled="selectedRows.length === 0"
-                   plain>鍒犻櫎宸ュ簭</el-button>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="processDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleProcessSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- 閫夋嫨鍙傛暟瀵硅瘽妗� -->
+    <el-dialog v-model="paramDialogVisible"
+               title="閫夋嫨鍙傛暟"
+               width="1000px">
+      <div class="param-select-container">
+        <!-- 宸︿晶鍙傛暟鍒楄〃 -->
+        <div class="param-list-area">
+          <div class="area-title">鍙�夊弬鏁�</div>
+          <div class="search-box">
+            <el-input v-model="paramSearchKeyword"
+                      placeholder="璇疯緭鍏ュ弬鏁板悕绉版悳绱�"
+                      clearable
+                      size="small"
+                      @input="handleSelectParam">
+              <template #prefix>
+                <el-icon>
+                  <Search />
+                </el-icon>
+              </template>
+            </el-input>
+          </div>
+          <el-table :data="filteredParamList"
+                    height="300"
+                    border
+                    highlight-current-row
+                    @current-change="handleParamSelect">
+            <el-table-column prop="paramName"
+                             label="鍙傛暟鍚嶇О" />
+            <el-table-column prop="paramType"
+                             label="鍙傛暟绫诲瀷">
+              <template #default="scope">
+                <el-tag size="small"
+                        :type="getParamTypeTag(scope.row.paramType)">
+                  {{ getParamTypeText(scope.row.paramType) }}
+                </el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- 鍒嗛〉鎺т欢 -->
+          <div class="pagination-container"
+               style="margin-top: 10px;">
+            <el-pagination v-model:current-page="paramPage.current"
+                           v-model:page-size="paramPage.size"
+                           :page-sizes="[10, 20, 50, 100]"
+                           layout="total, sizes, prev, pager, next, jumper"
+                           :total="paramPage.total"
+                           @size-change="handleParamSizeChange"
+                           @current-change="handleParamCurrentChange"
+                           size="small" />
+          </div>
+        </div>
+        <!-- 鍙充晶鍙傛暟璇︽儏 -->
+        <div class="param-detail-area">
+          <div class="area-title">鍙傛暟璇︽儏</div>
+          <el-form v-if="selectedParam"
+                   :model="selectedParam"
+                   label-width="100px"
+                   class="param-detail-form">
+            <el-form-item label="鍙傛暟鍚嶇О">
+              <span class="detail-text">{{ selectedParam.paramName }}</span>
+            </el-form-item>
+            <el-form-item label="鍙傛暟绫诲瀷">
+              <el-tag size="small"
+                      :type="getParamTypeTag(selectedParam.paramType)">
+                {{ getParamTypeText(selectedParam.paramType) }}
+              </el-tag>
+            </el-form-item>
+            <el-form-item label="鍙傛暟鏍煎紡">
+              <span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span>
+            </el-form-item>
+            <el-form-item label="鍗曚綅">
+              <span class="detail-text">{{ selectedParam.unit || '-' }}</span>
+            </el-form-item>
+            <el-form-item label="鏍囧噯鍊�">
+              <el-input v-model="selectedParam.standardValue"
+                        type="number"
+                        placeholder="璇疯緭鍏ラ粯璁ゅ��" />
+            </el-form-item>
+          </el-form>
+          <el-empty v-else
+                    description="璇蜂粠宸︿晶閫夋嫨鍙傛暟" />
+        </div>
       </div>
-      <PIMTable rowKey="id"
-                :column="tableColumn"
-                :tableData="tableData"
-                :page="page"
-                :isSelection="true"
-                @selection-change="handleSelectionChange"
-                :tableLoading="tableLoading"
-                @pagination="pagination"
-                :total="page.total"></PIMTable>
-    </div>
-    <new-process v-if="isShowNewModal"
-                 v-model:visible="isShowNewModal"
-                 @completed="getList" />
-    <edit-process v-if="isShowEditModal"
-                  v-model:visible="isShowEditModal"
-                  :record="record"
-                  @completed="getList" />
-    <ImportDialog ref="importDialogRef"
-                  v-model="importDialogVisible"
-                  title="瀵煎叆宸ュ簭"
-                  :action="importAction"
-                  :headers="importHeaders"
-                  :auto-upload="false"
-                  :on-success="handleImportSuccess"
-                  :on-error="handleImportError"
-                  @confirm="handleImportConfirm"
-                  @download-template="handleDownloadTemplate"
-                  @close="handleImportClose" />
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="paramDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     :disabled="!selectedParam"
+                     @click="handleParamSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- 缂栬緫鍙傛暟瀵硅瘽妗� -->
+    <el-dialog v-model="editParamDialogVisible"
+               title="缂栬緫鍙傛暟"
+               width="600px">
+      <el-form :model="editParamForm"
+               :rules="editParamRules"
+               ref="editParamFormRef"
+               label-width="120px">
+        <el-form-item label="鍙傛暟鍚嶇О">
+          <span class="detail-text">{{ editParamForm.paramName }}</span>
+        </el-form-item>
+        <el-form-item label="鏍囧噯鍊�"
+                      prop="standardValue">
+          <el-input v-model="editParamForm.standardValue"
+                    type="number"
+                    placeholder="璇疯緭鍏ユ爣鍑嗗��" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="editParamDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleEditParamSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-  import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
-  import NewProcess from "@/views/productionManagement/productionProcess/New.vue";
-  import EditProcess from "@/views/productionManagement/productionProcess/Edit.vue";
-  import ImportDialog from "@/components/Dialog/ImportDialog.vue";
+  import { ref, reactive, onMounted } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Plus, Edit, Delete, Search } from "@element-plus/icons-vue";
+  import PIMTable from "@/components/PIMTable/PIMTable.vue";
+  import { listType } from "@/api/system/dict/type";
   import {
-    listPage,
+    add,
+    update,
     del,
-    importData,
-    downloadTemplate,
+    list as getProcessListApi,
+    processList,
+    getProcessParamList,
+    addProcessParam,
+    editProcessParam,
+    deleteProcessParam,
   } from "@/api/productionManagement/productionProcess.js";
-  import { getToken } from "@/utils/auth";
+  import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+  import { getBaseParamList } from "@/api/basicData/parameterMaintenance.js";
 
-  const data = reactive({
-    searchForm: {
-      name: "",
-      no: "",
-    },
+  // 宸ュ簭鍒楄〃鏁版嵁
+  const processValueList = ref([]);
+  const selectedProcess = ref(null);
+  const processLoading = ref(false);
+  const deviceOptions = ref([]);
+
+  // 鍙傛暟鍒楄〃鏁版嵁
+  const paramList = ref([]);
+  const paramLoading = ref(false);
+
+  // 鏁版嵁瀛楀吀
+  const dictTypes = ref([]);
+
+  // 宸ュ簭瀵硅瘽妗�
+  const processDialogVisible = ref(false);
+  const isProcessEdit = ref(false);
+  const processFormRef = ref(null);
+  const processForm = reactive({
+    id: null,
+    no: "",
+    name: "",
+    salaryQuota: null,
+    isQuality: false,
+    remark: "",
+    status: true,
+    deviceLedgerId: null,
+    type: 0,
   });
-  const { searchForm } = toRefs(data);
-  const tableColumn = ref([
+  const processRules = {
+    no: [{ required: true, message: "璇疯緭鍏ュ伐搴忕紪鐮�", trigger: "blur" }],
+    name: [{ required: true, message: "璇疯緭鍏ュ伐搴忓悕绉�", trigger: "blur" }],
+    salaryQuota: [
+      {
+        required: false,
+        message: "璇疯緭鍏ュ伐璧勫畾棰�",
+        trigger: "blur",
+        validator: (rule, value, callback) => {
+          if (isNaN(value) || value < 0) {
+            callback(new Error("宸ヨ祫瀹氶蹇呴』鏄潪璐熸暟瀛�"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+    deviceLedgerId: [
+      { required: false, message: "璇烽�夋嫨璁惧", trigger: "change" },
+    ],
+    type: [{ required: false, message: "璇烽�夋嫨璁¤垂绫诲瀷", trigger: "change" }],
+  };
+
+  // 鍙傛暟瀵硅瘽妗�
+  const paramDialogVisible = ref(false);
+  const availableParamList = ref([]);
+  const filteredParamList = ref([]);
+  const selectedParam = ref(null);
+  const paramSearchKeyword = ref("");
+
+  // 鍙�夊弬鏁板垎椤�
+  const paramPage = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 缂栬緫鍙傛暟瀵硅瘽妗�
+  const editParamDialogVisible = ref(false);
+  const editParamFormRef = ref(null);
+  const editParamForm = reactive({
+    id: null,
+    processId: null,
+    paramId: null,
+    paramName: "",
+    standardValue: null,
+    tenantId: 1,
+  });
+  const editParamRules = {
+    standardValue: [
+      {
+        required: true,
+        message: "璇疯緭鍏ユ爣鍑嗗��",
+        trigger: "blur",
+        validator: (rule, value, callback) => {
+          if (value === null || value === undefined || value === "") {
+            callback(new Error("璇疯緭鍏ユ爣鍑嗗��"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+  };
+
+  // 鍙傛暟琛ㄦ牸鍒楅厤缃�
+  const paramColumn = ref([
     {
-      label: "宸ュ簭缂栧彿",
-      prop: "no",
+      label: "鍙傛暟鍚嶇О",
+      prop: "paramName",
     },
     {
-      label: "宸ュ簭鍚嶇О",
-      prop: "name",
-    },
-    {
-      label: "宸ュ簭绫诲瀷",
-      prop: "typeText",
-    },
-    {
-      label: "宸ヨ祫瀹氶",
-      prop: "salaryQuota",
-    },
-    {
-      label: "鏄惁璐ㄦ",
-      prop: "isQuality",
-      formatData: (params) => {
-        return params ? "鏄�" : "鍚�";
+      label: "鍙傛暟绫诲瀷",
+      prop: "paramType",
+      dataType: "tag",
+      formatType: params => {
+        const typeMap = {
+          1: "primary",
+          2: "info",
+          3: "warning",
+          4: "success",
+        };
+        return typeMap[params] || "default";
+      },
+      formatData: val => {
+        const labelMap = {
+          1: "鏁板�兼牸寮�",
+          2: "鏂囨湰鏍煎紡",
+          3: "涓嬫媺閫夐」",
+          4: "鏃堕棿鏍煎紡",
+        };
+        return labelMap[val] || val;
       },
     },
     {
-      label: "澶囨敞",
-      prop: "remark",
+      label: "鍙栧�兼牸寮�",
+      prop: "paramFormat",
+      formatData: (val, row) => {
+        if (row.paramType == "3") {
+          const dict = dictTypes.value.find(item => item.dictType === val);
+          return dict ? "瀛楀吀:" + dict.dictName : val;
+        }
+        return val;
+      },
     },
     {
-      label: "鏇存柊鏃堕棿",
-      prop: "updateTime",
+      label: "鏍囧噯鍊�",
+      prop: "standardValue",
     },
     {
-      dataType: "action",
+      label: "鍗曚綅",
+      prop: "unit",
+    },
+    {
       label: "鎿嶄綔",
-      align: "center",
-      fixed: "right",
-      width: 280,
+      dataType: "action",
+      width: "150",
       operation: [
         {
           name: "缂栬緫",
-          type: "text",
-          clickFun: row => {
-            showEditModal(row);
-          },
+          clickFun: row => handleEditParam(row),
+        },
+        {
+          name: "鍒犻櫎",
+          clickFun: row => handleDeleteParam(row),
         },
       ],
     },
   ]);
-  const tableData = ref([]);
-  const selectedRows = ref([]);
-  const tableLoading = ref(false);
-  const isShowNewModal = ref(false);
-  const isShowEditModal = ref(false);
-  const record = ref({});
-  const importDialogVisible = ref(false);
-  const importDialogRef = ref(null);
-  const page = reactive({
+
+  // 鑾峰彇宸ュ簭鍒楄〃
+  const getProcessList = () => {
+    processLoading.value = true;
+    getProcessListApi()
+      .then(res => {
+        processValueList.value = res.data.records || [];
+      })
+      .catch(() => {
+        ElMessage.error("鑾峰彇宸ュ簭鍒楄〃澶辫触");
+      })
+      .finally(() => {
+        processLoading.value = false;
+      });
+  };
+
+  const loadDeviceName = async () => {
+    try {
+      const { data } = await getDeviceLedger();
+      deviceOptions.value = data || [];
+    } catch (error) {
+      console.error("鍔犺浇璁惧鍒楄〃澶辫触", error);
+    }
+  };
+
+  const paramPage2 = ref({
     current: 1,
-    size: 100,
+    size: 10,
     total: 0,
   });
-  const { proxy } = getCurrentInstance();
 
-  // 瀵煎叆鐩稿叧閰嶇疆
-  const importAction =
-    import.meta.env.VITE_APP_BASE_API + "/productProcess/importData";
-  const importHeaders = { Authorization: "Bearer " + getToken() };
-
-  // 鏌ヨ鍒楄〃
-  /** 鎼滅储鎸夐挳鎿嶄綔 */
-  const handleQuery = () => {
-    page.current = 1;
-    getList();
-  };
-
-  const pagination = obj => {
-    page.current = obj.page;
-    page.size = obj.limit;
-    getList();
-  };
-  const getList = () => {
-    tableLoading.value = true;
-    const params = { ...searchForm.value, ...page };
-    params.entryDate = undefined;
-    listPage(params)
+  // 鑾峰彇鍙傛暟鍒楄〃
+  const getParamList = processId => {
+    paramLoading.value = true;
+    console.log(paramPage2.value, "paramPage2.value");
+    getProcessParamList(processId, {
+      current: paramPage2.value.current,
+      size: paramPage2.value.size,
+    })
       .then(res => {
-        tableLoading.value = false;
-        tableData.value = res.data.records.map(item => ({
-          ...item,
-          typeText: item.type !== undefined && item.type !== null ? (item.type === 0 ? "璁℃椂" : "璁′欢") : "",
-        }));
-        page.total = res.data.total;
+        paramList.value = res.data.records || [];
+        paramPage2.value.total = res.data.total;
       })
-      .catch(err => {
-        tableLoading.value = false;
+      .catch(() => {
+        ElMessage.error("鑾峰彇鍙傛暟鍒楄〃澶辫触");
+      })
+      .finally(() => {
+        paramLoading.value = false;
       });
   };
-  // 琛ㄦ牸閫夋嫨鏁版嵁
-  const handleSelectionChange = selection => {
-    selectedRows.value = selection;
+
+  // 閫夋嫨宸ュ簭
+  const selectProcess = process => {
+    selectedProcess.value = process;
+    getParamList(process.id);
   };
 
-  // 鎵撳紑鏂板寮规
-  const showNewModal = () => {
-    isShowNewModal.value = true;
+  // 宸ュ簭鎿嶄綔
+  const handleAddProcess = () => {
+    isProcessEdit.value = false;
+    processForm.id = null;
+    processForm.no = "";
+    processForm.name = "";
+    processForm.salaryQuota = null;
+    processForm.isQuality = false;
+    processForm.remark = "";
+    processForm.status = true;
+    processForm.deviceLedgerId = null;
+    processForm.type = 0;
+    loadDeviceName();
+    processDialogVisible.value = true;
   };
 
-  const showEditModal = row => {
-    isShowEditModal.value = true;
-    record.value = row;
+  const handleEditProcess = async process => {
+    isProcessEdit.value = true;
+    await loadDeviceName(); // Ensure deviceOptions is loaded before setting deviceLedgerId
+    processForm.id = process.id;
+    processForm.no = process.no;
+    processForm.name = process.name;
+    processForm.salaryQuota = process.salaryQuota;
+    processForm.isQuality = !!process.isQuality;
+    processForm.remark = process.remark || "";
+    processForm.status = process.status;
+    processForm.deviceLedgerId = Number(process.deviceLedgerId);
+    processForm.type = process.type;
+    processDialogVisible.value = true;
   };
 
-  // 鍒犻櫎
-  function handleDelete() {
-    const no = selectedRows.value.map(item => item.no);
-    const ids = selectedRows.value.map(item => item.id);
-    if (no.length > 2) {
-      proxy.$modal
-        .confirm(
-          '鏄惁纭鍒犻櫎宸ュ簭缂栧彿涓�"' +
-            no[0] +
-            "銆�" +
-            no[1] +
-            '"绛�' +
-            no.length +
-            "鏉℃暟鎹」锛�"
-        )
-        .then(function () {
-          return del(ids);
-        })
+  const handleDeleteProcess = process => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ宸ュ簭鍚楋紵", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      del([process.id])
         .then(() => {
-          getList();
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          ElMessage.success("鍒犻櫎鎴愬姛");
+          getProcessList();
+          if (selectedProcess.value?.id === process.id) {
+            selectedProcess.value = null;
+            paramList.value = [];
+          }
         })
-        .catch(() => {});
-    } else {
-      proxy.$modal
-        .confirm('鏄惁纭鍒犻櫎宸ュ簭缂栧彿涓�"' + no + '"鐨勬暟鎹」锛�')
-        .then(function () {
-          return del(ids);
-        })
-        .then(() => {
-          getList();
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-        })
-        .catch(() => {});
-    }
-  }
-
-  // 瀵煎叆
-  const handleImport = () => {
-    importDialogVisible.value = true;
+        .catch(() => {
+          ElMessage.error("鍒犻櫎澶辫触");
+        });
+    });
   };
 
-  // 纭瀵煎叆
-  const handleImportConfirm = () => {
-    if (importDialogRef.value) {
-      importDialogRef.value.submit();
-    }
-  };
-
-  // 瀵煎叆鎴愬姛
-  const handleImportSuccess = response => {
-    if (response.code === 200) {
-      proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
-      importDialogVisible.value = false;
-      if (importDialogRef.value) {
-        importDialogRef.value.clearFiles();
+  const handleProcessSubmit = () => {
+    processFormRef.value.validate(valid => {
+      if (valid) {
+        if (processForm.id) {
+          update(processForm)
+            .then(() => {
+              ElMessage.success("缂栬緫鎴愬姛");
+              processDialogVisible.value = false;
+              getProcessList();
+            })
+            .catch(() => {
+              ElMessage.error("缂栬緫澶辫触");
+            });
+        } else {
+          add(processForm)
+            .then(() => {
+              ElMessage.success("鏂板鎴愬姛");
+              processDialogVisible.value = false;
+              getProcessList();
+            })
+            .catch(() => {
+              ElMessage.error("鏂板澶辫触");
+            });
+        }
       }
-      getList();
-    } else {
-      proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+    });
+  };
+  const openParamDialog = () => {
+    paramSearchKeyword.value = "";
+    if (!selectedProcess.value) {
+      ElMessage.warning("璇峰厛閫夋嫨涓�涓伐搴�");
+      return;
     }
+    // 鑾峰彇鍙�夊弬鏁板垪琛�
+    getBaseParamList({
+      paramName: paramSearchKeyword.value,
+      current: paramPage.current,
+      size: paramPage.size,
+    }).then(res => {
+      if (res.code === 200) {
+        filteredParamList.value = res.data?.records || [];
+        paramPage.total = res.data?.total || 0;
+      } else {
+        ElMessage.error(res.msg || "鏌ヨ澶辫触");
+      }
+    });
+    console.log(filteredParamList.value, "鍙�夊弬鏁板垪琛�");
+    selectedParam.value = null;
+    paramDialogVisible.value = true;
   };
 
-  // 瀵煎叆澶辫触
-  const handleImportError = error => {
-    proxy.$modal.msgError("瀵煎叆澶辫触锛�" + (error.message || "鏈煡閿欒"));
-  };
-
-  // 鍏抽棴瀵煎叆寮圭獥
-  const handleImportClose = () => {
-    if (importDialogRef.value) {
-      importDialogRef.value.clearFiles();
+  // 鍙傛暟鎿嶄綔
+  const handleSelectParam = () => {
+    if (!selectedProcess.value) {
+      ElMessage.warning("璇峰厛閫夋嫨涓�涓伐搴�");
+      return;
     }
+    // 鑾峰彇鍙�夊弬鏁板垪琛�
+    getBaseParamList({
+      paramName: paramSearchKeyword.value,
+      current: paramPage.current,
+      size: paramPage.size,
+    }).then(res => {
+      if (res.code === 200) {
+        filteredParamList.value = res.data?.records || [];
+        paramPage.total = res.data?.total || 0;
+      } else {
+        ElMessage.error(res.msg || "鏌ヨ澶辫触");
+      }
+    });
+    console.log(filteredParamList.value, "鍙�夊弬鏁板垪琛�");
+    selectedParam.value = null;
+    paramDialogVisible.value = true;
   };
 
-  // 涓嬭浇妯℃澘
-  const handleDownloadTemplate = async () => {
-    try {
-      const res = await downloadTemplate();
-      const blob = new Blob([res], {
-        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+  const handleParamSelect = row => {
+    selectedParam.value = row;
+  };
+
+  const handleParamSearch = () => {
+    // 閲嶇疆鍒嗛〉
+    paramPage.current = 1;
+    // 閲嶆柊鍔犺浇鏁版嵁
+    handleSelectParam();
+  };
+
+  // 澶勭悊鍒嗛〉澶у皬鍙樺寲
+  const handleParamSizeChange = size => {
+    paramPage.size = size;
+    handleSelectParam();
+  };
+
+  // 澶勭悊褰撳墠椤电爜鍙樺寲
+  const handleParamCurrentChange = current => {
+    paramPage.current = current;
+    handleSelectParam();
+  };
+  const getParamTypeText = type => {
+    const typeMap = {
+      1: "鏁板�兼牸寮�",
+      2: "鏂囨湰鏍煎紡",
+      3: "涓嬫媺閫夐」",
+      4: "鏃堕棿鏍煎紡",
+    };
+    return typeMap[type] || "鏈煡鍙傛暟绫诲瀷";
+  };
+  const getParamTypeTag = type => {
+    const typeMap = {
+      1: "primary",
+      2: "info",
+      3: "warning",
+      4: "success",
+    };
+    return typeMap[type] || "default";
+  };
+
+  const handleDeleteParam = row => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ鍙傛暟鍚楋紵", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      deleteProcessParam(row.id)
+        .then(() => {
+          ElMessage.success("鍒犻櫎鎴愬姛");
+          getParamList(selectedProcess.value.id);
+        })
+        .catch(() => {
+          ElMessage.error("鍒犻櫎澶辫触");
+        });
+    });
+  };
+
+  const handleEditParam = row => {
+    editParamForm.id = row.id;
+    editParamForm.processId = row.processId;
+    editParamForm.paramId = row.paramId;
+    editParamForm.paramName = row.paramName;
+    editParamForm.standardValue = row.standardValue;
+    editParamForm.tenantId = 1;
+    editParamDialogVisible.value = true;
+  };
+
+  const handleEditParamSubmit = () => {
+    editParamFormRef.value.validate(valid => {
+      if (valid) {
+        editProcessParam(editParamForm)
+          .then(() => {
+            ElMessage.success("缂栬緫鎴愬姛");
+            editParamDialogVisible.value = false;
+            getParamList(selectedProcess.value.id);
+          })
+          .catch(() => {
+            ElMessage.error("缂栬緫澶辫触");
+          });
+      }
+    });
+  };
+
+  const handleParamSubmit = () => {
+    if (!selectedParam.value) {
+      ElMessage.warning("璇峰厛閫夋嫨涓�涓弬鏁�");
+      return;
+    }
+    addProcessParam({
+      processId: selectedProcess.value.id,
+      paramId: selectedParam.value.id,
+      standardValue: selectedParam.value.standardValue,
+      tenantId: 1,
+    })
+      .then(() => {
+        ElMessage.success("娣诲姞鎴愬姛");
+        paramDialogVisible.value = false;
+        getParamList(selectedProcess.value.id);
+      })
+      .catch(() => {
+        ElMessage.error("娣诲姞澶辫触");
       });
-      const url = window.URL.createObjectURL(blob);
-      const link = document.createElement("a");
-      link.href = url;
-      link.download = "宸ュ簭瀵煎叆妯℃澘.xlsx";
-      link.click();
-      window.URL.revokeObjectURL(url);
-      proxy.$modal.msgSuccess("妯℃澘涓嬭浇鎴愬姛");
-    } catch (error) {
-      proxy.$modal.msgError("妯℃澘涓嬭浇澶辫触");
-    }
   };
 
-  // 瀵煎嚭
-  // const handleOut = () => {
-  // 	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-  // 		confirmButtonText: "纭",
-  // 		cancelButtonText: "鍙栨秷",
-  // 		type: "warning",
-  // 	})
-  // 		.then(() => {
-  // 			proxy.download("/salesLedger/scheduling/exportTwo", {}, "宸ュ簭鎺掍骇.xlsx");
-  // 		})
-  // 		.catch(() => {
-  // 			proxy.$modal.msg("宸插彇娑�");
-  // 		});
-  // };
+  const handleParamPagination = obj => {
+    console.log(obj, "obj");
+    paramPage2.value.current = obj.page;
+    paramPage2.value.size = obj.limit;
+    getParamList(selectedProcess.value.id);
+  };
+
+  // 鑾峰彇鏁版嵁瀛楀吀
+  const getDictTypes = () => {
+    listType({ pageNum: 1, pageSize: 1000 }).then(res => {
+      dictTypes.value = res.rows || [];
+    });
+  };
 
   onMounted(() => {
-    getList();
+    getProcessList();
+    getDictTypes();
   });
 </script>
 
-<style scoped></style>
+<style scoped lang="scss">
+  .app-container {
+    padding: 20px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 84px);
+  }
+
+  .process-config-container {
+    display: flex;
+    gap: 20px;
+    height: calc(100vh - 124px);
+  }
+
+  // 宸︿晶宸ュ簭鍒楄〃
+  .process-list-section {
+    width: 370px;
+    min-width: 370px;
+    flex-shrink: 0;
+    background: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    display: flex;
+    flex-direction: column;
+  }
+
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 16px 20px;
+    border-bottom: 1px solid #ebeef5;
+
+    .section-title {
+      margin: 0;
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
+    }
+  }
+
+  .process-card-list {
+    flex: 1;
+    overflow-y: auto;
+    padding: 16px;
+  }
+
+  .process-card {
+    background: #fff;
+    border: 1px solid #ebeef5;
+    border-radius: 8px;
+    padding: 16px;
+    margin-bottom: 12px;
+    cursor: pointer;
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+      transform: translateY(-2px);
+    }
+
+    &.active {
+      border-color: #409eff;
+      background: #f5f7fa;
+      box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
+    }
+
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 8px;
+
+      .process-code {
+        font-size: 12px;
+        // color: #909399;
+        color: #cb9b18;
+        font-family: "Courier New", monospace;
+      }
+
+      .card-actions {
+        display: flex;
+        gap: 4px;
+
+        .el-button {
+          padding: 4px;
+        }
+      }
+    }
+
+    .card-body {
+      margin-bottom: 12px;
+
+      .process-name {
+        font-size: 16px;
+        font-weight: 600;
+        color: #303133;
+        margin-bottom: 4px;
+      }
+
+      .process-desc {
+        font-size: 12px;
+        color: #909399;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        margin-bottom: 4px;
+      }
+
+      .process-device {
+        font-size: 12px;
+        color: #606266;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+
+    .card-footer {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+
+      .param-count {
+        font-size: 12px;
+        color: #606266;
+      }
+    }
+  }
+
+  // 鍙充晶鍙傛暟鍒楄〃
+  .param-list-section {
+    flex: 1;
+    background: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    display: flex;
+    flex-direction: column;
+    min-width: 0;
+  }
+
+  .param-table-wrapper {
+    flex: 1;
+    padding: 0 20px 20px;
+    overflow: auto;
+    min-width: 100%;
+  }
+
+  /* 琛ㄦ牸妯悜婊氬姩 */
+  .param-table-wrapper :deep(.el-table) {
+    min-width: 100%;
+  }
+
+  .param-table-wrapper :deep(.el-table__body-wrapper) {
+    overflow-x: auto;
+  }
+
+  .pagination-container {
+    margin-top: 10px;
+    overflow-x: auto;
+    padding-bottom: 8px;
+  }
+
+  .pagination-container .el-pagination {
+    white-space: nowrap;
+  }
+
+  /* 鍝嶅簲寮忚皟鏁� */
+  @media screen and (max-width: 768px) {
+    .pagination-container {
+      font-size: 12px;
+    }
+
+    .pagination-container .el-pagination__sizes {
+      margin-right: 8px;
+    }
+
+    .pagination-container .el-pagination__jump {
+      margin-left: 8px;
+    }
+
+    .pagination-container .el-pagination__page-size {
+      font-size: 12px;
+    }
+  }
+
+  .empty-tip {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  // 琛ㄦ牸鏍峰紡
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-table__header-wrapper {
+      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+
+      th {
+        background: transparent;
+        font-weight: 600;
+        // color: #ffffff;
+        border-bottom: none;
+        padding: 16px 0;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background: linear-gradient(
+            90deg,
+            rgba(102, 126, 234, 0.05) 0%,
+            rgba(118, 75, 162, 0.05) 100%
+          );
+        }
+
+        td {
+          border-bottom: 1px solid #f0f0f0;
+          padding: 14px 0;
+          color: #303133;
+        }
+      }
+    }
+  }
+
+  // 缂栫爜鍗曞厓鏍兼牱寮�
+  :deep(.code-cell) {
+    color: #e6a23c;
+    font-family: "Courier New", monospace;
+    font-weight: 500;
+  }
+
+  // 鏁板�煎崟鍏冩牸鏍峰紡
+  :deep(.quantity-cell) {
+    font-weight: 600;
+    color: #409eff;
+    font-family: "Courier New", monospace;
+  }
+
+  // 閫夋嫨鍙傛暟瀵硅瘽妗嗘牱寮�
+  .param-select-container {
+    display: flex;
+    gap: 20px;
+    height: 450px;
+
+    .param-list-area {
+      // flex: 1;
+      width: 380px;
+      display: flex;
+      flex-direction: column;
+
+      .area-title {
+        font-size: 14px;
+        font-weight: 600;
+        color: #303133;
+        margin-bottom: 12px;
+        padding-bottom: 8px;
+        border-bottom: 1px solid #ebeef5;
+      }
+
+      .search-box {
+        margin-bottom: 12px;
+
+        .el-input {
+          width: 100%;
+        }
+      }
+    }
+
+    .param-detail-area {
+      // width: 380px;
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      background: #f5f7fa;
+      border-radius: 8px;
+      padding: 16px;
+
+      .area-title {
+        font-size: 14px;
+        font-weight: 600;
+        color: #303133;
+        margin-bottom: 16px;
+        padding-bottom: 8px;
+        border-bottom: 1px solid #ebeef5;
+      }
+
+      .param-detail-form {
+        .el-form-item {
+          margin-bottom: 12px;
+
+          .el-form-item__label {
+            color: #606266;
+            font-weight: 500;
+          }
+        }
+
+        .detail-text {
+          color: #303133;
+          font-weight: 500;
+        }
+      }
+    }
+  }
+</style>

--
Gitblit v1.9.3