From 1839bc040282f8972a7b55f504d3e72f4269e48e Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期三, 06 五月 2026 14:34:11 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro

---
 src/assets/styles/index.scss                                                         |    1 
 src/views/financialManagement/receivable/salesOut.vue                                |    8 
 src/api/productionManagement/workOrder.js                                            |    9 
 src/views/financialManagement/payable/payment.vue                                    |    7 
 src/views/financialManagement/salesRefund/components/ReceiptandRefundPopupWindow.vue |    5 
 src/views/financialManagement/generalLedger/index.vue                                |    7 
 src/api/productionManagement/productionOrder.js                                      |    9 
 src/views/qualityManagement/rawMaterialInspection/index.vue                          |    2 
 src/views/qualityManagement/finalInspection/index.vue                                |    2 
 src/views/personnelManagement/contractManagement/index.vue                           |    2 
 src/views/qualityManagement/processInspection/index.vue                              |    2 
 src/views/financialManagement/payable/input-invoice.vue                              |    7 
 src/views/productionManagement/workOrderManagement/index.vue                         |   10 
 src/views/basicData/customerFile/index.vue                                           |    2 
 src/views/safeProduction/safeWorkApproval/index.vue                                  |    2 
 src/views/productionManagement/processStatistics/index.vue                           |  268 +++++++
 src/views/productionManagement/productionTraceability/index.vue                      |  395 +++-------
 src/views/equipmentManagement/calibration/index.vue                                  |    2 
 vite.config.js                                                                       |    2 
 src/views/inventoryManagement/receiptManagement/Record.vue                           |    4 
 src/views/personnelManagement/employeeRecord/index.vue                               |    2 
 src/views/financialManagement/receivable/receipt.vue                                 |    7 
 src/views/safeProduction/hazardSourceLedger/index.vue                                |    2 
 src/views/productionManagement/workOrderEdit/index.vue                               |    6 
 src/views/financialManagement/assets/fixedAssets.vue                                 |    7 
 src/views/financialManagement/receivable/salesReturn.vue                             |    8 
 src/views/financialManagement/payable/paymentApply.vue                               |    7 
 src/views/procurementManagement/procurementLedger/index.vue                          |    1 
 src/views/equipmentManagement/measurementEquipment/index.vue                         |    2 
 src/views/financialManagement/payable/reconciliation.vue                             |  253 ++++++
 src/views/financialManagement/payable/purchaseIn.vue                                 |    8 
 src/views/productionManagement/productionOrder/index.vue                             |  129 +++
 src/views/qualityManagement/nonconformingManagement/index.vue                        |   36 
 src/views/salesManagement/receiptPaymentLedger/index.vue                             |    2 
 src/views/safeProduction/emergencyPlanReview/index.vue                               |    2 
 src/views/financialManagement/voucher/index.vue                                      |  576 +++++++++++++--
 src/views/lavorissue/statistics/index.vue                                            |    2 
 src/views/safeProduction/accidentReportingRecord/index.vue                           |    2 
 src/views/inventoryManagement/dispatchLog/Record.vue                                 |    4 
 src/views/financialManagement/assets/intangibleAssets.vue                            |    7 
 src/views/financialManagement/receivable/reconciliation.vue                          |  249 ++++++
 src/views/inventoryManagement/stockManagement/Record.vue                             |    4 
 src/views/customerService/afterSalesHandling/index.vue                               |    2 
 src/views/collaborativeApproval/knowledgeBase/index.vue                              |    2 
 src/views/basicData/supplierManage/components/HomeTab.vue                            |    6 
 src/views/personnelManagement/socialSecuritySet/index.vue                            |    2 
 src/views/procurementManagement/procurementReport/index.vue                          |    6 
 src/views/basicData/customerFileOpenSea/index.vue                                    |    2 
 src/views/financialManagement/receivable/invoiceApply.vue                            |    7 
 src/views/procurementManagement/paymentLedger/index.vue                              |    2 
 src/views/customerService/expiryAfterSales/index.vue                                 |    2 
 src/views/financialManagement/receivable/outputInvoice.vue                           |    7 
 src/views/personnelManagement/dimission/index.vue                                    |    2 
 src/views/safeProduction/hazardousMaterialsControl/index.vue                         |    2 
 54 files changed, 1,617 insertions(+), 487 deletions(-)

diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index 9b5751d..b84a188 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -102,6 +102,15 @@
     data,
   });
 }
+
+// 鐢熶骇璁㈠崟婧簮璇︽儏
+export function getOrderDetail(npsNo) {
+  return request({
+    url: "/productionOrder/ordeDetail",
+    method: "get",
+    params: { npsNo },
+  });
+}
 // 鐢熶骇璁㈠崟-棰嗘枡璇︽儏鍒楄〃
 // export function listMaterialPickingDetail(query) {
 //   return request({
diff --git a/src/api/productionManagement/workOrder.js b/src/api/productionManagement/workOrder.js
index 2e2fe2d..b3050c9 100644
--- a/src/api/productionManagement/workOrder.js
+++ b/src/api/productionManagement/workOrder.js
@@ -86,3 +86,12 @@
     data,
   });
 }
