From 2b8c32366a2916dfbeac269eea94b2e6ef65f556 Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期二, 20 一月 2026 14:40:23 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/views/collaborativeApproval/notificationManagement/summary/index.vue           |    8 
 src/views/financialManagement/accounting/index.vue                                 |  197 
 src/views/personnelManagement/payrollManagement/components/formDia.vue             |   14 
 src/views/personnelManagement/payrollManagement/index.vue                          |    1 
 src/views/personnelManagement/scheduling/index.vue                                 |   10 
 src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue       |    1 
 src/views/personnelManagement/contractManagement/index.vue                         |    2 
 src/views/equipmentManagement/ledger/Form.vue                                      |   74 
 src/views/collaborativeApproval/sealManagement/index.vue                           |    4 
 src/api/procurementManagement/paymentLedger.js                                     |    7 
 src/views/personnelManagement/contractManagement/components/formDia.vue            |   34 
 src/views/inventoryManagement/receiptManagement/index.vue                          |  997 +++---
 src/views/personnelManagement/employeeRecord/components/RenewContract.vue          |  141 
 src/views/qualityManagement/metricMaintenance/index.vue                            |   83 
 src/views/equipmentManagement/ledger/index.vue                                     |   67 
 src/views/equipmentManagement/upkeep/index.vue                                     |   55 
 src/views/qualityManagement/processInspection/components/formDia.vue               |  180 +
 src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue       |    8 
 src/views/procurementManagement/procurementLedger/fileList.vue                     |   67 
 src/views/equipmentManagement/repair/Modal/MaintainModal.vue                       |  115 
 src/views/reportAnalysis/projectProfit/index.vue                                   |  186 
 src/views/personnelManagement/employeeRecord/index.vue                             |   25 
 src/views/equipmentManagement/repair/Modal/RepairModal.vue                         |  190 +
 src/api/qualityManagement/metricMaintenance.js                                     |   14 
 src/views/procurementManagement/procurementLedger/index.vue                        | 3098 ++++++++++++---------
 src/views/productionManagement/productionReporting/index.vue                       |   17 
 src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue       |    8 
 src/views/qualityManagement/rawMaterialInspection/components/formDia.vue           |  109 
 src/views/productionManagement/productionOrder/index.vue                           |    2 
 src/views/inventoryManagement/receiptManagement/components/formDia.vue             |  400 ++
 src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue                     |  123 
 src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue |    1 
 src/views/equipmentManagement/upkeep/Form/PlanModal.vue                            |  188 +
 src/views/reportAnalysis/dataDashboard/index.vue                                   |  596 +++
 src/views/productionManagement/productionDispatching/components/formDia.vue        |    1 
 src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue      |  302 ++
 src/views/salesManagement/salesLedger/index.vue                                    |  116 
 src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue   |   12 
 src/views/personnelManagement/selfService/index.vue                                |   12 
 src/views/qualityManagement/metricBinding/index.vue                                |   36 
 src/api/personnelManagement/employeeRecord.js                                      |   27 
 src/views/qualityManagement/processInspection/components/inspectionFormDia.vue     |    1 
 src/views/collaborativeApproval/enterpriseBook/index.vue                           |    6 
 src/views/qualityManagement/finalInspection/components/formDia.vue                 |  112 
 src/views/productionManagement/productionCosting/index.vue                         |    2 
 src/views/equipmentManagement/repair/index.vue                                     |   48 
 src/components/PIMTable/PIMTable.vue                                               |    4 
 src/views/qualityManagement/finalInspection/components/filesDia.vue                |    1 
 /dev/null                                                                          |  280 -
 src/views/personnelManagement/dimission/components/formDia.vue                     |  181 
 src/views/lavorissue/ledger/Form.vue                                               |   10 
 src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue       |   55 
 src/api/personnelManagement/staffLeave.js                                          |   33 
 src/api/personnelManagement/staffOnJob.js                                          |   11 
 src/views/equipmentManagement/upkeep/Form/formDia.vue                              |  304 ++
 src/views/personnelManagement/contractManagement/filesDia.vue                      |   10 
 src/views/personnelManagement/dimission/index.vue                                  |   58 
 src/api/financialManagement/accounting.js                                          |   28 
 src/views/productionManagement/productionReporting/components/formDia.vue          |    1 
 59 files changed, 5,857 insertions(+), 2,816 deletions(-)

diff --git a/src/api/financialManagement/accounting.js b/src/api/financialManagement/accounting.js
new file mode 100644
index 0000000..69bc7cd
--- /dev/null
+++ b/src/api/financialManagement/accounting.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
+export const getAccountingTotal = (params) => {
+  return request({
+    url: "/accounting/total",
+    method: "get",
+    params,
+  });
+};
+
+// 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+export const getDeviceTypeDistribution = (params) => {
+  return request({
+    url: "/accounting/deviceTypeDistribution",
+    method: "get",
+    params,
+  });
+};
+
+// 鑾峰彇鎶樻棫璁$畻鏁版嵁锛堣〃鏍兼暟鎹級
+export const getCalculateDepreciation = (params) => {
+  return request({
+    url: "/accounting/calculateDepreciation",
+    method: "get",
+    params,
+  });
+};
diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
new file mode 100644
index 0000000..a4ad34b
--- /dev/null
+++ b/src/api/personnelManagement/employeeRecord.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+    return request({
+        url: '/staff/staffOnJob/listPage',
+        method: 'get',
+        params: query,
+    })
+}
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function staffOnJobInfo(query) {
+    return request({
+        url: '/staff/staffOnJob/staffNo',
+        method: 'get',
+        params: query,
+    })
+}
+
+// 瀵煎嚭鍚堝悓鍓湰
+export function staffOnJobExportCopy(data) {
+    return request({
+        url: '/staff/staffOnJob/exportCopy',
+        method: 'post',
+        data: data,
+    })
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/onboarding.js b/src/api/personnelManagement/onboarding.js
deleted file mode 100644
index 39dbf22..0000000
--- a/src/api/personnelManagement/onboarding.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ浜哄憳鍏ヨ亴鍒楄〃
-export function staffJoinListPage(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/listPage",
-    method: "get",
-    params: query,
-  });
-}
-// 鏂板浜哄憳鍏ヨ亴
-export function staffJoinAdd(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/add",
-    method: "post",
-    data: query,
-  });
-}
-// 淇敼浜哄憳鍏ヨ亴
-export function staffJoinUpdate(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/update",
-    method: "post",
-    data: query,
-  });
-}
-// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
-export function getStaffJoinInfo(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/" + query,
-    method: "get",
-    data: query,
-  });
-}
-// 鍒犻櫎鍛樺伐
-export function staffJoinDel(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/del",
-    method: "delete",
-    data: query,
-  });
-}
-
-export function getStaffOnJob() {
-  return request({
-    url: "/staff/staffOnJob/list",
-    method: "get",
-  });
-}
diff --git a/src/api/personnelManagement/staffLeave.js b/src/api/personnelManagement/staffLeave.js
new file mode 100644
index 0000000..d675996
--- /dev/null
+++ b/src/api/personnelManagement/staffLeave.js
@@ -0,0 +1,33 @@
+import request from "@/utils/request.js";
+
+export function findStaffLeaveListPage(query) {
+    return request({
+        url: "/staff/staffLeave/listPage",
+        method: "get",
+        params: query,
+    });
+}
+
+export function createStaffLeave(data) {
+    return request({
+        url: "/staff/staffLeave",
+        method: "post",
+        data: data,
+    });
+}
+
+export function updateStaffLeave(id, data) {
+    return request({
+        url: "/staff/staffLeave/" + id,
+        method: "put",
+        data: data,
+    });
+}
+
+export function batchDeleteStaffLeaves(data) {
+    return request({
+        url: "/staff/staffLeave/del",
+        method: "delete",
+        data: data,
+    });
+}
diff --git a/src/api/personnelManagement/staffOnJob.js b/src/api/personnelManagement/staffOnJob.js
index ba26878..7da5469 100644
--- a/src/api/personnelManagement/staffOnJob.js
+++ b/src/api/personnelManagement/staffOnJob.js
@@ -42,4 +42,13 @@
         method: "delete",
         data: query,
     });
-}
\ No newline at end of file
+}
+
+// 缁鍚堝悓
+export function renewContract(id, params) {
+    return request({
+        url: "/staff/staffOnJob/renewContract/" + id,
+        method: "post",
+        data: params,
+    });
+}
diff --git a/src/api/procurementManagement/paymentLedger.js b/src/api/procurementManagement/paymentLedger.js
index a6de8bc..3e20b78 100644
--- a/src/api/procurementManagement/paymentLedger.js
+++ b/src/api/procurementManagement/paymentLedger.js
@@ -4,17 +4,16 @@
 // 鍒嗛〉鏌ヨ
 export function paymentLedgerList(query) {
   return request({
-    url: "/purchase/paymentRegistration/supplierNameListPage",
+    url: "/purchase/paymentRegistration/paymentLedgerList",
     method: "get",
     params: query,
   });
 }
 
 // 鍒嗛〉鏌ヨ
-export function paymentRecordList(query) {
+export function paymentRecordList(supplierId) {
   return request({
-    url: "/purchase/paymentRegistration/supplierNameListPageDetails",
+    url: "/purchase/paymentRegistration/getPaymentRecordList/" + supplierId,
     method: "get",
-    params: query,
   });
 }
diff --git a/src/api/qualityManagement/metricMaintenance.js b/src/api/qualityManagement/metricMaintenance.js
index 53ca650..1ee9cad 100644
--- a/src/api/qualityManagement/metricMaintenance.js
+++ b/src/api/qualityManagement/metricMaintenance.js
@@ -37,10 +37,11 @@
 }
 
 // 鍒犻櫎鎸囨爣鍒楄〃
-export function qualityInspectDetailByProductId(productId) {
+export function qualityInspectDetailByProductId(params) {
   return request({
-    url: "/qualityTestStandard/product/" + productId,
+    url: "/qualityTestStandard/getQualityTestStandardByProductId",
     method: "get",
+    params: params,
   });
 }
 
@@ -98,3 +99,12 @@
     data: ids,
   });
 }
+
+// 鏍规嵁鏍囧噯ID鑾峰彇鏍囧噯鍙傛暟
+export function getQualityTestStandardParamByTestStandardId(testStandardId) {
+  return request({
+    url: "/qualityTestStandard/getQualityTestStandardParamByTestStandardId",
+    method: "get",
+    params: { testStandardId },
+  });
+}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 1480893..dfbc231 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -130,7 +130,7 @@
         </div>
 
         <!-- 鎸夐挳 -->
-        <div v-else-if="item.dataType == 'action'">
+        <div v-else-if="item.dataType == 'action'" @click.stop>
           <template v-for="(o, key) in item.operation" :key="key">
             <el-button
               v-show="o.type != 'upload'"
@@ -145,7 +145,7 @@
                     : o.color,
               }"
               link
-              @click="o.clickFun(scope.row)"
+              @click.stop="o.clickFun(scope.row)"
               :key="key"
             >
               {{ o.name }}
diff --git a/src/views/collaborativeApproval/enterpriseBook/index.vue b/src/views/collaborativeApproval/enterpriseBook/index.vue
index 0b33a32..fa9fa5c 100644
--- a/src/views/collaborativeApproval/enterpriseBook/index.vue
+++ b/src/views/collaborativeApproval/enterpriseBook/index.vue
@@ -295,7 +295,6 @@
   getEmployeeDetail
 } from '@/api/collaborativeApproval/enterpriseBook.js'
 import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
 import {
   changeUserStatus,
   listUser,
@@ -306,6 +305,7 @@
   addUser,
   deptTreeSelect,
 } from "@/api/system/user";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏍囩椤电姸鎬�
 const activeTab = ref('personal')
@@ -395,7 +395,7 @@
 }
   //鑾峰彇鍛樺伐鍒楄〃
 const getEmployeeList = async () => {
-  staffJoinListPage(publicSearch.value).then(res => {
+  staffOnJobListPage(Object.assign({current: -1, size: -1},publicSearch.value)).then(res => {
     console.log(res.data.records)
       EmployeeList.value = res.data.records
     }).catch(err => {})
@@ -403,7 +403,7 @@
 // 鑾峰彇鍗曚綅閫氳褰曞垪琛�
 const getCompanyContactsList = async () => {
   loading.value = true
-    staffJoinListPage(companySearch.value).then(res => {
+  staffOnJobListPage(Object.assign({current: -1, size: -1},companySearch.value)).then(res => {
     // console.log(res.data.records)
       companyContacts.value = res.data.records
     }).catch(err => {})
diff --git a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
index 7781593..ed2dafa 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
@@ -127,7 +127,7 @@
             <el-option
                 v-for="person in employees"
                 :key="person.id"
-                :label="`${person.staffName} (${person.postJob})`"
+                :label="`${person.staffName} (${person.postName})`"
                 :value="person.id"
             />
           </el-select>
@@ -156,7 +156,7 @@
 import {ElMessage} from 'element-plus'
 import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue'
 import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 褰撳墠鐢宠绫诲瀷
 const currentType = ref('department') // approval: 瀹℃壒娴佺▼, department: 閮ㄩ棬绾�, notification: 閫氱煡鍙戝竷
@@ -302,8 +302,12 @@
   getRoomEnum().then(res => {
     meetingRooms.value = res.data
   })
-  getStaffOnJob().then(res => {
-    employees.value = res.data.sort((a, b) => a.postJob.localeCompare(b.postJob))
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    employees.value = res.data.records.sort((a, b) => a.postName.localeCompare(b.postName))
   })
 })
 </script>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
index 83747a0..157b6b5 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
@@ -188,8 +188,8 @@
 import {ElMessage, ElMessageBox} from 'element-plus'
 import Pagination from '@/components/Pagination/index.vue'
 import {getRoomEnum, getExamineList,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -240,7 +240,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -342,9 +342,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
index 2351293..a85de7f 100644
--- a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
@@ -186,8 +186,8 @@
 import {ElMessage, ElMessageBox} from 'element-plus'
 import Pagination from '@/components/Pagination/index.vue'
 import {getRoomEnum, getMeetingPublish,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -239,7 +239,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -340,9 +340,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2]= await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/notificationManagement/summary/index.vue b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
index a00316d..f94e548 100644
--- a/src/views/collaborativeApproval/notificationManagement/summary/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
@@ -160,8 +160,8 @@
 import Pagination from '@/components/Pagination/index.vue'
 import Editor from '@/components/Editor/index.vue'
 import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js'
-import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js"
 import dayjs from "dayjs"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鏁版嵁鍒楄〃鍔犺浇鐘舵��
 const loading = ref(false)
@@ -214,7 +214,7 @@
     it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => {
       return {
         id: staff.id,
-        name: `${staff.staffName}(${staff.postJob})`
+        name: `${staff.staffName}(${staff.postName})`
       }
     })
 
@@ -337,9 +337,9 @@
 
 // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
 onMounted(async () => {
-  const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()])
+  const [resp1, resp2] = await Promise.all([getRoomEnum(), staffOnJobListPage({current: -1, size: -1, staffState: 1})])
   roomEnum.value = resp1.data
-  staffList.value = resp2.data
+  staffList.value = resp2.data.records
 
   await getList()
 })
diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
index 8e0d054..9f70a55 100644
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ b/src/views/collaborativeApproval/sealManagement/index.vue
@@ -261,9 +261,9 @@
 import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus  } from '@/api/collaborativeApproval/sealManagement.js'
 import { el } from 'element-plus/es/locales.mjs'
 import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js'
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
 import useUserStore from '@/store/modules/user'
 import { userLoginFacotryList } from "@/api/system/user.js"
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const currentUser = ref(null)
@@ -583,7 +583,7 @@
       currentUser.value = res.data.userName
     }
   })
