From cac302f302084ab310d0e35339f30966a4829a4e Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期五, 23 一月 2026 12:18:28 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/assets/images/chartCard3.svg                                                     |    1 
 src/views/collaborativeApproval/notificationManagement/summary/index.vue             |    8 
 src/views/financialManagement/accounting/index.vue                                   |  199 
 src/api/salesManagement/indicatorStats.js                                            |   20 
 src/views/personnelManagement/scheduling/index.vue                                   |   10 
 src/api/productionManagement/workOrder.js                                            |   25 
 src/views/basicData/product/index.vue                                                |    2 
 src/api/inventoryManagement/stockInRecord.js                                         |   27 
 src/views/financialManagement/loanManagement/Modal.vue                               |  222 
 src/views/qualityManagement/metricMaintenance/index0.vue                             |  415 
 src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue         |    1 
 src/views/productionManagement/productionDispatching/index.vue                       |  464 
 src/views/salesManagement/paymentShipping/index.vue                                  |   25 
 src/api/inventoryManagement/stockInventory.js                                        |   27 
 src/views/collaborativeApproval/sealManagement/index.vue                             |    4 
 src/views/productionManagement/productStructure/index.vue                            |  340 
 src/views/salesManagement/salespersonManagement/index.vue                            |   21 
 src/api/inventoryManagement/stockManage.js                                           |   27 
 src/views/salesManagement/invoiceLedger/index.vue                                    |   90 
 src/views/productionManagement/processRoute/New.vue                                  |  194 
 src/views/personnelManagement/contractManagement/components/formDia.vue              |   39 
 src/views/inventoryManagement/receiptManagement/index.vue                            |  679 
 src/views/collaborativeApproval/shipmentReview/index.vue                             |  340 
 src/views/inventoryManagement/stockManagement/index.vue                              |  342 
 src/views/personnelManagement/employeeRecord/components/RenewContract.vue            |  141 
 src/views/equipmentManagement/ledger/index.vue                                       |   67 
 src/views/procurementManagement/invoiceEntry/components/Modal.vue                    |  935 
 src/api/qualityManagement/qualityTestStandardBinding.js                              |   28 
 src/views/inventoryManagement/dispatchLog/index.vue                                  |  205 
 src/views/personnelManagement/analytics/index.vue                                    |  228 
 src/store/modules/user.js                                                            |    3 
 src/views/reportAnalysis/projectProfit/index.vue                                     |  186 
 src/api/productionManagement/productionReporting.js                                  |   10 
 src/views/financialManagement/revenueManagement/index.vue                            |  249 
 src/api/qualityManagement/metricMaintenance.js                                       |  119 
 src/views/productionManagement/productStructure/StructureEdit.vue                    |  311 
 src/views/personnelManagement/employeeRecord/components/Show.vue                     |    2 
 src/api/productionManagement/productionProductOutput.js                              |   11 
 src/layout/components/NotificationCenter/index.vue                                   |    4 
 src/views/reportAnalysis/reportManagement/index.vue                                  | 1908 ++
 src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue         |    8 
 src/api/viewIndex.js                                                                 |   18 
 src/api/reportAnalysis/qualityReport.js                                              |   52 
 src/views/salesManagement/orderManagement/index.vue                                  |   19 
 src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue         |    7 
 src/views/salesManagement/receiptPaymentHistory/index.vue                            |  123 
 src/views/collaborativeApproval/noticeManagement/index.vue                           |   46 
 src/views/procurementManagement/returnManagement/index.vue                           |    9 
 src/views/productionManagement/processRoute/index.vue                                |  204 
 src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue   |    1 
 src/views/equipmentManagement/upkeep/Form/PlanModal.vue                              |  188 
 src/views/reportAnalysis/dataDashboard/index.vue                                     |  843 +
 src/views/productionManagement/processRoute/processRouteItem/index.vue               |  876 +
 src/views/procurementManagement/invoiceEntry/index.vue                               |   24 
 src/views/salesManagement/receiptPaymentLedger/index.vue                             |   29 
 src/views/collaborativeApproval/approvalProcess/index.vue                            |    9 
 src/views/procurementManagement/paymentEntry/index.vue                               |  370 
 src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue                    |   78 
 src/views/salesManagement/salesLedger/index.vue                                      |  254 
 src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue     |   12 
 src/views/personnelManagement/selfService/index.vue                                  |   12 
 src/views/qualityManagement/metricBinding/index.vue                                  |  504 
 src/api/personnelManagement/employeeRecord.js                                        |    9 
 src/api/productionManagement/processRouteItem.js                                     |   38 
 src/api/productionManagement/processRoute.js                                         |   42 
 src/views/salesManagement/salesLedger/fileList.vue                                   |   43 
 src/api/salesManagement/receiptPayment.js                                            |    2 
 src/views/qualityManagement/processInspection/components/inspectionFormDia.vue       |    1 
 src/views/equipmentManagement/spareParts/index.vue                                   |    7 
 src/views/procurementManagement/procurementReport/index.vue                          |  834 -
 src/views/salesManagement/receiptPayment/index.vue                                   |  386 
 src/views/productionManagement/productionReporting/Output.vue                        |  106 
 src/views/system/dept/index.vue                                                      |  451 
 src/api/procurementManagement/procurementInvoiceLedger.js                            |    2 
 src/assets/images/chartCard.svg                                                      |    1 
 src/components/PIMTable/PIMTable.vue                                                 |   26 
 src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue           |   55 
 src/components/QRCodeGenerator/index.vue                                             |  859 
 src/views/salesManagement/invoiceRegistration/index.vue                              | 1254 +
 src/views/productionManagement/productionReporting/Input.vue                         |  115 
 src/views/qualityManagement/finalInspection/components/filesDia.vue                  |    1 
 src/api/collaborativeApproval/shipmentReview.js                                      |   21 
 src/views/lavorissue/ledger/Form.vue                                                 |   10 
 src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue         |   97 
 src/api/collaborativeApproval/noticeManagement.js                                    |   86 
 src/views/collaborativeApproval/notificationManagement/index.vue                     |    2 
 src/api/inventoryManagement/stockOut.js                                              |   40 
 src/api/basicData/productModel.js                                                    |    9 
 src/api/basicData/productProcess.js                                                  |   10 
 src/views/equipmentManagement/upkeep/Form/formDia.vue                                |  304 
 src/views/procurementManagement/transferManagement/index.vue                         |    9 
 src/views/inventoryManagement/stockManagement/Subtract.vue                           |  183 
 src/views/productionManagement/productionReporting/components/formDia.vue            |   39 
 src/views/productionManagement/productionProcess/index.vue                           |  302 
 src/views/basicData/product/ProductSelectDialog.vue                                  |  163 
 src/views/personnelManagement/payrollManagement/components/formDia.vue               |   14 
 src/views/personnelManagement/payrollManagement/index.vue                            |    1 
 src/views/collaborativeApproval/rulesRegulationsManagement/index.vue                 | 1076 +
 src/views/equipmentManagement/measurementEquipment/components/formDia.vue            |   96 
 src/api/productionManagement/productionOrder.js                                      |   97 
 src/api/inventoryManagement/stockIn.js                                               |   87 
 src/components/PageHeader/index.vue                                                  |   53 
 src/views/financialManagement/revenueManagement/Modal.vue                            |  192 
 src/views/personnelManagement/contractManagement/index.vue                           |   14 
 src/views/equipmentManagement/ledger/Form.vue                                        |   74 
 src/views/productionManagement/productionProcess/Edit.vue                            |  132 
 src/assets/images/chartCard2.svg                                                     |    1 
 src/api/personnelManagement/staffAnalytics.js                                        |   26 
 src/views/procurementManagement/procurementPlan/index.vue                            |   52 
 src/views/qualityManagement/metricMaintenance/index.vue                              | 1161 +
 vite.config.js                                                                       |    4 
 src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue |    5 
 src/views/procurementManagement/advancedPriceManagement/index.vue                    |   25 
 src/api/financialManagement/loanManagement.js                                        |   37 
 src/views/financialManagement/financialStatements/index.vue                          |  194 
 src/views/equipmentManagement/upkeep/index.vue                                       |   44 
 src/views/qualityManagement/processInspection/components/formDia.vue                 |  127 
 src/views/collaborativeApproval/shipmentReview/fileList.vue                          |   43 
 src/views/inventoryManagement/stockManagement/New.vue                                |  163 
 src/views/salesManagement/deliveryLedger/index.vue                                   |   13 
 src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue         |    8 
 src/views/procurementManagement/procurementLedger/fileList.vue                       |   67 
 src/views/productionManagement/operationScheduling/components/formDia.vue            |  121 
 src/views/equipmentManagement/repair/Modal/MaintainModal.vue                         |  115 
 src/views/personnelManagement/employeeRecord/index.vue                               |   82 
 src/views/equipmentManagement/repair/Modal/RepairModal.vue                           |  190 
 src/views/financialManagement/loanManagement/index.vue                               |  271 
 src/views/salesManagement/salesQuotation/index.vue                                   |  639 
 src/views/productionManagement/operationScheduling/index.vue                         |   47 
 src/api/productionManagement/productProcessRoute.js                                  |   54 
 src/views/financialManagement/expenseManagement/index.vue                            |  245 
 src/views/procurementManagement/procurementLedger/index.vue                          | 3248 ++--
 src/views/qualityManagement/nonconformingManagement/components/formDia.vue           |    5 
 src/views/equipmentManagement/measurementEquipment/index.vue                         |  142 
 src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue  |  153 
 src/views/productionManagement/productionReporting/index.vue                         |  822 
 src/main.js                                                                          |    3 
 src/views/qualityManagement/rawMaterialInspection/components/formDia.vue             |  110 
 src/api/productionManagement/productionProductMain.js                                |   11 
 src/views/productionManagement/productionOrder/index.vue                             |  567 
 src/api/system/message.js                                                            |    2 
 src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue                       |  123 
 src/views/productionManagement/productionProcess/New.vue                             |   99 
 src/views/procurementManagement/paymentHistory/index.vue                             |   87 
 src/api/productionManagement/productionProductInput.js                               |   11 
 src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue       |  128 
 src/views/procurementManagement/qualityInspection/index.vue                          |    9 
 multiple/config.json                                                                 |  404 
 src/views/productionManagement/workOrder/index.vue                                   |  653 +
 src/layout/components/Navbar.vue                                                     |   73 
 src/views/procurementManagement/purchaseOrder/index.vue                              |    9 
 src/views/productionManagement/productionDispatching/components/formDia.vue          |   26 
 src/views/productManagement/productIdentifier/index.vue                              | 1187 +
 src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue           |  125 
 src/views/productionManagement/processRoute/ItemsForm.vue                            |  531 
 src/api/personnelManagement/staffContract.js                                         |   10 
 src/api/productionManagement/productStructure.js                                     |   18 
 src/api/productionManagement/productBom.js                                           |   47 
 src/components/Dialog/FileListDialog.vue                                             |    7 
 src/views/collaborativeApproval/enterpriseBook/index.vue                             |    6 
 src/views/financialManagement/expenseManagement/Modal.vue                            |  192 
 src/views/qualityManagement/finalInspection/components/formDia.vue                   |  112 
 src/api/productionManagement/productionProcess.js                                    |   69 
 src/views/productionManagement/productionCosting/index.vue                           |   32 
 src/views/equipmentManagement/repair/index.vue                                       |   59 
 src/views/procurementManagement/arrivalManagement/index.vue                          |    9 
 src/views/procurementManagement/priceManagement/index.vue                            |    9 
 src/api/equipmentManagement/measurementEquipment.js                                  |   20 
 src/views/procurementManagement/paymentLedger/index.vue                              |   45 
 src/views/productionManagement/productStructure/Detail/index.vue                     |  300 
 /dev/null                                                                            |  727 -
 src/views/personnelManagement/dimission/components/formDia.vue                       |  425 
 src/views/system/user/index.vue                                                      | 1230 -
 src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue                 |  129 
 src/views/login.vue                                                                  |   23 
 src/api/personnelManagement/staffLeave.js                                            |   33 
 src/views/salesManagement/indicatorStats/index.vue                                   |  377 
 src/api/personnelManagement/staffOnJob.js                                            |   54 
 src/api/system/post.js                                                               |    9 
 src/api/procurementManagement/procurementReport.js                                   |   11 
 src/views/personnelManagement/contractManagement/filesDia.vue                        |   10 
 src/views/productionManagement/processRoute/Edit.vue                                 |  252 
 src/views/personnelManagement/dimission/index.vue                                    |   60 
 src/api/financialManagement/accounting.js                                            |   28 
 184 files changed, 23,474 insertions(+), 12,049 deletions(-)

diff --git a/multiple/config.json b/multiple/config.json
index 9fb34b8..7ad6795 100644
--- a/multiple/config.json
+++ b/multiple/config.json
@@ -10,412 +10,12 @@
   "TEST": {
     "env": {
       "VITE_APP_TITLE": "涓皬浼佷笟鏁板瓧鍖栬浆鍨嬩簩绾у椁愬寘",
-      "VITE_BASE_API": "http://114.132.189.42:9036",
-      "VITE_JAVA_API": "http://114.132.189.42:9037"
+      "VITE_BASE_API": "http://1.15.17.182:9003",
+      "VITE_JAVA_API": "http://1.15.17.182:9002"
     },
     "screen": "screen/HYSNView.png",
     "logo": "logo/ZGLTLogo.png",
     "favicon": "favicon/favicon.ico"
-  },
-  "LC": {
-    "env": {
-      "VITE_APP_TITLE": "涓皬浼佷笟鏁板瓧鍖栬浆鍨嬩簩绾у椁愬寘",
-      "VITE_BASE_API": "http://114.132.189.42:9036",
-      "VITE_JAVA_API": "http://114.132.189.42:9037"
-    },
-    "screen": "screen/HYSNView.png",
-    "logo": "logo/LCLogo.png",
-    "favicon": "favicon/favicon.ico"
-  },
-  "WDSY": {
-    "env": {
-      "VITE_APP_TITLE": "浼熷痉瀹炰笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:8068",
-      "VITE_JAVA_API": "http://114.132.189.42:8085"
-    },
-    "screen": "screen/WDSYView.png",
-    "logo": "logo/WDSYLogo.png",
-    "favicon": "favicon/WDSYico.ico"
-  },
-  "JZYJ": {
-    "env": {
-      "VITE_APP_TITLE": "鍩烘櫤娌逛簳淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:8078",
-      "VITE_JAVA_API": "http://114.132.189.42:8086"
-    },
-    "screen": "screen/JZYJView.png",
-    "logo": "logo/JZYJLogo.png",
-    "favicon": "favicon/JZYJico.ico"
-  },
-  "ZQHX": {
-    "env": {
-      "VITE_APP_TITLE": "涓己鎭掑叴淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:1234",
-      "VITE_JAVA_API": "http://114.132.189.42:8080"
-    },
-    "screen": "screen/ZQHXView.png",
-    "logo": "logo/ZQHXLogo.png",
-    "favicon": "favicon/ZQHXico.ico"
-  },
-  "XYHB": {
-    "env": {
-      "VITE_APP_TITLE": "瀹e惫鐜繚淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9052",
-      "VITE_JAVA_API": "http://114.132.189.42:9051"
-    },
-    "screen": "screen/XYHBView.png",
-    "logo": "logo/XYHBLogo.png",
-    "favicon": "favicon/XYHBico.ico"
-  },
-  "BHMY": {
-    "env": {
-      "VITE_APP_TITLE": "鍗氬畯鐓や笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9070",
-      "VITE_JAVA_API": "http://114.132.189.42:9069"
-    },
-    "screen": "screen/ZQHXView.png",
-    "logo": "logo/BHMYLogo.png",
-    "favicon": "favicon/BHMY.ico"
-  },
-  "HHKJ": {
-    "env": {
-      "VITE_APP_TITLE": "鎭掓櫀绉戞妧淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9046",
-      "VITE_JAVA_API": "http://114.132.189.42:9047"
-    },
-    "screen": "screen/HHKJView.png",
-    "logo": "logo/HHKJLogo.png",
-    "favicon": "favicon/HHKJIco.ico"
-  },
-  "RZNY": {
-    "env": {
-      "VITE_APP_TITLE": "閿愭嫨鑳芥簮淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9058",
-      "VITE_JAVA_API": "http://114.132.189.42:9057"
-    },
-    "screen": "screen/RZNYView.png",
-    "logo": "logo/RZNYLogo.png",
-    "favicon": "favicon/RZNY.ico"
-  },
-  "TJXM": {
-    "env": {
-      "VITE_APP_TITLE": "娉版睙娲楃叅淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9064",
-      "VITE_JAVA_API": "http://114.132.189.42:9063"
-    },
-    "screen": "screen/TJXMView.png",
-    "logo": "logo/TJXMLogo.png",
-    "favicon": "favicon/TJXM.ico"
-  },
-  "HYSN": {
-    "env": {
-      "VITE_APP_TITLE": "寮樹篃姘存偿淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9034",
-      "VITE_JAVA_API": "http://114.132.189.42:9035"
-    },
-    "screen": "screen/HYSNView.png",
-    "logo": "logo/HYSNLogo.png",
-    "favicon": "favicon/HYSNico.ico"
-  },
-  "JYHJ": {
-    "env": {
-      "VITE_APP_TITLE": "閲戦拱榛勯噾淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9030",
-      "VITE_JAVA_API": "http://114.132.189.42:9031"
-    },
-    "screen": "screen/HYSNView.png",
-    "logo": "logo/JYHJLogo.png",
-    "favicon": "favicon/JYHJico.ico"
-  },
-  "DHDC": {
-    "env": {
-      "VITE_APP_TITLE": "鏁︾厡榧庤瘹淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9032",
-      "VITE_JAVA_API": "http://114.132.189.42:9033"
-    },
-    "screen": "screen/DHDCView.png",
-    "logo": "logo/DHDCLogo.png",
-    "favicon": "favicon/DHDCico.ico"
-  },
-  "MXSC": {
-    "env": {
-      "VITE_APP_TITLE": "闂藉叴鐭虫潗淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9048",
-      "VITE_JAVA_API": "http://114.132.189.42:9049"
-    },
-    "screen": "screen/MXSCBack.png",
-    "logo": "logo/MXSCLogo.png",
-    "favicon": "favicon/MXSCIco.ico"
-  },
-  "CJNY": {
-    "env": {
-      "VITE_APP_TITLE": "鍒涘法鑳芥簮淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9038",
-      "VITE_JAVA_API": "http://114.132.189.42:9039"
-    },
-    "screen": "screen/MXSCBack.png",
-    "logo": "logo/CJNYLogo.png",
-    "favicon": "favicon/CJNYico.ico"
-  },
-  "JSMY": {
-    "env": {
-      "VITE_APP_TITLE": "閲戠煶鐓や笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9042",
-      "VITE_JAVA_API": "http://114.132.189.42:9043"
-    },
-    "screen": "screen/MXSCBack.png",
-    "logo": "logo/JSMYLogo.png",
-    "favicon": "favicon/JSMYico.ico"
-  },
-  "JSYNY": {
-    "env": {
-      "VITE_APP_TITLE": "閿︾洓婧愯兘婧愪俊鎭鐞嗙郴缁�",
-      "VITE_BASE_API": "http://114.132.189.42:9074",
-      "VITE_JAVA_API": "http://114.132.189.42:9073"
-    },
-    "screen": "screen/HYSNView.png",
-    "logo": "logo/JSYNYLogo.png",
-    "favicon": "favicon/JSYNYico.ico"
-  },
-  "CMNY": {
-    "env": {
-      "VITE_APP_TITLE": "鍒涢摥鑳芥簮淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9088",
-      "VITE_JAVA_API": "http://114.132.189.42:9087"
-    },
-    "screen": "screen/DHDCView.png",
-    "logo": "logo/CMNYLogo.png",
-    "favicon": "favicon/CMNYico.ico"
-  },
-  "HCKX": {
-    "env": {
-      "VITE_APP_TITLE": "娴峰窛寮�蹇冮鍝佷俊鎭鐞嗙郴缁�",
-      "VITE_BASE_API": "http://114.132.189.42:9090",
-      "VITE_JAVA_API": "http://114.132.189.42:9089"
-    },
-    "screen": "screen/HCKXView.png",
-    "logo": "logo/HCKXLogo.png",
-    "favicon": "favicon/HCKXico.ico"
-  },
-  "JLSN": {
-    "env": {
-      "VITE_APP_TITLE": "閿﹂緳姘存偿淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9094",
-      "VITE_JAVA_API": "http://114.132.189.42:9093"
-    },
-    "screen": "screen/JLSNView.png",
-    "logo": "logo/JLSNLogo.png",
-    "favicon": "favicon/JLSNico.ico"
-  },
-  "BDSM": {
-    "env": {
-      "VITE_APP_TITLE": "鍗氳揪鍟嗚锤淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9096",
-      "VITE_JAVA_API": "http://114.132.189.42:9095"
-    },
-    "screen": "screen/BDSMView.png",
-    "logo": "logo/BDSMLogo.png",
-    "favicon": "favicon/BDSMico.ico"
-  },
-  "HXGY": {
-    "env": {
-      "VITE_APP_TITLE": "姹囨槦閽欎笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9098",
-      "VITE_JAVA_API": "http://114.132.189.42:9097"
-    },
-    "screen": "screen/HXGYView.png",
-    "logo": "logo/HXGYLogo.png",
-    "favicon": "favicon/HXGYico.ico"
-  },
-  "ZDXM": {
-    "env": {
-      "VITE_APP_TITLE": "鏄痉鍨嬬叅淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9100",
-      "VITE_JAVA_API": "http://114.132.189.42:9096"
-    },
-    "screen": "screen/ZDXMView.png",
-    "logo": "logo/ZDXMLogo.png",
-    "favicon": "favicon/ZDXMico.ico"
-  },
-  "HSX": {
-    "env": {
-      "VITE_APP_TITLE": "婀熸按宄″啘涓氬彂灞曚俊鎭鐞嗙郴缁�",
-      "VITE_BASE_API": "http://114.132.189.42:9101",
-      "VITE_JAVA_API": "http://114.132.189.42:9098"
-    },
-    "screen": "screen/HSXView.png",
-    "logo": "logo/HSXLogo.png",
-    "favicon": "favicon/HSXico.ico"
-  },
-  "NYDL": {
-    "env": {
-      "VITE_APP_TITLE": "鍗楁磱鐢电紗浜ч摼閫氫俊鎭鐞嗙郴缁�",
-      "VITE_BASE_API": "http://114.132.189.42:9036",
-      "VITE_JAVA_API": "http://114.132.189.42:9037"
-    },
-    "screen": "screen/NYDLView.png",
-    "logo": "logo/NYDLLogo.png",
-    "favicon": "favicon/NYDLico.ico"
-  },
-  "HCMY": {
-    "env": {
-      "VITE_APP_TITLE": "娴╂垚鐓や笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9103",
-      "VITE_JAVA_API": "http://114.132.189.42:9094"
-    },
-    "screen": "screen/HCMYView.png",
-    "logo": "logo/HCMYLogo.png",
-    "favicon": "favicon/HCMYico.ico"
-  },
-  "HGJJ": {
-    "env": {
-      "VITE_APP_TITLE": "姹囧浗娲佸噣鍨嬬叅淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9107",
-      "VITE_JAVA_API": "http://114.132.189.42:9090"
-    },
-    "screen": "screen/HGJJView.png",
-    "logo": "logo/HGJJLogo.png",
-    "favicon": "favicon/HGJJico.ico"
-  },
-  "MKZS": {
-    "env": {
-      "VITE_APP_TITLE": "妯″嚡鍐嶇敓淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9111",
-      "VITE_JAVA_API": "http://114.132.189.42:9086"
-    },
-    "screen": "screen/MKZSView.png",
-    "logo": "logo/MKZSLogo.png",
-    "favicon": "favicon/MKZSico.ico"
-  },
-  "HSMY": {
-    "env": {
-      "VITE_APP_TITLE": "鍗庨『闀佷笟淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9115",
-      "VITE_JAVA_API": "http://114.132.189.42:9082"
-    },
-    "screen": "screen/HSMYView.png",
-    "logo": "logo/HSMYLogo.png",
-    "favicon": "favicon/HSMYico.ico"
-  },
-  "DHHB": {
-    "env": {
-      "VITE_APP_TITLE": "涓规捣鐜繚淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9117",
-      "VITE_JAVA_API": "http://114.132.189.42:9080"
-    },
-    "screen": "screen/DHHBView.png",
-    "logo": "logo/DHHBLogo.png",
-    "favicon": "favicon/DHHBico.ico"
-  },
-  "PHMK": {
-    "env": {
-      "VITE_APP_TITLE": "鏅鐓ょ熆淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9119",
-      "VITE_JAVA_API": "http://114.132.189.42:9078"
-    },
-    "screen": "screen/PHMKView.png",
-    "logo": "logo/PHMKLogo.png",
-    "favicon": "favicon/PHMKico.ico"
-  },
-  "TYMK": {
-    "env": {
-      "VITE_APP_TITLE": "閫氭簮鐓ょ熆淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9121",
-      "VITE_JAVA_API": "http://114.132.189.42:9076"
-    },
-    "screen": "screen/TYMKView.png",
-    "logo": "logo/TYMKLogo.png",
-    "favicon": "favicon/TYMKico.ico"
-  },
-  "LQM": {
-    "env": {
-      "VITE_APP_TITLE": "鑰佺惇楹﹂鍝佷俊鎭鐞嗙郴缁�",
-      "VITE_BASE_API": "http://114.132.189.42:9123",
-      "VITE_JAVA_API": "http://114.132.189.42:9074"
-    },
-    "screen": "screen/LQMView.png",
-    "logo": "logo/LQMLogo.png",
-    "favicon": "favicon/LQMico.ico"
-  },
-  "ZYRQ": {
-    "env": {
-      "VITE_APP_TITLE": "浼楁簮鐕冩皵淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9123",
-      "VITE_JAVA_API": "http://114.132.189.42:9031"
-    },
-    "screen": "screen/ZYRQView.png",
-    "logo": "logo/ZYRQLogo.png",
-    "favicon": "favicon/ZYRQico.ico"
-  },
-  "RTSW": {
-    "env": {
-      "VITE_APP_TITLE": "娑︽嘲鐢熺墿淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9064"
-    },
-    "screen": "screen/RTSWView.png",
-    "logo": "logo/RTSWLogo.png",
-    "favicon": "favicon/RTSWico.ico"
-  },
-  "HXSJ": {
-    "env": {
-      "VITE_APP_TITLE": "鍗庣幒鐮傛祮淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9062"
-    },
-    "screen": "screen/HXSJView.png",
-    "logo": "logo/HXSJLogo.png",
-    "favicon": "favicon/HXSJico.ico"
-  },
-  "QLMC": {
-    "env": {
-      "VITE_APP_TITLE": "绁佽繛鐗у満淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9060"
-    },
-    "screen": "screen/QLMCView.png",
-    "logo": "logo/QLMCLogo.png",
-    "favicon": "favicon/QLMCico.ico"
-  },
-  "AYNM": {
-    "env": {
-      "VITE_APP_TITLE": "瀹変綉鍐滅墽淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9058"
-    },
-    "screen": "screen/AYNMView.png",
-    "logo": "logo/AYNMLogo.png",
-    "favicon": "favicon/AYNMico.ico"
-  },
-  "JMSL": {
-    "env": {
-      "VITE_APP_TITLE": "閲戣寕濉戞枡鍖呰淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9058"
-    },
-    "screen": "screen/JMSLView.png",
-    "logo": "logo/JMSLLogo.png",
-    "favicon": "favicon/JMSLico.ico"
-  },
-  "TJKH": {
-    "env": {
-      "VITE_APP_TITLE": "澶╂触鍑崕淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9058"
-    },
-    "screen": "screen/TJKHView.png",
-    "logo": "logo/TJKHLogo.png",
-    "favicon": "favicon/TJKHico.ico"
-  },
-  "DZYS": {
-    "env": {
-      "VITE_APP_TITLE": "涓滄辰鍗板埛淇℃伅绠$悊绯荤粺",
-      "VITE_BASE_API": "http://114.132.189.42:9066",
-      "VITE_JAVA_API": "http://114.132.189.42:9046"
-    },
-    "screen": "screen/DZYSView.png",
-    "logo": "logo/DZYSLogo.png",
-    "favicon": "favicon/DZYSico.ico"
   },
   "screen": "/src/assets/images/login-background.png",
   "logo": "/src/assets/logo/logo.png",
diff --git a/src/api/basicData/productModel.js b/src/api/basicData/productModel.js
new file mode 100644
index 0000000..f048f9e
--- /dev/null
+++ b/src/api/basicData/productModel.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request.js";
+
+export function productModelList(query) {
+    return request({
+        url: '/basic/product/pageModel',
+        method: 'get',
+        params: query
+    })
+}
\ No newline at end of file
diff --git a/src/api/basicData/productProcess.js b/src/api/basicData/productProcess.js
new file mode 100644
index 0000000..e0208fa
--- /dev/null
+++ b/src/api/basicData/productProcess.js
@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 宸ュ簭鍒楄〃鍒嗛〉鏌ヨ
+export function productProcessListPage(query) {
+  return request({
+    url: '/productProcess/listPage',
+    method: 'get',
+    params: query
+  })
+}
diff --git a/src/api/collaborativeApproval/noticeManagement.js b/src/api/collaborativeApproval/noticeManagement.js
index aae4db7..c89f6c4 100644
--- a/src/api/collaborativeApproval/noticeManagement.js
+++ b/src/api/collaborativeApproval/noticeManagement.js
@@ -1,78 +1,78 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
 
 // 鏌ヨ鍏憡鍒楄〃
 export function listNotice(query) {
-    return request({
-        url: '/collaborativeApproval/notice/page',
-        method: 'get',
-        params: query
-    })
+  return request({
+    url: "/collaborativeApproval/notice/page",
+    method: "get",
+    params: query,
+  });
 }
 
 // 鏌ヨ鍏憡璇︾粏
 export function getNotice(noticeId) {
-    return request({
-        url: '/collaborativeApproval/notice/' + noticeId,
-        method: 'get'
-    })
+  return request({
+    url: "/collaborativeApproval/notice/" + noticeId,
+    method: "get",
+  });
 }
 
 // 鏂板鍏憡
 export function addNotice(data) {
-    return request({
-        url: '/collaborativeApproval/notice/add',
-        method: 'post',
-        data: data
-    })
+  return request({
+    url: "/collaborativeApproval/notice/add",
+    method: "post",
+    data: data,
+  });
 }
 
 // 淇敼鍏憡
 export function updateNotice(data) {
-    return request({
-        url: '/collaborativeApproval/notice/update',
-        method: 'put',
-        data: data
-    })
+  return request({
+    url: "/collaborativeApproval/notice/update",
+    method: "put",
+    data: data,
+  });
 }
 
 // 鍒犻櫎鍏憡
 export function delNotice(ids) {
-    return request({
-        url: '/collaborativeApproval/notice/' + ids,
-        method: 'delete',
-    })
+  return request({
+    url: "/collaborativeApproval/notice/" + ids,
+    method: "delete",
+  });
 }
 
 // 鑾峰彇鍏憡鏁伴噺
 export function getCount() {
-    return request({
-        url: '/collaborativeApproval/notice/count',
-        method: 'get',
-    })
+  return request({
+    url: "/collaborativeApproval/notice/count",
+    method: "get",
+  });
 }
 
 // 鏌ヨ鍏憡绫诲瀷鍒楄〃
 export function listNoticeType() {
-    return request({
-        url: '/noticeType/list',
-        method: 'get'
-    })
+  return request({
+    url: "/noticeType/list",
+    method: "get",
+  });
 }
 
 // 鏂板鍏憡绫诲瀷
 export function addNoticeType(data) {
-    return request({
-        url: '/noticeType/add',
-        method: 'post',
-        data: data
-    })
+  return request({
+    url: "/noticeType/add",
+    method: "post",
+    data: data,
+  });
 }
 
 // 鍒犻櫎鍏憡绫诲瀷
 export function delNoticeType(id) {
-    return request({
-        url: '/noticeType/del',
-        method: 'delete',
-        data: { id }
-    })
-}
\ No newline at end of file
+  return request({
+    url: "/noticeType/del",
+    method: "delete",
+    data: [id],
+  });
+}
diff --git a/src/api/collaborativeApproval/shipmentReview.js b/src/api/collaborativeApproval/shipmentReview.js
new file mode 100644
index 0000000..64fac69
--- /dev/null
+++ b/src/api/collaborativeApproval/shipmentReview.js
@@ -0,0 +1,21 @@
+// 鍙戣揣瀹℃壒
+import request from "@/utils/request";
+
+// 鑾峰彇鍙戣揣瀹℃壒鍒楄〃
+export function getShipmentApprovalList(query) {
+    return request({
+        url: '/shipmentApproval/listPage',
+        method: 'get',
+        params: query,
+    })
+}
+
+// 鍙戣揣鐢宠鎵瑰噯
+// /shipmentApproval/update
+export function approveShipment(query) {
+    return request({
+        url: '/shipmentApproval/update',
+        method: 'post',
+        data: query,
+    })
+}
\ No newline at end of file
diff --git a/src/api/equipmentManagement/measurementEquipment.js b/src/api/equipmentManagement/measurementEquipment.js
index a22c034..8bb8a7f 100644
--- a/src/api/equipmentManagement/measurementEquipment.js
+++ b/src/api/equipmentManagement/measurementEquipment.js
@@ -32,4 +32,24 @@
     method: "post",
     data: query,
   });
+}
+
+// 璁¢噺鍣ㄥ叿鍙拌处-鏂板
+// /measuringInstrumentLedger/add
+export function addMeasuringInstrumentLedger(data){
+    return request({
+        url:"/measuringInstrumentLedger/add",
+        method:"post",
+        data
+    })
+}
+
+// 璁¢噺鍣ㄥ叿鍙拌处-缂栬緫
+// /measuringInstrumentLedger/update
+export function updateMeasuringInstrumentLedger(data){
+    return request({
+        url:"/measuringInstrumentLedger/update",
+        method:"post",
+        data
+    })
 }
\ No newline at end of file
diff --git a/src/api/financialManagement/accounting.js b/src/api/financialManagement/accounting.js
new file mode 100644
index 0000000..69bc7cd
--- /dev/null
+++ b/src/api/financialManagement/accounting.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
+export const getAccountingTotal = (params) => {
+  return request({
+    url: "/accounting/total",
+    method: "get",
+    params,
+  });
+};
+
+// 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+export const getDeviceTypeDistribution = (params) => {
+  return request({
+    url: "/accounting/deviceTypeDistribution",
+    method: "get",
+    params,
+  });
+};
+
+// 鑾峰彇鎶樻棫璁$畻鏁版嵁锛堣〃鏍兼暟鎹級
+export const getCalculateDepreciation = (params) => {
+  return request({
+    url: "/accounting/calculateDepreciation",
+    method: "get",
+    params,
+  });
+};
diff --git a/src/api/financialManagement/loanManagement.js b/src/api/financialManagement/loanManagement.js
new file mode 100644
index 0000000..46ea749
--- /dev/null
+++ b/src/api/financialManagement/loanManagement.js
@@ -0,0 +1,37 @@
+import request from "@/utils/request";
+
+// 鏌ヨ鍒楄〃
+export const listPage = (params) => {
+  return request({
+    url: "/borrowInfo/listPage",
+    method: "get",
+    params,
+  });
+};
+
+// 鏂板
+export function add(data) {
+  return request({
+    url: "/borrowInfo/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 缂栬緫
+export function update(data) {
+  return request({
+    url: "/borrowInfo/update",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鍒犻櫎
+export const delAccountLoan = (data) => {
+  return request({
+    url: "/borrowInfo/delete",
+    method: "delete",
+    data,
+  });
+};
diff --git a/src/api/inventoryManagement/stockIn.js b/src/api/inventoryManagement/stockIn.js
index 55cef01..3481415 100644
--- a/src/api/inventoryManagement/stockIn.js
+++ b/src/api/inventoryManagement/stockIn.js
@@ -9,6 +9,50 @@
     });
 };
 
+// 鏌ヨ鐢熶骇鍏ュ簱淇℃伅鍒楄〃
+export const getStockInPageByProduction = (params) => {
+    return request({
+        url: "/stockin/listPageByProduction",
+        method: "get",
+        params,
+    });
+};
+
+// 鏌ヨ鐢熶骇鍏ュ簱淇℃伅鍒楄〃
+export const getStockInPageByProductProduction = (params) => {
+    return request({
+        url: "/stockin/listPageByProductProduction",
+        method: "get",
+        params,
+    });
+};
+
+// 鍑哄簱鍙拌处-鏌ヨ鑷畾涔夊叆搴撲俊鎭垪琛�
+export const getStockInPageByCustom = (params) => {
+    return request({
+        url: "/stockmanagement/listPageByCustom",
+        method: "get",
+        params,
+    });
+};
+// 鍏ュ簱绠$悊-鏌ヨ鑷畾涔夊叆搴撲俊鎭垪琛�
+export const getInPageByCustom = (params) => {
+    return request({
+        url: "/stockin/listPageByCustom",
+        method: "get",
+        params,
+    });
+};
+
+// 鍑哄簱鍙拌处-鏌ヨ鐢熶骇鍑哄簱淇℃伅鍒楄〃
+export const getStockInPageByProduct = (params) => {
+    return request({
+        url: "/stockmanagement/listPageByProduct",
+        method: "get",
+        params,
+    });
+};
+
 // 淇敼鍏ュ簱瀛樹俊鎭�
 export const updateStockIn = (data) => {
     return request({
@@ -26,6 +70,14 @@
         data,
     });
 };
+// 淇敼鏉愭枡搴撳瓨淇℃伅
+export const updateManagementByCustom = (data) => {
+    return request({
+        url: "/stockin/updateManagementByCustom ",
+        method: "post",
+        data,
+    });
+};
 
 // 鏂板鍟嗗搧鍏ュ簱淇℃伅
 export function addSutockIn(data) {
@@ -36,6 +88,32 @@
     })
 }
 
+// 鏂板鑷畾涔夊叆搴撲俊鎭�
+export function addStockInCustom(data) {
+    return request({
+        url: '/stockin/addCustom',
+        method: 'post',
+        data: data
+    })
+}
+
+// 缂栬緫鑷畾涔夊叆搴撲俊鎭�
+export function updateStockInCustom(data) {
+    return request({
+        url: '/stockin/updateCustom',
+        method: 'post',
+        data: data
+    })
+}
+// 缂栬緫鎴愬搧鍏ュ簱淇℃伅
+export function updateProduct(data) {
+    return request({
+        url: '/stockin/update',
+        method: 'post',
+        data: data
+    })
+}
+
 // 鍒犻櫎鍏ュ簱淇℃伅
 export function delStockIn(ids) {
     return request({
@@ -45,6 +123,15 @@
     })
 }
 
+// 鍒犻櫎鑷畾涔夊叆搴撲俊鎭�
+export function delStockInCustom(ids) {
+    return request({
+        url: '/stockin/delteCustom',
+        method: 'post',
+        data: ids
+    })
+}
+
 // 瀵煎嚭鍏ュ簱淇℃伅
 export function exportStockIn(query) {
     return request({
diff --git a/src/api/inventoryManagement/stockInRecord.js b/src/api/inventoryManagement/stockInRecord.js
new file mode 100644
index 0000000..1746bfe
--- /dev/null
+++ b/src/api/inventoryManagement/stockInRecord.js
@@ -0,0 +1,27 @@
+import request from "@/utils/request";
+
+// 鏌ヨ鍏ュ簱淇℃伅鍒楄〃
+export const getStockInRecordListPage = (params) => {
+    return request({
+        url: "/stockInRecord/listPage",
+        method: "get",
+        params,
+    });
+};
+
+
+export const updateStockInRecord = (id, data) => {
+    return request({
+        url: "/stockInRecord/" + id,
+        method: "put",
+        data: data,
+    });
+};
+
+export const batchDeleteStockInRecords = (ids) => {
+    return request({
+        url: "/stockInRecord",
+        method: "delete",
+        data: ids,
+    });
+};
\ No newline at end of file
diff --git a/src/api/inventoryManagement/stockInventory.js b/src/api/inventoryManagement/stockInventory.js
new file mode 100644
index 0000000..c677ebf
--- /dev/null
+++ b/src/api/inventoryManagement/stockInventory.js
@@ -0,0 +1,27 @@
+import request from "@/utils/request.js";
+// 鍒嗛〉鏌ヨ搴撳瓨璁板綍鍒楄〃
+export const getStockInventoryListPage = (params) => {
+    return request({
+        url: "/stockInventory/pagestockInventory",
+        method: "get",
+        params,
+    });
+};
+
+// 鍒涘缓搴撳瓨璁板綍
+export const createStockInventory = (params) => {
+    return request({
+        url: "/stockInventory/addstockInventory",
+        method: "post",
+        params,
+    });
+};
+
+// 鍑忓皯搴撳瓨璁板綍
+export const subtractStockInventory = (params) => {
+    return request({
+        url: "/stockInventory/subtractStockInventory",
+        method: "post",
+        params,
+    });
+};
diff --git a/src/api/inventoryManagement/stockManage.js b/src/api/inventoryManagement/stockManage.js
index bb2081b..e2a4ebf 100644
--- a/src/api/inventoryManagement/stockManage.js
+++ b/src/api/inventoryManagement/stockManage.js
@@ -9,6 +9,31 @@
     });
 };
 
+// 鏌ヨ鐢熶骇鍏ュ簱搴撳瓨淇℃伅鍒楄〃
+export const getStockManagePageByProduction = (params) => {
+    return request({
+        url: "/stockin/listPageCopyByProduction",
+        method: "get",
+        params,
+    });
+};
+// 鏌ヨ鎴愬搧搴撳瓨淇℃伅鍒楄〃
+export const getStockManageProduction = (params) => {
+    return request({
+        url: "/stockin/listPageProductionStock",
+        method: "get",
+        params,
+    });
+};
+// 鏌ヨ鑷畾涔夊叆搴撳簱瀛樹俊鎭垪琛�
+export const getStockManagePageByCustom = (params) => {
+    return request({
+        url: "/stockin/listPageCopyByCustom",
+        method: "get",
+        params,
+    });
+};
+
 
 // 淇敼搴撳瓨淇℃伅
 export const updateStockManage = (data) => {
@@ -38,7 +63,7 @@
     })
 }
 
-//鍑哄簱鎺ュ彛
+// 鍑哄簱绠$悊-棰嗙敤鎺ュ彛
 export const stockOut = (data) => {
     return request({
         url: '/stockmanagement/stockout',
diff --git a/src/api/inventoryManagement/stockOut.js b/src/api/inventoryManagement/stockOut.js
index 5d410d9..3d260b3 100644
--- a/src/api/inventoryManagement/stockOut.js
+++ b/src/api/inventoryManagement/stockOut.js
@@ -1,47 +1,19 @@
 import request from "@/utils/request";
 
-//鏌ヨ鍑哄簱鍒楄〃
+// 鍑哄簱鍙拌处-閲囪喘鍑哄簱鏌ヨ鍑哄簱鍒楄〃
 export const getStockOutPage = (params) => {
     return request({
-        url: "/stockmanagement/listPage",
+        url: "/stockOutRecord/listPage",
         method: "get",
         params,
     });
 };
 
-//鏂板鍑哄簱淇℃伅
-export const addStockOut = (data) => {
-    return request({
-        url: '/stockout/add',
-        method: 'post',
-        data: data
-    })
-}
-
-//淇敼鍑哄簱淇℃伅
-export const updateStockOut = (data) => {
-    return request({
-        url: "/stockout/update",
-        method: "put",
-        data,
-    });
-}
-
 //鍒犻櫎鍑哄簱淇℃伅
 export const delStockOut = (ids) => {
     return request({
-        url: '/stockmanagement/del',
-        method: 'post',
-        data: ids
-    })
+        url: "/stockOutRecord",
+        method: "delete",
+        data: ids,
+    });
 }
-
-//瀵煎嚭鍑哄簱淇℃伅
-export const exportStockOut = (query) => {
-    return request({
-        url: '/stockmanagement/export',
-        method: 'get',
-        params: query,
-        responseType: 'blob'
-    })
-}
\ No newline at end of file
diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
index 378756a..a4ad34b 100644
--- a/src/api/personnelManagement/employeeRecord.js
+++ b/src/api/personnelManagement/employeeRecord.js
@@ -15,4 +15,13 @@
         method: 'get',
         params: query,
     })
+}
+
+// 瀵煎嚭鍚堝悓鍓湰
+export function staffOnJobExportCopy(data) {
+    return request({
+        url: '/staff/staffOnJob/exportCopy',
+        method: 'post',
+        data: data,
+    })
 }
\ No newline at end of file
diff --git a/src/api/personnelManagement/onboarding.js b/src/api/personnelManagement/onboarding.js
deleted file mode 100644
index 39dbf22..0000000
--- a/src/api/personnelManagement/onboarding.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ浜哄憳鍏ヨ亴鍒楄〃
-export function staffJoinListPage(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/listPage",
-    method: "get",
-    params: query,
-  });
-}
-// 鏂板浜哄憳鍏ヨ亴
-export function staffJoinAdd(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/add",
-    method: "post",
-    data: query,
-  });
-}
-// 淇敼浜哄憳鍏ヨ亴
-export function staffJoinUpdate(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/update",
-    method: "post",
-    data: query,
-  });
-}
-// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
-export function getStaffJoinInfo(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/" + query,
-    method: "get",
-    data: query,
-  });
-}
-// 鍒犻櫎鍛樺伐
-export function staffJoinDel(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/del",
-    method: "delete",
-    data: query,
-  });
-}
-
-export function getStaffOnJob() {
-  return request({
-    url: "/staff/staffOnJob/list",
-    method: "get",
-  });
-}
diff --git a/src/api/personnelManagement/staffAnalytics.js b/src/api/personnelManagement/staffAnalytics.js
new file mode 100644
index 0000000..83eb375
--- /dev/null
+++ b/src/api/personnelManagement/staffAnalytics.js
@@ -0,0 +1,26 @@
+import request from "@/utils/request.js";
+
+// 绂昏亴鍘熷洜鍒嗘瀽
+export function findStaffLeaveReasonAnalysis() {
+    return request({
+        url: "/staff/analytics/reason",
+        method: "get"
+    });
+}
+
+// 12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋�
+export function findStaffAnalysisMonthlyTurnoverRateFor12Months() {
+    return request({
+        url: "/staff/analytics/monthly_turnover_rate",
+        method: "get"
+    });
+}
+
+export function findStaffAnalysisTotalStatistic() {
+    return request({
+        url: "/staff/analytics/total_statistic",
+        method: "get"
+    });
+}
+
+
diff --git a/src/api/personnelManagement/staffContract.js b/src/api/personnelManagement/staffContract.js
new file mode 100644
index 0000000..a6b71cb
--- /dev/null
+++ b/src/api/personnelManagement/staffContract.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request.js";
+
+
+export function findStaffContractListPage(query) {
+    return request({
+        url: "/staff/staffContract/listPage",
+        method: "get",
+        params: query,
+    });
+}
diff --git a/src/api/personnelManagement/staffLeave.js b/src/api/personnelManagement/staffLeave.js
new file mode 100644
index 0000000..d675996
--- /dev/null
+++ b/src/api/personnelManagement/staffLeave.js
@@ -0,0 +1,33 @@
+import request from "@/utils/request.js";
+
+export function findStaffLeaveListPage(query) {
+    return request({
+        url: "/staff/staffLeave/listPage",
+        method: "get",
+        params: query,
+    });
+}
+
+export function createStaffLeave(data) {
+    return request({
+        url: "/staff/staffLeave",
+        method: "post",
+        data: data,
+    });
+}
+
+export function updateStaffLeave(id, data) {
+    return request({
+        url: "/staff/staffLeave/" + id,
+        method: "put",
+        data: data,
+    });
+}
+
+export function batchDeleteStaffLeaves(data) {
+    return request({
+        url: "/staff/staffLeave/del",
+        method: "delete",
+        data: data,
+    });
+}
diff --git a/src/api/personnelManagement/staffOnJob.js b/src/api/personnelManagement/staffOnJob.js
new file mode 100644
index 0000000..7da5469
--- /dev/null
+++ b/src/api/personnelManagement/staffOnJob.js
@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+    return request({
+        url: '/staff/staffOnJob/listPage',
+        method: 'get',
+        params: query,
+    })
+}
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function staffOnJobInfo(id, query) {
+    return request({
+        url: '/staff/staffOnJob/' + id,
+        method: 'get',
+        params: query,
+    })
+}
+
+// 鏂板鍛樺伐
+export function createStaffOnJob(params) {
+    return request({
+        url: "/staff/staffOnJob",
+        method: "post",
+        data: params,
+    });
+}
+
+// 淇敼鍛樺伐
+export function updateStaffOnJob(id, params) {
+    return request({
+        url: "/staff/staffOnJob/" + id,
+        method: "put",
+        data: params,
+    });
+}
+
+// 鍒犻櫎鍛樺伐
+export function batchDeleteStaffOnJobs(query) {
+    return request({
+        url: "/staff/staffOnJob/del",
+        method: "delete",
+        data: query,
+    });
+}
+
+// 缁鍚堝悓
+export function renewContract(id, params) {
+    return request({
+        url: "/staff/staffOnJob/renewContract/" + id,
+        method: "post",
+        data: params,
+    });
+}
diff --git a/src/api/procurementManagement/procurementInvoiceLedger.js b/src/api/procurementManagement/procurementInvoiceLedger.js
index 76f8410..2408bbd 100644
--- a/src/api/procurementManagement/procurementInvoiceLedger.js
+++ b/src/api/procurementManagement/procurementInvoiceLedger.js
@@ -61,7 +61,7 @@
 // 鏌ヨ鍒楄〃
 export function invoiceListPage(query) {
   return request({
-    url: "/purchase/registration/listPage",
+    url: "/sales/product/listPagePurchaseLedger",
     method: "get",
     params: query,
   });
diff --git a/src/api/procurementManagement/procurementReport.js b/src/api/procurementManagement/procurementReport.js
new file mode 100644
index 0000000..32c50c7
--- /dev/null
+++ b/src/api/procurementManagement/procurementReport.js
@@ -0,0 +1,11 @@
+// 閲囪喘鎶ヨ〃椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 閲囪喘涓氬姟姹囨�昏〃鍒嗛〉鏌ヨ
+export function procurementBusinessSummaryListPage(query) {
+  return request({
+    url: "/procurementBusinessSummary/listPage",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/productionManagement/processRoute.js b/src/api/productionManagement/processRoute.js
new file mode 100644
index 0000000..c13b2fc
--- /dev/null
+++ b/src/api/productionManagement/processRoute.js
@@ -0,0 +1,42 @@
+// 宸ヨ壓璺嚎椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function listPage(query) {
+  return request({
+    url: "/processRoute/page",
+    method: "get",
+    params: query,
+  });
+}
+
+export function add(data) {
+  return request({
+    url: "/processRoute",
+    method: "post",
+    data: data,
+  });
+}
+
+export function del(ids) {
+  return request({
+    url: '/processRoute/' + ids,
+    method: 'delete',
+  })
+}
+
+export function update(data) {
+  return request({
+    url: '/processRoute',
+    method: 'put',
+    data: data,
+  })
+}
+
+// 鑾峰彇璇︽儏
+export function getById(id) {
+  return request({
+    url: `/processRoute/${id}`,
+    method: 'get',
+  })
+}
\ No newline at end of file
diff --git a/src/api/productionManagement/processRouteItem.js b/src/api/productionManagement/processRouteItem.js
new file mode 100644
index 0000000..9e81406
--- /dev/null
+++ b/src/api/productionManagement/processRouteItem.js
@@ -0,0 +1,38 @@
+// 宸ヨ壓璺嚎椤圭洰椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒楄〃鏌ヨ
+export function findProcessRouteItemList(query) {
+  return request({
+    url: "/processRouteItem/list",
+    method: "get",
+    params: query,
+  });
+}
+
+export function addOrUpdateProcessRouteItem(data) {
+  return request({
+    url: "/processRouteItem",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鎺掑簭鎺ュ彛
+export function sortProcessRouteItem(data) {
+  return request({
+    url: "/processRouteItem/sort",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鎵归噺鍒犻櫎鎺ュ彛
+export function batchDeleteProcessRouteItem(ids) {
+  // 灏唅d鏁扮粍杞崲涓洪�楀彿鍒嗛殧鐨勫瓧绗︿覆锛屾嫾鎺ュ埌URL鍚庨潰
+  const idsStr = Array.isArray(ids) ? ids.join(",") : ids;
+  return request({
+    url: `/processRouteItem/batchDelete/${idsStr}`,
+    method: "delete",
+  });
+}
diff --git a/src/api/productionManagement/productBom.js b/src/api/productionManagement/productBom.js
new file mode 100644
index 0000000..893755b
--- /dev/null
+++ b/src/api/productionManagement/productBom.js
@@ -0,0 +1,47 @@
+// 浜у搧BOM椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function listPage(query) {
+  return request({
+    url: "/productBom/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板
+export function add(data) {
+  return request({
+    url: "/productBom/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼
+export function update(data) {
+  return request({
+    url: "/productBom/update",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鎵归噺鍒犻櫎
+export function batchDelete(ids) {
+  return request({
+    url: "/productBom/batchDelete",
+    method: "delete",
+    data: ids,
+  });
+}
+
+// 鏍规嵁浜у搧鍨嬪彿ID鏌ヨBOM
+export function getByModel(productModelId) {
+  return request({
+    url: "/productBom/getByModel",
+    method: "get",
+    params: { productModelId },
+  });
+}
diff --git a/src/api/productionManagement/productProcessRoute.js b/src/api/productionManagement/productProcessRoute.js
new file mode 100644
index 0000000..e8d5da5
--- /dev/null
+++ b/src/api/productionManagement/productProcessRoute.js
@@ -0,0 +1,54 @@
+// 宸ヨ壓璺嚎椤圭洰椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒楄〃鏌ヨ
+export function findProductProcessRouteItemList(query) {
+  return request({
+    url: "/productProcessRoute/list",
+    method: "get",
+    params: query,
+  });
+}
+
+export function addOrUpdateProductProcessRouteItem(data) {
+  return request({
+    url: "/productProcessRoute/updateRouteItem",
+    method: "post",
+    data: data,
+  });
+}
+
+// 鐢熶骇璁㈠崟涓嬶細鏂板宸ヨ壓璺嚎椤圭洰
+export function addRouteItem(data) {
+  return request({
+    url: "/productProcessRoute/addRouteItem",
+    method: "post",
+    data,
+  });
+}
+
+// 鑾峰彇鐢熶骇璁㈠崟鍏宠仈鐨勫伐鑹鸿矾绾夸富淇℃伅
+export function listMain(orderId) {
+  return request({
+    url: "/productProcessRoute/listMain",
+    method: "get",
+    params: { orderId },
+  });
+}
+
+// 鍒犻櫎宸ヨ壓璺嚎椤圭洰锛堣矾鐢卞悗鎷兼帴 id锛�
+export function deleteRouteItem(id) {
+  return request({
+    url: `/productProcessRoute/deleteRouteItem/${id}`,
+    method: "delete",
+  });
+}
+
+// 鐢熶骇璁㈠崟涓嬶細鎺掑簭宸ヨ壓璺嚎椤圭洰
+export function sortRouteItem(data) {
+  return request({
+    url: "/productProcessRoute/sortRouteItem",
+    method: "post",
+    data,
+  });
+}
diff --git a/src/api/productionManagement/productStructure.js b/src/api/productionManagement/productStructure.js
new file mode 100644
index 0000000..e69e14a
--- /dev/null
+++ b/src/api/productionManagement/productStructure.js
@@ -0,0 +1,18 @@
+// 浜у搧缁撴瀯椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function queryList(id) {
+  return request({
+    url: "/productStructure/listBybomId/" + id,
+    method: "get",
+  });
+}
+
+export function add(data) {
+  return request({
+    url: "/productStructure",
+    method: "post",
+    data: data,
+  });
+}
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index ab3dc06..9f110a7 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -9,6 +9,69 @@
     params: query,
   });
 }
+
+export function productOrderListPage(query) {
+  return request({
+    url: "/productOrder/page",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鐢熶骇璁㈠崟-鎸変骇鍝佸瀷鍙锋煡璇㈠彲鐢ㄥ伐鑹鸿矾绾垮垪琛�
+export function listProcessRoute(query) {
+  return request({
+    url: "/productOrder/listProcessRoute",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鐢熶骇璁㈠崟-缁戝畾宸ヨ壓璺嚎
+export function bindingRoute(data) {
+  return request({
+    url: "/productOrder/bindingRoute",
+    method: "post",
+    data,
+  });
+}
+
+// 鐢熶骇璁㈠崟-鏌ヨ浜у搧缁撴瀯鍒楄〃
+export function listProcessBom(query) {
+  return request({
+    url: "/productOrder/listProcessBom",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+export function schedulingList(query) {
+  return request({
+    url: "/salesLedger/scheduling/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 淇濆瓨鐐掓満璁剧疆
+export function addSpeculatTrading(data) {
+  return request({
+    url: "/salesLedger/scheduling/addSpeculatTrading",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼鐐掓満璁剧疆
+export function updateSpeculatTrading(data) {
+  return request({
+    url: "/salesLedger/scheduling/updateSpeculatTrading",
+    method: "post",
+    data: data,
+  });
+}
+
 // 鐢熶骇娲惧伐
 export function productionDispatch(query) {
   return request({
@@ -16,4 +79,38 @@
     method: "post",
     data: query,
   });
+}
+// 鑷姩娲惧伐
+export function productionDispatchList(query) {
+  return request({
+    url: "/salesLedger/scheduling/productionDispatchList",
+    method: "post",
+    data: query,
+  });
+}
+
+// 鏌ヨ鎹熻�楃巼
+export function getLossRate() {
+  return request({
+    url: "/salesLedger/scheduling/loss",
+    method: "get",
+  });
+}
+
+// 鏂板鎹熻�楃巼
+export function addLossRate(data) {
+  return request({
+    url: "/salesLedger/scheduling/addLoss",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼鎹熻�楃巼
+export function updateLossRate(data) {
+  return request({
+    url: "/salesLedger/scheduling/updateLoss",
+    method: "post",
+    data: data,
+  });
 }
\ No newline at end of file
diff --git a/src/api/productionManagement/productionProcess.js b/src/api/productionManagement/productionProcess.js
new file mode 100644
index 0000000..d3a453c
--- /dev/null
+++ b/src/api/productionManagement/productionProcess.js
@@ -0,0 +1,69 @@
+// 宸ュ簭椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function listPage(query) {
+  return request({
+    url: "/productProcess/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+export function processList(query) {
+  return request({
+    url: "/productProcess/list",
+    method: "get",
+    params: query,
+  });
+}
+
+export function add(data) {
+  return request({
+    url: "/productProcess",
+    method: "post",
+    data: data,
+  });
+}
+
+export function del(data) {
+  return request({
+    url: '/productProcess/batchDelete',
+    method: 'delete',
+    data: data,
+  })
+}
+
+export function update(data) {
+  return request({
+    url: '/productProcess/update',
+    method: 'put',
+    data: data,
+  })
+}
+
+// 宸ュ簭鏌ヨ
+export function list() {
+    return request({
+        url: "/productProcess/list",
+        method: "get",
+    });
+}
+
+// 瀵煎叆鏁版嵁
+export function importData(data) {
+  return request({
+    url: "/productProcess/importData",
+    method: "post",
+    data: data,
+  });
+}
+
+// 涓嬭浇妯℃澘
+export function downloadTemplate() {
+  return request({
+    url: "/productProcess/downloadTemplate",
+    method: "post",
+    responseType: "blob",
+  });
+}
\ No newline at end of file
diff --git a/src/api/productionManagement/productionProductInput.js b/src/api/productionManagement/productionProductInput.js
new file mode 100644
index 0000000..f72cd9b
--- /dev/null
+++ b/src/api/productionManagement/productionProductInput.js
@@ -0,0 +1,11 @@
+// 鐢熶骇鎶曞叆椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function productionProductInputListPage(query) {
+    return request({
+        url: "/productionProductInput/listPage",
+        method: "get",
+        params: query,
+    });
+}
diff --git a/src/api/productionManagement/productionProductMain.js b/src/api/productionManagement/productionProductMain.js
new file mode 100644
index 0000000..0493f8b
--- /dev/null
+++ b/src/api/productionManagement/productionProductMain.js
@@ -0,0 +1,11 @@
+// 鐢熶骇鎶ュ伐椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function productionProductMainListPage(query) {
+    return request({
+        url: "/productionProductMain/listPage",
+        method: "get",
+        params: query,
+    });
+}
diff --git a/src/api/productionManagement/productionProductOutput.js b/src/api/productionManagement/productionProductOutput.js
new file mode 100644
index 0000000..10095e9
--- /dev/null
+++ b/src/api/productionManagement/productionProductOutput.js
@@ -0,0 +1,11 @@
+// 鐢熶骇浜у嚭椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function productionProductOutputListPage(query) {
+    return request({
+        url: "/productionProductOutput/listPage",
+        method: "get",
+        params: query,
+    });
+}
diff --git a/src/api/productionManagement/productionReporting.js b/src/api/productionManagement/productionReporting.js
index fdec712..3e29943 100644
--- a/src/api/productionManagement/productionReporting.js
+++ b/src/api/productionManagement/productionReporting.js
@@ -32,4 +32,12 @@
     method: "post",
     data: query,
   });
-}
\ No newline at end of file
+}
+// 鐢熶骇鎶ュ伐-鍒犻櫎
+export function productionReportDelete(query) {
+  return request({
+    url: "/productionProductMain/delete",
+    method: "delete",
+    data: query,
+  });
+}
diff --git a/src/api/productionManagement/workOrder.js b/src/api/productionManagement/workOrder.js
new file mode 100644
index 0000000..bf4b381
--- /dev/null
+++ b/src/api/productionManagement/workOrder.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request";
+
+export function productWorkOrderPage(query) {
+  return request({
+    url: "/productWorkOrder/page",
+    method: "get",
+    params: query,
+  });
+}
+
+export function updateProductWorkOrder(data) {
+  return request({
+    url: "/productWorkOrder/updateProductWorkOrder",
+    method: "post",
+    data: data,
+  });
+}
+
+export function addProductMain(data) {
+  return request({
+    url: "/productionProductMain/addProductMain",
+    method: "post",
+    data: data,
+  });
+}
diff --git a/src/api/qualityManagement/metricMaintenance.js b/src/api/qualityManagement/metricMaintenance.js
index 9bdff23..1ee9cad 100644
--- a/src/api/qualityManagement/metricMaintenance.js
+++ b/src/api/qualityManagement/metricMaintenance.js
@@ -1,45 +1,110 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
 
 // 鏌ヨ鎸囨爣鍒楄〃
 export function qualityTestStandardListPage(query) {
-    return request({
-        url: '/quality/qualityTestStandard/listPage',
-        method: 'get',
-        params: query,
-    })
+  return request({
+    url: "/qualityTestStandard/listPage",
+    method: "get",
+    params: query,
+  });
 }
 
 // 鏂板鎸囨爣鍒楄〃
 export function qualityTestStandardAdd(query) {
-    return request({
-        url: '/quality/qualityTestStandard/add',
-        method: 'post',
-        data: query,
-    })
+  return request({
+    url: "/qualityTestStandard/add",
+    method: "post",
+    data: query,
+  });
 }
 
 // 淇敼鎸囨爣鍒楄〃
 export function qualityTestStandardUpdate(query) {
-    return request({
-        url: '/quality/qualityTestStandard/update',
-        method: 'post',
-        data: query,
-    })
+  return request({
+    url: "/qualityTestStandard/update",
+    method: "post",
+    data: query,
+  });
 }
 
 // 鍒犻櫎鎸囨爣鍒楄〃
 export function qualityTestStandardDel(query) {
-    return request({
-        url: '/quality/qualityTestStandard/del',
-        method: 'delete',
-        data: query,
-    })
+  return request({
+    url: "/qualityTestStandard/del",
+    method: "delete",
+    data: query,
+  });
 }
 
 // 鍒犻櫎鎸囨爣鍒楄〃
-export function qualityInspectDetailByProductId(productId) {
-    return request({
-        url: '/quality/qualityTestStandard/product/' + productId,
-        method: 'get',
-    })
-}
\ No newline at end of file
+export function qualityInspectDetailByProductId(params) {
+  return request({
+    url: "/qualityTestStandard/getQualityTestStandardByProductId",
+    method: "get",
+    params: params,
+  });
+}
+
+// 澶嶅埗鏍囧噯鍙傛暟
+export function qualityTestStandardCopyParam(id) {
+  return request({
+    url: "/qualityTestStandard/copyParam",
+    method: "post",
+    data: { id },
+  });
+}
+
+// 鎵归噺瀹℃牳锛堢姸鎬侊細1=閫氳繃/鎵瑰噯锛�2=鎾ら攢锛�
+// 浼犲弬锛歔{ id, state }]
+export function qualityTestStandardAudit(data) {
+  return request({
+    url: "/qualityTestStandard/qualityTestStandardAudit",
+    method: "post",
+    data,
+  });
+}
+
+// 鏍囧噯鍙傛暟锛氬垪琛紙涓嶅垎椤碉級
+export function qualityTestStandardParamList(query) {
+  return request({
+    url: "/qualityTestStandardParam/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏍囧噯鍙傛暟锛氭柊澧�
+export function qualityTestStandardParamAdd(data) {
+  return request({
+    url: "/qualityTestStandardParam/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鏍囧噯鍙傛暟锛氫慨鏀�
+export function qualityTestStandardParamUpdate(data) {
+  return request({
+    url: "/qualityTestStandardParam/update",
+    method: "post",
+    data,
+  });
+}
+
+// 鏍囧噯鍙傛暟锛氬垹闄わ紙浼� id 鏁扮粍锛�
+export function qualityTestStandardParamDel(ids) {
+  return request({
+    url: "/qualityTestStandardParam/del",
+    method: "delete",
+    data: ids,
+  });
+}
+
+// 鏍规嵁鏍囧噯ID鑾峰彇鏍囧噯鍙傛暟
+export function getQualityTestStandardParamByTestStandardId(testStandardId) {
+  return request({
+    url: "/qualityTestStandard/getQualityTestStandardParamByTestStandardId",
+    method: "get",
+    params: { testStandardId },
+  });
+}
diff --git a/src/api/qualityManagement/qualityTestStandardBinding.js b/src/api/qualityManagement/qualityTestStandardBinding.js
new file mode 100644
index 0000000..e4432a6
--- /dev/null
+++ b/src/api/qualityManagement/qualityTestStandardBinding.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 缁戝畾鍒楄〃锛堜笉鍒嗛〉锛�
+export function qualityTestStandardBindingList(query) {
+  return request({
+    url: "/qualityTestStandardBinding/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板缁戝畾锛堟敮鎸佹壒閲忥級
+export function qualityTestStandardBindingAdd(data) {
+  return request({
+    url: "/qualityTestStandardBinding/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎缁戝畾锛堜紶 id 鏁扮粍锛�
+export function qualityTestStandardBindingDel(ids) {
+  return request({
+    url: "/qualityTestStandardBinding/del",
+    method: "delete",
+    data: ids,
+  });
+}
diff --git a/src/api/reportAnalysis/qualityReport.js b/src/api/reportAnalysis/qualityReport.js
new file mode 100644
index 0000000..a179a5f
--- /dev/null
+++ b/src/api/reportAnalysis/qualityReport.js
@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 鑾峰彇鍚勭被鍨嬪畬鎴愭暟閲�
+export function getInspectStatistics() {
+  return request({
+    url: '/qualityReport/getInspectStatistics',
+    method: 'get'
+  })
+}
+
+// 鑾峰彇璐ㄦ鍚堟牸鐜囩粺璁�
+export function getPassRateStatistics() {
+  return request({
+    url: '/qualityReport/getPassRateStatistics',
+    method: 'get'
+  })
+}
+
+// 鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�
+export function getMonthlyPassRateStatistics(year) {
+  return request({
+    url: '/qualityReport/getMonthlyPassRateStatistics',
+    method: 'get',
+    params: { year }
+  })
+}
+
+// 鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁
+export function getYearlyPassRateStatistics(year) {
+  return request({
+    url: '/qualityReport/getYearlyPassRateStatistics',
+    method: 'get',
+    params: { year }
+  })
+}
+// 鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁
+export function getMonthlyCompletionDetails(year) {
+  return request({
+    url: '/qualityReport/getMonthlyCompletionDetails',
+    method: 'get',
+    params: { year }
+  })
+}
+
+// 鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�
+export function getTopParameters(inspectType) {
+  return request({
+    url: '/qualityReport/getTopParameters',
+    method: 'get',
+    params: { inspectType }
+  })
+}
diff --git a/src/api/salesManagement/indicatorStats.js b/src/api/salesManagement/indicatorStats.js
new file mode 100644
index 0000000..47d7794
--- /dev/null
+++ b/src/api/salesManagement/indicatorStats.js
@@ -0,0 +1,20 @@
+// 鎸囨爣缁熻椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 澶撮儴缁熻鎺ュ彛
+export function getTotalStatistics(query) {
+  return request({
+    url: "/metricStatistics/total",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏌辩姸鍥炬暟鎹帴鍙�
+export function getStatisticsTable(query) {
+  return request({
+    url: "/metricStatistics/statisticsTable",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/salesManagement/receiptPayment.js b/src/api/salesManagement/receiptPayment.js
index b5d0cf5..0f0529d 100644
--- a/src/api/salesManagement/receiptPayment.js
+++ b/src/api/salesManagement/receiptPayment.js
@@ -40,7 +40,7 @@
 // 鏌ヨ宸茬粡缁戝畾鍙戠エ鐨勫紑绁ㄥ彴璐�
 export function bindInvoiceNoRegPage(query) {
     return request({
-        url: '/receiptPayment/bindInvoiceNoRegPage',
+        url: '/sales/product/listPageSalesLedger',
         method: 'get',
         params: query
     })
diff --git a/src/api/system/message.js b/src/api/system/message.js
index 871d7e8..dd81cc5 100644
--- a/src/api/system/message.js
+++ b/src/api/system/message.js
@@ -30,7 +30,7 @@
 // 涓�閿爣璁版墍鏈夋秷鎭负宸茶
 export function markAllAsRead() {
   return request({
-    url: "/system/notice/markAllAsRead",
+    url: "/system/notice/readAll",
     method: "post",
   });
 }
diff --git a/src/api/system/post.js b/src/api/system/post.js
index 8faa266..fcb5bba 100644
--- a/src/api/system/post.js
+++ b/src/api/system/post.js
@@ -9,6 +9,15 @@
   })
 }
 
+export function findPostOptions(query) {
+  return request({
+    url: '/system/post/optionselect',
+    method: 'get',
+    params: query
+  })
+}
+
+
 // 鏌ヨ宀椾綅璇︾粏
 export function getPost(postId) {
   return request({
diff --git a/src/api/viewIndex.js b/src/api/viewIndex.js
index 2d85171..9abd3cc 100644
--- a/src/api/viewIndex.js
+++ b/src/api/viewIndex.js
@@ -44,4 +44,22 @@
         url: '/sales/ledger/getAmountHalfYear',
         method: 'get'
     })
+}
+
+// 鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻
+// /home/progressStatistics
+export const getProgressStatistics = ()=>{
+    return request({
+        url: '/home/progressStatistics',
+        method: 'get'
+    })
+}
+
+//鍦ㄥ埗鍝佸懆杞儏鍐�
+//home/workInProcessTurnover
+export const getWorkInProcessTurnover= ()=>{
+    return request({
+        url: '/home/workInProcessTurnover',
+        method: 'get'
+    })
 }
\ No newline at end of file
diff --git a/src/assets/images/chartCard.svg b/src/assets/images/chartCard.svg
new file mode 100644
index 0000000..32d48b1
--- /dev/null
+++ b/src/assets/images/chartCard.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#0092FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/assets/images/chartCard2.svg b/src/assets/images/chartCard2.svg
new file mode 100644
index 0000000..ff67331
--- /dev/null
+++ b/src/assets/images/chartCard2.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#5EB334" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/assets/images/chartCard3.svg b/src/assets/images/chartCard3.svg
new file mode 100644
index 0000000..0e8ce16
--- /dev/null
+++ b/src/assets/images/chartCard3.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><defs><mask id="master_svg0_88_35670" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="40" height="40"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#FFFFFF" fill-opacity="1"/></mask><clipPath id="master_svg1_88_35666"><rect x="7" y="7" width="27" height="27" rx="0"/></clipPath><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg2_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient><linearGradient x1="0.5" y1="0" x2="0.5" y2="1" id="master_svg3_88_26531"><stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/><stop offset="98.57142567634583%" stop-color="#F0FBFF" stop-opacity="1"/></linearGradient></defs><g mask="url(#master_svg0_88_35670)"><ellipse cx="20" cy="20" rx="20" ry="20" fill="#8000FF" fill-opacity="1"/><g clip-path="url(#master_svg1_88_35666)"><path d="M21.175671875,27.58515925L14.263672875000001,27.58515925C13.750673275,27.58515925,13.426672974999999,27.24765625,13.426672974999999,26.74815725C13.426672974999999,26.23515525,13.764173075,25.911160250000002,14.263672875000001,25.911160250000002L21.351173875,25.911160250000002C21.688676875,24.89865825,22.188173875,23.88615425,22.863174875,23.211156250000002L14.263672875000001,23.211156250000002C13.750673275,23.211156250000002,13.426672974999999,22.87365525,13.426672974999999,22.37415225C13.426672974999999,21.87465325,13.764173075,21.537155249999998,14.263672875000001,21.537155249999998L25.738675875,21.537155249999998C26.251674875,21.37515325,26.751174875,21.37515325,27.088676875,21.37515325C28.438678875,21.37515325,29.626676875,21.88815525,30.625678875,22.549656249999998L30.625678875,13.072656349999999C30.625678875,11.38515625,29.275674875,10.03515625,27.588174875,10.03515625L27.075177875,10.03515625L27.075177875,13.24815675C27.075177875,14.935656550000001,25.725173875,16.285657450000002,24.037676875000002,16.285657450000002L16.113174475,16.285657450000002C14.425674475000001,16.272157149999998,13.075673375000001,14.922158249999999,13.075673375000001,13.23465635L13.075673375000001,10.03515625L12.238672475,10.03515625C10.551171974999999,10.03515625,9.201171875,11.38515625,9.201171875,13.072656349999999L9.201171875,29.94765825C9.201171875,31.63515625,10.551171974999999,32.985161250000004,12.238672475,32.985161250000004L25.576673875,32.985161250000004C23.200674875,32.485662250000004,21.337675875000002,30.28515825,21.175671875,27.58515925Z" fill="url(#master_svg2_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M16.1124145625,14.764538762499999L24.0504169625,14.764538762499999C24.8874170625,14.764538762499999,25.5624140625,14.0895385625,25.5624140625,13.252537762500001L25.5624140625,10.0395388625L22.5249171625,10.0395388625C22.3629159625,8.8650390625,21.3369150625,7.8525390625,19.986915562500002,7.8525390625C18.7989153625,7.8525390625,17.7864150625,8.8650390625,17.6244149625,10.0395388625L14.5869140625,10.0395388625L14.5869140625,13.252537762500001C14.5869140625,14.0895385625,15.2619143725,14.764538762499999,16.1124145625,14.764538762499999ZM30.7869150625,24.3900370625C29.9499160625,23.3775360625,28.5999220625,22.7025380625,27.2499170625,22.7025380625L26.412916062500003,22.7025380625C25.8999180625,22.7025380625,25.5759160625,22.8780390625,25.0629190625,23.2155400625C24.0504169625,23.7285370625,23.1999158625,24.7275330625,22.700415562499998,25.9155390625C22.5384173625,26.4285390625,22.5384173625,26.9280380625,22.5384173625,27.4275380625L22.5384173625,27.5895390625C22.700415562499998,30.1275410625,24.7254170625,31.9770390625,27.1014200625,31.9770390625C28.4514180625,31.9770390625,29.8014230625,31.3020400625,30.6384180625,30.2895320625C31.3134210625,29.4525340625,31.6509170625,28.4265380625,31.6509170625,27.2520330625C31.8129160625,26.2395310625,31.2999250625,25.2270370625,30.7869150625,24.3900370625ZM29.7879200625,26.5770380625L27.0879160625,29.2770390625C26.7504160625,29.6145400625,26.412916062500003,29.6145400625,26.0754160625,29.2770390625L24.387915562499998,27.5895390625C24.0504169625,27.2520370625,24.0504169625,26.9145390625,24.387915562499998,26.5770380625C24.725415062499998,26.2395380625,25.0629150625,26.2395400625,25.4004160625,26.5770380625L26.2374170625,27.4140400625L26.5749150625,27.7515370625L28.7619150625,25.5645350625C29.0994140625,25.2270370625,29.4369190625,25.2270370625,29.774416062500002,25.5645350625C30.1119160625,25.9020370625,30.1119160625,26.2395380625,29.7879200625,26.5770380625Z" fill="url(#master_svg3_88_26531)" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
\ No newline at end of file
diff --git a/src/components/Dialog/FileListDialog.vue b/src/components/Dialog/FileListDialog.vue
index ebe81dd..0721a55 100644
--- a/src/components/Dialog/FileListDialog.vue
+++ b/src/components/Dialog/FileListDialog.vue
@@ -229,10 +229,9 @@
 
 const handleUpload = async () => {
   if (props.uploadMethod) {
-    const newItem = await props.uploadMethod()
-    if (newItem) {
-      addAttachment(newItem)
-    }
+    // 濡傛灉鎻愪緵浜嗚嚜瀹氫箟涓婁紶鏂规硶锛岀敱鐖剁粍浠惰礋璐f洿鏂板垪琛紙閫氳繃 setList锛�
+    // 杩欓噷涓嶅啀鑷姩娣诲姞锛岄伩鍏嶄笌鐖剁粍浠剁殑 setList 閲嶅
+    await props.uploadMethod()
   }
   emit('upload')
 }
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 1fa1695..dfbc231 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -40,12 +40,22 @@
       :fixed="item.fixed"
       :label="item.label"
       :prop="item.prop"
-      show-overflow-tooltip
+      :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'"
       :align="item.align"
       :sortable="!!item.sortable"
       :type="item.type"
       :width="item.width"
     >
+      <template #header="scope">
+        <div class="pim-table-header-cell">
+          <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>
+        </div>
+      </template>
       <template
         v-if="item.hasOwnProperty('colunmTemplate')"
         #[item.colunmTemplate]="scope"
@@ -120,7 +130,7 @@
         </div>
 
         <!-- 鎸夐挳 -->
-        <div v-else-if="item.dataType == 'action'">
+        <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'"
@@ -135,7 +145,7 @@
                     : o.color,
               }"
               link
-              @click="o.clickFun(scope.row)"
+              @click.stop="o.clickFun(scope.row)"
               :key="key"
             >
               {{ o.name }}
@@ -204,6 +214,7 @@
     </el-table-column>
   </el-table>
   <pagination
+		v-if="isShowPagination"
     :total="page.total"
     :layout="page.layout"
     :page="page.current"
@@ -266,6 +277,10 @@
   isSelection: {
     type: Boolean,
     default: false,
+  },
+	isShowPagination: {
+    type: Boolean,
+    default: true,
   },
   isShowSummary: {
     type: Boolean,
@@ -429,4 +444,9 @@
   padding-right: 0 !important;
   padding-left: 0 !important;
 }
+
+.pim-table-header-extra :deep(.el-input),
+.pim-table-header-extra :deep(.el-select) {
+  width: 100%;
+}
 </style>
diff --git a/src/components/PageHeader/index.vue b/src/components/PageHeader/index.vue
new file mode 100644
index 0000000..d8fc6fa
--- /dev/null
+++ b/src/components/PageHeader/index.vue
@@ -0,0 +1,53 @@
+<template>
+  <div class="page-header-wrapper">
+    <el-page-header @back="handleBack" :content="content">
+      <template #icon v-if="$slots.icon">
+        <slot name="icon"></slot>
+      </template>
+      <template #title v-if="$slots.title">
+        <slot name="title"></slot>
+      </template>
+      <template #content v-if="$slots.content">
+        <slot name="content"></slot>
+      </template>
+      <template #extra>
+        <slot name="extra">
+          <slot name="right-button"></slot>
+        </slot>
+      </template>
+    </el-page-header>
+  </div>
+</template>
+
+<script setup>
+import { useRouter } from 'vue-router'
+
+const props = defineProps({
+  content: {
+    type: String,
+    default: ''
+  }
+})
+
+const emit = defineEmits(['back'])
+
+const router = useRouter()
+
+const handleBack = () => {
+  emit('back')
+  // 榛樿杩斿洖鍒颁笂涓�绾�
+  router.back()
+}
+</script>
+
+<style scoped>
+.page-header-wrapper {
+  margin-bottom: 16px;
+}
+
+.page-header-wrapper :deep(.el-page-header__extra) {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+</style>
diff --git a/src/components/QRCodeGenerator/index.vue b/src/components/QRCodeGenerator/index.vue
index 1708130..fd44f44 100644
--- a/src/components/QRCodeGenerator/index.vue
+++ b/src/components/QRCodeGenerator/index.vue
@@ -1,70 +1,79 @@
 <template>
   <div class="qr-code-generator">
     <!-- 浜岀淮鐮佺敓鎴愯〃鍗� -->
-    <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="qr-form">
+    <el-form :model="form"
+             :rules="rules"
+             ref="formRef"
+             label-width="120px"
+             class="qr-form">
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="鏍囪瘑绫诲瀷" prop="type">
-            <el-select v-model="form.type" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" style="width: 100%">
-              <el-option label="浜岀淮鐮�" value="qrcode"></el-option>
-              <el-option label="闃蹭吉鐮�" value="security"></el-option>
+          <el-form-item label="鏍囪瘑绫诲瀷"
+                        prop="type">
+            <el-select v-model="form.type"
+                       placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷"
+                       style="width: 100%">
+              <el-option label="浜岀淮鐮�"
+                         value="qrcode"></el-option>
+              <el-option label="闃蹭吉鐮�"
+                         value="security"></el-option>
             </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="鍐呭" prop="content">
-            <el-input 
-              v-model="form.content" 
-              placeholder="璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�"
-              :type="form.type === 'security' ? 'textarea' : 'text'"
-              :rows="form.type === 'security' ? 3 : 1"
-            ></el-input>
+          <el-form-item label="鍐呭"
+                        prop="content">
+            <el-input v-model="form.content"
+                      placeholder="璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�"
+                      :type="form.type === 'security' ? 'textarea' : 'text'"
+                      :rows="form.type === 'security' ? 3 : 1"></el-input>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="灏哄" prop="size">
-            <el-input-number 
-              v-model="form.size" 
-              :min="100" 
-              :max="500" 
-              :step="50"
-              style="width: 100%"
-            ></el-input-number>
+          <el-form-item label="灏哄"
+                        prop="size">
+            <el-input-number v-model="form.size"
+                             :min="100"
+                             :max="500"
+                             :step="50"
+                             style="width: 100%"></el-input-number>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="杈硅窛" prop="margin">
-            <el-input-number 
-              v-model="form.margin" 
-              :min="0" 
-              :max="10" 
-              :step="1"
-              style="width: 100%"
-            ></el-input-number>
+          <el-form-item label="杈硅窛"
+                        prop="margin">
+            <el-input-number v-model="form.margin"
+                             :min="0"
+                             :max="10"
+                             :step="1"
+                             style="width: 100%"></el-input-number>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="鍓嶆櫙鑹�" prop="foregroundColor">
-            <el-color-picker v-model="form.foregroundColor" style="width: 100%"></el-color-picker>
+          <el-form-item label="鍓嶆櫙鑹�"
+                        prop="foregroundColor">
+            <el-color-picker v-model="form.foregroundColor"
+                             style="width: 100%"></el-color-picker>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="鑳屾櫙鑹�" prop="backgroundColor">
-            <el-color-picker v-model="form.backgroundColor" style="width: 100%"></el-color-picker>
+          <el-form-item label="鑳屾櫙鑹�"
+                        prop="backgroundColor">
+            <el-color-picker v-model="form.backgroundColor"
+                             style="width: 100%"></el-color-picker>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="24">
           <el-form-item>
-            <el-button type="primary" @click="generateCode" :loading="generating">
+            <el-button type="primary"
+                       @click="generateCode"
+                       :loading="generating">
               鐢熸垚{{ form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�' }}
             </el-button>
             <el-button @click="resetForm">閲嶇疆</el-button>
@@ -72,18 +81,17 @@
         </el-col>
       </el-row>
     </el-form>
-
     <!-- 鐢熸垚鐨勭爜鏄剧ず鍖哄煙 -->
-    <div v-if="generatedCodeUrl" class="code-display">
+    <div v-if="generatedCodeUrl"
+         class="code-display">
       <el-divider content-position="center">
         {{ form.type === 'qrcode' ? '鐢熸垚鐨勪簩缁寸爜' : '鐢熸垚鐨勯槻浼爜' }}
       </el-divider>
-      
       <div class="code-container">
         <div class="code-image">
-          <img :src="generatedCodeUrl" :alt="form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'" />
+          <img :src="generatedCodeUrl"
+               :alt="form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'" />
         </div>
-        
         <div class="code-info">
           <p><strong>鍐呭锛�</strong>{{ form.content }}</p>
           <p><strong>绫诲瀷锛�</strong>{{ form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�' }}</p>
@@ -91,60 +99,71 @@
           <p><strong>鐢熸垚鏃堕棿锛�</strong>{{ generateTime }}</p>
         </div>
       </div>
-      
       <div class="code-actions">
-        <el-button type="success" @click="downloadCode" icon="Download">
+        <el-button type="success"
+                   @click="downloadCode"
+                   icon="Download">
           涓嬭浇鍥剧墖
         </el-button>
-        <el-button type="primary" @click="copyToClipboard" icon="CopyDocument">
+        <el-button type="primary"
+                   @click="copyToClipboard"
+                   icon="CopyDocument">
           澶嶅埗鍐呭
         </el-button>
-        <el-button @click="printCode" icon="Printer">
+        <el-button @click="printCode"
+                   icon="Printer">
           鎵撳嵃
         </el-button>
       </div>
     </div>
-
     <!-- 鎵归噺鐢熸垚瀵硅瘽妗� -->
-    <el-dialog v-model="batchDialogVisible" title="鎵归噺鐢熸垚" width="600px">
-      <el-form :model="batchForm" label-width="120px">
+    <el-dialog v-model="batchDialogVisible"
+               title="鎵归噺鐢熸垚"
+               width="600px">
+      <el-form :model="batchForm"
+               label-width="120px">
         <el-form-item label="鐢熸垚鏁伴噺">
-          <el-input-number v-model="batchForm.quantity" :min="1" :max="100" style="width: 100%"></el-input-number>
+          <el-input-number v-model="batchForm.quantity"
+                           :min="1"
+                           :max="100"
+                           style="width: 100%"></el-input-number>
         </el-form-item>
         <el-form-item label="鍓嶇紑">
-          <el-input v-model="batchForm.prefix" placeholder="璇疯緭鍏ュ墠缂�锛屽锛歅ROD_"></el-input>
+          <el-input v-model="batchForm.prefix"
+                    placeholder="璇疯緭鍏ュ墠缂�锛屽锛歅ROD_"></el-input>
         </el-form-item>
         <el-form-item label="璧峰缂栧彿">
-          <el-input-number v-model="batchForm.startNumber" :min="1" style="width: 100%"></el-input-number>
+          <el-input-number v-model="batchForm.startNumber"
+                           :min="1"
+                           style="width: 100%"></el-input-number>
         </el-form-item>
       </el-form>
-      
       <template #footer>
         <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="generateBatchCodes">寮�濮嬬敓鎴�</el-button>
           <el-button @click="batchDialogVisible = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="generateBatchCodes">寮�濮嬬敓鎴�</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 鎵归噺鐢熸垚缁撴灉 -->
-    <div v-if="batchCodes.length > 0" class="batch-results">
+    <div v-if="batchCodes.length > 0"
+         class="batch-results">
       <el-divider content-position="center">鎵归噺鐢熸垚缁撴灉</el-divider>
-      
       <div class="batch-grid">
-        <div 
-          v-for="(code, index) in batchCodes" 
-          :key="index" 
-          class="batch-item"
-        >
-          <img :src="code.url" :alt="code.content" />
+        <div v-for="(code, index) in batchCodes"
+             :key="index"
+             class="batch-item">
+          <img :src="code.url"
+               :alt="code.content" />
           <p class="batch-content">{{ code.content }}</p>
-          <el-button size="small" @click="downloadSingleCode(code)">涓嬭浇</el-button>
+          <el-button size="small"
+                     @click="downloadSingleCode(code)">涓嬭浇</el-button>
         </div>
       </div>
-      
       <div class="batch-actions">
-        <el-button type="success" @click="downloadAllCodes">涓嬭浇鍏ㄩ儴</el-button>
+        <el-button type="success"
+                   @click="downloadAllCodes">涓嬭浇鍏ㄩ儴</el-button>
         <el-button @click="clearBatchCodes">娓呯┖缁撴灉</el-button>
       </div>
     </div>
@@ -152,390 +171,396 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed, onMounted } from 'vue'
-import QRCode from 'qrcode'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Download, CopyDocument, Printer } from '@element-plus/icons-vue'
+  import { ref, reactive, computed, onMounted } from "vue";
+  import QRCode from "qrcode";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Download, CopyDocument, Printer } from "@element-plus/icons-vue";
 
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
-  name: 'QRCodeGenerator'
-})
+  // 瀹氫箟缁勪欢鍚嶇О
+  defineOptions({
+    name: "QRCodeGenerator",
+  });
 
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
-  type: 'qrcode',
-  content: '',
-  size: 200,
-  margin: 2,
-  foregroundColor: '#000000',
-  backgroundColor: '#FFFFFF'
-})
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    type: "qrcode",
+    content: "",
+    size: 200,
+    margin: 2,
+    foregroundColor: "#000000",
+    backgroundColor: "#FFFFFF",
+  });
 
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
-  type: [{ required: true, message: '璇烽�夋嫨鏍囪瘑绫诲瀷', trigger: 'change' }],
-  content: [{ required: true, message: '璇疯緭鍏ュ唴瀹�', trigger: 'blur' }]
-}
+  // 琛ㄥ崟楠岃瘉瑙勫垯
+  const rules = {
+    type: [{ required: true, message: "璇烽�夋嫨鏍囪瘑绫诲瀷", trigger: "change" }],
+    content: [{ required: true, message: "璇疯緭鍏ュ唴瀹�", trigger: "blur" }],
+  };
 
-// 鍝嶅簲寮忔暟鎹�
-const formRef = ref()
-const generating = ref(false)
-const generatedCodeUrl = ref('')
-const generateTime = ref('')
-const batchDialogVisible = ref(false)
-const batchForm = reactive({
-  quantity: 10,
-  prefix: '',
-  startNumber: 1
-})
-const batchCodes = ref([])
+  // 鍝嶅簲寮忔暟鎹�
+  const formRef = ref();
+  const generating = ref(false);
+  const generatedCodeUrl = ref("");
+  const generateTime = ref("");
+  const batchDialogVisible = ref(false);
+  const batchForm = reactive({
+    quantity: 10,
+    prefix: "",
+    startNumber: 1,
+  });
+  const batchCodes = ref([]);
 
-// 鐢熸垚浜岀淮鐮佹垨闃蹭吉鐮�
-const generateCode = async () => {
-  try {
-    await formRef.value.validate()
-    
-    if (!form.content.trim()) {
-      ElMessage.warning('璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�')
-      return
-    }
-    
-    generating.value = true
-    
-    if (form.type === 'qrcode') {
-      // 鐢熸垚浜岀淮鐮�
-      generatedCodeUrl.value = await QRCode.toDataURL(form.content, {
-        width: form.size,
-        margin: form.margin,
-        color: {
-          dark: form.foregroundColor,
-          light: form.backgroundColor
-        },
-        errorCorrectionLevel: 'M'
-      })
-    } else {
-      // 鐢熸垚闃蹭吉鐮侊紙浣跨敤浜岀淮鐮佹妧鏈紝浣嗗唴瀹规牸寮忎笉鍚岋級
-      const securityContent = generateSecurityCode(form.content)
-      generatedCodeUrl.value = await QRCode.toDataURL(securityContent, {
-        width: form.size,
-        margin: form.margin,
-        color: {
-          dark: form.foregroundColor,
-          light: form.backgroundColor
-        },
-        errorCorrectionLevel: 'H' // 闃蹭吉鐮佷娇鐢ㄦ渶楂樼籂閿欑骇鍒�
-      })
-    }
-    
-    generateTime.value = new Date().toLocaleString()
-    ElMessage.success('鐢熸垚鎴愬姛锛�')
-    
-  } catch (error) {
-    console.error('鐢熸垚澶辫触:', error)
-    ElMessage.error('鐢熸垚澶辫触锛�' + error.message)
-  } finally {
-    generating.value = false
-  }
-}
+  // 鐢熸垚浜岀淮鐮佹垨闃蹭吉鐮�
+  const generateCode = async () => {
+    try {
+      await formRef.value.validate();
 
-// 鐢熸垚闃蹭吉鐮佸唴瀹�
-const generateSecurityCode = (content) => {
-  const timestamp = Date.now()
-  const random = Math.random().toString(36).substr(2, 8)
-  return `SEC_${content}_${timestamp}_${random}`
-}
+      if (!form.content.trim()) {
+        ElMessage.warning("璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�");
+        return;
+      }
 
-// 涓嬭浇鐢熸垚鐨勭爜
-const downloadCode = () => {
-  if (!generatedCodeUrl.value) {
-    ElMessage.warning('璇峰厛鐢熸垚鐮�')
-    return
-  }
-  
-  const a = document.createElement('a')
-  a.href = generatedCodeUrl.value
-  a.download = `${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}_${new Date().getTime()}.png`
-  document.body.appendChild(a)
-  a.click()
-  document.body.removeChild(a)
-  ElMessage.success('涓嬭浇鎴愬姛锛�')
-}
+      generating.value = true;
 
-// 澶嶅埗鍐呭鍒板壀璐存澘
-const copyToClipboard = async () => {
-  try {
-    await navigator.clipboard.writeText(form.content)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  } catch (error) {
-    // 闄嶇骇鏂规
-    const textArea = document.createElement('textarea')
-    textArea.value = form.content
-    document.body.appendChild(textArea)
-    textArea.select()
-    document.execCommand('copy')
-    document.body.removeChild(textArea)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  }
-}
-
-// 鎵撳嵃鐮�
-const printCode = () => {
-  if (!generatedCodeUrl.value) {
-    ElMessage.warning('璇峰厛鐢熸垚鐮�')
-    return
-  }
-  
-  const printWindow = window.open('', '_blank')
-  printWindow.document.write(`
-    <html>
-      <head>
-        <title>鎵撳嵃${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}</title>
-        <style>
-          body { text-align: center; padding: 20px; }
-          img { max-width: 100%; height: auto; }
-          .info { margin: 20px 0; }
-        </style>
-      </head>
-      <body>
-        <h2>${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}</h2>
-        <img src="${generatedCodeUrl.value}" alt="${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}" />
-        <div class="info">
-          <p><strong>鍐呭锛�</strong>${form.content}</p>
-          <p><strong>鐢熸垚鏃堕棿锛�</strong>${generateTime.value}</p>
-        </div>
-      </body>
-    </html>
-  `)
-  printWindow.document.close()
-  printWindow.print()
-}
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
-  formRef.value.resetFields()
-  generatedCodeUrl.value = ''
-  generateTime.value = ''
-  batchCodes.value = []
-}
-
-// 鎵归噺鐢熸垚
-const generateBatchCodes = async () => {
-  if (!batchForm.prefix.trim()) {
-    ElMessage.warning('璇疯緭鍏ュ墠缂�')
-    return
-  }
-  
-  batchCodes.value = []
-  generating.value = true
-  
-  try {
-    for (let i = 0; i < batchForm.quantity; i++) {
-      const number = batchForm.startNumber + i
-      const content = `${batchForm.prefix}${number.toString().padStart(6, '0')}`
-      
-      let codeUrl
-      if (form.type === 'qrcode') {
-        codeUrl = await QRCode.toDataURL(content, {
+      if (form.type === "qrcode") {
+        // 鐢熸垚浜岀淮鐮�
+        generatedCodeUrl.value = await QRCode.toDataURL(form.content, {
           width: form.size,
           margin: form.margin,
           color: {
             dark: form.foregroundColor,
-            light: form.backgroundColor
-          }
-        })
+            light: form.backgroundColor,
+          },
+          errorCorrectionLevel: "M",
+        });
       } else {
-        const securityContent = generateSecurityCode(content)
-        codeUrl = await QRCode.toDataURL(securityContent, {
+        // 鐢熸垚闃蹭吉鐮侊紙浣跨敤浜岀淮鐮佹妧鏈紝浣嗗唴瀹规牸寮忎笉鍚岋級
+        const securityContent = generateSecurityCode(form.content);
+        generatedCodeUrl.value = await QRCode.toDataURL(securityContent, {
           width: form.size,
           margin: form.margin,
           color: {
             dark: form.foregroundColor,
-            light: form.backgroundColor
-          }
-        })
+            light: form.backgroundColor,
+          },
+          errorCorrectionLevel: "H", // 闃蹭吉鐮佷娇鐢ㄦ渶楂樼籂閿欑骇鍒�
+        });
       }
-      
-      batchCodes.value.push({
-        content,
-        url: codeUrl
-      })
+
+      generateTime.value = new Date().toLocaleString();
+      ElMessage.success("鐢熸垚鎴愬姛锛�");
+    } catch (error) {
+      console.error("鐢熸垚澶辫触:", error);
+      ElMessage.error("鐢熸垚澶辫触锛�" + error.message);
+    } finally {
+      generating.value = false;
     }
-    
-    ElMessage.success(`鎵归噺鐢熸垚瀹屾垚锛屽叡鐢熸垚 ${batchForm.quantity} 涓爜`)
-    batchDialogVisible.value = false
-    
-  } catch (error) {
-    console.error('鎵归噺鐢熸垚澶辫触:', error)
-    ElMessage.error('鎵归噺鐢熸垚澶辫触锛�' + error.message)
-  } finally {
-    generating.value = false
-  }
-}
+  };
 
-// 涓嬭浇鍗曚釜鎵归噺鐢熸垚鐨勭爜
-const downloadSingleCode = (code) => {
-  const a = document.createElement('a')
-  a.href = code.url
-  a.download = `${code.content}.png`
-  document.body.appendChild(a)
-  a.click()
-  document.body.removeChild(a)
-}
+  // 鐢熸垚闃蹭吉鐮佸唴瀹�
+  const generateSecurityCode = content => {
+    const timestamp = Date.now();
+    const random = Math.random().toString(36).substr(2, 8);
+    return `SEC_${content}_${timestamp}_${random}`;
+  };
 
-// 涓嬭浇鎵�鏈夋壒閲忕敓鎴愮殑鐮�
-const downloadAllCodes = async () => {
-  if (batchCodes.value.length === 0) {
-    ElMessage.warning('娌℃湁鍙笅杞界殑鐮�')
-    return
-  }
-  
-  try {
-    // 浣跨敤JSZip鎵撳寘涓嬭浇
-    const JSZip = await import('jszip')
-    const zip = new JSZip.default()
-    
-    batchCodes.value.forEach((code, index) => {
-      // 灏哹ase64杞崲涓篵lob
-      const base64Data = code.url.split(',')[1]
-      const byteCharacters = atob(base64Data)
-      const byteNumbers = new Array(byteCharacters.length)
-      for (let i = 0; i < byteCharacters.length; i++) {
-        byteNumbers[i] = byteCharacters.charCodeAt(i)
+  // 涓嬭浇鐢熸垚鐨勭爜
+  const downloadCode = () => {
+    if (!generatedCodeUrl.value) {
+      ElMessage.warning("璇峰厛鐢熸垚鐮�");
+      return;
+    }
+
+    const a = document.createElement("a");
+    a.href = generatedCodeUrl.value;
+    a.download = `${
+      form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+    }_${new Date().getTime()}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+    ElMessage.success("涓嬭浇鎴愬姛锛�");
+  };
+
+  // 澶嶅埗鍐呭鍒板壀璐存澘
+  const copyToClipboard = async () => {
+    try {
+      await navigator.clipboard.writeText(form.content);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    } catch (error) {
+      // 闄嶇骇鏂规
+      const textArea = document.createElement("textarea");
+      textArea.value = form.content;
+      document.body.appendChild(textArea);
+      textArea.select();
+      document.execCommand("copy");
+      document.body.removeChild(textArea);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    }
+  };
+
+  // 鎵撳嵃鐮�
+  const printCode = () => {
+    if (!generatedCodeUrl.value) {
+      ElMessage.warning("璇峰厛鐢熸垚鐮�");
+      return;
+    }
+
+    const printWindow = window.open("", "_blank");
+    printWindow.document.write(`
+      <html>
+        <head>
+          <title>鎵撳嵃${form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"}</title>
+          <style>
+            body { text-align: center; padding: 20px; }
+            img { max-width: 100%; height: auto; }
+            .info { margin: 20px 0; }
+          </style>
+        </head>
+        <body>
+          <h2>${form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"}</h2>
+          <img src="${generatedCodeUrl.value}" alt="${
+      form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+    }" />
+          <div class="info">
+            <p><strong>鍐呭锛�</strong>${form.content}</p>
+            <p><strong>鐢熸垚鏃堕棿锛�</strong>${generateTime.value}</p>
+          </div>
+        </body>
+      </html>
+    `);
+    printWindow.document.close();
+    printWindow.print();
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    formRef.value.resetFields();
+    generatedCodeUrl.value = "";
+    generateTime.value = "";
+    batchCodes.value = [];
+  };
+
+  // 鎵归噺鐢熸垚
+  const generateBatchCodes = async () => {
+    if (!batchForm.prefix.trim()) {
+      ElMessage.warning("璇疯緭鍏ュ墠缂�");
+      return;
+    }
+
+    batchCodes.value = [];
+    generating.value = true;
+
+    try {
+      for (let i = 0; i < batchForm.quantity; i++) {
+        const number = batchForm.startNumber + i;
+        const content = `${batchForm.prefix}${number
+          .toString()
+          .padStart(6, "0")}`;
+
+        let codeUrl;
+        if (form.type === "qrcode") {
+          codeUrl = await QRCode.toDataURL(content, {
+            width: form.size,
+            margin: form.margin,
+            color: {
+              dark: form.foregroundColor,
+              light: form.backgroundColor,
+            },
+          });
+        } else {
+          const securityContent = generateSecurityCode(content);
+          codeUrl = await QRCode.toDataURL(securityContent, {
+            width: form.size,
+            margin: form.margin,
+            color: {
+              dark: form.foregroundColor,
+              light: form.backgroundColor,
+            },
+          });
+        }
+
+        batchCodes.value.push({
+          content,
+          url: codeUrl,
+        });
       }
-      const byteArray = new Uint8Array(byteNumbers)
-      
-      zip.file(`${code.content}.png`, byteArray)
-    })
-    
-    const content = await zip.generateAsync({ type: 'blob' })
-    const a = document.createElement('a')
-    a.href = URL.createObjectURL(content)
-    a.download = `鎵归噺${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}_${new Date().getTime()}.zip`
-    document.body.appendChild(a)
-    a.click()
-    document.body.removeChild(a)
-    URL.revokeObjectURL(a.href)
-    
-    ElMessage.success('鎵归噺涓嬭浇瀹屾垚锛�')
-  } catch (error) {
-    console.error('鎵归噺涓嬭浇澶辫触:', error)
-    ElMessage.error('鎵归噺涓嬭浇澶辫触锛岃閫愪釜涓嬭浇')
-  }
-}
 
-// 娓呯┖鎵归噺鐢熸垚缁撴灉
-const clearBatchCodes = () => {
-  batchCodes.value = []
-}
+      ElMessage.success(`鎵归噺鐢熸垚瀹屾垚锛屽叡鐢熸垚 ${batchForm.quantity} 涓爜`);
+      batchDialogVisible.value = false;
+    } catch (error) {
+      console.error("鎵归噺鐢熸垚澶辫触:", error);
+      ElMessage.error("鎵归噺鐢熸垚澶辫触锛�" + error.message);
+    } finally {
+      generating.value = false;
+    }
+  };
 
-// 鏆撮湶鏂规硶缁欑埗缁勪欢
-defineExpose({
-  generateCode,
-  downloadCode,
-  resetForm,
-  form
-})
+  // 涓嬭浇鍗曚釜鎵归噺鐢熸垚鐨勭爜
+  const downloadSingleCode = code => {
+    const a = document.createElement("a");
+    a.href = code.url;
+    a.download = `${code.content}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+  };
+
+  // 涓嬭浇鎵�鏈夋壒閲忕敓鎴愮殑鐮�
+  const downloadAllCodes = async () => {
+    if (batchCodes.value.length === 0) {
+      ElMessage.warning("娌℃湁鍙笅杞界殑鐮�");
+      return;
+    }
+
+    try {
+      // 浣跨敤JSZip鎵撳寘涓嬭浇
+      const JSZip = await import("jszip");
+      const zip = new JSZip.default();
+
+      batchCodes.value.forEach((code, index) => {
+        // 灏哹ase64杞崲涓篵lob
+        const base64Data = code.url.split(",")[1];
+        const byteCharacters = atob(base64Data);
+        const byteNumbers = new Array(byteCharacters.length);
+        for (let i = 0; i < byteCharacters.length; i++) {
+          byteNumbers[i] = byteCharacters.charCodeAt(i);
+        }
+        const byteArray = new Uint8Array(byteNumbers);
+
+        zip.file(`${code.content}.png`, byteArray);
+      });
+
+      const content = await zip.generateAsync({ type: "blob" });
+      const a = document.createElement("a");
+      a.href = URL.createObjectURL(content);
+      a.download = `鎵归噺${
+        form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+      }_${new Date().getTime()}.zip`;
+      document.body.appendChild(a);
+      a.click();
+      document.body.removeChild(a);
+      URL.revokeObjectURL(a.href);
+
+      ElMessage.success("鎵归噺涓嬭浇瀹屾垚锛�");
+    } catch (error) {
+      console.error("鎵归噺涓嬭浇澶辫触:", error);
+      ElMessage.error("鎵归噺涓嬭浇澶辫触锛岃閫愪釜涓嬭浇");
+    }
+  };
+
+  // 娓呯┖鎵归噺鐢熸垚缁撴灉
+  const clearBatchCodes = () => {
+    batchCodes.value = [];
+  };
+
+  // 鏆撮湶鏂规硶缁欑埗缁勪欢
+  defineExpose({
+    generateCode,
+    downloadCode,
+    resetForm,
+    form,
+  });
 </script>
 
 <style scoped>
-.qr-code-generator {
-  padding: 20px;
-}
+  .qr-code-generator {
+    padding: 20px;
+  }
 
-.qr-form {
-  background: #f8f9fa;
-  padding: 20px;
-  border-radius: 8px;
-  margin-bottom: 20px;
-}
+  .qr-form {
+    background: #f8f9fa;
+    padding: 20px;
+    border-radius: 8px;
+    margin-bottom: 20px;
+  }
 
-.code-display {
-  margin-top: 30px;
-}
+  .code-display {
+    margin-top: 30px;
+  }
 
-.code-container {
-  display: flex;
-  justify-content: center;
-  align-items: flex-start;
-  gap: 40px;
-  margin: 20px 0;
-}
-
-.code-image img {
-  border: 2px solid #e0e0e0;
-  border-radius: 8px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.code-info {
-  text-align: left;
-  min-width: 200px;
-}
-
-.code-info p {
-  margin: 8px 0;
-  color: #666;
-}
-
-.code-actions {
-  text-align: center;
-  margin: 20px 0;
-}
-
-.code-actions .el-button {
-  margin: 0 10px;
-}
-
-.batch-results {
-  margin-top: 30px;
-}
-
-.batch-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
-  gap: 20px;
-  margin: 20px 0;
-}
-
-.batch-item {
-  text-align: center;
-  padding: 15px;
-  border: 1px solid #e0e0e0;
-  border-radius: 8px;
-  background: #fff;
-}
-
-.batch-item img {
-  width: 100px;
-  height: 100px;
-  margin-bottom: 10px;
-}
-
-.batch-content {
-  font-size: 12px;
-  color: #666;
-  margin: 10px 0;
-  word-break: break-all;
-}
-
-.batch-actions {
-  text-align: center;
-  margin: 20px 0;
-}
-
-.batch-actions .el-button {
-  margin: 0 10px;
-}
-
-@media (max-width: 768px) {
   .code-container {
-    flex-direction: column;
-    align-items: center;
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+    gap: 40px;
+    margin: 20px 0;
   }
-  
+
+  .code-image img {
+    border: 2px solid #e0e0e0;
+    border-radius: 8px;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  }
+
+  .code-info {
+    text-align: left;
+    min-width: 200px;
+  }
+
+  .code-info p {
+    margin: 8px 0;
+    color: #666;
+  }
+
+  .code-actions {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .code-actions .el-button {
+    margin: 0 10px;
+  }
+
+  .batch-results {
+    margin-top: 30px;
+  }
+
   .batch-grid {
-    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+    gap: 20px;
+    margin: 20px 0;
   }
-}
+
+  .batch-item {
+    text-align: center;
+    padding: 15px;
+    border: 1px solid #e0e0e0;
+    border-radius: 8px;
+    background: #fff;
+  }
+
+  .batch-item img {
+    width: 100px;
+    height: 100px;
+    margin-bottom: 10px;
+  }
+
+  .batch-content {
+    font-size: 12px;
+    color: #666;
+    margin: 10px 0;
+    word-break: break-all;
+  }
+
+  .batch-actions {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .batch-actions .el-button {
+    margin: 0 10px;
+  }
+
+  @media (max-width: 768px) {
+    .code-container {
+      flex-direction: column;
+      align-items: center;
+    }
+
+    .batch-grid {
+      grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    }
+  }
 </style>
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 03e2101..d4e938d 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -6,23 +6,6 @@
       <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
     </div>
     <!--    <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />-->
-    <div class="center-menu">
-      <span class="label">{{ userStore.currentFactoryName }}</span>
-      <el-dropdown @command="handleFactoryChange" class="right-menu-item hover-effect" trigger="click">
-        <div>
-          <el-icon size="20">
-            <Switch />
-          </el-icon>
-        </div>
-        <template #dropdown>
-          <el-dropdown-menu>
-            <el-dropdown-item v-for="item in factoryList" :key="item.deptId" :command="item">
-              {{ item.deptName }}
-            </el-dropdown-item>
-          </el-dropdown-menu>
-        </template>
-      </el-dropdown>
-    </div>
     <div class="right-menu">
       <!-- 娑堟伅閫氱煡 -->
       <el-popover
@@ -87,14 +70,10 @@
 import useAppStore from '@/store/modules/app'
 import useUserStore from '@/store/modules/user'
 import useSettingsStore from '@/store/modules/settings'
-import { userLoginFacotryList } from "@/api/system/user.js"
-import Cookies from "js-cookie";
-import { decrypt } from "@/utils/jsencrypt"
 
 const appStore = useAppStore()
 const userStore = useUserStore()
 const settingsStore = useSettingsStore()
-const factoryList = ref([])
 const notificationVisible = ref(false)
 const notificationCenterRef = ref(null)
 const unreadCount = ref(0)
@@ -139,42 +118,6 @@
 function toggleTheme() {
   settingsStore.toggleTheme()
 }
-
-function getUserLoginFacotryList() {
-  if (userStore.id) {
-    userLoginFacotryList({ userId: userStore.id }).then(res => {
-      console.log('res', res)
-      factoryList.value = res.data
-    })
-  } else {
-    factoryList.value = []
-  }
-}
-
-function handleFactoryChange(command) {
-  console.log('command', command)
-  handleLogin(command.deptId);
-}
-
-function handleLogin(currentFatoryId) {
-  const loginForm = {
-    username: Cookies.get("username"),
-    password: Cookies.get("password") === undefined ? null : decrypt(Cookies.get("password")),
-    currentFatoryId: currentFatoryId
-  }
-  userStore.loginCheckFactory(loginForm).then(res => {
-    forceReload();
-  }).catch((err) => {
-    console.log(err)
-  })
-}
-function forceReload() {
-  const currentUrl = window.location.origin + window.location.pathname;
-  const timestamp = new Date().getTime();
-  window.location.href = `${currentUrl}?reload=${timestamp}`;
-}
-
-getUserLoginFacotryList();
 
 // 娑堟伅閫氱煡鐩稿叧
 function handleUnreadCountChange(count) {
@@ -221,22 +164,6 @@
   position: relative;
   background: var(--navbar-bg);
   box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
-
-  .center-menu {
-    line-height: 50px;
-    position: absolute;
-    left: 50%;
-    transform: translateX(-50%);
-    display: flex;
-    align-items: center;
-
-    .label {
-      font-weight: bold;
-      font-size: 18px;
-      color: #333333;
-      margin-right: 10px;
-    }
-  }
 
   .hamburger-container {
     line-height: 46px;
diff --git a/src/layout/components/NotificationCenter/index.vue b/src/layout/components/NotificationCenter/index.vue
index df42650..6098153 100644
--- a/src/layout/components/NotificationCenter/index.vue
+++ b/src/layout/components/NotificationCenter/index.vue
@@ -107,8 +107,8 @@
     }
     const params = {
       consigneeId: consigneeId,
-      pageNum: pageNum.value,
-      pageSize: pageSize.value,
+      current: pageNum.value,
+      size: pageSize.value,
       status: activeTab.value === 'read' ? 1 : 0
     }
     const res = await listMessage(params)
diff --git a/src/main.js b/src/main.js
index abaac2e..0b3f714 100644
--- a/src/main.js
+++ b/src/main.js
@@ -52,6 +52,8 @@
 import DictTag from "@/components/DictTag";
 // 琛ㄦ牸缁勪欢
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
+// 椤甸潰澶撮儴缁勪欢
+import PageHeader from "@/components/PageHeader/index.vue";
 
 import { getToken } from "@/utils/auth";
 import {
@@ -93,6 +95,7 @@
 app.component("RightToolbar", RightToolbar);
 app.component("Editor", Editor);
 app.component("PIMTable", PIMTable);
+app.component("PageHeader", PageHeader);
 
 app.use(router);
 app.use(store);
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 057af50..4f3eab4 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -99,9 +99,8 @@
       loginCheckFactory(userInfo) {
         const username = userInfo.username.trim()
         const password = userInfo.password
-        const factoryId = userInfo.currentFatoryId
         return new Promise((resolve, reject) => {
-          loginCheckFactory(username, password, factoryId).then(res => {
+          loginCheckFactory(username, password).then(res => {
             setToken(res.token)
             this.token = res.token
             resolve()
diff --git a/src/views/basicData/product/ProductSelectDialog.vue b/src/views/basicData/product/ProductSelectDialog.vue
new file mode 100644
index 0000000..246cd88
--- /dev/null
+++ b/src/views/basicData/product/ProductSelectDialog.vue
@@ -0,0 +1,163 @@
+<template>
+  <el-dialog
+      v-model="visible"
+      title="閫夋嫨浜у搧"
+      width="900px"
+      destroy-on-close
+      :close-on-click-modal="false"
+  >
+    <el-form :inline="true" :model="query" class="mb-2">
+      <el-form-item label="浜у搧澶х被">
+        <el-input
+            v-model="query.productName"
+            placeholder="杈撳叆浜у搧澶х被"
+            clearable
+            @keyup.enter="onSearch"
+        />
+      </el-form-item>
+
+      <el-form-item label="鍨嬪彿鍚嶇О">
+        <el-input
+            v-model="query.model"
+            placeholder="杈撳叆鍨嬪彿鍚嶇О"
+            clearable
+            @keyup.enter="onSearch"
+        />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" @click="onSearch">鎼滅储</el-button>
+        <el-button @click="onReset">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 鍒楄〃 -->
+    <el-table
+        v-loading="loading"
+        :data="tableData"
+        height="420"
+        highlight-current-row
+        row-key="id"
+        @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column type="index" label="#" width="60"/>
+      <el-table-column prop="productName" label="浜у搧澶х被" min-width="160"/>
+      <el-table-column prop="model" label="鍨嬪彿鍚嶇О" min-width="200"/>
+      <el-table-column prop="unit" label="鍗曚綅" min-width="160"/>
+    </el-table>
+
+    <div class="mt-3 flex justify-end">
+      <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="total"
+          v-model:page-size="page.pageSize"
+          v-model:current-page="page.pageNum"
+          :page-sizes="[10, 20, 50, 100]"
+          @size-change="onPageChange"
+          @current-change="onPageChange"
+      />
+    </div>
+
+    <template #footer>
+      <el-button @click="close()">鍙栨秷</el-button>
+      <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm">
+        纭畾
+      </el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import {computed, onMounted, reactive, ref, watch} from "vue";
+import {ElMessage} from "element-plus";
+import {productModelList} from '@/api/basicData/productModel'
+
+export type ProductRow = {
+  id: number;
+  productName: string;
+  model: string;
+  unit?: string;
+};
+
+const props = defineProps<{
+  modelValue: boolean;
+}>();
+
+const emit = defineEmits(['update:modelValue', 'confirm']);
+
+const visible = computed({
+  get: () => props.modelValue,
+  set: (v) => emit("update:modelValue", v),
+});
+
+const query = reactive({
+  productName: "",
+  model: "",
+});
+
+const page = reactive({
+  pageNum: 1,
+  pageSize: 10,
+});
+
+const loading = ref(false);
+const tableData = ref<ProductRow[]>([]);
+const total = ref(0);
+const multipleSelection = ref<ProductRow[]>([])
+
+function close() {
+  visible.value = false;
+}
+
+const handleSelectionChange = (val: ProductRow[]) => {
+  multipleSelection.value = val
+}
+
+function onSearch() {
+  page.pageNum = 1;
+  loadData();
+}
+
+function onReset() {
+  query.productName = "";
+  query.model = "";
+  page.pageNum = 1;
+  loadData();
+}
+
+function onPageChange() {
+  loadData();
+}
+
+function onConfirm() {
+  if (multipleSelection.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨涓�鏉′骇鍝�");
+    return;
+  }
+  emit("confirm", multipleSelection.value);
+  close();
+}
+
+async function loadData() {
+  loading.value = true;
+  try {
+    multipleSelection.value = []; // 缈婚〉/鎼滅储鍚庢竻绌洪�夋嫨鏇寸鍚堥鏈�
+    const res = await productModelList({
+      productName: query.productName.trim(),
+      model: query.model.trim(),
+      current: page.pageNum,
+      size: page.pageSize,
+    });
+    tableData.value = res.records;
+    total.value = res.total;
+  } finally {
+    loading.value = false;
+  }
+}
+
+onMounted(() => {
+  loadData()
+})
+</script>
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index b88d678..3f0921a 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -25,9 +25,7 @@
           :data="list"
           @node-click="handleNodeClick"
           :expand-on-click-node="false"
-          default-expand-all
           :default-expanded-keys="expandedKeys"
-          :draggable="true"
           :filter-node-method="filterNode"
           :props="{ children: 'children', label: 'label' }"
           highlight-current
diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
index 9ff205f..44a0bcd 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -16,7 +16,7 @@
 				</el-row>
 				<el-row>
 					<el-col :span="24">
-						<el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptId">
+						<el-form-item label="鐢宠閮ㄩ棬锛�">
 							<el-select
 								disabled
 								v-model="form.approveDeptId"
@@ -32,7 +32,7 @@
 						</el-form-item>
 					</el-col>
 				</el-row>
-				<el-row>
+				<el-row v-if="!isQuotationApproval">
 					<el-col :span="24">
 						<el-form-item label="瀹℃壒浜嬬敱锛�" prop="approveReason">
 							<el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" disabled/>
@@ -73,6 +73,54 @@
 					</el-col>
 				</el-row>
 			</el-form>
+
+      <!-- 鎶ヤ环瀹℃壒锛氬睍绀烘姤浠疯鎯咃紙澶嶇敤閿�鍞姤浠封�滄煡鐪嬭鎯呭璇濇鈥濆唴瀹圭粨鏋勶級 -->
+      <div v-if="isQuotationApproval" style="margin: 10px 0 18px;">
+        <el-divider content-position="left">鎶ヤ环璇︽儏</el-divider>
+        <el-skeleton :loading="quotationLoading" animated>
+          <template #template>
+            <el-skeleton-item variant="h3" style="width: 30%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+          </template>
+          <template #default>
+            <el-empty v-if="!currentQuotation || !currentQuotation.quotationNo" description="鏈煡璇㈠埌瀵瑰簲鎶ヤ环璇︽儏" />
+            <template v-else>
+              <el-descriptions :column="2" border>
+                <el-descriptions-item label="鎶ヤ环鍗曞彿">{{ currentQuotation.quotationNo }}</el-descriptions-item>
+                <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ currentQuotation.customer }}</el-descriptions-item>
+                <el-descriptions-item label="涓氬姟鍛�">{{ currentQuotation.salesperson }}</el-descriptions-item>
+                <el-descriptions-item label="鎶ヤ环鏃ユ湡">{{ currentQuotation.quotationDate }}</el-descriptions-item>
+                <el-descriptions-item label="鏈夋晥鏈熻嚦">{{ currentQuotation.validDate }}</el-descriptions-item>
+                <el-descriptions-item label="浠樻鏂瑰紡">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
+                <el-descriptions-item label="鎶ヤ环鎬婚" :span="2">
+                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
+                    楼{{ Number(currentQuotation.totalAmount ?? 0).toFixed(2) }}
+                  </span>
+                </el-descriptions-item>
+              </el-descriptions>
+
+              <div style="margin-top: 20px;">
+                <h4>浜у搧鏄庣粏</h4>
+                <el-table :data="currentQuotation.products || []" border style="width: 100%">
+                  <el-table-column prop="product" label="浜у搧鍚嶇О" />
+                  <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" />
+                  <el-table-column prop="unit" label="鍗曚綅" />
+                  <el-table-column prop="unitPrice" label="鍗曚环">
+                    <template #default="scope">楼{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                </el-table>
+              </div>
+
+              <div v-if="currentQuotation.remark" style="margin-top: 20px;">
+                <h4>澶囨敞</h4>
+                <p>{{ currentQuotation.remark }}</p>
+              </div>
+            </template>
+          </template>
+        </el-skeleton>
+      </div>
+
       <el-form :model="{ activities }" ref="formRef" label-position="top">
         <el-steps :active="getActiveStep()" finish-status="success" process-status="process" align-center direction="vertical">
           <el-step
@@ -130,7 +178,7 @@
 </template>
 
 <script setup>
-import { getCurrentInstance, reactive, ref, toRefs } from "vue";
+import { computed, getCurrentInstance, nextTick, reactive, ref, toRefs } from "vue";
 import {
 	approveProcessDetails,
 	getDept,
@@ -139,8 +187,16 @@
 import useUserStore from "@/store/modules/user.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
+import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
 const emit = defineEmits(['close'])
 const { proxy } = getCurrentInstance()
+
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 0
+  }
+})
 
 const dialogFormVisible = ref(false);
 const operationType = ref('')
@@ -149,6 +205,10 @@
 const userStore = useUserStore()
 const productOptions = ref([]);
 const userList = ref([])
+const quotationLoading = ref(false)
+const currentQuotation = ref({})
+const isQuotationApproval = computed(() => Number(props.approveType) === 6)
+
 const data = reactive({
 	form: {
 		approveTime: "",
@@ -186,11 +246,51 @@
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
+  currentQuotation.value = {}
 	userListNoPageByTenantId().then((res) => {
 		userList.value = res.data;
 	});
 	form.value = {...row}
-	getProductOptions()
+	// 绔嬪嵆娓呴櫎琛ㄥ崟楠岃瘉鐘舵�侊紙鍥犱负瀛楁鏄痙isabled鐨勶紝涓嶉渶瑕侀獙璇侊級
+	nextTick(() => {
+		if (formRef.value) {
+			formRef.value.clearValidate();
+		}
+	});
+	// 纭繚閫夐」鍔犺浇瀹屾垚鍚庡啀鍖归厤鍊肩被鍨�
+	getProductOptions().then(() => {
+		// 纭繚鍊肩被鍨嬪尮閰嶏紙濡傛灉閫夐」宸插姞杞斤級
+		if (productOptions.value.length > 0 && form.value.approveDeptId) {
+			const matchedOption = productOptions.value.find(opt => 
+				opt.deptId == form.value.approveDeptId || 
+				String(opt.deptId) === String(form.value.approveDeptId)
+			);
+			if (matchedOption) {
+				form.value.approveDeptId = matchedOption.deptId;
+			}
+		}
+		// 鍐嶆娓呴櫎楠岃瘉锛岀‘淇濋�夐」鍔犺浇鍚庡�煎尮閰嶆纭�
+		nextTick(() => {
+			if (formRef.value) {
+				formRef.value.clearValidate();
+			}
+		});
+	});
+
+  // 鎶ヤ环瀹℃壒锛氱敤瀹℃壒浜嬬敱瀛楁鎵胯浇鐨勨�滄姤浠峰崟鍙封�濆幓鏌ユ姤浠峰垪琛�
+  if (isQuotationApproval.value) {
+    const quotationNo = row?.approveReason;
+    if (quotationNo) {
+      quotationLoading.value = true
+      getQuotationList({ quotationNo }).then((res) => {
+        const records = res?.data?.records || []
+        currentQuotation.value = records[0] || {}
+      }).finally(() => {
+        quotationLoading.value = false
+      })
+    }
+  }
+
   approveProcessDetails(row.approveId).then((res) => {
     activities.value = res.data
     // 澧炲姞isApproval瀛楁
@@ -211,17 +311,26 @@
   })
 }
 const getProductOptions = () => {
-	getDept().then((res) => {
+	return getDept().then((res) => {
 		productOptions.value = res.data;
 	});
 };
 // 鎻愪氦瀹℃壒
 const submitForm = (status) => {
   const filteredActivities = activities.value.filter(activity => activity.isShen);
-  filteredActivities[0].approveNodeStatus = status;
+  if (!filteredActivities || filteredActivities.length === 0) {
+    proxy.$modal.msgError("鏈壘鍒板緟瀹℃壒鐨勮妭鐐�");
+    return;
+  }
+  const currentActivity = filteredActivities[0];
+  if (!currentActivity) {
+    proxy.$modal.msgError("鏈壘鍒板緟瀹℃壒鐨勮妭鐐�");
+    return;
+  }
+  currentActivity.approveNodeStatus = status;
   // 鍒ゆ柇鏄惁涓烘渶鍚庝竴姝�
   const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1;
-  updateApproveNode({ ...filteredActivities[0], isLast }).then(() => {
+  updateApproveNode({ ...currentActivity, isLast }).then(() => {
     proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
     closeDia();
   });
@@ -230,6 +339,8 @@
 const closeDia = () => {
   proxy.resetForm("formRef");
   dialogFormVisible.value = false;
+  quotationLoading.value = false
+  currentQuotation.value = {}
   emit('close')
 };
 defineExpose({
diff --git a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
index a269375..67a635c 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -17,19 +17,19 @@
         <el-row>
           <el-col :span="24">
             <el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptName">
-              <el-input v-model="form.approveDeptName" placeholder="璇疯緭鍏�" clearable/>
-<!--							<el-select-->
-<!--								disabled-->
-<!--								v-model="form.approveDeptId"-->
-<!--								placeholder="閫夋嫨閮ㄩ棬"-->
-<!--							>-->
-<!--								<el-option-->
-<!--									v-for="user in productOptions"-->
-<!--									:key="user.deptId"-->
-<!--									:label="user.deptName"-->
-<!--									:value="user.deptId"-->
-<!--								/>-->
-<!--							</el-select>-->
+<!--              <el-input v-model="form.approveDeptName" placeholder="璇疯緭鍏�" clearable/>-->
+							<el-select
+								v-model="form.approveDeptId"
+								placeholder="閫夋嫨閮ㄩ棬"
+                @change="handleDeptChange"
+							>
+								<el-option
+									v-for="user in productOptions"
+									:key="user.deptId"
+									:label="user.deptName"
+									:value="user.deptId"
+								/>
+							</el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -217,6 +217,7 @@
 const emit = defineEmits(['close'])
 import useUserStore from "@/store/modules/user";
 import { getCurrentDate } from "@/utils/index.js";
+import log from "@/views/monitor/job/log.vue";
 const userStore = useUserStore();
 
 const dialogFormVisible = ref(false);
@@ -279,7 +280,17 @@
 function removeApproverNode(index) {
   approverNodes.value.splice(index, 1)
 }
-
+// 澶勭悊閮ㄩ棬閫夋嫨鍙樺寲
+const handleDeptChange = (deptId) => {
+  if (deptId) {
+    const selectedDept = productOptions.value.find(dept => dept.deptId === deptId);
+    if (selectedDept) {
+      form.value.approveDeptName = selectedDept.deptName;
+    }
+  } else {
+    form.value.approveDeptName = '';
+  }
+};
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
   operationType.value = type;
@@ -287,7 +298,6 @@
 	userListNoPageByTenantId().then((res) => {
     userList.value = res.data;
   });
-  getProductOptions();
 	form.value = {}
 	approverNodes.value = [
 		{ id: 1, userId: null }
@@ -297,6 +307,9 @@
   
   // 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅骞惰缃儴闂↖D
   form.value.approveDeptId = userStore.currentDeptId
+  
+  // 鍔犺浇閮ㄩ棬閫夐」锛屽苟鍦ㄥ姞杞藉畬鎴愬悗璁剧疆閮ㄩ棬鍚嶇О
+  getProductOptions();
   if (operationType.value === 'edit') {
     fileList.value = row.commonFileList
     form.value.tempFileIds = fileList.value.map(file => file.id)
@@ -319,8 +332,18 @@
   }
 }
 const getProductOptions = () => {
-  getDept().then((res) => {
+  return getDept().then((res) => {
     productOptions.value = res.data;
+    // 濡傛灉宸叉湁閮ㄩ棬ID锛岃嚜鍔ㄨ缃儴闂ㄥ悕绉帮紙鐢ㄤ簬楠岃瘉锛�
+    if (form.value.approveDeptId && productOptions.value.length > 0) {
+      const matchedDept = productOptions.value.find(dept => 
+        dept.deptId == form.value.approveDeptId || 
+        String(dept.deptId) === String(form.value.approveDeptId)
+      );
+      if (matchedDept) {
+        form.value.approveDeptName = matchedDept.deptName;
+      }
+    }
   });
 };
 function convertIdToValue(data) {
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index 8c84b27..5ce951d 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -35,7 +35,7 @@
         >
       </div>
       <div>
-        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
+        <el-button type="primary" @click="openForm('add')" v-if="currentApproveType !== 6">鏂板</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
@@ -54,7 +54,7 @@
       ></PIMTable>
     </div>
     <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="currentApproveType"></info-form-dia>
-    <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
+    <approval-dia ref="approvalDia" @close="handleQuery" :approveType="currentApproveType"></approval-dia>
     <FileList ref="fileListRef" />
   </div>
 </template>
@@ -103,6 +103,7 @@
 const tableColumnCopy = computed(() => {
   const isLeaveType = currentApproveType.value === 2; // 璇峰亣绠$悊
   const isReimburseType = currentApproveType.value === 4; // 鎶ラ攢绠$悊
+  const isQuotationType = currentApproveType.value === 6; // 鎶ヤ环瀹℃壒
   
   // 鍩虹鍒楅厤缃�
   const baseColumns = [
@@ -149,7 +150,7 @@
       width: 220
     },
     {
-      label: "瀹℃壒浜嬬敱",
+      label: isQuotationType ? "鎶ヤ环鍗曞彿" : "瀹℃壒浜嬬敱",
       prop: "approveReason",
       width: 200
     },
@@ -204,7 +205,7 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
-        disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
+        disabled: (row) => currentApproveType.value === 6 || row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
       },
       {
         name: "瀹℃牳",
diff --git a/src/views/collaborativeApproval/enterpriseBook/index.vue b/src/views/collaborativeApproval/enterpriseBook/index.vue
index 0b33a32..fa9fa5c 100644
--- a/src/views/collaborativeApproval/enterpriseBook/index.vue
+++ b/src/views/collaborativeApproval/enterpriseBook/index.vue
@@ -295,7 +295,6 @@
   getEmployeeDetail
 } from '@/api/collaborativeApproval/enterpriseBook.js'
 import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
 import {
   changeUserStatus,
   listUser,
@@ -306,6 +305,7 @@
   addUser,
   deptTreeSelect,
 } from "@/api/system/user";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏍囩椤电姸鎬�
 const activeTab = ref('personal')
@@ -395,7 +395,7 @@
 }
   //鑾峰彇鍛樺伐鍒楄〃
 const getEmployeeList = async () => {
-  staffJoinListPage(publicSearch.value).then(res => {
+  staffOnJobListPage(Object.assign({current: -1, size: -1},publicSearch.value)).then(res => {
     console.log(res.data.records)
       EmployeeList.value = res.data.records
     }).catch(err => {})
@@ -403,7 +403,7 @@
 // 鑾峰彇鍗曚綅閫氳褰曞垪琛�
 const getCompanyContactsList = async () => {
   loading.value = true
-    staffJoinListPage(companySearch.value).then(res => {
+  staffOnJobListPage(Object.assign({current: -1, size: -1},companySearch.value)).then(res => {
     // console.log(res.data.records)
       companyContacts.value = res.data.records
     }).catch(err => {})
diff --git a/src/views/collaborativeApproval/noticeManagement/index.vue b/src/views/collaborativeApproval/noticeManagement/index.vue
index 6b0ea98..0957882 100644
--- a/src/views/collaborativeApproval/noticeManagement/index.vue
+++ b/src/views/collaborativeApproval/noticeManagement/index.vue
@@ -617,34 +617,23 @@
   };
   
   if (row.id) {
-    // 缂栬緫妯″紡 - 鍏堝垹闄ゅ啀娣诲姞锛堝洜涓哄彧鏈� add 鍜� del 鎺ュ彛锛�
-    delNoticeType(row.id).then(res => {
-      if (res.code === 200) {
-        addNoticeType(data).then(addRes => {
-          if (addRes.code === 200) {
-            ElMessage.success('缂栬緫鎴愬姛');
-            row.editing = false;
-            delete row.originalNoticeType;
-            fetchNoticeTypeList().then(() => {
-              // 濡傛灉褰撳墠閫変腑鐨勭被鍨嬭缂栬緫锛岄渶瑕侀噸鏂拌幏鍙栨暟鎹�
-              if (activeNoticeTypeTab.value === String(row.id)) {
-                fetchNoticesByType(addRes.data?.id || row.id);
-              }
-            });
-          }
-        });
-      }
-    });
-  } else {
-    // 鏂板妯″紡
-    addNoticeType(data).then(res => {
-      if (res.code === 200) {
-        ElMessage.success('鏂板鎴愬姛');
-        row.editing = false;
-        fetchNoticeTypeList();
-      }
-    });
+    // 缂栬緫妯″紡 - 浼犲叆id
+    data.id = row.id;
   }
+  
+  addNoticeType(data).then(res => {
+    if (res.code === 200) {
+      ElMessage.success(row.id ? '缂栬緫鎴愬姛' : '鏂板鎴愬姛');
+      row.editing = false;
+      delete row.originalNoticeType;
+      fetchNoticeTypeList().then(() => {
+        // 濡傛灉褰撳墠閫変腑鐨勭被鍨嬭缂栬緫锛岄渶瑕侀噸鏂拌幏鍙栨暟鎹�
+        if (row.id && activeNoticeTypeTab.value === String(row.id)) {
+          fetchNoticesByType(res.data?.id || row.id);
+        }
+      });
+    }
+  });
 };
 
 const handleDeleteNoticeType = (row) => {
@@ -855,6 +844,9 @@
   color: #606266;
   line-height: 1.6;
   font-size: 14px;
+  word-break: break-all;
+  white-space: pre-wrap;
+  overflow-wrap: break-word;
 }
 
 .card-footer {
diff --git a/src/views/collaborativeApproval/notificationManagement/index.vue b/src/views/collaborativeApproval/notificationManagement/index.vue
index 37c13cf..fb3f7a8 100644
--- a/src/views/collaborativeApproval/notificationManagement/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/index.vue
@@ -322,7 +322,7 @@
 import { ElMessage, ElMessageBox } from "element-plus";
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
 import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
 import { listNotification, addNotification, updateNotification, delNotification,addOnlineMeeting,addFileSharing } from "@/api/collaborativeApproval/notificationManagement.js";
 import { id } from "element-plus/es/locales.mjs";
 
diff --git a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
index 7781593..ed2dafa 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
@@ -127,7 +127,7 @@
             <el-option
                 v-for="person in employees"
                 :key="person.id"
-                :label="`${person.staffName} (${person.postJob})`"
+                :label="`${person.staffName} (${person.postName})`"
                 :value="person.id"
             />
           </el-select>
@@ -156,7 +156,7 @@
 import {ElMessage} from 'element-plus'
 import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue'
 import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 褰撳墠鐢宠绫诲瀷
 const currentType = ref('department') // approval: 瀹℃壒娴佺▼, department: 閮ㄩ棬绾�, notification: 閫氱煡鍙戝竷
@@ -302,8 +302,12 @@
   getRoomEnum().then(res => {
     meetingRooms.value = res.data
   })
-  getStaffOnJob().then(res => {
-    employees.value = res.data.sort((a, b) => a.postJob.localeCompare(b.postJob))
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    employees.value = res.data.records.sort((a, b) => a.postName.localeCompare(b.postName))
   })
 })
 </script>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
index 83747a0..157b6b5 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
@@ -188,8 +188,8 @@
 import {ElMessage, ElMessageBox} from 'element-plus'
 import Pagination from '@/components/Pagination/index.vue'
 import {getRoomEnum, getExamineList,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -240,7 +240,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -342,9 +342,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
index 2351293..a85de7f 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
@@ -186,8 +186,8 @@
 import {ElMessage, ElMessageBox} from 'element-plus'
 import Pagination from '@/components/Pagination/index.vue'
 import {getRoomEnum, getMeetingPublish,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -239,7 +239,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -340,9 +340,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/notificationManagement/summary/index.vue b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
index a00316d..f94e548 100644
--- a/src/views/collaborativeApproval/notificationManagement/summary/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
@@ -160,8 +160,8 @@
 import Pagination from '@/components/Pagination/index.vue'
 import Editor from '@/components/Editor/index.vue'
 import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js'
-import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js"
 import dayjs from "dayjs"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -214,7 +214,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -337,9 +337,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2] = await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
index 91a6468..1c71cdc 100644
--- a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
+++ b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
@@ -1,101 +1,166 @@
 <template>
   <div class="app-container">
-    
-        <!-- 瑙勭珷鍒跺害绠$悊-->
-          <el-card class="box-card">
-            <template #header>
-              <div class="card-header">
-                <span>瑙勭珷鍒跺害鍙戝竷</span>
-              </div>
+    <!-- 瑙勭珷鍒跺害绠$悊-->
+    <el-card class="box-card">
+      <template #header>
+        <div class="card-header">
+          <span>瑙勭珷鍒跺害鍙戝竷</span>
+        </div>
+      </template>
+      <div class="tab-content">
+        <el-row :gutter="20"
+                class="mb-20">
+          <span class="ml-10">鍒跺害鏍囬锛�</span>
+          <el-col :span="6">
+            <el-input v-model="regulationSearchForm.title"
+                      placeholder="璇疯緭鍏ュ埗搴︽爣棰�"
+                      clearable />
+          </el-col>
+          <span class="search_title">鍒跺害鍒嗙被锛�</span>
+          <el-col :span="4">
+            <el-select v-model="regulationSearchForm.category"
+                       placeholder="鍒跺害鍒嗙被"
+                       clearable>
+              <el-option label="浜轰簨鍒跺害"
+                         value="hr" />
+              <el-option label="璐㈠姟鍒跺害"
+                         value="finance" />
+              <el-option label="瀹夊叏鍒跺害"
+                         value="safety" />
+              <el-option label="鎶�鏈埗搴�"
+                         value="tech" />
+            </el-select>
+          </el-col>
+          <el-col :span="8">
+            <el-button type="primary"
+                       @click="searchRegulations">鎼滅储</el-button>
+            <el-button @click="resetRegulationSearch">閲嶇疆</el-button>
+            <el-button @click="handleExport">瀵煎嚭</el-button>
+            <el-button type="success"
+                       @click="handleAdd">
+              鍙戝竷鍒跺害
+            </el-button>
+          </el-col>
+        </el-row>
+        <el-table :data="regulations"
+                  border
+                  v-loading="tableLoading"
+                  style="width: 100%">
+          <el-table-column prop="regulationNum"
+                           label="鍒跺害缂栧彿"
+                           width="120" />
+          <el-table-column prop="title"
+                           label="鍒跺害鏍囬"
+                           min-width="150" />
+          <el-table-column prop="category"
+                           label="鍒嗙被"
+                           width="120">
+            <template #default="scope">
+              <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag>
             </template>
-            <div class="tab-content">
-              <el-row :gutter="20" class="mb-20">
-                <span class="ml-10">鍒跺害鏍囬锛�</span>
-                <el-col :span="6">
-                  <el-input v-model="regulationSearchForm.title" placeholder="璇疯緭鍏ュ埗搴︽爣棰�" clearable />
-                </el-col>
-                <span class="search_title">鍒跺害鍒嗙被锛�</span>
-                <el-col :span="4">
-                  <el-select v-model="regulationSearchForm.category" placeholder="鍒跺害鍒嗙被" clearable>
-                    <el-option label="浜轰簨鍒跺害" value="hr" />
-                    <el-option label="璐㈠姟鍒跺害" value="finance" />
-                    <el-option label="瀹夊叏鍒跺害" value="safety" />
-                    <el-option label="鎶�鏈埗搴�" value="tech" />
-                  </el-select>
-                </el-col>
-                <el-col :span="8">
-                  <el-button type="primary" @click="searchRegulations">鎼滅储</el-button>
-                  <el-button @click="resetRegulationSearch">閲嶇疆</el-button>
-                  <el-button @click="handleExport">瀵煎嚭</el-button>
-                  <el-button type="success" @click="handleAdd">
-                    鍙戝竷鍒跺害
-                  </el-button>
-                </el-col>
-              </el-row>
-
-              <el-table :data="regulations" border v-loading="tableLoading"  style="width: 100%">
-                <el-table-column prop="regulationNum" label="鍒跺害缂栧彿" width="120" />
-                <el-table-column prop="title" label="鍒跺害鏍囬" min-width="150" />
-                <el-table-column prop="category" label="鍒嗙被" width="120">
-                  <template #default="scope">
-                    <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="version" label="鐗堟湰" width="120" />
-                <el-table-column prop="createUserName" label="鍙戝竷浜�" width="120" />
-                <el-table-column prop="createTime" label="鍙戝竷鏃堕棿" width="180" />
-                <el-table-column prop="status" label="鐘舵��" width="100">
-                  <template #default="scope">
-                    <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
-                      {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
-                    </el-tag>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="readCount" label="宸茶浜烘暟" width="100" />
-                <el-table-column label="鎿嶄綔" width="320" fixed="right">
-                  <template #default="scope">
-                    <el-button link @click="viewRegulation(scope.row)">鏌ョ湅</el-button>
-                    <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
-                    <el-button link type="danger" @click="repealEdit(scope.row)">搴熷純</el-button>
-                    <el-button link type="success" @click="viewVersionHistory(scope.row)">鐗堟湰鍘嗗彶</el-button>
-                    <el-button link type="warning" @click="viewReadStatus(scope.row)">闃呰鐘舵��</el-button>
-                    <el-button link type="primary" @click="openFileDialog(scope.row)">闄勪欢</el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-            </div>
-          </el-card>
-
+          </el-table-column>
+          <el-table-column prop="version"
+                           label="鐗堟湰"
+                           width="120" />
+          <el-table-column prop="createUserName"
+                           label="鍙戝竷浜�"
+                           width="120" />
+          <el-table-column prop="createTime"
+                           label="鍙戝竷鏃堕棿"
+                           width="180" />
+          <el-table-column prop="status"
+                           label="鐘舵��"
+                           width="100">
+            <template #default="scope">
+              <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+                {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="readCount"
+                           label="宸茶浜烘暟"
+                           width="100" />
+          <el-table-column label="鎿嶄綔"
+                           width="320"
+                           fixed="right">
+            <template #default="scope">
+              <el-button link
+                         @click="viewRegulation(scope.row)">鏌ョ湅</el-button>
+              <el-button link
+                         type="primary"
+                         @click="handleEdit(scope.row)">缂栬緫</el-button>
+              <el-button link
+                         type="danger"
+                         @click="repealEdit(scope.row)">搴熷純</el-button>
+              <el-button link
+                         type="success"
+                         @click="viewVersionHistory(scope.row)">鐗堟湰鍘嗗彶</el-button>
+              <!-- <el-button link type="warning" @click="viewReadStatus(scope.row)">闃呰鐘舵��</el-button> -->
+              <el-button link
+                         type="primary"
+                         @click="openFileDialog(scope.row)">闄勪欢</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-card>
     <!-- 鐢ㄥ嵃鐢宠瀵硅瘽妗嗭紙宸茬Щ闄わ級 -->
-
     <!-- 瑙勭珷鍒跺害鍙戝竷瀵硅瘽妗� -->
-    <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? '鍙戝竷鍒跺害' : '缂栬緫鍒跺害'" width="800px">
-      <el-form :model="regulationForm" :rules="regulationRules" ref="regulationFormRef" label-width="100px">
-        <el-form-item label="鍒跺害缂栧彿" prop="regulationNum">
-          <el-input v-model="regulationForm.regulationNum" placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
+    <el-dialog v-model="showRegulationDialog"
+               :title="operationType === 'add' ? '鍙戝竷鍒跺害' : '缂栬緫鍒跺害'"
+               width="800px">
+      <el-form :model="regulationForm"
+               :rules="regulationRules"
+               ref="regulationFormRef"
+               label-width="100px">
+        <el-form-item label="鍒跺害缂栧彿"
+                      prop="regulationNum">
+          <el-input v-model="regulationForm.regulationNum"
+                    placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
         </el-form-item>
-        <el-form-item label="鍒跺害鏍囬" prop="title">
-          <el-input v-model="regulationForm.title" placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
+        <el-form-item label="鍒跺害鏍囬"
+                      prop="title">
+          <el-input v-model="regulationForm.title"
+                    placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
         </el-form-item>
-        <el-form-item label="鍒跺害鍒嗙被" prop="category">
-          <el-select v-model="regulationForm.category" placeholder="璇烽�夋嫨鍒跺害鍒嗙被" style="width: 100%">
-            <el-option label="浜轰簨鍒跺害" value="hr" />
-            <el-option label="璐㈠姟鍒跺害" value="finance" />
-            <el-option label="瀹夊叏鍒跺害" value="safety" />
-            <el-option label="鎶�鏈埗搴�" value="tech" />
+        <el-form-item label="鍒跺害鍒嗙被"
+                      prop="category">
+          <el-select v-model="regulationForm.category"
+                     placeholder="璇烽�夋嫨鍒跺害鍒嗙被"
+                     style="width: 100%">
+            <el-option label="浜轰簨鍒跺害"
+                       value="hr" />
+            <el-option label="璐㈠姟鍒跺害"
+                       value="finance" />
+            <el-option label="瀹夊叏鍒跺害"
+                       value="safety" />
+            <el-option label="鎶�鏈埗搴�"
+                       value="tech" />
           </el-select>
         </el-form-item>
-        <el-form-item label="鍒跺害鍐呭" prop="content">
-          <el-input v-model="regulationForm.content" type="textarea" :rows="10" placeholder="璇疯緭鍏ュ埗搴﹁缁嗗唴瀹�" />
+        <el-form-item label="鍒跺害鍐呭"
+                      prop="content">
+          <el-input v-model="regulationForm.content"
+                    type="textarea"
+                    :rows="10"
+                    placeholder="璇疯緭鍏ュ埗搴﹁缁嗗唴瀹�" />
         </el-form-item>
-        <el-form-item label="鍒跺害鐗堟湰" prop="version">
-          <el-input v-model="regulationForm.version" placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
+        <el-form-item label="鍒跺害鐗堟湰"
+                      prop="version">
+          <el-input v-model="regulationForm.version"
+                    placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
         </el-form-item>
-        <el-form-item label="鐢熸晥鏃堕棿" prop="effectiveTime">
-          <el-date-picker v-model="regulationForm.effectiveTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
-             value-format="YYYY-MM-DD HH:mm:ss" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
+        <el-form-item label="鐢熸晥鏃堕棿"
+                      prop="effectiveTime">
+          <el-date-picker v-model="regulationForm.effectiveTime"
+                          type="datetime"
+                          format="YYYY-MM-DD HH:mm:ss"
+                          value-format="YYYY-MM-DD HH:mm:ss"
+                          placeholder="閫夋嫨鐢熸晥鏃堕棿"
+                          style="width: 100%" />
         </el-form-item>
-        <el-form-item label="閫傜敤鑼冨洿" prop="scope">
+        <el-form-item label="閫傜敤鑼冨洿"
+                      prop="scope">
           <el-checkbox-group v-model="regulationForm.scope">
             <el-checkbox label="all">鍏ㄤ綋鍛樺伐</el-checkbox>
             <el-checkbox label="manager">绠$悊灞�</el-checkbox>
@@ -104,7 +169,8 @@
             <el-checkbox label="tech">鎶�鏈儴闂�</el-checkbox>
           </el-checkbox-group>
         </el-form-item>
-        <el-form-item label="鏄惁闇�瑕佺‘璁�" prop="requireConfirm">
+        <el-form-item label="鏄惁闇�瑕佺‘璁�"
+                      prop="requireConfirm">
           <el-switch v-model="regulationForm.requireConfirm" />
           <span class="ml-10">寮�鍚悗鍛樺伐闇�瑕侀槄璇荤‘璁�</span>
         </el-form-item>
@@ -112,17 +178,19 @@
       <template #footer>
         <span class="dialog-footer">
           <el-button @click="showRegulationDialog = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="submitRegulation">鍙戝竷鍒跺害</el-button>
+          <el-button type="primary"
+                     @click="submitRegulation">鍙戝竷鍒跺害</el-button>
         </span>
       </template>
     </el-dialog>
-
     <!-- 鐢ㄥ嵃璇︽儏瀵硅瘽妗嗭紙宸茬Щ闄わ級 -->
-
     <!-- 瑙勭珷鍒跺害璇︽儏瀵硅瘽妗� -->
-    <el-dialog v-model="showRegulationDetailDialog" title="瑙勭珷鍒跺害璇︽儏" width="800px">
+    <el-dialog v-model="showRegulationDetailDialog"
+               title="瑙勭珷鍒跺害璇︽儏"
+               width="800px">
       <div v-if="currentRegulationDetail">
-        <el-descriptions :column="2" border>
+        <el-descriptions :column="2"
+                         border>
           <el-descriptions-item label="鍒跺害缂栧彿">{{ currentRegulationDetail.id }}</el-descriptions-item>
           <el-descriptions-item label="鍒跺害鏍囬">{{ currentRegulationDetail.title }}</el-descriptions-item>
           <el-descriptions-item label="鍒嗙被">{{ getCategoryText(currentRegulationDetail.category) }}</el-descriptions-item>
@@ -135,19 +203,30 @@
           <div class="regulation-content">{{ currentRegulationDetail.content }}</div>
         </div>
         <!-- 濡傛灉tableData>0 鏄剧ず -->
-        <div style="margin: 10px 0;" v-if="tableData && tableData.length > 0" >
-          <el-button type="success" @click="resetForm(currentRegulationDetail)">纭鏌ョ湅</el-button>
+        <div style="margin: 10px 0;"
+             v-if="tableData && tableData.length > 0">
+          <el-button type="success"
+                     @click="resetForm(currentRegulationDetail)">纭鏌ョ湅</el-button>
         </div>
       </div>
     </el-dialog>
-
     <!-- 鐗堟湰鍘嗗彶瀵硅瘽妗� -->
-    <el-dialog v-model="showVersionHistoryDialog" title="鐗堟湰鍘嗗彶" width="800px">
-      <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px">
-        <el-table-column prop="version" label="鐗堟湰鍙�" width="100" />
-        <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
-        <el-table-column prop="createUserName" label="鏇存柊浜�" width="120" />
-        <el-table-column prop="changeLog" label="鍙樻洿璇存槑">
+    <el-dialog v-model="showVersionHistoryDialog"
+               title="鐗堟湰鍘嗗彶"
+               width="800px">
+      <el-table :data="versionHistory"
+                style="width: 100%;margin-bottom: 10px">
+        <el-table-column prop="version"
+                         label="鐗堟湰鍙�"
+                         width="100" />
+        <el-table-column prop="updateTime"
+                         label="鏇存柊鏃堕棿"
+                         width="180" />
+        <el-table-column prop="createUserName"
+                         label="鏇存柊浜�"
+                         width="120" />
+        <el-table-column prop="changeLog"
+                         label="鍙樻洿璇存槑">
           <template #default="scope">
             <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
               {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
@@ -156,15 +235,27 @@
         </el-table-column>
       </el-table>
     </el-dialog>
-
     <!-- 闃呰鐘舵�佸璇濇 -->
-    <el-dialog v-model="showReadStatusDialog" title="闃呰鐘舵��" width="800px">
-      <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px">
-        <el-table-column prop="employee" label="鍛樺伐濮撳悕" width="120" />
-        <el-table-column prop="department" label="鎵�灞為儴闂�" width="150" />
-        <el-table-column prop="createTime" label="闃呰鏃堕棿" width="180" />
-        <el-table-column prop="confirmTime" label="纭鏃堕棿" width="180" />
-        <el-table-column prop="status" label="鐘舵��" width="100">
+    <el-dialog v-model="showReadStatusDialog"
+               title="闃呰鐘舵��"
+               width="800px">
+      <el-table :data="readStatusList"
+                style="width: 100%;margin-bottom: 10px">
+        <el-table-column prop="employee"
+                         label="鍛樺伐濮撳悕"
+                         width="120" />
+        <el-table-column prop="department"
+                         label="鎵�灞為儴闂�"
+                         width="150" />
+        <el-table-column prop="createTime"
+                         label="闃呰鏃堕棿"
+                         width="180" />
+        <el-table-column prop="confirmTime"
+                         label="纭鏃堕棿"
+                         width="180" />
+        <el-table-column prop="status"
+                         label="鐘舵��"
+                         width="100">
           <template #default="scope">
             <el-tag :type="scope.row.status === 'confirmed' ? 'success' : 'warning'">
               {{ scope.row.status === 'confirmed' ? '宸茬‘璁�' : '鏈‘璁�' }}
@@ -173,412 +264,437 @@
         </el-table-column>
       </el-table>
     </el-dialog>
-
-    <FileListDialog
-      ref="fileListDialogRef"
-      v-model="fileDialogVisible"
-      :show-upload-button="true"
-      :show-delete-button="true"
-      :delete-method="handleAttachmentDelete"
-      :rules-regulations-management-id="currentFileRuleId"
-      :name-column-label="'闄勪欢鍚嶇О'"
-      @upload="handleAttachmentUpload"
-    />
+    <FileListDialog ref="fileListDialogRef"
+                    v-model="fileDialogVisible"
+                    :show-upload-button="true"
+                    :show-delete-button="true"
+                    :delete-method="handleAttachmentDelete"
+                    :rules-regulations-management-id="currentFileRuleId"
+                    :name-column-label="'闄勪欢鍚嶇О'"
+                    @upload="handleAttachmentUpload" />
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,addReadingStatus,updateReadingStatus  } from '@/api/collaborativeApproval/sealManagement.js'
-import FileListDialog from '@/components/Dialog/FileListDialog.vue'
-import { listRuleFiles, delRuleFile, addRuleFile } from '@/api/collaborativeApproval/rulesRegulationsManagementFile.js'
+  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import {
+    listRuleManagement,
+    addRuleManagement,
+    updateRuleManagement,
+    delRuleManagement,
+    getReadingStatusByRuleId,
+    addReadingStatus,
+    updateReadingStatus,
+  } from "@/api/collaborativeApproval/sealManagement.js";
+  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
+  import {
+    listRuleFiles,
+    delRuleFile,
+    addRuleFile,
+  } from "@/api/collaborativeApproval/rulesRegulationsManagementFile.js";
 
-// 鍝嶅簲寮忔暟鎹�
-const operationType = ref('add')
-const tableData = ref([])
-const tableLoading = ref(false)
-// 鍒嗛〉鍙傛暟
-const page = reactive({
-  current: 1,
-  size: 10,
-  total: 0
-})
-// 闄勪欢寮圭獥
-const fileDialogVisible = ref(false)
-const fileListDialogRef = ref(null)
-const currentFileRuleId = ref(null)
-const filePage = reactive({
-  current: 1,
-  size: 10,
-  total: 0
-})
-// 瑙勭珷鍒跺害鐩稿叧
-const showRegulationDialog = ref(false)
-const showRegulationDetailDialog = ref(false)
-const showVersionHistoryDialog = ref(false)
-const showReadStatusDialog = ref(false)
-const currentRegulationDetail = ref(null)
-const regulationFormRef = ref()
-const regulationForm = reactive({
-  id: '',
-  regulationNum: '',
-  title: '',
-  category: '',
-  content: '',
-  version: '',
-  status: 'active',
-  readCount: 0,
-  effectiveTime: '',
-  scope: [],
-  requireConfirm: false
-})
+  // 鍝嶅簲寮忔暟鎹�
+  const operationType = ref("add");
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  // 鍒嗛〉鍙傛暟
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  // 闄勪欢寮圭獥
+  const fileDialogVisible = ref(false);
+  const fileListDialogRef = ref(null);
+  const currentFileRuleId = ref(null);
+  const filePage = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  // 瑙勭珷鍒跺害鐩稿叧
+  const showRegulationDialog = ref(false);
+  const showRegulationDetailDialog = ref(false);
+  const showVersionHistoryDialog = ref(false);
+  const showReadStatusDialog = ref(false);
+  const currentRegulationDetail = ref(null);
+  const regulationFormRef = ref();
+  const regulationForm = reactive({
+    id: "",
+    regulationNum: "",
+    title: "",
+    category: "",
+    content: "",
+    version: "",
+    status: "active",
+    readCount: 0,
+    effectiveTime: "",
+    scope: [],
+    requireConfirm: false,
+  });
 
-const readStatus = ref({
-  id: '',
-  ruleId: '',
-  employee: '',
-  department: '',
-  createTime: '',
-  confirmTime: '',
-  status: 'unconfirmed'
-})
+  const readStatus = ref({
+    id: "",
+    ruleId: "",
+    employee: "",
+    department: "",
+    createTime: "",
+    confirmTime: "",
+    status: "unconfirmed",
+  });
 
-const regulationRules = {
-  title: [{ required: true, message: '璇疯緭鍏ュ埗搴︽爣棰�', trigger: 'blur' }],
-  category: [{ required: true, message: '璇烽�夋嫨鍒跺害鍒嗙被', trigger: 'change' }],
-  content: [{ required: true, message: '璇疯緭鍏ュ埗搴﹀唴瀹�', trigger: 'blur' }],
-  effectiveTime: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃堕棿', trigger: 'change' }],
-  scope: [{ required: true, message: '璇烽�夋嫨閫傜敤鑼冨洿', trigger: 'change' }]
-}
+  const regulationRules = {
+    title: [{ required: true, message: "璇疯緭鍏ュ埗搴︽爣棰�", trigger: "blur" }],
+    category: [{ required: true, message: "璇烽�夋嫨鍒跺害鍒嗙被", trigger: "change" }],
+    content: [{ required: true, message: "璇疯緭鍏ュ埗搴﹀唴瀹�", trigger: "blur" }],
+    effectiveTime: [
+      { required: true, message: "璇烽�夋嫨鐢熸晥鏃堕棿", trigger: "change" },
+    ],
+    scope: [{ required: true, message: "璇烽�夋嫨閫傜敤鑼冨洿", trigger: "change" }],
+  };
 
-const regulationSearchForm = reactive({
-  title: '',
-  category: ''
-})
+  const regulationSearchForm = reactive({
+    title: "",
+    category: "",
+  });
 
-const regulations = ref([])
+  const regulations = ref([]);
 
-const versionHistory = ref([])
+  const versionHistory = ref([]);
 
-const readStatusList = ref([])
+  const readStatusList = ref([]);
   // { employee: '闄堝織寮�', department: '閿�鍞儴', readTime: '2025-01-11 10:30:00', confirmTime: '2025-01-11 10:35:00', status: 'confirmed' },
   // { employee: '鍒橀泤濠�', department: '鎶�鏈儴', readTime: '2025-01-11 14:20:00', confirmTime: '', status: 'unconfirmed' },
   // { employee: '鐜嬪缓鍥�', department: '璐㈠姟閮�', readTime: '2025-01-12 09:15:00', confirmTime: '2025-01-12 09:20:00', status: 'confirmed' }
 
-// 鍒跺害鍒嗙被
-const getCategoryText = (category) => {
-  const categoryMap = {
-    hr: '浜轰簨鍒跺害',
-    finance: '璐㈠姟鍒跺害',
-    safety: '瀹夊叏鍒跺害',
-    tech: '鎶�鏈埗搴�'
-  }
-  return categoryMap[category] || '鏈煡'
-}
-// 鎼滅储鍒跺害
-const searchRegulations = () => {
-  page.current=1
-  getRegulationList()
-}
-// 閲嶇疆鍒跺害鎼滅储
-const resetRegulationSearch = () => {
-  regulationSearchForm.title = ''
-  regulationSearchForm.category = ''
-  searchRegulations()
-}
-// 鏂板
-const handleAdd = () => {
-  operationType.value = 'add'
-  resetRegulationForm()
-  showRegulationDialog.value = true
-}
+  // 鍒跺害鍒嗙被
+  const getCategoryText = category => {
+    const categoryMap = {
+      hr: "浜轰簨鍒跺害",
+      finance: "璐㈠姟鍒跺害",
+      safety: "瀹夊叏鍒跺害",
+      tech: "鎶�鏈埗搴�",
+    };
+    return categoryMap[category] || "鏈煡";
+  };
+  // 鎼滅储鍒跺害
+  const searchRegulations = () => {
+    page.current = 1;
+    getRegulationList();
+  };
+  // 閲嶇疆鍒跺害鎼滅储
+  const resetRegulationSearch = () => {
+    regulationSearchForm.title = "";
+    regulationSearchForm.category = "";
+    searchRegulations();
+  };
+  // 鏂板
+  const handleAdd = () => {
+    operationType.value = "add";
+    resetRegulationForm();
+    showRegulationDialog.value = true;
+  };
 
-// 缂栬緫
-const handleEdit = (row) => {
-  operationType.value = 'edit'
-  Object.assign(regulationForm, row)
-  showRegulationDialog.value = true
-}
-// 搴熷純
-const repealEdit = (row) => {
-  operationType.value = 'edit'
-  Object.assign(regulationForm, row)
-  regulationForm.status = 'repealed'
-  ElMessageBox.confirm('纭搴熷純璇ュ埗搴︼紵', '鎻愮ず', {
-    confirmButtonText: '纭畾',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning'
-  }).then(() => {
-    updateRuleManagement(regulationForm).then(res => {
-      if(res.code == 200){
-        ElMessage.success('鍒跺害搴熷純鎴愬姛')
-        // showRegulationDialog.value = false
-        getRegulationList()
-        resetRegulationForm()
-      }
+  // 缂栬緫
+  const handleEdit = row => {
+    operationType.value = "edit";
+    Object.assign(regulationForm, row);
+    showRegulationDialog.value = true;
+  };
+  // 搴熷純
+  const repealEdit = row => {
+    operationType.value = "edit";
+    Object.assign(regulationForm, row);
+    regulationForm.status = "repealed";
+    ElMessageBox.confirm("纭搴熷純璇ュ埗搴︼紵", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
     })
-  }).catch(() => {
-    ElMessage({
-      type: 'info',
-      message: '宸插彇娑堝簾寮�'
-    })
-  })
-}
-// 鍙戝竷鍒跺害
-const submitRegulation = async () => {
-  try {
-    await regulationFormRef.value.validate()
-    if(operationType.value == 'add'){
-      addRuleManagement(regulationForm).then(res => {
-        if(res.code == 200){
-          ElMessage.success('鍒跺害鍙戝竷鎴愬姛')
-          showRegulationDialog.value = false
-          getRegulationList()
-          resetRegulationForm()
-        }
+      .then(() => {
+        updateRuleManagement(regulationForm).then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鍒跺害搴熷純鎴愬姛");
+            // showRegulationDialog.value = false
+            getRegulationList();
+            resetRegulationForm();
+          }
+        });
       })
-    }else{
-      updateRuleManagement(regulationForm).then(res => {
-        if(res.code == 200){
-          ElMessage.success('鍒跺害缂栬緫鎴愬姛')
-          showRegulationDialog.value = false
-          resetRegulationForm()
-          getRegulationList()
-      }})}
-  }catch(err){
-    ElMessage.error(err.msg)
-  }
-} 
-//閲嶇疆鍒跺害琛ㄥ崟
-const resetRegulationForm = () => {
-  Object.assign(regulationForm, {
-    id: '',
-    regulationNum: '',
-    title: '',
-    category: '',
-    content: '',
-    version: '',
-    status: 'active',
-    readCount: 0,
-    effectiveTime: '',
-    scope: [],
-    requireConfirm: false
-})
-}
-
-
-// 鏌ョ湅鍒跺害鐗堟湰鍘嗗彶
-const viewVersionHistory = (row) => {
-  showVersionHistoryDialog.value = true
-  const params = {
-
-    category: row.category
-  }
-  listRuleManagement(page,params).then(res => {
-    if(res.code == 200){
-      versionHistory.value = res.data.records
+      .catch(() => {
+        ElMessage({
+          type: "info",
+          message: "宸插彇娑堝簾寮�",
+        });
+      });
+  };
+  // 鍙戝竷鍒跺害
+  const submitRegulation = async () => {
+    try {
+      await regulationFormRef.value.validate();
+      if (operationType.value == "add") {
+        addRuleManagement(regulationForm).then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鍒跺害鍙戝竷鎴愬姛");
+            showRegulationDialog.value = false;
+            getRegulationList();
+            resetRegulationForm();
+          }
+        });
+      } else {
+        updateRuleManagement(regulationForm).then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鍒跺害缂栬緫鎴愬姛");
+            showRegulationDialog.value = false;
+            resetRegulationForm();
+            getRegulationList();
+          }
+        });
+      }
+    } catch (err) {
+      ElMessage.error(err.msg);
     }
-  })
-}
-// 鏌ョ湅鍒跺害璇︽儏
-const viewRegulation = (row) => {
-  currentRegulationDetail.value = row
-  showRegulationDetailDialog.value = true
-  getReadingStatusByRuleId(row.id).then(res => {
-    if(res.code == 200){
-      readStatusList.value = res.data
-      if(readStatusList.value.length==0 && tableData.value.length>0){
+  };
+  //閲嶇疆鍒跺害琛ㄥ崟
+  const resetRegulationForm = () => {
+    Object.assign(regulationForm, {
+      id: "",
+      regulationNum: "",
+      title: "",
+      category: "",
+      content: "",
+      version: "",
+      status: "active",
+      readCount: 0,
+      effectiveTime: "",
+      scope: [],
+      requireConfirm: false,
+    });
+  };
+
+  // 鏌ョ湅鍒跺害鐗堟湰鍘嗗彶
+  const viewVersionHistory = row => {
+    showVersionHistoryDialog.value = true;
+    const params = {
+      category: row.category,
+    };
+    listRuleManagement(page, params).then(res => {
+      if (res.code == 200) {
+        versionHistory.value = res.data.records;
+      }
+    });
+  };
+  // 鏌ョ湅鍒跺害璇︽儏
+  const viewRegulation = row => {
+    currentRegulationDetail.value = row;
+    showRegulationDetailDialog.value = true;
+    getReadingStatusByRuleId(row.id).then(res => {
+      if (res.code == 200) {
+        readStatusList.value = res.data;
+        if (readStatusList.value.length == 0 && tableData.value.length > 0) {
           const params = {
-          ruleId: row.id,
-          employee: tableData.value[0].staffName,
-          department: tableData.value[0].postJob,
-          status: 'unconfirmed'
+            ruleId: row.id,
+            employee: tableData.value[0].staffName,
+            department: tableData.value[0].postJob,
+            status: "unconfirmed",
+          };
+          addReadingStatus(params).then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒跺害闃呰鎴愬姛");
+            }
+          });
         }
-        addReadingStatus(params).then(res => {
-          if(res.code == 200){
-            ElMessage.success('鍒跺害闃呰鎴愬姛')
-          }
-        })
       }
-    }
-  })
-  
-}
-// 鏌ョ湅鍒跺害闃呰鐘舵��
-const viewReadStatus = (row) => {
-  showReadStatusDialog.value = true
-  //鏌ョ湅闃呰鐘舵�佸垪琛�
-  getReadingStatusByRuleId(row.id).then(res => {
-    if(res.code == 200){
-      readStatusList.value = res.data
-    }
-  })
-}
-
-//纭鏌ョ湅
-const resetForm = (row) => {
-  console.log("row",row)
-  row.readCount = row.readCount + 1
-  
-  updateRuleManagement(row).then(res => {
-    if(res.code == 200){
-      ElMessage.success('鏌ョ湅鏁伴噺淇敼鎴愬姛')
-      //淇敼闃呰鐘舵��
-      //鏍规嵁鍒跺害id鍜屽綋鍓嶇櫥褰曠殑鍛樺伐寰楀埌闃呰鐘舵��
-      // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName )
-      // if(item.length>0){
-      //   item[0].status = 'confirmed',
-      //   item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
-      // }
-      // 绛涢�夊綋鍓嶅憳宸ュ搴旇鍒跺害鐨勯槄璇荤姸鎬佽褰�
-      let statusItem = readStatusList.value.find(item => item.employee === tableData.value[0].staffName && item.ruleId === row.id);
-
-      if (statusItem) {
-        // 濡傛灉鎵惧埌璁板綍锛屾洿鏂扮姸鎬佸拰纭鏃堕棿
-        statusItem.status = 'confirmed';
-        // 鏍煎紡鍖栨椂闂翠负"YYYY-MM-DD HH:mm:ss"鏍煎紡
-        const now = new Date();
-        statusItem.confirmTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
-        // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
-        
-        updateReadingStatus(statusItem).then(res => {
-          if(res.code == 200){
-            ElMessage.success('鍒跺害闃呰鐘舵�佷慨鏀规垚鍔�')
-          }
-        })
+    });
+  };
+  // 鏌ョ湅鍒跺害闃呰鐘舵��
+  const viewReadStatus = row => {
+    showReadStatusDialog.value = true;
+    //鏌ョ湅闃呰鐘舵�佸垪琛�
+    getReadingStatusByRuleId(row.id).then(res => {
+      if (res.code == 200) {
+        readStatusList.value = res.data;
       }
+    });
+  };
 
+  //纭鏌ョ湅
+  const resetForm = row => {
+    console.log("row", row);
+    row.readCount = row.readCount + 1;
+
+    updateRuleManagement(row).then(res => {
+      if (res.code == 200) {
+        ElMessage.success("鏌ョ湅鏁伴噺淇敼鎴愬姛");
+        //淇敼闃呰鐘舵��
+        //鏍规嵁鍒跺害id鍜屽綋鍓嶇櫥褰曠殑鍛樺伐寰楀埌闃呰鐘舵��
+        // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName )
+        // if(item.length>0){
+        //   item[0].status = 'confirmed',
+        //   item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
+        // }
+        // 绛涢�夊綋鍓嶅憳宸ュ搴旇鍒跺害鐨勯槄璇荤姸鎬佽褰�
+        let statusItem = readStatusList.value.find(
+          item =>
+            item.employee === tableData.value[0].staffName &&
+            item.ruleId === row.id
+        );
+
+        if (statusItem) {
+          // 濡傛灉鎵惧埌璁板綍锛屾洿鏂扮姸鎬佸拰纭鏃堕棿
+          statusItem.status = "confirmed";
+          // 鏍煎紡鍖栨椂闂翠负"YYYY-MM-DD HH:mm:ss"鏍煎紡
+          const now = new Date();
+          statusItem.confirmTime = `${now.getFullYear()}-${String(
+            now.getMonth() + 1
+          ).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(
+            now.getHours()
+          ).padStart(2, "0")}:${String(now.getMinutes()).padStart(
+            2,
+            "0"
+          )}:${String(now.getSeconds()).padStart(2, "0")}`;
+          // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
+
+          updateReadingStatus(statusItem).then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒跺害闃呰鐘舵�佷慨鏀规垚鍔�");
+            }
+          });
+        }
+      }
+    });
+  };
+
+  // 瀵煎嚭瑙勭珷鍒跺害
+  const { proxy } = getCurrentInstance();
+  const handleExport = () => {
+    proxy.download(
+      "/rulesRegulationsManagement/export",
+      { ...regulationSearchForm },
+      "瑙勭珷鍒跺害.xlsx"
+    );
+  };
+
+  // 闄勪欢锛氭煡璇�
+  const fetchRuleFiles = async rulesRegulationsManagementId => {
+    const params = {
+      current: filePage.current,
+      size: filePage.size,
+      rulesRegulationsManagementId,
+    };
+    const res = await listRuleFiles(params);
+    const records = res?.data?.records || [];
+    filePage.total = res?.data?.total || records.length;
+    const mapped = records.map(item => ({
+      id: item.id,
+      name: item.fileName || item.name,
+      url: item.fileUrl || item.url,
+      raw: item,
+    }));
+    fileListDialogRef.value?.setList(mapped);
+  };
+
+  // 鎵撳紑闄勪欢寮圭獥
+  const openFileDialog = async row => {
+    currentFileRuleId.value = row.id;
+    fileDialogVisible.value = true;
+    await fetchRuleFiles(row.id);
+  };
+
+  // 鍒锋柊闄勪欢鍒楄〃
+  const refreshFileList = async () => {
+    if (!currentFileRuleId.value) return;
+    await fetchRuleFiles(currentFileRuleId.value);
+  };
+
+  // 涓婁紶闄勪欢锛堢敱瀛愮粍浠惰Е鍙戯級
+  const handleAttachmentUpload = async filePayload => {
+    if (!currentFileRuleId.value) return;
+    const payload = {
+      name: filePayload?.fileName || filePayload?.name,
+      url: filePayload?.fileUrl || filePayload?.url,
+      rulesRegulationsManagementId: currentFileRuleId.value,
+    };
+    await addRuleFile(payload);
+    ElMessage.success("鏂囦欢涓婁紶鎴愬姛");
+    await refreshFileList();
+  };
+
+  // 鍒犻櫎闄勪欢
+  const handleAttachmentDelete = async row => {
+    if (!row?.id) return false;
+    try {
+      await ElMessageBox.confirm("纭鍒犻櫎璇ラ檮浠讹紵", "鎻愮ず", { type: "warning" });
+    } catch {
+      return false;
     }
-  })
-}
+    await delRuleFile([row.id]);
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    await refreshFileList();
+  };
 
-// 瀵煎嚭瑙勭珷鍒跺害
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
-  proxy.download('/rulesRegulationsManagement/export', { ...regulationSearchForm }, '瑙勭珷鍒跺害.xlsx')
-}
+  // 鑾峰彇瑙勭珷鍒跺害鍒楄〃鏁版嵁
+  const getRegulationList = async () => {
+    tableLoading.value = true;
+    listRuleManagement(page, regulationSearchForm)
+      .then(res => {
+        regulations.value = res.data.records;
+        // 杩囨护鎺夊凡搴熷純鐨勫埗搴�
+        // regulations.value = res.data.records.filter(item => item.status !== 'repealed')
+        page.value.total = res.data.total;
+        tableLoading.value = false;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
 
-// 闄勪欢锛氭煡璇�
-const fetchRuleFiles = async (rulesRegulationsManagementId) => {
-  const params = {
-    current: filePage.current,
-    size: filePage.size,
-    rulesRegulationsManagementId
-  }
-  const res = await listRuleFiles(params)
-  const records = res?.data?.records || []
-  filePage.total = res?.data?.total || records.length
-  const mapped = records.map(item => ({
-    id: item.id,
-    name: item.fileName || item.name,
-    url: item.fileUrl || item.url,
-    raw: item
-  }))
-  fileListDialogRef.value?.setList(mapped)
-}
-
-// 鎵撳紑闄勪欢寮圭獥
-const openFileDialog = async (row) => {
-  currentFileRuleId.value = row.id
-  fileDialogVisible.value = true
-  await fetchRuleFiles(row.id)
-}
-
-// 鍒锋柊闄勪欢鍒楄〃
-const refreshFileList = async () => {
-  if (!currentFileRuleId.value) return
-  await fetchRuleFiles(currentFileRuleId.value)
-}
-
-// 涓婁紶闄勪欢锛堢敱瀛愮粍浠惰Е鍙戯級
-const handleAttachmentUpload = async (filePayload) => {
-  if (!currentFileRuleId.value) return
-  const payload = {
-    name: filePayload?.fileName || filePayload?.name,
-    url: filePayload?.fileUrl || filePayload?.url,
-    rulesRegulationsManagementId: currentFileRuleId.value
-  }
-  await addRuleFile(payload)
-  ElMessage.success('鏂囦欢涓婁紶鎴愬姛')
-  await refreshFileList()
-}
-
-// 鍒犻櫎闄勪欢
-const handleAttachmentDelete = async (row) => {
-  if (!row?.id) return false
-  try {
-    await ElMessageBox.confirm('纭鍒犻櫎璇ラ檮浠讹紵', '鎻愮ず', { type: 'warning' })
-  } catch {
-    return false
-  }
-  await delRuleFile([row.id])
-  ElMessage.success('鍒犻櫎鎴愬姛')
-  await refreshFileList()
-}
-
-// 鑾峰彇瑙勭珷鍒跺害鍒楄〃鏁版嵁
-const getRegulationList = async () => {
-  tableLoading.value = true
-  listRuleManagement(page,regulationSearchForm)
-  .then(res => {
-
-    regulations.value = res.data.records
-    // 杩囨护鎺夊凡搴熷純鐨勫埗搴�
-    // regulations.value = res.data.records.filter(item => item.status !== 'repealed')
-    page.value.total = res.data.total;
-    tableLoading.value = false;
-
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-}
-
-onMounted(() => {
-  // 鍒濆鍖�
-  getRegulationList()
-})
+  onMounted(() => {
+    // 鍒濆鍖�
+    getRegulationList();
+  });
 </script>
 
 <style scoped>
-.app-container {
-  padding: 20px;
-}
+  .app-container {
+    padding: 20px;
+  }
 
-.card-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
 
-.tab-content {
-  padding: 20px 0;
-}
+  .tab-content {
+    padding: 20px 0;
+  }
 
-.mb-20 {
-  margin-bottom: 20px;
-}
+  .mb-20 {
+    margin-bottom: 20px;
+  }
 
-.mt-20 {
-  margin-top: 20px;
-}
+  .mt-20 {
+    margin-top: 20px;
+  }
 
-.ml-10 {
-  margin-left: 10px;
-}
+  .ml-10 {
+    margin-left: 10px;
+  }
 
-.regulation-content {
-  background-color: #f5f5f5;
-  padding: 15px;
-  border-radius: 4px;
-  line-height: 1.6;
-  white-space: pre-wrap;
-  height: 200px;
-}
+  .regulation-content {
+    background-color: #f5f5f5;
+    padding: 15px;
+    border-radius: 4px;
+    line-height: 1.6;
+    white-space: pre-wrap;
+    height: 200px;
+  }
 
-.dialog-footer {
-  display: flex;
-  justify-content: flex-end;
-  gap: 10px;
-}
+  .dialog-footer {
+    display: flex;
+    justify-content: flex-end;
+    gap: 10px;
+  }
 </style>
diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
index 8e0d054..9f70a55 100644
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ b/src/views/collaborativeApproval/sealManagement/index.vue
@@ -261,9 +261,9 @@
 import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus  } from '@/api/collaborativeApproval/sealManagement.js'
 import { el } from 'element-plus/es/locales.mjs'
 import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js'
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
 import useUserStore from '@/store/modules/user'
 import { userLoginFacotryList } from "@/api/system/user.js"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const currentUser = ref(null)
@@ -583,7 +583,7 @@
       currentUser.value = res.data.userName
     }
   })
-  staffJoinListPage({staffState: 1, ...page}).then(res => {
+  staffOnJobListPage({staffState: 1, ...page}).then(res => {
     tableLoading.value = false;
     // tableData.value = res.data.records
     // //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
diff --git a/src/views/collaborativeApproval/shipmentReview/fileList.vue b/src/views/collaborativeApproval/shipmentReview/fileList.vue
new file mode 100644
index 0000000..da37db2
--- /dev/null
+++ b/src/views/collaborativeApproval/shipmentReview/fileList.vue
@@ -0,0 +1,43 @@
+<template>
+  <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+    <el-table :data="tableData" border height="40vh">
+      <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+      <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+          <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import filePreview from '@/components/filePreview/index.vue'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+  dialogVisible.value = false
+}
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list
+}
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+defineExpose({
+  open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/shipmentReview/index.vue b/src/views/collaborativeApproval/shipmentReview/index.vue
new file mode 100644
index 0000000..ac2b790
--- /dev/null
+++ b/src/views/collaborativeApproval/shipmentReview/index.vue
@@ -0,0 +1,340 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">閿�鍞悎鍚屽彿锛�</span>
+        <el-input
+            v-model="searchForm.salesContractNo"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
+            @change="handleQuery"
+            clearable
+            :prefix-icon="Search"
+        />
+        <span class="search_title ml10">瀹℃壒鐘舵�侊細</span>
+        <el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="寰呭鏍�" :value="2" />
+          <el-option label="瀹℃牳鎴愬姛" :value="3" />
+          <el-option label="瀹℃牳澶辫触" :value="4" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+        >鎼滅储</el-button
+        >
+      </div>
+      <div>
+<!--        <el-button type="primary" @click="openForm('add')">鏂板</el-button>-->
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+<!--        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :page="page"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          :tableLoading="tableLoading"
+          @pagination="pagination"
+          :total="page.total"
+      ></PIMTable>
+    </div>
+    <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
+    <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
+    <FileList ref="fileListRef" />
+  </div>
+</template>
+
+<script setup>
+import FileList from "./fileList.vue";
+import { Search } from "@element-plus/icons-vue";
+import {onMounted, ref} from "vue";
+import {ElMessageBox} from "element-plus";
+import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
+import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
+import {getShipmentApprovalList, approveShipment} from "@/api/collaborativeApproval/shipmentReview.js";
+// import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
+import useUserStore from "@/store/modules/user";
+import { userListNoPage } from "@/api/system/user.js";
+
+// 瀹氫箟缁勪欢鎺ユ敹鐨刾rops
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 6
+  }
+});
+
+const userList = ref([]);
+
+const userStore = useUserStore();
+
+
+const data = reactive({
+  searchForm: {
+    approveId: "",
+    approveStatus: "",
+  },
+});
+const { searchForm } = toRefs(data);
+const tableColumn = ref([
+  {
+    label: "瀹℃壒鐘舵��",
+    prop: "approveStatus",
+    dataType: "tag",
+    width: 100,
+    formatData: (params) => {
+      if (params === 2) {
+        return "寰呭鏍�";
+      } else if (params === 3) {
+        return "瀹℃牳瀹屾垚";
+      } else if (params === 4) {
+        return "瀹℃牳椹冲洖";
+      } else {
+        return '鏈煡鐘舵��';
+      }
+    },
+    formatType: (params) => {
+      if (params === 0) {
+        return "warning";
+      } else if (params === 2) {
+        return "info";
+      } else if (params === 3) {
+        return "success";
+      } else if (params === 4) {
+        return "danger";
+      } else {
+        return 'danger';
+      }
+    },
+  },
+  {
+    label: "閿�鍞悎鍚屽彿",
+    prop: "salesContractNo",
+    width: 170
+  },
+  {
+    label: "瀹㈡埛鍚嶇О",
+    prop: "customerName",
+    width: 200
+  },
+  {
+    label: "浜у搧澶х被",
+    prop: "productCategory",
+    width: 200
+  },
+  {
+    label: "瑙勬牸鍨嬪彿",
+    prop: "specificationModel",
+    width: 220
+  },
+  {
+    label: "鐢宠浜�",
+    prop: "approveUserId",
+    width: 120,
+    align: "center",
+    formatData:(params)=>{
+      const user = userList.value.find(item => item.userId === params)
+      return user ? user.nickName : '--'
+    }
+  },
+  {
+    label: "杞︾墝鍙�",
+    prop: "shippingCarNumber",
+    width: 120,
+  },
+  {
+    label: "鐢宠浜�",
+    prop: "approveUserId",
+    width: 120,
+  },
+  {
+    label: "鐢宠鏃ユ湡",
+    prop: "executionDate",
+    width: 200
+  },
+  {
+    label: "褰撳墠瀹℃壒浜�",
+    prop: "salesman",
+    width: 120
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 120,
+    operation: [
+      {
+        name: "閫氳繃",
+        type: "text",
+        clickFun: (row) => {
+          handleApproval("閫氳繃", row);
+        },
+        disabled: (row) => row.approveStatus !== 2
+      },
+      {
+        name: "椹冲洖",
+        type: "text",
+        clickFun: (row) => {
+          handleApproval("椹冲洖", row);
+        },
+        disabled: (row) => row.approveStatus !== 2
+      },
+      // {
+      //   name: "缂栬緫",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openForm("edit", row);
+      //   },
+      //   disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
+      // },
+      // {
+      //   name: "瀹℃牳",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openApprovalDia("approval", row);
+      //   },
+      //   disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
+      // },
+      // {
+      //   name: "璇︽儏",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openApprovalDia('view', row);
+      //   },
+      // },
+      // {
+      //   name: "闄勪欢",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     downLoadFile(row);
+      //   },
+      // },
+    ],
+  },
+]);
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+  current: 1,
+  size: 100,
+  total: 0
+});
+const infoFormDia = ref()
+const approvalDia = ref()
+const { proxy } = getCurrentInstance()
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  page.current = 1;
+  getList();
+};
+const fileListRef = ref(null)
+const downLoadFile = (row) => {
+  fileListRef.value.open(row.commonFileList)
+
+}
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+const getList =async () => {
+  let userLists = await userListNoPage();
+  userList.value = userLists.data;
+  tableLoading.value = true;
+  getShipmentApprovalList({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
+    tableLoading.value = false;
+    tableData.value = res.data.records
+    page.total = res.data.total;
+  }).catch(err => {
+    tableLoading.value = false;
+  })
+};
+// 瀵煎嚭
+const handleOut = () => {
+  const type = Number(props.approveType || 6)
+  const urlMap = {
+    0: "/shipmentApproval/export",
+  }
+  const url = urlMap[type] || urlMap[0]
+  const nameMap = {
+    0: "鍙戣揣瀹℃牳琛�",
+  }
+  const fileName = nameMap[type] || nameMap[0]
+  proxy.download(url, {}, `${fileName}.xlsx`)
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鎵撳紑鏂板銆佺紪杈戝脊妗�
+const openForm = (type, row) => {
+  nextTick(() => {
+    infoFormDia.value?.openDialog(type, row)
+  })
+};
+// 鎵撳紑鏂板妫�楠屽脊妗�
+const openApprovalDia = (type, row) => {
+  nextTick(() => {
+    approvalDia.value?.openDialog(type, row)
+  })
+};
+
+// 瀹℃牳閫氳繃/椹冲洖
+const handleApproval = (name = "瀹℃牳",row) => {
+  ElMessageBox.confirm(`閫変腑鐨勫唴瀹瑰皢琚�${name}锛屾槸鍚︾‘璁�${name}锛焋, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async()=>{
+    let res = await approveShipment({
+      id: row.id,
+      approveStatus: name === "閫氳繃" ? 3 : 4
+    });
+    if(res.code === 200){
+      proxy.$modal.msgSuccess(`${name}鎴愬姛`);
+    }else{
+      proxy.$modal.msgError(`${name}澶辫触`);
+    }
+    await getList()
+  }).catch(err=>{
+    proxy.$modal.msgError(`鏈煡閿欒,璇疯仈绯荤鐞嗗憳`);
+  })
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+  let ids = [];
+  if (selectedRows.value.length > 0) {
+    ids = selectedRows.value.map((item) => item.approveId);
+  } else {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        approveProcessDelete(ids).then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style scoped></style>
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index d14f4ff..f85a7fa 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+  <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
     <el-row :gutter="20">
       <el-col :span="12">
         <el-form-item label="璁惧鍚嶇О" prop="deviceName">
@@ -14,6 +14,27 @@
       <el-col :span="12">
         <el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
           <el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璁惧绫诲瀷" prop="type">
+          <el-select
+            v-model="form.type"
+            placeholder="璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�"
+            clearable
+            filterable
+            allow-create
+            default-first-option
+            style="width: 100%"
+            @change="handleDeviceTypeChange"
+          >
+            <el-option
+              v-for="item in deviceTypeOptions"
+              :key="item"
+              :label="item"
+              :value="item"
+            />
+          </el-select>
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -32,8 +53,19 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
-          <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
+        <el-form-item label="鍚敤鎶樻棫" prop="isDepr">
+          <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12" v-if="form.isDepr === 1">
+        <el-form-item label="姣忓勾鎶樻棫閲戦" prop="annualDepreciationAmount">
+          <el-input-number 
+            :step="0.01" 
+            :min="0" 
+            style="width: 100%"
+            v-model="form.annualDepreciationAmount"
+            placeholder="璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�"
+          />
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -149,24 +181,47 @@
 });
 const formRef = ref(null);
 const operationType = ref('');
+// 璁惧绫诲瀷鍥哄畾閫夐」
+const deviceTypeOptions = ref([
+  '鐢熶骇璁惧',
+  '鍔炲叕璁惧',
+  '妫�娴嬭澶�',
+  '杩愯緭璁惧',
+  '鍏朵粬璁惧'
+]);
 const formRules = {
 	deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+	type: [{ required: true, trigger: "change", message: "璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�" }],
 	supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
 	planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+	annualDepreciationAmount: [
+		{ 
+			validator: (rule, value, callback) => {
+				if (form.isDepr === 1 && (value === undefined || value === null || value === '')) {
+					callback(new Error('鍚敤鎶樻棫鏃讹紝璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�'));
+				} else {
+					callback();
+				}
+			}, 
+			trigger: "blur" 
+		}
+	],
 }
 
 const { form, resetForm } = useFormData({
   deviceName: undefined, // 璁惧鍚嶇О
   deviceModel: undefined, // 瑙勬牸鍨嬪彿
   deviceBrand: undefined, // 璁惧鍝佺墝
+  type: undefined, // 璁惧绫诲瀷
   supplierName: undefined, // 渚涘簲鍟�
   storageLocation: undefined, // 瀛樻斁浣嶇疆
-  enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
+  isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
+  annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
   unit: undefined, // 鍗曚綅
   number: 1, // 鏁伴噺
   taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
@@ -187,9 +242,11 @@
     form.deviceName = data.deviceName;
     form.deviceModel = data.deviceModel;
     form.deviceBrand = data.deviceBrand;
+    form.type = data.type;
     form.supplierName = data.supplierName;
     form.storageLocation = data.storageLocation;
-    form.enableDepreciation = data.enableDepreciation;
+    form.isDepr = data.isDepr;
+    form.annualDepreciationAmount = data.annualDepreciationAmount;
     form.unit = data.unit;
     form.number = 1;
     form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
@@ -200,6 +257,13 @@
   }
 };
 
+const handleDeviceTypeChange = (value) => {
+  // 濡傛灉杈撳叆鐨勬柊鍊间笉鍦ㄥ浐瀹氶�夐」涓紝鍒欐坊鍔犲埌閫夐」鍒楄〃
+  if (value && !deviceTypeOptions.value.includes(value)) {
+    deviceTypeOptions.value.push(value);
+  }
+};
+
 const mathNum = () => {
   if (!form.taxIncludingPriceUnit) {
     ElMessage.error("璇疯緭鍏ュ崟浠�");
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 8cdbf32..62f0c6a 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -7,7 +7,6 @@
           style="width: 240px"
           placeholder="璇疯緭鍏ヨ澶囧悕绉�"
           clearable
-          :prefix-icon="Search"
           @change="getTableData"
         />
       </el-form-item>
@@ -17,7 +16,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -27,17 +25,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ヤ緵搴斿晢"
             clearable
-            :prefix-icon="Search"
-            @change="getTableData"
-        />
-      </el-form-item>
-      <el-form-item label="鍗曚綅">
-        <el-input
-            v-model="filters.unit"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ュ崟浣�"
-            clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -130,81 +117,53 @@
     deviceName: undefined,
     deviceModel: undefined,
     supplierName: undefined,
-    unit: undefined,
     entryDateStart: undefined,
     entryDateEnd: undefined,
   },
   [
     {
       label: "璁惧鍚嶇О",
-      align: "center",
       prop: "deviceName",
     },
     {
       label: "瑙勬牸鍨嬪彿",
-      align: "center",
       prop: "deviceModel",
     },
     {
       label: "璁惧鍝佺墝",
-      align: "center",
       prop: "deviceBrand",
     },
     {
+      label: "璁惧绫诲瀷",
+      prop: "type",
+    },
+    {
       label: "渚涘簲鍟�",
-      align: "center",
       prop: "supplierName",
     },
     {
-      label: "鍗曚綅",
-      align: "center",
-      prop: "unit",
-    },
-    {
       label: "瀛樻斁浣嶇疆",
-      align: "center",
       prop: "storageLocation",
     },
     {
       label: "鏁伴噺",
-      align: "center",
       prop: "number",
     },
     {
-      label: "鍚◣鍗曚环",
-      align: "center",
-      prop: "taxIncludingPriceUnit",
-    },
-    {
-      label: "鍚◣鎬讳环",
-      align: "center",
-      prop: "taxIncludingPriceTotal",
-    },
-    {
-      label: "绋庣巼",
-      align: "center",
-      prop: "taxRate",
-    },
-    {
-      label: "涓嶅惈绋庢�讳环",
-      align: "center",
-      prop: "unTaxIncludingPriceTotal",
-    },
-    {
-      label: "鍚敤鎶樻棫",
-      align: "center",
-      prop: "enableDepreciation",
-      formatData: (v) => (v ? "鏄�" : "鍚�"),
-    },
-    {
       label: "褰曞叆浜�",
-      align: "center",
       prop: "createUser",
     },
     {
       label: "褰曞叆鏃ユ湡",
-      align: "center",
       prop: "createTime",
+      formatData: (v) => {
+        if (!v) return '';
+        // 濡傛灉鍖呭惈鏃跺垎绉掞紝鍙彇鏃ユ湡閮ㄥ垎
+        if (v.includes(' ')) {
+          return v.split(' ')[0];
+        }
+        return v;
+      },
     },
 		{
 			dataType: "action",
@@ -215,14 +174,12 @@
 			operation: [
 				{
 					name: "缂栬緫",
-					type: "text",
 					clickFun: (row) => {
 						edit(row.id)
 					},
 				},
 				{
 					name: "鐢熸垚浜岀淮鐮�",
-					type: "text",
 					clickFun: (row) => {
 						showQRCode(row)
 					},
diff --git a/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue b/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue
new file mode 100644
index 0000000..c6aa70e
--- /dev/null
+++ b/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue
@@ -0,0 +1,7 @@
+<template>
+
+</template>
+
+<script setup>
+
+</script>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
index 7b6097b..b215df1 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
@@ -15,19 +15,10 @@
 				ref="formRef"
 			>
 				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="璁¢噺鍣ㄥ叿缂栧彿锛�" prop="code">
+					<el-col :span="24">
+						<el-form-item label="鍑哄巶缂栧彿锛�" prop="code">
 							<el-input
 								v-model="form.code"
-								placeholder="璇疯緭鍏�"
-								clearable
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="璁¢噺鍣ㄥ叿鍚嶇О锛�" prop="name">
-							<el-input
-								v-model="form.name"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
@@ -36,28 +27,70 @@
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
-						<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
+						<el-form-item label="瀹夎浣嶇疆锛�" prop="installationLocation">
 							<el-input
-								v-model="form.model"
+								v-model="form.installationLocation"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="棰勮涓嬫妫�瀹氭棩鏈燂細" prop="nextDate">
-							<el-date-picker
-								style="width: 100%"
-								v-model="form.nextDate"
-								value-format="YYYY-MM-DD"
-								format="YYYY-MM-DD"
-								type="date"
-								placeholder="璇烽�夋嫨"
-								clearable
-							/>
+						<el-form-item label="妫�瀹氬崟浣嶏細" prop="unit">
+              <el-input
+                  v-model="form.unit"
+                  placeholder="璇疯緭鍏ユ瀹氬崟浣�"
+                  clearable
+              />
 						</el-form-item>
 					</el-col>
 				</el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="璇佷功缂栧彿锛�" prop="model">
+              <el-input
+                  v-model="form.model"
+                  placeholder="璇疯緭鍏�"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈�鏂伴壌瀹氭棩鏈燂細" prop="mostDate">
+              <el-date-picker
+                  style="width: 100%"
+                  v-model="form.mostDate"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  type="date"
+                  placeholder="璇烽�夋嫨"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏈夋晥鏃ユ湡(澶�)锛�" prop="valid">
+              <el-input
+                  v-model="form.valid"
+                  placeholder="璇疯緭鍏ユ湁鏁堟湡澶╂暟"
+                  clearable
+              >
+              <template #append>鏃�</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="妫�瀹氬懆鏈燂細" prop="cycle">
+              <el-input
+                  v-model="form.cycle"
+                  placeholder="璇疯緭鍏ユ瀹氬懆鏈�"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="褰曞叆浜猴細" prop="userId">
@@ -84,6 +117,7 @@
 								style="width: 100%"
 								v-model="form.recordDate"
 								value-format="YYYY-MM-DD"
+                disabled
 								format="YYYY-MM-DD"
 								type="date"
 								placeholder="璇烽�夋嫨"
@@ -126,7 +160,7 @@
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js";
 import {getToken} from "@/utils/auth.js";
-import {measuringInstrumentAdd, measuringInstrumentUpdate} from "@/api/equipmentManagement/measurementEquipment.js";
+import {addMeasuringInstrumentLedger, updateMeasuringInstrumentLedger} from "@/api/equipmentManagement/measurementEquipment.js";
 import { getCurrentDate } from "@/utils/index.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -137,8 +171,10 @@
 const data = reactive({
 	form: {
 		code: "",
-		name: "",
+    installationLocation: "",
+    mostDate:"",
 		model: "",
+    cycle:"",
 		validDate: "",
 		nextDate: "",
 		userId: "",
@@ -147,12 +183,16 @@
 	},
 	rules: {
 		code: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
-		name: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
 		model: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
 		validDate: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
 		nextDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
 		userId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
 		recordDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+    installationLocation: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+    mostDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+    cycle: [{required: true, message: "璇烽�夋嫨", trigger: "blur"}],
+    valid: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+    unit: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
 	}
 })
 const { form, rules } = toRefs(data);
@@ -217,13 +257,13 @@
 	proxy.$refs["formRef"].validate(valid => {
 		if (valid) {
 			if (operationType.value === "add") {
-				measuringInstrumentAdd(form.value).then(response => {
+        addMeasuringInstrumentLedger(form.value).then(response => {
 					proxy.$modal.msgSuccess("鏂板鎴愬姛")
           form.value.tempFileIds = []
 					closeDia()
 				})
 			} else {
-				measuringInstrumentUpdate(form.value).then(response => {
+        updateMeasuringInstrumentLedger(form.value).then(response => {
 					proxy.$modal.msgSuccess("淇敼鎴愬姛")
           form.value.tempFileIds = []
 					closeDia()
diff --git a/src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue b/src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue
new file mode 100644
index 0000000..6604587
--- /dev/null
+++ b/src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue
@@ -0,0 +1,128 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="妫�瀹氭牎鍑嗚褰�"
+        width="50%"
+        @close="closeDia"
+    >
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :tableLoading="tableLoading"
+          @selection-change="handleSelectionChange"
+          height="500"
+          :isPagination="false"
+      >
+      </PIMTable>
+      <pagination
+          style="margin: 10px 0"
+          v-show="total > 0"
+          @pagination="paginationSearch"
+          :total="total"
+          :page="page.current"
+          :limit="page.size"
+      />
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <filePreview ref="filePreviewRef" />
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import filePreview from '@/components/filePreview/index.vue'
+import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js";
+import Pagination from "@/components/PIMTable/Pagination.vue";
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const currentId = ref('')
+const selectedRows = ref([]);
+const filePreviewRef = ref()
+const tableColumn = ref([
+  {
+    label: "妫�瀹氭棩鏈�",
+    prop: "recordDate",
+    width: 130,
+  },
+  {
+    label: "璁¢噺鍣ㄥ叿缂栧彿",
+    prop: "code",
+    width: 150,
+  },
+  {
+    label: "璁¢噺鍣ㄥ叿鍚嶇О",
+    prop: "name",
+    width: 200,
+  },
+  {
+    label: "瑙勬牸鍨嬪彿",
+    prop: "model",
+    width:200
+  },
+  {
+    label: "鏈夋晥鏈�",
+    prop: "valid",
+    width: 100,
+  },
+  {
+    label: "褰曞叆浜�",
+    prop: "userName",
+  },
+  {
+    label: "褰曞叆鏃ユ湡",
+    prop: "entryDate",
+    width: 130,
+  },
+]);
+const page = reactive({
+  current: 1,
+  size: 100,
+});
+const total = ref(0);
+const tableData = ref([]);
+const tableLoading = ref(false);
+
+// 鎵撳紑寮规
+const openDialog = (row,type) => {
+  dialogFormVisible.value = true;
+  currentId.value = row.id;
+  getList()
+}
+const paginationSearch = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+const getList = () => {
+  let query = {
+    measuringInstrumentLedgerId:currentId.value,
+    current : page.current,
+    size : page.size
+  }
+  ledgerRecordListPage(query).then(res => {
+    tableData.value = res?.data?.records || [];
+    total.value = res?.data?.total;
+  })
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  dialogFormVisible.value = false;
+  emit('close')
+};
+
+defineExpose({
+  openDialog,
+});
+</script>
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
index 363a85a..129f23b 100644
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ b/src/views/equipmentManagement/measurementEquipment/index.vue
@@ -40,11 +40,13 @@
 				@selection-change="handleSelectionChange"
 				:tableLoading="tableLoading"
 				@pagination="pagination"
+        :dbRowClick="dbRowClick"
 			></PIMTable>
 		</div>
 		<form-dia ref="formDia" @close="handleQuery"></form-dia>
 		<calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
     <files-dia ref="filesDia"></files-dia>
+    <rowClickDataForm ref="rowClickData"></rowClickDataForm>
 	</div>
 </template>
 
@@ -55,10 +57,11 @@
 import useUserStore from "@/store/modules/user.js";
 import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
 import {
-	measuringInstrumentDelete,
-	measuringInstrumentListPage
+  measuringInstrumentDelete,
+  measuringInstrumentListPage,
 } from "@/api/equipmentManagement/measurementEquipment.js";
 import FilesDia from "./filesDia.vue";
+import rowClickDataForm from "./components/rowClickData.vue"
 const { proxy } = getCurrentInstance();
 const userStore = useUserStore()
 
@@ -73,67 +76,80 @@
 
 const tableColumn = ref([
 	{
-		label: "鐘舵��",
-		prop: "status",
-		dataType: "tag",
-		formatData: (params) => {
-			if (params == 1) {
-				return "鏈夋晥";
-			} else if (params == 2) {
-				return "閫炬湡";
-			} else {
-				return null;
-			}
-		},
-		formatType: (params) => {
-			if (params == 1) {
-				return "success";
-			} else if (params == 2) {
-				return "danger";
-			} else {
-				return null;
-			}
-		},
+		label: "鍑哄巶缂栧彿",
+		prop: "code",
+    minWidth:150,
+    align:"center"
 	},
 	{
-		label: "鏈�杩戜竴娆℃瀹氭棩鏈�",
+		label: "閮ㄩ棬",
+		prop: "deptName",
+		width: 130,
+    align:"center"
+	},
+	{
+		label: "瀹夎浣嶇疆",
+		prop: "installationLocation",
+		width: 150,
+    align:"center"
+	},
+	{
+		label: "妫�瀹氬崟浣�",
+		prop: "unit",
+		width: 200,
+    align:"center"
+	},
+	{
+		label: "璇佷功缂栧彿",
+		prop: "model",
+		width:200,
+    align:"center"
+	},
+	{
+		label: "鏈�鏂伴壌瀹氭棩鏈�",
 		prop: "mostDate",
 		width: 130,
-	},
-	{
-		label: "璁¢噺鍣ㄥ叿缂栧彿",
-		prop: "code",
-		width: 150,
-	},
-	{
-		label: "璁¢噺鍣ㄥ叿鍚嶇О",
-		prop: "name",
-		width: 200,
-	},
-	{
-		label: "瑙勬牸鍨嬪彿",
-		prop: "model",
-		width:200
-	},
-	{
-		label: "鏈夋晥鏈�",
-		prop: "valid",
-		width: 130,
-	},
-	{
-		label: "棰勮涓嬫妫�瀹氭棩鏈�",
-		prop: "nextDate",
-		width: 130,
+    align:"center"
 	},
 	{
 		label: "褰曞叆浜�",
 		prop: "userName",
+		width: 130,
+    align:"center"
 	},
 	{
 		label: "褰曞叆鏃ユ湡",
 		prop: "recordDate",
-		width: 130,
+    align:"center",
+    minWidth: 130
 	},
+	{
+		label: "鏈夋晥鏃ユ湡",
+		prop: "valid",
+		width: 130,
+    align:"center"
+	},
+  {
+    label: "妫�瀹氬懆鏈�(澶�)",
+    prop: "cycle",
+    width: 130,
+    align:"center"
+  },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    width: 130,
+    align: "center",
+    formatData: (params) => {
+      if (params === 1) {
+        return "鏈夋晥";
+      } else if (params === 2) {
+        return "閫炬湡";
+      } else {
+        return null;
+      }
+    }
+  },
 	{
 		dataType: "action",
 		label: "鎿嶄綔",
@@ -141,25 +157,26 @@
 		width: '130',
 		fixed: 'right',
 		operation: [
+      {
+      	name: "闄勪欢",
+      	type: "text",
+      	clickFun: (row) => {
+          openFilesFormDia(row);
+      	},
+      },
 			{
-				name: "妫�瀹氭牎鍑�",
+				name: "鏌ョ湅",
 				type: "text",
 				clickFun: (row) => {
 					openCalibrationDia("verifying", row);
 				},
 			},
-			// {
-			// 	name: "闄勪欢",
-			// 	type: "text",
-			// 	clickFun: (row) => {
-      //     openFilesFormDia(row);
-			// 	},
-			// },
 		],
 	},
 ]);
 const tableData = ref([]);
 const tableLoading = ref(false);
+const rowClickData = ref([])
 const filesDia = ref()
 const page = reactive({
 	current: 1,
@@ -170,12 +187,13 @@
 
 // 鎵撳紑闄勪欢寮规
 const openFilesFormDia = (row) => {
-  console.log(row)
-  nextTick(() => {
-    filesDia.value?.openDialog( row,'璁¢噺鍣ㄥ叿鍙拌处')
-  })
+    filesDia.value?.openDialog(row,'璁¢噺鍣ㄥ叿鍙拌处')
 };
 
+const dbRowClick = (row)=>{
+  rowClickData.value?.openDialog(row)
+}
+
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
 	selectedRows.value = selection;
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
deleted file mode 100644
index 2a64d3f..0000000
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-<template>
-  <el-form :model="form" label-width="80px">
-    <el-form-item label="缁翠慨浜�">
-      <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
-    </el-form-item>
-    <el-form-item label="缁翠慨缁撴灉">
-      <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
-    </el-form-item>
-    <el-form-item label="鎶ヤ慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呮姤淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="缁翠慨鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceTime"
-        placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
-  name: "璁惧缁翠慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceName: undefined, // 缁翠慨鍚嶇О
-  maintenanceResult: undefined, // 缁翠慨缁撴灉
-  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
-  status: 0,
-});
-
-const setForm = (data) => {
-  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
-  form.maintenanceResult = data.maintenanceResult;
-  form.maintenanceTime =
-    dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Form/RepairForm.vue b/src/views/equipmentManagement/repair/Form/RepairForm.vue
deleted file mode 100644
index 6697906..0000000
--- a/src/views/equipmentManagement/repair/Form/RepairForm.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-row>
-      <el-col :span="12">
-        <el-form-item label="璁惧鍚嶇О">
-          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
-            <el-option
-              v-for="(item, index) in deviceOptions"
-              :key="index"
-              :label="item.deviceName"
-              :value="item.id"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="瑙勬牸鍨嬪彿">
-          <el-input
-            v-model="form.deviceModel"
-            placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-            disabled
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鏃ユ湡">
-          <el-date-picker
-            v-model="form.repairTime"
-            placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            type="date"
-            clearable
-            style="width: 100%"
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨浜�">
-          <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row v-if="id">
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鐘舵��">
-          <el-select v-model="form.status">
-            <el-option label="寰呯淮淇�" :value="0"></el-option>
-            <el-option label="瀹岀粨" :value="1"></el-option>
-            <el-option label="澶辫触" :value="2"></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row>
-      <el-col :span="24">
-        <el-form-item label="鏁呴殰鐜拌薄">
-          <el-input
-            v-model="form.remark"
-            :rows="2"
-            type="textarea"
-            placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
-          />
-        </el-form-item>
-      </el-col>
-    </el-row>
-  </el-form>
-</template>
-
-<script setup>
-import dayjs from "dayjs";
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import useUserStore from "@/store/modules/user";
-
-const { id } = defineProps(["id"])
-
-defineOptions({
-  name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const deviceOptions = ref([]);
-
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
-  repairName: userStore.nickName, // 鎶ヤ慨浜�
-  remark: undefined, // 鏁呴殰鐜拌薄
-  status: 0, // 鎶ヤ慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.repairTime = data.repairTime;
-  form.repairName = data.repairName;
-  form.remark = data.remark;
-  form.status = data.status;
-};
-
-// onMounted(() => {
-//   loadDeviceName();
-// });
-
-defineExpose({
-  loadDeviceName,
-  resetForm,
-  getForm,
-  setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index a578a58..496b072 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,53 +1,108 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintainForm ref="maintainFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧缁翠慨'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="80px">
+      <el-form-item label="缁翠慨浜�">
+        <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
+      </el-form-item>
+      <el-form-item label="缁翠慨缁撴灉">
+        <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
+      </el-form-item>
+      <el-form-item label="缁翠慨鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呮姤淇�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="缁翠慨鏃ユ湡">
+        <el-date-picker
+          v-model="form.maintenanceTime"
+          placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import MaintainForm from "../Form/MaintainForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import { addMaintain } from "@/api/equipmentManagement/repair";
+import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
 
 defineOptions({
   name: "缁翠慨妯℃�佹",
 });
 
-const maintainFormRef = ref();
 const emits = defineEmits(["ok"]);
 
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧缁翠慨" });
+// 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+const repairId = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const { form, resetForm } = useFormData({
+  maintenanceName: undefined, // 缁翠慨鍚嶇О
+  maintenanceResult: undefined, // 缁翠慨缁撴灉
+  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
+  status: 0,
+});
+
+const setForm = (data) => {
+  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
+  form.maintenanceResult = data.maintenanceResult;
+  form.maintenanceTime =
+    data.maintenanceTime 
+      ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
 
 const sendForm = async () => {
   loading.value = true;
-  const form = await maintainFormRef.value.getForm();
-  const { code } = await addMaintain({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintainFormRef.value.resetForm();
-    closeModal();
+  try {
+    const { code } = await addMaintain({ id: repairId.value, ...form });
+    if (code == 200) {
+      ElMessage.success("缁翠慨鎴愬姛");
+      emits("ok");
+      resetForm();
+      visible.value = false;
+    }
+  } finally {
+    loading.value = false;
   }
-  loading.value = false;
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const open = async (id, row) => {
-  openModal(id);
+  repairId.value = id; // 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+  visible.value = true;
   await nextTick();
-  maintainFormRef.value.setForm(row);
+  setForm(row);
 };
 
 defineExpose({
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index c21b47a..1aa82ec 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,24 +1,93 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable>
-    <RepairForm ref="repairFormRef" :id="id" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧鎶ヤ慨' : '鏂板璁惧鎶ヤ慨'"
+    width="800px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="璁惧鍚嶇О">
+            <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
+              <el-option
+                v-for="(item, index) in deviceOptions"
+                :key="index"
+                :label="item.deviceName"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瑙勬牸鍨嬪彿">
+            <el-input
+              v-model="form.deviceModel"
+              placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+              disabled
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鏃ユ湡">
+            <el-date-picker
+              v-model="form.repairTime"
+              placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              type="date"
+              clearable
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨浜�">
+            <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="id">
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鐘舵��">
+            <el-select v-model="form.status">
+              <el-option label="寰呯淮淇�" :value="0"></el-option>
+              <el-option label="瀹岀粨" :value="1"></el-option>
+              <el-option label="澶辫触" :value="2"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="鏁呴殰鐜拌薄">
+            <el-input
+              v-model="form.remark"
+              :rows="2"
+              type="textarea"
+              placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import RepairForm from "../Form/RepairForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import {
   addRepair,
   editRepair,
   getRepairById,
 } from "@/api/equipmentManagement/repair";
 import { ElMessage } from "element-plus";
+import dayjs from "dayjs";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import useUserStore from "@/store/modules/user";
 
 defineOptions({
   name: "璁惧鎶ヤ慨寮圭獥",
@@ -26,48 +95,83 @@
 
 const emits = defineEmits(["ok"]);
 
-const repairFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧鎶ヤ慨" });
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const deviceOptions = ref([]);
+
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
+  repairName: userStore.nickName, // 鎶ヤ慨浜�
+  remark: undefined, // 鏁呴殰鐜拌薄
+  status: 0, // 鎶ヤ慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.repairTime = data.repairTime;
+  form.repairName = data.repairName;
+  form.remark = data.remark;
+  form.status = data.status;
+};
 
 const sendForm = async () => {
   loading.value = true;
-  const form = await repairFormRef.value.getForm();
-  const { code } = id.value
-    ? await editRepair({ id: unref(id), ...form })
-    : await addRepair(form);
-  if (code == 200) {
-    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
-    closeModal();
-    emits("ok");
+  try {
+    const { code } = id.value
+      ? await editRepair({ id: unref(id), ...form })
+      : await addRepair(form);
+    if (code == 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
   }
-  loading.value = false;
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const openAdd = async () => {
-  openModal();
+  id.value = undefined;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
+  await loadDeviceName();
 };
 
-const openEdit = async (id) => {
-  const { data } = await getRepairById(id);
-  openModal(id);
+const openEdit = async (editId) => {
+  const { data } = await getRepairById(editId);
+  id.value = editId;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
-  await repairFormRef.value.setForm(data);
-};
-
-const close = () => {
-  repairFormRef.value.resetForm();
-  closeModal();
+  await loadDeviceName();
+  setForm(data);
 };
 
 defineExpose({
@@ -75,3 +179,5 @@
   openEdit,
 });
 </script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 2443123..40a3c39 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -75,10 +75,10 @@
             瀵煎嚭
           </el-button>
           <el-button
-              type="danger"
-              icon="Delete"
-              :disabled="multipleList.length <= 0"
-              @click="delRepairByIds(multipleList.map((item) => item.id))"
+            type="danger"
+            icon="Delete"
+            :disabled="multipleList.length <= 0 || hasFinishedStatus"
+            @click="delRepairByIds(multipleList.map((item) => item.id))"
           >
             鎵归噺鍒犻櫎
           </el-button>
@@ -104,25 +104,26 @@
         </template>
         <template #operation="{ row }">
           <el-button
-              type="primary"
-              text
-              @click="addMaintain(row)"
-          >
-            鏂板缁翠慨
-          </el-button>
-          <el-button
-              type="primary"
-              text
-              icon="editPen"
-              @click="editRepair(row.id)"
+            type="primary"
+            link
+            :disabled="row.status === 1"
+            @click="editRepair(row.id)"
           >
             缂栬緫
           </el-button>
           <el-button
-              type="danger"
-              text
-              icon="delete"
-              @click="delRepairByIds(row.id)"
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            缁翠慨
+          </el-button>
+          <el-button
+            type="danger"
+            link
+            :disabled="row.status === 1"
+            @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
           </el-button>
@@ -135,9 +136,10 @@
 </template>
 
 <script setup>
+import { usePaginationApi } from "@/hooks/usePaginationApi";
+import { onMounted, getCurrentInstance, computed } from "vue";
 import {usePaginationApi} from "@/hooks/usePaginationApi";
 import {getRepairPage, delRepair} from "@/api/equipmentManagement/repair";
-import {onMounted, getCurrentInstance} from "vue";
 import RepairModal from "./Modal/RepairModal.vue";
 import {ElMessageBox, ElMessage} from "element-plus";
 import dayjs from "dayjs";
@@ -257,6 +259,11 @@
   multipleList.value = selectionList;
 };
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 // 鏂板鎶ヤ慨
 const addRepair = () => {
   repairModalRef.value.openAdd();
@@ -280,6 +287,18 @@
 
 // 鍗曡鍒犻櫎
 const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const idsArray = Array.isArray(ids) ? ids : [ids];
+  const hasFinished = idsArray.some(id => {
+    const record = dataList.value.find(item => item.id === id);
+    return record && record.status === 1;
+  });
+
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�');
+    return;
+  }
+
   ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
     confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index f18c84c..eb0bdd5 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -37,6 +37,7 @@
           </template>
         </el-table-column>
         <el-table-column prop="price" label="浠锋牸" width="140"></el-table-column>
+        <el-table-column prop="quantity" label="鏁伴噺" width="140"></el-table-column>
         <el-table-column prop="description" label="鎻忚堪" width="150"></el-table-column>
         <el-table-column label="鎿嶄綔" width="150" fixed="right" align="center">
           <template #default="{ row }">
@@ -85,6 +86,9 @@
         </el-form-item>
         <el-form-item label="澶囦欢缂栧彿" prop="sparePartsNo">
           <el-input v-model="form.sparePartsNo"></el-input>
+        </el-form-item>
+        <el-form-item label="鏁伴噺" prop="quantity">
+          <el-input type="number" v-model="form.quantity"></el-input>
         </el-form-item>
         <el-form-item label="鐘舵��" prop="status">
           <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
@@ -162,6 +166,9 @@
   sparePartsNo: [
     { required: true, message: '璇疯緭鍏ュ浠剁紪鍙�', trigger: 'blur' }
   ],
+  quantity:[
+    { required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' }
+  ],
   status: [
     { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
   ],
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
deleted file mode 100644
index 3aa0867..0000000
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="瀹為檯淇濆吇浜�">
-      <el-input
-        v-model="form.maintenanceActuallyName"
-        placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
-      ></el-input>
-    </el-form-item>
-    <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceActuallyTime"
-        placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-    <el-form-item label="淇濆吇鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚鍏�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="淇濆吇缁撴灉">
-      <!-- <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
-        <el-option label="瀹屽ソ" :value="1"></el-option>
-        <el-option label="缁翠慨" :value="0"></el-option>
-      </el-select> -->
-      <el-input
-        v-model="form.maintenanceResult"
-        placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
-        type="text" />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
-  name: "淇濆吇琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
-  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
-  maintenanceResult: undefined, // 淇濆吇缁撴灉
-  status: 0, // 淇濆吇鐘舵��
-});
-
-const setForm = (data) => {
-  form.maintenanceActuallyName =
-    data.maintenanceActuallyName ?? userStore.nickName;
-  form.maintenanceActuallyTime =
-    dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-  form.maintenanceResult = data.maintenanceResult;
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
new file mode 100644
index 0000000..c660840
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -0,0 +1,123 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧淇濆吇'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-form-item label="瀹為檯淇濆吇浜�">
+        <el-input
+          v-model="form.maintenanceActuallyName"
+          placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
+        <el-date-picker
+          v-model="form.maintenanceActuallyTime"
+          placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+      <el-form-item label="淇濆吇鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚鍏�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="淇濆吇缁撴灉">
+        <el-input
+          v-model="form.maintenanceResult"
+          placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
+          type="text" />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "淇濆吇妯℃�佹",
+});
+
+const emits = defineEmits(["ok"]);
+
+// 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+const planId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const userStore = useUserStore();
+
+const { form, resetForm } = useFormData({
+  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+  maintenanceResult: undefined, // 淇濆吇缁撴灉
+  status: 0, // 淇濆吇鐘舵��
+});
+
+const setForm = (data) => {
+  form.maintenanceActuallyName =
+    data.maintenanceActuallyName ?? userStore.nickName;
+  form.maintenanceActuallyTime =
+    data.maintenanceActuallyTime 
+      ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.maintenanceResult = data.maintenanceResult;
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
+
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    const { code } = await addMaintenance({ id: planId.value, ...form });
+    if (code == 200) {
+      ElMessage.success("淇濆吇鎴愬姛");
+      emits("ok");
+      resetForm();
+      visible.value = false;
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const open = async (id, row) => {
+  planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+  visible.value = true;
+  await nextTick();
+  setForm(row);
+};
+
+defineExpose({
+  open,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
deleted file mode 100644
index 2822e2c..0000000
--- a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="璁惧鍚嶇О">
-      <el-select
-        v-model="form.deviceLedgerId"
-        @change="setDeviceModel"
-        placeholder="璇烽�夋嫨璁惧"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-      >
-        <el-option
-          v-for="(item, index) in deviceOptions"
-          :key="index"
-          :label="item.deviceName"
-          :value="item.id"
-        ></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="瑙勬牸鍨嬪彿">
-      <el-input
-        v-model="form.deviceModel"
-        placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-        disabled
-      />
-    </el-form-item>
-    <el-form-item label="褰曞叆浜�">
-      <el-select
-        v-model="form.createUser"
-        placeholder="璇烽�夋嫨"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-        clearable
-      >
-        <el-option
-          v-for="item in userList"
-          :key="item.userId"
-          :label="item.nickName"
-          :value="item.userId"
-        />
-      </el-select>
-    </el-form-item>
-    <el-form-item v-if="id" label="淇濅慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="璁″垝淇濆吇鏃ユ湡">
-      <el-date-picker
-        style="width: 100%"
-        v-model="form.maintenancePlanTime"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="date"
-        placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
-        clearable
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-import { userListNoPage } from "@/api/system/user.js";
-
-defineOptions({
-  name: "璁″垝琛ㄥ崟",
-});
-
-const deviceOptions = ref([]);
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const { id } = defineProps(['id']);
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
-  createUser: undefined, // 褰曞叆浜�
-  status: 0, //淇濅慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.createUser = Number(data.createUser);
-  form.status = data.status;
-  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
-    "YYYY-MM-DD HH:mm:ss"
-  );
-};
-
-// 鐢ㄦ埛鍒楄〃
-const userList = ref([]);
-
-const loadForm = () => {};
-
-onMounted(() => {
-  loadDeviceName();
-  userListNoPage().then((res) => {
-    userList.value = res.data;
-  });
-});
-
-defineExpose({
-  loadForm,
-  resetForm,
-  getForm,
-  setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
new file mode 100644
index 0000000..19095b9
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -0,0 +1,188 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧淇濆吇璁″垝' : '鏂板璁惧淇濆吇璁″垝'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-form-item label="璁惧鍚嶇О">
+        <el-select
+          v-model="form.deviceLedgerId"
+          @change="setDeviceModel"
+          placeholder="璇烽�夋嫨璁惧"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+        >
+          <el-option
+            v-for="(item, index) in deviceOptions"
+            :key="index"
+            :label="item.deviceName"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瑙勬牸鍨嬪彿">
+        <el-input
+          v-model="form.deviceModel"
+          placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+          disabled
+        />
+      </el-form-item>
+      <el-form-item label="褰曞叆浜�">
+        <el-select
+          v-model="form.createUser"
+          placeholder="璇烽�夋嫨"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+          clearable
+        >
+          <el-option
+            v-for="item in userList"
+            :key="item.userId"
+            :label="item.nickName"
+            :value="item.userId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="id" label="淇濅慨鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚淇�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璁″垝淇濆吇鏃ユ湡">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.maintenancePlanTime"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="date"
+          placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import {
+  addUpkeep,
+  editUpkeep,
+  getUpkeepById,
+} from "@/api/equipmentManagement/upkeep";
+import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted } from "vue";
+import dayjs from "dayjs";
+import { userListNoPage } from "@/api/system/user.js";
+
+defineOptions({
+  name: "璁惧淇濆吇鏂板璁″垝",
+});
+
+const emits = defineEmits(["ok"]);
+
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const deviceOptions = ref([]);
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
+  createUser: undefined, // 褰曞叆浜�
+  status: 0, //淇濅慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+/**
+ * @desc 璁剧疆琛ㄥ崟鍐呭
+ * @param data 璁惧淇℃伅
+ */
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.createUser = Number(data.createUser);
+  form.status = data.status;
+  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+    "YYYY-MM-DD HH:mm:ss"
+  );
+};
+
+// 鐢ㄦ埛鍒楄〃
+const userList = ref([]);
+
+onMounted(() => {
+  loadDeviceName();
+  userListNoPage().then((res) => {
+    userList.value = res.data;
+  });
+});
+
+const openEdit = async (editId) => {
+  const { data } = await getUpkeepById(editId);
+  id.value = editId;
+  visible.value = true;
+  await nextTick();
+  setForm(data);
+};
+
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    const { code } = id.value
+      ? await editUpkeep({ id: unref(id), ...form })
+      : await addUpkeep(form);
+    if (code == 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const openModal = () => {
+  id.value = undefined;
+  visible.value = true;
+};
+
+defineExpose({
+  openModal,
+  openEdit,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/formDia.vue b/src/views/equipmentManagement/upkeep/Form/formDia.vue
new file mode 100644
index 0000000..66bf067
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -0,0 +1,304 @@
+<template>
+	<FormDialog
+		v-model="dialogVisitable"
+		:title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
+		width="800px"
+		:operation-type="operationType"
+		@confirm="submitForm"
+		@cancel="cancel"
+		@close="cancel"
+	>
+		<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="璁惧鍚嶇О" prop="taskId">
+						<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
+							<el-option
+								v-for="(item, index) in deviceOptions"
+								:key="index"
+								:label="item.deviceName"
+								:value="item.id"
+							></el-option>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="瑙勬牸鍨嬪彿">
+						<el-input
+							v-model="form.deviceModel"
+							placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="褰曞叆浜�" prop="inspector">
+						<el-select
+							v-model="form.inspector"
+							filterable
+							default-first-option
+							:reserve-keyword="false"
+							placeholder="璇烽�夋嫨"
+							clearable
+						>
+							<el-option
+								v-for="item in userList"
+								:label="item.nickName"
+								:value="item.userId"
+								:key="item.userId"
+							/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
+						<el-date-picker
+							v-model="form.registrationDate"
+							type="date"
+							placeholder="閫夋嫨鐧昏鏃ユ湡"
+							format="YYYY-MM-DD"
+							value-format="YYYY-MM-DD"
+							style="width: 100%"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
+						<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
+							<el-option label="姣忔棩" value="DAILY"/>
+							<el-option label="姣忓懆" value="WEEKLY"/>
+							<el-option label="姣忔湀" value="MONTHLY"/>
+							<el-option label="瀛e害" value="QUARTERLY"/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+							<el-option label="鍛ㄤ竴" value="MON"/>
+							<el-option label="鍛ㄤ簩" value="TUE"/>
+							<el-option label="鍛ㄤ笁" value="WED"/>
+							<el-option label="鍛ㄥ洓" value="THU"/>
+							<el-option label="鍛ㄤ簲" value="FRI"/>
+							<el-option label="鍛ㄥ叚" value="SAT"/>
+							<el-option label="鍛ㄦ棩" value="SUN"/>
+						</el-select>
+						<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm"  style="width: 50%"/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="DD,HH:mm"
+							value-format="DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="MM,DD,HH:mm"
+							value-format="MM,DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="澶囨敞" prop="remarks">
+						<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+	</FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { reactive, ref, getCurrentInstance, toRefs } from "vue";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
+import { getCurrentDate } from "@/utils/index.js";
+import useUserStore from "@/store/modules/user.js";
+
+const { proxy } = getCurrentInstance()
+const emit = defineEmits()
+const dialogVisitable = ref(false);
+const operationType = ref('add');
+const deviceOptions = ref([]);
+const userStore = useUserStore();
+const data = reactive({
+	form: {
+		taskId: undefined,
+		taskName: undefined,
+		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
+		inspector: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined, // 瑙勬牸鍨嬪彿
+		registrationDate: ''
+	},
+	rules: {
+		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
+		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
+		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
+	}
+})
+const { form, rules } = toRefs(data)
+const userList = ref([])
+
+const loadDeviceName = async () => {
+	const { data } = await getDeviceLedger();
+	deviceOptions.value = data;
+};
+
+// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
+const setDeviceModel = (id) => {
+	const option = deviceOptions.value.find((item) => item.id === id);
+	if (option) {
+		form.value.taskId = option.id;
+		form.value.taskName = option.deviceName;
+		form.value.deviceModel = option.deviceModel;
+	}
+}
+
+// 鎵撳紑寮规
+const openDialog = async (type, row) => {
+	dialogVisitable.value = true
+	operationType.value = type
+	
+	// 閲嶇疆琛ㄥ崟
+	resetForm();
+	
+	// 鍔犺浇鐢ㄦ埛鍒楄〃
+	userListNoPageByTenantId().then((res) => {
+		userList.value = res.data;
+	});
+	
+	// 鍔犺浇璁惧鍒楄〃
+	await loadDeviceName();
+	
+	if (type === 'edit' && row) {
+		form.value = { ...row }
+		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
+		if (row.registrantId) {
+			form.value.inspector = row.registrantId
+		}
+
+		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
+		if (form.value.taskId) {
+			setDeviceModel(form.value.taskId);
+		}
+	} else if (type === 'add') {
+		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
+		form.value.registrationDate = getCurrentDate();
+		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
+		form.value.inspector = userStore.id;
+	}
+}
+
+// 鍏抽棴瀵硅瘽妗�
+const cancel = () => {
+	resetForm()
+	dialogVisitable.value = false
+	emit('closeDia')
+}
+
+// 閲嶇疆琛ㄥ崟鍑芥暟
+const resetForm = () => {
+	if (proxy.$refs.formRef) {
+		proxy.$refs.formRef.resetFields()
+	}
+	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
+	form.value = {
+		taskId: undefined,
+		taskName: undefined,
+		inspector: undefined,
+		inspector: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined,
+		registrationDate: ''
+	}
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(async valid => {
+		if (valid) {
+			try {
+				const payload = { ...form.value }
+				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
+				// 鏍规嵁閫夋嫨鐨�"褰曞叆浜�"璁剧疆 registrant / registrantId
+				if (payload.inspector) {
+					const selectedUser = userList.value.find(
+						(u) => String(u.userId) === String(payload.inspector)
+					)
+					if (selectedUser) {
+						payload.registrantId = selectedUser.userId
+						payload.registrant = selectedUser.nickName
+					}
+				}
+				delete payload.inspector
+				delete payload.inspectorIds
+				
+				if (payload.frequencyType === 'WEEKLY') {
+					let frequencyDetail = ''
+					frequencyDetail = payload.week + ',' + payload.time
+					payload.frequencyDetail = frequencyDetail
+				}
+				
+				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
+				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
+				if (payload.status === undefined || payload.status === null || payload.status === '') {
+					payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
+				}
+				payload.active = true
+				payload.deleted = 0
+				
+				if (operationType.value === 'edit') {
+					await deviceMaintenanceTaskEdit(payload)
+				} else {
+					await deviceMaintenanceTaskAdd(payload)
+				}
+				cancel()
+				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
+			} catch (error) {
+				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
+			}
+		}
+	})
+}
+defineExpose({ openDialog })
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
deleted file mode 100644
index 0b44221..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintenanceForm ref="maintenanceFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import MaintenanceForm from "../Form/MaintenanceForm.vue";
-import { useModal } from "@/hooks/useModal";
-import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-
-defineOptions({
-  name: "淇濆吇妯℃�佹",
-});
-
-const maintenanceFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇" });
-
-/**
- * @desc 淇濆瓨淇濆吇
- */
-const sendForm = async () => {
-  loading.value = true;
-  const form = await maintenanceFormRef.value.getForm();
-  const { code } = await addMaintenance({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintenanceFormRef.value.resetForm();
-    closeModal();
-  }
-  loading.value = false;
-};
-
-const open = async (id, row) => {
-  openModal(id);
-  await nextTick();
-  maintenanceFormRef.value.setForm(row);
-};
-defineExpose({
-  open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
deleted file mode 100644
index 249c9c3..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-dialog
-    v-model="visible"
-    :title="modalOptions.title"
-    width="30%"
-		draggable
-    @close="close"
-  >
-    <PlanForm ref="planFormRef" :id="id"></PlanForm>
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import PlanForm from "../Form/PlanForm";
-import {
-  addUpkeep,
-  editUpkeep,
-  getUpkeepById,
-} from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-
-defineOptions({
-  name: "璁惧淇濆吇鏂板璁″垝",
-});
-
-const emits = defineEmits(["ok"]);
-const planFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇璁″垝" });
-
-const openEdit = async (id) => {
-  const { data } = await getUpkeepById(id);
-  openModal(id);
-  await nextTick();
-  await planFormRef.value.setForm(data);
-};
-
-const sendForm = async () => {
-  loading.value = true;
-  const form = await planFormRef.value.getForm();
-  const { code } = id.value
-    ? await editUpkeep({ id: unref(id), ...form })
-    : await addUpkeep(form);
-  if (code == 200) {
-    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
-    closeModal();
-    emits("ok");
-  }
-  loading.value = false;
-};
-
-const close = () => {
-  planFormRef.value.resetForm();
-  closeModal();
-};
-
-defineExpose({
-  openModal,
-  openEdit,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/formDia.vue b/src/views/equipmentManagement/upkeep/Modal/formDia.vue
deleted file mode 100644
index a484d23..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/formDia.vue
+++ /dev/null
@@ -1,304 +0,0 @@
-<template>
-	<div>
-		<el-dialog :title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
-							 v-model="dialogVisitable" width="800px" @close="cancel">
-			<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="璁惧鍚嶇О" prop="taskId">
-							<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
-								<el-option
-									v-for="(item, index) in deviceOptions"
-									:key="index"
-									:label="item.deviceName"
-									:value="item.id"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="瑙勬牸鍨嬪彿">
-							<el-input
-								v-model="form.deviceModel"
-								placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-								disabled
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="褰曞叆浜�" prop="inspector">
-							<el-select
-								v-model="form.inspector"
-								filterable
-								default-first-option
-								:reserve-keyword="false"
-								placeholder="璇烽�夋嫨"
-								clearable
-							>
-								<el-option
-									v-for="item in userList"
-									:label="item.nickName"
-									:value="item.userId"
-									:key="item.userId"
-								/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
-							<el-date-picker
-								v-model="form.registrationDate"
-								type="date"
-								placeholder="閫夋嫨鐧昏鏃ユ湡"
-								format="YYYY-MM-DD"
-								value-format="YYYY-MM-DD"
-								style="width: 100%"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
-							<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
-								<el-option label="姣忔棩" value="DAILY"/>
-								<el-option label="姣忓懆" value="WEEKLY"/>
-								<el-option label="姣忔湀" value="MONTHLY"/>
-								<el-option label="瀛e害" value="QUARTERLY"/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
-								<el-option label="鍛ㄤ竴" value="MON"/>
-								<el-option label="鍛ㄤ簩" value="TUE"/>
-								<el-option label="鍛ㄤ笁" value="WED"/>
-								<el-option label="鍛ㄥ洓" value="THU"/>
-								<el-option label="鍛ㄤ簲" value="FRI"/>
-								<el-option label="鍛ㄥ叚" value="SAT"/>
-								<el-option label="鍛ㄦ棩" value="SUN"/>
-							</el-select>
-							<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm"  style="width: 50%"/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="DD,HH:mm"
-								value-format="DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="MM,DD,HH:mm"
-								value-format="MM,DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="澶囨敞" prop="remarks">
-							<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">淇濆瓨</el-button>
-					<el-button @click="cancel">鍙栨秷</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
-
-<script setup>
-import { reactive, ref, getCurrentInstance, toRefs } from "vue";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
-import { getCurrentDate } from "@/utils/index.js";
-import useUserStore from "@/store/modules/user.js";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const dialogVisitable = ref(false);
-const operationType = ref('add');
-const deviceOptions = ref([]);
-const userStore = useUserStore();
-const data = reactive({
-	form: {
-		taskId: undefined,
-		taskName: undefined,
-		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined, // 瑙勬牸鍨嬪彿
-		registrationDate: ''
-	},
-	rules: {
-		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
-		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
-		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
-	}
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
-	const { data } = await getDeviceLedger();
-	deviceOptions.value = data;
-};
-
-// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
-const setDeviceModel = (id) => {
-	const option = deviceOptions.value.find((item) => item.id === id);
-	if (option) {
-		form.value.taskId = option.id;
-		form.value.taskName = option.deviceName;
-		form.value.deviceModel = option.deviceModel;
-	}
-}
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
-	dialogVisitable.value = true
-	operationType.value = type
-	
-	// 閲嶇疆琛ㄥ崟
-	resetForm();
-	
-	// 鍔犺浇鐢ㄦ埛鍒楄〃
-	userListNoPageByTenantId().then((res) => {
-		userList.value = res.data;
-	});
-	
-	// 鍔犺浇璁惧鍒楄〃
-	await loadDeviceName();
-	
-	if (type === 'edit' && row) {
-		form.value = { ...row }
-		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
-		if (row.registrantId) {
-			form.value.inspector = row.registrantId
-		}
-
-		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
-		if (form.value.taskId) {
-			setDeviceModel(form.value.taskId);
-		}
-	} else if (type === 'add') {
-		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
-		form.value.registrationDate = getCurrentDate();
-		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
-		form.value.inspector = userStore.id;
-	}
-}
-
-// 鍏抽棴瀵硅瘽妗�
-const cancel = () => {
-	resetForm()
-	dialogVisitable.value = false
-	emit('closeDia')
-}
-
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
-	if (proxy.$refs.formRef) {
-		proxy.$refs.formRef.resetFields()
-	}
-	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
-	form.value = {
-		taskId: undefined,
-		taskName: undefined,
-		inspector: undefined,
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined,
-		registrationDate: ''
-	}
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
-	proxy.$refs["formRef"].validate(async valid => {
-		if (valid) {
-			try {
-				const payload = { ...form.value }
-				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
-				// 鏍规嵁閫夋嫨鐨勨�滃綍鍏ヤ汉鈥濊缃� registrant / registrantId
-				if (payload.inspector) {
-					const selectedUser = userList.value.find(
-						(u) => String(u.userId) === String(payload.inspector)
-					)
-					if (selectedUser) {
-						payload.registrantId = selectedUser.userId
-						payload.registrant = selectedUser.nickName
-					}
-				}
-				delete payload.inspector
-				delete payload.inspectorIds
-				
-				if (payload.frequencyType === 'WEEKLY') {
-					let frequencyDetail = ''
-					frequencyDetail = payload.week + ',' + payload.time
-					payload.frequencyDetail = frequencyDetail
-				}
-				
-				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
-				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
-				if (payload.status === undefined || payload.status === null || payload.status === '') {
-					payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
-				}
-				payload.active = true
-				payload.deleted = 0
-				
-				if (operationType.value === 'edit') {
-					await deviceMaintenanceTaskEdit(payload)
-				} else {
-					await deviceMaintenanceTaskAdd(payload)
-				}
-				cancel()
-				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
-			} catch (error) {
-				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
-			}
-		}
-	})
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 75f0751..7ef639c 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -64,16 +64,14 @@
             <template #operation="{ row }">
               <el-button
                 type="primary"
-                text
-                icon="editPen"
+                link
                 @click="editScheduledTask(row)"
               >
                 缂栬緫
               </el-button>
               <el-button
                 type="danger"
-                text
-                icon="delete"
+                link
                 @click="delScheduledTaskByIds(row.id)"
               >
                 鍒犻櫎
@@ -144,7 +142,7 @@
               <el-button
                 type="danger"
                 icon="Delete"
-                :disabled="multipleList.length <= 0"
+                :disabled="multipleList.length <= 0 || hasFinishedStatus"
                 @click="delRepairByIds(multipleList.map((item) => item.id))"
               >
                 鎵归噺鍒犻櫎
@@ -182,16 +180,24 @@
           </el-button>
           <el-button
             type="primary"
-            text
-            icon="editPen"
+            link
+            :disabled="row.status === 1"
             @click="editPlan(row.id)"
           >
             缂栬緫
           </el-button>
           <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            淇濆吇
+          </el-button>
+          <el-button
             type="danger"
-            text
-            icon="delete"
+            link
+            :disabled="row.status === 1"
             @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
@@ -208,12 +214,12 @@
 </template>
 
 <script setup>
-import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
+import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue'
 import { Search } from '@element-plus/icons-vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import PlanModal from './Modal/PlanModal.vue'
-import MaintenanceModal from './Modal/MaintenanceModal.vue'
-import FormDia from './Modal/formDia.vue'
+import PlanModal from './Form/PlanModal.vue'
+import MaintenanceModal from './Form/MaintenanceModal.vue'
+import FormDia from './Form/formDia.vue'
 import {
   getUpkeepPage,
   delUpkeep,
@@ -493,6 +499,11 @@
   multipleList.value = selection
 }
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 const changePage = (page) => {
   pagination.value.currentPage = page.page
   pagination.value.pageSize = page.limit
@@ -512,6 +523,13 @@
 }
 
 const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const hasFinished = multipleList.value.some(item => item.status === 1)
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�')
+    return
+  }
+  
   try {
     await ElMessageBox.confirm('纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?', '璀﹀憡', {
       confirmButtonText: '纭畾',
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
index f8e4a9f..40bf1ae 100644
--- a/src/views/financialManagement/accounting/index.vue
+++ b/src/views/financialManagement/accounting/index.vue
@@ -2,14 +2,31 @@
   <div style="padding: 20px;">
     <!-- 椤甸潰鏍囬鍜岀瓫閫夋潯浠� -->
     <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
-      <el-button
-        type="primary"
-        icon="Refresh"
-        @click="resetFilters"
-        size="default"
-      >
-        鏌ヨ
-      </el-button>
+      <el-form :inline="true">
+        <el-form-item label="骞翠唤">
+          <el-date-picker
+            v-model="selectedYear"
+            type="year"
+            placeholder="璇烽�夋嫨骞翠唤"
+            format="YYYY"
+            value-format="YYYY"
+            clearable
+            @change="fetchData()"
+            style="width: 200px"
+            :disabled-date="(date) => date.getFullYear() > new Date().getFullYear()"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            icon="Refresh"
+            @click="resetFilters"
+            size="default"
+          >
+            閲嶇疆
+          </el-button>
+        </el-form-item>
+      </el-form>
     </div>
 
     <main class="container mx-auto px-4 pb-10">
@@ -27,7 +44,7 @@
         <el-card class="bg3">
           <p>璧勪骇鍘熷��</p>
           <h3>
-            楼{{ assetInfo.totalOriginalValue }}
+            楼{{ formatCurrency(assetInfo.totalOriginalValue) }}
           </h3>
         </el-card>
 
@@ -35,7 +52,7 @@
         <el-card class="bg4">
           <p>绱鎶樻棫</p>
           <h3>
-            楼{{ assetInfo.totalDepreciation }}
+            楼{{ formatCurrency(assetInfo.totalDepreciation) }}
           </h3>
         </el-card>
 
@@ -43,7 +60,21 @@
         <el-card class="bg5">
           <p>鍑�鍊�</p>
           <h3>
-            楼{{ assetInfo.totalNetValue }}
+            楼{{ formatCurrency(assetInfo.totalNetValue) }}
+          </h3>
+        </el-card>
+        <!-- 璐熷�� -->
+        <el-card class="bg2">
+          <p>璐熷��</p>
+          <h3>
+            楼{{ formatCurrency(assetInfo.debt) }}
+          </h3>
+        </el-card>
+        <!-- 搴撳瓨璧勪骇 -->
+        <el-card class="bg3">
+          <p>搴撳瓨璧勪骇</p>
+          <h3>
+            楼{{ formatCurrency(assetInfo.inventoryValue) }}
           </h3>
         </el-card>
       </div>
@@ -62,7 +93,7 @@
                 style="height: 260px; width: 35%;">
               <div class="chart-num">
                 <span style="font-size: 22px;">璁惧绫诲瀷</span>
-                <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ assetInfo.totalEquipment }}</span>
+                <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ deviceTypeTotalCount }}</span>
               </div>
             </Echarts>
             <Echarts
@@ -86,7 +117,6 @@
           style="width: 100%"
           :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
         >
-          <el-table-column prop="id" label="璧勪骇缂栧彿" width="120" />
           <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="250" />
           <el-table-column prop="deviceModel" label="鍨嬪彿瑙勬牸" min-width="150" />
           <el-table-column prop="supplierName" label="渚涘簲鍟�" min-width="120" />
@@ -94,27 +124,17 @@
           <el-table-column prop="number" label="鏁伴噺" width="120" />
           <el-table-column prop="originalValue" label="鍘熷��(鍏�)" width="120">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.taxIncludingPriceTotal) }}
+              {{ formatCurrency(row.taxIncludingPriceTotal) }}
             </template>
           </el-table-column>
           <el-table-column prop="depreciation" label="绱鎶樻棫(鍏�)" width="140">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }}
+              {{ formatCurrency(row.deprAmount) }}
             </template>
           </el-table-column>
           <el-table-column prop="netValue" label="鍑�鍊�(鍏�)" width="120">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.unTaxIncludingPriceTotal) }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="status" label="鐘舵��" width="100">
-            <template #default="{ row }">
-              <el-tag
-                :type="getStatusTagType(row.status)"
-                size="small"
-              >
-                {{ row.status }}
-              </el-tag>
+              {{ formatCurrency(row.netValue) }}
             </template>
           </el-table-column>
         </el-table>
@@ -141,21 +161,28 @@
 import { ref, computed, onMounted, reactive } from 'vue';
 import 'element-plus/dist/index.css';
 import Echarts from "@/components/Echarts/echarts.vue";
-import { getLedgerPage, getAssetInfo } from "@/api/equipmentManagement/ledger";
+import { getLedgerPage } from "@/api/equipmentManagement/ledger";
+import { getAccountingTotal, getDeviceTypeDistribution, getCalculateDepreciation } from "@/api/financialManagement/accounting";
 import dayjs from "dayjs";
 
 // 绛涢�夋潯浠�
 const dateRange = ref(null);
 const equipmentType = ref('');
+const selectedYear = ref(dayjs().format('YYYY')); // 榛樿褰撳墠骞翠唤
 
 
 // 鍥哄畾璧勪骇淇℃伅
 const assetInfo = ref({
-  totalEquipment: 0,
-  totalOriginalValue: 0,
-  totalDepreciation: 0,
-  totalNetValue: 0
+  totalEquipment: 0, // deviceTotal
+  totalOriginalValue: 0, // deviceAmount
+  totalDepreciation: 0, // deprAmount
+  totalNetValue: 0, // netValue
+  debt: 0, // 璐熷��
+  inventoryValue: 0 // 搴撳瓨璧勪骇
 });
+
+// 璁惧绫诲瀷鎬绘暟锛堢敤浜庡浘琛ㄦ樉绀猴級
+const deviceTypeTotalCount = ref(0);
 
 // 璁惧鍒楄〃
 const equipmentList = ref([]);
@@ -306,63 +333,96 @@
 const fetchData = async () => {
   try {
     // 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
-    const assetInfoRes = await getAssetInfo({
+    const assetInfoRes = await getAccountingTotal({
       startDate: dateRange.value ? dateRange.value[0] : null,
       endDate: dateRange.value ? dateRange.value[1] : null,
-      equipmentType: equipmentType.value
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
     });
 
     if (assetInfoRes.code === 200) {
-      assetInfo.value = assetInfoRes.data;
+      // 鏄犲皠鍚庣瀛楁鍒板墠绔瓧娈�
+      const data = assetInfoRes.data;
+      assetInfo.value = {
+        totalEquipment: data.deviceTotal || 0, // 璁惧鎬绘暟
+        totalOriginalValue: data.deviceAmount || 0, // 璧勪骇鍘熷��
+        totalDepreciation: data.deprAmount || 0, // 绱鎶樻棫
+        totalNetValue: data.netValue || 0, // 鍑�鍊�
+        debt: data.debt || 0, // 璐熷��
+        inventoryValue: data.inventoryValue || 0 // 搴撳瓨璧勪骇
+      };
     }
 
-    // 鑾峰彇璁惧鍒楄〃
-    const equipmentListRes = await getLedgerPage({
-      current: pagination.value.currentPage,
-      size: pagination.value.pageSize,
+    // 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+    const distributionRes = await getDeviceTypeDistribution({
       startDate: dateRange.value ? dateRange.value[0] : null,
       endDate: dateRange.value ? dateRange.value[1] : null,
-      equipmentType: equipmentType.value
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
     });
 
-    if (equipmentListRes.code === 200) {
-      equipmentList.value = equipmentListRes.data.records;
-      pagination.value.total = equipmentListRes.data.total;
-
-      // 鏍规嵁 equipmentList 鎸� deviceName 杩涜鍒嗙被缁熻
-      const deviceNameMap = {};
-      equipmentList.value.forEach(item => {
-        const deviceName = item.deviceName;
-        if (!deviceNameMap[deviceName]) {
-          deviceNameMap[deviceName] = {
-            name: deviceName,
-            count: 0,
-            totalValue: 0
-          };
-        }
-        deviceNameMap[deviceName].count += item.number || 1; // 鍋囪 number 涓鸿澶囨暟閲�
-        deviceNameMap[deviceName].totalValue += item.taxIncludingPriceTotal || 0; // 绱姞鍚◣鎬讳环
-      });
-
-      // 杞崲涓� typeDistributionData 鏍煎紡
-      typeDistributionData.value = Object.values(deviceNameMap).map(item => ({
-        name: item.name,
-        value: item.count,
-        count: item.count,
-        amount: `楼${formatCurrency(item.totalValue)}`
-      }));
+    if (distributionRes.code === 200) {
+      const data = distributionRes.data;
+      
+      // 鏇存柊璁惧绫诲瀷鎬绘暟
+      deviceTypeTotalCount.value = data.totalCount || 0;
+      
+      // 杞崲楗煎浘鏁版嵁鏍煎紡
+      if (data.details && data.details.length > 0) {
+        typeDistributionData.value = data.details.map(item => ({
+          name: item.type || '',
+          value: Number(item.count || 0),
+          count: Number(item.count || 0),
+          amount: `楼${formatCurrency(item.amount || 0)}`
+        }));
+      } else if (data.categories && data.categories.length > 0) {
+        // 濡傛灉娌℃湁 details锛屼娇鐢� categories銆乧ountData 鍜� amountData 鏋勫缓
+        typeDistributionData.value = data.categories.map((category, index) => ({
+          name: category,
+          value: Number(data.countData[index] || 0),
+          count: Number(data.countData[index] || 0),
+          amount: `楼${formatCurrency(data.amountData[index] || 0)}`
+        }));
+      } else {
+        typeDistributionData.value = [];
+      }
 
       // 鏇存柊x杞存暟鎹�
-      xAxis.value[0].data = typeDistributionData.value.map(item => item.name);
+      xAxis.value[0].data = data.categories || typeDistributionData.value.map(item => item.name);
 
       // 鏋勫缓鎶樼嚎鍥炬暟鎹�
       typeDistributionLineSeries.value = [
         {
           name: '璁惧鏁伴噺',
           type: 'line',
-          data: typeDistributionData.value.map(item => item.count)
+          data: data.countData || typeDistributionData.value.map(item => item.count)
         }
       ];
+    }
+
+    // 鑾峰彇璁惧鍒楄〃锛堟姌鏃ц绠楁暟鎹級
+    const equipmentListRes = await getCalculateDepreciation({
+      current: pagination.value.currentPage,
+      size: pagination.value.pageSize,
+      startDate: dateRange.value ? dateRange.value[0] : null,
+      endDate: dateRange.value ? dateRange.value[1] : null,
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
+    });
+
+    if (equipmentListRes.code === 200) {
+      // 濡傛灉杩斿洖鐨勬槸鍒嗛〉鏁版嵁
+      if (equipmentListRes.data.records) {
+        equipmentList.value = equipmentListRes.data.records;
+        pagination.value.total = equipmentListRes.data.total;
+      } else if (Array.isArray(equipmentListRes.data)) {
+        // 濡傛灉杩斿洖鐨勬槸鏁扮粍
+        equipmentList.value = equipmentListRes.data;
+        pagination.value.total = equipmentListRes.data.length;
+      } else {
+        equipmentList.value = [];
+        pagination.value.total = 0;
+      }
     }
   } catch (error) {
     console.error('鑾峰彇鍥哄畾璧勪骇鏁版嵁澶辫触锛�', error);
@@ -401,6 +461,7 @@
 const resetFilters = () => {
   dateRange.value = null;
   equipmentType.value = '';
+  selectedYear.value = dayjs().format('YYYY'); // 閲嶇疆涓哄綋鍓嶅勾浠�
   fetchData();
 };
 
@@ -486,10 +547,10 @@
   }
 }
 
-/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-5) */
+/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-6) */
 @media (min-width: 1024px) {
   .grid-container {
-    grid-template-columns: repeat(5, minmax(0, 1fr));
+    grid-template-columns: repeat(6, minmax(0, 1fr));
   }
 }
 
diff --git a/src/views/financialManagement/expenseManagement/Form.vue b/src/views/financialManagement/expenseManagement/Form.vue
deleted file mode 100644
index 9cfe5da..0000000
--- a/src/views/financialManagement/expenseManagement/Form.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
-    <el-form-item label="鏀嚭鏃ユ湡" prop="expenseDate">
-          <el-date-picker
-            style="width: 100%"
-            v-model="form.expenseDate"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            type="date"
-            placeholder="璇烽�夋嫨鏃ユ湡"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item label="鏀嚭绫诲瀷" prop="expenseType">
-          <el-select
-            v-model="form.expenseType"
-            placeholder="璇烽�夋嫨"
-            clearable
-          >
-            <el-option :label="item.label" :value="item.value" v-for="(item,index) in expense_types" :key="index" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
-          <el-input v-model="form.supplierName" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="鏀嚭閲戦" prop="expenseMoney">
-          <el-input-number :step="0.01" :min="0" style="width: 100%"
-            v-model="form.expenseMoney"
-            placeholder="璇疯緭鍏�"
-          />
-        </el-form-item>
-        <el-form-item label="鏀嚭鎻忚堪" prop="expenseDescribed">
-          <el-input v-model="form.expenseDescribed" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="浠樻鏂瑰紡" prop="expenseMethod">
-          <el-select
-            v-model="form.expenseMethod"
-            placeholder="璇烽�夋嫨"
-            clearable
-          >
-            <el-option :label="item.label" :value="item.value" v-for="(item,index) in checkout_payment" :key="index" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
-          <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="note">
-          <el-input
-            v-model="form.note"
-            placeholder="澶囨敞"
-          />
-        </el-form-item>
-        
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getAccountExpense } from "@/api/financialManagement/expenseManagement";
-import {ref} from "vue";
-const { proxy } = getCurrentInstance();
-
-
-defineOptions({
-  name: "鏂板鏀嚭",
-});
-const { expense_types } = proxy.useDict("expense_types");
-const { checkout_payment } = proxy.useDict("checkout_payment");
-const formRef = ref(null);
-const formRules = {
-	supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	expenseMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	expenseDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	expenseDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-  expenseType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-  expenseMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
-  expenseDate: undefined, // 鏀嚭鏃ユ湡
-  expenseType: undefined, // 鏀嚭绫诲瀷
-  supplierName: undefined, // 瀹㈡埛鍚嶇О
-  expenseMoney: undefined, // 鏀嚭閲戦
-  expenseDescribed: undefined, // 鏀嚭鎻忚堪
-  expenseMethod: undefined, // 鏀舵鏂瑰紡
-  invoiceNumber: undefined, // 鍙戠エ鍙风爜
-  note: undefined, // 澶囨敞
-});
-
-const loadForm = async (id) => {
-  const { code, data } = await getAccountExpense(id);
-  if (code == 200) {
-    form.expenseDate = data.expenseDate;
-    form.expenseType = data.expenseType;
-    form.supplierName = data.supplierName;
-    form.expenseMoney = data.expenseMoney;
-    form.expenseDescribed = data.expenseDescribed;
-    form.expenseMethod = data.expenseMethod;
-    form.invoiceNumber = data.invoiceNumber;
-    form.note = data.note;
-  }
-};
-
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
-  formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
-  resetForm();
-  clearValidate();
-};
-
-defineExpose({
-  form,
-  loadForm,
-  resetForm,
-  clearValidate,
-  resetFormAndValidate,
-	formRef,
-});
-</script>
diff --git a/src/views/financialManagement/expenseManagement/Modal.vue b/src/views/financialManagement/expenseManagement/Modal.vue
index 8e5b171..4d743c1 100644
--- a/src/views/financialManagement/expenseManagement/Modal.vue
+++ b/src/views/financialManagement/expenseManagement/Modal.vue
@@ -1,20 +1,75 @@
 <template>
-  <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
-    <Form ref="formRef"></Form>
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="dialogVisible"
+    :title="dialogTitle"
+    :operationType="operationType"
+    width="50%"
+    @confirm="sendForm"
+    @close="close"
+    @cancel="close"
+  >
+    <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+      <el-form-item label="鏀嚭鏃ユ湡" prop="expenseDate">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.expenseDate"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+          type="date"
+          placeholder="璇烽�夋嫨鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+      <el-form-item label="鏀嚭绫诲瀷" prop="expenseType">
+        <el-select
+          v-model="form.expenseType"
+          placeholder="璇烽�夋嫨"
+          clearable
+        >
+          <el-option :label="item.label" :value="item.value" v-for="(item,index) in expense_types" :key="index" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
+        <el-input v-model="form.supplierName" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="鏀嚭閲戦" prop="expenseMoney">
+        <el-input-number :step="0.01" :min="0" style="width: 100%"
+          v-model="form.expenseMoney"
+          placeholder="璇疯緭鍏�"
+        />
+      </el-form-item>
+      <el-form-item label="鏀嚭鎻忚堪" prop="expenseDescribed">
+        <el-input v-model="form.expenseDescribed" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="浠樻鏂瑰紡" prop="expenseMethod">
+        <el-select
+          v-model="form.expenseMethod"
+          placeholder="璇烽�夋嫨"
+          clearable
+        >
+          <el-option :label="item.label" :value="item.value" v-for="(item,index) in checkout_payment" :key="index" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
+        <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="澶囨敞" prop="note">
+        <el-input
+          v-model="form.note"
+          placeholder="澶囨敞"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import { add, update } from "@/api/financialManagement/expenseManagement";
-import Form from "./Form.vue";
+import { add, update, getAccountExpense } from "@/api/financialManagement/expenseManagement";
 import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { ref } from "vue";
+
 const { proxy } = getCurrentInstance()
 
 defineOptions({
@@ -23,43 +78,96 @@
 
 const emits = defineEmits(["success"]);
 
-const formRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "鏀嚭" });
+const formRef = ref(null);
+const dialogVisible = ref(false);
+const operationType = ref("add"); // add | edit
+const id = ref(undefined);
+const submitting = ref(false);
+
+const dialogTitle = (type) => {
+  if (type === "edit") return "缂栬緫鏀嚭";
+  return "鏂板鏀嚭";
+};
+
+const { expense_types } = proxy.useDict("expense_types");
+const { checkout_payment } = proxy.useDict("checkout_payment");
+
+const formRules = {
+  supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  expenseMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  expenseDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  expenseDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  expenseType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  expenseMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+}
+
+const { form, resetForm } = useFormData({
+  expenseDate: undefined, // 鏀嚭鏃ユ湡
+  expenseType: undefined, // 鏀嚭绫诲瀷
+  supplierName: undefined, // 渚涘簲鍟嗗悕绉�
+  expenseMoney: undefined, // 鏀嚭閲戦
+  expenseDescribed: undefined, // 鏀嚭鎻忚堪
+  expenseMethod: undefined, // 浠樻鏂瑰紡
+  invoiceNumber: undefined, // 鍙戠エ鍙风爜
+  note: undefined, // 澶囨敞
+});
 
 const sendForm = () => {
-	proxy.$refs.formRef.$refs.formRef.validate(async valid => {
-		if (valid) {
-			const {code} = id.value
-				? await update({id: id.value, ...formRef.value.form})
-				: await add(formRef.value.form);
-			if (code == 200) {
-				emits("success");
-				ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
-				close();
-			} else {
-				loading.value = false;
-			}
-		}
-	})
+  if (submitting.value) return;
+  formRef.value?.validate(async (valid) => {
+    if (valid) {
+      submitting.value = true;
+      try {
+        const { code } = id.value
+          ? await update({ id: id.value, ...form })
+          : await add(form);
+        if (code == 200) {
+          emits("success");
+          ElMessage({ message: "鎿嶄綔鎴愬姛", type: "success" });
+          close();
+        }
+      } finally {
+        submitting.value = false;
+      }
+    }
+  })
 };
 
 const close = () => {
-	formRef.value.resetFormAndValidate();
-  closeModal();
+  resetForm();
+  formRef.value?.clearValidate();
+  id.value = undefined;
+  dialogVisible.value = false;
 };
 
-const loadForm = async (id) => {
-  openModal(id);
-  await nextTick();
-  formRef.value.loadForm(id);
+const loadForm = async (rowId) => {
+  operationType.value = "edit";
+  id.value = rowId;
+  dialogVisible.value = true;
+  if (rowId) {
+    const { code, data } = await getAccountExpense(rowId);
+    if (code == 200) {
+      form.expenseDate = data.expenseDate;
+      form.expenseType = data.expenseType;
+      form.supplierName = data.supplierName;
+      form.expenseMoney = data.expenseMoney;
+      form.expenseDescribed = data.expenseDescribed;
+      form.expenseMethod = data.expenseMethod;
+      form.invoiceNumber = data.invoiceNumber;
+      form.note = data.note;
+    }
+  } else {
+    resetForm();
+    formRef.value?.clearValidate();
+  }
+};
+
+const openModal = () => {
+  operationType.value = "add";
+  id.value = undefined;
+  resetForm();
+  formRef.value?.clearValidate();
+  dialogVisible.value = true;
 };
 
 defineExpose({
diff --git a/src/views/financialManagement/expenseManagement/index.vue b/src/views/financialManagement/expenseManagement/index.vue
index a45c32d..801fa1f 100644
--- a/src/views/financialManagement/expenseManagement/index.vue
+++ b/src/views/financialManagement/expenseManagement/index.vue
@@ -34,8 +34,8 @@
           <el-button
             type="danger"
             icon="Delete"
-            :disabled="multipleList.length <= 0"
-            @click="deleteRow(multipleList.map((item) => item.id))"
+            :disabled="multipleList.length <= 0 || hasBusinessIdInSelection"
+            @click="handleBatchDelete"
           >
             鎵归噺鍒犻櫎
           </el-button>
@@ -55,12 +55,17 @@
         @pagination="changePage"
       >
         <template #operation="{ row }">
-          <el-button type="primary" text @click="edit(row.id)" icon="editPen">
+          <el-button 
+            type="primary" 
+            link 
+            :disabled="!!row.businessId"
+            @click="edit(row.id)"
+          >
             缂栬緫
           </el-button>
           <el-button
             type="primary"
-            text
+            link
             @click="openFilesFormDia(row)"
           >
             闄勪欢
@@ -69,18 +74,27 @@
       </PIMTable>
     </div>
     <Modal ref="modalRef" @success="getTableData"></Modal>
-    <files-dia ref="filesDia"></files-dia>
+    <FileListDialog 
+      ref="fileListRef" 
+      v-model="fileListDialogVisible"
+      :show-upload-button="true"
+      :show-delete-button="true"
+      :upload-method="handleUpload"
+      :delete-method="handleFileDelete"
+    />
   </div>
 </template>
 
 <script setup>
 import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountExpense } from "@/api/financialManagement/expenseManagement";
-import { onMounted, getCurrentInstance } from "vue";
+import { listPage, delAccountExpense, fileListPage, fileAdd, fileDel } from "@/api/financialManagement/expenseManagement";
+import { onMounted, getCurrentInstance, ref, computed } from "vue";
 import Modal from "./Modal.vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import dayjs from "dayjs";
-import FilesDia from "../revenueManagement/filesDia.vue";
+import FileListDialog from "@/components/Dialog/FileListDialog.vue";
+import request from "@/utils/request";
+import { getToken } from "@/utils/auth";
 
 defineOptions({
   name: "鏀嚭绠$悊",
@@ -92,7 +106,10 @@
 const modalRef = ref();
 const { checkout_payment } = proxy.useDict("checkout_payment");
 const { expense_types } = proxy.useDict("expense_types");
-const filesDia = ref()
+const fileListRef = ref(null);
+const fileListDialogVisible = ref(false);
+const currentFileRow = ref(null);
+const accountType = ref('鏀嚭');
 
 const {
   filters,
@@ -111,7 +128,6 @@
   [
     {
       label: "鏀嚭鏃ユ湡",
-      align: "center",
       prop: "expenseDate",
     },
     {
@@ -129,19 +145,16 @@
     },
     {
       label: "渚涘簲鍟嗗悕绉�",
-      align: "center",
       prop: "supplierName",
 
     },
     {
       label: "鏀嚭閲戦",
-      align: "center",
       prop: "expenseMoney",
 
     },
     {
       label: "鏀嚭鎻忚堪",
-      align: "center",
       prop: "expenseDescribed",
 
     },
@@ -149,6 +162,7 @@
       label: "浠樻鏂瑰紡",
       align: "center",
       prop: "expenseMethod",
+			width: '120',
       dataType: "tag",
       formatData: (params) => {
         if (checkout_payment.value.find((m) => m.value == params)) {
@@ -160,24 +174,20 @@
     },
     {
       label: "鍙戠エ鍙风爜",
-      align: "center",
       prop: "invoiceNumber",
 
     },
     {
       label: "澶囨敞",
-      align: "center",
       prop: "note",
 
     },
     {
       label: "褰曞叆浜�",
-      align: "center",
       prop: "inputUser",
     },
     {
       label: "褰曞叆鏃ユ湡",
-      align: "center",
       prop: "inputTime",
 
     },
@@ -187,7 +197,7 @@
       dataType: "slot",
       slot: "operation",
       align: "center",
-      width: "200px",
+      width: "160px",
     },
   ]
 );
@@ -197,10 +207,21 @@
   multipleList.value = selectionList;
 };
 
+// 鍒ゆ柇閫変腑鐨勯」涓槸鍚︽湁 businessId
+const hasBusinessIdInSelection = computed(() => {
+  return multipleList.value.some(item => item.businessId);
+});
+
 const add = () => {
   modalRef.value.openModal();
 };
 const edit = (id) => {
+  // 妫�鏌ュ綋鍓嶈鏄惁鏈� businessId
+  const row = dataList.value.find(item => item.id === id);
+  if (row && row.businessId) {
+    proxy.$modal.msgWarning("璇ヨ褰曞凡鍏宠仈涓氬姟锛屼笉鑳界紪杈�");
+    return;
+  }
   modalRef.value.loadForm(id);
 };
 const changePage = ({ page, limit }) => {
@@ -209,6 +230,25 @@
   onCurrentChange(page);
 };
 const deleteRow = (id) => {
+  // 濡傛灉鏄暟缁勶紝妫�鏌ユ槸鍚︽湁 businessId
+  if (Array.isArray(id)) {
+    const hasBusinessId = id.some(itemId => {
+      const row = dataList.value.find(item => item.id === itemId);
+      return row && row.businessId;
+    });
+    if (hasBusinessId) {
+      proxy.$modal.msgWarning("閫変腑鐨勮褰曚腑鍖呭惈宸插叧鑱斾笟鍔$殑璁板綍锛屼笉鑳藉垹闄�");
+      return;
+    }
+  } else {
+    // 鍗曚釜鍒犻櫎锛屾鏌ユ槸鍚︽湁 businessId
+    const row = dataList.value.find(item => item.id === id);
+    if (row && row.businessId) {
+      proxy.$modal.msgWarning("璇ヨ褰曞凡鍏宠仈涓氬姟锛屼笉鑳藉垹闄�");
+      return;
+    }
+  }
+  
   ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
     confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
@@ -223,6 +263,23 @@
       getTableData();
     }
   });
+};
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (multipleList.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  
+  // 妫�鏌ユ槸鍚︽湁 businessId
+  if (hasBusinessIdInSelection.value) {
+    proxy.$modal.msgWarning("閫変腑鐨勮褰曚腑鍖呭惈宸插叧鑱斾笟鍔$殑璁板綍锛屼笉鑳藉垹闄�");
+    return;
+  }
+  
+  const ids = multipleList.value.map((item) => item.id);
+  deleteRow(ids);
 };
 
 const changeDaterange = (value) => {
@@ -252,10 +309,154 @@
     });
 };
 // 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
-  nextTick(() => {
-    filesDia.value?.openDialog( row,'鏀嚭')
-  })
+const openFilesFormDia = async (row) => {
+  currentFileRow.value = row;
+  accountType.value = '鏀嚭';
+  try {
+    const res = await fileListPage({
+      accountId: row.id,
+      accountType: accountType.value,
+      current: 1,
+      size: 100
+    });
+    if (res.code === 200 && fileListRef.value) {
+      // 灏嗘暟鎹浆鎹负 FileListDialog 闇�瑕佺殑鏍煎紡
+      const fileList = (res.data?.records || []).map(item => ({
+        name: item.name,
+        url: item.url,
+        id: item.id,
+        ...item
+      }));
+      fileListRef.value.open(fileList);
+      fileListDialogVisible.value = true;
+    }
+  } catch (error) {
+    proxy.$modal.msgError("鑾峰彇闄勪欢鍒楄〃澶辫触");
+  }
+};
+
+// 涓婁紶闄勪欢
+const handleUpload = async () => {
+  if (!currentFileRow.value) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
+    return null;
+  }
+  
+  return new Promise((resolve) => {
+    // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
+    const input = document.createElement('input');
+    input.type = 'file';
+    input.style.display = 'none';
+    input.onchange = async (e) => {
+      const file = e.target.files[0];
+      if (!file) {
+        resolve(null);
+        return;
+      }
+      
+      try {
+        // 浣跨敤 FormData 涓婁紶鏂囦欢
+        const formData = new FormData();
+        formData.append('file', file);
+        
+        const uploadRes = await request({
+          url: '/file/upload',
+          method: 'post',
+          data: formData,
+          headers: {
+            'Content-Type': 'multipart/form-data',
+            Authorization: `Bearer ${getToken()}`
+          }
+        });
+        
+        if (uploadRes.code === 200) {
+          // 淇濆瓨闄勪欢淇℃伅
+          const fileData = {
+            accountId: currentFileRow.value.id,
+            accountType: accountType.value,
+            name: uploadRes.data.originalName || file.name,
+            url: uploadRes.data.tempPath || uploadRes.data.url
+          };
+          
+          const saveRes = await fileAdd(fileData);
+          if (saveRes.code === 200) {
+            proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+            // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+            const listRes = await fileListPage({
+              accountId: currentFileRow.value.id,
+              accountType: accountType.value,
+              current: 1,
+              size: 100
+            });
+            if (listRes.code === 200 && fileListRef.value) {
+              const fileList = (listRes.data?.records || []).map(item => ({
+                name: item.name,
+                url: item.url,
+                id: item.id,
+                ...item
+              }));
+              fileListRef.value.setList(fileList);
+            }
+            // 杩斿洖鏂版枃浠朵俊鎭�
+            resolve({
+              name: fileData.name,
+              url: fileData.url,
+              id: saveRes.data?.id
+            });
+          } else {
+            proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
+            resolve(null);
+          }
+        } else {
+          proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
+          resolve(null);
+        }
+      } catch (error) {
+        proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+        resolve(null);
+      } finally {
+        document.body.removeChild(input);
+      }
+    };
+    
+    document.body.appendChild(input);
+    input.click();
+  });
+};
+
+// 鍒犻櫎闄勪欢
+const handleFileDelete = async (row) => {
+  try {
+    const res = await fileDel([row.id]);
+    if (res.code === 200) {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+      if (currentFileRow.value && fileListRef.value) {
+        const listRes = await fileListPage({
+          accountId: currentFileRow.value.id,
+          accountType: accountType.value,
+          current: 1,
+          size: 100
+        });
+        if (listRes.code === 200) {
+          const fileList = (listRes.data?.records || []).map(item => ({
+            name: item.name,
+            url: item.url,
+            id: item.id,
+            ...item
+          }));
+          fileListRef.value.setList(fileList);
+        }
+      }
+      return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
+    } else {
+      proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
+      return false;
+    }
+  } catch (error) {
+    proxy.$modal.msgError("鍒犻櫎澶辫触");
+    return false;
+  }
 };
 
 onMounted(() => {
diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
index e5f9b23..88aa5d2 100644
--- a/src/views/financialManagement/financialStatements/index.vue
+++ b/src/views/financialManagement/financialStatements/index.vue
@@ -1,16 +1,16 @@
  <template>
   <div style="padding: 20px;">
-    <!-- 椤甸潰鏍囬鍜屾棩鏈熺瓫閫� -->
+    <!-- 椤甸潰鏍囬鍜屾湀浠界瓫閫� -->
     <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
       <el-date-picker
         v-model="dateRange"
-        type="daterange"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD"
+        type="monthrange"
+        format="YYYY-MM"
+        value-format="YYYY-MM"
         range-separator="鑷�"
-        start-placeholder="寮�濮嬫棩鏈�"
-        end-placeholder="缁撴潫鏃ユ湡"
-        clearable
+        start-placeholder="寮�濮嬫湀浠�"
+        end-placeholder="缁撴潫鏈堜唤"
+        :disabled-date="disabledDate"
         @change="handleDateChange"
         class="w-full md:w-auto"
         style="margin-right: 30px;"
@@ -130,7 +130,7 @@
 </template>
 
 <script setup>
-import { ref, computed, onMounted, reactive } from 'vue';
+import { ref, computed, onMounted, reactive, nextTick, getCurrentInstance } from 'vue';
 import 'element-plus/dist/index.css';
 import Echarts from "@/components/Echarts/echarts.vue";
 import { reportForms,reportIncome,reportExpense } from "@/api/financialManagement/financialStatements";
@@ -138,6 +138,7 @@
 
 // 鏃ユ湡鑼冨洿
 const dateRange = ref(null);
+const { proxy } = getCurrentInstance();
 const chartStyle = {
 	width: '100%',
 	height: '100%', // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
@@ -172,22 +173,35 @@
     return `<div>${axisLabel}</div><div>${rows}</div>`
   }
 })
-const months = ['1鏈�','2鏈�','3鏈�','4鏈�','5鏈�','6鏈�','7鏈�','8鏈�','9鏈�','10鏈�','11鏈�','12鏈�'];
 const lineSeries0 = ref([])
 const lineSeries1 = ref([])
+
+// 鏍规嵁鏈堜唤鑼冨洿鐢熸垚 x 杞存暟鎹�
+const generateMonthLabels = (startMonth, endMonth) => {
+  const labels = [];
+  let current = dayjs(startMonth);
+  const end = dayjs(endMonth);
+  
+  while (current.isBefore(end) || current.isSame(end, 'month')) {
+    labels.push(`${current.month() + 1}鏈坄);
+    current = current.add(1, 'month');
+  }
+  
+  return labels;
+};
 
 const xAxis0 = ref([
   {
     type: 'category',
     axisTick: { show: true, alignWithLabel: true },
-    data: months,
+    data: [],
   },
 ]);
 const xAxis1 = ref([
   {
     type: 'category',
     axisTick: { show: true, alignWithLabel: true },
-    data: months,
+    data: [],
   },
 ]);
 const yAxis0 = [
@@ -232,9 +246,10 @@
   left: '60%',
   orient: 'vertical',
   icon: 'circle',
-  data: pieData0.value.map(item => item.name),
+  data: (pieData0.value || []).filter(item => item && item.name).map(item => item.name),
   formatter: function(name) {
-    const item = pieData0.value.find(i => i.name === name);
+    if (!name) return '';
+    const item = pieData0.value.find(i => i && i.name === name);
     if (!item) return name;
     return `${name} | ${item.percent} ${item.amount}`;
   },
@@ -250,9 +265,10 @@
   left: '60%',
   orient: 'vertical',
   icon: 'circle',
-  data: pieData1.value.map(item => item.name),
+  data: (pieData1.value || []).filter(item => item && item.name).map(item => item.name),
   formatter: function(name) {
-    const item = pieData1.value.find(i => i.name === name);
+    if (!name) return '';
+    const item = pieData1.value.find(i => i && i.name === name);
     if (!item) return name;
     return `${name} | ${item.percent} ${item.amount}`;
   },
@@ -276,7 +292,7 @@
     label: {
       show: false
     },
-    data: pieData0.value,
+    data: (pieData0.value || []).filter(item => item && item.name),
     color: pieColors
   }
 ]);
@@ -293,7 +309,7 @@
     label: {
       show: false
     },
-    data: pieData1.value,
+    data: (pieData1.value || []).filter(item => item && item.name),
     color: pieColors
   }
 ]);
@@ -318,53 +334,81 @@
 const pageInfo = ref({
 })
 
+// 鑾峰彇鏈�杩戝叚涓湀鐨勮寖鍥�
+const getLastSixMonths = () => {
+  const endMonth = dayjs().format('YYYY-MM');
+  const startMonth = dayjs().subtract(5, 'month').format('YYYY-MM');
+  return [startMonth, endMonth];
+};
+
 const getData = async () => {
-  if (!dateRange.value || !dateRange.value.length) {
+  if (!dateRange.value || !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
     return;
   }
+  const startDateStr = dateRange.value[0];
+  const endDateStr = dateRange.value[1];
+  if (!startDateStr || !endDateStr) {
+    return;
+  }
+  
+  // 楠岃瘉鏃ユ湡鏍煎紡骞惰浆鎹负瀹屾暣鏃ユ湡
+  const startDate = dayjs(startDateStr);
+  const endDate = dayjs(endDateStr);
+  if (!startDate.isValid() || !endDate.isValid()) {
+    console.error('鏃犳晥鐨勬棩鏈熸牸寮�');
+    return;
+  }
+  
+  // 鏇存柊 x 杞存暟鎹�
+  const monthLabels = generateMonthLabels(startDateStr, endDateStr);
+  xAxis0.value[0].data = monthLabels;
+  xAxis1.value[0].data = monthLabels;
+  
+  // 寮�濮嬫湀浠芥嫾鎺ョ涓�澶╋紝缁撴潫鏈堜唤鎷兼帴鏈�鍚庝竴澶�
+  const entryDateStart = startDate.startOf('month').format('YYYY-MM-DD');
+  const entryDateEnd = endDate.endOf('month').format('YYYY-MM-DD');
+  
   try {
-    const {code,data} = await reportForms({entryDateStart:dateRange.value[0], entryDateEnd:dateRange.value[1]});
-    if(code === 200) {
-      pageInfo.value = data
-      pieData0.value = data.incomeType.map(item=>({
-        name:item.typeName,
-        value:item.account,
-        percent:`${item.proportion*100}%`,
-        amount:`楼${item.account}`
+    const {code,data} = await reportForms({entryDateStart, entryDateEnd});
+    if(code === 200 && data) {
+      pageInfo.value = data || {};
+      // 瀹夊叏澶勭悊鏁版嵁锛岃繃婊ゆ帀 null 鎴� undefined
+      pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
+        value:item.account || 0,
+        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+        amount:`楼${(item.account || 0).toFixed(2)}`
       }))
-      pieData1.value = data.expenseType.map(item=>({
-        name:item.typeName,
-        value:item.account,
-        percent:`${item.proportion*100}%`,
-        amount:`楼${item.account}`
+      pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
+        value:item.account || 0,
+        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+        amount:`楼${(item.account || 0).toFixed(2)}`
       }))
-
     }
   } catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
   }
   try{
-    const {code,data} = await reportIncome();
-    if(code==200){
-      lineSeries0.value = data.map(item=>({
-        name:item.typeName,
+    const {code,data} = await reportIncome({entryDateStart, entryDateEnd});
+    if(code==200 && data && Array.isArray(data)){
+      lineSeries0.value = data.filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
         type: 'line',
-        data:item.account.map(item=>Number(item))
+        data:(item.account || []).map(val => Number(val) || 0)
       }))
-
     }
   }catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
   }
   try{
-    const {code,data} = await reportExpense();
-    if(code==200){
-      lineSeries1.value = data.map(item=>({
-        name:item.typeName,
+    const {code,data} = await reportExpense({entryDateStart, entryDateEnd});
+    if(code==200 && data && Array.isArray(data)){
+      lineSeries1.value = data.filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
         type: 'line',
-        data:item.account.map(item=>Number(item))
+        data:(item.account || []).map(val => Number(val) || 0)
       }))
-
     }
   }catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
@@ -374,20 +418,66 @@
 
 // 鍒濆鍖�
 onMounted(() => {
-  // 涓嶈缃粯璁ゆ棩鏈燂紝鐢辩敤鎴锋墜鍔ㄩ�夋嫨
+  // 璁剧疆榛樿鍊间负鏈�杩戝叚涓湀
+  const defaultRange = getLastSixMonths();
+  dateRange.value = defaultRange;
+  // 浣跨敤 nextTick 纭繚缁勪欢瀹屽叏娓叉煋鍚庡啀璋冪敤
+  nextTick(() => {
+    getData();
+  });
 });
 
-// 澶勭悊鏃ユ湡鑼冨洿鍙樺寲
-const handleDateChange = (newRange) => {
-  dateRange.value = newRange;
-  if (newRange && newRange.length === 2) {
-    getData()
+// 闄愬埗鏈堜唤閫夋嫨鑼冨洿锛堟渶澶�12涓湀锛�
+const disabledDate = (time) => {
+  // 濡傛灉娌℃湁閫夋嫨寮�濮嬫湀浠斤紝涓嶇鐢ㄤ换浣曟棩鏈�
+  if (!dateRange.value || !Array.isArray(dateRange.value) || !dateRange.value[0]) {
+    return false;
   }
+  
+  const startMonth = dayjs(dateRange.value[0]);
+  const currentMonth = dayjs(time);
+  
+  // 濡傛灉褰撳墠鏈堜唤鍦ㄥ紑濮嬫湀浠戒箣鍓嶏紝绂佺敤
+  if (currentMonth.isBefore(startMonth, 'month')) {
+    return true;
+  }
+  
+  // 璁$畻鏈�澶у厑璁哥殑鏈堜唤锛堝紑濮嬫湀浠� + 11涓湀 = 12涓湀锛�
+  const maxMonth = startMonth.add(11, 'month');
+  
+  // 绂佺敤瓒呰繃12涓湀鐨勬湀浠�
+  return currentMonth.isAfter(maxMonth, 'month');
 };
 
-// 閲嶇疆鏃ユ湡鑼冨洿
+// 澶勭悊鏈堜唤鑼冨洿鍙樺寲
+const handleDateChange = (newRange) => {
+  if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
+    return;
+  }
+  
+  // 楠岃瘉鏈堜唤鑼冨洿涓嶈秴杩�12涓湀
+  const startDate = dayjs(newRange[0]);
+  const endDate = dayjs(newRange[1]);
+  const monthDiff = endDate.diff(startDate, 'month');
+  
+  if (monthDiff > 11) {
+    proxy.$modal.msgWarning('鏈�澶氬彧鑳介�夋嫨12涓湀浠�');
+    // 鑷姩璋冩暣涓�12涓湀
+    const adjustedEnd = startDate.add(11, 'month').format('YYYY-MM');
+    dateRange.value = [newRange[0], adjustedEnd];
+    getData();
+    return;
+  }
+  
+  dateRange.value = newRange;
+  getData();
+};
+
+// 閲嶇疆鏈堜唤鑼冨洿
 const resetDateRange = () => {
-  dateRange.value = null;
+  // 閲嶇疆涓烘渶杩戝叚涓湀
+  dateRange.value = getLastSixMonths();
+  getData();
 };
 
 </script>
diff --git a/src/views/financialManagement/loanManagement/Modal.vue b/src/views/financialManagement/loanManagement/Modal.vue
new file mode 100644
index 0000000..73b2cc3
--- /dev/null
+++ b/src/views/financialManagement/loanManagement/Modal.vue
@@ -0,0 +1,222 @@
+<template>
+  <FormDialog
+    v-model="dialogVisible"
+    :title="dialogTitle"
+    :operationType="operationType"
+    width="60%"
+    @confirm="sendForm"
+    @close="close"
+    @cancel="close"
+  >
+    <el-form
+      ref="formRef"
+      :model="form"
+      :rules="formRules"
+      label-width="120px"
+    >
+      <el-form-item label="鍊熸浜哄鍚�" prop="borrowerName">
+        <el-input v-model="form.borrowerName" placeholder="璇疯緭鍏ュ�熸浜哄鍚�" />
+      </el-form-item>
+      <el-form-item label="鍊熸閲戦锛堝厓锛�" prop="borrowAmount">
+        <el-input-number
+          :step="0.01"
+          :min="0"
+          :precision="2"
+          style="width: 100%"
+          v-model="form.borrowAmount"
+          placeholder="璇疯緭鍏ュ�熸閲戦"
+        />
+      </el-form-item>
+      <el-form-item label="鍊熸鍒╃巼锛�%锛�" prop="interestRate">
+        <el-input-number
+          :step="0.01"
+          :min="0"
+          :precision="2"
+          style="width: 100%"
+          v-model="form.interestRate"
+          placeholder="璇疯緭鍏ュ�熸鍒╃巼锛屽锛�5.85"
+        />
+      </el-form-item>
+      <el-form-item label="鍊熸鏃ユ湡" prop="borrowDate">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.borrowDate"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+          type="date"
+          placeholder="璇烽�夋嫨鍊熸鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+      <!-- 瀹為檯杩樻鏃ユ湡锛氫粎鈥滆繕娆锯�濇椂鍙~ -->
+      <el-form-item
+        v-if="operationType === 'repay'"
+        label="瀹為檯杩樻鏃ユ湡"
+        prop="repayDate"
+      >
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.repayDate"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+          type="date"
+          placeholder="璇烽�夋嫨瀹為檯杩樻鏃ユ湡锛堣繕娆惧悗濉啓锛�"
+          clearable
+        />
+      </el-form-item>
+      <el-form-item label="澶囨敞" prop="remark">
+        <el-input
+          v-model="form.remark"
+          type="textarea"
+          :rows="3"
+          placeholder="璇疯緭鍏ュ娉紙鍊熸璇存槑锛�"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import { add, update } from "@/api/financialManagement/loanManagement";
+import useFormData from "@/hooks/useFormData";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { ElMessage } from "element-plus";
+import { ref } from "vue";
+
+defineOptions({
+  name: "鍊熸鏂板缂栬緫",
+});
+
+const emits = defineEmits(["success"]);
+
+const formRef = ref(null);
+const dialogVisible = ref(false);
+const operationType = ref("add"); // add | edit
+const id = ref(undefined);
+const submitting = ref(false);
+
+const dialogTitle = (type) => {
+  if (type === "edit") return "缂栬緫鍊熸";
+  if (type === "repay") return "杩樻";
+  return "鏂板鍊熸";
+};
+
+const formRules = {
+  borrowerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏ュ�熸浜哄鍚�" }],
+  borrowAmount: [{ required: true, trigger: "blur", message: "璇疯緭鍏ュ�熸閲戦" }],
+  interestRate: [{ required: true, trigger: "blur", message: "璇疯緭鍏ュ�熸鍒╃巼" }],
+  borrowDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨鍊熸鏃ユ湡" }],
+  repayDate: [
+    {
+      validator: (_rule, value, callback) => {
+        if (operationType.value === "repay" && !value) {
+          callback(new Error("璇烽�夋嫨瀹為檯杩樻鏃ユ湡"));
+          return;
+        }
+        callback();
+      },
+      trigger: "change",
+    },
+  ],
+};
+
+const { form, resetForm } = useFormData({
+  borrowerName: undefined, // 鍊熸浜哄鍚�
+  borrowAmount: undefined, // 鍊熸閲戦锛堝厓锛�
+  interestRate: undefined, // 鍊熸鍒╃巼锛堝锛�5.85 浠h〃5.85%锛�
+  borrowDate: undefined, // 鍊熸鏃ユ湡
+  repayDate: undefined, // 瀹為檯杩樻鏃ユ湡锛堣繕娆惧悗濉厖锛�
+  remark: undefined, // 澶囨敞锛堝�熸璇存槑锛�
+});
+
+const sendForm = () => {
+  if (submitting.value) return;
+  formRef.value?.validate(async (valid) => {
+    if (valid) {
+      submitting.value = true;
+      try {
+        const isRepay = operationType.value === "repay";
+        // 杩樻锛氫笉灞曠ず status锛屼絾鎻愪氦鏃跺己鍒朵紶 status=2锛岃蛋鏇存柊鎺ュ彛
+        const payload = isRepay
+          ? { id: id.value, ...form, status: 2 }
+          : id.value
+            ? { id: id.value, ...form }
+            : form;
+
+        const { code } = isRepay
+          ? await update(payload)
+          : id.value
+            ? await update(payload)
+            : await add(payload);
+        if (code == 200) {
+          emits("success");
+          ElMessage({ message: "鎿嶄綔鎴愬姛", type: "success" });
+          close();
+        }
+      } finally {
+        submitting.value = false;
+      }
+    }
+  });
+};
+
+const close = () => {
+  resetForm();
+  formRef.value?.clearValidate();
+  id.value = undefined;
+  dialogVisible.value = false;
+};
+
+// 缂栬緫锛氱洿鎺ョ敤鍒楄〃琛屾暟鎹洖濉紙閬垮厤渚濊禆璇︽儏鎺ュ彛锛�
+const loadForm = async (row) => {
+  const rowId = row?.id;
+  operationType.value = "edit";
+  id.value = rowId;
+  dialogVisible.value = true;
+  if (rowId) {
+    form.borrowerName = row.borrowerName;
+    form.borrowAmount = row.borrowAmount;
+    form.interestRate = row.interestRate;
+    form.borrowDate = row.borrowDate;
+    form.repayDate = row.repayDate;
+    form.remark = row.remark;
+  } else {
+    resetForm();
+    formRef.value?.clearValidate();
+  }
+};
+
+// 杩樻锛氭墦寮�寮圭獥锛屼粎濉啓瀹為檯杩樻鏃ユ湡锛屾彁浜ゆ椂寮哄埗 status=2
+const repay = async (row) => {
+  const rowId = row?.id;
+  operationType.value = "repay";
+  id.value = rowId;
+  dialogVisible.value = true;
+  if (rowId) {
+    // 涓轰簡璧� update 鎺ュ彛鏇寸ǔ濡ワ紝甯︿笂鍘熸湁鏁版嵁锛涘彧璁╃敤鎴烽�� repayDate
+    form.borrowerName = row.borrowerName;
+    form.borrowAmount = row.borrowAmount;
+    form.interestRate = row.interestRate;
+    form.borrowDate = row.borrowDate;
+    form.remark = row.remark;
+    form.repayDate = undefined;
+  } else {
+    resetForm();
+    formRef.value?.clearValidate();
+  }
+};
+
+const openModal = () => {
+  operationType.value = "add";
+  id.value = undefined;
+  resetForm();
+  formRef.value?.clearValidate();
+  dialogVisible.value = true;
+};
+
+defineExpose({
+  openModal,
+  loadForm,
+  repay,
+});
+</script>
diff --git a/src/views/financialManagement/loanManagement/index.vue b/src/views/financialManagement/loanManagement/index.vue
new file mode 100644
index 0000000..7580d3b
--- /dev/null
+++ b/src/views/financialManagement/loanManagement/index.vue
@@ -0,0 +1,271 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍊熸浜哄鍚�:">
+        <el-input
+          v-model="filters.borrowerName"
+          placeholder="璇疯緭鍏ュ�熸浜哄鍚�"
+          clearable
+          style="width: 200px;"
+        />
+      </el-form-item>
+      <el-form-item label="鍊熸鏃ユ湡:">
+        <el-date-picker
+          v-model="filters.borrowDate"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          type="daterange"
+          range-separator="鑷�"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          clearable
+          @change="changeDaterange"
+        />
+      </el-form-item>
+      <el-form-item label="鍊熸鐘舵��:">
+        <el-select
+          v-model="filters.status"
+          placeholder="璇烽�夋嫨"
+          clearable
+          style="width: 200px;"
+        >
+          <el-option label="寰呰繕娆�" :value="1" />
+          <el-option label="宸茶繕娆�" :value="2" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+    <div class="table_list">
+      <div class="actions">
+        <div></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+          <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
+          <el-button
+            type="danger"
+            icon="Delete"
+            :disabled="multipleList.length <= 0"
+            @click="deleteRow(multipleList.map((item) => item.id))"
+          >
+            鎵归噺鍒犻櫎
+          </el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        isSelection
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @selection-change="handleSelectionChange"
+        @pagination="changePage"
+      >
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="edit(row)">
+            缂栬緫
+          </el-button>
+          <el-button
+            :disabled="row.status !== 1"
+            type="primary"
+            link
+            @click="repay(row)"
+          >
+            杩樻
+          </el-button>
+        </template>
+      </PIMTable>
+    </div>
+    <Modal ref="modalRef" @success="getTableData"></Modal>
+  </div>
+</template>
+
+<script setup>
+import { usePaginationApi } from "@/hooks/usePaginationApi";
+import { listPage, delAccountLoan } from "@/api/financialManagement/loanManagement";
+import { onMounted, getCurrentInstance, ref, nextTick } from "vue";
+import Modal from "./Modal.vue";
+import { ElMessageBox, ElMessage } from "element-plus";
+import dayjs from "dayjs";
+
+defineOptions({
+  name: "鍊熸绠$悊",
+});
+
+// 琛ㄦ牸澶氶�夋閫変腑椤�
+const multipleList = ref([]);
+const { proxy } = getCurrentInstance();
+const modalRef = ref();
+
+const {
+  filters,
+  columns,
+  dataList,
+  pagination,
+  getTableData,
+  resetFilters,
+  onCurrentChange,
+} = usePaginationApi(
+  listPage,
+  {
+    borrowerName: undefined,
+    borrowDate: undefined,
+    status: undefined,
+  },
+  [
+    {
+      label: "鍊熸浜哄鍚�",
+      prop: "borrowerName",
+    },
+    {
+      label: "鍊熸閲戦锛堝厓锛�",
+      prop: "borrowAmount",
+      formatData: (val) => {
+        return val ? `楼${parseFloat(val).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : '楼0.00';
+      },
+    },
+    {
+      label: "鍊熸鍒╃巼锛�%锛�",
+      prop: "interestRate",
+      formatData: (val) => {
+        return val ? `${parseFloat(val).toFixed(2)}%` : '-';
+      },
+    },
+    {
+      label: "鍊熸鏃ユ湡",
+      prop: "borrowDate",
+    },
+    {
+      label: "瀹為檯杩樻鏃ユ湡",
+      prop: "repayDate",
+    },
+    {
+      label: "鍊熸鐘舵��",
+      prop: "status",
+      dataType: "tag",
+			align: 'center',
+      formatData: (params) => {
+        if (params == 1) {
+          return "寰呰繕娆�";
+        } else if (params == 2) {
+          return "宸茶繕娆�";
+        }
+        return null;
+      },
+      formatType: (params) => {
+        if (params == 1) {
+          return "error";
+        } else if (params == 2) {
+          return "success";
+        }
+        return null;
+      },
+    },
+    {
+      fixed: "right",
+      label: "鎿嶄綔",
+      dataType: "slot",
+      slot: "operation",
+      align: "center",
+      width: "120px",
+    },
+  ],
+  null,
+  {
+    // 灏嗗墠绔�熸鏃ユ湡鑼冨洿杞崲涓哄悗绔渶瑕佺殑 entryDateStart / entryDateEnd锛屽苟涓斾笉浼� borrowDate
+    borrowDate: (val) => {
+      if (val && val.length === 2) {
+        return {
+          entryDateStart: dayjs(val[0]).format("YYYY-MM-DD"),
+          entryDateEnd: dayjs(val[1]).format("YYYY-MM-DD"),
+        };
+      }
+      return {};
+    },
+  }
+);
+
+// 澶氶�夊悗鍋氫粈涔�
+const handleSelectionChange = (selectionList) => {
+  multipleList.value = selectionList;
+};
+
+const add = () => {
+  modalRef.value.openModal();
+};
+
+const edit = (row) => {
+  modalRef.value.loadForm(row);
+};
+
+const repay = (row) => {
+  modalRef.value.repay(row);
+};
+
+const changePage = ({ page, limit }) => {
+  pagination.currentPage = page;
+  pagination.pageSize = limit;
+  onCurrentChange(page);
+};
+
+const deleteRow = (id) => {
+  ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const { code } = await delAccountLoan(id);
+    if (code == 200) {
+      ElMessage({
+        type: "success",
+        message: "鍒犻櫎鎴愬姛",
+      });
+      getTableData();
+    }
+  });
+};
+
+const changeDaterange = (value) => {
+  if (value) {
+    filters.borrowDate = value;
+  } else {
+    filters.borrowDate = null;
+  }
+  getTableData();
+};
+
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      proxy.download(`/borrowInfo/export`, {}, "鍊熸鍙拌处.xlsx");
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+  margin-top: unset;
+}
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/financialManagement/revenueManagement/Form.vue b/src/views/financialManagement/revenueManagement/Form.vue
deleted file mode 100644
index 67b175e..0000000
--- a/src/views/financialManagement/revenueManagement/Form.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
-    <el-form-item label="鏀跺叆鏃ユ湡" prop="incomeDate">
-          <el-date-picker
-            style="width: 100%"
-            v-model="form.incomeDate"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            type="date"
-            placeholder="璇烽�夋嫨鏃ユ湡"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item label="鏀跺叆绫诲瀷" prop="incomeType">
-          <el-select
-            v-model="form.incomeType"
-            placeholder="璇烽�夋嫨"
-            clearable
-          >
-            <el-option :label="item.label" :value="item.value" v-for="(item,index) in income_types" :key="index" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="瀹㈡埛鍚嶇О" prop="customerName">
-          <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="鏀跺叆閲戦" prop="incomeMoney">
-          <el-input-number :step="0.01" :min="0" style="width: 100%"
-            v-model="form.incomeMoney"
-            placeholder="璇疯緭鍏�"
-          />
-        </el-form-item>
-        <el-form-item label="鏀跺叆鎻忚堪" prop="incomeDescribed">
-          <el-input v-model="form.incomeDescribed" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="鏀舵鏂瑰紡" prop="incomeMethod">
-          <el-select
-            v-model="form.incomeMethod"
-            placeholder="璇烽�夋嫨"
-            clearable
-          >
-            <el-option :label="item.label" :value="item.value" v-for="(item,index) in payment_methods" :key="index" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
-          <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="note">
-          <el-input
-            v-model="form.note"
-            placeholder="澶囨敞"
-          />
-        </el-form-item>
-        
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getAccountIncome } from "@/api/financialManagement/revenueManagement";
-import {ref} from "vue";
-const { proxy } = getCurrentInstance();
-
-
-defineOptions({
-  name: "鏂板鏀跺叆",
-});
-const { income_types } = proxy.useDict("income_types");
-const { payment_methods } = proxy.useDict("payment_methods");
-const formRef = ref(null);
-const formRules = {
-	customerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	incomeMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	incomeDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	incomeDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-  incomeType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-  incomeMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
-  incomeDate: undefined, // 鏀跺叆鏃ユ湡
-  incomeType: undefined, // 鏀跺叆绫诲瀷
-  customerName: undefined, // 瀹㈡埛鍚嶇О
-  incomeMoney: undefined, // 鏀跺叆閲戦
-  incomeDescribed: undefined, // 鏀跺叆鎻忚堪
-  incomeMethod: undefined, // 鏀舵鏂瑰紡
-  invoiceNumber: undefined, // 鍙戠エ鍙风爜
-  note: undefined, // 澶囨敞
-});
-
-const loadForm = async (id) => {
-  const { code, data } = await getAccountIncome(id);
-  if (code == 200) {
-    form.incomeDate = data.incomeDate;
-    form.incomeType = data.incomeType;
-    form.customerName = data.customerName;
-    form.incomeMoney = data.incomeMoney;
-    form.incomeDescribed = data.incomeDescribed;
-    form.incomeMethod = data.incomeMethod;
-    form.invoiceNumber = data.invoiceNumber;
-    form.note = data.note;
-  }
-};
-
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
-  formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
-  resetForm();
-  clearValidate();
-};
-
-defineExpose({
-  form,
-  loadForm,
-  resetForm,
-  clearValidate,
-  resetFormAndValidate,
-	formRef,
-});
-</script>
diff --git a/src/views/financialManagement/revenueManagement/Modal.vue b/src/views/financialManagement/revenueManagement/Modal.vue
index 480b4fd..245cdf2 100644
--- a/src/views/financialManagement/revenueManagement/Modal.vue
+++ b/src/views/financialManagement/revenueManagement/Modal.vue
@@ -1,20 +1,75 @@
 <template>
-  <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
-    <Form ref="formRef"></Form>
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="dialogVisible"
+    :title="dialogTitle"
+    :operationType="operationType"
+    width="30%"
+    @confirm="sendForm"
+    @close="close"
+    @cancel="close"
+  >
+    <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+      <el-form-item label="鏀跺叆鏃ユ湡" prop="incomeDate">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.incomeDate"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+          type="date"
+          placeholder="璇烽�夋嫨鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+      <el-form-item label="鏀跺叆绫诲瀷" prop="incomeType">
+        <el-select
+          v-model="form.incomeType"
+          placeholder="璇烽�夋嫨"
+          clearable
+        >
+          <el-option :label="item.label" :value="item.value" v-for="(item,index) in income_types" :key="index" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瀹㈡埛鍚嶇О" prop="customerName">
+        <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="鏀跺叆閲戦" prop="incomeMoney">
+        <el-input-number :step="0.01" :min="0" style="width: 100%"
+          v-model="form.incomeMoney"
+          placeholder="璇疯緭鍏�"
+        />
+      </el-form-item>
+      <el-form-item label="鏀跺叆鎻忚堪" prop="incomeDescribed">
+        <el-input v-model="form.incomeDescribed" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="鏀舵鏂瑰紡" prop="incomeMethod">
+        <el-select
+          v-model="form.incomeMethod"
+          placeholder="璇烽�夋嫨"
+          clearable
+        >
+          <el-option :label="item.label" :value="item.value" v-for="(item,index) in payment_methods" :key="index" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
+        <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
+      </el-form-item>
+      <el-form-item label="澶囨敞" prop="note">
+        <el-input
+          v-model="form.note"
+          placeholder="澶囨敞"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import { add, update } from "@/api/financialManagement/revenueManagement";
-import Form from "./Form.vue";
+import { add, update, getAccountIncome } from "@/api/financialManagement/revenueManagement";
 import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { ref } from "vue";
+
 const { proxy } = getCurrentInstance()
 
 defineOptions({
@@ -23,43 +78,96 @@
 
 const emits = defineEmits(["success"]);
 
-const formRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "鏀跺叆" });
+const formRef = ref(null);
+const dialogVisible = ref(false);
+const operationType = ref("add"); // add | edit
+const id = ref(undefined);
+const submitting = ref(false);
+
+const dialogTitle = (type) => {
+  if (type === "edit") return "缂栬緫鏀跺叆";
+  return "鏂板鏀跺叆";
+};
+
+const { income_types } = proxy.useDict("income_types");
+const { payment_methods } = proxy.useDict("payment_methods");
+
+const formRules = {
+  customerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  incomeType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  incomeMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+}
+
+const { form, resetForm } = useFormData({
+  incomeDate: undefined, // 鏀跺叆鏃ユ湡
+  incomeType: undefined, // 鏀跺叆绫诲瀷
+  customerName: undefined, // 瀹㈡埛鍚嶇О
+  incomeMoney: undefined, // 鏀跺叆閲戦
+  incomeDescribed: undefined, // 鏀跺叆鎻忚堪
+  incomeMethod: undefined, // 鏀舵鏂瑰紡
+  invoiceNumber: undefined, // 鍙戠エ鍙风爜
+  note: undefined, // 澶囨敞
+});
 
 const sendForm = () => {
-	proxy.$refs.formRef.$refs.formRef.validate(async valid => {
-		if (valid) {
-			const {code} = id.value
-				? await update({id: id.value, ...formRef.value.form})
-				: await add(formRef.value.form);
-			if (code == 200) {
-				emits("success");
-				ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
-				close();
-			} else {
-				loading.value = false;
-			}
-		}
-	})
+  if (submitting.value) return;
+  formRef.value?.validate(async (valid) => {
+    if (valid) {
+      submitting.value = true;
+      try {
+        const { code } = id.value
+          ? await update({ id: id.value, ...form })
+          : await add(form);
+        if (code == 200) {
+          emits("success");
+          ElMessage({ message: "鎿嶄綔鎴愬姛", type: "success" });
+          close();
+        }
+      } finally {
+        submitting.value = false;
+      }
+    }
+  })
 };
 
 const close = () => {
-	formRef.value.resetFormAndValidate();
-  closeModal();
+  resetForm();
+  formRef.value?.clearValidate();
+  id.value = undefined;
+  dialogVisible.value = false;
 };
 
-const loadForm = async (id) => {
-  openModal(id);
-  await nextTick();
-  formRef.value.loadForm(id);
+const loadForm = async (rowId) => {
+  operationType.value = "edit";
+  id.value = rowId;
+  dialogVisible.value = true;
+  if (rowId) {
+    const { code, data } = await getAccountIncome(rowId);
+    if (code == 200) {
+      form.incomeDate = data.incomeDate;
+      form.incomeType = data.incomeType;
+      form.customerName = data.customerName;
+      form.incomeMoney = data.incomeMoney;
+      form.incomeDescribed = data.incomeDescribed;
+      form.incomeMethod = data.incomeMethod;
+      form.invoiceNumber = data.invoiceNumber;
+      form.note = data.note;
+    }
+  } else {
+    resetForm();
+    formRef.value?.clearValidate();
+  }
+};
+
+const openModal = () => {
+  operationType.value = "add";
+  id.value = undefined;
+  resetForm();
+  formRef.value?.clearValidate();
+  dialogVisible.value = true;
 };
 
 defineExpose({
diff --git a/src/views/financialManagement/revenueManagement/filesDia.vue b/src/views/financialManagement/revenueManagement/filesDia.vue
deleted file mode 100644
index f752496..0000000
--- a/src/views/financialManagement/revenueManagement/filesDia.vue
+++ /dev/null
@@ -1,202 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        title="涓婁紶闄勪欢"
-        width="50%"
-        @close="closeDia"
-    >
-      <div style="margin-bottom: 10px;text-align: right">
-        <el-upload
-            v-model:file-list="fileList"
-            class="upload-demo"
-            :action="uploadUrl"
-            :on-success="handleUploadSuccess"
-            :on-error="handleUploadError"
-            name="file"
-            :show-file-list="false"
-            :headers="headers"
-            style="display: inline;margin-right: 10px"
-        >
-          <el-button type="primary">涓婁紶闄勪欢</el-button>
-        </el-upload>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-      <PIMTable
-          rowKey="id"
-          :column="tableColumn"
-          :tableData="tableData"
-          :tableLoading="tableLoading"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          height="500"
-      >
-      </PIMTable>
-			<pagination
-				style="margin: 10px 0"
-				v-show="total > 0"
-				@pagination="paginationSearch"
-				:total="total"
-				:page="page.current"
-				:limit="page.size"
-			/>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-    <filePreview ref="filePreviewRef" />
-  </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
-  fileAdd,
-  fileDel,
-  fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
-  {
-    label: "鏂囦欢鍚嶇О",
-    prop: "name",
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    operation: [
-      {
-        name: "涓嬭浇",
-        type: "text",
-        clickFun: (row) => {
-          downLoadFile(row);
-        },
-      },
-      {
-        name: "棰勮",
-        type: "text",
-        clickFun: (row) => {
-          lookFile(row);
-        },
-      }
-    ],
-  },
-]);
-const page = reactive({
-	current: 1,
-	size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
-  Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
-  accountType.value = type;
-  dialogFormVisible.value = true;
-  currentId.value = row.id;
-  getList()
-}
-const paginationSearch = (obj) => {
-	page.current = obj.page;
-	page.size = obj.limit;
-	getList();
-};
-const getList = () => {
-  fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
-    tableData.value = res.data.records;
-		total.value = res.data.total;
-  })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  dialogFormVisible.value = false;
-  emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
-  // 濡傛灉涓婁紶鎴愬姛
-  if (res.code == 200) {
-    const fileRow = {}
-    fileRow.name = res.data.originalName
-    fileRow.url = res.data.tempPath
-    uploadFile(fileRow)
-  } else {
-    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-  }
-}
-function uploadFile(file) {
-  file.accountId = currentId.value;
-  file.accountType = accountType.value;
-  fileAdd(file).then(res => {
-    proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
-    getList()
-  })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
-  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
-  proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  }).then(() => {
-    fileDel(ids).then((res) => {
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      getList();
-    });
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�");
-  });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
-  filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/financialManagement/revenueManagement/index.vue b/src/views/financialManagement/revenueManagement/index.vue
index 9dcd23e..a8a59c8 100644
--- a/src/views/financialManagement/revenueManagement/index.vue
+++ b/src/views/financialManagement/revenueManagement/index.vue
@@ -34,8 +34,8 @@
           <el-button
             type="danger"
             icon="Delete"
-            :disabled="multipleList.length <= 0"
-            @click="deleteRow(multipleList.map((item) => item.id))"
+            :disabled="multipleList.length <= 0 || hasBusinessIdInSelection"
+            @click="handleBatchDelete"
           >
             鎵归噺鍒犻櫎
           </el-button>
@@ -55,12 +55,17 @@
         @pagination="changePage"
       >
         <template #operation="{ row }">
-          <el-button type="primary" text @click="edit(row.id)" icon="editPen">
+          <el-button 
+            type="primary" 
+            link 
+            :disabled="!!row.businessId"
+            @click="edit(row.id)"
+          >
             缂栬緫
           </el-button>
           <el-button
             type="primary"
-            text
+						link
             @click="openFilesFormDia(row)"
           >
             闄勪欢
@@ -69,18 +74,27 @@
       </PIMTable>
     </div>
     <Modal ref="modalRef" @success="getTableData"></Modal>
-    <files-dia ref="filesDia"></files-dia>
+    <FileListDialog 
+      ref="fileListRef" 
+      v-model="fileListDialogVisible"
+      :show-upload-button="true"
+      :show-delete-button="true"
+      :upload-method="handleUpload"
+      :delete-method="handleFileDelete"
+    />
   </div>
 </template>
 
 <script setup>
 import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountIncome } from "@/api/financialManagement/revenueManagement";
-import { onMounted, getCurrentInstance } from "vue";
+import { listPage, delAccountIncome, fileListPage, fileAdd, fileDel } from "@/api/financialManagement/revenueManagement";
+import { onMounted, getCurrentInstance, ref, computed } from "vue";
 import Modal from "./Modal.vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import dayjs from "dayjs";
-import FilesDia from "./filesDia.vue";
+import FileListDialog from "@/components/Dialog/FileListDialog.vue";
+import request from "@/utils/request";
+import { getToken } from "@/utils/auth";
 
 defineOptions({
   name: "鏀跺叆绠$悊",
@@ -92,7 +106,10 @@
 const modalRef = ref();
 const { payment_methods } = proxy.useDict("payment_methods");
 const { income_types } = proxy.useDict("income_types");
-const filesDia = ref()
+const fileListRef = ref(null);
+const fileListDialogVisible = ref(false);
+const currentFileRow = ref(null);
+const accountType = ref('鏀跺叆');
 
 const {
   filters,
@@ -111,12 +128,10 @@
   [
     {
       label: "鏀跺叆鏃ユ湡",
-      align: "center",
       prop: "incomeDate",
     },
     {
       label: "鏀跺叆绫诲瀷",
-      align: "center",
       prop: "incomeType",
       dataType: "tag",
       formatData: (params) => {
@@ -129,26 +144,25 @@
     },
     {
       label: "瀹㈡埛鍚嶇О",
-      align: "center",
       prop: "customerName",
+			width: '200'
 
     },
     {
       label: "鏀跺叆閲戦",
-      align: "center",
       prop: "incomeMoney",
 
     },
     {
       label: "鏀跺叆鎻忚堪",
-      align: "center",
       prop: "incomeDescribed",
 
     },
     {
       label: "鏀舵鏂瑰紡",
-      align: "center",
       prop: "incomeMethod",
+			align: 'center',
+			width: '100',
       dataType: "tag",
       formatData: (params) => {
         if (payment_methods.value.find((m) => m.value == params)) {
@@ -160,24 +174,20 @@
     },
     {
       label: "鍙戠エ鍙风爜",
-      align: "center",
       prop: "invoiceNumber",
 
     },
     {
       label: "澶囨敞",
-      align: "center",
       prop: "note",
 
     },
     {
       label: "褰曞叆浜�",
-      align: "center",
       prop: "inputUser",
     },
     {
       label: "褰曞叆鏃ユ湡",
-      align: "center",
       prop: "inputTime",
 
     },
@@ -187,7 +197,7 @@
       dataType: "slot",
       slot: "operation",
       align: "center",
-      width: "200px",
+      width: "160px",
     },
   ]
 );
@@ -197,10 +207,21 @@
   multipleList.value = selectionList;
 };
 
+// 鍒ゆ柇閫変腑鐨勯」涓槸鍚︽湁 businessId
+const hasBusinessIdInSelection = computed(() => {
+  return multipleList.value.some(item => item.businessId);
+});
+
 const add = () => {
   modalRef.value.openModal();
 };
 const edit = (id) => {
+  // 妫�鏌ュ綋鍓嶈鏄惁鏈� businessId
+  const row = dataList.value.find(item => item.id === id);
+  if (row && row.businessId) {
+    proxy.$modal.msgWarning("璇ヨ褰曞凡鍏宠仈涓氬姟锛屼笉鑳界紪杈�");
+    return;
+  }
   modalRef.value.loadForm(id);
 };
 const changePage = ({ page, limit }) => {
@@ -209,6 +230,25 @@
   onCurrentChange(page);
 };
 const deleteRow = (id) => {
+  // 濡傛灉鏄暟缁勶紝妫�鏌ユ槸鍚︽湁 businessId
+  if (Array.isArray(id)) {
+    const hasBusinessId = id.some(itemId => {
+      const row = dataList.value.find(item => item.id === itemId);
+      return row && row.businessId;
+    });
+    if (hasBusinessId) {
+      proxy.$modal.msgWarning("閫変腑鐨勮褰曚腑鍖呭惈宸插叧鑱斾笟鍔$殑璁板綍锛屼笉鑳藉垹闄�");
+      return;
+    }
+  } else {
+    // 鍗曚釜鍒犻櫎锛屾鏌ユ槸鍚︽湁 businessId
+    const row = dataList.value.find(item => item.id === id);
+    if (row && row.businessId) {
+      proxy.$modal.msgWarning("璇ヨ褰曞凡鍏宠仈涓氬姟锛屼笉鑳藉垹闄�");
+      return;
+    }
+  }
+  
   ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
     confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
@@ -223,6 +263,23 @@
       getTableData();
     }
   });
+};
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (multipleList.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  
+  // 妫�鏌ユ槸鍚︽湁 businessId
+  if (hasBusinessIdInSelection.value) {
+    proxy.$modal.msgWarning("閫変腑鐨勮褰曚腑鍖呭惈宸插叧鑱斾笟鍔$殑璁板綍锛屼笉鑳藉垹闄�");
+    return;
+  }
+  
+  const ids = multipleList.value.map((item) => item.id);
+  deleteRow(ids);
 };
 
 const changeDaterange = (value) => {
@@ -252,10 +309,154 @@
     });
 };
 // 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
-  nextTick(() => {
-    filesDia.value?.openDialog( row,'鏀跺叆')
-  })
+const openFilesFormDia = async (row) => {
+  currentFileRow.value = row;
+  accountType.value = '鏀跺叆';
+  try {
+    const res = await fileListPage({
+      accountId: row.id,
+      accountType: accountType.value,
+      current: 1,
+      size: 100
+    });
+    if (res.code === 200 && fileListRef.value) {
+      // 灏嗘暟鎹浆鎹负 FileListDialog 闇�瑕佺殑鏍煎紡
+      const fileList = (res.data?.records || []).map(item => ({
+        name: item.name,
+        url: item.url,
+        id: item.id,
+        ...item
+      }));
+      fileListRef.value.open(fileList);
+      fileListDialogVisible.value = true;
+    }
+  } catch (error) {
+    proxy.$modal.msgError("鑾峰彇闄勪欢鍒楄〃澶辫触");
+  }
+};
+
+// 涓婁紶闄勪欢
+const handleUpload = async () => {
+  if (!currentFileRow.value) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
+    return null;
+  }
+  
+  return new Promise((resolve) => {
+    // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
+    const input = document.createElement('input');
+    input.type = 'file';
+    input.style.display = 'none';
+    input.onchange = async (e) => {
+      const file = e.target.files[0];
+      if (!file) {
+        resolve(null);
+        return;
+      }
+      
+      try {
+        // 浣跨敤 FormData 涓婁紶鏂囦欢
+        const formData = new FormData();
+        formData.append('file', file);
+        
+        const uploadRes = await request({
+          url: '/file/upload',
+          method: 'post',
+          data: formData,
+          headers: {
+            'Content-Type': 'multipart/form-data',
+            Authorization: `Bearer ${getToken()}`
+          }
+        });
+        
+        if (uploadRes.code === 200) {
+          // 淇濆瓨闄勪欢淇℃伅
+          const fileData = {
+            accountId: currentFileRow.value.id,
+            accountType: accountType.value,
+            name: uploadRes.data.originalName || file.name,
+            url: uploadRes.data.tempPath || uploadRes.data.url
+          };
+          
+          const saveRes = await fileAdd(fileData);
+          if (saveRes.code === 200) {
+            proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+            // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+            const listRes = await fileListPage({
+              accountId: currentFileRow.value.id,
+              accountType: accountType.value,
+              current: 1,
+              size: 100
+            });
+            if (listRes.code === 200 && fileListRef.value) {
+              const fileList = (listRes.data?.records || []).map(item => ({
+                name: item.name,
+                url: item.url,
+                id: item.id,
+                ...item
+              }));
+              fileListRef.value.setList(fileList);
+            }
+            // 杩斿洖鏂版枃浠朵俊鎭�
+            resolve({
+              name: fileData.name,
+              url: fileData.url,
+              id: saveRes.data?.id
+            });
+          } else {
+            proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
+            resolve(null);
+          }
+        } else {
+          proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
+          resolve(null);
+        }
+      } catch (error) {
+        proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+        resolve(null);
+      } finally {
+        document.body.removeChild(input);
+      }
+    };
+    
+    document.body.appendChild(input);
+    input.click();
+  });
+};
+
+// 鍒犻櫎闄勪欢
+const handleFileDelete = async (row) => {
+  try {
+    const res = await fileDel([row.id]);
+    if (res.code === 200) {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
+      if (currentFileRow.value && fileListRef.value) {
+        const listRes = await fileListPage({
+          accountId: currentFileRow.value.id,
+          accountType: accountType.value,
+          current: 1,
+          size: 100
+        });
+        if (listRes.code === 200) {
+          const fileList = (listRes.data?.records || []).map(item => ({
+            name: item.name,
+            url: item.url,
+            id: item.id,
+            ...item
+          }));
+          fileListRef.value.setList(fileList);
+        }
+      }
+      return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
+    } else {
+      proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
+      return false;
+    }
+  } catch (error) {
+    proxy.$modal.msgError("鍒犻櫎澶辫触");
+    return false;
+  }
 };
 
 onMounted(() => {
diff --git a/src/views/inventoryManagement/dispatchLog/index.vue b/src/views/inventoryManagement/dispatchLog/index.vue
index b485aa7..6c660a8 100644
--- a/src/views/inventoryManagement/dispatchLog/index.vue
+++ b/src/views/inventoryManagement/dispatchLog/index.vue
@@ -2,15 +2,6 @@
 	<div class="app-container">
 		<div class="search_form">
 			<div>
-				<span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
-				<el-input
-					v-model="searchForm.supplierName"
-					style="width: 240px"
-					placeholder="璇疯緭鍏�"
-					@change="handleQuery"
-					clearable
-					prefix-icon="Search"
-				/>
 				<span class="search_title ml10">鍑哄簱鏃ユ湡锛�</span>
 				<el-date-picker
 					v-model="searchForm.timeStr"
@@ -26,7 +17,6 @@
 				>
 			</div>
 			<div>
-				<!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button> -->
 				<el-button @click="handleOut">瀵煎嚭</el-button>
 				<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
 				<el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
@@ -40,95 +30,47 @@
 				@selection-change="handleSelectionChange"
 				:expand-row-keys="expandedRowKeys"
 				:row-key="(row) => row.id"
-				show-summary
 				style="width: 100%"
-				:summary-method="summarizeMainTable"
 				height="calc(100vh - 18.5em)"
 			>
 				<el-table-column align="center" type="selection" width="55" />
 				<el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column
+            label="鍑哄簱鎵规"
+            prop="outboundBatches"
+            min-width="100"
+            show-overflow-tooltip
+        />
 				<el-table-column
 					label="鍑哄簱鏃ユ湡"
 					prop="createTime"
-					min-width="250"
-					show-overflow-tooltip
-				/>
-				<el-table-column
-					label="渚涘簲鍟嗗悕绉�"
-					prop="supplierName"
-					width="250"
 					show-overflow-tooltip
 				/>
 				<el-table-column
 					label="浜у搧澶х被"
-					prop="productCategory"
-					width="100"
+					prop="productName"
 					show-overflow-tooltip
 				/>
 				<el-table-column
 					label="瑙勬牸鍨嬪彿"
-					prop="specificationModel"
-					width="100"
+					prop="model"
 					show-overflow-tooltip
 				/>
 				<el-table-column
 					label="鍗曚綅"
 					prop="unit"
-					width="80"
 					show-overflow-tooltip
 				/>
 				<el-table-column
 					label="鍑哄簱鏁伴噺"
-					prop="inboundNum"
-					width="100"
-					show-overflow-tooltip
-				/>
-				<el-table-column
-					label="鍚◣鍗曚环(鍏�)"
-					prop="taxInclusiveUnitPrice"
-					width="100"
-					show-overflow-tooltip
-				/>
-				<el-table-column
-					label="鍚◣鎬讳环(鍏�)"
-					prop="taxInclusiveTotalPrice"
-					width="100"
-					show-overflow-tooltip
-				/>
-				<el-table-column
-					label="绋庣巼(%)"
-					prop="taxRate"
-					width="100"
-					show-overflow-tooltip
-				/>
-				<el-table-column
-					label="涓嶅惈绋庢�讳环(鍏�)"
-					prop="taxExclusiveTotalPrice"
-					width="180"
+					prop="stockOutNum"
 					show-overflow-tooltip
 				/>
 				<el-table-column
 					label="鍑哄簱浜�"
 					prop="createBy"
-					width="80"
 					show-overflow-tooltip
 				/>
-				<!-- <el-table-column
-					fixed="right"
-					label="鎿嶄綔"
-					min-width="60"
-					align="center"
-				>
-					<template #default="scope">
-						<el-button
-							link
-							type="primary"
-							size="small"
-							@click="openForm('edit', scope.row)"
-							>缂栬緫</el-button
-						>
-					</template>
-				</el-table-column> -->
 			</el-table>
 			<pagination
 				v-show="total > 0"
@@ -139,120 +81,6 @@
 				@pagination="paginationChange"
 			/>
 		</div>
-		
-		<!-- 鎵撳嵃棰勮寮圭獥 -->
-		<el-dialog
-			v-model="printPreviewVisible"
-			title="鎵撳嵃棰勮"
-			width="90%"
-			:close-on-click-modal="false"
-			class="print-preview-dialog"
-		>
-			<div class="print-preview-container">
-				<div class="print-preview-header">
-					<el-button type="primary" @click="executePrint">鎵ц鎵撳嵃</el-button>
-					<el-button @click="printPreviewVisible = false">鍏抽棴棰勮</el-button>
-				</div>
-				<div class="print-preview-content">
-					<div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
-						鏆傛棤鎵撳嵃鏁版嵁
-					</div>
-					<div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
-						鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
-					</div>
-					<div v-for="(item, index) in printData" :key="index" class="print-page">
-						<div class="delivery-note">
-							<div class="header">
-								<div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
-								<div class="document-title">闆跺敭鍙戣揣鍗�</div>
-							</div>
-							
-							<div class="info-section">
-								<div class="info-row">
-									<div>
-										<span class="label">鍙戣揣鏃ユ湡锛�</span>
-										<span class="value">{{ formatDate(item.createTime) }}</span>
-									</div>
-									<div>
-										
-										<span class="label">瀹㈡埛鍚嶇О锛�</span>
-										<span class="value">{{ item.supplierName || '寮犵埍鏈�' }}</span>
-									</div>
-								</div>
-								<div class="info-row">
-									<span class="label">鍗曞彿锛�</span>
-									<span class="value">{{ item.code }}</span>
-								</div>
-							</div>
-							
-							<div class="table-section">
-								<table class="product-table">
-									<thead>
-									<tr>
-										<th>浜у搧鍚嶇О</th>
-										<th>瑙勬牸鍨嬪彿</th>
-										<th>鍗曚綅</th>
-										<th>鍗曚环</th>
-										<th>闆跺敭鏁伴噺</th>
-										<th>闆跺敭閲戦</th>
-									</tr>
-									</thead>
-									<tbody>
-									<tr>
-										<td>{{ item.productCategory || '鐮傜伆鐮�' }}</td>
-										<td>{{ item.specificationModel || '鏍囧噯' }}</td>
-										<td>{{ item.unit || '鍧�' }}</td>
-										<td>{{ item.taxInclusiveUnitPrice || '0' }}</td>
-										<td>{{ item.inboundNum || '2000' }}</td>
-										<td>{{ item.taxInclusiveTotalPrice || '0' }}</td>
-									</tr>
-									</tbody>
-									<tfoot>
-									<tr>
-										<td class="label">鍚堣</td>
-										<td class="total-value"></td>
-										<td class="total-value"></td>
-										<td class="total-value"></td>
-										<td class="total-value">{{ item.inboundNum || '2000' }}</td>
-										<td class="total-value">{{ item.taxInclusiveTotalPrice || '0' }}</td>
-									</tr>
-									</tfoot>
-								</table>
-							</div>
-							
-							<div class="footer-section">
-								<div class="footer-row">
-									<div class="footer-item">
-										<span class="label">鏀惰揣鐢佃瘽锛�</span>
-										<span class="value"></span>
-									</div>
-									<div class="footer-item">
-										<span class="label">鏀惰揣浜猴細</span>
-										<span class="value"></span>
-									</div>
-									<div class="footer-item address-item">
-										<span class="label">鏀惰揣鍦板潃锛�</span>
-										<span class="value address-value"></span>
-									</div>
-								</div>
-								<div class="footer-row">
-									<div class="footer-item">
-										<span class="label">鎿嶄綔鍛橈細</span>
-										<span class="value">{{ userStore.nickName || '鎾曞紑鍓�' }}</span>
-									</div>
-									<div class="footer-item">
-										<span class="label">鎵撳嵃鏃ユ湡锛�</span>
-										<span class="value">{{ formatDateTime(new Date()) }}</span>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-		</el-dialog>
-	
-	
 	</div>
 </template>
 
@@ -345,15 +173,6 @@
 };
 const expandedRowKeys = ref([]);
 
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
-	return proxy.summarizeTable(param, [
-		"contractAmount",
-		"taxInclusiveTotalPrice",
-		"taxExclusiveTotalPrice",
-	]);
-};
-
 // 瀵煎嚭
 const handleOut = () => {
 	ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -384,7 +203,7 @@
 		type: "warning",
 	})
 		.then(() => {
-			delStockOut({ids:ids}).then((res) => {
+			delStockOut(ids).then((res) => {
 				proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 				getList();
 			});
@@ -590,8 +409,8 @@
               </thead>
               <tbody>
                 <tr>
-                  <td>${item.productCategory || '鐮傜伆鐮�'}</td>
-                  <td>${item.specificationModel || '鏍囧噯'}</td>
+                  <td>${item.productName || '鐮傜伆鐮�'}</td>
+                  <td>${item.model || '鏍囧噯'}</td>
                   <td>${item.unit || '鍧�'}</td>
                   <td>${item.taxInclusiveUnitPrice || '0'}</td>
                   <td>${item.inboundNum || '2000'}</td>
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
index 030b615..6dff880 100644
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ b/src/views/inventoryManagement/receiptManagement/index.vue
@@ -2,550 +2,219 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
-        <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
-          clearable prefix-icon="Search" />
         <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
-				<el-date-picker
-					v-model="searchForm.timeStr"
-					type="date"
-					placeholder="璇烽�夋嫨鏃ユ湡"
-					value-format="YYYY-MM-DD"
-					format="YYYY-MM-DD"
-					clearable
-					@change="handleQuery"
-				/>
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
+        <el-date-picker v-model="searchForm.timeStr"
+                        type="date"
+                        placeholder="璇烽�夋嫨鏃ユ湡"
+                        value-format="YYYY-MM-DD"
+                        format="YYYY-MM-DD"
+                        clearable
+                        @change="handleQuery"/>
+        <span class="search_title ml10">浜у搧澶х被锛�</span>
+        <el-input v-model="searchForm.productName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏�"
+                  clearable/>
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储
+        </el-button>
       </div>
       <div>
-        <el-button type="primary" @click="openForm('add')">鏂板鍏ュ簱</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎
+        </el-button>
       </div>
     </div>
     <div class="table_list">
-      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
-        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
-        <el-table-column align="center" type="selection" width="55" />
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip />
-        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
-        <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
-        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
-        <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
-        <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
-        <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
-        <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
-          <template #default="scope">
-            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">缂栬緫</el-button>
-          </template>
-        </el-table-column>
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                @selection-change="handleSelectionChange"
+                :expand-row-keys="expandedRowKeys"
+                :row-key="row => row.id"
+                show-summary
+                style="width: 100%"
+                :summary-method="summarizeMainTable"
+                height="calc(100vh - 18.5em)">
+        <el-table-column align="center"
+                         type="selection"
+                         width="55"/>
+        <el-table-column align="center"
+                         label="搴忓彿"
+                         type="index"
+                         width="60"/>
+        <el-table-column label="鍏ュ簱鎵规"
+                         prop="inboundBatches"
+                         width="280"
+                         show-overflow-tooltip/>
+        <el-table-column label="鍏ュ簱鏃堕棿"
+                         prop="createTime"
+                         show-overflow-tooltip/>
+        <el-table-column label="浜у搧澶х被"
+                         prop="productName"
+                         show-overflow-tooltip/>
+        <el-table-column label="瑙勬牸鍨嬪彿"
+                         prop="model"
+                         show-overflow-tooltip/>
+        <el-table-column label="鍗曚綅"
+                         prop="unit"
+                         show-overflow-tooltip/>
+        <el-table-column label="鍏ュ簱鏁伴噺"
+                         prop="stockInNum"
+                         show-overflow-tooltip/>
+        <el-table-column label="鍏ュ簱浜�"
+                         prop="createBy"
+                         show-overflow-tooltip/>
       </el-table>
-      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
-        :page="page.current" :limit="page.size" @pagination="paginationChange" />
+      <pagination v-show="total > 0"
+                  :total="total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="pageProductChange"/>
     </div>
-
-    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'" width="70%"
-      @close="closeDia">
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
-              <el-select
-                  v-model="form.purchaseContractNumber"
-                  placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
-                  clearable
-                  filterable
-                  remote
-                  :remote-method="loadPurchaseOptions"
-                  :loading="loadingPurchaseOptions"
-                  @change="handlePurchaseChange"
-                  :disabled="operationType === 'edit'"
-                  style="width: 100%"
-              >
-                <el-option
-                    v-for="item in purchaseOptions"
-                    :key="item.purchaseContractNumber"
-                    :label="formatPurchaseOption(item)"
-                    :value="item.purchaseContractNumber"
-                />
-              </el-select>
-            </el-form-item>
-        <el-table
-          :data="productList"
-          border
-          v-loading="loadingProducts"
-          @selection-change="handleSelectionChange"
-        >
-          <el-table-column align="center" type="selection" width="55" />
-          <el-table-column
-            align="center"
-            label="搴忓彿"
-            type="index"
-            width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-          <el-table-column label="鍗曚綅" prop="unit" width="70" />
-          <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" />
-          <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
-          <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
-          <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
-            <template #default="scope">
-              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
-            </template>
-          </el-table-column>
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
-          <el-table-column
-            label="鍚◣鍗曚环(鍏�)"
-            prop="taxInclusiveUnitPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-          <el-table-column
-            label="鍚◣鎬讳环(鍏�)"
-            prop="taxInclusiveTotalPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-          <el-table-column
-            label="涓嶅惈绋庢�讳环(鍏�)"
-            prop="taxExclusiveTotalPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-        </el-table>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
+import pagination from "@/components/PIMTable/Pagination.vue";
 import {
-  getStockInPage,
-  updateStockIn,
-  addSutockIn,
-  delStockIn,
-  selectProductRecordListByPuechaserId
-} from "@/api/inventoryManagement/stockIn.js";
-import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
-import { getCurrentDate } from "@/utils/index.js";
+  ref,
+  reactive,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+  nextTick,
+} from "vue";
+import {ElMessageBox} from "element-plus";
+import {
+  getStockInRecordListPage,
+  batchDeleteStockInRecords,
+} from "@/api/inventoryManagement/stockInRecord.js";
 
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
+const {proxy} = getCurrentInstance();
 
-const tableData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
-
-const purchaseOptions = ref([])
-const loadingPurchaseOptions = ref(false)
-
-
-const loading = ref(false);
-const tableLoading = ref(false)
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const activeTab = ref("production"); // 褰撳墠婵�娲荤殑 tab
 
 const page = reactive({
   current: 1,
   size: 100,
-})
-const total = ref(0)
+});
+const total = ref(0);
 
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
-const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
-const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
-const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
-const productSelectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
 const data = reactive({
   searchForm: {
-    supplierName: '',
-		timeStr: '',
+    productName: "",
+    timeStr: "",
   },
-  form: {
-    id: null,
-    purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
-    supplierId: null,       // 渚涘簲鍟咺D
-    supplierName: '',       // 渚涘簲鍟嗗悕绉�
-    inboundTime: '',        // 鍏ュ簱鏃堕棿
-    inboundBatch: '',       // 鍏ュ簱鎵规
-    recorderId: userStore.userId, // 褰曞叆浜篒D
-    recorderName: userStore.name, // 褰曞叆浜哄鍚�
-    entryDate: getCurrentDate(),  // 褰曞叆鏃ユ湡
-    remark: '',             // 澶囨敞
-  },
-  rules: {
-    purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
-    supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
-    inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
-    inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
-  }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-const formatPurchaseOption = (item = {}) => {
-  const contract = item.purchaseContractNumber || '--';
-  const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
-  return `${contract}${supplier}`;
-};
-
-const loadPurchaseOptions = async (keyword = '') => {
-  try {
-    loadingPurchaseOptions.value = true;
-    const res = await purchaseListPage({
-      current: -1,
-      size: -1,
-      purchaseContractNumber: keyword,
-    });
-    const records = res.data?.records || [];
-    purchaseOptions.value = records;
-    if (
-      form.value.purchaseContractNumber &&
-      !purchaseOptions.value.find(
-        (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
-      )
-    ) {
-      purchaseOptions.value.push({
-        purchaseContractNumber: form.value.purchaseContractNumber,
-        supplierName: form.value.supplierName,
-        supplierId: form.value.supplierId,
-      });
-    }
-  } finally {
-    loadingPurchaseOptions.value = false;
-  }
-};
-
-const handlePurchaseChange = (value) => {
-  form.value.purchaseContractNumber = value || '';
-  const matched = purchaseOptions.value.find(
-    (item) => item.purchaseContractNumber === value
-  );
-  if (matched) {
-    form.value.supplierName = matched.supplierName || form.value.supplierName;
-    form.value.supplierId = matched.supplierId || form.value.supplierId;
-  }
-  if (!value) {
-    productList.value = [];
-    return;
-  }
-  fetchProductsByContract();
-};
-const exceedsAddLimit = (product) => {
-  const stock = Number(product?.quantityStock ?? 0);
-  const waiting = Number(product?.quantity0 ?? 0);
-  if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
-    return false;
-  }
-  return stock > waiting;
-};
-
-const exceedsEditLimit = (product) => {
-  const stock = Number(product?.quantityStock ?? 0);
-  const waiting = Number(product?.quantity0 ?? 0);
-  const original = Number(product?.originalQuantityStock ?? 0);
-  if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
-    return false;
-  }
-  return stock > waiting + original;
-};
-const formattedNumber = (row, column, cellValue) => {
-	return parseFloat(cellValue).toFixed(2);
-};
+});
+const {searchForm} = toRefs(data);
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  page.current = 1
-  getList()
-}
-const paginationChange = (obj) => {
+  page.current = 1;
+  getList();
+};
+const paginationChange = obj => {
   page.current = obj.page;
   page.size = obj.limit;
-  getList()
-}
+  getList();
+};
+const pageProductChange = obj => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+
 const getList = () => {
-  tableLoading.value = true
-  getStockInPage({ ...searchForm.value, ...page }).then(res => {
-    tableLoading.value = false
-    tableData.value = res.data.records
-    total.value = res.data.total
-    console.log('tableData:', tableData.value)
-  }).catch(() => {
-    tableLoading.value = false
+  tableLoading.value = true;
+  const params = {...page};
+  params.timeStr = searchForm.value.timeStr;
+  params.productName = searchForm.value.productName;
+  getStockInRecordListPage(params)
+      .then(res => {
+        tableData.value = res.data.records;
+      }).finally(() => {
+        tableLoading.value = false;
   })
-}
+};
 
-
-// 璋冪敤selectProductRecordListByPuechaserId杩欎釜鏂规硶鏍规嵁鍚堝悓鏌ヨ鍒癷d锛屽啀璋冪敤getProductRecordByhetong杩欎釜鏂规硶鏍规嵁id鏌ヨ鍒颁骇鍝佽鍗曡褰�
-// 鏂板鏍规嵁鍚堝悓鍙锋煡璇骇鍝佽褰曠殑鏂规硶
-const fetchProductsByContract = async () =>
-{
-  if (!form.value.purchaseContractNumber) {
-    proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
-    return
-  }
-  try {
-    loadingProducts.value = true
-    // 鏍规嵁鍚堝悓鏌ヨ浜у搧璁板綍
-    const productRes = await selectProductRecordListByPuechaserId({
-      purchaseContractNumber: form.value.purchaseContractNumber
-    });
-    console.log('productRes:', productRes)
-    if (!productRes.data || productRes.data.length === 0) {
-      proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
-      productList.value = [];
-      return
-    }
-    // 澶勭悊浜у搧鏁版嵁锛屾坊鍔犳湰娆″叆搴撴暟閲忓瓧娈�
-    productList.value = productRes.data.map(item => ({
-      ...item,
-      quantityStock: 0,
-      originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
-    }))
-  } catch (error) {
-    console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
-    proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
-    productList.value = [];
-  } finally {
-    loadingProducts.value = false
-  }
-}
-
-
-// 鎵撳紑寮规
-  const openForm = async (type, row) => {
-    operationType.value = type
-    dialogFormVisible.value = true
-    selectedRows.value = []
-		await loadPurchaseOptions();
-
-    if (type === 'add') {
-      // 鏂板鏃跺垵濮嬪寲琛ㄥ崟
-      form.value = {
-        id: null,
-        purchaseContractNumber: '',
-        supplierId: null,
-        supplierName: '',
-        inboundTime: '',
-        inboundBatch: '',
-        recorderId: userStore.userId,
-        recorderName: userStore.name,
-        entryDate: getCurrentDate(),
-        remark: ''
-      }
-      productList.value = [] // 娓呯┖浜у搧鍒楄〃
-    } else {
-      form.value = JSON.parse(JSON.stringify(row))
-      try {
-        loadingProducts.value = true
-        // 鏍规嵁鍚堝悓鍙峰姞杞藉搴旂殑浜у搧鍒楄〃锛堝亣璁� getProductByContract 鏄彲鐢ㄦ帴鍙o級
-        const res = await selectProductRecordListByPuechaserId({
-          purchaseContractNumber: form.value.purchaseContractNumber,
-          id: row.id
-        });
-				productList.value = res.data.map(item => ({
-					...item,
-					quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
-					originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
-				}))
-        selectedRows.value = productList.value
-      } catch (error) {
-        console.error('鍔犺浇浜у搧澶辫触:', error)
-        proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
-        productList.value = []
-      } finally {
-        loadingProducts.value = false
-      }
-    }
-  }
-
-  const updatePro = async () => {
-     // 鍑嗗鎻愪氦鏁版嵁
-     // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
-    if (selectedRows.value.length === 0) {
-      proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
-      return;
-    }
-    const target = selectedRows.value[0];
-    const stock = Number(target?.quantityStock ?? 0);
-    if (!Number.isFinite(stock) || stock <= 0) {
-      proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
-      return;
-    }
-    if (exceedsEditLimit(target)) {
-      proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
-      return;
-    }
-    const stockInData = {
-      id: selectedRows.value[0].recordId,
-      quantityStock: Number(selectedRows.value[0].quantityStock),// 浣跨敤鏂版牸寮忓寲鍑芥暟
-    };
-    await updateStockIn(stockInData)
-    proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
-    closeDia()
-    getList() // 鍒锋柊鍒楄〃
-  }
-
-// 鎻愪氦琛ㄥ崟
-  const submitForm = async () => {
-    // 楠岃瘉鑷冲皯閫夋嫨浜嗕竴涓骇鍝�
-    if (selectedRows.value.length === 0) {
-      proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
-      return
-    }
-    if(operationType.value !== 'add'){
-      await updatePro()
-      return
-    }
-    try {
-      await proxy.$refs.formRef.validate()
-      // 楠岃瘉鍏ュ簱鏁伴噺
-      const invalidProducts = selectedRows.value.filter((product) => {
-          const stock = Number(product?.quantityStock ?? 0);
-          if (!Number.isFinite(stock) || stock <= 0) {
-            return true;
-          }
-          return exceedsAddLimit(product);
-      })
-
-      if (invalidProducts.length > 0) {
-        proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
-        return
-      }
-
-      // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
-      const stockInData = {
-        // 鍏ュ簱鍗曞熀鏈俊鎭�
-        ...form.value,
-        inboundTime: formatDateTime(form.value.inboundTime),
-        nickName: userStore.nickName,
-        details: selectedRows.value.map(product => ({
-          id: product.id,
-          // id: product.salesLedgerProductId,
-          inboundQuantity: Number(product.quantityStock)
-        })),
-      };
-      // 璋冪敤API
-      loading.value = true
-      await addSutockIn(stockInData)
-
-      proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
-      closeDia()
-      getList() // 鍒锋柊鍒楄〃
-
-    } catch (error) {
-      console.error('鎻愪氦澶辫触:', error)
-      if (!error.errors) {
-        proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
-      }
-    } finally {
-      loading.value = false
-    }
-  }
-
-// 鍏抽棴寮规
-  const closeDia = () => {
-    proxy.$refs.formRef.resetFields()
-    dialogFormVisible.value = false
-
-  }
 // 琛ㄦ牸閫夋嫨鏁版嵁
-  const handleSelectionChange = (selection) => {
-    // 杩囨护鎺夊瓙鏁版嵁
-    selectedRows.value = selection.filter(item => item.id);
-  }
+const handleSelectionChange = selection => {
+  selectedRows.value = selection.filter(item => item.id);
+};
 
-  const expandedRowKeys = ref([])
+const expandedRowKeys = ref([]);
 
 // 涓昏〃鍚堣鏂规硶
-  const summarizeMainTable = (param) => {
-    return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-  };
+const summarizeMainTable = param => {
+  return proxy.summarizeTable(param, [
+    "contractAmount",
+    "taxInclusiveTotalPrice",
+    "taxExclusiveTotalPrice",
+  ]);
+};
 
 // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm(
-        '鏄惁纭瀵煎嚭锛�',
-        '瀵煎嚭', {
-          confirmButtonText: '纭',
-          cancelButtonText: '鍙栨秷',
-          type: 'warning',
-        }
-    ).then(() => {
-      proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
-    }).catch(() => {
-      proxy.$modal.msg("宸插彇娑�")
-    })
-  }
-// 鍒犻櫎
-  const handleDelete = () => {
-    let ids = []
-    if (selectedRows.value.length > 0) {
-			// 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-			const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
-			if (unauthorizedData.length > 0) {
-				proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
-				return;
-			}
-      ids = selectedRows.value.map(item => item.id);
-    } else {
-      proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
-      return
-    }
-    ElMessageBox.confirm(
-        '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
-        '瀵煎嚭', {
-          confirmButtonText: '纭',
-          cancelButtonText: '鍙栨秷',
-          type: 'warning',
-        }
-    ).then(() => {
-      delStockIn({ids:ids}).then(res => {
-        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
-        getList()
-      })
-    }).catch(() => {
-      proxy.$modal.msg("宸插彇娑�")
-    })
-  }
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-// 淇敼涓烘洿閫氱敤鐨勬棩鏈熸椂闂存牸寮忓寲鍑芥暟
-function formatDateTime(date = new Date(), includeTime = true) {
-  const d = new Date(date);
-  const year = d.getFullYear();
-  const month = String(d.getMonth() + 1).padStart(2, '0');
-  const day = String(d.getDate()).padStart(2, '0');
-
-  if (!includeTime) {
-    return `${year}-${month}-${day}`; // 淇濇寔鍘熸湁 getCurrentDate 鍔熻兘
-  }
-
-  // 鏂板鏃堕棿閮ㄥ垎鏍煎紡鍖�
-  const hours = String(d.getHours()).padStart(2, '0');
-  const minutes = String(d.getMinutes()).padStart(2, '0');
-  const seconds = String(d.getSeconds()).padStart(2, '0');
-
-  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
-
-  onMounted(() => {
-    getList()
+const handleOut = () => {
+  ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
   })
+      .then(() => {
+        // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+        let exportUrl = "/stockin/export";
+        if (activeTab.value === "production") {
+          exportUrl = "/stockin/exportOne";
+        }
+        proxy.download(exportUrl, {}, "鍏ュ簱鍙拌处.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  const ids = selectedRows.value.map(item => item.id);
+
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        batchDeleteStockInRecords(ids)
+            .then(() => {
+              proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+              getList();
+            })
+            .catch(() => {
+              proxy.$modal.msgError("鍒犻櫎澶辫触");
+            });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
+onMounted(() => {
+  getList();
+});
 </script>
 
 <style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
new file mode 100644
index 0000000..8243748
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -0,0 +1,163 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="isShow"
+        title="鏂板搴撳瓨"
+        width="800"
+        @close="closeModal"
+    >
+      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
+        <el-form-item
+            label="浜у搧鍚嶇О"
+            prop="productModelId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨浜у搧',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-button type="primary" @click="showProductSelectDialog = true">
+            {{ formState.productName ? formState.productName : '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item
+            label="瑙勬牸"
+            prop="productModelName"
+        >
+          <el-input v-model="formState.productModelName"  disabled />
+        </el-form-item>
+
+        <el-form-item
+            label="鍗曚綅"
+            prop="unit"
+        >
+          <el-input v-model="formState.unit"  disabled />
+        </el-form-item>
+
+        <el-form-item
+            label="鏁伴噺"
+            prop="qualitity"
+        >
+          <el-input-number v-model="formState.qualitity" :step="1" :min="0" style="width: 100%" />
+        </el-form-item>
+
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="formState.remark" type="textarea" />
+        </el-form-item>
+      </el-form>
+
+      <!-- 浜у搧閫夋嫨寮圭獥 -->
+      <ProductSelectDialog
+          v-model="showProductSelectDialog"
+          @confirm="handleProductSelect"
+          single
+      />
+      <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 ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+import {createStockInventory} from "@/api/inventoryManagement/stockInventory.js";
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
+const formState = ref({
+  productId: undefined,
+  productModelId: undefined,
+  productName: "",
+  productModelName: "",
+  unit: "",
+  qualitity: 0,
+  remark: '',
+});
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+const showProductSelectDialog = ref(false);
+
+let { proxy } = getCurrentInstance()
+
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  formState.value = {
+    productId: undefined,
+    productModelId: undefined,
+    productName: "",
+    productModelName: "",
+    description: '',
+  };
+  isShow.value = false;
+};
+
+// 浜у搧閫夋嫨澶勭悊
+const handleProductSelect = async (products) => {
+  if (products && products.length > 0) {
+    const product = products[0];
+    console.log(product)
+    formState.value.productId = product.productId;
+    formState.value.productName = product.productName;
+    formState.value.productModelName = product.model;
+    formState.value.productModelId = product.id;
+    formState.value.unit = product.unit;
+    showProductSelectDialog.value = false;
+    // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+    proxy.$refs["formRef"]?.validateField('productModelId');
+  }
+};
+
+const handleSubmit = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰瑙勬牸
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨浜у搧");
+        return;
+      }
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
+        return;
+      }
+      createStockInventory(formState.value).then(res => {
+        // 鍏抽棴妯℃�佹
+        isShow.value = false;
+        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+        emit('completed');
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      })
+    }
+  })
+};
+
+
+defineExpose({
+  closeModal,
+  handleSubmit,
+  isShow,
+});
+</script>
diff --git a/src/views/inventoryManagement/stockManagement/Subtract.vue b/src/views/inventoryManagement/stockManagement/Subtract.vue
new file mode 100644
index 0000000..10fd763
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/Subtract.vue
@@ -0,0 +1,183 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="isShow"
+        title="棰嗙敤"
+        width="800"
+        @close="closeModal"
+    >
+      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
+        <el-form-item
+            label="浜у搧鍚嶇О"
+            prop="productModelId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨浜у搧',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-button type="primary" @click="showProductSelectDialog = true" disabled>
+            {{ formState.productName ? formState.productName : '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item
+            label="瑙勬牸"
+            prop="productModelName"
+        >
+          <el-input v-model="formState.model"  disabled />
+        </el-form-item>
+
+        <el-form-item
+            label="鍗曚綅"
+            prop="unit"
+        >
+          <el-input v-model="formState.unit"  disabled />
+        </el-form-item>
+
+        <el-form-item
+            label="鏁伴噺"
+            prop="qualitity"
+        >
+          <el-input-number v-model="formState.qualitity" :step="1" :min="1" :max="maxQuality" style="width: 100%" />
+        </el-form-item>
+
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="formState.remark" type="textarea" />
+        </el-form-item>
+      </el-form>
+
+      <!-- 浜у搧閫夋嫨寮圭獥 -->
+      <ProductSelectDialog
+          v-model="showProductSelectDialog"
+          @confirm="handleProductSelect"
+          single
+      />
+      <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 ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+import {subtractStockInventory} from "@/api/inventoryManagement/stockInventory.js";
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+  record: {
+    type: Object,
+    default: () => {},
+  }
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+onMounted(() => {
+  initFormData()
+})
+
+const maxQuality = computed(() => {
+  return props.record.qualitity ? props.record.qualitity :  0;
+})
+
+const initFormData = () => {
+  if (props.record) {
+    formState.value = {
+      ...props.record,
+    }
+  }
+}
+
+// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
+const formState = ref({
+  productId: undefined,
+  productModelId: undefined,
+  productName: "",
+  model: "",
+  unit: "",
+  qualitity: 0,
+  remark: '',
+});
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+const showProductSelectDialog = ref(false);
+
+let { proxy } = getCurrentInstance()
+
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  formState.value = {
+    productId: undefined,
+    productModelId: undefined,
+    productName: "",
+    productModelName: "",
+    description: '',
+  };
+  isShow.value = false;
+};
+
+// 浜у搧閫夋嫨澶勭悊
+const handleProductSelect = async (products) => {
+  if (products && products.length > 0) {
+    const product = products[0];
+    console.log(product)
+    formState.value.productId = product.productId;
+    formState.value.productName = product.productName;
+    formState.value.productModelName = product.model;
+    formState.value.productModelId = product.id;
+    formState.value.unit = product.unit;
+    showProductSelectDialog.value = false;
+    // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+    proxy.$refs["formRef"]?.validateField('productModelId');
+  }
+};
+
+const handleSubmit = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰瑙勬牸
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨浜у搧");
+        return;
+      }
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
+        return;
+      }
+      subtractStockInventory(formState.value).then(res => {
+        // 鍏抽棴妯℃�佹
+        isShow.value = false;
+        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+        emit('completed');
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      })
+    }
+  })
+};
+
+
+defineExpose({
+  closeModal,
+  handleSubmit,
+  isShow,
+});
+</script>
diff --git a/src/views/inventoryManagement/stockManagement/index.vue b/src/views/inventoryManagement/stockManagement/index.vue
index 52b0184..76c94d0 100644
--- a/src/views/inventoryManagement/stockManagement/index.vue
+++ b/src/views/inventoryManagement/stockManagement/index.vue
@@ -2,150 +2,48 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
-        <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
-          clearable prefix-icon="Search" />
-				<span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
-				<el-date-picker
-					v-model="searchForm.timeStr"
-					type="date"
-					placeholder="璇烽�夋嫨鏃ユ湡"
-					value-format="YYYY-MM-DD"
-					format="YYYY-MM-DD"
-					clearable
-					@change="handleQuery"
-				/>
+        <span class="search_title ml10">浜у搧澶х被锛�</span>
+        <el-input v-model="searchForm.productName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏�"
+                  clearable/>
         <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
       </div>
       <div>
-        <!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button> -->
+         <el-button type="primary" @click="isShowNewModal = true">鏂板搴撳瓨</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
     </div>
     <div class="table_list">
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
-        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :row-class-name="tableRowClassName"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" style="width: 100%"
+        :row-class-name="tableRowClassName" height="calc(100vh - 18.5em)">
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column label="鍏ュ簱鏃ユ湡" prop="createTime" width="100" show-overflow-tooltip />
-        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
-        <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
-        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
-        <el-table-column label="鍗曚綅" prop="unit" width="80" show-overflow-tooltip />
-        <el-table-column label="搴撳瓨鏁伴噺" prop="inboundNum0" width="100" show-overflow-tooltip />
-        <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="130" show-overflow-tooltip />
-        <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="绋庣巼(%)" prop="taxRate" width="100" show-overflow-tooltip />
-        <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
+        <el-table-column label="鍏ュ簱鏃ユ湡" prop="createTime" show-overflow-tooltip />
+        <el-table-column label="浜у搧澶х被" prop="productName" show-overflow-tooltip />
+        <el-table-column label="瑙勬牸鍨嬪彿" prop="model" show-overflow-tooltip />
+        <el-table-column label="鍗曚綅" prop="unit" show-overflow-tooltip />
+        <el-table-column label="搴撳瓨鏁伴噺" prop="qualitity" show-overflow-tooltip />
+        <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum"  show-overflow-tooltip />
+        <el-table-column label="鏈�杩戞洿鏂版椂闂�" prop="updateTime" show-overflow-tooltip />
         <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
           <template #default="scope">
-            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">缂栬緫</el-button>
+            <el-button link type="primary" size="small" @click="showSubtractModal(scope.row)" :disabled="scope.row.qualitity === 0">棰嗙敤</el-button>
           </template>
         </el-table-column>
       </el-table>
       <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
         :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
-    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板搴撳瓨' : '缂栬緫搴撳瓨'" width="70%"
-      @close="closeDia">
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
-              <el-input disabled v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="浜у搧澶х被锛�" prop="productId">
-              <el-select disabled v-model="form.productCategory" placeholder="璇烽�夋嫨" clearable filterable>
-                <el-option v-for="item in productList" :key="item.id" :label="item.productName"
-                           :value="item.productName" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productManageId">
-              <el-select disabled v-model="form.specificationModel" placeholder="璇峰厛閫夋嫨浜у搧澶х被" clearable filterable :disabled="!form.productCategory">
-                <el-option v-for="item in productModelList" :key="item.id" :label="item.model"
-                           :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item  label="鍗曚綅锛�" prop="customerId">
-              <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="搴撳瓨鏃堕棿锛�" prop="projectName">
-              <el-date-picker style="width: 100%" v-model="form.updateTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
-                type="date" placeholder="璇烽�夋嫨" clearable />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="projectName">
-              <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
-                type="date" placeholder="璇烽�夋嫨" clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
+    <new-stock-inventory v-if="isShowNewModal"
+                 v-model:visible="isShowNewModal"
+                 @completed="handleQuery" />
 
-          <el-col :span="12">
-            <el-form-item  label="鍚◣鍗曚环锛�" prop="customerId">
-              <el-input disabled v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item  label="鍚◣鎬讳环锛�" prop="customerContractNo">
-              <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-
-          <el-col :span="12">
-            <el-form-item  label="绋庣巼锛�" prop="customerId">
-              <el-input disabled v-model="form.taxRate" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓嶅惈绋庢�讳环锛�" prop="entryDate">
-              <el-input disabled v-model="form.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
-              <el-select v-model="form.createUser" placeholder="璇烽�夋嫨" clearable>
-                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-<!--          <el-col :span="12">-->
-<!--          <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">-->
-<!--            <el-input v-model="form.warnNum" placeholder="璇疯緭鍏ユ渶浣庡簱瀛�" clearable />-->
-<!--          </el-form-item>-->
-<!--        </el-col>-->
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    <subtract-stock-inventory v-if="isShowSubtractModal"
+                 v-model:visible="isShowSubtractModal"
+                 :record="record"
+                 @completed="handleQuery" />
   </div>
 </template>
 
@@ -153,84 +51,30 @@
 import pagination from '@/components/PIMTable/Pagination.vue'
 import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
 import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
-import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { productTreeList,modelList } from "@/api/basicData/product.js"
-import { getCurrentDate } from "@/utils/index.js";
-import {
-  getStockManagePage,
-  delStockManage,
-} from "@/api/inventoryManagement/stockManage.js";
-import {
-  updateManagement,updateStockIn
-} from "@/api/inventoryManagement/stockIn.js";
+import { getStockInventoryListPage } from "@/api/inventoryManagement/stockInventory.js";
+const NewStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/New.vue"));
+const SubtractStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Subtract.vue"));
 
-
-
-const userStore = useUserStore()
 const { proxy } = getCurrentInstance()
 const tableData = ref([])
-const productData = ref([])
 const selectedRows = ref([])
-const userList = ref([])
-const productList = ref([])
-const productModelList = ref([])
-// const customerOption = ref([])
+const record = ref({})
 const tableLoading = ref(false)
 const page = reactive({
   current: 1,
   size: 100,
 })
 const total = ref(0)
-const fileList = ref([])
-const loading = ref(false);
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')
-const dialogFormVisible = ref(false)
+// 鏄惁鏄剧ず鏂板寮规
+const isShowNewModal = ref(false)
+// 鏄惁鏄剧ず棰嗙敤寮规
+const isShowSubtractModal = ref(false)
 const data = reactive({
   searchForm: {
-    supplierName: '',
-		timeStr: '',
-  },
-  form: {
-    supplierId: null,
-    supplierName: '',
-    productId: null,
     productName: '',
-    userId: userStore.userId,
-    nickName: '',
-    productModelId: null,
-    model: '',
-    unit: '',
-    productrecordId: null,
-    taxInclusiveUnitPrice: '',
-    taxInclusiveTotalPrice: '',
-    taxRate: '',
-    taxExclusiveTotalPrice: '',
-    inboundTime: '',
-    inboundBatch: '',
-    stockQuantity: '',
-    boundTime: '',
-		warnNum: '', // 鏂板鏈�浣庡簱瀛樺瓧娈�
-    salesLedgerProductId: null,
-  },
-  rules: {
-    supplierName: [{ required: true, message: '璇疯緭鍏ヤ緵搴斿晢鍚嶇О', trigger: 'blur' }],
-    productCategory: [{ required: true, message: '璇烽�夋嫨浜у搧澶х被', trigger: 'change' }],
-    specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
-    unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
-    stockQuantity: [{ required: true, message: '璇疯緭鍏ュ嚭搴撴暟閲�', trigger: 'blur' }],
-    taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' }],
-    taxInclusiveTotalPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庢�讳环', trigger: 'blur' }],
-    taxRate: [{ required: true, message: '璇疯緭鍏ョ◣鐜�', trigger: 'blur' }],
-    taxExclusiveTotalPrice: [{ required: true, message: '璇疯緭鍏ヤ笉鍚◣鎬讳环', trigger: 'blur' }],
-    boundTime: [{ required: true, message: '璇烽�夋嫨搴撳瓨鏃堕棿', trigger: 'change' }],
-    inboundTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
-    inboundPerson: [{ required: true, message: '璇烽�夋嫨鍑哄簱浜�', trigger: 'change' }],
-		warnNum: [{ required: true, message: '璇疯緭鍏ユ渶浣庡簱瀛�', trigger: 'blur' }], 
   }
 })
-const { searchForm, form, rules } = toRefs(data)
+const { searchForm } = toRefs(data)
 
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -245,7 +89,7 @@
 }
 const getList = () => {
   tableLoading.value = true
-  getStockManagePage({ ...searchForm.value, ...page }).then(res => {
+  getStockInventoryListPage({ ...searchForm.value, ...page }).then(res => {
     tableLoading.value = false
     tableData.value = res.data.records
     total.value = res.data.total
@@ -256,19 +100,19 @@
   })
 }
 
+// 鐐瑰嚮棰嗙敤
+const showSubtractModal = (row) => {
+  record.value = row
+  isShowSubtractModal.value = true
+}
+
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
-
   // 杩囨护鎺夊瓙鏁版嵁
   selectedRows.value = selection.filter(item => item.id);
   console.log('selection', selectedRows.value)
 }
 const expandedRowKeys = ref([])
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-};
 
 // 琛ㄦ牸琛岀被鍚�
 const tableRowClassName = ({ row }) => {
@@ -279,74 +123,6 @@
   }
   return stock < warn ? 'row-low-stock' : '';
 };
-
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
-  operationType.value = type
-  form.value = {}
-  productData.value = []
-  let userLists = await userListNoPageByTenantId()
-  userList.value = userLists.data
-  if (type === 'edit') {
-    form.value = { ...row }
-    productTreeList().then(res =>{
-      productList.value = res
-      productList.value.forEach(i =>{
-        if (i.label === row.productCategory) {
-          modelList({ id: i.id }).then((res) => {
-            productModelList.value = res;
-          });
-        }
-      })
-    })
-  }
-  form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
-  dialogFormVisible.value = true
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
-  console.log(form.value)
-  proxy.$refs["formRef"].validate(valid => {
-    if (valid) {
-
-      updateManagement(form.value).then(res => {
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
-        closeDia()
-        getList()
-        // 鎻愪氦鍚庢鏌ュ簱瀛樺苟灏濊瘯鍒涘缓璇疯喘鍗�
-        // checkStockAndCreatePurchase();
-      })
-    }
-  })
-}
-// 妫�鏌ュ簱瀛樺苟鍒涘缓璇疯喘鍗�
-// const checkStockAndCreatePurchase = async () => {
-//   const stockList = tableData.value;
-//   // handList()
-//   for (const item of stockList) {
-//     if (item.inboundNum0 < item.warnNum) {
-//       try {
-// 				const stockInData = {
-// 					id: item.id,
-// 					quantityStock: item.warnNum + item.totalInboundNum,// 浣跨敤鏂版牸寮忓寲鍑芥暟
-// 				};
-// 				loading.value = true
-// 				await updateStockIn(stockInData)
-// 				proxy.$modal.msgSuccess(`浜у搧 ${item.productCategory} 淇敼鍏ュ簱鎴愬姛`)
-// 				loading.value = false
-//       } catch (error) {
-//         proxy.$modal.msgError(`浜у搧 ${item.productCategory} 鐢熸垚璇疯喘鍗曞け璐ワ紝璇锋墜鍔ㄥ鐞哷);
-//
-//       }
-//     }
-//   }
-// };
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef")
-  dialogFormVisible.value = false
-}
 
 // 瀵煎嚭
 const handleOut = () => {
@@ -363,47 +139,9 @@
     proxy.$modal.msg("宸插彇娑�")
   })
 }
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = []
-  if (selectedRows.value.length > 0) {
-		// 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-		const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
-		if (unauthorizedData.length > 0) {
-			proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
-			return;
-		}
-    ids = selectedRows.value.map(item => item.id);
-  } else {
-    proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
-    return
-  }
-  ElMessageBox.confirm(
-    '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
-    '瀵煎嚭', {
-    confirmButtonText: '纭',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning',
-  }
-  ).then(() => {
-    delStockManage({ids:ids}).then(res => {
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
-      getList()
-    })
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�")
-  })
-}
+
 onMounted(() => {
   getList()
-  // checkStockAndCreatePurchase();
-    // 姣忓皬鏃舵鏌ヤ竴娆″簱瀛�
-    // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
-
-// onUnmounted(() => {
-//   // 缁勪欢鍗歌浇鏃舵竻闄ゅ畾鏃跺櫒
-//   clearInterval(intervalId);
-// });
 })
 </script>
 
diff --git a/src/views/lavorissue/ledger/Form.vue b/src/views/lavorissue/ledger/Form.vue
index 7031957..785ef7a 100644
--- a/src/views/lavorissue/ledger/Form.vue
+++ b/src/views/lavorissue/ledger/Form.vue
@@ -73,12 +73,12 @@
 import useFormData from "@/hooks/useFormData";
 import {ref,onMounted} from "vue";
 import useUserStore from "@/store/modules/user";
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import {deepCopySameProperties} from '@/utils/util'
 const userStore = useUserStore();
 import {
   getDept
 } from "@/api/collaborativeApproval/approvalProcess.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance();
 
 
@@ -112,8 +112,12 @@
   issueDate: undefined,
 });
 const getPersonList = () => {
-  getStaffOnJob().then(res => {
-    personList.value = res.data
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records
   })
 };
 const loadForm = (data) => {
diff --git a/src/views/login.vue b/src/views/login.vue
index 5300637..6217877 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -10,7 +10,6 @@
           size="large"
           auto-complete="off"
           placeholder="璐﹀彿"
-          @input="getUserLoginFacotryList"
         >
           <template #prefix><el-icon><User /></el-icon></template>
         </el-input>
@@ -27,11 +26,6 @@
         >
           <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
         </el-input>
-      </el-form-item>
-      <el-form-item prop="currentFatoryId">
-        <el-select v-model="loginForm.currentFatoryId" placeholder="璇烽�夋嫨鍏徃" >
-          <el-option  v-for="item in factoryList" :key="item.deptId" :label="item.deptName" :value="item.deptId" />
-        </el-select>
       </el-form-item>
 <!--      <el-form-item prop="code" v-if="captchaEnabled">-->
 <!--        <el-input-->
@@ -77,7 +71,6 @@
 import Cookies from "js-cookie"
 import { encrypt, decrypt } from "@/utils/jsencrypt"
 import useUserStore from '@/store/modules/user'
-import {userLoginFacotryList} from "@/api/system/user.js"
 
 const title = import.meta.env.VITE_APP_TITLE
 const userStore = useUserStore()
@@ -89,7 +82,6 @@
   username: "",
   password: "",
   rememberMe: false,
-  currentFatoryId:'',
 })
 
 const loginRules = {
@@ -105,9 +97,6 @@
 // 娉ㄥ唽寮�鍏�
 const register = ref(false)
 const redirect = ref(undefined)
-
-const factoryList = ref([])
-const currentFatoryId = ref('')
 
 watch(route, (newRoute) => {
     redirect.value = newRoute.query && newRoute.query.redirect
@@ -162,20 +151,8 @@
   }
 }
 
-function getUserLoginFacotryList() {
-  if(loginForm.value.username){
-    userLoginFacotryList({userName:loginForm.value.username}).then(res => {
-      console.log('res', res)
-      factoryList.value = res.data
-    })
-  }else {
-    factoryList.value = []
-  }
-}
-
 getCode()
 getCookie()
-getUserLoginFacotryList()
 </script>
 
 <style lang='scss' scoped>
diff --git a/src/views/personnelManagement/analytics/index.vue b/src/views/personnelManagement/analytics/index.vue
index 2bca335..9e6e449 100644
--- a/src/views/personnelManagement/analytics/index.vue
+++ b/src/views/personnelManagement/analytics/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="app-container analytics-container">
+  <div class="app-container analytics-container" v-loading="loading">
 
     <!-- 鍏抽敭鎸囨爣鍗$墖 -->
     <el-row :gutter="20" class="metrics-cards">
@@ -11,18 +11,18 @@
                 <component :is="item.icon" />
               </el-icon>
             </div>
-              <div class="card-info">
+            <div class="card-info">
               <div class="card-number">
                 <el-skeleton-item v-if="loading" variant="text" style="width: 60px; height: 32px;" />
                 <span v-else>{{ item.value }}{{ item.unit }}</span>
               </div>
               <div class="card-label">{{ item.label }}</div>
-              <div class="card-trend" :class="item.trend > 0 ? 'positive' : 'negative'" v-if="item.showTrend !== false">
-                <el-icon>
-                  <component :is="item.trend > 0 ? 'ArrowUp' : 'ArrowDown'" />
-                </el-icon>
-                {{ Math.abs(item.trend) }}%
-              </div>
+<!--              <div class="card-trend" :class="item.trend > 0 ? 'positive' : 'negative'" v-if="item.showTrend !== false">-->
+<!--                <el-icon>-->
+<!--                  <component :is="item.trend > 0 ? 'ArrowUp' : 'ArrowDown'" />-->
+<!--                </el-icon>-->
+<!--                {{ Math.abs(item.trend) }}%-->
+<!--              </div>-->
             </div>
           </div>
         </el-card>
@@ -64,21 +64,6 @@
 
     <!-- 绗簩琛屽浘琛� -->
     <el-row :gutter="20" class="charts-section">
-      <!-- 缂栧埗杈炬垚鐜� -->
-      <el-col :span="12">
-        <el-card class="chart-card">
-          <template #header>
-            <div class="card-header">
-              <span>缂栧埗杈炬垚鐜�</span>
-              <el-tag type="warning">鍚勯儴闂ㄥ姣�</el-tag>
-            </div>
-          </template>
-          <div class="chart-container">
-            <div ref="staffingChartRef" class="chart"></div>
-          </div>
-        </el-card>
-      </el-col>
-
       <!-- 鍛樺伐娴佸け鍘熷洜鍒嗘瀽 -->
       <el-col :span="12">
         <el-card class="chart-card">
@@ -98,19 +83,15 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ref, onMounted, onUnmounted, nextTick } from 'vue'
 import { ElMessage } from 'element-plus'
-import { 
-  Refresh, 
-  User, 
-  TrendCharts, 
-  DataAnalysis, 
-  PieChart,
-  ArrowUp,
-  ArrowDown
-} from '@element-plus/icons-vue'
 import * as echarts from 'echarts'
-import { staffOnJobListPage } from '@/api/personnelManagement/employeeRecord.js'
+import {listDept} from "@/api/system/dept.js";
+import {
+  findStaffAnalysisMonthlyTurnoverRateFor12Months,
+  findStaffLeaveReasonAnalysis,
+  findStaffAnalysisTotalStatistic
+} from "@/api/personnelManagement/staffAnalytics.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
@@ -151,14 +132,6 @@
     trend: 0
   },
   {
-    label: '缂栧埗杈炬垚鐜�',
-    value: 0,
-    unit: '%',
-    icon: 'DataAnalysis',
-    type: 'success',
-    trend: 0
-  },
-  {
     label: '鍦ㄨ亴鍛樺伐鏁�',
     value: 0,
     unit: '浜�',
@@ -171,16 +144,56 @@
 
 // 閮ㄩ棬鏁版嵁
 const departmentData = ref([])
+// 鍛樺伐娴佸け鍘熷洜鍒嗘瀽鏁版嵁
+const staffLeaveReasons = ref([])
+// 12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋愭暟鎹�
+const turnoverRateStatistics = ref([])
 
-// 鑾峰彇鍦ㄨ亴鍛樺伐鏁�
-const getStaffCount = async () => {
+// 鑾峰彇閮ㄩ棬鏁版嵁
+const getDepartmentData = async () => {
   try {
-    const res = await staffOnJobListPage({ staffState: 1, current: 1, size: 1 })
+    const res = await listDept()
     if (res && res.data) {
-      keyMetrics.value[3].value = res.data.total || 0
+      departmentData.value = res.data
     }
   } catch (error) {
-    console.error('鑾峰彇鍦ㄨ亴鍛樺伐鏁板け璐�:', error)
+    console.error('鑾峰彇閮ㄩ棬鏁版嵁澶辫触:', error)
+  }
+}
+
+const getStaffLeaveReasonAnalysis = async () => {
+  try {
+    const res = await findStaffLeaveReasonAnalysis()
+    if (res && res.data) {
+      staffLeaveReasons.value = res.data || []
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍛樺伐娴佸け鍘熷洜鍒嗘瀽澶辫触:', error)
+  }
+}
+
+// 淇敼涓鸿繑鍥濸romise鐨勫紓姝ュ嚱鏁�
+const getMonthlyTurnoverRateFor12Months = async () => {
+  try {
+    const res = await findStaffAnalysisMonthlyTurnoverRateFor12Months()
+    if (res && res.data) {
+      turnoverRateStatistics.value = res.data || []
+    }
+  } catch (error) {
+    console.error('鑾峰彇12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋愭暟鎹け璐�:', error)
+  }
+}
+
+const getStaffAnalysisTotalStatistic = async () => {
+  try {
+    const res = await findStaffAnalysisTotalStatistic()
+    if (res && res.data) {
+      keyMetrics.value[0].value = res.data.totalFlowRate || 0
+      keyMetrics.value[1].value = res.data.totalTurnoverRate || 0
+      keyMetrics.value[2].value = res.data.currentOnJobCount || 0
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍛樺伐鍒嗘瀽鎬荤粺璁℃暟鎹け璐�:', error)
   }
 }
 
@@ -213,49 +226,28 @@
   }
 }
 
-// 鐢熸垚妯℃嫙鏁版嵁
-const generateMockData = () => {
-  // 鐢熸垚鍏抽敭鎸囨爣鏁版嵁
-  keyMetrics.value[0].value = (Math.random() * 5 + 2).toFixed(1)
-  keyMetrics.value[0].trend = (Math.random() * 3 - 1.5).toFixed(1)
-  
-  keyMetrics.value[1].value = (Math.random() * 3 + 1).toFixed(1)
-  keyMetrics.value[1].trend = (Math.random() * 2 - 1).toFixed(1)
-  
-  keyMetrics.value[2].value = (Math.random() * 15 + 85).toFixed(1)
-  keyMetrics.value[2].trend = (Math.random() * 3 - 1.5).toFixed(1)
-
-  // 鐢熸垚閮ㄩ棬鏁版嵁
-  const departments = ['鎶�鏈儴', '閿�鍞儴', '浜轰簨閮�', '璐㈠姟閮�', '鐢熶骇閮�', '甯傚満閮�']
-  departmentData.value = departments.map(dept => ({
-    department: dept,
-    currentStaff: Math.floor(Math.random() * 30 + 20),
-    plannedStaff: Math.floor(Math.random() * 10 + 35),
-    staffingRate: Math.floor(Math.random() * 20 + 80),
-    turnoverRate: (Math.random() * 4 + 1).toFixed(1),
-    attritionRate: (Math.random() * 2 + 0.5).toFixed(1),
-    newHires: Math.floor(Math.random() * 5 + 1),
-    resignations: Math.floor(Math.random() * 3 + 1),
-    status: Math.random() > 0.7 ? '寮傚父' : '姝e父'
-  }))
-}
-
-// 鍒锋柊鏁版嵁
+// 淇敼涓哄紓姝ュ嚱鏁帮紝纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀娓叉煋鍥捐〃
 const refreshData = async () => {
-  loading.value = true
   try {
-    // 妯℃嫙API璋冪敤寤惰繜
-    await new Promise(resolve => setTimeout(resolve, 500))
-    
-    generateMockData()
+    loading.value = true
+
+    // 绛夊緟鎵�鏈夋暟鎹姞杞藉畬鎴�
+    await Promise.all([
+      getDepartmentData(),
+      getStaffLeaveReasonAnalysis(),
+      getMonthlyTurnoverRateFor12Months(),
+      getStaffAnalysisTotalStatistic()
+    ])
+
+    await nextTick()
     renderAllCharts()
-    
+
     if (!autoRefreshEnabled.value) {
       ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
     }
   } catch (error) {
-    console.error('鍒锋柊鏁版嵁澶辫触:', error)
-    ElMessage.error('鍒锋柊鏁版嵁澶辫触')
+    console.error('鏁版嵁鍒锋柊澶辫触:', error)
+    ElMessage.error('鏁版嵁鍒锋柊澶辫触')
   } finally {
     loading.value = false
   }
@@ -276,8 +268,9 @@
     if (attritionChartRef.value) {
       attritionChart = echarts.init(attritionChartRef.value)
     }
-    
-    renderAllCharts()
+
+    // 鍒濆鍖栨椂涔熷厛鍔犺浇鏁版嵁鍐嶆覆鏌撳浘琛�
+    refreshData()
   }, 300)
 }
 
@@ -289,14 +282,15 @@
   renderAttritionChart()
 }
 
-// 娓叉煋鍛樺伐娴佸姩鐜囪秼鍔垮浘
+// 淇敼涓轰娇鐢ˋPI杩斿洖鐨勫疄闄呮暟鎹�
 const renderTurnoverChart = () => {
   if (!turnoverChart) return
-  
-  const months = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
-  const turnoverData = months.map(() => (Math.random() * 5 + 2).toFixed(1))
-  const attritionData = months.map(() => (Math.random() * 3 + 1).toFixed(1))
-  
+
+  // 浣跨敤API杩斿洖鐨勫疄闄呮暟鎹�
+  const months = turnoverRateStatistics.value.map(item => item.month)
+  const turnoverData = turnoverRateStatistics.value.map(item => item.flowRate || 0)
+  const attritionData = turnoverRateStatistics.value.map(item => item.turnoverRate || 0)
+
   const option = {
     title: {
       text: '鍛樺伐娴佸姩鐜囪秼鍔�',
@@ -346,19 +340,19 @@
       }
     ]
   }
-  
+
   turnoverChart.setOption(option)
 }
 
 // 娓叉煋閮ㄩ棬浜哄憳鍒嗗竷鍥�
 const renderDepartmentChart = () => {
   if (!departmentChart) return
-  
+
   const data = departmentData.value.map(item => ({
-    name: item.department,
-    value: item.currentStaff
+    name: item.deptName,
+    value: item.staffCount
   }))
-  
+
   const option = {
     title: {
       text: '閮ㄩ棬浜哄憳鍒嗗竷',
@@ -391,17 +385,17 @@
       }
     ]
   }
-  
+
   departmentChart.setOption(option)
 }
 
 // 娓叉煋缂栧埗杈炬垚鐜囧浘
 const renderStaffingChart = () => {
   if (!staffingChart) return
-  
-  const departments = departmentData.value.map(item => item.department)
+
+  const departments = departmentData.value.map(item => item.deptName)
   const rates = departmentData.value.map(item => item.staffingRate)
-  
+
   const option = {
     title: {
       text: '缂栧埗杈炬垚鐜�',
@@ -445,17 +439,17 @@
       }
     ]
   }
-  
+
   staffingChart.setOption(option)
 }
 
 // 娓叉煋鍛樺伐娴佸け鍘熷洜鍒嗘瀽鍥�
 const renderAttritionChart = () => {
   if (!attritionChart) return
-  
-  const reasons = ['钖祫寰呴亣', '鑱屼笟鍙戝睍', '宸ヤ綔鐜', '涓汉鍘熷洜', '鍏朵粬']
-  const data = reasons.map(() => Math.floor(Math.random() * 20 + 5))
-  
+
+  const reasons = staffLeaveReasons.value.map(item => item.reasonText)
+  const data = staffLeaveReasons.value.map(item => item.count)
+
   const option = {
     title: {
       text: '鍛樺伐娴佸け鍘熷洜鍒嗘瀽',
@@ -491,14 +485,12 @@
       }
     ]
   }
-  
+
   attritionChart.setOption(option)
 }
- 
+
 // 鐢熷懡鍛ㄦ湡
 onMounted(() => {
-  generateMockData()
-  getStaffCount()
   initCharts()
   startAutoRefresh()
 })
@@ -663,32 +655,32 @@
   .analytics-container {
     padding: 10px;
   }
-  
+
   .page-header {
     padding: 15px;
   }
-  
+
   .page-header h2 {
     font-size: 24px;
   }
-  
+
   .header-controls {
     flex-direction: column;
     gap: 15px;
   }
-  
+
   .refresh-btn {
     margin-left: 0;
   }
-  
+
   .metrics-cards .el-col {
     margin-bottom: 15px;
   }
-  
+
   .charts-section .el-col {
     margin-bottom: 20px;
   }
-  
+
   .chart-container {
     height: 300px;
   }
@@ -698,11 +690,11 @@
   .page-header h2 {
     font-size: 20px;
   }
-  
+
   .card-number {
     font-size: 24px;
   }
-  
+
   .chart-container {
     height: 250px;
   }
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
index 3c9674c..54b2ef9 100644
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ b/src/views/personnelManagement/contractManagement/components/formDia.vue
@@ -19,22 +19,24 @@
         </div>
       </template>
     </el-dialog>
+    <Files ref="filesDia"></Files>
   </div>
 </template>
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
+import {findStaffContractListPage} from "@/api/personnelManagement/staffContract.js";
+const Files = defineAsyncComponent(() => import( "@/views/personnelManagement/contractManagement/filesDia.vue"));
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
-
+const filesDia = ref()
 const dialogFormVisible = ref(false);
 const operationType = ref('')
 const tableColumn = ref([
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
+  {
+    label: "鍚堝悓骞撮檺",
+    prop: "contractTerm",
+  },
   {
     label: "鍚堝悓寮�濮嬫棩鏈�",
     prop: "contractStartTime",
@@ -42,6 +44,22 @@
   {
     label: "鍚堝悓缁撴潫鏃ユ湡",
     prop: "contractEndTime",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: 'right',
+    width: 120,
+    operation: [
+      {
+        name: "涓婁紶闄勪欢",
+        type: "text",
+        clickFun: (row) => {
+          filesDia.value.openDialog( row,'鍚堝悓')
+        },
+      }
+    ],
   },
 ]);
 const tableData = ref([]);
@@ -52,12 +70,17 @@
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    staffOnJobInfo({staffNo: row.staffNo}).then(res => {
-      tableData.value = res.data
+    findStaffContractListPage({staffOnJobId: row.id}).then(res => {
+      tableData.value = res.data.records
     })
   }
 }
 
+const openUploadFile = (row) => {
+  filesDia.value.open = true
+  filesDia.value.row = row
+}
+
 // 鍏抽棴寮规
 const closeDia = () => {
   dialogFormVisible.value = false;
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
index f752496..c0c5ee9 100644
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ b/src/views/personnelManagement/contractManagement/filesDia.vue
@@ -30,16 +30,10 @@
           :isSelection="true"
           @selection-change="handleSelectionChange"
           height="500"
+          @pagination="paginationSearch"
+          :total="page.total"
       >
       </PIMTable>
-			<pagination
-				style="margin: 10px 0"
-				v-show="total > 0"
-				@pagination="paginationSearch"
-				:total="total"
-				:page="page.current"
-				:limit="page.size"
-			/>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="closeDia">鍙栨秷</el-button>
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 9fcd73a..1d2aab7 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -74,7 +74,7 @@
 import { onMounted, ref } from "vue";
 import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
 import { ElMessageBox } from "element-plus";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
 import dayjs from "dayjs";
 import { getToken } from "@/utils/auth.js";
 import FilesDia from "./filesDia.vue";
@@ -191,14 +191,7 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
-      },
-      {
-        name: "闄勪欢",
-        type: "text",
-        clickFun: (row) => {
-          openFilesFormDia(row);
-        },
-      },
+      }
     ],
   },
 ]);
@@ -245,6 +238,7 @@
   tableLoading.value = true;
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
+  params.staffState = 1
   staffOnJobListPage(params).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
@@ -272,7 +266,7 @@
     type: "warning",
   })
     .then(() => {
-      proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
+      proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍚堝悓绠$悊.xlsx");
     })
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
index d77eb90..2b8a7fd 100644
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ b/src/views/personnelManagement/dimission/components/formDia.vue
@@ -9,145 +9,143 @@
       <!-- 鍛樺伐淇℃伅灞曠ず鍖哄煙 -->
       <div class="info-section">
         <div class="info-title">鍛樺伐淇℃伅</div>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">濮撳悕锛�</span>
-              <el-select v-model="form.staffName" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">
-                <el-option
-                  v-for="item in personList"
-                  :key="item.id"
-                  :label="item.staffName"
-                  :value="item.staffName"
+        <el-form :model="form" label-width="200px" label-position="left" :rules="rules" ref="formRef" style="margin-top: 20px">
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="濮撳悕锛�" prop="staffOnJobId">
+                <el-select v-model="form.staffOnJobId"
+                           placeholder="璇烽�夋嫨浜哄憳"
+                           style="width: 100%"
+                           :disabled="operationType === 'edit'"
+                           @change="handleSelect">
+                  <el-option
+                      v-for="item in personList"
+                      :key="item.id"
+                      :label="item.staffName"
+                      :value="item.id"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍛樺伐缂栧彿锛�">
+                {{ currentStaffRecord.staffNo || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="鎬у埆锛�">
+                {{ currentStaffRecord.sex || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鎴风睄浣忓潃锛�">
+                {{ currentStaffRecord.nativePlace || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="宀椾綅锛�">
+                {{ currentStaffRecord.postName || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鐜颁綇鍧�锛�">
+                {{ currentStaffRecord.adress || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绗竴瀛﹀巻锛�">
+                {{ currentStaffRecord.firstStudy || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="涓撲笟锛�">
+                {{ currentStaffRecord.profession || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="骞撮緞锛�">
+                {{ currentStaffRecord.age || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="鑱旂郴鐢佃瘽锛�">
+                {{ currentStaffRecord.phone || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="绱ф�ヨ仈绯讳汉锛�">
+                {{ currentStaffRecord.emergencyContact || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�">
+                {{ currentStaffRecord.emergencyContactPhone || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绂昏亴鍘熷洜锛�" prop="reason">
+                <el-select v-model="form.reason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
+                  <el-option
+                      v-for="(item, index) in dimissionReasonOptions"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="澶囨敞锛�" prop="remark" v-if="form.reason === 'other'">
+                <el-input
+                    v-model="form.remark"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="澶囨敞"
+                    maxlength="500"
+                    show-word-limit
                 />
-              </el-select>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍛樺伐缂栧彿锛�</span>
-              <span class="info-value">{{ form.staffNo || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鎬у埆锛�</span>
-              <span class="info-value">{{ form.sex || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鎴风睄浣忓潃锛�</span>
-              <span class="info-value">{{ form.nativePlace || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">宀椾綅锛�</span>
-              <span class="info-value">{{ form.postJob || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鐜颁綇鍧�锛�</span>
-              <span class="info-value">{{ form.adress || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绗竴瀛﹀巻锛�</span>
-              <span class="info-value">{{ form.firstStudy || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">涓撲笟锛�</span>
-              <span class="info-value">{{ form.profession || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">骞撮緞锛�</span>
-              <span class="info-value">{{ form.age || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鑱旂郴鐢佃瘽锛�</span>
-              <span class="info-value">{{ form.phone || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绱ф�ヨ仈绯讳汉锛�</span>
-              <span class="info-value">{{ form.emergencyContact || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�</span>
-              <span class="info-value">{{ form.emergencyContactPhone || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍚堝悓寮�濮嬫棩鏈燂細</span>
-              <span class="info-value">{{ form.contractStartTime || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-              <span class="info-value">{{ form.contractEndTime || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+
+<!--        <el-row :gutter="30">-->
+<!--          <el-col :span="12">-->
+<!--            <div class="info-item">-->
+<!--              <span class="info-label">绂昏亴鍘熷洜锛�</span>-->
+<!--              <el-select v-model="form.reason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
+<!--                <el-option-->
+<!--                    v-for="(item, index) in dimissionReasonOptions"-->
+<!--                    :key="index"-->
+<!--                    :label="item.label"-->
+<!--                    :value="item.value"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </div>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <div class="info-item">-->
+<!--              <span class="info-label">鍛樺伐缂栧彿锛�</span>-->
+<!--              <span class="info-value">{{ form.staffNo || '-' }}</span>-->
+<!--            </div>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
       </div>
 
-      <!-- 绂昏亴淇℃伅濉啓鍖哄煙 -->
-      <!-- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef" style="margin-top: 20px">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绂昏亴鏃ユ湡锛�" prop="dimissionDate">
-              <el-date-picker
-                v-model="form.dimissionDate"
-                type="date"
-                placeholder="璇烽�夋嫨绂昏亴鏃ユ湡"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                clearable
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绂昏亴鍘熷洜锛�" prop="dimissionReason">
-              <el-input
-                v-model="form.dimissionReason"
-                type="textarea"
-                :rows="3"
-                placeholder="璇疯緭鍏ョ鑱屽師鍥�"
-                maxlength="500"
-                show-word-limit
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form> -->
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitForm">纭</el-button>
@@ -160,8 +158,8 @@
 
 <script setup>
 import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {createStaffLeave, updateStaffLeave} from "@/api/personnelManagement/staffLeave.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -169,86 +167,80 @@
 const operationType = ref('')
 const data = reactive({
   form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   },
   rules: {
-    staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳", trigger: "change" }],
-    dimissionDate: [{ required: true, message: "璇烽�夋嫨绂昏亴鏃ユ湡", trigger: "change" }],
-    dimissionReason: [{ required: true, message: "璇疯緭鍏ョ鑱屽師鍥�", trigger: "blur" }],
+    staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳" }],
+    reason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
   },
+  dimissionReasonOptions: [
+      {label: '钖祫寰呴亣', value: 'salary'},
+      {label: '鑱屼笟鍙戝睍', value: 'career_development'},
+      {label: '宸ヤ綔鐜', value: 'work_environment'},
+      {label: '涓汉鍘熷洜', value: 'personal_reason'},
+      {label: '鍏朵粬', value: 'other'},
+  ],
+  currentStaffRecord: {},
 });
-const { form, rules } = toRefs(data);
+const { form, rules, dimissionReasonOptions, currentStaffRecord } = toRefs(data);
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
-  getList()
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-    })
+    currentStaffRecord.value = row
+    form.value.staffOnJobId = row.staffOnJobId
+    form.value.reason = row.reason
+    form.value.remark = row.remark
+    personList.value = [
+      {
+        staffName: row.staffName,
+        id: row.staffOnJobId,
+      }
+    ]
+  } else {
+    getList()
+  }
+}
+
+const handleSelectDimissionReason = (val) => {
+  if (val === 'other') {
+    form.value.remark = ''
   }
 }
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
-  // 琛ㄥ崟宸叉敞閲婏紝鐩存帴鎻愪氦锛屼笉杩涜楠岃瘉
-  if (!form.value.staffName) {
-    proxy.$modal.msgError("璇烽�夋嫨浜哄憳");
-    return;
-  }
   form.value.staffState = 0
-  if (operationType.value === "add") {
-    staffJoinAdd(form.value).then(res => {
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-    })
-  } else {
-    staffJoinUpdate(form.value).then(res => {
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-    })
+  if (form.value.reason !== 'other') {
+    form.value.remark = ''
   }
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      if (operationType.value === "add") {
+        createStaffLeave(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      } else {
+        updateStaffLeave(currentStaffRecord.value.id, form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      }
+    }
+  })
+
 }
 // 鍏抽棴寮规
 const closeDia = () => {
   // 琛ㄥ崟宸叉敞閲婏紝鎵嬪姩閲嶇疆琛ㄥ崟鏁版嵁
   form.value = {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   };
   dialogFormVisible.value = false;
   emit('close')
@@ -270,44 +262,11 @@
 };
 
 const handleSelect = (val) => {
-  let obj = personList.value.find(item => item.staffName === val)
+  let obj = personList.value.find(item => item.id === val)
+  currentStaffRecord.value = {}
   if (obj) {
-    let {
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postJob,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractEndTime,
-      staffName
-    } = obj
     // 淇濈暀绂昏亴鏃ユ湡鍜岀鑱屽師鍥狅紝鍙洿鏂板憳宸ヤ俊鎭�
-    form.value = {
-      ...form.value,
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postJob,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractEndTime,
-      staffName
-    }
+    currentStaffRecord.value = obj
   }
 }
 defineExpose({
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
index ae90d99..c6ed705 100644
--- a/src/views/personnelManagement/dimission/index.vue
+++ b/src/views/personnelManagement/dimission/index.vue
@@ -11,22 +11,6 @@
             clearable
             :prefix-icon="Search"
         />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
         <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
         >鎼滅储</el-button
         >
@@ -58,9 +42,8 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
 import FormDia from "@/views/personnelManagement/dimission/components/formDia.vue";
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {findStaffLeaveListPage, batchDeleteStaffLeaves} from "@/api/personnelManagement/staffLeave.js";
 import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
 
 const data = reactive({
   searchForm: {
@@ -109,8 +92,12 @@
     prop: "nativePlace",
   },
   {
+    label: "閮ㄩ棬",
+    prop: "deptName",
+  },
+  {
     label: "宀椾綅",
-    prop: "postJob",
+    prop: "postName",
   },
   {
     label: "鐜颁綇鍧�",
@@ -145,24 +132,11 @@
     prop: "emergencyContactPhone",
     width:150
   },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
+    fixed: 'right',
     operation: [
       {
         name: "缂栬緫",
@@ -186,20 +160,6 @@
 const { proxy } = getCurrentInstance()
 
 
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
@@ -213,7 +173,7 @@
 };
 const getList = () => {
   tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 0}).then(res => {
+  findStaffLeaveListPage({...page, ...searchForm.value}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
@@ -248,7 +208,7 @@
     type: "warning",
   })
       .then(() => {
-        staffJoinDel(ids).then((res) => {
+        batchDeleteStaffLeaves(ids).then((res) => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
@@ -265,7 +225,7 @@
     type: "warning",
   })
       .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 0}, "浜哄憳绂昏亴.xlsx");
+        proxy.download("/staff/staffLeave/export", {}, "浜哄憳绂昏亴.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
similarity index 77%
rename from src/views/personnelManagement/onboarding/components/formDia.vue
rename to src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
index a13d6ba..06eee04 100644
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -36,13 +36,40 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="postJob">
-              <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
+            <el-form-item label="宀椾綅锛�" prop="sysPostId">
+              <el-select v-model="form.sysPostId" placeholder="璇烽�夋嫨宀椾綅" clearable>
+                <el-option
+                    v-for="item in postOptions"
+                    :key="item.postId"
+                    :label="item.postName"
+                    :value="item.postId"
+                    :disabled="item.status === '1'"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
               <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="閮ㄩ棬锛�" prop="sysDeptId">
+              <el-tree-select
+                  v-model="form.sysDeptId"
+                  :data="deptOptions"
+                  :props="{ value: 'id', label: 'label', children: 'children' }"
+                  value-key="id"
+                  placeholder="璇烽�夋嫨閮ㄩ棬"
+                  check-strictly
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="骞撮緞锛�" prop="age">
+              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -55,13 +82,6 @@
           <el-col :span="12">
             <el-form-item label="涓撲笟锛�" prop="profession">
               <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -131,13 +151,17 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
+import {ref, onMounted} from "vue";
+import {findPostOptions} from "@/api/system/post.js";
+import {listDept} from "@/api/system/dept.js";
+import {staffOnJobInfo, createStaffOnJob, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
+import {deptTreeSelect} from "@/api/system/user.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
 const dialogFormVisible = ref(false);
 const operationType = ref('')
+const id = ref(0)
 const data = reactive({
   form: {
     staffNo: "",
@@ -156,6 +180,8 @@
     contractStartTime: "",
     contractEndTime: "",
     staffState: "",
+    sysPostId: undefined,
+    sysDeptId: undefined,
   },
   rules: {
     staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -174,35 +200,76 @@
     contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
   },
+  postOptions: [], // 宀椾綅閫夐」
+  deptOptions: [], // 閮ㄩ棬閫夐」
 });
-const { form, rules } = toRefs(data);
+const { form, rules, postOptions, deptOptions } = toRefs(data);
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
+    id.value = row.id
+    staffOnJobInfo(id.value, {}).then(res => {
       form.value = {...res.data}
+      if (form.value.sysPostId === 0) {
+        form.value.sysPostId = undefined
+      }
       // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
       calculateContractTerm();
     })
   } else {
 		form.value.id = ''
 	}
+
 }
+onMounted(() => {
+  fetchPostOptions()
+  fetchDeptOptions()
+})
+
+const fetchPostOptions = () => {
+  findPostOptions().then(res => {
+    postOptions.value = res.data
+  })
+}
+
+// 鏌ヨ閮ㄩ棬鍒楄〃
+const fetchDeptOptions = () => {
+  deptTreeSelect().then(response => {
+    deptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
+  })
+}
+
+/** 杩囨护绂佺敤鐨勯儴闂� */
+function filterDisabledDept(deptList) {
+  return deptList.filter(dept => {
+    if (dept.disabled) {
+      return false
+    }
+    if (dept.children && dept.children.length) {
+      dept.children = filterDisabledDept(dept.children)
+    }
+    return true
+  })
+}
+
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
+  if (!form.value.sysPostId) {
+    form.value.sysPostId = 0;
+  }
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.staffState = 1
       if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
+        createStaffOnJob(form.value).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
       } else {
-        staffJoinUpdate(form.value).then(res => {
+        updateStaffOnJob(id.value, form.value).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
diff --git a/src/views/personnelManagement/employeeRecord/components/RenewContract.vue b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
new file mode 100644
index 0000000..9c2acfc
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
@@ -0,0 +1,141 @@
+<template>
+  <el-dialog
+      v-model="isShow"
+      title="缁鍚堝悓"
+      width="800px"
+      @close="closeModal"
+  >
+    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+      <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
+        <el-date-picker
+            v-model="form.contractStartTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
+        <el-date-picker
+            v-model="form.contractEndTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
+        <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭</el-button>
+        <el-button @click="closeModal">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+// 缁鍚堝悓
+import { renewContract } from "@/api/personnelManagement/staffOnJob.js";
+import {computed, getCurrentInstance,} from "vue";
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const data = reactive({
+  form: {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  },
+  rules: {
+    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  }
+});
+const { form, rules } = toRefs(data);
+let { proxy } = getCurrentInstance()
+
+const props = defineProps({
+  id: {
+    type: Number,
+    default: 0,
+  },
+
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+})
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+// 璁$畻鍚堝悓骞撮檺
+const calculateContractTerm = () => {
+  if (form.value.contractStartTime && form.value.contractEndTime) {
+    const startDate = new Date(form.value.contractStartTime);
+    const endDate = new Date(form.value.contractEndTime);
+
+    if (endDate > startDate) {
+      // 璁$畻骞翠唤宸�
+      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+      const monthDiff = endDate.getMonth() - startDate.getMonth();
+      const dayDiff = endDate.getDate() - startDate.getDate();
+
+      let years = yearDiff;
+
+      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+        years = yearDiff - 1;
+      }
+
+      form.value.contractTerm = Math.max(0, years);
+    } else {
+      form.value.contractTerm = 0;
+    }
+  } else {
+    form.value.contractTerm = 0;
+  }
+};
+
+const submitForm = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      renewContract(props.id, form.value).then(res => {
+        if (res.code === 200) {
+          proxy.$modal.msgSuccess("缁鍚堝悓鎴愬姛");
+          emit('completed');
+          closeModal();
+        }
+      })
+    }
+  })
+}
+
+// 鍏抽棴寮规
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  form.value = {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  };
+  isShow.value = false;
+};
+</script>
diff --git a/src/views/personnelManagement/employeeRecord/components/formDia.vue b/src/views/personnelManagement/employeeRecord/components/Show.vue
similarity index 94%
rename from src/views/personnelManagement/employeeRecord/components/formDia.vue
rename to src/views/personnelManagement/employeeRecord/components/Show.vue
index 3c9674c..9220d45 100644
--- a/src/views/personnelManagement/employeeRecord/components/formDia.vue
+++ b/src/views/personnelManagement/employeeRecord/components/Show.vue
@@ -24,7 +24,7 @@
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
+import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index 5a0d07c..19addfa 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -19,9 +19,9 @@
         >
       </div>
       <div>
-<!--        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>-->
+        <el-button type="primary" @click="openFormNewOrEditFormDia('add')">鏂板鍏ヨ亴</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-<!--        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
     </div>
     <div class="table_list">
@@ -37,17 +37,26 @@
           :total="page.total"
       ></PIMTable>
     </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
+    <show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
+    <new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
+    <renew-contract
+        v-if="isShowRenewContractModal"
+        v-model:visible="isShowRenewContractModal"
+        :id="id"
+        @completed="handleQuery"
+    />
   </div>
 </template>
 
 <script setup>
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/employeeRecord/components/formDia.vue";
 import {ElMessageBox} from "element-plus";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
+import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 import dayjs from "dayjs";
+const NewOrEditFormDia = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"));
+const ShowFormDia = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/Show.vue"));
+const RenewContract = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/RenewContract.vue"));
 
 const data = reactive({
   searchForm: {
@@ -58,6 +67,8 @@
   },
 });
 const { searchForm } = toRefs(data);
+const isShowRenewContractModal = ref(false);
+const id = ref(0);
 const tableColumn = ref([
   {
     label: "鐘舵��",
@@ -97,6 +108,10 @@
   {
     label: "鎴风睄浣忓潃",
     prop: "nativePlace",
+  },
+  {
+    label: "閮ㄩ棬",
+    prop: "deptName",
   },
   {
     label: "宀椾綅",
@@ -154,14 +169,31 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: 'right',
+    width: 180,
     operation: [
       {
-        name: "璇︽儏",
+        name: "缂栬緫",
         type: "text",
         clickFun: (row) => {
-          openForm("edit", row);
+          openFormNewOrEditFormDia("edit", row);
         },
       },
+      {
+        name: "缁鍚堝悓",
+        type: "text",
+        showHide: row => row.staffState === 1,
+        clickFun: (row) => {
+          isShowRenewContractModal.value = true;
+          id.value = row.id;
+        },
+      },
+      // {
+      //   name: "璇︽儏",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openForm("edit", row);
+      //   },
+      // },
     ],
   },
 ]);
@@ -174,6 +206,7 @@
   total: 0
 });
 const formDia = ref()
+const formDiaNewOrEditFormDia = ref()
 const { proxy } = getCurrentInstance()
 
 const changeDaterange = (value) => {
@@ -200,7 +233,7 @@
   tableLoading.value = true;
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
-  staffOnJobListPage({...params, staffState: 1}).then(res => {
+  staffOnJobListPage({...params}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
@@ -219,6 +252,37 @@
     formDia.value?.openDialog(type, row)
   })
 };
+const openFormNewOrEditFormDia = (type, row) => {
+  nextTick(() => {
+    formDiaNewOrEditFormDia.value?.openDialog(type, row)
+  })
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+  let ids = [];
+  if (selectedRows.value.length > 0) {
+    ids = selectedRows.value.map((item) => item.id);
+  } else {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        batchDeleteStaffOnJobs(ids).then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
 // 瀵煎嚭
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -227,7 +291,7 @@
     type: "warning",
   })
       .then(() => {
-        proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍦ㄨ亴鍛樺伐鍙拌处.xlsx");
+        proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍛樺伐鍙拌处.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue b/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
deleted file mode 100644
index fa0c9e6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
+++ /dev/null
@@ -1,386 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
-              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="濮撳悕锛�" prop="staffName">
-              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鎬у埆锛�" prop="sex">
-              <el-select v-model="form.sex">
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="濂�" value="濂�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="postJob">
-              <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
-              <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
-              <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓撲笟锛�" prop="profession">
-              <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
-              <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
-              <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓绛捐鏃ユ湡锛�" prop="trialStartDate">
-              <el-date-picker
-                  v-model="form.trialStartDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="鍔冲姩鍚堝悓鏈熼檺閫夋嫨锛�" prop="dateSelect">
-              <el-radio-group v-model="form.dateSelect">
-                <el-radio :value="'A'">
-                  A銆佹湁鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'B'">
-                  B銆佹棤鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'C'">
-                  C銆佷互瀹屾垚涓�瀹氬伐浣滀换鍔′负鏈熼檺
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30" v-if="showProbationDates">
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熷紑濮嬫棩鏈燂細" prop="signDate">
-              <el-date-picker
-                  v-model="form.signDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熺粨鏉熸棩鏈燂細" prop="trialEndDate">
-              <el-date-picker
-                  v-model="form.trialEndDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-<!--        <el-row :gutter="30">-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">-->
-<!--              <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
-              <el-date-picker
-                  v-model="form.contractStartTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12" v-if="showContractEnd">
-            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
-              <el-date-picker
-                  v-model="form.contractEndTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="璇曠敤鏈熷伐璧勶細" prop="proSalary">
-							<el-input-number placeholder="璇疯緭鍏ヨ瘯鐢ㄦ湡宸ヨ祫" :precision="2"
-															 :step="100"
-															 :min="0" v-model="form.proSalary" style="width: 100%"/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="宸ヨ祫鎶ラ叕锛�" prop="salarySelect">
-              <el-radio-group v-model="form.salarySelect" class="salary-radio-group">
-                <el-radio :value="'A'" class="salary-radio-item">
-                  A銆佷箼鏂圭殑宸ヨ祫鎶ラ叕鎸夌収鐢叉柟渚濇硶鍒跺畾鐨勮绔犲埗搴︿腑鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曠‘瀹氾紝鏍规嵁涔欐柟鐨勫伐浣滃矖浣嶇‘瀹氬叾姣忔湀宸ヨ祫銆�
-                </el-radio>
-                <el-radio :value="'B'" class="salary-radio-item">
-                  B銆佺敳鏂瑰涔欐柟瀹炶鍩烘湰宸ヨ祫鍜岀哗鏁堝伐璧勭浉缁撳悎鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曪紝涔欐柟鐨勬敹鍏ュ寘鎷熀鏈伐璧勩�佽椁愩�佷氦閫氥�佺敓娲讳綇瀹跨瓑鍚勯」琛ュ姪锛屽鏈夊彉鍔ㄦ牴鎹唴閮ㄥ伐璧勫垎閰嶅姙娉曡皟鏁村叾宸ヨ祫锛涚哗鏁堝伐璧勬牴鎹箼鏂圭殑宸ヤ綔涓氱哗銆佸姵鍔ㄦ垚鏋滃拰瀹為檯璐$尞鎸夌収鍐呴儴鍒嗛厤鍔炴硶鑰冩牳纭畾銆�
-                </el-radio>
-                <el-radio :value="'C'" class="salary-radio-item">
-                  C銆佺敳鏂瑰疄琛岃浠跺伐璧勫埗锛屼互鐢叉柟鎺ュ埌璁㈠崟鍙婂叕鍙哥敓浜ц鍒掞紝鎸夌収瀹氶鍜岃浠跺崟浠凤紝鏍规嵁涔欐柟瀹屾垚鐨勪笟缁╋紝鎸夋椂瓒抽鏀粯涔欐柟鐨勫伐璧勬姤閰��
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="绂忓埄寰呴亣锛�" prop="remark">
-							<el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance, computed, watch} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
-  form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    dateSelect: "",
-    signDate: "",
-    trialEndDate: "",
-    proSalary: null,
-    trialStartDate: "",
-    salarySelect: "",
-    // contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    staffState: "",
-  },
-  rules: {
-    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		remark: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    dateSelect: [{ required: true, message: "璇烽�夋嫨鍔冲姩鍚堝悓鏈熼檺", trigger: "change" }],
-    signDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    trialEndDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    trialStartDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    salarySelect: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鎶ラ叕鏂瑰紡", trigger: "change" }],
-    // contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-});
-const { form, rules } = toRefs(data);
-
-const showContractEnd = computed(() => form.value.dateSelect === "A");
-const showProbationDates = computed(() => form.value.dateSelect === "A" || form.value.dateSelect === "B");
-
-watch(() => form.value.dateSelect, (type) => {
-  if (type !== "A") {
-    form.value.contractEndTime = "";
-  }
-
-  if (type === "C") {
-    form.value.signDate = "";
-    form.value.trialEndDate = "";
-    form.value.proSalary = null;
-  }
-}, { immediate: true });
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
-      // calculateContractTerm();
-    })
-  }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
-  proxy.$refs.formRef.validate(valid => {
-    if (valid) {
-      form.value.staffState = 1
-      if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      } else {
-        staffJoinUpdate(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      }
-    }
-  })
-}
-// 璁$畻鍚堝悓骞撮檺
-// const calculateContractTerm = () => {
-//   if (form.value.contractStartTime && form.value.contractEndTime) {
-//     const startDate = new Date(form.value.contractStartTime);
-//     const endDate = new Date(form.value.contractEndTime);
-//
-//     if (endDate > startDate) {
-//       // 璁$畻骞翠唤宸�
-//       const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-//       const monthDiff = endDate.getMonth() - startDate.getMonth();
-//       const dayDiff = endDate.getDate() - startDate.getDate();
-//
-//       let years = yearDiff;
-//
-//       // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-//       if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-//         years = yearDiff - 1;
-//       }
-//
-//       form.value.contractTerm = Math.max(0, years);
-//     } else {
-//       form.value.contractTerm = 0;
-//     }
-//   } else {
-//     form.value.contractTerm = 0;
-//   }
-// };
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-.salary-radio-group {
-  display: flex;
-  gap: 12px;
-}
-
-.salary-radio-item {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  align-items: flex-start;
-}
-
-.salary-radio-item :deep(.el-radio__label) {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  padding-left: 8px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
deleted file mode 100644
index 9151a6c..0000000
--- a/src/views/personnelManagement/onboarding/index.vue
+++ /dev/null
@@ -1,280 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="search_form">
-      <div>
-        <span class="search_title">濮撳悕锛�</span>
-        <el-input
-          v-model="searchForm.staffName"
-          style="width: 240px"
-          placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
-          @change="handleQuery"
-          clearable
-          :prefix-icon="Search"
-        />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-          >鎼滅储</el-button
-        >
-      </div>
-      <div>
-        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-    </div>
-    <div class="table_list">
-      <PIMTable
-        rowKey="id"
-        :column="tableColumn"
-        :tableData="tableData"
-        :page="page"
-        :isSelection="true"
-        @selection-change="handleSelectionChange"
-        :tableLoading="tableLoading"
-        @pagination="pagination"
-        :total="page.total"
-      ></PIMTable>
-    </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
-  </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
-// import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 鏂扮枂椋熷搧鍏徃鐢ㄧ殑琛ㄥ崟
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-
-const data = reactive({
-  searchForm: {
-    staffName: "",
-  },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
-  {
-    label: "鐘舵��",
-    prop: "staffState",
-    dataType: "tag",
-    formatData: (params) => {
-      if (params == 0) {
-        return "绂昏亴";
-      } else if (params == 1) {
-        return "鍏ヨ亴";
-      } else {
-        return null;
-      }
-    },
-    formatType: (params) => {
-      if (params == 0) {
-        return "danger";
-      } else if (params == 1) {
-        return "primary";
-      } else {
-        return null;
-      }
-    },
-  },
-  {
-    label: "鍛樺伐缂栧彿",
-    prop: "staffNo",
-  },
-  {
-    label: "濮撳悕",
-    prop: "staffName",
-  },
-  {
-    label: "鎬у埆",
-    prop: "sex",
-  },
-  {
-    label: "鎴风睄浣忓潃",
-    prop: "nativePlace",
-  },
-  {
-    label: "宀椾綅",
-    prop: "postJob",
-  },
-  {
-    label: "鐜颁綇鍧�",
-    prop: "adress",
-    width:200
-  },
-  {
-    label: "绗竴瀛﹀巻",
-    prop: "firstStudy",
-  },
-  {
-    label: "涓撲笟",
-    prop: "profession",
-    width:100
-  },
-  {
-    label: "骞撮緞",
-    prop: "age",
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "phone",
-    width:150
-  },
-  {
-    label: "绱ф�ヨ仈绯讳汉",
-    prop: "emergencyContact",
-    width: 120
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "emergencyContactPhone",
-    width:150
-  },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    fixed: 'right',
-    operation: [
-      {
-        name: "缂栬緫",
-        type: "text",
-        clickFun: (row) => {
-          openForm("edit", row);
-        },
-      },
-    ],
-  },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0,
-});
-const formDia = ref()
-const { proxy } = getCurrentInstance()
-
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
-    tableLoading.value = false;
-    tableData.value = res.data.records
-    page.total = res.data.total;
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  nextTick(() => {
-    formDia.value?.openDialog(type, row)
-  })
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        staffJoinDel(ids).then((res) => {
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-          getList();
-        });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/payrollManagement/components/formDia.vue b/src/views/personnelManagement/payrollManagement/components/formDia.vue
index e4cf0b3..cf93559 100644
--- a/src/views/personnelManagement/payrollManagement/components/formDia.vue
+++ b/src/views/personnelManagement/payrollManagement/components/formDia.vue
@@ -168,8 +168,8 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js";
+import {staffOnJobInfo, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -234,12 +234,16 @@
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
-	getStaffOnJob().then(res => {
-		personList.value = res.data
-	})
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
+  })
 	form.value = {}
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
+    staffOnJobInfo(row.staffId).then(res => {
 			form.value = {...row}
 			form.value.payDate = form.value.payDate + '-01'
     })
diff --git a/src/views/personnelManagement/payrollManagement/index.vue b/src/views/personnelManagement/payrollManagement/index.vue
index 24e3dd8..f17f42e 100644
--- a/src/views/personnelManagement/payrollManagement/index.vue
+++ b/src/views/personnelManagement/payrollManagement/index.vue
@@ -53,7 +53,6 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue";
-import {staffJoinDel} from "@/api/personnelManagement/onboarding.js";
 import {ElMessageBox} from "element-plus";
 import dayjs from "dayjs";
 import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js";
diff --git a/src/views/personnelManagement/scheduling/index.vue b/src/views/personnelManagement/scheduling/index.vue
index 251dbe9..19d2062 100644
--- a/src/views/personnelManagement/scheduling/index.vue
+++ b/src/views/personnelManagement/scheduling/index.vue
@@ -253,9 +253,9 @@
 import {useDict} from "@/utils/dict.js"
 import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue'
 import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js"
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
 import pagination from "@/components/PIMTable/Pagination.vue";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 const { proxy } = getCurrentInstance();
 
@@ -317,8 +317,12 @@
  * 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
  */
 const getPersonList = () => {
-  getStaffOnJob().then(res => {
-    personList.value = res.data
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
   })
 };
 const paginationChange = (obj) => {
diff --git a/src/views/personnelManagement/selfService/index.vue b/src/views/personnelManagement/selfService/index.vue
index ca683c0..647f149 100644
--- a/src/views/personnelManagement/selfService/index.vue
+++ b/src/views/personnelManagement/selfService/index.vue
@@ -221,8 +221,7 @@
 
 const { proxy } = getCurrentInstance()
 import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinUpdate, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import { fa, id } from 'element-plus/es/locales.mjs'
+import {staffOnJobListPage, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
 
 const tableLoading = ref(false)
 // 鍒嗛〉鍙傛暟
@@ -572,7 +571,7 @@
       currentUser.value = res.data
       // console.log("----",currentUser.value)
         //寰楀埌浜哄憳鍒楄〃
-        staffJoinListPage({staffState: 1}).then(res => {
+      staffOnJobListPage({staffState: 1}).then(res => {
           //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
           // let tableData = res.data.records
           user.value = res.data.records.find(item => item.staffName === currentUser.value.userName)
@@ -604,18 +603,15 @@
     const userRes = await getUserProfile();
     if (userRes.code === 200) {
       currentUser.value = userRes.data;
-      const staffListRes = await staffJoinListPage({ staffState: 1 });
+      const staffListRes = await staffOnJobListPage({ staffState: 1 });
       user.value = staffListRes.data.records.find(item => item.staffName === currentUser.value.userName);
-      // console.log("++++", user.value);
-
       Object.assign(joinForm, user.value);
       joinForm.staffName = profileForm.name;
       joinForm.phone = profileForm.phone;
       joinForm.email = profileForm.email;
       joinForm.adress = profileForm.adress; 
-      console.log(joinForm)
       // 璋冪敤鏇存柊涓汉淇℃伅鐨勬帴鍙�
-      staffJoinUpdate(joinForm).then(res => {
+      updateStaffOnJob(user.value.id, joinForm).then(res => {
         if (res.code === 200) {
           ElMessage.success('涓汉淇℃伅淇濆瓨鎴愬姛');
           getProfile();
diff --git a/src/views/procurementManagement/advancedPriceManagement/index.vue b/src/views/procurementManagement/advancedPriceManagement/index.vue
index 597b39b..84bd160 100644
--- a/src/views/procurementManagement/advancedPriceManagement/index.vue
+++ b/src/views/procurementManagement/advancedPriceManagement/index.vue
@@ -139,7 +139,7 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" width="800px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" :width="'800px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" :rules="formRules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -266,14 +266,10 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 鎵归噺鎶樻墸瀵硅瘽妗� -->
-    <el-dialog v-model="batchDiscountVisible" title="鎵归噺璁剧疆鎶樻墸" width="600px">
+    <FormDialog v-model="batchDiscountVisible" title="鎵归噺璁剧疆鎶樻墸" :width="'600px'" @close="batchDiscountVisible = false" @confirm="handleBatchDiscount" @cancel="batchDiscountVisible = false">
       <el-form :model="batchDiscountForm" label-width="120px">
         <el-form-item label="鎶樻墸绫诲瀷">
           <el-select v-model="batchDiscountForm.discountType" placeholder="璇烽�夋嫨鎶樻墸绫诲瀷" style="width: 100%">
@@ -303,14 +299,10 @@
           </div>
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="batchDiscountVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleBatchDiscount">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 浠锋牸鎺у埗瀵硅瘽妗� -->
-    <el-dialog v-model="priceControlVisible" title="浠锋牸鎺у埗璁剧疆" width="700px">
+    <FormDialog v-model="priceControlVisible" title="浠锋牸鎺у埗璁剧疆" :width="'700px'" @close="priceControlVisible = false" @confirm="handlePriceControl" @cancel="priceControlVisible = false">
       <el-form :model="priceControlForm" label-width="120px">
         <el-form-item label="榛樿鏈�浣庝环鏍�">
           <el-input-number v-model="priceControlForm.defaultMinPrice" :min="0" :precision="2" style="width: 200px" />
@@ -322,16 +314,13 @@
           <el-input-number v-model="priceControlForm.changeThreshold" :min="0" :max="100" :precision="1" style="width: 200px" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="priceControlVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handlePriceControl">淇濆瓨璁剧疆</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import {
diff --git a/src/views/procurementManagement/arrivalManagement/index.vue b/src/views/procurementManagement/arrivalManagement/index.vue
index 060d2f1..a1b5eed 100644
--- a/src/views/procurementManagement/arrivalManagement/index.vue
+++ b/src/views/procurementManagement/arrivalManagement/index.vue
@@ -51,7 +51,7 @@
       />
     </el-card>
 
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板鍒拌揣' : '缂栬緫鍒拌揣'" width="600px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板鍒拌揣' : '缂栬緫鍒拌揣'" :width="'600px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" label-width="120px">
         <el-form-item label="鍒拌揣鍗曞彿">
           <el-input v-model="formData.arrivalNo" placeholder="鍒拌揣鍗曞彿" />
@@ -69,15 +69,12 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive,onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import {listPage,add,update,del} from "@/api/procurementManagement/arrivalManagement.js"
diff --git a/src/views/procurementManagement/invoiceEntry/components/Modal.vue b/src/views/procurementManagement/invoiceEntry/components/Modal.vue
index f29b78a..2288183 100644
--- a/src/views/procurementManagement/invoiceEntry/components/Modal.vue
+++ b/src/views/procurementManagement/invoiceEntry/components/Modal.vue
@@ -1,160 +1,202 @@
 <template>
-  <el-dialog :title="modalOptions.title" v-model="visible" width="70%">
-    <el-form
-      ref="formRef"
-      :model="form"
-      :rules="rules"
-      label-width="120px"
-      label-position="top"
-    >
-      <el-row :gutter="30">
-        <el-col :span="12">
-          <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseLedgerNo">
-            <el-input v-model="form.purchaseLedgerNo" disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-            <el-input
-              v-model="form.salesContractNo"
-              placeholder="鑷姩濉厖"
-              clearable
-              disabled
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
-            <el-input
-              v-model="form.supplierName"
-              placeholder="鑷姩濉厖"
-              clearable
-              disabled
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-            <el-input
-              v-model="form.projectName"
-              placeholder="鑷姩濉厖"
-              clearable
-              disabled
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
-            <el-input
-              v-model="form.invoiceNumber"
-              placeholder="璇疯緭鍏�"
-              clearable
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
-            <el-input-number :step="0.01" :min="0" style="width: 100%"
-              v-model="form.invoiceAmount"
-              placeholder="鑷姩濉厖"
-              clearable
-              :disabled="true"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="褰曞叆浜猴細" prop="issUer">
-            <el-input
-              v-model="form.issUer"
-              placeholder="璇疯緭鍏�"
-              clearable
-              disabled
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="寮�绁ㄦ棩鏈燂細" prop="entryDate">
-            <el-date-picker
-              style="width: 100%"
-              v-model="form.entryDate"
-              type="date"
-              value-format="YYYY-MM-DD"
-              format="YYYY-MM-DD"
-              clearable
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="涓婁紶闄勪欢">
-            <FileUpload
-              :showTip="false"
-              accept="*"
-              :autoUpload="true"
-              :action="action"
-              :headers="{
+	<el-dialog :title="modalOptions.title" v-model="visible" width="70%" draggable>
+		<el-form
+			ref="formRef"
+			:model="form"
+			:rules="rules"
+			label-width="120px"
+			label-position="top"
+		>
+			<el-row :gutter="30">
+				<el-col :span="12">
+					<el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseLedgerNo">
+						<el-input v-model="form.purchaseLedgerNo" disabled placeholder="澶氬悎鍚屾壒閲忓鐞嗭紙鍏蜂綋鍚堝悓鍙疯浜у搧鍒楄〃锛�" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
+						<el-input
+							v-model="form.salesContractNo"
+							placeholder="鑷姩濉厖"
+							clearable
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
+						<el-input
+							v-model="form.supplierName"
+							placeholder="鑷姩濉厖"
+							clearable
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+<!--				<el-col :span="12">-->
+<!--					<el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">-->
+<!--						<el-input-->
+<!--							v-model="form.projectName"-->
+<!--							placeholder="鑷姩濉厖"-->
+<!--							clearable-->
+<!--							disabled-->
+<!--						/>-->
+<!--					</el-form-item>-->
+<!--				</el-col>-->
+				<el-col :span="12">
+					<el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
+						<el-input
+							v-model="form.invoiceNumber"
+							placeholder="璇疯緭鍏�"
+							clearable
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
+						<el-input-number :step="0.01" :min="0" style="width: 100%"
+														 v-model="form.invoiceAmount"
+														 placeholder="璇疯緭鍏ュ彂绁ㄩ噾棰�"
+														 clearable
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="褰曞叆浜猴細" prop="issUer">
+						<el-input
+							v-model="form.issUer"
+							placeholder="璇疯緭鍏�"
+							clearable
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="寮�绁ㄦ棩鏈燂細" prop="entryDate">
+						<el-date-picker
+							style="width: 100%"
+							v-model="form.entryDate"
+							type="date"
+							value-format="YYYY-MM-DD"
+							format="YYYY-MM-DD"
+							clearable
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="褰曞叆鏃ユ湡锛�" prop="enterDate">
+						<el-date-picker
+							style="width: 100%"
+							v-model="form.enterDate"
+							type="date"
+							value-format="YYYY-MM-DD"
+							format="YYYY-MM-DD"
+							clearable
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="涓婁紶闄勪欢">
+						<FileUpload
+							:showTip="false"
+							accept="*"
+							:autoUpload="true"
+							:action="action"
+							:headers="{
                 Authorization: 'Bearer ' + getToken(),
               }"
-              :limit="10"
-              @success="uploadSuccess"
-              @remove="removeFile"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="褰曞叆鏃ユ湡锛�" prop="enterDate">
-            <el-date-picker
-              style="width: 100%"
-              v-model="form.enterDate"
-              type="date"
-              value-format="YYYY-MM-DD"
-              format="YYYY-MM-DD"
-              clearable
-            />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-form-item label="浜у搧淇℃伅锛�"> </el-form-item>
-      <PIMTable
-        rowKey="id"
-        :column="columns"
-        :tableData="form.productData"
-				:summaryMethod="summarizeChildrenTable"
-				:isShowSummary="true"
-        height="auto"
-      >
-        <template #ticketsNumRef="{ row }">
-          <el-input-number
-            v-model="row.ticketsNum"
-            placeholder="璇疯緭鍏�"
-            :min="0"
-            :step="0.1"
-						:precision="2"
-            clearable
-            style="width: 100%"
-            @change="invoiceNumBlur(row)"
-          />
-        </template>
-        <template #ticketsAmountRef="{ row }">
-          <el-input-number
-            v-model="row.ticketsAmount"
-            placeholder="璇疯緭鍏�"
-            :min="0"
-						:precision="2"
-            :step="0.1"
-            clearable
-            style="width: 100%"
-            @change="invoiceAmountBlur(row)"
-          />
-        </template>
-      </PIMTable>
-    </el-form>
-    <template #footer>
+							:limit="10"
+							@success="uploadSuccess"
+							@remove="removeFile"
+						/>
+					</el-form-item>
+				</el-col>
+			
+			</el-row>
+			<el-form-item label="浜у搧淇℃伅锛�"> </el-form-item>
+			<el-table
+				:data="form.productData"
+				border
+				show-summary
+				:summary-method="summarizeChildrenTable"
+			>
+				<el-table-column align="center" label="搴忓彿" type="index" width="60" />
+				<el-table-column label="鎵�灞炲悎鍚�" prop="purchaseLedgerNo" width="200">
+					<template #default="{ row }">
+						<el-tag type="primary">{{ row.purchaseLedgerNo }}</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="浜у搧澶х被" prop="productCategory" />
+				<el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="150" />
+				<el-table-column label="鍗曚綅" prop="unit" width="70" />
+				<el-table-column label="鏁伴噺" prop="quantity" width="70" />
+				<el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+				<el-table-column
+					label="鍚◣鍗曚环(鍏�)"
+					prop="taxInclusiveUnitPrice"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="鍚◣鎬讳环(鍏�)"
+					prop="taxInclusiveTotalPrice"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="涓嶅惈绋庢�讳环(鍏�)"
+					prop="taxExclusiveTotalPrice"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column label="鏈寮�绁ㄦ暟" prop="ticketsNum" width="180">
+					<template #default="scope">
+						<el-input-number :step="0.1" :min="0" style="width: 100%"
+														 :precision="2"
+														 v-model="scope.row.ticketsNum"
+														 @change="invoiceNumBlur(scope.row)"
+						/>
+					</template>
+				</el-table-column>
+				<el-table-column
+					label="鏈寮�绁ㄩ噾棰�(鍏�)"
+					prop="ticketsAmount"
+					width="180"
+				>
+					<template #default="scope">
+						<el-input-number :step="0.01" :min="0" style="width: 100%"
+														 :precision="2"
+														 v-model="scope.row.ticketsAmount"
+														 @change="invoiceAmountBlur(scope.row)"
+						/>
+					</template>
+				</el-table-column>
+				<el-table-column
+					label="鏈潵绁ㄦ暟"
+					prop="futureTickets"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="鏈鏉ョエ閲戦(鍏�)"
+					prop="ticketsAmount"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="鏈潵绁ㄦ暟"
+					prop="futureTickets"
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="鏈潵绁ㄩ噾棰�(鍏�)"
+					prop="futureTicketsAmount"
+					:formatter="formattedNumber"
+				/>
+			</el-table>
+		</el-form>
+		<template #footer>
 			<el-button type="primary" :loading="modalLoading" @click="submitForm">
-				{{ modalOptions.confirmText }}
+				纭
 			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+			<el-button @click="closeModal">鍙栨秷</el-button>
+		</template>
+	</el-dialog>
 </template>
 
 <script setup>
@@ -164,9 +206,9 @@
 import useFormData from "@/hooks/useFormData";
 import FileUpload from "@/components/Upload/FileUpload.vue";
 import {
-  getPurchaseNoById,
-  getInfo,
-  addOrUpdateRegistration,
+	getPurchaseNoById,
+	getInfo,
+	addOrUpdateRegistration,
 } from "@/api/procurementManagement/invoiceEntry.js";
 import { getPurchaseById } from "@/api/procurementManagement/procurementLedger.js";
 import { getToken } from "@/utils/auth";
@@ -174,7 +216,7 @@
 import dayjs from "dayjs";
 
 defineOptions({
-  name: "鏉ョエ鐧昏妯℃�佹",
+	name: "鏉ョエ鐧昏妯℃�佹",
 });
 
 const userStore = useUserStore();
@@ -182,155 +224,237 @@
 const formRef = ref();
 const { proxy } = getCurrentInstance();
 const { form } = useFormData({
-  purchaseLedgerNo: undefined, // 閲囪喘鍚堝悓鍙�
-  salesContractNo: undefined, // 閿�鍞悎鍚屽彿
-  supplierName: undefined, // 渚涘簲鍟嗗悕绉�
-  projectName: undefined, // 椤圭洰鍚嶇О
-  invoiceNumber: undefined, // 鍙戠エ鍙�
-  invoiceAmount: undefined, // 鍙戠エ閲戦(鍏�)
-  issUerId: userStore.id, // 褰曞叆浜�
-  issUer: userStore.nickName, // 褰曞叆浜�
-  entryDate: undefined, // 寮�绁ㄦ棩鏈�
-  salesContractNoId: undefined, // 寮�绁ㄦ棩鏈�
-  enterDate: dayjs().format("YYYY-MM-DD"),
-  productData: [], // 琛ㄦ牸
-  tempFileIds: [], // 鏂囦欢
+	purchaseLedgerNo: undefined, // 閲囪喘鍚堝悓鍙�
+	salesContractNo: undefined, // 閿�鍞悎鍚屽彿
+	supplierName: undefined, // 渚涘簲鍟嗗悕绉�
+	projectName: undefined, // 椤圭洰鍚嶇О
+	invoiceNumber: undefined, // 鍙戠エ鍙�
+	invoiceAmount: undefined, // 鍙戠エ閲戦(鍏�)
+	issUerId: userStore.id, // 褰曞叆浜�
+	issUer: userStore.nickName, // 褰曞叆浜�
+	entryDate: undefined, // 寮�绁ㄦ棩鏈�
+	salesContractNoId: undefined, // 寮�绁ㄦ棩鏈�
+	enterDate: dayjs().format("YYYY-MM-DD"),
+	productData: [], // 琛ㄦ牸
+	tempFileIds: [], // 鏂囦欢
 });
 
+const selectedContracts = ref([]); // 瀛樺偍閫変腑鐨勫悎鍚屾暟鎹�
+
 const rules = ref({
-  invoiceNumber: [
-    { required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur" },
-    { type: "string" },
-  ],
-  invoiceAmount: [
-    { required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
-  ],
-  entryDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
-  enterDate: [{ required: true, message: "璇烽�夋嫨褰曞叆鏃ユ湡", trigger: "change" }],
+	invoiceNumber: [
+		{ required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur" },
+		{ type: "string" },
+	],
+	invoiceAmount: [
+		{ required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
+	],
+	entryDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
+	enterDate: [{ required: true, message: "璇烽�夋嫨褰曞叆鏃ユ湡", trigger: "change" }],
 });
 
 const {
-  id,
-  visible,
-  loading: modalLoading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
+	id,
+	visible,
+	loading: modalLoading,
+	openModal,
+	modalOptions,
+	handleConfirm,
+	closeModal,
 } = useModal({
-  title: "鏉ョエ鐧昏",
+	title: "鏉ョエ鐧昏",
 });
 
 const emit = defineEmits(['refreshList']);
 
 const columns = [
-  {
-    label: "浜у搧澶х被",
-    prop: "productCategory",
+	{
+		label: "浜у搧澶х被",
+		prop: "productCategory",
 		width: 120,
-  },
-  {
-    label: "瑙勬牸鍨嬪彿",
-    prop: "specificationModel",
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "specificationModel",
 		width: 120,
-  },
-  {
-    label: "鍗曚綅",
-    prop: "unit",
-    width: 80,
-  },
-  {
-    label: "鏁伴噺",
-    prop: "quantity",
-    width: 80,
-  },
-  {
-    label: "绋庣巼(%)",
-    prop: "taxRate",
-    width: 80,
-  },
-  {
-    label: "褰曞叆鏃ユ湡",
-    prop: "registerDate",
-    width: 120,
-  },
-  {
-    label: "鍚◣鍗曚环(鍏�)",
-    prop: "taxInclusiveUnitPrice",
-    width: 150,
-    formatData: (val) => {
-      return val ? parseFloat(val).toFixed(2) : 0;
-    },
-  },
-  {
-    label: "鍚◣鎬讳环(鍏�)",
-    prop: "taxInclusiveTotalPrice",
-    width: 150,
-    formatData: (val) => {
-      return parseFloat(val).toFixed(2) ?? 0;
-    },
-  },
-  {
-    label: "涓嶅惈绋庢�讳环(鍏�)",
-    prop: "taxExclusiveTotalPrice",
-    width: 150,
-    formatData: (val) => {
-      return parseFloat(val).toFixed(2) ?? 0;
-    },
-  },
-  {
-    label: "鏈鏉ョエ鏁�",
-    prop: "ticketsNum",
-    dataType: "slot",
-    slot: "ticketsNumRef",
-    width: 180,
-    align: "center",
-  },
-  {
-    label: "鏈鏉ョエ閲戦(鍏�)",
-    prop: "ticketsAmount",
-    dataType: "slot",
-    slot: "ticketsAmountRef",
-    width: 180,
-    align: "center",
-  },
-  {
-    label: "鏈潵绁ㄦ暟",
-    prop: "futureTickets",
+	},
+	{
+		label: "鍗曚綅",
+		prop: "unit",
+		width: 80,
+	},
+	{
+		label: "鏁伴噺",
+		prop: "quantity",
+		width: 80,
+	},
+	{
+		label: "绋庣巼(%)",
+		prop: "taxRate",
+		width: 80,
+	},
+	{
+		label: "褰曞叆鏃ユ湡",
+		prop: "registerDate",
+		width: 120,
+	},
+	{
+		label: "鍚◣鍗曚环(鍏�)",
+		prop: "taxInclusiveUnitPrice",
+		width: 150,
+		formatData: (val) => {
+			return val ? parseFloat(val).toFixed(2) : 0;
+		},
+	},
+	{
+		label: "鍚◣鎬讳环(鍏�)",
+		prop: "taxInclusiveTotalPrice",
+		width: 150,
+		formatData: (val) => {
+			return parseFloat(val).toFixed(2) ?? 0;
+		},
+	},
+	{
+		label: "涓嶅惈绋庢�讳环(鍏�)",
+		prop: "taxExclusiveTotalPrice",
+		width: 150,
+		formatData: (val) => {
+			return parseFloat(val).toFixed(2) ?? 0;
+		},
+	},
+	{
+		label: "鏈鏉ョエ鏁�",
+		prop: "ticketsNum",
+		dataType: "slot",
+		slot: "ticketsNumRef",
+		width: 180,
+		align: "center",
+	},
+	{
+		label: "鏈鏉ョエ閲戦(鍏�)",
+		prop: "ticketsAmount",
+		dataType: "slot",
+		slot: "ticketsAmountRef",
+		width: 180,
+		align: "center",
+	},
+	{
+		label: "鏈潵绁ㄦ暟",
+		prop: "futureTickets",
 		width: 100,
-  },
-  {
-    label: "鏈潵绁ㄩ噾棰�(鍏�)",
-    prop: "futureTicketsAmount",
+	},
+	{
+		label: "鏈潵绁ㄩ噾棰�(鍏�)",
+		prop: "futureTicketsAmount",
 		width: 200,
-  },
+	},
 ];
-
-const getTableData = async (type, id) => {
-  if (type == "add") {
-    const { data } = await getPurchaseNoById({ id });
-    form.purchaseLedgerNo = data.purchaseContractNumber;
-    form.invoiceAmount = data.invoiceAmount;
-    form.invoiceNumber = data.invoiceNumber;
-    form.entryDate = data.entryDate;
-    form.salesContractNoId = data.salesContractNoId;
-
-    const { data: infoData } = await getInfo({ id });
-    form.salesContractNo = infoData.salesContractNo;
-    form.projectName = infoData.projectName;
-    form.supplierName = infoData.supplierName;
-    form.productData = infoData.productData;
-  } else if (type == "edit") {
-    const data = await getPurchaseById({ id, type: 2 });
-    form.purchaseLedgerNo = data.purchaseContractNumber;
-    form.invoiceAmount = data.invoiceAmount;
-    form.invoiceNumber = data.invoiceNumber;
-    form.salesContractNo = data.salesContractNo;
-    form.projectName = data.projectName;
-    form.supplierName = data.supplierName;
-    form.entryDate = data.entryDate;
-    form.productData = data.productData;
-  }
+const formattedNumber = (row, column, cellValue) => {
+	if (cellValue == 0) {
+		return parseFloat(cellValue).toFixed(2);
+	}
+	if (cellValue) {
+		return parseFloat(cellValue).toFixed(2);
+	} else {
+		return cellValue;
+	}
+};
+const getTableData = async (type, selectedRows) => {
+	if (type == "add") {
+		// 妫�鏌ユ墍鏈夐�夋嫨鐨勫悎鍚屾槸鍚﹀叿鏈夌浉鍚岀殑渚涘簲鍟嗗悕绉�
+		const firstRow = selectedRows[0];
+		const isSameSupplier = selectedRows.every(row =>
+			row.supplierName === firstRow.supplierName
+		);
+		
+		if (!isSameSupplier) {
+			proxy.$modal.msgError("璇烽�夋嫨鐩稿悓渚涘簲鍟嗗悕绉扮殑鍚堝悓");
+			return;
+		}
+		
+		// 鍏佽涓嶅悓鐨勯噰璐悎鍚屽彿鎵归噺澶勭悊锛屾棤闇�妫�鏌ラ噸澶�
+		
+		// 娓呯┖琛ㄥ崟鏁版嵁
+		Object.keys(form).forEach(key => {
+			if (key !== 'productData') {
+				form[key] = undefined;
+			}
+		});
+		form.productData = [];
+		
+		// 鍔犺浇鎵�鏈夐�変腑鍚堝悓鐨勪骇鍝佹暟鎹�
+		const promises = selectedRows.map(row =>
+			getInfo({ id: row.id })
+		);
+		
+		Promise.all(promises).then(results => {
+			// 鍚堝苟鎵�鏈夊悎鍚岀殑浜у搧鏁版嵁锛屽苟涓烘瘡涓骇鍝佹坊鍔犲搴旂殑鍚堝悓淇℃伅
+			const allProductData = [];
+			results.forEach((result, index) => {
+				const contract = selectedRows[index];
+				const contractId = contract.id;
+				if (result.data && result.data.productData) {
+					result.data.productData.forEach(item => {
+						allProductData.push({
+							...item,
+							id: contractId, // 鏄庣‘璁剧疆鍚堝悓ID
+							purchaseLedgerNo: contract.purchaseContractNumber, // 娣诲姞閲囪喘鍚堝悓鍙�
+							supplierName: contract.supplierName, // 娣诲姞渚涘簲鍟嗗悕绉�
+							projectName: contract.projectName // 娣诲姞椤圭洰鍚嶇О
+						});
+					});
+				}
+			});
+			
+			// 璁剧疆琛ㄥ崟鏁版嵁锛堜娇鐢ㄧ涓�涓悎鍚岀殑鍩烘湰淇℃伅锛岄噰璐悎鍚屽彿鐣欑┖锛�
+			form.purchaseLedgerNo = ""; // 閲囪喘鍚堝悓鍙风暀绌猴紝鍥犱负浼氬湪浜у搧琛ㄦ牸涓垎鍒樉绀�
+			form.invoiceNumber = "";
+			form.entryDate = dayjs().format("YYYY-MM-DD");
+			form.enterDate = dayjs().format("YYYY-MM-DD");
+			form.salesContractNo = results[0].data.salesContractNo;
+			form.projectName = results[0].data.projectName;
+			form.supplierName = results[0].data.supplierName;
+			// 淇濈暀褰曞叆浜轰俊鎭�
+			form.issUerId = userStore.id;
+			form.issUer = userStore.nickName;
+			
+			// 璁剧疆浜у搧鏁版嵁锛屽苟鍒濆鍖栧紑绁ㄦ暟閲忓拰閲戦
+			allProductData.forEach(item => {
+				// 鏈寮�绁ㄦ暟榛樿涓烘�绘暟閲�
+				item.ticketsNum = Number(item.quantity || 0);
+				// 鏈寮�绁ㄩ噾棰濋粯璁や负鍚◣鎬讳环
+				item.ticketsAmount = Number(item.taxInclusiveTotalPrice || 0);
+				// 淇濆瓨鍘熷鏈潵绁ㄦ暟鍜岄噾棰濓紙鐢ㄤ簬璁$畻锛�
+				item.tempFutureTickets = Number(item.quantity || 0);
+				item.tempFutureTicketsAmount = Number(item.taxInclusiveTotalPrice || 0);
+				// 鏈潵绁ㄦ暟鍜岄噾棰濆垵濮嬩负0锛堝洜涓哄叏閮ㄥ紑绁級
+				item.futureTickets = 0;
+				item.futureTicketsAmount = 0;
+			});
+			
+			form.productData = allProductData;
+			
+			// 璁$畻鍙戠エ閲戦锛氭墍鏈変骇鍝佺殑鍚◣鎬讳环涔嬪拰
+			const totalAmount = allProductData.reduce((sum, item) => {
+				return sum + (Number(item.taxInclusiveTotalPrice) || 0);
+			}, 0);
+			form.invoiceAmount = totalAmount.toFixed(2);
+			
+			// 瀛樺偍閫変腑鐨勫悎鍚屾暟鎹�
+			selectedContracts.value = selectedRows;
+		});
+	} else if (type == "edit") {
+		const id = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows;
+		const data = await getPurchaseById({ id, type: 2 });
+		form.purchaseLedgerNo = data.purchaseContractNumber;
+		form.invoiceAmount = data.invoiceAmount;
+		form.invoiceNumber = data.invoiceNumber;
+		form.salesContractNo = data.salesContractNo;
+		form.projectName = data.projectName;
+		form.supplierName = data.supplierName;
+		form.entryDate = data.entryDate;
+		form.productData = data.productData;
+	}
 };
 // 瀛愯〃鍚堣鏂规硶
 const summarizeChildrenTable = (param) => {
@@ -347,109 +471,186 @@
 };
 //鏈鏉ョエ鏁板け鐒︽搷浣�
 const invoiceNumBlur = (row) => {
-  if (!row.ticketsNum || row.ticketsNum === "") {
-    row.ticketsNum = 0;
-  }
-  if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) {
-    proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
-    row.ticketsNum = 0;
-    return;
-  }
-  // 璁$畻鏈鏉ョエ閲戦
-  row.ticketsAmount = (row.ticketsNum * row.taxInclusiveUnitPrice).toFixed(2)
-  // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
-  // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
-  calculateinvoiceAmount();
+	if (!row.ticketsNum || row.ticketsNum === "") {
+		row.ticketsNum = 0;
+	}
+	if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) {
+		proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
+		row.ticketsNum = 0;
+		return;
+	}
+	// 璁$畻鏈鏉ョエ閲戦
+	row.ticketsAmount = (row.ticketsNum * row.taxInclusiveUnitPrice).toFixed(2)
+	// 璁$畻鏈潵绁ㄦ暟
+	row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
+	// 璁$畻鏈潵绁ㄩ噾棰�
+	row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
+	calculateinvoiceAmount();
 };
 
 // 鏈鏉ョエ閲戦澶辩劍鎿嶄綔
 const invoiceAmountBlur = (row) => {
-  if (!row.ticketsAmount) {
-    row.ticketsAmount = 0;
-  }
-  // 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰�
-  if (row.ticketsAmount > row.tempFutureTicketsAmount) {
-    proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�");
-    row.ticketsAmount = 0;
-  }
-  // 璁$畻鏈鏉ョエ鏁�
-  row.ticketsNum = Number(
-    (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2)
-  );
-  // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
-  // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
-  calculateinvoiceAmount();
+	if (!row.ticketsAmount) {
+		row.ticketsAmount = 0;
+	}
+	// 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰�
+	if (row.ticketsAmount > row.tempFutureTicketsAmount) {
+		proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�");
+		row.ticketsAmount = 0;
+	}
+	// 璁$畻鏈鏉ョエ鏁�
+	row.ticketsNum = Number(
+		(row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2)
+	);
+	// 璁$畻鏈潵绁ㄦ暟
+	row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
+	// 璁$畻鏈潵绁ㄩ噾棰�
+	row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
+	calculateinvoiceAmount();
 };
 
 const calculateinvoiceAmount = () => {
-  let invoiceAmountTotal = 0;
-  form.productData.forEach((item) => {
-    if (item.ticketsAmount) {
-      invoiceAmountTotal += Number(item.ticketsAmount);
-    }
-  });
-  form.invoiceAmount = invoiceAmountTotal.toFixed(2);
+	let invoiceAmountTotal = 0;
+	form.productData.forEach((item) => {
+		if (item.ticketsAmount) {
+			invoiceAmountTotal += Number(item.ticketsAmount);
+		}
+	});
+	form.invoiceAmount = invoiceAmountTotal.toFixed(2);
 };
 
-const open = (type, eid) => {
-  openModal();
-  getTableData(type, eid);
-  id.value = eid;
+const open = async (type, selectedRows) => {
+	visible.value = true;
+	
+	// 濡傛灉鏄壒閲忔搷浣滐紝璁剧疆鏍囬
+	if (Array.isArray(selectedRows) && selectedRows.length > 1) {
+		modalOptions.title = `鎵归噺鏂板 (${selectedRows.length}鏉�)`;
+	} else {
+		modalOptions.title = type === "add" ? "鏂板" : "缂栬緫";
+	}
+	
+	// 濡傛灉鏄崟涓搷浣滐紝鑾峰彇id
+	if (!Array.isArray(selectedRows) || selectedRows.length === 1) {
+		const idValue = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows;
+		id.value = idValue;
+	}
+	
+	await getTableData(type, selectedRows);
 };
 
 const uploadSuccess = (response) => {
-  form.tempFileIds.push(response.data.tempId);
-  console.log(form);
+	form.tempFileIds.push(response.data.tempId);
+	console.log(form);
 };
 
 const removeFile = (file) => {
-  const { tempId } = file.response.data;
-  form.tempFileIds = form.tempFileIds.filter((item) => item !== tempId);
+	const { tempId } = file.response.data;
+	form.tempFileIds = form.tempFileIds.filter((item) => item !== tempId);
 };
 
 const closeAndRefresh = () => {
-  closeModal();
-  emit('refreshList');
+	closeModal();
+	emit('refreshList');
 };
 
 const submitForm = () => {
-  formRef.value.validate(async (valid, fields) => {
-    if (valid) {
-      // modalLoading.value = true;
-      const { code } = await addOrUpdateRegistration({
-        purchaseLedgerId: id.value,
-        purchaseContractNumber: form.purchaseLedgerNo,
-        invoiceNumber: form.invoiceNumber,
-        invoiceAmount: form.invoiceAmount,
-        salesContractNo: form.salesContractNo,
-        projectName: form.projectName,
-        productData: form.productData,
-        issueDate: form.entryDate,
-        issUerId: form.issUerId, // 褰曞叆浜篿d
-        issUer: form.issUer, // 褰曞叆浜�
-        salesContractNoId: form.salesContractNoId,
-        supplierName: form.supplierName,
-        tempFileIds: form.tempFileIds,
-        enterDate: form.enterDate,
-        type: 4,
-      });
-      modalLoading.value = false;
-      if (code == 200) {
-        closeAndRefresh();
-      }
-    } else {
-      modalLoading.value = false;
-    }
-  });
+	proxy.$refs["formRef"].validate((valid) => {
+		if (valid) {
+			// 濡傛灉鏄壒閲忔搷浣滐紝灏嗘墍鏈夊悎鍚岀殑鏁版嵁鏀惧湪涓�涓暟缁勯噷锛屽彧璋冪敤涓�娆℃帴鍙�
+			if (selectedContracts.value.length > 1) {
+				// 鍒涘缓鍖呭惈鎵�鏈夊悎鍚屾暟鎹殑鏁扮粍
+				const batchData = selectedContracts.value.map(contract => {
+					// 绛涢�夊嚭灞炰簬褰撳墠鍚堝悓鐨勪骇鍝佹暟鎹�
+					const contractProductData = form.productData.filter(item =>
+						item.id === contract.id
+					);
+					
+					// 涓烘瘡涓噰璐悎鍚屽垱寤虹嫭绔嬬殑瀵硅薄
+					return {
+						// 鍩虹琛ㄥ崟鏁版嵁
+						invoiceNumber: form.invoiceNumber,
+						invoiceAmount: form.invoiceAmount,
+						entryDate: form.entryDate,
+						enterDate: form.enterDate,
+						issUerId: form.issUerId, // 褰曞叆浜篿d
+						issUer: form.issUer, // 褰曞叆浜�
+						tempFileIds: form.tempFileIds,
+						
+						// 鍚堝悓瀹為檯淇℃伅
+						purchaseLedgerId: contract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负purchaseLedgerId
+						purchaseContractNumber: contract.purchaseContractNumber, // 浣跨敤瀹為檯鐨勯噰璐悎鍚屽彿
+						salesContractNo: contract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+						supplierName: contract.supplierName, // 浣跨敤瀹為檯鐨勪緵搴斿晢鍚嶇О
+						projectName: contract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+						
+						// 浜у搧鏁版嵁
+						productData: proxy.HaveJson(contractProductData),
+						
+						// 鎵归噺鏍囪瘑
+						isBatch: true,
+						type: 4
+					};
+				});
+				
+				// 鍙皟鐢ㄤ竴娆℃帴鍙o紝浼犻�掑寘鍚墍鏈夊悎鍚屾暟鎹殑鏁扮粍
+				modalLoading.value = true;
+				addOrUpdateRegistration(batchData).then((res) => {
+					modalLoading.value = false;
+					if (res.code === 200) {
+						proxy.$modal.msgSuccess("鎵归噺鐧昏鎴愬姛");
+						closeAndRefresh();
+					}
+				}).catch(() => {
+					modalLoading.value = false;
+					proxy.$modal.msgError("鎵归噺鐧昏澶辫触");
+				});
+			} else {
+					// 鍗曚釜鍚堝悓鎻愪氦閫昏緫 - 浠ユ暟缁勬牸寮忎紶閫�
+					const singleContract = selectedContracts.value[0];
+					const singleFormArray = [{
+						// 鍩虹琛ㄥ崟鏁版嵁
+						invoiceNumber: form.invoiceNumber,
+						invoiceAmount: form.invoiceAmount,
+						entryDate: form.entryDate,
+						enterDate: form.enterDate,
+						issUerId: form.issUerId, // 褰曞叆浜篿d
+						issUer: form.issUer, // 褰曞叆浜�
+						tempFileIds: form.tempFileIds,
+						
+						// 鍚堝悓瀹為檯淇℃伅
+						purchaseLedgerId: singleContract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负purchaseLedgerId
+						purchaseContractNumber: singleContract.purchaseContractNumber, // 浣跨敤瀹為檯鐨勯噰璐悎鍚屽彿
+						salesContractNo: singleContract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+						supplierName: singleContract.supplierName, // 浣跨敤瀹為檯鐨勪緵搴斿晢鍚嶇О
+						projectName: singleContract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+						
+						// 浜у搧鏁版嵁
+						productData: proxy.HaveJson(form.productData),
+						
+						// 鎵归噺鏍囪瘑
+						isBatch: false,
+						type: 4
+					}];
+					
+					modalLoading.value = true;
+					addOrUpdateRegistration(singleFormArray).then((res) => {
+						modalLoading.value = false;
+						if (res.code === 200) {
+							proxy.$modal.msgSuccess("鐧昏鎴愬姛");
+							closeAndRefresh();
+						}
+					}).catch(() => {
+						modalLoading.value = false;
+						proxy.$modal.msgError("鐧昏澶辫触");
+					});
+				}
+		}
+	});
 };
 
 defineExpose({
-  open,
-  closeAndRefresh,
+	open,
+	closeAndRefresh,
 });
 </script>
 
diff --git a/src/views/procurementManagement/invoiceEntry/index.vue b/src/views/procurementManagement/invoiceEntry/index.vue
index 87e08e9..3719ffe 100644
--- a/src/views/procurementManagement/invoiceEntry/index.vue
+++ b/src/views/procurementManagement/invoiceEntry/index.vue
@@ -28,13 +28,6 @@
               clearable
           />
         </el-form-item>
-        <el-form-item label="椤圭洰鍚嶇О">
-          <el-input
-              v-model="filters.projectName"
-              placeholder="璇疯緭鍏ラ」鐩悕绉�"
-              clearable
-          />
-        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
           <el-button @click="resetFilters"> 閲嶇疆 </el-button>
@@ -47,7 +40,7 @@
         <div>
           <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
           <el-button type="primary" @click="handleAdd('add')">
-            鏂板鐧昏
+            鏉ョエ鐧昏
           </el-button>
 <!--          <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
         </div>
@@ -143,11 +136,6 @@
       width:300
     },
     {
-      label: "椤圭洰鍚嶇О",
-      prop: "projectName",
-      width:400
-    },
-    {
       label: "褰曞叆浜�",
       prop: "recorderName",
     },
@@ -198,11 +186,11 @@
 };
 
 const handleAdd = (type) => {
-  if (selectedRows.value.length !== 1) {
-    proxy.$modal.msgWarning("璇峰厛閫変腑涓�鏉℃暟鎹�");
-    return;
-  }
-  modalRef.value.open(type, selectedRows.value[0].id);
+	if (selectedRows.value.length < 1) {
+		proxy.$modal.msgWarning("璇疯嚦灏戦�変腑涓�鏉℃暟鎹�");
+		return;
+	}
+	modalRef.value.open(type, selectedRows.value);
 };
 
 const handleEdit = (type, id) => {
diff --git a/src/views/procurementManagement/invoiceEntry/indexOld.vue b/src/views/procurementManagement/invoiceEntry/indexOld.vue
deleted file mode 100644
index 1b4c6b9..0000000
--- a/src/views/procurementManagement/invoiceEntry/indexOld.vue
+++ /dev/null
@@ -1,727 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="search_form">
-      <div>
-        <span class="search_title">閲囪喘鍚堝悓鍙凤細</span>
-        <el-input
-          v-model="searchForm.purchaseContractNumber"
-          style="width: 240px"
-          placeholder="璇疯緭鍏�"
-          @change="handleQuery"
-          clearable
-          prefix-icon="Search"
-        />
-        <el-button
-          type="primary"
-          @click="handleQuery"
-          style="margin-left: 10px"
-        >
-          鎼滅储
-        </el-button>
-      </div>
-      <div>
-        <el-button type="primary" @click="handleAdd">鏂板鐧昏</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-    </div>
-    <div class="table_list">
-      <el-table
-        :data="tableData"
-        border
-        v-loading="tableLoading"
-        @selection-change="handleSelectionChange"
-        :expand-row-keys="expandedRowKeys"
-        :row-key="(row) => row.id"
-        show-summary
-        :summary-method="summarizeMainTable"
-        @expand-change="expandChange"
-        height="calc(100vh - 18.5em)"
-      >
-        <el-table-column align="center" type="selection" width="55" />
-        <el-table-column type="expand">
-          <template #default="props">
-            <el-table
-              :data="props.row.children"
-              border
-              show-summary
-              :summary-method="summarizeChildrenTable"
-            >
-              <el-table-column
-                align="center"
-                label="搴忓彿"
-                type="index"
-                width="60"
-              />
-              <el-table-column label="浜у搧澶х被" prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-              <el-table-column label="鍗曚綅" prop="unit" />
-              <el-table-column label="鏁伴噺" prop="quantity" />
-              <el-table-column label="绋庣巼(%)" prop="taxRate" />
-              <el-table-column
-                label="鍚◣鍗曚环(鍏�)"
-                prop="taxInclusiveUnitPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="鍚◣鎬讳环(鍏�)"
-                prop="taxInclusiveTotalPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="涓嶅惈绋庢�讳环(鍏�)"
-                prop="taxExclusiveTotalPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column label="鏈鏉ョエ鏁�" prop="ticketsNum" />
-              <el-table-column
-                label="鏈鏉ョエ閲戦(鍏�)"
-                prop="ticketsAmount"
-                :formatter="formattedNumber"
-              />
-              <el-table-column label="鏈潵绁ㄦ暟" prop="futureTickets" />
-              <el-table-column
-                label="鏈潵绁ㄩ噾棰�(鍏�)"
-                prop="futureTicketsAmount"
-                :formatter="formattedNumber"
-              />
-            </el-table>
-          </template>
-        </el-table-column>
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column
-          label="閲囪喘鍚堝悓鍙�"
-          prop="purchaseContractNumber"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="閿�鍞悎鍚屽彿"
-          prop="salesContractNo"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="渚涘簲鍟嗗悕绉�"
-          prop="supplierName"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="椤圭洰鍚嶇О"
-          prop="projectName"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="鍚堝悓閲戦(鍏�)"
-          prop="contractAmount"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
-        />
-        <el-table-column
-          label="宸插紑绁ㄩ噾棰�(鍏�)"
-          prop="receiptPaymentAmount"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
-        />
-        <el-table-column
-          label="寰呭紑绁ㄩ噾棰�(鍏�)"
-          prop="unReceiptPaymentAmount"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
-        />
-        <el-table-column
-          fixed="right"
-          label="鎿嶄綔"
-          min-width="60"
-          align="center"
-        >
-          <template #default="scope">
-            <el-button
-              text
-              type="primary"
-              size="small"
-              @click="openForm('edit', scope.row)"
-            >
-              缂栬緫
-            </el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <pagination
-        v-show="total > 0"
-        :total="total"
-        layout="total, sizes, prev, pager, next, jumper"
-        :page="page.current"
-        :limit="page.size"
-        @pagination="paginationChange"
-      />
-    </div>
-    <el-dialog
-      v-model="dialogFormVisible"
-      :title="operationType === 'add' ? '鏂板鏉ョエ鐧昏' : '缂栬緫鏉ョエ鐧昏'"
-      width="80%"
-      @close="closeDia"
-    >
-      <el-form
-        :model="form"
-        label-width="140px"
-        label-position="top"
-        :rules="rules"
-        ref="formRef"
-      >
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseLedgerNo">
-              <el-input v-model="form.purchaseLedgerNo" disabled />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-              <el-input
-                v-model="form.salesContractNo"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
-              <el-input
-                v-model="form.supplierName"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-              <el-input
-                v-model="form.projectName"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
-              <el-input
-                v-model="form.invoiceNumber"
-                placeholder="璇疯緭鍏�"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
-              <el-input
-                type="number"
-                :step="0.01"
-                v-model="form.invoiceAmount"
-                placeholder="鑷姩濉厖"
-                clearable
-                :disabled="true"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="褰曞叆浜猴細" prop="issUer">
-              <el-input
-                v-model="form.issUer"
-                placeholder="璇疯緭鍏�"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="寮�绁ㄦ棩鏈燂細" prop="issueDate">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.issueDate"
-                type="date"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="涓婁紶闄勪欢">
-              <FileUpload :showTip="false" accept="*" :autoUpload="true" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <!-- <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="createTime">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.createTime"
-                type="date"
-                placeholder="璇烽�夋嫨"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row> -->
-        <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
-        </el-row>
-        <el-table
-          :data="productData"
-          border
-          @selection-change="productSelected"
-          show-summary
-          style="width: 100%"
-          :summary-method="summarizeChildrenTable"
-        >
-          <el-table-column
-            align="center"
-            label="搴忓彿"
-            type="index"
-            width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-          <el-table-column label="鍗曚綅" prop="unit" width="70" />
-          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
-          <el-table-column label="褰曞叆鏃ユ湡" prop="createTime" width="120" />
-          <el-table-column
-            label="鍚◣鍗曚环(鍏�)"
-            width="200"
-            prop="taxInclusiveUnitPrice"
-            :formatter="formattedNumber"
-          />
-          <el-table-column
-            label="鍚◣鎬讳环(鍏�)"
-            width="200"
-            prop="taxInclusiveTotalPrice"
-            :formatter="formattedNumber"
-          />
-          <el-table-column
-            label="涓嶅惈绋庢�讳环(鍏�)"
-            width="200"
-            prop="taxExclusiveTotalPrice"
-            :formatter="formattedNumber"
-          />
-          <el-table-column label="鏈鏉ョエ鏁�" prop="ticketsNum" width="170">
-            <template #default="scope">
-              <el-input-number
-                v-model="scope.row.ticketsNum"
-                placeholder="璇烽�夋嫨"
-                :min="0"
-								:precision="2"
-                :step="0.1"
-                clearable
-                style="width: 100%"
-                @change="invoiceNumBlur(scope.row)"
-              />
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="鏈鏉ョエ閲戦(鍏�)"
-            prop="ticketsAmount"
-            :min="0"
-            :step="0.1"
-            :formatter="formattedNumber"
-            width="200"
-          >
-            <template #default="scope">
-              <el-input-number
-                v-model="scope.row.ticketsAmount"
-                placeholder="璇烽�夋嫨"
-                :min="0"
-								:precision="2"
-                :step="0.1"
-                clearable
-                style="width: 100%"
-                @change="invoiceAmountBlur(scope.row)"
-              />
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="鏈潵绁ㄦ暟"
-            prop="futureTickets"
-            :formatter="
-              (row) =>
-                row.futureTickets == null || row.futureTickets === ''
-                  ? row.quantity
-                  : row.futureTickets
-            "
-          >
-          </el-table-column>
-          <el-table-column
-            label="鏈潵绁ㄩ噾棰�(鍏�)"
-            prop="futureTicketsAmount"
-            :formatter="
-              (row) =>
-                row.futureTicketsAmount !== undefined &&
-                row.futureTicketsAmount !== null &&
-                row.futureTicketsAmount !== ''
-                  ? row.futureTicketsAmount
-                  : row.taxExclusiveTotalPrice
-            "
-          >
-          </el-table-column>
-        </el-table>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import { userListNoPage } from "@/api/system/user.js";
-import { productList } from "@/api/procurementManagement/procurementLedger.js";
-import useUserStore from "@/store/modules/user";
-import FileUpload from "@/components/Upload/FileUpload.vue";
-
-const userStore = useUserStore();
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const userList = ref([]);
-const purchaseLedgerList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
-import {
-  addOrUpdateRegistration,
-  delRegistration,
-  gePurchaseListPage,
-  getInfo,
-  getProduct,
-  getPurchaseNoById,
-  getRegistrationById,
-} from "@/api/procurementManagement/invoiceEntry.js";
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
-  searchForm: {
-    purchaseContractNumber: "",
-  },
-  form: {
-    issueDate: "", // 寮�绁ㄦ棩鏈�
-    purchaseLedgerId: "",
-    purchaseLedgerNo: "",
-    issUerId: "", // 寮�绁ㄤ汉id
-    issUer: "", // 寮�绁ㄤ汉濮撳悕
-    invoiceNumber: "", // 鍙戠エ鍙�
-    invoiceAmount: "", // 鍙戠エ閲戦
-    createTime: "", // 褰曞叆鏃ユ湡
-  },
-  rules: {
-    invoiceNumber: [
-      { required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur" },
-      { type: "string" },
-    ],
-    invoiceAmount: [
-      { required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
-    ],
-  },
-});
-const { searchForm, form, rules } = toRefs(data);
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const currentId = ref("");
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const paginationChange = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  gePurchaseListPage({ ...searchForm.value, ...page })
-    .then((res) => {
-      tableLoading.value = false;
-      tableData.value = res.records;
-      tableData.value.map((item) => {
-        item.children = [];
-      });
-      total.value = res.total;
-      expandedRowKeys.value = [];
-    })
-    .catch(() => {
-      tableLoading.value = false;
-    });
-};
-const formattedNumber = (row, column, cellValue) => {
-  return parseFloat(cellValue).toFixed(2) ?? 0;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection.filter(
-    (item) => item.purchaseContractNumber !== undefined
-  );
-};
-const productSelected = (selectedRows) => {
-  productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
-  if (expandedRows.length > 0) {
-    expandedRowKeys.value = [];
-    try {
-      productList({ salesLedgerId: row.id, type: 2 }).then((res) => {
-        const index = tableData.value.findIndex((item) => item.id === row.id);
-        if (index > -1) {
-          tableData.value[index].children = res;
-        }
-        expandedRowKeys.value.push(row.id);
-      });
-    } catch (error) {
-      console.log(error);
-    }
-  } else {
-    expandedRowKeys.value = [];
-  }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(
-    param,
-    ["contractAmount", "receiptPaymentAmount", "unReceiptPaymentAmount"],
-    {
-      ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-      futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-    }
-  );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
-  return proxy.summarizeTable(
-    param,
-    [
-      "taxInclusiveUnitPrice",
-      "taxInclusiveTotalPrice",
-      "taxExclusiveTotalPrice",
-      "ticketsNum",
-      "ticketsAmount",
-      "futureTickets",
-      "futureTicketsAmount",
-    ],
-    {
-      ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-      futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-    }
-  );
-};
-
-const handleAdd = () => {
-  if (selectedRows.value.length !== 1) {
-    proxy.$modal.msgWarning("璇峰厛閫変腑涓�鏉℃暟鎹�");
-    return;
-  }
-  openForm("add", selectedRows.value[0]);
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  invoiceNumBlur(row);
-  operationType.value = type;
-  form.value = {};
-  productData.value = [];
-  fileList.value = [];
-  form.value.issUerId = userStore.id;
-  form.value.issUer = userStore.name;
-  form.value.issueDate = getNowFormatDate();
-  userListNoPage().then((res) => {
-    userList.value = res.data;
-  });
-  // 鏂板鏃朵紶鍏ュ綋鍓嶈id骞舵煡璇㈤噰璐悎鍚屽彿
-  if (type === "add" && row && row.id) {
-    form.value.purchaseLedgerId = row.id;
-    getPurchaseNoById({ id: row.id }).then((res) => {
-      let result = res.data;
-      purchaseLedgerList.value = result;
-      form.value.purchaseLedgerNo = result.purchaseContractNumber;
-      form.value.invoiceAmount = result.invoiceAmount;
-      form.value.invoiceNumber = result.invoiceNumber;
-      setInfo(result.id);
-    });
-  } else {
-    getProduct().then((res) => {
-      purchaseLedgerList.value = res;
-    });
-  }
-  if (type === "edit") {
-    currentId.value = row.id;
-    getRegistrationById({ id: row.id }).then((res) => {
-      const { code, data } = res;
-      if (code == 200) {
-        form.value.invoiceAmount = data.invoiceAmount;
-        productData.value = data.productData;
-        if (data.salesLedgerFiles) {
-          fileList.value = data.salesLedgerFiles;
-        } else {
-          fileList.value = [];
-        }
-      }
-    });
-  }
-  dialogFormVisible.value = true;
-};
-// 閫夋嫨閲囪喘鍚堝悓鍙疯祴鍊�
-const setInfo = (value) => {
-  getInfo({ id: value }).then((res) => {
-    let result = res.data;
-    form.value.salesContractNo = result.salesContractNo;
-    form.value.projectName = result.projectName;
-    productData.value = result.productData;
-    form.value.supplierName = result.supplierName;
-  });
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
-  proxy.$refs["formRef"].validate((valid) => {
-    if (valid) {
-      form.value.productData = proxy.HaveJson(productData.value);
-      addOrUpdateRegistration(form.value).then((res) => {
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-        closeDia();
-        getList();
-      });
-    }
-  });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      proxy.download("/purchase/registration/export", {}, "鏉ョエ鐧昏.xlsx");
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
-};
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      delRegistration(ids).then((res) => {
-        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-        getList();
-      });
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
-};
-//鏈鏉ョエ鏁板け鐒︽搷浣�
-const invoiceNumBlur = (row) => {
-  if (!row.ticketsNum || row.ticketsNum === "") {
-    row.ticketsNum = 0;
-  }
-  if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) {
-    proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
-    row.ticketsNum = 0;
-    return;
-  }
-  // 璁$畻鏈鏉ョエ閲戦
-  row.ticketsAmount = row.ticketsNum * row.taxInclusiveUnitPrice;
-  // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = row.tempFutureTickets - row.ticketsNum;
-  // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
-  calculateinvoiceAmount();
-};
-// 鏈鏉ョエ閲戦澶辩劍鎿嶄綔
-const invoiceAmountBlur = (row) => {
-  if (!row.ticketsAmount) {
-    row.ticketsAmount = 0;
-  }
-  // 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰�
-  if (row.ticketsAmount > row.tempFutureTicketsAmount) {
-    proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�");
-    row.ticketsAmount = 0;
-  }
-  // 璁$畻鏈鏉ョエ鏁�
-  row.ticketsNum = (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2);
-  // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = row.tempFutureTickets - row.ticketsNum;
-  // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
-  calculateinvoiceAmount();
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡鍑芥暟
-function getNowFormatDate() {
-  let date = new Date(),
-    year = date.getFullYear(), //鑾峰彇瀹屾暣鐨勫勾浠�(4浣�)
-    month = date.getMonth() + 1, //鑾峰彇褰撳墠鏈堜唤(0-11,0浠h〃1鏈�)
-    strDate = date.getDate(); // 鑾峰彇褰撳墠鏃�(1-31)
-  if (month < 10) month = `0${month}`; // 濡傛灉鏈堜唤鏄釜浣嶆暟锛屽湪鍓嶉潰琛�0
-  if (strDate < 10) strDate = `0${strDate}`; // 濡傛灉鏃ユ槸涓綅鏁帮紝鍦ㄥ墠闈㈣ˉ0
-  return `${year}-${month}-${strDate}`;
-}
-
-function calculateinvoiceAmount() {
-  console.log("productData", productData.value);
-  var invoiceAmountTotal = 0;
-  productData.value.forEach((item) => {
-    if (item.ticketsAmount) {
-      invoiceAmountTotal += item.ticketsAmount;
-    }
-  });
-  form.value.invoiceAmount = invoiceAmountTotal.toFixed(2);
-}
-
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/procurementManagement/paymentEntry/index.vue b/src/views/procurementManagement/paymentEntry/index.vue
index 2f24fe9..5ee8d17 100644
--- a/src/views/procurementManagement/paymentEntry/index.vue
+++ b/src/views/procurementManagement/paymentEntry/index.vue
@@ -27,10 +27,10 @@
           </el-col>
           <el-col :span="4">
             <el-form-item style="float: right; margin-right: unset">
-              <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
               <el-button type="primary" @click="openForm('add')">
                 鏂板浠樻
               </el-button>
+              <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
 <!--              <el-button type="danger" plain @click="handleDelete">-->
 <!--                鍒犻櫎-->
 <!--              </el-button>-->
@@ -127,145 +127,100 @@
 				</template>
 			</PIMTable>
     </div>
-    <el-dialog
+    <FormDialog
       v-model="dialogFormVisible"
-      :title="operationType === 'add' ? '鏂板浠樻鐧昏' : '缂栬緫浠樻鐧昏'"
-      width="60%"
+      title="鏂板浠樻椤甸潰"
+      :width="'90%'"
       @close="closeDia"
+      @confirm="submitForm"
+      @cancel="closeDia"
     >
-      <el-form
-        :model="form"
-        label-width="140px"
-        label-position="top"
-        :rules="rules"
-        ref="formRef"
+      <el-table
+        v-if="forms.length"
+        :data="forms"
+        border
+        style="width: 100%"
+        size="small"
       >
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
-              <el-input
-                v-model="form.purchaseContractNumber"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-              <el-input
-                v-model="form.salesContractNo"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
-              <el-input
-                v-model="form.supplierName"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
-              <el-input
-                v-model="form.invoiceNumber"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
-              <el-input
-                v-model="form.invoiceAmount"
-                placeholder="鑷姩濉厖"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏈浠樻閲戦锛�" prop="currentPaymentAmount">
-              <el-input-number :step="0.01" :min="0" style="width: 100%"
-															 :precision="2"
-                v-model="form.currentPaymentAmount"
-                placeholder="璇疯緭鍏�"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="浠樻鏂瑰紡锛�" prop="paymentMethod">
-              <el-select
-                v-model="form.paymentMethod"
-                placeholder="璇烽�夋嫨"
-                clearable
-              >
-                <el-option label="鐢垫眹" value="鐢垫眹" />
-                <el-option label="鎵垮厬" value="鎵垮厬" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-					<el-col :span="12">
-						<el-form-item label="浠樻鏃ユ湡锛�" prop="paymentDate">
-							<el-date-picker
-								style="width: 100%"
-								v-model="form.paymentDate"
-								value-format="YYYY-MM-DD"
-								format="YYYY-MM-DD"
-								type="date"
-								placeholder="璇烽�夋嫨"
-								clearable
-							/>
-						</el-form-item>
-					</el-col>
-        </el-row>
-        <el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="鐧昏浜猴細" prop="registrant">
-							<el-input
-								v-model="form.registrant"
-								placeholder="璇疯緭鍏�"
-								clearable
-								disabled
-							/>
-						</el-form-item>
-					</el-col>
-          <el-col :span="12">
-            <el-form-item label="鐧昏鏃ユ湡锛�" prop="registrationtDate">
-              <el-input
-                v-model="form.registrationtDate"
-                placeholder="璇疯緭鍏�"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+        <el-table-column type="index" label="搴忓彿" width="50" align="center"/>
+        <el-table-column label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber" show-overflow-tooltip />
+        <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip />
+        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" show-overflow-tooltip />
+        <el-table-column
+          label="浜у搧澶х被"
+          prop="productCategory"
+          show-overflow-tooltip
+          width="100"
+        />
+        <el-table-column
+          label="瑙勬牸鍨嬪彿"
+          prop="specificationModel"
+          show-overflow-tooltip
+          width="150"
+        />
+        <el-table-column
+          label="寰呬粯娆鹃噾棰�(鍏�)"
+          prop="pendingTicketsTotal"
+          show-overflow-tooltip
+          width="170"
+        >
+          <template #default="{ row, column }">
+            <el-text type="danger">
+              {{ formattedNumber(row, column, row.pendingTicketsTotal) }}
+            </el-text>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏈浠樻閲戦(鍏�)" width="180">
+          <template #default="{ row }">
+            <el-input-number
+              v-model="row.currentPaymentAmount"
+              :step="0.01"
+              :min="0"
+              :max="Number(row.pendingTicketsTotal || 0)"
+              :precision="2"
+              style="width: 100%"
+              placeholder="璇疯緭鍏�"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="浠樻鏂瑰紡" width="160">
+          <template #default="{ row }">
+            <el-select v-model="row.paymentMethod" placeholder="璇烽�夋嫨" clearable>
+              <el-option label="鐢垫眹" value="鐢垫眹" />
+              <el-option label="鎵垮厬" value="鎵垮厬" />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="浠樻鏃ユ湡" width="170">
+          <template #default="{ row }">
+            <el-date-picker
+              v-model="row.paymentDate"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              type="date"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐧昏浜�" width="140">
+          <template #default="{ row }">
+            <el-input v-model="row.registrant" disabled />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐧昏鏃ユ湡" width="170">
+          <template #default="{ row }">
+            <el-input v-model="row.registrationtDate" />
+          </template>
+        </el-table-column>
+      </el-table>
+      <div v-else class="empty-tip">璇烽�夋嫨闇�瑕佷粯娆剧殑璁板綍</div>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive, toRefs, getCurrentInstance, nextTick, onMounted } from "vue";
 import { Search } from "@element-plus/icons-vue";
 import { ElMessageBox } from "element-plus";
@@ -296,10 +251,12 @@
   {
     label: "閲囪喘鍚堝悓鍙�",
     prop: "purchaseContractNumber",
+    width:160
   },
   {
     label: "閿�鍞悎鍚屽彿",
     prop: "salesContractNo",
+    width:160
   },
   {
     label: "渚涘簲鍟嗗悕绉�",
@@ -309,6 +266,7 @@
 	{
 		label: "浠樻鐘舵��",
 		prop: "statusName",
+    width:110,
 		dataType: "tag",
 		formatType: (params) => {
 			if (params == '鏈畬鎴愪粯娆�') {
@@ -320,35 +278,33 @@
 			}
 		},
 	},
-  {
-    label: "鍙戠エ鍙�",
-    prop: "invoiceNumber",
-    width:200
-  },
-  {
-    label: "鍙戠エ閲戦(鍏�)",
-    prop: "invoiceAmount",
-    formatData: (params) => {
-      return params ? parseFloat(params).toFixed(2) : 0;
-    },
-  },
+	{
+		label: "浜у搧澶х被",
+		prop: "productCategory",
+		showOverflowTooltip: true,
+		width: 100
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "specificationModel",
+		showOverflowTooltip: true,
+		width: 150
+	},
   {
     label: "宸蹭粯娆鹃噾棰�(鍏�)",
-    prop: "paymentAmountTotal",
+    prop: "ticketsTotal",
+    width: 120,
     formatData: (params) => {
       return params ? parseFloat(params).toFixed(2) : 0;
     },
   },
   {
     label: "寰呬粯娆鹃噾棰�(鍏�)",
-    prop: "unPaymentAmountTotal",
+    prop: "pendingTicketsTotal",
+    width: 120,
     formatData: (params) => {
       return params ? parseFloat(params).toFixed(2) : 0;
     },
-  },
-  {
-    label: "褰曞叆浜�",
-    prop: "issUer",
   },
 ]);
 const tableData = ref([]);
@@ -356,6 +312,7 @@
 const selectedRows = ref([]);
 const tableLoading = ref(false);
 const childrenLoading = ref(false);
+const forms = ref([]);
 const userStore = useUserStore();
 const page = reactive({
   current: 1,
@@ -376,8 +333,6 @@
     purchaseLedgerId: "",
     salesContractNo: "",
     supplierName: "",
-    invoiceNumber: "",
-    invoiceAmount: "",
     taxRate: "",
     currentPaymentAmount: "",
     paymentMethod: "",
@@ -394,9 +349,6 @@
       { required: true, message: "璇疯緭鍏�", trigger: "blur" },
     ],
     paymentMethod: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    invoiceNumber: [
-      { required: true, message: "璇烽�夋嫨閲囪喘鍚堝悓鍙�", trigger: "change" },
-    ],
   },
 });
 const { form, rules } = toRefs(data);
@@ -409,11 +361,16 @@
 	if (!normalized) return 'info';
 	return normalized === '鏈畬鎴愪粯娆�' ? 'danger' : 'success';
 };
+
+const formattedNumber = (row, column, cellValue) => {
+  const val = Number(cellValue ?? 0);
+  return Number.isFinite(val) ? val.toFixed(2) : "0.00";
+};
 // 瀛愯〃鍚堣鏂规硶
 const summarizeMainTable1 = (param) => {
   return proxy.summarizeTable(
     param,
-    ["invoiceAmount", "paymentAmountTotal", "unPaymentAmountTotal"],
+    ["ticketsTotal", "pendingTicketsTotal"],
     {
       ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
@@ -442,8 +399,8 @@
   tableLoading.value = true;
   invoiceListPage({ ...searchForm, ...page }).then((res) => {
     tableLoading.value = false;
-    tableData.value = res.records;
-		page.total = res.total;
+    tableData.value = res.data.records;
+		page.total = res.data.total;
 		if (expandedRowKeys.value.length > 0) {
 			const arr = []
 			const index = tableData.value.findIndex(item => item.id === expandedRowKeys.value[0]);
@@ -501,48 +458,66 @@
 };
 // 鎵撳紑寮规
 const openForm = (type, row) => {
-  if (selectedRows.value.length !== 1) {
-    proxy.$message.error("璇烽�夋嫨涓�鏉″彂绁ㄦ暟鎹�");
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgError("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
     return;
   }
-	if (selectedRows.value[0].unPaymentAmountTotal == 0) {
-		proxy.$message.warning("鏃犻渶鍐嶄粯娆�");
-		return;
-	}
-  operationType.value = type;
-  form.value = {};
-  form.value = { ...selectedRows.value[0] };
-  form.value.ticketRegistrationId = selectedRows.value[0].id;
-  form.value.id = null;
-  // 鏌ヨ閲囪喘鍚堝悓鍙�
-  form.value.registrationtDate = getCurrentDate();
-  form.value.paymentDate = getCurrentDate();
-  form.value.registrant = userStore.name;
+  const validRows = selectedRows.value.filter((item) => Number(item.pendingTicketsTotal || 0) !== 0);
+  if (validRows.length === 0) {
+    proxy.$modal.msgWarning("鎵�閫夎褰曞潎鏃犻渶浠樻");
+    return;
+  }
+  forms.value = validRows.map((row) => ({
+    purchaseContractNumber: row.purchaseContractNumber || "",
+    salesContractNo: row.salesContractNo || "",
+    supplierName: row.supplierName || "",
+    supplierId: row.supplierId,
+    productCategory: row.productCategory || "",
+    specificationModel: row.specificationModel || "",
+    pendingTicketsTotal: Number(row.pendingTicketsTotal || 0),
+    currentPaymentAmount: "",
+    paymentMethod: "",
+    paymentDate: "",
+    registrant: userStore.nickName,
+    registrationtDate: getCurrentDate(),
+    ticketRegistrationId: row.id,
+    purchaseLedgerId: row.salesLedgerId,
+    salesLedgerProductId: row.id,
+  }));
   dialogFormVisible.value = true;
 };
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
-  proxy.$refs["formRef"].validate((valid) => {
-    if (valid) {
-      if (operationType.value === "edit") {
-        submitEdit();
-      } else {
-        submitAdd();
-      }
+  if (forms.value.length === 0) {
+    proxy.$modal.msgError("璇烽�夋嫨浠樻璁板綍");
+    return;
+  }
+  for (let i = 0; i < forms.value.length; i++) {
+    const item = forms.value[i];
+    const pendingAmount = Number(item.pendingTicketsTotal || 0);
+    const currentAmount = Number(item.currentPaymentAmount);
+    if (!item.currentPaymentAmount && item.currentPaymentAmount !== 0) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇峰~鍐欎粯娆鹃噾棰漙);
+      return;
     }
-  });
-};
-// 鎻愪氦鏂板
-const submitAdd = () => {
-  paymentRegistrationAdd(form.value).then((res) => {
-    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-    closeDia();
-    getList();
-  });
-};
-// 鎻愪氦淇敼
-const submitEdit = () => {
-  paymentRegistrationEdit(form.value).then((res) => {
+    if (currentAmount > pendingAmount) {
+      proxy.$modal.msgError(
+        `绗� ${i + 1} 鏉★細浠樻閲戦涓嶈兘瓒呰繃寰呬粯娆鹃噾棰濓紙寰呬粯娆撅細${pendingAmount.toFixed(
+          2
+        )}锛塦
+      );
+      return;
+    }
+    if (!item.paymentMethod) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇烽�夋嫨浠樻鏂瑰紡`);
+      return;
+    }
+    if (!item.paymentDate) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇烽�夋嫨浠樻鏃ユ湡`);
+      return;
+    }
+  }
+  paymentRegistrationAdd(forms.value).then(() => {
     proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
     closeDia();
     getList();
@@ -550,7 +525,7 @@
 };
 // 鍏抽棴寮规
 const closeDia = () => {
-  proxy.resetForm("formRef");
+  forms.value = [];
   dialogFormVisible.value = false;
 };
 // 鍒犻櫎
@@ -562,7 +537,7 @@
   })
     .then(() => {
       tableLoading.value = true;
-			delPaymentRegistration(row.id)
+			delPaymentRegistration([row.id])
         .then((res) => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
@@ -602,4 +577,9 @@
 ::v-deep(.el-checkbox__label) {
   font-weight: bold;
 }
+.empty-tip {
+  text-align: center;
+  padding: 20px 0;
+  color: #909399;
+}
 </style>
diff --git a/src/views/procurementManagement/paymentHistory/index.vue b/src/views/procurementManagement/paymentHistory/index.vue
index c38b4b0..179373b 100644
--- a/src/views/procurementManagement/paymentHistory/index.vue
+++ b/src/views/procurementManagement/paymentHistory/index.vue
@@ -43,6 +43,13 @@
           鎼滅储
         </el-button>
         <el-button @click="handleExport">瀵煎嚭</el-button>
+        <el-button
+          type="danger"
+          :disabled="selectedRows.length === 0"
+          @click="handleBatchDelete"
+        >
+          鎵归噺鍒犻櫎 ({{ selectedRows.length }})
+        </el-button>
       </el-form-item>
     </el-form>
     <div class="table_list">
@@ -58,7 +65,18 @@
         :tableLoading="tableLoading"
         @pagination="pagination"
         :total="page.total"
-      ></PIMTable>
+      >
+        <template #operation="{ row }">
+          <el-button
+            type="primary"
+            link
+            size="small"
+            @click="handleDelete(row)"
+          >
+            鍒犻櫎
+          </el-button>
+        </template>
+      </PIMTable>
     </div>
   </div>
 </template>
@@ -66,7 +84,9 @@
 <script setup>
 import { ref, reactive, getCurrentInstance, onMounted } from "vue";
 import { Search } from "@element-plus/icons-vue";
-import { paymentHistoryListPage } from "@/api/procurementManagement/paymentEntry.js";
+import { ElMessageBox } from "element-plus";
+import { paymentHistoryListPage} from "@/api/procurementManagement/paymentEntry.js";
+import {delPaymentRegistration } from "@/api/procurementManagement/procurementInvoiceLedger.js";
 import useFormData from "@/hooks/useFormData";
 import dayjs from "dayjs";
 
@@ -104,6 +124,13 @@
   {
     label: "鐧昏鏃ユ湡",
     prop: "registrationtDate",
+  },
+  {
+    label: "鎿嶄綔",
+    dataType: "slot",
+    slot: "operation",
+    width: 100,
+    align: "center",
   },
 ]);
 const tableData = ref([]);
@@ -170,6 +197,62 @@
   getList();
 };
 
+// 鍒犻櫎
+const handleDelete = (row) => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      tableLoading.value = true;
+      delPaymentRegistration([row.id])
+        .then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm(
+    `纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉℃暟鎹悧锛焋,
+    "鍒犻櫎鎻愮ず",
+    {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }
+  )
+    .then(() => {
+      tableLoading.value = true;
+      const ids = selectedRows.value.map((item) => item.id);
+      delPaymentRegistration(ids)
+        .then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          selectedRows.value = [];
+          getList();
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
 // 瀵煎嚭
 const handleExport = () => {
   const { paymentDate, ...rest } = searchForm;
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
index 741e6ac..db34a7f 100644
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ b/src/views/procurementManagement/paymentLedger/index.vue
@@ -43,7 +43,7 @@
             />
             <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
             <el-table-column
-              label="鍙戠エ閲戦(鍏�)"
+              label="鍚堝悓閲戦(鍏�)"
               prop="invoiceAmount"
               show-overflow-tooltip
               :formatter="formattedNumber"
@@ -83,6 +83,7 @@
             :column="tableColumnSon"
             :tableData="originalTableDataSon"
             :isSelection="false"
+            :isShowPagination="false"
             :tableLoading="tableLoadingSon"
             :isShowSummary="isShowSummarySon"
             :summaryMethod="summarizeMainTable1"
@@ -94,14 +95,6 @@
               </el-text>
             </template>
           </PIMTable>
-          <pagination
-            v-show="sonTotal > 0"
-            :total="sonTotal"
-            @pagination="sonPaginationSearch"
-            :layout="page.layout"
-            :page="sonPage.current"
-            :limit="sonPage.size"
-          />
         </div>
       </el-col>
     </el-row>
@@ -117,25 +110,6 @@
 } from "@/api/procurementManagement/paymentLedger.js";
 import Pagination from "../../../components/PIMTable/Pagination.vue";
 
-const tableColumn = ref([
-  {
-    label: "渚涘簲鍟嗗悕绉�",
-    prop: "supplierName",
-    width:240
-  },
-  {
-    label: "鍙戠エ閲戦(鍏�)",
-    prop: "invoiceAmount",
-  },
-  {
-    label: "浠樻閲戦(鍏�)",
-    prop: "paymentAmount",
-  },
-  {
-    label: "搴斾粯閲戦(鍏�)",
-    prop: "payableAmount",
-  },
-]);
 const tableData = ref([]);
 const tableLoading = ref(false);
 const data = reactive({
@@ -164,11 +138,16 @@
 const tableColumnSon = ref([
   {
     label: "鍙戠敓鏃ユ湡",
-    prop: "happenTime",
+    prop: "paymentDate",
 		width: 110,
   },
   {
-    label: "鍙戠エ閲戦(鍏�)",
+    label: "閲囪喘鍚堝悓鍙�",
+    prop: "purchaseContractNumber",
+		width: 150,
+  },
+  {
+    label: "鍚堝悓閲戦(鍏�)",
     prop: "invoiceAmount",
 		width: 200,
     formatData: (params) => {
@@ -177,7 +156,7 @@
   },
   {
     label: "浠樻閲戦(鍏�)",
-    prop: "currentPaymentAmount",
+    prop: "paymentAmount",
 		width: 200,
     formatData: (params) => {
       return params ? parseFloat(params).toFixed(2) : 0;
@@ -214,7 +193,7 @@
 const summarizeMainTable1 = (param) => {
   let summarizeTable = proxy.summarizeTable(
     param,
-    ["invoiceAmount", "currentPaymentAmount"],
+    ["invoiceAmount", "paymentAmount"],
     {
       ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
@@ -245,8 +224,6 @@
   paymentLedgerList({
     ...searchForm.value,
     ...page,
-    detailPageNum: detailPageNum.value, // 鏂板
-    detailPageSize: detailPageSize.value, // 鏂板
   }).then((res) => {
     let result = res.data;
     tableLoading.value = false;
diff --git a/src/views/procurementManagement/priceManagement/index.vue b/src/views/procurementManagement/priceManagement/index.vue
index 006ce3c..76a39ed 100644
--- a/src/views/procurementManagement/priceManagement/index.vue
+++ b/src/views/procurementManagement/priceManagement/index.vue
@@ -62,7 +62,7 @@
       </el-table>
     </el-card>
 
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" width="600px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" :width="'600px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" label-width="120px">
         <el-form-item label="鍟嗗搧鍚嶇О">
           <el-select v-model="formData.productName" placeholder="璇烽�夋嫨鍟嗗搧" style="width: 100%">
@@ -102,15 +102,12 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive, computed } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 
diff --git a/src/views/procurementManagement/procurementLedger/fileList.vue b/src/views/procurementManagement/procurementLedger/fileList.vue
new file mode 100644
index 0000000..fb392c5
--- /dev/null
+++ b/src/views/procurementManagement/procurementLedger/fileList.vue
@@ -0,0 +1,67 @@
+<template>
+  <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+    <el-table :data="tableData" border height="40vh">
+      <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+      <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+          <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import filePreview from '@/components/filePreview/index.vue'
+import { delCommonFile } from '@/api/publicApi/commonFile.js'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+  dialogVisible.value = false
+}
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list
+}
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+// 鍒犻櫎闄勪欢
+const handleDelete = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎闄勪欢"${row.name}"鍚楋紵`, '鍒犻櫎纭', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning',
+  }).then(() => {
+    delCommonFile([row.id]).then(() => {
+      ElMessage.success('鍒犻櫎鎴愬姛')
+      // 浠庡垪琛ㄤ腑绉婚櫎宸插垹闄ょ殑闄勪欢
+      const index = tableData.value.findIndex(item => item.id === row.id)
+      if (index !== -1) {
+        tableData.value.splice(index, 1)
+      }
+    }).catch(() => {
+      ElMessage.error('鍒犻櫎澶辫触')
+    })
+  }).catch(() => {
+    proxy.$modal.msg('宸插彇娑堝垹闄�')
+  })
+}
+defineExpose({
+  open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index a8ca5f7..9b86624 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -2,466 +2,442 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <el-form :model="searchForm" :inline="true">
+        <el-form :model="searchForm"
+                 :inline="true">
           <el-form-item label="渚涘簲鍟嗗悕绉帮細">
-            <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.supplierName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="閲囪喘鍚堝悓鍙凤細">
-            <el-input
-                v-model="searchForm.purchaseContractNumber"
-                style="width: 240px"
-                placeholder="璇疯緭鍏�"
-                @change="handleQuery"
-                clearable
-                :prefix-icon="Search"
-            />
+            <el-input v-model="searchForm.purchaseContractNumber"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      @change="handleQuery"
+                      clearable
+                      :prefix-icon="Search" />
           </el-form-item>
           <el-form-item label="閿�鍞悎鍚屽彿锛�">
-            <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.salesContractNo"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="椤圭洰鍚嶇О锛�">
-            <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.projectName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="褰曞叆鏃ユ湡锛�">
-            <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-                            placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+            <el-date-picker v-model="searchForm.entryDate"
+                            value-format="YYYY-MM-DD"
+                            format="YYYY-MM-DD"
+                            type="daterange"
+                            placeholder="璇烽�夋嫨"
+                            clearable
+                            @change="changeDaterange" />
           </el-form-item>
           <el-form-item>
-            <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
+            <el-button type="primary"
+                       @click="handleQuery"> 鎼滅储 </el-button>
           </el-form-item>
         </el-form>
       </div>
-
     </div>
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
-        <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
-        <el-button type="success" @click="openScanAddDialog">鎵爜鏂板</el-button>
+        <el-button type="primary"
+                   @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="success"
+                   @click="openScanAddDialog">鎵爜鏂板</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</el-button>
       </div>
-      <el-table
-          :data="tableData"
-          border
-          v-loading="tableLoading"
-          @selection-change="handleSelectionChange"
-          :expand-row-keys="expandedRowKeys"
-          :row-key="(row) => row.id"
-          show-summary
-          :summary-method="summarizeMainTable"
-          @expand-change="expandChange"
-          height="calc(100vh - 18.5em)"
-          :row-class-name="tableRowClassName"
-      >
-        <el-table-column align="center" type="selection" width="55" />
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                @selection-change="handleSelectionChange"
+                :expand-row-keys="expandedRowKeys"
+                :row-key="(row) => row.id"
+                show-summary
+                :summary-method="summarizeMainTable"
+                @expand-change="expandChange"
+                height="calc(100vh - 19em)"
+                :row-class-name="tableRowClassName">
+        <el-table-column align="center"
+                         type="selection"
+                         width="55" />
         <el-table-column type="expand">
           <template #default="props">
-            <el-table
-                :data="props.row.children"
-                border
-                show-summary
-                :summary-method="summarizeChildrenTable"
-            >
-              <el-table-column
-                  align="center"
-                  label="搴忓彿"
-                  type="index"
-                  width="60"
-              />
-              <el-table-column label="浜у搧澶х被" prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-              <el-table-column label="鍗曚綅" prop="unit" />
-              <el-table-column label="鏁伴噺" prop="quantity" />
-              <el-table-column label="绋庣巼(%)" prop="taxRate" />
-              <el-table-column
-                  label="鍚◣鍗曚环(鍏�)"
-                  prop="taxInclusiveUnitPrice"
-                  :formatter="formattedNumber"
-              />
-              <el-table-column
-                  label="鍚◣鎬讳环(鍏�)"
-                  prop="taxInclusiveTotalPrice"
-                  :formatter="formattedNumber"
-              />
-              <el-table-column
-                  label="涓嶅惈绋庢�讳环(鍏�)"
-                  prop="taxExclusiveTotalPrice"
-                  :formatter="formattedNumber"
-              />
+            <el-table :data="props.row.children"
+                      border
+                      show-summary
+                      :summary-method="summarizeChildrenTable">
+              <el-table-column align="center"
+                               label="搴忓彿"
+                               type="index"
+                               width="60" />
+              <el-table-column label="浜у搧澶х被"
+                               prop="productCategory" />
+              <el-table-column label="瑙勬牸鍨嬪彿"
+                               prop="specificationModel" />
+              <el-table-column label="鍗曚綅"
+                               prop="unit" />
+              <el-table-column label="鏁伴噺"
+                               prop="quantity" />
+              <el-table-column label="绋庣巼(%)"
+                               prop="taxRate" />
+              <el-table-column label="鍚◣鍗曚环(鍏�)"
+                               prop="taxInclusiveUnitPrice"
+                               :formatter="formattedNumber" />
+              <el-table-column label="鍚◣鎬讳环(鍏�)"
+                               prop="taxInclusiveTotalPrice"
+                               :formatter="formattedNumber" />
+              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+                               prop="taxExclusiveTotalPrice"
+                               :formatter="formattedNumber" />
             </el-table>
           </template>
         </el-table-column>
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column
-            label="閲囪喘鍚堝悓鍙�"
-            prop="purchaseContractNumber"
-            width="200"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="閿�鍞悎鍚屽彿"
-            prop="salesContractNo"
-            width="200"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="渚涘簲鍟嗗悕绉�"
-            width="240"
-            prop="supplierName"
-            show-overflow-tooltip
-        />
-        <el-table-column label="璁㈠崟鐘舵��" width="100" align="center">
+        <el-table-column align="center"
+                         label="搴忓彿"
+                         type="index"
+                         width="60" />
+        <el-table-column label="閲囪喘鍚堝悓鍙�"
+                         prop="purchaseContractNumber"
+                         width="200"
+                         show-overflow-tooltip />
+        <el-table-column label="閿�鍞悎鍚屽彿"
+                         prop="salesContractNo"
+                         show-overflow-tooltip />
+        <el-table-column label="渚涘簲鍟嗗悕绉�"
+                         prop="supplierName"
+                         show-overflow-tooltip />
+        <el-table-column label="璁㈠崟鐘舵��"
+                         width="100"
+                         align="center">
           <template #default="scope">
-            <el-tag v-if="scope.row.isInvalid" type="danger" size="small">澶辨晥</el-tag>
-            <el-tag v-else type="success" size="small">姝e父</el-tag>
+            <el-tag v-if="scope.row.isInvalid"
+                    type="danger"
+                    size="small">澶辨晥</el-tag>
+            <el-tag v-else
+                    type="success"
+                    size="small">姝e父</el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-            label="椤圭洰鍚嶇О"
-            prop="projectName"
-            width="420"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="瀹℃壒鐘舵��"
-            prop="approvalStatus"
-            width="200"
-            show-overflow-tooltip
-        >
+        <el-table-column label="椤圭洰鍚嶇О"
+                         prop="projectName"
+                         width="420"
+                         show-overflow-tooltip />
+        <el-table-column label="瀹℃壒鐘舵��"
+                         prop="approvalStatus"
+                         width="200"
+                         show-overflow-tooltip>
           <template #default="scope">
-            <el-tag
-                size="small"
-            >
+            <el-tag size="small">
               {{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-            label="浠樻鏂瑰紡"
-            width="100"
-            prop="paymentMethod"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="鍚堝悓閲戦(鍏�)"
-            prop="contractAmount"
-            width="200"
-            show-overflow-tooltip
-            :formatter="formattedNumber"
-        />
-        <el-table-column
-            label="褰曞叆浜�"
-            prop="recorderName"
-            width="100"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="褰曞叆鏃ユ湡"
-            prop="entryDate"
-            width="100"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            fixed="right"
-            label="鎿嶄綔"
-            min-width="150"
-            align="center"
-        >
+        <el-table-column label="绛捐鏃ユ湡"
+                         prop="executionDate"
+                         width="100"
+                         show-overflow-tooltip />
+        <el-table-column label="浠樻鏂瑰紡"
+                         width="100"
+                         prop="paymentMethod"
+                         show-overflow-tooltip />
+        <el-table-column label="鍚堝悓閲戦(鍏�)"
+                         prop="contractAmount"
+                         width="200"
+                         show-overflow-tooltip
+                         :formatter="formattedNumber" />
+        <el-table-column label="褰曞叆浜�"
+                         prop="recorderName"
+                         width="120"
+                         show-overflow-tooltip />
+        <el-table-column label="褰曞叆鏃ユ湡"
+                         prop="entryDate"
+                         width="100"
+                         show-overflow-tooltip />
+        <el-table-column fixed="right"
+                         label="鎿嶄綔"
+                         width="180"
+                         align="center">
           <template #default="scope">
-            <el-button
-                link
-                type="primary"
-                size="small"
-                @click="openForm('edit', scope.row)"
-            >缂栬緫</el-button
-            >
-            <el-button
-                link
-                type="success"
-                size="small"
-                @click="showQRCode(scope.row)"
-            >鐢熸垚浜岀淮鐮�</el-button
-            >
-
+            <el-button link
+                       type="primary"
+                       size="small"
+                       @click="openForm('edit', scope.row)">缂栬緫</el-button>
+            <el-button link
+                       type="success"
+                       size="small"
+                       @click="showQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+            <el-button link
+                       type="primary"
+                       size="small"
+                       @click="downLoadFile(scope.row)">闄勪欢</el-button>
           </template>
         </el-table-column>
       </el-table>
-      <pagination
-          v-show="total > 0"
-          :total="total"
-          layout="total, sizes, prev, pager, next, jumper"
-          :page="page.current"
-          :limit="page.size"
-          @pagination="paginationChange"
-      />
+      <pagination v-show="total > 0"
+                  :total="total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="paginationChange" />
     </div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form
-          :model="form"
-          label-width="140px"
-          label-position="top"
-          :rules="rules"
-          ref="formRef"
-      >
+    <el-dialog v-model="dialogFormVisible"
+               :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
+               width="70%"
+               @close="closeDia">
+      <el-form :model="form"
+               label-width="140px"
+               label-position="top"
+               :rules="rules"
+               ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
-              <el-input
-                  v-model="form.purchaseContractNumber"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+                          prop="purchaseContractNumber">
+              <el-input v-model="form.purchaseContractNumber"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
-              <el-select
-                  v-model="form.salesLedgerId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="salesLedgerChange"
-              >
-                <el-option
-                    v-for="item in salesContractList"
-                    :key="item.id"
-                    :label="item.salesContractNo"
-                    :value="item.id"
-                />
+            <el-form-item label="閿�鍞悎鍚屽彿锛�"
+                          prop="salesLedgerId">
+              <el-select v-model="form.salesLedgerId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable
+                         @change="salesLedgerChange">
+                <el-option v-for="item in salesContractList"
+                           :key="item.id"
+                           :label="item.salesContractNo"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
-              <el-select
-                  v-model="form.supplierId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  filterable
-                  allow-create
-              >
-                <el-option
-                    v-for="item in supplierList"
-                    :key="item.id"
-                    :label="item.supplierName"
-                    :value="item.id"
-                />
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+                          prop="supplierId">
+              <el-select v-model="form.supplierId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable>
+                <el-option v-for="item in supplierList"
+                           :key="item.id"
+                           :label="item.supplierName"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-              <el-input
-                  v-model="form.projectName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="椤圭洰鍚嶇О"
+                          prop="projectName">
+              <el-input v-model="form.projectName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input
-                  v-model="form.paymentMethod"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+              <el-input v-model="form.paymentMethod"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
-              <el-date-picker
-                  style="width: 100%"
-                  v-model="form.executionDate"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  type="date"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              />
+            <el-form-item label="绛捐鏃ユ湡锛�"
+                          prop="executionDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.executionDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="瀹℃壒浜猴細" prop="approverId">
-              <el-select
-                  v-model="form.approverId"
-                  placeholder="璇烽�夋嫨瀹℃壒浜�"
-                  clearable
-              >
-                <el-option
-                    v-for="item in userList"
-                    :key="item.userId"
-                    :label="item.nickName"
-                    :value="item.userId"
-                />
+            <el-form-item label="瀹℃壒浜猴細"
+                          prop="approverId">
+              <el-select v-model="form.approverId"
+                         placeholder="璇烽�夋嫨瀹℃壒浜�"
+                         clearable>
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
               </el-select>
             </el-form-item>
-            <el-form-item label="褰曞叆浜猴細" prop="recorderId" v-show="false">
-              <el-select
-                  v-model="form.recorderId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  disabled
-              >
-                <el-option
-                    v-for="item in userList"
-                    :key="item.userId"
-                    :label="item.nickName"
-                    :value="item.userId"
-                />
+            <el-form-item label="褰曞叆浜猴細"
+                          prop="recorderId"
+                          v-show="false">
+              <el-select v-model="form.recorderId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         disabled>
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
-              <el-date-picker
-                  style="width: 100%"
-                  v-model="form.entryDate"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  type="date"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              />
+            <el-form-item label="褰曞叆鏃ユ湡锛�"
+                          prop="entryDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.entryDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
-            <el-button type="primary" @click="openProductForm('add')"
-            >娣诲姞</el-button
-            >
-            <el-button plain type="danger" @click="deleteProduct"
-            >鍒犻櫎</el-button
-            >
+          <el-form-item label="浜у搧淇℃伅锛�"
+                        prop="entryDate">
+            <el-button type="primary"
+                       @click="openProductForm('add')">娣诲姞</el-button>
+            <el-button plain
+                       type="danger"
+                       @click="deleteProduct">鍒犻櫎</el-button>
           </el-form-item>
-          <div class="select-button-group" style="width: 220px; margin: 20px 0;" v-if="operationType === 'add'">
-            <el-select
-                filterable
-                allow-create
-                :reserve-keyword="true"
-                :default-first-option="false"
-                v-model="templateName"
-                :input-value="filterInputValue"
-                @filter-change="onTemplateFilterChange"
-                @change="onTemplateChange"
-                style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
-                placeholder="璇烽�夋嫨"
-                class="no-arrow-select"
-            >
-              <el-option
-                  v-for="item in templateList"
-                  :key="item.value"
-                  :label="item.templateName"
-                  :value="item.templateName"
-              ></el-option>
+          <div class="select-button-group"
+               style="width: 220px; margin: 20px 0;"
+               v-if="operationType === 'add'">
+            <el-select filterable
+                       allow-create
+                       :reserve-keyword="true"
+                       :default-first-option="false"
+                       v-model="templateName"
+                       :input-value="filterInputValue"
+                       @filter-change="onTemplateFilterChange"
+                       @change="onTemplateChange"
+                       style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
+                       placeholder="璇烽�夋嫨"
+                       class="no-arrow-select">
+              <el-option v-for="item in templateList"
+                         :key="item.value"
+                         :label="item.templateName"
+                         :value="item.templateName"></el-option>
             </el-select>
             <!-- 鎸夐挳锛氫笌 Select 楂樺害鍖归厤锛屽幓鎺夊乏渚ц竟妗嗭紝鏃犵紳琛旀帴 -->
-            <el-button
-                size="small"
-                style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
-                @click="handleButtonClick"
-                :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate"
-            >
+            <el-button size="small"
+                       style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
+                       @click="handleButtonClick"
+                       :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate">
               淇濆瓨
             </el-button>
           </div>
         </el-row>
-        <el-table
-            :data="productData"
-            border
-            @selection-change="productSelected"
-            show-summary
-            :summary-method="summarizeProTable"
-        >
-          <el-table-column align="center" type="selection" width="55" />
-          <el-table-column
-              align="center"
-              label="搴忓彿"
-              type="index"
-              width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-          <el-table-column label="鍗曚綅" prop="unit" width="70" />
-          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
-          <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
-          <el-table-column
-              label="鍚◣鍗曚环(鍏�)"
-              prop="taxInclusiveUnitPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              label="鍚◣鎬讳环(鍏�)"
-              prop="taxInclusiveTotalPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              label="涓嶅惈绋庢�讳环(鍏�)"
-              prop="taxExclusiveTotalPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              fixed="right"
-              label="鎿嶄綔"
-              min-width="60"
-              align="center"
-          >
+        <el-table :data="productData"
+                  border
+                  @selection-change="productSelected"
+                  show-summary
+                  :summary-method="summarizeProTable">
+          <el-table-column align="center"
+                           type="selection"
+                           width="55" />
+          <el-table-column align="center"
+                           label="搴忓彿"
+                           type="index"
+                           width="60" />
+          <el-table-column label="浜у搧澶х被"
+                           prop="productCategory" />
+          <el-table-column label="瑙勬牸鍨嬪彿"
+                           prop="specificationModel" />
+          <el-table-column label="鍗曚綅"
+                           prop="unit"
+                           width="70" />
+          <el-table-column label="鏁伴噺"
+                           prop="quantity"
+                           width="70" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺"
+                           prop="warnNum"
+                           width="120"
+                           show-overflow-tooltip />
+          <el-table-column label="绋庣巼(%)"
+                           prop="taxRate"
+                           width="80" />
+          <el-table-column label="鍚◣鍗曚环(鍏�)"
+                           prop="taxInclusiveUnitPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="鍚◣鎬讳环(鍏�)"
+                           prop="taxInclusiveTotalPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+                           prop="taxExclusiveTotalPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="鏄惁璐ㄦ"
+                           prop="isChecked"
+                           width="150">
             <template #default="scope">
-              <el-button
-                  link
-                  type="primary"
-                  size="small"
-                  @click="openProductForm('edit', scope.row, scope.$index)"
-              >缂栬緫</el-button
-              >
+              <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
+                {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column fixed="right"
+                           label="鎿嶄綔"
+                           min-width="60"
+                           align="center">
+            <template #default="scope">
+              <el-button link
+                         type="primary"
+                         size="small"
+                         @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
             </template>
           </el-table-column>
         </el-table>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="澶囨敞路锛�" prop="remark">
-              <el-input
-                  v-model="form.remark"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-                  type="textarea"
-                  :rows="2"
-              />
+            <el-form-item label="澶囨敞路锛�"
+                          prop="remark">
+              <el-input v-model="form.remark"
+                        placeholder="璇疯緭鍏�"
+                        clearable
+                        type="textarea"
+                        :rows="2" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
-              <el-upload
-                  v-model:file-list="fileList"
-                  :action="upload.url"
-                  multiple
-                  ref="fileUpload"
-                  auto-upload
-                  :headers="upload.headers"
-                  :before-upload="handleBeforeUpload"
-                  :on-error="handleUploadError"
-                  :on-success="handleUploadSuccess"
-                  :on-remove="handleRemove"
-              >
+            <el-form-item label="闄勪欢鏉愭枡锛�"
+                          prop="remark">
+              <el-upload v-model:file-list="fileList"
+                         :action="upload.url"
+                         multiple
+                         ref="fileUpload"
+                         auto-upload
+                         :headers="upload.headers"
+                         :before-upload="handleBeforeUpload"
+                         :on-error="handleUploadError"
+                         :on-success="handleUploadSuccess"
+                         :on-remove="handleRemove">
                 <el-button type="primary">涓婁紶</el-button>
                 <template #tip>
                   <div class="el-upload__tip">
@@ -476,335 +452,332 @@
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
+          <el-button type="primary"
+                     @click="submitForm">纭</el-button>
           <el-button @click="closeDia">鍙栨秷</el-button>
         </div>
       </template>
     </el-dialog>
-    <el-dialog
-        v-model="productFormVisible"
-        :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
-        width="40%"
-        @close="closeProductDia"
-    >
-      <el-form
-          :model="productForm"
-          label-width="140px"
-          label-position="top"
-          :rules="productRules"
-          ref="productFormRef"
-      >
+    <el-dialog v-model="productFormVisible"
+               :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+               width="40%"
+               @close="closeProductDia">
+      <el-form :model="productForm"
+               label-width="140px"
+               label-position="top"
+               :rules="productRules"
+               ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="浜у搧澶х被锛�" prop="productId">
-              <el-tree-select
-                  v-model="productForm.productId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  check-strictly
-                  @change="getModels"
-                  :data="productOptions"
-                  :render-after-expand="false"
-                  style="width: 100%"
-              />
+            <el-form-item label="浜у搧澶х被锛�"
+                          prop="productId">
+              <el-tree-select v-model="productForm.productId"
+                              placeholder="璇烽�夋嫨"
+                              clearable
+                              check-strictly
+                              @change="getModels"
+                              :data="productOptions"
+                              :render-after-expand="false"
+                              style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
-              <el-select
-                  v-model="productForm.productModelId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="getProductModel"
-              >
-                <el-option
-                    v-for="item in modelOptions"
-                    :key="item.id"
-                    :label="item.model"
-                    :value="item.id"
-                />
+            <el-form-item label="瑙勬牸鍨嬪彿锛�"
+                          prop="productModelId">
+              <el-select v-model="productForm.productModelId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         @change="getProductModel">
+                <el-option v-for="item in modelOptions"
+                           :key="item.id"
+                           :label="item.model"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍗曚綅锛�" prop="unit">
-              <el-input
-                  v-model="productForm.unit"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="鍗曚綅锛�"
+                          prop="unit">
+              <el-input v-model="productForm.unit"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
-              <el-select
-                  v-model="productForm.taxRate"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="mathNum"
-              >
-                <el-option label="1" value="1" />
-                <el-option label="6" value="6" />
-                <el-option label="13" value="13" />
+            <el-form-item label="绋庣巼(%)锛�"
+                          prop="taxRate">
+              <el-select v-model="productForm.taxRate"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         @change="mathNum">
+                <el-option label="1"
+                           value="1" />
+                <el-option label="6"
+                           value="6" />
+                <el-option label="13"
+                           value="13" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
-              <el-input-number
-                  v-model="productForm.taxInclusiveUnitPrice"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-                  @change="mathNum"
-              />
+            <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
+                          prop="taxInclusiveUnitPrice">
+              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="mathNum" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鏁伴噺锛�" prop="quantity">
-              <el-input-number
-                  :step="0.1"
-                  clearable
-                  :precision="2"
-                  style="width: 100%"
-                  v-model="productForm.quantity"
-                  placeholder="璇疯緭鍏�"
-                  @change="mathNum"
-              />
+            <el-form-item label="鏁伴噺锛�"
+                          prop="quantity">
+              <el-input-number :step="0.1"
+                               clearable
+                               :precision="2"
+                               :min="0"
+                               style="width: 100%"
+                               v-model="productForm.quantity"
+                               placeholder="璇疯緭鍏�"
+                               @change="mathNum" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
-              <el-input-number
-                  v-model="productForm.taxInclusiveTotalPrice"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-                  @change="reverseMathNum('taxInclusiveTotalPrice')"
-              />
+            <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
+                          prop="taxInclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item
-                label="涓嶅惈绋庢�讳环(鍏�)锛�"
-                prop="taxExclusiveTotalPrice"
-            >
-              <el-input
-                  v-model="productForm.taxExclusiveTotalPrice"
-                  @change="reverseMathNum('taxExclusiveTotalPrice')"
-              />
+            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
+                          prop="taxExclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="reverseMathNum('taxExclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
-              <el-select
-                  v-model="productForm.invoiceType"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              >
-                <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
-                <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
+            <el-form-item label="鍙戠エ绫诲瀷锛�"
+                          prop="invoiceType">
+              <el-select v-model="productForm.invoiceType"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="澧炴櫘绁�"
+                           value="澧炴櫘绁�" />
+                <el-option label="澧炰笓绁�"
+                           value="澧炰笓绁�" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
-              <el-input-number
-                  v-model="productForm.warnNum"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-              />
+            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
+                          prop="warnNum">
+              <el-input-number v-model="productForm.warnNum"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏄惁璐ㄦ锛�"
+                          prop="isChecked">
+              <el-radio-group v-model="productForm.isChecked">
+                <el-radio label="鏄�"
+                          :value="true" />
+                <el-radio label="鍚�"
+                          :value="false" />
+              </el-radio-group>
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitProduct">纭</el-button>
+          <el-button type="primary"
+                     @click="submitProduct">纭</el-button>
           <el-button @click="closeProductDia">鍙栨秷</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
-    <el-dialog
-        v-model="qrCodeDialogVisible"
-        title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
-        width="400px"
-        center
-    >
+    <el-dialog v-model="qrCodeDialogVisible"
+               title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
+               width="400px"
+               center>
       <div style="text-align: center;">
-        <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
+        <img :src="qrCodeUrl"
+             alt="浜岀淮鐮�"
+             style="width:200px;height:200px;" />
         <div style="margin: 20px;">
-          <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
+          <el-button type="primary"
+                     @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
         </div>
       </div>
     </el-dialog>
-
     <!-- 鎵爜鏂板瀵硅瘽妗� -->
-    <el-dialog
-        v-model="scanAddDialogVisible"
-        title="鎵爜鏂板閲囪喘鍙拌处"
-        width="70%"
-        @close="closeScanAddDialog"
-    >
-      <el-form
-          :model="scanAddForm"
-          label-width="140px"
-          label-position="top"
-          :rules="scanAddRules"
-          ref="scanAddFormRef"
-      >
+    <el-dialog v-model="scanAddDialogVisible"
+               title="鎵爜鏂板閲囪喘鍙拌处"
+               width="70%"
+               @close="closeScanAddDialog">
+      <el-form :model="scanAddForm"
+               label-width="140px"
+               label-position="top"
+               :rules="scanAddRules"
+               ref="scanAddFormRef">
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="鎵爜鍐呭锛�">
-              <el-input
-                  v-model="scanAddForm.scanContent"
-                  type="textarea"
-                  :rows="3"
-                  placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
-                  @input="parseScanContent"
-              />
+              <el-input v-model="scanAddForm.scanContent"
+                        type="textarea"
+                        :rows="3"
+                        placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
+                        @input="parseScanContent" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
-              <el-input
-                  v-model="scanAddForm.purchaseContractNumber"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+                          prop="purchaseContractNumber">
+              <el-input v-model="scanAddForm.purchaseContractNumber"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
-              <el-input
-                  v-model="scanAddForm.supplierName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+                          prop="supplierName">
+              <el-input v-model="scanAddForm.supplierName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-              <el-input
-                  v-model="scanAddForm.projectName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="椤圭洰鍚嶇О锛�"
+                          prop="projectName">
+              <el-input v-model="scanAddForm.projectName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鍚堝悓閲戦(鍏�)锛�" prop="contractAmount">
-              <el-input-number
-                  v-model="scanAddForm.contractAmount"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-                  placeholder="璇疯緭鍏�"
-              />
+            <el-form-item label="鍚堝悓閲戦(鍏�)锛�"
+                          prop="contractAmount">
+              <el-input-number v-model="scanAddForm.contractAmount"
+                               :precision="2"
+                               :step="0.1"
+                               clearable
+                               style="width: 100%"
+                               placeholder="璇疯緭鍏�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡锛�">
-              <el-input
-                  v-model="scanAddForm.paymentMethod"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+              <el-input v-model="scanAddForm.paymentMethod"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="褰曞叆浜猴細">
-              <el-input v-model="scanAddForm.recorderName" disabled />
+              <el-input v-model="scanAddForm.recorderName"
+                        disabled />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="澶囨敞锛�">
-              <el-input
-                  v-model="scanAddForm.remark"
-                  type="textarea"
-                  :rows="2"
-                  placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
-                  clearable
-              />
+              <el-input v-model="scanAddForm.remark"
+                        type="textarea"
+                        :rows="2"
+                        placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                        clearable />
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitScanAdd">纭鏂板</el-button>
+          <el-button type="primary"
+                     @click="submitScanAdd">纭鏂板</el-button>
           <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 鎵爜鐧昏瀵硅瘽妗� -->
-    <el-dialog
-        v-model="scanDialogVisible"
-        title="鎵爜鐧昏"
-        width="60%"
-        @close="closeScanDialog"
-    >
-      <el-form
-          :model="scanForm"
-          label-width="120px"
-          label-position="left"
-          :rules="scanRules"
-          ref="scanFormRef"
-      >
+    <el-dialog v-model="scanDialogVisible"
+               title="鎵爜鐧昏"
+               width="60%"
+               @close="closeScanDialog">
+      <el-form :model="scanForm"
+               label-width="120px"
+               label-position="left"
+               :rules="scanRules"
+               ref="scanFormRef">
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="閲囪喘鍚堝悓鍙凤細">
-              <el-input v-model="scanForm.purchaseContractNumber" disabled />
+              <el-input v-model="scanForm.purchaseContractNumber"
+                        disabled />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="渚涘簲鍟嗗悕绉帮細">
-              <el-input v-model="scanForm.supplierName" disabled />
+              <el-input v-model="scanForm.supplierName"
+                        disabled />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="椤圭洰鍚嶇О锛�">
-              <el-input v-model="scanForm.projectName" disabled />
+              <el-input v-model="scanForm.projectName"
+                        disabled />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="鎵爜鏃堕棿锛�">
-              <el-input v-model="scanForm.scanTime" disabled />
+              <el-input v-model="scanForm.scanTime"
+                        disabled />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="鎵爜浜猴細">
-              <el-input v-model="scanForm.scannerName" disabled />
+              <el-input v-model="scanForm.scannerName"
+                        disabled />
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -818,30 +791,40 @@
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="鎵爜澶囨敞锛�">
-              <el-input
-                  v-model="scanForm.scanRemark"
-                  type="textarea"
-                  :rows="3"
-                  placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�"
-              />
+              <el-input v-model="scanForm.scanRemark"
+                        type="textarea"
+                        :rows="3"
+                        placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="鎵爜璁板綍锛�">
-              <el-table :data="scanRecords" border style="width: 100%">
-                <el-table-column label="搴忓彿" type="index" width="60" align="center" />
-                <el-table-column label="鎵爜鏃堕棿" prop="scanTime" width="180" />
-                <el-table-column label="鎵爜浜�" prop="scannerName" width="120" />
-                <el-table-column label="鎵爜鐘舵��" prop="scanStatus" width="100">
+              <el-table :data="scanRecords"
+                        border
+                        style="width: 100%">
+                <el-table-column label="搴忓彿"
+                                 type="index"
+                                 width="60"
+                                 align="center" />
+                <el-table-column label="鎵爜鏃堕棿"
+                                 prop="scanTime"
+                                 width="180" />
+                <el-table-column label="鎵爜浜�"
+                                 prop="scannerName"
+                                 width="120" />
+                <el-table-column label="鎵爜鐘舵��"
+                                 prop="scanStatus"
+                                 width="100">
                   <template #default="scope">
                     <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
                       {{ scope.row.scanStatus }}
                     </el-tag>
                   </template>
                 </el-table-column>
-                <el-table-column label="澶囨敞" prop="scanRemark" />
+                <el-table-column label="澶囨敞"
+                                 prop="scanRemark" />
               </el-table>
             </el-form-item>
           </el-col>
@@ -849,362 +832,382 @@
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitScan">纭鎵爜</el-button>
+          <el-button type="primary"
+                     @click="submitScan">纭鎵爜</el-button>
           <el-button @click="closeScanDialog">鍙栨秷</el-button>
         </div>
       </template>
     </el-dialog>
-
+    <FileList ref="fileListRef" />
   </div>
 </template>
 
 <script setup>
-import {getToken} from "@/utils/auth";
-import pagination from "@/components/PIMTable/Pagination.vue";
-import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from "vue";
-import {Search} from "@element-plus/icons-vue";
-import {ElMessage, ElMessageBox} from "element-plus";
-import {userListNoPage} from "@/api/system/user.js";
-import {
-  addOrUpdateSalesLedgerProduct,
-  delLedgerFile,
-  delProduct,
-  getProductInfoByContractNo,
-  getSalesLedgerWithProducts,
-} from "@/api/salesManagement/salesLedger.js";
-import {
-  addOrEditPurchase,
-  addPurchaseTemplate,
-  createPurchaseNo,
-  delPurchase,
-  getOptions,
-  getPurchaseById,
-  getPurchaseTemplateList,
-  getSalesNo,
-  productList,
-  purchaseListPage
-} from "@/api/procurementManagement/procurementLedger.js";
-import useFormData from "@/hooks/useFormData.js";
-import QRCode from "qrcode";
-import useUserStore from "@/store/modules/user";
-import {modelList, productTreeList} from "@/api/basicData/product.js";
-import dayjs from "dayjs";
-import { getCurrentDate } from "@/utils/index.js";
+  import { getToken } from "@/utils/auth";
+  import pagination from "@/components/PIMTable/Pagination.vue";
+  import {
+    ref,
+    onMounted,
+    reactive,
+    toRefs,
+    getCurrentInstance,
+    nextTick,
+  } from "vue";
+  import { Search } from "@element-plus/icons-vue";
+  import { ElMessageBox, ElMessage } from "element-plus";
+  import { userListNoPage } from "@/api/system/user.js";
+  import FileList from "./fileList.vue";
+  import {
+    getSalesLedgerWithProducts,
+    addOrUpdateSalesLedgerProduct,
+    delProduct,
+    delLedgerFile,
+    getProductInfoByContractNo,
+  } from "@/api/salesManagement/salesLedger.js";
+  import {
+    addOrEditPurchase,
+    addPurchaseTemplate,
+    createPurchaseNo,
+    delPurchase,
+    getSalesNo,
+    purchaseListPage,
+    productList,
+    getPurchaseById,
+    getOptions,
+    getPurchaseTemplateList,
+  } from "@/api/procurementManagement/procurementLedger.js";
+  import useFormData from "@/hooks/useFormData.js";
+  import QRCode from "qrcode";
 
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const modelOptions = ref([]);
-const userList = ref([]);
-const productOptions = ref([]);
-const salesContractList = ref([]);
-const supplierList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
+  const { proxy } = getCurrentInstance();
+  const tableData = ref([]);
+  const productData = ref([]);
+  const selectedRows = ref([]);
+  const productSelectedRows = ref([]);
+  const modelOptions = ref([]);
+  const userList = ref([]);
+  const productOptions = ref([]);
+  const salesContractList = ref([]);
+  const supplierList = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+  });
+  const total = ref(0);
+  const fileList = ref([]);
+  import useUserStore from "@/store/modules/user";
+  import { modelList, productTreeList } from "@/api/basicData/product.js";
+  import dayjs from "dayjs";
 
-const userStore = useUserStore();
+  const userStore = useUserStore();
 
-// 浜岀淮鐮佺浉鍏冲彉閲�
-const qrCodeDialogVisible = ref(false);
-const qrCodeUrl = ref("");
+  // 浜岀淮鐮佺浉鍏冲彉閲�
+  const qrCodeDialogVisible = ref(false);
+  const qrCodeUrl = ref("");
 
-// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
-const approvalStatusText = {
-  0: '瀹℃壒涓�',
-  1: '瀹℃壒閫氳繃',
-  2: '瀹℃壒澶辫触'
-};
+  // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
+  const approvalStatusText = {
+    0: "瀹℃壒涓�",
+    1: "瀹℃壒閫氳繃",
+    2: "瀹℃壒澶辫触",
+  };
 
-
-const templateName = ref('');
-const filterInputValue = ref('');
-const templateList = ref([]);
-const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
-
-// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-const checkTemplateNameDuplicate = (name) => {
-  if (!name || name.trim() === '') {
-    isTemplateNameDuplicate.value = false;
-    return false;
-  }
-  const isDuplicate = templateList.value.some(item => item.templateName === name.trim());
-  isTemplateNameDuplicate.value = isDuplicate;
-  return isDuplicate;
-};
-
-// 闃叉姈瀹氭椂鍣�
-let duplicateCheckTimer = null;
-const onTemplateFilterChange = (val) => {
-  filterInputValue.value = val ?? '';
-  // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
-  if (duplicateCheckTimer) {
-    clearTimeout(duplicateCheckTimer);
-  }
-  // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
-  if (val && val.trim()) {
-    duplicateCheckTimer = setTimeout(() => {
-      const isDuplicate = checkTemplateNameDuplicate(val);
-      if (isDuplicate) {
-        ElMessage({
-          message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
-          type: 'warning',
-          duration: 2000
-        });
-      }
-    }, 300); // 300ms 闃叉姈
-  } else {
-    isTemplateNameDuplicate.value = false;
-  }
-};
-
-// allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
-const onTemplateChange = async (val) => {
-  if (typeof val === 'string') {
-    filterInputValue.value = val;
-    // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
-    checkTemplateNameDuplicate(val);
-  }
-  
-  // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
-  const matchedTemplate = templateList.value.find(item => item.templateName === val);
-  
-  if (matchedTemplate?.id) {
-    // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
-    form.value = {
-      ...form.value,
-      ...matchedTemplate,
-    };
-    productData.value = matchedTemplate.productData || [];
-    // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
-    try {
-      const res = await createPurchaseNo();
-      if (res?.data) {
-        form.value.purchaseContractNumber = res.data;
-      }
-    } catch (error) {
-      console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
-    }
-  } else {
-    // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
-    const currentFormData = { ...form.value };
-    const currentProductData = [...productData.value];
-    
-    // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
-    if (!dialogFormVisible.value) {
-      operationType.value = 'add';
-      dialogFormVisible.value = true;
-    }
-    
-    // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
-    await nextTick();
-    form.value = {
-      ...form.value,
-      ...currentFormData,
-    };
-    productData.value = currentProductData;
-  }
-};
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
-  searchForm: {
-    supplierName: "", // 渚涘簲鍟嗗悕绉�
-    purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
-    salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
-    projectName: "", // 椤圭洰鍚嶇О
-    entryDate: null, // 褰曞叆鏃ユ湡
-    entryDateStart: undefined,
-    entryDateEnd: undefined,
-  },
-  form: {
-    purchaseContractNumber: "",
-    salesLedgerId: "",
-    projectName: "",
-    recorderId: "",
-    entryDate: "",
-    productData: [],
-    supplierName: "",
-    supplierId: "",
-    paymentMethod: "",
-    executionDate: "",
-  },
-  rules: {
-    purchaseContractNumber: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    approverId:[{ required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" }],
-    executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-  },
-});
-const {  form, rules } = toRefs(data);
-const { form: searchForm } = useFormData(data.searchForm);
-
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const productOperationIndex = ref("");
-const currentId = ref("");
-const productFormData = reactive({
-  productForm: {
-    productId: "",
-    productCategory: "",
-    productModelId: "",
-    specificationModel: "",
-    unit: "",
-    quantity: "",
-    taxInclusiveUnitPrice: "",
-    taxRate: "",
-    taxInclusiveTotalPrice: "",
-    taxExclusiveTotalPrice: "",
-    invoiceType: "",
-    warnNum: "",
-  },
-  productRules: {
-    productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    taxInclusiveUnitPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    warnNum: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
-    taxInclusiveTotalPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    taxExclusiveTotalPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-  },
-});
-const { productForm, productRules } = toRefs(productFormData);
-const upload = reactive({
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-  headers: { Authorization: "Bearer " + getToken() },
-});
-
-const changeDaterange = (value) => {
-  if (value) {
-    searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
-    searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
-  } else {
-    searchForm.entryDateStart = undefined;
-    searchForm.entryDateEnd = undefined;
-  }
-  handleQuery();
-};
-
-const formattedNumber = (row, column, cellValue) => {
-  if (cellValue === null || cellValue === undefined || cellValue === '') {
-    return '0.00';
-  }
-  const num = parseFloat(cellValue);
-  if (isNaN(num)) {
-    return '0.00';
-  }
-  return num.toFixed(2);
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-
-// 淇濆瓨妯℃澘
-const handleButtonClick = async () => {
-  // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
-  if (!templateName.value || templateName.value.trim() === '') {
-    ElMessage({
-      message: '璇疯緭鍏ユā鏉垮悕绉�',
-      type: 'warning',
-    });
-    return;
-  }
+  const templateName = ref("");
+  const filterInputValue = ref("");
+  const templateList = ref([]);
+  const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
 
   // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-  const isDuplicate = checkTemplateNameDuplicate(templateName.value);
-  if (isDuplicate) {
-    ElMessage({
-      message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
-      type: 'warning',
-    });
-    return;
-  }
-
-  // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
-  if (!form.value.supplierId) {
-    ElMessage({
-      message: '璇峰厛閫夋嫨渚涘簲鍟�',
-      type: 'warning',
-    });
-    return;
-  }
-
-  // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
-  // if (!productData.value || productData.value.length === 0) {
-  //   ElMessage({
-  //     message: '璇峰厛娣诲姞浜у搧淇℃伅',
-  //     type: 'warning',
-  //   });
-  //   return;
-  // }
-
-  try {
-    let params = {
-      productData: proxy.HaveJson(productData.value),
-      supplierId: form.value.supplierId,
-      paymentMethod: form.value.paymentMethod,
-      recorderId: form.value.recorderId,
-      approverId: form.value.approverId,
-      templateName: templateName.value.trim()
-    };
-    console.log(params);
-    let res = await addPurchaseTemplate(params);
-
-    if (res && res.code === 200) {
-      ElMessage({
-        message: '妯℃澘淇濆瓨鎴愬姛',
-        type: 'success',
-      });
-      // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
-      await getTemplateList();
-      // 娓呯┖妯℃澘鍚嶇О杈撳叆
-      templateName.value = '';
-      filterInputValue.value = '';
+  const checkTemplateNameDuplicate = name => {
+    if (!name || name.trim() === "") {
       isTemplateNameDuplicate.value = false;
+      return false;
+    }
+    const isDuplicate = templateList.value.some(
+      item => item.templateName === name.trim()
+    );
+    isTemplateNameDuplicate.value = isDuplicate;
+    return isDuplicate;
+  };
+
+  // 闃叉姈瀹氭椂鍣�
+  let duplicateCheckTimer = null;
+  const onTemplateFilterChange = val => {
+    filterInputValue.value = val ?? "";
+    // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+    if (duplicateCheckTimer) {
+      clearTimeout(duplicateCheckTimer);
+    }
+    // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
+    if (val && val.trim()) {
+      duplicateCheckTimer = setTimeout(() => {
+        const isDuplicate = checkTemplateNameDuplicate(val);
+        if (isDuplicate) {
+          ElMessage({
+            message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+            type: "warning",
+            duration: 2000,
+          });
+        }
+      }, 300); // 300ms 闃叉姈
     } else {
+      isTemplateNameDuplicate.value = false;
+    }
+  };
+
+  // allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
+  const onTemplateChange = async val => {
+    if (typeof val === "string") {
+      filterInputValue.value = val;
+      // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
+      checkTemplateNameDuplicate(val);
+    }
+
+    // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
+    const matchedTemplate = templateList.value.find(
+      item => item.templateName === val
+    );
+
+    if (matchedTemplate?.id) {
+      // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
+      form.value = {
+        ...form.value,
+        ...matchedTemplate,
+      };
+      productData.value = matchedTemplate.productData || [];
+      // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
+      try {
+        const res = await createPurchaseNo();
+        if (res?.data) {
+          form.value.purchaseContractNumber = res.data;
+        }
+      } catch (error) {
+        console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+      }
+    } else {
+      // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
+      const currentFormData = { ...form.value };
+      const currentProductData = [...productData.value];
+
+      // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
+      if (!dialogFormVisible.value) {
+        operationType.value = "add";
+        dialogFormVisible.value = true;
+      }
+
+      // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
+      await nextTick();
+      form.value = {
+        ...form.value,
+        ...currentFormData,
+      };
+      productData.value = currentProductData;
+    }
+  };
+
+  // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+  const operationType = ref("");
+  const dialogFormVisible = ref(false);
+  const data = reactive({
+    searchForm: {
+      supplierName: "", // 渚涘簲鍟嗗悕绉�
+      purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
+      salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+      projectName: "", // 椤圭洰鍚嶇О
+      entryDate: null, // 褰曞叆鏃ユ湡
+      entryDateStart: undefined,
+      entryDateEnd: undefined,
+    },
+    form: {
+      purchaseContractNumber: "",
+      salesLedgerId: "",
+      projectName: "",
+      recorderId: "",
+      entryDate: "",
+      productData: [],
+      supplierName: "",
+      supplierId: "",
+      paymentMethod: "",
+      executionDate: "",
+      isChecked: true,
+    },
+    rules: {
+      purchaseContractNumber: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      approverId: [
+        { required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" },
+      ],
+      projectName: [
+        { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
+      ],
+      supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    },
+  });
+  const { form, rules } = toRefs(data);
+  const { form: searchForm } = useFormData({
+    ...data.searchForm,
+    // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
+    entryDate: [
+      dayjs().startOf("day").format("YYYY-MM-DD"),
+      dayjs().endOf("day").format("YYYY-MM-DD"),
+    ],
+    entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
+    entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
+  });
+
+  // 浜у搧琛ㄥ崟寮规鏁版嵁
+  const productFormVisible = ref(false);
+  const productOperationType = ref("");
+  const productOperationIndex = ref("");
+  const currentId = ref("");
+  const productFormData = reactive({
+    productForm: {
+      productId: "",
+      productCategory: "",
+      productModelId: "",
+      specificationModel: "",
+      unit: "",
+      quantity: "",
+      taxInclusiveUnitPrice: "",
+      taxRate: "",
+      taxInclusiveTotalPrice: "",
+      taxExclusiveTotalPrice: "",
+      invoiceType: "",
+      warnNum: "",
+      isChecked: true,
+    },
+    productRules: {
+      productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxInclusiveUnitPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      taxInclusiveTotalPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      taxExclusiveTotalPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    },
+  });
+  const { productForm, productRules } = toRefs(productFormData);
+  const upload = reactive({
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+  });
+
+  const changeDaterange = value => {
+    if (value) {
+      searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+      searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+    } else {
+      searchForm.entryDateStart = undefined;
+      searchForm.entryDateEnd = undefined;
+    }
+    handleQuery();
+  };
+
+  const formattedNumber = (row, column, cellValue) => {
+    return parseFloat(cellValue).toFixed(2);
+  };
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+
+  // 淇濆瓨妯℃澘
+  const handleButtonClick = async () => {
+    // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
+    if (!templateName.value || templateName.value.trim() === "") {
       ElMessage({
-        message: res?.msg || '妯℃澘淇濆瓨澶辫触',
-        type: 'error',
+        message: "璇疯緭鍏ユā鏉垮悕绉�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
+    const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+    if (isDuplicate) {
+      ElMessage({
+        message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
+    if (!form.value.supplierId) {
+      ElMessage({
+        message: "璇峰厛閫夋嫨渚涘簲鍟�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
+    // if (!productData.value || productData.value.length === 0) {
+    //   ElMessage({
+    //     message: '璇峰厛娣诲姞浜у搧淇℃伅',
+    //     type: 'warning',
+    //   });
+    //   return;
+    // }
+
+    try {
+      let params = {
+        productData: proxy.HaveJson(productData.value),
+        supplierId: form.value.supplierId,
+        paymentMethod: form.value.paymentMethod,
+        recorderId: form.value.recorderId,
+        approverId: form.value.approverId,
+        templateName: templateName.value.trim(),
+      };
+      console.log(params);
+      let res = await addPurchaseTemplate(params);
+
+      if (res && res.code === 200) {
+        ElMessage({
+          message: "妯℃澘淇濆瓨鎴愬姛",
+          type: "success",
+        });
+        // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
+        await getTemplateList();
+        // 娓呯┖妯℃澘鍚嶇О杈撳叆
+        templateName.value = "";
+        filterInputValue.value = "";
+        isTemplateNameDuplicate.value = false;
+      } else {
+        ElMessage({
+          message: res?.msg || "妯℃澘淇濆瓨澶辫触",
+          type: "error",
+        });
+      }
+    } catch (error) {
+      console.error("淇濆瓨妯℃澘澶辫触:", error);
+      ElMessage({
+        message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+        type: "error",
       });
     }
-  } catch (error) {
-    console.error('淇濆瓨妯℃澘澶辫触:', error);
-    ElMessage({
-      message: '妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯',
-      type: 'error',
-    });
-  }
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
-  return proxy.summarizeTable(
+  };
+  // 瀛愯〃鍚堣鏂规硶
+  const summarizeChildrenTable = param => {
+    return proxy.summarizeTable(
       param,
       [
         "taxInclusiveUnitPrice",
@@ -1219,27 +1222,26 @@
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
-  );
-};
-const paginationChange = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  const { entryDate, ...rest } = searchForm;
-  purchaseListPage({ ...rest, ...page })
-      .then((res) => {
+    );
+  };
+  const paginationChange = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    tableLoading.value = true;
+    const { entryDate, ...rest } = searchForm;
+    purchaseListPage({ ...rest, ...page })
+      .then(res => {
         tableLoading.value = false;
         // tableData.value = res.data.records;
-        // 澶勭悊鏁版嵁锛屾坊鍔犲け鏁堢姸鎬佹爣璁�
         tableData.value = res.data.records.map(record => ({
           ...record,
-          isInvalid: record.isWhite === 1
+          isInvalid: record.isWhite === 1,
         }));
         // 鍒濆鍖栧瓙鏁版嵁鏁扮粍
-        tableData.value.forEach((item) => {
+        tableData.value.forEach(item => {
           item.children = [];
         });
         total.value = res.data.total;
@@ -1248,742 +1250,758 @@
       .catch(() => {
         tableLoading.value = false;
       });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-const productSelected = (selectedRows) => {
-  productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = async (row, expandedRows) => {
-  if (expandedRows.length > 0) {
-    expandedRowKeys.value = [];
-    try {
-      const res = await productList({ salesLedgerId: row.id, type: 2 });
-      const index = tableData.value.findIndex((item) => item.id === row.id);
-      if (index > -1) {
-        tableData.value[index].children = res.data || [];
-        expandedRowKeys.value.push(row.id);
-      }
-    } catch (error) {
-      console.error('鍔犺浇浜у搧鍒楄〃澶辫触:', error);
-      proxy.$modal.msgError('鍔犺浇浜у搧鍒楄〃澶辫触');
-      // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
-      const index = expandedRows.findIndex(item => item.id === row.id);
-      if (index > -1) {
-        expandedRows.splice(index, 1);
-      }
-    }
-  } else {
-    expandedRowKeys.value = [];
-  }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(param, ["contractAmount"]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeProTable = (param) => {
-  return proxy.summarizeTable(param, [
-    "taxInclusiveUnitPrice",
-    "taxInclusiveTotalPrice",
-    "taxExclusiveTotalPrice",
-  ]);
-};
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
-  await getTemplateList()
-  operationType.value = type;
-  form.value = {};
-  productData.value = [];
-  fileList.value = [];
-  templateName.value = '';
-  filterInputValue.value = '';
-  isTemplateNameDuplicate.value = false;
-  try {
-    // 骞惰鍔犺浇鍩虹鏁版嵁
-    const [userRes, salesRes, supplierRes] = await Promise.all([
-      userListNoPage(),
-      getSalesNo(),
-      getOptions()
-    ]);
-    
-    userList.value = userRes.data || [];
-    salesContractList.value = salesRes || [];
-    // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
-    supplierList.value = (supplierRes.data || []).filter((item) => item.isWhite === 0);
-    
-    // 璁剧疆榛樿鍊�
-    form.value.recorderId = userStore.id;
-    form.value.entryDate = getCurrentDate();
-    
-    if (type === "add") {
-      // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  const productSelected = selectedRows => {
+    productSelectedRows.value = selectedRows;
+  };
+  const expandedRowKeys = ref([]);
+  // 灞曞紑琛�
+  const expandChange = async (row, expandedRows) => {
+    if (expandedRows.length > 0) {
+      expandedRowKeys.value = [];
       try {
-        const purchaseNoRes = await createPurchaseNo();
-        if (purchaseNoRes?.data) {
-          form.value.purchaseContractNumber = purchaseNoRes.data;
+        const res = await productList({ salesLedgerId: row.id, type: 2 });
+        const index = tableData.value.findIndex(item => item.id === row.id);
+        if (index > -1) {
+          tableData.value[index].children = res.data || [];
+          expandedRowKeys.value.push(row.id);
         }
       } catch (error) {
-        console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
-        proxy.$modal.msgWarning('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�');
+        console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
+        proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
+        // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
+        const index = expandedRows.findIndex(item => item.id === row.id);
+        if (index > -1) {
+          expandedRows.splice(index, 1);
+        }
       }
-    } else if (type === "edit" && row?.id) {
-      // 缂栬緫鏃跺姞杞芥暟鎹�
-      currentId.value = row.id;
-      try {
-        const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
-        form.value = { ...purchaseRes };
-        productData.value = purchaseRes.productData || [];
-        fileList.value = purchaseRes.salesLedgerFiles || [];
-      } catch (error) {
-        console.error('鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:', error);
-        proxy.$modal.msgError('鍔犺浇鏁版嵁澶辫触');
-        return;
-      }
-    }
-    
-    dialogFormVisible.value = true;
-  } catch (error) {
-    console.error('鎵撳紑琛ㄥ崟澶辫触:', error);
-    proxy.$modal.msgError('鍔犺浇鍩虹鏁版嵁澶辫触');
-  }
-};
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
-  // 鏍℃鏂囦欢澶у皬
-  if (file.size > 1024 * 1024 * 10) {
-    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
-    return false;
-  }
-  proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
-  return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
-  proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
-  proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
-  proxy.$modal.closeLoading();
-  if (res.code === 200) {
-    file.tempId = res.data.tempId;
-    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
-  } else {
-    proxy.$modal.msgError(res.msg);
-    proxy.$refs.fileUpload.handleRemove(file);
-  }
-}
-// 绉婚櫎鏂囦欢
-async function handleRemove(file) {
-  if (!file?.id) {
-    return;
-  }
-  
-  if (file.size > 1024 * 1024 * 10) {
-    // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
-    return;
-  }
-  
-  if (operationType.value === "edit" && file.id) {
-    try {
-      await delLedgerFile([file.id]);
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-    } catch (error) {
-      console.error('鍒犻櫎鏂囦欢澶辫触:', error);
-      proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
-    }
-  }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  try {
-    const valid = await proxy.$refs["formRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
-    }
-    
-    if (!productData.value || productData.value.length === 0) {
-      proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
-      return;
-    }
-    
-    form.value.productData = proxy.HaveJson(productData.value);
-    form.value.tempFileIds = fileList.value
-      .filter(item => item.tempId)
-      .map((item) => item.tempId);
-    form.value.type = 2;
-    
-    try {
-      await addOrEditPurchase(form.value);
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-      getList();
-    } catch (error) {
-      console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
-      proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  } catch (error) {
-    console.error('琛ㄥ崟楠岃瘉澶辫触:', error);
-  }
-};
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-};
-// 鎵撳紑浜у搧寮规
-const openProductForm = (type, row, index) => {
-  productOperationType.value = type;
-  productOperationIndex.value = index;
-  productForm.value = {};
-  proxy.resetForm("productFormRef");
-  if (type === "edit") {
-    productForm.value = { ...row };
-  }
-  productFormVisible.value = true;
-  getProductOptions();
-};
-const getProductOptions = async () => {
-  try {
-    const res = await productTreeList();
-    productOptions.value = convertIdToValue(res);
-  } catch (error) {
-    console.error('鍔犺浇浜у搧閫夐」澶辫触:', error);
-    proxy.$modal.msgError('鍔犺浇浜у搧閫夐」澶辫触');
-  }
-};
-const getModels = async (value) => {
-  if (value) {
-    productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
-    try {
-      const res = await modelList({ id: value });
-      modelOptions.value = res || [];
-    } catch (error) {
-      console.error('鍔犺浇瑙勬牸鍨嬪彿澶辫触:', error);
-      proxy.$modal.msgError('鍔犺浇瑙勬牸鍨嬪彿澶辫触');
-      modelOptions.value = [];
-    }
-  } else {
-    productForm.value.productCategory = "";
-    modelOptions.value = [];
-  }
-};
-const getProductModel = (value) => {
-  const index = modelOptions.value.findIndex((item) => item.id === value);
-  if (index !== -1) {
-    productForm.value.specificationModel = modelOptions.value[index].model;
-    productForm.value.unit = modelOptions.value[index].unit;
-  } else {
-    productForm.value.specificationModel = null;
-    productForm.value.unit = null;
-  }
-};
-const findNodeById = (nodes, productId) => {
-  for (let i = 0; i < nodes.length; i++) {
-    if (nodes[i].value === productId) {
-      return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
-    }
-    if (nodes[i].children && nodes[i].children.length > 0) {
-      const foundNode = findNodeById(nodes[i].children, productId);
-      if (foundNode) {
-        return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
-      }
-    }
-  }
-  return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
-  return data.map((item) => {
-    const { id, children, ...rest } = item;
-    const newItem = {
-      ...rest,
-      value: id, // 灏� id 鏀逛负 value
-    };
-    if (children && children.length > 0) {
-      newItem.children = convertIdToValue(children);
-    }
-
-    return newItem;
-  });
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitProduct = async () => {
-  try {
-    const valid = await proxy.$refs["productFormRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
-    }
-    
-    if (operationType.value === "edit") {
-      await submitProductEdit();
     } else {
-      if (productOperationType.value === "add") {
-        productData.value.push({ ...productForm.value });
-      } else {
-        productData.value[productOperationIndex.value] = {
-          ...productForm.value,
-        };
-      }
-      closeProductDia();
+      expandedRowKeys.value = [];
     }
-  } catch (error) {
-    console.error('鎻愪氦浜у搧琛ㄥ崟澶辫触:', error);
-  }
-};
-
-const submitProductEdit = async () => {
-  try {
-    productForm.value.salesLedgerId = currentId.value;
-    productForm.value.type = 2;
-    await addOrUpdateSalesLedgerProduct(productForm.value);
-    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-    closeProductDia();
-    
-    // 閲嶆柊鍔犺浇浜у搧鏁版嵁
+  };
+  // 涓昏〃鍚堣鏂规硶
+  const summarizeMainTable = param => {
+    return proxy.summarizeTable(param, ["contractAmount"]);
+  };
+  // 瀛愯〃鍚堣鏂规硶
+  const summarizeProTable = param => {
+    return proxy.summarizeTable(param, [
+      "taxInclusiveUnitPrice",
+      "taxInclusiveTotalPrice",
+      "taxExclusiveTotalPrice",
+    ]);
+  };
+  // 鎵撳紑寮规
+  const openForm = async (type, row) => {
+    await getTemplateList();
+    operationType.value = type;
+    form.value = {};
+    productData.value = [];
+    fileList.value = [];
+    templateName.value = "";
+    filterInputValue.value = "";
+    isTemplateNameDuplicate.value = false;
     try {
-      const res = await getPurchaseById({ id: currentId.value, type: 2 });
-      productData.value = res.productData || [];
-    } catch (error) {
-      console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
-    }
-  } catch (error) {
-    console.error('鎻愪氦浜у搧缂栬緫澶辫触:', error);
-    proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
-  }
-};
-// 鍒犻櫎浜у搧
-const deleteProduct = async () => {
-  if (productSelectedRows.value.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  
-  if (operationType.value === "add") {
-    // 鏂板妯″紡涓嬶紝鐩存帴浠庡墠绔暟鎹腑鍒犻櫎
-    productSelectedRows.value.forEach((selectedRow) => {
-      const index = productData.value.findIndex(
-          (product) => product.id === selectedRow.id
+      // 骞惰鍔犺浇鍩虹鏁版嵁
+      const [userRes, salesRes, supplierRes] = await Promise.all([
+        userListNoPage(),
+        getSalesNo(),
+        getOptions(),
+      ]);
+
+      userList.value = userRes.data || [];
+      salesContractList.value = salesRes || [];
+      // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
+      supplierList.value = (supplierRes.data || []).filter(
+        item => item.isWhite === 0
       );
-      if (index !== -1) {
-        productData.value.splice(index, 1);
+
+      // 璁剧疆榛樿鍊�
+      form.value.recorderId = userStore.id;
+      form.value.entryDate = getCurrentDate();
+
+      if (type === "add") {
+        // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+        try {
+          const purchaseNoRes = await createPurchaseNo();
+          if (purchaseNoRes?.data) {
+            form.value.purchaseContractNumber = purchaseNoRes.data;
+          }
+        } catch (error) {
+          console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+          proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
+        }
+      } else if (type === "edit" && row?.id) {
+        // 缂栬緫鏃跺姞杞芥暟鎹�
+        currentId.value = row.id;
+        try {
+          const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
+          form.value = { ...purchaseRes };
+          productData.value = purchaseRes.productData || [];
+          fileList.value = purchaseRes.salesLedgerFiles || [];
+        } catch (error) {
+          console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
+          proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
+          return;
+        }
+      }
+
+      if (form.value.salesLedgerId == -1) {
+        form.value.salesLedgerId = null;
+      }
+      console.log(form.value, "form.value===========");
+      dialogFormVisible.value = true;
+    } catch (error) {
+      console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
+      proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
+    }
+  };
+  // 涓婁紶鍓嶆牎妫�
+  function handleBeforeUpload(file) {
+    // 鏍℃鏂囦欢澶у皬
+    if (file.size > 1024 * 1024 * 10) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+      return false;
+    }
+    proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+    return true;
+  }
+  // 涓婁紶澶辫触
+  function handleUploadError(err) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+    proxy.$modal.closeLoading();
+  }
+  // 涓婁紶鎴愬姛鍥炶皟
+  function handleUploadSuccess(res, file, uploadFiles) {
+    proxy.$modal.closeLoading();
+    if (res.code === 200) {
+      file.tempId = res.data.tempId;
+      proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+    } else {
+      proxy.$modal.msgError(res.msg);
+      proxy.$refs.fileUpload.handleRemove(file);
+    }
+  }
+  // 绉婚櫎鏂囦欢
+  async function handleRemove(file) {
+    if (!file?.id) {
+      return;
+    }
+    console.log("handleRemove", file.id);
+    if (file.size > 1024 * 1024 * 10) {
+      // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
+      return;
+    }
+
+    if (operationType.value === "edit" && file.id) {
+      try {
+        await delLedgerFile([file.id]);
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      } catch (error) {
+        console.error("鍒犻櫎鏂囦欢澶辫触:", error);
+        proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
+      }
+    }
+  }
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = () => {
+    proxy.$refs["formRef"].validate(valid => {
+      if (valid) {
+        if (productData.value.length > 0) {
+          form.value.productData = proxy.HaveJson(productData.value);
+        } else {
+          proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+          return;
+        }
+        let tempFileIds = [];
+        if (fileList.value.length > 0) {
+          tempFileIds = fileList.value.map(item => item.tempId);
+        }
+        form.value.tempFileIds = tempFileIds;
+        form.value.type = 2;
+
+        // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
+        if (!form.value.salesLedgerId) {
+          form.value.salesContractNo = "";
+        }
+
+        addOrEditPurchase(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+          getList();
+        });
       }
     });
-    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-  } else {
-    // 缂栬緫妯″紡涓嬶紝闇�瑕佽皟鐢ㄦ帴鍙e垹闄�
-    const ids = productSelectedRows.value
-      .filter(item => item.id)
-      .map((item) => item.id);
-    
-    if (ids.length === 0) {
-      proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
+  };
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    proxy.resetForm("formRef");
+    dialogFormVisible.value = false;
+  };
+  // 鎵撳紑浜у搧寮规
+  const openProductForm = (type, row, index) => {
+    productOperationType.value = type;
+    productOperationIndex.value = index;
+    productForm.value = {};
+    proxy.resetForm("productFormRef");
+    if (type === "edit") {
+      productForm.value = { ...row };
+    }
+    productFormVisible.value = true;
+    getProductOptions();
+  };
+  const getProductOptions = () => {
+    productTreeList().then(res => {
+      productOptions.value = convertIdToValue(res);
+    });
+  };
+  const getModels = value => {
+    if (value) {
+      productForm.value.productCategory =
+        findNodeById(productOptions.value, value) || "";
+      modelList({ id: value }).then(res => {
+        modelOptions.value = res;
+      });
+    } else {
+      productForm.value.productCategory = "";
+      modelOptions.value = [];
+    }
+  };
+  const getProductModel = value => {
+    const index = modelOptions.value.findIndex(item => item.id === value);
+    if (index !== -1) {
+      productForm.value.specificationModel = modelOptions.value[index].model;
+      productForm.value.unit = modelOptions.value[index].unit;
+    } else {
+      productForm.value.specificationModel = null;
+      productForm.value.unit = null;
+    }
+  };
+  const findNodeById = (nodes, productId) => {
+    for (let i = 0; i < nodes.length; i++) {
+      if (nodes[i].value === productId) {
+        return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
+      }
+      if (nodes[i].children && nodes[i].children.length > 0) {
+        const foundNode = findNodeById(nodes[i].children, productId);
+        if (foundNode) {
+          return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
+        }
+      }
+    }
+    return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+  };
+  function convertIdToValue(data) {
+    return data.map(item => {
+      const { id, children, ...rest } = item;
+      const newItem = {
+        ...rest,
+        value: id, // 灏� id 鏀逛负 value
+      };
+      if (children && children.length > 0) {
+        newItem.children = convertIdToValue(children);
+      }
+
+      return newItem;
+    });
+  }
+  // 鎻愪氦浜у搧琛ㄥ崟
+  const submitProduct = () => {
+    proxy.$refs["productFormRef"].validate(valid => {
+      if (valid) {
+        if (operationType.value === "edit") {
+          submitProductEdit();
+        } else {
+          if (productOperationType.value === "add") {
+            productData.value.push({ ...productForm.value });
+            console.log("productData.value---", productData.value);
+          } else {
+            productData.value[productOperationIndex.value] = {
+              ...productForm.value,
+            };
+          }
+          closeProductDia();
+        }
+      }
+    });
+  };
+  const submitProductEdit = () => {
+    productForm.value.salesLedgerId = currentId.value;
+    productForm.value.type = 2;
+    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeProductDia();
+      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
+        productData.value = res.productData;
+      });
+    });
+  };
+  // 鍒犻櫎浜у搧
+  const deleteProduct = () => {
+    if (productSelectedRows.value.length === 0) {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
-    
-    try {
-      await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
+    if (operationType.value === "add") {
+      productSelectedRows.value.forEach(selectedRow => {
+        const index = productData.value.findIndex(
+          product => product.id === selectedRow.id
+        );
+        if (index !== -1) {
+          productData.value.splice(index, 1);
+        }
+      });
+    } else {
+      let ids = [];
+      if (productSelectedRows.value.length > 0) {
+        ids = productSelectedRows.value.map(item => item.id);
+      }
+      ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
         confirmButtonText: "纭",
         cancelButtonText: "鍙栨秷",
         type: "warning",
+      })
+        .then(() => {
+          delProduct(ids).then(res => {
+            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+            closeProductDia();
+            getSalesLedgerWithProducts({ id: currentId.value, type: 2 }).then(
+              res => {
+                productData.value = res.productData;
+              }
+            );
+          });
+        })
+        .catch(() => {
+          proxy.$modal.msg("宸插彇娑�");
+        });
+    }
+  };
+  // 鍏抽棴浜у搧寮规
+  const closeProductDia = () => {
+    proxy.resetForm("productFormRef");
+    productFormVisible.value = false;
+  };
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
       });
-      
-      await delProduct(ids);
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      closeProductDia();
-      
-      // 閲嶆柊鍔犺浇浜у搧鏁版嵁
-      try {
-        const res = await getSalesLedgerWithProducts({ id: currentId.value, type: 2 });
-        productData.value = res.productData || [];
-      } catch (error) {
-        console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
-      }
-    } catch (error) {
-      if (error !== 'cancel') {
-        console.error('鍒犻櫎浜у搧澶辫触:', error);
-        proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
-      }
-    }
-  }
-};
-// 鍏抽棴浜у搧寮规
-const closeProductDia = () => {
-  proxy.resetForm("productFormRef");
-  productFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = async () => {
-  try {
-    await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭纭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    });
-    proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
-  } catch (error) {
-    if (error !== 'cancel') {
-      console.error('瀵煎嚭澶辫触:', error);
-      proxy.$modal.msgError("瀵煎嚭澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  }
-};
-
-// 鍒犻櫎
-const handleDelete = async () => {
-  if (selectedRows.value.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  
-  // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-  const unauthorizedData = selectedRows.value.filter(item => item.recorderName !== userStore.nickName);
-  if (unauthorizedData.length > 0) {
-    proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
-    return;
-  }
-  
-  const ids = selectedRows.value
-    .filter(item => item.id)
-    .map((item) => item.id);
-  
-  if (ids.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
-    return;
-  }
-  
-  try {
-    await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    });
-    
-    await delPurchase(ids);
-    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-    getList();
-  } catch (error) {
-    if (error !== 'cancel') {
-      console.error('鍒犻櫎澶辫触:', error);
-      proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  }
-};
-const mathNum = () => {
-  if (!productForm.value.taxRate) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-    return;
-  }
-  if (!productForm.value.taxInclusiveUnitPrice) {
-    return;
-  }
-  if (!productForm.value.quantity) {
-    return;
-  }
-  // 鍚◣鎬讳环璁$畻
-  productForm.value.taxInclusiveTotalPrice =
-      proxy.calculateTaxIncludeTotalPrice(
-          productForm.value.taxInclusiveUnitPrice,
-          productForm.value.quantity
+  };
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+      const unauthorizedData = selectedRows.value.filter(
+        item => item.recorderName !== userStore.nickName
       );
-  if (productForm.value.taxRate) {
-    // 涓嶅惈绋庢�讳环璁$畻
-    productForm.value.taxExclusiveTotalPrice =
-        proxy.calculateTaxExclusiveTotalPrice(
-            productForm.value.taxInclusiveTotalPrice,
-            productForm.value.taxRate
-        );
-  }
-};
-const reverseMathNum = (field) => {
-  if (!productForm.value.taxRate) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-    return;
-  }
-  const taxRate = Number(productForm.value.taxRate);
-  if (!taxRate) return;
-  if (field === 'taxInclusiveTotalPrice') {
-    // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
-    if (productForm.value.quantity) {
-      productForm.value.taxInclusiveUnitPrice =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
-    }
-    // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
-    else if (productForm.value.taxInclusiveUnitPrice) {
-      productForm.value.quantity =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
-    }
-    // 鍙嶇畻涓嶅惈绋庢�讳环
-    productForm.value.taxExclusiveTotalPrice =
-        (Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)).toFixed(2);
-  } else if (field === 'taxExclusiveTotalPrice') {
-    // 鍙嶇畻鍚◣鎬讳环
-    productForm.value.taxInclusiveTotalPrice =
-        (Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)).toFixed(2);
-    // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
-    if (productForm.value.quantity) {
-      productForm.value.taxInclusiveUnitPrice =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
-    }
-    // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
-    else if (productForm.value.taxInclusiveUnitPrice) {
-      productForm.value.quantity =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
-    }
-  }
-};
-// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
-const salesLedgerChange = async (row) => {
-  const index = salesContractList.value.findIndex((item) => item.id === row);
-  if (index > -1) {
-    form.value.projectName = salesContractList.value[index].projectName;
-    await querygProductInfoByContractNo();
-  }
-};
-
-const querygProductInfoByContractNo = async () => {
-  const { code, data } = await getProductInfoByContractNo({
-    contractNo: form.value.salesLedgerId,
-  });
-  if (code == 200) {
-    productData.value = data;
-  }
-};
-
-// 鏄剧ず浜岀淮鐮�
-const showQRCode = async (row) => {
-  try {
-    // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
-    const qrContent = row.purchaseContractNumber || '';
-    // 妫�鏌ュ唴瀹规槸鍚︿负绌�
-    if (!qrContent || qrContent.trim() === '') {
-      proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
+      if (unauthorizedData.length > 0) {
+        proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+        return;
+      }
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
-    qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
-      width: 200,
-      margin: 2,
-      color: {
-        dark: '#000000',
-        light: '#FFFFFF'
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        delPurchase(ids).then(res => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+  function getCurrentDate() {
+    const today = new Date();
+    const year = today.getFullYear();
+    const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+    const day = String(today.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+  }
+  const mathNum = () => {
+    if (!productForm.value.taxRate) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+      return;
+    }
+    if (!productForm.value.taxInclusiveUnitPrice) {
+      return;
+    }
+    if (!productForm.value.quantity) {
+      return;
+    }
+    // 鍚◣鎬讳环璁$畻
+    productForm.value.taxInclusiveTotalPrice =
+      proxy.calculateTaxIncludeTotalPrice(
+        productForm.value.taxInclusiveUnitPrice,
+        productForm.value.quantity
+      );
+    if (productForm.value.taxRate) {
+      // 涓嶅惈绋庢�讳环璁$畻
+      productForm.value.taxExclusiveTotalPrice =
+        proxy.calculateTaxExclusiveTotalPrice(
+          productForm.value.taxInclusiveTotalPrice,
+          productForm.value.taxRate
+        );
+    }
+  };
+  const reverseMathNum = field => {
+    if (!productForm.value.taxRate) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+      return;
+    }
+    const taxRate = Number(productForm.value.taxRate);
+    if (!taxRate) return;
+
+    // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
+    if (
+      field === "taxInclusiveTotalPrice" ||
+      field === "taxExclusiveTotalPrice"
+    ) {
+      const value = Number(productForm.value[field]);
+      if (value < 0) {
+        productForm.value[field] = "0";
+        proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
+        return;
       }
+    }
+
+    if (field === "taxInclusiveTotalPrice") {
+      // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
+      if (productForm.value.quantity) {
+        productForm.value.taxInclusiveUnitPrice = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.quantity)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+          productForm.value.taxInclusiveUnitPrice = "0";
+        }
+      }
+      // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
+      else if (productForm.value.taxInclusiveUnitPrice) {
+        productForm.value.quantity = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.taxInclusiveUnitPrice)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.quantity) < 0) {
+          productForm.value.quantity = "0";
+        }
+      }
+      // 鍙嶇畻涓嶅惈绋庢�讳环
+      productForm.value.taxExclusiveTotalPrice = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        (1 + taxRate / 100)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
+        productForm.value.taxExclusiveTotalPrice = "0";
+      }
+    } else if (field === "taxExclusiveTotalPrice") {
+      // 鍙嶇畻鍚◣鎬讳环
+      productForm.value.taxInclusiveTotalPrice = (
+        Number(productForm.value.taxExclusiveTotalPrice) *
+        (1 + taxRate / 100)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
+        productForm.value.taxInclusiveTotalPrice = "0";
+      }
+      // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
+      if (productForm.value.quantity) {
+        productForm.value.taxInclusiveUnitPrice = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.quantity)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+          productForm.value.taxInclusiveUnitPrice = "0";
+        }
+      }
+      // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
+      else if (productForm.value.taxInclusiveUnitPrice) {
+        productForm.value.quantity = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.taxInclusiveUnitPrice)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.quantity) < 0) {
+          productForm.value.quantity = "0";
+        }
+      }
+    }
+  };
+  // 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
+  const salesLedgerChange = async row => {
+    console.log("row", row);
+    var index = salesContractList.value.findIndex(item => item.id == row);
+    console.log("index", index);
+    if (index > -1) {
+      await querygProductInfoByContractNo();
+    }
+  };
+
+  const querygProductInfoByContractNo = async () => {
+    const { code, data } = await getProductInfoByContractNo({
+      contractNo: form.value.salesLedgerId,
     });
-    qrCodeDialogVisible.value = true;
-  } catch (error) {
-    console.error('鐢熸垚浜岀淮鐮佸け璐�:', error);
-    proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
-  }
-};
+    if (code == 200) {
+      productData.value = data;
+    }
+  };
 
-// 涓嬭浇浜岀淮鐮�
-const downloadQRCode = () => {
-  if (!qrCodeUrl.value) {
-    proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
-    return;
-  }
+  const fileListRef = ref(null);
+  const downLoadFile = row => {
+    fileListRef.value.open(row.salesLedgerFiles);
+  };
 
-  try {
-    const a = document.createElement('a');
+  // 鏄剧ず浜岀淮鐮�
+  const showQRCode = async row => {
+    try {
+      // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
+      const qrContent = row.purchaseContractNumber || "";
+      // 妫�鏌ュ唴瀹规槸鍚︿负绌�
+      if (!qrContent || qrContent.trim() === "") {
+        proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
+        return;
+      }
+      qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+        width: 200,
+        margin: 2,
+        color: {
+          dark: "#000000",
+          light: "#FFFFFF",
+        },
+      });
+      qrCodeDialogVisible.value = true;
+    } catch (error) {
+      console.error("鐢熸垚浜岀淮鐮佸け璐�:", error);
+      proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+    }
+  };
+
+  // 涓嬭浇浜岀淮鐮�
+  const downloadQRCode = () => {
+    if (!qrCodeUrl.value) {
+      proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
+      return;
+    }
+
+    const a = document.createElement("a");
     a.href = qrCodeUrl.value;
-    a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${dayjs().format('YYYYMMDDHHmmss')}.png`;
+    a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${new Date().getTime()}.png`;
     document.body.appendChild(a);
     a.click();
     document.body.removeChild(a);
     proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
-  } catch (error) {
-    console.error('涓嬭浇浜岀淮鐮佸け璐�:', error);
-    proxy.$modal.msgError("涓嬭浇澶辫触锛岃绋嶅悗閲嶈瘯");
-  }
-};
+  };
 
-// 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
-const scanAddDialogVisible = ref(false);
-const scanAddForm = reactive({
-  scanContent: "",
-  purchaseContractNumber: "",
-  supplierName: "",
-  projectName: "",
-  contractAmount: "",
-  paymentMethod: "",
-  recorderName: "",
-  scanRemark: "",
-});
-const scanAddRules = {
-  purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
-  supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }],
-  projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
-};
+  // 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
+  const scanAddDialogVisible = ref(false);
+  const scanAddForm = reactive({
+    scanContent: "",
+    purchaseContractNumber: "",
+    supplierName: "",
+    projectName: "",
+    contractAmount: "",
+    paymentMethod: "",
+    recorderName: "",
+    scanRemark: "",
+  });
+  const scanAddRules = {
+    purchaseContractNumber: [
+      { required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" },
+    ],
+    supplierName: [
+      { required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" },
+    ],
+    projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+  };
 
-// 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
-const scanDialogVisible = ref(false);
-const scanForm = reactive({
-  purchaseContractNumber: "",
-  supplierName: "",
-  projectName: "",
-  scanTime: "",
-  scannerName: "",
-  scanStatus: "鏈壂鐮�",
-  scanRemark: "",
-});
-const scanRules = {
-  scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
-};
-const scanRecords = ref([]);
+  // 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
+  const scanDialogVisible = ref(false);
+  const scanForm = reactive({
+    purchaseContractNumber: "",
+    supplierName: "",
+    projectName: "",
+    scanTime: "",
+    scannerName: "",
+    scanStatus: "鏈壂鐮�",
+    scanRemark: "",
+  });
+  const scanRules = {
+    scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
+  };
+  const scanRecords = ref([]);
 
-// 鎵撳紑鎵爜鏂板瀵硅瘽妗�
-const openScanAddDialog = () => {
-  scanAddForm.scanContent = "";
-  scanAddForm.purchaseContractNumber = "";
-  scanAddForm.supplierName = "";
-  scanAddForm.projectName = "";
-  scanAddForm.contractAmount = "";
-  scanAddForm.paymentMethod = "";
-  scanAddForm.recorderName = userStore.nickName;
-  scanAddForm.scanRemark = "";
-  scanAddDialogVisible.value = true;
-};
+  // 鎵撳紑鎵爜鏂板瀵硅瘽妗�
+  const openScanAddDialog = () => {
+    scanAddForm.scanContent = "";
+    scanAddForm.purchaseContractNumber = "";
+    scanAddForm.supplierName = "";
+    scanAddForm.projectName = "";
+    scanAddForm.contractAmount = "";
+    scanAddForm.paymentMethod = "";
+    scanAddForm.recorderName = userStore.nickName;
+    scanAddForm.scanRemark = "";
+    scanAddDialogVisible.value = true;
+  };
 
-// 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
-const parseScanContent = (content) => {
-  if (!content) return;
+  // 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
+  const parseScanContent = content => {
+    if (!content) return;
 
-  // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
-  // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡椤圭洰|閲戦|浠樻鏂瑰紡
-  const parts = content.split('|');
-  if (parts.length >= 3) {
-    scanAddForm.purchaseContractNumber = parts[0] || "";
-    scanAddForm.supplierName = parts[1] || "";
-    scanAddForm.projectName = parts[2] || "";
-    scanAddForm.contractAmount = parts[3] || "";
-    scanAddForm.paymentMethod = parts[4] || "";
-  }
-};
-
-// 鍏抽棴鎵爜鏂板瀵硅瘽妗�
-const closeScanAddDialog = () => {
-  scanAddDialogVisible.value = false;
-  proxy.resetForm("scanAddFormRef");
-};
-
-// 鎻愪氦鎵爜鏂板
-const submitScanAdd = async () => {
-  try {
-    const valid = await proxy.$refs["scanAddFormRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
+    // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
+    // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡閲戦|浠樻鏂瑰紡
+    const parts = content.split("|");
+    if (parts.length >= 2) {
+      scanAddForm.purchaseContractNumber = parts[0] || "";
+      scanAddForm.supplierName = parts[1] || "";
+      scanAddForm.contractAmount = parts[2] || "";
+      scanAddForm.paymentMethod = parts[3] || "";
+      scanAddForm.projectName = parts[4] || "";
+      // scanAddForm.contractAmount = parts[3] || "";
+      // scanAddForm.paymentMethod = parts[4] || "";
     }
-    
-    // 鏋勫缓鏂板鏁版嵁
-    const newData = {
-      purchaseContractNumber: scanAddForm.purchaseContractNumber,
-      supplierName: scanAddForm.supplierName,
-      projectName: scanAddForm.projectName,
-      contractAmount: scanAddForm.contractAmount,
-      paymentMethod: scanAddForm.paymentMethod,
-      recorderName: scanAddForm.recorderName,
-      entryDate: getCurrentDate(),
-      remark: scanAddForm.scanRemark,
-      type: 2
-    };
+  };
 
-    // await addOrEditPurchase(newData);
-    
-    proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
-    closeScanAddDialog();
-    getList(); // 鍒锋柊鍒楄〃
-  } catch (error) {
-    console.error('鎻愪氦鎵爜鏂板澶辫触:', error);
-    proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
-  }
-};
+  // 鍏抽棴鎵爜鏂板瀵硅瘽妗�
+  const closeScanAddDialog = () => {
+    scanAddDialogVisible.value = false;
+    proxy.resetForm("scanAddFormRef");
+  };
 
-// 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
-const openScanDialog = (row) => {
-  scanForm.purchaseContractNumber = row.purchaseContractNumber;
-  scanForm.supplierName = row.supplierName;
-  scanForm.projectName = row.projectName;
-  scanForm.scanTime = getCurrentDateTime();
-  scanForm.scannerName = userStore.nickName;
-  scanForm.scanStatus = "鏈壂鐮�";
-  scanForm.scanRemark = "";
-  scanRecords.value = [];
-  scanDialogVisible.value = true;
-};
+  // 鎻愪氦鎵爜鏂板
+  const submitScanAdd = () => {
+    proxy.$refs["scanAddFormRef"].validate(valid => {
+      if (valid) {
+        // 鏋勫缓鏂板鏁版嵁
+        const newData = {
+          purchaseContractNumber: scanAddForm.purchaseContractNumber,
+          supplierName: scanAddForm.supplierName,
+          projectName: scanAddForm.projectName,
+          contractAmount: scanAddForm.contractAmount,
+          paymentMethod: scanAddForm.paymentMethod,
+          recorderName: scanAddForm.recorderName,
+          entryDate: getCurrentDate(),
+          remark: scanAddForm.scanRemark,
+          type: 2,
+        };
 
-// 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
-const closeScanDialog = () => {
-  scanDialogVisible.value = false;
-  proxy.resetForm("scanFormRef");
-};
+        // 妯℃嫙鏂板鎴愬姛
+        proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
+        closeScanAddDialog();
 
-// 鎻愪氦鎵爜鐧昏
-const submitScan = async () => {
-  try {
-    const valid = await proxy.$refs["scanFormRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
-    }
-    
-    // 娣诲姞鎵爜璁板綍
-    scanRecords.value.push({
-      ...scanForm,
-      id: Date.now(), // 妯℃嫙ID
-      scanTime: getCurrentDateTime(),
+        // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
+        // getList();
+      }
     });
-    scanForm.scanStatus = "宸叉壂鐮�";
-    scanForm.scanRemark = scanForm.scanRemark || "鏃�";
-    proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
-    closeScanDialog();
-  } catch (error) {
-    console.error('鎻愪氦鎵爜鐧昏澶辫触:', error);
-    proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
+  };
+
+  // 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
+  const openScanDialog = row => {
+    scanForm.purchaseContractNumber = row.purchaseContractNumber;
+    scanForm.supplierName = row.supplierName;
+    scanForm.projectName = row.projectName;
+    scanForm.scanTime = getCurrentDateTime();
+    scanForm.scannerName = userStore.nickName;
+    scanForm.scanStatus = "鏈壂鐮�";
+    scanForm.scanRemark = "";
+    scanRecords.value = [];
+    scanDialogVisible.value = true;
+  };
+
+  // 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
+  const closeScanDialog = () => {
+    scanDialogVisible.value = false;
+    proxy.resetForm("scanFormRef");
+  };
+
+  // 鎻愪氦鎵爜鐧昏
+  const submitScan = () => {
+    proxy.$refs["scanFormRef"].validate(valid => {
+      if (valid) {
+        // 娣诲姞鎵爜璁板綍
+        scanRecords.value.push({
+          ...scanForm,
+          id: Date.now(), // 妯℃嫙ID
+          scanTime: getCurrentDateTime(),
+        });
+        scanForm.scanStatus = "宸叉壂鐮�";
+        scanForm.scanRemark = scanForm.scanRemark || "鏃�";
+        proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
+        closeScanDialog();
+      }
+    });
+  };
+
+  // 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
+  function getCurrentDateTime() {
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, "0");
+    const day = String(now.getDate()).padStart(2, "0");
+    const hours = String(now.getHours()).padStart(2, "0");
+    const minutes = String(now.getMinutes()).padStart(2, "0");
+    const seconds = String(now.getSeconds()).padStart(2, "0");
+    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
   }
-};
 
-// 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
-function getCurrentDateTime() {
-  return dayjs().format("YYYY-MM-DD HH:mm:ss");
-}
+  // 娣诲姞琛岀被鍚嶆柟娉�
+  const tableRowClassName = ({ row }) => {
+    return row.isInvalid ? "invalid-row" : "";
+  };
 
-// 娣诲姞琛岀被鍚嶆柟娉�
-const tableRowClassName = ({ row }) => {
-  return row.isInvalid ? 'invalid-row' : '';
-};
+  // 鑾峰彇妯℃澘淇℃伅
+  const getTemplateList = async () => {
+    let res = await getPurchaseTemplateList();
+    if (res && res.code === 200 && Array.isArray(res.data)) {
+      templateList.value = res.data;
+    }
+  };
 
-// 鑾峰彇妯℃澘淇℃伅
-const getTemplateList =async ()=>{
-  let res = await getPurchaseTemplateList()
-  if(res && res.code===200 && Array.isArray(res.data)){
-    templateList.value = res.data
-  }
-}
-
-onMounted(() => {
-  getList();
-  getTemplateList();
-
-});
+  onMounted(() => {
+    getList();
+    getTemplateList();
+  });
 </script>
 
 <style scoped lang="scss">
-.invalid-row {
-  opacity: 0.6;
-  background-color: #f5f7fa;
-}
-.el-row{
-  justify-content: space-between;
-  align-items: center
-}
-.no-arrow-select {
-  --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
-}
-.select-button-group {
-  display: flex;
-  align-items: center;
-}
-
+  .invalid-row {
+    opacity: 0.6;
+    background-color: #f5f7fa;
+  }
+  .el-row {
+    justify-content: space-between;
+    align-items: center;
+  }
+  .no-arrow-select {
+    --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
+  }
+  .select-button-group {
+    display: flex;
+    align-items: center;
+  }
 </style>
diff --git a/src/views/procurementManagement/procurementPlan/index.vue b/src/views/procurementManagement/procurementPlan/index.vue
index 14424cc..42a1bcf 100644
--- a/src/views/procurementManagement/procurementPlan/index.vue
+++ b/src/views/procurementManagement/procurementPlan/index.vue
@@ -88,11 +88,15 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog
+    <FormDialog
       v-model="dialogVisible"
       :title="dialogType === 'add' ? '鏂板閲囪喘璁″垝' : '缂栬緫閲囪喘璁″垝'"
-      width="1000px"
+      :width="'1000px'"
+      :operation-type="dialogType"
       :close-on-click-modal="false"
+      @close="dialogVisible = false"
+      @confirm="handleSubmit"
+      @cancel="dialogVisible = false"
     >
       <div class="form-container">
         <!-- 鍩烘湰淇℃伅 -->
@@ -202,21 +206,17 @@
           </div>
         </div>
       </div>
-
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
-    <el-dialog
+    <FormDialog
       v-model="productSelectDialogVisible"
       title="閫夋嫨浜у搧"
-      width="800px"
+      :width="'800px'"
       :close-on-click-modal="false"
+      @close="productSelectDialogVisible = false"
+      @confirm="handleConfirmProductSelection"
+      @cancel="productSelectDialogVisible = false"
     >
       <div class="product-select">
         <el-alert
@@ -247,23 +247,17 @@
           <el-table-column prop="inboundNum0" label="棰勮鍏ュ簱" width="100" align="right" />
         </el-table>
       </div>
-
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="productSelectDialogVisible = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="handleConfirmProductSelection" :disabled="selectedProducts.length === 0">
-            纭璁$畻
-          </el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 璁$畻缁撴灉瀵硅瘽妗� -->
-    <el-dialog
+    <FormDialog
       v-model="calculateDialogVisible"
       title="閲囪喘璁$畻缁撴灉"
-      width="1000px"
+      :width="'1000px'"
       :close-on-click-modal="false"
+      @close="calculateDialogVisible = false"
+      @confirm="handleCreatePurchaseOrder"
+      @cancel="calculateDialogVisible = false"
     >
       <div class="calculate-result">
         <el-alert
@@ -300,18 +294,12 @@
           </el-table-column>
         </el-table>
       </div>
-
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="calculateDialogVisible = false">鍏抽棴</el-button>
-          <el-button type="primary" @click="handleCreatePurchaseOrder">纭</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { Search, Refresh, Plus, Download } from '@element-plus/icons-vue'
diff --git a/src/views/procurementManagement/procurementReport/index.vue b/src/views/procurementManagement/procurementReport/index.vue
index 33a0e91..8c8f3f6 100644
--- a/src/views/procurementManagement/procurementReport/index.vue
+++ b/src/views/procurementManagement/procurementReport/index.vue
@@ -1,46 +1,7 @@
 <template>
   <div class="app-container">
-    <!-- 鎶ヨ〃閫夋嫨鍣� -->
-    <el-card class="report-selector" shadow="never">
-      <el-tabs v-model="activeReport" @tab-change="handleReportChange">
-        <el-tab-pane label="閲囪喘璁㈠崟鎵ц姹囨�昏〃" name="orderSummary">
-          <template #label>
-            <span class="tab-label">
-              <el-icon><Document /></el-icon>
-              閲囪喘璁㈠崟鎵ц姹囨�昏〃
-            </span>
-          </template>
-        </el-tab-pane>
-        <el-tab-pane label="閲囪喘璁㈠崟鎵ц鏄庣粏琛�" name="orderDetail">
-          <template #label>
-            <span class="tab-label">
-              <el-icon><List /></el-icon>
-              閲囪喘璁㈠崟鎵ц鏄庣粏琛�
-            </span>
-          </template>
-        </el-tab-pane>
-        <el-tab-pane label="閲囪喘涓氬姟姹囨�昏〃" name="businessSummary">
-          <template #label>
-            <span class="tab-label">
-              <el-icon><TrendCharts /></el-icon>
-              閲囪喘涓氬姟姹囨�昏〃
-            </span>
-          </template>
-        </el-tab-pane>
-        <el-tab-pane label="渚涘簲鍟嗕緵璐ф眹鎬昏〃" name="supplierSummary">
-          <template #label>
-            <span class="tab-label">
-              <el-icon><Shop /></el-icon>
-              渚涘簲鍟嗕緵璐ф眹鎬昏〃
-            </span>
-          </template>
-        </el-tab-pane>
-      </el-tabs>
-    </el-card>
-
     <!-- 鏌ヨ鏉′欢 -->
-    <el-card class="search-card" shadow="never">
-      <el-form :model="searchForm" :inline="true" class="search-form">
+    <el-form :model="searchForm" :inline="true" class="search-form">
         <el-form-item label="鏃堕棿鑼冨洿锛�">
           <el-date-picker
             v-model="searchForm.dateRange"
@@ -53,139 +14,35 @@
             style="width: 240px"
           />
         </el-form-item>
-        <el-form-item label="渚涘簲鍟嗭細" v-if="activeReport === 'supplierSummary'">
-          <el-select v-model="searchForm.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px">
-            <el-option
-              v-for="supplier in supplierList"
-              :key="supplier.id"
-              :label="supplier.name"
-              :value="supplier.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="鍟嗗搧绫诲埆锛�" v-if="activeReport === 'businessSummary'">
-          <el-select v-model="searchForm.categoryId" placeholder="璇烽�夋嫨鍟嗗搧绫诲埆" clearable style="width: 200px">
-            <el-option
-              v-for="category in categoryList"
-              :key="category.id"
-              :label="category.name"
-              :value="category.id"
-            />
-          </el-select>
+        <el-form-item label="浜у搧澶х被锛�">
+          <el-tree-select
+            v-model="searchForm.productCategory"
+            placeholder="璇烽�夋嫨鍟嗗搧绫诲埆"
+            clearable
+            check-strictly
+            :data="productOptions"
+            :render-after-expand="false"
+            style="width: 200px"
+          />
         </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleSearch" :loading="loading">
-            <el-icon><Search /></el-icon>
             鏌ヨ
           </el-button>
           <el-button @click="resetSearch">
-            <el-icon><Refresh /></el-icon>
             閲嶇疆
           </el-button>
-          <el-button type="success" @click="exportReport">
+          <el-button type="info" @click="exportReport">
             <el-icon><Download /></el-icon>
             瀵煎嚭
           </el-button>
         </el-form-item>
       </el-form>
-    </el-card>
 
     <!-- 鎶ヨ〃鍐呭 -->
     <el-card class="report-content" shadow="never">
-      <!-- 閲囪喘璁㈠崟鎵ц姹囨�昏〃 -->
-      <div v-if="activeReport === 'orderSummary'" class="report-section">
-        <div class="section-header">
-          <h3>閲囪喘璁㈠崟鎵ц姹囨�昏〃</h3>
-          <div class="summary-stats">
-            <div class="stat-item">
-              <span class="stat-label">鎬昏鍗曟暟锛�</span>
-              <span class="stat-value">{{ orderSummaryStats.totalOrders }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">鎬婚噾棰濓細</span>
-              <span class="stat-value">楼{{ orderSummaryStats.totalAmount.toLocaleString() }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">瀹屾垚鐜囷細</span>
-              <span class="stat-value">{{ orderSummaryStats.completionRate }}%</span>
-            </div>
-          </div>
-        </div>
-        
-        <el-table :data="orderSummaryData" border v-loading="loading" stripe style="width: 100%">
-          <el-table-column label="璁㈠崟缂栧彿" prop="orderNo" width="180" fixed="left" />
-          <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" min-width="150" />
-          <el-table-column label="璁㈠崟鏃ユ湡" prop="orderDate" width="120" />
-          <el-table-column label="璁″垝浜ゆ湡" prop="plannedDelivery" width="120" />
-          <el-table-column label="瀹為檯浜ゆ湡" prop="actualDelivery" width="120" />
-          <el-table-column label="璁㈠崟閲戦" prop="orderAmount" width="120">
-            <template #default="{ row }">楼{{ row.orderAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="宸蹭粯閲戦" prop="paidAmount" width="120">
-            <template #default="{ row }">楼{{ row.paidAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="瀹屾垚鐘舵��" prop="status" width="100">
-            <template #default="{ row }">
-              <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="瀹屾垚鐜�" prop="completionRate" width="100">
-            <template #default="{ row }">{{ row.completionRate }}%</template>
-          </el-table-column>
-          <el-table-column label="寤惰繜澶╂暟" prop="delayDays" width="100">
-            <template #default="{ row }">
-              <span :class="{ 'delay-text': row.delayDays > 0 }">{{ row.delayDays }}</span>
-            </template>
-          </el-table-column>
-        </el-table>
-      </div>
-
-      <!-- 閲囪喘璁㈠崟鎵ц鏄庣粏琛� -->
-      <div v-if="activeReport === 'orderDetail'" class="report-section">
-        <div class="section-header">
-          <h3>閲囪喘璁㈠崟鎵ц鏄庣粏琛�</h3>
-          <div class="summary-stats">
-            <div class="stat-item">
-              <span class="stat-label">鏄庣粏鏉℃暟锛�</span>
-              <span class="stat-value">{{ orderDetailStats.totalItems }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">宸叉敹璐э細</span>
-              <span class="stat-value">{{ orderDetailStats.receivedItems }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">寰呮敹璐э細</span>
-              <span class="stat-value">{{ orderDetailStats.pendingItems }}</span>
-            </div>
-          </div>
-        </div>
-        
-        <el-table :data="orderDetailData" border v-loading="loading" stripe style="width: 100%">
-          <el-table-column label="璁㈠崟缂栧彿" prop="orderNo" width="150" fixed="left" />
-          <el-table-column label="鍟嗗搧缂栫爜" prop="productCode" width="120" />
-          <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="200" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" min-width="150" />
-          <el-table-column label="鍗曚綅" prop="unit" width="80" />
-          <el-table-column label="璁″垝鏁伴噺" prop="plannedQuantity" width="100" />
-          <el-table-column label="宸叉敹璐ф暟閲�" prop="receivedQuantity" width="120" />
-          <el-table-column label="寰呮敹璐ф暟閲�" prop="pendingQuantity" width="120" />
-          <el-table-column label="鍗曚环" prop="unitPrice" width="100">
-            <template #default="{ row }">楼{{ row.unitPrice.toFixed(2) }}</template>
-          </el-table-column>
-          <el-table-column label="灏忚" prop="subtotal" width="120">
-            <template #default="{ row }">楼{{ row.subtotal.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="鏀惰揣鐘舵��" prop="status" width="100">
-            <template #default="{ row }">
-              <el-tag :type="getReceiptStatusType(row.status)">{{ getReceiptStatusText(row.status) }}</el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="鏈�鍚庢敹璐ф棩鏈�" prop="lastReceiptDate" width="120" />
-        </el-table>
-      </div>
-
       <!-- 閲囪喘涓氬姟姹囨�昏〃 -->
-      <div v-if="activeReport === 'businessSummary'" class="report-section">
+      <div class="report-section">
         <div class="section-header">
           <h3>閲囪喘涓氬姟姹囨�昏〃</h3>
           <div class="summary-stats">
@@ -197,80 +54,19 @@
               <span class="stat-label">鍟嗗搧绉嶇被锛�</span>
               <span class="stat-value">{{ businessSummaryStats.productTypes }}</span>
             </div>
-            <div class="stat-item">
-              <span class="stat-label">渚涘簲鍟嗘暟锛�</span>
-              <span class="stat-value">{{ businessSummaryStats.supplierCount }}</span>
-            </div>
           </div>
         </div>
         
-        <el-table :data="businessSummaryData" border v-loading="loading" stripe style="width: 100%">
-          <el-table-column label="鍟嗗搧绫诲埆" prop="category" width="150" fixed="left" />
-          <el-table-column label="鍟嗗搧缂栫爜" prop="productCode" width="120" />
-          <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="200" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" min-width="150" />
-          <el-table-column label="閲囪喘鏁伴噺" prop="purchaseQuantity" width="120" />
-          <el-table-column label="閲囪喘閲戦" prop="purchaseAmount" width="120">
-            <template #default="{ row }">楼{{ row.purchaseAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="骞冲潎鍗曚环" prop="avgPrice" width="100">
-            <template #default="{ row }">楼{{ row.avgPrice.toFixed(2) }}</template>
-          </el-table-column>
-          <el-table-column label="閲囪喘娆℃暟" prop="purchaseCount" width="100" />
-          <el-table-column label="涓昏渚涘簲鍟�" prop="mainSupplier" min-width="150" />
-          <el-table-column label="鏈�鍚庨噰璐棩鏈�" prop="lastPurchaseDate" width="120" />
-        </el-table>
-      </div>
-
-      <!-- 渚涘簲鍟嗕緵璐ф眹鎬昏〃 -->
-      <div v-if="activeReport === 'supplierSummary'" class="report-section">
-        <div class="section-header">
-          <h3>渚涘簲鍟嗕緵璐ф眹鎬昏〃</h3>
-          <div class="summary-stats">
-            <div class="stat-item">
-              <span class="stat-label">渚涘簲鍟嗘�绘暟锛�</span>
-              <span class="stat-value">{{ supplierSummaryStats.totalSuppliers }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">渚涜揣鎬婚锛�</span>
-              <span class="stat-value">楼{{ supplierSummaryStats.totalAmount.toLocaleString() }}</span>
-            </div>
-            <div class="stat-item">
-              <span class="stat-label">骞冲潎璇勫垎锛�</span>
-              <span class="stat-value">{{ supplierSummaryStats.avgRating.toFixed(1) }}</span>
-            </div>
-          </div>
-        </div>
-        
-        <el-table :data="supplierSummaryData" border v-loading="loading" stripe style="width: 100%">
-          <el-table-column label="渚涘簲鍟嗙紪鐮�" prop="supplierCode" width="120" fixed="left" />
-          <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" min-width="200" />
-          <el-table-column label="鑱旂郴浜�" prop="contactPerson" width="120" />
-          <el-table-column label="鑱旂郴鐢佃瘽" prop="phone" width="130" />
-          <el-table-column label="渚涜揣璁㈠崟鏁�" prop="orderCount" width="120" />
-          <el-table-column label="渚涜揣閲戦" prop="supplyAmount" width="120">
-            <template #default="{ row }">楼{{ row.supplyAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="宸蹭粯閲戦" prop="paidAmount" width="120">
-            <template #default="{ row }">楼{{ row.paidAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="鏈粯閲戦" prop="unpaidAmount" width="120">
-            <template #default="{ row }">楼{{ row.unpaidAmount.toLocaleString() }}</template>
-          </el-table-column>
-          <el-table-column label="鎸夋椂浜よ揣鐜�" prop="onTimeRate" width="120">
-            <template #default="{ row }">{{ row.onTimeRate }}%</template>
-          </el-table-column>
-          <el-table-column label="璐ㄩ噺璇勫垎" prop="qualityRating" width="100">
-            <template #default="{ row }">
-              <el-rate v-model="row.qualityRating" disabled show-score text-color="#ff9900" />
-            </template>
-          </el-table-column>
-          <el-table-column label="鍚堜綔鐘舵��" prop="status" width="100">
-            <template #default="{ row }">
-              <el-tag :type="getSupplierStatusType(row.status)">{{ getSupplierStatusText(row.status) }}</el-tag>
-            </template>
-          </el-table-column>
-        </el-table>
+        <PIMTable
+          :table-data="businessSummaryData"
+          :column="tableColumns"
+          :table-loading="loading"
+          :is-selection="false"
+          :border="true"
+          :is-show-pagination="true"
+          :page="page"
+          @pagination="handlePagination"
+        />
       </div>
     </el-card>
   </div>
@@ -279,354 +75,200 @@
 <script setup>
 import { ref, reactive, onMounted } from 'vue'
 import { ElMessage } from 'element-plus'
-import { Document, List, TrendCharts, Shop, Search, Refresh, Download } from '@element-plus/icons-vue'
+import { Download } from '@element-plus/icons-vue'
+import PIMTable from '@/components/PIMTable/PIMTable.vue'
+import { procurementBusinessSummaryListPage } from '@/api/procurementManagement/procurementReport'
+import { productTreeList } from '@/api/basicData/product'
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
-const activeReport = ref('orderSummary')
 
 // 鎼滅储琛ㄥ崟
 const searchForm = reactive({
   dateRange: [],
-  supplierId: '',
-  categoryId: ''
+  productCategory: ''
 })
 
-// 渚涘簲鍟嗗垪琛�
-const supplierList = ref([
-  { id: 1, name: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃' },
-  { id: 2, name: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�' },
-  { id: 3, name: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃' },
-  { id: 4, name: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃' },
-  { id: 5, name: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�' }
-])
-
-// 鍟嗗搧绫诲埆鍒楄〃
-const categoryList = ref([
-  { id: 1, name: '鐢靛瓙鍏冨櫒浠�' },
-  { id: 2, name: '鏈烘璁惧' },
-  { id: 3, name: '鍘熸潗鏂�' },
-  { id: 4, name: '鍔炲叕鐢ㄥ搧' },
-  { id: 5, name: '鍖呰鏉愭枡' }
-])
+// 浜у搧绫诲埆鏍戦�夐」
+const productOptions = ref([])
 
 // 缁熻鏁版嵁
-const orderSummaryStats = ref({
-  totalOrders: 156,
-  totalAmount: 2580000,
-  completionRate: 87.5
-})
-
-const orderDetailStats = ref({
-  totalItems: 1248,
-  receivedItems: 1089,
-  pendingItems: 159
-})
-
 const businessSummaryStats = ref({
-  totalAmount: 2580000,
-  productTypes: 89,
-  supplierCount: 25
+  totalAmount: 0,
+  productTypes: 0
 })
 
-const supplierSummaryStats = ref({
-  totalSuppliers: 25,
-  totalAmount: 2580000,
-  avgRating: 4.2
-})
-
-// 閲囪喘璁㈠崟鎵ц姹囨�昏〃鏁版嵁
-const orderSummaryData = ref([
+// 琛ㄦ牸鍒楅厤缃紙鏍规嵁鍚庣瀛楁瀹氫箟锛�
+const tableColumns = ref([
   {
-    orderNo: 'PO20241201001',
-    supplierName: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
-    orderDate: '2024-12-01',
-    plannedDelivery: '2024-12-15',
-    actualDelivery: '2024-12-14',
-    orderAmount: 125000,
-    paidAmount: 100000,
-    status: 'completed',
-    completionRate: 100,
-    delayDays: -1
+    label: '浜у搧澶х被',
+    prop: 'productCategory',
+    width: 150,
   },
   {
-    orderNo: 'PO20241201002',
-    supplierName: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
-    orderDate: '2024-12-02',
-    plannedDelivery: '2024-12-20',
-    actualDelivery: '2024-12-22',
-    orderAmount: 280000,
-    paidAmount: 140000,
-    status: 'partial',
-    completionRate: 75,
-    delayDays: 2
+    label: '瑙勬牸鍨嬪彿',
+    prop: 'specificationModel',
+    width: 180
   },
   {
-    orderNo: 'PO20241201003',
-    supplierName: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
-    orderDate: '2024-12-03',
-    plannedDelivery: '2024-12-25',
-    actualDelivery: '',
-    orderAmount: 180000,
-    paidAmount: 0,
-    status: 'pending',
-    completionRate: 0,
-    delayDays: 0
+    label: '閲囪喘鏁伴噺',
+    prop: 'purchaseNum',
+    width: 120,
+    formatData: (val) => {
+      return val ? parseFloat(val).toLocaleString() : '0'
+    }
   },
   {
-    orderNo: 'PO20241201004',
-    supplierName: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃',
-    orderDate: '2024-12-04',
-    plannedDelivery: '2024-12-18',
-    actualDelivery: '2024-12-18',
-    orderAmount: 95000,
-    paidAmount: 95000,
-    status: 'completed',
-    completionRate: 100,
-    delayDays: 0
+    label: '閲囪喘閲戦',
+    prop: 'purchaseAmount',
+    width: 140,
+    formatData: (val) => {
+      return val ? `楼${parseFloat(val).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : '楼0.00'
+    }
   },
   {
-    orderNo: 'PO20241201005',
-    supplierName: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�',
-    orderDate: '2024-12-05',
-    plannedDelivery: '2024-12-28',
-    actualDelivery: '',
-    orderAmount: 220000,
-    paidAmount: 0,
-    status: 'pending',
-    completionRate: 0,
-    delayDays: 0
-  }
-])
-
-// 閲囪喘璁㈠崟鎵ц鏄庣粏琛ㄦ暟鎹�
-const orderDetailData = ref([
-  {
-    orderNo: 'PO20241201001',
-    productCode: 'EL001',
-    productName: '鐢甸樆鍣� 1K惟 卤5%',
-    specification: '1/4W 纰宠啘鐢甸樆',
-    unit: '涓�',
-    plannedQuantity: 1000,
-    receivedQuantity: 1000,
-    pendingQuantity: 0,
-    unitPrice: 0.15,
-    subtotal: 150,
-    status: 'completed',
-    lastReceiptDate: '2024-12-14'
+    label: '閲囪喘娆℃暟',
+    prop: 'purchaseTimes',
+    width: 100
   },
   {
-    orderNo: 'PO20241201001',
-    productCode: 'EL002',
-    productName: '鐢靛鍣� 100渭F',
-    specification: '25V 閾濈數瑙g數瀹�',
-    unit: '涓�',
-    plannedQuantity: 500,
-    receivedQuantity: 500,
-    pendingQuantity: 0,
-    unitPrice: 0.85,
-    subtotal: 425,
-    status: 'completed',
-    lastReceiptDate: '2024-12-14'
+    label: '骞冲潎鍗曚环',
+    prop: 'averagePrice',
+    width: 120,
+    formatData: (val) => {
+      return val ? `楼${parseFloat(val).toFixed(2)}` : '楼0.00'
+    }
   },
   {
-    orderNo: 'PO20241201002',
-    productCode: 'ME001',
-    productName: '绮惧瘑杞存壙',
-    specification: '6205-2RS 娣辨矡鐞冭酱鎵�',
-    unit: '涓�',
-    plannedQuantity: 200,
-    receivedQuantity: 150,
-    pendingQuantity: 50,
-    unitPrice: 25.5,
-    subtotal: 5100,
-    status: 'partial',
-    lastReceiptDate: '2024-12-20'
+    label: '渚涘簲鍟嗗悕绉�',
+    prop: 'supplierName',
+    width: 200
   },
   {
-    orderNo: 'PO20241201002',
-    productCode: 'ME002',
-    productName: '涓嶉攬閽㈣灪涓�',
-    specification: 'M8脳20 304涓嶉攬閽�',
-    unit: '涓�',
-    plannedQuantity: 1000,
-    receivedQuantity: 1000,
-    pendingQuantity: 0,
-    unitPrice: 0.8,
-    subtotal: 800,
-    status: 'completed',
-    lastReceiptDate: '2024-12-20'
-  },
-  {
-    orderNo: 'PO20241201003',
-    productCode: 'SM001',
-    productName: '鏅鸿兘浼犳劅鍣�',
-    specification: '娓╁害浼犳劅鍣� DS18B20',
-    unit: '涓�',
-    plannedQuantity: 300,
-    receivedQuantity: 0,
-    pendingQuantity: 300,
-    unitPrice: 12.5,
-    subtotal: 3750,
-    status: 'pending',
-    lastReceiptDate: ''
+    label: '褰曞叆鏃ユ湡',
+    prop: 'entryDate',
+    width: 120
   }
 ])
 
 // 閲囪喘涓氬姟姹囨�昏〃鏁版嵁
-const businessSummaryData = ref([
-  {
-    category: '鐢靛瓙鍏冨櫒浠�',
-    productCode: 'EL001',
-    productName: '鐢甸樆鍣� 1K惟 卤5%',
-    specification: '1/4W 纰宠啘鐢甸樆',
-    purchaseQuantity: 5000,
-    purchaseAmount: 750,
-    avgPrice: 0.15,
-    purchaseCount: 8,
-    mainSupplier: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
-    lastPurchaseDate: '2024-12-01'
-  },
-  {
-    category: '鐢靛瓙鍏冨櫒浠�',
-    productCode: 'EL002',
-    productName: '鐢靛鍣� 100渭F',
-    specification: '25V 閾濈數瑙g數瀹�',
-    purchaseQuantity: 2500,
-    purchaseAmount: 2125,
-    avgPrice: 0.85,
-    purchaseCount: 6,
-    mainSupplier: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
-    lastPurchaseDate: '2024-12-01'
-  },
-  {
-    category: '鏈烘璁惧',
-    productCode: 'ME001',
-    productName: '绮惧瘑杞存壙',
-    specification: '6205-2RS 娣辨矡鐞冭酱鎵�',
-    purchaseQuantity: 800,
-    purchaseAmount: 20400,
-    avgPrice: 25.5,
-    purchaseCount: 4,
-    mainSupplier: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
-    lastPurchaseDate: '2024-12-02'
-  },
-  {
-    category: '鏈烘璁惧',
-    productCode: 'ME002',
-    productName: '涓嶉攬閽㈣灪涓�',
-    specification: 'M8脳20 304涓嶉攬閽�',
-    purchaseQuantity: 5000,
-    purchaseAmount: 4000,
-    avgPrice: 0.8,
-    purchaseCount: 12,
-    mainSupplier: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
-    lastPurchaseDate: '2024-12-02'
-  },
-  {
-    category: '鏅鸿兘璁惧',
-    productCode: 'SM001',
-    productName: '鏅鸿兘浼犳劅鍣�',
-    specification: '娓╁害浼犳劅鍣� DS18B20',
-    purchaseQuantity: 1200,
-    purchaseAmount: 15000,
-    avgPrice: 12.5,
-    purchaseCount: 5,
-    mainSupplier: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
-    lastPurchaseDate: '2024-12-03'
-  }
-])
+const businessSummaryData = ref([])
 
-// 渚涘簲鍟嗕緵璐ф眹鎬昏〃鏁版嵁
-const supplierSummaryData = ref([
-  {
-    supplierCode: 'SUP001',
-    supplierName: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
-    contactPerson: '寮犵粡鐞�',
-    phone: '0512-88888888',
-    orderCount: 45,
-    supplyAmount: 850000,
-    paidAmount: 680000,
-    unpaidAmount: 170000,
-    onTimeRate: 95,
-    qualityRating: 4.5,
-    status: 'active'
-  },
-  {
-    supplierCode: 'SUP002',
-    supplierName: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
-    contactPerson: '鏉庢��',
-    phone: '021-66666666',
-    orderCount: 32,
-    supplyAmount: 1200000,
-    paidAmount: 900000,
-    unpaidAmount: 300000,
-    onTimeRate: 88,
-    qualityRating: 4.2,
-    status: 'active'
-  },
-  {
-    supplierCode: 'SUP003',
-    supplierName: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
-    contactPerson: '鐜嬪伐绋嬪笀',
-    phone: '0755-77777777',
-    orderCount: 28,
-    supplyAmount: 680000,
-    paidAmount: 400000,
-    unpaidAmount: 280000,
-    onTimeRate: 92,
-    qualityRating: 4.3,
-    status: 'active'
-  },
-  {
-    supplierCode: 'SUP004',
-    supplierName: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃',
-    contactPerson: '闄堝崥澹�',
-    phone: '010-55555555',
-    orderCount: 18,
-    supplyAmount: 320000,
-    paidAmount: 250000,
-    unpaidAmount: 70000,
-    onTimeRate: 85,
-    qualityRating: 4.0,
-    status: 'active'
-  },
-  {
-    supplierCode: 'SUP005',
-    supplierName: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�',
-    contactPerson: '鍒樼粡鐞�',
-    phone: '020-44444444',
-    orderCount: 22,
-    supplyAmount: 480000,
-    paidAmount: 200000,
-    unpaidAmount: 280000,
-    onTimeRate: 78,
-    qualityRating: 3.8,
-    status: 'warning'
-  }
-])
+// 鍒嗛〉鍙傛暟锛堝悗绔繑鍥烇細total/size/current/pages锛�
+const page = reactive({
+  total: 0,
+  current: 1,
+  size: 50,
+})
 
-// 鏂规硶
-const handleReportChange = (tabName) => {
-  activeReport.value = tabName
-  handleSearch()
+// 杞崲浜у搧鏍戞暟鎹紝灏� id 鏀逛负 value
+function convertIdToValue(data) {
+  return data.map((item) => {
+    const { id, children, ...rest } = item
+    const newItem = {
+      ...rest,
+      value: id,
+    }
+    if (children && children.length > 0) {
+      newItem.children = convertIdToValue(children)
+    }
+    return newItem
+  })
 }
 
-const handleSearch = () => {
-  loading.value = true
-  // 妯℃嫙API璋冪敤
-  setTimeout(() => {
+// 鑾峰彇浜у搧绫诲埆鏍戞暟鎹�
+const getProductOptions = () => {
+  return productTreeList().then((res) => {
+    productOptions.value = convertIdToValue(res)
+  }).catch((error) => {
+    console.error('鑾峰彇浜у搧鏍戝け璐�:', error)
+    ElMessage.error('鑾峰彇浜у搧绫诲埆澶辫触')
+  })
+}
+
+// 鏍规嵁 id 鏌ユ壘浜у搧绫诲埆鍚嶇О
+const findNodeLabelById = (nodes, id) => {
+  if (!id) return null
+  for (let i = 0; i < nodes.length; i++) {
+    if (nodes[i].value === id) {
+      return nodes[i].label
+    }
+    if (nodes[i].children && nodes[i].children.length > 0) {
+      const found = findNodeLabelById(nodes[i].children, id)
+      if (found) return found
+    }
+  }
+  return null
+}
+
+// 鏌ヨ鍒楄〃
+const handleSearch = async () => {
+  try {
+    loading.value = true
+    const params = {}
+    
+    // 鏃堕棿鑼冨洿
+    if (searchForm.dateRange && searchForm.dateRange.length === 2) {
+      params.entryDateStart = searchForm.dateRange[0]
+      params.entryDateEnd = searchForm.dateRange[1]
+    }
+    
+    // 浜у搧绫诲埆
+    if (searchForm.productCategory) {
+      const categoryName = findNodeLabelById(productOptions.value, searchForm.productCategory)
+      if (categoryName) {
+        params.productCategory = categoryName
+      }
+    }
+    
+    // 鍒嗛〉鍙傛暟
+    params.current = page.current
+    params.size = page.size
+
+    const res = await procurementBusinessSummaryListPage(params)
+    if (res && res.data) {
+      // 鍏煎鍚庣鍙兘鐩存帴杩斿洖鏁扮粍/鎴栬繑鍥炲垎椤靛璞�
+      businessSummaryData.value = Array.isArray(res.data) ? res.data : (res.data.records || [])
+
+      if (!Array.isArray(res.data)) {
+        page.total = Number(res.data.total ?? 0)
+        page.current = Number(res.data.current ?? page.current)
+        page.size = Number(res.data.size ?? page.size)
+      }
+      
+      // 璁$畻缁熻鏁版嵁
+      if (businessSummaryData.value.length > 0) {
+        businessSummaryStats.value.totalAmount = businessSummaryData.value.reduce((sum, item) => {
+          return sum + (parseFloat(item.purchaseAmount) || 0)
+        }, 0)
+        businessSummaryStats.value.productTypes = new Set(businessSummaryData.value.map(item => item.productCategory)).size
+      } else {
+        businessSummaryStats.value = {
+          totalAmount: 0,
+          productTypes: 0
+        }
+      }
+    }
+  } catch (error) {
+    console.error('鏌ヨ澶辫触:', error)
+  } finally {
     loading.value = false
-    ElMessage.success('鏌ヨ瀹屾垚')
-  }, 1000)
+  }
+}
+
+// 缈婚〉/鍒囨崲姣忛〉鏉℃暟
+const handlePagination = ({ page: current, limit }) => {
+  page.current = current
+  page.size = limit
+  handleSearch()
 }
 
 const resetSearch = () => {
   Object.assign(searchForm, {
     dateRange: [],
-    supplierId: '',
-    categoryId: ''
+    productCategory: ''
   })
+  page.current = 1
   handleSearch()
 }
 
@@ -634,62 +276,11 @@
   ElMessage.success('瀵煎嚭鍔熻兘寮�鍙戜腑...')
 }
 
-// 鐘舵�佺浉鍏虫柟娉�
-const getStatusType = (status) => {
-  const statusMap = {
-    completed: 'success',
-    partial: 'warning',
-    pending: 'info'
-  }
-  return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
-  const statusMap = {
-    completed: '宸插畬鎴�',
-    partial: '閮ㄥ垎瀹屾垚',
-    pending: '寰呮墽琛�'
-  }
-  return statusMap[status] || '鏈煡'
-}
-
-const getReceiptStatusType = (status) => {
-  const statusMap = {
-    completed: 'success',
-    partial: 'warning',
-    pending: 'info'
-  }
-  return statusMap[status] || 'info'
-}
-
-const getReceiptStatusText = (status) => {
-  const statusMap = {
-    completed: '宸叉敹璐�',
-    partial: '閮ㄥ垎鏀惰揣',
-    pending: '寰呮敹璐�'
-  }
-  return statusMap[status] || '鏈煡'
-}
-
-const getSupplierStatusType = (status) => {
-  const statusMap = {
-    active: 'success',
-    warning: 'warning',
-    inactive: 'info'
-  }
-  return statusMap[status] || 'info'
-}
-
-const getSupplierStatusText = (status) => {
-  const statusMap = {
-    active: '姝e父鍚堜綔',
-    warning: '闇�鍏虫敞',
-    inactive: '鏆傚仠鍚堜綔'
-  }
-  return statusMap[status] || '鏈煡'
-}
 
 onMounted(() => {
+  // 鍒濆鍖栦骇鍝佺被鍒爲
+  getProductOptions()
+  
   // 璁剧疆榛樿鏃堕棿鑼冨洿涓烘渶杩�30澶�
   const endDate = new Date()
   const startDate = new Date()
@@ -699,6 +290,9 @@
     startDate.toISOString().split('T')[0],
     endDate.toISOString().split('T')[0]
   ]
+  
+  // 鍒濆鍔犺浇鏁版嵁
+  handleSearch()
 })
 </script>
 
@@ -728,26 +322,6 @@
   margin: 0;
   font-size: 16px;
   opacity: 0.9;
-}
-
-.report-selector {
-  margin-bottom: 20px;
-  border-radius: 8px;
-}
-
-.tab-label {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.search-card {
-  margin-bottom: 20px;
-  border-radius: 8px;
-}
-
-.search-form {
-  margin-bottom: 0;
 }
 
 .report-content {
@@ -802,55 +376,5 @@
   font-weight: 600;
 }
 
-:deep(.el-table) {
-  border-radius: 8px;
-  overflow: hidden;
-  width: 100% !important;
-}
 
-:deep(.el-table__body-wrapper) {
-  width: 100% !important;
-}
-
-:deep(.el-table__header-wrapper) {
-  width: 100% !important;
-}
-
-:deep(.el-table th) {
-  background-color: #f8f9fa;
-  color: #606266;
-  font-weight: 600;
-}
-
-:deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
-  background-color: #fafafa;
-}
-
-:deep(.el-tabs__header) {
-  margin-bottom: 0;
-}
-
-:deep(.el-tabs__nav-wrap) {
-  padding: 0 20px;
-}
-
-:deep(.el-tabs__item) {
-  font-size: 16px;
-  font-weight: 500;
-}
-
-:deep(.el-tabs__item.is-active) {
-  color: #409EFF;
-}
-
-:deep(.el-rate) {
-  display: flex;
-  align-items: center;
-}
-
-:deep(.el-rate__text) {
-  margin-left: 8px;
-  font-size: 14px;
-  color: #606266;
-}
 </style>
diff --git a/src/views/procurementManagement/purchaseOrder/index.vue b/src/views/procurementManagement/purchaseOrder/index.vue
index 79ca2fe..7e56cb4 100644
--- a/src/views/procurementManagement/purchaseOrder/index.vue
+++ b/src/views/procurementManagement/purchaseOrder/index.vue
@@ -48,7 +48,7 @@
       </el-table>
     </el-card>
 
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閲囪喘璁㈠崟' : '缂栬緫閲囪喘璁㈠崟'" width="800px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閲囪喘璁㈠崟' : '缂栬緫閲囪喘璁㈠崟'" :width="'800px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" ref="formRef" label-width="120px">
         <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
           <el-select v-model="formData.supplierName" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%">
@@ -60,15 +60,12 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 
diff --git a/src/views/procurementManagement/qualityInspection/index.vue b/src/views/procurementManagement/qualityInspection/index.vue
index 8d90243..ab19d6f 100644
--- a/src/views/procurementManagement/qualityInspection/index.vue
+++ b/src/views/procurementManagement/qualityInspection/index.vue
@@ -49,7 +49,7 @@
       </el-table>
     </el-card>
 
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板璐ㄦ鍗�' : '缂栬緫璐ㄦ鍗�'" width="1000px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板璐ㄦ鍗�' : '缂栬緫璐ㄦ鍗�'" :width="'1000px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -120,15 +120,12 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 
diff --git a/src/views/procurementManagement/returnManagement/index.vue b/src/views/procurementManagement/returnManagement/index.vue
index 2a54083..d44b588 100644
--- a/src/views/procurementManagement/returnManagement/index.vue
+++ b/src/views/procurementManagement/returnManagement/index.vue
@@ -60,7 +60,7 @@
       />
     </el-card>
 
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閫�璐у崟' : '缂栬緫閫�璐у崟'" width="600px">
+    <FormDialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閫�璐у崟' : '缂栬緫閫�璐у崟'" :width="'600px'" :operation-type="dialogType" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="formData" label-width="120px">
         <el-form-item label="閫�璐х被鍨�">
           <el-select v-model="formData.returnType" placeholder="璇烽�夋嫨閫�璐х被鍨�" style="width: 100%">
@@ -87,15 +87,12 @@
           <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
         </el-form-item>
       </el-form>
-      <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref, reactive,onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import Pagination from '@/components/PIMTable/Pagination.vue'
diff --git a/src/views/procurementManagement/transferManagement/index.vue b/src/views/procurementManagement/transferManagement/index.vue
index 10ef52f..3646449 100644
--- a/src/views/procurementManagement/transferManagement/index.vue
+++ b/src/views/procurementManagement/transferManagement/index.vue
@@ -64,7 +64,7 @@
         @pagination="paginationChange"
     />
     <!-- 纭鏀惰揣瀵硅瘽妗� -->
-    <el-dialog v-model="receiptDialogVisible" title="纭鏀惰揣" width="70%">
+    <FormDialog v-model="receiptDialogVisible" title="纭鏀惰揣" :width="'70%'" @close="receiptDialogVisible = false" @confirm="submitReceipt" @cancel="receiptDialogVisible = false">
       <el-form :model="receiptForm" label-width="120px" ref="formRef">
         <el-form-item label="閲囪喘鍚堝悓鍙�">
           <el-input v-model="receiptForm.purchaseContractNumber" disabled />
@@ -130,15 +130,12 @@
           />
         </el-table>
       </el-form>
-      <template #footer>
-        <el-button @click="receiptDialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="submitReceipt">纭鏀惰揣</el-button>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import {ref, onMounted, getCurrentInstance} from 'vue'
 import {
   getPurchaseOrders,
diff --git a/src/views/productManagement/productIdentifier/index.vue b/src/views/productManagement/productIdentifier/index.vue
index 59d8f90..519f745 100644
--- a/src/views/productManagement/productIdentifier/index.vue
+++ b/src/views/productManagement/productIdentifier/index.vue
@@ -1,159 +1,231 @@
 <template>
   <div class="app-container">
     <el-card class="box-card">
-             <!-- 鎼滅储鍖哄煙 -->
-       <el-row :gutter="20" class="search-row">
-         <el-col :span="6">
-           <el-input
-             v-model="searchForm.productName"
-             placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
-             clearable
-             @keyup.enter="handleSearch"
-           >
-             <template #prefix>
-               <el-icon><Search /></el-icon>
-             </template>
-           </el-input>
-         </el-col>
-         <el-col :span="6">
-           <el-select v-model="searchForm.identifierType" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" clearable>
-             <el-option label="浜岀淮鐮�" value="浜岀淮鐮�"></el-option>
-             <el-option label="闃蹭吉鐮�" value="闃蹭吉鐮�"></el-option>
-           </el-select>
-         </el-col>
-         <el-col :span="6">
-           <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
-             <el-option label="宸茬敓鎴�" value="宸茬敓鎴�"></el-option>
-             <el-option label="宸插垎閰�" value="宸插垎閰�"></el-option>
-             <el-option label="宸蹭娇鐢�" value="宸蹭娇鐢�"></el-option>
-             <el-option label="宸蹭綔搴�" value="宸蹭綔搴�"></el-option>
-           </el-select>
-         </el-col>
-         <el-col :span="6">
-           <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
-           <el-button @click="resetSearch">閲嶇疆</el-button>
-           <el-button style="float: right;" type="primary" @click="handleAdd">
-             鏂板鏍囪瘑
-           </el-button>
-         </el-col>
-       </el-row>
-
+      <!-- 鎼滅储鍖哄煙 -->
+      <el-row :gutter="20"
+              class="search-row">
+        <el-col :span="6">
+          <el-input v-model="searchForm.productName"
+                    placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+                    clearable
+                    @keyup.enter="handleSearch">
+            <template #prefix>
+              <el-icon>
+                <Search />
+              </el-icon>
+            </template>
+          </el-input>
+        </el-col>
+        <el-col :span="6">
+          <el-select v-model="searchForm.identifierType"
+                     placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷"
+                     clearable>
+            <el-option label="浜岀淮鐮�"
+                       value="浜岀淮鐮�"></el-option>
+            <el-option label="闃蹭吉鐮�"
+                       value="闃蹭吉鐮�"></el-option>
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-select v-model="searchForm.status"
+                     placeholder="璇烽�夋嫨鐘舵��"
+                     clearable>
+            <el-option label="宸茬敓鎴�"
+                       value="宸茬敓鎴�"></el-option>
+            <el-option label="宸插垎閰�"
+                       value="宸插垎閰�"></el-option>
+            <el-option label="宸蹭娇鐢�"
+                       value="宸蹭娇鐢�"></el-option>
+            <el-option label="宸蹭綔搴�"
+                       value="宸蹭綔搴�"></el-option>
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-button type="primary"
+                     @click="handleSearch">鎼滅储</el-button>
+          <el-button @click="resetSearch">閲嶇疆</el-button>
+          <el-button style="float: right;"
+                     type="primary"
+                     @click="handleAdd">
+            鏂板鏍囪瘑
+          </el-button>
+        </el-col>
+      </el-row>
       <!-- 浜у搧鏍囪瘑鍒楄〃 -->
-      <el-table
-        :data="filteredList"
-        style="width: 100%"
-        v-loading="loading"
-        border
-        stripe
-        height="calc(100vh - 22em)"
-      >
-        <el-table-column prop="id" label="ID" width="80" align="center"/>
-        <el-table-column prop="productName" label="浜у搧鍚嶇О" width="150" />
-        <el-table-column prop="productCode" label="浜у搧缂栫爜" width="120" />
-        <el-table-column prop="batchNo" label="鎵规鍙�" width="120" />
-        <el-table-column prop="identifierType" label="鏍囪瘑绫诲瀷" width="100">
+      <el-table :data="filteredList"
+                style="width: 100%"
+                v-loading="loading"
+                border
+                stripe
+                height="calc(100vh - 22em)">
+        <el-table-column prop="id"
+                         label="ID"
+                         width="80"
+                         align="center" />
+        <el-table-column prop="productName"
+                         label="浜у搧鍚嶇О"
+                         width="150" />
+        <el-table-column prop="productCode"
+                         label="浜у搧缂栫爜"
+                         width="120" />
+        <el-table-column prop="batchNo"
+                         label="鎵规鍙�"
+                         width="120" />
+        <el-table-column prop="identifierType"
+                         label="鏍囪瘑绫诲瀷"
+                         width="100">
           <template #default="scope">
             <el-tag :type="getIdentifierTypeType(scope.row.identifierType)">
               {{ scope.row.identifierType }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column prop="identifierCode" label="鏍囪瘑鐮�" />
-        <el-table-column prop="status" label="鐘舵��" width="100">
+        <el-table-column prop="identifierCode"
+                         label="鏍囪瘑鐮�" />
+        <el-table-column prop="status"
+                         label="鐘舵��"
+                         width="100">
           <template #default="scope">
             <el-tag :type="getStatusType(scope.row.status)">
               {{ scope.row.status }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column prop="generateTime" label="鐢熸垚鏃堕棿" width="160" />
-        <el-table-column label="鎿嶄綔" fixed="right" align="center" width="280">
+        <el-table-column prop="generateTime"
+                         label="鐢熸垚鏃堕棿"
+                         width="160" />
+        <el-table-column label="鎿嶄綔"
+                         fixed="right"
+                         align="center"
+                         width="280">
           <template #default="scope">
-            <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
-            <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
-            <el-button link type="success" @click="generateQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
-            <el-button link type="primary" @click="handleExport(scope.row)">瀵煎嚭</el-button>
-            <el-button link type="primary" @click="handleReassign(scope.row)" v-if="scope.row.status === '宸插垎閰�'">閲嶆柊鍒嗛厤</el-button>
-            <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+            <el-button link
+                       type="primary"
+                       @click="handleView(scope.row)">鏌ョ湅</el-button>
+            <el-button link
+                       type="primary"
+                       @click="handleEdit(scope.row)">缂栬緫</el-button>
+            <el-button link
+                       type="success"
+                       @click="generateQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+            <el-button link
+                       type="primary"
+                       @click="handleExport(scope.row)">瀵煎嚭</el-button>
+            <el-button link
+                       type="primary"
+                       @click="handleReassign(scope.row)"
+                       v-if="scope.row.status === '宸插垎閰�'">閲嶆柊鍒嗛厤</el-button>
+            <el-button link
+                       type="danger"
+                       @click="handleDelete(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
-
       <!-- 鍒嗛〉 -->
-      <pagination
-        :total="pagination.total"
-        layout="total, sizes, prev, pager, next, jumper"
-        :page="pagination.currentPage"
-        :limit="pagination.pageSize"
-        @pagination="handleCurrentChange"
-      />
+      <pagination :total="pagination.total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="pagination.currentPage"
+                  :limit="pagination.pageSize"
+                  @pagination="handleCurrentChange" />
     </el-card>
-
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
-      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="700px">
+      <el-form :model="form"
+               :rules="rules"
+               ref="formRef"
+               label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="浜у搧鍚嶇О" prop="productName">
-              <el-input v-model="form.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"></el-input>
+            <el-form-item label="浜у搧鍚嶇О"
+                          prop="productName">
+              <el-input v-model="form.productName"
+                        placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"></el-input>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="浜у搧缂栫爜" prop="productCode">
-              <el-input v-model="form.productCode" placeholder="璇疯緭鍏ヤ骇鍝佺紪鐮�"></el-input>
+            <el-form-item label="浜у搧缂栫爜"
+                          prop="productCode">
+              <el-input v-model="form.productCode"
+                        placeholder="璇疯緭鍏ヤ骇鍝佺紪鐮�"></el-input>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="鎵规鍙�" prop="batchNo">
-              <el-input v-model="form.batchNo" placeholder="璇疯緭鍏ユ壒娆″彿"></el-input>
+            <el-form-item label="鎵规鍙�"
+                          prop="batchNo">
+              <el-input v-model="form.batchNo"
+                        placeholder="璇疯緭鍏ユ壒娆″彿"></el-input>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鏍囪瘑绫诲瀷" prop="identifierType">
-              <el-select v-model="form.identifierType" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" style="width: 100%">
-                <el-option label="浜岀淮鐮�" value="浜岀淮鐮�"></el-option>
-                <el-option label="闃蹭吉鐮�" value="闃蹭吉鐮�"></el-option>
+            <el-form-item label="鏍囪瘑绫诲瀷"
+                          prop="identifierType">
+              <el-select v-model="form.identifierType"
+                         placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷"
+                         style="width: 100%">
+                <el-option label="浜岀淮鐮�"
+                           value="浜岀淮鐮�"></el-option>
+                <el-option label="闃蹭吉鐮�"
+                           value="闃蹭吉鐮�"></el-option>
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="鐢熸垚鏁伴噺" prop="quantity">
-              <el-input-number v-model="form.quantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
+            <el-form-item label="鐢熸垚鏁伴噺"
+                          prop="quantity">
+              <el-input-number v-model="form.quantity"
+                               :min="1"
+                               :max="10000"
+                               style="width: 100%"></el-input-number>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鐘舵��" prop="status">
-              <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
-                <el-option label="宸茬敓鎴�" value="宸茬敓鎴�"></el-option>
-                <el-option label="宸插垎閰�" value="宸插垎閰�"></el-option>
-                <el-option label="宸蹭娇鐢�" value="宸蹭娇鐢�"></el-option>
-                <el-option label="宸蹭綔搴�" value="宸蹭綔搴�"></el-option>
+            <el-form-item label="鐘舵��"
+                          prop="status">
+              <el-select v-model="form.status"
+                         placeholder="璇烽�夋嫨鐘舵��"
+                         style="width: 100%">
+                <el-option label="宸茬敓鎴�"
+                           value="宸茬敓鎴�"></el-option>
+                <el-option label="宸插垎閰�"
+                           value="宸插垎閰�"></el-option>
+                <el-option label="宸蹭娇鐢�"
+                           value="宸蹭娇鐢�"></el-option>
+                <el-option label="宸蹭綔搴�"
+                           value="宸蹭綔搴�"></el-option>
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="24">
-            <el-form-item label="澶囨敞" prop="remark">
-              <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
+            <el-form-item label="澶囨敞"
+                          prop="remark">
+              <el-input type="textarea"
+                        v-model="form.remark"
+                        placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                        rows="3"></el-input>
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="handleSubmit">纭� 瀹�</el-button>
           <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 鏍囪瘑鐢熸垚瀵硅瘽妗� -->
-    <el-dialog v-model="generateDialogVisible" title="鏍囪瘑鐢熸垚" width="500px">
+    <el-dialog v-model="generateDialogVisible"
+               title="鏍囪瘑鐢熸垚"
+               width="500px">
       <el-form label-width="100px">
         <el-form-item label="浜у搧鍚嶇О">
           <span>{{ currentProduct.productName }}</span>
@@ -167,30 +239,45 @@
         <el-form-item label="鏍囪瘑绫诲瀷">
           <span>{{ currentProduct.identifierType }}</span>
         </el-form-item>
-        <el-form-item label="鐢熸垚鏁伴噺" prop="generateQuantity">
-          <el-input-number v-model="generateQuantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
+        <el-form-item label="鐢熸垚鏁伴噺"
+                      prop="generateQuantity">
+          <el-input-number v-model="generateQuantity"
+                           :min="1"
+                           :max="10000"
+                           style="width: 100%"></el-input-number>
         </el-form-item>
-        <el-form-item label="缂栫爜瑙勫垯" prop="codeRule">
-          <el-select v-model="codeRule" placeholder="璇烽�夋嫨缂栫爜瑙勫垯" style="width: 100%">
-            <el-option label="浜у搧缂栫爜+鎵规鍙�+搴忓彿" value="浜у搧缂栫爜+鎵规鍙�+搴忓彿"></el-option>
-            <el-option label="鏃堕棿鎴�+闅忔満鏁�" value="鏃堕棿鎴�+闅忔満鏁�"></el-option>
-            <el-option label="鑷畾涔夎鍒�" value="鑷畾涔夎鍒�"></el-option>
+        <el-form-item label="缂栫爜瑙勫垯"
+                      prop="codeRule">
+          <el-select v-model="codeRule"
+                     placeholder="璇烽�夋嫨缂栫爜瑙勫垯"
+                     style="width: 100%">
+            <el-option label="浜у搧缂栫爜+鎵规鍙�+搴忓彿"
+                       value="浜у搧缂栫爜+鎵规鍙�+搴忓彿"></el-option>
+            <el-option label="鏃堕棿鎴�+闅忔満鏁�"
+                       value="鏃堕棿鎴�+闅忔満鏁�"></el-option>
+            <el-option label="鑷畾涔夎鍒�"
+                       value="鑷畾涔夎鍒�"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="鑷畾涔夊墠缂�" prop="customPrefix" v-if="codeRule === '鑷畾涔夎鍒�'">
-          <el-input v-model="customPrefix" placeholder="璇疯緭鍏ヨ嚜瀹氫箟鍓嶇紑"></el-input>
+        <el-form-item label="鑷畾涔夊墠缂�"
+                      prop="customPrefix"
+                      v-if="codeRule === '鑷畾涔夎鍒�'">
+          <el-input v-model="customPrefix"
+                    placeholder="璇疯緭鍏ヨ嚜瀹氫箟鍓嶇紑"></el-input>
         </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="generateIdentifiers">鐢� 鎴�</el-button>
           <el-button @click="generateDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="generateIdentifiers">鐢� 鎴�</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 閲嶆柊鍒嗛厤瀵硅瘽妗� -->
-    <el-dialog v-model="reassignDialogVisible" title="閲嶆柊鍒嗛厤鏍囪瘑" width="500px">
+    <el-dialog v-model="reassignDialogVisible"
+               title="閲嶆柊鍒嗛厤鏍囪瘑"
+               width="500px">
       <el-form label-width="100px">
         <el-form-item label="浜у搧鍚嶇О">
           <span>{{ currentProduct.productName }}</span>
@@ -198,26 +285,38 @@
         <el-form-item label="鏍囪瘑鐮�">
           <span>{{ currentProduct.identifierCode }}</span>
         </el-form-item>
-        <el-form-item label="鏂版壒娆″彿" prop="newBatchNo">
-          <el-input v-model="newBatchNo" placeholder="璇疯緭鍏ユ柊鎵规鍙�"></el-input>
+        <el-form-item label="鏂版壒娆″彿"
+                      prop="newBatchNo">
+          <el-input v-model="newBatchNo"
+                    placeholder="璇疯緭鍏ユ柊鎵规鍙�"></el-input>
         </el-form-item>
-        <el-form-item label="鍒嗛厤鍘熷洜" prop="reassignReason">
-          <el-input type="textarea" v-model="reassignReason" rows="3" placeholder="璇疯緭鍏ラ噸鏂板垎閰嶅師鍥�"></el-input>
+        <el-form-item label="鍒嗛厤鍘熷洜"
+                      prop="reassignReason">
+          <el-input type="textarea"
+                    v-model="reassignReason"
+                    rows="3"
+                    placeholder="璇疯緭鍏ラ噸鏂板垎閰嶅師鍥�"></el-input>
         </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="saveReassign">纭� 瀹�</el-button>
           <el-button @click="reassignDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="saveReassign">纭� 瀹�</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 浜岀淮鐮侀瑙堝璇濇 -->
-    <el-dialog v-model="qrCodeDialogVisible" title="浜岀淮鐮侀瑙�" width="500px" center>
+    <el-dialog v-model="qrCodeDialogVisible"
+               title="浜岀淮鐮侀瑙�"
+               width="500px"
+               center>
       <div class="qr-preview-container">
-        <div v-if="qrCodeUrl" class="qr-image-container">
-          <img :src="qrCodeUrl" alt="浜岀淮鐮�" class="qr-image" />
+        <div v-if="qrCodeUrl"
+             class="qr-image-container">
+          <img :src="qrCodeUrl"
+               alt="浜岀淮鐮�"
+               class="qr-image" />
           <div class="qr-info">
             <p><strong>浜у搧鍚嶇О锛�</strong>{{ currentQRProduct.productName }}</p>
             <p><strong>浜у搧缂栫爜锛�</strong>{{ currentQRProduct.productCode }}</p>
@@ -226,29 +325,27 @@
             <p><strong>鏍囪瘑绫诲瀷锛�</strong>{{ currentQRProduct.identifierType }}</p>
           </div>
         </div>
-        <div v-else class="qr-loading">
-          <el-icon class="is-loading"><Loading /></el-icon>
+        <div v-else
+             class="qr-loading">
+          <el-icon class="is-loading">
+            <Loading />
+          </el-icon>
           <p>姝e湪鐢熸垚浜岀淮鐮�...</p>
         </div>
       </div>
-      
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="qrCodeDialogVisible = false">鍏抽棴</el-button>
-          <el-button 
-            v-if="qrCodeUrl" 
-            type="primary" 
-            @click="copyQRContent" 
-            icon="CopyDocument"
-          >
+          <el-button v-if="qrCodeUrl"
+                     type="primary"
+                     @click="copyQRContent"
+                     icon="CopyDocument">
             澶嶅埗鍐呭
           </el-button>
-          <el-button 
-            v-if="qrCodeUrl" 
-            type="success" 
-            @click="downloadQRCode" 
-            icon="Download"
-          >
+          <el-button v-if="qrCodeUrl"
+                     type="success"
+                     @click="downloadQRCode"
+                     icon="Download">
             涓嬭浇浜岀淮鐮�
           </el-button>
         </div>
@@ -258,451 +355,465 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search, Loading, Download } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-import QRCode from 'qrcode'
+  import { ref, reactive, computed } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Plus, Search, Loading, Download } from "@element-plus/icons-vue";
+  import Pagination from "@/components/PIMTable/Pagination.vue";
+  import QRCode from "qrcode";
 
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
-  productName: '',
-  identifierType: '',
-  status: ''
-})
+  // 鍝嶅簲寮忔暟鎹�
+  const loading = ref(false);
+  const searchForm = reactive({
+    productName: "",
+    identifierType: "",
+    status: "",
+  });
 
-const identifierList = ref([
-  {
-    id: 1,
-    productName: '宸ヤ笟浼犳劅鍣ˋ鍨�',
-    productCode: 'SENSOR001',
-    batchNo: 'B202312001',
-    identifierType: '浜岀淮鐮�',
-    identifierCode: 'QR_SENSOR001_B202312001_001',
-    status: '宸插垎閰�',
-    generateTime: '2023-12-01 10:00:00',
-    remark: '閲嶈浜у搧鏍囪瘑'
-  },
-  {
-    id: 2,
-    productName: '鎺у埗闈㈡澘B鍨�',
-    productCode: 'PANEL002',
-    batchNo: 'B202312002',
-    identifierType: '闃蹭吉鐮�',
-    identifierCode: 'SEC_PANEL002_B202312002_001',
-    status: '宸茬敓鎴�',
-    generateTime: '2023-12-02 14:30:00',
-    remark: '甯歌浜у搧鏍囪瘑'
-  },
-  {
-    id: 3,
-    productName: '鏁版嵁閲囬泦鍣–鍨�',
-    productCode: 'COLLECTOR003',
-    batchNo: 'B202312003',
-    identifierType: '闃蹭吉鐮�',
-    identifierCode: 'SEC_COLLECTOR003_B202312003_001',
-    status: '宸蹭娇鐢�',
-    generateTime: '2023-12-03 09:15:00',
-    remark: '娴嬭瘯浜у搧鏍囪瘑'
-  }
-])
+  const identifierList = ref([
+    {
+      id: 1,
+      productName: "宸ヤ笟浼犳劅鍣ˋ鍨�",
+      productCode: "SENSOR001",
+      batchNo: "B202312001",
+      identifierType: "浜岀淮鐮�",
+      identifierCode: "QR_SENSOR001_B202312001_001",
+      status: "宸插垎閰�",
+      generateTime: "2023-12-01 10:00:00",
+      remark: "閲嶈浜у搧鏍囪瘑",
+    },
+    {
+      id: 2,
+      productName: "鎺у埗闈㈡澘B鍨�",
+      productCode: "PANEL002",
+      batchNo: "B202312002",
+      identifierType: "闃蹭吉鐮�",
+      identifierCode: "SEC_PANEL002_B202312002_001",
+      status: "宸茬敓鎴�",
+      generateTime: "2023-12-02 14:30:00",
+      remark: "甯歌浜у搧鏍囪瘑",
+    },
+    {
+      id: 3,
+      productName: "鏁版嵁閲囬泦鍣–鍨�",
+      productCode: "COLLECTOR003",
+      batchNo: "B202312003",
+      identifierType: "闃蹭吉鐮�",
+      identifierCode: "SEC_COLLECTOR003_B202312003_001",
+      status: "宸蹭娇鐢�",
+      generateTime: "2023-12-03 09:15:00",
+      remark: "娴嬭瘯浜у搧鏍囪瘑",
+    },
+  ]);
 
-const pagination = reactive({
-  total: 3,
-  currentPage: 1,
-  pageSize: 10
-})
+  const pagination = reactive({
+    total: 3,
+    currentPage: 1,
+    pageSize: 10,
+  });
 
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板鏍囪瘑')
-const form = reactive({
-  productName: '',
-  productCode: '',
-  batchNo: '',
-  identifierType: '',
-  quantity: 1,
-  status: '宸茬敓鎴�',
-  remark: ''
-})
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("鏂板鏍囪瘑");
+  const form = reactive({
+    productName: "",
+    productCode: "",
+    batchNo: "",
+    identifierType: "",
+    quantity: 1,
+    status: "宸茬敓鎴�",
+    remark: "",
+  });
 
-const rules = {
-  productName: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸悕绉�', trigger: 'blur' }],
-  productCode: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佺紪鐮�', trigger: 'blur' }],
-  batchNo: [{ required: true, message: '璇疯緭鍏ユ壒娆″彿', trigger: 'blur' }],
-  identifierType: [{ required: true, message: '璇烽�夋嫨鏍囪瘑绫诲瀷', trigger: 'change' }],
-  quantity: [{ required: true, message: '璇疯緭鍏ョ敓鎴愭暟閲�', trigger: 'blur' }],
-  status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
+  const rules = {
+    productName: [{ required: true, message: "璇疯緭鍏ヤ骇鍝佸悕绉�", trigger: "blur" }],
+    productCode: [{ required: true, message: "璇疯緭鍏ヤ骇鍝佺紪鐮�", trigger: "blur" }],
+    batchNo: [{ required: true, message: "璇疯緭鍏ユ壒娆″彿", trigger: "blur" }],
+    identifierType: [
+      { required: true, message: "璇烽�夋嫨鏍囪瘑绫诲瀷", trigger: "change" },
+    ],
+    quantity: [{ required: true, message: "璇疯緭鍏ョ敓鎴愭暟閲�", trigger: "blur" }],
+    status: [{ required: true, message: "璇烽�夋嫨鐘舵��", trigger: "change" }],
+  };
 
-const isEdit = ref(false)
-const editId = ref(null)
-const generateDialogVisible = ref(false)
-const reassignDialogVisible = ref(false)
-const currentProduct = ref({})
-const generateQuantity = ref(1)
-const codeRule = ref('')
-const customPrefix = ref('')
-const newBatchNo = ref('')
-const reassignReason = ref('')
-const formRef = ref()
+  const isEdit = ref(false);
+  const editId = ref(null);
+  const generateDialogVisible = ref(false);
+  const reassignDialogVisible = ref(false);
+  const currentProduct = ref({});
+  const generateQuantity = ref(1);
+  const codeRule = ref("");
+  const customPrefix = ref("");
+  const newBatchNo = ref("");
+  const reassignReason = ref("");
+  const formRef = ref();
 
-// 浜岀淮鐮佺浉鍏冲彉閲�
-const qrCodeDialogVisible = ref(false)
-const qrCodeUrl = ref('')
-const currentQRProduct = ref({})
+  // 浜岀淮鐮佺浉鍏冲彉閲�
+  const qrCodeDialogVisible = ref(false);
+  const qrCodeUrl = ref("");
+  const currentQRProduct = ref({});
 
-// 璁$畻灞炴��
-const filteredList = computed(() => {
-  let list = identifierList.value
-  if (searchForm.productName) {
-    list = list.filter(item => item.productName.includes(searchForm.productName))
-  }
-  if (searchForm.identifierType) {
-    list = list.filter(item => item.identifierType === searchForm.identifierType)
-  }
-  if (searchForm.status) {
-    list = list.filter(item => item.status === searchForm.status)
-  }
-  return list
-})
+  // 璁$畻灞炴��
+  const filteredList = computed(() => {
+    let list = identifierList.value;
+    if (searchForm.productName) {
+      list = list.filter(item =>
+        item.productName.includes(searchForm.productName)
+      );
+    }
+    if (searchForm.identifierType) {
+      list = list.filter(
+        item => item.identifierType === searchForm.identifierType
+      );
+    }
+    if (searchForm.status) {
+      list = list.filter(item => item.status === searchForm.status);
+    }
+    return list;
+  });
 
-// 鏂规硶
-const getIdentifierTypeType = (type) => {
-  const typeMap = {
-    '浜岀淮鐮�': 'success',
-    '闃蹭吉鐮�': 'warning'
-  }
-  return typeMap[type] || 'info'
-}
+  // 鏂规硶
+  const getIdentifierTypeType = type => {
+    const typeMap = {
+      浜岀淮鐮�: "success",
+      闃蹭吉鐮�: "warning",
+    };
+    return typeMap[type] || "info";
+  };
 
-const getStatusType = (status) => {
-  const statusMap = {
-    '宸茬敓鎴�': 'info',
-    '宸插垎閰�': 'primary',
-    '宸蹭娇鐢�': 'success',
-    '宸蹭綔搴�': 'danger'
-  }
-  return statusMap[status] || 'info'
-}
+  const getStatusType = status => {
+    const statusMap = {
+      宸茬敓鎴�: "info",
+      宸插垎閰�: "primary",
+      宸蹭娇鐢�: "success",
+      宸蹭綔搴�: "danger",
+    };
+    return statusMap[status] || "info";
+  };
 
-const handleSearch = () => {
-  // 鎼滅储閫昏緫宸插湪computed涓鐞�
-}
+  const handleSearch = () => {
+    // 鎼滅储閫昏緫宸插湪computed涓鐞�
+  };
 
-const resetSearch = () => {
-  searchForm.productName = ''
-  searchForm.identifierType = ''
-  searchForm.status = ''
-}
+  const resetSearch = () => {
+    searchForm.productName = "";
+    searchForm.identifierType = "";
+    searchForm.status = "";
+  };
 
-const handleAdd = () => {
-  dialogTitle.value = '鏂板鏍囪瘑'
-  isEdit.value = false
-  form.productName = ''
-  form.productCode = ''
-  form.batchNo = ''
-  form.identifierType = ''
-  form.quantity = 1
-  form.status = '宸茬敓鎴�'
-  form.remark = ''
-  dialogVisible.value = true
-}
+  const handleAdd = () => {
+    dialogTitle.value = "鏂板鏍囪瘑";
+    isEdit.value = false;
+    form.productName = "";
+    form.productCode = "";
+    form.batchNo = "";
+    form.identifierType = "";
+    form.quantity = 1;
+    form.status = "宸茬敓鎴�";
+    form.remark = "";
+    dialogVisible.value = true;
+  };
 
-const handleView = (row) => {
-  // 鏌ョ湅鏍囪瘑璇︽儏
-  ElMessage.info('鏌ョ湅鏍囪瘑璇︽儏鍔熻兘寰呭疄鐜�')
-}
+  const handleView = row => {
+    // 鏌ョ湅鏍囪瘑璇︽儏
+    ElMessage.info("鏌ョ湅鏍囪瘑璇︽儏鍔熻兘寰呭疄鐜�");
+  };
 
-const handleEdit = (row) => {
-  dialogTitle.value = '缂栬緫鏍囪瘑'
-  isEdit.value = true
-  editId.value = row.id
-  Object.assign(form, row)
-  dialogVisible.value = true
-}
+  const handleEdit = row => {
+    dialogTitle.value = "缂栬緫鏍囪瘑";
+    isEdit.value = true;
+    editId.value = row.id;
+    Object.assign(form, row);
+    dialogVisible.value = true;
+  };
 
-const handleExport = (row) => {
-  // 瀵煎嚭鏍囪瘑
-  ElMessage.success(`宸插鍑烘爣璇�: ${row.identifierCode}`)
-}
+  const handleExport = row => {
+    // 瀵煎嚭鏍囪瘑
+    ElMessage.success(`宸插鍑烘爣璇�: ${row.identifierCode}`);
+  };
 
-const handleReassign = (row) => {
-  currentProduct.value = row
-  newBatchNo.value = ''
-  reassignReason.value = ''
-  reassignDialogVisible.value = true
-}
+  const handleReassign = row => {
+    currentProduct.value = row;
+    newBatchNo.value = "";
+    reassignReason.value = "";
+    reassignDialogVisible.value = true;
+  };
 
-const handleDelete = (row) => {
-  ElMessageBox.confirm('纭鍒犻櫎璇ユ爣璇嗗悧锛�', '鎻愮ず', {
-    confirmButtonText: '纭畾',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning'
-  }).then(() => {
-    const index = identifierList.value.findIndex(item => item.id === row.id)
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭鍒犻櫎璇ユ爣璇嗗悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      const index = identifierList.value.findIndex(item => item.id === row.id);
+      if (index > -1) {
+        identifierList.value.splice(index, 1);
+        pagination.total--;
+        ElMessage.success("鍒犻櫎鎴愬姛");
+      }
+    });
+  };
+
+  // 鐢熸垚浜岀淮鐮�
+  const generateQRCode = async row => {
+    try {
+      // 妫�鏌ュ繀瑕佸瓧娈�
+      if (!row.productName || !row.productCode || !row.batchNo) {
+        ElMessage.warning("浜у搧淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚浜岀淮鐮�");
+        return;
+      }
+
+      currentQRProduct.value = row;
+      qrCodeUrl.value = "";
+      qrCodeDialogVisible.value = true;
+
+      // 鏋勫缓浜岀淮鐮佸唴瀹�
+      let qrContent = "";
+      if (row.identifierType === "浜岀淮鐮�") {
+        qrContent = `${row.productName}|${row.productCode}|${row.batchNo}|${row.identifierCode}`;
+      } else if (row.identifierType === "闃蹭吉鐮�") {
+        // 闃蹭吉鐮佹牸寮忥細SEC_浜у搧缂栫爜_鎵规鍙穇鏃堕棿鎴砡闅忔満鏁�
+        const timestamp = Date.now();
+        const random = Math.random().toString(36).substr(2, 8);
+        qrContent = `SEC_${row.productCode}_${row.batchNo}_${timestamp}_${random}`;
+      }
+
+      // 鐢熸垚浜岀淮鐮�
+      qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+        width: 256,
+        margin: 2,
+        color: {
+          dark: "#000000",
+          light: "#FFFFFF",
+        },
+        errorCorrectionLevel: row.identifierType === "闃蹭吉鐮�" ? "H" : "M",
+      });
+
+      ElMessage.success("浜岀淮鐮佺敓鎴愭垚鍔燂紒");
+    } catch (error) {
+      console.error("鐢熸垚浜岀淮鐮佸け璐�:", error);
+      ElMessage.error("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+      qrCodeDialogVisible.value = false;
+    }
+  };
+
+  // 涓嬭浇浜岀淮鐮�
+  const downloadQRCode = () => {
+    if (!qrCodeUrl.value) {
+      ElMessage.warning("璇峰厛鐢熸垚浜岀淮鐮�");
+      return;
+    }
+
+    const a = document.createElement("a");
+    a.href = qrCodeUrl.value;
+    a.download = `${currentQRProduct.value.productName}_${
+      currentQRProduct.value.identifierType
+    }_${new Date().getTime()}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+    ElMessage.success("涓嬭浇鎴愬姛锛�");
+  };
+
+  // 澶嶅埗浜岀淮鐮佸唴瀹�
+  const copyQRContent = async () => {
+    if (!currentQRProduct.value) {
+      ElMessage.warning("娌℃湁鍙鍒剁殑鍐呭");
+      return;
+    }
+
+    try {
+      let content = "";
+      if (currentQRProduct.value.identifierType === "浜岀淮鐮�") {
+        content = `${currentQRProduct.value.productName}|${currentQRProduct.value.productCode}|${currentQRProduct.value.batchNo}|${currentQRProduct.value.identifierCode}`;
+      } else if (currentQRProduct.value.identifierType === "闃蹭吉鐮�") {
+        const timestamp = Date.now();
+        const random = Math.random().toString(36).substr(2, 8);
+        content = `SEC_${currentQRProduct.value.productCode}_${currentQRProduct.value.batchNo}_${timestamp}_${random}`;
+      }
+
+      await navigator.clipboard.writeText(content);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    } catch (error) {
+      // 闄嶇骇鏂规
+      const textArea = document.createElement("textarea");
+      textArea.value = content;
+      document.body.appendChild(textArea);
+      textArea.select();
+      document.execCommand("copy");
+      document.body.removeChild(textArea);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    }
+  };
+
+  const generateIdentifiers = () => {
+    if (!codeRule.value) {
+      ElMessage.warning("璇烽�夋嫨缂栫爜瑙勫垯");
+      return;
+    }
+
+    // 鐢熸垚鏍囪瘑鐨勯�昏緫
+    const newIdentifiers = [];
+    for (let i = 1; i <= generateQuantity.value; i++) {
+      let identifierCode = "";
+      if (codeRule.value === "浜у搧缂栫爜+鎵规鍙�+搴忓彿") {
+        identifierCode = `${currentProduct.value.productCode}_${
+          currentProduct.value.batchNo
+        }_${String(i).padStart(3, "0")}`;
+      } else if (codeRule.value === "鏃堕棿鎴�+闅忔満鏁�") {
+        identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
+      } else if (codeRule.value === "鑷畾涔夎鍒�") {
+        identifierCode = `${customPrefix.value || "CUSTOM"}_${Date.now()}_${i}`;
+      }
+
+      newIdentifiers.push({
+        id: Math.max(...identifierList.value.map(item => item.id)) + i,
+        productName: currentProduct.value.productName,
+        productCode: currentProduct.value.productCode,
+        batchNo: currentProduct.value.batchNo,
+        identifierType: currentProduct.value.identifierType,
+        identifierCode: identifierCode,
+        status: "宸茬敓鎴�",
+        generateTime: new Date().toLocaleString(),
+        remark: "鎵归噺鐢熸垚",
+      });
+    }
+
+    identifierList.value.push(...newIdentifiers);
+    pagination.total += newIdentifiers.length;
+    ElMessage.success(`鎴愬姛鐢熸垚 ${newIdentifiers.length} 涓爣璇哷);
+    generateDialogVisible.value = false;
+  };
+
+  const saveReassign = () => {
+    if (!newBatchNo.value) {
+      ElMessage.warning("璇疯緭鍏ユ柊鎵规鍙�");
+      return;
+    }
+
+    const index = identifierList.value.findIndex(
+      item => item.id === currentProduct.value.id
+    );
     if (index > -1) {
-      identifierList.value.splice(index, 1)
-      pagination.total--
-      ElMessage.success('鍒犻櫎鎴愬姛')
+      identifierList.value[index].batchNo = newBatchNo.value;
+      identifierList.value[index].status = "宸插垎閰�";
+      ElMessage.success("鏍囪瘑閲嶆柊鍒嗛厤鎴愬姛");
+      reassignDialogVisible.value = false;
     }
-  })
-}
+  };
 
-// 鐢熸垚浜岀淮鐮�
-const generateQRCode = async (row) => {
-  try {
-    // 妫�鏌ュ繀瑕佸瓧娈�
-    if (!row.productName || !row.productCode || !row.batchNo) {
-      ElMessage.warning('浜у搧淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚浜岀淮鐮�')
-      return
-    }
-    
-    currentQRProduct.value = row
-    qrCodeUrl.value = ''
-    qrCodeDialogVisible.value = true
-    
-    // 鏋勫缓浜岀淮鐮佸唴瀹�
-    let qrContent = ''
-    if (row.identifierType === '浜岀淮鐮�') {
-      qrContent = `${row.productName}|${row.productCode}|${row.batchNo}|${row.identifierCode}`
-    } else if (row.identifierType === '闃蹭吉鐮�') {
-      // 闃蹭吉鐮佹牸寮忥細SEC_浜у搧缂栫爜_鎵规鍙穇鏃堕棿鎴砡闅忔満鏁�
-      const timestamp = Date.now()
-      const random = Math.random().toString(36).substr(2, 8)
-      qrContent = `SEC_${row.productCode}_${row.batchNo}_${timestamp}_${random}`
-    }
-    
-    // 鐢熸垚浜岀淮鐮�
-    qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
-      width: 256,
-      margin: 2,
-      color: {
-        dark: '#000000',
-        light: '#FFFFFF'
-      },
-      errorCorrectionLevel: row.identifierType === '闃蹭吉鐮�' ? 'H' : 'M'
-    })
-    
-    ElMessage.success('浜岀淮鐮佺敓鎴愭垚鍔燂紒')
-    
-  } catch (error) {
-    console.error('鐢熸垚浜岀淮鐮佸け璐�:', error)
-    ElMessage.error('鐢熸垚浜岀淮鐮佸け璐ワ細' + error.message)
-    qrCodeDialogVisible.value = false
-  }
-}
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        if (isEdit.value) {
+          // 缂栬緫
+          const index = identifierList.value.findIndex(
+            item => item.id === editId.value
+          );
+          if (index > -1) {
+            identifierList.value[index] = { ...form, id: editId.value };
+            ElMessage.success("缂栬緫鎴愬姛");
+          }
+        } else {
+          // 鏂板
+          const newId =
+            Math.max(...identifierList.value.map(item => item.id)) + 1;
 
-// 涓嬭浇浜岀淮鐮�
-const downloadQRCode = () => {
-  if (!qrCodeUrl.value) {
-    ElMessage.warning('璇峰厛鐢熸垚浜岀淮鐮�')
-    return
-  }
-  
-  const a = document.createElement('a')
-  a.href = qrCodeUrl.value
-  a.download = `${currentQRProduct.value.productName}_${currentQRProduct.value.identifierType}_${new Date().getTime()}.png`
-  document.body.appendChild(a)
-  a.click()
-  document.body.removeChild(a)
-  ElMessage.success('涓嬭浇鎴愬姛锛�')
-}
+          // 鏍规嵁鏍囪瘑绫诲瀷鐢熸垚涓嶅悓鐨勬爣璇嗙爜
+          let identifierCode = "";
+          if (form.identifierType === "浜岀淮鐮�") {
+            identifierCode = `QR_${form.productCode}_${form.batchNo}_001`;
+          } else if (form.identifierType === "闃蹭吉鐮�") {
+            identifierCode = `SEC_${form.productCode}_${form.batchNo}_001`;
+          }
 
-// 澶嶅埗浜岀淮鐮佸唴瀹�
-const copyQRContent = async () => {
-  if (!currentQRProduct.value) {
-    ElMessage.warning('娌℃湁鍙鍒剁殑鍐呭')
-    return
-  }
-  
-  try {
-    let content = ''
-    if (currentQRProduct.value.identifierType === '浜岀淮鐮�') {
-      content = `${currentQRProduct.value.productName}|${currentQRProduct.value.productCode}|${currentQRProduct.value.batchNo}|${currentQRProduct.value.identifierCode}`
-    } else if (currentQRProduct.value.identifierType === '闃蹭吉鐮�') {
-      const timestamp = Date.now()
-      const random = Math.random().toString(36).substr(2, 8)
-      content = `SEC_${currentQRProduct.value.productCode}_${currentQRProduct.value.batchNo}_${timestamp}_${random}`
-    }
-    
-    await navigator.clipboard.writeText(content)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  } catch (error) {
-    // 闄嶇骇鏂规
-    const textArea = document.createElement('textarea')
-    textArea.value = content
-    document.body.appendChild(textArea)
-    textArea.select()
-    document.execCommand('copy')
-    document.body.removeChild(textArea)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  }
-}
-
-const generateIdentifiers = () => {
-  if (!codeRule.value) {
-    ElMessage.warning('璇烽�夋嫨缂栫爜瑙勫垯')
-    return
-  }
-  
-  // 鐢熸垚鏍囪瘑鐨勯�昏緫
-  const newIdentifiers = []
-  for (let i = 1; i <= generateQuantity.value; i++) {
-    let identifierCode = ''
-    if (codeRule.value === '浜у搧缂栫爜+鎵规鍙�+搴忓彿') {
-      identifierCode = `${currentProduct.value.productCode}_${currentProduct.value.batchNo}_${String(i).padStart(3, '0')}`
-    } else if (codeRule.value === '鏃堕棿鎴�+闅忔満鏁�') {
-      identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`
-    } else if (codeRule.value === '鑷畾涔夎鍒�') {
-      identifierCode = `${customPrefix.value || 'CUSTOM'}_${Date.now()}_${i}`
-    }
-    
-    newIdentifiers.push({
-      id: Math.max(...identifierList.value.map(item => item.id)) + i,
-      productName: currentProduct.value.productName,
-      productCode: currentProduct.value.productCode,
-      batchNo: currentProduct.value.batchNo,
-      identifierType: currentProduct.value.identifierType,
-      identifierCode: identifierCode,
-      status: '宸茬敓鎴�',
-      generateTime: new Date().toLocaleString(),
-      remark: '鎵归噺鐢熸垚'
-    })
-  }
-  
-  identifierList.value.push(...newIdentifiers)
-  pagination.total += newIdentifiers.length
-  ElMessage.success(`鎴愬姛鐢熸垚 ${newIdentifiers.length} 涓爣璇哷)
-  generateDialogVisible.value = false
-}
-
-const saveReassign = () => {
-  if (!newBatchNo.value) {
-    ElMessage.warning('璇疯緭鍏ユ柊鎵规鍙�')
-    return
-  }
-  
-  const index = identifierList.value.findIndex(item => item.id === currentProduct.value.id)
-  if (index > -1) {
-    identifierList.value[index].batchNo = newBatchNo.value
-    identifierList.value[index].status = '宸插垎閰�'
-    ElMessage.success('鏍囪瘑閲嶆柊鍒嗛厤鎴愬姛')
-    reassignDialogVisible.value = false
-  }
-}
-
-const handleSubmit = () => {
-  formRef.value.validate((valid) => {
-    if (valid) {
-      if (isEdit.value) {
-        // 缂栬緫
-        const index = identifierList.value.findIndex(item => item.id === editId.value)
-        if (index > -1) {
-          identifierList.value[index] = { ...form, id: editId.value }
-          ElMessage.success('缂栬緫鎴愬姛')
+          identifierList.value.push({
+            ...form,
+            id: newId,
+            identifierCode: identifierCode,
+            generateTime: new Date().toLocaleString(),
+          });
+          pagination.total++;
+          ElMessage.success("鏂板鎴愬姛");
         }
-             } else {
-         // 鏂板
-         const newId = Math.max(...identifierList.value.map(item => item.id)) + 1
-         
-         // 鏍规嵁鏍囪瘑绫诲瀷鐢熸垚涓嶅悓鐨勬爣璇嗙爜
-         let identifierCode = ''
-         if (form.identifierType === '浜岀淮鐮�') {
-           identifierCode = `QR_${form.productCode}_${form.batchNo}_001`
-         } else if (form.identifierType === '闃蹭吉鐮�') {
-           identifierCode = `SEC_${form.productCode}_${form.batchNo}_001`
-         }
-         
-         identifierList.value.push({
-           ...form,
-           id: newId,
-           identifierCode: identifierCode,
-           generateTime: new Date().toLocaleString()
-         })
-         pagination.total++
-         ElMessage.success('鏂板鎴愬姛')
-       }
-      dialogVisible.value = false
-    }
-  })
-}
+        dialogVisible.value = false;
+      }
+    });
+  };
 
-const handleCurrentChange = (val) => {
-  pagination.currentPage = val.page
-  pagination.pageSize = val.limit
-}
+  const handleCurrentChange = val => {
+    pagination.currentPage = val.page;
+    pagination.pageSize = val.limit;
+  };
 </script>
 
 <style scoped>
-.search-row {
-  margin-bottom: 20px;
-}
+  .search-row {
+    margin-bottom: 20px;
+  }
 
-.quick-actions-row {
-  margin-bottom: 20px;
-}
+  .quick-actions-row {
+    margin-bottom: 20px;
+  }
 
-.quick-actions-row .el-alert {
-  margin-bottom: 0;
-}
+  .quick-actions-row .el-alert {
+    margin-bottom: 0;
+  }
 
-.quick-actions-row .el-alert p {
-  margin: 5px 0;
-  font-size: 14px;
-  line-height: 1.5;
-}
+  .quick-actions-row .el-alert p {
+    margin: 5px 0;
+    font-size: 14px;
+    line-height: 1.5;
+  }
 
-/* 浜岀淮鐮侀瑙堟牱寮� */
-.qr-preview-container {
-  text-align: center;
-  padding: 20px;
-}
+  /* 浜岀淮鐮侀瑙堟牱寮� */
+  .qr-preview-container {
+    text-align: center;
+    padding: 20px;
+  }
 
-.qr-image-container {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 20px;
-}
+  .qr-image-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 20px;
+  }
 
-.qr-image {
-  max-width: 100%;
-  height: auto;
-  border: 2px solid #e0e0e0;
-  border-radius: 8px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
+  .qr-image {
+    max-width: 100%;
+    height: auto;
+    border: 2px solid #e0e0e0;
+    border-radius: 8px;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  }
 
-.qr-info {
-  text-align: left;
-  background: #f8f9fa;
-  padding: 15px;
-  border-radius: 8px;
-  min-width: 300px;
-}
+  .qr-info {
+    text-align: left;
+    background: #f8f9fa;
+    padding: 15px;
+    border-radius: 8px;
+    min-width: 300px;
+  }
 
-.qr-info p {
-  margin: 8px 0;
-  color: #666;
-  font-size: 14px;
-}
+  .qr-info p {
+    margin: 8px 0;
+    color: #666;
+    font-size: 14px;
+  }
 
-.qr-loading {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 15px;
-  padding: 40px 0;
-}
+  .qr-loading {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 15px;
+    padding: 40px 0;
+  }
 
-.qr-loading .el-icon {
-  font-size: 32px;
-  color: #409EFF;
-}
+  .qr-loading .el-icon {
+    font-size: 32px;
+    color: #409eff;
+  }
 
-.qr-loading p {
-  color: #666;
-  margin: 0;
-}
+  .qr-loading p {
+    color: #666;
+    margin: 0;
+  }
 </style>
diff --git a/src/views/productionManagement/operationScheduling/components/formDia.vue b/src/views/productionManagement/operationScheduling/components/formDia.vue
index a4f36bf..06b46ac 100644
--- a/src/views/productionManagement/operationScheduling/components/formDia.vue
+++ b/src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -8,20 +8,47 @@
     >
       <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">鏂板</el-button>
 			<span style="font-size: 18px;margin-left: 10px">寰呮帓浜ф暟閲忥細{{pendingNum}}</span>
+<!--			<div style="margin-bottom: 10px; margin-left: 10px;">-->
+<!--				<el-form-item label="棰嗙敤锛�" style="margin-bottom: 0;">-->
+<!--					<el-input v-model="receive" placeholder="璇疯緭鍏ラ鐢�" style="width: 200px;" />-->
+<!--				</el-form-item>-->
+<!--			</div>-->
       <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id">
-        <el-table-column label="搴忓彿" width="60">
+        <el-table-column label="搴忓彿" width="60" align="center">
           <template #default="scope">
             {{ scope.$index + 1 }}
           </template>
         </el-table-column>
-        <el-table-column label="宸ュ簭" prop="process">
+        <el-table-column label="宸ュ簭" prop="process" width="150">
           <template #default="scope">
 						<el-input v-model="scope.row.process" placeholder="璇疯緭鍏ュ伐搴�" />
           </template>
         </el-table-column>
-        <el-table-column label="鍗曚綅" prop="unit">
+		<el-table-column label="浜х嚎" prop="productionLine" width="150">
+          <template #default="scope">
+            <el-select
+              v-model="scope.row.productionLine"
+              placeholder="閫夋嫨浜х嚎"
+              style="width: 100%;"
+              clearable
+            >
+              <el-option
+                v-for="line in productionLines"
+                :key="line.value"
+                :label="line.label"
+                :value="line.value"
+              />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍗曚綅" prop="unit" width="90">
           <template #default="scope">
             <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍙e懗/鍝佸悕/瑙勬牸" prop="type" width="150">
+          <template #default="scope">
+            <el-input v-model="scope.row.type" placeholder="璇疯緭鍏�" />
           </template>
         </el-table-column>
         <el-table-column label="鎺掍骇鏁伴噺" width="200" prop="schedulingNum">
@@ -50,17 +77,20 @@
 						/>
           </template>
         </el-table-column>
-        <el-table-column label="鎺掍骇鏃ユ湡" prop="schedulingDate">
+        <el-table-column label="鎺掍骇鏃ユ湡" prop="schedulingDate" width="200">
           <template #default="scope">
             <el-date-picker v-model="scope.row.schedulingDate" type="date" placeholder="閫夋嫨鏃ユ湡" style="width: 100%;" value-format="YYYY-MM-DD" format="YYYY-MM-DD"/>
           </template>
         </el-table-column>
-        <el-table-column label="鎺掍骇浜�" prop="schedulingUserId">
+        <el-table-column label="鎺掍骇浜�" prop="schedulingUserId" width="150">
           <template #default="scope">
 						<el-select
 							v-model="scope.row.schedulingUserId"
 							placeholder="閫夋嫨浜哄憳"
 							style="width: 100%;"
+              filterable
+              default-first-option
+              :reserve-keyword="false"
 						>
 							<el-option
 								v-for="user in userList"
@@ -69,6 +99,11 @@
 								:value="user.userId"
 							/>
 						</el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="澶囨敞" prop="remark" width="200">
+          <template #default="scope">
+            <el-input v-model="scope.row.remark" placeholder="璇疯緭鍏ュ娉�" />
           </template>
         </el-table-column>
         <el-table-column label="鎿嶄綔" width="80">
@@ -88,7 +123,7 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, getCurrentInstance} from "vue";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {processScheduling} from "@/api/productionManagement/operationScheduling.js";
 const { proxy } = getCurrentInstance()
@@ -97,33 +132,56 @@
 
 const dialogFormVisible = ref(false);
 const operationType = ref('')
-const tableData = ref([
-	{ process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' }
-]);
+const tableData = ref([]);
 const unitFromRow = ref('');
 const idFromRow = ref('');
-const pendingNum = ref('');
+const specificationModelFromRow = ref('');
+const pendingNum = ref(0);
 const userList = ref([])
+const receive = ref('')
+const sunqianUserId = ref('')
+// 浜х嚎閫夐」
+const productionLines = ref([
+  { label: '浜х嚎1', value: '浜х嚎1' },
+  { label: '浜х嚎2', value: '浜х嚎2' },
+  { label: '浜х嚎3', value: '浜х嚎3' },
+  { label: '浜х嚎4', value: '浜х嚎4' }
+])
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
+	pendingNum.value = row?.pendingNum ?? 0;
+	unitFromRow.value = row?.unit ?? '';
+	idFromRow.value = row?.id ?? '';
+	specificationModelFromRow.value = row?.specificationModel ?? '';
+	
 	userListNoPageByTenantId().then((res) => {
 		userList.value = res.data;
+		// 鎵惧埌瀛欏�╃殑鐢ㄦ埛ID骞惰缃负榛樿鍊�
+		const sunqianUser = userList.value.find(user => user.nickName === '瀛欏��');
+		if (sunqianUser) {
+			sunqianUserId.value = sunqianUser.userId;
+		}
+		// 鍦ㄧ敤鎴峰垪琛ㄥ姞杞藉畬鎴愬悗鍒涘缓琛屾暟鎹紝骞跺皢浜х嚎鏁版嵁甯﹀叆
+		tableData.value = [createRow(row)];
 	});
-	pendingNum.value = row.pendingNum
-  if (row && row.unit !== undefined) {
-    unitFromRow.value = row.unit;
-    idFromRow.value = row.id;
-    tableData.value.forEach(item => {
-      item.unit = row.unit;
-      item.id = row.id;
-    });
-  } else {
-    unitFromRow.value = '';
-  }
 }
+
+const createRow = (row) => ({
+	id: idFromRow.value,
+	process: '鍖呰',
+	schedulingDate: '',
+	schedulingNum: null,
+	schedulingUserId: sunqianUserId.value, // 榛樿璁剧疆涓哄瓩鍊╃殑鐢ㄦ埛ID
+	workHours: null,
+	unit: unitFromRow.value,
+	remark: '',
+	type: specificationModelFromRow.value,
+	productionLine: row?.productionLine ?? '', // 浠庤鏁版嵁涓幏鍙栦骇绾夸俊鎭�
+});
+
 const submitForm = () => {
 	// 1. 妫�鏌ユ瘡涓�琛屾槸鍚﹀~鍐欏畬鏁�
 	for (let i = 0; i < tableData.value.length; i++) {
@@ -134,7 +192,8 @@
 			row.schedulingNum === '' || row.schedulingNum === null ||
 			!row.schedulingUserId ||
 			row.workHours === '' || row.workHours === null ||
-			!row.unit
+			!row.unit ||
+			!row.productionLine
 		) {
 			proxy.$modal.msgError(`绗�${i + 1}琛屾暟鎹湭濉啓瀹屾暣`);
 			return;
@@ -148,7 +207,15 @@
 		proxy.$modal.msgError('鎺掍骇鏁伴噺鍚堣涓嶈兘瓒呰繃寰呮帓浜ф暟閲�');
 		return;
 	}
-	processScheduling(tableData.value).then((res) => {
+	// 3. 灏� receive 瀛楁娣诲姞鍒版瘡鏉℃暟鎹腑锛屽苟绉婚櫎 loss 瀛楁
+	const submitData = tableData.value.map(row => {
+		const { loss, ...rest } = row;
+		return {
+			...rest,
+			receive: receive.value
+		};
+	});
+	processScheduling(submitData).then((res) => {
 		proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
 		closeDia();
 	})
@@ -159,6 +226,12 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   dialogFormVisible.value = false;
+  receive.value = '';
+  tableData.value = [];
+  unitFromRow.value = '';
+  idFromRow.value = '';
+  specificationModelFromRow.value = '';
+  pendingNum.value = 0;
   emit('close')
 };
 defineExpose({
@@ -166,7 +239,7 @@
 });
 
 const addRow = () => {
-  tableData.value.push({ id: idFromRow.value, process: '', unit: unitFromRow.value, schedulingNum: '', workHours: '', schedulingDate: '', schedulingUserId: '' });
+  tableData.value.push(createRow());
 };
 const removeRow = (index) => {
   tableData.value.splice(index, 1);
diff --git a/src/views/productionManagement/operationScheduling/index.vue b/src/views/productionManagement/operationScheduling/index.vue
index 082b782..a9c06fb 100644
--- a/src/views/productionManagement/operationScheduling/index.vue
+++ b/src/views/productionManagement/operationScheduling/index.vue
@@ -7,11 +7,16 @@
 										style="width: 200px;"
 										@change="handleQuery" />
 				</el-form-item>
-				<el-form-item label="椤圭洰鍚嶇О:">
-					<el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+				<el-form-item label="鍚堝悓鍙�:">
+					<el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
 										style="width: 200px;"
 										@change="handleQuery" />
 				</el-form-item>
+<!--				<el-form-item label="椤圭洰鍚嶇О:">-->
+<!--					<el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"-->
+<!--										style="width: 200px;"-->
+<!--										@change="handleQuery" />-->
+<!--				</el-form-item>-->
 				<el-form-item label="娲惧伐鏃ユ湡:">
 					<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
 													placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
@@ -60,10 +65,12 @@
 const data = reactive({
 	searchForm: {
 		staffName: "",
+		customerName: "",
+		salesContractNo: "",
 		status: 1,
-		entryDate: null, // 褰曞叆鏃ユ湡
-		entryDateStart: undefined,
-		entryDateEnd: undefined,
+		entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // 褰曞叆鏃ユ湡锛岄粯璁ゅ綋澶�
+		entryDateStart: dayjs().format("YYYY-MM-DD"),
+		entryDateEnd: dayjs().format("YYYY-MM-DD"),
 	},
 });
 const { searchForm } = toRefs(data);
@@ -105,21 +112,21 @@
 		prop: "salesContractNo",
 		width: 200,
 	},
-	{
-		label: "瀹㈡埛鍚堝悓鍙�",
-		prop: "customerContractNo",
-		width: 200,
-	},
+	// {
+	// 	label: "瀹㈡埛鍚堝悓鍙�",
+	// 	prop: "customerContractNo",
+	// 	width: 200,
+	// },
 	{
 		label: "瀹㈡埛鍚嶇О",
 		prop: "customerName",
 		width: 200,
 	},
-	{
-		label: "椤圭洰鍚嶇О",
-		prop: "projectName",
-		width:300
-	},
+	// {
+	// 	label: "椤圭洰鍚嶇О",
+	// 	prop: "projectName",
+	// 	width:300
+	// },
 	{
 		label: "浜у搧澶х被",
 		prop: "productCategory",
@@ -131,6 +138,16 @@
 		width: 150,
 	},
 	{
+		label: "缁戝畾鏈哄櫒",
+		prop: "speculativeTradingName",
+		width: 220,
+	},
+	// {
+	// 	label: "浜х嚎",
+	// 	prop: "productionLine",
+	// 	width: 220,
+	// },
+	{
 		label: "鍗曚綅",
 		prop: "unit",
 	},
diff --git a/src/views/productionManagement/processRoute/Edit.vue b/src/views/productionManagement/processRoute/Edit.vue
new file mode 100644
index 0000000..0c0fe0f
--- /dev/null
+++ b/src/views/productionManagement/processRoute/Edit.vue
@@ -0,0 +1,252 @@
+<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="productModelId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨浜у搧',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-button type="primary" @click="showProductSelectDialog = true">
+            {{ formState.productName && formState.productModelName 
+              ? `${formState.productName} - ${formState.productModelName}` 
+              : '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item
+            label="BOM"
+            prop="bomId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨BOM',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-select
+              v-model="formState.bomId"
+              placeholder="璇烽�夋嫨BOM"
+              clearable
+              :disabled="!formState.productModelId || bomOptions.length === 0"
+              style="width: 100%"
+          >
+            <el-option
+                v-for="item in bomOptions"
+                :key="item.id"
+                :label="item.bomNo || `BOM-${item.id}`"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="澶囨敞" prop="description">
+          <el-input v-model="formState.description" type="textarea" />
+        </el-form-item>
+      </el-form>
+      
+      <!-- 浜у搧閫夋嫨寮圭獥 -->
+      <ProductSelectDialog
+          v-model="showProductSelectDialog"
+          @confirm="handleProductSelect"
+          single
+      />
+      <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, onMounted, nextTick, watch} from "vue";
+import {update} from "@/api/productionManagement/processRoute.js";
+import {getByModel} from "@/api/productionManagement/productBom.js";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+
+  record: {
+    type: Object,
+    required: true,
+  }
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
+const formState = ref({
+  productId: undefined,
+  productModelId: undefined,
+  productName: "",
+  productModelName: "",
+  bomId: undefined,
+  description: '',
+});
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+const showProductSelectDialog = ref(false);
+const bomOptions = ref([]);
+
+let { proxy } = getCurrentInstance()
+
+const closeModal = () => {
+  isShow.value = false;
+};
+
+// 璁剧疆琛ㄥ崟鏁版嵁
+const setFormData = () => {
+  if (props.record) {
+    formState.value = {
+      ...props.record,
+      productId: props.record.productId,
+      productModelId: props.record.productModelId,
+      productName: props.record.productName || "",
+      // 娉ㄦ剰锛歳ecord涓殑瀛楁鏄痬odel锛岄渶瑕佹槧灏勫埌productModelName
+      productModelName: props.record.model || props.record.productModelName || "",
+      bomId: props.record.bomId,
+      description: props.record.description || '',
+    };
+    // 濡傛灉鏈変骇鍝佸瀷鍙稩D锛屽姞杞紹OM鍒楄〃
+    if (props.record.productModelId) {
+      loadBomList(props.record.productModelId);
+    }
+  }
+}
+
+// 鍔犺浇BOM鍒楄〃
+const loadBomList = async (productModelId) => {
+  if (!productModelId) {
+    bomOptions.value = [];
+    return;
+  }
+  try {
+    const res = await getByModel(productModelId);
+    // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
+    let bomList = [];
+    if (Array.isArray(res)) {
+      bomList = res;
+    } else if (res && res.data) {
+      bomList = Array.isArray(res.data) ? res.data : [res.data];
+    } else if (res && typeof res === 'object') {
+      bomList = [res];
+    }
+    bomOptions.value = bomList;
+  } catch (error) {
+    console.error("鍔犺浇BOM鍒楄〃澶辫触锛�", error);
+    bomOptions.value = [];
+  }
+};
+
+// 浜у搧閫夋嫨澶勭悊
+const handleProductSelect = async (products) => {
+  if (products && products.length > 0) {
+    const product = products[0];
+    // 鍏堟煡璇OM鍒楄〃锛堝繀閫夛級
+    try {
+      const res = await getByModel(product.id);
+      // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
+      let bomList = [];
+      if (Array.isArray(res)) {
+        bomList = res;
+      } else if (res && res.data) {
+        bomList = Array.isArray(res.data) ? res.data : [res.data];
+      } else if (res && typeof res === 'object') {
+        bomList = [res];
+      }
+      
+      if (bomList.length > 0) {
+        formState.value.productModelId = product.id;
+        formState.value.productName = product.productName;
+        formState.value.productModelName = product.model;
+        // 濡傛灉褰撳墠閫夋嫨鐨凚OM涓嶅湪鏂板垪琛ㄤ腑锛屽垯閲嶇疆BOM閫夋嫨
+        const currentBomExists = bomList.some(bom => bom.id === formState.value.bomId);
+        if (!currentBomExists) {
+          formState.value.bomId = undefined;
+        }
+        bomOptions.value = bomList;
+        showProductSelectDialog.value = false;
+        // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+        proxy.$refs["formRef"]?.validateField('productModelId');
+      } else {
+        proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+      }
+    } catch (error) {
+      // 濡傛灉鎺ュ彛杩斿洖404鎴栧叾浠栭敊璇紝璇存槑娌℃湁BOM
+      proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+    }
+  }
+};
+
+const handleSubmit = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰BOM
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨浜у搧");
+        return;
+      }
+      if (!formState.value.bomId) {
+        proxy.$modal.msgError("璇烽�夋嫨BOM");
+        return;
+      }
+      update(formState.value).then(res => {
+        // 鍏抽棴妯℃�佹
+        isShow.value = false;
+        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+        emit('completed');
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      })
+    }
+  })
+};
+
+defineExpose({
+  closeModal,
+  handleSubmit,
+  isShow,
+});
+
+
+// 鐩戝惉寮圭獥鎵撳紑锛屽垵濮嬪寲琛ㄥ崟鏁版嵁
+watch(() => props.visible, (visible) => {
+  if (visible && props.record) {
+    nextTick(() => {
+      setFormData();
+    });
+  }
+}, { immediate: true });
+
+onMounted(() => {
+  if (props.visible && props.record) {
+    setFormData();
+  }
+});
+</script>
diff --git a/src/views/productionManagement/processRoute/ItemsForm.vue b/src/views/productionManagement/processRoute/ItemsForm.vue
new file mode 100644
index 0000000..ed6e499
--- /dev/null
+++ b/src/views/productionManagement/processRoute/ItemsForm.vue
@@ -0,0 +1,531 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="isShow"
+        title="宸ヨ壓璺嚎椤圭洰"
+        width="800px"
+        @close="closeModal"
+    >
+      <div class="operate-button">
+        <el-button
+            type="primary"
+            @click="isShowProductSelectDialog = true"
+            class="mb5"
+            style="margin-bottom: 10px;"
+        >
+          閫夋嫨浜у搧
+        </el-button>
+
+        <el-switch
+            v-model="isTable"
+            inline-prompt
+            active-text="琛ㄦ牸"
+            inactive-text="鍒楄〃"
+            @change="handleViewChange"
+        />
+      </div>
+
+      <el-table
+          v-if="isTable"
+          ref="multipleTable"
+          v-loading="tableLoading"
+          border
+          :data="routeItems"
+          :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+          row-key="id"
+          tooltip-effect="dark"
+          class="lims-table"
+          style="cursor: move;"
+      >
+        <el-table-column align="center" label="搴忓彿" width="60">
+          <template #default="scope">
+            {{ scope.$index + 1 }}
+          </template>
+        </el-table-column>
+
+        <el-table-column
+            v-for="(item, index) in tableColumn"
+            :key="index"
+            :label="item.label"
+            :width="item.width"
+            show-overflow-tooltip
+        >
+          <template #default="scope" v-if="item.dataType === 'action'">
+            <el-button
+                v-for="(op, opIndex) in item.operation"
+                :key="opIndex"
+                :type="op.type"
+                :link="op.link"
+                size="small"
+                @click.stop="op.clickFun(scope.row)"
+            >
+              {{ op.name }}
+            </el-button>
+          </template>
+
+          <template #default="scope" v-else>
+            <template v-if="item.prop === 'processId'">
+              <el-select
+                  v-model="scope.row[item.prop]"
+                  style="width: 100%;"
+                  @mousedown.stop
+              >
+                <el-option
+                    v-for="process in processOptions"
+                    :key="process.id"
+                    :label="process.name"
+                    :value="process.id"
+                />
+              </el-select>
+            </template>
+            <template v-else>
+              {{ scope.row[item.prop] || '-' }}
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 浣跨敤鏅�歞iv鏇夸唬el-steps -->
+      <div
+          v-else
+          ref="stepsContainer"
+          class="mb5 custom-steps"
+          style="padding: 10px 0; display: flex; flex-wrap: nowrap; gap: 20px; align-items: flex-start;"
+      >
+        <div
+            v-for="(item, index) in routeItems"
+            :key="item.id"
+            class="custom-step draggable-step"
+            :data-id="item.id"
+            style="cursor: move; flex: 0 0 auto; min-width: 220px;"
+        >
+          <div class="step-content">
+            <div class="step-number">{{ index + 1 }}</div>
+            <el-card
+                :header="item.productName"
+                class="step-card"
+                style="cursor: move;"
+            >
+              <div class="step-card-content">
+                <p>{{ item.model }}</p>
+                <p>{{ item.unit }}</p>
+                <el-select
+                    v-model="item.processId"
+                    style="width: 100%;"
+                    @mousedown.stop
+                >
+                  <el-option
+                      v-for="process in processOptions"
+                      :key="process.id"
+                      :label="process.name"
+                      :value="process.id"
+                  />
+                </el-select>
+              </div>
+              <template #footer>
+                <div class="step-card-footer">
+                  <el-button type="danger" link size="small" @click.stop="removeItemByID(item.id)">鍒犻櫎</el-button>
+                </div>
+              </template>
+            </el-card>
+          </div>
+        </div>
+      </div>
+
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="handleSubmit">纭</el-button>
+          <el-button @click="closeModal">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <ProductSelectDialog
+        v-model="isShowProductSelectDialog"
+        @confirm="handelSelectProducts"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick } from "vue";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+import { findProcessRouteItemList, addOrUpdateProcessRouteItem } from "@/api/productionManagement/processRouteItem.js";
+import { processList } from "@/api/productionManagement/productionProcess.js";
+import Sortable from 'sortablejs';
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+    default: false
+  },
+  record: {
+    type: Object,
+    required: true,
+    default: () => ({})
+  }
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const processOptions = ref([]);
+const tableLoading = ref(false);
+const isShowProductSelectDialog = ref(false);
+const routeItems = ref([]);
+let tableSortable = null;
+let stepsSortable = null;
+const multipleTable = ref(null);
+const stepsContainer = ref(null);
+const isTable = ref(true);
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  }
+});
+
+const tableColumn = ref([
+  { label: "浜у搧鍚嶇О", prop: "productName", width: 180 },
+  { label: "瑙勬牸鍚嶇О", prop: "model", width: 150 },
+  { label: "鍗曚綅", prop: "unit", width: 80 },
+  { label: "宸ュ簭鍚嶇О", prop: "processId", width: 180 },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 100,
+    operation: [
+      {
+        name: "鍒犻櫎",
+        type: "danger",
+        link: true,
+        clickFun: (row) => {
+          const idx = routeItems.value.findIndex(item => item.id === row.id);
+          if (idx > -1) {
+            removeItem(idx)
+          }
+        }
+      }
+    ]
+  }
+]);
+
+const removeItem = (index) => {
+  routeItems.value.splice(index, 1);
+  nextTick(() => initSortable());
+};
+
+const removeItemByID = (id) => {
+  const idx = routeItems.value.findIndex(item => item.id === id);
+  if (idx > -1) {
+    routeItems.value.splice(idx, 1);
+    nextTick(() => initSortable());
+  }
+};
+
+const closeModal = () => {
+  isShow.value = false;
+};
+
+const handelSelectProducts = (products) => {
+  destroySortable();
+
+  const newData = products.map(({ id, ...product }) => ({
+    ...product,
+    productModelId: id,
+    routeId: props.record.id,
+    id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
+    processId: undefined
+  }));
+
+  console.log('閫夋嫨浜у搧鍓嶆暟缁�:', routeItems.value);
+  routeItems.value.push(...newData);
+  routeItems.value = [...routeItems.value];
+  console.log('閫夋嫨浜у搧鍚庢暟缁�:', routeItems.value);
+
+  // 寤惰繜鍒濆鍖栵紝纭繚DOM瀹屽叏娓叉煋
+  nextTick(() => {
+    // 寮哄埗閲嶆柊娓叉煋缁勪欢
+    if (proxy?.$forceUpdate) {
+      proxy.$forceUpdate();
+    }
+
+    const temp = [...routeItems.value];
+    routeItems.value = [];
+    nextTick(() => {
+      routeItems.value = temp;
+      initSortable();
+    });
+  });
+};
+
+const findProcessRouteItems = () => {
+  tableLoading.value = true;
+  findProcessRouteItemList({ routeId: props.record.id })
+      .then(res => {
+        tableLoading.value = false;
+        routeItems.value = res.data.map(item => ({
+          ...item,
+          processId: item.processId === 0 ? undefined : item.processId
+        }));
+        // 寤惰繜鍒濆鍖栵紝纭繚DOM瀹屽叏娓叉煋
+        nextTick(() => {
+          setTimeout(() => initSortable(), 100);
+        });
+      })
+      .catch(err => {
+        tableLoading.value = false;
+        console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
+      });
+};
+
+const findProcessList = () => {
+  processList({})
+      .then(res => {
+        processOptions.value = res.data;
+      })
+      .catch(err => {
+        console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
+      });
+};
+
+const { proxy } = getCurrentInstance() || {};
+
+const handleSubmit = () => {
+  const hasEmptyProcess = routeItems.value.some(item => !item.processId);
+  if (hasEmptyProcess) {
+    proxy?.$modal?.msgError("璇蜂负鎵�鏈夐」鐩�夋嫨宸ュ簭");
+    return;
+  }
+
+  addOrUpdateProcessRouteItem({
+    routeId: props.record.id,
+    processRouteItem: routeItems.value.map(({ id, ...item }) => item)
+  })
+      .then(res => {
+        isShow.value = false;
+        emit('completed');
+        proxy?.$modal?.msgSuccess("鎻愪氦鎴愬姛");
+      })
+      .catch(err => {
+        proxy?.$modal?.msgError(`鎻愪氦澶辫触锛�${err.msg || "缃戠粶寮傚父"}`);
+      });
+};
+
+const destroySortable = () => {
+  if (tableSortable) {
+    tableSortable.destroy();
+    tableSortable = null;
+  }
+  if (stepsSortable) {
+    stepsSortable.destroy();
+    stepsSortable = null;
+  }
+};
+
+const initSortable = () => {
+  destroySortable();
+
+  if (isTable.value) {
+    if (!multipleTable.value) return;
+    const tbody = multipleTable.value.$el.querySelector('.el-table__body tbody') ||
+        multipleTable.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 || !routeItems.value[evt.oldIndex]) return;
+
+        // 浣跨敤鏁扮粍 splice 鏂规硶閲嶆柊鎺掑簭锛屼笌琛ㄦ牸妯″紡淇濇寔涓�鑷�
+        const moveItem = routeItems.value.splice(evt.oldIndex, 1)[0];
+        routeItems.value.splice(evt.newIndex, 0, moveItem);
+        routeItems.value = [...routeItems.value];
+        console.log('鎺掑簭鍚庢暟缁�:', routeItems.value);
+      }
+    });
+  } else {
+    if (!stepsContainer.value) return;
+
+    // 淇敼锛氱洿鎺ヤ娇鐢╯tepsContainer.value浣滀负鎷栨嫿瀹瑰櫒
+    const stepsList = stepsContainer.value;
+    if (!stepsList) {
+      console.warn('鏈壘鍒版楠ゆ潯鎷栨嫿瀹瑰櫒');
+      return;
+    }
+
+    // 淇敼锛氱畝鍖栨嫋鎷介厤缃�
+    stepsSortable = new Sortable(stepsList, {
+      animation: 150,
+      ghostClass: 'sortable-ghost',
+      draggable: '.draggable-step', // 鍙嫋鎷藉厓绱�
+      handle: '.draggable-step, .step-card', // 鎷栨嫿鎵嬫焺
+      filter: '.el-button, .el-select, .el-input', // 杩囨护鎸夐挳/閫夋嫨鍣�
+      forceFallback: true,
+      fallbackClass: 'sortable-fallback',
+      preventOnFilter: true,
+      scroll: true,
+      scrollSensitivity: 30,
+      scrollSpeed: 10,
+      bubbleScroll: true,
+      onEnd: (evt) => {
+        if (evt.oldIndex === evt.newIndex || !routeItems.value[evt.oldIndex]) return;
+
+        // 浣跨敤鏁扮粍 splice 鏂规硶閲嶆柊鎺掑簭
+        const moveItem = routeItems.value.splice(evt.oldIndex, 1)[0];
+        routeItems.value.splice(evt.newIndex, 0, moveItem);
+        routeItems.value = [...routeItems.value];
+      }
+    });
+
+    // 璋冭瘯锛氭墦鍗板鍣ㄥ拰瀹炰緥锛岀‘璁ょ粦瀹氭垚鍔�
+    console.log('姝ラ鏉℃嫋鎷藉鍣�:', stepsList);
+    console.log('Sortable瀹炰緥:', stepsSortable);
+  }
+};
+
+const handleViewChange = () => {
+  destroySortable();
+  // 寤惰繜鍒濆鍖栵紝纭繚瑙嗗浘鍒囨崲鍚嶥OM瀹屽叏娓叉煋
+  nextTick(() => {
+    setTimeout(() => initSortable(), 100);
+  });
+};
+
+onMounted(() => {
+  findProcessRouteItems();
+  findProcessList();
+});
+
+onUnmounted(() => {
+  destroySortable();
+});
+
+defineExpose({
+  closeModal,
+  handleSubmit,
+  isShow
+});
+</script>
+
+<style scoped>
+:deep(.sortable-ghost) {
+  opacity: 0.6;
+  background-color: #f5f7fa !important;
+}
+
+:deep(.el-table__row) {
+  transition: background-color 0.2s;
+}
+
+:deep(.el-table__row:hover) {
+  background-color: #f9fafc !important;
+}
+
+:deep(.el-card__footer){
+  padding: 0 !important;
+}
+
+.operate-button {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+/* 淇敼锛氳嚜瀹氫箟姝ラ鏉″鍣ㄦ牱寮� */
+.custom-steps {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: flex-start;
+  gap: 20px;
+  min-height: 100px;
+}
+
+/* 淇敼锛氳嚜瀹氫箟姝ラ椤规牱寮� */
+.custom-step {
+  cursor: move !important;
+  padding: 8px;
+  position: relative;
+  transition: all 0.2s ease;
+  flex: 0 0 auto;
+  min-width: 220px;
+  touch-action: none;
+}
+
+/* 鎷栨嫿鎮诞鏍峰紡锛屾彁绀哄彲鎷栨嫿 */
+.custom-step:hover {
+  background-color: rgba(64, 158, 255, 0.05);
+  transform: translateY(-2px);
+}
+
+.sortable-ghost {
+  opacity: 0.4;
+  background-color: #f5f7fa !important;
+  border: 2px dashed #409eff;
+  margin: 10px;
+  transform: scale(1.02);
+}
+
+.sortable-fallback {
+  opacity: 0.9;
+  background-color: #f5f7fa;
+  border: 1px solid #409eff;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  transform: rotate(2deg);
+  margin: 10px;
+}
+
+.step-card {
+  cursor: move !important;
+  transition: box-shadow 0.2s ease;
+  user-select: none;
+  -webkit-user-select: none;
+  pointer-events: auto;
+  margin: 10px;
+  height: 240px;
+}
+
+.step-card:hover {
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.step-content {
+  width: 220px;
+  user-select: none;
+}
+
+.step-card-content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.step-card-footer {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  padding: 10px;
+}
+
+/* 鑷畾涔夊簭鍙锋牱寮忎紭鍖� */
+.step-number {
+  font-weight: bold;
+  text-align: center;
+  width: 36px;
+  height: 36px;
+  line-height: 36px;
+  margin: 0 auto 10px;
+  background: #409eff;
+  color: #fff;
+  border-radius: 50%;
+  font-size: 14px;
+}
+</style>
diff --git a/src/views/productionManagement/processRoute/New.vue b/src/views/productionManagement/processRoute/New.vue
new file mode 100644
index 0000000..62c6873
--- /dev/null
+++ b/src/views/productionManagement/processRoute/New.vue
@@ -0,0 +1,194 @@
+<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="productModelId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨浜у搧',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-button type="primary" @click="showProductSelectDialog = true">
+            {{ formState.productName && formState.productModelName 
+              ? `${formState.productName} - ${formState.productModelName}` 
+              : '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item
+            label="BOM"
+            prop="bomId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨BOM',
+                trigger: 'change',
+              }
+            ]"
+        >
+          <el-select
+              v-model="formState.bomId"
+              placeholder="璇烽�夋嫨BOM"
+              clearable
+              :disabled="!formState.productModelId || bomOptions.length === 0"
+              style="width: 100%"
+          >
+            <el-option
+                v-for="item in bomOptions"
+                :key="item.id"
+                :label="item.bomNo || `BOM-${item.id}`"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="澶囨敞" prop="description">
+          <el-input v-model="formState.description" type="textarea" />
+        </el-form-item>
+      </el-form>
+      
+      <!-- 浜у搧閫夋嫨寮圭獥 -->
+      <ProductSelectDialog
+          v-model="showProductSelectDialog"
+          @confirm="handleProductSelect"
+          single
+      />
+      <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/processRoute.js";
+import {getByModel} from "@/api/productionManagement/productBom.js";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
+const formState = ref({
+  productId: undefined,
+  productModelId: undefined,
+  productName: "",
+  productModelName: "",
+  bomId: undefined,
+  description: '',
+});
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+const showProductSelectDialog = ref(false);
+const bomOptions = ref([]);
+
+let { proxy } = getCurrentInstance()
+
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  formState.value = {
+    productId: undefined,
+    productModelId: undefined,
+    productName: "",
+    productModelName: "",
+    bomId: undefined,
+    description: '',
+  };
+  bomOptions.value = [];
+  isShow.value = false;
+};
+
+// 浜у搧閫夋嫨澶勭悊
+const handleProductSelect = async (products) => {
+  if (products && products.length > 0) {
+    const product = products[0];
+    // 鍏堟煡璇OM鍒楄〃锛堝繀閫夛級
+    try {
+      const res = await getByModel(product.id);
+      // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
+      let bomList = [];
+      if (Array.isArray(res)) {
+        bomList = res;
+      } else if (res && res.data) {
+        bomList = Array.isArray(res.data) ? res.data : [res.data];
+      } else if (res && typeof res === 'object') {
+        bomList = [res];
+      }
+      
+      if (bomList.length > 0) {
+        formState.value.productModelId = product.id;
+        formState.value.productName = product.productName;
+        formState.value.productModelName = product.model;
+        formState.value.bomId = undefined; // 閲嶇疆BOM閫夋嫨
+        bomOptions.value = bomList;
+        showProductSelectDialog.value = false;
+        // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+        proxy.$refs["formRef"]?.validateField('productModelId');
+      } else {
+        proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+      }
+    } catch (error) {
+      // 濡傛灉鎺ュ彛杩斿洖404鎴栧叾浠栭敊璇紝璇存槑娌℃湁BOM
+      proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
+    }
+  }
+};
+
+const handleSubmit = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰BOM
+      if (!formState.value.productModelId) {
+        proxy.$modal.msgError("璇烽�夋嫨浜у搧");
+        return;
+      }
+      if (!formState.value.bomId) {
+        proxy.$modal.msgError("璇烽�夋嫨BOM");
+        return;
+      }
+      add(formState.value).then(res => {
+        // 鍏抽棴妯℃�佹
+        isShow.value = false;
+        // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
+        emit('completed');
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      })
+    }
+  })
+};
+
+
+defineExpose({
+  closeModal,
+  handleSubmit,
+  isShow,
+});
+</script>
diff --git a/src/views/productionManagement/processRoute/index.vue b/src/views/productionManagement/processRoute/index.vue
new file mode 100644
index 0000000..41103f9
--- /dev/null
+++ b/src/views/productionManagement/processRoute/index.vue
@@ -0,0 +1,204 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <el-form :model="searchForm" :inline="true">
+        <el-form-item label="瑙勬牸鍚嶇О:">
+          <el-input v-model="searchForm.model" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+                    style="width: 200px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+        </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="danger" @click="handleDelete" :disabled="selectedRows.length === 0" plain>鍒犻櫎宸ヨ壓璺嚎</el-button>
+      </div>
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :page="page"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          :tableLoading="tableLoading"
+          @pagination="pagination"
+          :total="page.total"
+      />
+    </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"
+    />
+
+    <route-item-form
+        v-if="isShowItemModal"
+        v-model:visible="isShowItemModal"
+        :record="record"
+        @completed="getList"
+    />
+  </div>
+</template>
+
+<script setup>
+import {onMounted, ref} from "vue";
+import NewProcess from "@/views/productionManagement/processRoute/New.vue";
+import EditProcess from "@/views/productionManagement/processRoute/Edit.vue";
+import RouteItemForm from "@/views/productionManagement/processRoute/ItemsForm.vue";
+import {listPage, del} from "@/api/productionManagement/processRoute.js";
+import { useRouter } from 'vue-router'
+
+const router = useRouter()
+const data = reactive({
+  searchForm: {
+    model: "",
+  },
+});
+const { searchForm } = toRefs(data);
+const tableColumn = ref([
+  {
+    label: "宸ヨ壓璺嚎缂栧彿",
+    prop: "processRouteCode",
+  },
+  {
+    label: "浜у搧鍚嶇О",
+    prop: "productName",
+  },
+  {
+    label: "瑙勬牸鍚嶇О",
+    prop: "model",
+  },
+  {
+    label: "BOM缂栧彿",
+    prop: "bomNo",
+  },
+  {
+    label: "鎻忚堪",
+    prop: "description",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 280,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          showEditModal(row);
+        }
+      },
+      {
+        name: "璺嚎椤圭洰",
+        type: "text",
+        clickFun: (row) => {
+          showItemModal(row);
+        }
+      }
+    ]
+  }
+]);
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const isShowNewModal = ref(false);
+const isShowEditModal = ref(false);
+const isShowItemModal = ref(false);
+const record = ref({});
+const page = reactive({
+  current: 1,
+  size: 100,
+  total: 0,
+});
+const { proxy } = getCurrentInstance()
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+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).then(res => {
+    tableLoading.value = false;
+    tableData.value = res.data.records.map(item => ({
+      ...item,
+    }));
+    page.total = res.data.total;
+  }).catch(err => {
+    tableLoading.value = false;
+  })
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鎵撳紑鏂板寮规
+const showNewModal = () => {
+  isShowNewModal.value = true
+};
+
+const showEditModal = (row) => {
+  isShowEditModal.value = true
+  record.value = row
+};
+
+const showItemModal = (row) => {
+  router.push({
+    path: '/productionManagement/processRouteItem',
+    query: {
+      id: row.id,
+      processRouteCode: row.processRouteCode || '',
+      productName: row.productName || '',
+      model: row.model || '',
+      bomNo: row.bomNo || '',
+      description: row.description || '',
+      type: 'route',
+    }
+  })
+};
+
+// 鍒犻櫎
+function handleDelete() {
+  const ids = selectedRows.value.map((item) => item.id);
+  proxy.$modal
+      .confirm('鏄惁纭鍒犻櫎宸插嬀閫夌殑鏁版嵁椤癸紵')
+      .then(function () {
+        return del(ids);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      })
+      .catch(() => {});
+}
+
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style scoped></style>
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
new file mode 100644
index 0000000..18e21e8
--- /dev/null
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -0,0 +1,876 @@
+<template>
+  <div class="app-container">
+    <PageHeader content="宸ヨ壓璺嚎椤圭洰" />
+    
+    <!-- 宸ヨ壓璺嚎淇℃伅灞曠ず -->
+    <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">
+            <span class="info-label">宸ヨ壓璺嚎缂栧彿</span>
+          </div>
+          <div class="info-value-wrapper">
+            <span class="info-value">{{ routeInfo.processRouteCode }}</span>
+          </div>
+        </div>
+        <div class="info-item">
+          <div class="info-label-wrapper">
+            <span class="info-label">浜у搧鍚嶇О</span>
+          </div>
+          <div class="info-value-wrapper">
+            <span class="info-value">{{ routeInfo.productName || '-' }}</span>
+          </div>
+        </div>
+        <div class="info-item">
+          <div class="info-label-wrapper">
+            <span class="info-label">瑙勬牸鍚嶇О</span>
+          </div>
+          <div class="info-value-wrapper">
+            <span class="info-value">{{ routeInfo.model || '-' }}</span>
+          </div>
+        </div>
+        <div class="info-item">
+          <div class="info-label-wrapper">
+            <span class="info-label">BOM缂栧彿</span>
+          </div>
+          <div class="info-value-wrapper">
+            <span class="info-value">{{ routeInfo.bomNo || '-' }}</span>
+          </div>
+        </div>
+        <div class="info-item full-width" v-if="routeInfo.description">
+          <div class="info-label-wrapper">
+            <span class="info-label">鎻忚堪</span>
+          </div>
+          <div class="info-value-wrapper">
+            <span class="info-value">{{ routeInfo.description }}</span>
+          </div>
+        </div>
+      </div>
+    </el-card>
+    
+    <!-- 琛ㄦ牸瑙嗗浘 -->
+    <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>
+        <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">
+        <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="鎿嶄綔" align="center" fixed="right" width="150">
+        <template #default="scope">
+          <el-button type="primary" link size="small" @click="handleEdit(scope.row)">缂栬緫</el-button>
+          <el-button type="danger" link size="small" @click="handleDelete(scope.row)">鍒犻櫎</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>
+          <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>
+            </div>
+            <div v-else class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
+          </div>
+          
+          <!-- 鎿嶄綔鎸夐挳 -->
+          <div class="card-footer">
+            <el-button type="primary" link size="small" @click="handleEdit(item)">缂栬緫</el-button>
+            <el-button type="danger" link size="small" @click="handleDelete(item)">鍒犻櫎</el-button>
+          </div>
+        </div>
+      </div>
+      </div>
+    </template>
+
+    <!-- 鏂板/缂栬緫寮圭獥 -->
+    <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">
+            {{ 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>
+      </el-form>
+
+      <template #footer>
+        <el-button @click="closeDialog">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
+    <ProductSelectDialog
+        v-model="showProductSelectDialog"
+        @confirm="handleProductSelect"
+        single
+    />
+  </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'
+
+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 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 form = ref({
+  id: undefined,
+  routeId: routeId.value,
+  processId: undefined,
+  productModelId: undefined,
+  productName: "",
+  model: "",
+  unit: "",
+});
+
+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 || "",
+  };
+  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,
+              dragSort,
+            })
+          : addOrUpdateProcessRouteItem({
+              routeId: routeId.value,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+              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,
+            })
+          : addOrUpdateProcessRouteItem({
+              routeId: routeId.value,
+              processId: form.value.processId,
+              productModelId: form.value.productModelId,
+              id: form.value.id,
+            });
+
+        updatePromise
+          .then(() => {
+            proxy?.$modal?.msgSuccess('淇敼鎴愬姛');
+            closeDialog();
+            getList();
+          })
+          .catch(() => {
+            proxy?.$modal?.msgError('淇敼澶辫触');
+          })
+          .finally(() => {
+            submitLoading.value = false;
+          });
+      }
+    }
+  });
+};
+
+// 閲嶇疆琛ㄥ崟
+const resetForm = () => {
+  form.value = {
+    id: undefined,
+    routeId: routeId.value,
+    processId: undefined,
+    productModelId: undefined,
+    productName: "",
+    model: "",
+    unit: "",
+  };
+  formRef.value?.resetFields();
+};
+
+// 鍏抽棴寮圭獥
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+
+// 鍒濆鍖栨嫋鎷芥帓搴�
+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;
+}
+
+.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-track {
+  background: #f1f1f1;
+  border-radius: 4px;
+}
+
+.cards-wrapper::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 4px;
+}
+
+.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:hover {
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  transform: translateY(-2px);
+}
+
+.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-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;
+}
+
+.product-info {
+  font-size: 13px;
+  color: #666;
+  text-align: center;
+  width: 100%;
+}
+
+.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-model {
+  color: #909399;
+  font-size: 12px;
+  word-break: break-all;
+  line-height: 1.5;
+  text-align: center;
+}
+
+.product-unit {
+  margin-left: 4px;
+  color: #409eff;
+}
+
+.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;
+}
+
+:deep(.sortable-ghost) {
+  opacity: 0.5;
+  background-color: #f5f7fa !important;
+}
+
+:deep(.sortable-drag) {
+  opacity: 0.8;
+}
+
+/* 琛ㄦ牸瑙嗗浘鏍峰紡 */
+:deep(.el-table__row) {
+  transition: background-color 0.2s;
+  cursor: move;
+}
+
+:deep(.el-table__row:hover) {
+  background-color: #f9fafc !important;
+}
+
+/* 鍖哄煙鏍囬鏍峰紡 */
+.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::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;
+}
+
+/* 宸ヨ壓璺嚎淇℃伅鍗$墖鏍峰紡 */
+.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;
+}
+
+.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.full-width {
+  grid-column: 1 / -1;
+}
+
+.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::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 {
+  display: block;
+  color: #303133;
+  font-size: 15px;
+  font-weight: 500;
+  line-height: 1.5;
+  word-break: break-all;
+}
+</style>
diff --git a/src/views/productionManagement/productStructure/Detail/index.vue b/src/views/productionManagement/productStructure/Detail/index.vue
new file mode 100644
index 0000000..20a472b
--- /dev/null
+++ b/src/views/productionManagement/productStructure/Detail/index.vue
@@ -0,0 +1,300 @@
+<template>
+  <div class="app-container">
+    <PageHeader content="浜у搧缁撴瀯璇︽儏">
+      <template #right-button>
+        <el-button v-if="dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="addItem">娣诲姞
+        </el-button>
+        <el-button v-if="!dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="dataValue.isEdit = true">缂栬緫
+        </el-button>
+        <el-button v-if="dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="cancelEdit">鍙栨秷
+        </el-button>
+        <el-button v-if="!isOrderPage"
+                   type="primary"
+                   :loading="dataValue.loading"
+                   @click="submit"
+                   :disabled="!dataValue.isEdit">纭
+        </el-button>
+      </template>
+    </PageHeader>
+    <el-table
+        :data="tableData"
+        border
+        :preserve-expanded-content="false"
+        :default-expand-all="true"
+        style="width: 100%"
+    >
+      <el-table-column type="expand">
+        <template #default="props">
+          <el-form ref="form"
+                   :model="dataValue">
+            <el-table :data="dataValue.dataList"
+                      style="width: 100%">
+              <el-table-column prop="productName"
+                               label="浜у搧"/>
+              <el-table-column prop="model"
+                               label="瑙勬牸">
+                <template #default="{ row, $index }">
+                  <el-form-item v-if="dataValue.isEdit"
+                                :prop="`dataList.${$index}.model`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-select v-model="row.model"
+                               placeholder="璇烽�夋嫨瑙勬牸"
+                               clearable
+                               :disabled="!dataValue.isEdit"
+                               style="width: 100%"
+                               @visible-change="(v) => { if (v) openDialog($index) }">
+                      <el-option v-if="row.model"
+                                 :label="row.model"
+                                 :value="row.model" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="processId"
+                               label="娑堣�楀伐搴�">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.processId`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+                                style="margin: 0">
+                    <el-select v-model="row.processId"
+                               placeholder="璇烽�夋嫨"
+                               filterable
+                               clearable
+                               style="width: 100%"
+                               :disabled="!dataValue.isEdit">
+                      <el-option v-for="item in dataValue.processOptions"
+                                 :key="item.id"
+                                 :label="item.name"
+                                 :value="item.id" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unitQuantity"
+                               label="鍗曚綅浜у嚭鎵�闇�鏁伴噺">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unitQuantity`"
+                                :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="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column v-if="isOrderPage"
+                               prop="demandedQuantity"
+                               label="闇�姹傛�婚噺">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.demandedQuantity`"
+                                :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="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unit"
+                               label="鍗曚綅">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unit`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input v-model="row.unit"
+                              placeholder="璇疯緭鍏ュ崟浣�"
+                              clearable
+                              :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="鎿嶄綔" fixed="right" width="100">
+                <template #default="{ row, $index }">
+                  <el-button v-if="dataValue.isEdit"
+                             type="danger"
+                             text
+                             @click="dataValue.dataList.splice($index, 1)">鍒犻櫎
+                  </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>
+
+    <product-select-dialog v-if="dataValue.showProductDialog"
+                           v-model:model-value="dataValue.showProductDialog"
+                           @confirm="handleProduct" />
+  </div>
+</template>
+
+<script setup lang="ts">
+import {
+  computed,
+  defineAsyncComponent,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref,
+} from "vue";
+import { queryList, add } from "@/api/productionManagement/productStructure.js";
+import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
+import { list } from "@/api/productionManagement/productionProcess";
+import { ElMessage } from "element-plus";
+import {useRoute, useRouter} from "vue-router";
+
+defineComponent({
+  name: "StructureEdit",
+});
+
+const ProductSelectDialog = defineAsyncComponent(
+    () => import("@/views/basicData/product/ProductSelectDialog.vue")
+);
+const form = ref();
+
+const route = useRoute()
+const router = useRouter()
+const routeId = computed({
+  get() {
+    return route.query.id;
+  },
+
+  set(val) {
+    emit('update:router', val)
+  }
+});
+
+// 浠庤矾鐢卞弬鏁拌幏鍙栦骇鍝佷俊鎭�
+const routeBomNo = computed(() => route.query.bomNo || '');
+const routeProductName = computed(() => route.query.productName || '');
+const routeProductModelName = computed(() => route.query.productModelName || '');
+const routeOrderId = computed(() => route.query.orderId);
+const pageType = computed(() => route.query.type);
+const isOrderPage = computed(() => pageType.value === 'order' && routeOrderId.value);
+
+const dataValue = reactive({
+  dataList: [],
+  productOptions: [],
+  processOptions: [],
+  showProductDialog: false,
+  currentRowIndex: null,
+  loading: false,
+  isEdit: false,
+});
+
+const tableData = reactive([
+  {
+    productName: "",
+    model: "",
+    bomNo: "",
+  }
+])
+
+const openDialog = index => {
+  dataValue.currentRowIndex = index;
+  dataValue.showProductDialog = true;
+};
+
+const fetchData = async () => {
+  if (isOrderPage.value) {
+    // 璁㈠崟鎯呭喌锛氫娇鐢ㄨ鍗曠殑浜у搧缁撴瀯鎺ュ彛
+    const { data } = await listProcessBom({ orderId: routeOrderId.value });
+    dataValue.dataList = data || [];
+  } else {
+    // 闈炶鍗曟儏鍐碉細浣跨敤鍘熸潵鐨勬帴鍙�
+    const { data } = await queryList(routeId.value);
+    dataValue.dataList = data || [];
+  }
+};
+
+const fetchProcessOptions = async () => {
+  const { data } = await list(routeId.value);
+  dataValue.processOptions = data;
+};
+
+const handleProduct = row => {
+  if (row?.length > 1) {
+    ElMessage.error("鍙兘閫夋嫨涓�涓骇鍝�");
+  }
+  dataValue.dataList[dataValue.currentRowIndex].productName =
+      row[0].productName;
+  dataValue.dataList[dataValue.currentRowIndex].model = row[0].model;
+  dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id;
+  dataValue.dataList[dataValue.currentRowIndex].unit = row[0].unit || "";
+  dataValue.showProductDialog = false;
+};
+
+const submit = () => {
+  form.value
+      .validate(valid => {
+        dataValue.loading = true;
+        if (valid) {
+          add({
+            bomId: routeId.value,
+            productStructureList: dataValue.dataList || [],
+          }).then(res => {
+            router.push({
+              path: '/productionManagement/productionManagement/productStructure/index',
+            })
+            ElMessage.success("淇濆瓨鎴愬姛");
+            dataValue.loading = false;
+          });
+        }
+      })
+      .finally(() => {
+        dataValue.loading = false;
+      });
+};
+
+const addItem = () => {
+  dataValue.dataList.push({
+    productName: "",
+    productId: "",
+    model: undefined,
+    productModelId: undefined,
+    processId: "",
+    unitQuantity: 0,
+    demandedQuantity: 0,
+    unit: "",
+  });
+};
+
+const cancelEdit = () => {
+  dataValue.isEdit = false;
+  dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined);
+};
+
+onMounted(() => {
+  // 浠庤矾鐢卞弬鏁板洖鏄炬暟鎹�
+  tableData[0].productName = routeProductName.value;
+  tableData[0].model = routeProductModelName.value;
+  tableData[0].bomNo = routeBomNo.value;
+  
+  // 璁㈠崟鎯呭喌涓嬬鐢ㄧ紪杈�
+  if (isOrderPage.value) {
+    dataValue.isEdit = false;
+  }
+  
+  fetchData();
+  fetchProcessOptions();
+});
+</script>
\ No newline at end of file
diff --git a/src/views/productionManagement/productStructure/StructureEdit.vue b/src/views/productionManagement/productStructure/StructureEdit.vue
new file mode 100644
index 0000000..4d07f5d
--- /dev/null
+++ b/src/views/productionManagement/productStructure/StructureEdit.vue
@@ -0,0 +1,311 @@
+<template>
+  <el-dialog v-model="visible"
+             title="缁撴瀯"
+             width="1200"
+             close-on-click-modal
+             @close="visible = false">
+    <el-button v-if="dataValue.isEdit"
+               type="primary"
+               @click="addItem"
+               style="margin-bottom: 10px">娣诲姞
+    </el-button>
+    <el-button v-if="!dataValue.isEdit"
+               type="primary"
+               @click="dataValue.isEdit = true"
+               style="margin-bottom: 10px">缂栬緫
+    </el-button>
+    <el-button v-if="dataValue.isEdit"
+               type="primary"
+               @click="cancelEdit"
+               style="margin-bottom: 10px">鍙栨秷
+    </el-button>
+
+    <el-table
+        :data="tableData"
+        border
+        :preserve-expanded-content="false"
+        style="width: 100%"
+    >
+      <el-table-column type="expand">
+        <template #default="props">
+          <el-form ref="form"
+                   :model="dataValue">
+            <el-table :data="dataValue.dataList"
+                      style="width: 100%">
+              <el-table-column prop="productName"
+                               label="浜у搧"
+                               width="150" />
+              <el-table-column prop="model"
+                               label="瑙勬牸"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item v-if="dataValue.isEdit"
+                                :prop="`dataList.${$index}.model`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-select v-model="row.model"
+                               placeholder="璇烽�夋嫨浜у搧"
+                               clearable
+                               :disabled="!dataValue.isEdit"
+                               style="width: 100%"
+                               @visible-change="(v) => { if (v) openDialog($index) }">
+                      <el-option v-if="row.model"
+                                 :label="row.model"
+                                 :value="row.model" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="processId"
+                               label="娑堣�楀伐搴�"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.processId`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+                                style="margin: 0">
+                    <el-select v-model="row.processId"
+                               placeholder="璇烽�夋嫨"
+                               filterable
+                               clearable
+                               style="width: 100%"
+                               :disabled="!dataValue.isEdit">
+                      <el-option v-for="item in dataValue.processOptions"
+                                 :key="item.id"
+                                 :label="item.name"
+                                 :value="item.id" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unitQuantity"
+                               label="鍗曚綅浜у嚭鎵�闇�鏁伴噺"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unitQuantity`"
+                                :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="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="demandedQuantity"
+                               label="闇�姹傛�婚噺"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.demandedQuantity`"
+                                :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="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unit"
+                               label="鍗曚綅"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unit`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input v-model="row.unit"
+                              placeholder="璇疯緭鍏ュ崟浣�"
+                              clearable
+                              :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="diskQuantity"
+                               label="鐩樻暟锛堢洏锛�"
+                               width="150">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.diskQuantity`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ョ洏鏁�', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input-number v-model="row.diskQuantity"
+                                     :min="0"
+                                     :precision="0"
+                                     :step="1"
+                                     controls-position="right"
+                                     style="width: 100%"
+                                     :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="鎿嶄綔">
+                <template #default="{ row, $index }">
+                  <el-button type="danger"
+                             text
+                             @click="dataValue.dataList.splice($index, 1)">鍒犻櫎
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form>
+        </template>
+      </el-table-column>
+      <el-table-column label="浜у搧缂栫爜" prop="productCode" />
+      <el-table-column label="浜у搧鍚嶇О" prop="productName" />
+      <el-table-column label="瑙勬牸鍨嬪彿" prop="model" />
+      <el-table-column label="鍗曚綅" prop="unit" />
+    </el-table>
+
+    <product-select-dialog v-if="dataValue.showProductDialog"
+                           v-model:model-value="dataValue.showProductDialog"
+                           @confirm="handleProduct" />
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary"
+                   :loading="dataValue.loading"
+                   @click="submit"
+                   :disabled="!dataValue.isEdit">
+          纭
+        </el-button>
+        <el-button @click="visible = false">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+  import {
+    computed,
+    defineAsyncComponent,
+    defineComponent,
+    onMounted,
+    reactive,
+    ref,
+  } from "vue";
+  import { queryList, add } from "@/api/productionManagement/productStructure.js";
+  import { list } from "@/api/productionManagement/productionProcess";
+  import { ElMessage } from "element-plus";
+
+  defineComponent({
+    name: "StructureEdit",
+  });
+
+  const ProductSelectDialog = defineAsyncComponent(
+    () => import("@/views/basicData/product/ProductSelectDialog.vue")
+  );
+  const form = ref();
+
+  const props = defineProps({
+    showModel: {
+      type: Boolean,
+      default: false,
+    },
+    record: {
+      type: Object,
+      required: true,
+    },
+  });
+
+  const emits = defineEmits(["update:showModel"]);
+  const visible = computed({
+    get() {
+      return props.showModel;
+    },
+    set(val) {
+      emits("update:showModel", val);
+    },
+  });
+
+  const dataValue = reactive({
+    dataList: [],
+    productOptions: [],
+    processOptions: [],
+    showProductDialog: false,
+    currentRowIndex: null,
+    loading: false,
+    isEdit: false,
+  });
+
+  const tableData = [
+    {
+      productName: props.record.productName,
+      model: props.record.model,
+      unit: props.record.unit,
+      productCode: props.record.productCode,
+    }
+  ]
+
+  const openDialog = index => {
+    dataValue.currentRowIndex = index;
+    dataValue.showProductDialog = true;
+  };
+
+  const fetchData = async () => {
+    const { data } = await queryList(props.record.id);
+    dataValue.dataList = data;
+  };
+
+  const fetchProcessOptions = async () => {
+    const { data } = await list(props.record.id);
+    dataValue.processOptions = data;
+  };
+
+  const handleProduct = row => {
+    if (row?.length > 1) {
+      ElMessage.error("鍙兘閫夋嫨涓�涓骇鍝�");
+    }
+    dataValue.dataList[dataValue.currentRowIndex].productName =
+      row[0].productName;
+    dataValue.dataList[dataValue.currentRowIndex].model = row[0].model;
+    dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id;
+    dataValue.showProductDialog = false;
+  };
+
+  const submit = () => {
+    form.value
+      .validate(valid => {
+        dataValue.loading = true;
+        if (valid) {
+          add({
+            parentId: props.record.id,
+            productStructureList: dataValue.dataList || [],
+          }).then(res => {
+            ElMessage.success("淇濆瓨鎴愬姛");
+            visible.value = false;
+            dataValue.loading = false;
+          });
+        }
+      })
+      .finally(() => {
+        dataValue.loading = false;
+      });
+  };
+
+  const addItem = () => {
+    dataValue.dataList.push({
+      productName: "",
+      productId: "",
+      model: undefined,
+      productModelId: undefined,
+      processId: "",
+      unitQuantity: 0,
+      demandedQuantity: 0,
+      unit: "",
+      diskQuantity: 0,
+    });
+  };
+
+  const cancelEdit = () => {
+    dataValue.isEdit = false;
+    dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined);
+  };
+
+  onMounted(() => {
+    fetchData();
+    fetchProcessOptions();
+  });
+</script>
\ No newline at end of file
diff --git a/src/views/productionManagement/productStructure/index.vue b/src/views/productionManagement/productStructure/index.vue
new file mode 100644
index 0000000..d8ce689
--- /dev/null
+++ b/src/views/productionManagement/productStructure/index.vue
@@ -0,0 +1,340 @@
+<template>
+  <div class="app-container">
+    <div style="text-align: right; margin-bottom: 10px;">
+      <el-button type="primary" @click="handleAdd">鏂板</el-button>
+      <el-button type="danger" plain @click="handleBatchDelete" :disabled="selectedRows.length === 0">鍒犻櫎</el-button>
+    </div>
+    <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+    >
+      <template #detail="{row}">
+        <el-button
+            type="primary"
+            text
+            @click="showDetail(row)">{{ row.bomNo }}
+        </el-button>
+      </template>
+    </PIMTable>
+    <StructureEdit v-if="showEdit" v-model:show-model="showEdit" :record="currentRow"/>
+    
+    <!-- 鏂板/缂栬緫寮圭獥 -->
+    <el-dialog
+        v-model="dialogVisible"
+        :title="operationType === 'add' ? '鏂板BOM' : '缂栬緫BOM'"
+        width="600px"
+        @close="closeDialog"
+    >
+      <el-form
+          ref="formRef"
+          :model="form"
+          :rules="rules"
+          label-width="120px"
+      >
+        <el-form-item label="浜у搧鍚嶇О" prop="productModelId">
+          <el-button type="primary" @click="showProductSelectDialog = true">
+            {{ form.productName || '閫夋嫨浜у搧' }}
+          </el-button>
+        </el-form-item>
+        <el-form-item label="鐗堟湰鍙�" prop="version">
+          <el-input v-model="form.version" placeholder="璇疯緭鍏ョ増鏈彿" clearable />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input
+              v-model="form.remark"
+              type="textarea"
+              :rows="3"
+              placeholder="璇疯緭鍏ュ娉�"
+              clearable
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="closeDialog">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
+      </template>
+    </el-dialog>
+    
+    <!-- 浜у搧閫夋嫨寮圭獥 -->
+    <ProductSelectDialog
+        v-model="showProductSelectDialog"
+        @confirm="handleProductSelect"
+        single
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, onMounted, getCurrentInstance, defineAsyncComponent } from "vue";
+import { listPage, add, update, batchDelete } from "@/api/productionManagement/productBom.js";
+import { useRouter } from 'vue-router'
+import { ElMessageBox } from 'element-plus'
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+
+const router = useRouter()
+const { proxy } = getCurrentInstance()
+const StructureEdit = defineAsyncComponent(() => import('@/views/productionManagement/productStructure/StructureEdit.vue'))
+
+const tableColumn = ref([
+  {
+    label: "BOM缂栧彿",
+    prop: "bomNo",
+    dataType: 'slot',
+    slot: "detail",
+    minWidth: 140
+  },
+  {
+    label: "浜у搧鍚嶇О",
+    prop: "productName",
+    
+    minWidth: 160
+  },
+  {
+    label: "瑙勬牸鍨嬪彿",
+    prop: "productModelName",
+    minWidth: 140
+  },
+  {
+    label: "鐗堟湰鍙�",
+    prop: "version",
+    width: 100
+  },
+  {
+    label: "澶囨敞",
+    prop: "remark",
+    minWidth: 160
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 150,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          handleEdit(row)
+        }
+      },
+      {
+        name: "鍒犻櫎",
+        type: "danger",
+        link: true,
+        clickFun: (row) => {
+          handleDelete(row)
+        }
+      }
+    ]
+  }
+]);
+
+const tableData = ref([]);
+const tableLoading = ref(false);
+const showEdit = ref(false);
+const selectedRows = ref([]);
+const currentRow = ref({});
+const dialogVisible = ref(false);
+const operationType = ref('add'); // add | edit
+const formRef = ref(null);
+const showProductSelectDialog = ref(false);
+
+const page = reactive({
+  current: 1,
+  size: 10,
+  total: 0,
+});
+
+const data = reactive({
+  form: {
+    id: undefined,
+    productName: "",
+    productModelName: "",
+    productModelId: "",
+    remark: "",
+    version: ""
+  },
+  rules: {
+    productModelId: [{ required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" }],
+    version: [{ required: true, message: "璇疯緭鍏ョ増鏈彿", trigger: "blur" }]
+  }
+});
+
+const { form, rules } = toRefs(data);
+
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鍒嗛〉
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+
+// 鏌ヨ鍒楄〃
+const getList = () => {
+  tableLoading.value = true;
+  listPage({
+    current: page.current,
+    size: page.size,
+  })
+    .then((res) => {
+      const records = res?.data?.records || [];
+      tableData.value = records;
+      page.total = res?.data?.total || 0;
+    })
+    .catch((err) => {
+      console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
+    })
+    .finally(() => {
+      tableLoading.value = false;
+    });
+};
+
+// 鏂板
+const handleAdd = () => {
+  operationType.value = 'add';
+  Object.assign(form.value, {
+    id: undefined,
+    productName: "",
+    productModelName: "",
+    productModelId: "",
+    remark: "",
+    version: ""
+  });
+  dialogVisible.value = true;
+};
+
+// 缂栬緫
+const handleEdit = (row) => {
+  operationType.value = 'edit';
+  Object.assign(form.value, {
+    id: row.id,
+    productName: row.productName || "",
+    productModelName: row.productModelName || "",
+    productModelId: row.productModelId || "",
+    remark: row.remark || "",
+    version: row.version || ""
+  });
+  dialogVisible.value = true;
+};
+
+// 鍒犻櫎锛堝崟鏉★級
+const handleDelete = (row) => {
+  ElMessageBox.confirm('纭鍒犻櫎璇OM锛�', '鎻愮ず', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(() => {
+      batchDelete([row.id])
+        .then(() => {
+          proxy.$modal.msgSuccess('鍒犻櫎鎴愬姛');
+          getList();
+        })
+        .catch(() => {
+          proxy.$modal.msgError('鍒犻櫎澶辫触');
+        });
+    })
+    .catch(() => {});
+};
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (!selectedRows.value.length) {
+    proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁');
+    return;
+  }
+  const ids = selectedRows.value.map(item => item.id);
+  ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(() => {
+      batchDelete(ids)
+        .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.productModelName = product.model;
+  }
+  showProductSelectDialog.value = false;
+};
+
+// 鎻愪氦琛ㄥ崟
+const handleSubmit = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const payload = { ...form.value };
+      if (operationType.value === 'add') {
+        add(payload)
+          .then(() => {
+            proxy.$modal.msgSuccess('鏂板鎴愬姛');
+            closeDialog();
+            getList();
+          })
+          .catch(() => {
+            proxy.$modal.msgError('鏂板澶辫触');
+          });
+      } else {
+        update(payload)
+          .then(() => {
+            proxy.$modal.msgSuccess('淇敼鎴愬姛');
+            closeDialog();
+            getList();
+          })
+          .catch(() => {
+            proxy.$modal.msgError('淇敼澶辫触');
+          });
+      }
+    }
+  });
+};
+
+// 鍏抽棴寮圭獥
+const closeDialog = () => {
+  dialogVisible.value = false;
+  formRef.value?.resetFields();
+};
+
+// 鏌ョ湅璇︽儏
+const showDetail = (row) => {
+  router.push({
+    path: '/productionManagement/productStructureDetail',
+    query: {
+      id: row.id,
+      bomNo: row.bomNo || '',
+      productName: row.productName || '',
+      productModelName: row.productModelName || ''
+    }
+  });
+};
+
+onMounted(() => {
+  getList();
+});
+</script>
diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index 76e7414..229bf04 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -14,6 +14,15 @@
 					clearable
 					prefix-icon="Search"
 				/>
+				<span class="search_title ml10">鍚堝悓鍙凤細</span>
+				<el-input
+					v-model="searchForm.salesContractNo"
+					style="width: 240px"
+					placeholder="璇疯緭鍏�"
+					@change="handleQuery"
+					clearable
+					prefix-icon="Search"
+				/>
 				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
 				>鎼滅储</el-button
 				>
@@ -61,21 +70,21 @@
 		prop: "salesContractNo",
 		width: 220,
 	},
-	{
-		label: "瀹㈡埛鍚堝悓鍙�",
-		prop: "customerContractNo",
-		width: 250,
-	},
+	// {
+	// 	label: "瀹㈡埛鍚堝悓鍙�",
+	// 	prop: "customerContractNo",
+	// 	width: 250,
+	// },
 	{
 		label: "瀹㈡埛鍚嶇О",
 		prop: "customerName",
 		width: 250,
 	},
-	{
-		label: "椤圭洰鍚嶇О",
-		prop: "projectName",
-		width:300
-	},
+	// {
+	// 	label: "椤圭洰鍚嶇О",
+	// 	prop: "projectName",
+	// 	width:300
+	// },
 	{
 		label: "浜у搧澶х被",
 		prop: "productCategory",
@@ -121,6 +130,7 @@
 const data = reactive({
 	searchForm: {
 		schedulingUserName: "",
+		salesContractNo: "",
 		entryDate: [
 			dayjs().format("YYYY-MM-DD"),
 			dayjs().add(1, "day").format("YYYY-MM-DD"),
@@ -171,7 +181,7 @@
 		type: "warning",
 	})
 		.then(() => {
-			proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
+			proxy.download("/salesLedger/productionAccounting/export", {}, "鐢熶骇鏍哥畻.xlsx");
 		})
 		.catch(() => {
 			proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue b/src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue
new file mode 100644
index 0000000..b4a76f6
--- /dev/null
+++ b/src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue
@@ -0,0 +1,153 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="鑷姩娲惧伐"
+        width="80%"
+        @close="closeDia"
+    >
+      <el-form :model="form" label-width="140px" label-position="top" ref="formRef">
+        <el-divider content-position="left">娲惧伐鍒楄〃</el-divider>
+        
+        <el-table
+            :data="dispatchList"
+            border
+            style="width: 100%; margin-top: 20px;"
+            :row-class-name="tableRowClassName"
+        >
+          <el-table-column label="搴忓彿" type="index" width="60" align="center" />
+          <el-table-column label="鍚堝悓鍙�" prop="salesContractNo" width="200" />
+          <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="200" />
+          <!-- <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="250" /> -->
+          <el-table-column label="浜у搧澶х被" prop="productCategory" width="150" />
+          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" />
+          <el-table-column label="缁戝畾鏈哄櫒" prop="speculativeTradingName" width="120" />
+          <el-table-column label="鎬绘暟閲�" prop="quantity" width="100" align="right" />
+          <el-table-column label="宸叉帓浜�" prop="schedulingNum" width="100" align="right" fixed="right" />
+          <el-table-column label="寰呮帓浜�" prop="pendingQuantity" width="100" align="right" fixed="right" />
+          <el-table-column label="鏈鎺掍骇" width="150" align="center" fixed="right">
+            <template #default="{ row }">
+              <el-input-number
+                  v-model="row.schedulingNum"
+                  :min="0"
+                  :max="row.pendingQuantity"
+                  :step="1"
+                  :precision="0"
+                  size="small"
+                  style="width: 120px"
+                  @change="(value) => changeCurrentNum(value, row)"
+              />
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form>
+      
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭娲惧伐</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref, reactive, toRefs, computed} from "vue";
+import {productionDispatch, productionDispatchList} from "@/api/productionManagement/productionOrder.js";
+
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+
+const data = reactive({
+  form: {},
+  dispatchList: [], // 娲惧伐鍒楄〃鏁版嵁
+});
+
+const { form, dispatchList } = toRefs(data);
+
+
+// 琛ㄦ牸琛屾牱寮�
+const tableRowClassName = ({ rowIndex }) => {
+  if (rowIndex % 2 === 1) {
+    return 'even-row'
+  }
+  return ''
+}
+
+// 淇敼鏈鎺掍骇鏁伴噺
+const changeCurrentNum = (value, row) => {
+  if (value > row.pendingQuantity) {
+    row.schedulingNum = row.pendingQuantity
+    proxy.$modal.msgWarning('鎺掍骇鏁伴噺涓嶅彲澶т簬寰呮帓浜ф暟閲�')
+  }
+}
+
+// 鎵撳紑寮规
+const openDialog = (type, rows) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+  
+  // 澶勭悊浼犲叆鐨勬暟鎹�
+  dispatchList.value = rows.map(row => ({
+    ...row,
+    schedulingNum: 0, // 鍒濆鍖栨湰娆℃帓浜ф暟閲忎负0
+    pendingQuantity: (Number(row.quantity) || 0) - (Number(row.schedulingNum) || 0) // 璁$畻寰呮帓浜ф暟閲�
+  }))
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+  // 妫�鏌ユ槸鍚︽湁鎺掍骇鏁版嵁
+  const hasSchedulingData = dispatchList.value.some(item => item.schedulingNum > 0)
+  if (!hasSchedulingData) {
+    proxy.$modal.msgWarning('璇疯嚦灏戜负涓�鏉¤褰曡缃帓浜ф暟閲�')
+    return
+  }
+  
+  // 鏋勯�犳彁浜ゆ暟鎹� - 鐩存帴浼犻�掓暟缁勶紝涓嶈繃婊�
+  const submitData = dispatchList.value
+  
+  console.log('鎻愪氦鑷姩娲惧伐鏁版嵁:', submitData)
+  
+  // 璋冪敤API锛堣繖閲岄渶瑕佹牴鎹疄闄呮帴鍙h皟鏁达級
+  productionDispatchList(submitData).then(res => {
+    proxy.$modal.msgSuccess(res.msg);
+    closeDia();
+  }).catch(err => {
+    proxy.$modal.msgError("娲惧伐澶辫触");
+    console.error('娲惧伐澶辫触:', err);
+  })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  dispatchList.value = []
+  emit('close')
+};
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+:deep(.even-row) {
+  background-color: #fafafa;
+}
+
+:deep(.el-table .cell) {
+  padding: 8px 12px;
+}
+
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 600;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue
index a60f751..e7e6e15 100644
--- a/src/views/productionManagement/productionDispatching/components/formDia.vue
+++ b/src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -7,7 +7,7 @@
         @close="closeDia"
     >
       <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
+        <!-- <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
               <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable disabled/>
@@ -16,6 +16,18 @@
           <el-col :span="12">
             <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
               <el-input v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable disabled/>
+            </el-form-item>
+          </el-col>
+        </el-row> -->
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+              <el-input v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="缁戝畾鏈哄櫒锛�" prop="speculativeTradingName">
+              <el-input v-model="form.speculativeTradingName" placeholder="鑷姩鑾峰彇" clearable disabled/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -46,6 +58,11 @@
 							/>
 						</el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+              <el-input v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable disabled/>
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row :gutter="30">
 					<el-col :span="12">
@@ -54,6 +71,9 @@
 								v-model="form.schedulingUserId"
 								placeholder="閫夋嫨浜哄憳"
 								style="width: 100%;"
+                filterable
+                default-first-option
+                :reserve-keyword="false"
 							>
 								<el-option
 									v-for="user in userList"
@@ -91,7 +111,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
 import useUserStore from "@/store/modules/user.js";
@@ -105,11 +124,13 @@
   form: {
 		projectName: "",
 		productCategory: "",
+		specificationModel: "", // 瑙勬牸鍨嬪彿
 		quantity: "",
 		schedulingNum: "",
 		schedulingUserId: "",
 		schedulingDate: "",
 		pendingQuantity: "",
+		speculativeTradingName: "", // 缁戝畾鏈哄櫒鍚嶇О
   },
   rules: {
 		schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -121,6 +142,7 @@
 const userList = ref([])
 const userStore = useUserStore()
 
+
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
   operationType.value = type;
diff --git a/src/views/productionManagement/productionDispatching/index.vue b/src/views/productionManagement/productionDispatching/index.vue
index 527880f..2d39890 100644
--- a/src/views/productionManagement/productionDispatching/index.vue
+++ b/src/views/productionManagement/productionDispatching/index.vue
@@ -1,5 +1,32 @@
 <template>
 	<div class="app-container">
+		<!-- 鐐掓満1-4 灞曠ず锛堟�婚噺 / 姝e湪鐢熶骇閲� / 绌轰綑閲忥級 -->
+		<div class="machines-grid">
+			<div v-for="machine in machines" :key="machine.id" class="machine-card">
+				<div class="machine-title">{{ machine.name }}</div>
+				<div class="machine-metrics">
+				<div class="machine-control">
+					<span>鎬婚噺(kg)锛�</span>
+					<el-input-number v-model="machineData[machine.name].workLoad" :min="0" :step="1" size="small" />
+				</div>
+				<div><span> 棰勮鎶曞叆閲�(kg)锛�</span><span>{{ machineData[machine.name].currentWorkLoad }}</span></div>
+				<div><span>绌轰綑宸ヤ綔閲�(kg)锛�</span><span>{{ machineData[machine.name].vacant }}</span></div>
+			</div>
+			</div>
+			<div class="save-button-container">
+				<div class="loss-rate-container">
+					<span class="loss-rate-label">鎹熻�楃巼(%)锛�</span>
+					<el-select v-model="rate" placeholder="璇烽�夋嫨鎹熻�楃巼" style="width: 120px" size="small">
+						<el-option label="6" :value="6" />
+						<el-option label="7" :value="7" />
+						<el-option label="8" :value="8" />
+						<el-option label="9" :value="9" />
+						<el-option label="10" :value="10" />
+					</el-select>
+				</div>
+				<el-button type="primary" @click="saveMachineTotals" size="small">淇濆瓨璁剧疆</el-button>
+			</div>
+		</div>
 		<div class="search_form">
 			<div>
 				<span class="search_title">瀹㈡埛鍚嶇О锛�</span>
@@ -11,24 +38,40 @@
 					clearable
 					prefix-icon="Search"
 				/>
-				<span class="search_title ml10">椤圭洰鍚嶇О锛�</span>
+				<span class="search_title ml10">鍚堝悓鍙凤細</span>
 				<el-input
-					v-model="searchForm.projectName"
+					v-model="searchForm.salesContractNo"
 					style="width: 240px"
 					placeholder="璇疯緭鍏�"
 					@change="handleQuery"
 					clearable
 					prefix-icon="Search"
 				/>
+<!--				<span class="search_title ml10">椤圭洰鍚嶇О锛�</span>-->
+<!--				<el-input-->
+<!--					v-model="searchForm.projectName"-->
+<!--					style="width: 240px"-->
+<!--					placeholder="璇疯緭鍏�"-->
+<!--					@change="handleQuery"-->
+<!--					clearable-->
+<!--					prefix-icon="Search"-->
+<!--				/>-->
 				<span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
 				<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-												placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+										placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+				<el-checkbox
+					style="margin-left: 10px"
+					v-model="searchForm.status"
+					label="涓嶆樉绀哄緟鎺掓暟閲忎负0"
+					@change="handleQuery"
+				/>
 				<el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
 			</div>
 			<div>
-				<el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</el-button>
-				<el-button @click="handleOut">瀵煎嚭</el-button>
-			</div>
+			<el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</el-button>
+			<el-button type="success" @click="openAutoDispatch">鑷姩娲惧伐</el-button>
+			<el-button @click="handleOut">瀵煎嚭</el-button>
+		</div>
 		</div>
 		<div class="table_list">
 			<PIMTable
@@ -44,23 +87,27 @@
 			></PIMTable>
 		</div>
 		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+		<auto-dispatch-dia ref="autoDispatchDia" @close="handleQuery"></auto-dispatch-dia>
 	</div>
 </template>
 
 <script setup>
-import {onMounted, ref} from "vue";
+import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, computed, watch} from "vue";
 import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
+import AutoDispatchDia from "@/views/productionManagement/productionDispatching/components/autoDispatchDia.vue";
 import dayjs from "dayjs";
-import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
+import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading, getLossRate, addLossRate, updateLossRate} from "@/api/productionManagement/productionOrder.js";
 import { ElMessageBox } from "element-plus";
 
 const data = reactive({
 	searchForm: {
 		customerName: "",
+		salesContractNo: "",
 		projectName: "",
-		entryDate: null, // 褰曞叆鏃ユ湡
-		entryDateStart: undefined,
-		entryDateEnd: undefined,
+		status: true,
+		entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // 褰曞叆鏃ユ湡锛岄粯璁ゅ綋澶�
+		entryDateStart: dayjs().format("YYYY-MM-DD"),
+		entryDateEnd: dayjs().format("YYYY-MM-DD"),
 	},
 });
 const { searchForm } = toRefs(data);
@@ -71,19 +118,9 @@
 		width: 220,
 	},
 	{
-		label: "瀹㈡埛鍚堝悓鍙�",
-		prop: "customerContractNo",
-		width: 250,
-	},
-	{
 		label: "瀹㈡埛鍚嶇О",
 		prop: "customerName",
 		width: 250,
-	},
-	{
-		label: "椤圭洰鍚嶇О",
-		prop: "projectName",
-		width:300
 	},
 	{
 		label: "浜у搧澶х被",
@@ -93,7 +130,12 @@
 	{
 		label: "瑙勬牸鍨嬪彿",
 		prop: "specificationModel",
-		width: 220,
+		width: 120,
+	},
+	{
+		label: "缁戝畾鏈哄櫒",
+		prop: "speculativeTradingName",
+		width: 160,
 	},
 	{
 		label: "鍗曚綅",
@@ -104,6 +146,32 @@
 		label: "褰曞叆鏃ユ湡",
 		prop: "entryDate",
 		width: 120,
+	},
+	{
+		label: "鐘舵��",
+		prop: "status",
+		dataType: "tag",
+		formatType: (params) => {
+			if (params == '鐢熶骇涓�') {
+				return "warning";
+			} else if (params == '鏈紑濮�') {
+				return "danger";
+			} else {
+				return "success";
+			}
+		},
+	},
+	{
+		label: "鐢熶骇杩涘害",
+		prop: "progress",
+		formatData: (cellValue) => {
+			// 濡傛灉鍊间负绌烘垨undefined锛屾樉绀虹┖瀛楃涓�
+			if (cellValue === null || cellValue === undefined || cellValue === '') {
+				return '';
+			}
+			// 鐩存帴鍦ㄦ暟瀛楀悗闈㈡坊鍔犵櫨鍒嗗彿
+			return `${cellValue}%`;
+		}
 	},
 	{
 		label: "鏁伴噺",
@@ -118,6 +186,7 @@
 		label: "寰呮帓鏁伴噺",
 		prop: "pendingQuantity",
 		width: 100,
+		fixed: 'right',
 	},
 ]);
 const tableData = ref([]);
@@ -129,7 +198,140 @@
 	total: 0,
 });
 const formDia = ref()
+const autoDispatchDia = ref()
 const { proxy } = getCurrentInstance()
+
+// 鐐掓満鏁版嵁
+const machineData = reactive({
+	"鐐掓満1": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満2": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満3": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満4": { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+})
+
+// 鐐掓満閰嶇疆鏁扮粍
+const machines = [
+	{ id: 1, name: '鐐掓満1' },
+	{ id: 2, name: '鐐掓満2' },
+	{ id: 3, name: '鐐掓満3' },
+	{ id: 4, name: '鐐掓満4' }
+]
+
+// 淇濆瓨鐐掓満鎬婚噺璁剧疆
+const saveMachineTotals = () => {
+	// 楠岃瘉鎹熻�楃巼鏄惁宸查�夋嫨
+	if (rate.value === null || rate.value === undefined || isNaN(rate.value)) {
+		proxy.$message.warning('璇烽�夋嫨鎹熻�楃巼');
+		return;
+	}
+	
+	// 鏋勯�犱繚瀛樻暟鎹暟缁勶紝浣跨敤machines鏁扮粍寰幆鏋勫缓
+	const saveData = machines.map(machine => {
+		const saveItem = {
+			name: machine.name, // 鐐掓満鍚嶇О
+			workLoad: machineData[machine.name].workLoad,  // 鎬婚噺
+			currentWorkLoad: machineData[machine.name].currentWorkLoad, //  棰勮鎶曞叆閲�
+			vacant: machineData[machine.name].vacant   // 绌轰綑閲�
+		};
+		
+		// 濡傛灉鏄慨鏀规搷浣滐紝闇�瑕佷紶閫抜d瀛楁
+		if (hasQueryData.value) {
+			const queryData = getMachineQueryData(machine.id);
+			if (queryData && queryData.id) {
+				saveItem.id = queryData.id;
+			}
+		}
+		
+		return saveItem;
+	});
+	
+	// 鏋勯�犳崯鑰楃巼鏁版嵁
+	const rateData = {
+		rate: rate.value
+	};
+	
+	// 濡傛灉鏈塈D锛岃鏄庢槸淇敼鎿嶄綔
+	if (rateId.value) {
+		rateData.id = rateId.value;
+	}
+	
+	// 鏍规嵁鏄惁鏈夋煡璇㈡暟鎹喅瀹氳皟鐢ㄦ柊澧炴帴鍙h繕鏄慨鏀规帴鍙�
+	const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading;
+	const successMessage = hasQueryData.value ? '鐐掓満璁剧疆淇敼鎴愬姛' : '鐐掓満璁剧疆鏂板鎴愬姛';
+	
+	// 鏍规嵁鏄惁鏈塈D鍐冲畾璋冪敤鏂板鎺ュ彛杩樻槸淇敼鎺ュ彛
+	const rateApi = rateId.value ? updateLossRate : addLossRate;
+	const rateSuccessMessage = rateId.value ? '鎹熻�楃巼淇敼鎴愬姛' : '鎹熻�楃巼鏂板鎴愬姛';
+	
+	// 骞惰璋冪敤涓や釜鎺ュ彛
+	Promise.all([
+		saveApi(saveData),
+		rateApi(rateData)
+	]).then(([saveRes, rateRes]) => {
+		proxy.$message.success(successMessage);
+		proxy.$message.success(rateSuccessMessage);
+		
+		// 淇濆瓨鎴愬姛鍚庯紝璁剧疆hasQueryData涓簍rue锛屼笅娆′繚瀛樺皢璋冪敤淇敼鎺ュ彛
+		if (!hasQueryData.value) {
+			hasQueryData.value = true;
+		}
+		
+		// 濡傛灉杩斿洖浜咺D锛屼繚瀛樿捣鏉�
+		if (rateRes && rateRes.data && rateRes.data.id) {
+			rateId.value = rateRes.data.id;
+		}
+		
+		// 淇濆瓨鎴愬姛鍚庨噸鏂拌皟鐢ㄦ煡璇㈤〉闈�
+		getList();
+	}).catch(err => {
+		proxy.$message.error('淇濆瓨澶辫触');
+		console.error('淇濆瓨澶辫触:', err);
+	});
+}
+
+// 鑾峰彇鐐掓満鏌ヨ鏁版嵁
+const machineQueryData = ref([]);
+
+const getMachineQueryData = (machineId) => {
+	return machineQueryData.value.find(item => item.id === machineId);
+};
+
+const getMachineIndex = (item) => {
+	// 鍏煎澶氱瀛楁鍛藉悕锛岃繑鍥� 1-4 涔嬩竴锛屽惁鍒欒繑鍥� 0锛堟湭鐭ワ級
+	const candidates = [item.machineId, item.machineNo, item.machine, item.deviceNo, item.deviceId]
+	for (const v of candidates) {
+		if (v === undefined || v === null) continue
+		const n = Number(String(v).replace(/[^\d]/g, "")) // 鎶藉彇鏁板瓧
+		if ([1,2,3,4].includes(n)) return n
+	}
+	return 0
+}
+
+const computeTodaySummary = () => {
+	const todayStr = dayjs().format("YYYY-MM-DD")
+	
+	// 閲嶇疆鎵�鏈夌倰鏈烘暟鎹�
+	machines.forEach(machine => {
+		machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+	})
+	
+	tableData.value.forEach(item => {
+		// 浠呯粺璁″綋澶�
+		const isToday = dayjs(item.entryDate).format("YYYY-MM-DD") === todayStr
+		if (!isToday) return
+		
+		// 浣跨敤姝g‘鐨勫瓧娈靛悕锛歸orkLoad锛堢倰鏈哄伐浣滈噺锛�, currentWorkLoad锛堢倰鏈烘鍦ㄥ伐浣滈噺锛�
+		const workLoad = Number(item.workLoad) || 0
+		const currentWorkLoad = Number(item.currentWorkLoad) || 0
+		const machineName = item.speculativeTradingName || '鐐掓満1'
+		
+		if (machineData[machineName]) {
+			machineData[machineName].workLoad += workLoad
+			machineData[machineName].currentWorkLoad += currentWorkLoad
+			machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad
+		}
+	})
+}
 
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -137,6 +339,56 @@
 	page.current = 1;
 	getList();
 };
+
+// 鏄惁鏈夋煡璇㈡暟鎹�
+const hasQueryData = ref(false)
+// 鎹熻�楃巼
+const rate = ref(6)
+// 鎹熻�楃巼ID
+const rateId = ref(null)
+
+// 鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+const getMachineProductionData = () => {
+	schedulingList().then((res) => {
+		// 澶勭悊鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+		if (res.data && Array.isArray(res.data)) {
+			// 璁剧疆鏄惁鏈夋煡璇㈡暟鎹�
+			hasQueryData.value = res.data.length > 0
+			
+			// 淇濆瓨鏌ヨ鏁版嵁鍒癿achineQueryData
+			machineQueryData.value = res.data;
+			
+			// 閲嶇疆鎵�鏈夌倰鏈烘暟鎹�
+			machines.forEach(machine => {
+				machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+			});
+			
+			// 閬嶅巻鏁版嵁锛屾牴鎹煡璇㈣繑鍥炵殑鏁版嵁缁撴瀯澶勭悊
+			res.data.forEach(item => {
+				// 鏍规嵁name瀛楁纭畾鐐掓満
+				const machineName = item.name || '鐐掓満1';
+				
+				if (machineData[machineName]) {
+					// 濡傛灉鏌ヨ鏁版嵁涓湁workLoad锛屽垯鍒濆鍖栫倰鏈烘�婚噺
+					if (item.workLoad !== null && item.workLoad !== undefined) {
+						machineData[machineName].workLoad = Number(item.workLoad) || 0;
+					}
+					
+					// 濡傛灉鏌ヨ鏁版嵁涓湁currentWorkLoad锛屽垯璁剧疆姝e湪宸ヤ綔閲�
+					if (item.currentWorkLoad !== null && item.currentWorkLoad !== undefined) {
+						machineData[machineName].currentWorkLoad = Number(item.currentWorkLoad) || 0;
+					}
+					
+					// 璁$畻绌轰綑宸ヤ綔閲�
+					machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad;
+				}
+			});
+		}
+	}).catch(err => {
+		console.error('鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹け璐�:', err);
+	});
+};
+
 const changeDaterange = (value) => {
 	if (value) {
 		searchForm.value.entryDateStart = value[0];
@@ -165,9 +417,33 @@
 			pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
 		}));
 		page.total = res.data.total;
+		computeTodaySummary()
+		
+		// 鍚屾椂鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+		getMachineProductionData();
+		// 鑾峰彇鎹熻�楃巼鏁版嵁
+		getLossRateData();
 	}).catch(() => {
 		tableLoading.value = false;
 	})
+};
+
+// 鑾峰彇鎹熻�楃巼鏁版嵁
+const getLossRateData = () => {
+	getLossRate().then((res) => {
+		const data = res.data || res;
+		if (data && data.rate !== undefined && data.rate !== null) {
+			rate.value = Number(data.rate); // 纭繚杞崲涓烘暟瀛�
+			rateId.value = data.id || null;
+		} else {
+			rate.value = 6;
+			rateId.value = null;
+		}
+	}).catch(err => {
+		console.error('鑾峰彇鎹熻�楃巼鏁版嵁澶辫触:', err);
+		rate.value = 6;
+		rateId.value = null;
+	});
 };
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
@@ -189,6 +465,26 @@
 	})
 };
 
+// 鎵撳紑鑷姩娲惧伐寮规
+const openAutoDispatch = () => {
+	if (selectedRows.value.length === 0) {
+		proxy.$message.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+		return;
+	}
+	
+	// 杩囨护鎺夊緟鎺掍骇鏁伴噺涓�0鐨勬暟鎹�
+	const validRows = selectedRows.value.filter(row => row.pendingQuantity > 0);
+	
+	if (validRows.length === 0) {
+		proxy.$message.warning("閫変腑鐨勬暟鎹棤闇�娲惧伐");
+		return;
+	}
+	
+	nextTick(() => {
+		autoDispatchDia.value?.openDialog('auto', validRows)
+	})
+};
+
 // 瀵煎嚭
 const handleOut = () => {
 	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -206,7 +502,129 @@
 
 onMounted(() => {
 	getList();
+	getLossRateData();
 });
 </script>
 
-<style scoped></style>
+<style scoped>
+.summary-bar{
+	display: flex;
+	gap: 16px;
+	margin: 10px 0 16px 0;
+}
+.summary-item{
+	background: #f5f7fa;
+	border: 1px solid #ebeef5;
+	border-radius: 6px;
+	padding: 10px 16px;
+	min-width: 160px;
+}
+.summary-label{
+	color: #909399;
+	font-size: 12px;
+	margin-bottom: 6px;
+}
+.summary-value{
+	color: #303133;
+	font-size: 20px;
+	font-weight: 600;
+}
+.summary-control{
+	display: flex;
+	align-items: center;
+	height: 28px;
+}
+.machines-grid{
+	display: grid;
+	grid-template-columns: repeat(4, 1fr);
+	gap: 16px;
+	margin-bottom: 20px;
+	padding: 16px;
+	background: #f8f9fa;
+	border-radius: 8px;
+	border: 1px solid #e9ecef;
+}
+.machine-card{
+	border: 1px solid #dee2e6;
+	border-radius: 8px;
+	padding: 16px;
+	background: #fff;
+	box-shadow: 0 2px 4px rgba(0,0,0,0.05);
+	transition: all 0.3s ease;
+}
+.machine-card:hover{
+	transform: translateY(-2px);
+	box-shadow: 0 4px 8px rgba(0,0,0,0.1);
+}
+.machine-title{
+	font-weight: 600;
+	font-size: 16px;
+	margin-bottom: 12px;
+	color: #2c3e50;
+	text-align: center;
+	padding-bottom: 8px;
+	border-bottom: 2px solid #3498db;
+}
+.machine-metrics{
+	display: flex;
+	flex-direction: column;
+	gap: 10px;
+	color: #495057;
+}
+.machine-control{
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	gap: 8px;
+	padding: 8px 0;
+	border-bottom: 1px solid #f1f3f4;
+}
+.machine-control span{
+	font-size: 14px;
+	white-space: nowrap;
+	color: #6c757d;
+	font-weight: 500;
+}
+.machine-metrics > div:not(.machine-control) {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 4px 0;
+	font-size: 14px;
+}
+.machine-metrics > div:not(.machine-control) span:first-child {
+	color: #6c757d;
+}
+.machine-metrics > div:not(.machine-control) span:last-child {
+	font-weight: 600;
+	color: #2c3e50;
+}
+.save-button-container{
+	grid-column: 1 / -1;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	gap: 16px;
+	margin-top: 16px;
+	padding-top: 16px;
+	border-top: 1px solid #e9ecef;
+}
+.loss-rate-container{
+	display: flex;
+	align-items: center;
+	gap: 8px;
+}
+.loss-rate-label{
+	font-size: 14px;
+	color: #6c757d;
+	font-weight: 500;
+	white-space: nowrap;
+}
+</style>
+
+
+
+
+
+
+
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 9928d46..51b42ac 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -1,198 +1,391 @@
 <template>
-	<div class="app-container">
-		<div class="search_form">
-			<div>
-				<span class="search_title">瀹㈡埛鍚嶇О锛�</span>
-				<el-input
-					v-model="searchForm.customerName"
-					style="width: 240px"
-					placeholder="璇疯緭鍏�"
-					@change="handleQuery"
-					clearable
-					prefix-icon="Search"
-				/>
-				<span class="search_title ml10">椤圭洰鍚嶇О锛�</span>
-				<el-input
-					v-model="searchForm.projectName"
-					style="width: 240px"
-					placeholder="璇疯緭鍏�"
-					@change="handleQuery"
-					clearable
-					prefix-icon="Search"
-				/>
-				<span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
-				<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-												placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
-				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-				>鎼滅储</el-button
-				>
-			</div>
-			<div>
-				<el-button @click="handleOut">瀵煎嚭</el-button>
-			</div>
-		</div>
-		<div class="table_list">
-			<PIMTable
-				rowKey="id"
-				:column="tableColumn"
-				:tableData="tableData"
-				:page="page"
-				:tableLoading="tableLoading"
-				@pagination="pagination"
-			></PIMTable>
-		</div>
-	</div>
+  <div class="app-container">
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="瀹㈡埛鍚嶇О:">
+          <el-input v-model="searchForm.customerName"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 160px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item label="鍚堝悓鍙�:">
+          <el-input v-model="searchForm.salesContractNo"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 160px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item label="浜у搧鍚嶇О:">
+          <el-input v-model="searchForm.productCategory"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 160px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item label="瑙勬牸:">
+          <el-input v-model="searchForm.specificationModel"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 160px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :tableLoading="tableLoading"
+                @pagination="pagination">
+        <template #completionStatus="{ row }">
+          <el-progress
+            :percentage="toProgressPercentage(row?.completionStatus)"
+            :color="progressColor(toProgressPercentage(row?.completionStatus))"
+            :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
+          />
+        </template>
+      </PIMTable>
+    </div>
+    <el-dialog v-model="bindRouteDialogVisible"
+               title="缁戝畾宸ヨ壓璺嚎"
+               width="500px">
+      <el-form label-width="90px">
+        <el-form-item label="宸ヨ壓璺嚎">
+          <el-select v-model="bindForm.routeId"
+                     placeholder="璇烽�夋嫨宸ヨ壓璺嚎"
+                     style="width: 100%;"
+                     :loading="bindRouteLoading">
+            <el-option v-for="item in routeOptions"
+                       :key="item.id"
+                       :label="`${item.processRouteCode || ''}`"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="bindRouteDialogVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary"
+                     :loading="bindRouteSaving"
+                     @click="handleBindRouteConfirm">纭� 璁�</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 
 <script setup>
-import {onMounted, ref} from "vue";
-import { ElMessageBox } from "element-plus";
-import dayjs from "dayjs";
-import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
-const { proxy } = getCurrentInstance();
+  import { onMounted, ref } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import dayjs from "dayjs";
+  import { useRouter } from "vue-router";
+  import {
+    productOrderListPage,
+    listProcessRoute,
+    bindingRoute,
+    listProcessBom,
+  } from "@/api/productionManagement/productionOrder.js";
+  import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
+  const { proxy } = getCurrentInstance();
 
-const tableColumn = ref([
-	{
-		label: "褰曞叆鏃ユ湡",
-		prop: "entryDate",
-		width: 120,
-	},
-	{
-		label: "鍚堝悓鍙�",
-		prop: "salesContractNo",
-		width: 220,
-	},
-	{
-		label: "瀹㈡埛鍚堝悓鍙�",
-		prop: "customerContractNo",
-		width: 250,
-	},
-	{
-		label: "瀹㈡埛鍚嶇О",
-		prop: "customerName",
-		width: 250,
-	},
-	{
-		label: "椤圭洰鍚嶇О",
-		prop: "projectName",
-		width:300
-	},
-	{
-		label: "浠樻鐘舵��",
-		prop: "status",
-		dataType: "tag",
-		formatType: (params) => {
-			if (params == '鏈畬鎴�') {
-				return "danger";
-			} else if (params == '宸插畬鎴�') {
-				return "success";
-			} else {
-				return null;
-			}
-		},
-	},
-	{
-		label: "浜у搧澶х被",
-		prop: "productCategory",
-		width: 160,
-	},
-	{
-		label: "瑙勬牸鍨嬪彿",
-		prop: "specificationModel",
-		width: 220,
-	},
-	{
-		label: "鍗曚綅",
-		prop: "unit",
-		width:90
-	},
-	{
-		label: "鏁伴噺",
-		prop: "quantity",
-	},
-	{
-		label: "鎺掍骇鏁伴噺",
-		prop: "schedulingNum",
-		width: 100,
-	},
-	{
-		label: "瀹屽伐鏁伴噺",
-		prop: "successNum",
-		width: 100,
-	},
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-	current: 1,
-	size: 100,
-	total: 0,
-});
+  const router = useRouter();
 
-const data = reactive({
-	searchForm: {
-		customerName: "",
-		projectName: "",
-		entryDate: null, // 褰曞叆鏃ユ湡
-		entryDateStart: undefined,
-		entryDateEnd: undefined,
-	},
-});
-const { searchForm } = toRefs(data);
+  const tableColumn = ref([
+    {
+      label: "鐢熶骇璁㈠崟鍙�",
+      prop: "npsNo",
+      width: '120px',
+    },
+    {
+      label: "閿�鍞悎鍚屽彿",
+      prop: "salesContractNo",
+      width: '150px',
+    },
+    {
+      label: "瀹㈡埛鍚嶇О",
+      prop: "customerName",
+      width: '200px',
+    },
+    {
+      label: "浜у搧鍚嶇О",
+      prop: "productCategory",
+      width: '120px',
+    },
+    {
+      label: "瑙勬牸",
+      prop: "specificationModel",
+      width: '120px',
+    },
+    {
+      label: "宸ヨ壓璺嚎缂栧彿",
+      prop: "processRouteCode",
+      width: '200px',
+    },
+    {
+      label: "闇�姹傛暟閲�",
+      prop: "quantity",
+    },
+    {
+      label: "瀹屾垚鏁伴噺",
+      prop: "completeQuantity",
+    },
+    {
+      dataType: "slot",
+      label: "瀹屾垚杩涘害",
+      prop: "completionStatus",
+      slot: "completionStatus",
+      width: 180,
+    },
+    {
+      label: "寮�濮嬫棩鏈�",
+      prop: "startTime",
+      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
+      width: 120,
+    },
+    {
+      label: "缁撴潫鏃ユ湡",
+      prop: "endTime",
+      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
+      width: 120,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 200,
+      operation: [
+        {
+          name: "宸ヨ壓璺嚎",
+          type: "text",
+          clickFun: row => {
+            showRouteItemModal(row);
+          },
+        },
+        {
+          name: "缁戝畾宸ヨ壓璺嚎",
+          type: "text",
+          showHide: row => !row.processRouteCode,
+          clickFun: row => {
+            openBindRouteDialog(row);
+          },
+        },
+        {
+          name: "浜у搧缁撴瀯",
+          type: "text",
+          clickFun: row => {
+            showProductStructure(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
 
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-	page.current = 1;
-	getList();
-};
-const pagination = (obj) => {
-	page.current = obj.page;
-	page.size = obj.limit;
-	getList();
-};
-const changeDaterange = (value) => {
-	if (value) {
-		searchForm.value.entryDateStart = value[0];
-		searchForm.value.entryDateEnd = value[1];
-	} else {
-		searchForm.value.entryDateStart = undefined;
-		searchForm.value.entryDateEnd = undefined;
-	}
-	handleQuery();
-};
-const getList = () => {
-	tableLoading.value = true;
-	// 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
-	const params = { ...searchForm.value, ...page };
-	params.entryDate = undefined
-	schedulingListPage(params).then((res) => {
-		tableLoading.value = false;
-		tableData.value = res.data.records;
-		page.total = res.data.total;
-	}).catch(() => {
-		tableLoading.value = false;
-	})
-};
+  const data = reactive({
+    searchForm: {
+      customerName: "",
+      salesContractNo: "",
+      projectName: "",
+      productCategory: "",
+      specificationModel: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
 
-// 瀵煎嚭
-const handleOut = () => {
-	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-		confirmButtonText: "纭",
-		cancelButtonText: "鍙栨秷",
-		type: "warning",
-	})
-		.then(() => {
-			proxy.download("/salesLedger/scheduling/export", {}, "鐢熶骇璁㈠崟.xlsx");
-		})
-		.catch(() => {
-			proxy.$modal.msg("宸插彇娑�");
-		});
-};
+  const toProgressPercentage = val => {
+    const n = Number(val);
+    if (!Number.isFinite(n)) return 0;
+    if (n <= 0) return 0;
+    if (n >= 100) return 100;
+    return Math.round(n);
+  };
 
-onMounted(() => {
-	getList();
-});
+  // 30/50/80/100 鍒嗘棰滆壊锛氱孩/姗�/钃�/缁�
+  const progressColor = percentage => {
+    const p = toProgressPercentage(percentage);
+    if (p < 30) return "#f56c6c";
+    if (p < 50) return "#e6a23c";
+    if (p < 80) return "#409eff";
+    return "#67c23a";
+  };
+
+  // 缁戝畾宸ヨ壓璺嚎寮规
+  const bindRouteDialogVisible = ref(false);
+  const bindRouteLoading = ref(false);
+  const bindRouteSaving = ref(false);
+  const routeOptions = ref([]);
+  const bindForm = reactive({
+    orderId: null,
+    routeId: null,
+  });
+
+  const openBindRouteDialog = async row => {
+    bindForm.orderId = row.id;
+    bindForm.routeId = null;
+    bindRouteDialogVisible.value = true;
+    routeOptions.value = [];
+    if (!row.productModelId) {
+      proxy.$modal.msgWarning("褰撳墠璁㈠崟缂哄皯浜у搧鍨嬪彿锛屾棤娉曟煡璇㈠伐鑹鸿矾绾�");
+      bindRouteDialogVisible.value = false;
+      return;
+    }
+    bindRouteLoading.value = true;
+    try {
+      const res = await listProcessRoute({ productModelId: row.productModelId });
+      routeOptions.value = res.data || [];
+    } catch (e) {
+      console.error("鑾峰彇宸ヨ壓璺嚎鍒楄〃澶辫触锛�", e);
+      proxy.$modal.msgError("鑾峰彇宸ヨ壓璺嚎鍒楄〃澶辫触");
+    } finally {
+      bindRouteLoading.value = false;
+    }
+  };
+
+  const handleBindRouteConfirm = async () => {
+    if (!bindForm.routeId) {
+      proxy.$modal.msgWarning("璇烽�夋嫨宸ヨ壓璺嚎");
+      return;
+    }
+    bindRouteSaving.value = true;
+    try {
+      await bindingRoute({
+        id: bindForm.orderId,
+        routeId: bindForm.routeId,
+      });
+      proxy.$modal.msgSuccess("缁戝畾鎴愬姛");
+      bindRouteDialogVisible.value = false;
+      getList();
+    } catch (e) {
+      console.error("缁戝畾宸ヨ壓璺嚎澶辫触锛�", e);
+      proxy.$modal.msgError("缁戝畾宸ヨ壓璺嚎澶辫触");
+    } finally {
+      bindRouteSaving.value = false;
+    }
+  };
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const changeDaterange = value => {
+    if (value) {
+      searchForm.value.entryDateStart = value[0];
+      searchForm.value.entryDateEnd = value[1];
+    } else {
+      searchForm.value.entryDateStart = undefined;
+      searchForm.value.entryDateEnd = undefined;
+    }
+    handleQuery();
+  };
+  const getList = () => {
+    tableLoading.value = true;
+    // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
+    const params = { ...searchForm.value, ...page };
+    params.entryDate = undefined;
+    productOrderListPage(params)
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(() => {
+        tableLoading.value = false;
+      });
+  };
+
+  const showRouteItemModal = async row => {
+    const orderId = row.id;
+    try {
+      const res = await getOrderProcessRouteMain(orderId);
+      const data = res.data || {};
+      if (!data || !data.id) {
+        proxy.$modal.msgWarning("鏈壘鍒板叧鑱旂殑宸ヨ壓璺嚎");
+        return;
+      }
+      router.push({
+        path: "/productionManagement/processRouteItem",
+        query: {
+          id: data.id,
+          processRouteCode: data.processRouteCode || "",
+          productName: data.productName || "",
+          model: data.model || "",
+          bomNo: data.bomNo || "",
+          description: data.description || "",
+          orderId,
+          type: "order",
+        },
+      });
+    } catch (e) {
+      console.error("鑾峰彇宸ヨ壓璺嚎涓讳俊鎭け璐ワ細", e);
+      proxy.$modal.msgError("鑾峰彇宸ヨ壓璺嚎淇℃伅澶辫触");
+    }
+  };
+
+  const showProductStructure = row => {
+    router.push({
+      path: "/productionManagement/productStructureDetail",
+      query: {
+        id: row.id,
+        bomNo: row.bomNo || "",
+        productName: row.productCategory || "",
+        productModelName: row.specificationModel || "",
+        orderId: row.id,
+        type: "order",
+      },
+    });
+  };
+
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download("/productOrder/export", {...searchForm.value}, "鐢熶骇璁㈠崟.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  const handleConfirmRoute = () => {};
+
+  onMounted(() => {
+    getList();
+  });
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.search_form{
+  align-items: start;
+}</style>
diff --git a/src/views/productionManagement/productionProcess/Edit.vue b/src/views/productionManagement/productionProcess/Edit.vue
new file mode 100644
index 0000000..f979d51
--- /dev/null
+++ b/src/views/productionManagement/productionProcess/Edit.vue
@@ -0,0 +1,132 @@
+<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="salaryQuota">
+          <el-input v-model="formState.salaryQuota" type="number" :step="0.001" />
+        </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,
+  no: props.record.no,
+  remark: props.record.remark,
+  salaryQuota: props.record.salaryQuota,
+});
+
+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 || '',
+      remark: newRecord.remark || '',
+      salaryQuota: newRecord.salaryQuota || '',
+    };
+  }
+}, { 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 || '',
+      remark: props.record.remark || '',
+      salaryQuota: props.record.salaryQuota || '',
+    };
+  }
+});
+
+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
new file mode 100644
index 0000000..7558ba7
--- /dev/null
+++ b/src/views/productionManagement/productionProcess/New.vue
@@ -0,0 +1,99 @@
+<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="salaryQuota">
+          <el-input v-model="formState.salaryQuota" type="number" :step="0.001" />
+        </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: '',
+  remark: '',
+  salaryQuota:  '',
+});
+
+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
new file mode 100644
index 0000000..7ab8c9a
--- /dev/null
+++ b/src/views/productionManagement/productionProcess/index.vue
@@ -0,0 +1,302 @@
+<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>
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+        </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>
+      </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"
+    />
+  </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 { listPage, del, importData, downloadTemplate } from "@/api/productionManagement/productionProcess.js";
+  import { getToken } from "@/utils/auth";
+
+  const data = reactive({
+    searchForm: {
+      name: "",
+      no: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
+  const tableColumn = ref([
+    {
+      label: "宸ュ簭缂栧彿",
+      prop: "no",
+    },
+    {
+      label: "宸ュ簭鍚嶇О",
+      prop: "name",
+    },
+   
+    {
+      label: "宸ヨ祫瀹氶",
+      prop: "salaryQuota",
+    },
+    {
+      label: "澶囨敞",
+      prop: "remark",
+    },
+     {
+      label: "鏇存柊鏃堕棿",
+      prop: "updateTime",
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 280,
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            showEditModal(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({
+    current: 1,
+    size: 100,
+    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)
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records.map(item => ({
+          ...item,
+        }));
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+
+  // 鎵撳紑鏂板寮规
+  const showNewModal = () => {
+    isShowNewModal.value = true;
+  };
+
+  const showEditModal = row => {
+    isShowEditModal.value = true;
+    record.value = row;
+  };
+
+  // 鍒犻櫎
+  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);
+        })
+        .then(() => {
+          getList();
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    } else {
+      proxy.$modal
+        .confirm('鏄惁纭鍒犻櫎宸ュ簭缂栧彿涓�"' + no + '"鐨勬暟鎹」锛�')
+        .then(function () {
+          return del(ids);
+        })
+        .then(() => {
+          getList();
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    }
+  }
+
+  // 瀵煎叆
+  const handleImport = () => {
+    importDialogVisible.value = true;
+  };
+
+  // 纭瀵煎叆
+  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();
+      }
+      getList();
+    } else {
+      proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+    }
+  };
+
+  // 瀵煎叆澶辫触
+  const handleImportError = (error) => {
+    proxy.$modal.msgError("瀵煎叆澶辫触锛�" + (error.message || "鏈煡閿欒"));
+  };
+
+  // 鍏抽棴瀵煎叆寮圭獥
+  const handleImportClose = () => {
+    if (importDialogRef.value) {
+      importDialogRef.value.clearFiles();
+    }
+  };
+
+  // 涓嬭浇妯℃澘
+  const handleDownloadTemplate = async () => {
+    try {
+      const res = await downloadTemplate();
+      const blob = new Blob([res], {
+        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+      });
+      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("宸插彇娑�");
+  // 		});
+  // };
+
+  onMounted(() => {
+    getList();
+  });
+</script>
+
+<style scoped></style>
diff --git a/src/views/productionManagement/productionReporting/Input.vue b/src/views/productionManagement/productionReporting/Input.vue
new file mode 100644
index 0000000..3ba68f7
--- /dev/null
+++ b/src/views/productionManagement/productionReporting/Input.vue
@@ -0,0 +1,115 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="isShow"
+        title="鎶曞叆"
+        @close="closeModal"
+    >
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="data"
+          :page="page"
+          :tableLoading="tableLoading"
+          @pagination="pagination"
+      ></PIMTable>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="closeModal">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref, computed, onMounted} from "vue";
+import { productionProductInputListPage } from "@/api/productionManagement/productionProductInput";
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+  productionProductMainId: {
+    type: Number,
+    required: true,
+  },
+});
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const page = reactive({
+  current: 1,
+  size: 100,
+  total: 0
+});
+
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  fetchData();
+};
+
+const tableLoading = ref(false);
+
+const tableColumn = [
+  {
+    label: '鎶ュ伐鍗曞彿',
+    prop: 'productNo',
+  },
+  {
+    label: '鎶曞叆浜у搧鍚嶇О',
+    prop: 'productName',
+  },
+  {
+    label: '鎶曞叆浜у搧鍨嬪彿',
+    prop: 'model',
+  },
+  {
+    label: '鎶曞叆鏁伴噺',
+    prop: 'quantity',
+  },
+  {
+    label: '鍗曚綅',
+    prop: 'unit',
+  },
+]
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+const data = ref([])
+
+const closeModal = () => {
+  isShow.value = false;
+};
+
+const fetchData = () => {
+  tableLoading.value = true;
+  const params = { productMainId: props.productionProductMainId, ...page };
+
+  productionProductInputListPage(params).then(res => {
+    tableLoading.value = false;
+    data.value = res.data.records;
+    page.total = res.data.total;
+  }).catch(err => {
+    tableLoading.value = false;
+  })
+};
+
+defineExpose({
+  closeModal,
+  isShow,
+});
+
+onMounted(() => {
+  fetchData()
+})
+</script>
diff --git a/src/views/productionManagement/productionReporting/Output.vue b/src/views/productionManagement/productionReporting/Output.vue
new file mode 100644
index 0000000..4eeac43
--- /dev/null
+++ b/src/views/productionManagement/productionReporting/Output.vue
@@ -0,0 +1,106 @@
+<template>
+  <div>
+    <el-dialog v-model="isShow"
+               title="浜у嚭"
+               @close="closeModal">
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="data"
+                :page="page"
+                :tableLoading="tableLoading"
+                @pagination="pagination"></PIMTable>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="closeModal">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { ref, computed, onMounted } from "vue";
+  import { productionProductOutputListPage } from "@/api/productionManagement/productionProductOutput.js";
+
+  const props = defineProps({
+    visible: {
+      type: Boolean,
+      required: true,
+    },
+    productionProductMainId: {
+      type: Number,
+      required: true,
+    },
+  });
+
+  const emit = defineEmits(["update:visible", "completed"]);
+
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    fetchData();
+  };
+
+  const tableLoading = ref(false);
+
+  const tableColumn = [
+    {
+      label: "鎶ュ伐鍗曞彿",
+      prop: "productNo",
+    },
+    {
+      label: "浜у搧鍨嬪彿",
+      prop: "model",
+    },
+    {
+      label: "浜у嚭鏁伴噺",
+      prop: "quantity",
+    },
+  ];
+
+  const isShow = computed({
+    get() {
+      return props.visible;
+    },
+    set(val) {
+      emit("update:visible", val);
+    },
+  });
+
+  const data = ref([]);
+
+  const closeModal = () => {
+    isShow.value = false;
+  };
+
+  const fetchData = () => {
+    tableLoading.value = true;
+    const params = { productMainId: props.productionProductMainId, ...page };
+
+    productionProductOutputListPage(params)
+      .then(res => {
+        tableLoading.value = false;
+        data.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+
+  defineExpose({
+    closeModal,
+    isShow,
+  });
+
+  onMounted(() => {
+    fetchData();
+  });
+</script>
diff --git a/src/views/productionManagement/productionReporting/components/formDia.vue b/src/views/productionManagement/productionReporting/components/formDia.vue
index 89f6c76..126c5b0 100644
--- a/src/views/productionManagement/productionReporting/components/formDia.vue
+++ b/src/views/productionManagement/productionReporting/components/formDia.vue
@@ -13,8 +13,15 @@
               <el-input v-model="form.schedulingNum" placeholder="璇疯緭鍏�" clearable disabled/>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏈鐢熶骇鏁伴噺锛�" prop="finishedNum">
+					<el-col :span="12">
+						<el-form-item label="寰呯敓浜ф暟閲忥細" prop="pendingNum">
+							<el-input v-model="form.pendingNum" placeholder="璇疯緭鍏�" clearable disabled/>
+						</el-form-item>
+					</el-col>
+        </el-row>
+        <el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="鏈鐢熶骇鏁伴噺锛�" prop="finishedNum">
 							<el-input-number
 								v-model="form.finishedNum"
 								placeholder="璇疯緭鍏�"
@@ -25,13 +32,18 @@
 								style="width: 100%"
 								@change="changeNum"
 							/>
+						</el-form-item>
+					</el-col>
+          <el-col :span="12">
+            <el-form-item label="鍗曚环(鍏�)锛�" prop="unitPrice">
+              <el-input v-model="form.unitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice"/>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="寰呯敓浜ф暟閲忥細" prop="pendingNum">
-              <el-input v-model="form.pendingNum" placeholder="璇疯緭鍏�" clearable disabled/>
+            <el-form-item label="鎬讳环(鍏�)锛�" prop="totalPrice">
+              <el-input v-model="form.totalPrice" placeholder="璇疯緭鍏�" clearable disabled/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -42,6 +54,9 @@
 								v-model="form.schedulingUserId"
 								placeholder="閫夋嫨浜哄憳"
 								style="width: 100%;"
+                filterable
+                default-first-option
+                :reserve-keyword="false"
 							>
 								<el-option
 									v-for="user in userList"
@@ -79,7 +94,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {productionReport, productionReportUpdate} from "@/api/productionManagement/productionReporting.js";
 const { proxy } = getCurrentInstance()
@@ -95,6 +109,8 @@
 		finishedNum: "",
 		schedulingUserId: "",
 		schedulingDate: "",
+		unitPrice: "",
+		totalPrice: "",
   },
   rules: {
 		schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -118,6 +134,19 @@
 		proxy.$modal.msgWarning('鏈鐢熶骇鏁伴噺涓嶅彲澶т簬鎺掍骇鏁伴噺')
 	}
 	form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum;
+	calculateTotalPrice();
+}
+
+// 璁$畻鎬讳环
+const calculateTotalPrice = () => {
+	const quantity = Number(form.value.finishedNum ?? 0);
+	const unitPrice = Number(form.value.unitPrice ?? 0);
+	
+	if (quantity > 0 && unitPrice > 0) {
+		form.value.totalPrice = (quantity * unitPrice).toFixed(2);
+	} else {
+		form.value.totalPrice = '0.00';
+	}
 }
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index 996a00b..08b515d 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -1,427 +1,415 @@
 <template>
-	<div class="app-container">
-		<div class="search_form">
-			<el-form :model="searchForm" :inline="true">
-				<el-form-item label="瀹㈡埛鍚嶇О:">
-					<el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
-										style="width: 200px;"
-										@change="handleQuery" />
-				</el-form-item>
-				<el-form-item label="椤圭洰鍚嶇О:">
-					<el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
-										style="width: 200px;"
-										@change="handleQuery" />
-				</el-form-item>
-				<el-form-item label="鎺掍骇鏃ユ湡:">
-					<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-													placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
-				</el-form-item>
-				<el-form-item label="鐘舵��:">
-					<el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 140px" clearable>
-						<el-option label="寰呯敓浜�" :value="1"></el-option>
-						<el-option label="宸叉姤宸�" :value="3"></el-option>
-						<el-option label="鐢熶骇涓�" :value="2"></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" @click="handleQuery">鎼滅储</el-button>
-				</el-form-item>
-			</el-form>
-		</div>
-		<div class="table_list">
-			<div style="text-align: right" class="mb10">
-				<el-button type="primary" @click="openForm('add')">鐢熶骇鎶ュ伐</el-button>
-				<el-button @click="handleOut">瀵煎嚭</el-button>
-			</div>
-			<PIMTable
-				rowKey="id"
-				:column="tableColumn"
-				:tableData="tableData"
-				:page="page"
-				:isSelection="true"
-				:expandRowKeys="expandedRowKeys"
-				@expand-change="expandChange"
-				@selection-change="handleSelectionChange"
-				:tableLoading="tableLoading"
-				@pagination="pagination"
-				:total="page.total"
-			>
-				<template #expand="{ row }">
-					<el-table
-						:data="expandData"
-						border
-						show-summary
-						:summary-method="summarizeMainTable"
-						v-loading="childrenLoading"
-					>
-						<el-table-column
-							align="center"
-							label="搴忓彿"
-							type="index"
-							width="60"
-						/>
-						<el-table-column label="鏈鐢熶骇鏁伴噺" prop="finishedNum" align="center" width="400">
-							<template #default="scope">
-								<el-input-number :step="0.01" :min="0" style="width: 100%"
-																 v-model="scope.row.finishedNum"
-																 :disabled="!scope.row.editType"
-																 :precision="2"
-																 placeholder="璇疯緭鍏�"
-																 clearable
-																 @change="changeNum(scope.row)"
-								/>
-							</template>
-						</el-table-column>
-<!--						<el-table-column label="寰呯敓浜ф暟閲�" prop="pendingNum" width="240" align="center"></el-table-column>-->
-						<el-table-column label="鐢熶骇浜�" prop="schedulingUserId" width="400">
-							<template #default="scope">
-								<el-select
-									v-model="scope.row.schedulingUserId"
-									placeholder="閫夋嫨浜哄憳"
-									:disabled="!scope.row.editType"
-									style="width: 100%;"
-								>
-									<el-option
-										v-for="user in userList"
-										:key="user.userId"
-										:label="user.nickName"
-										:value="user.userId"
-									/>
-								</el-select>
-							</template>
-						</el-table-column>
-						<el-table-column label="鐢熶骇鏃ユ湡" prop="schedulingDate" width="400">
-							<template #default="scope">
-								<el-date-picker
-									v-model="scope.row.schedulingDate"
-									type="date"
-									:disabled="!scope.row.editType"
-									placeholder="璇烽�夋嫨鏃ユ湡"
-									value-format="YYYY-MM-DD"
-									format="YYYY-MM-DD"
-									clearable
-									style="width: 100%"
-								/>
-							</template>
-						</el-table-column>
-						<el-table-column label="鎿嶄綔" width="60">
-							<template #default="scope">
-								<el-button
-									link
-									type="primary"
-									size="small"
-									@click="changeEditType(scope.row)"
-									v-if="!scope.row.editType"
-								>缂栬緫</el-button
-								>
-								<el-button
-									link
-									type="primary"
-									size="small"
-									@click="saveReceiptPayment(scope.row)"
-									v-if="scope.row.editType"
-								>淇濆瓨</el-button
-								>
-							</template>
-						</el-table-column>
-					</el-table>
-				</template>
-			</PIMTable>
-		</div>
-		<form-dia ref="formDia" @close="handleQuery"></form-dia>
-	</div>
+  <div class="app-container">
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="鎶ュ伐浜哄憳鍚嶇О:">
+          <el-input v-model="searchForm.nickName"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 200px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item label="宸ュ崟鍙�:">
+          <el-input v-model="searchForm.workOrderNo"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    prefix-icon="Search"
+                    style="width: 200px;"
+                    @change="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="table_list">
+      <div style="text-align: right"
+           class="mb10">
+        <!-- <el-button type="primary"
+                   @click="openForm('add')">鐢熶骇鎶ュ伐</el-button> -->
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+      </div>
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :isSelection="true"
+                :expandRowKeys="expandedRowKeys"
+                @expand-change="expandChange"
+                @selection-change="handleSelectionChange"
+                :tableLoading="tableLoading"
+                @pagination="pagination"
+                :total="page.total">
+        <template #expand="{ row }">
+          <el-table :data="expandData"
+                    border
+                    show-summary
+                    :summary-method="summarizeMainTable"
+                    v-loading="childrenLoading">
+            <el-table-column align="center"
+                             label="搴忓彿"
+                             type="index"
+                             width="60" />
+            <el-table-column label="鏈鐢熶骇鏁伴噺"
+                             prop="finishedNum"
+                             align="center"
+                             width="400">
+              <template #default="scope">
+                <el-input-number :step="0.01"
+                                 :min="0"
+                                 style="width: 100%"
+                                 v-model="scope.row.finishedNum"
+                                 :disabled="!scope.row.editType"
+                                 :precision="2"
+                                 placeholder="璇疯緭鍏�"
+                                 clearable
+                                 @change="changeNum(scope.row)" />
+              </template>
+            </el-table-column>
+            <!--						<el-table-column label="寰呯敓浜ф暟閲�" prop="pendingNum" width="240" align="center"></el-table-column>-->
+            <el-table-column label="鐢熶骇浜�"
+                             prop="schedulingUserId"
+                             width="400">
+              <template #default="scope">
+                <el-select v-model="scope.row.schedulingUserId"
+                           placeholder="閫夋嫨浜哄憳"
+                           :disabled="!scope.row.editType"
+                           style="width: 100%;">
+                  <el-option v-for="user in userList"
+                             :key="user.userId"
+                             :label="user.nickName"
+                             :value="user.userId" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="鐢熶骇鏃ユ湡"
+                             prop="schedulingDate"
+                             width="400">
+              <template #default="scope">
+                <el-date-picker v-model="scope.row.schedulingDate"
+                                type="date"
+                                :disabled="!scope.row.editType"
+                                placeholder="璇烽�夋嫨鏃ユ湡"
+                                value-format="YYYY-MM-DD"
+                                format="YYYY-MM-DD"
+                                clearable
+                                style="width: 100%" />
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔"
+                             >
+              <template #default="scope">
+                <el-button link
+                           type="primary"
+                           size="small"
+                           @click="changeEditType(scope.row)"
+                           v-if="!scope.row.editType"
+                           :disabled="scope.row.parentStatus === 3">缂栬緫</el-button>
+                <el-button link
+                           type="primary"
+                           size="small"
+                           @click="saveReceiptPayment(scope.row)"
+                           v-if="scope.row.editType">淇濆瓨</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </PIMTable>
+    </div>
+    <form-dia ref="formDia"
+              @close="handleQuery"></form-dia>
+    <input-modal v-if="isShowInput"
+                 v-model:visible="isShowInput"
+                 :production-product-main-id="isShowingId" />
+  </div>
 </template>
 
 <script setup>
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/productionManagement/productionReporting/components/formDia.vue";
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-import {
-	productionReportUpdate,
-	workListPage,
-	workListPageById
-} from "@/api/productionManagement/productionReporting.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
+  import { onMounted, ref } from "vue";
+  import FormDia from "@/views/productionManagement/productionReporting/components/formDia.vue";
+  import { ElMessageBox } from "element-plus";
+  import {
+    productionReportUpdate,
+    workListPageById,
+    productionReportDelete,
+  } from "@/api/productionManagement/productionReporting.js";
+  import { productionProductMainListPage } from "@/api/productionManagement/productionProductMain.js";
+  import { userListNoPageByTenantId } from "@/api/system/user.js";
+  import InputModal from "@/views/productionManagement/productionReporting/Input.vue";
 
-const data = reactive({
-	searchForm: {
-		staffName: "",
-		entryDate: null, // 褰曞叆鏃ユ湡
-		entryDateStart: undefined,
-		entryDateEnd: undefined,
-	},
-});
-const { searchForm } = toRefs(data);
-const expandedRowKeys = ref([]);
-const expandData = ref([]);
-const userList = ref([])
-const tableColumn = ref([
-	{
-		type: "expand",
-		dataType: "slot",
-		slot: "expand",
-	},
-	{
-		label: "鐘舵��",
-		prop: "status",
-		dataType: "tag",
-		formatData: (params) => {
-			if (params == 3) {
-				return "宸叉姤宸�";
-			} else if (params == 1) {
-				return "寰呯敓浜�";
-			} else {
-				return '鐢熶骇涓�';
-			}
-		},
-		formatType: (params) => {
-			if (params == 3) {
-				return "success";
-			} else if (params == 1) {
-				return "primary";
-			} else {
-				return 'warning';
-			}
-		},
-	},
-	{
-		label: "鎺掍骇鏃ユ湡",
-		prop: "schedulingDate",
-		width: 120,
-	},
-	{
-		label: "鎺掍骇浜�",
-		prop: "schedulingUserName",
-	},
-	{
-		label: "鍚堝悓鍙�",
-		prop: "salesContractNo",
-		width: 200,
-	},
-	{
-		label: "瀹㈡埛鍚堝悓鍙�",
-		prop: "customerContractNo",
-		width: 200,
-	},
-	{
-		label: "瀹㈡埛鍚嶇О",
-		prop: "customerName",
-		width: 200,
-	},
-	{
-		label: "椤圭洰鍚嶇О",
-		prop: "projectName",
-		width:300
-	},
-	{
-		label: "浜у搧澶х被",
-		prop: "productCategory",
-		width: 150,
-	},
-	{
-		label: "瑙勬牸鍨嬪彿",
-		prop: "specificationModel",
-		width: 150,
-	},
-	{
-		label: "鍗曚綅",
-		prop: "unit",
-	},
-	{
-		label: "宸ュ簭",
-		prop: "process",
-	},
-	{
-		label: "鎺掍骇鏁伴噺",
-		prop: "schedulingNum",
-		width: 100,
-	},
-	{
-		label: "鐢熶骇鏁伴噺",
-		prop: "finishedNum",
-		width: 100,
-	},
-	{
-		label: "寰呯敓浜ф暟閲�",
-		prop: "pendingFinishNum",
-		width: 100,
-	},
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const childrenLoading = ref(false);
-const page = reactive({
-	current: 1,
-	size: 100,
-	total: 0,
-});
-const formDia = ref()
-const { proxy } = getCurrentInstance()
+  const data = reactive({
+    searchForm: {
+      nickName: "",
+      workOrderNo: "",
+      workOrderStatus: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
+  const expandedRowKeys = ref([]);
+  const expandData = ref([]);
+  const userList = ref([]);
+  const tableColumn = ref([
+    {
+      label: "鎶ュ伐鍗曞彿",
+      prop: "productNo",
+      width: 120,
+    },
+    {
+      label: "鎶ュ伐浜哄憳",
+      prop: "nickName",
+      width: 120,
+    },
+    {
+      label: "宸ュ崟缂栧彿",
+      prop: "workOrderNo",
+      width: 120,
+    },
+    {
+      label: "閿�鍞悎鍚屽彿",
+      prop: "salesContractNo",
+      width: 120,
+    },
+    {
+      label: "浜у搧鍚嶇О",
+      prop: "productName",
+      width: 120,
+    },
+    {
+      label: "浜у搧瑙勬牸鍨嬪彿",
+      prop: "productModelName",
+      width: 120,
+    },
+    {
+      label: "浜у嚭鏁伴噺",
+      prop: "quantity",
+      width: 120,
+    },
+    {
+      label: "鎶ュ簾鏁伴噺",
+      prop: "scrapQty",
+      width: 120,
+    },
+    {
+      label: "鍗曚綅",
+      prop: "unit",
+      width: 120,
+    },
+    
+    {
+      label: "鍒涘缓鏃堕棿",
+      prop: "createTime",
+      width: 120,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      operation: [
+        {
+          name: "鏌ョ湅鎶曞叆",
+          type: "text",
+          clickFun: row => {
+            showInput(row);
+          },
+        },
+        {
+          name: "鍒犻櫎",
+          type: "danger",
+          clickFun: row => {
+            deleteReport(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const tableLoading = ref(false);
+  const childrenLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+  const formDia = ref();
+  const { proxy } = getCurrentInstance();
 
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-	page.current = 1;
-	getList();
-};
-const changeDaterange = (value) => {
-	if (value) {
-		searchForm.value.entryDateStart = value[0];
-		searchForm.value.entryDateEnd = value[1];
-	} else {
-		searchForm.value.entryDateStart = undefined;
-		searchForm.value.entryDateEnd = undefined;
-	}
-	handleQuery();
-};
-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
-	expandedRowKeys.value = []
-	workListPage(params).then(res => {
-		tableLoading.value = false;
-		tableData.value = res.data.records.map(item => ({
-			...item,
-			pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
-		}));
-		page.total = res.data.total;
-	}).catch(err => {
-		tableLoading.value = false;
-	})
-};
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
-	userListNoPageByTenantId().then((res) => {
-		userList.value = res.data;
-	});
-	if (expandedRows.length > 0) {
-		nextTick(() => {
-			expandedRowKeys.value = [];
-			try {
-				childrenLoading.value = true;
-				workListPageById({ id: row.id }).then((res) => {
-					childrenLoading.value = false;
-					const index = tableData.value.findIndex((item) => item.id === row.id);
-					if (index > -1) {
-						expandData.value = res.data.map(item => ({
-							...item,
-							pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0),
-							parentStatus: row.status // 鏂板鐖惰〃鐘舵��
-						}));
-					}
-					expandedRowKeys.value.push(row.id);
-				});
-			} catch (error) {
-				childrenLoading.value = false;
-				console.log(error);
-			}
-		})
-	} else {
-		expandedRowKeys.value = [];
-	}
-};
-const changeNum = (row) => {
-	// 鎵惧埌鐖惰〃鏍兼暟鎹�
-	const parentRow = tableData.value.find(item => item.id === expandedRowKeys.value[0]);
-	// 璁$畻鎵�鏈夊瓙琛ㄦ牸 finishedNum 鐨勬�诲拰
-	const totalFinishedNum = expandData.value.reduce((sum, item) => sum + (Number(item.finishedNum) || 0), 0);
-	// 鐖惰〃鏍肩殑鎺掍骇鏁伴噺
-	const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0;
-	
-	if (totalFinishedNum > schedulingNum) {
-		// 鍥為��鏈杈撳叆
-		row.finishedNum = schedulingNum - (totalFinishedNum - Number(row.finishedNum));
-		proxy.$modal.msgWarning('鎵�鏈夋湰娆$敓浜ф暟閲忎箣鍜屼笉鍙ぇ浜庢帓浜ф暟閲�');
-	}
-	row.pendingNum = row.schedulingNum - row.finishedNum;
-}
-// 缂栬緫淇敼鐘舵��
-const changeEditType = (row) => {
-	row.editType = !row.editType;
-};
-// 淇濆瓨璁板綍
-const saveReceiptPayment = (row) => {
-	productionReportUpdate(row).then((res) => {
-		row.editType = !row.editType;
-		getList();
-		proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-	});
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-	selectedRows.value = selection;
-};
-const summarizeMainTable = (param) => {
-	return proxy.summarizeTable(param, [
-		"finishedNum"
-	]);
-};
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-	if (selectedRows.value.length !== 1) {
-		proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
-		return;
-	}
-	if (selectedRows.value[0].pendingFinishNum == 0) {
-		proxy.$message.warning("鏃犻渶鍐嶆姤宸�");
-		return;
-	}
-	nextTick(() => {
-		const rowInfo = type === 'add' ? selectedRows.value[0] : row
-		formDia.value?.openDialog(type, rowInfo)
-	})
-};
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const changeDaterange = value => {
+    if (value) {
+      searchForm.value.entryDateStart = value[0];
+      searchForm.value.entryDateEnd = value[1];
+    } else {
+      searchForm.value.entryDateStart = undefined;
+      searchForm.value.entryDateEnd = undefined;
+    }
+    handleQuery();
+  };
+  const deleteReport = row => {
+    ElMessageBox.confirm("纭畾鍒犻櫎璇ユ姤宸ュ悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      productionReportDelete({ id: row.id }).then(res => {
+        if (res.code === 200) {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        } else {
+          ElMessageBox.alert(res.msg || "鍒犻櫎澶辫触", "鎻愮ず", {
+            confirmButtonText: "纭畾",
+          });
+        }
+      });
+    });
+  };
+  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;
+    expandedRowKeys.value = [];
+    productionProductMainListPage(params)
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records.map(item => ({
+          ...item,
+          pendingFinishNum:
+            (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0),
+        }));
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+  // 灞曞紑琛�
+  const expandChange = (row, expandedRows) => {
+    userListNoPageByTenantId().then(res => {
+      userList.value = res.data;
+    });
+    if (expandedRows.length > 0) {
+      nextTick(() => {
+        expandedRowKeys.value = [];
+        try {
+          childrenLoading.value = true;
+          workListPageById({ id: row.id }).then(res => {
+            childrenLoading.value = false;
+            const index = tableData.value.findIndex(item => item.id === row.id);
+            if (index > -1) {
+              expandData.value = res.data.map(item => ({
+                ...item,
+                pendingNum:
+                  (Number(item.schedulingNum) || 0) -
+                  (Number(item.finishedNum) || 0),
+                parentStatus: row.status, // 鏂板鐖惰〃鐘舵��
+              }));
+            }
+            expandedRowKeys.value.push(row.id);
+          });
+        } catch (error) {
+          childrenLoading.value = false;
+          console.log(error);
+        }
+      });
+    } else {
+      expandedRowKeys.value = [];
+    }
+  };
+  const changeNum = row => {
+    // 鎵惧埌鐖惰〃鏍兼暟鎹�
+    const parentRow = tableData.value.find(
+      item => item.id === expandedRowKeys.value[0]
+    );
+    // 璁$畻鎵�鏈夊瓙琛ㄦ牸 finishedNum 鐨勬�诲拰
+    const totalFinishedNum = expandData.value.reduce(
+      (sum, item) => sum + (Number(item.finishedNum) || 0),
+      0
+    );
+    // 鐖惰〃鏍肩殑鎺掍骇鏁伴噺
+    const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0;
 
-// 鍒犻櫎
-const handleDelete = () => {
-	let ids = [];
-	if (selectedRows.value.length > 0) {
-		ids = selectedRows.value.map((item) => item.id);
-	} else {
-		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-		return;
-	}
-	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-		confirmButtonText: "纭",
-		cancelButtonText: "鍙栨秷",
-		type: "warning",
-	})
-		.then(() => {
-			staffJoinDel(ids).then((res) => {
-				proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-				getList();
-			});
-		})
-		.catch(() => {
-			proxy.$modal.msg("宸插彇娑�");
-		});
-};
-// 瀵煎嚭
-const handleOut = () => {
-	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-		confirmButtonText: "纭",
-		cancelButtonText: "鍙栨秷",
-		type: "warning",
-	})
-		.then(() => {
-			proxy.download("/salesLedger/work/export", {}, "鐢熶骇鎶ュ伐.xlsx");
-		})
-		.catch(() => {
-			proxy.$modal.msg("宸插彇娑�");
-		});
-};
-onMounted(() => {
-	getList();
-});
+    if (totalFinishedNum > schedulingNum) {
+      // 鍥為��鏈杈撳叆
+      row.finishedNum =
+        schedulingNum - (totalFinishedNum - Number(row.finishedNum));
+      proxy.$modal.msgWarning("鎵�鏈夋湰娆$敓浜ф暟閲忎箣鍜屼笉鍙ぇ浜庢帓浜ф暟閲�");
+    }
+    row.pendingNum = row.schedulingNum - row.finishedNum;
+  };
+  // 缂栬緫淇敼鐘舵��
+  const changeEditType = row => {
+    row.editType = !row.editType;
+  };
+  // 淇濆瓨璁板綍
+  const saveReceiptPayment = row => {
+    productionReportUpdate(row).then(res => {
+      row.editType = !row.editType;
+      getList();
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+    });
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  const summarizeMainTable = param => {
+    return proxy.summarizeTable(param, ["finishedNum"]);
+  };
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    if (selectedRows.value.length !== 1) {
+      proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
+      return;
+    }
+    if (selectedRows.value[0].pendingFinishNum == 0) {
+      proxy.$message.warning("鏃犻渶鍐嶆姤宸�");
+      return;
+    }
+    nextTick(() => {
+      const rowInfo = type === "add" ? selectedRows.value[0] : row;
+      formDia.value?.openDialog(type, rowInfo);
+    });
+  };
+
+  // 鎵撳紑鎶曞叆妯℃�佹
+  const isShowInput = ref(false);
+  const isShowingId = ref(0);
+  const showInput = row => {
+    isShowInput.value = true;
+    isShowingId.value = row.id;
+  };
+
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download("/productionProductMain/export", {}, "鐢熶骇鎶ュ伐.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  onMounted(() => {
+    getList();
+  });
 </script>
 
 <style scoped></style>
diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
new file mode 100644
index 0000000..de91893
--- /dev/null
+++ b/src/views/productionManagement/workOrder/index.vue
@@ -0,0 +1,653 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div class="search-row">
+        <div class="search-item">
+          <span class="search_title">宸ュ崟缂栧彿锛�</span>
+          <el-input v-model="searchForm.workOrderNo"
+                    style="width: 240px"
+                    placeholder="璇疯緭鍏�"
+                    @change="handleQuery"
+                    clearable
+                    prefix-icon="Search" />
+        </div>
+        <div class="search-item">
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+        </div>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :tableLoading="tableLoading"
+                @pagination="pagination">
+                <template #completionStatus="{ row }">
+                  <el-progress :percentage="toProgressPercentage(row?.completionStatus)" :color="progressColor(toProgressPercentage(row?.completionStatus))" :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
+                </template>
+              </PIMTable>
+    </div>
+    <el-dialog v-model="editDialogVisible"
+               title="缂栬緫鏃堕棿"
+               width="500px">
+      <el-form :model="editrow"
+               label-width="120px">
+        <el-form-item label="璁″垝寮�濮嬫椂闂�">
+          <el-date-picker v-model="editrow.planStartTime"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 300px" />
+        </el-form-item>
+        <el-form-item label="璁″垝缁撴潫鏃堕棿">
+          <el-date-picker v-model="editrow.planEndTime"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 300px" />
+        </el-form-item>
+        <el-form-item label="瀹為檯寮�濮嬫椂闂�">
+          <el-date-picker v-model="editrow.actualStartTime"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 300px" />
+        </el-form-item>
+        <el-form-item label="瀹為檯缁撴潫鏃堕棿">
+          <el-date-picker v-model="editrow.actualEndTime"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 300px" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary"
+                     @click="handleUpdate">纭畾</el-button>
+          <el-button @click="editDialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="transferCardVisible"
+               title="娴佽浆鍗�"
+               width="1000px">
+      <div class="transfer-card-title">宸ュ崟娴佽浆鍗�</div>
+      <div class="transfer-card-container">
+        <div class="transfer-card-info">
+          <div class="info-group">
+            <div class="info-item">
+              <span class="info-label">宸ュ崟缂栧彿</span>
+              <span class="info-value">{{ transferCardRowData.workOrderNo }}</span>
+            </div>
+            <!-- <div class="info-item">
+              <span class="info-label">浜у搧缂栧彿</span>
+              <span class="info-value">{{ transferCardRowData.productNo }}</span>
+            </div> -->
+            <div class="info-item">
+              <span class="info-label">浜у搧鍚嶇О</span>
+              <span class="info-value">{{ transferCardRowData.productName }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">浜у搧瑙勬牸</span>
+              <span class="info-value">{{ transferCardRowData.model }}</span>
+            </div>
+            <!-- <div class="info-item">
+              <span class="info-label">宸ュ崟鐘舵��</span>
+              <span class="info-value">{{ 
+                transferCardRowData.status === 1 ? '寰呯‘璁�' : 
+                transferCardRowData.status === 2 ? '寰呯敓浜�' : 
+                transferCardRowData.status === 3 ? '鐢熶骇涓�' : 
+                transferCardRowData.status === 4 ? '宸茬敓浜�' : 
+                transferCardRowData.status 
+              }}</span>
+            </div> -->
+           
+            <div class="info-item">
+              <span class="info-label">璁″垝寮�濮嬫椂闂�</span>
+              <span class="info-value">{{ transferCardRowData.planStartTime }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">璁″垝缁撴潫鏃堕棿</span>
+              <span class="info-value">{{ transferCardRowData.planEndTime }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">澶囨敞</span>
+              <span class="info-value">{{ transferCardRowData.remark }}</span>
+            </div>
+          </div>
+          <div class="info-group">
+            <div class="info-item">
+              <span class="info-label">闇�姹傛暟閲�</span>
+              <span class="info-value">{{ transferCardRowData.planQuantity }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">瀹屾垚鏁伴噺</span>
+              <span class="info-value">{{ transferCardRowData.completeQuantity }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">鑹搧鏁伴噺</span>
+              <span class="info-value">0</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">涓嶈壇鍝佹暟</span>
+              <span class="info-value">0</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">瀹為檯寮�濮嬫椂闂�</span>
+              <span class="info-value">{{ transferCardRowData.actualStartTime }}</span>
+            </div>
+            <div class="info-item">
+              <span class="info-label">瀹為檯缁撴潫鏃堕棿</span>
+              <span class="info-value">{{ transferCardRowData.actualEndTime }}</span>
+            </div>
+          </div>
+        </div>
+        <div class="transfer-card-qr">
+          <div class="qr-container">
+            <img :src="transferCardQrUrl"
+                 alt="娴佽浆鍗′簩缁寸爜"
+                 style="width: 200px; height: 200px;" />
+            <!-- <div class="qr-tip"
+                 style="margin-top: 10px; text-align: center;">娴佽浆鍗′簩缁寸爜</div> -->
+          </div>
+        </div>
+      </div>
+      <div class="print-button-container"
+           style=" text-align: center;
+      margin-bottom: 40px;">
+        <el-button type="primary"
+                   style="margin-top: 20px;"
+                   @click="printTransferCard">鎵撳嵃娴佽浆鍗�</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog v-model="reportDialogVisible"
+               title="鎶ュ伐"
+               width="500px">
+      <el-form :model="reportForm"
+               label-width="120px">
+        <el-form-item label="寰呯敓浜ф暟閲�">
+          <el-input v-model="reportForm.planQuantity"
+                    readonly
+                    style="width: 300px" />
+        </el-form-item>
+        <el-form-item label="鏈鐢熶骇鏁伴噺">
+          <el-input v-model.number="reportForm.quantity"
+                    type="number"
+                    min="1"
+                    style="width: 300px"
+                    placeholder="璇疯緭鍏ユ湰娆$敓浜ф暟閲�" />
+        </el-form-item>
+        <el-form-item label="鎶ュ簾鏁伴噺">
+          <el-input v-model.number="reportForm.scrapQty"
+                    type="number"
+                    min="1"
+                    style="width: 300px"
+                    placeholder="璇疯緭鍏ユ姤搴熸暟閲�" />
+        </el-form-item>
+        <el-form-item label="鐝粍淇℃伅">
+          <el-select v-model="reportForm.userId"
+                     style="width: 300px"
+                     placeholder="璇烽�夋嫨鐝粍淇℃伅"
+                     clearable
+                     filterable
+                     @change="handleUserChange">
+            <el-option v-for="user in userOptions"
+                       :key="user.userId"
+                       :label="user.userName"
+                       :value="user.userId" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary"
+                     @click="handleReport">纭畾</el-button>
+          <el-button @click="reportDialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import dayjs from "dayjs";
+  import {
+    productWorkOrderPage,
+    updateProductWorkOrder,
+    addProductMain,
+  } from "@/api/productionManagement/workOrder.js";
+  import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js";
+  import QRCode from "qrcode";
+  import { getCurrentInstance, reactive, toRefs } from "vue";
+  const { proxy } = getCurrentInstance();
+
+  const tableColumn = ref([
+    {
+      label: "宸ュ崟缂栧彿",
+      prop: "workOrderNo",
+      width: "140",
+    },
+    {
+      label: "鐢熶骇璁㈠崟鍙�",
+      prop: "productOrderNpsNo",
+      width: "140",
+    },
+    {
+      label: "浜у搧鍚嶇О",
+      prop: "productName",
+      width: "140",
+    },
+    {
+      label: "瑙勬牸",
+      prop: "model",
+    },
+    {
+      label: "鍗曚綅",
+      prop: "unit",
+    },
+    {
+      label: "宸ュ簭鍚嶇О",
+      prop: "processName",
+    },
+    {
+      label: "闇�姹傛暟閲�",
+      prop: "planQuantity",
+      width: "140",
+    },
+    {
+      label: "瀹屾垚鏁伴噺",
+      prop: "completeQuantity",
+      width: "140",
+    },
+    {
+      label: "瀹屾垚杩涘害",
+      prop: "completionStatus",
+      dataType: "slot",
+      slot: "completionStatus",
+      width: "140",
+    },
+    {
+      label: "璁″垝寮�濮嬫椂闂�",
+      prop: "planStartTime",
+      width: "140",
+    },
+    {
+      label: "璁″垝缁撴潫鏃堕棿",
+      prop: "planEndTime",
+      width: "140",
+    },
+    {
+      label: "瀹為檯寮�濮嬫椂闂�",
+      prop: "actualStartTime",
+      width: "140",
+    },
+    {
+      label: "瀹為檯缁撴潫鏃堕棿",
+      prop: "actualEndTime",
+      width: "140",
+    },
+    {
+      label: "鎿嶄綔",
+      width: "200",
+      align: "center",
+      dataType: "action",
+      fixed: "right",
+      operation: [
+        {
+          name: "缂栬緫",
+          clickFun: row => {
+            handleEdit(row);
+          },
+        },
+        {
+          name: "娴佽浆鍗�",
+          clickFun: row => {
+            showTransferCard(row);
+          },
+        },
+        {
+          name: "鎶ュ伐",
+          clickFun: row => {
+            showReportDialog(row);
+          },
+          disabled: row => row.planQuantity <= 0,
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  const qrCodeUrl = ref("");
+  const qrRowData = ref(null);
+  const editDialogVisible = ref(false);
+  const transferCardVisible = ref(false);
+  const transferCardData = ref([]);
+  const transferCardQrUrl = ref("");
+  const transferCardRowData = ref(null);
+  const reportDialogVisible = ref(false);
+  const userOptions = ref([]);
+  const reportForm = reactive({
+    planQuantity: 0,
+    quantity: 0,
+    userName: "",
+    workOrderId: "",
+    reportWork: "",
+    productProcessRouteItemId: "",
+    userId: "",
+    productMainId: null,
+  });
+  const currentReportRowData = ref(null);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+
+  const data = reactive({
+    searchForm: {
+      workOrderNo: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
+  const toProgressPercentage = val => {
+    const n = Number(val);
+    if (!Number.isFinite(n)) return 0;
+    if (n <= 0) return 0;
+    if (n >= 100) return 100;
+    return Math.round(n);
+  };
+  const progressColor = percentage => {
+    const p = toProgressPercentage(percentage);
+    if (p < 30) return "#f56c6c";
+    if (p < 50) return "#e6a23c";
+    if (p < 80) return "#409eff";
+    return "#67c23a";
+  };
+  let editrow = ref(null);
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  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 };
+    productWorkOrderPage(params)
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(() => {
+        tableLoading.value = false;
+      });
+  };
+
+  const showTransferCard = async row => {
+    transferCardRowData.value = row;
+    const qrContent = String(row.id);
+
+    transferCardQrUrl.value = await QRCode.toDataURL(qrContent);
+    transferCardVisible.value = true;
+  };
+
+  const printTransferCard = () => {
+    window.print();
+  };
+
+  const handleEdit = row => {
+    editrow.value = JSON.parse(JSON.stringify(row));
+    editDialogVisible.value = true;
+  };
+
+  const handleUpdate = () => {
+    updateProductWorkOrder(editrow.value)
+      .then(res => {
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+        editDialogVisible.value = false;
+        getList();
+      })
+      .catch(() => {
+        ElMessageBox.alert("淇敼澶辫触", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+      });
+  };
+
+  const showReportDialog = row => {
+    currentReportRowData.value = row;
+    reportForm.planQuantity = row.planQuantity;
+    reportForm.quantity = row.quantity;
+    reportForm.productProcessRouteItemId = row.productProcessRouteItemId;
+    reportForm.workOrderId = row.id;
+    reportForm.reportWork = row.reportWork;
+    reportForm.productMainId = row.productMainId;
+    reportForm.scrapQty = row.scrapQty;
+    // 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛淇℃伅锛岃缃负榛樿閫変腑
+    getUserProfile()
+      .then(res => {
+        if (res.code === 200) {
+          reportForm.userId = res.data.userId;
+          reportForm.userName = res.data.userName;
+        }
+      })
+      .catch(err => {
+        console.error("鑾峰彇鐢ㄦ埛淇℃伅澶辫触", err);
+      });
+
+    reportDialogVisible.value = true;
+  };
+
+  const handleReport = () => {
+    if (reportForm.planQuantity <= 0) {
+      ElMessageBox.alert("寰呯敓浜ф暟閲忎负0锛屾棤娉曟姤宸�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+      });
+      return;
+    }
+    if (!reportForm.quantity || reportForm.quantity <= 0) {
+      ElMessageBox.alert("璇疯緭鍏ユ湁鏁堢殑鏈鐢熶骇鏁伴噺", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+      });
+      return;
+    }
+    if (reportForm.quantity > reportForm.planQuantity) {
+      ElMessageBox.alert("鏈鐢熶骇鏁伴噺涓嶈兘瓒呰繃寰呯敓浜ф暟閲�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+      });
+      return;
+    }
+    // console.log(reportForm);
+    addProductMain(reportForm).then(res => {
+      if (res.code === 200) {
+        proxy.$modal.msgSuccess("鎶ュ伐鎴愬姛");
+        reportDialogVisible.value = false;
+        getList();
+      } else {
+        ElMessageBox.alert(res.msg || "鎶ュ伐澶辫触", "鎻愮ず", {
+          confirmButtonText: "纭畾",
+        });
+      }
+    });
+  };
+
+  // 鑾峰彇鐢ㄦ埛鍒楄〃
+  const getUserList = () => {
+    userListNoPageByTenantId()
+      .then(res => {
+        if (res.code === 200) {
+          userOptions.value = res.data || [];
+        }
+      })
+      .catch(err => {
+        console.error("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触", err);
+      });
+  };
+
+  // 鐢ㄦ埛閫夋嫨鍙樺寲鏃舵洿鏂� userName
+  const handleUserChange = (userId) => {
+    if (userId) {
+      const selectedUser = userOptions.value.find(user => user.userId === userId);
+      if (selectedUser) {
+        reportForm.userName = selectedUser.userName;
+      }
+    } else {
+      reportForm.userName = "";
+    }
+  };
+
+  onMounted(() => {
+    getList();
+    getUserList();
+  });
+</script>
+
+<style scoped lang="scss">
+  .search_form {
+    margin-bottom: 20px;
+    .search-row {
+      display: flex;
+      gap: 20px;
+      align-items: center;
+      .search-item {
+        display: flex;
+        align-items: center;
+        gap: 10px;
+      }
+    }
+  }
+
+  .transfer-card-title {
+    font-size: 24px;
+    font-weight: bold;
+    text-align: center;
+    margin-bottom: 20px;
+  }
+
+  .transfer-card-container {
+    display: flex;
+    gap: 20px;
+    height: 350px;
+    .transfer-card-info {
+      flex: 1;
+      overflow: auto;
+      .info-group {
+        width: 50%;
+        float: left;
+      }
+      .info-item {
+        display: flex;
+        margin-bottom: 15px;
+        .info-label {
+          width: 120px;
+          font-weight: bold;
+          margin-right: 20px;
+        }
+        .info-value {
+          flex: 1;
+        }
+      }
+    }
+    .transfer-card-qr {
+      width: 240px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: flex-start;
+    }
+  }
+</style>
+
+<style  lang="scss">
+  @media print {
+    @page {
+      size: landscape;
+    }
+    body * {
+      visibility: hidden;
+    }
+    .el-dialog__wrapper,
+    .el-dialog,
+    .el-dialog__body,
+    .transfer-card-title,
+    .transfer-card-container,
+    .transfer-card-container *,
+    .info-item,
+    .info-label,
+    .info-value {
+      visibility: visible;
+    }
+    .print-button-container {
+      visibility: hidden;
+    }
+    .el-dialog__wrapper {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      margin: 0;
+    }
+    .el-dialog {
+      width: 100% !important;
+      max-width: 800px;
+      margin: 0 auto !important;
+    }
+    .el-dialog__header,
+    .el-dialog__footer {
+      display: none;
+    }
+    .el-dialog__body {
+      padding: 20px;
+    }
+    .transfer-card-container {
+      height: auto;
+      display: flex;
+      gap: 20px;
+    }
+    .transfer-card-info {
+      flex: 1;
+      .info-group {
+        width: 100%;
+        float: none;
+        margin-bottom: 20px;
+      }
+      .info-item {
+        display: flex;
+        margin-bottom: 10px;
+        .info-label {
+          width: 100px;
+          font-weight: bold;
+          margin-right: 15px;
+          white-space: nowrap;
+        }
+        .info-value {
+          flex: 1;
+          word-break: break-word;
+        }
+      }
+    }
+    .transfer-card-qr {
+      width: 160px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: flex-start;
+    }
+    .qr-container img {
+      width: 140px !important;
+      height: 140px !important;
+    }
+  }
+</style>
diff --git a/src/views/qualityManagement/finalInspection/components/filesDia.vue b/src/views/qualityManagement/finalInspection/components/filesDia.vue
index 66392f3..51dd78f 100644
--- a/src/views/qualityManagement/finalInspection/components/filesDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/filesDia.vue
@@ -51,7 +51,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 057781c..ec0cb42 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -27,6 +27,24 @@
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
@@ -101,12 +119,12 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
 import {userListNoPage} from "@/api/system/user.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -121,6 +139,7 @@
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -132,6 +151,7 @@
     checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    testStandardId: [{required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -169,6 +189,7 @@
 const tableLoading = ref(false);
 const userList = ref([]);
 const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
 
 // 鎵撳紑寮规
 const openDialog = async (type, row) => {
@@ -180,11 +201,54 @@
 	let userLists = await userListNoPage();
 	userList.value = userLists.data;
 	form.value = {}
+  testStandardOptions.value = [];
+  tableData.value = [];
   getProductOptions();
   if (operationType.value === 'edit') {
-    form.value = {...row}
+    // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+    const savedTestStandardId = row.testStandardId;
+    // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+    form.value = {...row, testStandardId: ''}
 		currentProductId.value = row.productId || 0
-		getQualityInspectParamList(row.id)
+		// 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+		if (currentProductId.value) {
+			// 鍏堝姞杞芥寚鏍囬�夐」
+			let params = {
+				productId: currentProductId.value,
+				inspectType: 2
+			}
+			qualityInspectDetailByProductId(params).then(res => {
+				testStandardOptions.value = res.data || [];
+				// 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+				nextTick(() => {
+					setTimeout(() => {
+						// 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+						if (savedTestStandardId) {
+							// 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+							const matchedOption = testStandardOptions.value.find(item => 
+								item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+							);
+							if (matchedOption) {
+								// 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+								form.value.testStandardId = matchedOption.id;
+								// 缂栬緫鍦烘櫙淇濈暀宸叉湁妫�楠屽�硷紝鐩存帴鎷夊彇鍘熷弬鏁版暟鎹�
+								getQualityInspectParamList(row.id);
+							} else {
+								// 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+								console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+								form.value.testStandardId = savedTestStandardId;
+								getQualityInspectParamList(row.id);
+							}
+						} else {
+							// 鍚﹀垯浣跨敤鏃х殑閫昏緫
+							getQualityInspectParamList(row.id);
+						}
+					}, 100);
+				});
+			});
+		} else {
+			getQualityInspectParamList(row.id);
+		}
   }
 }
 const getProductOptions = () => {
@@ -195,7 +259,7 @@
 const getModels = (value) => {
 	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-	if (currentProductId) {
+	if (currentProductId.value) {
 		getList();
 	}
 };
@@ -253,9 +317,40 @@
   })
 }
 const getList = () => {
-	qualityInspectDetailByProductId(currentProductId.value).then(res => {
-		tableData.value = res.data;
+  if (!currentProductId.value) {
+    testStandardOptions.value = [];
+    tableData.value = [];
+    return;
+  }
+  let params = {
+    productId: currentProductId.value,
+    inspectType: 2
+  }
+	qualityInspectDetailByProductId(params).then(res => {
+		// 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+		testStandardOptions.value = res.data || [];
+		// 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+		tableData.value = [];
+		// 娓呯┖鎸囨爣閫夋嫨
+		form.value.testStandardId = '';
 	})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+  if (!testStandardId) {
+    tableData.value = [];
+    return;
+  }
+  tableLoading.value = true;
+  getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+    tableData.value = res.data || [];
+  }).catch(error => {
+    console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+    tableData.value = [];
+  }).finally(() => {
+    tableLoading.value = false;
+  })
 }
 const getQualityInspectParamList = (id) => {
 	qualityInspectParamInfo(id).then(res => {
@@ -265,6 +360,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
new file mode 100644
index 0000000..ac67474
--- /dev/null
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -0,0 +1,504 @@
+<template>
+  <div class="app-container metric-binding">
+    <!-- 宸︿晶锛氭娴嬫爣鍑嗗垪琛紙鍙锛� -->
+    <div class="left-panel">
+      <PIMTable
+        rowKey="id"
+        :column="standardColumns"
+        :tableData="standardTableData"
+        :page="page"
+        :isSelection="false"
+        :rowClassName="rowClassNameCenter"
+        :tableLoading="tableLoading"
+        :rowClick="handleTableRowClick"
+        @pagination="handlePagination"
+        :total="page.total"
+      >
+        <template #standardNoCell="{ row }">
+          <span class="clickable-link" @click="handleStandardRowClick(row)">
+            {{ row.standardNo }}
+          </span>
+        </template>
+
+        <!-- 琛ㄥご鎼滅储 -->
+        <template #standardNoHeader>
+          <el-input
+            v-model="searchForm.standardNo"
+            placeholder="鏍囧噯缂栧彿"
+            clearable
+            size="small"
+            @change="handleQuery"
+            @clear="handleQuery"
+          />
+        </template>
+        <template #standardNameHeader>
+          <el-input
+            v-model="searchForm.standardName"
+            placeholder="鏍囧噯鍚嶇О"
+            clearable
+            size="small"
+            @change="handleQuery"
+            @clear="handleQuery"
+          />
+        </template>
+        <template #inspectTypeHeader>
+          <el-select
+            v-model="searchForm.inspectType"
+            placeholder="绫诲埆"
+            clearable
+            size="small"
+            style="width: 120px"
+            @change="handleQuery"
+            @clear="handleQuery"
+          >
+            <el-option label="鍘熸潗鏂欐楠�" value="0" />
+            <el-option label="杩囩▼妫�楠�" value="1" />
+            <el-option label="鍑哄巶妫�楠�" value="2" />
+          </el-select>
+        </template>
+        <template #stateHeader>
+          <el-select
+            v-model="searchForm.state"
+            placeholder="鐘舵��"
+            clearable
+            size="small"
+            style="width: 110px"
+            @change="handleQuery"
+            @clear="handleQuery"
+          >
+            <el-option label="鑽夌" value="0" />
+            <el-option label="閫氳繃" value="1" />
+            <el-option label="鎾ら攢" value="2" />
+          </el-select>
+        </template>
+      </PIMTable>
+    </div>
+
+    <!-- 鍙充晶锛氱粦瀹氬垪琛� -->
+    <div class="right-panel">
+      <div class="right-header">
+        <div class="title">缁戝畾鍏崇郴</div>
+        <div class="desc" v-if="currentStandard">
+          褰撳墠妫�娴嬫爣鍑嗙紪鍙凤細<span class="link-text">{{ currentStandard.standardNo }}</span>
+        </div>
+        <div class="desc" v-else>璇烽�夋嫨宸︿晶妫�娴嬫爣鍑�</div>
+      </div>
+
+      <div class="right-toolbar">
+        <el-button type="primary" :disabled="!currentStandard" @click="openBindingDialog">娣诲姞缁戝畾</el-button>
+        <el-button type="danger" plain :disabled="!currentStandard" @click="handleBatchUnbind">鍒犻櫎</el-button>
+      </div>
+
+      <el-table
+        v-loading="bindingLoading"
+        :data="bindingTableData"
+        border
+        :row-class-name="() => 'row-center'"
+        class="center-table"
+        style="width: 100%"
+        height="calc(100vh - 220px)"
+        @selection-change="handleBindingSelectionChange"
+      >
+        <el-table-column type="selection" width="48" align="center" />
+        <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+        <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="140" />
+        <el-table-column label="鎿嶄綔" width="120" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="danger" size="small" @click="handleUnbind(row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 娣诲姞缁戝畾寮规 -->
+    <el-dialog
+      v-model="bindingDialogVisible"
+      title="娣诲姞缁戝畾"
+      width="520px"
+      @close="closeBindingDialog"
+    >
+      <el-form label-width="100px">
+        <el-form-item label="浜у搧">
+          <el-tree-select
+            v-model="selectedProductIds"
+            multiple
+            collapse-tags
+            collapse-tags-tooltip
+            placeholder="璇烽�夋嫨浜у搧锛堝彲澶氶�夛級"
+            clearable
+            check-strictly
+            :data="productOptions"
+            :render-after-expand="false"
+            style="width: 100%"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="closeBindingDialog">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitBinding">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from '@element-plus/icons-vue'
+import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
+import { ElMessageBox } from 'element-plus'
+import PIMTable from '@/components/PIMTable/PIMTable.vue'
+import { productTreeList } from '@/api/basicData/product.js'
+import {
+  qualityTestStandardListPage
+} from '@/api/qualityManagement/metricMaintenance.js'
+import { productProcessListPage } from '@/api/basicData/productProcess.js'
+import {
+  qualityTestStandardBindingList,
+  qualityTestStandardBindingAdd,
+  qualityTestStandardBindingDel
+} from '@/api/qualityManagement/qualityTestStandardBinding.js'
+
+const { proxy } = getCurrentInstance()
+
+// 宸︿晶鏍囧噯鍒楄〃锛氭暣琛屽唴瀹瑰眳涓紙閰嶅悎鏍峰紡锛�
+const rowClassNameCenter = () => 'row-center'
+
+const data = reactive({
+  searchForm: {
+    standardNo: '',
+    standardName: '',
+    state: '',
+    inspectType: ''
+  }
+})
+const { searchForm } = toRefs(data)
+
+// 宸︿晶
+const standardTableData = ref([])
+const tableLoading = ref(false)
+const page = reactive({ current: 1, size: 10, total: 0 })
+
+// 宸ュ簭涓嬫媺锛堢敤浜庡垪琛ㄥ洖鏄撅級
+const processOptions = ref([])
+
+const getProcessList = async () => {
+  try {
+    const res = await productProcessListPage({ current: 1, size: 1000 })
+    if (res?.code === 200) {
+      const records = res?.data?.records || []
+      processOptions.value = records.map((item) => ({
+        label: item.processName || item.name || item.label,
+        value: item.id || item.processId || item.value
+      }))
+    }
+  } catch (error) {
+    console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+  }
+}
+
+const standardColumns = ref([
+  { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
+  { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
+  {
+    label: '绫诲埆',
+    prop: 'inspectType',
+    headerSlot: 'inspectTypeHeader',
+    align: 'center',
+    dataType: 'tag',
+    formatData: (val) => {
+      const map = { 0: '鍘熸潗鏂欐楠�', 1: '杩囩▼妫�楠�', 2: '鍑哄巶妫�楠�' }
+      return map[val] || val
+    }
+  },
+  {
+    label: '宸ュ簭',
+    prop: 'processId',
+    align: 'center',
+    dataType: 'tag',
+    formatData: (val) => {
+      const target = processOptions.value.find(
+        (item) => String(item.value) === String(val)
+      )
+      return target?.label || val
+    }
+  },
+  {
+    label: '澶囨敞',
+    prop: 'remark',
+    minWidth: 160,
+    align: 'center'
+  }
+  // {
+  //   label: '鐘舵��',
+  //   prop: 'state',
+  //   headerSlot: 'stateHeader',
+  //   dataType: 'tag',
+  //   formatData: (val) => {
+  //     const map = { 0: '鑽夌', 1: '閫氳繃', 2: '鎾ら攢' }
+  //     return map[val] || val
+  //   },
+  //   formatType: (val) => {
+  //     if (val == 1) return 'success'
+  //     if (val == 2) return 'warning'
+  //     return 'info'
+  //   }
+  // }
+])
+
+const currentStandard = ref(null)
+
+// 鍙充晶缁戝畾
+const bindingTableData = ref([])
+const bindingLoading = ref(false)
+const bindingSelectedRows = ref([])
+const bindingDialogVisible = ref(false)
+
+// 浜у搧鏍戯紙鐢ㄤ簬缁戝畾閫夋嫨锛�
+const productOptions = ref([])
+const selectedProductIds = ref([])
+
+const getProductOptions = async () => {
+  // 閬垮厤閲嶅璇锋眰
+  if (productOptions.value?.length) return
+  const res = await productTreeList()
+  productOptions.value = convertIdToValue(Array.isArray(res) ? res : [])
+}
+
+function convertIdToValue(data) {
+  return (data || []).map((item) => {
+    const { id, children, ...rest } = item
+    const newItem = {
+      ...rest,
+      value: id
+    }
+    if (children && children.length > 0) {
+      newItem.children = convertIdToValue(children)
+    }
+    return newItem
+  })
+}
+
+const handleQuery = () => {
+  page.current = 1
+  getStandardList()
+}
+
+const handlePagination = (obj) => {
+  page.current = obj.page
+  page.size = obj.limit
+  getStandardList()
+}
+
+const getStandardList = () => {
+  tableLoading.value = true
+  qualityTestStandardListPage({
+    ...searchForm.value,
+    current: page.current,
+    size: page.size,
+    state: 1
+  })
+    .then((res) => {
+      const records = res?.data?.records || []
+      standardTableData.value = records
+      page.total = res?.data?.total || records.length
+    })
+    .finally(() => {
+      tableLoading.value = false
+    })
+}
+
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
+const handleTableRowClick = (row) => {
+  currentStandard.value = row
+  loadBindingList()
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
+const handleStandardRowClick = (row) => {
+  currentStandard.value = row
+  loadBindingList()
+}
+
+const loadBindingList = () => {
+  if (!currentStandard.value?.id) {
+    bindingTableData.value = []
+    return
+  }
+  bindingLoading.value = true
+  qualityTestStandardBindingList({ testStandardId: currentStandard.value.id })
+    .then((res) => {
+      const base = res?.data || []
+      // 灏嗗綋鍓嶆爣鍑嗙殑宸ュ簭鍜屽娉ㄥ甫鍒扮粦瀹氬垪琛ㄤ腑灞曠ず
+      bindingTableData.value = base.map((item) => ({
+        ...item,
+        processId: currentStandard.value?.processId,
+        remark: currentStandard.value?.remark
+      }))
+    })
+    .finally(() => {
+      bindingLoading.value = false
+    })
+}
+
+const handleBindingSelectionChange = (selection) => {
+  bindingSelectedRows.value = selection
+}
+
+const openBindingDialog = () => {
+  if (!currentStandard.value?.id) return
+  selectedProductIds.value = []
+  getProductOptions()
+  bindingDialogVisible.value = true
+}
+
+const closeBindingDialog = () => {
+  bindingDialogVisible.value = false
+}
+
+const submitBinding = async () => {
+  const testStandardId = currentStandard.value?.id
+  if (!testStandardId) return
+  const ids = (selectedProductIds.value || []).filter(Boolean)
+  if (!ids.length) {
+    proxy.$message.warning('璇烽�夋嫨浜у搧')
+    return
+  }
+  const payload = ids.map((pid) => ({
+    productId: pid,
+    testStandardId
+  }))
+  await qualityTestStandardBindingAdd(payload)
+  proxy.$message.success('娣诲姞鎴愬姛')
+  bindingDialogVisible.value = false
+  loadBindingList()
+}
+
+const handleUnbind = async (row) => {
+  if (!row?.id) return
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎璇ョ粦瀹氾紵', '鎻愮ず', { type: 'warning' })
+  } catch {
+    return
+  }
+  await qualityTestStandardBindingDel([row.qualityTestStandardBindingId])
+  proxy.$message.success('鍒犻櫎鎴愬姛')
+  loadBindingList()
+}
+
+const handleBatchUnbind = async () => {
+  if (!bindingSelectedRows.value.length) {
+    proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+    return
+  }
+  const ids = bindingSelectedRows.value.map((i) => i.qualityTestStandardBindingId)
+  try {
+    await ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', { type: 'warning' })
+  } catch {
+    return
+  }
+  await qualityTestStandardBindingDel(ids)
+  proxy.$message.success('鍒犻櫎鎴愬姛')
+  loadBindingList()
+}
+
+onMounted(() => {
+  getStandardList()
+  getProcessList()
+})
+</script>
+
+<style scoped>
+.metric-binding {
+  display: flex;
+  gap: 16px;
+}
+
+.left-panel,
+.right-panel {
+  flex: 1;
+  background: #ffffff;
+  padding: 16px;
+  box-sizing: border-box;
+}
+
+.toolbar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.toolbar-right {
+  flex-shrink: 0;
+}
+
+.right-header {
+  display: flex;
+  align-items: baseline;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+
+.right-header .title {
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.right-header .desc {
+  font-size: 13px;
+  color: #666;
+}
+
+.right-toolbar {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  margin-bottom: 10px;
+}
+
+.link-text {
+  color: #409eff;
+  cursor: default;
+}
+
+.clickable-link {
+  color: #409eff;
+  cursor: pointer;
+}
+
+.clickable-link:hover {
+  text-decoration: underline;
+}
+
+:deep(.row-center td) {
+  text-align: center !important;
+}
+
+/* el-table 琛ㄥご/鍐呭缁熶竴灞呬腑锛坮ow-class-name 涓嶄綔鐢ㄤ簬琛ㄥご锛� */
+:deep(.center-table .el-table__header-wrapper th .cell) {
+  text-align: center !important;
+}
+:deep(.center-table .el-table__body-wrapper td .cell) {
+  text-align: center !important;
+}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+  text-align: center;
+  width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+  width: 100%;
+  margin-top: 4px;
+}
+</style>
diff --git a/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
new file mode 100644
index 0000000..4c958a0
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
@@ -0,0 +1,78 @@
+<template>
+  <FormDialog
+    v-model="dialogVisible"
+    :title="computedTitle"
+    :operation-type="operationType"
+    width="520px"
+    @close="emit('close')"
+    @cancel="handleCancel"
+    @confirm="handleConfirm"
+  >
+    <el-form
+      ref="formRef"
+      :model="form"
+      :rules="rules"
+      label-width="100px"
+    >
+      <el-form-item label="鍙傛暟椤�" prop="parameterItem">
+        <el-input v-model="form.parameterItem" placeholder="璇疯緭鍏ュ弬鏁伴」" />
+      </el-form-item>
+      <el-form-item label="鍗曚綅" prop="unit">
+        <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+      </el-form-item>
+      <el-form-item label="鏍囧噯鍊�" prop="standardValue">
+        <el-input v-model="form.standardValue" placeholder="璇疯緭鍏ユ爣鍑嗗��" />
+      </el-form-item>
+      <el-form-item label="鍐呮帶鍊�" prop="controlValue">
+        <el-input v-model="form.controlValue" placeholder="璇疯緭鍏ュ唴鎺у��" />
+      </el-form-item>
+      <el-form-item label="榛樿鍊�" prop="defaultValue">
+        <el-input v-model="form.defaultValue" placeholder="璇疯緭鍏ラ粯璁ゅ��" />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
+
+const props = defineProps({
+  modelValue: { type: Boolean, default: false },
+  operationType: { type: String, default: 'add' }, // add | edit
+  form: { type: Object, required: true }
+})
+
+const emit = defineEmits(['update:modelValue', 'close', 'cancel', 'confirm'])
+
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
+})
+
+const formRef = ref(null)
+
+const rules = {
+  parameterItem: [{ required: true, message: '璇疯緭鍏ュ弬鏁伴」', trigger: 'blur' }],
+  unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }]
+}
+
+const computedTitle = computed(() => (props.operationType === 'edit' ? '缂栬緫鏍囧噯鍙傛暟' : '鏂板鏍囧噯鍙傛暟'))
+
+const handleConfirm = () => {
+  formRef.value?.validate?.((valid) => {
+    if (valid) emit('confirm')
+  })
+}
+
+const handleCancel = () => {
+  emit('cancel')
+  dialogVisible.value = false
+}
+
+const resetFields = () => {
+  formRef.value?.resetFields?.()
+}
+
+defineExpose({ resetFields })
+</script>
diff --git a/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue b/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue
new file mode 100644
index 0000000..38d535a
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue
@@ -0,0 +1,129 @@
+<template>
+  <FormDialog
+    v-model="dialogVisible"
+    :title="computedTitle"
+    :operation-type="operationType"
+    :width="width"
+    @close="emit('close')"
+    @cancel="handleCancel"
+    @confirm="handleConfirm"
+  >
+    <el-form
+      ref="formRef"
+      :model="form"
+      :rules="rules"
+      label-width="100px"
+    >
+      <el-form-item label="鏍囧噯缂栧彿" prop="standardNo">
+        <el-input v-model="form.standardNo" placeholder="璇疯緭鍏ユ爣鍑嗙紪鍙�" />
+      </el-form-item>
+      <el-form-item label="鏍囧噯鍚嶇О" prop="standardName">
+        <el-input v-model="form.standardName" placeholder="璇疯緭鍏ユ爣鍑嗗悕绉�" />
+      </el-form-item>
+      <el-form-item label="绫诲埆" prop="inspectType">
+        <el-select v-model="form.inspectType" placeholder="璇烽�夋嫨绫诲埆" style="width: 100%">
+          <el-option label="鍘熸潗鏂欐楠�" value="0" />
+          <el-option label="杩囩▼妫�楠�" value="1" />
+          <el-option label="鍑哄巶妫�楠�" value="2" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="宸ュ簭" prop="processId">
+        <el-select v-model="form.processId" placeholder="璇烽�夋嫨宸ュ簭" style="width: 100%">
+          <el-option
+            v-for="item in processOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鐘舵��" prop="state">
+        <el-select v-model="form.state" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
+          <el-option label="鑽夌" value="0" />
+          <el-option label="閫氳繃" value="1" />
+          <el-option label="鎾ら攢" value="2" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="澶囨敞" prop="remark">
+        <el-input
+          v-model="form.remark"
+          type="textarea"
+          :rows="3"
+          placeholder="璇疯緭鍏ュ娉�"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  operationType: {
+    type: String,
+    default: 'add'
+  },
+  form: {
+    type: Object,
+    required: true
+  },
+  rules: {
+    type: Object,
+    default: () => ({})
+  },
+  processOptions: {
+    type: Array,
+    default: () => []
+  },
+  width: {
+    type: String,
+    default: '500px'
+  }
+})
+
+const emit = defineEmits(['update:modelValue', 'close', 'cancel', 'confirm'])
+
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
+})
+
+const formRef = ref(null)
+
+const computedTitle = computed(() => {
+  if (props.operationType === 'edit') return '缂栬緫妫�娴嬫爣鍑�'
+  if (props.operationType === 'copy') return '澶嶅埗妫�娴嬫爣鍑�'
+  return '鏂板妫�娴嬫爣鍑�'
+})
+
+const handleConfirm = () => {
+  if (!formRef.value) {
+    emit('confirm')
+    return
+  }
+  formRef.value.validate((valid) => {
+    if (valid) {
+      emit('confirm')
+    }
+  })
+}
+
+const handleCancel = () => {
+  emit('cancel')
+  dialogVisible.value = false
+}
+
+const resetFields = () => {
+  formRef.value?.resetFields?.()
+}
+
+defineExpose({
+  resetFields
+})
+</script>
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index 016a4c1..44d3fae 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -1,415 +1,834 @@
 <template>
-  <div class="app-container product-view">
-    <div class="left">
-      <div>
-        <el-input
-            v-model="search"
-            style="width: 210px"
-            placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
-            @change="searchFilter"
-            @clear="searchFilter"
+  <div class="app-container metric-maintenance">
+    <!-- 宸︿晶锛氭娴嬫爣鍑嗗垪琛� -->
+    <div class="left-panel">
+      <div class="toolbar">
+        <div class="toolbar-left"></div>
+        <div class="toolbar-right">
+          <el-button type="primary" @click="openStandardDialog('add')">鏂板</el-button>
+          <el-button type="success" plain @click="handleBatchAudit(1)">鎵瑰噯</el-button>
+          <el-button type="warning" plain @click="handleBatchAudit(2)">鎾ら攢</el-button>
+          <el-button type="danger" plain @click="handleBatchDelete">鍒犻櫎</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="standardColumns"
+        :tableData="standardTableData"
+        :page="page"
+        :isSelection="true"
+        :tableLoading="tableLoading"
+        :rowClassName="rowClassNameCenter"
+        :rowClick="handleTableRowClick"
+        @selection-change="handleSelectionChange"
+        @pagination="handlePagination"
+        :total="page.total"
+      >
+        <template #standardNoCell="{ row }">
+          <span class="clickable-link" @click="handleStandardRowClick(row)">
+            {{ row.standardNo }}
+          </span>
+        </template>
+
+        <!-- 琛ㄥご鎼滅储鎻掓Ы -->
+        <template #standardNoHeader>
+          <el-input
+            v-model="searchForm.standardNo"
+            placeholder="鏍囧噯缂栧彿"
             clearable
-            prefix-icon="Search"
-        />
-      </div>
-      <div ref="containerRef">
-        <el-tree
-            ref="tree"
-            v-loading="treeLoad"
-            :data="list"
-            @node-click="handleNodeClick"
-            :expand-on-click-node="false"
-            default-expand-all
-            :default-expanded-keys="expandedKeys"
-            :draggable="true"
-            :filter-node-method="filterNode"
-            :props="{ children: 'children', label: 'label' }"
-            highlight-current
-            node-key="id"
-            style="
-            height: calc(100vh - 190px);
-            overflow-y: scroll;
-            scrollbar-width: none;
-          "
-        >
-          <template #default="{ node, data }">
-            <div class="custom-tree-node">
-              <span class="tree-node-content">
-                <el-icon class="orange-icon">
-                  <component :is="data.children && data.children.length > 0
-                  ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
-                </el-icon>
-                {{ data.label }}
-              </span>
-            </div>
-          </template>
-        </el-tree>
-      </div>
+            size="small"
+            @change="handleQuery"
+            @clear="handleQuery"
+          />
+        </template>
+        <template #standardNameHeader>
+          <el-input
+            v-model="searchForm.standardName"
+            placeholder="鏍囧噯鍚嶇О"
+            clearable
+            size="small"
+            @change="handleQuery"
+            @clear="handleQuery"
+          />
+        </template>
+        <template #inspectTypeHeader>
+          <el-select
+            v-model="searchForm.inspectType"
+            placeholder="绫诲埆"
+            clearable
+            size="small"
+            style="width: 120px"
+            @change="handleQuery"
+            @clear="handleQuery"
+          >
+            <el-option label="鍘熸潗鏂欐楠�" value="0" />
+            <el-option label="杩囩▼妫�楠�" value="1" />
+            <el-option label="鍑哄巶妫�楠�" value="2" />
+          </el-select>
+        </template>
+        <template #stateHeader>
+          <el-select
+            v-model="searchForm.state"
+            placeholder="鐘舵��"
+            clearable
+            size="small"
+            style="width: 110px"
+            @change="handleQuery"
+            @clear="handleQuery"
+          >
+            <el-option label="鑽夌" value="0" />
+            <el-option label="閫氳繃" value="1" />
+            <el-option label="鎾ら攢" value="2" />
+          </el-select>
+        </template>
+      </PIMTable>
     </div>
-    <div class="right">
-      <div style="margin-bottom: 10px">
-        <el-button type="primary" @click="openModelDia('add')">
-          鏂板妫�娴嬫寚鏍�
+
+    <!-- 鍙充晶锛氭爣鍑嗗弬鏁板垪琛� -->
+    <div class="right-panel">
+      <div class="right-header">
+        <div class="title">鏍囧噯鍙傛暟</div>
+        <div class="desc" v-if="currentStandard">
+          鎮ㄥ綋鍓嶉�夋嫨鐨勬娴嬫爣鍑嗙紪鍙锋槸锛�
+          <span class="link-text">{{ currentStandard.standardNo }}</span>
+        </div>
+        <div class="desc" v-else>璇峰厛鍦ㄥ乏渚ч�夋嫨涓�涓娴嬫爣鍑�</div>
+      </div>
+
+      <div class="right-toolbar">
+        <el-button type="primary" :disabled="!currentStandard || isStandardReadonly" @click="openParamDialog('add')">
+          鏂板
         </el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button
-            type="danger"
-            @click="handleDelete"
-            style="margin-left: 10px"
-            plain
-        >
+        <el-button type="danger" plain :disabled="!currentStandard || isStandardReadonly" @click="handleParamBatchDelete">
           鍒犻櫎
         </el-button>
       </div>
-      <PIMTable
-          rowKey="id"
-          :column="tableColumn"
-          :tableData="tableData"
-          :page="page"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          :tableLoading="tableLoading"
-          @pagination="pagination"
-          :total="page.total"
-      ></PIMTable>
-    </div>
-    <el-dialog
-        v-model="modelDia"
-        title="妫�娴嬫寚鏍�"
-        width="400px"
-        @close="closeModelDia"
-    >
-      <el-form
-          :model="modelForm"
-          label-width="140px"
-          label-position="top"
-          :rules="modelRules"
-          ref="modelFormRef"
+
+      <el-table
+        v-loading="detailLoading"
+        :data="detailTableData"
+        border
+        :row-class-name="() => 'row-center'"
+        class="center-table"
+        style="width: 100%"
+        height="calc(100vh - 220px)"
+        @selection-change="handleParamSelectionChange"
       >
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="鎸囨爣锛�" prop="parameterItem">
-              <el-input
-                  v-model="modelForm.parameterItem"
-                  placeholder="璇疯緭鍏ユ寚鏍�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="鍗曚綅锛�" prop="unit">
-              <el-input
-                  v-model="modelForm.unit"
-                  placeholder="璇疯緭鍏ュ崟浣�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="鏍囧噯鍊硷細" prop="standardValue">
-              <el-input
-                  v-model="modelForm.standardValue"
-                  placeholder="璇疯緭鍏ユ爣鍑嗗��"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="鍐呮帶鍊硷細" prop="controlValue">
-              <el-input
-                  v-model="modelForm.controlValue"
-                  placeholder="璇疯緭鍏ュ唴鎺у��"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitModelForm">纭</el-button>
-          <el-button @click="closeModelDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+        <el-table-column type="selection" width="48" align="center" />
+        <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+        <el-table-column prop="parameterItem" label="鍙傛暟椤�" min-width="120" />
+        <el-table-column prop="unit" label="鍗曚綅" width="80" />
+        <el-table-column prop="standardValue" label="鏍囧噯鍊�" min-width="120" />
+        <el-table-column prop="controlValue" label="鍐呮帶鍊�" min-width="120" />
+        <el-table-column prop="defaultValue" label="榛樿鍊�" min-width="120" />
+        <el-table-column label="鎿嶄綔" width="140" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" size="small" :disabled="isStandardReadonly" @click="openParamDialog('edit', row)">
+              缂栬緫
+            </el-button>
+            <el-button link type="danger" size="small" :disabled="isStandardReadonly" @click="handleParamDelete(row)">
+              鍒犻櫎
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 鏂板 / 缂栬緫妫�娴嬫爣鍑� -->
+    <StandardFormDialog
+      ref="standardFormDialogRef"
+      v-model="standardDialogVisible"
+      :operation-type="standardOperationType"
+      :form="standardForm"
+      :rules="standardRules"
+      :process-options="processOptions"
+      @confirm="submitStandardForm"
+      @close="closeStandardDialog"
+      @cancel="closeStandardDialog"
+    />
+
+    <ParamFormDialog
+      ref="paramFormDialogRef"
+      v-model="paramDialogVisible"
+      :operation-type="paramOperationType"
+      :form="paramForm"
+      @confirm="submitParamForm"
+      @close="closeParamDialog"
+      @cancel="closeParamDialog"
+    />
   </div>
 </template>
 
 <script setup>
-import {ref} from "vue";
-import {addOrEditProductModel, delProductModel, modelListPage, productTreeList} from "@/api/basicData/product.js";
-import ImportExcel from "@/views/basicData/product/ImportExcel/index.vue";
-import {ElMessageBox} from "element-plus";
+import { Search } from '@element-plus/icons-vue'
+import { ref, reactive, toRefs, onMounted, getCurrentInstance, computed } from 'vue'
+import { ElMessageBox } from 'element-plus'
 import {
-  qualityTestStandardAdd, qualityTestStandardDel,
   qualityTestStandardListPage,
-  qualityTestStandardUpdate
-} from "@/api/qualityManagement/metricMaintenance.js";
-const { proxy } = getCurrentInstance();
-// 鏍�
-const search = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const currentId = ref("");
-const currentParentId = ref("");
-// 鎸囨爣琛ㄦ牸
-const tableData = ref([]);
-const tableLoading = ref(false);
+  qualityTestStandardAdd,
+  qualityTestStandardUpdate,
+  qualityTestStandardDel,
+  qualityTestStandardCopyParam,
+  qualityTestStandardAudit,
+  qualityTestStandardParamList,
+  qualityTestStandardParamAdd,
+  qualityTestStandardParamUpdate,
+  qualityTestStandardParamDel
+} from '@/api/qualityManagement/metricMaintenance.js'
+import { productProcessListPage } from '@/api/basicData/productProcess.js'
+import StandardFormDialog from './StandardFormDialog.vue'
+import ParamFormDialog from './ParamFormDialog.vue'
+
+const { proxy } = getCurrentInstance()
+
+// 宸︿晶鏍囧噯鍒楄〃锛氭暣琛屽唴瀹瑰眳涓紙閰嶅悎鏍峰紡锛�
+const rowClassNameCenter = () => 'row-center'
+
+// 鏍囧噯鐘舵�佷负鈥滈�氳繃(1)鈥濇椂锛屽彸渚у弬鏁扮姝㈠鍒犳敼
+const isStandardReadonly = computed(() => {
+  const state = currentStandard.value?.state
+  return state === 1 || state === '1'
+})
+
+// 鎼滅储鏉′欢
+const data = reactive({
+  searchForm: {
+    standardNo: '',
+    standardName: '',
+    remark: '',
+    state: '',
+    inspectType: '',
+    processId: ''
+  },
+  standardForm: {
+    id: undefined,
+    standardNo: '',
+    standardName: '',
+    remark: '',
+    state: '0',
+    inspectType: '',
+    processId: ''
+  },
+  standardRules: {
+    standardNo: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗙紪鍙�', trigger: 'blur' }],
+    standardName: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗗悕绉�', trigger: 'blur' }],
+    inspectType: [{ required: true, message: '璇烽�夋嫨妫�娴嬬被鍨�', trigger: 'change' }],
+    processId: [{ required: false, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
+  }
+})
+
+const { searchForm, standardForm, standardRules } = toRefs(data)
+
+// 宸︿晶琛ㄦ牸
+const standardTableData = ref([])
+const selectedRows = ref([])
+const tableLoading = ref(false)
 const page = reactive({
   current: 1,
   size: 10,
-});
-const tableColumn = ref([
+  total: 0
+})
+
+// 宸ュ簭涓嬫媺
+const processOptions = ref([])
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessList = async () => {
+  try {
+    const res = await productProcessListPage({ current: 1, size: 1000 })
+    if (res?.code === 200) {
+      const records = res?.data?.records || []
+      processOptions.value = records.map(item => ({
+        label: item.processName || item.name || item.label,
+        value: item.id || item.processId || item.value
+      }))
+    }
+  } catch (error) {
+    console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+  }
+}
+
+// 褰撳墠閫変腑鐨勬爣鍑� & 鍙充晶璇︽儏
+const currentStandard = ref(null)
+const detailTableData = ref([])
+const detailLoading = ref(false)
+const paramSelectedRows = ref([])
+const paramDialogVisible = ref(false)
+const paramOperationType = ref('add') // add | edit
+const paramFormDialogRef = ref(null)
+const paramForm = reactive({
+  id: undefined,
+  parameterItem: '',
+  unit: '',
+  standardValue: '',
+  controlValue: '',
+  defaultValue: ''
+})
+
+// 寮圭獥
+const standardDialogVisible = ref(false)
+const standardOperationType = ref('add') // add | edit | copy
+const standardFormDialogRef = ref(null)
+
+// 鍒楀畾涔�
+const standardColumns = ref([
   {
-    label: "鎸囨爣",
-    prop: "parameterItem",
+    label: '鏍囧噯缂栧彿',
+    prop: 'standardNo',
+    dataType: 'slot',
+    slot: 'standardNoCell',
+    minWidth: 160,
+    align: 'center',
+    headerSlot: 'standardNoHeader'
   },
   {
-    label: "鍗曚綅",
-    prop: "unit",
+    label: '鏍囧噯鍚嶇О',
+    prop: 'standardName',
+    minWidth: 180,
+    align: 'center',
+    headerSlot: 'standardNameHeader'
   },
   {
-    label: "鏍囧噯鍊�",
-    prop: "standardValue",
+    label: '绫诲埆',
+    prop: 'inspectType',
+    headerSlot: 'inspectTypeHeader',
+    align: 'center',
+    dataType: 'tag',
+    formatData: (val) => {
+      const map = {
+        0: '鍘熸潗鏂欐楠�',
+        1: '杩囩▼妫�楠�',
+        2: '鍑哄巶妫�楠�'
+      }
+      return map[val] || val
+    }
   },
   {
-    label: "鍐呮帶鍊�",
-    prop: "controlValue",
+    label: '宸ュ簭',
+    prop: 'processId',
+    align: 'center',
+    dataType: 'tag',
+    formatData: (val) => {
+      const target = processOptions.value.find(
+        (item) => String(item.value) === String(val)
+      )
+      return target?.label || val
+    }
   },
   {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
+    label: '鐘舵��',
+    prop: 'state',
+    headerSlot: 'stateHeader',
+    align: 'center',
+    dataType: 'tag',
+    formatData: (val) => {
+      const map = {
+        0: '鑽夌',
+        1: '閫氳繃',
+        2: '鎾ら攢'
+      }
+      return map[val] || val
+    },
+    formatType: (val) => {
+      if (val === '1' || val === 1) return 'success'
+      if (val === '2' || val === 2) return 'warning'
+      return 'info'
+    }
+  },
+  {
+    label: '澶囨敞',
+    prop: 'remark',
+    minWidth: 160,
+    align: 'center'
+  },
+  {
+    dataType: 'action',
+    label: '鎿嶄綔',
+    align: 'center',
+    fixed: 'right',
+    width: 220,
     operation: [
       {
-        name: "缂栬緫",
-        type: "text",
+        name: '缂栬緫',
+        type: 'text',
         clickFun: (row) => {
-          openModelDia("edit", row);
-        },
+          openStandardDialog('edit', row)
+        }
       },
-    ],
-  },
-]);
-const selectedRows = ref([]);
-// 鎸囨爣寮规
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const data = reactive({
-  modelForm: {
-    parameterItem: "",
-    unit: "",
-    standardValue: "",
-    controlValue: "",
-  },
-  modelRules: {
-    parameterItem: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    standardValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    controlValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-});
-const { modelForm, modelRules } = toRefs(data);
-
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
-  treeLoad.value = true;
-  productTreeList().then((res) => {
-    list.value = res;
-    list.value.forEach((a) => {
-      expandedKeys.value.push(a.label);
-    });
-    treeLoad.value = false;
-  }).catch((err) => {
-    treeLoad.value = false;
-  });
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
-  proxy.$refs.tree.filter(search.value);
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
-  // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
-  currentId.value = val.id;
-  currentParentId.value = val.parentId;
-  getModelList();
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-// 鏌ヨ鎸囨爣鏁版嵁
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getModelList();
-};
-const getModelList = () => {
-  tableLoading.value = true;
-  qualityTestStandardListPage({
-    productId: currentId.value,
-    current: page.current,
-    size: page.size,
-  }).then((res) => {
-    tableData.value = res.data.records;
-    page.total = res.data.total;
-    tableLoading.value = false;
-  });
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
-  if (!value) {
-    //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
-    return true;
-  }
-  // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
-  let val = value.toLowerCase();
-  return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
-  if (data.label.indexOf(value) !== -1) {
-    return true;
-  }
-  const level = node.level;
-  // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
-  if (level === 1) {
-    return false;
-  }
-  // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
-  let parentData = node.parent;
-  // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
-  let index = 0;
-  while (index < level - 1) {
-    // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
-    if (parentData.data.label.indexOf(value) !== -1) {
-      return true;
-    }
-    // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
-    parentData = parentData.parent;
-    index++;
-  }
-  // 娌″尮閰嶅埌杩斿洖false
-  return false;
-};
-// 鎵撳紑鎸囨爣寮规
-const openModelDia = (type, data) => {
-  modelOperationType.value = type;
-  modelDia.value = true;
-  modelForm.value.model = "";
-  modelForm.value.model = "";
-  modelForm.value.id = "";
-  if (type === "edit") {
-    modelForm.value = { ...data };
-  }
-};
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  }).then(() => {
-    proxy.download("/quality/qualityTestStandard/export", {}, "妫�娴嬫寚鏍�.xlsx");
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�");
-  });
-};
-
-// 鍒犻櫎鎸囨爣
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  }).then(() => {
-    tableLoading.value = true;
-    qualityTestStandardDel(ids).then((res) => {
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      getModelList();
-    }).finally(() => {
-      tableLoading.value = false;
-    });
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�");
-  });
-};
-
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
-  proxy.$refs.modelFormRef.validate((valid) => {
-    if (valid) {
-      modelForm.value.productId = Number(currentId.value);
-      if(modelOperationType.value === 'add') {
-        qualityTestStandardAdd(modelForm.value).then((res) => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeModelDia();
-          getModelList();
-        });
-      } else {
-        qualityTestStandardUpdate(modelForm.value).then((res) => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeModelDia();
-          getModelList();
-        });
+      {
+        name: '澶嶅埗',
+        type: 'text',
+        clickFun: async (row) => {
+          if (!row?.id) return
+          try {
+            await ElMessageBox.confirm('纭澶嶅埗璇ユ爣鍑嗗弬鏁帮紵', '鎻愮ず', { type: 'warning' })
+          } catch {
+            return
+          }
+          await qualityTestStandardCopyParam(row.id)
+          proxy.$message.success('澶嶅埗鎴愬姛')
+          getStandardList()
+          if (currentStandard.value?.id === row.id) {
+            loadDetail(row.id)
+          }
+        }
+      },
+      {
+        name: '鍒犻櫎',
+        type: 'text',
+        clickFun: (row) => {
+          handleDelete(row)
+        }
       }
-    }
-  });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
-  proxy.$refs.modelFormRef.resetFields();
-  modelDia.value = false;
-};
-getProductTreeList();
+    ]
+  }
+])
+
+// 鏌ヨ鍒楄〃
+const getStandardList = () => {
+  tableLoading.value = true
+  const params = {
+    ...searchForm.value,
+    current: page.current,
+    size: page.size
+  }
+  qualityTestStandardListPage(params)
+    .then((res) => {
+      const records = res?.data?.records || []
+      standardTableData.value = records
+      page.total = res?.data?.total || records.length
+    })
+    .finally(() => {
+      tableLoading.value = false
+    })
+}
+
+const handleQuery = () => {
+  page.current = 1
+  getStandardList()
+}
+
+const resetQuery = () => {
+  searchForm.value.standardNo = ''
+  searchForm.value.standardName = ''
+  searchForm.value.remark = ''
+  searchForm.value.state = ''
+  searchForm.value.inspectType = ''
+  searchForm.value.processId = ''
+  handleQuery()
+}
+
+const handlePagination = (obj) => {
+  page.current = obj.page
+  page.size = obj.limit
+  getStandardList()
+}
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection
+}
+
+// 鎵归噺瀹℃牳锛氱姸鎬� 1=鎵瑰噯锛�2=鎾ら攢
+const handleBatchAudit = async (state) => {
+  if (!selectedRows.value.length) {
+    proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+    return
+  }
+  const text = state === 1 ? '鎵瑰噯' : '鎾ら攢'
+  const payload = selectedRows.value
+    .filter(i => i?.id)
+    .map((item) => ({ id: item.id, state }))
+
+  if (!payload.length) {
+    proxy.$message.warning('璇烽�夋嫨鏈夋晥鏁版嵁')
+    return
+  }
+
+  try {
+    await ElMessageBox.confirm(`纭${text}閫変腑鐨勬爣鍑嗭紵`, '鎻愮ず', { type: 'warning' })
+  } catch {
+    return
+  }
+  await qualityTestStandardAudit(payload)
+  proxy.$message.success(`${text}鎴愬姛`)
+  getStandardList()
+}
+
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+const handleTableRowClick = (row) => {
+  currentStandard.value = row
+  loadDetail(row.id)
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
+const handleStandardRowClick = (row) => {
+  currentStandard.value = row
+  loadDetail(row.id)
+}
+
+const loadDetail = (standardId) => {
+  if (!standardId) {
+    detailTableData.value = []
+    return
+  }
+  detailLoading.value = true
+  qualityTestStandardParamList({ testStandardId: standardId }).then((res) => {
+    detailTableData.value = res?.data || []
+  })
+    .finally(() => {
+      detailLoading.value = false
+    })
+}
+
+const handleParamSelectionChange = (selection) => {
+  paramSelectedRows.value = selection
+}
+
+const openParamDialog = (type, row) => {
+  if (!currentStandard.value?.id) return
+  if (isStandardReadonly.value) {
+    proxy.$message.warning('璇ユ爣鍑嗗凡閫氳繃锛屽弬鏁颁笉鍙紪杈�')
+    return
+  }
+  paramOperationType.value = type
+  if (type === 'add') {
+    Object.assign(paramForm, {
+      id: undefined,
+      parameterItem: '',
+      unit: '',
+      standardValue: '',
+      controlValue: '',
+      defaultValue: ''
+    })
+  } else if (type === 'edit' && row) {
+    Object.assign(paramForm, row)
+  }
+  paramDialogVisible.value = true
+}
+
+const closeParamDialog = () => {
+  paramDialogVisible.value = false
+  paramFormDialogRef.value?.resetFields?.()
+}
+
+const submitParamForm = async () => {
+  const testStandardId = currentStandard.value?.id
+  if (!testStandardId) return
+  if (isStandardReadonly.value) {
+    proxy.$message.warning('璇ユ爣鍑嗗凡閫氳繃锛屽弬鏁颁笉鍙紪杈�')
+    return
+  }
+  const payload = { ...paramForm, testStandardId }
+  if (paramOperationType.value === 'edit') {
+    await qualityTestStandardParamUpdate(payload)
+    proxy.$message.success('鎻愪氦鎴愬姛')
+  } else {
+    await qualityTestStandardParamAdd(payload)
+    proxy.$message.success('鎻愪氦鎴愬姛')
+  }
+  closeParamDialog()
+  loadDetail(testStandardId)
+}
+
+const handleParamDelete = async (row) => {
+  if (!row?.id) return
+  if (isStandardReadonly.value) {
+    proxy.$message.warning('璇ユ爣鍑嗗凡閫氳繃锛屽弬鏁颁笉鍙紪杈�')
+    return
+  }
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎璇ュ弬鏁帮紵', '鎻愮ず', { type: 'warning' })
+  } catch {
+    return
+  }
+  await qualityTestStandardParamDel([row.id])
+  proxy.$message.success('鍒犻櫎鎴愬姛')
+  loadDetail(currentStandard.value?.id)
+}
+
+const handleParamBatchDelete = async () => {
+  if (isStandardReadonly.value) {
+    proxy.$message.warning('璇ユ爣鍑嗗凡閫氳繃锛屽弬鏁颁笉鍙紪杈�')
+    return
+  }
+  if (!paramSelectedRows.value.length) {
+    proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+    return
+  }
+  const ids = paramSelectedRows.value.map((i) => i.id)
+  try {
+    await ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', { type: 'warning' })
+  } catch {
+    return
+  }
+  await qualityTestStandardParamDel(ids)
+  proxy.$message.success('鍒犻櫎鎴愬姛')
+  loadDetail(currentStandard.value?.id)
+}
+
+// 鏂板 / 缂栬緫 / 澶嶅埗
+const openStandardDialog = (type, row) => {
+  standardOperationType.value = type
+  if (type === 'add') {
+    Object.assign(standardForm.value, {
+      id: undefined,
+      standardNo: '',
+      standardName: '',
+      remark: '',
+      state: '0',
+      inspectType: '',
+      processId: ''
+    })
+  } else if (type === 'edit' && row) {
+    Object.assign(standardForm.value, {
+      ...row,
+      // 纭繚 inspectType 鍜� state 杞崲涓哄瓧绗︿覆锛屼互鍖归厤 el-select 鐨� value 绫诲瀷
+      inspectType: row.inspectType !== null && row.inspectType !== undefined ? String(row.inspectType) : '',
+      state: row.state !== null && row.state !== undefined ? String(row.state) : '0',
+      // 纭繚 processId 杞崲涓哄瓧绗︿覆鎴栨暟瀛楋紙鏍规嵁瀹為檯闇�瑕侊級
+      processId: row.processId !== null && row.processId !== undefined ? row.processId : ''
+    })
+  } else if (type === 'copy' && row) {
+    const { id, ...rest } = row
+    Object.assign(standardForm.value, {
+      ...rest,
+      id: undefined,
+      standardNo: '',
+      state: '0',
+      // 纭繚 inspectType 杞崲涓哄瓧绗︿覆
+      inspectType: rest.inspectType !== null && rest.inspectType !== undefined ? String(rest.inspectType) : ''
+    })
+  }
+  standardDialogVisible.value = true
+}
+
+const closeStandardDialog = () => {
+  standardDialogVisible.value = false
+  standardFormDialogRef.value?.resetFields?.()
+}
+
+const submitStandardForm = () => {
+  const payload = { ...standardForm.value }
+  const isEdit = standardOperationType.value === 'edit'
+  if (isEdit) {
+    qualityTestStandardUpdate(payload).then(() => {
+      proxy.$message.success('鎻愪氦鎴愬姛')
+      standardDialogVisible.value = false
+      getStandardList()
+    })
+  } else {
+    qualityTestStandardAdd(payload).then(() => {
+       proxy.$message.success('鎻愪氦鎴愬姛')
+      standardDialogVisible.value = false
+      getStandardList()
+    })
+  }
+}
+
+// 鍒犻櫎锛堝崟鏉★級
+const handleDelete = (row) => {
+  const ids = [row.id]
+  ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(() => {
+      tableLoading.value = true
+      qualityTestStandardDel(ids)
+        .then(() => {
+          proxy.$message.success('鍒犻櫎鎴愬姛')
+          getStandardList()
+          if (currentStandard.value && currentStandard.value.id === row.id) {
+            currentStandard.value = null
+            detailTableData.value = []
+          }
+        })
+        .finally(() => {
+          tableLoading.value = false
+        })
+    })
+    .catch(() => {
+      proxy.$modal?.msg('宸插彇娑�')
+    })
+}
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (!selectedRows.value.length) {
+    proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+    return
+  }
+  const ids = selectedRows.value.map((item) => item.id)
+  ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(() => {
+      tableLoading.value = true
+      qualityTestStandardDel(ids)
+        .then(() => {
+           proxy.$message.success('鍒犻櫎鎴愬姛')
+          getStandardList()
+          if (currentStandard.value && ids.includes(currentStandard.value.id)) {
+            currentStandard.value = null
+            detailTableData.value = []
+          }
+        })
+        .finally(() => {
+          tableLoading.value = false
+        })
+    })
+    .catch(() => {
+      proxy.$modal?.msg('宸插彇娑�')
+    })
+}
+
+onMounted(() => {
+  getProcessList()
+  getStandardList()
+})
 </script>
 
 <style scoped>
-.product-view {
+.metric-maintenance {
   display: flex;
+  gap: 16px;
+  min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
 }
-.left {
-  width: 380px;
-  padding: 16px;
-  background: #ffffff;
-}
-.right {
-  width: calc(100% - 380px);
-  padding: 16px;
-  margin-left: 20px;
-  background: #ffffff;
-}
-.custom-tree-node {
+
+.left-panel,
+.right-panel {
   flex: 1;
+  min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
+  background: #ffffff;
+  padding: 16px;
+  box-sizing: border-box;
+  overflow: hidden; /* 闃叉鍐呭婧㈠嚭 */
+}
+
+/* 浣庡垎杈ㄧ巼閫傞厤 */
+@media (max-width: 1400px) {
+  .metric-maintenance {
+    flex-direction: column;
+  }
+  
+  .left-panel,
+  .right-panel {
+    width: 100%;
+    min-width: 0;
+  }
+}
+
+@media (max-width: 768px) {
+  .metric-maintenance {
+    gap: 12px;
+  }
+  
+  .left-panel,
+  .right-panel {
+    padding: 12px;
+  }
+}
+
+.toolbar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.toolbar-left {
   display: flex;
   align-items: center;
-  justify-content: space-between;
-  font-size: 14px;
-  padding-right: 8px;
+  flex-wrap: wrap;
+  gap: 4px;
 }
-.tree-node-content {
+
+.toolbar-right {
+  flex-shrink: 0;
   display: flex;
-  align-items: center; /* 鍨傜洿灞呬腑 */
-  height: 100%;
+  flex-wrap: wrap;
+  gap: 8px;
 }
-.orange-icon {
-  color: orange;
-  font-size: 18px;
-  margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+
+.search-label {
+  margin: 0 4px 0 12px;
+}
+
+.search-label:first-of-type {
+  margin-left: 0;
+}
+
+.right-header {
+  display: flex;
+  align-items: baseline;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+
+.right-header .title {
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.right-header .desc {
+  font-size: 13px;
+  color: #666;
+}
+
+.right-toolbar {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  margin-bottom: 10px;
+}
+
+.link-text {
+  color: #409eff;
+  cursor: default;
+}
+
+.clickable-link {
+  color: #409eff;
+  cursor: pointer;
+}
+
+.clickable-link:hover {
+  text-decoration: underline;
+}
+
+:deep(.row-center td) {
+  text-align: center !important;
+}
+
+/* el-table 琛ㄥご/鍐呭缁熶竴灞呬腑锛坮ow-class-name 涓嶄綔鐢ㄤ簬琛ㄥご锛� */
+:deep(.center-table .el-table__header-wrapper th .cell) {
+  text-align: center !important;
+}
+:deep(.center-table .el-table__body-wrapper td .cell) {
+  text-align: center !important;
+}
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+  text-align: center;
+  width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+  width: 100%;
+  margin-top: 4px;
 }
 </style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/metricMaintenance/index0.vue b/src/views/qualityManagement/metricMaintenance/index0.vue
new file mode 100644
index 0000000..016a4c1
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/index0.vue
@@ -0,0 +1,415 @@
+<template>
+  <div class="app-container product-view">
+    <div class="left">
+      <div>
+        <el-input
+            v-model="search"
+            style="width: 210px"
+            placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+            @change="searchFilter"
+            @clear="searchFilter"
+            clearable
+            prefix-icon="Search"
+        />
+      </div>
+      <div ref="containerRef">
+        <el-tree
+            ref="tree"
+            v-loading="treeLoad"
+            :data="list"
+            @node-click="handleNodeClick"
+            :expand-on-click-node="false"
+            default-expand-all
+            :default-expanded-keys="expandedKeys"
+            :draggable="true"
+            :filter-node-method="filterNode"
+            :props="{ children: 'children', label: 'label' }"
+            highlight-current
+            node-key="id"
+            style="
+            height: calc(100vh - 190px);
+            overflow-y: scroll;
+            scrollbar-width: none;
+          "
+        >
+          <template #default="{ node, data }">
+            <div class="custom-tree-node">
+              <span class="tree-node-content">
+                <el-icon class="orange-icon">
+                  <component :is="data.children && data.children.length > 0
+                  ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
+                </el-icon>
+                {{ data.label }}
+              </span>
+            </div>
+          </template>
+        </el-tree>
+      </div>
+    </div>
+    <div class="right">
+      <div style="margin-bottom: 10px">
+        <el-button type="primary" @click="openModelDia('add')">
+          鏂板妫�娴嬫寚鏍�
+        </el-button>
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+        <el-button
+            type="danger"
+            @click="handleDelete"
+            style="margin-left: 10px"
+            plain
+        >
+          鍒犻櫎
+        </el-button>
+      </div>
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :page="page"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          :tableLoading="tableLoading"
+          @pagination="pagination"
+          :total="page.total"
+      ></PIMTable>
+    </div>
+    <el-dialog
+        v-model="modelDia"
+        title="妫�娴嬫寚鏍�"
+        width="400px"
+        @close="closeModelDia"
+    >
+      <el-form
+          :model="modelForm"
+          label-width="140px"
+          label-position="top"
+          :rules="modelRules"
+          ref="modelFormRef"
+      >
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鎸囨爣锛�" prop="parameterItem">
+              <el-input
+                  v-model="modelForm.parameterItem"
+                  placeholder="璇疯緭鍏ユ寚鏍�"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鍗曚綅锛�" prop="unit">
+              <el-input
+                  v-model="modelForm.unit"
+                  placeholder="璇疯緭鍏ュ崟浣�"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鏍囧噯鍊硷細" prop="standardValue">
+              <el-input
+                  v-model="modelForm.standardValue"
+                  placeholder="璇疯緭鍏ユ爣鍑嗗��"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鍐呮帶鍊硷細" prop="controlValue">
+              <el-input
+                  v-model="modelForm.controlValue"
+                  placeholder="璇疯緭鍏ュ唴鎺у��"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitModelForm">纭</el-button>
+          <el-button @click="closeModelDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {addOrEditProductModel, delProductModel, modelListPage, productTreeList} from "@/api/basicData/product.js";
+import ImportExcel from "@/views/basicData/product/ImportExcel/index.vue";
+import {ElMessageBox} from "element-plus";
+import {
+  qualityTestStandardAdd, qualityTestStandardDel,
+  qualityTestStandardListPage,
+  qualityTestStandardUpdate
+} from "@/api/qualityManagement/metricMaintenance.js";
+const { proxy } = getCurrentInstance();
+// 鏍�
+const search = ref("");
+const treeLoad = ref(false);
+const list = ref([]);
+const expandedKeys = ref([]);
+const currentId = ref("");
+const currentParentId = ref("");
+// 鎸囨爣琛ㄦ牸
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+  current: 1,
+  size: 10,
+});
+const tableColumn = ref([
+  {
+    label: "鎸囨爣",
+    prop: "parameterItem",
+  },
+  {
+    label: "鍗曚綅",
+    prop: "unit",
+  },
+  {
+    label: "鏍囧噯鍊�",
+    prop: "standardValue",
+  },
+  {
+    label: "鍐呮帶鍊�",
+    prop: "controlValue",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openModelDia("edit", row);
+        },
+      },
+    ],
+  },
+]);
+const selectedRows = ref([]);
+// 鎸囨爣寮规
+const modelDia = ref(false);
+const modelOperationType = ref("");
+const data = reactive({
+  modelForm: {
+    parameterItem: "",
+    unit: "",
+    standardValue: "",
+    controlValue: "",
+  },
+  modelRules: {
+    parameterItem: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    standardValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    controlValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  },
+});
+const { modelForm, modelRules } = toRefs(data);
+
+// 鏌ヨ浜у搧鏍�
+const getProductTreeList = () => {
+  treeLoad.value = true;
+  productTreeList().then((res) => {
+    list.value = res;
+    list.value.forEach((a) => {
+      expandedKeys.value.push(a.label);
+    });
+    treeLoad.value = false;
+  }).catch((err) => {
+    treeLoad.value = false;
+  });
+};
+// 杩囨护浜у搧鏍�
+const searchFilter = () => {
+  proxy.$refs.tree.filter(search.value);
+};
+// 閫夋嫨浜у搧
+const handleNodeClick = (val, node, el) => {
+  // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
+  currentId.value = val.id;
+  currentParentId.value = val.parentId;
+  getModelList();
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+// 鏌ヨ鎸囨爣鏁版嵁
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getModelList();
+};
+const getModelList = () => {
+  tableLoading.value = true;
+  qualityTestStandardListPage({
+    productId: currentId.value,
+    current: page.current,
+    size: page.size,
+  }).then((res) => {
+    tableData.value = res.data.records;
+    page.total = res.data.total;
+    tableLoading.value = false;
+  });
+};
+// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
+const filterNode = (value, data, node) => {
+  if (!value) {
+    //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
+    return true;
+  }
+  // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
+  let val = value.toLowerCase();
+  return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
+};
+// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
+const chooseNode = (value, data, node) => {
+  if (data.label.indexOf(value) !== -1) {
+    return true;
+  }
+  const level = node.level;
+  // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
+  if (level === 1) {
+    return false;
+  }
+  // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
+  let parentData = node.parent;
+  // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
+  let index = 0;
+  while (index < level - 1) {
+    // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
+    if (parentData.data.label.indexOf(value) !== -1) {
+      return true;
+    }
+    // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+    parentData = parentData.parent;
+    index++;
+  }
+  // 娌″尮閰嶅埌杩斿洖false
+  return false;
+};
+// 鎵撳紑鎸囨爣寮规
+const openModelDia = (type, data) => {
+  modelOperationType.value = type;
+  modelDia.value = true;
+  modelForm.value.model = "";
+  modelForm.value.model = "";
+  modelForm.value.id = "";
+  if (type === "edit") {
+    modelForm.value = { ...data };
+  }
+};
+// 瀵煎嚭
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    proxy.download("/quality/qualityTestStandard/export", {}, "妫�娴嬫寚鏍�.xlsx");
+  }).catch(() => {
+    proxy.$modal.msg("宸插彇娑�");
+  });
+};
+
+// 鍒犻櫎鎸囨爣
+const handleDelete = () => {
+  let ids = [];
+  if (selectedRows.value.length > 0) {
+    ids = selectedRows.value.map((item) => item.id);
+  } else {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    tableLoading.value = true;
+    qualityTestStandardDel(ids).then((res) => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      getModelList();
+    }).finally(() => {
+      tableLoading.value = false;
+    });
+  }).catch(() => {
+    proxy.$modal.msg("宸插彇娑�");
+  });
+};
+
+// 鎻愪氦瑙勬牸鍨嬪彿淇敼
+const submitModelForm = () => {
+  proxy.$refs.modelFormRef.validate((valid) => {
+    if (valid) {
+      modelForm.value.productId = Number(currentId.value);
+      if(modelOperationType.value === 'add') {
+        qualityTestStandardAdd(modelForm.value).then((res) => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeModelDia();
+          getModelList();
+        });
+      } else {
+        qualityTestStandardUpdate(modelForm.value).then((res) => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeModelDia();
+          getModelList();
+        });
+      }
+    }
+  });
+};
+// 鍏抽棴鍨嬪彿寮规
+const closeModelDia = () => {
+  proxy.$refs.modelFormRef.resetFields();
+  modelDia.value = false;
+};
+getProductTreeList();
+</script>
+
+<style scoped>
+.product-view {
+  display: flex;
+}
+.left {
+  width: 380px;
+  padding: 16px;
+  background: #ffffff;
+}
+.right {
+  width: calc(100% - 380px);
+  padding: 16px;
+  margin-left: 20px;
+  background: #ffffff;
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding-right: 8px;
+}
+.tree-node-content {
+  display: flex;
+  align-items: center; /* 鍨傜洿灞呬腑 */
+  height: 100%;
+}
+.orange-icon {
+  color: orange;
+  font-size: 18px;
+  margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+}
+</style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
index 13a231d..9451ef0 100644
--- a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
+++ b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -87,7 +87,9 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="澶勭悊缁撴灉锛�" prop="dealResult">
-              <el-input v-model="form.dealResult" placeholder="璇疯緭鍏�" clearable/>
+              <el-select v-model="form.dealResult" placeholder="璇烽�夋嫨" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="item in rejection_handling" :key="item.value" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -135,6 +137,7 @@
 
 const dialogFormVisible = ref(false);
 const operationType = ref('')
+const { rejection_handling } = proxy.useDict("rejection_handling")
 const data = reactive({
   form: {
     checkTime: "",
diff --git a/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue b/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
index 196eda0..a53c648 100644
--- a/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
@@ -89,7 +89,9 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="澶勭悊缁撴灉锛�" prop="dealResult">
-              <el-input v-model="form.dealResult" placeholder="璇疯緭鍏�" clearable/>
+              <el-select v-model="form.dealResult" placeholder="璇烽�夋嫨" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="item in rejection_handling" :key="item.value" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -135,6 +137,7 @@
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
+const { rejection_handling } = proxy.useDict("rejection_handling")
 const dialogFormVisible = ref(false);
 const operationType = ref('')
 const data = reactive({
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 6126e6b..37b3914 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -10,7 +10,7 @@
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="宸ュ簭锛�" prop="process">
-              <el-input v-model="form.process" placeholder="璇疯緭鍏�" clearable/>
+              <el-input v-model="form.process" placeholder="璇疯緭鍏ュ伐搴�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -32,6 +32,24 @@
           <el-col :span="12">
             <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -108,11 +126,11 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 import {userListNoPage} from "@/api/system/user.js";
 import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
@@ -128,6 +146,7 @@
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -135,10 +154,11 @@
   },
   rules: {
     checkTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    process: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    process: [{ required: true, message: "璇疯緭鍏ュ伐搴�", trigger: "blur" }],
     checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    testStandardId: [{required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -176,6 +196,7 @@
 const tableData = ref([]);
 const tableLoading = ref(false);
 const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
 
 // 鎵撳紑寮规
 const openDialog = async (type, row) => {
@@ -187,11 +208,55 @@
 	let userLists = await userListNoPage();
 	userList.value = userLists.data;
 	form.value = {}
+	testStandardOptions.value = [];
+	tableData.value = [];
 	getProductOptions();
 	if (operationType.value === 'edit') {
-		form.value = {...row}
+		// 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+		const savedTestStandardId = row.testStandardId;
+		// 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+		form.value = {...row, testStandardId: ''}
 		currentProductId.value = row.productId || 0
-		getQualityInspectParamList(row.id)
+		// 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+		if (currentProductId.value) {
+			// 鍏堝姞杞芥寚鏍囬�夐」
+			let params = {
+				productId: currentProductId.value,
+				inspectType: 1,
+				process: form.value.process || ''
+			}
+			qualityInspectDetailByProductId(params).then(res => {
+				testStandardOptions.value = res.data || [];
+				// 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+				nextTick(() => {
+					setTimeout(() => {
+						// 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+						if (savedTestStandardId) {
+							// 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+							const matchedOption = testStandardOptions.value.find(item => 
+								item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+							);
+							if (matchedOption) {
+								// 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+								form.value.testStandardId = matchedOption.id;
+								// 缂栬緫淇濈暀鍘熸楠屽�硷紝鐩存帴鎷夊彇鍘熷弬鏁版暟鎹�
+								getQualityInspectParamList(row.id);
+							} else {
+								// 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+								console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+								form.value.testStandardId = savedTestStandardId;
+								getQualityInspectParamList(row.id);
+							}
+						} else {
+							// 鍚﹀垯浣跨敤鏃х殑閫昏緫
+							getQualityInspectParamList(row.id);
+						}
+					}, 100);
+				});
+			});
+		} else {
+			getQualityInspectParamList(row.id);
+		}
 	}
 }
 const getProductOptions = () => {
@@ -202,7 +267,7 @@
 const getModels = (value) => {
 	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-	if (currentProductId) {
+	if (currentProductId.value) {
 		getList();
 	}
 };
@@ -234,17 +299,23 @@
     return newItem;
   });
 }
+// 宸ュ簭鍙樺寲澶勭悊
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.inspectType = 1
+			const processName = form.value.process || '';
 			if (operationType.value === "add") {
 				tableData.value.forEach((item) => {
 					delete item.id
 				})
 			}
-			const data = {...form.value, qualityInspectParams: tableData.value}
+			const data = {
+				...form.value, 
+				process: processName, // 淇濈暀 process 瀛楁浠ュ吋瀹瑰悗绔�
+				qualityInspectParams: tableData.value
+			}
       if (operationType.value === "add") {
         qualityInspectAdd(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
@@ -260,8 +331,41 @@
   })
 }
 const getList = () => {
-	qualityInspectDetailByProductId(currentProductId.value).then(res => {
-		tableData.value = res.data;
+	if (!currentProductId.value) {
+		testStandardOptions.value = [];
+		tableData.value = [];
+		return;
+	}
+	const processName = form.value.process || '';
+	let params = {
+		productId: currentProductId.value,
+		inspectType: 1,
+		process: processName
+	}
+	qualityInspectDetailByProductId(params).then(res => {
+		// 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+		testStandardOptions.value = res.data || [];
+		// 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+		tableData.value = [];
+		// 娓呯┖鎸囨爣閫夋嫨
+		form.value.testStandardId = '';
+	})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+	if (!testStandardId) {
+		tableData.value = [];
+		return;
+	}
+	tableLoading.value = true;
+	getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+		tableData.value = res.data || [];
+	}).catch(error => {
+		console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+		tableData.value = [];
+	}).finally(() => {
+		tableLoading.value = false;
 	})
 }
 const getQualityInspectParamList = (id) => {
@@ -272,6 +376,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index 5ea1e47..442d7fd 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -45,6 +45,24 @@
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
@@ -121,13 +139,13 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
 import {ElMessageBox} from "element-plus";
 import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 
 const {proxy} = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -142,6 +160,7 @@
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -153,6 +172,7 @@
     checkName: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
     productId: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
     model: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
+    testStandardId: [{required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
     quantity: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
     checkCompany: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
@@ -190,6 +210,7 @@
 const supplierList = ref([]);
 const productOptions = ref([]);
 const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
@@ -199,11 +220,53 @@
     supplierList.value = res.data;
   });
 	form.value = {}
+  testStandardOptions.value = [];
+  tableData.value = [];
   getProductOptions();
   if (operationType.value === 'edit') {
+    // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+    const savedTestStandardId = row.testStandardId;
     form.value = {...row}
     currentProductId.value = row.productId || 0
-    getQualityInspectParamList(row.id)
+    // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+    if (currentProductId.value) {
+      // 鍏堝姞杞芥寚鏍囬�夐」
+      let params = {
+        productId: currentProductId.value,
+        inspectType: 0
+      }
+      qualityInspectDetailByProductId(params).then(res => {
+        testStandardOptions.value = res.data || [];
+        // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+        nextTick(() => {
+          setTimeout(() => {
+            // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+            if (savedTestStandardId) {
+              // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+              const matchedOption = testStandardOptions.value.find(item => 
+                item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+              );
+              if (matchedOption) {
+                // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+                form.value.testStandardId = matchedOption.id;
+                // 缂栬緫淇濈暀鍘熸楠屽�硷紝鐩存帴鎷夊彇鍘熷弬鏁版暟鎹�
+                getQualityInspectParamList(row.id);
+              } else {
+                // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+                console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+                form.value.testStandardId = savedTestStandardId;
+                getQualityInspectParamList(row.id);
+              }
+            } else {
+              // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+              getQualityInspectParamList(row.id);
+            }
+          }, 100);
+        });
+      });
+    } else {
+      getQualityInspectParamList(row.id);
+    }
   }
 }
 const getProductOptions = () => {
@@ -214,7 +277,7 @@
 const getModels = (value) => {
   currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-  if (currentProductId) {
+  if (currentProductId.value) {
     getList();
   }
 };
@@ -275,8 +338,39 @@
 }
 
 const getList = () => {
-  qualityInspectDetailByProductId(currentProductId.value).then(res => {
-    tableData.value = res.data;
+  if (!currentProductId.value) {
+    testStandardOptions.value = [];
+    tableData.value = [];
+    return;
+  }
+  let params = {
+    productId: currentProductId.value,
+    inspectType: 0
+  }
+  qualityInspectDetailByProductId(params).then(res => {
+    // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+    testStandardOptions.value = res.data || [];
+    // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+    tableData.value = [];
+    // 娓呯┖鎸囨爣閫夋嫨
+    form.value.testStandardId = '';
+  })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+  if (!testStandardId) {
+    tableData.value = [];
+    return;
+  }
+  tableLoading.value = true;
+  getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+    tableData.value = res.data || [];
+  }).catch(error => {
+    console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+    tableData.value = [];
+  }).finally(() => {
+    tableLoading.value = false;
   })
 }
 
@@ -288,7 +382,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
-  tableData.value = []
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
index 9848898..5c318c8 100644
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ b/src/views/reportAnalysis/dataDashboard/index.vue
@@ -1,5 +1,6 @@
 <template>
-    <div class="data-dashboard">
+		<div class="scale-container">
+			<div class="data-dashboard" :style="{ transform: `scale(${scaleRatio})` }">
       <!-- 鍏ㄥ睆鎸夐挳 - 绉诲姩鍒板乏涓婅 -->
       <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '閫�鍑哄叏灞�' : '鍏ㄥ睆鏄剧ず'">
         <svg v-if="!isFullscreen" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -21,40 +22,50 @@
       <div class="left-panel">
         <!-- 瀹㈡埛淇℃伅缁熻鍒嗘瀽 -->
 				<div class="panel-header">
-					<span class="panel-title">瀹㈡埛淇℃伅缁熻鍒嗘瀽</span>
+					<span class="panel-title">鍦ㄥ埗鍝佺粺璁″垎鏋�</span>
 				</div>
         <div class="panel-item-customers">
-					<div class="panel-title-second">
-						<div class="panel-title-icon"></div>
-						<div class="total-customers">
-							<span class="label">鎬诲悎鍚岄噾棰�(鍏�)</span>
-							<span class="value">{{sum}}</span>
+					<div class="quality-cards">
+						<div class="quality-cardSec">
+							<div class="quality-card one"></div>
+							<div class="quality-cardTitle">
+								<div>鎬诲湪鍒舵暟閲�</div>
+								<div>{{workInProcessStatistics.totalQuantity}}浠�</div>
+							</div>
 						</div>
-<!--						<div class="jiantou"></div>-->
+						<div class="quality-cardSec">
+							<div class="quality-card two"></div>
+							<div class="quality-cardTitle">
+								<div>骞冲潎鍛ㄨ浆澶╂暟</div>
+								<div>{{workInProcessStatistics.avgTurnoverDays}}澶�</div>
+							</div>
+						</div>
+						<div class="quality-cardSec">
+							<div class="quality-card three"></div>
+							<div class="quality-cardTitle">
+								<div>鍛ㄨ浆鏁堢巼</div>
+								<div>{{workInProcessStatistics.turnoverEfficiency}}%</div>
+							</div>
+						</div>
 					</div>
-					<!-- 楗煎浘鍖哄煙 -->
-					<div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px">
-						<div style="width: 240px; height: 240px; background-image: url('/src/assets/BI/zonghetongbingtubiankuang@2x.png'); background-size: contain; background-position: center; background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;">
-							<Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
-											 :series="materialPieSeries"
-											 :tooltip="pieTooltip"
-											 :options="{backgroundColor: 'transparent'}"
-											 style="margin-left: 5px;"></Echarts>
-						</div>
-						<ul class="contract-list" style="margin: 0; padding: 0; display: flex; flex-direction: column;justify-content: space-around; height: 100%; overflow-y: auto; scroll-behavior: smooth;" ref="refContractList">
-							<li v-for="item in materialPieSeries[0].data" :key="item.name" style="list-style: none; margin-bottom: 12px;">
-								<div style="display: flex;align-items: center;justify-content: space-between;width: 100%">
-									<div class="line" :style="{color: item.itemStyle.color}">鈻� {{item.name}}</div>
-									<div style="font-weight: 700;font-size: 16px;color: #85B1E4;">锟{item.value}}</div>
-								</div>
-							</li>
-						</ul>
+					<!-- 宸ュ簭鍦ㄥ埗鍝佹暟閲忔煴鐘跺浘 -->
+					<div style="height: 70%">
+						<Echarts ref="chart"
+										 :chartStyle="chartStyle"
+										 :grid="grid"
+										 :legend="workInProcessBarLegend"
+										 :series="workInProcessBarSeries"
+										 :tooltip="tooltip"
+										 :xAxis="workInProcessXAxis"
+										 :yAxis="workInProcessYAxis"
+										 :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
+										 style="height: 100%"></Echarts>
 					</div>
         </div>
 
         <!-- 璐ㄩ噺缁熻 -->
 				<div class="panel-header">
-					<span class="panel-title">璐ㄩ噺缁熻</span>
+					<span class="panel-title">杩�4鏈堣川閲忕粺璁�</span>
 				</div>
 				<div class="main-panel">
 					<div class="panel-item-customers">
@@ -62,21 +73,21 @@
 							<div class="quality-cardSec">
 								<div class="quality-card one"></div>
 								<div class="quality-cardTitle">
-									<div>鍘熸潗鏂欏凡妫�娴嬫暟</div>
+									<div>鍘熸潗鏂欐鏁�</div>
 									<div>{{qualityStatisticsObject.supplierNum}}浠�</div>
 								</div>
 							</div>
 							<div class="quality-cardSec">
 								<div class="quality-card two"></div>
 								<div class="quality-cardTitle">
-									<div>杩囩▼妫�楠屾暟閲�</div>
+									<div>杩囩▼妫�鏁�</div>
 									<div>{{qualityStatisticsObject.processNum}}浠�</div>
 								</div>
 							</div>
 							<div class="quality-cardSec">
 								<div class="quality-card three"></div>
 								<div class="quality-cardTitle">
-									<div>鍑哄巶宸叉鏁伴噺</div>
+									<div>鍑哄巶妫�鏁�</div>
 									<div>{{qualityStatisticsObject.factoryNum}}浠�</div>
 								</div>
 							</div>
@@ -174,24 +185,76 @@
         </div>
 				
 				<div class="financial-header">
-					<span class="financial-title">璐㈠姟鍒嗘瀽</span>
+					<span class="financial-title">鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻</span>
 				</div>
 				<div class="main-panel">
 					<div class="panel-item-customers">
-						<div class="event-header">
-							<img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
-							<span class="event-title">缁忚惀鎴愭灉鍒嗘瀽</span>
+						<div class="order-statistics-cards" style="margin-bottom: 0px;">
+							<div class="quality-cardSec">
+								<div class="quality-card four"></div>
+								<div class="quality-cardTitle">
+									<div>鎬昏鍗曟暟</div>
+									<div>{{orderStatisticsObject.totalOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card five"></div>
+								<div class="quality-cardTitle">
+									<div>鏈畬鎴愯鍗曟暟</div>
+									<div>{{orderStatisticsObject.uncompletedOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card six"></div>
+								<div class="quality-cardTitle">
+									<div>閮ㄥ垎瀹屾垚璁㈠崟鏁�</div>
+									<div>{{orderStatisticsObject.partialCompletedOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card seven"></div>
+								<div class="quality-cardTitle">
+									<div>宸插畬鎴愯鍗曟暟</div>
+									<div>{{orderStatisticsObject.completedOrderCount}}浠�</div>
+								</div>
+							</div>
 						</div>
-						<Echarts ref="chart"
-										 :chartStyle="chartStyle"
-										 :grid="grid"
-										 :legend="barLegend1"
-										 :series="barSeries11"
-										 :tooltip="tooltip"
-										 :xAxis="xAxis3"
-										 :yAxis="yAxis3"
-										 :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
-										 style="height: 300px"></Echarts>
+						<div class="progress-table-container" ref="progressTableRef" style="margin-top: 0px;" @scroll="handleTableScroll">
+							<table class="progress-table">
+								<thead>
+									<tr>
+										<th>鐢熶骇璁㈠崟鍙�</th>
+										<th>浜у搧鍚嶇О</th>
+										<th>瑙勬牸</th>
+										<th>闇�姹傛暟閲�</th>
+										<th>瀹屾垚鏁伴噺</th>
+										<th>瀹屾垚杩涘害</th>
+									</tr>
+								</thead>
+								<tbody>
+									<tr 
+										v-for="(item, index) in progressTableData" 
+										:key="index"
+										:ref="el => setRowRef(el, index)"
+										:class="{ 'row-under-header': isRowUnderHeader(index) }"
+									>
+										<td>{{ item.npsNo || '-' }}</td>
+										<td>{{ item.productCategory || '-' }}</td>
+										<td>{{ item.specificationModel || '-' }}</td>
+										<td>{{ item.quantity || 0 }}</td>
+										<td>{{ item.completeQuantity || 0 }}</td>
+										<td>
+											<el-progress
+												:percentage="calculateProgress(item)"
+												:color="progressColor(calculateProgress(item))"
+												:status="calculateProgress(item) >= 100 ? 'success' : ''"
+												:stroke-width="8"
+											/>
+										</td>
+									</tr>
+								</tbody>
+							</table>
+						</div>
 					</div>
 				</div>
       </div>
@@ -205,11 +268,11 @@
 				<div class="panel-item-customers">
 					<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
 						<div class="section-title">搴旀敹搴斾粯缁熻</div>
-						<el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group">
-							<el-radio-button label="鎸夊懆" :value="1" />
-							<el-radio-button label="鎸夋湀" :value="2" />
-							<el-radio-button label="鎸夊搴�" :value="3" />
-						</el-radio-group>
+<!--						<el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group">-->
+<!--							<el-radio-button label="鎸夊懆" :value="1" />-->
+<!--							<el-radio-button label="鎸夋湀" :value="2" />-->
+<!--							<el-radio-button label="鎸夊搴�" :value="3" />-->
+<!--						</el-radio-group>-->
 					</div>
 					<Echarts ref="chart"
 									 :color="barColors2"
@@ -226,7 +289,7 @@
 
         <!-- 鍥炴涓庡紑绁ㄥ垎鏋� -->
          <div class="panel-header">
-					<span class="panel-title">鍥炴涓庡紑绁ㄥ垎鏋�</span>
+					<span class="panel-title">杩戜竴鏈堝洖娆句笌寮�绁ㄥ垎鏋�</span>
 				</div>
         <div class="panel-item-customers" style="padding-top: 60px;">
 					<Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries"
@@ -234,12 +297,13 @@
 				</div>
       </div>
       </div>
+      </div>
     </div>
 </template>
 
 <script setup>
 import * as echarts from 'echarts'
-import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
+import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue'
 import autofit from 'autofit.js'
 import Echarts from "@/components/Echarts/echarts.vue";
 import useUserStore from '@/store/modules/user'
@@ -247,7 +311,9 @@
 	analysisCustomerContractAmounts, getAmountHalfYear,
 	homeTodos,
 	qualityStatistics,
-	statisticsReceivablePayable
+	statisticsReceivablePayable,
+	getProgressStatistics,
+  	getWorkInProcessTurnover
 } from "@/api/viewIndex.js";
 import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
 import {listCustomer} from "@/api/basicData/customerFile.js";
@@ -257,9 +323,16 @@
 import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js";
 import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js";
 import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js";
+import {productOrderListPage} from "@/api/productionManagement/productionOrder.js";
 
 // 鍏ㄥ睆鐩稿叧鐘舵��
 const isFullscreen = ref(false);
+
+// 缂╂斁姣斾緥
+const scaleRatio = ref(1)
+// 璁捐灏哄锛堝熀鍑嗗昂瀵革級- 鏍规嵁瀹為檯璁捐绋胯皟鏁�
+const designWidth = 1920
+const designHeight = 1080
 
 // 鐢ㄦ埛store
 const userStore = useUserStore()
@@ -278,11 +351,17 @@
 const realtimeLineChartRef = ref(null)
 const refContractList = ref(null)
 const refTodoList = ref(null)
+const progressTableRef = ref(null)
 const timerScroll = ref(null)
+const progressTableScrollTimer = ref(null)
+const isTableScrolling = ref(false)
+const tableScrollTimeout = ref(null)
+const tableRowRefs = ref([])
+const rowsUnderHeader = ref(new Set())
 
 const chartStylePie = {
-	width: '140%',
-	height: '140%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+	width: '100%',
+	height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
 }
 const materialPieSeries = ref([
 	{
@@ -326,6 +405,21 @@
 	supplierNum: 0,
 	processNum: 0,
 	factoryNum: 0,
+})
+
+// 璁㈠崟缁熻瀵硅薄
+const orderStatisticsObject = ref({
+	totalOrderCount: 0,
+	uncompletedOrderCount: 0,
+	partialCompletedOrderCount: 0,
+	completedOrderCount: 0,
+})
+
+// 鍦ㄥ埗鍝佸懆杞粺璁″璞�
+const workInProcessStatistics = ref({
+	totalQuantity: 0,
+	avgTurnoverDays: 0,
+	turnoverEfficiency: 0,
 })
 const chartStyle = {
 	width: '100%',
@@ -412,82 +506,59 @@
 const barLegend = {
 	show: true,
 	textStyle: { color: '#B8C8E0' },
-	data: ['鍘熸潗鏂欎笉鍚堟牸鏁�', '杩囩▼涓嶅悎鏍兼暟', '鍑哄巶涓嶅悎鏍兼暟']
+	data: ['鍘熸潗鏂欏悎鏍兼暟', '杩囩▼鍚堟牸鏁�', '鍑轰笉鍚堟牸鏁�']
 }
 const barLegend1 = {
-	show: true,
+	show: false,
 	textStyle: { color: '#B8C8E0' },
-	data: ['鎬绘敹鍏�', '鎬绘敮鍑�', '鍑�鏀跺叆']
+	data: []
 }
 const barSeries11 = ref([
 	{
-		name: '鎬绘敹鍏�',
+		name: '鐢熶骇璁㈠崟缁熻',
 		type: 'bar',
 		barGap: 0,
 		emphasis: {
 			focus: 'series'
 		},
 		itemStyle: {
-			color: {
-				type: 'linear',
-				x: 0,
-				y: 0,
-				x2: 0,
-				y2: 1,
-				colorStops: [
-					{ offset: 1, color: '#00A4ED' },
-					{ offset: 0, color: '#4EE4FF' }
+			// 浣跨敤鍑芥暟鏍规嵁鏁版嵁绱㈠紩杩斿洖涓嶅悓棰滆壊
+			color: function(params) {
+				const colorStops = [
+					[
+						{ offset: 1, color: '#00A4ED' },
+						{ offset: 0, color: '#4EE4FF' }
+					],
+					[
+						{ offset: 1, color: '#3378FF' },
+						{ offset: 0, color: '#4E8AFF' }
+					],
+					[
+						{ offset: 1, color: '#FF6B6B' },
+						{ offset: 0, color: '#FF8E8E' }
+					],
+					[
+						{ offset: 1, color: '#537EF5' },
+						{ offset: 0, color: '#9061F8' }
+					]
 				]
+				const stops = colorStops[params.dataIndex] || colorStops[0]
+				return {
+					type: 'linear',
+					x: 0,
+					y: 0,
+					x2: 0,
+					y2: 1,
+					colorStops: stops
+				}
 			}
 		},
 		data: []
-	},
-	{
-		name: '鎬绘敮鍑�',
-		type: 'bar',
-		emphasis: {
-			focus: 'series'
-		},
-		itemStyle: {
-			color: {
-				type: 'linear',
-				x: 0,
-				y: 0,
-				x2: 0,
-				y2: 1,
-				colorStops: [
-					{ offset: 1, color: '#3378FF' },
-					{ offset: 0, color: '#4E8AFF' }
-				]
-			}
-		},
-		data: []
-	},
-	{
-		name: '鍑�鏀跺叆',
-		type: 'bar',
-		emphasis: {
-			focus: 'series'
-		},
-		itemStyle: {
-			color: {
-				type: 'linear',
-				x: 0,
-				y: 0,
-				x2: 0,
-				y2: 1,
-				colorStops: [
-					{ offset: 1, color: '#537EF5' },
-					{ offset: 0, color: '#9061F8' }
-				]
-			}
-		},
-		data: []
-	},
+	}
 ])
 const barSeries1 = ref([
 	{
-		name: '鍘熸潗鏂欎笉鍚堟牸鏁�',
+		name: '鍘熸潗鏂欏悎鏍兼暟',
 		type: 'bar',
 		barGap: 0,
 		emphasis: {
@@ -509,7 +580,7 @@
 		data: []
 	},
 	{
-		name: '杩囩▼涓嶅悎鏍兼暟',
+		name: '杩囩▼鍚堟牸鏁�',
 		type: 'bar',
 		emphasis: {
 			focus: 'series'
@@ -530,7 +601,7 @@
 		data: []
 	},
 	{
-		name: '鍑哄巶涓嶅悎鏍兼暟',
+		name: '鍑哄巶鍚堟牸鏁�',
 		type: 'bar',
 		emphasis: {
 			focus: 'series'
@@ -592,16 +663,113 @@
 	axisLabel: { color: '#B8C8E0' }
 }]
 
+// 鍦ㄥ埗鍝佸伐搴忔煴鐘跺浘閰嶇疆
+const workInProcessXAxis = ref([{
+	type: 'category',
+	axisTick: { show: false },
+	axisLabel: { color: '#B8C8E0' },
+	data: []
+}])
+const workInProcessYAxis = [{
+	type: 'value',
+	axisLabel: { color: '#B8C8E0' },
+	name: ''
+}]
+const workInProcessBarLegend = {
+	show: false,
+	textStyle: { color: '#B8C8E0' },
+	data: []
+}
+const workInProcessBarSeries = ref([
+	{
+		name: '鍦ㄥ埗鍝佹暟閲�',
+		type: 'bar',
+		barWidth: 25, // 鍥哄畾鏌辩姸鍥惧搴︿负40px
+		barGap: 0,
+		emphasis: {
+			focus: 'series'
+		},
+		itemStyle: {
+			color: {
+				type: 'linear',
+				x: 0,
+				y: 0,
+				x2: 0,
+				y2: 1,
+				colorStops: [
+					{ offset: 0, color: '#4EE4FF' },
+					{ offset: 1, color: '#00A4ED' }
+				]
+			}
+		},
+		label: {
+			show: true,
+			position: 'top',
+			color: '#B8C8E0'
+		},
+		data: []
+	}
+])
+
 // 寰呭姙浜嬮」
 const todoList = ref([])
 
-// 绐楀彛澶у皬鍙樺寲澶勭悊
-const handleResize = () => {
+// 鐢熶骇璁㈠崟瀹屾垚杩涘害琛ㄦ牸鏁版嵁
+const progressTableData = ref([])
+
+// 璁$畻瀹屾垚杩涘害鐧惧垎姣�
+const calculateProgress = (item) => {
+	if (!item) return 0
+	// 浼樺厛浣跨敤completionStatus瀛楁
+	if (item.completionStatus !== undefined && item.completionStatus !== null) {
+		const percentage = Number(item.completionStatus)
+		if (isNaN(percentage)) return 0
+		return Math.min(Math.max(Math.round(percentage), 0), 100)
+	}
+	// 濡傛灉娌℃湁completionStatus锛屽垯鏍规嵁瀹屾垚鏁伴噺鍜岄渶姹傛暟閲忚绠�
+	if (!item.quantity || item.quantity === 0) return 0
+	const percentage = (item.completeQuantity || 0) / item.quantity * 100
+	return Math.min(Math.max(Math.round(percentage), 0), 100)
+}
+
+// 鏍规嵁杩涘害鐧惧垎姣旇繑鍥為鑹�
+const progressColor = (percentage) => {
+	const p = percentage || 0
+	if (p < 30) return "#f56c6c"
+	if (p < 50) return "#e6a23c"
+	if (p < 80) return "#409eff"
+	return "#67c23a"
+}
+
+// 璁$畻缂╂斁姣斾緥
+const calculateScale = () => {
+  const container = document.querySelector('.scale-container')
+  if (!container) return
+  
+  // 鑾峰彇瀹瑰櫒鐨勫疄闄呭昂瀵�
+	const rect = container.getBoundingClientRect?.()
+	const containerWidth = container.clientWidth || rect?.width || window.innerWidth
+	const containerHeight = container.clientHeight || rect?.height || window.innerHeight
+  
+  // 璁$畻瀹介珮缂╂斁姣斾緥锛屽彇杈冨皬鍊间互淇濊瘉鍐呭瀹屾暣鏄剧ず锛堢瓑姣旂缉鏀撅級
+  const scaleX = containerWidth / designWidth
+  const scaleY = containerHeight / designHeight
+  scaleRatio.value = Math.min(scaleX, scaleY)
+  
+  // 瑙﹀彂鍥捐〃resize
   charts.value.forEach(chart => {
     if (chart && chart.resize) {
       chart.resize()
     }
   })
+}
+
+// 绐楀彛澶у皬鍙樺寲澶勭悊
+const handleResize = () => {
+  // 寤惰繜鎵ц锛岀‘淇滵OM鏇存柊瀹屾垚
+  setTimeout(() => {
+    calculateScale()
+  }, 100)
 }
 
 // 閿�姣佸浘琛ㄥ疄渚�
@@ -626,6 +794,43 @@
 		}))
 	})
 }
+// 鍦ㄥ埗鍝佸懆杞粺璁�
+const workInProcessTurnoverInfo = () => {
+	getWorkInProcessTurnover().then((res) => {
+		console.log("鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹�:", res)
+		
+		if (!res || !res.data) {
+			console.warn('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹负绌�')
+			return
+		}
+		
+		// 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+		workInProcessStatistics.value = {
+			totalQuantity: res.data.totalOrderCount || 0,
+			avgTurnoverDays: res.data.averageTurnoverDays || 0,
+			turnoverEfficiency: res.data.turnoverEfficiency || 0,
+		}
+		
+		// 璁剧疆宸ュ簭鏌辩姸鍥炬暟鎹�
+		// X杞达細processDetails (宸ュ簭璇︽儏鏁扮粍)
+		// Y杞达細processQuantityDetails (宸ュ簭鏁伴噺璇︽儏鏁扮粍)
+		if (res.data.processDetails && Array.isArray(res.data.processDetails)) {
+			// 璁剧疆X杞存暟鎹紙宸ュ簭鍚嶇О锛�
+			workInProcessXAxis.value[0].data = res.data.processDetails
+		} else {
+			workInProcessXAxis.value[0].data = []
+		}
+		
+		if (res.data.processQuantityDetails && Array.isArray(res.data.processQuantityDetails)) {
+			// 璁剧疆Y杞存暟鎹紙鍦ㄥ埗鍝佹暟閲忥級
+			workInProcessBarSeries.value[0].data = res.data.processQuantityDetails
+		} else {
+			workInProcessBarSeries.value[0].data = []
+		}
+	}).catch((error) => {
+		console.error('鑾峰彇鍦ㄥ埗鍝佸懆杞粺璁″け璐�:', error)
+	})
+}
 // 璐ㄦ缁熻
 const qualityStatisticsInfo = () => {
 	qualityStatistics().then((res) => {
@@ -640,15 +845,44 @@
 		qualityStatisticsObject.value.factoryNum = res.data.factoryNum
 	})
 }
-// 璐㈠姟缁熻
-const accountStatisticsInfo = () => {
-	listPageAnalysis().then((res) => {
-		xAxis3.value[0].data = res.data.days
-		barSeries11.value[0].data = res.data.totalIncome
-		barSeries11.value[1].data = res.data.totalExpense
-		barSeries11.value[2].data = res.data.netIncome
+// 鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻
+const progressStatisticsInfo = () => {
+	// 浠庣粺璁℃帴鍙h幏鍙栫粺璁℃暟鎹�
+	getProgressStatistics().then((res) => {
+		console.log("鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻鏁版嵁:", res)
+		
+		if (!res || !res.data) {
+			console.warn('鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻鏁版嵁涓虹┖')
+			return
+		}
+		
+		// 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+		orderStatisticsObject.value = {
+			totalOrderCount: res.data.totalOrderCount || 0,
+			uncompletedOrderCount: res.data.uncompletedOrderCount || 0,
+			partialCompletedOrderCount: res.data.partialCompletedOrderCount || 0,
+			completedOrderCount: res.data.completedOrderCount || 0
+		}
+		progressTableData.value = res.data.completedOrderDetails || []
+		// 閲嶇疆琛屽紩鐢�
+		tableRowRefs.value = []
+		rowsUnderHeader.value.clear()
+		
+		// 鍦ㄨ幏鍙栧埌鏁版嵁鍚庯紝鍒濆鍖栨粴鍔ㄥ姛鑳�
+		nextTick(() => {
+			initProgressTableScroll()
+		})
+	}).catch((error) => {
+		console.error('鑾峰彇鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻澶辫触:', error)
 	})
 }
+// 璐㈠姟缁熻
+// const accountStatisticsInfo = () => {
+// 	listPageAnalysis().then((res) => {
+// 		xAxis3.value[0].data = res.data.days
+// 		barSeries11.value[0].data = res.data.totalIncome
+// 	})
+// }
 const getNum = () => {
 	const params = {
 		pageNum: -1,
@@ -672,10 +906,10 @@
 	getLedgerPage(params).then((res) => {
 		equipmentNum.value = res.data.total
 	});
-	getRepairPage(params).then((res) => {
+	getRepairPage({...params, status:0}).then((res) => {
 		equipmentRepair.value = res.data.total
 	});
-	getUpkeepPage(params).then((res) => {
+	getUpkeepPage({...params, status:0}).then((res) => {
 		equipmentMaintain.value = res.data.total
 	});
 	measuringInstrumentListPage(params).then((res) => {
@@ -783,6 +1017,163 @@
 
 // 鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
 const autoSwitchTimer = ref(null)
+
+// 璁剧疆琛屽紩鐢�
+const setRowRef = (el, index) => {
+	if (el) {
+		tableRowRefs.value[index] = el
+	}
+}
+
+// 鍒ゆ柇琛屾槸鍚﹀湪琛ㄥご涓嬫柟
+const isRowUnderHeader = (index) => {
+	return rowsUnderHeader.value.has(index)
+}
+
+// 澶勭悊琛ㄦ牸婊氬姩浜嬩欢
+const handleTableScroll = () => {
+	const tableContainer = progressTableRef.value
+	if (!tableContainer) return
+	
+	const thead = tableContainer.querySelector('thead')
+	if (!thead) return
+	
+	const theadHeight = thead.offsetHeight
+	const containerRect = tableContainer.getBoundingClientRect()
+	const containerTop = containerRect.top
+	const theadBottom = containerTop + theadHeight
+	
+	// 娓呯┖涔嬪墠鐨勮褰�
+	rowsUnderHeader.value.clear()
+	
+	// 妫�鏌ユ瘡涓�琛屾槸鍚﹀湪琛ㄥご涓嬫柟锛堣琛ㄥご閬尅锛�
+	tableRowRefs.value.forEach((row, index) => {
+		if (row) {
+			const rowRect = row.getBoundingClientRect()
+			const rowTop = rowRect.top
+			const rowBottom = rowRect.bottom
+			
+			// 濡傛灉琛屼笌琛ㄥご鏈夐噸鍙狅紙琛屽湪琛ㄥご涓嬫柟琚伄鎸★級
+			// 琛岀殑椤堕儴鍦ㄨ〃澶村簳閮ㄤ笅鏂癸紝浣嗚鐨勫簳閮ㄥ湪琛ㄥご搴曢儴涓婃柟锛岃鏄庤閬尅
+			if (rowTop < theadBottom && rowBottom > containerTop) {
+				rowsUnderHeader.value.add(index)
+			}
+		}
+	})
+	
+	// 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+	if (tableScrollTimeout.value) {
+		clearTimeout(tableScrollTimeout.value)
+	}
+	
+	// 婊氬姩鍋滄鍚庢竻绌烘贰鍖栨爣璁�
+	tableScrollTimeout.value = setTimeout(() => {
+		rowsUnderHeader.value.clear()
+	}, 150)
+}
+
+// 鍒濆鍖栫敓浜ц鍗曡繘搴﹁〃鏍兼粴鍔ㄥ姛鑳�
+const initProgressTableScroll = () => {
+	const tableContainer = progressTableRef.value
+	if (!tableContainer) return
+	
+	// 娓呯悊涔嬪墠鐨勬粴鍔ㄥ姩鐢诲拰瀹氭椂鍣�
+	if (progressTableScrollTimer.value) {
+		cancelAnimationFrame(progressTableScrollTimer.value)
+		progressTableScrollTimer.value = null
+	}
+	if (tableContainer._pauseTimer) {
+		clearInterval(tableContainer._pauseTimer)
+		tableContainer._pauseTimer = null
+	}
+	
+	const tbody = tableContainer.querySelector('tbody')
+	if (!tbody) return
+	
+	// 娓呯悊涔嬪墠鍙兘瀛樺湪鐨勫厠闅嗚锛堜繚鐣欏師濮嬫暟鎹锛�
+	// 鍘熷鏁版嵁琛岀殑鏁伴噺搴旇绛変簬 progressTableData.value.length
+	const originalCount = progressTableData.value.length
+	const allRows = Array.from(tbody.querySelectorAll('tr'))
+	if (allRows.length > originalCount) {
+		// 绉婚櫎鎵�鏈夎秴杩囧師濮嬫暟閲忕殑琛岋紙杩欎簺鏄厠闅嗙殑琛岋級
+		for (let i = originalCount; i < allRows.length; i++) {
+			allRows[i].remove()
+		}
+	}
+	
+	const scrollItems = Array.from(tbody.querySelectorAll('tr'))
+	if (scrollItems.length === 0) return
+	
+	// 鑾峰彇鍘熷鏁版嵁椤规暟閲�
+	const originalItemCount = scrollItems.length
+	
+	// 璁$畻瀹瑰櫒楂樺害鍜岃〃澶撮珮搴�
+	const thead = tableContainer.querySelector('thead')
+	const theadHeight = thead ? thead.offsetHeight : 40
+	const containerHeight = tableContainer.clientHeight
+	const visibleHeight = containerHeight - theadHeight
+	
+	// 璁$畻鍘熷鏁版嵁鐨勬�婚珮搴�
+	const itemHeight = scrollItems[0]?.offsetHeight || 40
+	const totalContentHeight = itemHeight * originalItemCount
+	
+	// 濡傛灉鏁版嵁閲忎笉澶燂紝瀹瑰櫒鍙互瀹屽叏鏄剧ず鎵�鏈夋暟鎹紝灏变笉闇�瑕佹粴鍔ㄥ拰鍏嬮殕
+	if (totalContentHeight <= visibleHeight) {
+		// 鏁版嵁閲忓皯锛屼笉闇�瑕佹粴鍔紝鐩存帴杩斿洖
+		return
+	}
+	
+	// 鏁版嵁閲忚冻澶燂紝闇�瑕佹粴鍔紝杩涜鍏嬮殕浠ュ疄鐜版棤缂濇粴鍔�
+	const cloneCount = Math.ceil(visibleHeight / itemHeight) + 2
+	
+	// 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
+	for (let i = 0; i < cloneCount; i++) {
+		const clone = scrollItems[i % originalItemCount].cloneNode(true)
+		tbody.appendChild(clone)
+	}
+	
+	let scrollPosition = 0
+	const scrollSpeed = 1.5
+	const pauseTime = 3000
+	let isPaused = false
+	let lastTimestamp = 0
+	
+	// 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
+	function scrollAnimation(timestamp) {
+		if (!lastTimestamp) lastTimestamp = timestamp
+		const deltaTime = timestamp - lastTimestamp
+		lastTimestamp = timestamp
+		
+		if (!isPaused) {
+			scrollPosition += scrollSpeed * (deltaTime / 16)
+			
+			// 璁$畻鏈�澶ф粴鍔ㄤ綅缃紙鍘熷鍐呭鐨勯珮搴︼級
+			const maxScroll = itemHeight * originalItemCount
+			
+			// 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
+			if (scrollPosition >= maxScroll) {
+				scrollPosition = 0
+				tableContainer.scrollTop = 0
+			} else {
+				tableContainer.scrollTop = scrollPosition
+			}
+		}
+		
+		progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+	}
+	
+	// 鍚姩婊氬姩鍔ㄧ敾
+	progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+	
+	// 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
+	const pauseTimer = setInterval(() => {
+		isPaused = !isPaused
+	}, pauseTime)
+	
+	// 娓呯悊瀹氭椂鍣�
+	tableContainer._pauseTimer = pauseTimer
+}
+
 // 鍒濆鍖栧緟鍔炰簨椤瑰垪琛ㄦ粴鍔ㄥ姛鑳�
 const initTodoListScroll = () => {
 	const todoList = refTodoList.value
@@ -881,9 +1272,9 @@
   updateTime()
   timer.value = setInterval(updateTime, 1000)
 }
-// 鍏ㄥ睆鍔熻兘瀹炵幇 - 閽堝data-dashboard鍏冪礌
+// 鍏ㄥ睆鍔熻兘瀹炵幇 - 閽堝scale-container鍏冪礌
 const toggleFullscreen = () => {
-	const element = document.querySelector('.data-dashboard')
+	const element = document.querySelector('.scale-container')
 	
 	if (!element) return
 	
@@ -911,7 +1302,12 @@
   const fullscreenElement = document.fullscreenElement || 
                            document.webkitFullscreenElement || 
                            document.msFullscreenElement
-  isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('data-dashboard')
+  isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('scale-container')
+  
+  // 鍏ㄥ睆鐘舵�佸彉鍖栨椂锛屽欢杩熼噸鏂拌绠楃缉鏀炬瘮渚嬶紙纭繚DOM鏇存柊瀹屾垚锛�
+  setTimeout(() => {
+    calculateScale()
+  }, 200)
 }
 
 // 鐢熷懡鍛ㄦ湡閽╁瓙
@@ -919,8 +1315,11 @@
   initTime()
   // 浣跨敤nextTick纭繚DOM瀹屽叏娓叉煋鍚庡啀鍒濆鍖栧浘琛�
   nextTick(() => {
-    // 鍒濆鍖朼utofit鑷�傚簲
-    autofit.init({ dh: 1080, dw: 1920, el: '.data-dashboard', resize: true }, false)
+    // 璁$畻鍒濆缂╂斁姣斾緥
+    calculateScale()
+    
+    // 鍒濆鍖朼utofit鑷�傚簲锛堝鏋滈渶瑕佷繚鐣檃utofit锛屽彲浠ヤ繚鐣欙紝浣嗕富瑕佺缉鏀剧敱scale-container鎺у埗锛�
+    // autofit.init({ dh: 800, dw: 1280, el: '.data-dashboard', resize: true }, false)
     
     // 娣诲姞鑷姩婊氬姩鍔ㄧ敾鏁堟灉 - 瀹㈡埛淇℃伅鍒楄〃
     const contractList = refContractList.value
@@ -980,9 +1379,14 @@
   })
   
   window.addEventListener('resize', handleResize)
+  window.addEventListener('fullscreenchange', handleFullscreenChange)
+  window.addEventListener('webkitfullscreenchange', handleFullscreenChange)
+  window.addEventListener('MSFullscreenChange', handleFullscreenChange)
   analysisCustomer()
+  workInProcessTurnoverInfo()
   qualityStatisticsInfo()
-	accountStatisticsInfo()
+	// accountStatisticsInfo()
+	progressStatisticsInfo()
   getNum()
   getLedgerNum()
   todoInfoS()
@@ -1023,6 +1427,25 @@
     }
   }
   
+  // 娓呯悊鐢熶骇璁㈠崟杩涘害琛ㄦ牸鐨勫姩鐢诲拰瀹氭椂鍣�
+  const progressTable = progressTableRef.value
+  if (progressTable) {
+    if (progressTableScrollTimer.value) {
+      cancelAnimationFrame(progressTableScrollTimer.value)
+      progressTableScrollTimer.value = null
+    }
+    if (progressTable._pauseTimer) {
+      clearInterval(progressTable._pauseTimer)
+      progressTable._pauseTimer = null
+    }
+  }
+  
+  // 娓呯悊琛ㄦ牸婊氬姩瀹氭椂鍣�
+  if (tableScrollTimeout.value) {
+    clearTimeout(tableScrollTimeout.value)
+    tableScrollTimeout.value = null
+  }
+  
   // 娓呯悊鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
   if (autoSwitchTimer.value) {
     clearInterval(autoSwitchTimer.value)
@@ -1045,43 +1468,58 @@
 </script>
 
 <style scoped>
+/* 澶栭儴缂╂斁瀹瑰櫒 - 鍗犳嵁鏁翠釜瑙嗗彛 */
+.scale-container {
+  position: relative;
+	width: 100%;
+	/* 椤甸潰鍦ㄥ父瑙勫竷灞�涓嬶紙鏈夐《鏍忥級榛樿鍑忓幓 84px锛岄伩鍏嶅唴瀹硅瑁佸垏 */
+	height: calc(100vh - 84px);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #000;
+	overflow: hidden;
+}
+
+/* 鍐呴儴鍐呭鍖哄煙 - 鍥哄畾璁捐灏哄 */
 .data-dashboard {
   position: relative;
-  width: 100%;
-	height: 100%;
+  width: 1920px;
+  height: 1080px;
 	background-image: url("@/assets/BI/backImage@2x.png");
 	background-size: cover;
 	background-position: center;
 	background-repeat: no-repeat;
+	transform-origin: center center;
 }
 
-/* 鍏ㄥ睆鐘舵�佺殑鏍峰紡 */
-.data-dashboard:fullscreen {
-  width: 100%;
-  height: 100%;
+/* 鍏ㄥ睆鐘舵�佺殑鏍峰紡 - 浣滅敤浜巗cale-container */
+.scale-container:fullscreen {
+	width: 100vw;
+	height: 100vh;
   margin: 0;
   padding: 0;
-  background-color: inherit;
+  background-color: #000;
   z-index: 9999;
 }
 
 /* Webkit娴忚鍣ㄥ墠缂� */
-.data-dashboard:-webkit-full-screen {
-  width: 100%;
-  height: 100%;
+.scale-container:-webkit-full-screen {
+  width: 100vw;
+  height: 100vh;
   margin: 0;
   padding: 0;
-  background-color: inherit;
+  background-color: #000;
   z-index: 9999;
 }
 
 /* MS娴忚鍣ㄥ墠缂� */
-.data-dashboard:-ms-fullscreen {
-  width: 100%;
-  height: 100%;
+.scale-container:-ms-fullscreen {
+  width: 100vw;
+  height: 100vh;
   margin: 0;
   padding: 0;
-  background-color: inherit;
+  background-color: #000;
   z-index: 9999;
 }
 
@@ -1089,10 +1527,9 @@
 .dashboard-header {
   position: relative;
   z-index: 1;
-  height: 170px;
+	height: 86px;
 	background-image: url("@/assets/BI/biaoti.png");
 	background-size: cover;
-	background-position: center;
 	background-repeat: no-repeat;
   display: flex;
   align-items: center;
@@ -1103,7 +1540,7 @@
   font-weight: 600;
 font-size: 52px;
 color: #FFFFFF;
-top: 32px;
+top: 16px;
 position: absolute;
 }
 
@@ -1136,7 +1573,7 @@
   display: flex;
   gap: 30px;
   padding: 0 30px;
-  height: calc(100% - 120px);
+	height: calc(100% - 86px);
   overflow: hidden;
 }
 
@@ -1177,7 +1614,7 @@
 	display: flex;
 	gap: 12px;
 	width: 100%;
-	height: 94px;
+	height: 54px;
 	justify-content: space-between;
 	align-items: center;
 }
@@ -1207,7 +1644,33 @@
 }
 .quality-card.three {
 	background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
-	
+}
+
+/* 璁㈠崟缁熻鍗$墖鏍峰紡 */
+.order-statistics-cards {
+	display: flex;
+	gap: 12px;
+	width: 100%;
+	height: 94px;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 20px;
+}
+
+.quality-card.four {
+	background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
+}
+
+.quality-card.five {
+	background-image: url("@/assets/BI/guochengyijianicon@2x.png");
+}
+
+.quality-card.six {
+	background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
+}
+
+.quality-card.seven {
+	background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
 }
 .panel-title-icon {
 	width: 60px;
@@ -1490,4 +1953,84 @@
   border-color: rgba(255, 255, 255, 0.5);
   box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5);
 }
+
+/* 鐢熶骇璁㈠崟杩涘害琛ㄦ牸鏍峰紡 */
+.progress-table-container {
+  height: 200px;
+  overflow-y: auto;
+  overflow-x: hidden;
+  margin-top: 10px;
+  scrollbar-width: none; /* Firefox */
+  -ms-overflow-style: none; /* IE鍜孍dge */
+}
+
+.progress-table-container::-webkit-scrollbar {
+  display: none; /* Chrome銆丼afari鍜孫pera */
+}
+
+.progress-table {
+  width: 100%;
+  border-collapse: collapse;
+  color: #B8C8E0;
+  font-size: 12px;
+  table-layout: fixed;
+}
+
+.progress-table thead {
+  position: sticky;
+  top: 0;
+  background-color: rgba(26, 88, 176, 0.9);
+  z-index: 10;
+}
+
+.progress-table th {
+  padding: 8px 6px;
+  text-align: left;
+  font-weight: 500;
+  border-bottom: 1px solid rgba(184, 200, 224, 0.3);
+  color: #B8C8E0;
+  font-size: 12px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.progress-table th:nth-child(1) { width: 15%; } /* 鐢熶骇璁㈠崟鍙� */
+.progress-table th:nth-child(2) { width: 15%; } /* 浜у搧鍚嶇О */
+.progress-table th:nth-child(3) { width: 15%; } /* 瑙勬牸 */
+.progress-table th:nth-child(4) { width: 12%; } /* 闇�姹傛暟閲� */
+.progress-table th:nth-child(5) { width: 12%; } /* 瀹屾垚鏁伴噺 */
+.progress-table th:nth-child(6) { width: 31%; } /* 瀹屾垚杩涘害 */
+
+.progress-table td {
+  padding: 8px 6px;
+  border-bottom: 1px solid rgba(184, 200, 224, 0.1);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-size: 12px;
+  transition: opacity 0.3s ease;
+}
+
+.progress-table tbody tr:hover {
+  background-color: rgba(184, 200, 224, 0.1);
+}
+
+.progress-table tbody tr.row-under-header {
+  opacity: 0.5;
+}
+
+/* el-progress 缁勪欢鏍峰紡璋冩暣 */
+.progress-table :deep(.el-progress) {
+  width: 100%;
+}
+
+.progress-table :deep(.el-progress-bar__outer) {
+  background-color: rgba(184, 200, 224, 0.2);
+}
+
+.progress-table :deep(.el-progress__text) {
+  color: #B8C8E0;
+  font-size: 11px;
+}
 </style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
index 1aa36c1..f61cbe5 100644
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ b/src/views/reportAnalysis/projectProfit/index.vue
@@ -1,30 +1,32 @@
 <template>
-  <div class="app-container">
-    <el-form :model="filters" :inline="true" label-width="80px">
-      <el-form-item label="瀹㈡埛鍚嶇О">
-        <el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
-        <el-button @click="resetFilters"> 閲嶇疆 </el-button>
-        <el-button @click="handleOut"> 瀵煎嚭 </el-button>
-      </el-form-item>
-    </el-form>
-    <div class="table_list">
-      <PIMTable
-        rowKey="id"
-        :column="columns"
-        :tableLoading="loading"
-        :tableData="dataList"
-        :page="{
+	<div class="app-container">
+		<el-form :model="filters" :inline="true" label-width="80px">
+			<el-form-item label="瀹㈡埛鍚嶇О">
+				<el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" clearable style="width: 240px"/>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
+				<el-button @click="resetFilters"> 閲嶇疆 </el-button>
+				<el-button @click="handleOut"> 瀵煎嚭 </el-button>
+			</el-form-item>
+		</el-form>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="columns"
+				:tableLoading="loading"
+				:tableData="dataList"
+				:page="{
           current: pagination.currentPage,
           size: pagination.pageSize,
-          total: pagination.total,
+          total: pagination.total
         }"
-        @pagination="changePage"
-      ></PIMTable>
-    </div>
-  </div>
+				:isShowSummary="true"
+				:summaryMethod="summarizeMainTable"
+				@pagination="changePage"
+			></PIMTable>
+		</div>
+	</div>
 </template>
 
 <script setup>
@@ -36,93 +38,89 @@
 const { proxy } = getCurrentInstance();
 
 defineOptions({
-  name: "椤圭洰鍒╂鼎",
+	name: "椤圭洰鍒╂鼎",
 });
 
 const {
-  loading,
-  filters,
-  columns,
-  dataList,
-  pagination,
-  getTableData,
-  resetFilters,
-  onCurrentChange,
+	loading,
+	filters,
+	columns,
+	dataList,
+	pagination,
+	getTableData,
+	resetFilters,
+	onCurrentChange,
 } = usePaginationApi(
-  getPurchaseList,
-  {
-    customerName: undefined,
-  },
-  [
-    {
-      label: "閿�鍞悎鍚屽彿",
-      align: "center",
-      prop: "customerContractNo",
-    },
-    {
-      label: "瀹㈡埛鍚嶇О",
-      align: "center",
-      prop: "customerName",
-    },
-    {
-      label: "椤圭洰鍚嶇О",
-      align: "center",
-      prop: "projectName",
-    },
-    {
-      label: "鍚堝悓閲戦",
-      align: "center",
-      prop: "contractAmount",
-    },
-    {
-      label: "閲囪喘閲戦",
-      align: "center",
-      prop: "purchaseAmount",
-    },
-    {
-      label: "鍒╂鼎",
-      align: "center",
-      prop: "balance",
-    },
-    {
-      label: "鍒╂鼎鐜�",
-      align: "center",
-      prop: "balanceRatio",
-    },
-    {
-      label: "澧炲�肩◣",
-      align: "center",
-      prop: "balanceAmount",
-    },
-  ]
+	getPurchaseList,
+	{
+		customerName: undefined,
+	},
+	[
+		{
+			label: "閿�鍞悎鍚屽彿",
+			align: "center",
+			prop: "customerContractNo",
+		},
+		{
+			label: "瀹㈡埛鍚嶇О",
+			align: "center",
+			prop: "customerName",
+		},
+		{
+			label: "鍚堝悓閲戦",
+			align: "center",
+			prop: "contractAmount",
+		},
+		{
+			label: "閲囪喘閲戦",
+			align: "center",
+			prop: "purchaseAmount",
+		},
+		{
+			label: "鍒╂鼎",
+			align: "center",
+			prop: "balance",
+		},
+		{
+			label: "鍒╂鼎鐜�",
+			align: "center",
+			prop: "balanceRatio",
+		},
+	]
 );
 
-const changePage = ({ page }) => {
-  pagination.currentPage = page;
-  onCurrentChange(page);
+const changePage = ({ page, limit }) => {
+	pagination.currentPage = page;
+	pagination.pageSize = limit;
+	onCurrentChange(page);
+};
+
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = (param) => {
+	return proxy.summarizeTable(param, ["contractAmount", "purchaseAmount", "balance"]);
 };
 
 // 瀵煎嚭
 const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
 };
 
 onMounted(() => {
-  getTableData();
+	getTableData();
 });
 </script>
 <style lang="scss" scoped>
 .table_list {
-  margin-top: unset;
+	margin-top: unset;
 }
 </style>
diff --git a/src/views/reportAnalysis/reportManagement/index.vue b/src/views/reportAnalysis/reportManagement/index.vue
index 2adfb54..343a2c2 100644
--- a/src/views/reportAnalysis/reportManagement/index.vue
+++ b/src/views/reportAnalysis/reportManagement/index.vue
@@ -1,715 +1,1471 @@
 <template>
-	<div class="report-management">
-		<!-- 绛涢�夋潯浠� -->
-		<el-card class="filter-card" shadow="never">
-			<el-form :model="filterForm" inline>
-				<el-form-item label="鏃堕棿鑼冨洿">
-					<el-date-picker
-						style="width: 300px"
-						v-model="filterForm.dateRange"
-						type="daterange"
-						range-separator="鑷�"
-						start-placeholder="寮�濮嬫棩鏈�"
-						end-placeholder="缁撴潫鏃ユ湡"
-						format="YYYY-MM-DD"
-						value-format="YYYY-MM-DD"
-						@change="handleFilterChange"
-					/>
-				</el-form-item>
-				<el-form-item label="鎶ヨ〃绫诲瀷">
-					<el-select v-model="filterForm.reportType" placeholder="璇烽�夋嫨鎶ヨ〃绫诲瀷" @change="handleFilterChange" style="width: 300px">
-						<el-option label="鏍峰搧杩涘害鎶ヨ〃" value="sample" />
-						<el-option label="璁惧浣跨敤鎶ヨ〃" value="equipment" />
-						<el-option label="妫�娴嬮」鐩姤琛�" value="inspection" />
-						<el-option label="棰嗙敤璁板綍鎶ヨ〃" value="usage" />
-					</el-select>
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" @click="handleFilterChange">鏌ヨ</el-button>
-					<el-button @click="resetFilter">閲嶇疆</el-button>
-					<el-button type="success" @click="exportReport">瀵煎嚭鎶ヨ〃</el-button>
-				</el-form-item>
-			</el-form>
-		</el-card>
-		
-		<!-- 缁熻鍗$墖 -->
-		<div class="statistics-cards">
-			<el-row :gutter="20">
-				<el-col :span="6">
-					<el-card class="stat-card" shadow="hover">
-						<div class="stat-content">
-							<div class="stat-icon">
-								<el-icon><Box /></el-icon>
-							</div>
-							<div class="stat-info">
-								<div class="stat-number">{{ statistics.totalSamples }}</div>
-								<div class="stat-label">鎬绘牱鍝佹暟</div>
-							</div>
-						</div>
-					</el-card>
-				</el-col>
-				<el-col :span="6">
-					<el-card class="stat-card" shadow="hover">
-						<div class="stat-content">
-							<div class="stat-icon">
-								<el-icon><Tools /></el-icon>
-							</div>
-							<div class="stat-info">
-								<div class="stat-number">{{ statistics.activeEquipment }}</div>
-								<div class="stat-label">鍦ㄧ敤璁惧</div>
-							</div>
-						</div>
-					</el-card>
-				</el-col>
-				<el-col :span="6">
-					<el-card class="stat-card" shadow="hover">
-						<div class="stat-content">
-							<div class="stat-icon">
-								<el-icon><Document /></el-icon>
-							</div>
-							<div class="stat-info">
-								<div class="stat-number">{{ statistics.completedInspections }}</div>
-								<div class="stat-label">宸插畬鎴愭娴�</div>
-							</div>
-						</div>
-					</el-card>
-				</el-col>
-				<el-col :span="6">
-					<el-card class="stat-card" shadow="hover">
-						<div class="stat-content">
-							<div class="stat-icon">
-								<el-icon><ShoppingCart /></el-icon>
-							</div>
-							<div class="stat-info">
-								<div class="stat-number">{{ statistics.totalUsage }}</div>
-								<div class="stat-label">鎬婚鐢ㄦ鏁�</div>
-							</div>
-						</div>
-					</el-card>
-				</el-col>
-			</el-row>
-		</div>
-		
-		<!-- 鍥捐〃鍖哄煙 -->
-		<div class="charts-container">
-			<el-row :gutter="20">
-				<!-- 鏍峰搧杩涘害鍥捐〃 -->
-				<el-col :span="12">
-					<el-card class="chart-card" shadow="hover">
-						<template #header>
-							<div class="card-header">
-								<span>鏍峰搧杩涘害缁熻</span>
-								<el-button link @click="refreshSampleChart">鍒锋柊</el-button>
-							</div>
-						</template>
-						<div ref="sampleChartRef" class="chart-container"></div>
-					</el-card>
-				</el-col>
-				
-				<!-- 璁惧浣跨敤鍥捐〃 -->
-				<el-col :span="12">
-					<el-card class="chart-card" shadow="hover">
-						<template #header>
-							<div class="card-header">
-								<span>璁惧浣跨敤鐜囩粺璁�</span>
-								<el-button link @click="refreshEquipmentChart">鍒锋柊</el-button>
-							</div>
-						</template>
-						<div ref="equipmentChartRef" class="chart-container"></div>
-					</el-card>
-				</el-col>
-			</el-row>
-			
-			<el-row :gutter="20" style="margin-top: 20px;">
-				<!-- 妫�娴嬮」鐩粺璁� -->
-				<el-col :span="12">
-					<el-card class="chart-card" shadow="hover">
-						<template #header>
-							<div class="card-header">
-								<span>妫�娴嬮」鐩垎甯�</span>
-								<el-button link @click="refreshInspectionChart">鍒锋柊</el-button>
-							</div>
-						</template>
-						<div ref="inspectionChartRef" class="chart-container"></div>
-					</el-card>
-				</el-col>
-				
-				<!-- 棰嗙敤璁板綍瓒嬪娍 -->
-				<el-col :span="12">
-					<el-card class="chart-card" shadow="hover">
-						<template #header>
-							<div class="card-header">
-								<span>棰嗙敤璁板綍瓒嬪娍</span>
-								<el-button link @click="refreshUsageChart">鍒锋柊</el-button>
-							</div>
-						</template>
-						<div ref="usageChartRef" class="chart-container"></div>
-					</el-card>
-				</el-col>
-			</el-row>
-		</div>
-		
-		<!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
-		<el-card class="table-card" shadow="hover">
-			<template #header>
-				<div class="card-header">
-					<span>璇︾粏鏁版嵁</span>
-					<div>
-						<el-button type="primary" size="small" @click="refreshTable">鍒锋柊</el-button>
-						<el-button type="success" size="small" @click="exportTable">瀵煎嚭</el-button>
-					</div>
-				</div>
-			</template>
-			
-			<el-table
-				:data="tableData"
-				style="width: 100%"
-				v-loading="tableLoading"
-				stripe
-				border
-			>
-				<el-table-column prop="id" label="缂栧彿" width="80" />
-				<el-table-column prop="name" label="鍚嶇О" />
-				<el-table-column prop="status" label="鐘舵��">
-					<template #default="scope">
-						<el-tag :type="getStatusType(scope.row.status)">
-							{{ scope.row.status }}
-						</el-tag>
-					</template>
-				</el-table-column>
-				<el-table-column prop="progress" label="杩涘害">
-					<template #default="scope">
-						<el-progress :percentage="scope.row.progress" :status="getProgressStatus(scope.row.progress)" />
-					</template>
-				</el-table-column>
-				<el-table-column prop="createTime" label="鍒涘缓鏃堕棿" width="180" />
-				<el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
-				<el-table-column label="鎿嶄綔" width="150" fixed="right">
-					<template #default="scope">
-						<el-button link size="small" @click="viewDetail(scope.row)">鏌ョ湅</el-button>
-						<el-button link size="small" @click="editItem(scope.row)">缂栬緫</el-button>
-					</template>
-				</el-table-column>
-			</el-table>
-			
-			<div class="pagination-container">
-				<el-pagination
-					v-model:current-page="pagination.currentPage"
-					v-model:page-size="pagination.pageSize"
-					:page-sizes="[10, 20, 50, 100]"
-					:total="pagination.total"
-					layout="total, sizes, prev, pager, next, jumper"
-					@size-change="handleSizeChange"
-					@current-change="handleCurrentChange"
-				/>
-			</div>
-		</el-card>
-	</div>
+  <div class="report-management">
+    <!-- 鍥捐〃鍖哄煙 -->
+    <div class="charts-container">
+      <el-row :gutter="20">
+        <!-- 鍚勭被鍨嬪畬鎴愭暟閲� -->
+        <el-col :span="9">
+          <el-card class="chart-card" shadow="hover">
+            <template #header>
+              <div class="card-header">
+                <div class="chart-title-line"></div>
+                <span>鍚勭被鍨嬪畬鎴愭暟閲�</span>
+              </div>
+            </template>
+            <div class="top-container">
+              <div class="typeNum">
+                <div class="typeNum-left">
+                  <img src="~@/assets/images/chartCard.svg" alt="鍥捐〃"
+                    style="width: 40px; height: 40px; object-fit: contain;">
+                  <div class="typeNum-left-text">鍘熸潗鏂�</div>
+                </div>
+                <div class="typeNum-center">
+                  <div class="typeNum-leftLine">-</div>
+                  <div class="typeNum-rightLine"></div>
+                </div>
+                <div class="typeNum-right">
+                  <div class="typeNum-right-top">
+                    <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(0, 'totalCount') }} <span
+                        class="unit">涓�</span></div>
+                  </div>
+                  <div class="typeNum-right-bottom">
+                    <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(0, 'completedCount') }} <span
+                        class="unit">涓�</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="typeNum">
+                <div class="typeNum-left">
+                  <img src="~@/assets/images/chartCard2.svg" alt="鍥捐〃"
+                    style="width: 40px; height: 40px; object-fit: contain;">
+                  <div class="typeNum-left-text" style="color: #5EB334;">鍗婃垚鍝�</div>
+                </div>
+                <div class="typeNum-center">
+                  <div class="typeNum-leftLine2">-</div>
+                  <div class="typeNum-rightLine2"></div>
+                </div>
+                <div class="typeNum-right">
+                  <div class="typeNum-right-top">
+                    <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(1, 'totalCount') }} <span
+                        class="unit">涓�</span></div>
+                  </div>
+                  <div class="typeNum-right-bottom">
+                    <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(1, 'completedCount') }} <span
+                        class="unit">涓�</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="typeNum">
+                <div class="typeNum-left">
+                  <img src="~@/assets/images/chartCard3.svg" alt="鍥捐〃"
+                    style="width: 40px; height: 40px; object-fit: contain;">
+                  <div class="typeNum-left-text" style="color: #8000FF;">鎴愬搧</div>
+                </div>
+                <div class="typeNum-center">
+                  <div class="typeNum-leftLine3">-</div>
+                  <div class="typeNum-rightLine3"></div>
+                </div>
+                <div class="typeNum-right">
+                  <div class="typeNum-right-top">
+                    <div class="typeNum-right-top-name">鎬绘暟閲�</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(2, 'totalCount') }} <span
+                        class="unit">涓�</span></div>
+                  </div>
+                  <div class="typeNum-right-bottom">
+                    <div class="typeNum-right-top-name">宸插畬鎴愭暟</div>
+                    <div class="typeNum-right-top-text">{{ getInspectStatValue(2, 'completedCount') }} <span
+                        class="unit">涓�</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <!-- 璐ㄦ鍚堟牸鐜� -->
+        <el-col :span="15">
+          <el-card class="chart-card" shadow="hover">
+            <template #header>
+              <div class="card-header">
+                <div class="chart-title-line"></div>
+                <span>璐ㄦ鍚堟牸鐜�</span>
+              </div>
+            </template>
+            <div class="top-container flex-center">
+              <div class="quality-card blue-card">
+                <div class="quality-card-title">
+                  <img src="~@/assets/images/chartCard.svg" alt="鍘熸潗鏂�"
+                    style="width: 24px; height: 24px; margin-right: 8px;">
+                  鍘熸潗鏂欏悎鏍肩巼
+                </div>
+                <div class="quality-card-content">
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(0, 'completionRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="materialCompletionChart"></div>
+                  </div>
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(0, 'passRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="materialQualityChart"></div>
+                  </div>
+                </div>
+              </div>
+              <div class="quality-card green-card">
+                <div class="quality-card-title">
+                  <img src="~@/assets/images/chartCard2.svg" alt="鍗婃垚鍝�"
+                    style="width: 24px; height: 24px; margin-right: 8px;">
+                  鍗婃垚鍝佸悎鏍肩巼
+                </div>
+                <div class="quality-card-content">
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(1, 'completionRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="semiCompletionChart"></div>
+                  </div>
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(1, 'passRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="semiQualityChart"></div>
+                  </div>
+                </div>
+              </div>
+              <div class="quality-card purple-card">
+                <div class="quality-card-title">
+                  <img src="~@/assets/images/chartCard3.svg" alt="鎴愬搧"
+                    style="width: 24px; height: 24px; margin-right: 8px;">
+                  鎴愬搧鍚堟牸鐜�
+                </div>
+                <div class="quality-card-content">
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label blue-label">瀹屾垚鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(2, 'completionRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="finalCompletionChart"></div>
+                  </div>
+                  <div class="quality-item">
+                    <div>
+                      <div class="quality-item-label green-label">鍚堟牸鐜�</div>
+                      <div class="quality-item-tip">鍗犳瘮</div>
+                      <div class="quality-item-value">{{ getPassRateStatValue(2, 'passRate') }}</div>
+                    </div>
+                    <div class="quality-item-chart" ref="finalQualityChart"></div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="charts-container">
+      <el-row :gutter="20">
+        <!-- 璐ㄦ鍚堟牸鐜� -->
+        <el-col :span="24">
+          <el-card class="chart-card" shadow="hover">
+            <template #header>
+              <div class="card-header">
+                <div class="chart-title-line"></div>
+                <span>璐ㄦ鍚堟牸鐜�</span>
+              </div>
+            </template>
+            <div class="chart-container-line">
+              <div class="container-line-left">
+                <div style="height: 100%; width: 100%;" ref="usageChartRef">
+                </div>
+              </div>
+              <div class="container-line-right">
+                <div style="height: 80%; width: 100%;" ref="inspectionChartRef">
+                </div>
+                <div class="container-line-right-bottom">
+                  <div class="inspection-chart-box">
+                    <div class="chart-box-title">鍘熸潗鏂欐�绘暟</div>
+                    <div class="chart-box-num">{{ getYearlyStatValue(0, 'totalCount') }}</div>
+                  </div>
+                  <div class="inspection-chart-box">
+                    <div class="chart-box-title">鍗婃垚鍝佹�绘暟</div>
+                    <div class="chart-box-num">{{ getYearlyStatValue(1, 'totalCount') }}</div>
+                  </div>
+                  <div class="inspection-chart-box">
+                    <div class="chart-box-title">鎴愬搧鎬绘暟</div>
+                    <div class="chart-box-num">{{ getYearlyStatValue(2, 'totalCount') }}</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <!-- </div> -->
+            <!-- <div ref="sampleChartRef"
+                 class="chart-container"></div> -->
+            <div class="yearchange">
+              <div style="margin-right: 8px;font-size: 14px;">骞翠唤:</div>
+              <el-date-picker v-model="value3" size="mini" :clearable="false" style="width: 60px;" type="year"
+                :disabled-date="disabledDate" placeholder="">
+              </el-date-picker>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="charts-container">
+      <el-row :gutter="20">
+        <!-- 鏍峰搧杩涘害鍥捐〃 -->
+        <el-col :span="12">
+          <el-card class="chart-card" shadow="hover">
+            <template #header>
+              <div class="card-header">
+                <div class="chart-title-line"></div>
+                <span>璐ㄩ噺瀹屾垚鏄庣粏</span>
+              </div>
+            </template>
+            <div ref="equipmentChartRef" class="chart-container"></div>
+          </el-card>
+        </el-col>
+        <!-- 璁惧浣跨敤鍥捐〃 -->
+        <el-col :span="12">
+          <el-card class="chart-card" shadow="hover">
+            <template #header>
+              <div class="card-header">
+                <div class="chart-title-line"></div>
+                <span>妫�娴嬮」鐩垎绫�</span>
+              </div>
+            </template>
+            <div class="chart-container-line">
+              <div class="container-line2-left">
+                <div class="info-box">
+                  <div class="info-box-header">椤圭洰鍒嗗竷</div>
+                  <div class="info-line" v-for="(item, index) in topParametersData.list" :key="index">
+                    <div class="info-icon" :style="{ backgroundColor: getParameterColor(index) }"></div>
+                    <div class="info-line-title">{{ item.name }}</div>
+                    <div class="info-line-value1">{{ item.percentage }}%</div>
+                    <div class="info-line-value2">{{ item.count }}</div>
+                  </div>
+                </div>
+              </div>
+              <div ref="sampleChartRef" style="height: 100%; width: 50%;" class="chart-container"></div>
+            </div>
+            <!-- Tab 閫夋嫨鍣� -->
+            <div class="tab-selector">
+              <div class="tab-item" :class="{ active: activeTab === 'raw' }" @click="activeTab = 'raw'">鍘熸潗鏂�</div>
+              <div class="tab-item" :class="{ active: activeTab === 'semi' }" @click="activeTab = 'semi'">鍗婃垚鍝�</div>
+              <div class="tab-item" :class="{ active: activeTab === 'final' }" @click="activeTab = 'final'">鎴愬搧</div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+  </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import * as echarts from 'echarts'
-import { Box, Tools, Document, ShoppingCart } from '@element-plus/icons-vue'
+import { ref, reactive, onMounted, nextTick } from "vue";
+import { ElMessage } from "element-plus";
+import * as echarts from "echarts";
+import { getInspectStatistics, getPassRateStatistics, getMonthlyPassRateStatistics, getYearlyPassRateStatistics, getMonthlyCompletionDetails, getTopParameters } from "@/api/reportAnalysis/qualityReport";
 
 // 鍝嶅簲寮忔暟鎹�
 const filterForm = reactive({
-	dateRange: [],
-	reportType: 'sample'
-})
+  dateRange: [],
+  reportType: "sample",
+});
 
-const statistics = reactive({
-	totalSamples: 1250,
-	activeEquipment: 45,
-	completedInspections: 890,
-	totalUsage: 2340
-})
+const inspectStatisticsData = ref([]);
+const passRateStatisticsData = ref([]);
+const monthlyPassRateData = ref([]);
+const yearlyPassRateData = ref([]);
+const monthlyCompletionDetailsData = ref([]);
+const topParametersData = ref({ totalCount: 0, list: [] });
+const activeTab = ref("raw");
 
-const tableData = ref([])
-const tableLoading = ref(false)
+const getParameterColor = (index) => {
+  const colors = ['#165DFF', '#14C9C9', '#F7BA1E', '#722ED1', '#3491FA', '#FF7D00', '#F53F3F'];
+  return colors[index % colors.length];
+};
+
+const getYearlyStatValue = (type, field) => {
+  const stat = yearlyPassRateData.value.find(item => item.inspectType === type);
+  return stat ? stat[field] : 0;
+};
+
+const getInspectStatValue = (type, field) => {
+  const stat = inspectStatisticsData.value.find(item => item.inspectType === type);
+  return stat ? stat[field] : 0;
+};
+
+const getPassRateStatValue = (type, field) => {
+  const stat = passRateStatisticsData.value.find(item => item.inspectType === type);
+  if (stat) {
+    if (field === 'completionRate' || field === 'passRate') {
+      return stat[field] ? Number(stat[field]).toFixed(0) + '%' : '0%';
+    }
+    return stat[field];
+  }
+  return field === 'completionRate' || field === 'passRate' ? '0%' : 0;
+};
+
+const fetchInspectStatisticsData = async () => {
+  try {
+    const res = await getInspectStatistics();
+    if (res.code === 200) {
+      inspectStatisticsData.value = res.data;
+    }
+  } catch (error) {
+    console.error("Failed to fetch inspect statistics:", error);
+  }
+};
+
+const fetchPassRateStatisticsData = async () => {
+  try {
+    const res = await getPassRateStatistics();
+    if (res.code === 200) {
+      passRateStatisticsData.value = res.data;
+      // 鏁版嵁鑾峰彇鍚庨噸鏂板垵濮嬪寲鍥捐〃
+      initAllQualityCharts();
+    }
+  } catch (error) {
+    console.error("Failed to fetch pass rate statistics:", error);
+  }
+};
+
+const fetchMonthlyPassRateData = async () => {
+  try {
+    const year = value3.value.getFullYear().toString();
+    const res = await getMonthlyPassRateStatistics(year);
+    if (res.code === 200) {
+      monthlyPassRateData.value = res.data;
+      initUsageChart();
+    }
+  } catch (error) {
+    console.error("Failed to fetch monthly pass rate statistics:", error);
+  }
+};
+
+const fetchYearlyPassRateData = async () => {
+  try {
+    const year = value3.value.getFullYear().toString();
+    const res = await getYearlyPassRateStatistics(year);
+    if (res.code === 200) {
+      yearlyPassRateData.value = res.data;
+      initInspectionChart();
+    }
+  } catch (error) {
+    console.error("Failed to fetch yearly pass rate statistics:", error);
+  }
+};
+
+const fetchMonthlyCompletionDetailsData = async () => {
+  try {
+    const year = value3.value.getFullYear().toString();
+    const res = await getMonthlyCompletionDetails(year);
+    if (res.code === 200) {
+      monthlyCompletionDetailsData.value = res.data;
+      initEquipmentChart();
+    }
+  } catch (error) {
+    console.error("Failed to fetch monthly completion details:", error);
+  }
+};
+
+const fetchTopParametersData = async () => {
+  try {
+    const typeMap = { raw: 0, semi: 1, final: 2 };
+    const res = await getTopParameters(typeMap[activeTab.value]);
+    if (res.code === 200) {
+      topParametersData.value = res.data;
+      initSampleChart();
+    }
+  } catch (error) {
+    console.error("Failed to fetch top parameters:", error);
+  }
+};
+
+const tableData = ref([]);
+const tableLoading = ref(false);
 const pagination = reactive({
-	currentPage: 1,
-	pageSize: 20,
-	total: 0
-})
+  currentPage: 1,
+  pageSize: 20,
+  total: 0,
+});
+
+// 鍒濆鍖栧勾浠戒负褰撳墠骞翠唤锛堜娇鐢―ate瀵硅薄锛�
+const currentYear = new Date().getFullYear();
+const value3 = ref(new Date(currentYear, 0, 1));
+
+// 闄愬埗鏃ユ湡閫夋嫨锛屼笉鍏佽閫夋嫨浠婂勾涔嬪悗鐨勫勾浠�
+const disabledDate = time => {
+  const currentYear = new Date().getFullYear();
+  return time.getFullYear() > currentYear;
+};
+
+// 鐩戝惉骞翠唤鍙樺寲
+import { watch } from "vue";
+watch(value3, () => {
+  fetchMonthlyPassRateData();
+  fetchYearlyPassRateData();
+  fetchMonthlyCompletionDetailsData();
+});
+
+watch(activeTab, () => {
+  fetchTopParametersData();
+});
+
 
 // 鍥捐〃寮曠敤
-const sampleChartRef = ref(null)
-const equipmentChartRef = ref(null)
-const inspectionChartRef = ref(null)
-const usageChartRef = ref(null)
+const sampleChartRef = ref(null);
+const equipmentChartRef = ref(null);
+const inspectionChartRef = ref(null);
+const usageChartRef = ref(null);
+
+// 璐ㄦ鍚堟牸鐜囧浘琛ㄥ紩鐢�
+const materialCompletionChart = ref(null);
+const materialQualityChart = ref(null);
+const semiCompletionChart = ref(null);
+const semiQualityChart = ref(null);
+const finalCompletionChart = ref(null);
+const finalQualityChart = ref(null);
 
 // 鍥捐〃瀹炰緥
-let sampleChart = null
-let equipmentChart = null
-let inspectionChart = null
-let usageChart = null
+let sampleChart = null;
+let equipmentChart = null;
+let inspectionChart = null;
+let usageChart = null;
 
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
-	// 妯℃嫙琛ㄦ牸鏁版嵁
-	tableData.value = [
-		{
-			id: 'SP001',
-			name: '鏍峰搧A-001',
-			type: '閲戝睘鏉愭枡',
-			status: '妫�娴嬩腑',
-			progress: 75,
-			createTime: '2025-01-15 09:30:00',
-			updateTime: '2025-01-20 14:20:00'
-		},
-		{
-			id: 'SP002',
-			name: '鏍峰搧B-002',
-			type: '濉戞枡鍒跺搧',
-			status: '宸插畬鎴�',
-			progress: 100,
-			createTime: '2025-01-10 10:15:00',
-			updateTime: '2025-01-18 16:45:00'
-		},
-		{
-			id: 'SP003',
-			name: '鏍峰搧C-003',
-			type: '鐢靛瓙鍏冧欢',
-			status: '寰呮娴�',
-			progress: 0,
-			createTime: '2025-01-22 08:45:00',
-			updateTime: '2025-01-22 08:45:00'
-		},
-		{
-			id: 'EQ001',
-			name: '妫�娴嬭澶嘇',
-			type: '鍏夎氨浠�',
-			status: '浣跨敤涓�',
-			progress: 60,
-			createTime: '2025-01-05 14:20:00',
-			updateTime: '2025-01-20 11:30:00'
-		},
-		{
-			id: 'EQ002',
-			name: '妫�娴嬭澶嘊',
-			type: '鏄惧井闀�',
-			status: '绌洪棽',
-			progress: 0,
-			createTime: '2025-01-08 16:10:00',
-			updateTime: '2025-01-19 09:15:00'
-		}
-	]
-	
-	pagination.total = tableData.value.length
-}
+// 璐ㄦ鍚堟牸鐜囧浘琛ㄥ疄渚�
+let materialCompletionChartInstance = null;
+let materialQualityChartInstance = null;
+let semiCompletionChartInstance = null;
+let semiQualityChartInstance = null;
+let finalCompletionChartInstance = null;
+let finalQualityChartInstance = null;
 
 // 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
 const initSampleChart = () => {
-	if (sampleChartRef.value) {
-		sampleChart = echarts.init(sampleChartRef.value)
-		const option = {
-			title: {
-				show: false
-			},
-			tooltip: {
-				trigger: 'item',
-				formatter: '{a} <br/>{b}: {c} ({d}%)'
-			},
-			legend: {
-				orient: 'vertical',
-				left: 'left'
-			},
-			series: [
-				{
-					name: '鏍峰搧鐘舵��',
-					type: 'pie',
-					radius: ['40%', '70%'],
-					avoidLabelOverlap: false,
-					label: {
-						show: false,
-						position: 'center'
-					},
-					emphasis: {
-						label: {
-							show: true,
-							fontSize: '18',
-							fontWeight: 'bold'
-						}
-					},
-					labelLine: {
-						show: false
-					},
-					data: [
-						{ value: 450, name: '宸插畬鎴�' },
-						{ value: 320, name: '妫�娴嬩腑' },
-						{ value: 280, name: '寰呮娴�' },
-						{ value: 200, name: '宸叉殏鍋�' }
-					]
-				}
-			]
-		}
-		sampleChart.setOption(option)
-	}
-}
+  if (sampleChartRef.value) {
+    sampleChart = echarts.init(sampleChartRef.value);
+    const option = {
+      title: {
+        show: false,
+      },
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b}: {c} ({d}%)",
+      },
+      // legend: {
+      //   orient: "vertical",
+      //   left: "left",
+      // },
+      series: [
+        {
+          name: "妫�娴嬮」鐩�",
+          type: "pie",
+          radius: ["40%", "80%"],
+          avoidLabelOverlap: false,
+          label: {
+            show: false,
+            position: "center",
+          },
+          emphasis: {
+            label: {
+              show: true,
+              fontSize: "18",
+              fontWeight: "bold",
+            },
+          },
+          labelLine: {
+            show: false,
+          },
+          data: topParametersData.value.list.map((item, index) => ({
+            value: item.count,
+            name: item.name,
+            itemStyle: { color: getParameterColor(index) }
+          })),
+        },
+      ],
+    };
+    sampleChart.setOption(option);
+  }
+};
 
 // 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
 const initEquipmentChart = () => {
-	if (equipmentChartRef.value) {
-		equipmentChart = echarts.init(equipmentChartRef.value)
-		const option = {
-			title: {
-				show: false
-			},
-			tooltip: {
-				trigger: 'axis',
-				axisPointer: {
-					type: 'shadow'
-				}
-			},
-			xAxis: {
-				type: 'category',
-				data: ['鍏夎氨浠�', '鏄惧井闀�', '纭害璁�', '鎷夊姏鏈�', '鍐插嚮鏈�', '閲戠浉浠�']
-			},
-			yAxis: {
-				type: 'value',
-				name: '浣跨敤鐜�(%)'
-			},
-			series: [
-				{
-					name: '浣跨敤鐜�',
-					type: 'bar',
-					data: [85, 60, 75, 90, 45, 70],
-					itemStyle: {
-						color: function(params) {
-							const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
-							return colors[params.dataIndex]
-						}
-					}
-				}
-			]
-		}
-		equipmentChart.setOption(option)
-	}
-}
+  if (equipmentChartRef.value) {
+    equipmentChart = echarts.init(equipmentChartRef.value);
+    const option = {
+      title: {
+        show: false,
+      },
+      tooltip: {
+        trigger: "axis",
+        axisPointer: {
+          type: "shadow",
+        },
+      },
+      grid: {
+        left: "1%",
+        right: "1%",
+        bottom: "1%",
+        containLabel: true,
+      },
+      legend: {
+        data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+        icon: ["circle", "circle", "circle"],
+        itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+        itemHeight: 10,
+        itemGap: 30,
+        right: 10,
+      },
+      xAxis: {
+        type: "category",
+        data: [
+          value3.value.getFullYear() + "-1",
+          value3.value.getFullYear() + "-2",
+          value3.value.getFullYear() + "-3",
+          value3.value.getFullYear() + "-4",
+          value3.value.getFullYear() + "-5",
+          value3.value.getFullYear() + "-6",
+          value3.value.getFullYear() + "-7",
+          value3.value.getFullYear() + "-8",
+          value3.value.getFullYear() + "-9",
+          value3.value.getFullYear() + "-10",
+          value3.value.getFullYear() + "-11",
+          value3.value.getFullYear() + "-12",
+        ], // 鏀逛负鍗佷簩涓湀
+      },
+      yAxis: {
+        type: "value",
+        name: "鏁�(涓�)",
+      },
+      series: [
+        {
+          name: "鍘熸潗鏂�",
+          type: "bar",
+          barWidth: "15%",
+          data: monthlyCompletionDetailsData.value.map(item => item.rawMaterialCount),
+          itemStyle: {
+            color: "#409EFF",
+          },
+        },
+        {
+          name: "鍗婃垚鍝�",
+          type: "bar",
+          barWidth: "15%",
+
+          data: monthlyCompletionDetailsData.value.map(item => item.processCount),
+          itemStyle: {
+            color: "#67C23A",
+          },
+        },
+        {
+          name: "鎴愬搧",
+          type: "bar",
+          barWidth: "15%",
+
+          data: monthlyCompletionDetailsData.value.map(item => item.outgoingCount),
+          itemStyle: {
+            color: "#E6A23C",
+          },
+        },
+      ],
+    };
+    equipmentChart.setOption(option);
+  }
+};
 
 // 鍒濆鍖栨娴嬮」鐩浘琛�
 const initInspectionChart = () => {
-	if (inspectionChartRef.value) {
-		inspectionChart = echarts.init(inspectionChartRef.value)
-		const option = {
-			title: {
-				show: false
-			},
-			tooltip: {
-				trigger: 'item'
-			},
-			legend: {
-				orient: 'vertical',
-				left: 'left'
-			},
-			series: [
-				{
-					name: '妫�娴嬮」鐩�',
-					type: 'pie',
-					radius: '50%',
-					data: [
-						{ value: 335, name: '鐗╃悊鎬ц兘' },
-						{ value: 310, name: '鍖栧鍒嗘瀽' },
-						{ value: 234, name: '灏哄娴嬮噺' },
-						{ value: 135, name: '澶栬妫�鏌�' },
-						{ value: 148, name: '鍏朵粬妫�娴�' }
-					],
-					emphasis: {
-						itemStyle: {
-							shadowBlur: 10,
-							shadowOffsetX: 0,
-							shadowColor: 'rgba(0, 0, 0, 0.5)'
-						}
-					}
-				}
-			]
-		}
-		inspectionChart.setOption(option)
-	}
-}
+  if (inspectionChartRef.value) {
+    inspectionChart = echarts.init(inspectionChartRef.value);
+    const option = {
+      title: {
+        show: false,
+      },
+      tooltip: {
+        trigger: "item",
+      },
+      series: [
+        {
+          type: "pie",
+          radius: "70%",
+          data: [
+            { value: getYearlyStatValue(0, 'totalCount'), name: "鍘熸潗鏂�", itemStyle: { color: "#1890FF" } },
+            { value: getYearlyStatValue(1, 'totalCount'), name: "鍗婃垚鍝�", itemStyle: { color: "#F7BA1E" } },
+            { value: getYearlyStatValue(2, 'totalCount'), name: "鎴愬搧", itemStyle: { color: "#14C9C9" } },
+          ],
+          label: {
+            show: true,
+            formatter: '{b}: {c}'
+          },
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.5)",
+            },
+          },
+        },
+      ],
+    };
+    inspectionChart.setOption(option);
+  }
+};
 
 // 鍒濆鍖栭鐢ㄨ褰曞浘琛�
 const initUsageChart = () => {
-	if (usageChartRef.value) {
-		usageChart = echarts.init(usageChartRef.value)
-		const option = {
-			title: {
-				show: false
-			},
-			tooltip: {
-				trigger: 'axis'
-			},
-			legend: {
-				data: ['棰嗙敤娆℃暟', '褰掕繕娆℃暟']
-			},
-			xAxis: {
-				type: 'category',
-				boundaryGap: false,
-				data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
-			},
-			yAxis: {
-				type: 'value'
-			},
-			series: [
-				{
-					name: '棰嗙敤娆℃暟',
-					type: 'line',
-					stack: 'Total',
-					data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330]
-				},
-				{
-					name: '褰掕繕娆℃暟',
-					type: 'line',
-					stack: 'Total',
-					data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320]
-				}
-			]
-		}
-		usageChart.setOption(option)
-	}
-}
+  // 妫�鏌ュ浘琛ㄥ鍣ㄦ槸鍚﹀瓨鍦�
+  if (usageChartRef.value) {
+    // 鍒濆鍖� ECharts 瀹炰緥
+    usageChart = echarts.init(usageChartRef.value);
+    // 閰嶇疆鍥捐〃閫夐」
+    const option = {
+      // 鏍囬閰嶇疆锛堥殣钘忥級
+      title: {
+        show: false,
+      },
+
+      // 缃戞牸閰嶇疆锛堣皟鏁磋竟璺濓級
+      grid: {
+        left: "1%",
+        right: "4%",
+        bottom: "3%",
+        top: "14%",
+        containLabel: true,
+      },
+      // 鎻愮ず妗嗛厤缃�
+      tooltip: {
+        trigger: "axis", // 瑙﹀彂绫诲瀷涓哄潗鏍囪酱瑙﹀彂
+      },
+      // 鍥句緥閰嶇疆
+      legend: {
+        data: ["鍘熸潗鏂�", "鍗婃垚鍝�", "鎴愬搧"], // 鍥句緥鏁版嵁
+        icon: ["circle", "circle", "circle"],
+        itemWidth: 10, // 璁剧疆鍥炬爣瀹藉害
+        itemHeight: 10,
+        itemGap: 30,
+      },
+      // X杞撮厤缃�
+      xAxis: {
+        type: "category", // 绫诲埆杞�
+        boundaryGap: false, // 鍧愭爣杞翠袱杈圭暀鐧界瓥鐣�
+        data: [
+          value3.value.getFullYear() + "-1",
+          value3.value.getFullYear() + "-2",
+          value3.value.getFullYear() + "-3",
+          value3.value.getFullYear() + "-4",
+          value3.value.getFullYear() + "-5",
+          value3.value.getFullYear() + "-6",
+          value3.value.getFullYear() + "-7",
+          value3.value.getFullYear() + "-8",
+          value3.value.getFullYear() + "-9",
+          value3.value.getFullYear() + "-10",
+          value3.value.getFullYear() + "-11",
+          value3.value.getFullYear() + "-12",
+        ], // X杞存暟鎹�
+      },
+      // Y杞撮厤缃�
+      yAxis: {
+        type: "value", // 鏁板�艰酱
+        name: "鍗曚綅锛�%",
+      },
+      // 绯诲垪鏁版嵁
+      series: [
+        {
+          name: "鍘熸潗鏂�", // 绯诲垪鍚嶇О
+          type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+          // stack: "Total", // 鍫嗗彔鍚嶇О
+          symbol: "circle",
+          itemStyle: {
+            color: "#1890FF", // 璁剧疆杩欐潯绾跨殑棰滆壊
+          },
+          data: monthlyPassRateData.value.map(item => item.rawMaterial.passRate),
+        },
+        {
+          name: "鍗婃垚鍝�", // 绯诲垪鍚嶇О
+          type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+          // stack: "Total", // 鍫嗗彔鍚嶇О
+          symbol: "circle",
+          itemStyle: {
+            color: "#F7BA1E", // 璁剧疆杩欐潯绾跨殑棰滆壊
+          },
+          data: monthlyPassRateData.value.map(item => item.process.passRate),
+        },
+        {
+          name: "鎴愬搧", // 绯诲垪鍚嶇О
+          type: "line", // 鍥捐〃绫诲瀷涓烘姌绾垮浘
+          // stack: "Total", // 鍫嗗彔鍚嶇О
+          symbol: "circle",
+          itemStyle: {
+            color: "#14C9C9", // 璁剧疆杩欐潯绾跨殑棰滆壊
+          },
+          data: monthlyPassRateData.value.map(item => item.outgoing.passRate),
+        },
+      ],
+    };
+    // 灏嗛厤缃簲鐢ㄥ埌鍥捐〃
+    usageChart.setOption(option);
+  }
+};
+
+// 鍒濆鍖栬川妫�鍚堟牸鐜囧浘琛�
+const initQualityChart = (chartRef, color, value = 0.8) => {
+  if (chartRef.value) {
+    let chart = echarts.getInstanceByDom(chartRef.value);
+    if (!chart) {
+      chart = echarts.init(chartRef.value);
+    }
+    const numericValue = typeof value === 'string' ? parseFloat(value) / 100 : value / 100;
+    const option = {
+      series: [
+        {
+          type: "pie",
+          radius: ["45%", "90%"],
+          itemStyle: {
+            borderColor: "#f5f5f5",
+            // borderWidth: 2,
+          },
+          labelLine: {
+            show: false,
+          },
+          data: [
+            { value: numericValue, itemStyle: { color: color } },
+            { value: 1 - numericValue, itemStyle: { color: "#f5f5f5" } },
+          ],
+        },
+      ],
+    };
+    chart.setOption(option);
+    return chart;
+  }
+  return null;
+};
+
+// 鍒濆鍖栨墍鏈夎川妫�鍚堟牸鐜囧浘琛�
+const initAllQualityCharts = () => {
+  materialCompletionChartInstance = initQualityChart(
+    materialCompletionChart,
+    "#1890ff",
+    getPassRateStatValue(0, 'completionRate')
+  );
+  materialQualityChartInstance = initQualityChart(
+    materialQualityChart,
+    "#52c41a",
+    getPassRateStatValue(0, 'passRate')
+  );
+  semiCompletionChartInstance = initQualityChart(
+    semiCompletionChart,
+    "#1890ff",
+    getPassRateStatValue(1, 'completionRate')
+  );
+  semiQualityChartInstance = initQualityChart(
+    semiQualityChart,
+    "#52c41a",
+    getPassRateStatValue(1, 'passRate')
+  );
+  finalCompletionChartInstance = initQualityChart(
+    finalCompletionChart,
+    "#1890ff",
+    getPassRateStatValue(2, 'completionRate')
+  );
+  finalQualityChartInstance = initQualityChart(
+    finalQualityChart,
+    "#722ed1",
+    getPassRateStatValue(2, 'passRate')
+  );
+};
 
 // 浜嬩欢澶勭悊鍑芥暟
 const handleFilterChange = () => {
-	ElMessage.success('绛涢�夋潯浠跺凡鏇存柊')
-	// 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
-}
+  ElMessage.success("绛涢�夋潯浠跺凡鏇存柊");
+  // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
+};
 
 const resetFilter = () => {
-	filterForm.dateRange = []
-	filterForm.reportType = 'sample'
-	ElMessage.info('绛涢�夋潯浠跺凡閲嶇疆')
-}
+  filterForm.dateRange = [];
+  filterForm.reportType = "sample";
+  ElMessage.info("绛涢�夋潯浠跺凡閲嶇疆");
+};
 
 const exportReport = () => {
-	ElMessage.success('鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
+  ElMessage.success("鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...");
+};
 
 const refreshSampleChart = () => {
-	initSampleChart()
-	ElMessage.success('鏍峰搧杩涘害鍥捐〃宸插埛鏂�')
-}
+  initSampleChart();
+  ElMessage.success("鏍峰搧杩涘害鍥捐〃宸插埛鏂�");
+};
 
 const refreshEquipmentChart = () => {
-	initEquipmentChart()
-	ElMessage.success('璁惧浣跨敤鍥捐〃宸插埛鏂�')
-}
+  initEquipmentChart();
+  ElMessage.success("璁惧浣跨敤鍥捐〃宸插埛鏂�");
+};
 
 const refreshInspectionChart = () => {
-	initInspectionChart()
-	ElMessage.success('妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊')
-}
+  initInspectionChart();
+  ElMessage.success("妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊");
+};
 
 const refreshUsageChart = () => {
-	initUsageChart()
-	ElMessage.success('棰嗙敤璁板綍鍥捐〃宸插埛鏂�')
-}
+  initUsageChart();
+  ElMessage.success("棰嗙敤璁板綍鍥捐〃宸插埛鏂�");
+};
 
 const refreshTable = () => {
-	tableLoading.value = true
-	setTimeout(() => {
-		tableLoading.value = false
-		ElMessage.success('琛ㄦ牸鏁版嵁宸插埛鏂�')
-	}, 1000)
-}
+  tableLoading.value = true;
+  setTimeout(() => {
+    tableLoading.value = false;
+    ElMessage.success("琛ㄦ牸鏁版嵁宸插埛鏂�");
+  }, 1000);
+};
 
 const exportTable = () => {
-	ElMessage.success('琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
+  ElMessage.success("琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...");
+};
 
-const handleSizeChange = (val) => {
-	pagination.pageSize = val
-	// 閲嶆柊鍔犺浇鏁版嵁
-}
+const handleSizeChange = val => {
+  pagination.pageSize = val;
+  // 閲嶆柊鍔犺浇鏁版嵁
+};
 
-const handleCurrentChange = (val) => {
-	pagination.currentPage = val
-	// 閲嶆柊鍔犺浇鏁版嵁
-}
+const handleCurrentChange = val => {
+  pagination.currentPage = val;
+  // 閲嶆柊鍔犺浇鏁版嵁
+};
 
-const getStatusType = (status) => {
-	const statusMap = {
-		'宸插畬鎴�': 'success',
-		'妫�娴嬩腑': 'warning',
-		'寰呮娴�': 'info',
-		'宸叉殏鍋�': 'danger',
-		'浣跨敤涓�': 'primary',
-		'绌洪棽': 'info'
-	}
-	return statusMap[status] || 'info'
-}
+const getStatusType = status => {
+  const statusMap = {
+    宸插畬鎴�: "success",
+    妫�娴嬩腑: "warning",
+    寰呮娴�: "info",
+    宸叉殏鍋�: "danger",
+    浣跨敤涓�: "primary",
+    绌洪棽: "info",
+  };
+  return statusMap[status] || "info";
+};
 
-const getProgressStatus = (progress) => {
-	if (progress === 100) return 'success'
-	if (progress >= 80) return 'warning'
-	if (progress >= 50) return ''
-	return 'exception'
-}
+const getProgressStatus = progress => {
+  if (progress === 100) return "success";
+  if (progress >= 80) return "warning";
+  if (progress >= 50) return "";
+  return "exception";
+};
 
-const viewDetail = (row) => {
-	ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`)
-}
+const viewDetail = row => {
+  ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`);
+};
 
-const editItem = (row) => {
-	ElMessage.info(`缂栬緫椤圭洰: ${row.name}`)
-}
+const editItem = row => {
+  ElMessage.info(`缂栬緫椤圭洰: ${row.name}`);
+};
 
 // 鐢熷懡鍛ㄦ湡
 onMounted(() => {
-	initData()
-	nextTick(() => {
-		initSampleChart()
-		initEquipmentChart()
-		initInspectionChart()
-		initUsageChart()
-	})
-	
-	// 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
-	window.addEventListener('resize', () => {
-		sampleChart?.resize()
-		equipmentChart?.resize()
-		inspectionChart?.resize()
-		usageChart?.resize()
-	})
-})
+  fetchInspectStatisticsData();
+  fetchPassRateStatisticsData();
+  fetchMonthlyPassRateData();
+  fetchYearlyPassRateData();
+  fetchMonthlyCompletionDetailsData();
+  fetchTopParametersData();
+  nextTick(() => {
+    initSampleChart();
+    initEquipmentChart();
+    initInspectionChart();
+    initUsageChart();
+    initAllQualityCharts();
+  });
+  // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
+  window.addEventListener("resize", () => {
+    sampleChart?.resize();
+    equipmentChart?.resize();
+    inspectionChart?.resize();
+    usageChart?.resize();
+
+    // 璋冩暣璐ㄦ鍚堟牸鐜囧浘琛ㄥぇ灏�
+    materialCompletionChartInstance?.resize();
+    materialQualityChartInstance?.resize();
+    semiCompletionChartInstance?.resize();
+    semiQualityChartInstance?.resize();
+    finalCompletionChartInstance?.resize();
+    finalQualityChartInstance?.resize();
+  });
+});
 </script>
 
 <style scoped>
 .report-management {
-	padding: 20px;
-	background-color: #f5f5f5;
-	min-height: 100vh;
+  padding: 20px;
+  background-color: #f5f5f5;
+  min-height: 100vh;
+  /* height: 87vh;
+  overflow: hidden; */
 }
 
 .page-header {
-	margin-bottom: 20px;
-	text-align: center;
+  margin-bottom: 20px;
+  text-align: center;
 }
 
 .page-header h2 {
-	color: #303133;
-	margin-bottom: 8px;
-	font-size: 24px;
-	font-weight: 600;
+  color: #303133;
+  margin-bottom: 8px;
+  font-size: 24px;
+  font-weight: 600;
 }
 
 .page-header p {
-	color: #909399;
-	font-size: 14px;
-	margin: 0;
+  color: #909399;
+  font-size: 14px;
+  margin: 0;
 }
 
 .filter-card {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 
 .statistics-cards {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 
 .stat-card {
-	height: 120px;
+  height: 120px;
 }
 
 .stat-content {
-	display: flex;
-	align-items: center;
-	height: 100%;
+  display: flex;
+  align-items: center;
+  height: 100%;
 }
 
 .stat-icon {
-	width: 60px;
-	height: 60px;
-	border-radius: 50%;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	margin-right: 20px;
-	font-size: 24px;
-	color: white;
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 20px;
+  font-size: 24px;
+  color: white;
 }
 
 .stat-card:nth-child(1) .stat-icon {
-	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 }
 
 .stat-card:nth-child(2) .stat-icon {
-	background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
 }
 
 .stat-card:nth-child(3) .stat-icon {
-	background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
 }
 
 .stat-card:nth-child(4) .stat-icon {
-	background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+  background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
 }
 
 .stat-info {
-	flex: 1;
+  flex: 1;
 }
 
 .stat-number {
-	font-size: 28px;
-	font-weight: bold;
-	color: #303133;
-	margin-bottom: 8px;
+  font-size: 28px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 8px;
 }
 
 .stat-label {
-	font-size: 14px;
-	color: #909399;
+  font-size: 14px;
+  color: #909399;
 }
 
 .charts-container {
-	margin-bottom: 20px;
+  /* margin-bottom: 20px; */
+  position: relative;
 }
 
 .chart-card {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
+}
+
+.container-line-right-bottom {
+  height: 20%;
+  width: 100%;
+  display: flex;
+  justify-content: space-evenly;
+  align-items: center;
+  /* background-color: #5b3f3f; */
 }
 
 .card-header {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  font-family: Source Han Sans, Source Han Sans;
+  font-weight: 700;
+  font-size: 18px;
+  color: #000000;
+  /* line-height: 27px; */
+  text-align: left;
+  font-style: normal;
+  text-transform: none;
+}
+
+.chart-title-line {
+  width: 6px;
+  height: 22px;
+  background-color: #161a9a;
+  margin-right: 16px;
+  border-radius: 3px;
 }
 
 .chart-container {
-	height: 300px;
-	width: 100%;
+  height: 250px;
+  width: 100%;
+}
+
+.chart-container-line {
+  height: 250px;
+  width: 100%;
+  display: flex;
+  position: relative;
+}
+
+/* Tab 閫夋嫨鍣ㄦ牱寮� */
+.tab-selector {
+  position: absolute;
+  top: 20px;
+  right: 40px;
+  display: flex;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.tab-item {
+  padding: 4px 12px;
+  cursor: pointer;
+  font-size: 14px;
+  color: #606266;
+  background-color: #fff;
+  border-right: 1px solid #dcdfe6;
+  transition: all 0.3s;
+}
+
+.tab-item:last-child {
+  border-right: none;
+}
+
+.tab-item:hover {
+  color: #409eff;
+}
+
+.tab-item.active {
+  color: #fff;
+  background-color: #409eff;
+}
+
+.container-line-left {
+  height: 100%;
+  width: 66%;
+}
+
+.container-line-right {
+  height: 100%;
+  width: 34%;
+}
+
+.container-line2-left {
+  height: 100%;
+  width: 50%;
+}
+
+.info-box {
+  width: 92%;
+  margin-left: 4%;
+  height: 100%;
+  background-color: #f7f8fa;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-around;
+}
+
+.info-box-header {
+  width: 100%;
+  margin-left: 20px;
+  color: #1d2129;
+  font-size: 16px;
+  font-weight: 500;
+}
+
+.info-line {
+  width: 100%;
+  display: flex;
+  padding-left: 20px;
+  align-items: center;
+}
+
+.info-icon {
+  width: 7px;
+  height: 7px;
+  border-radius: 50%;
+  margin-right: 8px;
+}
+
+.info-line-title {
+  font-size: 12px;
+  color: #4e5969;
+  flex: 1;
+}
+
+.info-line-value1 {
+  font-size: 12px;
+  color: #3d3d3d;
+  color: #1d2129;
+  font-weight: 500;
+  margin-right: 15%;
+}
+
+.info-line-value2 {
+  font-size: 12px;
+  color: #3d3d3d;
+  color: #1d2129;
+  font-weight: 500;
+  margin-right: 10%;
+}
+
+.top-container {
+  height: 130px;
+  width: 100%;
+  display: flex;
+}
+
+.typeNum {
+  height: 100%;
+  width: 33.33%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.typeNum-left {
+  font-size: 12px;
+  color: #909399;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.typeNum-left-text {
+  font-size: 12px;
+  color: #3491fa;
+  font-weight: 500;
+  margin-top: 5px;
 }
 
 .table-card {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
+}
+
+.typeNum-center {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-left: 10px;
+}
+
+.typeNum-leftLine {
+  color: #3491fa;
+  font-size: 12px;
+}
+
+.typeNum-rightLine {
+  border-top: 1px solid #3491fa;
+  border-left: 1px solid #3491fa;
+  border-bottom: 1px solid #3491fa;
+  height: 80px;
+  width: 8px;
+}
+
+.typeNum-leftLine2 {
+  color: #5eb334;
+  font-size: 12px;
+}
+
+.typeNum-rightLine2 {
+  border-top: 1px solid #3491fa;
+  border-left: 1px solid #5eb334;
+  border-bottom: 1px solid #5eb334;
+  height: 80px;
+  width: 8px;
+}
+
+.typeNum-leftLine3 {
+  color: #8000ff;
+  font-size: 12px;
+}
+
+.typeNum-rightLine3 {
+  border-top: 1px solid #8000ff;
+  border-left: 1px solid #8000ff;
+  border-bottom: 1px solid #8000ff;
+  height: 80px;
+  width: 8px;
+}
+
+.typeNum-right {
+  margin-left: 10px;
+  display: flex;
+  flex-direction: column;
+  height: 90%;
+  justify-content: space-between;
+}
+
+.typeNum-right-top-name {
+  font-weight: 400;
+  font-size: 12px;
+  color: #3d3d3d;
+}
+
+.typeNum-right-top-text {
+  font-weight: 400;
+  font-size: 16px;
+  color: rgba(0, 0, 0, 0.85);
+  margin-top: 5px;
+}
+
+.unit {
+  font-size: 12px;
+  color: #3d3d3d;
+}
+
+.inspection-chart-box {
+  height: 50px;
+  width: 30%;
+  background-color: #f7f8fa;
+  border-radius: 8px;
+  padding-left: 15px;
+}
+
+.chart-box-title {
+  font-size: 12px;
+  color: #4e5969;
+  margin-top: 5px;
+}
+
+.unit {
+  font-size: 12px;
+  color: #3d3d3d;
+}
+
+.chart-box-num {
+  font-size: 18px;
+  color: #000;
+  margin-top: 5px;
+  font-weight: 500;
+}
+
+/* 璐ㄦ鍚堟牸鐜囧崱鐗囨牱寮� */
+.top-container鍚堟牸鐜� {
+  height: 130px;
+  width: 100%;
+  display: flex;
+  gap: 15px;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.flex-center {
+  justify-content: space-evenly;
+}
+
+.quality-card {
+  /* flex: 1; */
+  width: 32%;
+  /* height: 100px; */
+  border-radius: 8px;
+  padding: 12px;
+  display: flex;
+  flex-direction: column;
+}
+
+.blue-card {
+  background-color: #e6f7ff;
+}
+
+.green-card {
+  background-color: #f6ffed;
+  color: #000000;
+}
+
+.purple-card {
+  background-color: #f9f0ff;
+}
+
+.quality-card-title {
+  font-size: 14px;
+  font-weight: 500;
+  margin-bottom: 10px;
+  display: flex;
+  align-items: center;
+}
+
+.quality-item-tip {
+  font-size: 12px;
+  color: #666666;
+  margin-bottom: 3px;
+}
+
+.blue-label {
+  color: #1890ff;
+}
+
+.green-label {
+  color: #52c41a;
+}
+
+.quality-card-title {
+  color: #000;
+  font-weight: bold;
+}
+
+.quality-card-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex: 1;
+}
+
+.quality-item {
+  display: flex;
+  /* flex-direction: column; */
+  align-items: center;
+  justify-content: center;
+  margin-top: 5px;
+  flex: 1;
+}
+
+.quality-item-label {
+  font-size: 12px;
+  /* color: #666; */
+  margin-bottom: 4px;
+}
+
+.quality-item-value {
+  font-size: 20px;
+  font-weight: 500;
+  margin-bottom: 4px;
+}
+
+.quality-item-chart {
+  width: 60px;
+  height: 60px;
+  margin-left: 10px;
+}
+
+/* .flex-center {
+justify-content: space-evenly;
+} */
+
+.blue-chart {
+  /* background-color: rgba(24, 144, 255, 0.1); */
+}
+
+.green-chart {
+  /* background-color: rgba(82, 196, 26, 0.1); */
+}
+
+.purple-chart {
+  /* background-color: rgba(114, 46, 209, 0.1); */
+}
+
+.chart-ring {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  border: 15px solid transparent;
+  position: relative;
+}
+
+.blue-chart .chart-ring {
+  border-top-color: #1890ff;
+  border-right-color: #1890ff;
+  border-bottom-color: #1890ff;
+  transform: rotate(45deg);
+}
+
+.green-chart .chart-ring {
+  border-top-color: #52c41a;
+  border-right-color: #52c41a;
+  border-bottom-color: #52c41a;
+  transform: rotate(45deg);
+}
+
+.purple-chart .chart-ring {
+  border-top-color: #722ed1;
+  border-right-color: #722ed1;
+  border-bottom-color: #722ed1;
+  transform: rotate(45deg);
 }
 
 .pagination-container {
-	margin-top: 20px;
-	text-align: right;
+  margin-top: 20px;
+  text-align: right;
+}
+
+.yearchange {
+  position: absolute;
+  right: 40px;
+  top: 20px;
+  display: flex;
+  align-items: center;
+  /* width: 60px; */
 }
 
 :deep(.el-card__header) {
-	padding: 15px 20px;
-	border-bottom: 1px solid #ebeef5;
-	background-color: #fafafa;
+  padding: 15px 20px;
+  border-bottom: 1px solid #ffffff;
+  background-color: #ffffff;
 }
 
 :deep(.el-card__body) {
-	padding: 20px;
+  padding: 20px;
 }
 
 :deep(.el-table) {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 
 :deep(.el-progress) {
-	margin: 0;
+  margin: 0;
 }
 
 :deep(.el-tag) {
-	margin: 0;
+  margin: 0;
+}
+
+:deep(.el-input__prefix) {
+  display: none !important;
 }
 </style>
diff --git a/src/views/salesManagement/deliveryLedger/index.vue b/src/views/salesManagement/deliveryLedger/index.vue
index ea81717..d838924 100644
--- a/src/views/salesManagement/deliveryLedger/index.vue
+++ b/src/views/salesManagement/deliveryLedger/index.vue
@@ -41,8 +41,8 @@
       <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
         :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
-    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍙戣揣鍙拌处' : '缂栬緫鍙戣揣鍙拌处'" width="50%"
-      @close="closeDia">
+    <FormDialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍙戣揣鍙拌处' : '缂栬緫鍙戣揣鍙拌处'" :width="'50%'"
+      :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
       <el-form :model="form" label-width="120px" label-position="top" :rules="rules" ref="formRef">
         <el-row :gutter="30">
           <el-col :span="24">
@@ -81,18 +81,13 @@
         </el-row>
         
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import pagination from "@/components/PIMTable/Pagination.vue";
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
 import { ElMessageBox } from "element-plus";
 import { getCurrentDate } from "@/utils/index.js";
diff --git a/src/views/salesManagement/indicatorStats/index.vue b/src/views/salesManagement/indicatorStats/index.vue
index 617ef6f..65dae96 100644
--- a/src/views/salesManagement/indicatorStats/index.vue
+++ b/src/views/salesManagement/indicatorStats/index.vue
@@ -3,7 +3,7 @@
     <el-card class="box-card">
       <!-- KPI 姹囨�� -->
       <el-row :gutter="20" class="stats-row">
-        <el-col :span="6">
+        <el-col :span="8">
           <div class="stat-card">
             <div class="stat-icon" style="background: #ecf5ff;">
               <el-icon :size="30" color="#409eff"><Document /></el-icon>
@@ -14,7 +14,7 @@
             </div>
           </div>
         </el-col>
-        <el-col :span="6">
+        <el-col :span="8">
           <div class="stat-card">
             <div class="stat-icon" style="background: #f0f9ff;">
               <el-icon :size="30" color="#67c23a"><Tickets /></el-icon>
@@ -25,25 +25,14 @@
             </div>
           </div>
         </el-col>
-        <el-col :span="6">
+        <el-col :span="8">
           <div class="stat-card">
             <div class="stat-icon" style="background: #fef0f0;">
               <el-icon :size="30" color="#e6a23c"><Van /></el-icon>
             </div>
             <div class="stat-content">
-              <div class="stat-value">{{ indicatorKpis.shipmentRate }}%</div>
+              <div class="stat-value">{{ indicatorKpis.shipRate }}%</div>
               <div class="stat-label">鍙戣揣鐜�</div>
-            </div>
-          </div>
-        </el-col>
-        <el-col :span="6">
-          <div class="stat-card">
-            <div class="stat-icon" style="background: #f4f4f5;">
-              <el-icon :size="30" color="#f56c6c"><Wallet /></el-icon>
-            </div>
-            <div class="stat-content">
-              <div class="stat-value">{{ indicatorKpis.collectionRate }}%</div>
-              <div class="stat-label">鍥炴鐜�</div>
             </div>
           </div>
         </el-col>
@@ -52,58 +41,38 @@
       <!-- 缁村害绛涢�� -->
       <el-row :gutter="20" class="search-row">
         <el-col :span="6">
-          <el-select v-model="indicatorFilter.product" placeholder="浜у搧" clearable>
-            <el-option label="鍏ㄩ儴浜у搧" value="" />
-            <el-option label="P.O 42.5鏅�氱閰哥洂姘存偿" value="P.O 42.5鏅�氱閰哥洂姘存偿" />
-            <el-option label="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" value="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" />
-            <el-option label="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" value="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" />
-          </el-select>
+          <el-tree-select v-model="indicatorFilter.productCategory" placeholder="浜у搧绫诲埆" clearable check-strictly
+            :data="productOptions" :render-after-expand="false" style="width: 100%" />
         </el-col>
         <el-col :span="6">
-          <el-select v-model="indicatorFilter.customer" placeholder="瀹㈡埛" clearable>
-            <el-option label="鍏ㄩ儴瀹㈡埛" value="" />
-            <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟" />
-            <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�" />
-            <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�" />
-          </el-select>
-        </el-col>
-        <el-col :span="6">
-          <el-select v-model="indicatorFilter.region" placeholder="鍖哄煙" clearable>
-            <el-option label="鍏ㄩ儴鍖哄煙" value="" />
-            <el-option label="鍗庝笢鍦板尯" value="鍗庝笢鍦板尯" />
-            <el-option label="鍗庡崡鍦板尯" value="鍗庡崡鍦板尯" />
-            <el-option label="鍗庡寳鍦板尯" value="鍗庡寳鍦板尯" />
+          <el-select v-model="indicatorFilter.customerName" placeholder="瀹㈡埛" clearable filterable>
+            <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName" />
           </el-select>
         </el-col>
         <el-col :span="6">
           <el-date-picker v-model="indicatorFilter.dateRange" type="daterange" range-separator="鑷�"
                           start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%" />
         </el-col>
-        <el-col :span="24" style="text-align: right; margin-top: 10px;">
+        <el-col :span="6" style="text-align: right;">
           <el-button type="primary" @click="applyIndicatorFilter">鏌ヨ</el-button>
           <el-button @click="resetIndicatorFilter">閲嶇疆</el-button>
-          <el-button @click="exportIndicatorTable">瀵煎嚭鎶ヨ〃</el-button>
-          <el-button @click="exportIndicatorChart">瀵煎嚭鍥捐〃</el-button>
         </el-col>
       </el-row>
 
       <!-- 鍥捐〃鍖� -->
       <div class="chart-container">
-        <div ref="indicatorChartRef" style="width: 100%; height: 360px;"></div>
+        <div ref="indicatorChartRef" class="chart-wrapper"></div>
       </div>
 
       <!-- 涓氱哗缁熻锛堝洟闃熺淮搴︼紝鏃犱釜浜哄鍚嶏級 -->
-      <el-table :data="teamPerformanceList" border stripe style="margin-top: 20px;">
+      <el-table v-if="showTeamPerformance" :data="teamPerformanceList" border stripe style="margin-top: 20px;">
         <el-table-column prop="team" label="閿�鍞洟闃�"/>
         <el-table-column prop="orderCount" label="璁㈠崟鏁�"/>
         <el-table-column prop="salesAmount" label="閿�鍞">
           <template #default="scope">楼{{ scope.row.salesAmount.toLocaleString() }}</template>
         </el-table-column>
-        <el-table-column prop="shipmentRate" label="鍙戣揣鐜�">
-          <template #default="scope">{{ scope.row.shipmentRate }}%</template>
-        </el-table-column>
-        <el-table-column prop="collectionRate" label="鍥炴鐜�">
-          <template #default="scope">{{ scope.row.collectionRate }}%</template>
+        <el-table-column prop="shipRate" label="鍙戣揣鐜�">
+          <template #default="scope">{{ scope.row.shipRate }}</template>
         </el-table-column>
         <el-table-column prop="attainment" label="鐩爣杈炬垚鐜�">
           <template #default="scope">
@@ -118,33 +87,209 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { Document, Van, Tickets, Wallet } from '@element-plus/icons-vue'
+import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
+import { Document, Van, Tickets } from '@element-plus/icons-vue'
 import * as echarts from 'echarts'
+import { getTotalStatistics, getStatisticsTable } from '@/api/salesManagement/indicatorStats'
+import { productTreeList } from '@/api/basicData/product.js'
+import { customerList } from '@/api/salesManagement/salesLedger.js'
+import { ElMessage } from 'element-plus'
 
 const indicatorKpis = reactive({
-  orderCount: 1280,
-  salesAmount: 9650000,
-  shipmentRate: 89.2,
-  collectionRate: 76.4
+  orderCount: 0,
+  salesAmount: 0,
+  shipRate: 0
 })
 
+// 鏄惁灞曠ず閿�鍞洟闃熸槑缁嗚〃锛屾寜闇�寮�鍚�
+const showTeamPerformance = ref(false)
+const loading = ref(false)
+
 const indicatorFilter = reactive({
-  product: '',
-  customer: '',
-  region: '',
+  productCategory: '',
+  customerName: '',
   dateRange: []
 })
 
 const indicatorChartRef = ref(null)
 let indicatorChart = null
 
+const productOptions = ref([])
+const customerOption = ref([])
+
 const teamPerformanceList = ref([
-  { team: '鍗庝笢澶у尯', orderCount: 320, salesAmount: 2850000, shipmentRate: 90, collectionRate: 80, attainment: 105 },
-  { team: '鍗庡寳澶у尯', orderCount: 280, salesAmount: 2150000, shipmentRate: 86, collectionRate: 73, attainment: 92 },
-  { team: '鍗庡崡澶у尯', orderCount: 210, salesAmount: 1850000, shipmentRate: 88, collectionRate: 70, attainment: 78 },
-  { team: '瑗垮崡澶у尯', orderCount: 180, salesAmount: 1500000, shipmentRate: 83, collectionRate: 68, attainment: 74 }
+  { team: '鍗庝笢澶у尯', orderCount: 320, salesAmount: 2850000, shipRate: 90, attainment: 105 },
+  { team: '鍗庡寳澶у尯', orderCount: 280, salesAmount: 2150000, shipRate: 86, attainment: 92 },
+  { team: '鍗庡崡澶у尯', orderCount: 210, salesAmount: 1850000, shipRate: 88, attainment: 78 },
+  { team: '瑗垮崡澶у尯', orderCount: 180, salesAmount: 1500000, shipRate: 83, attainment: 74 }
 ])
+
+// 杞崲浜у搧鏍戞暟鎹紝灏� id 鏀逛负 value
+function convertIdToValue(data) {
+  return data.map((item) => {
+    const { id, children, ...rest } = item
+    const newItem = {
+      ...rest,
+      value: id, // 灏� id 鏀逛负 value
+    }
+    if (children && children.length > 0) {
+      newItem.children = convertIdToValue(children)
+    }
+    return newItem
+  })
+}
+
+// 鑾峰彇浜у搧鏍戞暟鎹�
+const getProductOptions = () => {
+  return productTreeList().then((res) => {
+    productOptions.value = convertIdToValue(res)
+  }).catch((error) => {
+    console.error('鑾峰彇浜у搧鏍戝け璐�:', error)
+    ElMessage.error('鑾峰彇浜у搧绫诲埆澶辫触')
+  })
+}
+
+// 鑾峰彇瀹㈡埛鍒楄〃
+const getCustomerList = () => {
+  return customerList().then((res) => {
+    customerOption.value = res || []
+  }).catch((error) => {
+    console.error('鑾峰彇瀹㈡埛鍒楄〃澶辫触:', error)
+    ElMessage.error('鑾峰彇瀹㈡埛鍒楄〃澶辫触')
+  })
+}
+
+// 鏍规嵁 id 鏌ユ壘浜у搧绫诲埆鍚嶇О
+const findNodeLabelById = (nodes, id) => {
+  if (!id) return null
+  for (let i = 0; i < nodes.length; i++) {
+    if (nodes[i].value === id) {
+      return nodes[i].label
+    }
+    if (nodes[i].children && nodes[i].children.length > 0) {
+      const found = findNodeLabelById(nodes[i].children, id)
+      if (found) return found
+    }
+  }
+  return null
+}
+
+// 鑾峰彇澶撮儴缁熻鏁版嵁
+const fetchTotalStatistics = async () => {
+  try {
+    loading.value = true
+    const params = {}
+    if (indicatorFilter.customerName) {
+      params.customerName = indicatorFilter.customerName
+    }
+    if (indicatorFilter.productCategory) {
+      // 鏍规嵁 id 鏌ユ壘浜у搧绫诲埆鍚嶇О
+      const categoryName = findNodeLabelById(productOptions.value, indicatorFilter.productCategory)
+      if (categoryName) {
+        params.productCategory = categoryName
+      }
+    }
+    if (indicatorFilter.dateRange && indicatorFilter.dateRange.length === 2) {
+      params.entryDateStart = indicatorFilter.dateRange[0]
+      params.entryDateEnd = indicatorFilter.dateRange[1]
+    }
+    const res = await getTotalStatistics(params)
+    if (res && res.data) {
+      indicatorKpis.orderCount = res.data.total || 0
+      indicatorKpis.salesAmount = res.data.contractAmountTotal || 0
+      // 鍙戣揣鐜囧鏋滄帴鍙f病鏈夎繑鍥烇紝淇濇寔鍘熷�兼垨璁句负0
+      // indicatorKpis.shipRate = res.data.shipRate || 0
+    }
+  } catch (error) {
+    console.error('鑾峰彇澶撮儴缁熻澶辫触:', error)
+    ElMessage.error('鑾峰彇缁熻鏁版嵁澶辫触')
+  } finally {
+    loading.value = false
+  }
+}
+
+// 鑾峰彇鏌辩姸鍥炬暟鎹�
+const fetchStatisticsTable = async () => {
+  try {
+    loading.value = true
+    const params = {}
+    if (indicatorFilter.customerName) {
+      params.customerName = indicatorFilter.customerName
+    }
+    if (indicatorFilter.productCategory) {
+      // 鏍规嵁 id 鏌ユ壘浜у搧绫诲埆鍚嶇О
+      const categoryName = findNodeLabelById(productOptions.value, indicatorFilter.productCategory)
+      if (categoryName) {
+        params.productCategory = categoryName
+      }
+    }
+    if (indicatorFilter.dateRange && indicatorFilter.dateRange.length === 2) {
+      params.entryDateStart = indicatorFilter.dateRange[0]
+      params.entryDateEnd = indicatorFilter.dateRange[1]
+    }
+    const res = await getStatisticsTable(params)
+    if (res && res.data) {
+      updateChart(res.data)
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍥捐〃鏁版嵁澶辫触:', error)
+    ElMessage.error('鑾峰彇鍥捐〃鏁版嵁澶辫触')
+  } finally {
+    loading.value = false
+  }
+}
+
+// 鏇存柊鍥捐〃
+const updateChart = (chartData) => {
+  if (!indicatorChartRef.value) return
+  if (indicatorChart) indicatorChart.dispose()
+  indicatorChart = echarts.init(indicatorChartRef.value)
+  
+  // 鏍规嵁鎺ュ彛杩斿洖鐨勬暟鎹粨鏋勬洿鏂板浘琛�
+  // 鎺ュ彛杩斿洖: dateList, orderCountList, salesAmountList
+  const option = {
+    title: { text: '澶氱淮搴﹂攢鍞寚鏍囪秼鍔�', left: 'center' },
+    tooltip: { trigger: 'axis' },
+    legend: { data: ['璁㈠崟鏁�', '閿�鍞'], top: 30 },
+    grid: { left: '3%', right: '8%', bottom: '3%', containLabel: true },
+    xAxis: { 
+      type: 'category', 
+      data: chartData.dateList || [] 
+    },
+    yAxis: [
+      { type: 'value', name: '閲戦', position: 'left', axisLabel: { formatter: '{value}' } },
+      { 
+        type: 'value', 
+        name: '鏁伴噺', 
+        position: 'right', 
+        minInterval: 1,
+        axisLabel: { 
+          formatter: (value) => {
+            const intValue = Math.round(value)
+            return intValue.toString()
+          }
+        }
+      }
+    ],
+    series: [
+      { 
+        name: '璁㈠崟鏁�', 
+        type: 'line', 
+        yAxisIndex: 1,
+        data: chartData.orderCountList || [], 
+        itemStyle: { color: '#409eff' } 
+      },
+      { 
+        name: '閿�鍞', 
+        type: 'bar', 
+        yAxisIndex: 0,
+        data: chartData.salesAmountList || [], 
+        itemStyle: { color: '#67c23a' } 
+      }
+    ]
+  }
+  indicatorChart.setOption(option)
+}
 
 const initIndicatorChart = () => {
   if (!indicatorChartRef.value) return
@@ -153,78 +298,73 @@
   const option = {
     title: { text: '澶氱淮搴﹂攢鍞寚鏍囪秼鍔�', left: 'center' },
     tooltip: { trigger: 'axis' },
-    legend: { data: ['璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�', '鍥炴鐜�'], top: 30 },
-    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
-    xAxis: { type: 'category', data: ['2024-12', '2025-01', '2025-02', '2025-03', '2025-04', '2025-05'] },
+    legend: { data: ['璁㈠崟鏁�', '閿�鍞'], top: 30 },
+    grid: { left: '3%', right: '8%', bottom: '3%', containLabel: true },
+    xAxis: { type: 'category', data: [] },
     yAxis: [
-      { type: 'value', name: '鏁伴噺/閲戦', axisLabel: { formatter: '{value}' } },
-      { type: 'value', name: '姣斾緥(%)', min: 0, max: 100, axisLabel: { formatter: '{value}%' } }
+      { type: 'value', name: '閲戦', position: 'left', axisLabel: { formatter: '{value}' } },
+      { 
+        type: 'value', 
+        name: '鏁伴噺', 
+        position: 'right', 
+        minInterval: 1,
+        axisLabel: { 
+          formatter: (value) => {
+            const intValue = Math.round(value)
+            return intValue.toString()
+          }
+        }
+      }
     ],
     series: [
-      { name: '璁㈠崟鏁�', type: 'bar', data: [180, 220, 210, 260, 205, 225], itemStyle: { color: '#409eff' } },
-      { name: '閿�鍞', type: 'bar', data: [820, 950, 910, 1080, 980, 1020], itemStyle: { color: '#67c23a' } },
-      { name: '鍙戣揣鐜�', type: 'line', yAxisIndex: 1, data: [86, 89, 88, 91, 87, 90], itemStyle: { color: '#e6a23c' } },
-      { name: '鍥炴鐜�', type: 'line', yAxisIndex: 1, data: [72, 76, 74, 79, 75, 78], itemStyle: { color: '#f56c6c' } }
+      { name: '璁㈠崟鏁�', type: 'line', yAxisIndex: 1, data: [], itemStyle: { color: '#409eff' } },
+      { name: '閿�鍞', type: 'bar', yAxisIndex: 0, data: [], itemStyle: { color: '#67c23a' } }
     ]
   }
   indicatorChart.setOption(option)
 }
 
-const applyIndicatorFilter = () => {
-  const random = (base, delta) => {
-    const v = base + Math.round((Math.random() - 0.5) * delta)
-    return v < 0 ? 0 : v
-  }
-  indicatorKpis.orderCount = random(1280, 120)
-  indicatorKpis.salesAmount = random(9650000, 350000)
-  indicatorKpis.shipmentRate = (85 + Math.random() * 10).toFixed(1) * 1
-  indicatorKpis.collectionRate = (70 + Math.random() * 12).toFixed(1) * 1
-  setTimeout(() => initIndicatorChart(), 200)
+const applyIndicatorFilter = async () => {
+  await Promise.all([
+    fetchTotalStatistics(),
+    fetchStatisticsTable()
+  ])
 }
 
 const resetIndicatorFilter = () => {
-  indicatorFilter.product = ''
-  indicatorFilter.customer = ''
-  indicatorFilter.region = ''
+  indicatorFilter.productCategory = ''
+  indicatorFilter.customerName = ''
   indicatorFilter.dateRange = []
   applyIndicatorFilter()
 }
 
-const exportIndicatorTable = () => {
-  const header = ['閿�鍞洟闃�', '璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�(%)', '鍥炴鐜�(%)', '鐩爣杈炬垚鐜�(%)']
-  const rows = teamPerformanceList.value.map(r => [
-    r.team,
-    r.orderCount,
-    r.salesAmount,
-    r.shipmentRate,
-    r.collectionRate,
-    r.attainment
-  ])
-  const csv = [header, ...rows].map(r => r.join(',')).join('\n')
-  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
-  const url = URL.createObjectURL(blob)
-  const link = document.createElement('a')
-  link.href = url
-  link.download = '鎸囨爣缁熻-鍥㈤槦涓氱哗.csv'
-  document.body.appendChild(link)
-  link.click()
-  document.body.removeChild(link)
-  URL.revokeObjectURL(url)
-}
-
-const exportIndicatorChart = () => {
-  if (!indicatorChart) return
-  const url = indicatorChart.getDataURL({ type: 'png', pixelRatio: 2, backgroundColor: '#fff' })
-  const link = document.createElement('a')
-  link.href = url
-  link.download = '鎸囨爣缁熻-鍥捐〃.png'
-  document.body.appendChild(link)
-  link.click()
-  document.body.removeChild(link)
+// 绐楀彛澶у皬鍙樺寲鏃惰皟鏁村浘琛ㄥぇ灏�
+const handleResize = () => {
+  if (indicatorChart) {
+    indicatorChart.resize()
+  }
 }
 
 onMounted(() => {
-  nextTick(() => initIndicatorChart())
+  nextTick(() => {
+    initIndicatorChart()
+    getProductOptions()
+    getCustomerList()
+    fetchTotalStatistics()
+    fetchStatisticsTable()
+  })
+  // 鐩戝惉绐楀彛澶у皬鍙樺寲
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  // 绉婚櫎绐楀彛澶у皬鍙樺寲鐩戝惉鍣�
+  window.removeEventListener('resize', handleResize)
+  // 閿�姣佸浘琛ㄥ疄渚�
+  if (indicatorChart) {
+    indicatorChart.dispose()
+    indicatorChart = null
+  }
 })
 </script>
 
@@ -240,7 +380,20 @@
 .stat-content { flex: 1; }
 .stat-value { font-size: 28px; font-weight: bold; color: #303133; margin-bottom: 4px; }
 .stat-label { font-size: 14px; color: #909399; }
-.chart-container { margin: 20px 0; padding: 20px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); }
+.chart-container { 
+  margin: 20px 0; 
+  padding: 20px; 
+  background: #fff; 
+  border-radius: 8px; 
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  width: 100%;
+  overflow: hidden;
+}
+.chart-wrapper {
+  width: 100%;
+  height: 360px;
+  min-width: 0;
+}
 </style>
 
 
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
index cb8466e..eec3a26 100644
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ b/src/views/salesManagement/invoiceLedger/index.vue
@@ -31,9 +31,8 @@
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip width="180" />
-        <el-table-column label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" show-overflow-tooltip width="180" />
         <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip width="240" />
-        <el-table-column label="椤圭洰" prop="projectName" width="320" />
+<!--        <el-table-column label="椤圭洰" prop="projectName" width="320" />-->
         <el-table-column label="浜у搧澶х被" prop="productCategory" width="200" />
         <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="160" show-overflow-tooltip />
         <el-table-column label="鍙戠エ鍙�" prop="invoiceNo" width="200" show-overflow-tooltip />
@@ -43,7 +42,7 @@
         <el-table-column label="褰曞叆浜�" prop="invoicePerson" show-overflow-tooltip />
         <el-table-column label="褰曞叆鏃ユ湡" prop="createTime" show-overflow-tooltip :formatter="formatDate" width="180" />
         <el-table-column label="寮�绁ㄦ棩鏈�" prop="invoiceDate" show-overflow-tooltip width="120" />
-        <el-table-column label="鍙戠エ" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right">
+        <!-- <el-table-column label="鍙戠エ" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right">
           <template #default="scope">
             <el-button v-if="scope.row.invoiceFileName" text bg type="primary"
               @click="handleFile(scope.row.commonFiles)">
@@ -53,10 +52,11 @@
               涓婁紶
             </el-button>
           </template>
-        </el-table-column>
+        </el-table-column> -->
         <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
           <template #default="scope">
             <el-button link type="primary" size="small" @click="openForm(scope.row)">缂栬緫</el-button>
+            <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">闄勪欢</el-button>
             <el-button link type="primary" size="small" @click="delInvoiceLedger(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
@@ -64,7 +64,7 @@
       <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
         :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
-    <el-dialog v-model="dialogFormVisible" title="寮�绁ㄥ彴璐﹂〉闈�" width="70%" @close="closeDia">
+    <FormDialog v-model="dialogFormVisible" title="寮�绁ㄥ彴璐﹂〉闈�" :width="'70%'" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
       <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
@@ -108,7 +108,7 @@
             <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
               <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
                 :headers="upload.headers" accept=".pdf" :limit="10" :before-upload="handleBeforeUpload"
-                :on-error="handleUploadError" :on-success="handleUploadSuccess" :on-remove="handleRemove">
+                :on-error="handleUploadError" :on-success="handleUploadSuccess">
                 <el-button type="primary">涓婁紶</el-button>
                 <template #tip>
                   <!--                  鏂囦欢鏍煎紡鏀寔 doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
@@ -119,13 +119,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
     <el-dialog title="涓婁紶寮圭獥" width="50%" v-model="uploadModal">
       <el-row :gutter="30">
         <el-col :span="24">
@@ -149,11 +143,13 @@
         </div>
       </template>
     </el-dialog>
+    <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" />
   </div>
 </template>
 
 <script setup>
 import pagination from "@/components/PIMTable/Pagination.vue";
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { ref } from "vue";
 import { Search } from "@element-plus/icons-vue";
 import { ElMessageBox } from "element-plus";
@@ -164,10 +160,11 @@
   commitFile,
   registrationProductPage,
   delInvoiceLedgerByRegProductId,
-} from "../../../api/salesManagement/invoiceLedger.js";
+} from "@/api/salesManagement/invoiceLedger.js";
 import useUserStore from "@/store/modules/user.js";
 import useFormData from "@/hooks/useFormData";
 import dayjs from "dayjs";
+import FileListDialog from '@/components/Dialog/FileListDialog.vue';
 import { getCurrentDate } from "@/utils/index.js";
 
 const { proxy } = getCurrentInstance();
@@ -246,7 +243,11 @@
 const getList = () => {
   tableLoading.value = true;
   const { invoiceDate, ...rest } = searchForm;
-  registrationProductPage({ ...rest, ...page }).then((res) => {
+  // 灏嗚寖鍥存棩鏈熷瓧娈典紶閫掔粰鍚庣
+  const params = { ...rest, ...page };
+  // 绉婚櫎寮�绁ㄦ棩鏈熺殑榛樿鍊艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
+  delete params.invoiceDate;
+  registrationProductPage(params).then((res) => {
     tableLoading.value = false;
     tableData.value = res.data.records;
     total.value = res.data.total;
@@ -273,12 +274,12 @@
   invoiceLedgerProductInfo({ id: row.id }).then((res) => {
     form.value = { ...res.data };
     fileList.value = res.data.fileList;
+    // 淇濆瓨ticketRegistrationId鍒拌〃鍗曟暟鎹腑
+    if (row.ticketRegistrationId) {
+      form.value.ticketRegistrationId = row.ticketRegistrationId;
+    }
     if (!form.value.invoicePerson) {
       form.value.invoicePerson = userStore.nickName;
-      form.value.entryDate = getCurrentDate();
-    }
-    if (!form.value.invoiceDate) {
-      form.value.invoiceDate = getCurrentDate();
     }
   });
   dialogFormVisible.value = true;
@@ -292,7 +293,6 @@
 };
 // 涓婁紶鍓嶆牎妫�
 function handleBeforeUpload(file) {
-  console.log("file", file);
   // 鏍℃鏂囦欢澶у皬
   if (file.size > 1024 * 1024 * 10) {
     proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
@@ -316,19 +316,25 @@
 function handleUploadSuccess(res, file, uploadFiles) {
   proxy.$modal.closeLoading();
   if (res.code === 200) {
-    proxy.$refs["fileUpload"].handleRemove(file);
-    fileList.value.push(res.data);
     proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+    // 灏嗕笂浼犳垚鍔熺殑鏂囦欢淇℃伅娣诲姞鍒癴ileList涓�
+    const fileInfo = {
+      name: file.name,
+      url: res.data.url || file.response?.data?.url || file.url,
+      response: file.response
+    };
+    // 妫�鏌ユ槸鍚﹀凡瀛樺湪鐩稿悓鏂囦欢锛岄伩鍏嶉噸澶嶆坊鍔�
+    const existingFileIndex = fileList.value.findIndex(f => f.name === fileInfo.name);
+    if (existingFileIndex === -1) {
+      fileList.value.push(fileInfo);
+    } else {
+      fileList.value[existingFileIndex] = fileInfo;
+    }
+    // 纭繚琛ㄥ崟鏁版嵁涓殑fileList涔熸洿鏂�
+    form.value.fileList = fileList.value;
   } else {
     proxy.$modal.msgError(res.msg);
     proxy.$refs.fileUpload.handleRemove(file);
-  }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
-  let index = fileList.value.findIndex((item) => item.url === file.url);
-  if (index > -1) {
-    fileList.value.splice(index, 1);
   }
 }
 // 鎻愪氦琛ㄥ崟
@@ -362,13 +368,6 @@
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
     });
-};
-
-// 鎵撳紑闄勪欢涓婁紶寮圭獥
-const handleDownload = (val) => {
-  fileList.value = [];
-  uploadModal.value = true;
-  currentId.value = val.id;
 };
 
 // 纭鏂囦欢涓婁紶
@@ -426,7 +425,26 @@
   getList();
 };
 
+//闄勪欢鐩稿叧
+const fileListRef = ref(null)
+const fileListDialogVisible = ref(false)
+//鏌ョ湅闄勪欢
+const downLoadFile = (row) => {
+	invoiceLedgerProductInfo({ id: row.id }).then((res) => {
+		if (fileListRef.value) {
+			fileListRef.value.open(res.data.fileList)
+			fileListDialogVisible.value = true
+		}
+	});
+}
+
 onMounted(() => {
+  // 璁剧疆寮�绁ㄦ棩鏈熻寖鍥撮粯璁ゅ�间负褰撳ぉ
+  const today = dayjs().format('YYYY-MM-DD');
+  searchForm.invoiceDate = [today, today];
+  // 璁剧疆鑼冨洿鏃ユ湡瀛楁鐨勮捣濮嬪拰缁撴潫鏃堕棿
+  searchForm.invoiceDateStart = today;
+  searchForm.invoiceDateEnd = today;
   getList();
 });
 </script>
diff --git a/src/views/salesManagement/invoiceRegistration/index.vue b/src/views/salesManagement/invoiceRegistration/index.vue
index 8bf1236..9cc1d66 100644
--- a/src/views/salesManagement/invoiceRegistration/index.vue
+++ b/src/views/salesManagement/invoiceRegistration/index.vue
@@ -1,418 +1,388 @@
 <template>
-  <div class="app-container">
-    <div class="search_form">
-      <el-form :inline="true" :model="searchForm">
-        <el-form-item label="瀹㈡埛鍚嶇О">
-          <el-input
-            v-model="searchForm.customerName"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ュ悕绉版悳绱�"
-            clearable
-            :prefix-icon="Search"
-            @change="handleQuery"
-          />
-        </el-form-item>
-        <el-form-item label="瀹㈡埛鍚堝悓鍙�">
-          <el-input
-            v-model="searchForm.customerContractNo"
-            placeholder="璇疯緭鍏ュ鎴峰悎鍚屽彿"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item label="椤圭洰鍚嶇О">
-          <el-input
-            v-model="searchForm.projectName"
-            placeholder="璇疯緭鍏ラ」鐩悕绉�"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item>
-          <el-checkbox
-            v-model="searchForm.status"
-            label="涓嶆樉绀烘湭寮�绁ㄩ噾棰濅负0"
-            @change="handleQuery"
-          />
-        </el-form-item>
-        <el-form-item>
-          <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
-          <el-button @click="resetForm"> 閲嶇疆 </el-button>
-          <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-    <div class="table_list">
-      <div class="flex justify-between">
-        <div></div>
-        <div>
-        <el-button type="primary" @click="openForm" style="margin-bottom: 8px">
-          鏂板鐧昏
-        </el-button>
-        </div>
-      </div>
-      <el-table
-        :data="tableData"
-        :border="true"
-        height="calc(100vh - 21em)"
-        v-loading="tableLoading"
-        :expand-row-keys="expandedRowKeys"
-        :row-key="(row) => row.id"
-        show-summary
-        :summary-method="summarizeMainTable"
-        @expand-change="expandChange"
-        @selection-change="handleSelectionChange"
-      >
-        <el-table-column align="center" type="selection" width="55" />
-        <el-table-column type="expand">
-          <template #default="props">
-            <el-table
-              :data="props.row.children"
-              border
-              show-summary
-              :summary-method="summarizeChildrenTable"
-            >
-              <el-table-column
-                align="center"
-                label="搴忓彿"
-                type="index"
-                width="60"
-              />
-              <el-table-column label="浜у搧澶х被" prop="productCategory" />
-              <el-table-column
-                label="瑙勬牸鍨嬪彿"
-                prop="specificationModel"
-                width="150"
-              />
-              <el-table-column label="鍗曚綅" prop="unit" width="70" />
-              <el-table-column label="鏁伴噺" prop="quantity" width="70" />
-              <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
-              <el-table-column
-                label="鍚◣鍗曚环(鍏�)"
-                prop="taxInclusiveUnitPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="鍚◣鎬讳环(鍏�)"
-                prop="taxInclusiveTotalPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="涓嶅惈绋庢�讳环(鍏�)"
-                prop="taxExclusiveTotalPrice"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="寮�绁ㄦ暟"
-                prop="invoiceNum"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="寮�绁ㄩ噾棰�(鍏�)"
-                prop="invoiceAmount"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="鏈紑绁ㄦ暟"
-                prop="noInvoiceNum"
-                :formatter="formattedNumber"
-              />
-              <el-table-column
-                label="鏈紑绁ㄩ噾棰�(鍏�)"
-                prop="noInvoiceAmount"
-                :formatter="formattedNumber"
-              />
-            </el-table>
-          </template>
-        </el-table-column>
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column
-          label="閿�鍞悎鍚屽彿"
-          prop="salesContractNo"
-          show-overflow-tooltip
-          width="200"
-        />
-        <el-table-column
-          label="瀹㈡埛鍚堝悓鍙�"
-          prop="customerContractNo"
-          width="200"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="瀹㈡埛鍚嶇О"
-          prop="customerName"
-          show-overflow-tooltip
-          width="240"
-        />
-        <el-table-column label="涓氬姟鍛�" prop="salesman" show-overflow-tooltip width="90"/>
-        <el-table-column
-          label="椤圭洰鍚嶇О"
-          prop="projectName"
-          show-overflow-tooltip
-          width="200"
-        />
-        <el-table-column
-          label="鍚堝悓閲戦(鍏�)"
-          prop="contractAmount"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
-					width="220"
-
-        />
-        <el-table-column
-          label="宸插紑绁ㄩ噾棰�(鍏�)"
-          prop="invoiceTotal"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
-          width="120"
-        />
-        <el-table-column
-          label="鏈紑绁ㄩ噾棰�(鍏�)"
-          prop="noInvoiceAmountTotal"
-          show-overflow-tooltip
-          width="120"
-        >
-          <template #default="{ row, column }">
-            <el-text type="danger">
-              {{ formattedNumber(row, column, row.noInvoiceAmountTotal) }}
-            </el-text>
-          </template>
-        </el-table-column>
-      </el-table>
-      <pagination
-        v-show="total > 0"
-        :total="total"
-        layout="total, sizes, prev, pager, next, jumper"
-        :page="page.current"
-        :limit="page.size"
-        @pagination="paginationChange"
-      />
-    </div>
-    <el-dialog
-      v-model="dialogFormVisible"
-      title="鏂板寮�绁ㄧ櫥璁伴〉闈�"
-      width="85%"
-      @close="closeDia"
-    >
-      <el-form
-        :model="form"
-        label-width="140px"
-        label-position="top"
-        :rules="rules"
-        ref="formRef"
-      >
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-              <el-input v-model="form.salesContractNo" disabled></el-input>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
-              <el-input
-                v-model="form.customerName"
-                placeholder="鑷姩濉厖"
-                disabled
-              ></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="涓氬姟鍛橈細" prop="salesman">
-              <el-input
-                v-model="form.salesman"
-                placeholder="鑷姩濉厖"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-              <el-input
-                v-model="form.projectName"
-                placeholder="鑷姩濉厖"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="褰曞叆浜�" prop="createUer">
-              <el-input v-model="form.createUer" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="寮�绁ㄦ棩鏈�" prop="issueDate">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.issueDate"
-                type="date"
-                placeholder="璇烽�夋嫨"
-                clearable
-                format="YYYY-MM-DD"
-                value-format="YYYY-MM-DD"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="createTime">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.createTime"
-                type="date"
-                placeholder="璇烽�夋嫨"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ鍙风爜锛�" prop="invoiceNo">
-              <el-input
-                v-model="form.invoiceNo"
-                placeholder="璇疯緭鍏�"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
-        </el-row>
-        <el-table
-          :data="productData"
-          border
-          show-summary
-          :summary-method="summarizeChildrenTable"
-        >
-          <el-table-column
-            align="center"
-            label="搴忓彿"
-            type="index"
-            width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column
-            label="瑙勬牸鍨嬪彿"
-            prop="specificationModel"
-            width="150"
-          />
-          <el-table-column label="鍗曚綅" prop="unit" />
-          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
-          <el-table-column
-            label="鍚◣鍗曚环(鍏�)"
-            prop="taxInclusiveUnitPrice"
-            :formatter="formattedNumber"
+	<div class="app-container">
+		<div class="search_form">
+			<el-form :inline="true" :model="searchForm">
+				<el-form-item label="瀹㈡埛鍚嶇О">
+					<el-input
+						v-model="searchForm.customerName"
+						style="width: 240px"
+						placeholder="璇疯緭鍏ュ悕绉版悳绱�"
+						clearable
+						:prefix-icon="Search"
+						@change="handleQuery"
+					/>
+				</el-form-item>
+				<el-form-item>
+					<el-checkbox
+						v-model="searchForm.status"
+						label="涓嶆樉绀烘湭寮�绁ㄩ噾棰濅负0"
+						@change="handleQuery"
+					/>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
+					<el-button @click="resetForm"> 閲嶇疆 </el-button>
+					<el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
+				</el-form-item>
+			</el-form>
+		</div>
+		<div class="table_list">
+			<div class="flex justify-between">
+				<div></div>
+				<div>
+					<el-button type="primary" @click="openForm" style="margin-bottom: 8px">
+						寮�绁ㄧ櫥璁�
+					</el-button>
+				</div>
+			</div>
+			<el-table
+				:data="tableData"
+				:border="true"
+				height="calc(100vh - 21em)"
+				v-loading="tableLoading"
+				:expand-row-keys="expandedRowKeys"
+				:row-key="(row) => row.id"
+				show-summary
+				:summary-method="summarizeMainTable"
+				@expand-change="expandChange"
+				@selection-change="handleSelectionChange"
+			>
+				<el-table-column align="center" type="selection" width="55" />
+				<el-table-column type="expand">
+					<template #default="props">
+						<el-table
+							:data="props.row.children"
+							border
+							show-summary
+							:summary-method="summarizeChildrenTable"
+						>
+							<el-table-column
+								align="center"
+								label="搴忓彿"
+								type="index"
+								width="60"
+							/>
+							<el-table-column label="浜у搧澶х被" prop="productCategory" />
+							<el-table-column
+								label="瑙勬牸鍨嬪彿"
+								prop="specificationModel"
+								width="150"
+							/>
+							<el-table-column label="鍗曚綅" prop="unit" width="70" />
+							<el-table-column label="鏁伴噺" prop="quantity" width="70" />
+							<el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+							<el-table-column
+								label="鍚◣鍗曚环(鍏�)"
+								prop="taxInclusiveUnitPrice"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="鍚◣鎬讳环(鍏�)"
+								prop="taxInclusiveTotalPrice"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="涓嶅惈绋庢�讳环(鍏�)"
+								prop="taxExclusiveTotalPrice"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="寮�绁ㄦ暟"
+								prop="invoiceNum"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="寮�绁ㄩ噾棰�(鍏�)"
+								prop="invoiceAmount"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="鏈紑绁ㄦ暟"
+								prop="noInvoiceNum"
+								:formatter="formattedNumber"
+							/>
+							<el-table-column
+								label="鏈紑绁ㄩ噾棰�(鍏�)"
+								prop="noInvoiceAmount"
+								:formatter="formattedNumber"
+							/>
+						</el-table>
+					</template>
+				</el-table-column>
+				<el-table-column align="center" label="搴忓彿" type="index" width="60" />
+				<el-table-column
+					label="閿�鍞悎鍚屽彿"
+					prop="salesContractNo"
+					show-overflow-tooltip
+				/>
+<!--				<el-table-column-->
+<!--					label="瀹㈡埛鍚堝悓鍙�"-->
+<!--					prop="customerContractNo"-->
+<!--					width="200"-->
+<!--					show-overflow-tooltip-->
+<!--				/>-->
+				<el-table-column
+					label="瀹㈡埛鍚嶇О"
+					prop="customerName"
+					show-overflow-tooltip
+				/>
+				<el-table-column label="涓氬姟鍛�" prop="salesman" show-overflow-tooltip/>
+				<el-table-column
+					label="鍚堝悓閲戦(鍏�)"
+					prop="contractAmount"
+					show-overflow-tooltip
+					:formatter="formattedNumber"
+				
+				/>
+				<el-table-column
+					label="宸插紑绁ㄩ噾棰�(鍏�)"
+					prop="invoiceTotal"
+					show-overflow-tooltip
+					:formatter="formattedNumber"
+				/>
+				<el-table-column
+					label="鏈紑绁ㄩ噾棰�(鍏�)"
+					prop="noInvoiceAmountTotal"
+					show-overflow-tooltip
+					width="120"
+				>
+					<template #default="{ row, column }">
+						<el-text type="danger">
+							{{ formattedNumber(row, column, row.noInvoiceAmountTotal) }}
+						</el-text>
+					</template>
+				</el-table-column>
+			</el-table>
+			<pagination
+				v-show="total > 0"
+				:total="total"
+				layout="total, sizes, prev, pager, next, jumper"
+				:page="page.current"
+				:limit="page.size"
+				@pagination="paginationChange"
+			/>
+		</div>
+		<FormDialog
+			v-model="dialogFormVisible"
+			title="鏂板寮�绁ㄧ櫥璁伴〉闈�"
+			:width="'85%'"
+			@close="closeDia"
+			@confirm="submitForm"
+			@cancel="closeDia"
+		>
+			<el-form
+				:model="form"
+				label-width="140px"
+				label-position="top"
+				:rules="rules"
+				ref="formRef"
+			>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
+							<el-input v-model="form.salesContractNo" disabled placeholder="澶氬悎鍚屾壒閲忓鐞嗭紙鍏蜂綋鍚堝悓鍙疯浜у搧鍒楄〃锛�"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
+							<el-input
+								v-model="form.customerName"
+								placeholder="鑷姩濉厖"
+								disabled
+							></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="涓氬姟鍛橈細" prop="salesman">
+							<el-input
+								v-model="form.salesman"
+								placeholder="鑷姩濉厖"
+								disabled
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鍙戠エ鍙风爜锛�" prop="invoiceNo">
+							<el-input
+								v-model="form.invoiceNo"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="寮�绁ㄦ棩鏈�" prop="issueDate">
+							<el-date-picker
+								style="width: 100%"
+								v-model="form.issueDate"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+								format="YYYY-MM-DD"
+								value-format="YYYY-MM-DD"
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="褰曞叆浜�" prop="createUer">
+							<el-input v-model="form.createUer" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="褰曞叆鏃ユ湡锛�" prop="createTime">
+							<el-date-picker
+								style="width: 100%"
+								v-model="form.createTime"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					
+				</el-row>
+				<el-row>
+					<el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
+				</el-row>
+				<el-table
+					:data="productData"
+					border
+					show-summary
+					:summary-method="summarizeChildrenTable"
+				>
+					<el-table-column
+						align="center"
+						label="搴忓彿"
+						type="index"
+						width="60"
+					/>
+					<el-table-column label="鎵�灞炲悎鍚�" prop="salesContractNo" width="200">
+						<template #default="{ row }">
+							<el-tag type="primary">{{ row.salesContractNo }}</el-tag>
+						</template>
+					</el-table-column>
+					<el-table-column label="浜у搧澶х被" prop="productCategory" />
+					<el-table-column
+						label="瑙勬牸鍨嬪彿"
+						prop="specificationModel"
+						width="150"
+					/>
+					<el-table-column label="鍗曚綅" prop="unit" />
+					<el-table-column label="鏁伴噺" prop="quantity" width="70" />
+					<el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+					<el-table-column
+						label="鍚◣鍗曚环(鍏�)"
+						prop="taxInclusiveUnitPrice"
+						:formatter="formattedNumber"
 						width="200"
-          />
-          <el-table-column
-            label="鍚◣鎬讳环(鍏�)"
-            prop="taxInclusiveTotalPrice"
-            :formatter="formattedNumber"
+					/>
+					<el-table-column
+						label="鍚◣鎬讳环(鍏�)"
+						prop="taxInclusiveTotalPrice"
+						:formatter="formattedNumber"
 						width="200"
-          />
-          <el-table-column
-            label="涓嶅惈绋庢�讳环(鍏�)"
-            prop="taxExclusiveTotalPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-          <el-table-column label="鏈寮�绁ㄦ暟" prop="currentInvoiceNum" width="180">
-            <template #default="scope">
-              <el-input-number :step="0.1" :min="0" style="width: 100%"
+					/>
+					<el-table-column
+						label="涓嶅惈绋庢�讳环(鍏�)"
+						prop="taxExclusiveTotalPrice"
+						:formatter="formattedNumber"
+						width="150"
+					/>
+					<el-table-column label="鏈寮�绁ㄦ暟" prop="currentInvoiceNum" width="180">
+						<template #default="scope">
+							<el-input-number :step="0.1" :min="0" style="width: 100%"
 															 :precision="2"
-                v-model="scope.row.currentInvoiceNum"
-                @change="invoiceNumBlur(scope.row)"
-              ></el-input-number>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="鏈寮�绁ㄩ噾棰�(鍏�)"
-            prop="currentInvoiceAmount"
-            width="180"
-          >
-            <template #default="scope">
-              <el-input-number :step="0.01" :min="0" style="width: 100%"
+															 v-model="scope.row.currentInvoiceNum"
+															 @change="invoiceNumBlur(scope.row)"
+							></el-input-number>
+						</template>
+					</el-table-column>
+					<el-table-column
+						label="鏈寮�绁ㄩ噾棰�(鍏�)"
+						prop="currentInvoiceAmount"
+						width="180"
+					>
+						<template #default="scope">
+							<el-input-number :step="0.01" :min="0" style="width: 100%"
 															 :precision="2"
-                v-model="scope.row.currentInvoiceAmount"
-                @change="invoiceAmountBlur(scope.row)"
-              ></el-input-number>
-            </template>
-          </el-table-column>
-          <el-table-column label="鏈紑绁ㄦ暟" prop="noInvoiceNum" width="120">
-            <template #default="scope">
-              <el-input
-                type="number"
-                min="0"
-                disabled
-                v-model="scope.row.noInvoiceNum"
-              ></el-input>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="鏈紑绁ㄩ噾棰�(鍏�)"
-            prop="noInvoiceAmount"
-            width="200"
-          >
-            <template #default="scope">
-              <el-input
-                type="number"
-                min="0"
-                disabled
-                v-model="scope.row.noInvoiceAmount"
-                :formatter="formattedInputNumber"
-                :precision="2"
-                :step="0.01"
-              ></el-input>
-            </template>
-          </el-table-column>
-          <el-table-column label="鐧昏浜�" prop="register" width="100">
-            <!-- <template #default="{ row }">
-              <el-input
-                v-model="row.register"
-                placeholder="璇疯緭鍏ョ櫥璁颁汉"
-                disabled
-              />
-            </template> -->
-          </el-table-column>
-          <el-table-column label="鐧昏鏃ユ湡" prop="registerDate" width="150">
-            <!-- <template #default="{ row }">
-              <el-date-picker
-                style="width: 100%"
-                v-model="row.registerDate"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                type="date"
-                placeholder="璇烽�夋嫨"
-                clearable
-                disabled
-              />
-            </template> -->
-          </el-table-column>
-        </el-table>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
+															 v-model="scope.row.currentInvoiceAmount"
+															 @change="invoiceAmountBlur(scope.row)"
+							></el-input-number>
+						</template>
+					</el-table-column>
+					<el-table-column label="鏈紑绁ㄦ暟" prop="noInvoiceNum" width="120">
+						<template #default="scope">
+							<el-input
+								type="number"
+								min="0"
+								disabled
+								v-model="scope.row.noInvoiceNum"
+							></el-input>
+						</template>
+					</el-table-column>
+					<el-table-column
+						label="鏈紑绁ㄩ噾棰�(鍏�)"
+						prop="noInvoiceAmount"
+						width="200"
+					>
+						<template #default="scope">
+							<el-input
+								type="number"
+								min="0"
+								disabled
+								v-model="scope.row.noInvoiceAmount"
+								:formatter="formattedInputNumber"
+								:precision="2"
+								:step="0.01"
+							></el-input>
+						</template>
+					</el-table-column>
+					<el-table-column label="鐧昏浜�" prop="register" width="100">
+						<!-- <template #default="{ row }">
+							<el-input
+								v-model="row.register"
+								placeholder="璇疯緭鍏ョ櫥璁颁汉"
+								disabled
+							/>
+						</template> -->
+					</el-table-column>
+					<el-table-column label="鐧昏鏃ユ湡" prop="registerDate" width="150">
+						<!-- <template #default="{ row }">
+							<el-date-picker
+								style="width: 100%"
+								v-model="row.registerDate"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+								disabled
+							/>
+						</template> -->
+					</el-table-column>
+				</el-table>
+			</el-form>
+		</FormDialog>
+	</div>
 </template>
 
 <script setup>
 import pagination from "@/components/PIMTable/Pagination.vue";
+import FormDialog from '@/components/Dialog/FormDialog.vue';
 import { onMounted, ref } from "vue";
 import { Search } from "@element-plus/icons-vue";
 import { ElMessageBox } from "element-plus";
 // import {userListNoPage} from "@/api/system/user.js";
 import {
-  getSalesLedgerWithProducts,
-  ledgerListPage,
-  productList,
+	getSalesLedgerWithProducts,
+	ledgerListPage,
+	productList,
 } from "@/api/salesManagement/salesLedger.js";
 import { invoiceRegistrationSave } from "@/api/salesManagement/invoiceRegistration.js";
 import useFormData from "@/hooks/useFormData";
@@ -426,261 +396,377 @@
 const selectedRows = ref([]);
 const tableLoading = ref(false);
 const page = reactive({
-  current: 1,
-  size: 100,
+	current: 1,
+	size: 100,
 });
 const total = ref(0);
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
 const operationType = ref("");
 const dialogFormVisible = ref(false);
 const data = reactive({
-  searchForm: {
-    customerName: "",
-    status: false,
-    customerContractNo: undefined, // 瀹㈡埛鍚堝悓鍙�
-    projectName: undefined, // 椤圭洰鍚嶇О
-    createUer: undefined, // 鐧昏浜�
-    issueDate: undefined, // 寮�绁ㄦ棩鏈�
-    createTime: undefined, // 褰曞叆鏃ユ湡锛�
-  },
-  form: {
-    salesLedgerId: "",
-    customerName: "",
-    salesman: "",
-    projectName: "",
-    productData: [],
-    invoiceNo: "",
-    createUer: userStore.nickName,
-    issueDate: dayjs().format("YYYY-MM-DD"),
-  },
-  rules: {
-    salesLedgerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    createUer: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
-    issueDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    invoiceNo: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
-    createTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-  },
+	searchForm: {
+		customerName: "",
+		status: false,
+		customerContractNo: undefined, // 瀹㈡埛鍚堝悓鍙�
+		projectName: undefined, // 椤圭洰鍚嶇О
+		createUer: undefined, // 鐧昏浜�
+		issueDate: undefined, // 寮�绁ㄦ棩鏈�
+		createTime: undefined, // 褰曞叆鏃ユ湡锛�
+		productCategory: "",
+		isInvoice: 1
+	},
+	form: {
+		salesLedgerId: "",
+		customerName: "",
+		salesman: "",
+		projectName: "",
+		productData: [],
+		invoiceNo: "",
+		createUer: userStore.nickName,
+		issueDate: dayjs().format("YYYY-MM-DD"),
+		selectedContractIds: [], // 鏂板锛氬瓨鍌ㄦ墍鏈夐�変腑鐨勫悎鍚孖D
+		isBatch: false // 鏂板锛氭爣璇嗘槸鍚︿负鎵归噺鎿嶄綔
+	},
+	rules: {
+		createUer: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
+		issueDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		invoiceNo: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
+		createTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+	},
 });
 const { form, rules } = toRefs(data);
 const { form: searchForm, resetForm } = useFormData(data.searchForm);
 
 const formattedNumber = (row, column, cellValue) => {
-  if (cellValue == 0) {
-    return parseFloat(cellValue).toFixed(2);
-  }
-  if (cellValue) {
-    return parseFloat(cellValue).toFixed(2);
-  } else {
-    return cellValue;
-  }
+	if (cellValue == 0) {
+		return parseFloat(cellValue).toFixed(2);
+	}
+	if (cellValue) {
+		return parseFloat(cellValue).toFixed(2);
+	} else {
+		return cellValue;
+	}
 };
 
 const formattedInputNumber = (value) => {
-  return value ? parseFloat(value).toFixed(2) : 0;
+	return value ? parseFloat(value).toFixed(2) : 0;
 };
 
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  page.current = 1;
-  getList();
+	page.current = 1;
+	getList();
 };
 const paginationChange = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
 };
 const getList = () => {
-  tableLoading.value = true;
-  ledgerListPage({ ...searchForm, ...page }).then((res) => {
-    tableLoading.value = false;
-    tableData.value = res.records;
-    total.value = res.total;
-    expandedRowKeys.value = [];
-  });
+	tableLoading.value = true;
+	ledgerListPage({ ...searchForm, ...page }).then((res) => {
+		tableLoading.value = false;
+		tableData.value = res.records;
+		total.value = res.total;
+		expandedRowKeys.value = [];
+	});
 };
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
-  console.log("selection", selection);
-  selectedRows.value = selection.filter(
-    (item) => item.salesContractNo !== undefined
-  );
+	console.log("selection", selection);
+	selectedRows.value = selection.filter(
+		(item) => item.salesContractNo !== undefined
+	);
 };
 const expandedRowKeys = ref([]);
 // 灞曞紑琛�
 const expandChange = (row, expandedRows) => {
-  if (expandedRows.length > 0) {
-    expandedRowKeys.value = [];
-    try {
-      productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
-        const index = tableData.value.findIndex((item) => item.id === row.id);
-        if (index > -1) {
-          tableData.value[index].children = res.data;
-        }
-        expandedRowKeys.value.push(row.id);
-      });
-    } catch (error) {
-      console.log(error);
-    }
-  } else {
-    expandedRowKeys.value = [];
-  }
+	if (expandedRows.length > 0) {
+		expandedRowKeys.value = [];
+		try {
+			productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
+				const index = tableData.value.findIndex((item) => item.id === row.id);
+				if (index > -1) {
+					tableData.value[index].children = res.data;
+				}
+				expandedRowKeys.value.push(row.id);
+			});
+		} catch (error) {
+			console.log(error);
+		}
+	} else {
+		expandedRowKeys.value = [];
+	}
 };
 // 涓昏〃鍚堣鏂规硶
 const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(param, [
-    "contractAmount",
-    "invoiceTotal",
-    "noInvoiceAmountTotal",
-  ]);
+	return proxy.summarizeTable(param, [
+		"contractAmount",
+		"invoiceTotal",
+		"noInvoiceAmountTotal",
+	]);
 };
 // 瀛愯〃鍚堣鏂规硶
 const summarizeChildrenTable = (param) => {
-  return proxy.summarizeTable(param, [
-    "taxInclusiveUnitPrice",
-    "taxInclusiveTotalPrice",
-    "taxExclusiveTotalPrice",
-    "invoiceNum",
-    "invoiceAmount",
-    "currentInvoiceAmount",
-    "noInvoiceNum",
-    "noInvoiceAmount",
-    "currentInvoiceNum",
-  ]);
+	return proxy.summarizeTable(param, [
+		"taxInclusiveUnitPrice",
+		"taxInclusiveTotalPrice",
+		"taxExclusiveTotalPrice",
+		"invoiceNum",
+		"invoiceAmount",
+		"currentInvoiceAmount",
+		"noInvoiceNum",
+		"noInvoiceAmount",
+		"currentInvoiceNum",
+	]);
 };
 // 鎵撳紑寮规
 const openForm = () => {
-  // 鍒ゆ柇鏄惁澶氶��
-  if (selectedRows.value.length != 1) {
-    proxy.$modal.msgError("璇烽�夋嫨涓�鏉″悎鍚�");
-    return;
-  }
-  form.value = {};
-  productData.value = [];
-  getSalesLedgerWithProducts({ id: selectedRows.value[0].id }).then((res) => {
-    form.value = { ...res };
-    form.value.createTime = dayjs().format("YYYY-MM-DD");
-    form.value.issueDate = dayjs().format("YYYY-MM-DD");
-    form.value.createUer = userStore.nickName;
-    productData.value = form.value.productData.map((item) => {
-      return item;
-    });
-    dialogFormVisible.value = true;
-    console.log("productData.value ", productData.value);
-  });
+	// 鍒ゆ柇鏄惁閫夋嫨浜嗗悎鍚�
+	if (selectedRows.value.length === 0) {
+		proxy.$modal.msgError("璇疯嚦灏戦�夋嫨涓�鏉″悎鍚�");
+		return;
+	}
+	
+	// 妫�鏌ユ墍鏈夐�夋嫨鐨勫悎鍚屾槸鍚﹀叿鏈夌浉鍚岀殑瀹㈡埛鍚嶇О
+	const firstRow = selectedRows.value[0];
+	const isSameCustomer = selectedRows.value.every(row =>
+		row.customerName === firstRow.customerName
+	);
+	
+	if (!isSameCustomer) {
+		proxy.$modal.msgError("璇烽�夋嫨鐩稿悓瀹㈡埛鍚嶇О鐨勫悎鍚�");
+		return;
+	}
+	
+	// 鍏佽涓嶅悓鐨勯攢鍞悎鍚屽彿鎵归噺澶勭悊锛屾棤闇�妫�鏌ラ噸澶�
+	
+	form.value = {};
+	productData.value = [];
+	
+	// 鍔犺浇鎵�鏈夐�変腑鍚堝悓鐨勪骇鍝佹暟鎹�
+	const promises = selectedRows.value.map(row =>
+		getSalesLedgerWithProducts({ id: row.id })
+	);
+	
+	Promise.all(promises).then(results => {
+		// 鍚堝苟鎵�鏈夊悎鍚岀殑浜у搧鏁版嵁锛屽苟涓烘瘡涓骇鍝佹坊鍔犲搴旂殑鍚堝悓淇℃伅
+		const allProductData = [];
+		results.forEach((result, index) => {
+			const contract = selectedRows.value[index];
+			// const contractId = contract.id;
+			if (result.productData) {
+				result.productData.forEach(item => {
+					allProductData.push({
+						...item,
+						// id: contractId, // 鏄庣‘璁剧疆鍚堝悓ID
+						salesContractNo: contract.salesContractNo, // 娣诲姞閿�鍞悎鍚屽彿
+						customerName: contract.customerName, // 娣诲姞瀹㈡埛鍚嶇О
+						customerContractNo: contract.customerContractNo // 娣诲姞瀹㈡埛鍚堝悓鍙�
+					});
+				});
+			}
+		});
+		
+		// 璁剧疆琛ㄥ崟鏁版嵁锛堜娇鐢ㄧ涓�涓悎鍚岀殑鍩烘湰淇℃伅锛岄攢鍞悎鍚屽彿鐣欑┖锛�
+		form.value = { ...results[0] };
+		form.value.createTime = dayjs().format("YYYY-MM-DD");
+		form.value.issueDate = dayjs().format("YYYY-MM-DD");
+		form.value.createUer = userStore.nickName;
+		form.value.selectedContractIds = selectedRows.value.map(row => row.id); // 瀛樺偍鎵�鏈夐�変腑鐨勫悎鍚孖D
+		form.value.salesContractNo = ""; // 閿�鍞悎鍚屽彿鐣欑┖锛屽洜涓轰細鍦ㄤ骇鍝佽〃鏍间腑鍒嗗埆鏄剧ず
+		
+		productData.value = allProductData;
+		
+		dialogFormVisible.value = true;
+		console.log("productData.value ", productData.value);
+	});
 };
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
-  proxy.$refs["formRef"].validate((valid) => {
-    if (valid) {
-      form.value.productData = proxy.HaveJson(productData.value);
-      invoiceRegistrationSave(form.value).then((res) => {
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-        closeDia();
-        getList();
-      });
-    }
-  });
+	proxy.$refs["formRef"].validate((valid) => {
+		if (valid) {
+			// 濡傛灉鏄壒閲忔搷浣滐紝灏嗘墍鏈夊悎鍚岀殑鏁版嵁鏀惧湪涓�涓暟缁勯噷锛屽彧璋冪敤涓�娆℃帴鍙�
+			if (selectedRows.value.length > 1) {
+				// 鍒涘缓鍖呭惈鎵�鏈夊悎鍚屾暟鎹殑鏁扮粍
+				const batchData = selectedRows.value.map(contract => {
+					// 绛涢�夊嚭灞炰簬褰撳墠鍚堝悓鐨勪骇鍝佹暟鎹�
+					const contractProductData = productData.value.filter(item =>
+						item.salesLedgerId === contract.id
+					);
+					
+					// 涓烘瘡涓攢鍞悎鍚屽彿鍒涘缓鐙珛鐨勫璞�
+					return {
+						// 鍩虹琛ㄥ崟鏁版嵁
+						issueDate: form.value.issueDate,
+						createTime: form.value.createTime,
+						createUer: form.value.createUer,
+						invoiceNo: form.value.invoiceNo,
+						
+						// 鍚堝悓瀹為檯淇℃伅
+						id: contract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负salesLedgerId
+						salesContractNo: contract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+						customerName: contract.customerName, // 浣跨敤瀹為檯鐨勫鎴峰悕绉�
+						customerId: contract.customerId, // 娣诲姞瀹㈡埛ID
+						customerContractNo: contract.customerContractNo, // 浣跨敤瀹為檯鐨勫鎴峰悎鍚屽彿
+						projectName: contract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+						salesman: contract.salesman, // 浣跨敤瀹為檯鐨勪笟鍔″憳
+						
+						// 浜у搧鏁版嵁
+						productData: proxy.HaveJson(contractProductData),
+						
+						// 鎵归噺鏍囪瘑
+						isBatch: true
+					};
+				});
+				
+				// 鍙皟鐢ㄤ竴娆℃帴鍙o紝浼犻�掑寘鍚墍鏈夊悎鍚屾暟鎹殑鏁扮粍
+				invoiceRegistrationSave(batchData).then(() => {
+					proxy.$modal.msgSuccess("鎵归噺鏂板鎴愬姛");
+					closeDia();
+					getList();
+				});
+			} else {
+				// 鍗曚釜鍚堝悓鎻愪氦閫昏緫 - 涔熶互鏁扮粍褰㈠紡浼犻��
+				const singleContract = selectedRows.value[0];
+				const singleFormArray = [
+					{
+						// 鍩虹琛ㄥ崟鏁版嵁
+						issueDate: form.value.issueDate,
+						createTime: form.value.createTime,
+						createUer: form.value.createUer,
+						invoiceNo: form.value.invoiceNo,
+						
+						// 鍚堝悓瀹為檯淇℃伅
+						id: singleContract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负salesLedgerId
+						salesContractNo: singleContract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+						customerName: singleContract.customerName, // 浣跨敤瀹為檯鐨勫鎴峰悕绉�
+						customerId: singleContract.customerId, // 娣诲姞瀹㈡埛ID
+						customerContractNo: singleContract.customerContractNo, // 浣跨敤瀹為檯鐨勫鎴峰悎鍚屽彿
+						projectName: singleContract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+						salesman: singleContract.salesman, // 浣跨敤瀹為檯鐨勪笟鍔″憳
+						
+						// 浜у搧鏁版嵁
+						productData: proxy.HaveJson(productData.value),
+						
+						// 鎵归噺鏍囪瘑
+						isBatch: false
+					}
+				];
+				invoiceRegistrationSave(singleFormArray).then((res) => {
+					proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+					closeDia();
+					getList();
+				});
+			}
+		}
+	});
 };
 // 鍏抽棴寮规
 const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
+	proxy.resetForm("formRef");
+	dialogFormVisible.value = false;
 };
 // 瀵煎嚭
 const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      proxy.download("/invoiceRegistration/export", {}, "寮�绁ㄧ櫥璁颁俊鎭�.xlsx");
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			proxy.download("/invoiceRegistration/export", {}, "寮�绁ㄧ櫥璁颁俊鎭�.xlsx");
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
 };
 
 // 瀵煎嚭閿�鍞彴璐�
 const handleExport = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      proxy.download("/sales/ledger/exportOne", { ...searchForm, ...page }, "寮�绁ㄧ櫥璁�.xlsx");
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			proxy.download("/sales/ledger/exportOne", { ...searchForm, ...page }, "寮�绁ㄧ櫥璁�.xlsx");
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
 };
 
 //鏈寮�绁ㄥけ鐒︽搷浣�
 const invoiceNumBlur = (row) => {
-  if (!row.currentInvoiceNum) {
-    row.currentInvoiceNum = 0;
-  }
-  if (row.currentInvoiceNum > row.tempNoInvoiceNum) {
-    proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
-    row.currentInvoiceNum = 0;
-  }
-  // 璁$畻鏈寮�绁ㄩ噾棰�
-  row.currentInvoiceAmount = (
-    row.currentInvoiceNum * row.taxInclusiveUnitPrice
-  ).toFixed(2);
-  // 璁$畻鏈紑绁ㄦ暟
-  row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
-    2
-  );
-  // 璁$畻鏈紑绁ㄩ噾棰�
-  row.noInvoiceAmount = (
-    row.tempnoInvoiceAmount - row.currentInvoiceAmount
-  ).toFixed(2);
+	if (!row.currentInvoiceNum) {
+		row.currentInvoiceNum = 0;
+	}
+	if (row.currentInvoiceNum > row.tempNoInvoiceNum) {
+		proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
+		row.currentInvoiceNum = 0;
+	}
+	// 璁$畻鏈寮�绁ㄩ噾棰�
+	row.currentInvoiceAmount = (
+		row.currentInvoiceNum * row.taxInclusiveUnitPrice
+	).toFixed(2);
+	// 璁$畻鏈紑绁ㄦ暟
+	row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
+		2
+	);
+	// 璁$畻鏈紑绁ㄩ噾棰�
+	row.noInvoiceAmount = (
+		row.tempnoInvoiceAmount - row.currentInvoiceAmount
+	).toFixed(2);
 };
 // 鏈寮�绁ㄩ噾棰濆け鐒︽搷浣�
 const invoiceAmountBlur = (row) => {
-  if (!row.currentInvoiceAmount) {
-    row.currentInvoiceAmount = 0;
-  }
-  // 璁$畻鏄惁瓒呰繃寮�绁ㄦ�婚噾棰�
-  if (row.currentInvoiceAmount > row.tempnoInvoiceAmount) {
-    proxy.$modal.msgWarning("鏈寮�绁ㄩ噾棰濅笉寰楀ぇ浜庢湭寮�绁ㄩ噾棰�");
-    row.currentInvoiceAmount = 0;
-  }
-  // 璁$畻鏈寮�绁ㄦ暟
-  row.currentInvoiceNum = (
-    row.currentInvoiceAmount / row.taxInclusiveUnitPrice
-  ).toFixed(2);
-  console.log("row.currentInvoiceNum ", row.currentInvoiceNum);
-  console.log(" row.originalNoInvoiceNum  ", row.originalNoInvoiceNum);
-  // 璁$畻鏈紑绁ㄦ暟
-  row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
-    2
-  );
-  // 璁$畻鏈紑绁ㄩ噾棰�
-  row.noInvoiceAmount = (
-    row.tempnoInvoiceAmount - row.currentInvoiceAmount
-  ).toFixed(2);
+	if (!row.currentInvoiceAmount) {
+		row.currentInvoiceAmount = 0;
+	}
+	// 璁$畻鏄惁瓒呰繃寮�绁ㄦ�婚噾棰�
+	if (row.currentInvoiceAmount > row.tempnoInvoiceAmount) {
+		proxy.$modal.msgWarning("鏈寮�绁ㄩ噾棰濅笉寰楀ぇ浜庢湭寮�绁ㄩ噾棰�");
+		row.currentInvoiceAmount = 0;
+	}
+	// 璁$畻鏈寮�绁ㄦ暟
+	row.currentInvoiceNum = (
+		row.currentInvoiceAmount / row.taxInclusiveUnitPrice
+	).toFixed(2);
+	console.log("row.currentInvoiceNum ", row.currentInvoiceNum);
+	console.log(" row.originalNoInvoiceNum  ", row.originalNoInvoiceNum);
+	// 璁$畻鏈紑绁ㄦ暟
+	row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
+		2
+	);
+	// 璁$畻鏈紑绁ㄩ噾棰�
+	row.noInvoiceAmount = (
+		row.tempnoInvoiceAmount - row.currentInvoiceAmount
+	).toFixed(2);
 };
 
 onMounted(() => {
-  getList();
+	getList();
 });
 </script>
 
 <style scoped lang="scss">
 .table_list {
-  margin-top: unset;
+	margin-top: unset;
 }
 .flex {
-  display: flex;
+	display: flex;
 }
 .justify-between {
-  justify-content: space-between;
+	justify-content: space-between;
 }
 ::v-deep(.el-checkbox__label) {
-  font-weight: bold;
+	font-weight: bold;
 }
 </style>
+
+
+
+
+
diff --git a/src/views/salesManagement/orderManagement/index.vue b/src/views/salesManagement/orderManagement/index.vue
index aac840f..6107966 100644
--- a/src/views/salesManagement/orderManagement/index.vue
+++ b/src/views/salesManagement/orderManagement/index.vue
@@ -89,7 +89,7 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
+    <FormDialog v-model="dialogVisible" :title="dialogTitle" :width="'700px'" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -166,10 +166,10 @@
           <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
         </div>
       </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 璁㈠崟瀹℃牳瀵硅瘽妗� -->
-    <el-dialog v-model="reviewDialogVisible" title="璁㈠崟瀹℃牳" width="500px">
+    <FormDialog v-model="reviewDialogVisible" title="璁㈠崟瀹℃牳" :width="'500px'" @close="reviewDialogVisible = false" @confirm="saveReview" @cancel="reviewDialogVisible = false">
       <el-form label-width="100px">
         <el-form-item label="璁㈠崟鍙�">
           <span>{{ currentOrder.orderNo }}</span>
@@ -196,10 +196,10 @@
           <el-button type="primary" @click="saveReview">纭� 瀹�</el-button>
         </div>
       </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 璁㈠崟杞崟瀵硅瘽妗� -->
-    <el-dialog v-model="transferDialogVisible" title="璁㈠崟杞崟" width="500px">
+    <FormDialog v-model="transferDialogVisible" title="璁㈠崟杞崟" :width="'500px'" @close="transferDialogVisible = false" @confirm="saveTransfer" @cancel="transferDialogVisible = false">
       <el-form label-width="100px">
         <el-form-item label="璁㈠崟鍙�">
           <span>{{ currentOrder.orderNo }}</span>
@@ -218,13 +218,7 @@
           <el-input type="textarea" v-model="transferReason" rows="3" placeholder="璇疯緭鍏ヨ浆鍗曞師鍥�"></el-input>
         </el-form-item>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="transferDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="saveTransfer">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
@@ -233,6 +227,7 @@
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { Plus, Search } from '@element-plus/icons-vue'
 import Pagination from '@/components/PIMTable/Pagination.vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
diff --git a/src/views/salesManagement/paymentShipping/index.vue b/src/views/salesManagement/paymentShipping/index.vue
index 0bcfd87..56caf3b 100644
--- a/src/views/salesManagement/paymentShipping/index.vue
+++ b/src/views/salesManagement/paymentShipping/index.vue
@@ -98,7 +98,7 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
+    <FormDialog v-model="dialogVisible" :title="dialogTitle" :width="'700px'" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -185,10 +185,10 @@
           <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
         </div>
       </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 浠樻瀵硅瘽妗� -->
-    <el-dialog v-model="paymentDialogVisible" title="璁㈠崟浠樻" width="500px">
+    <FormDialog v-model="paymentDialogVisible" title="璁㈠崟浠樻" :width="'500px'" @close="paymentDialogVisible = false" @confirm="savePayment" @cancel="paymentDialogVisible = false">
       <el-form label-width="100px">
         <el-form-item label="璁㈠崟鍙�">
           <span>{{ currentRecord.orderNo }}</span>
@@ -214,16 +214,10 @@
           <el-input type="textarea" v-model="paymentRemark" rows="3" placeholder="璇疯緭鍏ヤ粯娆惧娉�"></el-input>
         </el-form-item>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="paymentDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="savePayment">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 鍙戣揣瀵硅瘽妗� -->
-    <el-dialog v-model="shippingDialogVisible" title="璁㈠崟鍙戣揣" width="500px">
+    <FormDialog v-model="shippingDialogVisible" title="璁㈠崟鍙戣揣" :width="'500px'" @close="shippingDialogVisible = false" @confirm="saveShipping" @cancel="shippingDialogVisible = false">
       <el-form label-width="100px">
         <el-form-item label="璁㈠崟鍙�">
           <span>{{ currentRecord.orderNo }}</span>
@@ -257,13 +251,7 @@
           <el-input type="textarea" v-model="shippingRemark" rows="3" placeholder="璇疯緭鍏ュ彂璐у娉�"></el-input>
         </el-form-item>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="shippingDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="saveShipping">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
@@ -273,6 +261,7 @@
 import { Plus, Search } from '@element-plus/icons-vue'
 import {listPage,add,update,deletePaymentShipping} from "@/api/salesManagement/paymentShipping.js"
 import Pagination from '@/components/PIMTable/Pagination.vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
 
 const total = ref(0)
 onMounted(() => {
diff --git a/src/views/salesManagement/receiptPayment/index.vue b/src/views/salesManagement/receiptPayment/index.vue
index 26f089b..66af76a 100644
--- a/src/views/salesManagement/receiptPayment/index.vue
+++ b/src/views/salesManagement/receiptPayment/index.vue
@@ -13,24 +13,6 @@
                 prefix-icon="Search"
               />
             </el-form-item>
-            <el-form-item label="瀹㈡埛鍚堝悓鍙�">
-              <el-input
-                v-model="searchForm.customerContractNo"
-                placeholder="璇疯緭鍏�"
-                @change="handleQuery"
-                clearable
-                prefix-icon="Search"
-              />
-            </el-form-item>
-            <el-form-item label="椤圭洰鍚嶇О">
-              <el-input
-                v-model="searchForm.projectName"
-                placeholder="璇疯緭鍏�"
-                @change="handleQuery"
-                clearable
-                prefix-icon="Search"
-              />
-            </el-form-item>
             <el-form-item>
               <el-checkbox
                 v-model="searchForm.status"
@@ -152,23 +134,10 @@
           width="240"
         />
         <el-table-column
-          label="瀹㈡埛鍚堝悓鍙�"
-          prop="customerContractNo"
-          show-overflow-tooltip
-          width="240"
-
-        />
-        <el-table-column
           label="瀹㈡埛鍚嶇О"
           prop="customerName"
           show-overflow-tooltip
           width="240"
-        />
-        <el-table-column
-          label="椤圭洰鍚嶇О"
-          prop="projectName"
-          show-overflow-tooltip
-          width="340"
         />
         <el-table-column
           label="鍥炴鐘舵��"
@@ -188,35 +157,28 @@
           width="100"
         />
         <el-table-column
-          label="鍙戠エ鍙�"
-          prop="invoiceNo"
+          label="瑙勬牸鍨嬪彿"
+          prop="specificationModel"
           show-overflow-tooltip
-          width="200"
-        />
-        <el-table-column
-          label="鍙戠エ閲戦(鍏�)"
-          prop="invoiceTotal"
-          show-overflow-tooltip
-          :formatter="formattedNumber"
           width="200"
         />
         <el-table-column label="绋庣巼(%)" prop="taxRate" show-overflow-tooltip />
         <el-table-column
-          label="鍥炴閲戦(鍏�)"
-          prop="receiptPaymentAmountTotal"
+          label="宸插洖娆鹃噾棰�(鍏�)"
+          prop="invoiceTotal"
           show-overflow-tooltip
           :formatter="formattedNumber"
           width="200"
         />
         <el-table-column
           label="寰呭洖娆鹃噾棰�(鍏�)"
-          prop="noReceiptAmount"
+          prop="pendingInvoiceTotal"
           show-overflow-tooltip
           width="200"
         >
           <template #default="{ row, column }">
             <el-text type="danger">
-              {{ formattedNumber(row, column, row.noReceiptAmount) }}
+              {{ formattedNumber(row, column, row.pendingInvoiceTotal) }}
             </el-text>
           </template>
         </el-table-column>
@@ -230,145 +192,108 @@
         @pagination="paginationChange"
       />
     </div>
-    <el-dialog
+    <FormDialog
       v-model="dialogFormVisible"
       title="鏂板鍥炴椤甸潰"
-      width="70%"
+      :width="'90%'"
       @close="closeDia"
+      @confirm="submitForm"
+      @cancel="closeDia"
     >
-      <el-form
-        :model="form"
-        label-width="140px"
-        label-position="top"
-        :rules="rules"
-        ref="formRef"
+      <el-table
+        v-if="forms.length"
+        :data="forms"
+        border
+        style="width: 100%"
+        size="small"
       >
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-              <el-input
-                v-model="form.salesContractNo"
-                placeholder="鑷姩濉厖"
-                disabled
+        <el-table-column type="index" label="搴忓彿" width="50" align="center"/>
+        <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip />
+        <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip />
+				<el-table-column
+					label="浜у搧澶х被"
+					prop="productCategory"
+					show-overflow-tooltip
+					width="100"
+				/>
+				<el-table-column
+					label="瑙勬牸鍨嬪彿"
+					prop="specificationModel"
+					show-overflow-tooltip
+					width="200"
+				/>
+        <el-table-column label="绋庣巼(%)" width="110">
+          <template #default="{ row }">
+            <el-input v-model="row.taxRate" disabled />
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="寰呭洖娆鹃噾棰�(鍏�)"
+          prop="pendingInvoiceTotal"
+          show-overflow-tooltip
+          width="170"
+        >
+          <template #default="{ row, column }">
+            <el-text type="danger">
+              {{ formattedNumber(row, column, row.pendingInvoiceTotal) }}
+            </el-text>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏈鍥炴閲戦(鍏�)" width="180">
+          <template #default="{ row }">
+            <el-input-number
+              v-model="row.receiptPaymentAmount"
+              :step="0.01"
+              :min="0"
+              :max="Number(row.pendingInvoiceTotal || 0)"
+              :precision="2"
+              style="width: 100%"
+              placeholder="璇疯緭鍏�"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍥炴褰㈠紡" width="160">
+          <template #default="{ row }">
+            <el-select v-model="row.receiptPaymentType" placeholder="璇烽�夋嫨" clearable>
+              <el-option
+                v-for="opt in receipt_payment_type"
+                :key="opt.value"
+                :label="opt.label"
+                :value="opt.value"
               />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
-              <el-input
-                v-model="form.customerName"
-                placeholder="鑷姩濉厖"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNo">
-              <el-input
-                v-model="form.invoiceNo"
-                placeholder="鑷姩濉厖"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceTotal">
-              <el-input
-                type="number"
-                v-model="form.invoiceTotal"
-                placeholder="鑷姩濉厖"
-                :step="0.01"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绋庣巼锛�" prop="taxRate">
-              <el-input
-                type="number"
-                v-model="form.taxRate"
-                placeholder="鑷姩濉厖"
-                :step="0.01"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏈鍥炴閲戦锛�" prop="receiptPaymentAmount">
-              <el-input-number :step="0.01" :min="0" style="width: 100%"
-															 :precision="2"
-                v-model="form.receiptPaymentAmount"
-                placeholder="璇疯緭鍏�"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍥炴褰㈠紡锛�" prop="receiptPaymentType">
-              <el-select
-                v-model="form.receiptPaymentType"
-                placeholder="璇烽�夋嫨"
-                clearable
-              >
-                <el-option
-                  v-for="item in receipt_payment_type"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-					<el-col :span="12">
-						<el-form-item label="鍥炴鏃ユ湡锛�" prop="receiptPaymentDate">
-							<el-date-picker
-								style="width: 100%"
-								v-model="form.receiptPaymentDate"
-								value-format="YYYY-MM-DD"
-								format="YYYY-MM-DD"
-								type="date"
-								placeholder="璇烽�夋嫨"
-								clearable
-							/>
-						</el-form-item>
-					</el-col>
-        </el-row>
-        <el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="鐧昏浜猴細" prop="registrant">
-							<el-input
-								v-model="form.registrant"
-								placeholder="璇疯緭鍏�"
-								clearable
-								disabled
-							/>
-						</el-form-item>
-					</el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍥炴鏃ユ湡" width="170">
+          <template #default="{ row }">
+            <el-date-picker
+              v-model="row.receiptPaymentDate"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              type="date"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐧昏浜�" width="140">
+          <template #default="{ row }">
+            <el-input v-model="row.registrant" />
+          </template>
+        </el-table-column>
+      </el-table>
+      <div v-else class="empty-tip">璇烽�夋嫨闇�瑕佸洖娆剧殑璁板綍</div>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref } from "vue";
+import FormDialog from '@/components/Dialog/FormDialog.vue';
+import { onMounted, ref, reactive, getCurrentInstance } from "vue";
 import {
   receiptPaymentSaveOrUpdate,
   bindInvoiceNoRegPage,
-  invoiceInfo,
   receiptPaymentHistoryListNoPage,
   receiptPaymentDel,
 } from "../../../api/salesManagement/receiptPayment.js";
@@ -381,6 +306,7 @@
 const tableData = ref([]);
 const selectedRows = ref([]);
 const tableLoading = ref(false);
+const forms = ref([]);
 const page = reactive({
   current: 1,
   size: 100,
@@ -395,44 +321,15 @@
     searchText: "",
     status: true,
     customerName: "",
-    customerContractNo: "",
-    projectName: "",
-  },
-  form: {
-    salesContractNo: "",
-    customerName: "",
-    invoiceNo: "",
-    invoiceTotal: "",
-    taxRate: "",
-    receiptPaymentAmount: "",
-    receiptPaymentType: "",
-    registrant: "",
-    receiptPaymentDate: "",
-  },
-  rules: {
-    salesContractNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    customerName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    invoiceNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    invoiceTotal: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    receiptPaymentAmount: [
-      { required: true, message: "璇烽�夋嫨", trigger: "change" },
-    ],
-    receiptPaymentType: [
-      { required: true, message: "璇烽�夋嫨", trigger: "change" },
-    ],
-    registrant: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    receiptPaymentDate: [
-      { required: true, message: "璇烽�夋嫨", trigger: "change" },
-    ],
+    specificationModel: "",
   },
 });
-const { form, rules } = toRefs(data);
-const { form: searchForm, resetForm } = useFormData(data.searchForm);
+const { form: searchForm } = useFormData(data.searchForm);
 const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
 
 const formattedNumber = (row, column, cellValue) => {
-  return parseFloat(cellValue).toFixed(2);
+  const val = Number(cellValue ?? 0);
+  return Number.isFinite(val) ? val.toFixed(2) : "0.00";
 };
 
 const getStatusTagType = (statusName = '') => {
@@ -501,15 +398,13 @@
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
   console.log("selection", selection);
-  selectedRows.value = selection.filter(
-    (item) => item.customerContractNo !== null
-  );
+  selectedRows.value = selection;
 };
 // 涓昏〃鍚堣鏂规硶
 const summarizeMainTable = (param) => {
   return proxy.summarizeTable(
     param,
-    ["invoiceTotal", "receiptPaymentAmountTotal", "noReceiptAmount"],
+    ["receiptPaymentAmountTotal", "noReceiptAmount"],
     {
       ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
@@ -522,38 +417,72 @@
 };
 // 鎵撳紑寮规
 const openForm = () => {
-  form.value = {};
-  if (selectedRows.value.length !== 1) {
-    proxy.$modal.msgError("璇烽�夋嫨涓�鏉℃暟鎹�");
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgError("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
     return;
   }
-  if (selectedRows.value[0].noReceiptAmount == 0) {
-    proxy.$modal.msgWarning("鏃犻渶鍐嶅洖娆�");
+  const validRows = selectedRows.value.filter((item) => item.noReceiptAmount !== 0);
+  if (validRows.length === 0) {
+    proxy.$modal.msgWarning("鎵�閫夎褰曞潎鏃犻渶鍥炴");
     return;
   }
-  invoiceInfo({ id: selectedRows.value[0].id }).then((res) => {
-    form.value = { ...res.data };
-    form.value.invoiceLedgerId = form.value.id;
-    form.value.id = "";
-    form.value.registrant = userStore.nickName;
-  });
+  forms.value = validRows.map((row) => ({
+    salesContractNo: row.salesContractNo || "",
+    customerName: row.customerName || "",
+    productCategory: row.productCategory || "",
+    specificationModel: row.specificationModel || "",
+    pendingInvoiceTotal: Number(row.pendingInvoiceTotal || 0),
+    taxRate: row.taxRate ?? "",
+    receiptPaymentAmount: "",
+    receiptPaymentType: "",
+    registrant: userStore.nickName,
+    receiptPaymentDate: "",
+    invoiceLedgerId: row.id,
+    salesLedgerId: row.salesLedgerId,
+    salesLedgerProductId: row.id,
+  }));
   dialogFormVisible.value = true;
 };
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
-  proxy.$refs["formRef"].validate((valid) => {
-    if (valid) {
-      receiptPaymentSaveOrUpdate(form.value).then((res) => {
-        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-        closeDia();
-        getList();
-      });
+  if (forms.value.length === 0) {
+    proxy.$modal.msgError("璇烽�夋嫨鍥炴璁板綍");
+    return;
+  }
+  for (let i = 0; i < forms.value.length; i++) {
+    const item = forms.value[i];
+    const pendingAmount = Number(item.pendingInvoiceTotal || 0);
+    const currentAmount = Number(item.receiptPaymentAmount);
+    if (!item.receiptPaymentAmount && item.receiptPaymentAmount !== 0) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇峰~鍐欏洖娆鹃噾棰漙);
+      return;
     }
+    if (currentAmount > pendingAmount) {
+      proxy.$modal.msgError(
+        `绗� ${i + 1} 鏉★細鍥炴閲戦涓嶈兘瓒呰繃寰呭洖娆鹃噾棰濓紙寰呭洖娆撅細${pendingAmount.toFixed(
+          2
+        )}锛塦
+      );
+      return;
+    }
+    if (!item.receiptPaymentType) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇烽�夋嫨鍥炴褰㈠紡`);
+      return;
+    }
+    if (!item.receiptPaymentDate) {
+      proxy.$modal.msgError(`绗� ${i + 1} 鏉★細璇烽�夋嫨鍥炴鏃ユ湡`);
+      return;
+    }
+  }
+  receiptPaymentSaveOrUpdate(forms.value).then(() => {
+    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+    closeDia();
+    getList();
   });
 };
 // 鍏抽棴寮规
 const closeDia = () => {
-  proxy.resetForm("formRef");
+  forms.value = [];
   dialogFormVisible.value = false;
 };
 
@@ -594,7 +523,7 @@
     receiptPaymentType: row.receiptPaymentType,
     receiptPaymentAmount: row.receiptPaymentAmount,
   };
-  receiptPaymentSaveOrUpdate(updateData).then((res) => {
+  receiptPaymentSaveOrUpdate([updateData]).then((res) => {
     row.editType = !row.editType;
 		getList();
 		proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
@@ -638,4 +567,9 @@
   justify-content: space-between;
   margin-bottom: 10px;
 }
+.empty-tip {
+  text-align: center;
+  padding: 20px 0;
+  color: #909399;
+}
 </style>
diff --git a/src/views/salesManagement/receiptPaymentHistory/index.vue b/src/views/salesManagement/receiptPaymentHistory/index.vue
index 589d567..f66bed7 100644
--- a/src/views/salesManagement/receiptPaymentHistory/index.vue
+++ b/src/views/salesManagement/receiptPaymentHistory/index.vue
@@ -10,24 +10,6 @@
           :prefix-icon="Search"
         />
       </el-form-item>
-      <el-form-item label="瀹㈡埛鍚堝悓鍙�">
-        <el-input
-          v-model="searchForm.customerContractNo"
-          placeholder="杈撳叆瀹㈡埛鍚堝悓鍙�"
-          @change="handleQuery"
-          clearable
-          :prefix-icon="Search"
-        />
-      </el-form-item>
-      <el-form-item label="椤圭洰鍚嶇О">
-        <el-input
-          v-model="searchForm.projectName"
-          placeholder="杈撳叆椤圭洰鍚嶇О"
-          @change="handleQuery"
-          clearable
-          :prefix-icon="Search"
-        />
-      </el-form-item>
       <el-form-item label="鍥炴鏃ユ湡">
         <el-date-picker
           v-model="searchForm.receiptPaymentDate"
@@ -45,6 +27,13 @@
       <el-form-item>
         <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
         <el-button @click="handleExport">瀵煎嚭</el-button>
+        <el-button
+          type="danger"
+          :disabled="selectedRows.length === 0"
+          @click="handleBatchDelete"
+        >
+          鎵归噺鍒犻櫎 ({{ selectedRows.length }})
+        </el-button>
       </el-form-item>
     </el-form>
     <div class="table_list">
@@ -60,15 +49,27 @@
         :total="page.total"
         @pagination="pagination"
         @selection-change="handleSelectionChange"
-      ></PIMTable>
+      >
+        <template #operation="{ row }">
+          <el-button
+            type="primary"
+            link
+            size="small"
+            @click="handleDelete(row)"
+          >
+            鍒犻櫎
+          </el-button>
+        </template>
+      </PIMTable>
     </div>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, getCurrentInstance } from "vue";
+import { ref, reactive, getCurrentInstance, onMounted } from "vue";
 import { Search } from "@element-plus/icons-vue";
-import { receiptPaymentHistoryListPage } from "@/api/salesManagement/receiptPayment.js";
+import { ElMessageBox } from "element-plus";
+import { receiptPaymentHistoryListPage, receiptPaymentDel } from "@/api/salesManagement/receiptPayment.js";
 import useFormData from "@/hooks/useFormData";
 import dayjs from "dayjs";
 
@@ -80,11 +81,6 @@
     width:240
   },
   {
-    label: "瀹㈡埛鍚堝悓鍙�",
-    prop: "customerContractNo",
-    width:240
-  },
-  {
     label: "鍥炴鏃ユ湡",
     prop: "receiptPaymentDate",
     width:100
@@ -93,11 +89,6 @@
     label: "瀹㈡埛鍚嶇О",
     prop: "customerName",
     width:240
-  },
-  {
-    label: "椤圭洰鍚嶇О",
-    prop: "projectName",
-    width:200
   },
   {
     label: "鍥炴閲戦锛堝厓锛�",
@@ -133,6 +124,14 @@
     prop: "createTime",
     width:100
   },
+  {
+    label: "鎿嶄綔",
+    dataType: "slot",
+    fixed: "right",
+    slot: "operation",
+    width: 100,
+    align: "center",
+  },
 ]);
 const tableData = ref([]);
 const selectedRows = ref([]);
@@ -149,8 +148,6 @@
   receiptPaymentDate: [],
   receiptPaymentDateStart: undefined,
   receiptPaymentDateEnd: undefined,
-  customerContractNo: undefined,
-  projectName: undefined,
 });
 const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
 const isShowSummarySon = ref(true);
@@ -205,6 +202,66 @@
   getList();
 };
 
+// 鍒犻櫎
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ヨ褰曞悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(async () => {
+      try {
+        tableLoading.value = true;
+        await receiptPaymentDel([row.id]);
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        getList();
+      } catch (error) {
+        console.error("鍒犻櫎澶辫触:", error);
+        proxy.$modal.msgError("鍒犻櫎澶辫触");
+      } finally {
+        tableLoading.value = false;
+      }
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑堝垹闄�");
+    });
+};
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm(
+    `纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉℃暟鎹悧锛焋,
+    "鍒犻櫎鎻愮ず",
+    {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }
+  )
+    .then(async () => {
+      try {
+        tableLoading.value = true;
+        const ids = selectedRows.value.map((item) => item.id);
+        await receiptPaymentDel(ids);
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        selectedRows.value = [];
+        getList();
+      } catch (error) {
+        console.error("鍒犻櫎澶辫触:", error);
+        proxy.$modal.msgError("鍒犻櫎澶辫触");
+      } finally {
+        tableLoading.value = false;
+      }
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
 // 瀵煎嚭
 const handleExport = () => {
   const { receiptPaymentDate, ...rest } = searchForm;
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index 2cec625..7029cfc 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -41,7 +41,7 @@
 						width="200"
           />
           <el-table-column
-            label="寮�绁ㄩ噾棰�(鍏�)"
+            label="鍚堝悓閲戦(鍏�)"
             prop="invoiceTotal"
             show-overflow-tooltip
             :formatter="formattedNumber"
@@ -93,45 +93,43 @@
           />
           <el-table-column
             label="鍙戠敓鏃ユ湡"
-            prop="happenTime"
+            prop="receiptPaymentDate"
             show-overflow-tooltip
 						width="110"
           />
           <el-table-column
-            label="寮�绁ㄩ噾棰�(鍏�)"
-            prop="invoiceAmount"
+            label="閿�鍞悎鍚屽彿"
+            prop="salesContractNo"
+            show-overflow-tooltip
+						width="200"
+          />
+          <el-table-column
+            label="鍚堝悓閲戦(鍏�)"
+            prop="invoiceTotal"
             show-overflow-tooltip
             :formatter="formattedNumber"
 						width="200"
           />
           <el-table-column
             label="鍥炴閲戦(鍏�)"
-            prop="receiptAmount"
+            prop="receiptPaymentAmount"
             show-overflow-tooltip
             :formatter="formattedNumber"
 						width="200"
           />
           <el-table-column
             label="搴旀敹閲戦(鍏�)"
-            prop="unReceiptAmount"
+            prop="unReceiptPaymentAmount"
             show-overflow-tooltip
 						width="200"
           >
             <template #default="{ row, column }">
               <el-text type="danger">
-                {{ formattedNumber(row, column, row.unReceiptAmount) }}
+                {{ formattedNumber(row, column, row.unReceiptPaymentAmount) }}
               </el-text>
             </template>
           </el-table-column>
         </el-table>
-        <pagination
-          v-show="recordTotal > 0"
-          :total="recordTotal"
-          layout="total, sizes, prev, pager, next, jumper"
-          :page="recordPage.current"
-          :limit="recordPage.size"
-          @pagination="recordPaginationChange"
-        />
       </div>
     </div>
   </div>
@@ -172,7 +170,6 @@
   getList();
 };
 const paginationChange = (obj) => {
-  console.log("paginationChange", current, limit);
   page.current = obj.page;
   page.size = obj.limit;
   getList();
diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue
new file mode 100644
index 0000000..da37db2
--- /dev/null
+++ b/src/views/salesManagement/salesLedger/fileList.vue
@@ -0,0 +1,43 @@
+<template>
+  <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+    <el-table :data="tableData" border height="40vh">
+      <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+      <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+          <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import filePreview from '@/components/filePreview/index.vue'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+  dialogVisible.value = false
+}
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list
+}
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+defineExpose({
+  open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5b5268e..54114f1 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -50,11 +50,42 @@
               <el-table-column label="浜у搧澶х被" prop="productCategory" />
               <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
               <el-table-column label="鍗曚綅" prop="unit" />
+              <el-table-column label="浜у搧鐘舵��" width="100px" align="center">
+                <template #default="scope">
+                  <el-tag v-if="scope.row.approveStatus === 0" type="info">鏈嚭搴�</el-tag>
+                  <el-tag v-if="scope.row.approveStatus === 1" type="success">宸插嚭搴�</el-tag>
+                  <el-tag v-if="scope.row.approveStatus === 2" type="warning">瀹℃牳涓�</el-tag>
+                  <el-tag v-if="scope.row.approveStatus === 3" type="success">瀹℃牳鎴愬姛</el-tag>
+                  <el-tag v-if="scope.row.approveStatus === 4" type="danger">瀹℃牳澶辫触</el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="鍙戣揣杞︾墝" minWidth="100px" align="center">
+                <template #default="scope">
+                  <div>
+                    <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
+                    <el-tag v-else type="info">鏈彂璐�</el-tag>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="鍙戣揣鏃ユ湡" minWidth="100px" align="center">
+                <template #default="scope">
+                  <div>
+                    <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
+                    <el-tag v-else type="info">鏈彂璐�</el-tag>
+                  </div>
+                </template>
+              </el-table-column>
               <el-table-column label="鏁伴噺" prop="quantity" />
               <el-table-column label="绋庣巼(%)" prop="taxRate" />
               <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
               <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
               <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
+            <!--鎿嶄綔-->
+              <el-table-column Width="60px" label="鎿嶄綔" align="center">
+                <template #default="scope">
+                  <el-button :disabled="scope.row.approveStatus!==2 || scope.row.approveStatus!==5" link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>
+                </template>
+              </el-table-column>
             </el-table>
           </template>
         </el-table-column>
@@ -70,12 +101,12 @@
         <el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
         <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
         <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
-        <el-table-column fixed="right" label="鎿嶄綔" min-width="200" align="center">
+        <el-table-column fixed="right" label="鎿嶄綔" min-width="100" align="center">
           <template #default="scope">
             <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">缂栬緫</el-button>
 <!--            <el-button link type="primary" size="small" @click="openForm('view', scope.row)">璇︽儏</el-button>-->
             <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">闄勪欢</el-button>
-            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>
+<!--            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>-->
           </template>
         </el-table-column>
       </el-table>
@@ -209,8 +240,7 @@
         </div>
       </template>
     </el-dialog>
-    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" width="40%"
-      @close="closeProductDia">
+    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" width="40%" @close="closeProductDia">
       <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
@@ -328,7 +358,7 @@
 										<span class="value">{{ formatDate(item.createTime) }}</span>
 									</div>
 									<div>
-										
+
 										<span class="label">瀹㈡埛鍚嶇О锛�</span>
 										<span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
 									</div>
@@ -442,6 +472,15 @@
 						</el-form-item>
 					</el-col>
 				</el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="瀹℃壒浜猴細" prop="approverId">
+              <el-select v-model="deliveryForm.approverId" placeholder="璇烽�夋嫨瀹℃壒浜�" clearable :disabled="operationType === 'view'">
+                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
 			</el-form>
 			<template #footer>
 				<div class="dialog-footer">
@@ -451,18 +490,56 @@
 			</template>
 		</el-dialog>
     <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" />
+    <!-- 瀵煎叆瀵硅瘽妗� -->
+    <el-dialog
+      :title="importUpload.title"
+      v-model="importUpload.open"
+      width="400px"
+      append-to-body
+    >
+      <el-upload
+        ref="importUploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="importUpload.headers"
+        :action="importUpload.url"
+        :disabled="importUpload.isUploading"
+        :before-upload="importUpload.beforeUpload"
+        :on-progress="importUpload.onProgress"
+        :on-success="importUpload.onSuccess"
+        :on-error="importUpload.onError"
+        :on-change="importUpload.onChange"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitImportFile" :loading="importUpload.isUploading">纭� 瀹�</el-button>
+          <el-button @click="importUpload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref} from "vue";
+import {onMounted, ref, getCurrentInstance} from "vue";
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
-import {ElMessage, ElMessageBox} from "element-plus";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { UploadFilled } from "@element-plus/icons-vue";
 import useUserStore from "@/store/modules/user";
 import { userListNoPage } from "@/api/system/user.js";
-import FileListDialog from '@/components/Dialog/FileListDialog.vue';
+import FileList from "./fileList.vue";
 import {
   ledgerListPage,
   productList,
@@ -477,7 +554,6 @@
 import { modelList, productTreeList } from "@/api/basicData/product.js";
 import useFormData from "@/hooks/useFormData.js";
 import dayjs from "dayjs";
-import { getCurrentDate } from "@/utils/index.js";
 
 const userStore = useUserStore();
 const { proxy } = getCurrentInstance();
@@ -602,9 +678,62 @@
     shippingCarNumber: [
       { required: true, message: "璇疯緭鍏ュ彂璐ц溅鐗屽彿", trigger: "blur" }
     ],
+    approverId:[
+      {
+        required: true,message: "",
+      }
+    ]
   },
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
+
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+  title: "瀵煎叆閿�鍞彴璐�",
+  open: false,
+  url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
+  headers: { Authorization: "Bearer " + getToken() },
+  isUploading: false,
+  beforeUpload: (file) => {
+    const isExcel = file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+    const isLt10M = file.size / 1024 / 1024 < 10;
+    if (!isExcel) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+      return false;
+    }
+    if (!isLt10M) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+      return false;
+    }
+    return true;
+  },
+  onChange: (file, fileList) => {
+    console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+  },
+  onProgress: (event, file, fileList) => {
+    console.log('涓婁紶涓�...', event.percent);
+  },
+  onSuccess: (response, file, fileList) => {
+    console.log('涓婁紶鎴愬姛', response, file, fileList);
+    importUpload.isUploading = false;
+    if (response.code === 200) {
+      proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+      importUpload.open = false;
+      if (importUploadRef.value) {
+        importUploadRef.value.clearFiles();
+      }
+      getList();
+    } else {
+      proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+    }
+  },
+  onError: (error, file, fileList) => {
+    console.error('涓婁紶澶辫触', error, file, fileList);
+    importUpload.isUploading = false;
+    proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+  },
+});
 
 const changeDaterange = (value) => {
   if (value) {
@@ -629,7 +758,9 @@
   page.size = obj.limit;
   getList();
 };
-const getList = () => {
+const getList =async () => {
+  let userLists = await userListNoPage();
+  userList.value = userLists.data;
   tableLoading.value = true;
   const { entryDate, ...rest } = searchForm;
   ledgerListPage({ ...rest, ...page })
@@ -662,7 +793,6 @@
   });
 };
 const getProductModel = (value) => {
-  console.log("value", value);
   const index = modelOptions.value.findIndex((item) => item.id === value);
   if (index !== -1) {
     productForm.value.specificationModel = modelOptions.value[index].model;
@@ -687,6 +817,7 @@
   return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
 };
 function convertIdToValue(data) {
+  if (!data || !Array.isArray(data)) return [];
   return data.map((item) => {
     const { id, children, ...rest } = item;
     const newItem = {
@@ -710,23 +841,31 @@
   productSelectedRows.value = selectedRows;
 };
 const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
-  if (expandedRows.length > 0) {
+// 灞曞紑琛岋紙濮嬬粓鍙睍寮�涓�琛岋級
+const expandChange = (row) => {
+  const rowKey = row.id;
+  const isExpanded = expandedRowKeys.value.includes(rowKey);
+
+  if (isExpanded) {
+    // 褰撳墠琛屽凡灞曞紑 -> 鏀惰捣
     expandedRowKeys.value = [];
-    try {
-      productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
-        const index = tableData.value.findIndex((item) => item.id === row.id);
-        if (index > -1) {
-          tableData.value[index].children = res.data;
-        }
-        expandedRowKeys.value.push(row.id);
-      });
-    } catch (error) {
-      console.log(error);
-    }
-  } else {
-    expandedRowKeys.value = [];
+    return;
+  }
+
+  // 灞曞紑褰撳墠琛屽墠锛屽厛鏀惰捣鍏跺畠琛�
+  expandedRowKeys.value = [];
+
+  try {
+    productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
+      const index = tableData.value.findIndex((item) => item.id === row.id);
+      if (index > -1) {
+        tableData.value[index].children = res.data;
+      }
+      // 鍙繚鐣欏綋鍓嶈繖涓�琛屽浜庡睍寮�鐘舵��
+      expandedRowKeys.value = [rowKey];
+    });
+  } catch (error) {
+    console.log(error);
   }
 };
 // 涓昏〃鍚堣鏂规硶
@@ -750,8 +889,6 @@
   operationType.value = type;
   form.value = {};
   productData.value = [];
-  let userLists = await userListNoPage();
-  userList.value = userLists.data;
   customerList().then((res) => {
     customerOption.value = res;
   });
@@ -846,10 +983,16 @@
 
 const productIndex = ref(0);
 // 鎵撳紑浜у搧寮规
-const openProductForm = (type, row,index) => {
+const openProductForm =async (type, row,index) => {
   productOperationType.value = type;
   productForm.value = {};
   proxy.resetForm("productFormRef");
+  // 鏂板銆佺紪杈戦兘闇�鍏堝姞杞戒骇鍝佹爲锛屽惁鍒� el-tree-select 鏃犳暟鎹�
+  try {
+    await getProductOptions();
+  } catch (e) {
+    console.error("鍔犺浇浜у搧鏍戝け璐�", e);
+  }
   if (type === "edit") {
     productForm.value = { ...row };
     productIndex.value = index;
@@ -931,6 +1074,21 @@
   proxy.resetForm("productFormRef");
   productFormVisible.value = false;
 };
+// 瀵煎叆
+const handleImport = () => {
+  importUpload.title = "瀵煎叆閿�鍞彴璐�";
+  importUpload.open = true;
+  if (importUploadRef.value) {
+    importUploadRef.value.clearFiles();
+  }
+};
+
+// 鎻愪氦瀵煎叆鏂囦欢
+const submitImportFile = () => {
+  importUpload.isUploading = true;
+  proxy.$refs["importUploadRef"].submit();
+};
+
 // 瀵煎嚭
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -1296,6 +1454,15 @@
 	const seconds = String(date.getSeconds()).padStart(2, "0");
 	return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
 };
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+  const today = new Date();
+  const year = today.getFullYear();
+  const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+  const day = String(today.getDate()).padStart(2, "0");
+  return `${year}-${month}-${day}`;
+}
+
 // 璁$畻浜у搧鎬绘暟閲�
 const getTotalQuantity = (products) => {
   if (!products || products.length === 0) return '0';
@@ -1508,28 +1675,20 @@
  * @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
  */
 const fileListRef = ref(null)
-const fileListDialogVisible = ref(false)
 const downLoadFile = (row) => {
   getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
-    if (fileListRef.value) {
-      fileListRef.value.open(res.salesLedgerFiles)
-      fileListDialogVisible.value = true
-    }
+    fileListRef.value.open(res.salesLedgerFiles)
   });
 }
 
 // 鎵撳紑鍙戣揣寮规
 const openDeliveryForm = (row) => {
-  getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => {
-    currentDeliveryRow.value = row;
-    deliveryForm.value = {
-      shippingDate: getCurrentDate(),
-      shippingCarNumber: "",
-    };
-    deliveryFormVisible.value = true;
-  }).catch(err => {
-    ElMessage.error(err.msg);
-  });
+  currentDeliveryRow.value = row;
+  deliveryForm.value = {
+    shippingDate: "", // 绉婚櫎榛樿鍊艰缃�
+    shippingCarNumber: "",
+  };
+  deliveryFormVisible.value = true;
 };
 
 // 鎻愪氦鍙戣揣琛ㄥ崟
@@ -1537,7 +1696,9 @@
   proxy.$refs["deliveryFormRef"].validate((valid) => {
     if (valid) {
       addShippingInfo({
-        salesLedgerId: currentDeliveryRow.value.id,
+        approverId:deliveryForm.value.approverId,
+        salesLedgerId: currentDeliveryRow.value.salesLedgerId,
+        salesLedgerProductId: currentDeliveryRow.value.id,
         shippingDate: deliveryForm.value.shippingDate,
         shippingCarNumber: deliveryForm.value.shippingCarNumber,
       })
@@ -1545,6 +1706,7 @@
           proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
           closeDeliveryDia();
           getList();
+          expandedRowKeys.value = [];
         })
         .catch(() => {
           proxy.$modal.msgError("鍙戣揣澶辫触锛岃閲嶈瘯");
diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index cefc769..cbbc4f8 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -56,23 +56,23 @@
         <el-table-column prop="salesperson" label="涓氬姟鍛�" width="100" />
         <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="120" />
         <el-table-column prop="validDate" label="鏈夋晥鏈熻嚦" width="120" />
+        <el-table-column prop="status" label="瀹℃壒鐘舵��" width="120" align="center">
+          <template #default="{ row }">
+            <el-tag :type="getStatusType(row.status)" disable-transitions>
+              {{ row.status || '--' }}
+            </el-tag>
+          </template>
+        </el-table-column>
         <el-table-column prop="totalAmount" label="鎶ヤ环閲戦" width="120">
           <template #default="scope">
             楼{{ scope.row.totalAmount.toFixed(2) }}
           </template>
         </el-table-column>
-<!--        <el-table-column prop="status" label="鎶ヤ环鐘舵��" width="100">-->
-<!--          <template #default="scope">-->
-<!--            <el-tag :type="getStatusType(scope.row.status)">-->
-<!--              {{ scope.row.status }}-->
-<!--            </el-tag>-->
-<!--          </template>-->
-<!--        </el-table-column>-->
-        <el-table-column label="鎿嶄綔" width="250" fixed="right" align="center">
+        <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
           <template #default="scope">
             <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
-            <el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.status === '鑽夌'">缂栬緫</el-button>
-            <el-button link type="danger" @click="handleDelete(scope.row)" v-if="scope.row.status === '鑽夌'">鍒犻櫎</el-button>
+            <el-button link type="primary" @click="handleEdit(scope.row)" :disabled="!['寰呭鎵�','鎷掔粷'].includes(scope.row.status)">缂栬緫</el-button>
+            <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -88,94 +88,147 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="1300px" :close-on-click-modal="false">
-      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+    <FormDialog v-model="dialogVisible" :title="dialogTitle" width="85%" :close-on-click-modal="false" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
+      <div class="quotation-form-container">
+        <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="quotation-form">
         <!-- 鍩烘湰淇℃伅 -->
-        <el-card class="form-card" shadow="never">
+        <el-card class="form-card" shadow="hover">
           <template #header>
-            <span class="card-title">鍩烘湰淇℃伅</span>
+            <div class="card-header-wrapper">
+              <el-icon class="card-icon"><Document /></el-icon>
+              <span class="card-title">鍩烘湰淇℃伅</span>
+            </div>
           </template>
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
-                <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%" @change="handleCustomerChange">
-									<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
-										{{
-											item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
-										}}
-									</el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="涓氬姟鍛�" prop="salesperson">
-                <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%">
-									<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
-														 :value="item.nickName" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="鎶ヤ环鏃ユ湡" prop="quotationDate">
-                <el-date-picker
-                  v-model="form.quotationDate"
-                  type="date"
-                  placeholder="閫夋嫨鎶ヤ环鏃ユ湡"
-                  style="width: 100%"
-                  format="YYYY-MM-DD"
-                  value-format="YYYY-MM-DD"
-                />
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鏈夋晥鏈熻嚦" prop="validDate">
-                <el-date-picker
-                  v-model="form.validDate"
-                  type="date"
-                  placeholder="閫夋嫨鏈夋晥鏈�"
-                  style="width: 100%"
-                  format="YYYY-MM-DD"
-                  value-format="YYYY-MM-DD"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
-                <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%">
-                  <el-option label="鍏ㄦ鍒颁粯" value="鍏ㄦ鍒颁粯"></el-option>
-                  <el-option label="鍒嗘湡浠樻" value="鍒嗘湡浠樻"></el-option>
-                  <el-option label="鏈堢粨" value="鏈堢粨"></el-option>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="浜よ揣鏈�" prop="deliveryPeriod">
-                <el-date-picker
-                  v-model="form.deliveryPeriod"
-                  type="date"
-                  placeholder="閫夋嫨浜よ揣鏈�"
-                  style="width: 100%"
-                  format="YYYY-MM-DD"
-                  value-format="YYYY-MM-DD"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
+          <div class="form-content">
+            <el-row :gutter="24">
+              <el-col :span="12">
+                <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
+                  <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%" @change="handleCustomerChange" clearable>
+                    <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
+                      {{
+                        item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
+                      }}
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="涓氬姟鍛�" prop="salesperson">
+                  <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%" clearable>
+                    <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
+                      :value="item.nickName" />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="12">
+                <el-form-item label="鎶ヤ环鏃ユ湡" prop="quotationDate">
+                  <el-date-picker
+                    v-model="form.quotationDate"
+                    type="date"
+                    placeholder="閫夋嫨鎶ヤ环鏃ユ湡"
+                    style="width: 100%"
+                    format="YYYY-MM-DD"
+                    value-format="YYYY-MM-DD"
+                    clearable
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鏈夋晥鏈熻嚦" prop="validDate">
+                  <el-date-picker
+                    v-model="form.validDate"
+                    type="date"
+                    placeholder="閫夋嫨鏈夋晥鏈�"
+                    style="width: 100%"
+                    format="YYYY-MM-DD"
+                    value-format="YYYY-MM-DD"
+                    clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="12">
+                <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
+                  <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" clearable />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+        </el-card>
+
+        <!-- 瀹℃壒浜轰俊鎭� -->
+        <el-card class="form-card" shadow="hover">
+          <template #header>
+            <div class="card-header-wrapper">
+              <el-icon class="card-icon"><UserFilled /></el-icon>
+              <span class="card-title">瀹℃壒浜洪�夋嫨</span>
+              <el-button type="primary" size="small" @click="addApproverNode" class="header-btn">
+                <el-icon><Plus /></el-icon>
+                鏂板鑺傜偣
+              </el-button>
+            </div>
+          </template>
+          <div class="form-content">
+            <el-row>
+              <el-col :span="24">
+                <el-form-item>
+                  <div class="approver-nodes-container">
+                    <div
+                      v-for="(node, index) in approverNodes"
+                      :key="node.id"
+                      class="approver-node-item"
+                    >
+                      <div class="approver-node-label">
+                        <span class="node-step">{{ index + 1 }}</span>
+                        <span class="node-text">瀹℃壒浜�</span>
+                        <el-icon class="arrow-icon"><ArrowRight /></el-icon>
+                      </div>
+                      <el-select
+                        v-model="node.userId"
+                        placeholder="閫夋嫨浜哄憳"
+                        class="approver-select"
+                        clearable
+                      >
+                        <el-option
+                          v-for="user in userList"
+                          :key="user.userId"
+                          :label="user.nickName"
+                          :value="user.userId"
+                        />
+                      </el-select>
+                      <el-button
+                        type="danger"
+                        size="small"
+                        :icon="Delete"
+                        @click="removeApproverNode(index)"
+                        v-if="approverNodes.length > 1"
+                        class="remove-btn"
+                      >鍒犻櫎</el-button>
+                    </div>
+                  </div>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
         </el-card>
 
         <!-- 浜у搧淇℃伅 -->
-        <el-card class="form-card" shadow="never">
+        <el-card class="form-card" shadow="hover">
           <template #header>
-            <div class="card-header">
+            <div class="card-header-wrapper">
+              <el-icon class="card-icon"><Box /></el-icon>
               <span class="card-title">浜у搧淇℃伅</span>
-              <el-button type="primary" size="small" @click="addProduct">娣诲姞浜у搧</el-button>
+              <el-button type="primary" size="small" @click="addProduct" class="header-btn">
+                <el-icon><Plus /></el-icon>
+                娣诲姞浜у搧
+              </el-button>
             </div>
           </template>
-          <el-table :data="form.products" border style="width: 100%">
+          <div class="form-content">
+            <el-table :data="form.products" border style="width: 100%" class="product-table" v-if="form.products.length > 0">
             <el-table-column prop="product" label="浜у搧鍚嶇О" width="200">
               <template #default="scope">
 								<el-tree-select
@@ -207,11 +260,6 @@
 								</el-select>
               </template>
             </el-table-column>
-            <el-table-column prop="quantity" label="鏁伴噺">
-              <template #default="scope">
-                <el-input-number v-model="scope.row.quantity" :min="1" :precision="0" style="width: 100%" />
-              </template>
-            </el-table-column>
             <el-table-column prop="unit" label="鍗曚綅">
               <template #default="scope">
                 <el-input v-model="scope.row.unit" placeholder="鍗曚綅" />
@@ -219,12 +267,7 @@
             </el-table-column>
             <el-table-column prop="unitPrice" label="鍗曚环">
               <template #default="scope">
-                <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" @change="calculateAmount(scope.row)" />
-              </template>
-            </el-table-column>
-            <el-table-column prop="amount" label="閲戦" width="120">
-              <template #default="scope">
-                <span>楼{{ scope.row.amount.toFixed(2) }}</span>
+                <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" />
               </template>
             </el-table-column>
             <el-table-column label="鎿嶄綔" width="80" align="center">
@@ -233,66 +276,34 @@
               </template>
             </el-table-column>
           </el-table>
-        </el-card>
-
-        <!-- 璐圭敤淇℃伅 -->
-        <el-card class="form-card" shadow="never">
-          <template #header>
-            <span class="card-title">璐圭敤淇℃伅</span>
-          </template>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="浜у搧灏忚">
-                <el-input-number v-model="form.subtotal" :precision="2" :min="0" style="width: 100%" readonly />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="杩愯垂">
-                <el-input-number v-model="form.freight" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="鍏朵粬璐圭敤">
-                <el-input-number v-model="form.otherFee" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="鎶樻墸鐜�(%)">
-                <el-input-number v-model="form.discountRate" :precision="2" :min="0" :max="100" style="width: 100%" @change="calculateTotal" />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="鎶樻墸閲戦">
-                <el-input-number v-model="form.discountAmount" :precision="2" :min="0" style="width: 100%" readonly />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="鎶ヤ环鎬婚">
-                <el-input-number v-model="form.totalAmount" :precision="2" :min="0" style="width: 100%" readonly />
-              </el-form-item>
-            </el-col>
-          </el-row>
+          <el-empty v-else description="鏆傛棤浜у搧锛岃鐐瑰嚮娣诲姞浜у搧" :image-size="80" />
+          </div>
         </el-card>
 
         <!-- 澶囨敞淇℃伅 -->
-        <el-card class="form-card" shadow="never">
+        <el-card class="form-card" shadow="hover">
           <template #header>
-            <span class="card-title">澶囨敞淇℃伅</span>
+            <div class="card-header-wrapper">
+              <el-icon class="card-icon"><EditPen /></el-icon>
+              <span class="card-title">澶囨敞淇℃伅</span>
+            </div>
           </template>
-          <el-form-item label="澶囨敞" prop="remark">
-            <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
-          </el-form-item>
+          <div class="form-content">
+            <el-form-item label="澶囨敞" prop="remark">
+              <el-input 
+                type="textarea" 
+                v-model="form.remark" 
+                placeholder="璇疯緭鍏ュ娉ㄤ俊鎭紙閫夊~锛�" 
+                :rows="4"
+                maxlength="500"
+                show-word-limit
+              ></el-input>
+            </el-form-item>
+          </div>
         </el-card>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+      </div>
+    </FormDialog>
 
     <!-- 鏌ョ湅璇︽儏瀵硅瘽妗� -->
     <el-dialog v-model="viewDialogVisible" title="鎶ヤ环璇︽儏" width="800px">
@@ -303,7 +314,6 @@
         <el-descriptions-item label="鎶ヤ环鏃ユ湡">{{ currentQuotation.quotationDate }}</el-descriptions-item>
         <el-descriptions-item label="鏈夋晥鏈熻嚦">{{ currentQuotation.validDate }}</el-descriptions-item>
         <el-descriptions-item label="浠樻鏂瑰紡">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
-        <el-descriptions-item label="浜よ揣鏈�">{{ currentQuotation.deliveryPeriod }}</el-descriptions-item>
 <!--        <el-descriptions-item label="鎶ヤ环鐘舵��">-->
 <!--          <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>-->
 <!--        </el-descriptions-item>-->
@@ -317,16 +327,10 @@
         <el-table :data="currentQuotation.products" border style="width: 100%">
           <el-table-column prop="product" label="浜у搧鍚嶇О" />
           <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" />
-          <el-table-column prop="quantity" label="鏁伴噺" />
           <el-table-column prop="unit" label="鍗曚綅" />
           <el-table-column prop="unitPrice" label="鍗曚环">
             <template #default="scope">
               楼{{ scope.row.unitPrice.toFixed(2) }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="amount" label="閲戦">
-            <template #default="scope">
-              楼{{ scope.row.amount.toFixed(2) }}
             </template>
           </el-table-column>
         </el-table>
@@ -343,8 +347,9 @@
 <script setup>
 import { ref, reactive, computed, onMounted, markRaw, shallowRef } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { Search } from '@element-plus/icons-vue'
+import { Search, Document, UserFilled, Box, EditPen, Plus, ArrowRight, Delete } from '@element-plus/icons-vue'
 import Pagination from '@/components/PIMTable/Pagination.vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
 import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js'
 import {userListNoPage} from "@/api/system/user.js";
 import {customerList} from "@/api/salesManagement/salesLedger.js";
@@ -377,7 +382,6 @@
   quotationDate: '',
   validDate: '',
   paymentMethod: '',
-  deliveryPeriod: '',
   status: '鑽夌',
   remark: '',
   products: [],
@@ -394,16 +398,31 @@
   salesperson: [{ required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'change' }],
   quotationDate: [{ required: true, message: '璇烽�夋嫨鎶ヤ环鏃ユ湡', trigger: 'change' }],
   validDate: [{ required: true, message: '璇烽�夋嫨鏈夋晥鏈�', trigger: 'change' }],
-  paymentMethod: [{ required: true, message: '璇烽�夋嫨浠樻鏂瑰紡', trigger: 'change' }],
-  deliveryPeriod: [{ required: true, message: '璇烽�夋嫨浜よ揣鏈�', trigger: 'change' }]
+  paymentMethod: [{ required: true, message: '璇疯緭鍏ヤ粯娆炬柟寮�', trigger: 'blur' }]
 }
 const userList = ref([]);
 const customerOption = ref([]);
+
+// 瀹℃壒浜鸿妭鐐圭浉鍏�
+const approverNodes = ref([
+  { id: 1, userId: null }
+])
+let nextApproverId = 2
 
 const isEdit = ref(false)
 const editId = ref(null)
 const currentQuotation = ref({})
 const formRef = ref()
+
+// 娣诲姞瀹℃壒浜鸿妭鐐�
+function addApproverNode() {
+  approverNodes.value.push({ id: nextApproverId++, userId: null })
+}
+
+// 鍒犻櫎瀹℃壒浜鸿妭鐐�
+function removeApproverNode(index) {
+  approverNodes.value.splice(index, 1)
+}
 
 // 璁$畻灞炴��
 const filteredList = computed(() => {
@@ -423,10 +442,10 @@
 // 鏂规硶
 const getStatusType = (status) => {
   const statusMap = {
-    '鑽夌': 'info',
-    '宸插彂閫�': 'primary',
-    '瀹㈡埛纭': 'success',
-    '宸茶繃鏈�': 'danger'
+    '寰呭鎵�': 'info',
+    '瀹℃牳涓�': 'primary',
+    '閫氳繃': 'success',
+    '鎷掔粷': 'danger'
   }
   return statusMap[status] || 'info'
 }
@@ -441,6 +460,9 @@
   dialogTitle.value = '鏂板鎶ヤ环'
   isEdit.value = false
   resetForm()
+  // 閲嶇疆瀹℃壒浜鸿妭鐐�
+  approverNodes.value = [{ id: 1, userId: null }]
+  nextApproverId = 2
   dialogVisible.value = true
 	let userLists = await userListNoPage();
 	// 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
@@ -460,8 +482,10 @@
 	});
 }
 const getProductOptions = () => {
-	productTreeList().then((res) => {
+	// 杩斿洖 Promise锛屼究浜庣紪杈戞椂 await 纭繚鑳藉弽鏄�
+	return productTreeList().then((res) => {
 		productOptions.value = convertIdToValue(res);
+		return productOptions.value
 	});
 };
 function convertIdToValue(data) {
@@ -477,6 +501,19 @@
 		
 		return newItem;
 	});
+}
+// 鏍规嵁鍚嶇О鍙嶆煡鑺傜偣 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
+function findNodeIdByLabel(nodes, label) {
+	if (!label) return null;
+	for (let i = 0; i < nodes.length; i++) {
+		const node = nodes[i];
+		if (node.label === label) return node.value;
+		if (node.children && node.children.length > 0) {
+			const found = findNodeIdByLabel(node.children, label);
+			if (found !== null && found !== undefined) return found;
+		}
+	}
+	return null;
 }
 const getModels = (value, row) => {
 	if (!row) return;
@@ -545,7 +582,6 @@
     quotationDate: row.quotationDate || '',
     validDate: row.validDate || '',
     paymentMethod: row.paymentMethod || '',
-    deliveryPeriod: row.deliveryPeriod || '',
     status: row.status || '',
     remark: row.remark || '',
     products: row.products ? row.products.map(product => ({
@@ -563,10 +599,14 @@
   viewDialogVisible.value = true
 }
 
-const handleEdit = (row) => {
+const handleEdit = async (row) => {
   dialogTitle.value = '缂栬緫鎶ヤ环'
   isEdit.value = true
   editId.value = row.id
+  form.id = row.id || form.id || null
+  // 鍏堝姞杞戒骇鍝佹爲鏁版嵁锛屽惁鍒� el-tree-select 鏃犳硶鍙嶆樉浜у搧鍚嶇О
+  await getProductOptions()
+
   // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
   form.quotationNo = row.quotationNo || ''
   form.customer = row.customer || ''
@@ -574,25 +614,53 @@
   form.quotationDate = row.quotationDate || ''
   form.validDate = row.validDate || ''
   form.paymentMethod = row.paymentMethod || ''
-  form.deliveryPeriod = row.deliveryPeriod || ''
   form.status = row.status || '鑽夌'
   form.remark = row.remark || ''
-  form.products = row.products ? row.products.map(product => ({
-    productId: product.productId || '',
-    product: product.product || product.productName || '',
-    specificationId: product.specificationId || '',
-    specification: product.specification || '',
-    quantity: product.quantity || 0,
-    unit: product.unit || '',
-    unitPrice: product.unitPrice || 0,
-    amount: product.amount || 0
-  })) : []
+  form.products = row.products ? row.products.map(product => {
+    const productName = product.product || product.productName || ''
+    // 浼樺厛鐢� productId锛涘鏋滃彧鏈夊悕绉帮紝灏濊瘯鍙嶆煡 id 浠ヤ究鏍戦�夋嫨鍣ㄥ弽鏄�
+    const resolvedId = product.productId
+      ? Number(product.productId)
+      : findNodeIdByLabel(productOptions.value, productName) || ''
+    return {
+      productId: resolvedId,
+      product: productName,
+      specificationId: product.specificationId || '',
+      specification: product.specification || '',
+      quantity: product.quantity || 0,
+      unit: product.unit || '',
+      unitPrice: product.unitPrice || 0,
+      amount: product.amount || 0
+    }
+  }) : []
   form.subtotal = row.subtotal || 0
   form.freight = row.freight || 0
   form.otherFee = row.otherFee || 0
   form.discountRate = row.discountRate || 0
   form.discountAmount = row.discountAmount || 0
   form.totalAmount = row.totalAmount || 0
+  
+  // 鍙嶆樉瀹℃壒浜�
+  if (row.approveUserIds) {
+    const userIds = row.approveUserIds.split(',')
+    approverNodes.value = userIds.map((userId, idx) => ({
+      id: idx + 1,
+      userId: parseInt(userId.trim())
+    }))
+    nextApproverId = userIds.length + 1
+  } else {
+    approverNodes.value = [{ id: 1, userId: null }]
+    nextApproverId = 2
+  }
+  
+  // 鍔犺浇鐢ㄦ埛鍒楄〃
+  let userLists = await userListNoPage();
+  userList.value = (userLists.data || []).map(item => ({
+    userId: item.userId,
+    nickName: item.nickName || '',
+    userName: item.userName || ''
+  }));
+  
   dialogVisible.value = true
 }
 
@@ -625,7 +693,6 @@
   form.quotationDate = ''
   form.validDate = ''
   form.paymentMethod = ''
-  form.deliveryPeriod = ''
   form.status = '鑽夌'
   form.remark = ''
   form.products = []
@@ -683,6 +750,22 @@
         return
       }
       
+      // 瀹℃壒浜哄繀濉牎楠�
+      const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
+      if (hasEmptyApprover) {
+        ElMessage.error('璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒')
+        return
+      }
+      
+      // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
+      form.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
+      
+      // 璁$畻鎵�鏈変骇鍝佺殑鍗曚环鎬诲拰
+      form.totalAmount = form.products.reduce((sum, product) => {
+        const price = Number(product.unitPrice) || 0
+        return sum + price
+      }, 0)
+      
       if (isEdit.value) {
         // 缂栬緫
         const index = quotationList.value.findIndex(item => item.id === editId.value)
@@ -695,30 +778,16 @@
               handleSearch()
             }
           })
-          // quotationList.value[index] = { ...form, id: editId.value }
-          // ElMessage.success('缂栬緫鎴愬姛')
         }
       } else {
         // 鏂板
-        // const newId = Math.max(...quotationList.value.map(item => item.id)) + 1
-        form.quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}`
-
         addQuotation(form).then(res=>{
-          // console.log(res)
           if(res.code===200){
             ElMessage.success('鏂板鎴愬姛')
             dialogVisible.value = false
             handleSearch()
           }
         })
-
-        // quotationList.value.push({
-        //   ...form,
-        //   // id: newId,
-        //   quotationNo: quotationNo
-        // })
-        // pagination.total++
-        // ElMessage.success('鏂板鎴愬姛')
       }
       
     }
@@ -731,7 +800,7 @@
 }
 const handleSearch = ()=>{
   const params = {
-    page:pagination,
+    ...pagination,
     ...searchForm
   }
   getQuotationList(params).then(res=>{
@@ -746,8 +815,9 @@
         quotationDate: item.quotationDate || '',
         validDate: item.validDate || '',
         paymentMethod: item.paymentMethod || '',
-        deliveryPeriod: item.deliveryPeriod || '',
         status: item.status || '鑽夌',
+        // 瀹℃壒浜猴紙鐢ㄤ簬缂栬緫鏃跺弽鏄撅級
+        approveUserIds: item.approveUserIds || '',
         remark: item.remark || '',
         products: item.products ? item.products.map(product => ({
           productId: product.productId || '',
@@ -784,27 +854,182 @@
 })
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 .search-row {
   margin-bottom: 20px;
 }
 
+.quotation-form-container {
+  padding: 10px 0;
+  max-height: calc(100vh - 200px);
+  overflow-y: auto;
+  
+  &::-webkit-scrollbar {
+    width: 6px;
+    height: 6px;
+  }
+  
+  &::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 3px;
+    
+    &:hover {
+      background: #a8a8a8;
+    }
+  }
+}
+
+.quotation-form {
+  .el-form-item {
+    margin-bottom: 22px;
+  }
+}
+
 .form-card {
-  margin-bottom: 20px;
+  margin-bottom: 24px;
+  border-radius: 8px;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important;
+  }
+  
+  :deep(.el-card__header) {
+    padding: 16px 20px;
+    background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
+    border-bottom: 1px solid #ebeef5;
+  }
+  
+  :deep(.el-card__body) {
+    padding: 20px;
+  }
 }
 
-.card-title {
-  font-weight: bold;
-  color: #303133;
-}
-
-.card-header {
+.card-header-wrapper {
   display: flex;
-  justify-content: space-between;
   align-items: center;
+  gap: 8px;
+  
+  .card-icon {
+    font-size: 18px;
+    color: #409eff;
+  }
+  
+  .card-title {
+    font-weight: 600;
+    font-size: 16px;
+    color: #303133;
+    flex: 1;
+  }
+  
+  .header-btn {
+    margin-left: auto;
+  }
+}
+
+.form-content {
+  padding: 8px 0;
+}
+
+.approver-nodes-container {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 24px;
+  padding: 12px 0;
+}
+
+.approver-node-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 12px;
+  padding: 16px;
+  background: #f8f9fa;
+  border-radius: 8px;
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+  min-width: 180px;
+  
+  &:hover {
+    border-color: #409eff;
+    background: #f0f7ff;
+    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
+  }
+}
+
+.approver-node-label {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 14px;
+  color: #606266;
+  
+  .node-step {
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    width: 24px;
+    height: 24px;
+    background: #409eff;
+    color: #fff;
+    border-radius: 50%;
+    font-size: 12px;
+    font-weight: 600;
+  }
+  
+  .node-text {
+    font-weight: 500;
+  }
+  
+  .arrow-icon {
+    color: #909399;
+    font-size: 14px;
+  }
+}
+
+.approver-select {
+  width: 100%;
+  min-width: 150px;
+}
+
+.remove-btn {
+  margin-top: 4px;
+}
+
+.product-table {
+  :deep(.el-table__header) {
+    background-color: #f5f7fa;
+    
+    th {
+      background-color: #f5f7fa !important;
+      color: #606266;
+      font-weight: 600;
+    }
+  }
+  
+  :deep(.el-table__row) {
+    &:hover {
+      background-color: #f5f7fa;
+    }
+  }
+  
+  :deep(.el-table__cell) {
+    padding: 12px 0;
+  }
 }
 
 .dialog-footer {
   text-align: right;
 }
+
+// 鍝嶅簲寮忎紭鍖�
+@media (max-width: 1200px) {
+  .approver-nodes-container {
+    gap: 16px;
+  }
+  
+  .approver-node-item {
+    min-width: 160px;
+  }
+}
 </style>
diff --git a/src/views/salesManagement/salespersonManagement/index.vue b/src/views/salesManagement/salespersonManagement/index.vue
index e597538..e0094ec 100644
--- a/src/views/salesManagement/salespersonManagement/index.vue
+++ b/src/views/salesManagement/salespersonManagement/index.vue
@@ -86,7 +86,7 @@
     </el-card>
 
     <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+    <FormDialog v-model="dialogVisible" :title="dialogTitle" :width="'600px'" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -147,16 +147,10 @@
           </el-col>
         </el-row>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
 
     <!-- 鏉冮檺璁剧疆瀵硅瘽妗� -->
-    <el-dialog v-model="permissionDialogVisible" title="鏉冮檺璁剧疆" width="500px">
+    <FormDialog v-model="permissionDialogVisible" title="鏉冮檺璁剧疆" :width="'500px'" @close="permissionDialogVisible = false" @confirm="savePermissions" @cancel="permissionDialogVisible = false">
       <el-form label-width="100px">
         <el-form-item label="涓氬姟鍛樺鍚�">
           <span>{{ currentSalesperson.name }}</span>
@@ -172,13 +166,7 @@
           </el-checkbox-group>
         </el-form-item>
       </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="permissionDialogVisible = false">鍙� 娑�</el-button>
-          <el-button type="primary" @click="savePermissions">纭� 瀹�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
@@ -188,6 +176,7 @@
 import {listPage,add,update,deleteSalespersonManagement} from '@/api/salesManagement/salespersonManagement.js'
 import { Plus, Search } from '@element-plus/icons-vue'
 import Pagination from '@/components/PIMTable/Pagination.vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
 
 const salespersonList = ref([])
 const total = ref(0)
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
index f68bbec..a177314 100644
--- a/src/views/system/dept/index.vue
+++ b/src/views/system/dept/index.vue
@@ -1,148 +1,147 @@
 <template>
-   <div class="app-container">
-      <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
-         <el-form-item label="鍏徃鍚嶇О" prop="deptName">
-            <el-input
-               v-model="queryParams.deptName"
-               placeholder="璇疯緭鍏ュ叕鍙稿悕绉�"
-               clearable
-               style="width: 200px"
-               @keyup.enter="handleQuery"
-            />
-         </el-form-item>
-         <el-form-item label="鐘舵��" prop="status">
-            <el-select v-model="queryParams.status" placeholder="鍏徃鐘舵��" clearable style="width: 200px">
-               <el-option
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-               />
-            </el-select>
-         </el-form-item>
-         <el-form-item>
-            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-         </el-form-item>
-      </el-form>
-
-      <el-row :gutter="10" class="mb8">
-         <el-col :span="1.5">
-            <el-button
-               type="primary"
-               plain
-               icon="Plus"
-               @click="handleAdd"
-               v-hasPermi="['system:dept:add']"
-            >鏂板</el-button>
-         </el-col>
-         <el-col :span="1.5">
-            <el-button
-               type="info"
-               plain
-               icon="Sort"
-               @click="toggleExpandAll"
-            >灞曞紑/鎶樺彔</el-button>
-         </el-col>
-         <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-      </el-row>
-
-      <el-table
-         v-if="refreshTable"
-         v-loading="loading"
-         :data="deptList"
-         row-key="deptId"
-         :default-expand-all="isExpandAll"
-         :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-      >
-         <el-table-column prop="deptName" label="鍏徃鍚嶇О" width="260"></el-table-column>
-         <el-table-column prop="orderNum" label="鎺掑簭" width="200"></el-table-column>
-         <el-table-column prop="status" label="鐘舵��" width="100">
-            <template #default="scope">
-               <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-            </template>
-         </el-table-column>
-         <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200">
-            <template #default="scope">
-               <span>{{ parseTime(scope.row.createTime) }}</span>
-            </template>
-         </el-table-column>
-         <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-            <template #default="scope">
-               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']">淇敼</el-button>
-               <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">鏂板</el-button>
-               <el-button v-if="scope.row.parentId != 0" link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']">鍒犻櫎</el-button>
-            </template>
-         </el-table-column>
-      </el-table>
-
-      <!-- 娣诲姞鎴栦慨鏀瑰叕鍙稿璇濇 -->
-      <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-         <el-form ref="deptRef" :model="form" :rules="rules" label-width="80px">
-            <el-row>
-               <el-col :span="24" v-if="form.parentId !== 0">
-                  <el-form-item label="涓婄骇鍏徃" prop="parentId">
-                     <el-tree-select
-                        v-model="form.parentId"
-                        :data="deptOptions"
-                        :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
-                        value-key="deptId"
-                        placeholder="閫夋嫨涓婄骇鍏徃"
-                        check-strictly
-                     />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="鍏徃鍚嶇О" prop="deptName">
-                     <el-input v-model="form.deptName" placeholder="璇疯緭鍏ュ叕鍙稿悕绉�" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
-                     <el-input-number v-model="form.orderNum" controls-position="right" :min="0"/>
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="璐熻矗浜�" prop="leader">
-                     <el-input v-model="form.leader" placeholder="璇疯緭鍏ヨ礋璐d汉" maxlength="20" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
-                     <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" maxlength="11" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="閭" prop="email">
-                     <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="鍏徃鐘舵��">
-                     <el-radio-group v-model="form.status">
-                        <el-radio
-                           v-for="dict in sys_normal_disable"
-                           :key="dict.value"
-                           :value="dict.value"
-                        >{{ dict.label }}</el-radio>
-                     </el-radio-group>
-                  </el-form-item>
-               </el-col>
-              <el-col :span="12">
-                <el-form-item label="鍏徃缂栧彿" prop="deptNick">
-                  <el-input v-model="form.deptNick" placeholder="璇疯緭鍏ュ叕鍙哥紪鍙�" maxlength="50" />
-                </el-form-item>
-              </el-col>
-            </el-row>
-         </el-form>
-         <template #footer>
-            <div class="dialog-footer">
-               <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-               <el-button @click="cancel">鍙� 娑�</el-button>
-            </div>
-         </template>
-      </el-dialog>
-   </div>
+	<div class="app-container">
+		<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
+			<el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
+				<el-input
+					v-model="queryParams.deptName"
+					placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
+					clearable
+					style="width: 200px"
+					@keyup.enter="handleQuery"
+				/>
+			</el-form-item>
+			<el-form-item label="鐘舵��" prop="status">
+				<el-select v-model="queryParams.status" placeholder="閮ㄩ棬鐘舵��" clearable style="width: 200px">
+					<el-option
+						v-for="dict in sys_normal_disable"
+						:key="dict.value"
+						:label="dict.label"
+						:value="dict.value"
+					/>
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+				<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+			</el-form-item>
+		</el-form>
+		
+		<el-row :gutter="10" class="mb8">
+			<el-col :span="1.5">
+				<el-button
+					type="primary"
+					plain
+					icon="Plus"
+					@click="handleAdd"
+					v-hasPermi="['system:dept:add']"
+				>鏂板</el-button>
+			</el-col>
+			<el-col :span="1.5">
+				<el-button
+					type="info"
+					plain
+					icon="Sort"
+					@click="toggleExpandAll"
+				>灞曞紑/鎶樺彔</el-button>
+			</el-col>
+			<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+		</el-row>
+		<el-table
+			v-if="refreshTable"
+			v-loading="loading"
+			:data="deptList"
+			row-key="deptId"
+			:default-expand-all="isExpandAll"
+			:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+		>
+			<el-table-column prop="deptName" label="閮ㄩ棬鍚嶇О" width="260"></el-table-column>
+			<el-table-column prop="orderNum" label="鎺掑簭" width="200"></el-table-column>
+			<el-table-column prop="status" label="鐘舵��" width="100">
+				<template #default="scope">
+					<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+				</template>
+			</el-table-column>
+			<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200">
+				<template #default="scope">
+					<span>{{ parseTime(scope.row.createTime) }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+				<template #default="scope">
+					<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']">淇敼</el-button>
+					<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">鏂板</el-button>
+					<el-button v-if="scope.row.parentId != 0" link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']">鍒犻櫎</el-button>
+				</template>
+			</el-table-column>
+		</el-table>
+		
+		<!-- 娣诲姞鎴栦慨鏀归儴闂ㄥ璇濇 -->
+		<el-dialog :title="title" v-model="open" width="600px" append-to-body>
+			<el-form ref="deptRef" :model="form" :rules="rules" label-width="80px">
+				<el-row>
+					<el-col :span="24" v-if="form.parentId !== 0">
+						<el-form-item label="涓婄骇閮ㄩ棬" prop="parentId">
+							<el-tree-select
+								v-model="form.parentId"
+								:data="deptOptions"
+								:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
+								value-key="deptId"
+								placeholder="閫夋嫨涓婄骇閮ㄩ棬"
+								check-strictly
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
+							<el-input v-model="form.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
+							<el-input-number v-model="form.orderNum" controls-position="right" :min="0"/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="璐熻矗浜�" prop="leader">
+							<el-input v-model="form.leader" placeholder="璇疯緭鍏ヨ礋璐d汉" maxlength="20" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
+							<el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" maxlength="11" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="閭" prop="email">
+							<el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="閮ㄩ棬鐘舵��">
+							<el-radio-group v-model="form.status">
+								<el-radio
+									v-for="dict in sys_normal_disable"
+									:key="dict.value"
+									:value="dict.value"
+								>{{ dict.label }}</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="閮ㄩ棬缂栧彿" prop="deptNick">
+							<el-input v-model="form.deptNick" placeholder="璇疯緭鍏ラ儴闂ㄧ紪鍙�" maxlength="50" />
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+					<el-button @click="cancel">鍙� 娑�</el-button>
+				</div>
+			</template>
+		</el-dialog>
+	</div>
 </template>
 
 <script setup name="Dept">
@@ -161,129 +160,129 @@
 const refreshTable = ref(true)
 
 const data = reactive({
-  form: {},
-  queryParams: {
-    deptName: undefined,
-    status: undefined
-  },
-  rules: {
-    parentId: [{ required: true, message: "涓婄骇鍏徃涓嶈兘涓虹┖", trigger: "blur" }],
-    deptName: [{ required: true, message: "鍏徃鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-    orderNum: [{ required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }],
-    email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
-    phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }],
-    deptNick: [{ required: true, message: "鍏徃缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
-  },
+	form: {},
+	queryParams: {
+		deptName: undefined,
+		status: undefined
+	},
+	rules: {
+		parentId: [{ required: true, message: "涓婄骇閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" }],
+		deptName: [{ required: true, message: "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+		orderNum: [{ required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }],
+		email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
+		phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }],
+		deptNick: [{ required: true, message: "閮ㄩ棬缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
+	},
 })
 
 const { queryParams, form, rules } = toRefs(data)
 
-/** 鏌ヨ鍏徃鍒楄〃 */
+/** 鏌ヨ閮ㄩ棬鍒楄〃 */
 function getList() {
-  loading.value = true
-  listDept(queryParams.value).then(response => {
-    deptList.value = proxy.handleTree(response.data, "deptId")
-    loading.value = false
-  })
+	loading.value = true
+	listDept(queryParams.value).then(response => {
+		deptList.value = proxy.handleTree(response.data, "deptId")
+		loading.value = false
+	})
 }
 
 /** 鍙栨秷鎸夐挳 */
 function cancel() {
-  open.value = false
-  reset()
+	open.value = false
+	reset()
 }
 
 /** 琛ㄥ崟閲嶇疆 */
 function reset() {
-  form.value = {
-    deptId: undefined,
-    parentId: undefined,
-    deptName: undefined,
-    orderNum: 0,
-    leader: undefined,
-    phone: undefined,
-    email: undefined,
-    status: "0",
-    deptNick: undefined,
-  }
-  proxy.resetForm("deptRef")
+	form.value = {
+		deptId: undefined,
+		parentId: undefined,
+		deptName: undefined,
+		orderNum: 0,
+		leader: undefined,
+		phone: undefined,
+		email: undefined,
+		status: "0",
+		deptNick: undefined,
+	}
+	proxy.resetForm("deptRef")
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 function handleQuery() {
-  getList()
+	getList()
 }
 
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 function resetQuery() {
-  proxy.resetForm("queryRef")
-  handleQuery()
+	proxy.resetForm("queryRef")
+	handleQuery()
 }
 
 /** 鏂板鎸夐挳鎿嶄綔 */
 function handleAdd(row) {
-  reset()
-  listDept().then(response => {
-    deptOptions.value = proxy.handleTree(response.data, "deptId")
-  })
-  if (row != undefined) {
-    form.value.parentId = row.deptId
-  }
-  open.value = true
-  title.value = "娣诲姞鍏徃"
+	reset()
+	listDept().then(response => {
+		deptOptions.value = proxy.handleTree(response.data, "deptId")
+	})
+	if (row != undefined) {
+		form.value.parentId = row.deptId
+	}
+	open.value = true
+	title.value = "娣诲姞閮ㄩ棬"
 }
 
 /** 灞曞紑/鎶樺彔鎿嶄綔 */
 function toggleExpandAll() {
-  refreshTable.value = false
-  isExpandAll.value = !isExpandAll.value
-  nextTick(() => {
-    refreshTable.value = true
-  })
+	refreshTable.value = false
+	isExpandAll.value = !isExpandAll.value
+	nextTick(() => {
+		refreshTable.value = true
+	})
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 function handleUpdate(row) {
-  reset()
-  listDeptExcludeChild(row.deptId).then(response => {
-    deptOptions.value = proxy.handleTree(response.data, "deptId")
-  })
-  getDept(row.deptId).then(response => {
-    form.value = response.data
-    open.value = true
-    title.value = "淇敼鍏徃"
-  })
+	reset()
+	listDeptExcludeChild(row.deptId).then(response => {
+		deptOptions.value = proxy.handleTree(response.data, "deptId")
+	})
+	getDept(row.deptId).then(response => {
+		form.value = response.data
+		open.value = true
+		title.value = "淇敼閮ㄩ棬"
+	})
 }
 
 /** 鎻愪氦鎸夐挳 */
 function submitForm() {
-  proxy.$refs["deptRef"].validate(valid => {
-    if (valid) {
-      if (form.value.deptId != undefined) {
-        updateDept(form.value).then(response => {
-          proxy.$modal.msgSuccess("淇敼鎴愬姛")
-          open.value = false
-          getList()
-        })
-      } else {
-        addDept(form.value).then(response => {
-          proxy.$modal.msgSuccess("鏂板鎴愬姛")
-          open.value = false
-          getList()
-        })
-      }
-    }
-  })
+	proxy.$refs["deptRef"].validate(valid => {
+		if (valid) {
+			if (form.value.deptId != undefined) {
+				updateDept(form.value).then(response => {
+					proxy.$modal.msgSuccess("淇敼鎴愬姛")
+					open.value = false
+					getList()
+				})
+			} else {
+				addDept(form.value).then(response => {
+					proxy.$modal.msgSuccess("鏂板鎴愬姛")
+					open.value = false
+					getList()
+				})
+			}
+		}
+	})
 }
 
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 function handleDelete(row) {
-  proxy.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.deptName + '"鐨勬暟鎹」?').then(function() {
-    return delDept(row.deptId)
-  }).then(() => {
-    getList()
-    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
-  }).catch(() => {})
+	proxy.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.deptName + '"鐨勬暟鎹」?').then(function() {
+		return delDept(row.deptId)
+	}).then(() => {
+		getList()
+		proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
+	}).catch(() => {})
 }
 
 getList()
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 40fb371..f28463b 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -1,902 +1,546 @@
 <template>
-  <div class="app-container">
-    <el-row :gutter="20" style="height: calc(100vh - 8em)">
-      <splitpanes
-        :horizontal="appStore.device === 'mobile'"
-        class="default-theme"
-      >
-        <!--閮ㄩ棬鏁版嵁-->
-        <pane size="16">
-          <el-col style="padding: 10px">
-            <div class="head-container">
-              <el-input
-                v-model="deptName"
-                placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
-                clearable
-                prefix-icon="Search"
-                style="margin-bottom: 20px"
-              />
-            </div>
-            <div class="head-container">
-              <el-tree
-                :data="deptOptions"
-                :props="{ label: 'label', children: 'children' }"
-                :expand-on-click-node="false"
-                :filter-node-method="filterNode"
-                ref="deptTreeRef"
-                node-key="id"
-                highlight-current
-                default-expand-all
-                @node-click="handleNodeClick"
-              />
-            </div>
-          </el-col>
-        </pane>
-        <!--鐢ㄦ埛鏁版嵁-->
-        <pane size="84">
-          <el-col style="padding: 10px">
-            <el-form
-              :model="queryParams"
-              ref="queryRef"
-              :inline="true"
-              v-show="showSearch"
-              label-width="68px"
-            >
-              <el-form-item label="鐧诲綍璐﹀彿" prop="userName">
-                <el-input
-                  v-model="queryParams.userName"
-                  placeholder="璇疯緭鍏ョ櫥褰曡处鍙�"
-                  clearable
-                  style="width: 240px"
-                  @keyup.enter="handleQuery"
-                />
-              </el-form-item>
-              <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-                <el-input
-                  v-model="queryParams.phonenumber"
-                  placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�"
-                  clearable
-                  style="width: 240px"
-                  @keyup.enter="handleQuery"
-                />
-              </el-form-item>
-              <el-form-item label="鐘舵��" prop="status">
-                <el-select
-                  v-model="queryParams.status"
-                  placeholder="鐢ㄦ埛鐘舵��"
-                  clearable
-                  style="width: 240px"
-                >
-                  <el-option
-                    v-for="dict in sys_normal_disable"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                  />
-                </el-select>
-              </el-form-item>
-              <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
-                <el-date-picker
-                  v-model="dateRange"
-                  value-format="YYYY-MM-DD"
-                  type="daterange"
-                  range-separator="-"
-                  start-placeholder="寮�濮嬫棩鏈�"
-                  end-placeholder="缁撴潫鏃ユ湡"
-                ></el-date-picker>
-              </el-form-item>
-              <el-form-item>
-                <el-button type="primary" icon="Search" @click="handleQuery"
-                  >鎼滅储</el-button
-                >
-                <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-              </el-form-item>
-            </el-form>
-
-            <el-row :gutter="10" class="mb8">
-              <el-col :span="1.5">
-                <el-button
-                  type="primary"
-                  plain
-                  icon="Plus"
-                  @click="handleAdd"
-                  v-hasPermi="['system:user:add']"
-                  >鏂板</el-button
-                >
-              </el-col>
-              <el-col :span="1.5">
-                <el-button
-                  type="success"
-                  plain
-                  icon="Edit"
-                  :disabled="single"
-                  @click="handleUpdate"
-                  v-hasPermi="['system:user:edit']"
-                  >淇敼</el-button
-                >
-              </el-col>
-              <el-col :span="1.5">
-                <el-button
-                  type="danger"
-                  plain
-                  icon="Delete"
-                  :disabled="multiple"
-                  @click="handleDelete"
-                  v-hasPermi="['system:user:remove']"
-                  >鍒犻櫎</el-button
-                >
-              </el-col>
-              <el-col :span="1.5">
-                <el-button
-                  type="info"
-                  plain
-                  icon="Upload"
-                  @click="handleImport"
-                  v-hasPermi="['system:user:import']"
-                  >瀵煎叆</el-button
-                >
-              </el-col>
-              <el-col :span="1.5">
-                <el-button
-                  type="warning"
-                  plain
-                  icon="Download"
-                  @click="handleExport"
-                  v-hasPermi="['system:user:export']"
-                  >瀵煎嚭</el-button
-                >
-              </el-col>
-              <right-toolbar
-                v-model:showSearch="showSearch"
-                @queryTable="getList"
-                :columns="columns"
-              ></right-toolbar>
-            </el-row>
-
-            <el-table
-              v-loading="loading"
-              :data="userList"
-              @selection-change="handleSelectionChange"
-            >
-              <el-table-column type="selection" width="50" align="center" />
-              <el-table-column
-                label="鐢ㄦ埛缂栧彿"
-                align="center"
-                key="userId"
-                prop="userId"
-                v-if="columns[0].visible"
-              />
-              <el-table-column
-                label="鐧诲綍璐﹀彿"
-                align="center"
-                key="userName"
-                prop="userName"
-                v-if="columns[1].visible"
-                :show-overflow-tooltip="true"
-              />
-              <el-table-column
-                label="鐢ㄦ埛鏄电О"
-                align="center"
-                key="nickName"
-                prop="nickName"
-                v-if="columns[2].visible"
-                :show-overflow-tooltip="true"
-              />
-              <el-table-column
-                label="閮ㄩ棬"
-                align="center"
-                key="deptNames"
-                prop="deptNames"
-                v-if="columns[3].visible"
-                :show-overflow-tooltip="true"
-              />
-              <el-table-column
-                label="鎵嬫満鍙风爜"
-                align="center"
-                key="phonenumber"
-                prop="phonenumber"
-                v-if="columns[4].visible"
-                width="120"
-              />
-              <el-table-column
-                label="鐘舵��"
-                align="center"
-                key="status"
-                v-if="columns[5].visible"
-              >
-                <template #default="scope">
-                  <el-switch
-                    v-model="scope.row.status"
-                    active-value="0"
-                    inactive-value="1"
-                    @change="handleStatusChange(scope.row)"
-                  ></el-switch>
-                </template>
-              </el-table-column>
-              <el-table-column
-                label="鍒涘缓鏃堕棿"
-                align="center"
-                prop="createTime"
-                v-if="columns[6].visible"
-                width="160"
-              >
-                <template #default="scope">
-                  <span>{{ parseTime(scope.row.createTime) }}</span>
-                </template>
-              </el-table-column>
-              <el-table-column
-                label="鎿嶄綔"
-                align="center"
-                width="150"
-                class-name="small-padding fixed-width"
-              >
-                <template #default="scope">
-                  <el-tooltip
-                    content="淇敼"
-                    placement="top"
-                    v-if="scope.row.userId !== 1"
-                  >
-                    <el-button
-                      link
-                      type="primary"
-                      icon="Edit"
-                      @click="handleUpdate(scope.row)"
-                      v-hasPermi="['system:user:edit']"
-                    ></el-button>
-                  </el-tooltip>
-                  <el-tooltip
-                    content="鍒犻櫎"
-                    placement="top"
-                    v-if="scope.row.userId !== 1"
-                  >
-                    <el-button
-                      link
-                      type="primary"
-                      icon="Delete"
-                      @click="handleDelete(scope.row)"
-                      v-hasPermi="['system:user:remove']"
-                    ></el-button>
-                  </el-tooltip>
-                  <el-tooltip
-                    content="閲嶇疆瀵嗙爜"
-                    placement="top"
-                    v-if="scope.row.userId !== 1"
-                  >
-                    <el-button
-                      link
-                      type="primary"
-                      icon="Key"
-                      @click="handleResetPwd(scope.row)"
-                      v-hasPermi="['system:user:resetPwd']"
-                    ></el-button>
-                  </el-tooltip>
-                  <el-tooltip
-                    content="鍒嗛厤瑙掕壊"
-                    placement="top"
-                    v-if="scope.row.userId !== 1"
-                  >
-                    <el-button
-                      link
-                      type="primary"
-                      icon="CircleCheck"
-                      @click="handleAuthRole(scope.row)"
-                      v-hasPermi="['system:user:edit']"
-                    ></el-button>
-                  </el-tooltip>
-                </template>
-              </el-table-column>
-            </el-table>
-            <pagination
-              v-show="total > 0"
-              :total="total"
-              v-model:page="queryParams.pageNum"
-              v-model:limit="queryParams.pageSize"
-              @pagination="getList"
-            />
-          </el-col>
-        </pane>
-      </splitpanes>
-    </el-row>
-
-    <!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-              <el-input
-                v-model="form.nickName"
-                placeholder="璇疯緭鍏ョ敤鎴锋樀绉�"
-                maxlength="30"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="褰掑睘鍏徃" prop="deptIds">
-              <el-tree-select
-                v-model="form.deptIds"
-                :data="enabledDeptOptions"
-                :render-after-expand="false"
-                show-checkbox
-                multiple
-                placeholder="璇烽�夋嫨褰掑睘鍏徃"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-              <el-input
-                v-model="form.phonenumber"
-                placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�"
-                maxlength="11"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="閭" prop="email">
-              <el-input
-                v-model="form.email"
-                placeholder="璇疯緭鍏ラ偖绠�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item
-              v-if="form.userId == undefined"
-              label="鐧诲綍璐﹀彿"
-              prop="userName"
-            >
-              <el-input
-                v-model="form.userName"
-                placeholder="璇疯緭鍏ョ櫥褰曡处鍙�"
-                maxlength="30"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item
-              v-if="form.userId == undefined"
-              label="鐢ㄦ埛瀵嗙爜"
-              prop="password"
-            >
-              <el-input
-                v-model="form.password"
-                placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�"
-                type="password"
-                maxlength="20"
-                show-password
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鐢ㄦ埛鎬у埆">
-              <el-select v-model="form.sex" placeholder="璇烽�夋嫨">
-                <el-option
-                  v-for="dict in sys_user_sex"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="宀椾綅">
-              <el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨">
-                <el-option
-                  v-for="item in postOptions"
-                  :key="item.postId"
-                  :label="item.postName"
-                  :value="item.postId"
-                  :disabled="item.status == 1"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="瑙掕壊" prop="roleIds">
-              <el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨">
-                <el-option
-                  v-for="item in roleOptions"
-                  :key="item.roleId"
-                  :label="item.roleName"
-                  :value="item.roleId"
-                  :disabled="item.status == 1"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-          <el-button @click="cancel">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
-
-    <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
-    <el-dialog
-      :title="upload.title"
-      v-model="upload.open"
-      width="400px"
-      append-to-body
-    >
-      <el-upload
-        ref="uploadRef"
-        :limit="1"
-        accept=".xlsx, .xls"
-        :headers="upload.headers"
-        :action="upload.url + '?updateSupport=' + upload.updateSupport"
-        :disabled="upload.isUploading"
-        :on-progress="handleFileUploadProgress"
-        :on-success="handleFileSuccess"
-        :auto-upload="false"
-        drag
-      >
-        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
-        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
-        <template #tip>
-          <div class="el-upload__tip text-center">
-            <div class="el-upload__tip">
-              <el-checkbox
-                v-model="upload.updateSupport"
-              />鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
-            </div>
-            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
-            <el-link
-              type="primary"
-              :underline="false"
-              style="font-size: 12px; vertical-align: baseline"
-              @click="importTemplate"
-              >涓嬭浇妯℃澘</el-link
-            >
-          </div>
-        </template>
-      </el-upload>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
-          <el-button @click="upload.open = false">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
+	<div class="app-container">
+		<el-row :gutter="20" style="height: calc(100vh - 8em)">
+			<splitpanes :horizontal="appStore.device === 'mobile'" class="default-theme">
+				<!--閮ㄩ棬鏁版嵁-->
+				<pane size="16">
+					<el-col style="padding: 10px">
+						<div class="head-container">
+							<el-input v-model="deptNames" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" clearable prefix-icon="Search" style="margin-bottom: 20px" />
+						</div>
+						<div class="head-container">
+							<el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false" :filter-node-method="filterNode" ref="deptTreeRef" node-key="id" highlight-current default-expand-all @node-click="handleNodeClick" />
+						</div>
+					</el-col>
+				</pane>
+				<!--鐢ㄦ埛鏁版嵁-->
+				<pane size="84">
+					<el-col style="padding: 10px">
+						<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+							<el-form-item label="鐧诲綍璐﹀彿" prop="userName">
+								<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ櫥褰曡处鍙�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+							</el-form-item>
+							<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+								<el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+							</el-form-item>
+							<el-form-item label="鐘舵��" prop="status">
+								<el-select v-model="queryParams.status" placeholder="鐢ㄦ埛鐘舵��" clearable style="width: 240px">
+									<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+								</el-select>
+							</el-form-item>
+							<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
+								<el-date-picker v-model="dateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡"></el-date-picker>
+							</el-form-item>
+							<el-form-item>
+								<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+								<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+							</el-form-item>
+						</el-form>
+						
+						<el-row :gutter="10" class="mb8">
+							<el-col :span="1.5">
+								<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']">鏂板</el-button>
+							</el-col>
+							<el-col :span="1.5">
+								<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">淇敼</el-button>
+							</el-col>
+							<el-col :span="1.5">
+								<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">鍒犻櫎</el-button>
+							</el-col>
+							<el-col :span="1.5">
+								<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']">瀵煎叆</el-button>
+							</el-col>
+							<el-col :span="1.5">
+								<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">瀵煎嚭</el-button>
+							</el-col>
+							<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+						</el-row>
+						
+						<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+							<el-table-column type="selection" width="50" align="center" />
+							<el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
+							<el-table-column label="鐧诲綍璐﹀彿" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+							<el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+							<el-table-column label="閮ㄩ棬" align="center" key="deptNames" prop="deptNames" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+							<el-table-column label="鎵嬫満鍙风爜" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
+							<el-table-column label="鐘舵��" align="center" key="status" v-if="columns[5].visible">
+								<template #default="scope">
+									<el-switch
+										v-model="scope.row.status"
+										active-value="0"
+										inactive-value="1"
+										@change="handleStatusChange(scope.row)"
+									></el-switch>
+								</template>
+							</el-table-column>
+							<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[6].visible" width="160">
+								<template #default="scope">
+									<span>{{ parseTime(scope.row.createTime) }}</span>
+								</template>
+							</el-table-column>
+							<el-table-column label="鎿嶄綔" align="center" width="150" class-name="small-padding fixed-width">
+								<template #default="scope">
+									<el-tooltip content="淇敼" placement="top" v-if="scope.row.userId !== 1">
+										<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
+									</el-tooltip>
+									<el-tooltip content="鍒犻櫎" placement="top" v-if="scope.row.userId !== 1">
+										<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']"></el-button>
+									</el-tooltip>
+									<el-tooltip content="閲嶇疆瀵嗙爜" placement="top" v-if="scope.row.userId !== 1">
+										<el-button link type="primary" icon="Key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:user:resetPwd']"></el-button>
+									</el-tooltip>
+									<el-tooltip content="鍒嗛厤瑙掕壊" placement="top" v-if="scope.row.userId !== 1">
+										<el-button link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
+									</el-tooltip>
+								</template>
+							</el-table-column>
+						</el-table>
+						<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+					</el-col>
+				</pane>
+			</splitpanes>
+		</el-row>
+		
+		<!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 -->
+		<el-dialog :title="title" v-model="open" width="600px" append-to-body>
+			<el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
+				<el-row>
+					<el-col :span="12">
+						<el-form-item v-if="form.userId == undefined" label="鐧诲綍璐﹀彿" prop="userName">
+							<el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" maxlength="30" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password">
+							<el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" maxlength="20" show-password />
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="12">
+						<el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
+							<el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" maxlength="30" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
+							<el-tree-select v-model="form.deptId" :data="enabledDeptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬" check-strictly />
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="12">
+						<el-form-item label="宀椾綅" prop="postIds">
+							<el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨">
+								<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="瑙掕壊" prop="roleIds">
+							<el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨">
+								<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="12">
+						<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+							<el-input v-model="form.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" maxlength="11" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="閭" prop="email">
+							<el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="12">
+						<el-form-item label="鐢ㄦ埛鎬у埆">
+							<el-select v-model="form.sex" placeholder="璇烽�夋嫨">
+								<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鐘舵��">
+							<el-radio-group v-model="form.status">
+								<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="24">
+						<el-form-item label="澶囨敞">
+							<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+					<el-button @click="cancel">鍙� 娑�</el-button>
+				</div>
+			</template>
+		</el-dialog>
+		
+		<!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
+		<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+			<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
+				<el-icon class="el-icon--upload"><upload-filled /></el-icon>
+				<div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+				<template #tip>
+					<div class="el-upload__tip text-center">
+						<div class="el-upload__tip">
+							<el-checkbox v-model="upload.updateSupport" />鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+						</div>
+						<span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+						<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">涓嬭浇妯℃澘</el-link>
+					</div>
+				</template>
+			</el-upload>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+					<el-button @click="upload.open = false">鍙� 娑�</el-button>
+				</div>
+			</template>
+		</el-dialog>
+	</div>
 </template>
 
 <script setup name="User">
-import { getToken } from "@/utils/auth";
-import useAppStore from "@/store/modules/app";
-import {
-  changeUserStatus,
-  listUser,
-  resetUserPwd,
-  delUser,
-  getUser,
-  updateUser,
-  addUser,
-  deptTreeSelect,
-} from "@/api/system/user";
-import { Splitpanes, Pane } from "splitpanes";
-import "splitpanes/dist/splitpanes.css";
-import {onMounted} from "vue";
+import { getToken } from "@/utils/auth"
+import useAppStore from '@/store/modules/app'
+import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user"
+import { Splitpanes, Pane } from "splitpanes"
+import "splitpanes/dist/splitpanes.css"
 
-const router = useRouter();
-const appStore = useAppStore();
-const { proxy } = getCurrentInstance();
-const { sys_normal_disable, sys_user_sex } = proxy.useDict(
-  "sys_normal_disable",
-  "sys_user_sex"
-);
+const router = useRouter()
+const appStore = useAppStore()
+const { proxy } = getCurrentInstance()
+const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable", "sys_user_sex")
 
-const userList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-const dateRange = ref([]);
-const deptName = ref("");
-const deptOptions = ref(undefined);
-const enabledDeptOptions = ref(undefined);
-const initPassword = ref(undefined);
-const postOptions = ref([]);
-const roleOptions = ref([]);
+const userList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+const dateRange = ref([])
+const deptNames = ref("")
+const deptOptions = ref(undefined)
+const enabledDeptOptions = ref(undefined)
+const initPassword = ref(undefined)
+const postOptions = ref([])
+const roleOptions = ref([])
 /*** 鐢ㄦ埛瀵煎叆鍙傛暟 */
 const upload = reactive({
-  // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
-  open: false,
-  // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
-  title: "",
-  // 鏄惁绂佺敤涓婁紶
-  isUploading: false,
-  // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
-  updateSupport: 0,
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-  headers: { Authorization: "Bearer " + getToken() },
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData",
-});
+	// 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
+	open: false,
+	// 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
+	title: "",
+	// 鏄惁绂佺敤涓婁紶
+	isUploading: false,
+	// 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+	updateSupport: 0,
+	// 璁剧疆涓婁紶鐨勮姹傚ご閮�
+	headers: { Authorization: "Bearer " + getToken() },
+	// 涓婁紶鐨勫湴鍧�
+	url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData"
+})
 // 鍒楁樉闅愪俊鎭�
 const columns = ref([
-  { key: 0, label: `鐢ㄦ埛缂栧彿`, visible: true },
-  { key: 1, label: `鐧诲綍璐﹀彿`, visible: true },
-  { key: 2, label: `鐢ㄦ埛鏄电О`, visible: true },
-  { key: 3, label: `閮ㄩ棬`, visible: true },
-  { key: 4, label: `鎵嬫満鍙风爜`, visible: true },
-  { key: 5, label: `鐘舵�乣, visible: true },
-  { key: 6, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
+	{ key: 0, label: `鐢ㄦ埛缂栧彿`, visible: true },
+	{ key: 1, label: `鐧诲綍璐﹀彿`, visible: true },
+	{ key: 2, label: `鐢ㄦ埛鏄电О`, visible: true },
+	{ key: 3, label: `閮ㄩ棬`, visible: true },
+	{ key: 4, label: `鎵嬫満鍙风爜`, visible: true },
+	{ key: 5, label: `鐘舵�乣, visible: true },
+	{ key: 6, label: `鍒涘缓鏃堕棿`, visible: true }
+])
 
 const data = reactive({
-  form: {},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    userName: undefined,
-    phonenumber: undefined,
-    status: undefined,
-    deptId: undefined,
-  },
-  rules: {
-    userName: [
-      { required: true, message: "鐧诲綍璐﹀彿涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 2,
-        max: 20,
-        message: "鐧诲綍璐﹀彿闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿",
-        trigger: "blur",
-      },
-    ],
-    nickName: [
-      { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    deptIds: [{ required: true, message: "鍏徃涓嶈兘涓虹┖", trigger: "change" }],
-		roleIds: [{ required: true, message: "瑙掕壊涓嶈兘涓虹┖", trigger: "change" }],
-    password: [
-      { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 5,
-        max: 20,
-        message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
-        trigger: "blur",
-      },
-      {
-        pattern: /^[^<>"'|\\]+$/,
-        message: "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |",
-        trigger: "blur",
-      },
-    ],
-    email: [
-      {
-        type: "email",
-        message: "璇疯緭鍏ユ纭殑閭鍦板潃",
-        trigger: ["blur", "change"],
-      },
-    ],
-    phonenumber: [
-      {
-        pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
-        message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜",
-        trigger: "blur",
-      },
-    ],
-  },
-});
+	form: {},
+	queryParams: {
+		pageNum: 1,
+		pageSize: 10,
+		userName: undefined,
+		phonenumber: undefined,
+		status: undefined,
+		deptId: undefined
+	},
+	rules: {
+		userName: [{ required: true, message: "鐢ㄦ埛鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }, { min: 2, max: 20, message: "鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿", trigger: "blur" }],
+		nickName: [{ required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }],
+		password: [{ required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, { min: 5, max: 20, message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |", trigger: "blur" }],
+		email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
+		phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }],
+		deptId: [{ required: true, message: "褰掑睘閮ㄩ棬涓嶈兘涓虹┖", trigger: "change" }],
+		postIds: [{ required: true, message: "宀椾綅涓嶈兘涓虹┖", trigger: "change" }],
+		roleIds: [{ required: true, message: "瑙掕壊涓嶈兘涓虹┖", trigger: "change" }]
+	}
+})
 
-const { queryParams, form, rules } = toRefs(data);
+const { queryParams, form, rules } = toRefs(data)
 
 /** 閫氳繃鏉′欢杩囨护鑺傜偣  */
 const filterNode = (value, data) => {
-  if (!value) return true;
-  return data.label.indexOf(value) !== -1;
-};
+	if (!value) return true
+	return data.label.indexOf(value) !== -1
+}
 
 /** 鏍规嵁鍚嶇О绛涢�夐儴闂ㄦ爲 */
-watch(deptName, (val) => {
-  proxy.$refs["deptTreeRef"].filter(val);
-});
+watch(deptNames, val => {
+	proxy.$refs["deptTreeRef"].filter(val)
+})
 
 /** 鏌ヨ鐢ㄦ埛鍒楄〃 */
 function getList() {
-  loading.value = true;
-  listUser(proxy.addDateRange(queryParams.value, dateRange.value)).then(
-    (res) => {
-      loading.value = false;
-      userList.value = res.rows;
-      total.value = res.total;
-    }
-  );
+	loading.value = true
+	listUser(proxy.addDateRange(queryParams.value, dateRange.value)).then(res => {
+		loading.value = false
+		userList.value = res.rows
+		total.value = res.total
+	})
 }
 
 /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */
 function getDeptTree() {
-  deptTreeSelect().then((response) => {
-    deptOptions.value = response.data;
-    enabledDeptOptions.value = filterDisabledDept(
-      JSON.parse(JSON.stringify(response.data))
-    );
-  });
+	deptTreeSelect().then(response => {
+		deptOptions.value = response.data
+		enabledDeptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
+	})
 }
 
 /** 杩囨护绂佺敤鐨勯儴闂� */
 function filterDisabledDept(deptList) {
-  return deptList.filter((dept) => {
-    if (dept.disabled) {
-      return false;
-    }
-    if (dept.children && dept.children.length) {
-      dept.children = filterDisabledDept(dept.children);
-    }
-    return true;
-  });
+	return deptList.filter(dept => {
+		if (dept.disabled) {
+			return false
+		}
+		if (dept.children && dept.children.length) {
+			dept.children = filterDisabledDept(dept.children)
+		}
+		return true
+	})
 }
 
 /** 鑺傜偣鍗曞嚮浜嬩欢 */
 function handleNodeClick(data) {
-  queryParams.value.deptId = data.id;
-  handleQuery();
+	queryParams.value.deptId = data.id
+	handleQuery()
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
+	queryParams.value.pageNum = 1
+	getList()
 }
 
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 function resetQuery() {
-  dateRange.value = [];
-  proxy.resetForm("queryRef");
-  queryParams.value.deptId = undefined;
-  proxy.$refs.deptTreeRef.setCurrentKey(null);
-  handleQuery();
+	dateRange.value = []
+	proxy.resetForm("queryRef")
+	queryParams.value.deptId = undefined
+	proxy.$refs.deptTreeRef.setCurrentKey(null)
+	handleQuery()
 }
 
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 function handleDelete(row) {
-  const userIds = row.userId || ids.value;
-  proxy.$modal
-    .confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」锛�')
-    .then(function () {
-      return delUser(userIds);
-    })
-    .then(() => {
-      getList();
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-    })
-    .catch(() => {});
+	const userIds = row.userId || ids.value
+	proxy.$modal.confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」锛�').then(function () {
+		return delUser(userIds)
+	}).then(() => {
+		getList()
+		proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
+	}).catch(() => {})
 }
 
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 function handleExport() {
-  proxy.download(
-    "system/user/export",
-    {
-      ...queryParams.value,
-    },
-    `user_${new Date().getTime()}.xlsx`
-  );
+	proxy.download("system/user/export", {
+		...queryParams.value,
+	},`user_${new Date().getTime()}.xlsx`)
 }
 
 /** 鐢ㄦ埛鐘舵�佷慨鏀�  */
 function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  proxy.$modal
-    .confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚�?')
-    .then(function () {
-      return changeUserStatus(row.userId, row.status);
-    })
-    .then(() => {
-      proxy.$modal.msgSuccess(text + "鎴愬姛");
-    })
-    .catch(function () {
-      row.status = row.status === "0" ? "1" : "0";
-    });
+	let text = row.status === "0" ? "鍚敤" : "鍋滅敤"
+	proxy.$modal.confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚�?').then(function () {
+		return changeUserStatus(row.userId, row.status)
+	}).then(() => {
+		proxy.$modal.msgSuccess(text + "鎴愬姛")
+	}).catch(function () {
+		row.status = row.status === "0" ? "1" : "0"
+	})
 }
 
 /** 鏇村鎿嶄綔 */
 function handleCommand(command, row) {
-  switch (command) {
-    case "handleResetPwd":
-      handleResetPwd(row);
-      break;
-    case "handleAuthRole":
-      handleAuthRole(row);
-      break;
-    default:
-      break;
-  }
+	switch (command) {
+		case "handleResetPwd":
+			handleResetPwd(row)
+			break
+		case "handleAuthRole":
+			handleAuthRole(row)
+			break
+		default:
+			break
+	}
 }
 
 /** 璺宠浆瑙掕壊鍒嗛厤 */
 function handleAuthRole(row) {
-  const userId = row.userId;
-  router.push("/system/user-auth/role/" + userId);
+	const userId = row.userId
+	router.push("/system/user-auth/role/" + userId)
 }
 
 /** 閲嶇疆瀵嗙爜鎸夐挳鎿嶄綔 */
 function handleResetPwd(row) {
-  proxy
-    .$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
-      confirmButtonText: "纭畾",
-      cancelButtonText: "鍙栨秷",
-      closeOnClickModal: false,
-      inputPattern: /^.{5,20}$/,
-      inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
-      inputValidator: (value) => {
-        if (/<|>|"|'|\||\\/.test(value)) {
-          return "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |";
-        }
-      },
-    })
-    .then(({ value }) => {
-      resetUserPwd(row.userId, value).then((response) => {
-        proxy.$modal.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + value);
-      });
-    })
-    .catch(() => {});
+	proxy.$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
+		confirmButtonText: "纭畾",
+		cancelButtonText: "鍙栨秷",
+		closeOnClickModal: false,
+		inputPattern: /^.{5,20}$/,
+		inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
+		inputValidator: (value) => {
+			if (/<|>|"|'|\||\\/.test(value)) {
+				return "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |"
+			}
+		},
+	}).then(({ value }) => {
+		resetUserPwd(row.userId, value).then(response => {
+			proxy.$modal.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + value)
+		})
+	}).catch(() => {})
 }
 
 /** 閫夋嫨鏉℃暟  */
 function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.userId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+	ids.value = selection.map(item => item.userId)
+	single.value = selection.length != 1
+	multiple.value = !selection.length
 }
 
 /** 瀵煎叆鎸夐挳鎿嶄綔 */
 function handleImport() {
-  upload.title = "鐢ㄦ埛瀵煎叆";
-  upload.open = true;
+	upload.title = "鐢ㄦ埛瀵煎叆"
+	upload.open = true
 }
 
 /** 涓嬭浇妯℃澘鎿嶄綔 */
 function importTemplate() {
-  proxy.download(
-    "system/user/importTemplate",
-    {},
-    `user_template_${new Date().getTime()}.xlsx`
-  );
+	proxy.download("system/user/importTemplate", {
+	}, `user_template_${new Date().getTime()}.xlsx`)
 }
 
 /**鏂囦欢涓婁紶涓鐞� */
 const handleFileUploadProgress = (event, file, fileList) => {
-  upload.isUploading = true;
-};
+	upload.isUploading = true
+}
 
 /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
 const handleFileSuccess = (response, file, fileList) => {
-  upload.open = false;
-  upload.isUploading = false;
-  proxy.$refs["uploadRef"].handleRemove(file);
-  proxy.$alert(
-    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
-      response.msg +
-      "</div>",
-    "瀵煎叆缁撴灉",
-    { dangerouslyUseHTMLString: true }
-  );
-  getList();
-};
+	upload.open = false
+	upload.isUploading = false
+	proxy.$refs["uploadRef"].handleRemove(file)
+	proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true })
+	getList()
+}
 
 /** 鎻愪氦涓婁紶鏂囦欢 */
 function submitFileForm() {
-  proxy.$refs["uploadRef"].submit();
+	proxy.$refs["uploadRef"].submit()
 }
 
 /** 閲嶇疆鎿嶄綔琛ㄥ崟 */
 function reset() {
-  form.value = {
-    userId: undefined,
-    deptId: undefined,
-    userName: undefined,
-    nickName: undefined,
-    password: undefined,
-    phonenumber: undefined,
-    email: undefined,
-    sex: undefined,
-    status: "0",
-    remark: undefined,
-    postIds: [],
-    roleIds: [],
-  };
-  proxy.resetForm("userRef");
+	form.value = {
+		userId: undefined,
+		deptId: undefined,
+		userName: undefined,
+		nickName: undefined,
+		password: undefined,
+		phonenumber: undefined,
+		email: undefined,
+		sex: undefined,
+		status: "0",
+		remark: undefined,
+		postIds: [],
+		roleIds: []
+	}
+	proxy.resetForm("userRef")
 }
 
 /** 鍙栨秷鎸夐挳 */
 function cancel() {
-  open.value = false;
-  reset();
+	open.value = false
+	reset()
 }
 
 /** 鏂板鎸夐挳鎿嶄綔 */
 function handleAdd() {
-  reset();
-  getUser().then((response) => {
-    postOptions.value = response.posts;
-    roleOptions.value = response.roles;
-    open.value = true;
-    title.value = "娣诲姞鐢ㄦ埛";
-    form.value.password = initPassword.value;
-  });
+	reset()
+	getUser().then(response => {
+		postOptions.value = response.posts
+		roleOptions.value = response.roles
+		open.value = true
+		title.value = "娣诲姞鐢ㄦ埛"
+		form.value.password = initPassword.value
+	})
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 function handleUpdate(row) {
-  reset();
-  const userId = row.userId || ids.value;
-  getUser(userId).then((response) => {
-    form.value = response.data;
-    postOptions.value = response.posts;
-    roleOptions.value = response.roles;
-    form.value.postIds = response.postIds;
-    form.value.roleIds = response.roleIds;
-    form.value.deptIds = response.deptIds;
-    open.value = true;
-    title.value = "淇敼鐢ㄦ埛";
-    form.password = "";
-  });
+	reset()
+	const userId = row.userId || ids.value
+	getUser(userId).then(response => {
+		form.value = response.data
+		postOptions.value = response.posts
+		roleOptions.value = response.roles
+		form.value.postIds = response.postIds
+		form.value.roleIds = response.roleIds
+		open.value = true
+		title.value = "淇敼鐢ㄦ埛"
+		form.password = ""
+	})
 }
 
 /** 鎻愪氦鎸夐挳 */
 function submitForm() {
-  proxy.$refs["userRef"].validate((valid) => {
-    if (valid) {
-      if (form.value.userId != undefined) {
-        updateUser(form.value).then((response) => {
-          proxy.$modal.msgSuccess("淇敼鎴愬姛");
-          open.value = false;
-          getList();
-        });
-      } else {
-        addUser(form.value).then((response) => {
-          proxy.$modal.msgSuccess("鏂板鎴愬姛");
-          open.value = false;
-          getList();
-        });
-      }
-    }
-  });
+	proxy.$refs["userRef"].validate(valid => {
+		if (valid) {
+			// 褰掑睘閮ㄩ棬铏界劧鏄崟閫夛紝浣嗗悗绔渶瑕佷紶鏁扮粍瀛楁 deptIds
+			const payload = {
+				...form.value,
+				deptIds: form.value.deptId ? [form.value.deptId] : []
+			}
+			if (form.value.userId != undefined) {
+				updateUser(payload).then(response => {
+					proxy.$modal.msgSuccess("淇敼鎴愬姛")
+					open.value = false
+					getList()
+				})
+			} else {
+				addUser(payload).then(response => {
+					proxy.$modal.msgSuccess("鏂板鎴愬姛")
+					open.value = false
+					getList()
+				})
+			}
+		}
+	})
 }
-onMounted(() => {
-	getDeptTree();
-	getList();
-});
+
+getDeptTree()
+getList()
 </script>
diff --git a/vite.config.js b/vite.config.js
index b30be40..dc687a8 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,11 +8,11 @@
   const { VITE_APP_ENV } = env;
   const baseUrl =
       env.VITE_APP_ENV === "development"
-          ? "http://localhost:6666"
+          ? "http://1.15.17.182:9003"
           : env.VITE_BASE_API;
   const javaUrl =
       env.VITE_APP_ENV === "development"
-          ? "http://114.132.189.42:9037"
+          ? "http://1.15.17.182:9002"
           : env.VITE_JAVA_API;
   return {
     define:{

--
Gitblit v1.9.3