+
+// 鑾峰彇宸ュ簭缁熻鏁版嵁
+export function getOperationStatistics(query) {
+  return request({
+    url: "/productionOperationTask/getOperation",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index 883f03f..f905a36 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -148,7 +148,6 @@
   }
 }
 .table_list {
-  margin-top: 20px;
   background: rgba(255, 255, 255, 0.88);
   border: 1px solid var(--surface-border);
   border-radius: var(--radius-md);
diff --git a/src/views/basicData/customerFile/index.vue b/src/views/basicData/customerFile/index.vue
index d0f829c..a3a3dcf 100644
--- a/src/views/basicData/customerFile/index.vue
+++ b/src/views/basicData/customerFile/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form" style="margin-bottom: 20px;">
       <div>
         <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
         <el-input v-model="searchForm.customerName"
diff --git a/src/views/basicData/customerFileOpenSea/index.vue b/src/views/basicData/customerFileOpenSea/index.vue
index 71cc051..8bc8f6f 100644
--- a/src/views/basicData/customerFileOpenSea/index.vue
+++ b/src/views/basicData/customerFileOpenSea/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form" style="margin-bottom: 20px;">
       <div>
         <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
         <el-input v-model="searchForm.customerName"
diff --git a/src/views/basicData/supplierManage/components/HomeTab.vue b/src/views/basicData/supplierManage/components/HomeTab.vue
index 85c3265..47dce00 100644
--- a/src/views/basicData/supplierManage/components/HomeTab.vue
+++ b/src/views/basicData/supplierManage/components/HomeTab.vue
@@ -1,7 +1,7 @@
 <template>
-  <div class="app-container">
+  <div>
     <div class="search_form">
-      <div>
+      <div style="margin-bottom: 10px;">
         <span class="search_title">渚涘簲鍟嗘。妗堬細</span>
         <el-input
             v-model="searchForm.supplierName"
@@ -15,7 +15,7 @@
         >鎼滅储</el-button
         >
       </div>
-      <div>
+      <div style="margin-bottom: 10px;">
         <el-button type="primary" @click="openForm('add')"
         >鏂板渚涘簲鍟�</el-button
         >
diff --git a/src/views/collaborativeApproval/knowledgeBase/index.vue b/src/views/collaborativeApproval/knowledgeBase/index.vue
index bdce9bd..43fee33 100644
--- a/src/views/collaborativeApproval/knowledgeBase/index.vue
+++ b/src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form" style="margin-bottom: 20px;">
       <div>
         <span class="search_title">鐭ヨ瘑鏍囬锛�</span>
         <el-input
diff --git a/src/views/customerService/afterSalesHandling/index.vue b/src/views/customerService/afterSalesHandling/index.vue
index d023f51..a42337d 100644
--- a/src/views/customerService/afterSalesHandling/index.vue
+++ b/src/views/customerService/afterSalesHandling/index.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="app-container">
-		<div class="search-wrapper">
+		<div class="search-wrapper mb20">
       <el-form
           :model="searchForm"
           class="demo-form-inline"
diff --git a/src/views/customerService/expiryAfterSales/index.vue b/src/views/customerService/expiryAfterSales/index.vue
index c5abd0d..c94e3dd 100644
--- a/src/views/customerService/expiryAfterSales/index.vue
+++ b/src/views/customerService/expiryAfterSales/index.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="app-container">
-		<div class="search_form">
+		<div class="search_form mb20">
 			<div>
 				<span class="search_title">涓存湡鏃ユ湡锛�</span>
 				<el-date-picker
diff --git a/src/views/equipmentManagement/calibration/index.vue b/src/views/equipmentManagement/calibration/index.vue
index e3eaef6..b04da2e 100644
--- a/src/views/equipmentManagement/calibration/index.vue
+++ b/src/views/equipmentManagement/calibration/index.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="app-container">
-		<div class="search_form">
+		<div class="search_form mb20">
 			<div>
 				<span class="search_title">妫�瀹氭棩鏈燂細</span>
 				<el-date-picker
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
index 46ca100..c1d5379 100644
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ b/src/views/equipmentManagement/measurementEquipment/index.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="app-container">
-		<div class="search_form">
+		<div class="search_form mb20">
 			<div>
 				<span class="search_title">褰曞叆鏃ユ湡锛�</span>
 				<el-date-picker
diff --git a/src/views/financialManagement/assets/fixedAssets.vue b/src/views/financialManagement/assets/fixedAssets.vue
index 1690a33..61eb245 100644
--- a/src/views/financialManagement/assets/fixedAssets.vue
+++ b/src/views/financialManagement/assets/fixedAssets.vue
@@ -75,7 +75,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -178,16 +178,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "鍥哄畾璧勪骇",
diff --git a/src/views/financialManagement/assets/intangibleAssets.vue b/src/views/financialManagement/assets/intangibleAssets.vue
index f0b9af9..14dae55 100644
--- a/src/views/financialManagement/assets/intangibleAssets.vue
+++ b/src/views/financialManagement/assets/intangibleAssets.vue
@@ -76,7 +76,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -171,16 +171,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "鏃犲舰璧勪骇",
diff --git a/src/views/financialManagement/generalLedger/index.vue b/src/views/financialManagement/generalLedger/index.vue
index 0b5d597..0570627 100644
--- a/src/views/financialManagement/generalLedger/index.vue
+++ b/src/views/financialManagement/generalLedger/index.vue
@@ -60,7 +60,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="600px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-form-item label="绉戠洰缂栫爜" prop="subjectCode">
           <el-input v-model="form.subjectCode" placeholder="璇疯緭鍏ョ鐩紪鐮�" />
@@ -94,16 +94,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "鎬诲笎绉戠洰",
diff --git a/src/views/financialManagement/payable/input-invoice.vue b/src/views/financialManagement/payable/input-invoice.vue
index 8258e96..b809c98 100644
--- a/src/views/financialManagement/payable/input-invoice.vue
+++ b/src/views/financialManagement/payable/input-invoice.vue
@@ -67,7 +67,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -142,16 +142,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "杩涢」鍙戠エ",
diff --git a/src/views/financialManagement/payable/payment.vue b/src/views/financialManagement/payable/payment.vue
index 3ea0df8..d4774fe 100644
--- a/src/views/financialManagement/payable/payment.vue
+++ b/src/views/financialManagement/payable/payment.vue
@@ -70,7 +70,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -134,16 +134,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "浠樻鍗�",
diff --git a/src/views/financialManagement/payable/paymentApply.vue b/src/views/financialManagement/payable/paymentApply.vue
index 82981d7..fb23db3 100644
--- a/src/views/financialManagement/payable/paymentApply.vue
+++ b/src/views/financialManagement/payable/paymentApply.vue
@@ -60,7 +60,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -118,16 +118,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "浠樻鐢宠",
diff --git a/src/views/financialManagement/payable/purchaseIn.vue b/src/views/financialManagement/payable/purchaseIn.vue
index 131fe49..4813159 100644
--- a/src/views/financialManagement/payable/purchaseIn.vue
+++ b/src/views/financialManagement/payable/purchaseIn.vue
@@ -21,7 +21,6 @@
       <div class="actions">
         <div></div>
         <div>
-          <el-button type="primary" @click="add" icon="Plus">鏂板鍏ュ簱</el-button>
           <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
         </div>
       </div>
@@ -50,7 +49,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -118,16 +117,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "閲囪喘鍏ュ簱",
diff --git a/src/views/financialManagement/payable/reconciliation.vue b/src/views/financialManagement/payable/reconciliation.vue
index 06854b8..3aa23cd 100644
--- a/src/views/financialManagement/payable/reconciliation.vue
+++ b/src/views/financialManagement/payable/reconciliation.vue
@@ -55,7 +55,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" append-to-body>
+    <FormDialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail">
       <div class="statement-header">
         <h3>{{ currentSupplier }} 搴斾粯瀵硅处鍗�</h3>
         <p>瀵硅处鏈熼棿: {{ currentPeriod }}</p>
@@ -88,16 +88,72 @@
         <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
       </el-table>
       <template #footer>
-        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
         <el-button type="primary" @click="printDetail">鎵撳嵃</el-button>
+        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
+
+    <FormDialog title="鐢熸垚瀵硅处鍗�" v-model="generateDialogVisible" width="1000px" @confirm="confirmGenerate" @cancel="generateDialogVisible = false">
+      <el-form :model="generateForm" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫夋嫨渚涘簲鍟�" prop="supplierId">
+              <el-select v-model="generateForm.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%;" @change="onSupplierChange">
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀵硅处鏈堜唤" prop="period">
+              <el-date-picker v-model="generateForm.period" type="month" placeholder="閫夋嫨鏈堜唤" value-format="YYYY-MM" style="width: 100%;" @change="onPeriodChange" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+
+      <div v-if="purchaseData.length > 0" class="purchase-section">
+        <div class="section-title">鏈湀閲囪喘鏁版嵁</div>
+        <el-table :data="purchaseData" border style="width: 100%; margin-bottom: 15px;" v-loading="purchaseLoading" @selection-change="handlePurchaseSelectionChange">
+          <el-table-column type="selection" width="55" align="center" />
+          <el-table-column prop="date" label="鏃ユ湡" width="120" />
+          <el-table-column prop="code" label="鍗曟嵁缂栧彿" width="150" />
+          <el-table-column prop="type" label="绫诲瀷" width="100">
+            <template #default="{ row }">
+              <el-tag :type="row.type === '鍏ュ簱' ? 'success' : 'danger'">{{ row.type }}</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="amount" label="閲戦" width="120">
+            <template #default="{ row }">
+              <span :class="row.type === '鍏ュ簱' ? 'text-danger' : 'text-success'">楼{{ formatMoney(row.amount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="remark" label="澶囨敞" />
+        </el-table>
+
+        <div class="summary-row">
+          <span>鏈熷垵浣欓: <strong class="text-primary">楼{{ formatMoney(generateForm.beginBalance) }}</strong></span>
+          <span>鏈湡搴斾粯: <strong class="text-danger">楼{{ formatMoney(generateForm.currentPayable) }}</strong></span>
+          <span>鏈湡浠樻: <strong class="text-success">楼{{ formatMoney(generateForm.currentPayment) }}</strong></span>
+          <span>鏈熸湯浣欓: <strong class="text-primary">楼{{ formatMoney(calculateEndBalance(generateForm.beginBalance, generateForm.currentPayable, generateForm.currentPayment)) }}</strong></span>
+        </div>
+      </div>
+
+      <div v-else-if="generateForm.supplierId && !purchaseLoading" class="empty-tip">
+        <el-empty description="璇ヤ緵搴斿晢鏈湀鏆傛棤閲囪喘鏁版嵁" />
+      </div>
+
+      <template #footer>
+        <el-button type="primary" @click="confirmGenerate" :disabled="!canGenerate">纭鐢熸垚</el-button>
+        <el-button @click="generateDialogVisible = false">鍙栨秷</el-button>
+      </template>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from "vue";
+import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "搴斾粯瀵硅处",
@@ -132,6 +188,24 @@
 const currentPeriod = ref("");
 const detailData = ref([]);
 
+const generateDialogVisible = ref(false);
+const purchaseLoading = ref(false);
+const purchaseData = ref([]);
+const selectedPurchases = ref([]);
+
+const generateForm = reactive({
+  supplierId: "",
+  supplierName: "",
+  period: "",
+  beginBalance: 0,
+  currentPayable: 0,
+  currentPayment: 0,
+});
+
+const canGenerate = computed(() => {
+  return generateForm.supplierId && generateForm.period && selectedPurchases.value.length > 0;
+});
+
 const supplierList = [
   { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
   { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
@@ -144,6 +218,10 @@
   { id: 2, statementCode: "DZ202401002", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", period: "2024-01", beginBalance: 10000, currentPayable: 20000, currentPayment: 15000, endBalance: 15000 },
   { id: 3, statementCode: "DZ202402001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", period: "2024-02", beginBalance: 25000, currentPayable: 18000, currentPayment: 20000, endBalance: 23000 },
 ];
+
+const calculateEndBalance = (beginBalance, currentPayable, currentPayment) => {
+  return beginBalance + currentPayable - currentPayment;
+};
 
 const formatMoney = (value) => {
   if (value === undefined || value === null) return "0.00";
@@ -177,34 +255,133 @@
 };
 
 const generateStatement = () => {
-  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
+  generateForm.supplierId = "";
+  generateForm.supplierName = "";
+  generateForm.period = "";
+  generateForm.beginBalance = 0;
+  generateForm.currentPayable = 0;
+  generateForm.currentPayment = 0;
+  purchaseData.value = [];
+  selectedPurchases.value = [];
+  generateDialogVisible.value = true;
+};
+
+const onSupplierChange = (supplierId) => {
+  const supplier = supplierList.find(item => item.id === supplierId);
+  if (supplier) {
+    generateForm.supplierName = supplier.name;
+  }
+  loadPurchaseData();
+};
+
+const onPeriodChange = () => {
+  loadPurchaseData();
+};
+
+const loadPurchaseData = () => {
+  if (!generateForm.supplierId || !generateForm.period) {
+    purchaseData.value = [];
+    return;
+  }
+
+  purchaseLoading.value = true;
+
+  setTimeout(() => {
+    const mockPurchaseData = [
+      { id: 1, date: generateForm.period + "-05", code: "RK2024001", type: "鍏ュ簱", amount: 8000, remark: "鍘熸潗鏂欓噰璐�" },
+      { id: 2, date: generateForm.period + "-10", code: "FK2024001", type: "浠樻", amount: 5000, remark: "鏀粯璐ф" },
+      { id: 3, date: generateForm.period + "-15", code: "RK2024002", type: "鍏ュ簱", amount: 12000, remark: "鐢靛瓙鍏冨櫒浠�" },
+      { id: 4, date: generateForm.period + "-18", code: "TH2024001", type: "閫�璐�", amount: 2000, remark: "璐ㄩ噺闂閫�璐�" },
+      { id: 5, date: generateForm.period + "-22", code: "RK2024003", type: "鍏ュ簱", amount: 6000, remark: "鍖呰鏉愭枡" },
+      { id: 6, date: generateForm.period + "-25", code: "FK2024002", type: "浠樻", amount: 8000, remark: "鏀粯璐ф" },
+    ];
+
+    purchaseData.value = mockPurchaseData;
+
+    const lastPeriod = getLastPeriod(generateForm.period);
+    const lastStatement = mockData.find(item =>
+      item.supplierId === generateForm.supplierId && item.period === lastPeriod
+    );
+    generateForm.beginBalance = lastStatement ? lastStatement.endBalance : 0;
+
+    calculateSummary();
+
+    purchaseLoading.value = false;
+  }, 500);
+};
+
+const getLastPeriod = (period) => {
+  const [year, month] = period.split("-").map(Number);
+  if (month === 1) {
+    return `${year - 1}-12`;
+  }
+  return `${year}-${String(month - 1).padStart(2, "0")}`;
+};
+
+const calculateSummary = () => {
+  let payable = 0;
+  let payment = 0;
+
+  selectedPurchases.value.forEach(item => {
+    if (item.type === "鍏ュ簱") {
+      payable += item.amount;
+    } else if (item.type === "閫�璐�") {
+      payable -= item.amount;
+    } else if (item.type === "浠樻") {
+      payment += item.amount;
+    }
+  });
+
+  generateForm.currentPayable = payable;
+  generateForm.currentPayment = payment;
+};
+
+const handlePurchaseSelectionChange = (selection) => {
+  selectedPurchases.value = selection;
+  calculateSummary();
+};
+
+const confirmGenerate = () => {
   const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
-  const supplier = supplierList[Math.floor(Math.random() * supplierList.length)];
+  const endBalance = calculateEndBalance(generateForm.beginBalance, generateForm.currentPayable, generateForm.currentPayment);
+
   mockData.unshift({
     id: newId,
     statementCode: "DZ" + Date.now(),
-    supplierId: supplier.id,
-    supplierName: supplier.name,
-    period: "2024-03",
-    beginBalance: Math.floor(Math.random() * 20000),
-    currentPayable: Math.floor(Math.random() * 25000),
-    currentPayment: Math.floor(Math.random() * 20000),
-    endBalance: Math.floor(Math.random() * 25000),
+    supplierId: generateForm.supplierId,
+    supplierName: generateForm.supplierName,
+    period: generateForm.period,
+    beginBalance: generateForm.beginBalance,
+    currentPayable: generateForm.currentPayable,
+    currentPayment: generateForm.currentPayment,
+    endBalance,
   });
+
+  generateDialogVisible.value = false;
+  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
   getTableData();
 };
 
 const viewDetail = (row) => {
   currentSupplier.value = row.supplierName;
   currentPeriod.value = row.period;
+
+  const purchaseInAmount = Math.floor(row.currentPayable * 0.7);
+  const returnAmount = Math.floor(row.currentPayable * 0.1);
+  const firstPayment = Math.floor(row.currentPayment * 0.5);
+  const secondPayment = row.currentPayment - firstPayment;
+
+  let runningBalance = row.beginBalance;
+
   detailData.value = [
-    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "鏈熷垵浣欓" },
-    { date: row.period + "-05", type: "鍏ュ簱", code: "RK2024001", debit: 0, credit: 8000, balance: row.beginBalance + 8000, remark: "" },
-    { date: row.period + "-10", type: "浠樻", code: "FK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 3000, remark: "" },
-    { date: row.period + "-15", type: "鍏ュ簱", code: "RK2024002", credit: 12000, balance: row.beginBalance + 15000, remark: "" },
-    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 2000, credit: 0, balance: row.beginBalance + 13000, remark: "" },
-    { date: row.period + "-25", type: "浠樻", code: "FK2024002", debit: row.currentPayment - 5000, balance: row.endBalance, remark: "" },
+    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: runningBalance, remark: "鏈熷垵浣欓" },
+    { date: row.period + "-05", type: "鍏ュ簱", code: "RK2024001", debit: 0, credit: purchaseInAmount, balance: runningBalance += purchaseInAmount, remark: "閲囪喘鍏ュ簱" },
+    { date: row.period + "-10", type: "浠樻", code: "FK2024001", debit: firstPayment, credit: 0, balance: runningBalance -= firstPayment, remark: "鏀粯璐ф" },
+    { date: row.period + "-15", type: "鍏ュ簱", code: "RK2024002", debit: 0, credit: row.currentPayable - purchaseInAmount - returnAmount, balance: runningBalance += (row.currentPayable - purchaseInAmount - returnAmount), remark: "閲囪喘鍏ュ簱" },
+    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 0, credit: -returnAmount, balance: runningBalance -= returnAmount, remark: "閲囪喘閫�璐�" },
+    { date: row.period + "-25", type: "浠樻", code: "FK2024002", debit: secondPayment, credit: 0, balance: runningBalance -= secondPayment, remark: "鏀粯璐ф" },
   ];
+
   detailDialogVisible.value = true;
 };
 
@@ -251,4 +428,42 @@
     margin: 0;
   }
 }
+
+.purchase-section {
+  margin-top: 20px;
+
+  .section-title {
+    font-size: 16px;
+    font-weight: bold;
+    margin-bottom: 15px;
+    padding-left: 10px;
+    border-left: 4px solid #409eff;
+  }
+}
+
+.summary-row {
+  display: flex;
+  justify-content: space-around;
+  padding: 15px;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+  margin-top: 15px;
+
+  span {
+    font-size: 14px;
+
+    strong {
+      font-size: 16px;
+      margin-left: 5px;
+    }
+  }
+}
+
+.empty-tip {
+  margin-top: 30px;
+}
+
+.text-primary {
+  color: #409eff;
+}
 </style>
diff --git a/src/views/financialManagement/receivable/invoiceApply.vue b/src/views/financialManagement/receivable/invoiceApply.vue
index e637a3e..be9621d 100644
--- a/src/views/financialManagement/receivable/invoiceApply.vue
+++ b/src/views/financialManagement/receivable/invoiceApply.vue
@@ -61,7 +61,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -119,16 +119,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "寮�绁ㄧ敵璇�",
diff --git a/src/views/financialManagement/receivable/outputInvoice.vue b/src/views/financialManagement/receivable/outputInvoice.vue
index 289905a..1f6b0a4 100644
--- a/src/views/financialManagement/receivable/outputInvoice.vue
+++ b/src/views/financialManagement/receivable/outputInvoice.vue
@@ -57,7 +57,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -132,16 +132,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "閿�椤瑰彂绁�",
diff --git a/src/views/financialManagement/receivable/receipt.vue b/src/views/financialManagement/receivable/receipt.vue
index 51bb1f2..2bbbb96 100644
--- a/src/views/financialManagement/receivable/receipt.vue
+++ b/src/views/financialManagement/receivable/receipt.vue
@@ -63,7 +63,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -120,16 +120,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "鏀舵鍗�",
diff --git a/src/views/financialManagement/receivable/reconciliation.vue b/src/views/financialManagement/receivable/reconciliation.vue
index fc6d7c1..883e12e 100644
--- a/src/views/financialManagement/receivable/reconciliation.vue
+++ b/src/views/financialManagement/receivable/reconciliation.vue
@@ -55,7 +55,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" append-to-body>
+    <FormDialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail">
       <div class="statement-header">
         <h3>{{ currentCustomer }} 搴旀敹瀵硅处鍗�</h3>
         <p>瀵硅处鏈熼棿: {{ currentPeriod }}</p>
@@ -88,16 +88,72 @@
         <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
       </el-table>
       <template #footer>
-        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
         <el-button type="primary" @click="printDetail">鎵撳嵃</el-button>
+        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
+
+    <FormDialog title="鐢熸垚瀵硅处鍗�" v-model="generateDialogVisible" width="1000px" @confirm="confirmGenerate" @cancel="generateDialogVisible = false">
+      <el-form :model="generateForm" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫夋嫨瀹㈡埛" prop="customerId">
+              <el-select v-model="generateForm.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" @change="onCustomerChange">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀵硅处鏈堜唤" prop="period">
+              <el-date-picker v-model="generateForm.period" type="month" placeholder="閫夋嫨鏈堜唤" value-format="YYYY-MM" style="width: 100%;" @change="onPeriodChange" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+
+      <div v-if="salesData.length > 0" class="sales-section">
+        <div class="section-title">鏈湀閿�鍞暟鎹�</div>
+        <el-table :data="salesData" border style="width: 100%; margin-bottom: 15px;" v-loading="salesLoading" @selection-change="handleSalesSelectionChange">
+          <el-table-column type="selection" width="55" align="center" />
+          <el-table-column prop="date" label="鏃ユ湡" width="120" />
+          <el-table-column prop="code" label="鍗曟嵁缂栧彿" width="150" />
+          <el-table-column prop="type" label="绫诲瀷" width="100">
+            <template #default="{ row }">
+              <el-tag :type="row.type === '鍑哄簱' ? 'success' : row.type === '鏀舵' ? 'primary' : 'danger'">{{ row.type }}</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="amount" label="閲戦" width="120">
+            <template #default="{ row }">
+              <span :class="row.type === '鍑哄簱' ? 'text-primary' : row.type === '鏀舵' ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.amount) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="remark" label="澶囨敞" />
+        </el-table>
+
+        <div class="summary-row">
+          <span>鏈熷垵浣欓: <strong class="text-primary">楼{{ formatMoney(generateForm.beginBalance) }}</strong></span>
+          <span>鏈湡搴旀敹: <strong class="text-primary">楼{{ formatMoney(generateForm.currentReceivable) }}</strong></span>
+          <span>鏈湡鏀舵: <strong class="text-success">楼{{ formatMoney(generateForm.currentReceipt) }}</strong></span>
+          <span>鏈熸湯浣欓: <strong :class="calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt) >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt)) }}</strong></span>
+        </div>
+      </div>
+
+      <div v-else-if="generateForm.customerId && !salesLoading" class="empty-tip">
+        <el-empty description="璇ュ鎴锋湰鏈堟殏鏃犻攢鍞暟鎹�" />
+      </div>
+
+      <template #footer>
+        <el-button type="primary" @click="confirmGenerate" :disabled="!canGenerate">纭鐢熸垚</el-button>
+        <el-button @click="generateDialogVisible = false">鍙栨秷</el-button>
+      </template>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from "vue";
+import { ref, reactive, onMounted, computed } from "vue";
 import { ElMessage } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "搴旀敹瀵硅处",
@@ -132,6 +188,24 @@
 const currentPeriod = ref("");
 const detailData = ref([]);
 
+const generateDialogVisible = ref(false);
+const salesLoading = ref(false);
+const salesData = ref([]);
+const selectedSales = ref([]);
+
+const generateForm = reactive({
+  customerId: "",
+  customerName: "",
+  period: "",
+  beginBalance: 0,
+  currentReceivable: 0,
+  currentReceipt: 0,
+});
+
+const canGenerate = computed(() => {
+  return generateForm.customerId && generateForm.period && selectedSales.value.length > 0;
+});
+
 const customerList = [
   { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
   { id: 2, name: "涓婃捣璐告槗鍏徃" },
@@ -144,6 +218,10 @@
   { id: 2, statementCode: "DZ202401002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", period: "2024-01", beginBalance: 5000, currentReceivable: 12000, currentReceipt: 10000, endBalance: 7000 },
   { id: 3, statementCode: "DZ202402001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", period: "2024-02", beginBalance: 17000, currentReceivable: 20000, currentReceipt: 15000, endBalance: 22000 },
 ];
+
+const calculateEndBalance = (beginBalance, currentReceivable, currentReceipt) => {
+  return beginBalance + currentReceivable - currentReceipt;
+};
 
 const formatMoney = (value) => {
   if (value === undefined || value === null) return "0.00";
@@ -177,34 +255,133 @@
 };
 
 const generateStatement = () => {
-  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
+  generateForm.customerId = "";
+  generateForm.customerName = "";
+  generateForm.period = "";
+  generateForm.beginBalance = 0;
+  generateForm.currentReceivable = 0;
+  generateForm.currentReceipt = 0;
+  salesData.value = [];
+  selectedSales.value = [];
+  generateDialogVisible.value = true;
+};
+
+const onCustomerChange = (customerId) => {
+  const customer = customerList.find(item => item.id === customerId);
+  if (customer) {
+    generateForm.customerName = customer.name;
+  }
+  loadSalesData();
+};
+
+const onPeriodChange = () => {
+  loadSalesData();
+};
+
+const loadSalesData = () => {
+  if (!generateForm.customerId || !generateForm.period) {
+    salesData.value = [];
+    return;
+  }
+
+  salesLoading.value = true;
+
+  setTimeout(() => {
+    const mockSalesData = [
+      { id: 1, date: generateForm.period + "-03", code: "CK2024001", type: "鍑哄簱", amount: 8000, remark: "浜у搧A閿�鍞�" },
+      { id: 2, date: generateForm.period + "-08", code: "SK2024001", type: "鏀舵", amount: 5000, remark: "瀹㈡埛鍥炴" },
+      { id: 3, date: generateForm.period + "-12", code: "CK2024002", type: "鍑哄簱", amount: 12000, remark: "浜у搧B閿�鍞�" },
+      { id: 4, date: generateForm.period + "-15", code: "TH2024001", type: "閫�璐�", amount: 2000, remark: "璐ㄩ噺闂閫�璐�" },
+      { id: 5, date: generateForm.period + "-20", code: "CK2024003", type: "鍑哄簱", amount: 5000, remark: "浜у搧C閿�鍞�" },
+      { id: 6, date: generateForm.period + "-25", code: "SK2024002", type: "鏀舵", amount: 8000, remark: "瀹㈡埛鍥炴" },
+    ];
+
+    salesData.value = mockSalesData;
+
+    const lastPeriod = getLastPeriod(generateForm.period);
+    const lastStatement = mockData.find(item =>
+      item.customerId === generateForm.customerId && item.period === lastPeriod
+    );
+    generateForm.beginBalance = lastStatement ? lastStatement.endBalance : 0;
+
+    calculateSummary();
+
+    salesLoading.value = false;
+  }, 500);
+};
+
+const getLastPeriod = (period) => {
+  const [year, month] = period.split("-").map(Number);
+  if (month === 1) {
+    return `${year - 1}-12`;
+  }
+  return `${year}-${String(month - 1).padStart(2, "0")}`;
+};
+
+const calculateSummary = () => {
+  let receivable = 0;
+  let receipt = 0;
+
+  selectedSales.value.forEach(item => {
+    if (item.type === "鍑哄簱") {
+      receivable += item.amount;
+    } else if (item.type === "閫�璐�") {
+      receivable -= item.amount;
+    } else if (item.type === "鏀舵") {
+      receipt += item.amount;
+    }
+  });
+
+  generateForm.currentReceivable = receivable;
+  generateForm.currentReceipt = receipt;
+};
+
+const handleSalesSelectionChange = (selection) => {
+  selectedSales.value = selection;
+  calculateSummary();
+};
+
+const confirmGenerate = () => {
   const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
-  const customer = customerList[Math.floor(Math.random() * customerList.length)];
+  const endBalance = calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt);
+
   mockData.unshift({
     id: newId,
     statementCode: "DZ" + Date.now(),
-    customerId: customer.id,
-    customerName: customer.name,
-    period: "2024-03",
-    beginBalance: Math.floor(Math.random() * 10000),
-    currentReceivable: Math.floor(Math.random() * 20000),
-    currentReceipt: Math.floor(Math.random() * 15000),
-    endBalance: Math.floor(Math.random() * 20000),
+    customerId: generateForm.customerId,
+    customerName: generateForm.customerName,
+    period: generateForm.period,
+    beginBalance: generateForm.beginBalance,
+    currentReceivable: generateForm.currentReceivable,
+    currentReceipt: generateForm.currentReceipt,
+    endBalance,
   });
+
+  generateDialogVisible.value = false;
+  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
   getTableData();
 };
 
 const viewDetail = (row) => {
   currentCustomer.value = row.customerName;
   currentPeriod.value = row.period;
+
+  const saleOutAmount = Math.floor(row.currentReceivable * 0.6);
+  const returnAmount = Math.floor(row.currentReceivable * 0.1);
+  const firstReceipt = Math.floor(row.currentReceipt * 0.4);
+  const secondReceipt = row.currentReceipt - firstReceipt;
+
+  let runningBalance = row.beginBalance;
+
   detailData.value = [
-    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "鏈熷垵浣欓" },
-    { date: row.period + "-05", type: "鍑哄簱", code: "CK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 5000, remark: "" },
-    { date: row.period + "-10", type: "鏀舵", code: "SK2024001", debit: 0, credit: 3000, balance: row.beginBalance + 2000, remark: "" },
-    { date: row.period + "-15", type: "鍑哄簱", code: "CK2024002", debit: 8000, credit: 0, balance: row.beginBalance + 10000, remark: "" },
-    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 0, credit: 2000, balance: row.beginBalance + 8000, remark: "" },
-    { date: row.period + "-25", type: "鏀舵", code: "SK2024002", credit: row.currentReceipt - 3000, balance: row.endBalance, remark: "" },
+    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: runningBalance, remark: "鏈熷垵浣欓" },
+    { date: row.period + "-05", type: "鍑哄簱", code: "CK2024001", debit: saleOutAmount, credit: 0, balance: runningBalance += saleOutAmount, remark: "閿�鍞嚭搴�" },
+    { date: row.period + "-10", type: "鏀舵", code: "SK2024001", debit: 0, credit: firstReceipt, balance: runningBalance -= firstReceipt, remark: "瀹㈡埛鍥炴" },
+    { date: row.period + "-15", type: "鍑哄簱", code: "CK2024002", debit: row.currentReceivable - saleOutAmount - returnAmount, credit: 0, balance: runningBalance += (row.currentReceivable - saleOutAmount - returnAmount), remark: "閿�鍞嚭搴�" },
+    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 0, credit: returnAmount, balance: runningBalance -= returnAmount, remark: "閿�鍞��璐�" },
+    { date: row.period + "-25", type: "鏀舵", code: "SK2024002", debit: 0, credit: secondReceipt, balance: runningBalance -= secondReceipt, remark: "瀹㈡埛鍥炴" },
   ];
+
   detailDialogVisible.value = true;
 };
 