-  staffJoinListPage({staffState: 1, ...page}).then(res => {
+  staffOnJobListPage({staffState: 1, ...page}).then(res => {
     tableLoading.value = false;
     // tableData.value = res.data.records
     // //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index d14f4ff..f85a7fa 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+  <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
     <el-row :gutter="20">
       <el-col :span="12">
         <el-form-item label="璁惧鍚嶇О" prop="deviceName">
@@ -14,6 +14,27 @@
       <el-col :span="12">
         <el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
           <el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璁惧绫诲瀷" prop="type">
+          <el-select
+            v-model="form.type"
+            placeholder="璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�"
+            clearable
+            filterable
+            allow-create
+            default-first-option
+            style="width: 100%"
+            @change="handleDeviceTypeChange"
+          >
+            <el-option
+              v-for="item in deviceTypeOptions"
+              :key="item"
+              :label="item"
+              :value="item"
+            />
+          </el-select>
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -32,8 +53,19 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
-          <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
+        <el-form-item label="鍚敤鎶樻棫" prop="isDepr">
+          <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12" v-if="form.isDepr === 1">
+        <el-form-item label="姣忓勾鎶樻棫閲戦" prop="annualDepreciationAmount">
+          <el-input-number 
+            :step="0.01" 
+            :min="0" 
+            style="width: 100%"
+            v-model="form.annualDepreciationAmount"
+            placeholder="璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�"
+          />
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -149,24 +181,47 @@
 });
 const formRef = ref(null);
 const operationType = ref('');
+// 璁惧绫诲瀷鍥哄畾閫夐」
+const deviceTypeOptions = ref([
+  '鐢熶骇璁惧',
+  '鍔炲叕璁惧',
+  '妫�娴嬭澶�',
+  '杩愯緭璁惧',
+  '鍏朵粬璁惧'
+]);
 const formRules = {
 	deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+	type: [{ required: true, trigger: "change", message: "璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�" }],
 	supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
 	planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+	annualDepreciationAmount: [
+		{ 
+			validator: (rule, value, callback) => {
+				if (form.isDepr === 1 && (value === undefined || value === null || value === '')) {
+					callback(new Error('鍚敤鎶樻棫鏃讹紝璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�'));
+				} else {
+					callback();
+				}
+			}, 
+			trigger: "blur" 
+		}
+	],
 }
 
 const { form, resetForm } = useFormData({
   deviceName: undefined, // 璁惧鍚嶇О
   deviceModel: undefined, // 瑙勬牸鍨嬪彿
   deviceBrand: undefined, // 璁惧鍝佺墝
+  type: undefined, // 璁惧绫诲瀷
   supplierName: undefined, // 渚涘簲鍟�
   storageLocation: undefined, // 瀛樻斁浣嶇疆
-  enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
+  isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
+  annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
   unit: undefined, // 鍗曚綅
   number: 1, // 鏁伴噺
   taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
@@ -187,9 +242,11 @@
     form.deviceName = data.deviceName;
     form.deviceModel = data.deviceModel;
     form.deviceBrand = data.deviceBrand;
+    form.type = data.type;
     form.supplierName = data.supplierName;
     form.storageLocation = data.storageLocation;
-    form.enableDepreciation = data.enableDepreciation;
+    form.isDepr = data.isDepr;
+    form.annualDepreciationAmount = data.annualDepreciationAmount;
     form.unit = data.unit;
     form.number = 1;
     form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
@@ -200,6 +257,13 @@
   }
 };
 
+const handleDeviceTypeChange = (value) => {
+  // 濡傛灉杈撳叆鐨勬柊鍊间笉鍦ㄥ浐瀹氶�夐」涓紝鍒欐坊鍔犲埌閫夐」鍒楄〃
+  if (value && !deviceTypeOptions.value.includes(value)) {
+    deviceTypeOptions.value.push(value);
+  }
+};
+
 const mathNum = () => {
   if (!form.taxIncludingPriceUnit) {
     ElMessage.error("璇疯緭鍏ュ崟浠�");
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 8cdbf32..62f0c6a 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -7,7 +7,6 @@
           style="width: 240px"
           placeholder="璇疯緭鍏ヨ澶囧悕绉�"
           clearable
-          :prefix-icon="Search"
           @change="getTableData"
         />
       </el-form-item>
@@ -17,7 +16,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -27,17 +25,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ヤ緵搴斿晢"
             clearable
-            :prefix-icon="Search"
-            @change="getTableData"
-        />
-      </el-form-item>
-      <el-form-item label="鍗曚綅">
-        <el-input
-            v-model="filters.unit"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ュ崟浣�"
-            clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -130,81 +117,53 @@
     deviceName: undefined,
     deviceModel: undefined,
     supplierName: undefined,
-    unit: undefined,
     entryDateStart: undefined,
     entryDateEnd: undefined,
   },
   [
     {
       label: "璁惧鍚嶇О",
-      align: "center",
       prop: "deviceName",
     },
     {
       label: "瑙勬牸鍨嬪彿",
-      align: "center",
       prop: "deviceModel",
     },
     {
       label: "璁惧鍝佺墝",
-      align: "center",
       prop: "deviceBrand",
     },
     {
+      label: "璁惧绫诲瀷",
+      prop: "type",
+    },
+    {
       label: "渚涘簲鍟�",
-      align: "center",
       prop: "supplierName",
     },
     {
-      label: "鍗曚綅",
-      align: "center",
-      prop: "unit",
-    },
-    {
       label: "瀛樻斁浣嶇疆",
-      align: "center",
       prop: "storageLocation",
     },
     {
       label: "鏁伴噺",
-      align: "center",
       prop: "number",
     },
     {
-      label: "鍚◣鍗曚环",
-      align: "center",
-      prop: "taxIncludingPriceUnit",
-    },
-    {
-      label: "鍚◣鎬讳环",
-      align: "center",
-      prop: "taxIncludingPriceTotal",
-    },
-    {
-      label: "绋庣巼",
-      align: "center",
-      prop: "taxRate",
-    },
-    {
-      label: "涓嶅惈绋庢�讳环",
-      align: "center",
-      prop: "unTaxIncludingPriceTotal",
-    },
-    {
-      label: "鍚敤鎶樻棫",
-      align: "center",
-      prop: "enableDepreciation",
-      formatData: (v) => (v ? "鏄�" : "鍚�"),
-    },
-    {
       label: "褰曞叆浜�",
-      align: "center",
       prop: "createUser",
     },
     {
       label: "褰曞叆鏃ユ湡",
-      align: "center",
       prop: "createTime",
+      formatData: (v) => {
+        if (!v) return '';
+        // 濡傛灉鍖呭惈鏃跺垎绉掞紝鍙彇鏃ユ湡閮ㄥ垎
+        if (v.includes(' ')) {
+          return v.split(' ')[0];
+        }
+        return v;
+      },
     },
 		{
 			dataType: "action",
@@ -215,14 +174,12 @@
 			operation: [
 				{
 					name: "缂栬緫",
-					type: "text",
 					clickFun: (row) => {
 						edit(row.id)
 					},
 				},
 				{
 					name: "鐢熸垚浜岀淮鐮�",
-					type: "text",
 					clickFun: (row) => {
 						showQRCode(row)
 					},
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
deleted file mode 100644
index 2a64d3f..0000000
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-<template>
-  <el-form :model="form" label-width="80px">
-    <el-form-item label="缁翠慨浜�">
-      <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
-    </el-form-item>
-    <el-form-item label="缁翠慨缁撴灉">
-      <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
-    </el-form-item>
-    <el-form-item label="鎶ヤ慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呮姤淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="缁翠慨鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceTime"
-        placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
-  name: "璁惧缁翠慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceName: undefined, // 缁翠慨鍚嶇О
-  maintenanceResult: undefined, // 缁翠慨缁撴灉
-  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
-  status: 0,
-});
-
-const setForm = (data) => {
-  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
-  form.maintenanceResult = data.maintenanceResult;
-  form.maintenanceTime =
-    dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Form/RepairForm.vue b/src/views/equipmentManagement/repair/Form/RepairForm.vue
deleted file mode 100644
index 6697906..0000000
--- a/src/views/equipmentManagement/repair/Form/RepairForm.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-row>
-      <el-col :span="12">
-        <el-form-item label="璁惧鍚嶇О">
-          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
-            <el-option
-              v-for="(item, index) in deviceOptions"
-              :key="index"
-              :label="item.deviceName"
-              :value="item.id"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="瑙勬牸鍨嬪彿">
-          <el-input
-            v-model="form.deviceModel"
-            placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-            disabled
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鏃ユ湡">
-          <el-date-picker
-            v-model="form.repairTime"
-            placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            type="date"
-            clearable
-            style="width: 100%"
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨浜�">
-          <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row v-if="id">
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鐘舵��">
-          <el-select v-model="form.status">
-            <el-option label="寰呯淮淇�" :value="0"></el-option>
-            <el-option label="瀹岀粨" :value="1"></el-option>
-            <el-option label="澶辫触" :value="2"></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row>
-      <el-col :span="24">
-        <el-form-item label="鏁呴殰鐜拌薄">
-          <el-input
-            v-model="form.remark"
-            :rows="2"
-            type="textarea"
-            placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
-          />
-        </el-form-item>
-      </el-col>
-    </el-row>
-  </el-form>
-</template>
-
-<script setup>
-import dayjs from "dayjs";
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import useUserStore from "@/store/modules/user";
-
-const { id } = defineProps(["id"])
-
-defineOptions({
-  name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const deviceOptions = ref([]);
-
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
-  repairName: userStore.nickName, // 鎶ヤ慨浜�
-  remark: undefined, // 鏁呴殰鐜拌薄
-  status: 0, // 鎶ヤ慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.repairTime = data.repairTime;
-  form.repairName = data.repairName;
-  form.remark = data.remark;
-  form.status = data.status;
-};
-
-// onMounted(() => {
-//   loadDeviceName();
-// });
-
-defineExpose({
-  loadDeviceName,
-  resetForm,
-  getForm,
-  setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index a578a58..496b072 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,53 +1,108 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintainForm ref="maintainFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧缁翠慨'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="80px">
+      <el-form-item label="缁翠慨浜�">
+        <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
+      </el-form-item>
+      <el-form-item label="缁翠慨缁撴灉">
+        <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
+      </el-form-item>
+      <el-form-item label="缁翠慨鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呮姤淇�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="缁翠慨鏃ユ湡">
+        <el-date-picker
+          v-model="form.maintenanceTime"
+          placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import MaintainForm from "../Form/MaintainForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import { addMaintain } from "@/api/equipmentManagement/repair";
+import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
 
 defineOptions({
   name: "缁翠慨妯℃�佹",
 });
 
-const maintainFormRef = ref();
 const emits = defineEmits(["ok"]);
 
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧缁翠慨" });
+// 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+const repairId = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const { form, resetForm } = useFormData({
+  maintenanceName: undefined, // 缁翠慨鍚嶇О
+  maintenanceResult: undefined, // 缁翠慨缁撴灉
+  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
+  status: 0,
+});
+
+const setForm = (data) => {
+  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
+  form.maintenanceResult = data.maintenanceResult;
+  form.maintenanceTime =
+    data.maintenanceTime 
+      ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
 
 const sendForm = async () => {
   loading.value = true;
-  const form = await maintainFormRef.value.getForm();
-  const { code } = await addMaintain({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintainFormRef.value.resetForm();
-    closeModal();
+  try {
+    const { code } = await addMaintain({ id: repairId.value, ...form });
+    if (code == 200) {
+      ElMessage.success("缁翠慨鎴愬姛");
+      emits("ok");
+      resetForm();
+      visible.value = false;
+    }
+  } finally {
+    loading.value = false;
   }
-  loading.value = false;
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const open = async (id, row) => {
-  openModal(id);
+  repairId.value = id; // 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+  visible.value = true;
   await nextTick();
-  maintainFormRef.value.setForm(row);
+  setForm(row);
 };
 
 defineExpose({
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index c21b47a..1aa82ec 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,24 +1,93 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable>
-    <RepairForm ref="repairFormRef" :id="id" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧鎶ヤ慨' : '鏂板璁惧鎶ヤ慨'"
+    width="800px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="璁惧鍚嶇О">
+            <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
+              <el-option
+                v-for="(item, index) in deviceOptions"
+                :key="index"
+                :label="item.deviceName"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瑙勬牸鍨嬪彿">
+            <el-input
+              v-model="form.deviceModel"
+              placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+              disabled
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鏃ユ湡">
+            <el-date-picker
+              v-model="form.repairTime"
+              placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              type="date"
+              clearable
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨浜�">
+            <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="id">
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鐘舵��">
+            <el-select v-model="form.status">
+              <el-option label="寰呯淮淇�" :value="0"></el-option>
+              <el-option label="瀹岀粨" :value="1"></el-option>
+              <el-option label="澶辫触" :value="2"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="鏁呴殰鐜拌薄">
+            <el-input
+              v-model="form.remark"
+              :rows="2"
+              type="textarea"
+              placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import RepairForm from "../Form/RepairForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import {
   addRepair,
   editRepair,
   getRepairById,
 } from "@/api/equipmentManagement/repair";
 import { ElMessage } from "element-plus";
+import dayjs from "dayjs";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import useUserStore from "@/store/modules/user";
 
 defineOptions({
   name: "璁惧鎶ヤ慨寮圭獥",
@@ -26,48 +95,83 @@
 
 const emits = defineEmits(["ok"]);
 
-const repairFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧鎶ヤ慨" });
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const userStore = useUserStore();
+const deviceOptions = ref([]);
+
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
+  repairName: userStore.nickName, // 鎶ヤ慨浜�
+  remark: undefined, // 鏁呴殰鐜拌薄
+  status: 0, // 鎶ヤ慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.repairTime = data.repairTime;
+  form.repairName = data.repairName;
+  form.remark = data.remark;
+  form.status = data.status;
+};
 
 const sendForm = async () => {
   loading.value = true;
-  const form = await repairFormRef.value.getForm();
-  const { code } = id.value
-    ? await editRepair({ id: unref(id), ...form })
-    : await addRepair(form);
-  if (code == 200) {
-    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
-    closeModal();
-    emits("ok");
+  try {
+    const { code } = id.value
+      ? await editRepair({ id: unref(id), ...form })
+      : await addRepair(form);
+    if (code == 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
   }
-  loading.value = false;
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const openAdd = async () => {
-  openModal();
+  id.value = undefined;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
+  await loadDeviceName();
 };
 
-const openEdit = async (id) => {
-  const { data } = await getRepairById(id);
-  openModal(id);
+const openEdit = async (editId) => {
+  const { data } = await getRepairById(editId);
+  id.value = editId;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
-  await repairFormRef.value.setForm(data);
-};
-
-const close = () => {
-  repairFormRef.value.resetForm();
-  closeModal();
+  await loadDeviceName();
+  setForm(data);
 };
 
 defineExpose({
@@ -75,3 +179,5 @@
   openEdit,
 });
 </script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 08cbcc2..477e880 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -68,14 +68,6 @@
       <div class="actions">
         <el-text class="mx-1" size="large">璁惧鎶ヤ慨</el-text>
         <div>
-          <el-button
-            type="primary"
-            icon="Plus"
-            :disabled="multipleList.length !== 1"
-            @click="addMaintain"
-          >
-            鏂板缁翠慨
-          </el-button>
           <el-button type="success" icon="Van" @click="addRepair">
             鏂板鎶ヤ慨
           </el-button>
@@ -85,7 +77,7 @@
           <el-button
             type="danger"
             icon="Delete"
-            :disabled="multipleList.length <= 0"
+            :disabled="multipleList.length <= 0 || hasFinishedStatus"
             @click="delRepairByIds(multipleList.map((item) => item.id))"
           >
             鎵归噺鍒犻櫎
@@ -113,16 +105,24 @@
         <template #operation="{ row }">
           <el-button
             type="primary"
-            text
-            icon="editPen"
+            link
+            :disabled="row.status === 1"
             @click="editRepair(row.id)"
           >
             缂栬緫
           </el-button>
           <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            缁翠慨
+          </el-button>
+          <el-button
             type="danger"
-            text
-            icon="delete"
+            link
+            :disabled="row.status === 1"
             @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
@@ -138,7 +138,7 @@
 <script setup>
 import { usePaginationApi } from "@/hooks/usePaginationApi";
 import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
-import { onMounted, getCurrentInstance } from "vue";
+import { onMounted, getCurrentInstance, computed } from "vue";
 import RepairModal from "./Modal/RepairModal.vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import dayjs from "dayjs";
@@ -258,6 +258,11 @@
   multipleList.value = selectionList;
 };
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 // 鏂板鎶ヤ慨
 const addRepair = () => {
   repairModalRef.value.openAdd();
@@ -269,8 +274,7 @@
 };
 
 // 鏂板缁翠慨
-const addMaintain = () => {
-  const row = multipleList.value[0];
+const addMaintain = (row) => {
   maintainModalRef.value.open(row.id, row);
 };
 
@@ -282,6 +286,18 @@
 
 // 鍗曡鍒犻櫎
 const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const idsArray = Array.isArray(ids) ? ids : [ids];
+  const hasFinished = idsArray.some(id => {
+    const record = dataList.value.find(item => item.id === id);
+    return record && record.status === 1;
+  });
+  
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�');
+    return;
+  }
+  
   ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
     confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
deleted file mode 100644
index 3aa0867..0000000
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="瀹為檯淇濆吇浜�">
-      <el-input
-        v-model="form.maintenanceActuallyName"
-        placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
-      ></el-input>
-    </el-form-item>
-    <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceActuallyTime"
-        placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-    <el-form-item label="淇濆吇鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚鍏�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="淇濆吇缁撴灉">
-      <!-- <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
-        <el-option label="瀹屽ソ" :value="1"></el-option>
-        <el-option label="缁翠慨" :value="0"></el-option>
-      </el-select> -->
-      <el-input
-        v-model="form.maintenanceResult"
-        placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
-        type="text" />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
-  name: "淇濆吇琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
-  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
-  maintenanceResult: undefined, // 淇濆吇缁撴灉
-  status: 0, // 淇濆吇鐘舵��
-});
-
-const setForm = (data) => {
-  form.maintenanceActuallyName =
-    data.maintenanceActuallyName ?? userStore.nickName;
-  form.maintenanceActuallyTime =
-    dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-  form.maintenanceResult = data.maintenanceResult;
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
new file mode 100644
index 0000000..c660840
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -0,0 +1,123 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧淇濆吇'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-form-item label="瀹為檯淇濆吇浜�">
+        <el-input
+          v-model="form.maintenanceActuallyName"
+          placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
+        <el-date-picker
+          v-model="form.maintenanceActuallyTime"
+          placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+      <el-form-item label="淇濆吇鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚鍏�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="淇濆吇缁撴灉">
+        <el-input
+          v-model="form.maintenanceResult"
+          placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
+          type="text" />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "淇濆吇妯℃�佹",
+});
+
+const emits = defineEmits(["ok"]);
+
+// 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+const planId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const userStore = useUserStore();
+
+const { form, resetForm } = useFormData({
+  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+  maintenanceResult: undefined, // 淇濆吇缁撴灉
+  status: 0, // 淇濆吇鐘舵��
+});
+
+const setForm = (data) => {
+  form.maintenanceActuallyName =
+    data.maintenanceActuallyName ?? userStore.nickName;
+  form.maintenanceActuallyTime =
+    data.maintenanceActuallyTime 
+      ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.maintenanceResult = data.maintenanceResult;
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
+
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    const { code } = await addMaintenance({ id: planId.value, ...form });
+    if (code == 200) {
+      ElMessage.success("淇濆吇鎴愬姛");
+      emits("ok");
+      resetForm();
+      visible.value = false;
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const open = async (id, row) => {
+  planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+  visible.value = true;
+  await nextTick();
+  setForm(row);
+};
+
+defineExpose({
+  open,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
deleted file mode 100644
index 2822e2c..0000000
--- a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="璁惧鍚嶇О">
-      <el-select
-        v-model="form.deviceLedgerId"
-        @change="setDeviceModel"
-        placeholder="璇烽�夋嫨璁惧"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-      >
-        <el-option
-          v-for="(item, index) in deviceOptions"
-          :key="index"
-          :label="item.deviceName"
-          :value="item.id"
-        ></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="瑙勬牸鍨嬪彿">
-      <el-input
-        v-model="form.deviceModel"
-        placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-        disabled
-      />
-    </el-form-item>
-    <el-form-item label="褰曞叆浜�">
-      <el-select
-        v-model="form.createUser"
-        placeholder="璇烽�夋嫨"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-        clearable
-      >
-        <el-option
-          v-for="item in userList"
-          :key="item.userId"
-          :label="item.nickName"
-          :value="item.userId"
-        />
-      </el-select>
-    </el-form-item>
-    <el-form-item v-if="id" label="淇濅慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="璁″垝淇濆吇鏃ユ湡">
-      <el-date-picker
-        style="width: 100%"
-        v-model="form.maintenancePlanTime"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="date"
-        placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
-        clearable
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-import { userListNoPage } from "@/api/system/user.js";
-
-defineOptions({
-  name: "璁″垝琛ㄥ崟",
-});
-
-const deviceOptions = ref([]);
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const { id } = defineProps(['id']);
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
-  createUser: undefined, // 褰曞叆浜�
-  status: 0, //淇濅慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.createUser = Number(data.createUser);
-  form.status = data.status;
-  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
-    "YYYY-MM-DD HH:mm:ss"
-  );
-};
-
-// 鐢ㄦ埛鍒楄〃
-const userList = ref([]);
-
-const loadForm = () => {};
-
-onMounted(() => {
-  loadDeviceName();
-  userListNoPage().then((res) => {
-    userList.value = res.data;
-  });
-});
-
-defineExpose({
-  loadForm,
-  resetForm,
-  getForm,
-  setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
new file mode 100644
index 0000000..19095b9
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -0,0 +1,188 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧淇濆吇璁″垝' : '鏂板璁惧淇濆吇璁″垝'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-form-item label="璁惧鍚嶇О">
+        <el-select
+          v-model="form.deviceLedgerId"
+          @change="setDeviceModel"
+          placeholder="璇烽�夋嫨璁惧"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+        >
+          <el-option
+            v-for="(item, index) in deviceOptions"
+            :key="index"
+            :label="item.deviceName"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瑙勬牸鍨嬪彿">
+        <el-input
+          v-model="form.deviceModel"
+          placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+          disabled
+        />
+      </el-form-item>
+      <el-form-item label="褰曞叆浜�">
+        <el-select
+          v-model="form.createUser"
+          placeholder="璇烽�夋嫨"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+          clearable
+        >
+          <el-option
+            v-for="item in userList"
+            :key="item.userId"
+            :label="item.nickName"
+            :value="item.userId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="id" label="淇濅慨鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚淇�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璁″垝淇濆吇鏃ユ湡">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.maintenancePlanTime"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="date"
+          placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import {
+  addUpkeep,
+  editUpkeep,
+  getUpkeepById,
+} from "@/api/equipmentManagement/upkeep";
+import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted } from "vue";
+import dayjs from "dayjs";
+import { userListNoPage } from "@/api/system/user.js";
+
+defineOptions({
+  name: "璁惧淇濆吇鏂板璁″垝",
+});
+
+const emits = defineEmits(["ok"]);
+
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const deviceOptions = ref([]);
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
+  createUser: undefined, // 褰曞叆浜�
+  status: 0, //淇濅慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+/**
+ * @desc 璁剧疆琛ㄥ崟鍐呭
+ * @param data 璁惧淇℃伅
+ */
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.createUser = Number(data.createUser);
+  form.status = data.status;
+  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+    "YYYY-MM-DD HH:mm:ss"
+  );
+};
+
+// 鐢ㄦ埛鍒楄〃
+const userList = ref([]);
+
+onMounted(() => {
+  loadDeviceName();
+  userListNoPage().then((res) => {
+    userList.value = res.data;
+  });
+});
+
+const openEdit = async (editId) => {
+  const { data } = await getUpkeepById(editId);
+  id.value = editId;
+  visible.value = true;
+  await nextTick();
+  setForm(data);
+};
+
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    const { code } = id.value
+      ? await editUpkeep({ id: unref(id), ...form })
+      : await addUpkeep(form);
+    if (code == 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const openModal = () => {
+  id.value = undefined;
+  visible.value = true;
+};
+
+defineExpose({
+  openModal,
+  openEdit,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/formDia.vue b/src/views/equipmentManagement/upkeep/Form/formDia.vue
new file mode 100644
index 0000000..66bf067
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -0,0 +1,304 @@
+<template>
+	<FormDialog
+		v-model="dialogVisitable"
+		:title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
+		width="800px"
+		:operation-type="operationType"
+		@confirm="submitForm"
+		@cancel="cancel"
+		@close="cancel"
+	>
+		<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="璁惧鍚嶇О" prop="taskId">
+						<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
+							<el-option
+								v-for="(item, index) in deviceOptions"
+								:key="index"
+								:label="item.deviceName"
+								:value="item.id"
+							></el-option>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="瑙勬牸鍨嬪彿">
+						<el-input
+							v-model="form.deviceModel"
+							placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="褰曞叆浜�" prop="inspector">
+						<el-select
+							v-model="form.inspector"
+							filterable
+							default-first-option
+							:reserve-keyword="false"
+							placeholder="璇烽�夋嫨"
+							clearable
+						>
+							<el-option
+								v-for="item in userList"
+								:label="item.nickName"
+								:value="item.userId"
+								:key="item.userId"
+							/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
+						<el-date-picker
+							v-model="form.registrationDate"
+							type="date"
+							placeholder="閫夋嫨鐧昏鏃ユ湡"
+							format="YYYY-MM-DD"
+							value-format="YYYY-MM-DD"
+							style="width: 100%"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
+						<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
+							<el-option label="姣忔棩" value="DAILY"/>
+							<el-option label="姣忓懆" value="WEEKLY"/>
+							<el-option label="姣忔湀" value="MONTHLY"/>
+							<el-option label="瀛e害" value="QUARTERLY"/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+							<el-option label="鍛ㄤ竴" value="MON"/>
+							<el-option label="鍛ㄤ簩" value="TUE"/>
+							<el-option label="鍛ㄤ笁" value="WED"/>
+							<el-option label="鍛ㄥ洓" value="THU"/>
+							<el-option label="鍛ㄤ簲" value="FRI"/>
+							<el-option label="鍛ㄥ叚" value="SAT"/>
+							<el-option label="鍛ㄦ棩" value="SUN"/>
+						</el-select>
+						<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm"  style="width: 50%"/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="DD,HH:mm"
+							value-format="DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="MM,DD,HH:mm"
+							value-format="MM,DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="澶囨敞" prop="remarks">
+						<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+	</FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { reactive, ref, getCurrentInstance, toRefs } from "vue";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
+import { getCurrentDate } from "@/utils/index.js";
+import useUserStore from "@/store/modules/user.js";
+
+const { proxy } = getCurrentInstance()
+const emit = defineEmits()
+const dialogVisitable = ref(false);
+const operationType = ref('add');
+const deviceOptions = ref([]);
+const userStore = useUserStore();
+const data = reactive({
+	form: {
+		taskId: undefined,
+		taskName: undefined,
+		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
+		inspector: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined, // 瑙勬牸鍨嬪彿
+		registrationDate: ''
+	},
+	rules: {
+		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
+		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
+		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
+	}
+})
+const { form, rules } = toRefs(data)
+const userList = ref([])
+
+const loadDeviceName = async () => {
+	const { data } = await getDeviceLedger();
+	deviceOptions.value = data;
+};
+
+// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
+const setDeviceModel = (id) => {
+	const option = deviceOptions.value.find((item) => item.id === id);
+	if (option) {
+		form.value.taskId = option.id;
+		form.value.taskName = option.deviceName;
+		form.value.deviceModel = option.deviceModel;
+	}
+}
+
+// 鎵撳紑寮规
+const openDialog = async (type, row) => {
+	dialogVisitable.value = true
+	operationType.value = type
+	
+	// 閲嶇疆琛ㄥ崟
+	resetForm();
+	
+	// 鍔犺浇鐢ㄦ埛鍒楄〃
+	userListNoPageByTenantId().then((res) => {
+		userList.value = res.data;
+	});
+	
+	// 鍔犺浇璁惧鍒楄〃
+	await loadDeviceName();
+	
+	if (type === 'edit' && row) {
+		form.value = { ...row }
+		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
+		if (row.registrantId) {
+			form.value.inspector = row.registrantId
+		}
+
+		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
+		if (form.value.taskId) {
+			setDeviceModel(form.value.taskId);
+		}
+	} else if (type === 'add') {
+		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
+		form.value.registrationDate = getCurrentDate();
+		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
+		form.value.inspector = userStore.id;
+	}
+}
+
+// 鍏抽棴瀵硅瘽妗�
+const cancel = () => {
+	resetForm()
+	dialogVisitable.value = false
+	emit('closeDia')
+}
+
+// 閲嶇疆琛ㄥ崟鍑芥暟
+const resetForm = () => {
+	if (proxy.$refs.formRef) {
+		proxy.$refs.formRef.resetFields()
+	}
+	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
+	form.value = {
+		taskId: undefined,
+		taskName: undefined,
+		inspector: undefined,
+		inspector: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined,
+		registrationDate: ''
+	}
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(async valid => {
+		if (valid) {
+			try {
+				const payload = { ...form.value }
+				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
+				// 鏍规嵁閫夋嫨鐨�"褰曞叆浜�"璁剧疆 registrant / registrantId
+				if (payload.inspector) {
+					const selectedUser = userList.value.find(
+						(u) => String(u.userId) === String(payload.inspector)
+					)
+					if (selectedUser) {
+						payload.registrantId = selectedUser.userId
+						payload.registrant = selectedUser.nickName
+					}
+				}
+				delete payload.inspector
+				delete payload.inspectorIds
+				
+				if (payload.frequencyType === 'WEEKLY') {
+					let frequencyDetail = ''
+					frequencyDetail = payload.week + ',' + payload.time
+					payload.frequencyDetail = frequencyDetail
+				}
+				
+				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
+				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
+				if (payload.status === undefined || payload.status === null || payload.status === '') {
+					payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
+				}
+				payload.active = true
+				payload.deleted = 0
+				
+				if (operationType.value === 'edit') {
+					await deviceMaintenanceTaskEdit(payload)
+				} else {
+					await deviceMaintenanceTaskAdd(payload)
+				}
+				cancel()
+				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
+			} catch (error) {
+				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
+			}
+		}
+	})
+}
+defineExpose({ openDialog })
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
deleted file mode 100644
index 0b44221..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintenanceForm ref="maintenanceFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import MaintenanceForm from "../Form/MaintenanceForm.vue";
-import { useModal } from "@/hooks/useModal";
-import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-
-defineOptions({
-  name: "淇濆吇妯℃�佹",
-});
-
-const maintenanceFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇" });
-
-/**
- * @desc 淇濆瓨淇濆吇
- */
-const sendForm = async () => {
-  loading.value = true;
-  const form = await maintenanceFormRef.value.getForm();
-  const { code } = await addMaintenance({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintenanceFormRef.value.resetForm();
-    closeModal();
-  }
-  loading.value = false;
-};
-
-const open = async (id, row) => {
-  openModal(id);
-  await nextTick();
-  maintenanceFormRef.value.setForm(row);
-};
-defineExpose({
-  open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
deleted file mode 100644
index 249c9c3..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-dialog
-    v-model="visible"
-    :title="modalOptions.title"
-    width="30%"
-		draggable
-    @close="close"
-  >
-    <PlanForm ref="planFormRef" :id="id"></PlanForm>
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import PlanForm from "../Form/PlanForm";
-import {
-  addUpkeep,
-  editUpkeep,
-  getUpkeepById,
-} from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-
-defineOptions({
-  name: "璁惧淇濆吇鏂板璁″垝",
-});
-
-const emits = defineEmits(["ok"]);
-const planFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇璁″垝" });
-
-const openEdit = async (id) => {
-  const { data } = await getUpkeepById(id);
-  openModal(id);
-  await nextTick();
-  await planFormRef.value.setForm(data);
-};
-
-const sendForm = async () => {
-  loading.value = true;
-  const form = await planFormRef.value.getForm();
-  const { code } = id.value
-    ? await editUpkeep({ id: unref(id), ...form })
-    : await addUpkeep(form);
-  if (code == 200) {
-    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
-    closeModal();
-    emits("ok");
-  }
-  loading.value = false;
-};
-
-const close = () => {
-  planFormRef.value.resetForm();
-  closeModal();
-};
-
-defineExpose({
-  openModal,
-  openEdit,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/formDia.vue b/src/views/equipmentManagement/upkeep/Modal/formDia.vue
deleted file mode 100644
index a484d23..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/formDia.vue
+++ /dev/null
@@ -1,304 +0,0 @@
-<template>
-	<div>
-		<el-dialog :title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
-							 v-model="dialogVisitable" width="800px" @close="cancel">
-			<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="璁惧鍚嶇О" prop="taskId">
-							<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
-								<el-option
-									v-for="(item, index) in deviceOptions"
-									:key="index"
-									:label="item.deviceName"
-									:value="item.id"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="瑙勬牸鍨嬪彿">
-							<el-input
-								v-model="form.deviceModel"
-								placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-								disabled
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="褰曞叆浜�" prop="inspector">
-							<el-select
-								v-model="form.inspector"
-								filterable
-								default-first-option
-								:reserve-keyword="false"
-								placeholder="璇烽�夋嫨"
-								clearable
-							>
-								<el-option
-									v-for="item in userList"
-									:label="item.nickName"
-									:value="item.userId"
-									:key="item.userId"
-								/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
-							<el-date-picker
-								v-model="form.registrationDate"
-								type="date"
-								placeholder="閫夋嫨鐧昏鏃ユ湡"
-								format="YYYY-MM-DD"
-								value-format="YYYY-MM-DD"
-								style="width: 100%"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
-							<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
-								<el-option label="姣忔棩" value="DAILY"/>
-								<el-option label="姣忓懆" value="WEEKLY"/>
-								<el-option label="姣忔湀" value="MONTHLY"/>
-								<el-option label="瀛e害" value="QUARTERLY"/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
-								<el-option label="鍛ㄤ竴" value="MON"/>
-								<el-option label="鍛ㄤ簩" value="TUE"/>
-								<el-option label="鍛ㄤ笁" value="WED"/>
-								<el-option label="鍛ㄥ洓" value="THU"/>
-								<el-option label="鍛ㄤ簲" value="FRI"/>
-								<el-option label="鍛ㄥ叚" value="SAT"/>
-								<el-option label="鍛ㄦ棩" value="SUN"/>
-							</el-select>
-							<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm"  style="width: 50%"/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="DD,HH:mm"
-								value-format="DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="MM,DD,HH:mm"
-								value-format="MM,DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="澶囨敞" prop="remarks">
-							<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">淇濆瓨</el-button>
-					<el-button @click="cancel">鍙栨秷</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
-
-<script setup>
-import { reactive, ref, getCurrentInstance, toRefs } from "vue";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
-import { getCurrentDate } from "@/utils/index.js";
-import useUserStore from "@/store/modules/user.js";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const dialogVisitable = ref(false);
-const operationType = ref('add');
-const deviceOptions = ref([]);
-const userStore = useUserStore();
-const data = reactive({
-	form: {
-		taskId: undefined,
-		taskName: undefined,
-		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined, // 瑙勬牸鍨嬪彿
-		registrationDate: ''
-	},
-	rules: {
-		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
-		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
-		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
-	}
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
-	const { data } = await getDeviceLedger();
-	deviceOptions.value = data;
-};
-
-// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
-const setDeviceModel = (id) => {
-	const option = deviceOptions.value.find((item) => item.id === id);
-	if (option) {
-		form.value.taskId = option.id;
-		form.value.taskName = option.deviceName;
-		form.value.deviceModel = option.deviceModel;
-	}
-}
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
-	dialogVisitable.value = true
-	operationType.value = type
-	
-	// 閲嶇疆琛ㄥ崟
-	resetForm();
-	
-	// 鍔犺浇鐢ㄦ埛鍒楄〃
-	userListNoPageByTenantId().then((res) => {
-		userList.value = res.data;
-	});
-	
-	// 鍔犺浇璁惧鍒楄〃
-	await loadDeviceName();
-	
-	if (type === 'edit' && row) {
-		form.value = { ...row }
-		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
-		if (row.registrantId) {
-			form.value.inspector = row.registrantId
-		}
-
-		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
-		if (form.value.taskId) {
-			setDeviceModel(form.value.taskId);
-		}
-	} else if (type === 'add') {
-		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
-		form.value.registrationDate = getCurrentDate();
-		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
-		form.value.inspector = userStore.id;
-	}
-}
-
-// 鍏抽棴瀵硅瘽妗�
-const cancel = () => {
-	resetForm()
-	dialogVisitable.value = false
-	emit('closeDia')
-}
-
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
-	if (proxy.$refs.formRef) {
-		proxy.$refs.formRef.resetFields()
-	}
-	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
-	form.value = {
-		taskId: undefined,
-		taskName: undefined,
-		inspector: undefined,
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined,
-		registrationDate: ''
-	}
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
-	proxy.$refs["formRef"].validate(async valid => {
-		if (valid) {
-			try {
-				const payload = { ...form.value }
-				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
-				// 鏍规嵁閫夋嫨鐨勨�滃綍鍏ヤ汉鈥濊缃� registrant / registrantId
-				if (payload.inspector) {
-					const selectedUser = userList.value.find(
-						(u) => String(u.userId) === String(payload.inspector)
-					)
-					if (selectedUser) {
-						payload.registrantId = selectedUser.userId
-						payload.registrant = selectedUser.nickName
-					}
-				}
-				delete payload.inspector
-				delete payload.inspectorIds
-				
-				if (payload.frequencyType === 'WEEKLY') {
-					let frequencyDetail = ''
-					frequencyDetail = payload.week + ',' + payload.time
-					payload.frequencyDetail = frequencyDetail
-				}
-				
-				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
-				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
-				if (payload.status === undefined || payload.status === null || payload.status === '') {
-					payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
-				}
-				payload.active = true
-				payload.deleted = 0
-				
-				if (operationType.value === 'edit') {
-					await deviceMaintenanceTaskEdit(payload)
-				} else {
-					await deviceMaintenanceTaskAdd(payload)
-				}
-				cancel()
-				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
-			} catch (error) {
-				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
-			}
-		}
-	})
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 9b13b47..44f4af7 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -64,16 +64,14 @@
             <template #operation="{ row }">
               <el-button
                 type="primary"
-                text
-                icon="editPen"
+                link
                 @click="editScheduledTask(row)"
               >
                 缂栬緫
               </el-button>
               <el-button
                 type="danger"
-                text
-                icon="delete"
+                link
                 @click="delScheduledTaskByIds(row.id)"
               >
                 鍒犻櫎
@@ -135,14 +133,6 @@
           <div class="actions">
             <el-text class="mx-1" size="large">浠诲姟璁板綍</el-text>
             <div>
-              <el-button
-                type="primary"
-                icon="Plus"
-                :disabled="multipleList.length !== 1"
-                @click="addMaintain"
-              >
-                鏂板淇濆吇
-              </el-button>
               <el-button type="success" icon="Van" @click="addPlan">
                 鏂板璁″垝
               </el-button>
@@ -152,7 +142,7 @@
               <el-button
                 type="danger"
                 icon="Delete"
-                :disabled="multipleList.length <= 0"
+                :disabled="multipleList.length <= 0 || hasFinishedStatus"
                 @click="delRepairByIds(multipleList.map((item) => item.id))"
               >
                 鎵归噺鍒犻櫎
@@ -183,16 +173,24 @@
         <template #operation="{ row }">
           <el-button
             type="primary"
-            text
-            icon="editPen"
+            link
+            :disabled="row.status === 1"
             @click="editPlan(row.id)"
           >
             缂栬緫
           </el-button>
           <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            淇濆吇
+          </el-button>
+          <el-button
             type="danger"
-            text
-            icon="delete"
+            link
+            :disabled="row.status === 1"
             @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
@@ -209,12 +207,12 @@
 </template>
 
 <script setup>
-import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
+import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue'
 import { Search } from '@element-plus/icons-vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import PlanModal from './Modal/PlanModal.vue'
-import MaintenanceModal from './Modal/MaintenanceModal.vue'
-import FormDia from './Modal/formDia.vue'
+import PlanModal from './Form/PlanModal.vue'
+import MaintenanceModal from './Form/MaintenanceModal.vue'
+import FormDia from './Form/formDia.vue'
 import {
   getUpkeepPage,
   delUpkeep,
@@ -494,14 +492,18 @@
   multipleList.value = selection
 }
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 const changePage = (page) => {
   pagination.value.currentPage = page.page
   pagination.value.pageSize = page.limit
   getTableData()
 }
 
-const addMaintain = () => {
-  const row = multipleList.value[0]
+const addMaintain = (row) => {
   maintainModalRef.value.open(row.id, row)
 }
 
@@ -514,6 +516,13 @@
 }
 
 const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const hasFinished = multipleList.value.some(item => item.status === 1)
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�')
+    return
+  }
+  
   try {
     await ElMessageBox.confirm('纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?', '璀﹀憡', {
       confirmButtonText: '纭畾',
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
index 91588fd..40bf1ae 100644
--- a/src/views/financialManagement/accounting/index.vue
+++ b/src/views/financialManagement/accounting/index.vue
@@ -2,14 +2,31 @@
   <div style="padding: 20px;">
     <!-- 椤甸潰鏍囬鍜岀瓫閫夋潯浠� -->
     <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
-      <el-button
-        type="primary"
-        icon="Refresh"
-        @click="resetFilters"
-        size="default"
-      >
-        鏌ヨ
-      </el-button>
+      <el-form :inline="true">
+        <el-form-item label="骞翠唤">
+          <el-date-picker
+            v-model="selectedYear"
+            type="year"
+            placeholder="璇烽�夋嫨骞翠唤"
+            format="YYYY"
+            value-format="YYYY"
+            clearable
+            @change="fetchData()"
+            style="width: 200px"
+            :disabled-date="(date) => date.getFullYear() > new Date().getFullYear()"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            icon="Refresh"
+            @click="resetFilters"
+            size="default"
+          >
+            閲嶇疆
+          </el-button>
+        </el-form-item>
+      </el-form>
     </div>
 
     <main class="container mx-auto px-4 pb-10">
@@ -27,7 +44,7 @@
         <el-card class="bg3">
           <p>璧勪骇鍘熷��</p>
           <h3>
-            楼{{ assetInfo.totalOriginalValue }}
+            楼{{ formatCurrency(assetInfo.totalOriginalValue) }}
           </h3>
         </el-card>
 
@@ -35,7 +52,7 @@
         <el-card class="bg4">
           <p>绱鎶樻棫</p>
           <h3>
-            楼{{ assetInfo.totalDepreciation }}
+            楼{{ formatCurrency(assetInfo.totalDepreciation) }}
           </h3>
         </el-card>
 
@@ -43,7 +60,21 @@
         <el-card class="bg5">
           <p>鍑�鍊�</p>
           <h3>
-            楼{{ assetInfo.totalNetValue }}
+            楼{{ formatCurrency(assetInfo.totalNetValue) }}
+          </h3>
+        </el-card>
+        <!-- 璐熷�� -->
+        <el-card class="bg2">
+          <p>璐熷��</p>
+          <h3>
+            楼{{ formatCurrency(assetInfo.debt) }}
+          </h3>
+        </el-card>
+        <!-- 搴撳瓨璧勪骇 -->
+        <el-card class="bg3">
+          <p>搴撳瓨璧勪骇</p>
+          <h3>
+            楼{{ formatCurrency(assetInfo.inventoryValue) }}
           </h3>
         </el-card>
       </div>
@@ -62,7 +93,7 @@
                 style="height: 260px; width: 35%;">
               <div class="chart-num">
                 <span style="font-size: 22px;">璁惧绫诲瀷</span>
-                <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ assetInfo.totalEquipment }}</span>
+                <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ deviceTypeTotalCount }}</span>
               </div>
             </Echarts>
             <Echarts
@@ -86,7 +117,6 @@
           style="width: 100%"
           :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
         >
-          <el-table-column prop="id" label="璧勪骇缂栧彿" width="120" />
           <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="250" />
           <el-table-column prop="deviceModel" label="鍨嬪彿瑙勬牸" min-width="150" />
           <el-table-column prop="supplierName" label="渚涘簲鍟�" min-width="120" />
@@ -94,27 +124,17 @@
           <el-table-column prop="number" label="鏁伴噺" width="120" />
           <el-table-column prop="originalValue" label="鍘熷��(鍏�)" width="120">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.taxIncludingPriceTotal) }}
+              {{ formatCurrency(row.taxIncludingPriceTotal) }}
             </template>
           </el-table-column>
           <el-table-column prop="depreciation" label="绱鎶樻棫(鍏�)" width="140">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }}
+              {{ formatCurrency(row.deprAmount) }}
             </template>
           </el-table-column>
           <el-table-column prop="netValue" label="鍑�鍊�(鍏�)" width="120">
             <template #default="{ row }">
-              楼{{ formatCurrency(row.unTaxIncludingPriceTotal) }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="status" label="鐘舵��" width="100">
-            <template #default="{ row }">
-              <el-tag
-                :type="getStatusTagType(row.status)"
-                size="small"
-              >
-                {{ row.status }}
-              </el-tag>
+              {{ formatCurrency(row.netValue) }}
             </template>
           </el-table-column>
         </el-table>
@@ -142,20 +162,27 @@
 import 'element-plus/dist/index.css';
 import Echarts from "@/components/Echarts/echarts.vue";
 import { getLedgerPage } from "@/api/equipmentManagement/ledger";
+import { getAccountingTotal, getDeviceTypeDistribution, getCalculateDepreciation } from "@/api/financialManagement/accounting";
 import dayjs from "dayjs";
 
 // 绛涢�夋潯浠�
 const dateRange = ref(null);
 const equipmentType = ref('');
+const selectedYear = ref(dayjs().format('YYYY')); // 榛樿褰撳墠骞翠唤
 
 
 // 鍥哄畾璧勪骇淇℃伅
 const assetInfo = ref({
-  totalEquipment: 0,
-  totalOriginalValue: 0,
-  totalDepreciation: 0,
-  totalNetValue: 0
+  totalEquipment: 0, // deviceTotal
+  totalOriginalValue: 0, // deviceAmount
+  totalDepreciation: 0, // deprAmount
+  totalNetValue: 0, // netValue
+  debt: 0, // 璐熷��
+  inventoryValue: 0 // 搴撳瓨璧勪骇
 });
+
+// 璁惧绫诲瀷鎬绘暟锛堢敤浜庡浘琛ㄦ樉绀猴級
+const deviceTypeTotalCount = ref(0);
 
 // 璁惧鍒楄〃
 const equipmentList = ref([]);
@@ -306,63 +333,96 @@
 const fetchData = async () => {
   try {
     // 鑾峰彇鍥哄畾璧勪骇姹囨�讳俊鎭�
-    const assetInfoRes = await getAssetInfo({
+    const assetInfoRes = await getAccountingTotal({
       startDate: dateRange.value ? dateRange.value[0] : null,
       endDate: dateRange.value ? dateRange.value[1] : null,
-      equipmentType: equipmentType.value
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
     });
 
     if (assetInfoRes.code === 200) {
-      assetInfo.value = assetInfoRes.data;
+      // 鏄犲皠鍚庣瀛楁鍒板墠绔瓧娈�
+      const data = assetInfoRes.data;
+      assetInfo.value = {
+        totalEquipment: data.deviceTotal || 0, // 璁惧鎬绘暟
+        totalOriginalValue: data.deviceAmount || 0, // 璧勪骇鍘熷��
+        totalDepreciation: data.deprAmount || 0, // 绱鎶樻棫
+        totalNetValue: data.netValue || 0, // 鍑�鍊�
+        debt: data.debt || 0, // 璐熷��
+        inventoryValue: data.inventoryValue || 0 // 搴撳瓨璧勪骇
+      };
     }
 
-    // 鑾峰彇璁惧鍒楄〃
-    const equipmentListRes = await getLedgerPage({
-      current: pagination.value.currentPage,
-      size: pagination.value.pageSize,
+    // 鑾峰彇璁惧绫诲瀷鍒嗗竷鏁版嵁锛堥ゼ鍥惧拰鎶樼嚎鍥撅級
+    const distributionRes = await getDeviceTypeDistribution({
       startDate: dateRange.value ? dateRange.value[0] : null,
       endDate: dateRange.value ? dateRange.value[1] : null,
-      equipmentType: equipmentType.value
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
     });
 
-    if (equipmentListRes.code === 200) {
-      equipmentList.value = equipmentListRes.data.records;
-      pagination.value.total = equipmentListRes.data.total;
-
-      // 鏍规嵁 equipmentList 鎸� deviceName 杩涜鍒嗙被缁熻
-      const deviceNameMap = {};
-      equipmentList.value.forEach(item => {
-        const deviceName = item.deviceName;
-        if (!deviceNameMap[deviceName]) {
-          deviceNameMap[deviceName] = {
-            name: deviceName,
-            count: 0,
-            totalValue: 0
-          };
-        }
-        deviceNameMap[deviceName].count += item.number || 1; // 鍋囪 number 涓鸿澶囨暟閲�
-        deviceNameMap[deviceName].totalValue += item.taxIncludingPriceTotal || 0; // 绱姞鍚◣鎬讳环
-      });
-
-      // 杞崲涓� typeDistributionData 鏍煎紡
-      typeDistributionData.value = Object.values(deviceNameMap).map(item => ({
-        name: item.name,
-        value: item.count,
-        count: item.count,
-        amount: `楼${formatCurrency(item.totalValue)}`
-      }));
+    if (distributionRes.code === 200) {
+      const data = distributionRes.data;
+      
+      // 鏇存柊璁惧绫诲瀷鎬绘暟
+      deviceTypeTotalCount.value = data.totalCount || 0;
+      
+      // 杞崲楗煎浘鏁版嵁鏍煎紡
+      if (data.details && data.details.length > 0) {
+        typeDistributionData.value = data.details.map(item => ({
+          name: item.type || '',
+          value: Number(item.count || 0),
+          count: Number(item.count || 0),
+          amount: `楼${formatCurrency(item.amount || 0)}`
+        }));
+      } else if (data.categories && data.categories.length > 0) {
+        // 濡傛灉娌℃湁 details锛屼娇鐢� categories銆乧ountData 鍜� amountData 鏋勫缓
+        typeDistributionData.value = data.categories.map((category, index) => ({
+          name: category,
+          value: Number(data.countData[index] || 0),
+          count: Number(data.countData[index] || 0),
+          amount: `楼${formatCurrency(data.amountData[index] || 0)}`
+        }));
+      } else {
+        typeDistributionData.value = [];
+      }
 
       // 鏇存柊x杞存暟鎹�
-      xAxis.value[0].data = typeDistributionData.value.map(item => item.name);
+      xAxis.value[0].data = data.categories || typeDistributionData.value.map(item => item.name);
 
       // 鏋勫缓鎶樼嚎鍥炬暟鎹�
       typeDistributionLineSeries.value = [
         {
           name: '璁惧鏁伴噺',
           type: 'line',
-          data: typeDistributionData.value.map(item => item.count)
+          data: data.countData || typeDistributionData.value.map(item => item.count)
         }
       ];
+    }
+
+    // 鑾峰彇璁惧鍒楄〃锛堟姌鏃ц绠楁暟鎹級
+    const equipmentListRes = await getCalculateDepreciation({
+      current: pagination.value.currentPage,
+      size: pagination.value.pageSize,
+      startDate: dateRange.value ? dateRange.value[0] : null,
+      endDate: dateRange.value ? dateRange.value[1] : null,
+      equipmentType: equipmentType.value,
+      year: selectedYear.value
+    });
+
+    if (equipmentListRes.code === 200) {
+      // 濡傛灉杩斿洖鐨勬槸鍒嗛〉鏁版嵁
+      if (equipmentListRes.data.records) {
+        equipmentList.value = equipmentListRes.data.records;
+        pagination.value.total = equipmentListRes.data.total;
+      } else if (Array.isArray(equipmentListRes.data)) {
+        // 濡傛灉杩斿洖鐨勬槸鏁扮粍
+        equipmentList.value = equipmentListRes.data;
+        pagination.value.total = equipmentListRes.data.length;
+      } else {
+        equipmentList.value = [];
+        pagination.value.total = 0;
+      }
     }
   } catch (error) {
     console.error('鑾峰彇鍥哄畾璧勪骇鏁版嵁澶辫触锛�', error);
@@ -401,6 +461,7 @@
 const resetFilters = () => {
   dateRange.value = null;
   equipmentType.value = '';
+  selectedYear.value = dayjs().format('YYYY'); // 閲嶇疆涓哄綋鍓嶅勾浠�
   fetchData();
 };
 
@@ -486,10 +547,10 @@
   }
 }
 
-/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-5) */
+/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-6) */
 @media (min-width: 1024px) {
   .grid-container {
-    grid-template-columns: repeat(5, minmax(0, 1fr));
+    grid-template-columns: repeat(6, minmax(0, 1fr));
   }
 }
 
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDia.vue b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
new file mode 100644
index 0000000..5ea86b2
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
@@ -0,0 +1,400 @@
+<template>
+  <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="70%"
+    @close="closeDia">
+    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+      <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
+        <el-select
+          v-model="form.purchaseContractNumber"
+          placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
+          clearable
+          filterable
+          :loading="loadingPurchaseOptions"
+          @change="handlePurchaseChange"
+          :disabled="operationType === 'edit'"
+          style="width: 100%"
+        >
+          <el-option
+            v-for="item in purchaseOptions"
+            :key="item.purchaseContractNumber"
+            :label="formatPurchaseOption(item)"
+            :value="item.purchaseContractNumber"
+          />
+        </el-select>
+      </el-form-item>
+      <el-table
+        :data="productList"
+        border
+        v-loading="loadingProducts"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column align="center" type="selection" width="55" />
+        <el-table-column
+          align="center"
+          label="搴忓彿"
+          type="index"
+          width="60"
+        />
+        <el-table-column label="浜у搧澶х被" prop="productCategory" />
+        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+        <el-table-column label="鍗曚綅" prop="unit" width="70" />
+        <!-- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" /> -->
+        <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
+        <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
+        <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
+          <template #default="scope">
+            <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" />
+          </template>
+        </el-table-column>
+        <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
+        <el-table-column label="鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150">
+					<template #default="scope">
+						<el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" :disabled="operationType === 'edit'"/>
+					</template>
+				</el-table-column>
+        <el-table-column
+          label="鎬讳环(鍏�)"
+					:formatter="formattedNumber"
+          prop="taxInclusiveTotalPrice"
+          width="150"
+        >
+        </el-table-column>
+      </el-table>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭</el-button>
+        <el-button @click="closeDia">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+  updateStockIn,
+  addSutockIn,
+  selectProductRecordListByPuechaserId
+} from "@/api/inventoryManagement/stockIn.js";
+import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const selectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
+const purchaseOptions = ref([])
+const loadingPurchaseOptions = ref(false)
+const loading = ref(false);
+
+const data = reactive({
+  form: {
+    id: null,
+    purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
+    supplierId: null,       // 渚涘簲鍟咺D
+    supplierName: '',       // 渚涘簲鍟嗗悕绉�
+    inboundTime: '',        // 鍏ュ簱鏃堕棿
+    inboundBatch: '',       // 鍏ュ簱鎵规
+    recorderId: userStore.userId, // 褰曞叆浜篒D
+    recorderName: userStore.name, // 褰曞叆浜哄鍚�
+    entryDate: getCurrentDate(),  // 褰曞叆鏃ユ湡
+    remark: '',             // 澶囨敞
+  },
+  rules: {
+    purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
+    supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+    inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
+    inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
+  }
+})
+const { form, rules } = toRefs(data)
+
+// 鍔ㄦ�佽绠楀璇濇鏍囬
+const getDialogTitle = () => {
+  return operationType.value === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'
+}
+
+const formatPurchaseOption = (item = {}) => {
+  const contract = item.purchaseContractNumber || '--';
+  const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
+  return `${contract}${supplier}`;
+};
+
+const loadPurchaseOptions = async (keyword = '') => {
+  try {
+    loadingPurchaseOptions.value = true;
+    const res = await purchaseListPage({
+      current: -1,
+      size: -1,
+      purchaseContractNumber: keyword,
+    });
+    const records = res.data?.records || [];
+    purchaseOptions.value = records;
+    if (
+      form.value.purchaseContractNumber &&
+      !purchaseOptions.value.find(
+        (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
+      )
+    ) {
+      purchaseOptions.value.push({
+        purchaseContractNumber: form.value.purchaseContractNumber,
+        supplierName: form.value.supplierName,
+        supplierId: form.value.supplierId,
+      });
+    }
+  } finally {
+    loadingPurchaseOptions.value = false;
+  }
+};
+
+const handlePurchaseChange = (value) => {
+  form.value.purchaseContractNumber = value || '';
+  const matched = purchaseOptions.value.find(
+    (item) => item.purchaseContractNumber === value
+  );
+  if (matched) {
+    form.value.supplierName = matched.supplierName || form.value.supplierName;
+    form.value.supplierId = matched.supplierId || form.value.supplierId;
+  }
+  if (!value) {
+    productList.value = [];
+    return;
+  }
+  fetchProductsByContract();
+};
+
+const exceedsAddLimit = (product) => {
+  const stock = Number(product?.quantityStock ?? 0);
+  const waiting = Number(product?.quantity0 ?? 0);
+  if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
+    return false;
+  }
+  return stock > waiting;
+};
+
+const exceedsEditLimit = (product) => {
+  const stock = Number(product?.quantityStock ?? 0);
+  const waiting = Number(product?.quantity0 ?? 0);
+  const original = Number(product?.originalQuantityStock ?? 0);
+  if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
+    return false;
+  }
+  return stock > waiting + original;
+};
+
+const formattedNumber = (row, column, cellValue) => {
+  return parseFloat(cellValue).toFixed(2);
+};
+
+// 璁$畻鎬讳环
+const calculateTotalPrice = (row) => {
+  const quantityStock = Number(row?.quantityStock ?? 0);
+  const taxInclusiveUnitPrice = Number(row?.taxInclusiveUnitPrice ?? 0);
+  
+  if (Number.isFinite(quantityStock) && Number.isFinite(taxInclusiveUnitPrice)) {
+    row.taxInclusiveTotalPrice = quantityStock * taxInclusiveUnitPrice;
+  } else {
+    row.taxInclusiveTotalPrice = 0;
+  }
+};
+
+const fetchProductsByContract = async () => {
+  if (!form.value.purchaseContractNumber) {
+    proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
+    return
+  }
+  try {
+    loadingProducts.value = true
+    const productRes = await selectProductRecordListByPuechaserId({
+      purchaseContractNumber: form.value.purchaseContractNumber
+    });
+    if (!productRes.data || productRes.data.length === 0) {
+      proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
+      productList.value = [];
+      return
+    }
+    productList.value = productRes.data.map(item => ({
+      ...item,
+      quantityStock: 0,
+      taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+      taxInclusiveTotalPrice: 0,
+      originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
+    }))
+  } catch (error) {
+    console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
+    proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
+    productList.value = [];
+  } finally {
+    loadingProducts.value = false
+  }
+}
+
+const updatePro = async () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
+    return;
+  }
+  const target = selectedRows.value[0];
+  const stock = Number(target?.quantityStock ?? 0);
+  if (!Number.isFinite(stock) || stock <= 0) {
+    proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
+    return;
+  }
+  if (exceedsEditLimit(target)) {
+    proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
+    return;
+  }
+  const stockInData = {
+    id: selectedRows.value[0].recordId,
+    quantityStock: Number(selectedRows.value[0].quantityStock),
+  };
+  await updateStockIn(stockInData)
+  proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
+  closeDia()
+  emit('success')
+}
+
+const submitForm = async () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
+    return
+  }
+  if(operationType.value !== 'add'){
+    await updatePro()
+    return
+  }
+  try {
+    await proxy.$refs.formRef.validate()
+    const invalidProducts = selectedRows.value.filter((product) => {
+        const stock = Number(product?.quantityStock ?? 0);
+        if (!Number.isFinite(stock) || stock <= 0) {
+          return true;
+        }
+        return exceedsAddLimit(product);
+    })
+
+    if (invalidProducts.length > 0) {
+      proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
+      return
+    }
+
+    const stockInData = {
+      ...form.value,
+      inboundTime: formatDateTime(form.value.inboundTime),
+      nickName: userStore.nickName,
+      details: selectedRows.value.map(product => ({
+        id: product.id,
+        inboundQuantity: Number(product.quantityStock),
+				unitPrice: Number(product.taxInclusiveUnitPrice),
+        taxRate: Number(product.taxRate),
+				taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice)
+      })),
+    };
+    loading.value = true
+    await addSutockIn(stockInData)
+
+    proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
+    closeDia()
+    emit('success')
+
+  } catch (error) {
+    console.error('鎻愪氦澶辫触:', error)
+    if (!error.errors) {
+      proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+    }
+  } finally {
+    loading.value = false
+  }
+}
+
+const closeDia = () => {
+  proxy.$refs.formRef.resetFields()
+  dialogFormVisible.value = false
+  emit('close')
+}
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection.filter(item => item.id);
+}
+
+function formatDateTime(date = new Date(), includeTime = true) {
+  const d = new Date(date);
+  const year = d.getFullYear();
+  const month = String(d.getMonth() + 1).padStart(2, '0');
+  const day = String(d.getDate()).padStart(2, '0');
+
+  if (!includeTime) {
+    return `${year}-${month}-${day}`;
+  }
+
+  const hours = String(d.getHours()).padStart(2, '0');
+  const minutes = String(d.getMinutes()).padStart(2, '0');
+  const seconds = String(d.getSeconds()).padStart(2, '0');
+
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+  return formatDateTime(new Date(), false);
+}
+
+const openDialog = async (type, row) => {
+  operationType.value = type
+  dialogFormVisible.value = true
+  selectedRows.value = []
+  await loadPurchaseOptions();
+
+  if (type === 'add') {
+    form.value = {
+      id: null,
+      purchaseContractNumber: '',
+      supplierId: null,
+      supplierName: '',
+      inboundTime: '',
+      inboundBatch: '',
+      recorderId: userStore.userId,
+      recorderName: userStore.name,
+      entryDate: getCurrentDate(),
+      remark: ''
+    }
+    productList.value = []
+  } else {
+    form.value = JSON.parse(JSON.stringify(row))
+    try {
+      loadingProducts.value = true
+      const res = await selectProductRecordListByPuechaserId({
+        purchaseContractNumber: form.value.purchaseContractNumber,
+        id: row.id
+      });
+      productList.value = res.data.map(item => ({
+        ...item,
+        quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+        taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0),
+        taxInclusiveTotalPrice: Number(item?.quantityStock ?? 0) * Number(item?.taxInclusiveUnitPrice ?? 0),
+        originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
+      }))
+      selectedRows.value = productList.value
+    } catch (error) {
+      console.error('鍔犺浇浜у搧澶辫触:', error)
+      proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
+      productList.value = []
+    } finally {
+      loadingProducts.value = false
+    }
+  }
+}
+
+defineExpose({
+  openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
new file mode 100644
index 0000000..6048e18
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
@@ -0,0 +1,302 @@
+<template>
+  <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鑷畾涔夊叆搴�' : '缂栬緫鑷畾涔夊叆搴�'" width="70%"
+    @close="closeDia">
+    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+      <div style="margin-bottom: 10px;" v-if="operationType === 'add'">
+        <el-button type="primary" @click="addProductRow">鏂板</el-button>
+      </div>
+      <el-table
+        :data="productList"
+        border
+        v-loading="loadingProducts"
+      >
+        <el-table-column
+          align="center"
+          label="搴忓彿"
+          type="index"
+          width="60"
+        />
+        <el-table-column label="浜у搧澶х被" prop="productCategory" width="200">
+          <template #default="scope">
+            <el-input v-model="scope.row.productCategory" placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�" />
+          </template>
+        </el-table-column>
+        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200">
+          <template #default="scope">
+            <el-input v-model="scope.row.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍗曚綅" prop="unit" width="100">
+          <template #default="scope">
+            <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="150">
+          <template #default="scope">
+            <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍏ュ簱鏃ユ湡" prop="inboundDate" width="180">
+          <template #default="scope">
+            <el-date-picker
+              v-model="scope.row.inboundDate"
+              type="date"
+              placeholder="璇烽�夋嫨鍏ュ簱鏃ユ湡"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              style="width: 100%"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍗曚环(鍏�)" prop="unitPrice" width="150">
+          <template #default="scope">
+            <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.unitPrice" @change="() => calculateTotalPrice(scope.row)" />
+          </template>
+        </el-table-column>
+        <el-table-column 
+           label="鎬讳环(鍏�)" 
+           prop="totalPrice" 
+           width="150" 
+         >
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
+          <template #default="scope">
+            <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭</el-button>
+        <el-button @click="closeDia">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+	addStockInCustom, updateProduct
+} from "@/api/inventoryManagement/stockIn.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const loading = ref(false);
+
+function formatDateTime(date = new Date(), includeTime = true) {
+  const d = new Date(date);
+  const year = d.getFullYear();
+  const month = String(d.getMonth() + 1).padStart(2, '0');
+  const day = String(d.getDate()).padStart(2, '0');
+
+  if (!includeTime) {
+    return `${year}-${month}-${day}`;
+  }
+
+  const hours = String(d.getHours()).padStart(2, '0');
+  const minutes = String(d.getMinutes()).padStart(2, '0');
+  const seconds = String(d.getSeconds()).padStart(2, '0');
+
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+function getCurrentDate() {
+  return formatDateTime(new Date(), false);
+}
+
+const itemTypeOptions = [
+  { label: '鐗╂枡', value: '鐗╂枡' },
+  { label: '鍘熸枡', value: '鍘熸枡' },
+  { label: '鎴愬搧', value: '鎴愬搧' },
+  { label: '鍏朵粬', value: '鍏朵粬' },
+]
+
+const taxRateOptions = [
+  { label: '1', value: 1 },
+  { label: '6', value: 6 },
+  { label: '13', value: 13 },
+]
+
+const data = reactive({
+  form: {
+    id: null,
+    supplierId: null,       // 渚涘簲鍟咺D
+    supplierName: '',       // 渚涘簲鍟嗗悕绉�
+    recorderId: userStore.userId, // 褰曞叆浜篒D
+    recorderName: userStore.name, // 褰曞叆浜哄鍚�
+    entryDate: getCurrentDate(),  // 褰曞叆鏃ユ湡
+    remark: '',             // 澶囨敞
+  },
+  rules: {
+    supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }]
+  }
+})
+const { form, rules } = toRefs(data)
+
+// 鏂板浜у搧琛�
+const addProductRow = () => {
+  productList.value.push({
+    id: null,
+    productCategory: '',
+    specificationModel: '',
+    unit: '',
+    supplierName: form.value.supplierName || '',
+    itemType: '',
+    inboundNum: 0,
+    inboundDate: '',
+    quantityStock: 0,
+    unitPrice: 0,
+    totalPrice: 0,
+    taxRate: null,
+    taxExclusiveTotalPrice: 0,
+  });
+};
+
+// 鍒犻櫎浜у搧琛�
+const removeProductRow = (index) => {
+  productList.value.splice(index, 1);
+};
+
+// 璁$畻鎬讳环锛堟牴鎹暟閲忋�佸崟浠峰拰鍚◣鍗曚环锛�
+const calculateTotalPrice = (row) => {
+  // 璁$畻鏅�氭�讳环锛歩nboundNum * unitPrice
+  const quantity = Number(row.inboundNum || 0);
+  const unitPrice = Number(row.unitPrice || 0);
+  row.totalPrice = quantity * unitPrice;
+  calculateExclusivePrice(row);
+};
+
+// 璁$畻涓嶅惈绋庢�讳环锛堟牴鎹惈绋庢�讳环鍜岀◣鐜囷級
+const calculateExclusivePrice = (row) => {
+  const totalPrice = Number(row.totalPrice || 0);
+  const taxRate = Number(row.taxRate || 0);
+  row.taxExclusiveTotalPrice = totalPrice / (1 + taxRate / 100);
+};
+
+const submitForm = async () => {
+  try {
+    await proxy.$refs.formRef.validate()
+    
+    if (!productList.value.length) {
+      proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
+      return
+    }
+
+    // 楠岃瘉鑷畾涔夋坊鍔犵殑鏁版嵁蹇呭~瀛楁
+    for (let i = 0; i < productList.value.length; i++) {
+      const product = productList.value[i];
+      if (!product.productCategory || !product.specificationModel || !product.unit) {
+        proxy.$modal.msgError(`绗�${i + 1}琛屼骇鍝佹暟鎹湭濉啓瀹屾暣锛堜骇鍝佸ぇ绫汇�佽鏍煎瀷鍙枫�佸崟浣嶄负蹇呭~锛塦)
+        return
+      }
+      if (!product.inboundDate) {
+        proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鍏ュ簱鏃ユ湡`)
+        return
+      }
+      const stock = Number(product?.inboundNum ?? 0);
+      if (!Number.isFinite(stock) || stock <= 0) {
+        proxy.$modal.msgError(`绗�${i + 1}琛屾湰娆″叆搴撴暟閲忛渶澶т簬0`)
+        return
+      }
+    }
+
+    const payloadList = productList.value.map(product => ({
+      id: product.id ?? null,
+			inboundNum: Number(product.inboundNum),
+      productCategory: product.productCategory,
+      specificationModel: product.specificationModel,
+      unit: product.unit,
+      supplierName: product.supplierName || form.value.supplierName,
+      itemType: product.itemType,
+      inboundDate: formatDateTime(product.inboundDate, false),
+      taxRate: Number(product.taxRate || 0),
+      taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0),
+			unitPrice: Number(product.unitPrice || 0),
+    }));
+    loading.value = true
+    if (operationType.value === 'edit') {
+      const editPayload = payloadList[0]
+      await updateProduct(editPayload)
+    } else {
+      await addStockInCustom(payloadList)
+    }
+
+    proxy.$modal.msgSuccess(operationType.value === 'edit' ? '缂栬緫鑷畾涔夊叆搴撴垚鍔�' : '鏂板鑷畾涔夊叆搴撴垚鍔�')
+    closeDia()
+    emit('success')
+
+  } catch (error) {
+    console.error('鎻愪氦澶辫触:', error)
+    if (!error.errors) {
+      proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+    }
+  } finally {
+    loading.value = false
+  }
+}
+
+const closeDia = () => {
+  proxy.$refs.formRef.resetFields()
+  dialogFormVisible.value = false
+  productList.value = []
+  emit('close')
+}
+
+const openDialog = async (type, row) => {
+  operationType.value = type
+  dialogFormVisible.value = true
+
+  if (type === 'add') {
+    form.value = {
+      id: null,
+      supplierId: null,
+      supplierName: '',
+      recorderId: userStore.userId,
+      recorderName: userStore.name,
+      entryDate: getCurrentDate(),
+      remark: ''
+    }
+    productList.value = []
+  } else {
+    // 缂栬緫妯″紡锛氬皢琛屾暟鎹~鍏呭埌琛ㄦ牸涓互鏀寔淇敼
+    form.value = {
+      id: row?.id ?? null,
+      supplierId: row?.supplierId ?? null,
+      supplierName: row?.supplierName ?? '',
+      recorderId: userStore.userId,
+      recorderName: userStore.name,
+      entryDate: getCurrentDate(),
+      remark: row?.remark ?? ''
+    }
+    productList.value = [{
+      id: row?.id ?? null,
+      productCategory: row?.productCategory ?? '',
+      specificationModel: row?.specificationModel ?? '',
+      unit: row?.unit ?? '',
+      supplierName: row?.supplierName ?? '',
+      itemType: row?.itemType ?? '',
+      inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0),
+      inboundDate: row?.inboundDate ?? row?.createTime ?? '',
+      taxRate: Number(row?.taxRate ?? 0),
+      unitPrice: Number(row?.unitPrice ?? 0),
+      taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0),
+    }]
+  }
+}
+
+defineExpose({
+  openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
index 030b615..9aebae4 100644
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ b/src/views/inventoryManagement/receiptManagement/index.vue
@@ -1,551 +1,538 @@
 <template>
   <div class="app-container">
-    <div class="search_form">
-      <div>
-        <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
-        <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
-          clearable prefix-icon="Search" />
-        <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
-				<el-date-picker
-					v-model="searchForm.timeStr"
-					type="date"
-					placeholder="璇烽�夋嫨鏃ユ湡"
-					value-format="YYYY-MM-DD"
-					format="YYYY-MM-DD"
-					clearable
-					@change="handleQuery"
-				/>
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
-      </div>
-      <div>
-        <el-button type="primary" @click="openForm('add')">鏂板鍏ュ簱</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-    </div>
-    <div class="table_list">
-      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
-        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
-        <el-table-column align="center" type="selection" width="55" />
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip />
-        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
-        <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
-        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
-        <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
-        <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
-        <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
-        <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
-        <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
-          <template #default="scope">
-            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">缂栬緫</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
-        :page="page.current" :limit="page.size" @pagination="paginationChange" />
-    </div>
-
-    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍏ュ簱' : '缂栬緫鍏ュ簱'" width="70%"
-      @close="closeDia">
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
-              <el-select
-                  v-model="form.purchaseContractNumber"
-                  placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
-                  clearable
-                  filterable
-                  remote
-                  :remote-method="loadPurchaseOptions"
-                  :loading="loadingPurchaseOptions"
-                  @change="handlePurchaseChange"
-                  :disabled="operationType === 'edit'"
-                  style="width: 100%"
-              >
-                <el-option
-                    v-for="item in purchaseOptions"
-                    :key="item.purchaseContractNumber"
-                    :label="formatPurchaseOption(item)"
-                    :value="item.purchaseContractNumber"
-                />
-              </el-select>
-            </el-form-item>
-        <el-table
-          :data="productList"
-          border
-          v-loading="loadingProducts"
-          @selection-change="handleSelectionChange"
-        >
-          <el-table-column align="center" type="selection" width="55" />
-          <el-table-column
-            align="center"
-            label="搴忓彿"
-            type="index"
-            width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-          <el-table-column label="鍗曚綅" prop="unit" width="70" />
-          <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" />
-          <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
-          <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
-          <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
-            <template #default="scope">
-              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
-            </template>
-          </el-table-column>
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
-          <el-table-column
-            label="鍚◣鍗曚环(鍏�)"
-            prop="taxInclusiveUnitPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-          <el-table-column
-            label="鍚◣鎬讳环(鍏�)"
-            prop="taxInclusiveTotalPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-          <el-table-column
-            label="涓嶅惈绋庢�讳环(鍏�)"
-            prop="taxExclusiveTotalPrice"
-            :formatter="formattedNumber"
-            width="150"
-          />
-        </el-table>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
+    <el-tabs v-model="activeTab"
+             @tab-change="handleTabChange">
+      <el-tab-pane label="鎴愬搧鍏ュ簱"
+                   name="production">
+        <div class="search_form">
+          <div>
+            <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+            <el-date-picker v-model="searchForm.timeStr"
+                            type="date"
+                            placeholder="璇烽�夋嫨鏃ユ湡"
+                            value-format="YYYY-MM-DD"
+                            format="YYYY-MM-DD"
+                            clearable
+                            @change="handleQuery"/>
+            <span class="search_title ml10">浜у搧澶х被锛�</span>
+            <el-input v-model="searchForm.productCategory"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      clearable/>
+            <el-button type="primary"
+                       @click="handleQuery"
+                       style="margin-left: 10px">鎼滅储
+            </el-button>
+          </div>
+          <div>
+            <el-button @click="handleOut">瀵煎嚭</el-button>
+            <el-button type="danger"
+                       plain
+                       @click="handleDelete">鍒犻櫎
+            </el-button>
+          </div>
         </div>
-      </template>
-    </el-dialog>
+        <div class="table_list">
+          <el-table :data="tableData"
+                    border
+                    v-loading="tableLoading"
+                    @selection-change="handleSelectionChange"
+                    :expand-row-keys="expandedRowKeys"
+                    :row-key="row => row.id"
+                    show-summary
+                    style="width: 100%"
+                    :summary-method="summarizeMainTable"
+                    height="calc(100vh - 18.5em)">
+            <el-table-column align="center"
+                             type="selection"
+                             width="55"/>
+            <el-table-column align="center"
+                             label="搴忓彿"
+                             type="index"
+                             width="60"/>
+            <el-table-column label="鍏ュ簱鏃堕棿"
+                             prop="createTime"
+                             show-overflow-tooltip/>
+            <el-table-column label="閿�鍞悎鍚屽彿"
+                             prop="salesContractNo"
+                             width="180"
+                             show-overflow-tooltip/>
+            <el-table-column label="浜у搧澶х被"
+                             prop="productCategory"
+                             show-overflow-tooltip/>
+            <el-table-column label="瑙勬牸鍨嬪彿"
+                             prop="specificationModel"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍗曚綅"
+                             prop="unit"
+                             width="70"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍏ュ簱鏁伴噺"
+                             prop="inboundNum"
+                             width="100"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍗曚环(鍏�)"
+                             prop="unitPrice"
+                             width="150"></el-table-column>
+            <el-table-column label="鎬讳环(鍏�)"
+                             prop="totalPrice"
+                             width="150"></el-table-column>
+            <!-- <el-table-column fixed="right"
+                             label="鎿嶄綔"
+                             min-width="60"
+                             align="center">
+              <template #default="scope">
+                <el-button link
+                           type="primary"
+                           size="small"
+                           @click="openForm('edit', scope.row, 'production');">缂栬緫</el-button>
+              </template>
+            </el-table-column> -->
+          </el-table>
+          <pagination v-show="total > 0"
+                      :total="total"
+                      layout="total, sizes, prev, pager, next, jumper"
+                      :page="page.current"
+                      :limit="page.size"
+                      @pagination="paginationChange"/>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="鍘熸枡鍏ュ簱"
+                   name="purchase">
+        <div class="search_form">
+          <div>
+            <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+            <el-date-picker v-model="searchForm.timeStr"
+                            type="date"
+                            placeholder="璇烽�夋嫨鏃ユ湡"
+                            value-format="YYYY-MM-DD"
+                            format="YYYY-MM-DD"
+                            clearable
+                            @change="handleQuery"/>
+            <span class="search_title ml10">浜у搧澶х被锛�</span>
+            <el-input v-model="searchForm.productCategory"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      clearable/>
+            <el-button type="primary"
+                       @click="handleQuery"
+                       style="margin-left: 10px">鎼滅储
+            </el-button>
+          </div>
+          <div>
+            <el-button type="primary"
+                       @click="openForm('add', 'purchase')">鏂板鍏ュ簱
+            </el-button>
+            <el-button @click="handleOut">瀵煎嚭</el-button>
+            <el-button type="danger"
+                       plain
+                       @click="handleDelete">鍒犻櫎
+            </el-button>
+          </div>
+        </div>
+        <div class="table_list">
+          <el-table :data="tableData"
+                    border
+                    v-loading="tableLoading"
+                    @selection-change="handleSelectionChange"
+                    :expand-row-keys="expandedRowKeys"
+                    :row-key="row => row.id"
+                    show-summary
+                    style="width: 100%"
+                    :summary-method="summarizeMainTable"
+                    height="calc(100vh - 18.5em)">
+            <el-table-column align="center"
+                             type="selection"
+                             width="55"/>
+            <el-table-column align="center"
+                             label="搴忓彿"
+                             type="index"
+                             width="60"/>
+            <el-table-column label="鍏ュ簱鏃堕棿"
+                             prop="createTime"
+                             width="100"
+                             show-overflow-tooltip/>
+            <el-table-column label="閲囪喘鍚堝悓鍙�"
+                             prop="purchaseContractNumber"
+                             width="180"
+                             show-overflow-tooltip/>
+            <el-table-column label="渚涘簲鍟嗗悕绉�"
+                             prop="supplierName"
+                             width="240"
+                             show-overflow-tooltip/>
+            <el-table-column label="浜у搧澶х被"
+                             prop="productCategory"
+                             show-overflow-tooltip/>
+            <el-table-column label="瑙勬牸鍨嬪彿"
+                             prop="specificationModel"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍗曚綅"
+                             prop="unit"
+                             width="70"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍏ュ簱鏁伴噺"
+                             prop="inboundNum"
+                             width="100"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍚◣鍗曚环(鍏�)"
+                             prop="taxInclusiveUnitPrice"
+                             width="150"></el-table-column>
+            <el-table-column label="鍚◣鎬讳环(鍏�)"
+                             prop="taxInclusiveTotalPrice"
+                             width="150"></el-table-column>
+            <el-table-column label="鍏ュ簱浜�"
+                             prop="createBy"
+                             width="80"
+                             show-overflow-tooltip/>
+            <el-table-column fixed="right"
+                             label="鎿嶄綔"
+                             min-width="60"
+                             align="center">
+              <template #default="scope">
+                <el-button link
+                           :disabled="scope.row.type == 1"
+                           type="primary"
+                           size="small"
+                           @click="openForm('edit', scope.row, 'purchase');">缂栬緫
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <pagination v-show="total > 0"
+                      :total="total"
+                      layout="total, sizes, prev, pager, next, jumper"
+                      :page="page.current"
+                      :limit="page.size"
+                      @pagination="paginationChange"/>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="鐢熶骇鍏ュ簱"
+                   name="product">
+        <div class="search_form">
+          <div>
+            <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
+            <el-date-picker v-model="searchForm.timeStr"
+                            type="date"
+                            placeholder="璇烽�夋嫨鏃ユ湡"
+                            value-format="YYYY-MM-DD"
+                            format="YYYY-MM-DD"
+                            clearable
+                            @change="handleQuery"/>
+            <span class="search_title ml10">浜у搧澶х被锛�</span>
+            <el-input v-model="searchForm.productCategory"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      clearable/>
+            <el-button type="primary"
+                       @click="handleQuery"
+                       style="margin-left: 10px">鎼滅储
+            </el-button>
+          </div>
+          <div>
+            <el-button type="primary"
+                       @click="openForm('add', 'purchase')">鏂板鍏ュ簱
+            </el-button>
+            <el-button @click="handleOut">瀵煎嚭</el-button>
+            <el-button type="danger"
+                       plain
+                       @click="handleDelete">鍒犻櫎
+            </el-button>
+          </div>
+        </div>
+        <div class="table_list">
+          <el-table :data="tableData"
+                    border
+                    v-loading="tableLoading"
+                    @selection-change="handleSelectionChange"
+                    :expand-row-keys="expandedRowKeys"
+                    :row-key="row => row.id"
+                    show-summary
+                    style="width: 100%"
+                    :summary-method="summarizeMainTable"
+                    height="calc(100vh - 18.5em)">
+            <el-table-column align="center"
+                             type="selection"
+                             width="55"/>
+            <el-table-column align="center"
+                             label="搴忓彿"
+                             type="index"
+                             width="60"/>
+            <el-table-column label="鍏ュ簱鏃堕棿"
+                             prop="createTime"
+                             width="100"
+                             show-overflow-tooltip/>
+            <el-table-column label="浜у搧澶х被"
+                             prop="productCategory"
+                             show-overflow-tooltip/>
+            <el-table-column label="瑙勬牸鍨嬪彿"
+                             prop="specificationModel"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍗曚綅"
+                             prop="unit"
+                             width="220"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍏ュ簱鏁伴噺"
+                             prop="inboundNum"
+                             width="220"
+                             show-overflow-tooltip/>
+            <el-table-column label="鍏ュ簱浜�"
+                             prop="createBy"
+                             width="220"
+                             show-overflow-tooltip/>
+          </el-table>
+          <pagination v-show="total > 0"
+                      :total="total"
+                      layout="total, sizes, prev, pager, next, jumper"
+                      :page="page.current"
+                      :limit="page.size"
+                      @pagination="pageProductChange"/>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+    <form-dia ref="formDia"
+              @close="handleQuery"
+              @success="handleQuery"></form-dia>
+    <form-dia-product ref="formDiaProduct"
+                      @close="handleQuery"
+                      @success="handleQuery"></form-dia-product>
   </div>
 </template>
 
 <script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
+import pagination from "@/components/PIMTable/Pagination.vue";
+import {
+  ref,
+  reactive,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+  nextTick,
+} from "vue";
+import {ElMessageBox} from "element-plus";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
 import {
   getStockInPage,
-  updateStockIn,
-  addSutockIn,
+  getStockInPageByProduction,
+  getStockInPageByProductProduction,
   delStockIn,
-  selectProductRecordListByPuechaserId
 } from "@/api/inventoryManagement/stockIn.js";
-import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
-import { getCurrentDate } from "@/utils/index.js";
+import FormDia from "./components/formDia.vue";
+import FormDiaProduct from "./components/formDiaProduct.vue";
 
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
+// 鑾峰彇褰撳墠鏃ユ湡
+function getCurrentDate() {
+  return dayjs().format("YYYY-MM-DD");
+}
 
-const tableData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
+const {proxy} = getCurrentInstance();
 
-const purchaseOptions = ref([])
-const loadingPurchaseOptions = ref(false)
-
-
-const loading = ref(false);
-const tableLoading = ref(false)
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const formDia = ref();
+const formDiaProduct = ref();
+const activeTab = ref("production"); // 褰撳墠婵�娲荤殑 tab
 
 const page = reactive({
   current: 1,
   size: 100,
-})
-const total = ref(0)
+});
+const total = ref(0);
 
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
-const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
-const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
-const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
-const productSelectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
 const data = reactive({
   searchForm: {
-    supplierName: '',
-		timeStr: '',
+    supplierName: "",
+    customerName: "",
+    productCategory: "",
+    timeStr: "",
   },
-  form: {
-    id: null,
-    purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
-    supplierId: null,       // 渚涘簲鍟咺D
-    supplierName: '',       // 渚涘簲鍟嗗悕绉�
-    inboundTime: '',        // 鍏ュ簱鏃堕棿
-    inboundBatch: '',       // 鍏ュ簱鎵规
-    recorderId: userStore.userId, // 褰曞叆浜篒D
-    recorderName: userStore.name, // 褰曞叆浜哄鍚�
-    entryDate: getCurrentDate(),  // 褰曞叆鏃ユ湡
-    remark: '',             // 澶囨敞
-  },
-  rules: {
-    purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
-    supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
-    inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
-    inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
-  }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-const formatPurchaseOption = (item = {}) => {
-  const contract = item.purchaseContractNumber || '--';
-  const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
-  return `${contract}${supplier}`;
-};
-
-const loadPurchaseOptions = async (keyword = '') => {
-  try {
-    loadingPurchaseOptions.value = true;
-    const res = await purchaseListPage({
-      current: -1,
-      size: -1,
-      purchaseContractNumber: keyword,
-    });
-    const records = res.data?.records || [];
-    purchaseOptions.value = records;
-    if (
-      form.value.purchaseContractNumber &&
-      !purchaseOptions.value.find(
-        (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
-      )
-    ) {
-      purchaseOptions.value.push({
-        purchaseContractNumber: form.value.purchaseContractNumber,
-        supplierName: form.value.supplierName,
-        supplierId: form.value.supplierId,
-      });
-    }
-  } finally {
-    loadingPurchaseOptions.value = false;
-  }
-};
-
-const handlePurchaseChange = (value) => {
-  form.value.purchaseContractNumber = value || '';
-  const matched = purchaseOptions.value.find(
-    (item) => item.purchaseContractNumber === value
-  );
-  if (matched) {
-    form.value.supplierName = matched.supplierName || form.value.supplierName;
-    form.value.supplierId = matched.supplierId || form.value.supplierId;
-  }
-  if (!value) {
-    productList.value = [];
-    return;
-  }
-  fetchProductsByContract();
-};
-const exceedsAddLimit = (product) => {
-  const stock = Number(product?.quantityStock ?? 0);
-  const waiting = Number(product?.quantity0 ?? 0);
-  if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
-    return false;
-  }
-  return stock > waiting;
-};
-
-const exceedsEditLimit = (product) => {
-  const stock = Number(product?.quantityStock ?? 0);
-  const waiting = Number(product?.quantity0 ?? 0);
-  const original = Number(product?.originalQuantityStock ?? 0);
-  if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
-    return false;
-  }
-  return stock > waiting + original;
-};
-const formattedNumber = (row, column, cellValue) => {
-	return parseFloat(cellValue).toFixed(2);
-};
+});
+const {searchForm} = toRefs(data);
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  page.current = 1
-  getList()
-}
-const paginationChange = (obj) => {
+  page.current = 1;
+  getList();
+};
+const paginationChange = obj => {
   page.current = obj.page;
   page.size = obj.limit;
-  getList()
-}
+  getList();
+};
+const pageProductChange = obj => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
 const getList = () => {
-  tableLoading.value = true
-  getStockInPage({ ...searchForm.value, ...page }).then(res => {
-    tableLoading.value = false
-    tableData.value = res.data.records
-    total.value = res.data.total
-    console.log('tableData:', tableData.value)
-  }).catch(() => {
-    tableLoading.value = false
-  })
-}
+  tableLoading.value = true;
+  const params = {...page};
 
-
-// 璋冪敤selectProductRecordListByPuechaserId杩欎釜鏂规硶鏍规嵁鍚堝悓鏌ヨ鍒癷d锛屽啀璋冪敤getProductRecordByhetong杩欎釜鏂规硶鏍规嵁id鏌ヨ鍒颁骇鍝佽鍗曡褰�
-// 鏂板鏍规嵁鍚堝悓鍙锋煡璇骇鍝佽褰曠殑鏂规硶
-const fetchProductsByContract = async () =>
-{
-  if (!form.value.purchaseContractNumber) {
-    proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
-    return
+  // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷浼犻�掍笉鍚岀殑鏌ヨ鍙傛暟
+  if (activeTab.value === "production") {
+    params.customerName = searchForm.value.customerName;
+    params.timeStr = searchForm.value.timeStr;
+  } else {
+    params.supplierName = searchForm.value.supplierName;
+    params.timeStr = searchForm.value.timeStr;
   }
-  try {
-    loadingProducts.value = true
-    // 鏍规嵁鍚堝悓鏌ヨ浜у搧璁板綍
-    const productRes = await selectProductRecordListByPuechaserId({
-      purchaseContractNumber: form.value.purchaseContractNumber
-    });
-    console.log('productRes:', productRes)
-    if (!productRes.data || productRes.data.length === 0) {
-      proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
-      productList.value = [];
-      return
-    }
-    // 澶勭悊浜у搧鏁版嵁锛屾坊鍔犳湰娆″叆搴撴暟閲忓瓧娈�
-    productList.value = productRes.data.map(item => ({
-      ...item,
-      quantityStock: 0,
-      originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
-    }))
-  } catch (error) {
-    console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
-    proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
-    productList.value = [];
-  } finally {
-    loadingProducts.value = false
-  }
-}
+  params.productCategory = searchForm.value.productCategory;
+  if (activeTab.value === "product") {
+    getStockInPageByProductProduction(params)
+        .then(res => {
+          tableLoading.value = false;
+          tableData.value = res.data.records;
+        });
 
+  }else {
+    // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勬帴鍙�
+    const apiCall =
+        activeTab.value === "production"
+            ? getStockInPageByProduction(params)
+            : getStockInPage(params);
+
+    apiCall
+        .then(res => {
+          tableLoading.value = false;
+          tableData.value = res.data.records;
+
+          // 鍓嶇璁$畻鎬讳环锛氭�讳环 = unitPrice * inboundNum
+          tableData.value = tableData.value.map(item => {
+            // 浣跨敤鍏ュ簱鏁伴噺璁$畻鎬讳环
+            const inboundNum = Number(item.inboundNum) || 0;
+            const unitPrice = Number(item.unitPrice) || 0;
+            const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0;
+
+            // 鏍规嵁鏍囩椤电被鍨嬭绠椾笉鍚岀殑鎬讳环
+            if (activeTab.value === "production") {
+              // 鎴愬搧搴撳瓨锛氭�讳环 = unitPrice * 鍏ュ簱鏁伴噺
+              item.totalPrice = (unitPrice * inboundNum).toFixed(2);
+            } else {
+              // 鍘熸枡鍜屾潗鏂欏簱瀛橈細鍚◣鎬讳环 = taxInclusiveUnitPrice * 鍏ュ簱鏁伴噺
+              item.taxInclusiveTotalPrice = (
+                  taxInclusiveUnitPrice * inboundNum
+              ).toFixed(2);
+            }
+
+            return item;
+          });
+
+          total.value = res.data.total;
+        })
+        .catch(() => {
+          tableLoading.value = false;
+        });
+  }
+
+};
+
+// 鍒囨崲 tab
+const handleTabChange = tabName => {
+  page.current = 1;
+  // 鍒囨崲 tab 鏃舵竻绌烘悳绱㈡潯浠�
+  searchForm.value.supplierName = "";
+  searchForm.value.customerName = "";
+  searchForm.value.timeStr = "";
+  searchForm.value.productCategory = "";
+  getList();
+};
 
 // 鎵撳紑寮规
-  const openForm = async (type, row) => {
-    operationType.value = type
-    dialogFormVisible.value = true
-    selectedRows.value = []
-		await loadPurchaseOptions();
-
-    if (type === 'add') {
-      // 鏂板鏃跺垵濮嬪寲琛ㄥ崟
-      form.value = {
-        id: null,
-        purchaseContractNumber: '',
-        supplierId: null,
-        supplierName: '',
-        inboundTime: '',
-        inboundBatch: '',
-        recorderId: userStore.userId,
-        recorderName: userStore.name,
-        entryDate: getCurrentDate(),
-        remark: ''
-      }
-      productList.value = [] // 娓呯┖浜у搧鍒楄〃
+const openForm = async (type, row, tabType) => {
+  const currentTab = tabType || activeTab.value;
+  await nextTick(() => {
+    if (currentTab === "production") {
+      formDiaProduct.value?.openDialog(type, row);
     } else {
-      form.value = JSON.parse(JSON.stringify(row))
-      try {
-        loadingProducts.value = true
-        // 鏍规嵁鍚堝悓鍙峰姞杞藉搴旂殑浜у搧鍒楄〃锛堝亣璁� getProductByContract 鏄彲鐢ㄦ帴鍙o級
-        const res = await selectProductRecordListByPuechaserId({
-          purchaseContractNumber: form.value.purchaseContractNumber,
-          id: row.id
-        });
-				productList.value = res.data.map(item => ({
-					...item,
-					quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
-					originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
-				}))
-        selectedRows.value = productList.value
-      } catch (error) {
-        console.error('鍔犺浇浜у搧澶辫触:', error)
-        proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
-        productList.value = []
-      } finally {
-        loadingProducts.value = false
-      }
+      formDia.value?.openDialog(type, row);
     }
-  }
+  });
+};
 
-  const updatePro = async () => {
-     // 鍑嗗鎻愪氦鏁版嵁
-     // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
-    if (selectedRows.value.length === 0) {
-      proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
-      return;
-    }
-    const target = selectedRows.value[0];
-    const stock = Number(target?.quantityStock ?? 0);
-    if (!Number.isFinite(stock) || stock <= 0) {
-      proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
-      return;
-    }
-    if (exceedsEditLimit(target)) {
-      proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
-      return;
-    }
-    const stockInData = {
-      id: selectedRows.value[0].recordId,
-      quantityStock: Number(selectedRows.value[0].quantityStock),// 浣跨敤鏂版牸寮忓寲鍑芥暟
-    };
-    await updateStockIn(stockInData)
-    proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
-    closeDia()
-    getList() // 鍒锋柊鍒楄〃
-  }
-
-// 鎻愪氦琛ㄥ崟
-  const submitForm = async () => {
-    // 楠岃瘉鑷冲皯閫夋嫨浜嗕竴涓骇鍝�
-    if (selectedRows.value.length === 0) {
-      proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
-      return
-    }
-    if(operationType.value !== 'add'){
-      await updatePro()
-      return
-    }
-    try {
-      await proxy.$refs.formRef.validate()
-      // 楠岃瘉鍏ュ簱鏁伴噺
-      const invalidProducts = selectedRows.value.filter((product) => {
-          const stock = Number(product?.quantityStock ?? 0);
-          if (!Number.isFinite(stock) || stock <= 0) {
-            return true;
-          }
-          return exceedsAddLimit(product);
-      })
-
-      if (invalidProducts.length > 0) {
-        proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
-        return
-      }
-
-      // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
-      const stockInData = {
-        // 鍏ュ簱鍗曞熀鏈俊鎭�
-        ...form.value,
-        inboundTime: formatDateTime(form.value.inboundTime),
-        nickName: userStore.nickName,
-        details: selectedRows.value.map(product => ({
-          id: product.id,
-          // id: product.salesLedgerProductId,
-          inboundQuantity: Number(product.quantityStock)
-        })),
-      };
-      // 璋冪敤API
-      loading.value = true
-      await addSutockIn(stockInData)
-
-      proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
-      closeDia()
-      getList() // 鍒锋柊鍒楄〃
-
-    } catch (error) {
-      console.error('鎻愪氦澶辫触:', error)
-      if (!error.errors) {
-        proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
-      }
-    } finally {
-      loading.value = false
-    }
-  }
-
-// 鍏抽棴寮规
-  const closeDia = () => {
-    proxy.$refs.formRef.resetFields()
-    dialogFormVisible.value = false
-
-  }
 // 琛ㄦ牸閫夋嫨鏁版嵁
-  const handleSelectionChange = (selection) => {
-    // 杩囨护鎺夊瓙鏁版嵁
-    selectedRows.value = selection.filter(item => item.id);
-  }
+const handleSelectionChange = selection => {
+  selectedRows.value = selection.filter(item => item.id);
+};
 
-  const expandedRowKeys = ref([])
+const expandedRowKeys = ref([]);
 
 // 涓昏〃鍚堣鏂规硶
-  const summarizeMainTable = (param) => {
-    return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-  };
+const summarizeMainTable = param => {
+  return proxy.summarizeTable(param, [
+    "contractAmount",
+    "taxInclusiveTotalPrice",
+    "taxExclusiveTotalPrice",
+  ]);
+};
 
 // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm(
-        '鏄惁纭瀵煎嚭锛�',
-        '瀵煎嚭', {
-          confirmButtonText: '纭',
-          cancelButtonText: '鍙栨秷',
-          type: 'warning',
-        }
-    ).then(() => {
-      proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
-    }).catch(() => {
-      proxy.$modal.msg("宸插彇娑�")
-    })
-  }
-// 鍒犻櫎
-  const handleDelete = () => {
-    let ids = []
-    if (selectedRows.value.length > 0) {
-			// 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-			const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
-			if (unauthorizedData.length > 0) {
-				proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
-				return;
-			}
-      ids = selectedRows.value.map(item => item.id);
-    } else {
-      proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
-      return
-    }
-    ElMessageBox.confirm(
-        '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
-        '瀵煎嚭', {
-          confirmButtonText: '纭',
-          cancelButtonText: '鍙栨秷',
-          type: 'warning',
-        }
-    ).then(() => {
-      delStockIn({ids:ids}).then(res => {
-        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
-        getList()
-      })
-    }).catch(() => {
-      proxy.$modal.msg("宸插彇娑�")
-    })
-  }
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-// 淇敼涓烘洿閫氱敤鐨勬棩鏈熸椂闂存牸寮忓寲鍑芥暟
-function formatDateTime(date = new Date(), includeTime = true) {
-  const d = new Date(date);
-  const year = d.getFullYear();
-  const month = String(d.getMonth() + 1).padStart(2, '0');
-  const day = String(d.getDate()).padStart(2, '0');
-
-  if (!includeTime) {
-    return `${year}-${month}-${day}`; // 淇濇寔鍘熸湁 getCurrentDate 鍔熻兘
-  }
-
-  // 鏂板鏃堕棿閮ㄥ垎鏍煎紡鍖�
-  const hours = String(d.getHours()).padStart(2, '0');
-  const minutes = String(d.getMinutes()).padStart(2, '0');
-  const seconds = String(d.getSeconds()).padStart(2, '0');
-
-  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
-
-  onMounted(() => {
-    getList()
+const handleOut = () => {
+  ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
   })
+      .then(() => {
+        // 鏍规嵁涓嶅悓鐨� tab 绫诲瀷璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+        let exportUrl = "/stockin/export";
+        if (activeTab.value === "production") {
+          exportUrl = "/stockin/exportOne";
+        }
+        proxy.download(exportUrl, {}, "鍏ュ簱鍙拌处.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  const ids = selectedRows.value.map(item => item.id);
+
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        // 鏍规嵁褰撳墠 tab 绫诲瀷閫夋嫨涓嶅悓鐨勫垹闄ゆ帴鍙e拰type鍙傛暟
+        let deleteApi, deleteParams;
+
+        if (activeTab.value === "production") {
+          // 鎴愬搧鍒犻櫎锛宼ype浼�2
+          deleteApi = delStockIn;
+          deleteParams = {ids, type: 2};
+        } else {
+          // 鍘熸枡鍒犻櫎锛宼ype浼�1
+          deleteApi = delStockIn;
+          deleteParams = {ids, type: 1};
+        }
+
+        deleteApi(deleteParams)
+            .then(() => {
+              proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+              getList();
+            })
+            .catch(() => {
+              proxy.$modal.msgError("鍒犻櫎澶辫触");
+            });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
+onMounted(() => {
+  getList();
+});
 </script>
 
 <style scoped lang="scss"></style>
+
+
+
diff --git a/src/views/lavorissue/ledger/Form.vue b/src/views/lavorissue/ledger/Form.vue
index 7031957..785ef7a 100644
--- a/src/views/lavorissue/ledger/Form.vue
+++ b/src/views/lavorissue/ledger/Form.vue
@@ -73,12 +73,12 @@
 import useFormData from "@/hooks/useFormData";
 import {ref,onMounted} from "vue";
 import useUserStore from "@/store/modules/user";
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import {deepCopySameProperties} from '@/utils/util'
 const userStore = useUserStore();
 import {
   getDept
 } from "@/api/collaborativeApproval/approvalProcess.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance();
 
 
@@ -112,8 +112,12 @@
   issueDate: undefined,
 });
 const getPersonList = () => {
-  getStaffOnJob().then(res => {
-    personList.value = res.data
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records
   })
 };
 const loadForm = (data) => {
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
index 224fdbb..54b2ef9 100644
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ b/src/views/personnelManagement/contractManagement/components/formDia.vue
@@ -19,23 +19,24 @@
         </div>
       </template>
     </el-dialog>
+    <Files ref="filesDia"></Files>
   </div>
 </template>
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
 import {findStaffContractListPage} from "@/api/personnelManagement/staffContract.js";
+const Files = defineAsyncComponent(() => import( "@/views/personnelManagement/contractManagement/filesDia.vue"));
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
-
+const filesDia = ref()
 const dialogFormVisible = ref(false);
 const operationType = ref('')
 const tableColumn = ref([
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
+  {
+    label: "鍚堝悓骞撮檺",
+    prop: "contractTerm",
+  },
   {
     label: "鍚堝悓寮�濮嬫棩鏈�",
     prop: "contractStartTime",
@@ -43,6 +44,22 @@
   {
     label: "鍚堝悓缁撴潫鏃ユ湡",
     prop: "contractEndTime",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: 'right',
+    width: 120,
+    operation: [
+      {
+        name: "涓婁紶闄勪欢",
+        type: "text",
+        clickFun: (row) => {
+          filesDia.value.openDialog( row,'鍚堝悓')
+        },
+      }
+    ],
   },
 ]);
 const tableData = ref([]);
@@ -59,6 +76,11 @@
   }
 }
 
+const openUploadFile = (row) => {
+  filesDia.value.open = true
+  filesDia.value.row = row
+}
+
 // 鍏抽棴寮规
 const closeDia = () => {
   dialogFormVisible.value = false;
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
index f752496..c0c5ee9 100644
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ b/src/views/personnelManagement/contractManagement/filesDia.vue
@@ -30,16 +30,10 @@
           :isSelection="true"
           @selection-change="handleSelectionChange"
           height="500"
+          @pagination="paginationSearch"
+          :total="page.total"
       >
       </PIMTable>
-			<pagination
-				style="margin: 10px 0"
-				v-show="total > 0"
-				@pagination="paginationSearch"
-				:total="total"
-				:page="page.current"
-				:limit="page.size"
-			/>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="closeDia">鍙栨秷</el-button>
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 76f1401..1d2aab7 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -266,7 +266,7 @@
     type: "warning",
   })
     .then(() => {
-      proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
+      proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍚堝悓绠$悊.xlsx");
     })
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
index 84808f8..2b8a7fd 100644
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ b/src/views/personnelManagement/dimission/components/formDia.vue
@@ -12,101 +12,93 @@
         <el-form :model="form" label-width="200px" label-position="left" :rules="rules" ref="formRef" style="margin-top: 20px">
           <el-row :gutter="30">
             <el-col :span="12">
-              <el-form-item label="濮撳悕锛�" prop="staffName">
-                <el-select v-model="form.staffName" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">
+              <el-form-item label="濮撳悕锛�" prop="staffOnJobId">
+                <el-select v-model="form.staffOnJobId"
+                           placeholder="璇烽�夋嫨浜哄憳"
+                           style="width: 100%"
+                           :disabled="operationType === 'edit'"
+                           @change="handleSelect">
                   <el-option
                       v-for="item in personList"
                       :key="item.id"
                       :label="item.staffName"
-                      :value="item.staffName"
+                      :value="item.id"
                   />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="12">
               <el-form-item label="鍛樺伐缂栧彿锛�">
-                {{ form.staffNo || '-' }}
+                {{ currentStaffRecord.staffNo || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="鎬у埆锛�">
-                {{ form.sex || '-' }}
+                {{ currentStaffRecord.sex || '-' }}
               </el-form-item>
             </el-col>
             <el-col :span="12">
               <el-form-item label="鎴风睄浣忓潃锛�">
-                {{ form.nativePlace || '-' }}
+                {{ currentStaffRecord.nativePlace || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="宀椾綅锛�">
-                {{ form.postName || '-' }}
+                {{ currentStaffRecord.postName || '-' }}
               </el-form-item>
             </el-col>
             <el-col :span="12">
               <el-form-item label="鐜颁綇鍧�锛�">
-                {{ form.adress || '-' }}
+                {{ currentStaffRecord.adress || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="绗竴瀛﹀巻锛�">
-                {{ form.firstStudy || '-' }}
+                {{ currentStaffRecord.firstStudy || '-' }}
               </el-form-item>
             </el-col>
             <el-col :span="12">
               <el-form-item label="涓撲笟锛�">
-                {{ form.profession || '-' }}
+                {{ currentStaffRecord.profession || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="骞撮緞锛�">
-                {{ form.age || '-' }}
+                {{ currentStaffRecord.age || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="鑱旂郴鐢佃瘽锛�">
-                {{ form.phone || '-' }}
+                {{ currentStaffRecord.phone || '-' }}
               </el-form-item>
             </el-col>
             <el-col :span="12">
               <el-form-item label="绱ф�ヨ仈绯讳汉锛�">
-                {{ form.emergencyContact || '-' }}
+                {{ currentStaffRecord.emergencyContact || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
               <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�">
-                {{ form.emergencyContactPhone || '-' }}
+                {{ currentStaffRecord.emergencyContactPhone || '-' }}
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
-              <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細">
-                {{ form.contractStartTime || '-' }}
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�">
-                {{ form.contractEndTime || '-' }}
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="30">
-            <el-col :span="12">
-              <el-form-item label="绂昏亴鍘熷洜锛�" prop="dimissionReason">
-                <el-select v-model="form.dimissionReason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
+              <el-form-item label="绂昏亴鍘熷洜锛�" prop="reason">
+                <el-select v-model="form.reason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
                   <el-option
                       v-for="(item, index) in dimissionReasonOptions"
                       :key="index"
@@ -117,11 +109,10 @@
               </el-form-item>
             </el-col>
             <el-col :span="12">
-              <el-form-item label="澶囨敞锛�" prop="dimissionRemark" v-show="form.dimissionReason === 'other'">
+              <el-form-item label="澶囨敞锛�" prop="remark" v-if="form.reason === 'other'">
                 <el-input
-                    v-model="form.dimissionRemark"
+                    v-model="form.remark"
                     type="textarea"
-                    v-show="form.dimissionReason === 'other'"
                     :rows="3"
                     placeholder="澶囨敞"
                     maxlength="500"
@@ -136,7 +127,7 @@
 <!--          <el-col :span="12">-->
 <!--            <div class="info-item">-->
 <!--              <span class="info-label">绂昏亴鍘熷洜锛�</span>-->
-<!--              <el-select v-model="form.dimissionReason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
+<!--              <el-select v-model="form.reason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
 <!--                <el-option-->
 <!--                    v-for="(item, index) in dimissionReasonOptions"-->
 <!--                    :key="index"-->
@@ -167,8 +158,8 @@
 
 <script setup>
 import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {createStaffLeave, updateStaffLeave} from "@/api/personnelManagement/staffLeave.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -176,30 +167,13 @@
 const operationType = ref('')
 const data = reactive({
   form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postName: "",
-    sysPostId: 0,
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    dimissionRemark: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   },
   rules: {
     staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳" }],
-    dimissionReason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
+    reason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
   },
   dimissionReasonOptions: [
       {label: '钖祫寰呴亣', value: 'salary'},
@@ -207,45 +181,51 @@
       {label: '宸ヤ綔鐜', value: 'work_environment'},
       {label: '涓汉鍘熷洜', value: 'personal_reason'},
       {label: '鍏朵粬', value: 'other'},
-  ]
+  ],
+  currentStaffRecord: {},
 });
-const { form, rules, dimissionReasonOptions } = toRefs(data);
+const { form, rules, dimissionReasonOptions, currentStaffRecord } = toRefs(data);
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
-  getList()
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-    })
+    currentStaffRecord.value = row
+    form.value.staffOnJobId = row.staffOnJobId
+    form.value.reason = row.reason
+    form.value.remark = row.remark
+    personList.value = [
+      {
+        staffName: row.staffName,
+        id: row.staffOnJobId,
+      }
+    ]
+  } else {
+    getList()
   }
 }
 
 const handleSelectDimissionReason = (val) => {
   if (val === 'other') {
-    form.value.dimissionRemark = ''
+    form.value.remark = ''
   }
 }
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
   form.value.staffState = 0
-  if (form.value.dimissionReason !== 'other') {
-    form.value.dimissionRemark = ''
-  }
-  if (!form.value.sysPostId) {
-    form.value.sysPostId = 0;
+  if (form.value.reason !== 'other') {
+    form.value.remark = ''
   }
   proxy.$refs["formRef"].validate(valid => {
     if (valid) {
       if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
+        createStaffLeave(form.value).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
       } else {
-        staffJoinUpdate(form.value).then(res => {
+        updateStaffLeave(currentStaffRecord.value.id, form.value).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
@@ -258,25 +238,9 @@
 const closeDia = () => {
   // 琛ㄥ崟宸叉敞閲婏紝鎵嬪姩閲嶇疆琛ㄥ崟鏁版嵁
   form.value = {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postName: "",
-    sysPostId: 0,
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   };
   dialogFormVisible.value = false;
   emit('close')
@@ -298,46 +262,11 @@
 };
 
 const handleSelect = (val) => {
-  let obj = personList.value.find(item => item.staffName === val)
+  let obj = personList.value.find(item => item.id === val)
+  currentStaffRecord.value = {}
   if (obj) {
-    let {
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postName,
-      sysPostId,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractEndTime,
-      staffName
-    } = obj
     // 淇濈暀绂昏亴鏃ユ湡鍜岀鑱屽師鍥狅紝鍙洿鏂板憳宸ヤ俊鎭�
-    form.value = {
-      ...form.value,
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postName,
-      sysPostId,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractEndTime,
-      staffName
-    }
+    currentStaffRecord.value = obj
   }
 }
 defineExpose({
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
index 27e6766..c6ed705 100644
--- a/src/views/personnelManagement/dimission/index.vue
+++ b/src/views/personnelManagement/dimission/index.vue
@@ -11,22 +11,6 @@
             clearable
             :prefix-icon="Search"
         />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
         <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
         >鎼滅储</el-button
         >
@@ -58,9 +42,8 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
 import FormDia from "@/views/personnelManagement/dimission/components/formDia.vue";
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {findStaffLeaveListPage, batchDeleteStaffLeaves} from "@/api/personnelManagement/staffLeave.js";
 import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
 
 const data = reactive({
   searchForm: {
@@ -109,6 +92,10 @@
     prop: "nativePlace",
   },
   {
+    label: "閮ㄩ棬",
+    prop: "deptName",
+  },
+  {
     label: "宀椾綅",
     prop: "postName",
   },
@@ -145,24 +132,11 @@
     prop: "emergencyContactPhone",
     width:150
   },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
+    fixed: 'right',
     operation: [
       {
         name: "缂栬緫",
@@ -186,20 +160,6 @@
 const { proxy } = getCurrentInstance()
 
 
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
@@ -213,7 +173,7 @@
 };
 const getList = () => {
   tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 0}).then(res => {
+  findStaffLeaveListPage({...page, ...searchForm.value}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
@@ -248,7 +208,7 @@
     type: "warning",
   })
       .then(() => {
-        staffJoinDel(ids).then((res) => {
+        batchDeleteStaffLeaves(ids).then((res) => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
@@ -265,7 +225,7 @@
     type: "warning",
   })
       .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 0}, "浜哄憳绂昏亴.xlsx");
+        proxy.download("/staff/staffLeave/export", {}, "浜哄憳绂昏亴.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
index 00e796c..06eee04 100644
--- a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
+++ b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -56,6 +56,25 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
+            <el-form-item label="閮ㄩ棬锛�" prop="sysDeptId">
+              <el-tree-select
+                  v-model="form.sysDeptId"
+                  :data="deptOptions"
+                  :props="{ value: 'id', label: 'label', children: 'children' }"
+                  value-key="id"
+                  placeholder="璇烽�夋嫨閮ㄩ棬"
+                  check-strictly
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="骞撮緞锛�" prop="age">
+              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
             <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
               <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
             </el-form-item>
@@ -63,13 +82,6 @@
           <el-col :span="12">
             <el-form-item label="涓撲笟锛�" prop="profession">
               <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -140,9 +152,10 @@
 
 <script setup>
 import {ref, onMounted} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {findPostOptions} from "@/api/system/post.js";
+import {listDept} from "@/api/system/dept.js";
 import {staffOnJobInfo, createStaffOnJob, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
+import {deptTreeSelect} from "@/api/system/user.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -168,6 +181,7 @@
     contractEndTime: "",
     staffState: "",
     sysPostId: undefined,
+    sysDeptId: undefined,
   },
   rules: {
     staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -187,8 +201,9 @@
     contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
   },
   postOptions: [], // 宀椾綅閫夐」
+  deptOptions: [], // 閮ㄩ棬閫夐」
 });
-const { form, rules, postOptions } = toRefs(data);
+const { form, rules, postOptions, deptOptions } = toRefs(data);
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
@@ -211,6 +226,7 @@
 }
 onMounted(() => {
   fetchPostOptions()
+  fetchDeptOptions()
 })
 
 const fetchPostOptions = () => {
@@ -218,6 +234,27 @@
     postOptions.value = res.data
   })
 }
+
+// 鏌ヨ閮ㄩ棬鍒楄〃
+const fetchDeptOptions = () => {
+  deptTreeSelect().then(response => {
+    deptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
+  })
+}
+
+/** 杩囨护绂佺敤鐨勯儴闂� */
+function filterDisabledDept(deptList) {
+  return deptList.filter(dept => {
+    if (dept.disabled) {
+      return false
+    }
+    if (dept.children && dept.children.length) {
+      dept.children = filterDisabledDept(dept.children)
+    }
+    return true
+  })
+}
+
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
   if (!form.value.sysPostId) {
diff --git a/src/views/personnelManagement/employeeRecord/components/RenewContract.vue b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
new file mode 100644
index 0000000..9c2acfc
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
@@ -0,0 +1,141 @@
+<template>
+  <el-dialog
+      v-model="isShow"
+      title="缁鍚堝悓"
+      width="800px"
+      @close="closeModal"
+  >
+    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+      <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
+        <el-date-picker
+            v-model="form.contractStartTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
+        <el-date-picker
+            v-model="form.contractEndTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
+        <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭</el-button>
+        <el-button @click="closeModal">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+// 缁鍚堝悓
+import { renewContract } from "@/api/personnelManagement/staffOnJob.js";
+import {computed, getCurrentInstance,} from "vue";
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const data = reactive({
+  form: {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  },
+  rules: {
+    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  }
+});
+const { form, rules } = toRefs(data);
+let { proxy } = getCurrentInstance()
+
+const props = defineProps({
+  id: {
+    type: Number,
+    default: 0,
+  },
+
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+})
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+// 璁$畻鍚堝悓骞撮檺
+const calculateContractTerm = () => {
+  if (form.value.contractStartTime && form.value.contractEndTime) {
+    const startDate = new Date(form.value.contractStartTime);
+    const endDate = new Date(form.value.contractEndTime);
+
+    if (endDate > startDate) {
+      // 璁$畻骞翠唤宸�
+      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+      const monthDiff = endDate.getMonth() - startDate.getMonth();
+      const dayDiff = endDate.getDate() - startDate.getDate();
+
+      let years = yearDiff;
+
+      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+        years = yearDiff - 1;
+      }
+
+      form.value.contractTerm = Math.max(0, years);
+    } else {
+      form.value.contractTerm = 0;
+    }
+  } else {
+    form.value.contractTerm = 0;
+  }
+};
+
+const submitForm = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      renewContract(props.id, form.value).then(res => {
+        if (res.code === 200) {
+          proxy.$modal.msgSuccess("缁鍚堝悓鎴愬姛");
+          emit('completed');
+          closeModal();
+        }
+      })
+    }
+  })
+}
+
+// 鍏抽棴寮规
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  form.value = {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  };
+  isShow.value = false;
+};
+</script>
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index b8e48eb..19addfa 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -39,6 +39,12 @@
     </div>
     <show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
     <new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
+    <renew-contract
+        v-if="isShowRenewContractModal"
+        v-model:visible="isShowRenewContractModal"
+        :id="id"
+        @completed="handleQuery"
+    />
   </div>
 </template>
 
@@ -48,9 +54,9 @@
 import {ElMessageBox} from "element-plus";
 import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 import dayjs from "dayjs";
-
 const NewOrEditFormDia = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"));
 const ShowFormDia = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/Show.vue"));
+const RenewContract = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/RenewContract.vue"));
 
 const data = reactive({
   searchForm: {
@@ -61,6 +67,8 @@
   },
 });
 const { searchForm } = toRefs(data);
+const isShowRenewContractModal = ref(false);
+const id = ref(0);
 const tableColumn = ref([
   {
     label: "鐘舵��",
@@ -100,6 +108,10 @@
   {
     label: "鎴风睄浣忓潃",
     prop: "nativePlace",
+  },
+  {
+    label: "閮ㄩ棬",
+    prop: "deptName",
   },
   {
     label: "宀椾綅",
@@ -166,6 +178,15 @@
           openFormNewOrEditFormDia("edit", row);
         },
       },
+      {
+        name: "缁鍚堝悓",
+        type: "text",
+        showHide: row => row.staffState === 1,
+        clickFun: (row) => {
+          isShowRenewContractModal.value = true;
+          id.value = row.id;
+        },
+      },
       // {
       //   name: "璇︽儏",
       //   type: "text",
@@ -212,7 +233,7 @@
   tableLoading.value = true;
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
-  staffOnJobListPage({...params, staffState: 1}).then(res => {
+  staffOnJobListPage({...params}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/onboarding/components/formDia.vue
deleted file mode 100644
index 7cd6ab6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ /dev/null
@@ -1,281 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
-              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="濮撳悕锛�" prop="staffName">
-              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鎬у埆锛�" prop="sex">
-              <el-select v-model="form.sex">
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="濂�" value="濂�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="sysPostId">
-              <el-select v-model="form.sysPostId" placeholder="璇烽�夋嫨宀椾綅" clearable>
-                <el-option
-                    v-for="item in postOptions"
-                    :key="item.postId"
-                    :label="item.postName"
-                    :value="item.postId"
-                    :disabled="item.status === '1'"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
-              <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
-              <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓撲笟锛�" prop="profession">
-              <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
-              <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
-              <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
-              <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
-              <el-date-picker
-                  v-model="form.contractStartTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-									@change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
-              <el-date-picker
-                  v-model="form.contractEndTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-									@change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, onMounted} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import {findPostOptions} from "@/api/system/post.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
-  form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    staffState: "",
-    sysPostId: undefined,
-  },
-  rules: {
-    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-  postOptions: [], // 宀椾綅閫夐」
-});
-const { form, rules, postOptions } = toRefs(data);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-      if (form.value.sysPostId === 0) {
-        form.value.sysPostId = undefined
-      }
-      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
-      calculateContractTerm();
-    })
-  } else {
-		form.value.id = ''
-	}
-
-}
-onMounted(() => {
-  fetchPostOptions()
-})
-
-const fetchPostOptions = () => {
-  findPostOptions().then(res => {
-    postOptions.value = res.data
-  })
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
-  if (!form.value.sysPostId) {
-    form.value.sysPostId = 0;
-  }
-  proxy.$refs.formRef.validate(valid => {
-    if (valid) {
-      form.value.staffState = 1
-      if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      } else {
-        staffJoinUpdate(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      }
-    }
-  })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
-  if (form.value.contractStartTime && form.value.contractEndTime) {
-    const startDate = new Date(form.value.contractStartTime);
-    const endDate = new Date(form.value.contractEndTime);
-    
-    if (endDate > startDate) {
-      // 璁$畻骞翠唤宸�
-      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-      const monthDiff = endDate.getMonth() - startDate.getMonth();
-      const dayDiff = endDate.getDate() - startDate.getDate();
-      
-      let years = yearDiff;
-      
-      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-        years = yearDiff - 1;
-      }
-      
-      form.value.contractTerm = Math.max(0, years);
-    } else {
-      form.value.contractTerm = 0;
-    }
-  } else {
-    form.value.contractTerm = 0;
-  }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue b/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
deleted file mode 100644
index fa0c9e6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
+++ /dev/null
@@ -1,386 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
-              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="濮撳悕锛�" prop="staffName">
-              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鎬у埆锛�" prop="sex">
-              <el-select v-model="form.sex">
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="濂�" value="濂�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="postJob">
-              <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
-              <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
-              <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓撲笟锛�" prop="profession">
-              <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
-              <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
-              <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓绛捐鏃ユ湡锛�" prop="trialStartDate">
-              <el-date-picker
-                  v-model="form.trialStartDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="鍔冲姩鍚堝悓鏈熼檺閫夋嫨锛�" prop="dateSelect">
-              <el-radio-group v-model="form.dateSelect">
-                <el-radio :value="'A'">
-                  A銆佹湁鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'B'">
-                  B銆佹棤鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'C'">
-                  C銆佷互瀹屾垚涓�瀹氬伐浣滀换鍔′负鏈熼檺
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30" v-if="showProbationDates">
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熷紑濮嬫棩鏈燂細" prop="signDate">
-              <el-date-picker
-                  v-model="form.signDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熺粨鏉熸棩鏈燂細" prop="trialEndDate">
-              <el-date-picker
-                  v-model="form.trialEndDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-<!--        <el-row :gutter="30">-->
-<!--          <el-col :span="12">-->
-<!--            <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">-->
-<!--              <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>-->
-<!--            </el-form-item>-->
-<!--          </el-col>-->
-<!--        </el-row>-->
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
-              <el-date-picker
-                  v-model="form.contractStartTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12" v-if="showContractEnd">
-            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
-              <el-date-picker
-                  v-model="form.contractEndTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="璇曠敤鏈熷伐璧勶細" prop="proSalary">
-							<el-input-number placeholder="璇疯緭鍏ヨ瘯鐢ㄦ湡宸ヨ祫" :precision="2"
-															 :step="100"
-															 :min="0" v-model="form.proSalary" style="width: 100%"/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="宸ヨ祫鎶ラ叕锛�" prop="salarySelect">
-              <el-radio-group v-model="form.salarySelect" class="salary-radio-group">
-                <el-radio :value="'A'" class="salary-radio-item">
-                  A銆佷箼鏂圭殑宸ヨ祫鎶ラ叕鎸夌収鐢叉柟渚濇硶鍒跺畾鐨勮绔犲埗搴︿腑鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曠‘瀹氾紝鏍规嵁涔欐柟鐨勫伐浣滃矖浣嶇‘瀹氬叾姣忔湀宸ヨ祫銆�
-                </el-radio>
-                <el-radio :value="'B'" class="salary-radio-item">
-                  B銆佺敳鏂瑰涔欐柟瀹炶鍩烘湰宸ヨ祫鍜岀哗鏁堝伐璧勭浉缁撳悎鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曪紝涔欐柟鐨勬敹鍏ュ寘鎷熀鏈伐璧勩�佽椁愩�佷氦閫氥�佺敓娲讳綇瀹跨瓑鍚勯」琛ュ姪锛屽鏈夊彉鍔ㄦ牴鎹唴閮ㄥ伐璧勫垎閰嶅姙娉曡皟鏁村叾宸ヨ祫锛涚哗鏁堝伐璧勬牴鎹箼鏂圭殑宸ヤ綔涓氱哗銆佸姵鍔ㄦ垚鏋滃拰瀹為檯璐$尞鎸夌収鍐呴儴鍒嗛厤鍔炴硶鑰冩牳纭畾銆�
-                </el-radio>
-                <el-radio :value="'C'" class="salary-radio-item">
-                  C銆佺敳鏂瑰疄琛岃浠跺伐璧勫埗锛屼互鐢叉柟鎺ュ埌璁㈠崟鍙婂叕鍙哥敓浜ц鍒掞紝鎸夌収瀹氶鍜岃浠跺崟浠凤紝鏍规嵁涔欐柟瀹屾垚鐨勪笟缁╋紝鎸夋椂瓒抽鏀粯涔欐柟鐨勫伐璧勬姤閰��
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="绂忓埄寰呴亣锛�" prop="remark">
-							<el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance, computed, watch} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
-  form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    dateSelect: "",
-    signDate: "",
-    trialEndDate: "",
-    proSalary: null,
-    trialStartDate: "",
-    salarySelect: "",
-    // contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    staffState: "",
-  },
-  rules: {
-    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		remark: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    dateSelect: [{ required: true, message: "璇烽�夋嫨鍔冲姩鍚堝悓鏈熼檺", trigger: "change" }],
-    signDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    trialEndDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    trialStartDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    salarySelect: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鎶ラ叕鏂瑰紡", trigger: "change" }],
-    // contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-});
-const { form, rules } = toRefs(data);
-
-const showContractEnd = computed(() => form.value.dateSelect === "A");
-const showProbationDates = computed(() => form.value.dateSelect === "A" || form.value.dateSelect === "B");
-
-watch(() => form.value.dateSelect, (type) => {
-  if (type !== "A") {
-    form.value.contractEndTime = "";
-  }
-
-  if (type === "C") {
-    form.value.signDate = "";
-    form.value.trialEndDate = "";
-    form.value.proSalary = null;
-  }
-}, { immediate: true });
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
-      // calculateContractTerm();
-    })
-  }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
-  proxy.$refs.formRef.validate(valid => {
-    if (valid) {
-      form.value.staffState = 1
-      if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      } else {
-        staffJoinUpdate(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      }
-    }
-  })
-}
-// 璁$畻鍚堝悓骞撮檺
-// const calculateContractTerm = () => {
-//   if (form.value.contractStartTime && form.value.contractEndTime) {
-//     const startDate = new Date(form.value.contractStartTime);
-//     const endDate = new Date(form.value.contractEndTime);
-//
-//     if (endDate > startDate) {
-//       // 璁$畻骞翠唤宸�
-//       const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-//       const monthDiff = endDate.getMonth() - startDate.getMonth();
-//       const dayDiff = endDate.getDate() - startDate.getDate();
-//
-//       let years = yearDiff;
-//
-//       // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-//       if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-//         years = yearDiff - 1;
-//       }
-//
-//       form.value.contractTerm = Math.max(0, years);
-//     } else {
-//       form.value.contractTerm = 0;
-//     }
-//   } else {
-//     form.value.contractTerm = 0;
-//   }
-// };
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-.salary-radio-group {
-  display: flex;
-  gap: 12px;
-}
-
-.salary-radio-item {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  align-items: flex-start;
-}
-
-.salary-radio-item :deep(.el-radio__label) {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  padding-left: 8px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
deleted file mode 100644
index edf4fa3..0000000
--- a/src/views/personnelManagement/onboarding/index.vue
+++ /dev/null
@@ -1,280 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="search_form">
-      <div>
-        <span class="search_title">濮撳悕锛�</span>
-        <el-input
-          v-model="searchForm.staffName"
-          style="width: 240px"
-          placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
-          @change="handleQuery"
-          clearable
-          :prefix-icon="Search"
-        />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-          >鎼滅储</el-button
-        >
-      </div>
-      <div>
-        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-    </div>
-    <div class="table_list">
-      <PIMTable
-        rowKey="id"
-        :column="tableColumn"
-        :tableData="tableData"
-        :page="page"
-        :isSelection="true"
-        @selection-change="handleSelectionChange"
-        :tableLoading="tableLoading"
-        @pagination="pagination"
-        :total="page.total"
-      ></PIMTable>
-    </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
-  </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
-// import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 鏂扮枂椋熷搧鍏徃鐢ㄧ殑琛ㄥ崟
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-
-const data = reactive({
-  searchForm: {
-    staffName: "",
-  },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
-  {
-    label: "鐘舵��",
-    prop: "staffState",
-    dataType: "tag",
-    formatData: (params) => {
-      if (params == 0) {
-        return "绂昏亴";
-      } else if (params == 1) {
-        return "鍏ヨ亴";
-      } else {
-        return null;
-      }
-    },
-    formatType: (params) => {
-      if (params == 0) {
-        return "danger";
-      } else if (params == 1) {
-        return "primary";
-      } else {
-        return null;
-      }
-    },
-  },
-  {
-    label: "鍛樺伐缂栧彿",
-    prop: "staffNo",
-  },
-  {
-    label: "濮撳悕",
-    prop: "staffName",
-  },
-  {
-    label: "鎬у埆",
-    prop: "sex",
-  },
-  {
-    label: "鎴风睄浣忓潃",
-    prop: "nativePlace",
-  },
-  {
-    label: "宀椾綅",
-    prop: "postName",
-  },
-  {
-    label: "鐜颁綇鍧�",
-    prop: "adress",
-    width:200
-  },
-  {
-    label: "绗竴瀛﹀巻",
-    prop: "firstStudy",
-  },
-  {
-    label: "涓撲笟",
-    prop: "profession",
-    width:100
-  },
-  {
-    label: "骞撮緞",
-    prop: "age",
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "phone",
-    width:150
-  },
-  {
-    label: "绱ф�ヨ仈绯讳汉",
-    prop: "emergencyContact",
-    width: 120
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "emergencyContactPhone",
-    width:150
-  },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    fixed: 'right',
-    operation: [
-      {
-        name: "缂栬緫",
-        type: "text",
-        clickFun: (row) => {
-          openForm("edit", row);
-        },
-      },
-    ],
-  },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0,
-});
-const formDia = ref()
-const { proxy } = getCurrentInstance()
-
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
-    tableLoading.value = false;
-    tableData.value = res.data.records
-    page.total = res.data.total;
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  nextTick(() => {
-    formDia.value?.openDialog(type, row)
-  })
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        staffJoinDel(ids).then((res) => {
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-          getList();
-        });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/payrollManagement/components/formDia.vue b/src/views/personnelManagement/payrollManagement/components/formDia.vue
index e4cf0b3..cf93559 100644
--- a/src/views/personnelManagement/payrollManagement/components/formDia.vue
+++ b/src/views/personnelManagement/payrollManagement/components/formDia.vue
@@ -168,8 +168,8 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js";
+import {staffOnJobInfo, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -234,12 +234,16 @@
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
-	getStaffOnJob().then(res => {
-		personList.value = res.data
-	})
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
+  })
 	form.value = {}
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
+    staffOnJobInfo(row.staffId).then(res => {
 			form.value = {...row}
 			form.value.payDate = form.value.payDate + '-01'
     })
diff --git a/src/views/personnelManagement/payrollManagement/index.vue b/src/views/personnelManagement/payrollManagement/index.vue
index 24e3dd8..f17f42e 100644
--- a/src/views/personnelManagement/payrollManagement/index.vue
+++ b/src/views/personnelManagement/payrollManagement/index.vue
@@ -53,7 +53,6 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue";
-import {staffJoinDel} from "@/api/personnelManagement/onboarding.js";
 import {ElMessageBox} from "element-plus";
 import dayjs from "dayjs";
 import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js";
diff --git a/src/views/personnelManagement/scheduling/index.vue b/src/views/personnelManagement/scheduling/index.vue
index 251dbe9..19d2062 100644
--- a/src/views/personnelManagement/scheduling/index.vue
+++ b/src/views/personnelManagement/scheduling/index.vue
@@ -253,9 +253,9 @@
 import {useDict} from "@/utils/dict.js"
 import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue'
 import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js"
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
 import pagination from "@/components/PIMTable/Pagination.vue";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 const { proxy } = getCurrentInstance();
 
@@ -317,8 +317,12 @@
  * 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
  */
 const getPersonList = () => {
-  getStaffOnJob().then(res => {
-    personList.value = res.data
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
   })
 };
 const paginationChange = (obj) => {
diff --git a/src/views/personnelManagement/selfService/index.vue b/src/views/personnelManagement/selfService/index.vue
index ca683c0..647f149 100644
--- a/src/views/personnelManagement/selfService/index.vue
+++ b/src/views/personnelManagement/selfService/index.vue
@@ -221,8 +221,7 @@
 
 const { proxy } = getCurrentInstance()
 import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinUpdate, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import { fa, id } from 'element-plus/es/locales.mjs'
+import {staffOnJobListPage, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
 
 const tableLoading = ref(false)
 // 鍒嗛〉鍙傛暟
@@ -572,7 +571,7 @@
       currentUser.value = res.data
       // console.log("----",currentUser.value)
         //寰楀埌浜哄憳鍒楄〃
-        staffJoinListPage({staffState: 1}).then(res => {
+      staffOnJobListPage({staffState: 1}).then(res => {
           //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
           // let tableData = res.data.records
           user.value = res.data.records.find(item => item.staffName === currentUser.value.userName)
@@ -604,18 +603,15 @@
     const userRes = await getUserProfile();
     if (userRes.code === 200) {
       currentUser.value = userRes.data;
-      const staffListRes = await staffJoinListPage({ staffState: 1 });
+      const staffListRes = await staffOnJobListPage({ staffState: 1 });
       user.value = staffListRes.data.records.find(item => item.staffName === currentUser.value.userName);
-      // console.log("++++", user.value);
-
       Object.assign(joinForm, user.value);
       joinForm.staffName = profileForm.name;
       joinForm.phone = profileForm.phone;
       joinForm.email = profileForm.email;
       joinForm.adress = profileForm.adress; 
-      console.log(joinForm)
       // 璋冪敤鏇存柊涓汉淇℃伅鐨勬帴鍙�
-      staffJoinUpdate(joinForm).then(res => {
+      updateStaffOnJob(user.value.id, joinForm).then(res => {
         if (res.code === 200) {
           ElMessage.success('涓汉淇℃伅淇濆瓨鎴愬姛');
           getProfile();
diff --git a/src/views/procurementManagement/procurementLedger/fileList.vue b/src/views/procurementManagement/procurementLedger/fileList.vue
new file mode 100644
index 0000000..fb392c5
--- /dev/null
+++ b/src/views/procurementManagement/procurementLedger/fileList.vue
@@ -0,0 +1,67 @@
+<template>
+  <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+    <el-table :data="tableData" border height="40vh">
+      <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+      <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+          <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+          <el-button link type="danger" size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import filePreview from '@/components/filePreview/index.vue'
+import { delCommonFile } from '@/api/publicApi/commonFile.js'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+  dialogVisible.value = false
+}
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list
+}
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+// 鍒犻櫎闄勪欢
+const handleDelete = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎闄勪欢"${row.name}"鍚楋紵`, '鍒犻櫎纭', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning',
+  }).then(() => {
+    delCommonFile([row.id]).then(() => {
+      ElMessage.success('鍒犻櫎鎴愬姛')
+      // 浠庡垪琛ㄤ腑绉婚櫎宸插垹闄ょ殑闄勪欢
+      const index = tableData.value.findIndex(item => item.id === row.id)
+      if (index !== -1) {
+        tableData.value.splice(index, 1)
+      }
+    }).catch(() => {
+      ElMessage.error('鍒犻櫎澶辫触')
+    })
+  }).catch(() => {
+    proxy.$modal.msg('宸插彇娑堝垹闄�')
+  })
+}
+defineExpose({
+  open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 4fde128..9b86624 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -2,461 +2,442 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <el-form :model="searchForm" :inline="true">
+        <el-form :model="searchForm"
+                 :inline="true">
           <el-form-item label="渚涘簲鍟嗗悕绉帮細">
-            <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.supplierName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="閲囪喘鍚堝悓鍙凤細">
-            <el-input
-                v-model="searchForm.purchaseContractNumber"
-                style="width: 240px"
-                placeholder="璇疯緭鍏�"
-                @change="handleQuery"
-                clearable
-                :prefix-icon="Search"
-            />
+            <el-input v-model="searchForm.purchaseContractNumber"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      @change="handleQuery"
+                      clearable
+                      :prefix-icon="Search" />
           </el-form-item>
           <el-form-item label="閿�鍞悎鍚屽彿锛�">
-            <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.salesContractNo"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="椤圭洰鍚嶇О锛�">
-            <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+            <el-input v-model="searchForm.projectName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                      prefix-icon="Search"
                       @change="handleQuery" />
           </el-form-item>
           <el-form-item label="褰曞叆鏃ユ湡锛�">
-            <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-                            placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+            <el-date-picker v-model="searchForm.entryDate"
+                            value-format="YYYY-MM-DD"
+                            format="YYYY-MM-DD"
+                            type="daterange"
+                            placeholder="璇烽�夋嫨"
+                            clearable
+                            @change="changeDaterange" />
           </el-form-item>
           <el-form-item>
-            <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
+            <el-button type="primary"
+                       @click="handleQuery"> 鎼滅储 </el-button>
           </el-form-item>
         </el-form>
       </div>
-
     </div>
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
-        <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="primary"
+                   @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="success"
+                   @click="openScanAddDialog">鎵爜鏂板</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</el-button>
       </div>
-      <el-table
-          :data="tableData"
-          border
-          v-loading="tableLoading"
-          @selection-change="handleSelectionChange"
-          :expand-row-keys="expandedRowKeys"
-          :row-key="(row) => row.id"
-          show-summary
-          :summary-method="summarizeMainTable"
-          @expand-change="expandChange"
-          height="calc(100vh - 22em)"
-          :row-class-name="tableRowClassName"
-      >
-        <el-table-column align="center" type="selection" width="55" />
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                @selection-change="handleSelectionChange"
+                :expand-row-keys="expandedRowKeys"
+                :row-key="(row) => row.id"
+                show-summary
+                :summary-method="summarizeMainTable"
+                @expand-change="expandChange"
+                height="calc(100vh - 19em)"
+                :row-class-name="tableRowClassName">
+        <el-table-column align="center"
+                         type="selection"
+                         width="55" />
         <el-table-column type="expand">
           <template #default="props">
-            <el-table
-                :data="props.row.children"
-                border
-                show-summary
-                :summary-method="summarizeChildrenTable"
-            >
-              <el-table-column
-                  align="center"
-                  label="搴忓彿"
-                  type="index"
-                  width="60"
-              />
-              <el-table-column label="浜у搧澶х被" prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-              <el-table-column label="鍗曚綅" prop="unit" />
-              <el-table-column label="鏁伴噺" prop="quantity" />
-              <el-table-column label="绋庣巼(%)" prop="taxRate" />
-              <el-table-column
-                  label="鍚◣鍗曚环(鍏�)"
-                  prop="taxInclusiveUnitPrice"
-                  :formatter="formattedNumber"
-              />
-              <el-table-column
-                  label="鍚◣鎬讳环(鍏�)"
-                  prop="taxInclusiveTotalPrice"
-                  :formatter="formattedNumber"
-              />
-              <el-table-column
-                  label="涓嶅惈绋庢�讳环(鍏�)"
-                  prop="taxExclusiveTotalPrice"
-                  :formatter="formattedNumber"
-              />
+            <el-table :data="props.row.children"
+                      border
+                      show-summary
+                      :summary-method="summarizeChildrenTable">
+              <el-table-column align="center"
+                               label="搴忓彿"
+                               type="index"
+                               width="60" />
+              <el-table-column label="浜у搧澶х被"
+                               prop="productCategory" />
+              <el-table-column label="瑙勬牸鍨嬪彿"
+                               prop="specificationModel" />
+              <el-table-column label="鍗曚綅"
+                               prop="unit" />
+              <el-table-column label="鏁伴噺"
+                               prop="quantity" />
+              <el-table-column label="绋庣巼(%)"
+                               prop="taxRate" />
+              <el-table-column label="鍚◣鍗曚环(鍏�)"
+                               prop="taxInclusiveUnitPrice"
+                               :formatter="formattedNumber" />
+              <el-table-column label="鍚◣鎬讳环(鍏�)"
+                               prop="taxInclusiveTotalPrice"
+                               :formatter="formattedNumber" />
+              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+                               prop="taxExclusiveTotalPrice"
+                               :formatter="formattedNumber" />
             </el-table>
           </template>
         </el-table-column>
-        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-        <el-table-column
-            label="閲囪喘鍚堝悓鍙�"
-            prop="purchaseContractNumber"
-            width="200"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="閿�鍞悎鍚屽彿"
-            prop="salesContractNo"
-            width="200"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="渚涘簲鍟嗗悕绉�"
-            width="240"
-            prop="supplierName"
-            show-overflow-tooltip
-        />
-        <el-table-column label="璁㈠崟鐘舵��" width="100" align="center">
+        <el-table-column align="center"
+                         label="搴忓彿"
+                         type="index"
+                         width="60" />
+        <el-table-column label="閲囪喘鍚堝悓鍙�"
+                         prop="purchaseContractNumber"
+                         width="200"
+                         show-overflow-tooltip />
+        <el-table-column label="閿�鍞悎鍚屽彿"
+                         prop="salesContractNo"
+                         show-overflow-tooltip />
+        <el-table-column label="渚涘簲鍟嗗悕绉�"
+                         prop="supplierName"
+                         show-overflow-tooltip />
+        <el-table-column label="璁㈠崟鐘舵��"
+                         width="100"
+                         align="center">
           <template #default="scope">
-            <el-tag v-if="scope.row.isInvalid" type="danger" size="small">澶辨晥</el-tag>
-            <el-tag v-else type="success" size="small">姝e父</el-tag>
+            <el-tag v-if="scope.row.isInvalid"
+                    type="danger"
+                    size="small">澶辨晥</el-tag>
+            <el-tag v-else
+                    type="success"
+                    size="small">姝e父</el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-            label="椤圭洰鍚嶇О"
-            prop="projectName"
-            width="420"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="瀹℃壒鐘舵��"
-            prop="approvalStatus"
-            width="200"
-            show-overflow-tooltip
-        >
+        <el-table-column label="椤圭洰鍚嶇О"
+                         prop="projectName"
+                         width="420"
+                         show-overflow-tooltip />
+        <el-table-column label="瀹℃壒鐘舵��"
+                         prop="approvalStatus"
+                         width="200"
+                         show-overflow-tooltip>
           <template #default="scope">
-            <el-tag
-                size="small"
-            >
+            <el-tag size="small">
               {{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-            label="浠樻鏂瑰紡"
-            width="100"
-            prop="paymentMethod"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="鍚堝悓閲戦(鍏�)"
-            prop="contractAmount"
-            width="200"
-            show-overflow-tooltip
-            :formatter="formattedNumber"
-        />
-        <el-table-column
-            label="褰曞叆浜�"
-            prop="recorderName"
-            width="100"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            label="褰曞叆鏃ユ湡"
-            prop="entryDate"
-            width="100"
-            show-overflow-tooltip
-        />
-        <el-table-column
-            fixed="right"
-            label="鎿嶄綔"
-            width="100"
-            align="center"
-        >
+        <el-table-column label="绛捐鏃ユ湡"
+                         prop="executionDate"
+                         width="100"
+                         show-overflow-tooltip />
+        <el-table-column label="浠樻鏂瑰紡"
+                         width="100"
+                         prop="paymentMethod"
+                         show-overflow-tooltip />
+        <el-table-column label="鍚堝悓閲戦(鍏�)"
+                         prop="contractAmount"
+                         width="200"
+                         show-overflow-tooltip
+                         :formatter="formattedNumber" />
+        <el-table-column label="褰曞叆浜�"
+                         prop="recorderName"
+                         width="120"
+                         show-overflow-tooltip />
+        <el-table-column label="褰曞叆鏃ユ湡"
+                         prop="entryDate"
+                         width="100"
+                         show-overflow-tooltip />
+        <el-table-column fixed="right"
+                         label="鎿嶄綔"
+                         width="180"
+                         align="center">
           <template #default="scope">
-            <el-button
-                link
-                type="primary"
-                size="small"
-                @click="openForm('edit', scope.row)"
-            >缂栬緫</el-button
-            >
-
+            <el-button link
+                       type="primary"
+                       size="small"
+                       @click="openForm('edit', scope.row)">缂栬緫</el-button>
+            <el-button link
+                       type="success"
+                       size="small"
+                       @click="showQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
+            <el-button link
+                       type="primary"
+                       size="small"
+                       @click="downLoadFile(scope.row)">闄勪欢</el-button>
           </template>
         </el-table-column>
       </el-table>
-      <pagination
-          v-show="total > 0"
-          :total="total"
-          layout="total, sizes, prev, pager, next, jumper"
-          :page="page.current"
-          :limit="page.size"
-          @pagination="paginationChange"
-      />
+      <pagination v-show="total > 0"
+                  :total="total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="paginationChange" />
     </div>
-    <FormDialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
-        :width="'70%'"
-        :operation-type="operationType"
-        @close="closeDia"
-        @confirm="submitForm"
-        @cancel="closeDia"
-    >
-      <el-form
-          :model="form"
-          label-width="140px"
-          label-position="top"
-          :rules="rules"
-          ref="formRef"
-      >
+    <el-dialog v-model="dialogFormVisible"
+               :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
+               width="70%"
+               @close="closeDia">
+      <el-form :model="form"
+               label-width="140px"
+               label-position="top"
+               :rules="rules"
+               ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
-              <el-input
-                  v-model="form.purchaseContractNumber"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+                          prop="purchaseContractNumber">
+              <el-input v-model="form.purchaseContractNumber"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
-              <el-select
-                  v-model="form.salesLedgerId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="salesLedgerChange"
-              >
-                <el-option
-                    v-for="item in salesContractList"
-                    :key="item.id"
-                    :label="item.salesContractNo"
-                    :value="item.id"
-                />
+            <el-form-item label="閿�鍞悎鍚屽彿锛�"
+                          prop="salesLedgerId">
+              <el-select v-model="form.salesLedgerId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable
+                         @change="salesLedgerChange">
+                <el-option v-for="item in salesContractList"
+                           :key="item.id"
+                           :label="item.salesContractNo"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
-              <el-select
-                  v-model="form.supplierId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  filterable
-                  allow-create
-              >
-                <el-option
-                    v-for="item in supplierList"
-                    :key="item.id"
-                    :label="item.supplierName"
-                    :value="item.id"
-                />
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+                          prop="supplierId">
+              <el-select v-model="form.supplierId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable>
+                <el-option v-for="item in supplierList"
+                           :key="item.id"
+                           :label="item.supplierName"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
-              <el-input
-                  v-model="form.projectName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="椤圭洰鍚嶇О"
+                          prop="projectName">
+              <el-input v-model="form.projectName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input
-                  v-model="form.paymentMethod"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+              <el-input v-model="form.paymentMethod"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
-              <el-date-picker
-                  style="width: 100%"
-                  v-model="form.executionDate"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  type="date"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              />
+            <el-form-item label="绛捐鏃ユ湡锛�"
+                          prop="executionDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.executionDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="瀹℃壒浜猴細" prop="approverId">
-              <el-select
-                  v-model="form.approverId"
-                  placeholder="璇烽�夋嫨瀹℃壒浜�"
-                  clearable
-              >
-                <el-option
-                    v-for="item in userList"
-                    :key="item.userId"
-                    :label="item.nickName"
-                    :value="item.userId"
-                />
+            <el-form-item label="瀹℃壒浜猴細"
+                          prop="approverId">
+              <el-select v-model="form.approverId"
+                         placeholder="璇烽�夋嫨瀹℃壒浜�"
+                         clearable>
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
               </el-select>
             </el-form-item>
-            <el-form-item label="褰曞叆浜猴細" prop="recorderId" v-show="false">
-              <el-select
-                  v-model="form.recorderId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  disabled
-              >
-                <el-option
-                    v-for="item in userList"
-                    :key="item.userId"
-                    :label="item.nickName"
-                    :value="item.userId"
-                />
+            <el-form-item label="褰曞叆浜猴細"
+                          prop="recorderId"
+                          v-show="false">
+              <el-select v-model="form.recorderId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         disabled>
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
-              <el-date-picker
-                  style="width: 100%"
-                  v-model="form.entryDate"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  type="date"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              />
+            <el-form-item label="褰曞叆鏃ユ湡锛�"
+                          prop="entryDate">
+              <el-date-picker style="width: 100%"
+                              v-model="form.entryDate"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
-            <el-button type="primary" @click="openProductForm('add')"
-            >娣诲姞</el-button
-            >
-            <el-button plain type="danger" @click="deleteProduct"
-            >鍒犻櫎</el-button
-            >
+          <el-form-item label="浜у搧淇℃伅锛�"
+                        prop="entryDate">
+            <el-button type="primary"
+                       @click="openProductForm('add')">娣诲姞</el-button>
+            <el-button plain
+                       type="danger"
+                       @click="deleteProduct">鍒犻櫎</el-button>
           </el-form-item>
-          <div class="select-button-group" style="width: 220px; margin: 20px 0;" v-if="operationType === 'add'">
-            <el-select
-                filterable
-                allow-create
-                :reserve-keyword="true"
-                :default-first-option="false"
-                v-model="templateName"
-                :input-value="filterInputValue"
-                @filter-change="onTemplateFilterChange"
-                @change="onTemplateChange"
-                style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
-                placeholder="璇烽�夋嫨"
-                class="no-arrow-select"
-            >
-              <el-option
-                  v-for="item in templateList"
-                  :key="item.value"
-                  :label="item.templateName"
-                  :value="item.templateName"
-              ></el-option>
+          <div class="select-button-group"
+               style="width: 220px; margin: 20px 0;"
+               v-if="operationType === 'add'">
+            <el-select filterable
+                       allow-create
+                       :reserve-keyword="true"
+                       :default-first-option="false"
+                       v-model="templateName"
+                       :input-value="filterInputValue"
+                       @filter-change="onTemplateFilterChange"
+                       @change="onTemplateChange"
+                       style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
+                       placeholder="璇烽�夋嫨"
+                       class="no-arrow-select">
+              <el-option v-for="item in templateList"
+                         :key="item.value"
+                         :label="item.templateName"
+                         :value="item.templateName"></el-option>
             </el-select>
             <!-- 鎸夐挳锛氫笌 Select 楂樺害鍖归厤锛屽幓鎺夊乏渚ц竟妗嗭紝鏃犵紳琛旀帴 -->
-            <el-button
-                size="small"
-                style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
-                @click="handleButtonClick"
-                :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate"
-            >
+            <el-button size="small"
+                       style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
+                       @click="handleButtonClick"
+                       :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate">
               淇濆瓨
             </el-button>
           </div>
         </el-row>
-        <el-table
-            :data="productData"
-            border
-            @selection-change="productSelected"
-            show-summary
-            :summary-method="summarizeProTable"
-        >
-          <el-table-column align="center" type="selection" width="55" />
-          <el-table-column
-              align="center"
-              label="搴忓彿"
-              type="index"
-              width="60"
-          />
-          <el-table-column label="浜у搧澶х被" prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-          <el-table-column label="鍗曚綅" prop="unit" width="70" />
-          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
-          <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
-          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
-          <el-table-column
-              label="鍚◣鍗曚环(鍏�)"
-              prop="taxInclusiveUnitPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              label="鍚◣鎬讳环(鍏�)"
-              prop="taxInclusiveTotalPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              label="涓嶅惈绋庢�讳环(鍏�)"
-              prop="taxExclusiveTotalPrice"
-              :formatter="formattedNumber"
-              width="150"
-          />
-          <el-table-column
-              fixed="right"
-              label="鎿嶄綔"
-              min-width="60"
-              align="center"
-          >
+        <el-table :data="productData"
+                  border
+                  @selection-change="productSelected"
+                  show-summary
+                  :summary-method="summarizeProTable">
+          <el-table-column align="center"
+                           type="selection"
+                           width="55" />
+          <el-table-column align="center"
+                           label="搴忓彿"
+                           type="index"
+                           width="60" />
+          <el-table-column label="浜у搧澶х被"
+                           prop="productCategory" />
+          <el-table-column label="瑙勬牸鍨嬪彿"
+                           prop="specificationModel" />
+          <el-table-column label="鍗曚綅"
+                           prop="unit"
+                           width="70" />
+          <el-table-column label="鏁伴噺"
+                           prop="quantity"
+                           width="70" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺"
+                           prop="warnNum"
+                           width="120"
+                           show-overflow-tooltip />
+          <el-table-column label="绋庣巼(%)"
+                           prop="taxRate"
+                           width="80" />
+          <el-table-column label="鍚◣鍗曚环(鍏�)"
+                           prop="taxInclusiveUnitPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="鍚◣鎬讳环(鍏�)"
+                           prop="taxInclusiveTotalPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+                           prop="taxExclusiveTotalPrice"
+                           :formatter="formattedNumber"
+                           width="150" />
+          <el-table-column label="鏄惁璐ㄦ"
+                           prop="isChecked"
+                           width="150">
             <template #default="scope">
-              <el-button
-                  link
-                  type="primary"
-                  size="small"
-                  @click="openProductForm('edit', scope.row, scope.$index)"
-              >缂栬緫</el-button
-              >
+              <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
+                {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column fixed="right"
+                           label="鎿嶄綔"
+                           min-width="60"
+                           align="center">
+            <template #default="scope">
+              <el-button link
+                         type="primary"
+                         size="small"
+                         @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
             </template>
           </el-table-column>
         </el-table>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="澶囨敞路锛�" prop="remark">
-              <el-input
-                  v-model="form.remark"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-                  type="textarea"
-                  :rows="2"
-              />
+            <el-form-item label="澶囨敞路锛�"
+                          prop="remark">
+              <el-input v-model="form.remark"
+                        placeholder="璇疯緭鍏�"
+                        clearable
+                        type="textarea"
+                        :rows="2" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
-              <el-upload
-                  v-model:file-list="fileList"
-                  :action="upload.url"
-                  multiple
-                  ref="fileUpload"
-                  auto-upload
-                  :headers="upload.headers"
-                  :before-upload="handleBeforeUpload"
-                  :on-error="handleUploadError"
-                  :on-success="handleUploadSuccess"
-                  :on-remove="handleRemove"
-              >
+            <el-form-item label="闄勪欢鏉愭枡锛�"
+                          prop="remark">
+              <el-upload v-model:file-list="fileList"
+                         :action="upload.url"
+                         multiple
+                         ref="fileUpload"
+                         auto-upload
+                         :headers="upload.headers"
+                         :before-upload="handleBeforeUpload"
+                         :on-error="handleUploadError"
+                         :on-success="handleUploadSuccess"
+                         :on-remove="handleRemove">
                 <el-button type="primary">涓婁紶</el-button>
                 <template #tip>
                   <div class="el-upload__tip">
@@ -469,509 +450,764 @@
           </el-col>
         </el-row>
       </el-form>
-    </FormDialog>
-    <FormDialog
-        v-model="productFormVisible"
-        :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
-        :width="'40%'"
-        :operation-type="productOperationType"
-        @close="closeProductDia"
-        @confirm="submitProduct"
-        @cancel="closeProductDia"
-    >
-      <el-form
-          :model="productForm"
-          label-width="140px"
-          label-position="top"
-          :rules="productRules"
-          ref="productFormRef"
-      >
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitForm">纭</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <el-dialog v-model="productFormVisible"
+               :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+               width="40%"
+               @close="closeProductDia">
+      <el-form :model="productForm"
+               label-width="140px"
+               label-position="top"
+               :rules="productRules"
+               ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="浜у搧澶х被锛�" prop="productId">
-              <el-tree-select
-                  v-model="productForm.productId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  check-strictly
-                  @change="getModels"
-                  :data="productOptions"
-                  :render-after-expand="false"
-                  style="width: 100%"
-              />
+            <el-form-item label="浜у搧澶х被锛�"
+                          prop="productId">
+              <el-tree-select v-model="productForm.productId"
+                              placeholder="璇烽�夋嫨"
+                              clearable
+                              check-strictly
+                              @change="getModels"
+                              :data="productOptions"
+                              :render-after-expand="false"
+                              style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
-              <el-select
-                  v-model="productForm.productModelId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="getProductModel"
-              >
-                <el-option
-                    v-for="item in modelOptions"
-                    :key="item.id"
-                    :label="item.model"
-                    :value="item.id"
-                />
+            <el-form-item label="瑙勬牸鍨嬪彿锛�"
+                          prop="productModelId">
+              <el-select v-model="productForm.productModelId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         @change="getProductModel">
+                <el-option v-for="item in modelOptions"
+                           :key="item.id"
+                           :label="item.model"
+                           :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍗曚綅锛�" prop="unit">
-              <el-input
-                  v-model="productForm.unit"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
+            <el-form-item label="鍗曚綅锛�"
+                          prop="unit">
+              <el-input v-model="productForm.unit"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
-              <el-select
-                  v-model="productForm.taxRate"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  @change="mathNum"
-              >
-                <el-option label="1" value="1" />
-                <el-option label="6" value="6" />
-                <el-option label="13" value="13" />
+            <el-form-item label="绋庣巼(%)锛�"
+                          prop="taxRate">
+              <el-select v-model="productForm.taxRate"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         @change="mathNum">
+                <el-option label="1"
+                           value="1" />
+                <el-option label="6"
+                           value="6" />
+                <el-option label="13"
+                           value="13" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
-              <el-input-number
-                  v-model="productForm.taxInclusiveUnitPrice"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-                  @change="mathNum"
-              />
+            <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
+                          prop="taxInclusiveUnitPrice">
+              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="mathNum" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鏁伴噺锛�" prop="quantity">
-              <el-input-number
-                  :step="0.1"
-                  clearable
-                  :precision="2"
-                  style="width: 100%"
-                  v-model="productForm.quantity"
-                  placeholder="璇疯緭鍏�"
-                  @change="mathNum"
-              />
+            <el-form-item label="鏁伴噺锛�"
+                          prop="quantity">
+              <el-input-number :step="0.1"
+                               clearable
+                               :precision="2"
+                               :min="0"
+                               style="width: 100%"
+                               v-model="productForm.quantity"
+                               placeholder="璇疯緭鍏�"
+                               @change="mathNum" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
-              <el-input-number
-                  v-model="productForm.taxInclusiveTotalPrice"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-                  @change="reverseMathNum('taxInclusiveTotalPrice')"
-              />
+            <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
+                          prop="taxInclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item
-                label="涓嶅惈绋庢�讳环(鍏�)锛�"
-                prop="taxExclusiveTotalPrice"
-            >
-              <el-input
-                  v-model="productForm.taxExclusiveTotalPrice"
-                  @change="reverseMathNum('taxExclusiveTotalPrice')"
-              />
+            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
+                          prop="taxExclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%"
+                               @change="reverseMathNum('taxExclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
-              <el-select
-                  v-model="productForm.invoiceType"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              >
-                <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
-                <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
+            <el-form-item label="鍙戠エ绫诲瀷锛�"
+                          prop="invoiceType">
+              <el-select v-model="productForm.invoiceType"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="澧炴櫘绁�"
+                           value="澧炴櫘绁�" />
+                <el-option label="澧炰笓绁�"
+                           value="澧炰笓绁�" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
-              <el-input-number
-                  v-model="productForm.warnNum"
-                  :precision="2"
-                  :step="0.1"
-                  clearable
-                  style="width: 100%"
-              />
+            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
+                          prop="warnNum">
+              <el-input-number v-model="productForm.warnNum"
+                               :precision="2"
+                               :step="0.1"
+                               :min="0"
+                               clearable
+                               style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏄惁璐ㄦ锛�"
+                          prop="isChecked">
+              <el-radio-group v-model="productForm.isChecked">
+                <el-radio label="鏄�"
+                          :value="true" />
+                <el-radio label="鍚�"
+                          :value="false" />
+              </el-radio-group>
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
-    </FormDialog>
-
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitProduct">纭</el-button>
+          <el-button @click="closeProductDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
+    <el-dialog v-model="qrCodeDialogVisible"
+               title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
+               width="400px"
+               center>
+      <div style="text-align: center;">
+        <img :src="qrCodeUrl"
+             alt="浜岀淮鐮�"
+             style="width:200px;height:200px;" />
+        <div style="margin: 20px;">
+          <el-button type="primary"
+                     @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!-- 鎵爜鏂板瀵硅瘽妗� -->
+    <el-dialog v-model="scanAddDialogVisible"
+               title="鎵爜鏂板閲囪喘鍙拌处"
+               width="70%"
+               @close="closeScanAddDialog">
+      <el-form :model="scanAddForm"
+               label-width="140px"
+               label-position="top"
+               :rules="scanAddRules"
+               ref="scanAddFormRef">
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜鍐呭锛�">
+              <el-input v-model="scanAddForm.scanContent"
+                        type="textarea"
+                        :rows="3"
+                        placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
+                        @input="parseScanContent" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
+                          prop="purchaseContractNumber">
+              <el-input v-model="scanAddForm.purchaseContractNumber"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
+                          prop="supplierName">
+              <el-input v-model="scanAddForm.supplierName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�"
+                          prop="projectName">
+              <el-input v-model="scanAddForm.projectName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓閲戦(鍏�)锛�"
+                          prop="contractAmount">
+              <el-input-number v-model="scanAddForm.contractAmount"
+                               :precision="2"
+                               :step="0.1"
+                               clearable
+                               style="width: 100%"
+                               placeholder="璇疯緭鍏�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡锛�">
+              <el-input v-model="scanAddForm.paymentMethod"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="褰曞叆浜猴細">
+              <el-input v-model="scanAddForm.recorderName"
+                        disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞锛�">
+              <el-input v-model="scanAddForm.remark"
+                        type="textarea"
+                        :rows="2"
+                        placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitScanAdd">纭鏂板</el-button>
+          <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 鎵爜鐧昏瀵硅瘽妗� -->
+    <el-dialog v-model="scanDialogVisible"
+               title="鎵爜鐧昏"
+               width="60%"
+               @close="closeScanDialog">
+      <el-form :model="scanForm"
+               label-width="120px"
+               label-position="left"
+               :rules="scanRules"
+               ref="scanFormRef">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+              <el-input v-model="scanForm.purchaseContractNumber"
+                        disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+              <el-input v-model="scanForm.supplierName"
+                        disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�">
+              <el-input v-model="scanForm.projectName"
+                        disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鏃堕棿锛�">
+              <el-input v-model="scanForm.scanTime"
+                        disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鎵爜浜猴細">
+              <el-input v-model="scanForm.scannerName"
+                        disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鐘舵�侊細">
+              <el-tag :type="scanForm.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                {{ scanForm.scanStatus }}
+              </el-tag>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜澶囨敞锛�">
+              <el-input v-model="scanForm.scanRemark"
+                        type="textarea"
+                        :rows="3"
+                        placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜璁板綍锛�">
+              <el-table :data="scanRecords"
+                        border
+                        style="width: 100%">
+                <el-table-column label="搴忓彿"
+                                 type="index"
+                                 width="60"
+                                 align="center" />
+                <el-table-column label="鎵爜鏃堕棿"
+                                 prop="scanTime"
+                                 width="180" />
+                <el-table-column label="鎵爜浜�"
+                                 prop="scannerName"
+                                 width="120" />
+                <el-table-column label="鎵爜鐘舵��"
+                                 prop="scanStatus"
+                                 width="100">
+                  <template #default="scope">
+                    <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                      {{ scope.row.scanStatus }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column label="澶囨敞"
+                                 prop="scanRemark" />
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitScan">纭鎵爜</el-button>
+          <el-button @click="closeScanDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <FileList ref="fileListRef" />
   </div>
 </template>
 
 <script setup>
-import {getToken} from "@/utils/auth";
-import pagination from "@/components/PIMTable/Pagination.vue";
-import FormDialog from '@/components/Dialog/FormDialog.vue';
-import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from "vue";
-import {Search} from "@element-plus/icons-vue";
-import {ElMessage, ElMessageBox} from "element-plus";
-import {userListNoPage} from "@/api/system/user.js";
-import {
-  addOrUpdateSalesLedgerProduct,
-  delLedgerFile,
-  delProduct,
-  getProductInfoByContractNo,
-  getSalesLedgerWithProducts,
-} from "@/api/salesManagement/salesLedger.js";
-import {
-  addOrEditPurchase,
-  addPurchaseTemplate,
-  createPurchaseNo,
-  delPurchase,
-  getOptions,
-  getPurchaseById,
-  getPurchaseTemplateList,
-  getSalesNo,
-  productList,
-  purchaseListPage
-} from "@/api/procurementManagement/procurementLedger.js";
-import useFormData from "@/hooks/useFormData.js";
-import useUserStore from "@/store/modules/user";
-import {modelList, productTreeList} from "@/api/basicData/product.js";
-import dayjs from "dayjs";
-import { getCurrentDate } from "@/utils/index.js";
+  import { getToken } from "@/utils/auth";
+  import pagination from "@/components/PIMTable/Pagination.vue";
+  import {
+    ref,
+    onMounted,
+    reactive,
+    toRefs,
+    getCurrentInstance,
+    nextTick,
+  } from "vue";
+  import { Search } from "@element-plus/icons-vue";
+  import { ElMessageBox, ElMessage } from "element-plus";
+  import { userListNoPage } from "@/api/system/user.js";
+  import FileList from "./fileList.vue";
+  import {
+    getSalesLedgerWithProducts,
+    addOrUpdateSalesLedgerProduct,
+    delProduct,
+    delLedgerFile,
+    getProductInfoByContractNo,
+  } from "@/api/salesManagement/salesLedger.js";
+  import {
+    addOrEditPurchase,
+    addPurchaseTemplate,
+    createPurchaseNo,
+    delPurchase,
+    getSalesNo,
+    purchaseListPage,
+    productList,
+    getPurchaseById,
+    getOptions,
+    getPurchaseTemplateList,
+  } from "@/api/procurementManagement/procurementLedger.js";
+  import useFormData from "@/hooks/useFormData.js";
+  import QRCode from "qrcode";
 
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const modelOptions = ref([]);
-const userList = ref([]);
-const productOptions = ref([]);
-const salesContractList = ref([]);
-const supplierList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
+  const { proxy } = getCurrentInstance();
+  const tableData = ref([]);
+  const productData = ref([]);
+  const selectedRows = ref([]);
+  const productSelectedRows = ref([]);
+  const modelOptions = ref([]);
+  const userList = ref([]);
+  const productOptions = ref([]);
+  const salesContractList = ref([]);
+  const supplierList = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+  });
+  const total = ref(0);
+  const fileList = ref([]);
+  import useUserStore from "@/store/modules/user";
+  import { modelList, productTreeList } from "@/api/basicData/product.js";
+  import dayjs from "dayjs";
 
-const userStore = useUserStore();
+  const userStore = useUserStore();
 
-// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
-const approvalStatusText = {
-  0: '瀹℃壒涓�',
-  1: '瀹℃壒閫氳繃',
-  2: '瀹℃壒澶辫触'
-};
+  // 浜岀淮鐮佺浉鍏冲彉閲�
+  const qrCodeDialogVisible = ref(false);
+  const qrCodeUrl = ref("");
 
+  // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
+  const approvalStatusText = {
+    0: "瀹℃壒涓�",
+    1: "瀹℃壒閫氳繃",
+    2: "瀹℃壒澶辫触",
+  };
 
-const templateName = ref('');
-const filterInputValue = ref('');
-const templateList = ref([]);
-const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
-
-// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-const checkTemplateNameDuplicate = (name) => {
-  if (!name || name.trim() === '') {
-    isTemplateNameDuplicate.value = false;
-    return false;
-  }
-  const isDuplicate = templateList.value.some(item => item.templateName === name.trim());
-  isTemplateNameDuplicate.value = isDuplicate;
-  return isDuplicate;
-};
-
-// 闃叉姈瀹氭椂鍣�
-let duplicateCheckTimer = null;
-const onTemplateFilterChange = (val) => {
-  filterInputValue.value = val ?? '';
-  // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
-  if (duplicateCheckTimer) {
-    clearTimeout(duplicateCheckTimer);
-  }
-  // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
-  if (val && val.trim()) {
-    duplicateCheckTimer = setTimeout(() => {
-      const isDuplicate = checkTemplateNameDuplicate(val);
-      if (isDuplicate) {
-        ElMessage({
-          message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
-          type: 'warning',
-          duration: 2000
-        });
-      }
-    }, 300); // 300ms 闃叉姈
-  } else {
-    isTemplateNameDuplicate.value = false;
-  }
-};
-
-// allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
-const onTemplateChange = async (val) => {
-  if (typeof val === 'string') {
-    filterInputValue.value = val;
-    // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
-    checkTemplateNameDuplicate(val);
-  }
-  
-  // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
-  const matchedTemplate = templateList.value.find(item => item.templateName === val);
-  
-  if (matchedTemplate?.id) {
-    // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
-    form.value = {
-      ...form.value,
-      ...matchedTemplate,
-    };
-    productData.value = matchedTemplate.productData || [];
-    // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
-    try {
-      const res = await createPurchaseNo();
-      if (res?.data) {
-        form.value.purchaseContractNumber = res.data;
-      }
-    } catch (error) {
-      console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
-    }
-  } else {
-    // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
-    const currentFormData = { ...form.value };
-    const currentProductData = [...productData.value];
-    
-    // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
-    if (!dialogFormVisible.value) {
-      operationType.value = 'add';
-      dialogFormVisible.value = true;
-    }
-    
-    // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
-    await nextTick();
-    form.value = {
-      ...form.value,
-      ...currentFormData,
-    };
-    productData.value = currentProductData;
-  }
-};
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
-  searchForm: {
-    supplierName: "", // 渚涘簲鍟嗗悕绉�
-    purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
-    salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
-    projectName: "", // 椤圭洰鍚嶇О
-    entryDate: null, // 褰曞叆鏃ユ湡
-    entryDateStart: undefined,
-    entryDateEnd: undefined,
-  },
-  form: {
-    purchaseContractNumber: "",
-    salesLedgerId: "",
-    projectName: "",
-    recorderId: "",
-    entryDate: "",
-    productData: [],
-    supplierName: "",
-    supplierId: "",
-    paymentMethod: "",
-    executionDate: "",
-  },
-  rules: {
-    purchaseContractNumber: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    approverId:[{ required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" }],
-    executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-  },
-});
-const {  form, rules } = toRefs(data);
-const { form: searchForm } = useFormData(data.searchForm);
-
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const productOperationIndex = ref("");
-const currentId = ref("");
-const productFormData = reactive({
-  productForm: {
-    productId: "",
-    productCategory: "",
-    productModelId: "",
-    specificationModel: "",
-    unit: "",
-    quantity: "",
-    taxInclusiveUnitPrice: "",
-    taxRate: "",
-    taxInclusiveTotalPrice: "",
-    taxExclusiveTotalPrice: "",
-    invoiceType: "",
-    warnNum: "",
-  },
-  productRules: {
-    productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    taxInclusiveUnitPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    warnNum: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
-    taxInclusiveTotalPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    taxExclusiveTotalPrice: [
-      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-    ],
-    invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-  },
-});
-const { productForm, productRules } = toRefs(productFormData);
-const upload = reactive({
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-  headers: { Authorization: "Bearer " + getToken() },
-});
-
-const changeDaterange = (value) => {
-  if (value) {
-    searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
-    searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
-  } else {
-    searchForm.entryDateStart = undefined;
-    searchForm.entryDateEnd = undefined;
-  }
-  handleQuery();
-};
-
-const formattedNumber = (row, column, cellValue) => {
-  if (cellValue === null || cellValue === undefined || cellValue === '') {
-    return '0.00';
-  }
-  const num = parseFloat(cellValue);
-  if (isNaN(num)) {
-    return '0.00';
-  }
-  return num.toFixed(2);
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-
-// 淇濆瓨妯℃澘
-const handleButtonClick = async () => {
-  // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
-  if (!templateName.value || templateName.value.trim() === '') {
-    ElMessage({
-      message: '璇疯緭鍏ユā鏉垮悕绉�',
-      type: 'warning',
-    });
-    return;
-  }
+  const templateName = ref("");
+  const filterInputValue = ref("");
+  const templateList = ref([]);
+  const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
 
   // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-  const isDuplicate = checkTemplateNameDuplicate(templateName.value);
-  if (isDuplicate) {
-    ElMessage({
-      message: '妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�',
-      type: 'warning',
-    });
-    return;
-  }
-
-  // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
-  if (!form.value.supplierId) {
-    ElMessage({
-      message: '璇峰厛閫夋嫨渚涘簲鍟�',
-      type: 'warning',
-    });
-    return;
-  }
-
-  // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
-  // if (!productData.value || productData.value.length === 0) {
-  //   ElMessage({
-  //     message: '璇峰厛娣诲姞浜у搧淇℃伅',
-  //     type: 'warning',
-  //   });
-  //   return;
-  // }
-
-  try {
-    let params = {
-      productData: proxy.HaveJson(productData.value),
-      supplierId: form.value.supplierId,
-      paymentMethod: form.value.paymentMethod,
-      recorderId: form.value.recorderId,
-      approverId: form.value.approverId,
-      templateName: templateName.value.trim()
-    };
-    console.log(params);
-    let res = await addPurchaseTemplate(params);
-
-    if (res && res.code === 200) {
-      ElMessage({
-        message: '妯℃澘淇濆瓨鎴愬姛',
-        type: 'success',
-      });
-      // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
-      await getTemplateList();
-      // 娓呯┖妯℃澘鍚嶇О杈撳叆
-      templateName.value = '';
-      filterInputValue.value = '';
+  const checkTemplateNameDuplicate = name => {
+    if (!name || name.trim() === "") {
       isTemplateNameDuplicate.value = false;
+      return false;
+    }
+    const isDuplicate = templateList.value.some(
+      item => item.templateName === name.trim()
+    );
+    isTemplateNameDuplicate.value = isDuplicate;
+    return isDuplicate;
+  };
+
+  // 闃叉姈瀹氭椂鍣�
+  let duplicateCheckTimer = null;
+  const onTemplateFilterChange = val => {
+    filterInputValue.value = val ?? "";
+    // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+    if (duplicateCheckTimer) {
+      clearTimeout(duplicateCheckTimer);
+    }
+    // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
+    if (val && val.trim()) {
+      duplicateCheckTimer = setTimeout(() => {
+        const isDuplicate = checkTemplateNameDuplicate(val);
+        if (isDuplicate) {
+          ElMessage({
+            message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+            type: "warning",
+            duration: 2000,
+          });
+        }
+      }, 300); // 300ms 闃叉姈
     } else {
+      isTemplateNameDuplicate.value = false;
+    }
+  };
+
+  // allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
+  const onTemplateChange = async val => {
+    if (typeof val === "string") {
+      filterInputValue.value = val;
+      // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
+      checkTemplateNameDuplicate(val);
+    }
+
+    // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
+    const matchedTemplate = templateList.value.find(
+      item => item.templateName === val
+    );
+
+    if (matchedTemplate?.id) {
+      // 濡傛灉鎵惧埌妯℃澘锛屽姞杞芥ā鏉挎暟鎹�
+      form.value = {
+        ...form.value,
+        ...matchedTemplate,
+      };
+      productData.value = matchedTemplate.productData || [];
+      // 鐢熸垚鏂扮殑閲囪喘鍚堝悓鍙�
+      try {
+        const res = await createPurchaseNo();
+        if (res?.data) {
+          form.value.purchaseContractNumber = res.data;
+        }
+      } catch (error) {
+        console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+      }
+    } else {
+      // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
+      const currentFormData = { ...form.value };
+      const currentProductData = [...productData.value];
+
+      // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
+      if (!dialogFormVisible.value) {
+        operationType.value = "add";
+        dialogFormVisible.value = true;
+      }
+
+      // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
+      await nextTick();
+      form.value = {
+        ...form.value,
+        ...currentFormData,
+      };
+      productData.value = currentProductData;
+    }
+  };
+
+  // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+  const operationType = ref("");
+  const dialogFormVisible = ref(false);
+  const data = reactive({
+    searchForm: {
+      supplierName: "", // 渚涘簲鍟嗗悕绉�
+      purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
+      salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+      projectName: "", // 椤圭洰鍚嶇О
+      entryDate: null, // 褰曞叆鏃ユ湡
+      entryDateStart: undefined,
+      entryDateEnd: undefined,
+    },
+    form: {
+      purchaseContractNumber: "",
+      salesLedgerId: "",
+      projectName: "",
+      recorderId: "",
+      entryDate: "",
+      productData: [],
+      supplierName: "",
+      supplierId: "",
+      paymentMethod: "",
+      executionDate: "",
+      isChecked: true,
+    },
+    rules: {
+      purchaseContractNumber: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      approverId: [
+        { required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" },
+      ],
+      projectName: [
+        { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
+      ],
+      supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    },
+  });
+  const { form, rules } = toRefs(data);
+  const { form: searchForm } = useFormData({
+    ...data.searchForm,
+    // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
+    entryDate: [
+      dayjs().startOf("day").format("YYYY-MM-DD"),
+      dayjs().endOf("day").format("YYYY-MM-DD"),
+    ],
+    entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
+    entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
+  });
+
+  // 浜у搧琛ㄥ崟寮规鏁版嵁
+  const productFormVisible = ref(false);
+  const productOperationType = ref("");
+  const productOperationIndex = ref("");
+  const currentId = ref("");
+  const productFormData = reactive({
+    productForm: {
+      productId: "",
+      productCategory: "",
+      productModelId: "",
+      specificationModel: "",
+      unit: "",
+      quantity: "",
+      taxInclusiveUnitPrice: "",
+      taxRate: "",
+      taxInclusiveTotalPrice: "",
+      taxExclusiveTotalPrice: "",
+      invoiceType: "",
+      warnNum: "",
+      isChecked: true,
+    },
+    productRules: {
+      productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxInclusiveUnitPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      taxInclusiveTotalPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      taxExclusiveTotalPrice: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    },
+  });
+  const { productForm, productRules } = toRefs(productFormData);
+  const upload = reactive({
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+  });
+
+  const changeDaterange = value => {
+    if (value) {
+      searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+      searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+    } else {
+      searchForm.entryDateStart = undefined;
+      searchForm.entryDateEnd = undefined;
+    }
+    handleQuery();
+  };
+
+  const formattedNumber = (row, column, cellValue) => {
+    return parseFloat(cellValue).toFixed(2);
+  };
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+
+  // 淇濆瓨妯℃澘
+  const handleButtonClick = async () => {
+    // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
+    if (!templateName.value || templateName.value.trim() === "") {
       ElMessage({
-        message: res?.msg || '妯℃澘淇濆瓨澶辫触',
-        type: 'error',
+        message: "璇疯緭鍏ユā鏉垮悕绉�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
+    const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+    if (isDuplicate) {
+      ElMessage({
+        message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
+    if (!form.value.supplierId) {
+      ElMessage({
+        message: "璇峰厛閫夋嫨渚涘簲鍟�",
+        type: "warning",
+      });
+      return;
+    }
+
+    // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
+    // if (!productData.value || productData.value.length === 0) {
+    //   ElMessage({
+    //     message: '璇峰厛娣诲姞浜у搧淇℃伅',
+    //     type: 'warning',
+    //   });
+    //   return;
+    // }
+
+    try {
+      let params = {
+        productData: proxy.HaveJson(productData.value),
+        supplierId: form.value.supplierId,
+        paymentMethod: form.value.paymentMethod,
+        recorderId: form.value.recorderId,
+        approverId: form.value.approverId,
+        templateName: templateName.value.trim(),
+      };
+      console.log(params);
+      let res = await addPurchaseTemplate(params);
+
+      if (res && res.code === 200) {
+        ElMessage({
+          message: "妯℃澘淇濆瓨鎴愬姛",
+          type: "success",
+        });
+        // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
+        await getTemplateList();
+        // 娓呯┖妯℃澘鍚嶇О杈撳叆
+        templateName.value = "";
+        filterInputValue.value = "";
+        isTemplateNameDuplicate.value = false;
+      } else {
+        ElMessage({
+          message: res?.msg || "妯℃澘淇濆瓨澶辫触",
+          type: "error",
+        });
+      }
+    } catch (error) {
+      console.error("淇濆瓨妯℃澘澶辫触:", error);
+      ElMessage({
+        message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+        type: "error",
       });
     }
-  } catch (error) {
-    console.error('淇濆瓨妯℃澘澶辫触:', error);
-    ElMessage({
-      message: '妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯',
-      type: 'error',
-    });
-  }
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
-  return proxy.summarizeTable(
+  };
+  // 瀛愯〃鍚堣鏂规硶
+  const summarizeChildrenTable = param => {
+    return proxy.summarizeTable(
       param,
       [
         "taxInclusiveUnitPrice",
@@ -986,27 +1222,26 @@
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
-  );
-};
-const paginationChange = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  const { entryDate, ...rest } = searchForm;
-  purchaseListPage({ ...rest, ...page })
-      .then((res) => {
+    );
+  };
+  const paginationChange = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    tableLoading.value = true;
+    const { entryDate, ...rest } = searchForm;
+    purchaseListPage({ ...rest, ...page })
+      .then(res => {
         tableLoading.value = false;
         // tableData.value = res.data.records;
-        // 澶勭悊鏁版嵁锛屾坊鍔犲け鏁堢姸鎬佹爣璁�
         tableData.value = res.data.records.map(record => ({
           ...record,
-          isInvalid: record.isWhite === 1
+          isInvalid: record.isWhite === 1,
         }));
         // 鍒濆鍖栧瓙鏁版嵁鏁扮粍
-        tableData.value.forEach((item) => {
+        tableData.value.forEach(item => {
           item.children = [];
         });
         total.value = res.data.total;
@@ -1015,547 +1250,758 @@
       .catch(() => {
         tableLoading.value = false;
       });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-const productSelected = (selectedRows) => {
-  productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = async (row, expandedRows) => {
-  if (expandedRows.length > 0) {
-    expandedRowKeys.value = [];
-    try {
-      const res = await productList({ salesLedgerId: row.id, type: 2 });
-      const index = tableData.value.findIndex((item) => item.id === row.id);
-      if (index > -1) {
-        tableData.value[index].children = res.data || [];
-        expandedRowKeys.value.push(row.id);
-      }
-    } catch (error) {
-      console.error('鍔犺浇浜у搧鍒楄〃澶辫触:', error);
-      proxy.$modal.msgError('鍔犺浇浜у搧鍒楄〃澶辫触');
-      // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
-      const index = expandedRows.findIndex(item => item.id === row.id);
-      if (index > -1) {
-        expandedRows.splice(index, 1);
-      }
-    }
-  } else {
-    expandedRowKeys.value = [];
-  }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
-  return proxy.summarizeTable(param, ["contractAmount"]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeProTable = (param) => {
-  return proxy.summarizeTable(param, [
-    "taxInclusiveUnitPrice",
-    "taxInclusiveTotalPrice",
-    "taxExclusiveTotalPrice",
-  ]);
-};
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
-  await getTemplateList()
-  operationType.value = type;
-  form.value = {};
-  productData.value = [];
-  fileList.value = [];
-  templateName.value = '';
-  filterInputValue.value = '';
-  isTemplateNameDuplicate.value = false;
-  try {
-    // 骞惰鍔犺浇鍩虹鏁版嵁
-    const [userRes, salesRes, supplierRes] = await Promise.all([
-      userListNoPage(),
-      getSalesNo(),
-      getOptions()
-    ]);
-    
-    userList.value = userRes.data || [];
-    salesContractList.value = salesRes || [];
-    // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
-    supplierList.value = (supplierRes.data || []).filter((item) => item.isWhite === 0);
-    
-    // 璁剧疆榛樿鍊�
-    form.value.recorderId = userStore.id;
-    form.value.entryDate = getCurrentDate();
-    
-    if (type === "add") {
-      // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  const productSelected = selectedRows => {
+    productSelectedRows.value = selectedRows;
+  };
+  const expandedRowKeys = ref([]);
+  // 灞曞紑琛�
+  const expandChange = async (row, expandedRows) => {
+    if (expandedRows.length > 0) {
+      expandedRowKeys.value = [];
       try {
-        const purchaseNoRes = await createPurchaseNo();
-        if (purchaseNoRes?.data) {
-          form.value.purchaseContractNumber = purchaseNoRes.data;
+        const res = await productList({ salesLedgerId: row.id, type: 2 });
+        const index = tableData.value.findIndex(item => item.id === row.id);
+        if (index > -1) {
+          tableData.value[index].children = res.data || [];
+          expandedRowKeys.value.push(row.id);
         }
       } catch (error) {
-        console.error('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:', error);
-        proxy.$modal.msgWarning('鐢熸垚閲囪喘鍚堝悓鍙峰け璐�');
+        console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
+        proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
+        // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
+        const index = expandedRows.findIndex(item => item.id === row.id);
+        if (index > -1) {
+          expandedRows.splice(index, 1);
+        }
       }
-    } else if (type === "edit" && row?.id) {
-      // 缂栬緫鏃跺姞杞芥暟鎹�
-      currentId.value = row.id;
-      try {
-        const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
-        form.value = { ...purchaseRes };
-        productData.value = purchaseRes.productData || [];
-        fileList.value = purchaseRes.salesLedgerFiles || [];
-      } catch (error) {
-        console.error('鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:', error);
-        proxy.$modal.msgError('鍔犺浇鏁版嵁澶辫触');
-        return;
-      }
-    }
-    
-    dialogFormVisible.value = true;
-  } catch (error) {
-    console.error('鎵撳紑琛ㄥ崟澶辫触:', error);
-    proxy.$modal.msgError('鍔犺浇鍩虹鏁版嵁澶辫触');
-  }
-};
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
-  // 鏍℃鏂囦欢澶у皬
-  if (file.size > 1024 * 1024 * 10) {
-    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
-    return false;
-  }
-  proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
-  return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
-  proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
-  proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
-  proxy.$modal.closeLoading();
-  if (res.code === 200) {
-    file.tempId = res.data.tempId;
-    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
-  } else {
-    proxy.$modal.msgError(res.msg);
-    proxy.$refs.fileUpload.handleRemove(file);
-  }
-}
-// 绉婚櫎鏂囦欢
-async function handleRemove(file) {
-  if (!file?.id) {
-    return;
-  }
-  
-  if (file.size > 1024 * 1024 * 10) {
-    // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
-    return;
-  }
-  
-  if (operationType.value === "edit" && file.id) {
-    try {
-      await delLedgerFile([file.id]);
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-    } catch (error) {
-      console.error('鍒犻櫎鏂囦欢澶辫触:', error);
-      proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
-    }
-  }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  try {
-    const valid = await proxy.$refs["formRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
-    }
-    
-    if (!productData.value || productData.value.length === 0) {
-      proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
-      return;
-    }
-    
-    form.value.productData = proxy.HaveJson(productData.value);
-    form.value.tempFileIds = fileList.value
-      .filter(item => item.tempId)
-      .map((item) => item.tempId);
-    form.value.type = 2;
-    
-    try {
-      await addOrEditPurchase(form.value);
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-      getList();
-    } catch (error) {
-      console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
-      proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  } catch (error) {
-    console.error('琛ㄥ崟楠岃瘉澶辫触:', error);
-  }
-};
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-};
-// 鎵撳紑浜у搧寮规
-const openProductForm = (type, row, index) => {
-  productOperationType.value = type;
-  productOperationIndex.value = index;
-  productForm.value = {};
-  proxy.resetForm("productFormRef");
-  if (type === "edit") {
-    productForm.value = { ...row };
-  }
-  productFormVisible.value = true;
-  getProductOptions();
-};
-const getProductOptions = async () => {
-  try {
-    const res = await productTreeList();
-    productOptions.value = convertIdToValue(res);
-  } catch (error) {
-    console.error('鍔犺浇浜у搧閫夐」澶辫触:', error);
-    proxy.$modal.msgError('鍔犺浇浜у搧閫夐」澶辫触');
-  }
-};
-const getModels = async (value) => {
-  if (value) {
-    productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
-    try {
-      const res = await modelList({ id: value });
-      modelOptions.value = res || [];
-    } catch (error) {
-      console.error('鍔犺浇瑙勬牸鍨嬪彿澶辫触:', error);
-      proxy.$modal.msgError('鍔犺浇瑙勬牸鍨嬪彿澶辫触');
-      modelOptions.value = [];
-    }
-  } else {
-    productForm.value.productCategory = "";
-    modelOptions.value = [];
-  }
-};
-const getProductModel = (value) => {
-  const index = modelOptions.value.findIndex((item) => item.id === value);
-  if (index !== -1) {
-    productForm.value.specificationModel = modelOptions.value[index].model;
-    productForm.value.unit = modelOptions.value[index].unit;
-  } else {
-    productForm.value.specificationModel = null;
-    productForm.value.unit = null;
-  }
-};
-const findNodeById = (nodes, productId) => {
-  for (let i = 0; i < nodes.length; i++) {
-    if (nodes[i].value === productId) {
-      return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
-    }
-    if (nodes[i].children && nodes[i].children.length > 0) {
-      const foundNode = findNodeById(nodes[i].children, productId);
-      if (foundNode) {
-        return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
-      }
-    }
-  }
-  return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
-  return data.map((item) => {
-    const { id, children, ...rest } = item;
-    const newItem = {
-      ...rest,
-      value: id, // 灏� id 鏀逛负 value
-    };
-    if (children && children.length > 0) {
-      newItem.children = convertIdToValue(children);
-    }
-
-    return newItem;
-  });
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitProduct = async () => {
-  try {
-    const valid = await proxy.$refs["productFormRef"].validate().catch(() => false);
-    if (!valid) {
-      return;
-    }
-    
-    if (operationType.value === "edit") {
-      await submitProductEdit();
     } else {
-      if (productOperationType.value === "add") {
-        productData.value.push({ ...productForm.value });
-      } else {
-        productData.value[productOperationIndex.value] = {
-          ...productForm.value,
-        };
-      }
-      closeProductDia();
+      expandedRowKeys.value = [];
     }
-  } catch (error) {
-    console.error('鎻愪氦浜у搧琛ㄥ崟澶辫触:', error);
-  }
-};
-
-const submitProductEdit = async () => {
-  try {
-    productForm.value.salesLedgerId = currentId.value;
-    productForm.value.type = 2;
-    await addOrUpdateSalesLedgerProduct(productForm.value);
-    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-    closeProductDia();
-    
-    // 閲嶆柊鍔犺浇浜у搧鏁版嵁
+  };
+  // 涓昏〃鍚堣鏂规硶
+  const summarizeMainTable = param => {
+    return proxy.summarizeTable(param, ["contractAmount"]);
+  };
+  // 瀛愯〃鍚堣鏂规硶
+  const summarizeProTable = param => {
+    return proxy.summarizeTable(param, [
+      "taxInclusiveUnitPrice",
+      "taxInclusiveTotalPrice",
+      "taxExclusiveTotalPrice",
+    ]);
+  };
+  // 鎵撳紑寮规
+  const openForm = async (type, row) => {
+    await getTemplateList();
+    operationType.value = type;
+    form.value = {};
+    productData.value = [];
+    fileList.value = [];
+    templateName.value = "";
+    filterInputValue.value = "";
+    isTemplateNameDuplicate.value = false;
     try {
-      const res = await getPurchaseById({ id: currentId.value, type: 2 });
-      productData.value = res.productData || [];
-    } catch (error) {
-      console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
-    }
-  } catch (error) {
-    console.error('鎻愪氦浜у搧缂栬緫澶辫触:', error);
-    proxy.$modal.msgError("鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
-  }
-};
-// 鍒犻櫎浜у搧
-const deleteProduct = async () => {
-  if (productSelectedRows.value.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  
-  if (operationType.value === "add") {
-    // 鏂板妯″紡涓嬶紝鐩存帴浠庡墠绔暟鎹腑鍒犻櫎
-    productSelectedRows.value.forEach((selectedRow) => {
-      const index = productData.value.findIndex(
-          (product) => product.id === selectedRow.id
+      // 骞惰鍔犺浇鍩虹鏁版嵁
+      const [userRes, salesRes, supplierRes] = await Promise.all([
+        userListNoPage(),
+        getSalesNo(),
+        getOptions(),
+      ]);
+
+      userList.value = userRes.data || [];
+      salesContractList.value = salesRes || [];
+      // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
+      supplierList.value = (supplierRes.data || []).filter(
+        item => item.isWhite === 0
       );
-      if (index !== -1) {
-        productData.value.splice(index, 1);
+
+      // 璁剧疆榛樿鍊�
+      form.value.recorderId = userStore.id;
+      form.value.entryDate = getCurrentDate();
+
+      if (type === "add") {
+        // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+        try {
+          const purchaseNoRes = await createPurchaseNo();
+          if (purchaseNoRes?.data) {
+            form.value.purchaseContractNumber = purchaseNoRes.data;
+          }
+        } catch (error) {
+          console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+          proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
+        }
+      } else if (type === "edit" && row?.id) {
+        // 缂栬緫鏃跺姞杞芥暟鎹�
+        currentId.value = row.id;
+        try {
+          const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
+          form.value = { ...purchaseRes };
+          productData.value = purchaseRes.productData || [];
+          fileList.value = purchaseRes.salesLedgerFiles || [];
+        } catch (error) {
+          console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
+          proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
+          return;
+        }
+      }
+
+      if (form.value.salesLedgerId == -1) {
+        form.value.salesLedgerId = null;
+      }
+      console.log(form.value, "form.value===========");
+      dialogFormVisible.value = true;
+    } catch (error) {
+      console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
+      proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
+    }
+  };
+  // 涓婁紶鍓嶆牎妫�
+  function handleBeforeUpload(file) {
+    // 鏍℃鏂囦欢澶у皬
+    if (file.size > 1024 * 1024 * 10) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+      return false;
+    }
+    proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+    return true;
+  }
+  // 涓婁紶澶辫触
+  function handleUploadError(err) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+    proxy.$modal.closeLoading();
+  }
+  // 涓婁紶鎴愬姛鍥炶皟
+  function handleUploadSuccess(res, file, uploadFiles) {
+    proxy.$modal.closeLoading();
+    if (res.code === 200) {
+      file.tempId = res.data.tempId;
+      proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+    } else {
+      proxy.$modal.msgError(res.msg);
+      proxy.$refs.fileUpload.handleRemove(file);
+    }
+  }
+  // 绉婚櫎鏂囦欢
+  async function handleRemove(file) {
+    if (!file?.id) {
+      return;
+    }
+    console.log("handleRemove", file.id);
+    if (file.size > 1024 * 1024 * 10) {
+      // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
+      return;
+    }
+
+    if (operationType.value === "edit" && file.id) {
+      try {
+        await delLedgerFile([file.id]);
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      } catch (error) {
+        console.error("鍒犻櫎鏂囦欢澶辫触:", error);
+        proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
+      }
+    }
+  }
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = () => {
+    proxy.$refs["formRef"].validate(valid => {
+      if (valid) {
+        if (productData.value.length > 0) {
+          form.value.productData = proxy.HaveJson(productData.value);
+        } else {
+          proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+          return;
+        }
+        let tempFileIds = [];
+        if (fileList.value.length > 0) {
+          tempFileIds = fileList.value.map(item => item.tempId);
+        }
+        form.value.tempFileIds = tempFileIds;
+        form.value.type = 2;
+
+        // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
+        if (!form.value.salesLedgerId) {
+          form.value.salesContractNo = "";
+        }
+
+        addOrEditPurchase(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+          getList();
+        });
       }
     });
-    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-  } else {
-    // 缂栬緫妯″紡涓嬶紝闇�瑕佽皟鐢ㄦ帴鍙e垹闄�
-    const ids = productSelectedRows.value
-      .filter(item => item.id)
-      .map((item) => item.id);
-    
-    if (ids.length === 0) {
-      proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
+  };
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    proxy.resetForm("formRef");
+    dialogFormVisible.value = false;
+  };
+  // 鎵撳紑浜у搧寮规
+  const openProductForm = (type, row, index) => {
+    productOperationType.value = type;
+    productOperationIndex.value = index;
+    productForm.value = {};
+    proxy.resetForm("productFormRef");
+    if (type === "edit") {
+      productForm.value = { ...row };
+    }
+    productFormVisible.value = true;
+    getProductOptions();
+  };
+  const getProductOptions = () => {
+    productTreeList().then(res => {
+      productOptions.value = convertIdToValue(res);
+    });
+  };
+  const getModels = value => {
+    if (value) {
+      productForm.value.productCategory =
+        findNodeById(productOptions.value, value) || "";
+      modelList({ id: value }).then(res => {
+        modelOptions.value = res;
+      });
+    } else {
+      productForm.value.productCategory = "";
+      modelOptions.value = [];
+    }
+  };
+  const getProductModel = value => {
+    const index = modelOptions.value.findIndex(item => item.id === value);
+    if (index !== -1) {
+      productForm.value.specificationModel = modelOptions.value[index].model;
+      productForm.value.unit = modelOptions.value[index].unit;
+    } else {
+      productForm.value.specificationModel = null;
+      productForm.value.unit = null;
+    }
+  };
+  const findNodeById = (nodes, productId) => {
+    for (let i = 0; i < nodes.length; i++) {
+      if (nodes[i].value === productId) {
+        return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
+      }
+      if (nodes[i].children && nodes[i].children.length > 0) {
+        const foundNode = findNodeById(nodes[i].children, productId);
+        if (foundNode) {
+          return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
+        }
+      }
+    }
+    return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+  };
+  function convertIdToValue(data) {
+    return data.map(item => {
+      const { id, children, ...rest } = item;
+      const newItem = {
+        ...rest,
+        value: id, // 灏� id 鏀逛负 value
+      };
+      if (children && children.length > 0) {
+        newItem.children = convertIdToValue(children);
+      }
+
+      return newItem;
+    });
+  }
+  // 鎻愪氦浜у搧琛ㄥ崟
+  const submitProduct = () => {
+    proxy.$refs["productFormRef"].validate(valid => {
+      if (valid) {
+        if (operationType.value === "edit") {
+          submitProductEdit();
+        } else {
+          if (productOperationType.value === "add") {
+            productData.value.push({ ...productForm.value });
+            console.log("productData.value---", productData.value);
+          } else {
+            productData.value[productOperationIndex.value] = {
+              ...productForm.value,
+            };
+          }
+          closeProductDia();
+        }
+      }
+    });
+  };
+  const submitProductEdit = () => {
+    productForm.value.salesLedgerId = currentId.value;
+    productForm.value.type = 2;
+    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeProductDia();
+      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
+        productData.value = res.productData;
+      });
+    });
+  };
+  // 鍒犻櫎浜у搧
+  const deleteProduct = () => {
+    if (productSelectedRows.value.length === 0) {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
-    
-    try {
-      await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
+    if (operationType.value === "add") {
+      productSelectedRows.value.forEach(selectedRow => {
+        const index = productData.value.findIndex(
+          product => product.id === selectedRow.id
+        );
+        if (index !== -1) {
+          productData.value.splice(index, 1);
+        }
+      });
+    } else {
+      let ids = [];
+      if (productSelectedRows.value.length > 0) {
+        ids = productSelectedRows.value.map(item => item.id);
+      }
+      ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
         confirmButtonText: "纭",
         cancelButtonText: "鍙栨秷",
         type: "warning",
+      })
+        .then(() => {
+          delProduct(ids).then(res => {
+            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+            closeProductDia();
+            getSalesLedgerWithProducts({ id: currentId.value, type: 2 }).then(
+              res => {
+                productData.value = res.productData;
+              }
+            );
+          });
+        })
+        .catch(() => {
+          proxy.$modal.msg("宸插彇娑�");
+        });
+    }
+  };
+  // 鍏抽棴浜у搧寮规
+  const closeProductDia = () => {
+    proxy.resetForm("productFormRef");
+    productFormVisible.value = false;
+  };
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
       });
-      
-      await delProduct(ids);
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      closeProductDia();
-      
-      // 閲嶆柊鍔犺浇浜у搧鏁版嵁
-      try {
-        const res = await getSalesLedgerWithProducts({ id: currentId.value, type: 2 });
-        productData.value = res.productData || [];
-      } catch (error) {
-        console.error('閲嶆柊鍔犺浇浜у搧鏁版嵁澶辫触:', error);
-      }
-    } catch (error) {
-      if (error !== 'cancel') {
-        console.error('鍒犻櫎浜у搧澶辫触:', error);
-        proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
-      }
-    }
-  }
-};
-// 鍏抽棴浜у搧寮规
-const closeProductDia = () => {
-  proxy.resetForm("productFormRef");
-  productFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = async () => {
-  try {
-    await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭纭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    });
-    proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
-  } catch (error) {
-    if (error !== 'cancel') {
-      console.error('瀵煎嚭澶辫触:', error);
-      proxy.$modal.msgError("瀵煎嚭澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  }
-};
-
-// 鍒犻櫎
-const handleDelete = async () => {
-  if (selectedRows.value.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  
-  // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-  const unauthorizedData = selectedRows.value.filter(item => item.recorderName !== userStore.nickName);
-  if (unauthorizedData.length > 0) {
-    proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
-    return;
-  }
-  
-  const ids = selectedRows.value
-    .filter(item => item.id)
-    .map((item) => item.id);
-  
-  if (ids.length === 0) {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏈夋晥鐨勬暟鎹�");
-    return;
-  }
-  
-  try {
-    await ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎纭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    });
-    
-    await delPurchase(ids);
-    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-    getList();
-  } catch (error) {
-    if (error !== 'cancel') {
-      console.error('鍒犻櫎澶辫触:', error);
-      proxy.$modal.msgError("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯");
-    }
-  }
-};
-const mathNum = () => {
-  if (!productForm.value.taxRate) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-    return;
-  }
-  if (!productForm.value.taxInclusiveUnitPrice) {
-    return;
-  }
-  if (!productForm.value.quantity) {
-    return;
-  }
-  // 鍚◣鎬讳环璁$畻
-  productForm.value.taxInclusiveTotalPrice =
-      proxy.calculateTaxIncludeTotalPrice(
-          productForm.value.taxInclusiveUnitPrice,
-          productForm.value.quantity
+  };
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+      const unauthorizedData = selectedRows.value.filter(
+        item => item.recorderName !== userStore.nickName
       );
-  if (productForm.value.taxRate) {
-    // 涓嶅惈绋庢�讳环璁$畻
-    productForm.value.taxExclusiveTotalPrice =
-        proxy.calculateTaxExclusiveTotalPrice(
-            productForm.value.taxInclusiveTotalPrice,
-            productForm.value.taxRate
-        );
-  }
-};
-const reverseMathNum = (field) => {
-  if (!productForm.value.taxRate) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-    return;
-  }
-  const taxRate = Number(productForm.value.taxRate);
-  if (!taxRate) return;
-  if (field === 'taxInclusiveTotalPrice') {
-    // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
-    if (productForm.value.quantity) {
-      productForm.value.taxInclusiveUnitPrice =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
+      if (unauthorizedData.length > 0) {
+        proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+        return;
+      }
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
     }
-    // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
-    else if (productForm.value.taxInclusiveUnitPrice) {
-      productForm.value.quantity =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        delPurchase(ids).then(res => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+  function getCurrentDate() {
+    const today = new Date();
+    const year = today.getFullYear();
+    const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+    const day = String(today.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+  }
+  const mathNum = () => {
+    if (!productForm.value.taxRate) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+      return;
     }
-    // 鍙嶇畻涓嶅惈绋庢�讳环
-    productForm.value.taxExclusiveTotalPrice =
-        (Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)).toFixed(2);
-  } else if (field === 'taxExclusiveTotalPrice') {
-    // 鍙嶇畻鍚◣鎬讳环
+    if (!productForm.value.taxInclusiveUnitPrice) {
+      return;
+    }
+    if (!productForm.value.quantity) {
+      return;
+    }
+    // 鍚◣鎬讳环璁$畻
     productForm.value.taxInclusiveTotalPrice =
-        (Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)).toFixed(2);
-    // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
-    if (productForm.value.quantity) {
-      productForm.value.taxInclusiveUnitPrice =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
+      proxy.calculateTaxIncludeTotalPrice(
+        productForm.value.taxInclusiveUnitPrice,
+        productForm.value.quantity
+      );
+    if (productForm.value.taxRate) {
+      // 涓嶅惈绋庢�讳环璁$畻
+      productForm.value.taxExclusiveTotalPrice =
+        proxy.calculateTaxExclusiveTotalPrice(
+          productForm.value.taxInclusiveTotalPrice,
+          productForm.value.taxRate
+        );
     }
-    // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
-    else if (productForm.value.taxInclusiveUnitPrice) {
-      productForm.value.quantity =
-          (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
+  };
+  const reverseMathNum = field => {
+    if (!productForm.value.taxRate) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+      return;
     }
-  }
-};
-// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
-const salesLedgerChange = async (row) => {
-  const index = salesContractList.value.findIndex((item) => item.id === row);
-  if (index > -1) {
-    form.value.projectName = salesContractList.value[index].projectName;
-    await querygProductInfoByContractNo();
-  }
-};
+    const taxRate = Number(productForm.value.taxRate);
+    if (!taxRate) return;
 
-const querygProductInfoByContractNo = async () => {
-  const { code, data } = await getProductInfoByContractNo({
-    contractNo: form.value.salesLedgerId,
+    // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
+    if (
+      field === "taxInclusiveTotalPrice" ||
+      field === "taxExclusiveTotalPrice"
+    ) {
+      const value = Number(productForm.value[field]);
+      if (value < 0) {
+        productForm.value[field] = "0";
+        proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
+        return;
+      }
+    }
+
+    if (field === "taxInclusiveTotalPrice") {
+      // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
+      if (productForm.value.quantity) {
+        productForm.value.taxInclusiveUnitPrice = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.quantity)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+          productForm.value.taxInclusiveUnitPrice = "0";
+        }
+      }
+      // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
+      else if (productForm.value.taxInclusiveUnitPrice) {
+        productForm.value.quantity = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.taxInclusiveUnitPrice)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.quantity) < 0) {
+          productForm.value.quantity = "0";
+        }
+      }
+      // 鍙嶇畻涓嶅惈绋庢�讳环
+      productForm.value.taxExclusiveTotalPrice = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        (1 + taxRate / 100)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
+        productForm.value.taxExclusiveTotalPrice = "0";
+      }
+    } else if (field === "taxExclusiveTotalPrice") {
+      // 鍙嶇畻鍚◣鎬讳环
+      productForm.value.taxInclusiveTotalPrice = (
+        Number(productForm.value.taxExclusiveTotalPrice) *
+        (1 + taxRate / 100)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
+        productForm.value.taxInclusiveTotalPrice = "0";
+      }
+      // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
+      if (productForm.value.quantity) {
+        productForm.value.taxInclusiveUnitPrice = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.quantity)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+          productForm.value.taxInclusiveUnitPrice = "0";
+        }
+      }
+      // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
+      else if (productForm.value.taxInclusiveUnitPrice) {
+        productForm.value.quantity = (
+          Number(productForm.value.taxInclusiveTotalPrice) /
+          Number(productForm.value.taxInclusiveUnitPrice)
+        ).toFixed(2);
+        // 纭繚缁撴灉涓嶄负璐熸暟
+        if (Number(productForm.value.quantity) < 0) {
+          productForm.value.quantity = "0";
+        }
+      }
+    }
+  };
+  // 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
+  const salesLedgerChange = async row => {
+    console.log("row", row);
+    var index = salesContractList.value.findIndex(item => item.id == row);
+    console.log("index", index);
+    if (index > -1) {
+      await querygProductInfoByContractNo();
+    }
+  };
+
+  const querygProductInfoByContractNo = async () => {
+    const { code, data } = await getProductInfoByContractNo({
+      contractNo: form.value.salesLedgerId,
+    });
+    if (code == 200) {
+      productData.value = data;
+    }
+  };
+
+  const fileListRef = ref(null);
+  const downLoadFile = row => {
+    fileListRef.value.open(row.salesLedgerFiles);
+  };
+
+  // 鏄剧ず浜岀淮鐮�
+  const showQRCode = async row => {
+    try {
+      // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
+      const qrContent = row.purchaseContractNumber || "";
+      // 妫�鏌ュ唴瀹规槸鍚︿负绌�
+      if (!qrContent || qrContent.trim() === "") {
+        proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
+        return;
+      }
+      qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+        width: 200,
+        margin: 2,
+        color: {
+          dark: "#000000",
+          light: "#FFFFFF",
+        },
+      });
+      qrCodeDialogVisible.value = true;
+    } catch (error) {
+      console.error("鐢熸垚浜岀淮鐮佸け璐�:", error);
+      proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+    }
+  };
+
+  // 涓嬭浇浜岀淮鐮�
+  const downloadQRCode = () => {
+    if (!qrCodeUrl.value) {
+      proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
+      return;
+    }
+
+    const a = document.createElement("a");
+    a.href = qrCodeUrl.value;
+    a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${new Date().getTime()}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+    proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
+  };
+
+  // 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
+  const scanAddDialogVisible = ref(false);
+  const scanAddForm = reactive({
+    scanContent: "",
+    purchaseContractNumber: "",
+    supplierName: "",
+    projectName: "",
+    contractAmount: "",
+    paymentMethod: "",
+    recorderName: "",
+    scanRemark: "",
   });
-  if (code == 200) {
-    productData.value = data;
+  const scanAddRules = {
+    purchaseContractNumber: [
+      { required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" },
+    ],
+    supplierName: [
+      { required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" },
+    ],
+    projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+  };
+
+  // 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
+  const scanDialogVisible = ref(false);
+  const scanForm = reactive({
+    purchaseContractNumber: "",
+    supplierName: "",
+    projectName: "",
+    scanTime: "",
+    scannerName: "",
+    scanStatus: "鏈壂鐮�",
+    scanRemark: "",
+  });
+  const scanRules = {
+    scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
+  };
+  const scanRecords = ref([]);
+
+  // 鎵撳紑鎵爜鏂板瀵硅瘽妗�
+  const openScanAddDialog = () => {
+    scanAddForm.scanContent = "";
+    scanAddForm.purchaseContractNumber = "";
+    scanAddForm.supplierName = "";
+    scanAddForm.projectName = "";
+    scanAddForm.contractAmount = "";
+    scanAddForm.paymentMethod = "";
+    scanAddForm.recorderName = userStore.nickName;
+    scanAddForm.scanRemark = "";
+    scanAddDialogVisible.value = true;
+  };
+
+  // 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
+  const parseScanContent = content => {
+    if (!content) return;
+
+    // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
+    // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡閲戦|浠樻鏂瑰紡
+    const parts = content.split("|");
+    if (parts.length >= 2) {
+      scanAddForm.purchaseContractNumber = parts[0] || "";
+      scanAddForm.supplierName = parts[1] || "";
+      scanAddForm.contractAmount = parts[2] || "";
+      scanAddForm.paymentMethod = parts[3] || "";
+      scanAddForm.projectName = parts[4] || "";
+      // scanAddForm.contractAmount = parts[3] || "";
+      // scanAddForm.paymentMethod = parts[4] || "";
+    }
+  };
+
+  // 鍏抽棴鎵爜鏂板瀵硅瘽妗�
+  const closeScanAddDialog = () => {
+    scanAddDialogVisible.value = false;
+    proxy.resetForm("scanAddFormRef");
+  };
+
+  // 鎻愪氦鎵爜鏂板
+  const submitScanAdd = () => {
+    proxy.$refs["scanAddFormRef"].validate(valid => {
+      if (valid) {
+        // 鏋勫缓鏂板鏁版嵁
+        const newData = {
+          purchaseContractNumber: scanAddForm.purchaseContractNumber,
+          supplierName: scanAddForm.supplierName,
+          projectName: scanAddForm.projectName,
+          contractAmount: scanAddForm.contractAmount,
+          paymentMethod: scanAddForm.paymentMethod,
+          recorderName: scanAddForm.recorderName,
+          entryDate: getCurrentDate(),
+          remark: scanAddForm.scanRemark,
+          type: 2,
+        };
+
+        // 妯℃嫙鏂板鎴愬姛
+        proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
+        closeScanAddDialog();
+
+        // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
+        // getList();
+      }
+    });
+  };
+
+  // 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
+  const openScanDialog = row => {
+    scanForm.purchaseContractNumber = row.purchaseContractNumber;
+    scanForm.supplierName = row.supplierName;
+    scanForm.projectName = row.projectName;
+    scanForm.scanTime = getCurrentDateTime();
+    scanForm.scannerName = userStore.nickName;
+    scanForm.scanStatus = "鏈壂鐮�";
+    scanForm.scanRemark = "";
+    scanRecords.value = [];
+    scanDialogVisible.value = true;
+  };
+
+  // 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
+  const closeScanDialog = () => {
+    scanDialogVisible.value = false;
+    proxy.resetForm("scanFormRef");
+  };
+
+  // 鎻愪氦鎵爜鐧昏
+  const submitScan = () => {
+    proxy.$refs["scanFormRef"].validate(valid => {
+      if (valid) {
+        // 娣诲姞鎵爜璁板綍
+        scanRecords.value.push({
+          ...scanForm,
+          id: Date.now(), // 妯℃嫙ID
+          scanTime: getCurrentDateTime(),
+        });
+        scanForm.scanStatus = "宸叉壂鐮�";
+        scanForm.scanRemark = scanForm.scanRemark || "鏃�";
+        proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
+        closeScanDialog();
+      }
+    });
+  };
+
+  // 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
+  function getCurrentDateTime() {
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, "0");
+    const day = String(now.getDate()).padStart(2, "0");
+    const hours = String(now.getHours()).padStart(2, "0");
+    const minutes = String(now.getMinutes()).padStart(2, "0");
+    const seconds = String(now.getSeconds()).padStart(2, "0");
+    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
   }
-};
 
-// 娣诲姞琛岀被鍚嶆柟娉�
-const tableRowClassName = ({ row }) => {
-  return row.isInvalid ? 'invalid-row' : '';
-};
+  // 娣诲姞琛岀被鍚嶆柟娉�
+  const tableRowClassName = ({ row }) => {
+    return row.isInvalid ? "invalid-row" : "";
+  };
 
-// 鑾峰彇妯℃澘淇℃伅
-const getTemplateList =async ()=>{
-  let res = await getPurchaseTemplateList()
-  if(res && res.code===200 && Array.isArray(res.data)){
-    templateList.value = res.data
-  }
-}
+  // 鑾峰彇妯℃澘淇℃伅
+  const getTemplateList = async () => {
+    let res = await getPurchaseTemplateList();
+    if (res && res.code === 200 && Array.isArray(res.data)) {
+      templateList.value = res.data;
+    }
+  };
 
-onMounted(() => {
-  getList();
-  getTemplateList();
-
-});
+  onMounted(() => {
+    getList();
+    getTemplateList();
+  });
 </script>
 
 <style scoped lang="scss">
-.invalid-row {
-  opacity: 0.6;
-  background-color: #f5f7fa;
-}
-.el-row{
-  justify-content: space-between;
-  align-items: center
-}
-.no-arrow-select {
-  --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
-}
-.select-button-group {
-  display: flex;
-  align-items: center;
-}
-
+  .invalid-row {
+    opacity: 0.6;
+    background-color: #f5f7fa;
+  }
+  .el-row {
+    justify-content: space-between;
+    align-items: center;
+  }
+  .no-arrow-select {
+    --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
+  }
+  .select-button-group {
+    display: flex;
+    align-items: center;
+  }
 </style>
diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index a597317..229bf04 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -181,7 +181,7 @@
 		type: "warning",
 	})
 		.then(() => {
-			proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
+			proxy.download("/salesLedger/productionAccounting/export", {}, "鐢熶骇鏍哥畻.xlsx");
 		})
 		.catch(() => {
 			proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue
index 971bc6e..e7e6e15 100644
--- a/src/views/productionManagement/productionDispatching/components/formDia.vue
+++ b/src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -111,7 +111,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
 import useUserStore from "@/store/modules/user.js";
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 9250eb8..51b42ac 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -133,7 +133,7 @@
     {
       label: "宸ヨ壓璺嚎缂栧彿",
       prop: "processRouteCode",
-      width: '140px',
+      width: '200px',
     },
     {
       label: "闇�姹傛暟閲�",
diff --git a/src/views/productionManagement/productionReporting/components/formDia.vue b/src/views/productionManagement/productionReporting/components/formDia.vue
index 2eb1c0b..126c5b0 100644
--- a/src/views/productionManagement/productionReporting/components/formDia.vue
+++ b/src/views/productionManagement/productionReporting/components/formDia.vue
@@ -94,7 +94,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
 import {productionReport, productionReportUpdate} from "@/api/productionManagement/productionReporting.js";
 const { proxy } = getCurrentInstance()
diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index f4137af..6b543e7 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -19,21 +19,6 @@
                     style="width: 200px;"
                     @change="handleQuery" />
         </el-form-item>
-        <el-form-item label="宸ュ崟鐘舵��:">
-          <el-select v-model="searchForm.workOrderStatus"
-                     placeholder="璇烽�夋嫨宸ュ崟鐘舵��"
-                     style="width: 140px"
-                     clearable>
-            <el-option label="寰呯‘璁�"
-                       :value="1"></el-option>
-            <el-option label="寰呯敓浜�"
-                       :value="2"></el-option>
-            <el-option label="鐢熶骇涓�"
-                       :value="3"></el-option>
-            <el-option label="宸茬敓浜�"
-                       :value="4"></el-option>
-          </el-select>
-        </el-form-item>
         <el-form-item>
           <el-button type="primary"
                      @click="handleQuery">鎼滅储</el-button>
@@ -416,7 +401,7 @@
       type: "warning",
     })
       .then(() => {
-        proxy.download("/salesLedger/work/export", {}, "鐢熶骇鎶ュ伐.xlsx");
+        proxy.download("/productionProductMain/export", {}, "鐢熶骇鎶ュ伐.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/qualityManagement/finalInspection/components/filesDia.vue b/src/views/qualityManagement/finalInspection/components/filesDia.vue
index 66392f3..51dd78f 100644
--- a/src/views/qualityManagement/finalInspection/components/filesDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/filesDia.vue
@@ -51,7 +51,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 057781c..5bd847f 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -27,6 +27,24 @@
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
@@ -101,12 +119,12 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
 import {userListNoPage} from "@/api/system/user.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -121,6 +139,7 @@
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -132,6 +151,7 @@
     checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -169,6 +189,7 @@
 const tableLoading = ref(false);
 const userList = ref([]);
 const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
 
 // 鎵撳紑寮规
 const openDialog = async (type, row) => {
@@ -180,11 +201,54 @@
 	let userLists = await userListNoPage();
 	userList.value = userLists.data;
 	form.value = {}
+  testStandardOptions.value = [];
+  tableData.value = [];
   getProductOptions();
   if (operationType.value === 'edit') {
-    form.value = {...row}
+    // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+    const savedTestStandardId = row.testStandardId;
+    // 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+    form.value = {...row, testStandardId: ''}
 		currentProductId.value = row.productId || 0
-		getQualityInspectParamList(row.id)
+		// 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+		if (currentProductId.value) {
+			// 鍏堝姞杞芥寚鏍囬�夐」
+			let params = {
+				productId: currentProductId.value,
+				inspectType: 2
+			}
+			qualityInspectDetailByProductId(params).then(res => {
+				testStandardOptions.value = res.data || [];
+				// 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+				nextTick(() => {
+					setTimeout(() => {
+						// 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+						if (savedTestStandardId) {
+							// 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+							const matchedOption = testStandardOptions.value.find(item => 
+								item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+							);
+							if (matchedOption) {
+								// 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+								form.value.testStandardId = matchedOption.id;
+                console.log(22222,form.value.testStandardId);
+								handleTestStandardChange(matchedOption.id);
+							} else {
+								// 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+								console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+								form.value.testStandardId = savedTestStandardId;
+								handleTestStandardChange(savedTestStandardId);
+							}
+						} else {
+							// 鍚﹀垯浣跨敤鏃х殑閫昏緫
+							getQualityInspectParamList(row.id);
+						}
+					}, 100);
+				});
+			});
+		} else {
+			getQualityInspectParamList(row.id);
+		}
   }
 }
 const getProductOptions = () => {
@@ -195,7 +259,7 @@
 const getModels = (value) => {
 	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-	if (currentProductId) {
+	if (currentProductId.value) {
 		getList();
 	}
 };
@@ -253,9 +317,40 @@
   })
 }
 const getList = () => {
-	qualityInspectDetailByProductId(currentProductId.value).then(res => {
-		tableData.value = res.data;
+  if (!currentProductId.value) {
+    testStandardOptions.value = [];
+    tableData.value = [];
+    return;
+  }
+  let params = {
+    productId: currentProductId.value,
+    inspectType: 2
+  }
+	qualityInspectDetailByProductId(params).then(res => {
+		// 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+		testStandardOptions.value = res.data || [];
+		// 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+		tableData.value = [];
+		// 娓呯┖鎸囨爣閫夋嫨
+		form.value.testStandardId = '';
 	})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+  if (!testStandardId) {
+    tableData.value = [];
+    return;
+  }
+  tableLoading.value = true;
+  getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+    tableData.value = res.data || [];
+  }).catch(error => {
+    console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+    tableData.value = [];
+  }).finally(() => {
+    tableLoading.value = false;
+  })
 }
 const getQualityInspectParamList = (id) => {
 	qualityInspectParamInfo(id).then(res => {
@@ -265,6 +360,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
index d32a5df..ac67474 100644
--- a/src/views/qualityManagement/metricBinding/index.vue
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -10,6 +10,7 @@
         :isSelection="false"
         :rowClassName="rowClassNameCenter"
         :tableLoading="tableLoading"
+        :rowClick="handleTableRowClick"
         @pagination="handlePagination"
         :total="page.total"
       >
@@ -197,12 +198,13 @@
 }
 
 const standardColumns = ref([
-  { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, headerSlot: 'standardNoHeader' },
-  { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, headerSlot: 'standardNameHeader' },
+  { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
+  { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
   {
     label: '绫诲埆',
     prop: 'inspectType',
     headerSlot: 'inspectTypeHeader',
+    align: 'center',
     dataType: 'tag',
     formatData: (val) => {
       const map = { 0: '鍘熸潗鏂欐楠�', 1: '杩囩▼妫�楠�', 2: '鍑哄巶妫�楠�' }
@@ -212,6 +214,7 @@
   {
     label: '宸ュ簭',
     prop: 'processId',
+    align: 'center',
     dataType: 'tag',
     formatData: (val) => {
       const target = processOptions.value.find(
@@ -223,7 +226,8 @@
   {
     label: '澶囨敞',
     prop: 'remark',
-    minWidth: 160
+    minWidth: 160,
+    align: 'center'
   }
   // {
   //   label: '鐘舵��',
@@ -304,6 +308,13 @@
     })
 }
 
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
+const handleTableRowClick = (row) => {
+  currentStandard.value = row
+  loadBindingList()
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
 const handleStandardRowClick = (row) => {
   currentStandard.value = row
   loadBindingList()
@@ -471,4 +482,23 @@
 :deep(.center-table .el-table__body-wrapper td .cell) {
   text-align: center !important;
 }
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+  text-align: center;
+  width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+  width: 100%;
+  margin-top: 4px;
+}
 </style>
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index f152a04..44d3fae 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -19,6 +19,7 @@
         :isSelection="true"
         :tableLoading="tableLoading"
         :rowClassName="rowClassNameCenter"
+        :rowClick="handleTableRowClick"
         @selection-change="handleSelectionChange"
         @pagination="handlePagination"
         :total="page.total"
@@ -212,7 +213,7 @@
     standardNo: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗙紪鍙�', trigger: 'blur' }],
     standardName: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗗悕绉�', trigger: 'blur' }],
     inspectType: [{ required: true, message: '璇烽�夋嫨妫�娴嬬被鍨�', trigger: 'change' }],
-    processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
+    processId: [{ required: false, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
   }
 })
 
@@ -277,18 +278,21 @@
     dataType: 'slot',
     slot: 'standardNoCell',
     minWidth: 160,
+    align: 'center',
     headerSlot: 'standardNoHeader'
   },
   {
     label: '鏍囧噯鍚嶇О',
     prop: 'standardName',
     minWidth: 180,
+    align: 'center',
     headerSlot: 'standardNameHeader'
   },
   {
     label: '绫诲埆',
     prop: 'inspectType',
     headerSlot: 'inspectTypeHeader',
+    align: 'center',
     dataType: 'tag',
     formatData: (val) => {
       const map = {
@@ -302,6 +306,7 @@
   {
     label: '宸ュ簭',
     prop: 'processId',
+    align: 'center',
     dataType: 'tag',
     formatData: (val) => {
       const target = processOptions.value.find(
@@ -314,6 +319,7 @@
     label: '鐘舵��',
     prop: 'state',
     headerSlot: 'stateHeader',
+    align: 'center',
     dataType: 'tag',
     formatData: (val) => {
       const map = {
@@ -332,7 +338,8 @@
   {
     label: '澶囨敞',
     prop: 'remark',
-    minWidth: 160
+    minWidth: 160,
+    align: 'center'
   },
   {
     dataType: 'action',
@@ -447,7 +454,13 @@
   getStandardList()
 }
 
-// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+const handleTableRowClick = (row) => {
+  currentStandard.value = row
+  loadDetail(row.id)
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
 const handleStandardRowClick = (row) => {
   currentStandard.value = row
   loadDetail(row.id)
@@ -567,14 +580,23 @@
       processId: ''
     })
   } else if (type === 'edit' && row) {
-    Object.assign(standardForm.value, row)
+    Object.assign(standardForm.value, {
+      ...row,
+      // 纭繚 inspectType 鍜� state 杞崲涓哄瓧绗︿覆锛屼互鍖归厤 el-select 鐨� value 绫诲瀷
+      inspectType: row.inspectType !== null && row.inspectType !== undefined ? String(row.inspectType) : '',
+      state: row.state !== null && row.state !== undefined ? String(row.state) : '0',
+      // 纭繚 processId 杞崲涓哄瓧绗︿覆鎴栨暟瀛楋紙鏍规嵁瀹為檯闇�瑕侊級
+      processId: row.processId !== null && row.processId !== undefined ? row.processId : ''
+    })
   } else if (type === 'copy' && row) {
     const { id, ...rest } = row
     Object.assign(standardForm.value, {
       ...rest,
       id: undefined,
       standardNo: '',
-      state: '0'
+      state: '0',
+      // 纭繚 inspectType 杞崲涓哄瓧绗︿覆
+      inspectType: rest.inspectType !== null && rest.inspectType !== undefined ? String(rest.inspectType) : ''
     })
   }
   standardDialogVisible.value = true
@@ -673,14 +695,41 @@
 .metric-maintenance {
   display: flex;
   gap: 16px;
+  min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
 }
 
 .left-panel,
 .right-panel {
   flex: 1;
+  min-width: 0; /* 鍏佽 flex 瀛愬厓绱犳敹缂� */
   background: #ffffff;
   padding: 16px;
   box-sizing: border-box;
+  overflow: hidden; /* 闃叉鍐呭婧㈠嚭 */
+}
+
+/* 浣庡垎杈ㄧ巼閫傞厤 */
+@media (max-width: 1400px) {
+  .metric-maintenance {
+    flex-direction: column;
+  }
+  
+  .left-panel,
+  .right-panel {
+    width: 100%;
+    min-width: 0;
+  }
+}
+
+@media (max-width: 768px) {
+  .metric-maintenance {
+    gap: 12px;
+  }
+  
+  .left-panel,
+  .right-panel {
+    padding: 12px;
+  }
 }
 
 .toolbar {
@@ -688,6 +737,8 @@
   justify-content: space-between;
   align-items: center;
   margin-bottom: 12px;
+  flex-wrap: wrap;
+  gap: 8px;
 }
 
 .toolbar-left {
@@ -699,6 +750,9 @@
 
 .toolbar-right {
   flex-shrink: 0;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
 }
 
 .search-label {
@@ -758,4 +812,23 @@
 :deep(.center-table .el-table__body-wrapper td .cell) {
   text-align: center !important;
 }
+
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+:deep(.lims-table .pim-table-header-title) {
+  text-align: center;
+  width: 100%;
+}
+
+:deep(.lims-table .pim-table-header-extra) {
+  width: 100%;
+  margin-top: 4px;
+}
 </style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 6126e6b..4821db2 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -9,8 +9,21 @@
       <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="宸ュ簭锛�" prop="process">
-              <el-input v-model="form.process" placeholder="璇疯緭鍏�" clearable/>
+            <el-form-item label="宸ュ簭锛�" prop="processId">
+              <el-select 
+                v-model="form.processId" 
+                placeholder="璇烽�夋嫨宸ュ簭" 
+                clearable 
+                @change="handleProcessChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in processOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -32,6 +45,24 @@
           <el-col :span="12">
             <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -108,11 +139,12 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
+import {productProcessListPage} from "@/api/basicData/productProcess.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 import {userListNoPage} from "@/api/system/user.js";
 import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
@@ -123,11 +155,12 @@
 const data = reactive({
   form: {
     checkTime: "",
-    process: "",
+    processId: "",
     checkName: "",
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -135,10 +168,11 @@
   },
   rules: {
     checkTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    process: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
     checkName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     productId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     model: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     checkCompany: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -176,6 +210,24 @@
 const tableData = ref([]);
 const tableLoading = ref(false);
 const currentProductId = ref(0);
+const processOptions = ref([]); // 宸ュ簭涓嬫媺妗嗘暟鎹�
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessList = async () => {
+	try {
+		const res = await productProcessListPage({ current: 1, size: 1000 })
+		if (res?.code === 200) {
+			const records = res?.data?.records || []
+			processOptions.value = records.map(item => ({
+				label: item.processName || item.name || item.label,
+				value: item.id || item.processId || item.value
+			}))
+		}
+	} catch (error) {
+		console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+	}
+}
 
 // 鎵撳紑寮规
 const openDialog = async (type, row) => {
@@ -187,11 +239,64 @@
 	let userLists = await userListNoPage();
 	userList.value = userLists.data;
 	form.value = {}
+	testStandardOptions.value = [];
+	tableData.value = [];
 	getProductOptions();
+	// 鍏堝姞杞藉伐搴忓垪琛�
+	await getProcessList();
 	if (operationType.value === 'edit') {
-		form.value = {...row}
+		// 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+		const savedTestStandardId = row.testStandardId;
+		// 鍏堣缃〃鍗曟暟鎹紝浣嗘殏鏃舵竻绌� testStandardId锛岀瓑閫夐」鍔犺浇瀹屾垚鍚庡啀璁剧疆
+		form.value = {...row, testStandardId: ''}
+		// 鍏煎鏃ф暟鎹細濡傛灉 row 涓湁 process 瀛楁锛岃浆鎹负 processId
+		if (row.process && !row.processId) {
+			// 灏濊瘯浠� processOptions 涓煡鎵惧尮閰嶇殑宸ュ簭
+			const processOption = processOptions.value.find(p => p.label === row.process);
+			if (processOption) {
+				form.value.processId = processOption.value;
+			}
+		}
 		currentProductId.value = row.productId || 0
-		getQualityInspectParamList(row.id)
+		// 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+		if (currentProductId.value) {
+			// 鍏堝姞杞芥寚鏍囬�夐」
+			let params = {
+				productId: currentProductId.value,
+				inspectType: 1,
+				process: form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : ''
+			}
+			qualityInspectDetailByProductId(params).then(res => {
+				testStandardOptions.value = res.data || [];
+				// 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+				nextTick(() => {
+					setTimeout(() => {
+						// 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+						if (savedTestStandardId) {
+							// 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+							const matchedOption = testStandardOptions.value.find(item => 
+								item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+							);
+							if (matchedOption) {
+								// 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+								form.value.testStandardId = matchedOption.id;
+								handleTestStandardChange(matchedOption.id);
+							} else {
+								// 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+								console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+								form.value.testStandardId = savedTestStandardId;
+								handleTestStandardChange(savedTestStandardId);
+							}
+						} else {
+							// 鍚﹀垯浣跨敤鏃х殑閫昏緫
+							getQualityInspectParamList(row.id);
+						}
+					}, 100);
+				});
+			});
+		} else {
+			getQualityInspectParamList(row.id);
+		}
 	}
 }
 const getProductOptions = () => {
@@ -202,7 +307,7 @@
 const getModels = (value) => {
 	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-	if (currentProductId) {
+	if (currentProductId.value) {
 		getList();
 	}
 };
@@ -234,17 +339,31 @@
     return newItem;
   });
 }
+// 宸ュ簭鍙樺寲澶勭悊
+const handleProcessChange = () => {
+	// 宸ュ簭鍙樺寲鏃讹紝濡傛灉宸查�夋嫨浜у搧锛岄噸鏂板姞杞芥寚鏍囧垪琛�
+	if (currentProductId.value) {
+		getList();
+	}
+}
+
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.inspectType = 1
+			// 灏� processId 杞崲涓� process 鍚嶇О锛堝鏋滃悗绔渶瑕� process 瀛楁锛�
+			const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
 			if (operationType.value === "add") {
 				tableData.value.forEach((item) => {
 					delete item.id
 				})
 			}
-			const data = {...form.value, qualityInspectParams: tableData.value}
+			const data = {
+				...form.value, 
+				process: processName, // 淇濈暀 process 瀛楁浠ュ吋瀹瑰悗绔�
+				qualityInspectParams: tableData.value
+			}
       if (operationType.value === "add") {
         qualityInspectAdd(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
@@ -260,8 +379,42 @@
   })
 }
 const getList = () => {
-	qualityInspectDetailByProductId(currentProductId.value).then(res => {
-		tableData.value = res.data;
+	if (!currentProductId.value) {
+		testStandardOptions.value = [];
+		tableData.value = [];
+		return;
+	}
+	// 鑾峰彇宸ュ簭鍚嶇О
+	const processName = form.value.processId ? processOptions.value.find(p => p.value === form.value.processId)?.label : '';
+	let params = {
+		productId: currentProductId.value,
+		inspectType: 1,
+		process: processName
+	}
+	qualityInspectDetailByProductId(params).then(res => {
+		// 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+		testStandardOptions.value = res.data || [];
+		// 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+		tableData.value = [];
+		// 娓呯┖鎸囨爣閫夋嫨
+		form.value.testStandardId = '';
+	})
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+	if (!testStandardId) {
+		tableData.value = [];
+		return;
+	}
+	tableLoading.value = true;
+	getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+		tableData.value = res.data || [];
+	}).catch(error => {
+		console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+		tableData.value = [];
+	}).finally(() => {
+		tableLoading.value = false;
 	})
 }
 const getQualityInspectParamList = (id) => {
@@ -272,6 +425,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/processInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index 5ea1e47..5cafd2c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -45,6 +45,24 @@
               <el-input v-model="form.model" placeholder="璇疯緭鍏�" clearable/>
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎸囨爣閫夋嫨锛�" prop="testStandardId">
+              <el-select
+                v-model="form.testStandardId"
+                placeholder="璇烽�夋嫨鎸囨爣"
+                clearable
+                @change="handleTestStandardChange"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in testStandardOptions"
+                  :key="item.id"
+                  :label="item.standardName || item.standardNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
@@ -121,13 +139,13 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
 import {ElMessageBox} from "element-plus";
 import {qualityInspectParamDel, qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
-import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectDetailByProductId, getQualityTestStandardParamByTestStandardId} from "@/api/qualityManagement/metricMaintenance.js";
 
 const {proxy} = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -142,6 +160,7 @@
     productName: "",
     productId: "",
     model: "",
+    testStandardId: "",
     unit: "",
     quantity: "",
     checkCompany: "",
@@ -153,6 +172,7 @@
     checkName: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
     productId: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
     model: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
+    testStandardId: [{required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change"}],
     unit: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
     quantity: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
     checkCompany: [{required: false, message: "璇疯緭鍏�", trigger: "blur"}],
@@ -190,6 +210,7 @@
 const supplierList = ref([]);
 const productOptions = ref([]);
 const currentProductId = ref(0);
+const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
@@ -199,11 +220,52 @@
     supplierList.value = res.data;
   });
 	form.value = {}
+  testStandardOptions.value = [];
+  tableData.value = [];
   getProductOptions();
   if (operationType.value === 'edit') {
+    // 鍏堜繚瀛� testStandardId锛岄伩鍏嶈娓呯┖
+    const savedTestStandardId = row.testStandardId;
     form.value = {...row}
     currentProductId.value = row.productId || 0
-    getQualityInspectParamList(row.id)
+    // 缂栬緫妯″紡涓嬶紝鍏堝姞杞芥寚鏍囬�夐」锛岀劧鍚庡姞杞藉弬鏁板垪琛�
+    if (currentProductId.value) {
+      // 鍏堝姞杞芥寚鏍囬�夐」
+      let params = {
+        productId: currentProductId.value,
+        inspectType: 0
+      }
+      qualityInspectDetailByProductId(params).then(res => {
+        testStandardOptions.value = res.data || [];
+        // 浣跨敤 nextTick 鍜� setTimeout 纭繚閫夐」宸茬粡娓叉煋鍒� DOM
+        nextTick(() => {
+          setTimeout(() => {
+            // 濡傛灉缂栬緫鏁版嵁涓湁 testStandardId锛屽垯璁剧疆骞跺姞杞藉搴旂殑鍙傛暟
+            if (savedTestStandardId) {
+              // 纭繚绫诲瀷鍖归厤锛坕tem.id 鍙兘鏄暟瀛楁垨瀛楃涓诧級
+              const matchedOption = testStandardOptions.value.find(item => 
+                item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId)
+              );
+              if (matchedOption) {
+                // 纭繚浣跨敤鍖归厤椤圭殑 id锛堜繚鎸佺被鍨嬩竴鑷达級
+                form.value.testStandardId = matchedOption.id;
+                handleTestStandardChange(matchedOption.id);
+              } else {
+                // 濡傛灉鎵句笉鍒板尮閰嶉」锛屽皾璇曠洿鎺ヤ娇鐢ㄥ師鍊�
+                console.warn('鏈壘鍒板尮閰嶇殑鎸囨爣閫夐」锛宼estStandardId:', savedTestStandardId, '鍙敤閫夐」:', testStandardOptions.value);
+                form.value.testStandardId = savedTestStandardId;
+                handleTestStandardChange(savedTestStandardId);
+              }
+            } else {
+              // 鍚﹀垯浣跨敤鏃х殑閫昏緫
+              getQualityInspectParamList(row.id);
+            }
+          }, 100);
+        });
+      });
+    } else {
+      getQualityInspectParamList(row.id);
+    }
   }
 }
 const getProductOptions = () => {
@@ -214,7 +276,7 @@
 const getModels = (value) => {
   currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
-  if (currentProductId) {
+  if (currentProductId.value) {
     getList();
   }
 };
@@ -275,8 +337,39 @@
 }
 
 const getList = () => {
-  qualityInspectDetailByProductId(currentProductId.value).then(res => {
-    tableData.value = res.data;
+  if (!currentProductId.value) {
+    testStandardOptions.value = [];
+    tableData.value = [];
+    return;
+  }
+  let params = {
+    productId: currentProductId.value,
+    inspectType: 0
+  }
+  qualityInspectDetailByProductId(params).then(res => {
+    // 淇濆瓨涓嬫媺妗嗛�夐」鏁版嵁
+    testStandardOptions.value = res.data || [];
+    // 娓呯┖琛ㄦ牸鏁版嵁锛岀瓑寰呯敤鎴烽�夋嫨鎸囨爣
+    tableData.value = [];
+    // 娓呯┖鎸囨爣閫夋嫨
+    form.value.testStandardId = '';
+  })
+}
+
+// 鎸囨爣閫夋嫨鍙樺寲澶勭悊
+const handleTestStandardChange = (testStandardId) => {
+  if (!testStandardId) {
+    tableData.value = [];
+    return;
+  }
+  tableLoading.value = true;
+  getQualityTestStandardParamByTestStandardId(testStandardId).then(res => {
+    tableData.value = res.data || [];
+  }).catch(error => {
+    console.error('鑾峰彇鏍囧噯鍙傛暟澶辫触:', error);
+    tableData.value = [];
+  }).finally(() => {
+    tableLoading.value = false;
   })
 }
 
@@ -288,7 +381,9 @@
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
-  tableData.value = []
+  tableData.value = [];
+  testStandardOptions.value = [];
+  form.value.testStandardId = '';
   dialogFormVisible.value = false;
   emit('close')
 };
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
index 32a36fa..411856c 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/inspectionFormDia.vue
@@ -34,7 +34,6 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {Search} from "@element-plus/icons-vue";
 import {
   qualityInspectParamDel,
diff --git a/src/views/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
index 574c3f2..566d7ea 100644
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ b/src/views/reportAnalysis/dataDashboard/index.vue
@@ -22,34 +22,44 @@
       <div class="left-panel">
         <!-- 瀹㈡埛淇℃伅缁熻鍒嗘瀽 -->
 				<div class="panel-header">
-					<span class="panel-title">瀹㈡埛淇℃伅缁熻鍒嗘瀽</span>
+					<span class="panel-title">鍦ㄥ埗鍝佺粺璁″垎鏋�</span>
 				</div>
         <div class="panel-item-customers">
-					<div class="panel-title-second">
-						<div class="panel-title-icon"></div>
-						<div class="total-customers">
-							<span class="label">鎬诲悎鍚岄噾棰�(鍏�)</span>
-							<span class="value">{{sum}}</span>
+					<div class="quality-cards">
+						<div class="quality-cardSec">
+							<div class="quality-card one"></div>
+							<div class="quality-cardTitle">
+								<div>鎬诲湪鍒舵暟閲�</div>
+								<div>{{workInProcessStatistics.totalQuantity}}浠�</div>
+							</div>
 						</div>
-<!--						<div class="jiantou"></div>-->
+						<div class="quality-cardSec">
+							<div class="quality-card two"></div>
+							<div class="quality-cardTitle">
+								<div>骞冲潎鍛ㄨ浆澶╂暟</div>
+								<div>{{workInProcessStatistics.avgTurnoverDays}}澶�</div>
+							</div>
+						</div>
+						<div class="quality-cardSec">
+							<div class="quality-card three"></div>
+							<div class="quality-cardTitle">
+								<div>鍛ㄨ浆鏁堢巼</div>
+								<div>{{workInProcessStatistics.turnoverEfficiency}}%</div>
+							</div>
+						</div>
 					</div>
-					<!-- 楗煎浘鍖哄煙 -->
-					<div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px">
-						<div style="width: 240px; height: 240px; background-image: url('/src/assets/BI/zonghetongbingtubiankuang@2x.png'); background-size: contain; background-position: center; background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;">
-							<Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
-											 :series="materialPieSeries"
-											 :tooltip="pieTooltip"
-											 :options="{backgroundColor: 'transparent'}"
-											 style="margin-left: 5px;"></Echarts>
-						</div>
-						<ul class="contract-list" style="margin: 0; padding: 0; display: flex; flex-direction: column;justify-content: space-around; height: 100%; overflow-y: auto; scroll-behavior: smooth;" ref="refContractList">
-							<li v-for="item in materialPieSeries[0].data" :key="item.name" style="list-style: none; margin-bottom: 12px;">
-								<div style="display: flex;align-items: center;justify-content: space-between;width: 100%">
-									<div class="line" :style="{color: item.itemStyle.color}">鈻� {{item.name}}</div>
-									<div style="font-weight: 700;font-size: 16px;color: #85B1E4;">锟{item.value}}</div>
-								</div>
-							</li>
-						</ul>
+					<!-- 宸ュ簭鍦ㄥ埗鍝佹暟閲忔煴鐘跺浘 -->
+					<div style="height: 82%;margin-top: 20px">
+						<Echarts ref="chart"
+										 :chartStyle="chartStyle"
+										 :grid="grid"
+										 :legend="workInProcessBarLegend"
+										 :series="workInProcessBarSeries"
+										 :tooltip="tooltip"
+										 :xAxis="workInProcessXAxis"
+										 :yAxis="workInProcessYAxis"
+										 :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
+										 style="height: 100%"></Echarts>
 					</div>
         </div>
 
@@ -63,21 +73,21 @@
 							<div class="quality-cardSec">
 								<div class="quality-card one"></div>
 								<div class="quality-cardTitle">
-									<div>鍘熸潗鏂欏凡妫�娴嬫暟</div>
+									<div>鍘熸潗鏂欐鏁�</div>
 									<div>{{qualityStatisticsObject.supplierNum}}浠�</div>
 								</div>
 							</div>
 							<div class="quality-cardSec">
 								<div class="quality-card two"></div>
 								<div class="quality-cardTitle">
-									<div>杩囩▼妫�楠屾暟閲�</div>
+									<div>杩囩▼妫�鏁�</div>
 									<div>{{qualityStatisticsObject.processNum}}浠�</div>
 								</div>
 							</div>
 							<div class="quality-cardSec">
 								<div class="quality-card three"></div>
 								<div class="quality-cardTitle">
-									<div>鍑哄巶宸叉鏁伴噺</div>
+									<div>鍑哄巶妫�鏁�</div>
 									<div>{{qualityStatisticsObject.factoryNum}}浠�</div>
 								</div>
 							</div>
@@ -179,20 +189,72 @@
 				</div>
 				<div class="main-panel">
 					<div class="panel-item-customers">
-						<div class="event-header">
-							<img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
-							<span class="event-title">缁忚惀鍒嗘瀽</span>
+						<div class="order-statistics-cards" style="margin-bottom: 0px;">
+							<div class="quality-cardSec">
+								<div class="quality-card four"></div>
+								<div class="quality-cardTitle">
+									<div>鎬昏鍗曟暟</div>
+									<div>{{orderStatisticsObject.totalOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card five"></div>
+								<div class="quality-cardTitle">
+									<div>鏈畬鎴愯鍗曟暟</div>
+									<div>{{orderStatisticsObject.uncompletedOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card six"></div>
+								<div class="quality-cardTitle">
+									<div>閮ㄥ垎瀹屾垚璁㈠崟鏁�</div>
+									<div>{{orderStatisticsObject.partialCompletedOrderCount}}浠�</div>
+								</div>
+							</div>
+							<div class="quality-cardSec">
+								<div class="quality-card seven"></div>
+								<div class="quality-cardTitle">
+									<div>宸插畬鎴愯鍗曟暟</div>
+									<div>{{orderStatisticsObject.completedOrderCount}}浠�</div>
+								</div>
+							</div>
 						</div>
-						<Echarts ref="chart"
-										 :chartStyle="chartStyle"
-										 :grid="grid"
-										 :legend="barLegend1"
-										 :series="barSeries11"
-										 :tooltip="tooltip"
-										 :xAxis="xAxis3"
-										 :yAxis="yAxis3"
-										 :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
-										 style="height: 170px"></Echarts>
+						<div class="progress-table-container" ref="progressTableRef" style="margin-top: 0px;" @scroll="handleTableScroll">
+							<table class="progress-table">
+								<thead>
+									<tr>
+										<th>鐢熶骇璁㈠崟鍙�</th>
+										<th>浜у搧鍚嶇О</th>
+										<th>瑙勬牸</th>
+										<th>闇�姹傛暟閲�</th>
+										<th>瀹屾垚鏁伴噺</th>
+										<th>瀹屾垚杩涘害</th>
+									</tr>
+								</thead>
+								<tbody>
+									<tr 
+										v-for="(item, index) in progressTableData" 
+										:key="index"
+										:ref="el => setRowRef(el, index)"
+										:class="{ 'row-under-header': isRowUnderHeader(index) }"
+									>
+										<td>{{ item.npsNo || '-' }}</td>
+										<td>{{ item.productCategory || '-' }}</td>
+										<td>{{ item.specificationModel || '-' }}</td>
+										<td>{{ item.quantity || 0 }}</td>
+										<td>{{ item.completeQuantity || 0 }}</td>
+										<td>
+											<el-progress
+												:percentage="calculateProgress(item)"
+												:color="progressColor(calculateProgress(item))"
+												:status="calculateProgress(item) >= 100 ? 'success' : ''"
+												:stroke-width="8"
+											/>
+										</td>
+									</tr>
+								</tbody>
+							</table>
+						</div>
 					</div>
 				</div>
       </div>
@@ -253,7 +315,7 @@
 	getProgressStatistics,
   	getWorkInProcessTurnover
 } from "@/api/viewIndex.js";
-import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
 import {listCustomer} from "@/api/basicData/customerFile.js";
 import {listSupplier} from "@/api/basicData/supplierManageFile.js";
 import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
@@ -261,6 +323,7 @@
 import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js";
 import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js";
 import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js";
+import {productOrderListPage} from "@/api/productionManagement/productionOrder.js";
 
 // 鍏ㄥ睆鐩稿叧鐘舵��
 const isFullscreen = ref(false);
@@ -288,11 +351,17 @@
 const realtimeLineChartRef = ref(null)
 const refContractList = ref(null)
 const refTodoList = ref(null)
+const progressTableRef = ref(null)
 const timerScroll = ref(null)
+const progressTableScrollTimer = ref(null)
+const isTableScrolling = ref(false)
+const tableScrollTimeout = ref(null)
+const tableRowRefs = ref([])
+const rowsUnderHeader = ref(new Set())
 
 const chartStylePie = {
-	width: '140%',
-	height: '140%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+	width: '100%',
+	height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
 }
 const materialPieSeries = ref([
 	{
@@ -336,6 +405,21 @@
 	supplierNum: 0,
 	processNum: 0,
 	factoryNum: 0,
+})
+
+// 璁㈠崟缁熻瀵硅薄
+const orderStatisticsObject = ref({
+	totalOrderCount: 0,
+	uncompletedOrderCount: 0,
+	partialCompletedOrderCount: 0,
+	completedOrderCount: 0,
+})
+
+// 鍦ㄥ埗鍝佸懆杞粺璁″璞�
+const workInProcessStatistics = ref({
+	totalQuantity: 0,
+	avgTurnoverDays: 0,
+	turnoverEfficiency: 0,
 })
 const chartStyle = {
 	width: '100%',
@@ -579,8 +663,83 @@
 	axisLabel: { color: '#B8C8E0' }
 }]
 
+// 鍦ㄥ埗鍝佸伐搴忔煴鐘跺浘閰嶇疆
+const workInProcessXAxis = ref([{
+	type: 'category',
+	axisTick: { show: false },
+	axisLabel: { color: '#B8C8E0' },
+	data: []
+}])
+const workInProcessYAxis = [{
+	type: 'value',
+	axisLabel: { color: '#B8C8E0' },
+	name: ''
+}]
+const workInProcessBarLegend = {
+	show: false,
+	textStyle: { color: '#B8C8E0' },
+	data: []
+}
+const workInProcessBarSeries = ref([
+	{
+		name: '鍦ㄥ埗鍝佹暟閲�',
+		type: 'bar',
+		barWidth: 25, // 鍥哄畾鏌辩姸鍥惧搴︿负40px
+		barGap: 0,
+		emphasis: {
+			focus: 'series'
+		},
+		itemStyle: {
+			color: {
+				type: 'linear',
+				x: 0,
+				y: 0,
+				x2: 0,
+				y2: 1,
+				colorStops: [
+					{ offset: 0, color: '#4EE4FF' },
+					{ offset: 1, color: '#00A4ED' }
+				]
+			}
+		},
+		label: {
+			show: true,
+			position: 'top',
+			color: '#B8C8E0'
+		},
+		data: []
+	}
+])
+
 // 寰呭姙浜嬮」
 const todoList = ref([])
+
+// 鐢熶骇璁㈠崟瀹屾垚杩涘害琛ㄦ牸鏁版嵁
+const progressTableData = ref([])
+
+// 璁$畻瀹屾垚杩涘害鐧惧垎姣�
+const calculateProgress = (item) => {
+	if (!item) return 0
+	// 浼樺厛浣跨敤completionStatus瀛楁
+	if (item.completionStatus !== undefined && item.completionStatus !== null) {
+		const percentage = Number(item.completionStatus)
+		if (isNaN(percentage)) return 0
+		return Math.min(Math.max(Math.round(percentage), 0), 100)
+	}
+	// 濡傛灉娌℃湁completionStatus锛屽垯鏍规嵁瀹屾垚鏁伴噺鍜岄渶姹傛暟閲忚绠�
+	if (!item.quantity || item.quantity === 0) return 0
+	const percentage = (item.completeQuantity || 0) / item.quantity * 100
+	return Math.min(Math.max(Math.round(percentage), 0), 100)
+}
+
+// 鏍规嵁杩涘害鐧惧垎姣旇繑鍥為鑹�
+const progressColor = (percentage) => {
+	const p = percentage || 0
+	if (p < 30) return "#f56c6c"
+	if (p < 50) return "#e6a23c"
+	if (p < 80) return "#409eff"
+	return "#67c23a"
+}
 
 // 璁$畻缂╂斁姣斾緥
 const calculateScale = () => {
@@ -635,6 +794,43 @@
 		}))
 	})
 }
+// 鍦ㄥ埗鍝佸懆杞粺璁�
+const workInProcessTurnoverInfo = () => {
+	getWorkInProcessTurnover().then((res) => {
+		console.log("鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹�:", res)
+		
+		if (!res || !res.data) {
+			console.warn('鍦ㄥ埗鍝佸懆杞粺璁℃暟鎹负绌�')
+			return
+		}
+		
+		// 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+		workInProcessStatistics.value = {
+			totalQuantity: res.data.totalOrderCount || 0,
+			avgTurnoverDays: res.data.averageTurnoverDays || 0,
+			turnoverEfficiency: res.data.turnoverEfficiency || 0,
+		}
+		
+		// 璁剧疆宸ュ簭鏌辩姸鍥炬暟鎹�
+		// X杞达細processDetails (宸ュ簭璇︽儏鏁扮粍)
+		// Y杞达細processQuantityDetails (宸ュ簭鏁伴噺璇︽儏鏁扮粍)
+		if (res.data.processDetails && Array.isArray(res.data.processDetails)) {
+			// 璁剧疆X杞存暟鎹紙宸ュ簭鍚嶇О锛�
+			workInProcessXAxis.value[0].data = res.data.processDetails
+		} else {
+			workInProcessXAxis.value[0].data = []
+		}
+		
+		if (res.data.processQuantityDetails && Array.isArray(res.data.processQuantityDetails)) {
+			// 璁剧疆Y杞存暟鎹紙鍦ㄥ埗鍝佹暟閲忥級
+			workInProcessBarSeries.value[0].data = res.data.processQuantityDetails
+		} else {
+			workInProcessBarSeries.value[0].data = []
+		}
+	}).catch((error) => {
+		console.error('鑾峰彇鍦ㄥ埗鍝佸懆杞粺璁″け璐�:', error)
+	})
+}
 // 璐ㄦ缁熻
 const qualityStatisticsInfo = () => {
 	qualityStatistics().then((res) => {
@@ -651,6 +847,7 @@
 }
 // 鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻
 const progressStatisticsInfo = () => {
+	// 浠庣粺璁℃帴鍙h幏鍙栫粺璁℃暟鎹�
 	getProgressStatistics().then((res) => {
 		console.log("鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻鏁版嵁:", res)
 		
@@ -659,24 +856,22 @@
 			return
 		}
 		
-		// 璁剧疆X杞存暟鎹� - 浣跨敤鍒嗙被鍚嶇О
-		xAxis3.value[0].data = ['宸插畬鎴愯繘搴︽暟', '鎬昏鍗曟暟', '鏈畬鎴愯鍗曟暟', '宸插畬鎴愯鍗曟暟']
-		
-		// 璁剧疆鍗曚釜绯诲垪鐨勬暟鎹� - 姣忎釜X杞村垎绫诲搴斾竴涓��
-		if (barSeries11.value && barSeries11.value.length > 0) {
-			barSeries11.value[0].data = [
-				res.data.completedProgressCount || 0,
-				res.data.totalOrderCount || 0,
-				res.data.uncompletedOrderCount || 0,
-				res.data.completedOrderCount || 0
-			]
+		// 浠庢帴鍙h幏鍙栫粺璁℃暟鎹�
+		orderStatisticsObject.value = {
+			totalOrderCount: res.data.totalOrderCount || 0,
+			uncompletedOrderCount: res.data.uncompletedOrderCount || 0,
+			partialCompletedOrderCount: res.data.partialCompletedOrderCount || 0,
+			completedOrderCount: res.data.completedOrderCount || 0
 		}
+		progressTableData.value = res.data.completedOrderDetails || []
+		// 閲嶇疆琛屽紩鐢�
+		tableRowRefs.value = []
+		rowsUnderHeader.value.clear()
 		
-		console.log('鍥捐〃鏁版嵁璁剧疆瀹屾垚:', {
-			xAxis: xAxis3.value[0].data,
-			series: barSeries11.value[0]?.data
+		// 鍦ㄨ幏鍙栧埌鏁版嵁鍚庯紝鍒濆鍖栨粴鍔ㄥ姛鑳�
+		nextTick(() => {
+			initProgressTableScroll()
 		})
-		
 	}).catch((error) => {
 		console.error('鑾峰彇鐢熶骇璁㈠崟瀹屾垚杩涘害缁熻澶辫触:', error)
 	})
@@ -822,6 +1017,163 @@
 
 // 鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
 const autoSwitchTimer = ref(null)
+
+// 璁剧疆琛屽紩鐢�
+const setRowRef = (el, index) => {
+	if (el) {
+		tableRowRefs.value[index] = el
+	}
+}
+
+// 鍒ゆ柇琛屾槸鍚﹀湪琛ㄥご涓嬫柟
+const isRowUnderHeader = (index) => {
+	return rowsUnderHeader.value.has(index)
+}
+
+// 澶勭悊琛ㄦ牸婊氬姩浜嬩欢
+const handleTableScroll = () => {
+	const tableContainer = progressTableRef.value
+	if (!tableContainer) return
+	
+	const thead = tableContainer.querySelector('thead')
+	if (!thead) return
+	
+	const theadHeight = thead.offsetHeight
+	const containerRect = tableContainer.getBoundingClientRect()
+	const containerTop = containerRect.top
+	const theadBottom = containerTop + theadHeight
+	
+	// 娓呯┖涔嬪墠鐨勮褰�
+	rowsUnderHeader.value.clear()
+	
+	// 妫�鏌ユ瘡涓�琛屾槸鍚﹀湪琛ㄥご涓嬫柟锛堣琛ㄥご閬尅锛�
+	tableRowRefs.value.forEach((row, index) => {
+		if (row) {
+			const rowRect = row.getBoundingClientRect()
+			const rowTop = rowRect.top
+			const rowBottom = rowRect.bottom
+			
+			// 濡傛灉琛屼笌琛ㄥご鏈夐噸鍙狅紙琛屽湪琛ㄥご涓嬫柟琚伄鎸★級
+			// 琛岀殑椤堕儴鍦ㄨ〃澶村簳閮ㄤ笅鏂癸紝浣嗚鐨勫簳閮ㄥ湪琛ㄥご搴曢儴涓婃柟锛岃鏄庤閬尅
+			if (rowTop < theadBottom && rowBottom > containerTop) {
+				rowsUnderHeader.value.add(index)
+			}
+		}
+	})
+	
+	// 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+	if (tableScrollTimeout.value) {
+		clearTimeout(tableScrollTimeout.value)
+	}
+	
+	// 婊氬姩鍋滄鍚庢竻绌烘贰鍖栨爣璁�
+	tableScrollTimeout.value = setTimeout(() => {
+		rowsUnderHeader.value.clear()
+	}, 150)
+}
+
+// 鍒濆鍖栫敓浜ц鍗曡繘搴﹁〃鏍兼粴鍔ㄥ姛鑳�
+const initProgressTableScroll = () => {
+	const tableContainer = progressTableRef.value
+	if (!tableContainer) return
+	
+	// 娓呯悊涔嬪墠鐨勬粴鍔ㄥ姩鐢诲拰瀹氭椂鍣�
+	if (progressTableScrollTimer.value) {
+		cancelAnimationFrame(progressTableScrollTimer.value)
+		progressTableScrollTimer.value = null
+	}
+	if (tableContainer._pauseTimer) {
+		clearInterval(tableContainer._pauseTimer)
+		tableContainer._pauseTimer = null
+	}
+	
+	const tbody = tableContainer.querySelector('tbody')
+	if (!tbody) return
+	
+	// 娓呯悊涔嬪墠鍙兘瀛樺湪鐨勫厠闅嗚锛堜繚鐣欏師濮嬫暟鎹锛�
+	// 鍘熷鏁版嵁琛岀殑鏁伴噺搴旇绛変簬 progressTableData.value.length
+	const originalCount = progressTableData.value.length
+	const allRows = Array.from(tbody.querySelectorAll('tr'))
+	if (allRows.length > originalCount) {
+		// 绉婚櫎鎵�鏈夎秴杩囧師濮嬫暟閲忕殑琛岋紙杩欎簺鏄厠闅嗙殑琛岋級
+		for (let i = originalCount; i < allRows.length; i++) {
+			allRows[i].remove()
+		}
+	}
+	
+	const scrollItems = Array.from(tbody.querySelectorAll('tr'))
+	if (scrollItems.length === 0) return
+	
+	// 鑾峰彇鍘熷鏁版嵁椤规暟閲�
+	const originalItemCount = scrollItems.length
+	
+	// 璁$畻瀹瑰櫒楂樺害鍜岃〃澶撮珮搴�
+	const thead = tableContainer.querySelector('thead')
+	const theadHeight = thead ? thead.offsetHeight : 40
+	const containerHeight = tableContainer.clientHeight
+	const visibleHeight = containerHeight - theadHeight
+	
+	// 璁$畻鍘熷鏁版嵁鐨勬�婚珮搴�
+	const itemHeight = scrollItems[0]?.offsetHeight || 40
+	const totalContentHeight = itemHeight * originalItemCount
+	
+	// 濡傛灉鏁版嵁閲忎笉澶燂紝瀹瑰櫒鍙互瀹屽叏鏄剧ず鎵�鏈夋暟鎹紝灏变笉闇�瑕佹粴鍔ㄥ拰鍏嬮殕
+	if (totalContentHeight <= visibleHeight) {
+		// 鏁版嵁閲忓皯锛屼笉闇�瑕佹粴鍔紝鐩存帴杩斿洖
+		return
+	}
+	
+	// 鏁版嵁閲忚冻澶燂紝闇�瑕佹粴鍔紝杩涜鍏嬮殕浠ュ疄鐜版棤缂濇粴鍔�
+	const cloneCount = Math.ceil(visibleHeight / itemHeight) + 2
+	
+	// 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
+	for (let i = 0; i < cloneCount; i++) {
+		const clone = scrollItems[i % originalItemCount].cloneNode(true)
+		tbody.appendChild(clone)
+	}
+	
+	let scrollPosition = 0
+	const scrollSpeed = 1.5
+	const pauseTime = 3000
+	let isPaused = false
+	let lastTimestamp = 0
+	
+	// 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
+	function scrollAnimation(timestamp) {
+		if (!lastTimestamp) lastTimestamp = timestamp
+		const deltaTime = timestamp - lastTimestamp
+		lastTimestamp = timestamp
+		
+		if (!isPaused) {
+			scrollPosition += scrollSpeed * (deltaTime / 16)
+			
+			// 璁$畻鏈�澶ф粴鍔ㄤ綅缃紙鍘熷鍐呭鐨勯珮搴︼級
+			const maxScroll = itemHeight * originalItemCount
+			
+			// 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
+			if (scrollPosition >= maxScroll) {
+				scrollPosition = 0
+				tableContainer.scrollTop = 0
+			} else {
+				tableContainer.scrollTop = scrollPosition
+			}
+		}
+		
+		progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+	}
+	
+	// 鍚姩婊氬姩鍔ㄧ敾
+	progressTableScrollTimer.value = requestAnimationFrame(scrollAnimation)
+	
+	// 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
+	const pauseTimer = setInterval(() => {
+		isPaused = !isPaused
+	}, pauseTime)
+	
+	// 娓呯悊瀹氭椂鍣�
+	tableContainer._pauseTimer = pauseTimer
+}
+
 // 鍒濆鍖栧緟鍔炰簨椤瑰垪琛ㄦ粴鍔ㄥ姛鑳�
 const initTodoListScroll = () => {
 	const todoList = refTodoList.value
@@ -1031,6 +1383,7 @@
   window.addEventListener('webkitfullscreenchange', handleFullscreenChange)
   window.addEventListener('MSFullscreenChange', handleFullscreenChange)
   analysisCustomer()
+  workInProcessTurnoverInfo()
   qualityStatisticsInfo()
 	// accountStatisticsInfo()
 	progressStatisticsInfo()
@@ -1072,6 +1425,25 @@
       clearInterval(todoList._pauseTimer)
       todoList._pauseTimer = null
     }
+  }
+  
+  // 娓呯悊鐢熶骇璁㈠崟杩涘害琛ㄦ牸鐨勫姩鐢诲拰瀹氭椂鍣�
+  const progressTable = progressTableRef.value
+  if (progressTable) {
+    if (progressTableScrollTimer.value) {
+      cancelAnimationFrame(progressTableScrollTimer.value)
+      progressTableScrollTimer.value = null
+    }
+    if (progressTable._pauseTimer) {
+      clearInterval(progressTable._pauseTimer)
+      progressTable._pauseTimer = null
+    }
+  }
+  
+  // 娓呯悊琛ㄦ牸婊氬姩瀹氭椂鍣�
+  if (tableScrollTimeout.value) {
+    clearTimeout(tableScrollTimeout.value)
+    tableScrollTimeout.value = null
   }
   
   // 娓呯悊鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
@@ -1272,7 +1644,33 @@
 }
 .quality-card.three {
 	background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
-	
+}
+
+/* 璁㈠崟缁熻鍗$墖鏍峰紡 */
+.order-statistics-cards {
+	display: flex;
+	gap: 12px;
+	width: 100%;
+	height: 94px;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 20px;
+}
+
+.quality-card.four {
+	background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
+}
+
+.quality-card.five {
+	background-image: url("@/assets/BI/guochengyijianicon@2x.png");
+}
+
+.quality-card.six {
+	background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
+}
+
+.quality-card.seven {
+	background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
 }
 .panel-title-icon {
 	width: 60px;
@@ -1555,4 +1953,84 @@
   border-color: rgba(255, 255, 255, 0.5);
   box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5);
 }
+
+/* 鐢熶骇璁㈠崟杩涘害琛ㄦ牸鏍峰紡 */
+.progress-table-container {
+  height: 250px;
+  overflow-y: auto;
+  overflow-x: hidden;
+  margin-top: 10px;
+  scrollbar-width: none; /* Firefox */
+  -ms-overflow-style: none; /* IE鍜孍dge */
+}
+
+.progress-table-container::-webkit-scrollbar {
+  display: none; /* Chrome銆丼afari鍜孫pera */
+}
+
+.progress-table {
+  width: 100%;
+  border-collapse: collapse;
+  color: #B8C8E0;
+  font-size: 12px;
+  table-layout: fixed;
+}
+
+.progress-table thead {
+  position: sticky;
+  top: 0;
+  background-color: rgba(26, 88, 176, 0.9);
+  z-index: 10;
+}
+
+.progress-table th {
+  padding: 8px 6px;
+  text-align: left;
+  font-weight: 500;
+  border-bottom: 1px solid rgba(184, 200, 224, 0.3);
+  color: #B8C8E0;
+  font-size: 12px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.progress-table th:nth-child(1) { width: 15%; } /* 鐢熶骇璁㈠崟鍙� */
+.progress-table th:nth-child(2) { width: 15%; } /* 浜у搧鍚嶇О */
+.progress-table th:nth-child(3) { width: 15%; } /* 瑙勬牸 */
+.progress-table th:nth-child(4) { width: 12%; } /* 闇�姹傛暟閲� */
+.progress-table th:nth-child(5) { width: 12%; } /* 瀹屾垚鏁伴噺 */
+.progress-table th:nth-child(6) { width: 31%; } /* 瀹屾垚杩涘害 */
+
+.progress-table td {
+  padding: 8px 6px;
+  border-bottom: 1px solid rgba(184, 200, 224, 0.1);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-size: 12px;
+  transition: opacity 0.3s ease;
+}
+
+.progress-table tbody tr:hover {
+  background-color: rgba(184, 200, 224, 0.1);
+}
+
+.progress-table tbody tr.row-under-header {
+  opacity: 0.5;
+}
+
+/* el-progress 缁勪欢鏍峰紡璋冩暣 */
+.progress-table :deep(.el-progress) {
+  width: 100%;
+}
+
+.progress-table :deep(.el-progress-bar__outer) {
+  background-color: rgba(184, 200, 224, 0.2);
+}
+
+.progress-table :deep(.el-progress__text) {
+  color: #B8C8E0;
+  font-size: 11px;
+}
 </style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
index 1aa36c1..f61cbe5 100644
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ b/src/views/reportAnalysis/projectProfit/index.vue
@@ -1,30 +1,32 @@
 <template>
-  <div class="app-container">
-    <el-form :model="filters" :inline="true" label-width="80px">
-      <el-form-item label="瀹㈡埛鍚嶇О">
-        <el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
-        <el-button @click="resetFilters"> 閲嶇疆 </el-button>
-        <el-button @click="handleOut"> 瀵煎嚭 </el-button>
-      </el-form-item>
-    </el-form>
-    <div class="table_list">
-      <PIMTable
-        rowKey="id"
-        :column="columns"
-        :tableLoading="loading"
-        :tableData="dataList"
-        :page="{
+	<div class="app-container">
+		<el-form :model="filters" :inline="true" label-width="80px">
+			<el-form-item label="瀹㈡埛鍚嶇О">
+				<el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" clearable style="width: 240px"/>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
+				<el-button @click="resetFilters"> 閲嶇疆 </el-button>
+				<el-button @click="handleOut"> 瀵煎嚭 </el-button>
+			</el-form-item>
+		</el-form>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="columns"
+				:tableLoading="loading"
+				:tableData="dataList"
+				:page="{
           current: pagination.currentPage,
           size: pagination.pageSize,
-          total: pagination.total,
+          total: pagination.total
         }"
-        @pagination="changePage"
-      ></PIMTable>
-    </div>
-  </div>
+				:isShowSummary="true"
+				:summaryMethod="summarizeMainTable"
+				@pagination="changePage"
+			></PIMTable>
+		</div>
+	</div>
 </template>
 
 <script setup>
@@ -36,93 +38,89 @@
 const { proxy } = getCurrentInstance();
 
 defineOptions({
-  name: "椤圭洰鍒╂鼎",
+	name: "椤圭洰鍒╂鼎",
 });
 
 const {
-  loading,
-  filters,
-  columns,
-  dataList,
-  pagination,
-  getTableData,
-  resetFilters,
-  onCurrentChange,
+	loading,
+	filters,
+	columns,
+	dataList,
+	pagination,
+	getTableData,
+	resetFilters,
+	onCurrentChange,
 } = usePaginationApi(
-  getPurchaseList,
-  {
-    customerName: undefined,
-  },
-  [
-    {
-      label: "閿�鍞悎鍚屽彿",
-      align: "center",
-      prop: "customerContractNo",
-    },
-    {
-      label: "瀹㈡埛鍚嶇О",
-      align: "center",
-      prop: "customerName",
-    },
-    {
-      label: "椤圭洰鍚嶇О",
-      align: "center",
-      prop: "projectName",
-    },
-    {
-      label: "鍚堝悓閲戦",
-      align: "center",
-      prop: "contractAmount",
-    },
-    {
-      label: "閲囪喘閲戦",
-      align: "center",
-      prop: "purchaseAmount",
-    },
-    {
-      label: "鍒╂鼎",
-      align: "center",
-      prop: "balance",
-    },
-    {
-      label: "鍒╂鼎鐜�",
-      align: "center",
-      prop: "balanceRatio",
-    },
-    {
-      label: "澧炲�肩◣",
-      align: "center",
-      prop: "balanceAmount",
-    },
-  ]
+	getPurchaseList,
+	{
+		customerName: undefined,
+	},
+	[
+		{
+			label: "閿�鍞悎鍚屽彿",
+			align: "center",
+			prop: "customerContractNo",
+		},
+		{
+			label: "瀹㈡埛鍚嶇О",
+			align: "center",
+			prop: "customerName",
+		},
+		{
+			label: "鍚堝悓閲戦",
+			align: "center",
+			prop: "contractAmount",
+		},
+		{
+			label: "閲囪喘閲戦",
+			align: "center",
+			prop: "purchaseAmount",
+		},
+		{
+			label: "鍒╂鼎",
+			align: "center",
+			prop: "balance",
+		},
+		{
+			label: "鍒╂鼎鐜�",
+			align: "center",
+			prop: "balanceRatio",
+		},
+	]
 );
 
-const changePage = ({ page }) => {
-  pagination.currentPage = page;
-  onCurrentChange(page);
+const changePage = ({ page, limit }) => {
+	pagination.currentPage = page;
+	pagination.pageSize = limit;
+	onCurrentChange(page);
+};
+
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = (param) => {
+	return proxy.summarizeTable(param, ["contractAmount", "purchaseAmount", "balance"]);
 };
 
 // 瀵煎嚭
 const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
-    })
-    .catch(() => {
-      proxy.$modal.msg("宸插彇娑�");
-    });
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
 };
 
 onMounted(() => {
-  getTableData();
+	getTableData();
 });
 </script>
 <style lang="scss" scoped>
 .table_list {
-  margin-top: unset;
+	margin-top: unset;
 }
 </style>
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5304faf..18f8cc5 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -359,7 +359,7 @@
 										<span class="value">{{ formatDate(item.createTime) }}</span>
 									</div>
 									<div>
-										
+
 										<span class="label">瀹㈡埛鍚嶇О锛�</span>
 										<span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
 									</div>
@@ -490,16 +490,55 @@
 				</div>
 			</template>
 		</el-dialog>
-    <FileList ref="fileListRef" />
+    <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" />
+    <!-- 瀵煎叆瀵硅瘽妗� -->
+    <el-dialog
+      :title="importUpload.title"
+      v-model="importUpload.open"
+      width="400px"
+      append-to-body
+    >
+      <el-upload
+        ref="importUploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="importUpload.headers"
+        :action="importUpload.url"
+        :disabled="importUpload.isUploading"
+        :before-upload="importUpload.beforeUpload"
+        :on-progress="importUpload.onProgress"
+        :on-success="importUpload.onSuccess"
+        :on-error="importUpload.onError"
+        :on-change="importUpload.onChange"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitImportFile" :loading="importUpload.isUploading">纭� 瀹�</el-button>
+          <el-button @click="importUpload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref} from "vue";
+import {onMounted, ref, getCurrentInstance} from "vue";
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
 import {ElMessage, ElMessageBox} from "element-plus";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { UploadFilled } from "@element-plus/icons-vue";
 import useUserStore from "@/store/modules/user";
 import { userListNoPage } from "@/api/system/user.js";
 import FileList from "./fileList.vue";
@@ -650,6 +689,54 @@
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
 
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+  title: "瀵煎叆閿�鍞彴璐�",
+  open: false,
+  url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
+  headers: { Authorization: "Bearer " + getToken() },
+  isUploading: false,
+  beforeUpload: (file) => {
+    const isExcel = file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+    const isLt10M = file.size / 1024 / 1024 < 10;
+    if (!isExcel) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+      return false;
+    }
+    if (!isLt10M) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+      return false;
+    }
+    return true;
+  },
+  onChange: (file, fileList) => {
+    console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+  },
+  onProgress: (event, file, fileList) => {
+    console.log('涓婁紶涓�...', event.percent);
+  },
+  onSuccess: (response, file, fileList) => {
+    console.log('涓婁紶鎴愬姛', response, file, fileList);
+    importUpload.isUploading = false;
+    if (response.code === 200) {
+      proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+      importUpload.open = false;
+      if (importUploadRef.value) {
+        importUploadRef.value.clearFiles();
+      }
+      getList();
+    } else {
+      proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+    }
+  },
+  onError: (error, file, fileList) => {
+    console.error('涓婁紶澶辫触', error, file, fileList);
+    importUpload.isUploading = false;
+    proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+  },
+});
+
 const changeDaterange = (value) => {
   if (value) {
     searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
@@ -708,7 +795,6 @@
   });
 };
 const getProductModel = (value) => {
-  console.log("value", value);
   const index = modelOptions.value.findIndex((item) => item.id === value);
   if (index !== -1) {
     productForm.value.specificationModel = modelOptions.value[index].model;
@@ -733,6 +819,7 @@
   return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
 };
 function convertIdToValue(data) {
+  if (!data || !Array.isArray(data)) return [];
   return data.map((item) => {
     const { id, children, ...rest } = item;
     const newItem = {
@@ -902,6 +989,12 @@
   productOperationType.value = type;
   productForm.value = {};
   proxy.resetForm("productFormRef");
+  // 鏂板銆佺紪杈戦兘闇�鍏堝姞杞戒骇鍝佹爲锛屽惁鍒� el-tree-select 鏃犳暟鎹�
+  try {
+    await getProductOptions();
+  } catch (e) {
+    console.error("鍔犺浇浜у搧鏍戝け璐�", e);
+  }
   if (type === "edit") {
     productForm.value = { ...row };
     productIndex.value = index;
@@ -983,6 +1076,21 @@
   proxy.resetForm("productFormRef");
   productFormVisible.value = false;
 };
+// 瀵煎叆
+const handleImport = () => {
+  importUpload.title = "瀵煎叆閿�鍞彴璐�";
+  importUpload.open = true;
+  if (importUploadRef.value) {
+    importUploadRef.value.clearFiles();
+  }
+};
+
+// 鎻愪氦瀵煎叆鏂囦欢
+const submitImportFile = () => {
+  importUpload.isUploading = true;
+  proxy.$refs["importUploadRef"].submit();
+};
+
 // 瀵煎嚭
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {

--
Gitblit v1.9.3