@@ -255,4 +432,38 @@
     margin: 0;
   }
 }
+
+.sales-section {
+  margin-top: 20px;
+
+  .section-title {
+    font-size: 16px;
+    font-weight: bold;
+    margin-bottom: 15px;
+    padding-left: 10px;
+    border-left: 4px solid #409eff;
+  }
+}
+
+.summary-row {
+  display: flex;
+  justify-content: space-around;
+  padding: 15px;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+  margin-top: 15px;
+
+  span {
+    font-size: 14px;
+
+    strong {
+      font-size: 16px;
+      margin-left: 5px;
+    }
+  }
+}
+
+.empty-tip {
+  margin-top: 30px;
+}
 </style>
diff --git a/src/views/financialManagement/receivable/salesOut.vue b/src/views/financialManagement/receivable/salesOut.vue
index 15e5106..fce0c20 100644
--- a/src/views/financialManagement/receivable/salesOut.vue
+++ b/src/views/financialManagement/receivable/salesOut.vue
@@ -21,7 +21,6 @@
       <div class="actions">
         <div></div>
         <div>
-          <el-button type="primary" @click="add" icon="Plus">鏂板鍑哄簱</el-button>
           <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
         </div>
       </div>
@@ -47,7 +46,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -80,16 +79,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "閿�鍞嚭搴�",
diff --git a/src/views/financialManagement/receivable/salesReturn.vue b/src/views/financialManagement/receivable/salesReturn.vue
index 7077b97..4cf54d6 100644
--- a/src/views/financialManagement/receivable/salesReturn.vue
+++ b/src/views/financialManagement/receivable/salesReturn.vue
@@ -21,7 +21,6 @@
       <div class="actions">
         <div></div>
         <div>
-          <el-button type="primary" @click="add" icon="Plus">鏂板閫�璐�</el-button>
           <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
         </div>
       </div>
@@ -47,7 +46,7 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -94,16 +93,17 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
         <el-button type="primary" @click="submitForm">纭畾</el-button>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "閿�鍞��璐�",
diff --git a/src/views/financialManagement/salesRefund/components/ReceiptandRefundPopupWindow.vue b/src/views/financialManagement/salesRefund/components/ReceiptandRefundPopupWindow.vue
index d8218c1..35215a5 100644
--- a/src/views/financialManagement/salesRefund/components/ReceiptandRefundPopupWindow.vue
+++ b/src/views/financialManagement/salesRefund/components/ReceiptandRefundPopupWindow.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-dialog v-model="visible" title="鏀舵/閫�娆�" width="90%" append-to-body>
+  <FormDialog v-model="visible" title="鏀舵/閫�娆�" width="90%" @confirm="submit" @cancel="visible=false">
     <div class="section">
       <div class="section-title descriptions">鍩虹璧勬枡</div>
       <el-form :model="form" label-width="100px">
@@ -140,12 +140,13 @@
       <el-button type="primary" @click="submit">纭</el-button>
       <el-button @click="visible=false">鍙栨秷</el-button>
     </template>
-  </el-dialog>
+  </FormDialog>
 </template>
 
 <script setup>
 import { ref } from 'vue';
 import { getToken } from '@/utils/auth';
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 const visible = ref(false);
 const form = ref({
diff --git a/src/views/financialManagement/voucher/index.vue b/src/views/financialManagement/voucher/index.vue
index 440336f..817185c 100644
--- a/src/views/financialManagement/voucher/index.vue
+++ b/src/views/financialManagement/voucher/index.vue
@@ -69,87 +69,142 @@
       </PIMTable>
     </div>
 
-    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="900px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="鍑瘉瀛楀彿" prop="voucherNo">
-              <el-input v-model="form.voucherNo" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鍑瘉鏃ユ湡" prop="voucherDate">
-              <el-date-picker v-model="form.voucherDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="闄勪欢寮犳暟" prop="attachmentCount">
-              <el-input-number v-model="form.attachmentCount" :min="0" style="width: 100%;" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-form-item label="鍑瘉鍒嗗綍" prop="entries">
-          <el-table :data="form.entries" border style="width: 100%">
-            <el-table-column type="index" label="搴忓彿" width="60" />
-            <el-table-column prop="subjectCode" label="绉戠洰缂栫爜" width="120">
-              <template #default="{ $index }">
-                <el-select v-model="form.entries[$index].subjectCode" placeholder="閫夋嫨绉戠洰" filterable style="width: 100%;" @change="(val) => handleSubjectChange(val, $index)">
-                  <el-option v-for="item in subjectList" :key="item.code" :label="item.code" :value="item.code" />
-                </el-select>
-              </template>
-            </el-table-column>
-            <el-table-column prop="subjectName" label="绉戠洰鍚嶇О" width="150">
-              <template #default="{ $index }">
-                <el-input v-model="form.entries[$index].subjectName" disabled />
-              </template>
-            </el-table-column>
-            <el-table-column prop="summary" label="鎽樿">
-              <template #default="{ $index }">
-                <el-input v-model="form.entries[$index].summary" placeholder="璇疯緭鍏ユ憳瑕�" />
-              </template>
-            </el-table-column>
-            <el-table-column prop="debit" label="鍊熸柟閲戦" width="130">
-              <template #default="{ $index }">
-                <el-input-number v-model="form.entries[$index].debit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" />
-              </template>
-            </el-table-column>
-            <el-table-column prop="credit" label="璐锋柟閲戦" width="130">
-              <template #default="{ $index }">
-                <el-input-number v-model="form.entries[$index].credit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" />
-              </template>
-            </el-table-column>
-            <el-table-column label="鎿嶄綔" width="80">
-              <template #default="{ $index }">
-                <el-button type="danger" link @click="removeEntry($index)">鍒犻櫎</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-          <div style="display: flex; justify-content: space-between; margin-top: 10px;">
-            <el-button type="primary" link @click="addEntry">+ 娣诲姞鍒嗗綍</el-button>
-            <div>
-              <span style="margin-right: 20px;">鍚堣: 鍊熸柟 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">楼{{ formatMoney(totalDebitEntry) }}</span></span>
-              <span>璐锋柟 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">楼{{ formatMoney(totalCreditEntry) }}</span></span>
+    <FormDialog :title="dialogTitle" v-model="dialogVisible" width="1200px" @confirm="submitForm" @cancel="dialogVisible = false">
+      <div class="voucher-container">
+        <div class="voucher-header">
+          <h2 class="voucher-title">璁拌处鍑瘉</h2>
+          <div class="voucher-period">{{ form.voucherDate ? form.voucherDate.substring(0, 7) + '鏈�' : '' }}</div>
+        </div>
+        <el-form :model="form" :rules="rules" ref="formRef" label-width="0">
+          <div class="voucher-info">
+            <div class="voucher-no-section">
+              <span class="label">鍑瘉瀛楋細</span>
+              <el-select v-model="form.voucherPrefix" style="width: 70px;">
+                <el-option label="璁�" value="璁�" />
+              </el-select>
+              <el-input v-model="form.voucherNum" style="width: 60px;" />
+              <span class="label" style="margin-left: 5px;">鍙�</span>
+            </div>
+            <div class="voucher-date-section">
+              <span class="label">鏃ユ湡锛�</span>
+              <el-date-picker v-model="form.voucherDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 140px;" />
+            </div>
+            <div class="voucher-attachment-section">
+              <span class="label">闄勪欢锛�</span>
+              <el-input-number v-model="form.attachmentCount" :min="0" :controls="false" style="width: 60px;" />
+              <span class="label" style="margin-left: 5px;">寮�</span>
+              <el-button type="primary" link style="margin-left: 10px;">涓婁紶鏂囦欢</el-button>
             </div>
           </div>
-        </el-form-item>
-        <el-form-item label="鍒跺崟浜�" prop="creator">
-          <el-input v-model="form.creator" disabled />
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="remark">
-          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
-        </el-form-item>
-      </el-form>
+          <div class="voucher-table">
+            <table class="accounting-voucher">
+              <thead>
+                <tr>
+                  <th class="col-summary" rowspan="2">鎽樿</th>
+                  <th class="col-subject" rowspan="2">浼氳绉戠洰</th>
+                  <th class="col-debit-header" colspan="11">鍊熸柟</th>
+                  <th class="col-credit-header" colspan="11">璐锋柟</th>
+                  <th class="col-action" rowspan="2">鎿嶄綔</th>
+                </tr>
+                <tr class="amount-header">
+                  <th>浜�</th>
+                  <th>鍗�</th>
+                  <th>鐧�</th>
+                  <th>鍗�</th>
+                  <th>涓�</th>
+                  <th>鍗�</th>
+                  <th>鐧�</th>
+                  <th>鍗�</th>
+                  <th>鍏�</th>
+                  <th>瑙�</th>
+                  <th>鍒�</th>
+                  <th>浜�</th>
+                  <th>鍗�</th>
+                  <th>鐧�</th>
+                  <th>鍗�</th>
+                  <th>涓�</th>
+                  <th>鍗�</th>
+                  <th>鐧�</th>
+                  <th>鍗�</th>
+                  <th>鍏�</th>
+                  <th>瑙�</th>
+                  <th>鍒�</th>
+                </tr>
+              </thead>
+              <tbody>
+                <tr v-for="(entry, rowIndex) in form.entries" :key="rowIndex" @click="selectRow(rowIndex)" :class="{ 'selected-row': selectedRowIndex === rowIndex }">
+                  <td class="col-summary">
+                    <el-input v-model="entry.summary" placeholder="璇疯緭鍏ユ憳瑕�" @focus="selectRow(rowIndex)" />
+                  </td>
+                  <td class="col-subject">
+                    <el-select v-model="entry.subjectCode" placeholder="閫夋嫨绉戠洰" filterable @change="(val) => handleSubjectChange(val, rowIndex)" @focus="selectRow(rowIndex)">
+                      <el-option v-for="item in subjectList" :key="item.code" :label="item.code + item.name" :value="item.code" />
+                    </el-select>
+                    <div class="subject-name">{{ entry.subjectName }}</div>
+                  </td>
+                  <!-- 鍊熸柟11鍒� -->
+                  <template v-if="editingCell.row === rowIndex && editingCell.type === 'debit'">
+                    <td colspan="11" class="debit-input-cell">
+                      <el-input-number ref="amountInputRef" v-model="entry.debit" :min="0" :precision="2" :controls="false" size="small" @blur="finishEdit" class="full-width-input" />
+                    </td>
+                  </template>
+                  <template v-else>
+                    <td v-for="(digit, dIndex) in getAmountDigits(entry.debit, 11)" :key="'debit-'+dIndex" class="amount-cell debit-cell" @click="openAmountInput(rowIndex, 'debit')">
+                      <span :class="{ 'text-primary': digit !== '', 'zero': digit === '' }">{{ digit || '' }}</span>
+                    </td>
+                  </template>
+                  <!-- 璐锋柟11鍒� -->
+                  <template v-if="editingCell.row === rowIndex && editingCell.type === 'credit'">
+                    <td colspan="11" class="credit-input-cell">
+                      <el-input-number ref="amountInputRef" v-model="entry.credit" :min="0" :precision="2" :controls="false" size="small" @blur="finishEdit" class="full-width-input" />
+                    </td>
+                  </template>
+                  <template v-else>
+                    <td v-for="(digit, dIndex) in getAmountDigits(entry.credit, 11)" :key="'credit-'+dIndex" class="amount-cell credit-cell" @click="openAmountInput(rowIndex, 'credit')">
+                      <span :class="{ 'text-danger': digit !== '', 'zero': digit === '' }">{{ digit || '' }}</span>
+                    </td>
+                  </template>
+                  <td class="col-action">
+                    <el-button type="danger" link size="small" @click="removeEntry(rowIndex)" icon="Delete" :disabled="form.entries.length <= 2">鍒犻櫎</el-button>
+                  </td>
+                </tr>
+                <tr class="total-row">
+                  <td class="col-summary" colspan="2" style="text-align: center; font-weight: bold;">鍚堣锛�</td>
+                  <td v-for="(digit, index) in getAmountDigits(totalDebitEntry, 11)" :key="'total-debit-'+index" class="amount-cell total-debit-cell">
+                    <span :class="{ 'text-primary': digit !== '' }">{{ digit }}</span>
+                  </td>
+                  <td v-for="(digit, index) in getAmountDigits(totalCreditEntry, 11)" :key="'total-credit-'+index" class="amount-cell total-credit-cell">
+                    <span :class="{ 'text-danger': digit !== '' }">{{ digit }}</span>
+                  </td>
+                  <td class="col-action"></td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <div class="voucher-toolbar">
+            <el-button type="primary" link @click="addEntry" icon="Plus">鏂板琛�</el-button>
+          </div>
+          <div class="voucher-footer">
+            <div class="creator-section">
+              <span class="label">鍒跺崟浜猴細{{ form.creator }}</span>
+            </div>
+          </div>
+        </el-form>
+      </div>
       <template #footer>
-        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="submitForm" :disabled="totalDebitEntry !== totalCreditEntry">纭畾</el-button>
+        <div>
+          <el-button type="primary" @click="submitForm" :disabled="!isBalanced">淇濆瓨</el-button>
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        </div>
       </template>
-    </el-dialog>
+    </FormDialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, computed } from "vue";
+import { ref, reactive, onMounted, computed, nextTick } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 
 defineOptions({
   name: "鍑瘉绠$悊",
@@ -198,11 +253,24 @@
 
 const form = reactive({
   voucherNo: "",
+  voucherPrefix: "璁�",
+  voucherNum: "",
   voucherDate: "",
   attachmentCount: 0,
   entries: [],
   creator: "寮犱笁",
   remark: "",
+});
+
+const selectedRowIndex = ref(-1);
+const editingCell = reactive({
+  row: -1,
+  type: "",
+});
+const amountInputRef = ref(null);
+
+const isBalanced = computed(() => {
+  return totalDebitEntry.value === totalCreditEntry.value && totalDebitEntry.value > 0;
 });
 
 const rules = {
@@ -283,6 +351,56 @@
   form.entries.push({ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 });
 };
 
+const selectRow = (index) => {
+  selectedRowIndex.value = index;
+};
+
+const openAmountInput = (index, type) => {
+  editingCell.row = index;
+  editingCell.type = type;
+  nextTick(() => {
+    if (amountInputRef.value) {
+      amountInputRef.value.focus();
+    }
+  });
+};
+
+const finishEdit = () => {
+  editingCell.row = -1;
+  editingCell.type = "";
+};
+
+const getAmountDigits = (amount, length) => {
+  if (!amount || amount === 0) {
+    return new Array(length).fill('');
+  }
+
+  const amountStr = Number(amount).toFixed(2);
+  const [intPart, decPart] = amountStr.split('.');
+  const fullAmount = intPart + decPart;
+
+  // 宸﹀~鍏�0鍒版寚瀹氶暱搴�
+  const paddedAmount = fullAmount.padStart(length, '0');
+  const digits = paddedAmount.split('');
+
+  // 鎵惧埌绗竴涓潪闆舵暟瀛楃殑浣嶇疆
+  let firstNonZeroIndex = 0;
+  for (let i = 0; i < digits.length; i++) {
+    if (digits[i] !== '0') {
+      firstNonZeroIndex = i;
+      break;
+    }
+  }
+
+  // 鍙殣钘忓墠瀵奸浂锛堢涓�涓潪闆舵暟瀛椾箣鍓嶇殑闆讹級
+  return digits.map((d, index) => {
+    if (index < firstNonZeroIndex) {
+      return ''; // 鍓嶅闆舵樉绀轰负绌�
+    }
+    return d; // 淇濈暀閲戦涓殑闆�
+  });
+};
+
 const removeEntry = (index) => {
   form.entries.splice(index, 1);
   calculateTotal();
@@ -302,14 +420,23 @@
 const add = () => {
   isEdit.value = false;
   dialogTitle.value = "鏂板鍑瘉";
+  const nextNum = String(mockData.length + 1).padStart(2, "0");
   Object.assign(form, {
-    voucherNo: "璁�-" + String(mockData.length + 1).padStart(4, "0"),
+    voucherNo: "璁�-" + nextNum,
+    voucherPrefix: "璁�",
+    voucherNum: nextNum,
     voucherDate: new Date().toISOString().split('T')[0],
     attachmentCount: 0,
-    entries: [{ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }],
+    entries: [
+      { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 },
+      { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 },
+      { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 },
+      { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 },
+    ],
     creator: "寮犱笁",
     remark: "",
   });
+  selectedRowIndex.value = 0;
   dialogVisible.value = true;
 };
 
@@ -317,7 +444,18 @@
   isEdit.value = true;
   currentId.value = row.id;
   dialogTitle.value = "缂栬緫鍑瘉";
-  Object.assign(form, row);
+  const parts = row.voucherNo.split('-');
+  Object.assign(form, {
+    ...row,
+    voucherPrefix: parts[0] || '璁�',
+    voucherNum: parts[1] || '',
+  });
+  if (form.entries.length < 4) {
+    while (form.entries.length < 4) {
+      form.entries.push({ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 });
+    }
+  }
+  selectedRowIndex.value = 0;
   dialogVisible.value = true;
 };
 
@@ -366,20 +504,33 @@
 const submitForm = () => {
   formRef.value.validate((valid) => {
     if (valid) {
-      if (totalDebitEntry.value !== totalCreditEntry.value) {
+      if (!isBalanced.value) {
         ElMessage.error("鍊熻捶涓嶅钩琛★紝璇锋鏌ュ垎褰�");
         return;
       }
-      const summary = form.entries.find(e => e.debit > 0)?.summary || "";
+
+      const validEntries = form.entries.filter(e => e.subjectCode && (e.debit > 0 || e.credit > 0));
+      const summary = validEntries.find(e => e.debit > 0)?.summary || "";
+
+      const voucherNo = `${form.voucherPrefix}-${form.voucherNum}`;
+      const dataToSave = {
+        ...form,
+        voucherNo,
+        summary,
+        debit: totalDebitEntry.value,
+        credit: totalCreditEntry.value,
+        entries: validEntries,
+      };
+
       if (isEdit.value) {
         const index = mockData.findIndex(item => item.id === currentId.value);
         if (index !== -1) {
-          mockData[index] = { ...mockData[index], ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value };
+          mockData[index] = { ...mockData[index], ...dataToSave };
         }
         ElMessage.success("缂栬緫鎴愬姛");
       } else {
         const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
-        mockData.push({ id: newId, ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value, status: "unposted" });
+        mockData.push({ id: newId, ...dataToSave, status: "unposted" });
         ElMessage.success("鏂板鎴愬姛");
       }
       dialogVisible.value = false;
@@ -415,4 +566,271 @@
   color: #f56c6c;
   font-weight: bold;
 }
+
+.text-primary {
+  color: #409eff;
+}
+
+.voucher-container {
+  background: #fff;
+  padding: 20px;
+}
+
+.voucher-header {
+  text-align: center;
+  margin-bottom: 15px;
+
+  .voucher-title {
+    font-size: 22px;
+    font-weight: bold;
+    margin: 0 0 5px 0;
+    color: #303133;
+  }
+
+  .voucher-period {
+    font-size: 14px;
+    color: #909399;
+  }
+}
+
+.voucher-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 0 10px;
+
+  .label {
+    font-size: 14px;
+    color: #606266;
+  }
+
+  .voucher-no-section,
+  .voucher-date-section,
+  .voucher-attachment-section {
+    display: flex;
+    align-items: center;
+  }
+}
+
+.voucher-table {
+  border: 1px solid #dcdfe6;
+  border-right: none;
+  margin-bottom: 15px;
+}
+
+.accounting-voucher {
+  width: 100%;
+  border-collapse: collapse;
+  font-size: 13px;
+
+  th,
+  td {
+    border: 1px solid #dcdfe6;
+    text-align: center;
+    padding: 0;
+    height: 36px;
+  }
+
+  & th:last-child,
+  & td:last-child {
+    border-right: none !important;
+  }
+
+  thead {
+    background-color: #f5f7fa;
+
+    th {
+      font-weight: normal;
+      color: #606266;
+      font-size: 12px;
+    }
+
+    .col-summary,
+    .col-subject {
+      font-weight: bold;
+      font-size: 13px;
+    }
+
+    .col-debit-header,
+    .col-credit-header {
+      background-color: #ecf5ff;
+      color: #409eff;
+      font-weight: bold;
+    }
+  }
+
+  .amount-header {
+    th {
+      font-size: 11px;
+      padding: 2px 0;
+      background-color: #f5f7fa;
+    }
+  }
+
+  .col-summary {
+    width: 160px;
+    min-width: 160px;
+  }
+
+  .col-subject {
+    width: 180px;
+    min-width: 180px;
+  }
+
+  .col-action {
+    width: 60px;
+    min-width: 60px;
+    text-align: center;
+  }
+
+  .amount-cell {
+    width: 24px;
+    min-width: 24px;
+    max-width: 24px;
+    padding: 0;
+    font-size: 13px;
+    font-family: 'Courier New', monospace;
+    cursor: pointer;
+    text-align: center;
+
+    &:hover {
+      background-color: #f5f7fa;
+    }
+
+    span {
+      display: block;
+      width: 100%;
+      height: 100%;
+      line-height: 36px;
+
+      &.zero {
+        color: #c0c4cc;
+      }
+    }
+  }
+
+  .debit-input-cell,
+  .credit-input-cell {
+    padding: 0;
+    background-color: #ecf5ff;
+
+    .full-width-input {
+      width: 100%;
+
+      :deep(.el-input__wrapper) {
+        padding: 0 10px;
+        box-shadow: none;
+        background-color: transparent;
+      }
+
+      input {
+        text-align: right;
+        font-size: 14px;
+        height: 34px;
+      }
+    }
+  }
+
+  tbody {
+    tr {
+      &:hover {
+        background-color: #f5f7fa;
+      }
+
+      &.selected-row {
+        background-color: #ecf5ff;
+      }
+    }
+
+    td {
+      .el-input {
+        .el-input__wrapper {
+          box-shadow: none;
+          padding: 0 5px;
+        }
+
+        input {
+          text-align: center;
+          height: 34px;
+        }
+      }
+
+      .el-select {
+        width: 100%;
+
+        .el-input__wrapper {
+          box-shadow: none;
+        }
+
+        input {
+          text-align: center;
+          height: 34px;
+        }
+      }
+    }
+
+    .col-summary {
+      .el-input input {
+        text-align: left;
+        padding-left: 10px;
+      }
+    }
+
+    .col-subject {
+      position: relative;
+
+      .el-select {
+        .el-input input {
+          font-size: 12px;
+        }
+      }
+
+      .subject-name {
+        font-size: 11px;
+        color: #909399;
+        margin-top: 2px;
+        line-height: 1.2;
+      }
+    }
+  }
+
+  .total-row {
+    background-color: #fdf6ec;
+
+    td {
+      font-weight: bold;
+    }
+
+    .total-cell {
+      background-color: #fdf6ec;
+      font-weight: bold;
+    }
+  }
+}
+
+.voucher-toolbar {
+  display: flex;
+  justify-content: flex-start;
+  padding: 10px 0;
+  margin-top: 5px;
+}
+
+.voucher-footer {
+  display: flex;
+  justify-content: flex-end;
+  padding: 0 10px;
+  margin-top: 10px;
+
+  .creator-section {
+    .label {
+      font-size: 14px;
+      color: #606266;
+    }
+  }
+}
+
+:deep(.el-dialog__body) {
+  padding: 10px 20px;
+}
 </style>
diff --git a/src/views/inventoryManagement/dispatchLog/Record.vue b/src/views/inventoryManagement/dispatchLog/Record.vue
index 80d7515..6060cf5 100644
--- a/src/views/inventoryManagement/dispatchLog/Record.vue
+++ b/src/views/inventoryManagement/dispatchLog/Record.vue
@@ -1,6 +1,6 @@
 <template>
-	<div class="app-container">
-		<div class="search_form">
+	<div>
+		<div class="search_form" style="margin-bottom: 10px;">
 			<div>
 				<span class="search_title ml10">鍑哄簱鏃ユ湡锛�</span>
 				<el-date-picker
diff --git a/src/views/inventoryManagement/receiptManagement/Record.vue b/src/views/inventoryManagement/receiptManagement/Record.vue
index d8bc1ea..7ca8fea 100644
--- a/src/views/inventoryManagement/receiptManagement/Record.vue
+++ b/src/views/inventoryManagement/receiptManagement/Record.vue
@@ -1,6 +1,6 @@
 <template>
-  <div class="app-container">
-    <div class="search_form">
+  <div>
+    <div class="search_form" style="margin-bottom: 10px;">
       <div>
         <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
         <el-date-picker v-model="searchForm.timeStr"
diff --git a/src/views/inventoryManagement/stockManagement/Record.vue b/src/views/inventoryManagement/stockManagement/Record.vue
index b1bb0ea..7c0a461 100644
--- a/src/views/inventoryManagement/stockManagement/Record.vue
+++ b/src/views/inventoryManagement/stockManagement/Record.vue
@@ -1,6 +1,6 @@
 <template>
-  <div class="app-container">
-    <div class="search_form">
+  <div>
+    <div class="search_form mb10">
       <div>
         <span class="search_title ml10">浜у搧澶х被锛�</span>
         <el-input v-model="searchForm.productName"
diff --git a/src/views/lavorissue/statistics/index.vue b/src/views/lavorissue/statistics/index.vue
index 2c34f67..54e1f38 100644
--- a/src/views/lavorissue/statistics/index.vue
+++ b/src/views/lavorissue/statistics/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">鍙戞斁瀛e害锛�</span>
         <el-select
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 1d2aab7..a55a502 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">濮撳悕锛�</span>
         <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="璇疯緭鍏ュ鍚嶆悳绱�" @change="handleQuery"
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
index 5993b3f..c2b8c3e 100644
--- a/src/views/personnelManagement/dimission/index.vue
+++ b/src/views/personnelManagement/dimission/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">濮撳悕锛�</span>
         <el-input
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index 131d37b..cd4ecf5 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">濮撳悕锛�</span>
         <el-input
diff --git a/src/views/personnelManagement/socialSecuritySet/index.vue b/src/views/personnelManagement/socialSecuritySet/index.vue
index 2a1ff65..1f3f104 100644
--- a/src/views/personnelManagement/socialSecuritySet/index.vue
+++ b/src/views/personnelManagement/socialSecuritySet/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">涓婚锛�</span>
         <el-input
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
index 294561d..23a62aa 100644
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ b/src/views/procurementManagement/paymentLedger/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form" style="margin-bottom: 20px;">
       <div>
         <span class="search_title">渚涘簲鍟嗗悕绉�:</span>
         <el-input
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 1991342..28fb968 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -635,7 +635,6 @@
 </template>
 
 <script setup>
-import {Search, Delete} from "@element-plus/icons-vue";
 import FormDialog from '@/components/Dialog/FormDialog.vue';
 import FileListDialog from '@/components/Dialog/FileListDialog.vue';
   import { getToken } from "@/utils/auth";
diff --git a/src/views/procurementManagement/procurementReport/index.vue b/src/views/procurementManagement/procurementReport/index.vue
index 4ba1802..26e682d 100644
--- a/src/views/procurementManagement/procurementReport/index.vue
+++ b/src/views/procurementManagement/procurementReport/index.vue
@@ -334,12 +334,6 @@
 </script>
 
 <style scoped>
-.app-container {
-  padding: 20px;
-  background-color: #f5f7fa;
-  min-height: 100vh;
-}
-
 .page-header {
   text-align: center;
   margin-bottom: 20px;
diff --git a/src/views/productionManagement/processStatistics/index.vue b/src/views/productionManagement/processStatistics/index.vue
new file mode 100644
index 0000000..25fa531
--- /dev/null
+++ b/src/views/productionManagement/processStatistics/index.vue
@@ -0,0 +1,268 @@
+<template>
+  <div class="app-container">
+    <div class="search-bar">
+      <el-form :model="searchForm"
+               inline>
+        <el-form-item label="鏃ユ湡鍖洪棿:">
+          <el-date-picker v-model="searchForm.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          value-format="YYYY-MM-DD"
+                          style="width: 240px" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     icon="Search"
+                     @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="stats-grid"
+         v-loading="loading">
+      <el-row :gutter="16"
+              v-if="statsData.length > 0">
+        <el-col v-for="(item, index) in statsData"
+                :key="index"
+                :xs="24"
+                :sm="12"
+                :md="8"
+                :lg="4.8"
+                :xl="4.8"
+                class="mb-16">
+          <div class="stats-card">
+            <div class="card-header">
+              <span class="process-name">{{ item.name }}</span>
+              <div class="header-stats">
+                <div class="stat-row">
+                  <span class="label">璁″垝鏁�</span>
+                  <span class="value">{{ item.planned }}</span>
+                </div>
+                <div class="stat-row">
+                  <span class="label">鑹搧鏁�</span>
+                  <span class="value">{{ item.good }}</span>
+                </div>
+                <div class="stat-row">
+                  <span class="label">涓嶈壇鍝佹暟</span>
+                  <span class="value">{{ item.bad }}</span>
+                </div>
+              </div>
+            </div>
+            <div class="card-body">
+              <div class="main-stat">
+                <div class="big-number">{{ item.total }}</div>
+                <div class="sub-label">鐢熶骇浠诲姟鏁�</div>
+              </div>
+            </div>
+            <div class="card-footer">
+              <div class="progress-info">
+                <span class="progress-label">杩涘害:</span>
+                <el-progress :percentage="Math.min(item.percentage, 100)"
+                             :color="getProgressColor(item.percentage)"
+                             :stroke-width="10"
+                             :show-text="false"
+                             class="flex-1" />
+                <span class="percentage-text">{{ item.percentage }}%</span>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-empty v-else
+                description="鏆傛棤鏁版嵁" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { reactive, ref, onMounted } from "vue";
+  import dayjs from "dayjs";
+  import { getOperationStatistics } from "@/api/productionManagement/workOrder.js";
+
+  const loading = ref(false);
+  const searchForm = reactive({
+    dateRange: [],
+  });
+
+  const statsData = ref([]);
+
+  const getProgressColor = percentage => {
+    if (percentage >= 100) return "#67c23a";
+    if (percentage >= 50) return "#409eff";
+    if (percentage >= 25) return "#e6a23c";
+    return "red";
+  };
+
+  const getList = () => {
+    loading.value = true;
+    const params = {
+      startDate: searchForm.dateRange?.[0] || "",
+      endDate: searchForm.dateRange?.[1] || "",
+    };
+    getOperationStatistics(params)
+      .then(res => {
+        // 鏍规嵁瀹為檯鎺ュ彛杩斿洖鐨勫瓧娈佃繘琛屾槧灏�
+        statsData.value = (res.data || []).map(item => ({
+          name: item.operationName || "-",
+          total: item.productionTaskCount || 0,
+          planned: item.planQuantity || 0,
+          good: item.goodQuantity || 0,
+          bad: item.scrapQty || 0,
+          percentage: Number(item.completionStatus || 0),
+        }));
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  const handleQuery = () => {
+    getList();
+  };
+
+  onMounted(() => {
+    getList();
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 20px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 84px);
+  }
+
+  .search-bar {
+    background: #fff;
+    padding: 15px 20px 0;
+    border-radius: 4px;
+    margin-bottom: 20px;
+    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+  }
+
+  .mb-16 {
+    margin-bottom: 16px;
+  }
+
+  // 妯℃嫙 lg="4.8" 鍥犱负 element 涓嶆敮鎸� 24/5
+  @media only screen and (min-width: 1200px) {
+    .el-col-lg-4-8 {
+      width: 20%;
+      max-width: 20%;
+      flex: 0 0 20%;
+    }
+  }
+
+  .stats-card {
+    background: #fff;
+    border-radius: 8px;
+    padding: 16px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: transform 0.3s;
+
+    &:hover {
+      transform: translateY(-2px);
+    }
+
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 12px;
+
+      .process-name {
+        background-color: #e6f7ff;
+        color: #1890ff;
+        padding: 2px 8px;
+        border-radius: 4px;
+        font-size: 14px;
+        font-weight: 500;
+      }
+
+      .header-stats {
+        text-align: right;
+
+        .stat-row {
+          display: flex;
+          justify-content: flex-end;
+          align-items: center;
+          gap: 8px;
+          margin-bottom: 2px;
+
+          .label {
+            font-size: 12px;
+            color: #909399;
+          }
+
+          .value {
+            font-size: 13px;
+            color: #303133;
+            font-weight: bold;
+            min-width: 24px;
+          }
+        }
+      }
+    }
+
+    .card-body {
+      padding: 10px 0;
+
+      .main-stat {
+        .big-number {
+          font-size: 28px;
+          font-weight: bold;
+          color: #303133;
+          line-height: 1;
+        }
+
+        .sub-label {
+          font-size: 14px;
+          color: #606266;
+          margin-top: 8px;
+          font-weight: 500;
+        }
+      }
+    }
+
+    .card-footer {
+      margin-top: 16px;
+
+      .progress-info {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+
+        .progress-label {
+          font-size: 12px;
+          color: #909399;
+          white-space: nowrap;
+        }
+
+        .flex-1 {
+          flex: 1;
+        }
+
+        .percentage-text {
+          font-size: 12px;
+          color: #606266;
+          min-width: 45px;
+          text-align: right;
+        }
+      }
+    }
+  }
+
+  // 淇 el-col 甯冨眬閫傞厤 5 鍒�
+  :deep(.el-row) {
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  @media only screen and (min-width: 1200px) {
+    .el-col-lg-4\.8 {
+      flex: 0 0 20%;
+      max-width: 20%;
+    }
+  }
+</style>
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 93fc177..c37358b 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -75,6 +75,26 @@
                        :color="progressColor(toProgressPercentage(row?.completionStatus))"
                        :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
         </template>
+        <template #processRouteStatus="{ row }">
+          <div v-if="row.processRouteStatus && row.processRouteStatus.length"
+               class="process-progress-container">
+            <div v-for="(item, index) in row.processRouteStatus"
+                 :key="index"
+                 class="process-step">
+              <div class="step-content">
+                <div class="step-circle"
+                     :class="{ 'is-completed': item.percentage >= 100 }">
+                  <span class="step-percentage"
+                        :style="{ color: item.percentage >= 70 ? item.percentage >= 100 ? '#67c23a' : '#f56c6c' : '#000' }">{{ item.percentage }}%</span>
+                </div>
+                <div class="step-name">{{ item.name }}</div>
+              </div>
+              <div v-if="index < row.processRouteStatus.length - 1"
+                   class="step-line"></div>
+            </div>
+          </div>
+          <span v-else>-</span>
+        </template>
       </PIMTable>
     </div>
     <el-dialog v-model="bindRouteDialogVisible"
@@ -215,6 +235,7 @@
     getProductOrderSource,
     updateProductOrder,
   } from "@/api/productionManagement/productionOrder.js";
+  import { productWorkOrderPage } from "@/api/productionManagement/workOrder.js";
   import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
   import MaterialLedgerDialog from "@/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue";
   import MaterialDetailDialog from "@/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue";
@@ -241,7 +262,17 @@
     total: 0,
   });
 
-  const tableColumn = ref([
+  const processColumnWidth = computed(() => {
+    if (!tableData.value || tableData.value.length === 0) return "200px";
+    const maxProcesses = Math.max(
+      ...tableData.value.map(row => row.processRouteStatus?.length || 0)
+    );
+    if (maxProcesses === 0) return "100px";
+    // 姣忎釜宸ュ簭鍦嗗湀 36px + 绾挎潯 30px = 66px锛岄澶栧姞 60px 杈硅窛鍜屾枃瀛楃┖闂�
+    return `${maxProcesses * 66 + 60}px`;
+  });
+
+  const tableColumn = computed(() => [
     {
       label: "鐢熶骇璁㈠崟鍙�",
       prop: "npsNo",
@@ -296,6 +327,13 @@
     {
       label: "瀹屾垚鏁伴噺",
       prop: "completeQuantity",
+    },
+    {
+      label: "宸ュ簭鐢熶骇杩涘害",
+      prop: "processRouteStatus",
+      dataType: "slot",
+      slot: "processRouteStatus",
+      width: processColumnWidth.value,
     },
     {
       dataType: "slot",
@@ -630,10 +668,35 @@
     const params = { ...searchForm.value, ...page };
     params.entryDate = undefined;
     productOrderListPage(params)
-      .then(res => {
-        tableLoading.value = false;
-        tableData.value = res.data.records;
+      .then(async res => {
+        const records = res.data.records || [];
+        // 涓烘瘡涓鍗曟煡璇㈠搴旂殑宸ュ簭杩涘害鏁版嵁
+        const processPromises = records.map(async item => {
+          if (item.npsNo) {
+            try {
+              const workOrderRes = await productWorkOrderPage({
+                npsNo: item.npsNo,
+                size: 100,
+              });
+              const workOrders = workOrderRes.data.records || [];
+              // 鎸夌収宸ュ簭椤哄簭鎺掑簭锛堝鏋滄湁椤哄簭瀛楁锛屽亣璁句负 orderNum 鎴栨寜杩斿洖椤哄簭锛�
+              // 杞崲涓� processRouteStatus 鏍煎紡
+              const processRouteStatus = workOrders.map(wo => ({
+                name: wo.operationName || "鏈煡宸ュ簭",
+                percentage: wo.completionStatus > 100 ? 100 : wo.completionStatus,
+              }));
+              return { ...item, processRouteStatus };
+            } catch (error) {
+              console.error(`鑾峰彇宸ュ崟 ${item.npsNo} 杩涘害澶辫触:`, error);
+              return { ...item, processRouteStatus: [] };
+            }
+          }
+          return { ...item, processRouteStatus: [] };
+        });
+
+        tableData.value = await Promise.all(processPromises);
         page.total = res.data.total;
+        tableLoading.value = false;
       })
       .catch(() => {
         tableLoading.value = false;
@@ -813,6 +876,64 @@
   .table_list {
     margin-top: unset;
   }
+
+  .process-progress-container {
+    display: inline-flex;
+    align-items: center;
+    padding: 10px 0;
+    white-space: nowrap;
+
+    .process-step {
+      display: flex;
+      align-items: center;
+      position: relative;
+
+      .step-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        z-index: 1;
+
+        .step-circle {
+          width: 36px;
+          height: 36px;
+          border-radius: 50%;
+          border: 2px solid #409eff;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          background-color: #fff;
+          margin-bottom: 4px;
+
+          .step-percentage {
+            font-size: 11px;
+            font-weight: bold;
+          }
+
+          &.is-completed {
+            border-color: #67c23a;
+            .step-percentage {
+              color: #67c23a;
+            }
+          }
+        }
+
+        .step-name {
+          font-size: 12px;
+          color: #606266;
+          white-space: nowrap;
+        }
+      }
+
+      .step-line {
+        width: 30px;
+        height: 1px;
+        background-color: #dcdfe6;
+        margin: 0 -2px;
+        margin-top: -20px; // 鍚戜笂鍋忕Щ浠ュ榻愬渾蹇�
+      }
+    }
+  }
 </style>
 <style lang="scss">
   .status-cell {
diff --git a/src/views/productionManagement/productionTraceability/index.vue b/src/views/productionManagement/productionTraceability/index.vue
index e2ac6df..a850788 100644
--- a/src/views/productionManagement/productionTraceability/index.vue
+++ b/src/views/productionManagement/productionTraceability/index.vue
@@ -22,9 +22,6 @@
                            :value="option.id" />
               </el-select>
             </el-form-item>
-            <el-form-item>
-              <el-button @click="handleBack">杩斿洖</el-button>
-            </el-form-item>
           </el-form>
         </div>
       </template>
@@ -37,7 +34,7 @@
           <el-descriptions-item label="鐢熶骇璁㈠崟鍙�">{{ rowData.productionOrderDto?.npsNo || '-' }}</el-descriptions-item>
           <el-descriptions-item label="浜у搧鍚嶇О">{{ rowData.productionOrderDto?.productName || '-' }}</el-descriptions-item>
           <el-descriptions-item label="浜у搧瑙勬牸">{{ rowData.productionOrderDto?.model || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="鐗╂枡缂栫爜">{{ rowData.productionOrderDto?.materialCode || '-' }}</el-descriptions-item>
+          <!-- <el-descriptions-item label="鐗╂枡缂栫爜">{{ rowData.productionOrderDto?.materialCode || '-' }}</el-descriptions-item> -->
           <el-descriptions-item label="璁″垝鏁伴噺">{{ rowData.productionOrderDto?.quantity || 0 }} <span class="unit">{{ rowData.productionOrderDto?.unit || '-' }}</span></el-descriptions-item>
           <el-descriptions-item label="褰撳墠鐘舵��">
             <el-tag :type="getStatusType(rowData.productionOrderDto?.status)">
@@ -45,12 +42,12 @@
             </el-tag>
           </el-descriptions-item>
           <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ rowData.productionOrderDto?.customerName || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="寮�濮嬫棩鏈�">{{ rowData.productionOrderDto?.startTime || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="寮�濮嬫棩鏈�">{{ parseTime(rowData.productionOrderDto?.startTime) || '-' }}</el-descriptions-item>
           <el-descriptions-item label="瀹屾垚杩涘害">
-            <el-progress :percentage="rowData.productionOrderDto?.completionStatus"
+            <el-progress :percentage="rowData.productionOrderDto?.completionStatus>=100?100:rowData.productionOrderDto?.completionStatus"
                          :color="customColors(rowData.productionOrderDto?.completionStatus)"
-                         :status="rowData.productionOrderDto?.completionStatus === 100 ? 'success' : ''"
-                         style="width: 120px;" />
+                         :status="rowData.productionOrderDto?.completionStatus >= 100 ? 'success' : ''"
+                         style="width: 80%;" />
           </el-descriptions-item>
         </el-descriptions>
       </div>
@@ -65,25 +62,35 @@
             <el-table :data="rowData.productionRecords"
                       border
                       style="width: 100%">
-              <el-table-column prop="productNo"
+              <el-table-column prop="workOrder.workOrderNo"
                                label="宸ュ崟缂栧彿"
                                align="center">
               </el-table-column>
-              <el-table-column prop="productName"
-                               label="浜у搧鍚嶇О"
-                               align="center" />
-              <el-table-column prop="model"
-                               label="瑙勬牸"
-                               align="center" />
-              <el-table-column prop="processName"
-                               label="宸ュ簭鍚嶇О"
-                               align="center" />
-              <el-table-column prop="requiredQuantity"
+              <el-table-column label="浜у搧鍚嶇О"
+                               align="center">
+                <template #default="{ row }">
+                  {{ row.workOrder.productName || '-' }}
+                </template>
+              </el-table-column>
+              <el-table-column label="瑙勬牸"
+                               align="center">
+                <template #default="{ row }">
+                  {{ row.workOrder.model || '-' }}
+                </template>
+              </el-table-column>
+              <el-table-column prop="workOrder.planQuantity"
                                label="闇�姹傛暟閲�"
                                align="center" />
-              <el-table-column prop="completedQuantity"
+              <el-table-column prop="workOrder.completeQuantity"
                                label="瀹屾垚鏁伴噺"
                                align="center" />
+              <el-table-column prop="workOrder.completionStatus"
+                               label="瀹屾垚杩涘害"
+                               align="center">
+                <template #default="{ row }">
+                  <span :style="{ color: customColors(row.workOrder.completionStatus) }">{{ row.workOrder.completionStatus || 0 }}%</span>
+                </template>
+              </el-table-column>
               <el-table-column label="璇︽儏"
                                align="center"
                                width="200">
@@ -111,39 +118,40 @@
       <div class="detail-container">
         <!-- 鍩虹淇℃伅 -->
         <div class="detail-section">
-          <h3 class="section-title">鍩虹淇℃伅</h3>
+          <h3 class="section-title">宸ュ崟鍩虹淇℃伅</h3>
           <el-descriptions :column="3"
                            border>
-            <el-descriptions-item label="鐢熶骇宸ュ崟鍙�">{{ detailData.npsNo || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="鐝粍">
-              <el-tag :type="detailData.schedule === '鐧界彮' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag>
-            </el-descriptions-item>
-            <el-descriptions-item label="浜у搧缂栫爜">{{ detailData.materialCode || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="浜у搧鍚嶇О">{{ detailData.productName || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="瑙勬牸">{{ detailData.model || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="鍚堟牸鏁伴噺"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
-            <el-descriptions-item label="涓嶅悎鏍兼暟閲�"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
-            <el-descriptions-item label="鎬绘暟閲�"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
-            <el-descriptions-item label="寮�濮嬫椂闂�">{{ detailData.reportingTime || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="鐢熶骇宸ュ崟鍙�">{{ detailData.workOrder.workOrderNo || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="璁″垝鏁伴噺">{{ detailData.workOrder.planQuantity || 0 }}</el-descriptions-item>
+            <el-descriptions-item label="瀹屾垚鏁伴噺">{{ detailData.workOrder.completeQuantity || 0 }}</el-descriptions-item>
+            <el-descriptions-item label="瀹為檯寮�濮嬫椂闂�">{{ parseTime(detailData.workOrder.actualStartTime) || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="瀹為檯缁撴潫鏃堕棿">{{ parseTime(detailData.workOrder.actualEndTime) || '-' }}</el-descriptions-item>
+            <!-- <el-descriptions-item label="瀹屾垚杩涘害">
+              <el-progress :percentage="detailData.workOrder.completionStatus >= 100 ? 100 : (detailData.workOrder.completionStatus || 0)"
+                           :color="customColors(detailData.workOrder.completionStatus)"
+                           :status="detailData.workOrder.completionStatus >= 100 ? 'success' : ''"
+                           style="width:500px;" />
+            </el-descriptions-item> -->
+            <el-descriptions-item label="瀹屾垚杩涘害"><span :style="{ color: customColors(detailData.workOrder.completionStatus) }">{{ detailData.workOrder.completionStatus || 0 }}%</span></el-descriptions-item>
           </el-descriptions>
         </div>
         <div class="detail-section">
           <h3 class="section-title">鎶ュ伐鏄庣粏</h3>
-          <el-table :data="[detailData]"
+          <el-table :data="detailData.reports"
                     border
                     style="width: 100%">
             <el-table-column label="鎶ュ伐鍗曞彿"
                              prop="productNo"
                              align="center" />
-            <el-table-column label="浜у嚭鏁伴噺"
-                             prop="qualifiedQuantity"
-                             align="center" />
-            <el-table-column label="鎶ュ簾鏁伴噺"
-                             prop="unqualifiedQuantity"
+            <el-table-column label="鍒涘缓浜�"
+                             prop="userName"
                              align="center" />
             <el-table-column label="鍒涘缓鏃堕棿"
-                             prop="reportingTime"
-                             align="center" />
+                             align="center">
+              <template #default="{ row }">
+                {{ parseTime(row.createTime) }}
+              </template>
+            </el-table-column>
             <el-table-column label="鎿嶄綔"
                              align="center"
                              width="200">
@@ -205,25 +213,24 @@
              :key="record.id"
              class="quality-record-block">
           <div class="detail-section">
-            <h3 class="section-title">妫�娴嬭褰� {{ index + 1 }} - {{ record.checkTime }}</h3>
+            <h3 class="section-title">妫�娴嬭褰� {{ index + 1 }} - {{ parseTime(record.createTime) }}</h3>
             <el-descriptions :column="3"
                              border>
-              <el-descriptions-item label="妫�娴嬫棩鏈�">{{ record.checkTime || '-' }}</el-descriptions-item>
-              <el-descriptions-item label="鐢熶骇宸ュ崟鍙�">{{ record.workOrderNo || '-' }}</el-descriptions-item>
-              <el-descriptions-item label="宸ュ簭">{{ record.process || '-' }}</el-descriptions-item>
-              <el-descriptions-item label="妫�楠屽憳">{{ record.checkName || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="妫�娴嬫棩鏈�">{{ parseTime(record.createTime) || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="鎶ュ伐鍗曞彿">{{ record.reportNo || '-' }}</el-descriptions-item>
+              <el-descriptions-item label="妫�楠屽憳">{{ record.userName || '-' }}</el-descriptions-item>
               <el-descriptions-item label="浜у搧鍚嶇О">{{ record.productName || '-' }}</el-descriptions-item>
               <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ record.model || '-' }}</el-descriptions-item>
               <el-descriptions-item label="鏁伴噺">{{ record.quantity || 0 }} {{ record.unit || '-' }}</el-descriptions-item>
               <el-descriptions-item label="妫�娴嬪崟浣�">{{ record.checkCompany || '-' }}</el-descriptions-item>
               <el-descriptions-item label="妫�娴嬬粨鏋�">
                 <el-tag :type="record.checkResult === '鍚堟牸' ? 'success' : 'danger'">
-                  {{ record.checkResult || '-' }}
+                  {{ record.checkResult || '寰呮娴�' }}
                 </el-tag>
               </el-descriptions-item>
             </el-descriptions>
             <h4 class="sub-section-title">妫�楠屾寚鏍囧垪琛�</h4>
-            <el-table :data="record.inspectItems"
+            <el-table :data="record.inspectParamList"
                       border
                       style="width: 100%">
               <el-table-column label="搴忓彿"
@@ -231,7 +238,7 @@
                                width="60"
                                align="center" />
               <el-table-column label="鎸囨爣"
-                               prop="itemName"
+                               prop="parameterItem"
                                align="center" />
               <el-table-column label="鍗曚綅"
                                prop="unit"
@@ -243,13 +250,10 @@
                                prop="controlValue"
                                align="center" />
               <el-table-column label="瀹為檯鍊�"
-                               prop="actualValue"
+                               prop="testValue"
                                align="center" />
             </el-table>
           </div>
-          <!-- <div class="detail-section">
-
-          </div> -->
           <el-divider v-if="index < qualityRecords.length - 1" />
         </div>
       </div>
@@ -266,7 +270,12 @@
   import { ref, reactive, onMounted } from "vue";
   import { useRoute, useRouter } from "vue-router";
   import { ElMessage } from "element-plus";
+  import { parseTime } from "@/utils/ruoyi";
   import InputModal from "@/views/productionManagement/productionReporting/Input.vue";
+  import {
+    getOrderDetail,
+    productOrderListPage,
+  } from "@/api/productionManagement/productionOrder";
 
   const route = useRoute();
   const router = useRouter();
@@ -277,47 +286,7 @@
   });
   const selectedNpsNo = ref(null);
   const npsNoLoading = ref(false);
-  const npsNoOptions = ref([
-    {
-      id: 1,
-      npsNo: "PO20240301001",
-      productName: "绮惧瘑娑插帇缂�",
-      model: "HG-100/50-500",
-      materialCode: "MAT-2024-001",
-      quantity: 500,
-      unit: "浠�",
-      status: 1,
-      customerName: "閲嶅伐鏈烘鏈夐檺鍏徃",
-      startTime: "2024-03-01",
-      completionStatus: 65,
-    },
-    {
-      id: 2,
-      npsNo: "PO20240301002",
-      productName: "宸ヤ笟浼烘湇鐢垫満",
-      model: "SV-400W-3000",
-      materialCode: "MAT-2024-002",
-      quantity: 200,
-      unit: "鍙�",
-      status: 2,
-      customerName: "鑷姩鍖栬澶囩鎶�鍏徃",
-      startTime: "2024-03-02",
-      completionStatus: 100,
-    },
-    {
-      id: 3,
-      npsNo: "PO20240301003",
-      productName: "楂樺帇瀵嗗皝鍦�",
-      model: "SR-80-5",
-      materialCode: "MAT-2024-003",
-      quantity: 5000,
-      unit: "涓�",
-      status: 0,
-      customerName: "瀵嗗皝绯荤粺閰嶄欢鍘�",
-      startTime: "2024-03-05",
-      completionStatus: 0,
-    },
-  ]);
+  const npsNoOptions = ref([]);
 
   // 璇︽儏鏁版嵁
   const rowData = reactive({
@@ -327,7 +296,10 @@
 
   // 鎶ュ伐璇︽儏寮圭獥
   const detailDialogVisible = ref(false);
-  const detailData = ref({});
+  const detailData = ref({
+    workOrder: {},
+    reports: [],
+  });
 
   // 鎶曞叆妯℃�佹
   const isShowInput = ref(false);
@@ -351,12 +323,12 @@
 
   // 鐘舵�佸鐞�
   const getStatusType = status => {
-    const typeMap = { 0: "info", 1: "primary", 2: "success" };
+    const typeMap = { 1: "primary", 2: "warning", 3: "success", 5: "danger" };
     return typeMap[status] || "info";
   };
   const getStatusText = status => {
-    const statusMap = { 0: "鏈紑濮�", 1: "鐢熶骇涓�", 2: "宸插畬鎴�" };
-    return statusMap[status] || "鏈煡";
+    const statusMap = { 1: "寰呭紑濮�", 2: "杩涜涓�", 3: "宸插畬鎴�", 5: "宸茬粨鏉�" };
+    return statusMap[status] || "宸插彇娑�";
   };
   const customColors = percentage => {
     if (percentage < 30) return "#f56c6c";
@@ -365,51 +337,41 @@
   };
 
   // 妯℃嫙鎼滅储鏂规硶
-  const handleNpsNoSearch = query => {
-    if (query) {
-      npsNoLoading.value = true;
-      setTimeout(() => {
-        npsNoLoading.value = false;
-      }, 300);
+  const handleNpsNoSearch = async query => {
+    npsNoLoading.value = true;
+    try {
+      const res = await productOrderListPage({
+        npsNo: query || "",
+        pageNum: 1,
+        pageSize: 50,
+      });
+      // 鍙傜収 productionOrder/index.vue 鐨勬暟鎹粨鏋� res.data.records
+      npsNoOptions.value = res.data?.records || res.rows || [];
+    } catch (error) {
+      console.error(error);
+    } finally {
+      npsNoLoading.value = false;
     }
   };
 
-  const handleSearch = id => {
+  const handleSearch = async id => {
     const selected = npsNoOptions.value.find(item => item.id === id);
     if (selected) {
-      rowData.productionOrderDto = selected;
-      rowData.productionRecords = [
-        {
-          id: 1001,
-          productNo: "MO-2024-001-01",
-          productName: selected.productName,
-          model: selected.model,
-          processName: "姣涘澂鍔犲伐",
-          requiredQuantity: selected.quantity,
-          completedQuantity: Math.floor(selected.quantity * 0.4),
-          qualifiedQuantity: Math.floor(selected.quantity * 0.4) - 2,
-          unqualifiedQuantity: 2,
-          reportingTime: "2024-03-01 10:00:00",
-          schedule: "鐧界彮",
-          postName: "寮犱笁",
-          unit: selected.unit,
-        },
-        {
-          id: 1002,
-          productNo: "MO-2024-001-02",
-          productName: selected.productName,
-          model: selected.model,
-          processName: "绮惧姞宸�",
-          requiredQuantity: Math.floor(selected.quantity * 0.4),
-          completedQuantity: Math.floor(selected.quantity * 0.25),
-          qualifiedQuantity: Math.floor(selected.quantity * 0.25),
-          unqualifiedQuantity: 0,
-          reportingTime: "2024-03-01 16:00:00",
-          schedule: "鐧界彮",
-          postName: "鏉庡洓",
-          unit: selected.unit,
-        },
-      ];
+      try {
+        const res = await getOrderDetail(selected.npsNo);
+        if (res.code === 200) {
+          const { productionOrder, workOrderList } = res.data;
+          rowData.productionOrderDto = productionOrder || selected;
+          rowData.productionRecords = workOrderList || [];
+        } else {
+          rowData.productionOrderDto = selected;
+          rowData.productionRecords = [];
+        }
+      } catch (error) {
+        console.error(error);
+        ElMessage.error("鑾峰彇璁㈠崟璇︽儏澶辫触");
+        rowData.productionOrderDto = selected;
+      }
     }
   };
 
@@ -418,121 +380,34 @@
   };
 
   const handleClickStep = row => {
+    // row 鏄� workOrderList 涓殑涓�椤癸紝鍖呭惈 workOrder, reportList, inspectList
     detailData.value = {
-      id: row.id || Math.floor(Math.random() * 1000),
-      productNo: row.productNo,
-      npsNo: rowData.productionOrderDto.npsNo,
-      schedule: row.schedule,
-      postName: row.postName,
-      materialCode: rowData.productionOrderDto.materialCode,
-      productName: row.productName,
-      model: row.model,
-      qualifiedQuantity: row.qualifiedQuantity,
-      unqualifiedQuantity: row.unqualifiedQuantity || 0,
-      quantity: row.completedQuantity,
-      unit: row.unit,
-      reportingTime: row.reportingTime,
-      productionOperationParamList: [
-        { id: 1, paramName: "涓昏酱杞��", inputValue: "2400", unit: "rpm" },
-        { id: 2, paramName: "杩涚粰閫熷害", inputValue: "120", unit: "mm/min" },
-        { id: 3, paramName: "鍒囧墛娣卞害", inputValue: "0.5", unit: "mm" },
-        { id: 4, paramName: "鍐峰嵈娑插帇鍔�", inputValue: "0.6", unit: "Mpa" },
-      ],
+      workOrder: row.workOrder || {},
+      reports: (row.reportList || []).map(r => ({
+        ...r.reportMain,
+        productionOperationParamList: r.reportParamList || [],
+      })),
     };
     detailDialogVisible.value = true;
   };
 
   const handleClickQuality = row => {
-    qualityRecords.value = [
-      {
-        id: 2001,
-        checkTime: "2024-03-01 11:30:00",
-        workOrderNo: row.productNo,
-        process: row.processName,
-        checkName: "璐ㄩ噺閮�-鐜嬪缓鍥�",
-        productName: row.productName,
-        model: row.model,
-        unit: row.unit,
-        quantity: row.completedQuantity,
-        checkCompany: "鍐呴儴瀹為獙瀹�",
-        checkResult: "鍚堟牸",
-        inspectItems: [
-          {
-            id: 1,
-            itemName: "澶栧緞灏哄",
-            unit: "mm",
-            standardValue: "100.00卤0.05",
-            controlValue: "100.00卤0.03",
-            actualValue: "100.01",
-            result: "鍚堟牸",
-          },
-          {
-            id: 2,
-            itemName: "鍐呭緞灏哄",
-            unit: "mm",
-            standardValue: "50.00+0.02/-0",
-            controlValue: "50.00+0.01/-0",
-            actualValue: "50.01",
-            result: "鍚堟牸",
-          },
-          {
-            id: 3,
-            itemName: "琛ㄩ潰绮楃硻搴�",
-            unit: "Ra",
-            standardValue: "鈮�1.6",
-            controlValue: "鈮�1.2",
-            actualValue: "0.8",
-            result: "鍚堟牸",
-          },
-        ],
-      },
-      {
-        id: 2001,
-        checkTime: "2024-03-01 11:30:00",
-        workOrderNo: row.productNo,
-        process: row.processName,
-        checkName: "璐ㄩ噺閮�-鐜嬪缓鍥�",
-        productName: row.productName,
-        model: row.model,
-        unit: row.unit,
-        quantity: row.completedQuantity,
-        checkCompany: "鍐呴儴瀹為獙瀹�",
-        checkResult: "鍚堟牸",
-        inspectItems: [
-          {
-            id: 1,
-            itemName: "澶栧緞灏哄",
-            unit: "mm",
-            standardValue: "100.00卤0.05",
-            controlValue: "100.00卤0.03",
-            actualValue: "100.01",
-            result: "鍚堟牸",
-          },
-          {
-            id: 2,
-            itemName: "鍐呭緞灏哄",
-            unit: "mm",
-            standardValue: "50.00+0.02/-0",
-            controlValue: "50.00+0.01/-0",
-            actualValue: "50.01",
-            result: "鍚堟牸",
-          },
-          {
-            id: 3,
-            itemName: "琛ㄩ潰绮楃硻搴�",
-            unit: "Ra",
-            standardValue: "鈮�1.6",
-            controlValue: "鈮�1.2",
-            actualValue: "0.8",
-            result: "鍚堟牸",
-          },
-        ],
-      },
-    ];
+    // row 鏄� workOrderList 涓殑涓�椤�
+    const inspects = row.inspectList || [];
+    qualityRecords.value = inspects.map(i => ({
+      ...i.inspect,
+      reportNo: i.reportNo,
+      userName: i.reportMain?.userName || "-",
+      inspectParamList: i.inspectParamList || [],
+      inspectFileList: i.inspectFileList || [],
+    }));
     qualityDialogVisible.value = true;
   };
 
-  onMounted(() => {
+  onMounted(async () => {
+    // 鍒濆鍔犺浇鍒楄〃
+    await handleNpsNoSearch();
+
     if (route.query.npsNo) {
       const npsNo = route.query.npsNo;
       const found = npsNoOptions.value.find(item => item.npsNo === npsNo);
@@ -540,23 +415,23 @@
         selectedNpsNo.value = found.id;
         handleSearch(found.id);
       } else {
-        // 濡傛灉娌℃壘鍒帮紝鍒涘缓涓�涓复鏃剁殑
-        const mockItem = {
-          id: Date.now(),
-          npsNo: npsNo,
-          productName: route.query.productName || "绮惧瘑娑插帇缂�",
-          model: route.query.model || "HG-100/50-500",
-          materialCode: "MAT-2024-MOCK",
-          quantity: 100,
-          unit: "浠�",
-          status: 1,
-          customerName: "妯℃嫙瀹㈡埛",
-          startTime: "2024-03-01",
-          completionStatus: 50,
-        };
-        npsNoOptions.value.push(mockItem);
-        selectedNpsNo.value = mockItem.id;
-        handleSearch(mockItem.id);
+        // 濡傛灉鍒楄〃涓病鏈夛紙鍙兘鏄垎椤靛師鍥狅級锛屽垯鏍规嵁 npsNo 鍐嶆绮惧噯鎼滅储
+        try {
+          const res = await productOrderListPage({
+            npsNo,
+            pageNum: -1,
+            pageSize: -1,
+          });
+          const records = res.data?.records || res.rows || [];
+          if (records.length > 0) {
+            const item = records[0];
+            npsNoOptions.value.unshift(item);
+            selectedNpsNo.value = item.id;
+            handleSearch(item.id);
+          }
+        } catch (error) {
+          console.error("鑾峰彇璺敱鍙傛暟瀵瑰簲鐨勮鍗曞け璐�", error);
+        }
       }
     }
   });
diff --git a/src/views/productionManagement/workOrderEdit/index.vue b/src/views/productionManagement/workOrderEdit/index.vue
index 693fea0..1cde5ea 100644
--- a/src/views/productionManagement/workOrderEdit/index.vue
+++ b/src/views/productionManagement/workOrderEdit/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div class="search-row">
         <div class="search-item">
           <span class="search_title">宸ュ崟缂栧彿锛�</span>
@@ -13,7 +13,7 @@
         </div>
         <div class="search-item">
           <span class="search_title">鐢熶骇璁㈠崟鍙凤細</span>
-          <el-input v-model="searchForm.productOrderNpsNo"
+          <el-input v-model="searchForm.npsNo"
                     style="width: 240px"
                     placeholder="璇疯緭鍏�"
                     @change="handleQuery"
@@ -259,7 +259,7 @@
   const data = reactive({
     searchForm: {
       workOrderNo: "",
-      productOrderNpsNo: "",
+      npsNo: "",
     },
   });
   const { searchForm } = toRefs(data);
diff --git a/src/views/productionManagement/workOrderManagement/index.vue b/src/views/productionManagement/workOrderManagement/index.vue
index dda27fc..600b274 100644
--- a/src/views/productionManagement/workOrderManagement/index.vue
+++ b/src/views/productionManagement/workOrderManagement/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div class="search-row">
         <div class="search-item">
           <span class="search_title">宸ュ崟缂栧彿锛�</span>
@@ -13,7 +13,7 @@
         </div>
         <div class="search-item">
           <span class="search_title">鐢熶骇璁㈠崟鍙凤細</span>
-          <el-input v-model="searchForm.productOrderNpsNo"
+          <el-input v-model="searchForm.npsNo"
                     style="width: 240px"
                     placeholder="璇疯緭鍏�"
                     @change="handleQuery"
@@ -265,7 +265,9 @@
   import QRCode from "qrcode";
   import { getCurrentInstance, reactive, toRefs } from "vue";
   import MaterialDialog from "./components/MaterialDialog.vue";
-  const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
+  const FileList = defineAsyncComponent(() =>
+    import("@/components/Dialog/FileList.vue")
+  );
 
   import useUserStore from "@/store/modules/user";
   const { proxy } = getCurrentInstance();
@@ -525,7 +527,7 @@
   const data = reactive({
     searchForm: {
       workOrderNo: "",
-      productOrderNpsNo: "",
+      npsNo: "",
     },
   });
   const { searchForm } = toRefs(data);
diff --git a/src/views/qualityManagement/finalInspection/index.vue b/src/views/qualityManagement/finalInspection/index.vue
index eaed2e9..a2d1acc 100644
--- a/src/views/qualityManagement/finalInspection/index.vue
+++ b/src/views/qualityManagement/finalInspection/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">浜у搧鍚嶇О锛�</span>
         <el-input
diff --git a/src/views/qualityManagement/nonconformingManagement/index.vue b/src/views/qualityManagement/nonconformingManagement/index.vue
index 55d2472..6306397 100644
--- a/src/views/qualityManagement/nonconformingManagement/index.vue
+++ b/src/views/qualityManagement/nonconformingManagement/index.vue
@@ -1,24 +1,21 @@
 <template>
   <div class="app-container">
     <div class="search_form">
-      <div style="display: flex;flex-direction: row;align-items: center;">
-        <div>
-          <span class="search_title">绫诲瀷锛�</span>
+      <el-form :model="searchForm" inline style="margin-bottom: 0;">
+        <el-form-item label="绫诲瀷锛�">
           <el-select v-model="searchForm.inspectType" clearable style="width: 200px" @change="handleQuery">
             <el-option label="鍘熸潗鏂欐楠�" :value="0" />
             <el-option label="杩囩▼妫�楠�" :value="1" />
             <el-option label="鍑哄巶妫�楠�" :value="2" />
           </el-select>
-        </div>
-        <div style="margin-left: 10px">
-          <span class="search_title">鐘舵�侊細</span>
+        </el-form-item>
+        <el-form-item label="鐘舵�侊細">
           <el-select v-model="searchForm.inspectState" clearable style="width: 200px" @change="handleQuery">
             <el-option label="寰呭鐞�" :value="0" />
             <el-option label="宸插鐞�" :value="1" />
           </el-select>
-        </div>
-        <div style="margin-left: 10px">
-          <span class="search_title">浜у搧鍚嶇О锛�</span>
+        </el-form-item>
+        <el-form-item label="浜у搧鍚嶇О锛�">
           <el-input
               v-model="searchForm.productName"
               style="width: 200px"
@@ -27,19 +24,22 @@
               clearable
               :prefix-icon="Search"
           />
-        </div>
-        <span  style="margin-left: 10px" class="search_title">妫�娴嬫棩鏈燂細</span>
-        <el-date-picker  v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-												 style="width: 300px"
-                         placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
-      </div>
-      <div>
+        </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"
+                          style="width: 300px"
+                          placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="mb20" style="text-align: right;">
         <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"
diff --git a/src/views/qualityManagement/processInspection/index.vue b/src/views/qualityManagement/processInspection/index.vue
index cbeab71..e5504b6 100644
--- a/src/views/qualityManagement/processInspection/index.vue
+++ b/src/views/qualityManagement/processInspection/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">宸ュ簭锛�</span>
         <el-input
diff --git a/src/views/qualityManagement/rawMaterialInspection/index.vue b/src/views/qualityManagement/rawMaterialInspection/index.vue
index 26504b0..cc2c151 100644
--- a/src/views/qualityManagement/rawMaterialInspection/index.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">渚涘簲鍟嗭細</span>
         <el-input
diff --git a/src/views/safeProduction/accidentReportingRecord/index.vue b/src/views/safeProduction/accidentReportingRecord/index.vue
index ff5b301..5a6c345 100644
--- a/src/views/safeProduction/accidentReportingRecord/index.vue
+++ b/src/views/safeProduction/accidentReportingRecord/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">浜嬫晠鍚嶇О锛�</span>
         <el-input v-model="searchForm.accidentName"
diff --git a/src/views/safeProduction/emergencyPlanReview/index.vue b/src/views/safeProduction/emergencyPlanReview/index.vue
index eb68508..1850c18 100644
--- a/src/views/safeProduction/emergencyPlanReview/index.vue
+++ b/src/views/safeProduction/emergencyPlanReview/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">搴旀�ラ妗堝悕绉帮細</span>
         <el-input v-model="searchForm.planName"
diff --git a/src/views/safeProduction/hazardSourceLedger/index.vue b/src/views/safeProduction/hazardSourceLedger/index.vue
index 9aa131a..416202e 100644
--- a/src/views/safeProduction/hazardSourceLedger/index.vue
+++ b/src/views/safeProduction/hazardSourceLedger/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">鍗遍櫓婧愬悕绉帮細</span>
         <el-input v-model="searchForm.name"
diff --git a/src/views/safeProduction/hazardousMaterialsControl/index.vue b/src/views/safeProduction/hazardousMaterialsControl/index.vue
index a53490c..e43b4f6 100644
--- a/src/views/safeProduction/hazardousMaterialsControl/index.vue
+++ b/src/views/safeProduction/hazardousMaterialsControl/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">鍗遍櫓婧愬悕绉帮細</span>
         <el-input v-model="searchForm.name"
diff --git a/src/views/safeProduction/safeWorkApproval/index.vue b/src/views/safeProduction/safeWorkApproval/index.vue
index 2d8362e..bfd1d90 100644
--- a/src/views/safeProduction/safeWorkApproval/index.vue
+++ b/src/views/safeProduction/safeWorkApproval/index.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <!-- 鏍囩椤靛垏鎹笉鍚岀殑瀹℃壒绫诲瀷 -->
-    <div class="search_form">
+    <div class="search_form mb20">
       <div>
         <span class="search_title">娴佺▼缂栧彿锛�</span>
         <el-input v-model="searchForm.approveId"
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index 7029cfc..e41e24f 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
+    <div class="search_form" style="margin-bottom: 20px;">
       <div>
         <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
         <el-input
diff --git a/vite.config.js b/vite.config.js
index ac18ec5..dc687a8 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,7 +8,7 @@
   const { VITE_APP_ENV } = env;
   const baseUrl =
       env.VITE_APP_ENV === "development"
-          ? "http://localhost:7005"
+          ? "http://1.15.17.182:9003"
           : env.VITE_BASE_API;
   const javaUrl =
       env.VITE_APP_ENV === "development"

--
Gitblit v1.9.3