From 2d3530a7c11557a40807ad7c0b9e302ce6ce3a9f Mon Sep 17 00:00:00 2001
From: hsy <1029150275@qq.com>
Date: 星期五, 28 八月 2026 10:16:32 +0800
Subject: [PATCH] feat: 综合业务模块页面重构与交互完善

---
 src/api/salesManagement/indicatorStats.js                                                      |   17 
 src/views/projectManagement/config/index.vue                                                   |  109 +
 src/api/projectManagement/config.js                                                            |   18 
 src/api/projectManagement/project.js                                                           |    8 
 src/views/officeProcessAutomation/ReimburseManage/shared/finReimbursementMappers.js            |   88 
 src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue                                 |   19 
 src/views/qualityManagement/finalInspection/index.vue                                          |   33 
 src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue |   20 
 src/views/equipmentManagement/ledger/Form.vue                                                  |  293 ++
 src/views/inventoryManagement/fuelCardManagement/index.vue                                     |  430 ++++
 src/views/inventoryManagement/vehicleFuelManagement/index.vue                                  |  765 +++----
 src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/useCostReimburse.js           |  139 +
 src/api/qualityManagement/rawMaterialInspection.js                                             |   12 
 src/views/equipmentManagement/calibration/index.vue                                            |   67 
 src/views/qualityManagement/metricMaintenance/index.vue                                        |   13 
 src/views/projectManagement/Management/components/ContractListDialog.vue                       |  104 +
 src/views/equipmentManagement/ledger/index.vue                                                 |  228 ++
 src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/components/DetailPanel.vue    |    2 
 src/views/inventoryManagement/vehicleManagement/index.vue                                      |  889 ++++----
 src/views/equipmentManagement/upkeep/index.vue                                                 |   36 
 src/views/qualityManagement/processInspection/components/formDia.vue                           |   17 
 src/views/salesManagement/deliveryLedger/index.vue                                             |  203 +
 src/views/equipmentManagement/operationManagement/index.vue                                    |   22 
 src/views/equipmentManagement/repair/Modal/MaintainModal.vue                                   |   10 
 src/views/equipmentManagement/repair/Modal/RepairModal.vue                                     |   77 
 src/views/inventoryManagement/issueManagement/index.vue                                        |    4 
 src/views/salesManagement/salesQuotation/index.vue                                             |   45 
 src/views/projectManagement/Management/components/ArchiveDialog.vue                            |  175 +
 src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js                 |   26 
 src/views/qualityManagement/rawMaterialInspection/components/formDia.vue                       |   21 
 src/views/salesManagement/lawsuitManagement/index.vue                                          |   16 
 src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue                                 |    7 
 src/api/device/statusChangeRecord.js                                                           |    9 
 .gitignore                                                                                     |    3 
 src/api/inventoryManagement/vehicle.js                                                         |  144 +
 src/views/equipmentManagement/upkeep/Form/PlanModal.vue                                        |   27 
 src/views/salesManagement/receiptPaymentLedger/index.vue                                       |  836 +++++--
 src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue                              |   56 
 src/views/salesManagement/salesLedger/index.vue                                                |  439 +++
 src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/index.vue                     |   68 
 src/api/system/user.js                                                                         |    5 
 src/views/salesManagement/biddingManagement/index.vue                                          |    8 
 src/views/qualityManagement/finalInspection/components/formDia.vue                             |  214 +
 src/views/equipmentManagement/repair/index.vue                                                 |   11 
 src/components/PIMTable/PIMTable.vue                                                           |   29 
 src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue               |  119 +
 src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/costReimburseUtils.js         |    2 
 src/views/equipmentManagement/upkeep/Form/formDia.vue                                          |   41 
 src/views/projectManagement/Management/index.vue                                               |   26 
 49 files changed, 4,456 insertions(+), 1,494 deletions(-)

diff --git a/.gitignore b/.gitignore
index f979342..dfa1a4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,6 @@
 
 package-lock.json
 yarn.lock
+
+/graphify-out
+build_graph.py
diff --git a/src/api/device/statusChangeRecord.js b/src/api/device/statusChangeRecord.js
new file mode 100644
index 0000000..a4a5367
--- /dev/null
+++ b/src/api/device/statusChangeRecord.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function listStatusChangeRecord(query) {
+  return request({
+    url: '/device/statusChangeRecord/list',
+    method: 'get',
+    params: query
+  })
+}
diff --git a/src/api/inventoryManagement/vehicle.js b/src/api/inventoryManagement/vehicle.js
new file mode 100644
index 0000000..7df1888
--- /dev/null
+++ b/src/api/inventoryManagement/vehicle.js
@@ -0,0 +1,144 @@
+import request from '@/utils/request'
+
+// 杞﹁締淇℃伅
+export function listVehicleInfo(query) {
+  return request({
+    url: '/vehicle/info/listPage',
+    method: 'get',
+    params: query
+  })
+}
+export function getWarningList() {
+  return request({
+    url: '/vehicle/info/warningList',
+    method: 'get'
+  })
+}
+export function addVehicleInfo(data) {
+  return request({
+    url: '/vehicle/info',
+    method: 'post',
+    data: data
+  })
+}
+export function updateVehicleInfo(data) {
+  return request({
+    url: '/vehicle/info',
+    method: 'put',
+    data: data
+  })
+}
+export function delVehicleInfo(id) {
+  return request({
+    url: '/vehicle/info/' + id,
+    method: 'delete'
+  })
+}
+
+// 鍔犳补鍗�
+export function listFuelCardPage(query) {
+  return request({
+    url: '/vehicle/fuelCard/listPage',
+    method: 'get',
+    params: query
+  })
+}
+export function listAllFuelCard() {
+  return request({
+    url: '/vehicle/fuelCard/listAll',
+    method: 'get'
+  })
+}
+export function addFuelCard(data) {
+  return request({
+    url: '/vehicle/fuelCard',
+    method: 'post',
+    data: data
+  })
+}
+export function updateFuelCard(data) {
+  return request({
+    url: '/vehicle/fuelCard',
+    method: 'put',
+    data: data
+  })
+}
+export function delFuelCard(id) {
+  return request({
+    url: '/vehicle/fuelCard/' + id,
+    method: 'delete'
+  })
+}
+
+// 鍔犳补璁板綍
+export function listFuelRecord(query) {
+  return request({
+    url: '/vehicle/fuelRecord/listPage',
+    method: 'get',
+    params: query
+  })
+}
+export function addFuelRecord(data) {
+  return request({
+    url: '/vehicle/fuelRecord',
+    method: 'post',
+    data: data
+  })
+}
+export function updateFuelRecord(data) {
+  return request({
+    url: '/vehicle/fuelRecord',
+    method: 'put',
+    data: data
+  })
+}
+export function delFuelRecord(id) {
+  return request({
+    url: '/vehicle/fuelRecord/' + id,
+    method: 'delete'
+  })
+}
+
+
+// 鍒嗛〉鏌ヨ鍔犳补鍗″厖鍊艰褰�
+export function listRecharge(query) {
+  return request({
+    url: '/vehicle/fuelCardRecharge/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏂板鍔犳补鍗″厖鍊�
+export function addRecharge(data) {
+  return request({
+    url: '/vehicle/fuelCardRecharge/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 鍒犻櫎鍔犳补鍗″厖鍊�
+export function delRecharge(id) {
+  return request({
+    url: '/vehicle/fuelCardRecharge/' + id,
+    method: 'delete'
+  })
+}
+
+
+// 鎻愪氦鍔犳补璁板綍
+export function submitFuelRecord(id) {
+  return request({
+    url: '/vehicle/fuelRecord/submit/' + id,
+    method: 'post'
+  })
+}
+
+// 鎾ゅ洖鍔犳补璁板綍
+export function revokeFuelRecord(id) {
+  return request({
+    url: '/vehicle/fuelRecord/revoke/' + id,
+    method: 'post'
+  })
+}
diff --git a/src/api/projectManagement/config.js b/src/api/projectManagement/config.js
new file mode 100644
index 0000000..3d77e4c
--- /dev/null
+++ b/src/api/projectManagement/config.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 鏌ヨ椤圭洰绠$悊鍏ㄥ眬閰嶇疆
+export function getConfig() {
+  return request({
+    url: '/projectManagement/config',
+    method: 'get'
+  })
+}
+
+// 鏇存柊椤圭洰绠$悊鍏ㄥ眬閰嶇疆
+export function updateConfig(data) {
+  return request({
+    url: '/projectManagement/config',
+    method: 'put',
+    data: data
+  })
+}
diff --git a/src/api/projectManagement/project.js b/src/api/projectManagement/project.js
index 2d6eff1..c373542 100644
--- a/src/api/projectManagement/project.js
+++ b/src/api/projectManagement/project.js
@@ -116,3 +116,11 @@
     method: 'post'
   })
 }
+
+// 鑾峰彇椤圭洰褰掓。闄勪欢
+export function getProjectAttachments(id) {
+  return request({
+    url: `/projectManagement/info/attachments/${id}`,
+    method: 'get'
+  })
+}
diff --git a/src/api/qualityManagement/rawMaterialInspection.js b/src/api/qualityManagement/rawMaterialInspection.js
index dcb3869..7727ef3 100644
--- a/src/api/qualityManagement/rawMaterialInspection.js
+++ b/src/api/qualityManagement/rawMaterialInspection.js
@@ -45,7 +45,7 @@
     })
 }
 
-// 鎻愪氦鍘熸潗鏂欐楠�
+// 涓嬭浇鍘熸潗鏂欐楠學ord
 export function downloadQualityInspect(data) {
     return request({
         url: '/quality/qualityInspect/down',
@@ -55,3 +55,13 @@
     })
 }
 
+// 涓嬭浇鍘熸潗鏂欐楠孭DF
+export function downloadQualityInspectPdf(data) {
+    return request({
+        url: '/quality/qualityInspect/downPdf',
+        method: 'post',
+        data: data,
+        responseType: "blob",
+    })
+}
+
diff --git a/src/api/salesManagement/indicatorStats.js b/src/api/salesManagement/indicatorStats.js
index c29eac3..4c19f29 100644
--- a/src/api/salesManagement/indicatorStats.js
+++ b/src/api/salesManagement/indicatorStats.js
@@ -19,6 +19,15 @@
   });
 }
 
+// 椤圭洰寰�鏉ユ眹鎬伙紙椤跺眰锛�
+export function projectTransactions(query) {
+  return request({
+    url: "/metricStatistics/projectTransactions",
+    method: "get",
+    params: query,
+  });
+}
+
 // 瀹㈡埛寰�鏉ュ垪琛�
 export function customewTransactions(query) {
   return request({
@@ -36,3 +45,11 @@
     params: query,
   });
 }
+
+// 澶х洏鎬昏
+export function transactionsSummary() {
+  return request({
+    url: "/metricStatistics/transactionsSummary",
+    method: "get"
+  });
+}
diff --git a/src/api/system/user.js b/src/api/system/user.js
index 431f6b0..541cba7 100644
--- a/src/api/system/user.js
+++ b/src/api/system/user.js
@@ -135,10 +135,11 @@
   })
 }
 // 鏌ヨ鐢ㄦ埛鍒楄〃
-export function userListNoPageByTenantId() {
+export function userListNoPageByTenantId(params) {
   return request({
     url: '/system/user/userListNoPageByTenantId',
-    method: 'get'
+    method: 'get',
+    params
   })
 }
 
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 74615af..b8c6792 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -117,7 +117,33 @@
              @click.stop>
           <template v-for="(o, key) in item.operation"
                     :key="key">
-            <el-button v-show="o.type != 'upload'"
+            <el-dropdown v-if="o.type == 'dropdown'"
+                         v-show="o.showHide ? o.showHide(scope.row) : true"
+                         trigger="click"
+                         @command="(command) => o.commandFun(command, scope.row)"
+                         style="margin-left: 12px; margin-right: 12px; vertical-align: middle;">
+              <el-button :disabled="isOperationDisabled(o, scope.row)"
+                         :plain="o.plain"
+                         type="primary"
+                         :style="{
+                  color: getOperationColor(o, scope.row),
+                  fontWeight: 'bold',
+                }"
+                         link>
+                {{ o.name }}<el-icon class="el-icon--right"><ArrowDown /></el-icon>
+              </el-button>
+              <template #dropdown>
+                <el-dropdown-menu>
+                  <el-dropdown-item v-for="(dItem, dIdx) in (typeof o.dropdownItems === 'function' ? o.dropdownItems(scope.row) : o.dropdownItems)"
+                                    :key="dIdx"
+                                    :command="dItem.command"
+                                    :disabled="dItem.disabled ? dItem.disabled(scope.row) : false">
+                    {{ dItem.label }}
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </template>
+            </el-dropdown>
+            <el-button v-show="o.type != 'upload' && o.type != 'dropdown'"
                        v-if="o.showHide ? o.showHide(scope.row) : true"
                        :disabled="isOperationDisabled(o, scope.row)"
                        :plain="o.plain"
@@ -204,6 +230,7 @@
   import pagination from "./Pagination.vue";
   import { computed, ref, inject, getCurrentInstance } from "vue";
   import { ElMessage } from "element-plus";
+  import { ArrowDown } from "@element-plus/icons-vue";
 
   // 鑾峰彇鍏ㄥ眬鐨� uploadHeader
   const { proxy } = getCurrentInstance();
diff --git a/src/views/equipmentManagement/calibration/index.vue b/src/views/equipmentManagement/calibration/index.vue
index b04da2e..0d5b9cf 100644
--- a/src/views/equipmentManagement/calibration/index.vue
+++ b/src/views/equipmentManagement/calibration/index.vue
@@ -50,7 +50,13 @@
 				@selection-change="handleSelectionChange"
 				:tableLoading="tableLoading"
 				@pagination="pagination"
-			></PIMTable>
+			>
+				<template #validUntilSlot="{ row }">
+					<span>{{ row.validUntil ? row.validUntil.split(' ')[0] : '' }}</span>
+					<el-tag v-if="isWarning(row.validUntil)" type="warning" class="ml10">鍗冲皢鍒版湡</el-tag>
+					<el-tag v-else-if="isOverdue(row.validUntil)" type="danger" class="ml10">宸查�炬湡</el-tag>
+				</template>
+			</PIMTable>
 		</div>
 		<calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
 	</div>
@@ -59,6 +65,7 @@
 <script setup>
 import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import {ElMessageBox, ElMessage} from "element-plus";
+import dayjs from "dayjs";
 import useUserStore from "@/store/modules/user.js";
 import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
 import {ledgerRecordListPage, ledgerRecordDelete} from "@/api/equipmentManagement/calibration.js";
@@ -119,9 +126,46 @@
 		width:200
 	},
 	{
-		label: "鏈夋晥鏈�",
+		label: "鏈夋晥鏈�(澶�)",
 		prop: "valid",
 		width: 100,
+	},
+	{
+		label: "鏈夋晥鏈熻嚦",
+		prop: "validUntil",
+		dataType: "slot",
+		slot: "validUntilSlot",
+		width: 160,
+	},
+	{
+		label: "婧簮/鏍告煡绫诲瀷",
+		prop: "traceabilityType",
+		width: 150,
+	},
+	{
+		label: "瀹炴柦鏈烘瀯",
+		prop: "implementingAgency",
+		width: 150,
+	},
+	{
+		label: "璇佷功缂栧彿",
+		prop: "certificateNumber",
+		width: 150,
+	},
+	{
+		label: "鏍稿績缁撴灉",
+		prop: "coreResult",
+		width: 150,
+	},
+	{
+		label: "缁撴灉纭",
+		prop: "resultConfirmation",
+		width: 150,
+	},
+	{
+		label: "纭浜�",
+		prop: "confirmerName",
+		width: 120,
 	},
 	{
 		label: "褰曞叆浜�",
@@ -197,12 +241,27 @@
 const getList = () => {
 	tableLoading.value = true;
 	ledgerRecordListPage({ ...searchForm.value, ...page }).then((res) => {
-		tableLoading.value = false;
 		tableData.value = res.data.records;
 		page.total = res.data.total;
+		tableLoading.value = false;
 	}).catch((err) => {
 		tableLoading.value = false;
-	})
+	});
+};
+
+const isWarning = (validUntil) => {
+	if (!validUntil) return false;
+	const now = dayjs().startOf('day');
+	const until = dayjs(validUntil).startOf('day');
+	const diffDays = until.diff(now, 'day');
+	return diffDays >= 0 && diffDays <= 30;
+};
+
+const isOverdue = (validUntil) => {
+	if (!validUntil) return false;
+	const now = dayjs().startOf('day');
+	const until = dayjs(validUntil).startOf('day');
+	return until.isBefore(now);
 };
 
 // 鎵撳紑妫�瀹氭牎鍑嗗脊妗�
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index f1d21f2..4405f90 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -1,6 +1,24 @@
 <template>
   <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
+    <el-divider content-position="left">鍩虹淇℃伅</el-divider>
     <el-row :gutter="20">
+      <el-col :span="12">
+        <el-form-item label="璁惧缂栧彿" prop="uniqueCode">
+          <div style="display: flex; gap: 10px; width: 100%;">
+            <el-checkbox
+              v-model="form.autoGenerateUniqueCode"
+              v-if="operationType === 'add'"
+              >鑷姩鐢熸垚
+            </el-checkbox>
+            <el-input 
+              v-model="form.uniqueCode" 
+              :placeholder="form.autoGenerateUniqueCode ? '淇濆瓨鍚庤嚜鍔ㄧ敓鎴�' : '璇疯緭鍏ヨ澶囩紪鍙�'" 
+              :disabled="form.autoGenerateUniqueCode || operationType === 'view'" 
+              clearable
+            />
+          </div>
+        </el-form-item>
+      </el-col>
       <el-col :span="12">
         <el-form-item label="璁惧鍚嶇О" prop="deviceName">
           <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
@@ -38,8 +56,8 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="渚涘簲鍟�" prop="supplierName">
-          <el-input v-model="form.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
+        <el-form-item label="鍑哄巶缂栧彿" prop="factoryNumber">
+          <el-input v-model="form.factoryNumber" placeholder="璇疯緭鍏ュ嚭鍘傜紪鍙�" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -48,31 +66,68 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍗曚綅" prop="unit">
-          <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+        <el-form-item label="璐d换浜�" prop="responsiblePerson">
+          <el-input v-model="form.responsiblePerson" placeholder="璇疯緭鍏ヨ矗浠讳汉" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍚敤鎶樻棫" prop="isDepr">
-          <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" />
+        <el-form-item label="寤烘。鏃ユ湡" prop="filingDate">
+          <el-date-picker
+            style="width: 100%"
+            v-model="form.filingDate"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            type="date"
+            placeholder="璇烽�夋嫨寤烘。鏃ユ湡"
+            clearable
+          />
         </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" 
+    </el-row>
+
+    <el-divider content-position="left">閲囪喘淇℃伅</el-divider>
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-form-item label="渚涘簲鍟�" prop="supplierName">
+          <el-input v-model="form.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍒堕�犲巶鍟�" prop="manufacturer">
+          <el-input v-model="form.manufacturer" placeholder="璇疯緭鍏ュ埗閫犲巶鍟�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璐疆鏃ユ湡" prop="purchaseDate">
+          <el-date-picker
             style="width: 100%"
-            v-model="form.annualDepreciationAmount"
-            placeholder="璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�"
+            v-model="form.purchaseDate"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            type="date"
+            placeholder="璇烽�夋嫨璐疆鏃ユ湡"
+            clearable
           />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="璧勪骇鍘熷��" prop="originalAssetValue">
+          <el-input-number :step="0.01" :min="0" style="width: 100%"
+            v-model="form.originalAssetValue"
+            placeholder="璇疯緭鍏ヨ祫浜у師鍊�"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍗曚綅" prop="unit">
+          <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
         <el-form-item label="鏁伴噺" prop="number">
           <el-input-number :min="1" style="width: 100%"
             v-model="form.number"
-													 disabled
+            disabled
             placeholder="璇疯緭鍏ユ暟閲�"
             @change="mathNum"
           />
@@ -125,37 +180,80 @@
           />
         </el-form-item>
       </el-col>
-      <!-- <el-col :span="12">
-        <el-form-item label="褰曞叆浜�" prop="createUser">
-          <el-input v-model="form.createUser" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
+    </el-row>
+
+    <el-divider content-position="left">鎶�鏈弬鏁�</el-divider>
+    <el-row :gutter="20">
+      <el-col :span="24">
+        <el-form-item label="涓昏鎶�鏈弬鏁�" prop="technicalParameters">
+          <el-input type="textarea" :rows="3" v-model="form.technicalParameters" placeholder="璇疯緭鍏ヤ富瑕佹妧鏈弬鏁�" />
         </el-form-item>
-      </el-col> -->
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="涓昏鐢ㄩ��" prop="mainPurpose">
+          <el-input type="textarea" :rows="3" v-model="form.mainPurpose" placeholder="璇疯緭鍏ヤ富瑕佺敤閫�" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-divider content-position="left">杩愯绠$悊</el-divider>
+    <el-row :gutter="20">
       <el-col :span="12">
-        <el-form-item label="褰曞叆鏃ユ湡" prop="createTime">
+        <el-form-item label="璁惧鐘舵��" prop="status">
+          <el-select
+            v-model="form.status"
+            placeholder="璇烽�夋嫨"
+            :disabled="operationType === 'edit'"
+            style="width: 100%"
+          >
+            <el-option label="鍋滅敤" :value="0" />
+            <el-option label="鍚敤" :value="1" />
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍚敤鏃ユ湡" prop="activationDate">
           <el-date-picker
             style="width: 100%"
-            v-model="form.createTime"
+            v-model="form.activationDate"
             format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD HH:mm:ss"
+            value-format="YYYY-MM-DD"
             type="date"
-            placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
+            placeholder="璇烽�夋嫨鍚敤鏃ユ湡"
             clearable
           />
         </el-form-item>
       </el-col>
-			<el-col :span="12">
-				<el-form-item label="棰勮杩愯鏃堕棿" prop="planRuntimeTime">
-					<el-date-picker
-						style="width: 100%"
-						v-model="form.planRuntimeTime"
-						format="YYYY-MM-DD"
-						value-format="YYYY-MM-DD"
-						type="date"
-						placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
-						clearable
-					/>
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item label="棰勮杩愯鏃堕棿" prop="planRuntimeTime">
+          <el-date-picker
+            style="width: 100%"
+            v-model="form.planRuntimeTime"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            type="date"
+            placeholder="璇烽�夋嫨棰勮杩愯鏃堕棿"
+            clearable
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <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="24">
         <el-form-item label="璁惧鍥剧墖" prop="storageBlobDTOs">
           <AttachmentUploadImage
@@ -172,7 +270,6 @@
 
 <script setup>
 import useFormData from "@/hooks/useFormData";
-// import useUserStore from "@/store/modules/user";
 import { getLedgerById } from "@/api/equipmentManagement/ledger";
 import dayjs from "dayjs";
 import {
@@ -190,7 +287,7 @@
   name: "璁惧鍙拌处琛ㄥ崟",
 });
 const formRef = ref(null);
-const operationType = ref('');
+const operationType = ref('add');
 // 璁惧绫诲瀷鍥哄畾閫夐」
 const deviceTypeOptions = ref([
   '鐢熶骇璁惧',
@@ -200,47 +297,77 @@
   '鍏朵粬璁惧'
 ]);
 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" 
-		}
-	],
+  uniqueCode: [
+    { 
+      validator: (rule, value, callback) => {
+        if (!form.autoGenerateUniqueCode && (value === undefined || value === null || value === '')) {
+          callback(new Error('璇疯緭鍏ヨ澶囩紪鍙�'));
+        } else {
+          callback();
+        }
+      }, 
+      trigger: "blur" 
+    }
+  ],
+  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: "璇烽�夋嫨" }],
+  status: [{ 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({
+  // Basic Info
+  autoGenerateUniqueCode: true,
+  uniqueCode: undefined, // 鍞竴鎬х紪鍙�
   deviceName: undefined, // 璁惧鍚嶇О
   deviceModel: undefined, // 瑙勬牸鍨嬪彿
   deviceBrand: undefined, // 璁惧鍝佺墝
   type: undefined, // 璁惧绫诲瀷
-  supplierName: undefined, // 渚涘簲鍟�
+  factoryNumber: undefined, // 鍑哄巶缂栧彿
   storageLocation: undefined, // 瀛樻斁浣嶇疆
-  isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
-  annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
+  responsiblePerson: undefined, // 璐d换浜�
+  filingDate: dayjs().format("YYYY-MM-DD"), // 寤烘。鏃ユ湡
+  
+  // Purchase Info
+  supplierName: undefined, // 渚涘簲鍟�
+  manufacturer: undefined, // 鍒堕�犲巶鍟�
+  purchaseDate: undefined, // 璐疆鏃ユ湡
+  originalAssetValue: undefined, // 璧勪骇鍘熷��
   unit: undefined, // 鍗曚綅
   number: 1, // 鏁伴噺
   taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
   taxIncludingPriceTotal: undefined, // 鍚◣鎬讳环
   taxRate: undefined, // 绋庣巼
   unTaxIncludingPriceTotal: undefined, // 涓嶅惈绋庢�讳环
-  // createUser: useUserStore().nickName, // 褰曞叆浜�
-  createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 褰曞叆鏃ユ湡
-	planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 褰曞叆鏃ユ湡
+  
+  // Technical Specs
+  technicalParameters: undefined, // 涓昏鎶�鏈弬鏁�
+  mainPurpose: undefined, // 涓昏鐢ㄩ��
+  
+  // Operation Info
+  status: 1, // 璁惧鐘舵�� (0鍋滅敤 1鍚敤)
+  activationDate: undefined, // 鍚敤鏃ユ湡
+  planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 棰勮杩愯鏃堕棿
+  isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
+  annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
   storageBlobDTOs: undefined, // 璁惧鍥剧墖鎻愪氦
   storageBlobVOs: undefined, // 璁惧鍥剧墖灞曠ず
 });
@@ -256,26 +383,47 @@
 });
 
 const loadForm = async (id) => {
-	if (id) {
-		operationType.value = 'edit'
-	}
+  if (id) {
+    operationType.value = 'edit';
+  } else {
+    operationType.value = 'add';
+  }
   const { code, data } = await getLedgerById(id);
   if (code == 200) {
+    form.autoGenerateUniqueCode = false;
+    form.uniqueCode = data.uniqueCode;
     form.deviceName = data.deviceName;
     form.deviceModel = data.deviceModel;
     form.deviceBrand = data.deviceBrand;
     form.type = data.type;
-    form.supplierName = data.supplierName;
+    form.factoryNumber = data.factoryNumber;
     form.storageLocation = data.storageLocation;
-    form.isDepr = data.isDepr;
-    form.annualDepreciationAmount = data.annualDepreciationAmount;
+    form.responsiblePerson = data.responsiblePerson;
+    form.filingDate = data.filingDate;
+
+    form.supplierName = data.supplierName;
+    form.manufacturer = data.manufacturer;
+    if (data.purchaseDate) {
+      form.purchaseDate = dayjs(data.purchaseDate).format('YYYY-MM-DD');
+    }
+    form.originalAssetValue = data.originalAssetValue;
     form.unit = data.unit;
     form.number = 1;
     form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
     form.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
     form.taxRate = data.taxRate;
     form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
-    form.createTime = data.createTime;
+
+    form.technicalParameters = data.technicalParameters;
+    form.mainPurpose = data.mainPurpose;
+
+    form.status = data.status != null ? data.status : 1;
+    if (data.activationDate) {
+      form.activationDate = dayjs(data.activationDate).format('YYYY-MM-DD');
+    }
+    form.isDepr = data.isDepr;
+    form.annualDepreciationAmount = data.annualDepreciationAmount;
+    
     // 棰勮杩愯鏃堕棿锛氬悗绔繑鍥炲悗杞负 YYYY-MM-DD 浠ヤ究鏃ユ湡閫夋嫨鍣ㄦ纭睍绀�
     if (data.planRuntimeTime) {
       form.planRuntimeTime = dayjs(data.planRuntimeTime).format('YYYY-MM-DD');
@@ -319,6 +467,7 @@
 // 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
 const resetFormAndValidate = () => {
   resetForm();
+  operationType.value = 'add'; // 閲嶇疆涓烘柊澧�
   clearValidate();
 };
 
@@ -328,6 +477,6 @@
   resetForm,
   clearValidate,
   resetFormAndValidate,
-	formRef,
+  formRef,
 });
 </script>
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index af10532..fbc9869 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -1,6 +1,15 @@
 <template>
   <div class="app-container">
     <el-form :model="filters" :inline="true">
+      <el-form-item label="璁惧缂栧彿">
+        <el-input
+          v-model="filters.uniqueCode"
+          style="width: 200px"
+          placeholder="璇疯緭鍏ヨ澶囩紪鍙�"
+          clearable
+          @change="getTableData"
+        />
+      </el-form-item>
       <el-form-item label="璁惧鍚嶇О">
         <el-input
           v-model="filters.deviceName"
@@ -113,6 +122,7 @@
     <!-- 璇︽儏瀵硅瘽妗� -->
     <el-dialog v-model="detailDialogVisible" title="璁惧鍙拌处璇︽儏" width="60%" draggable>
       <el-descriptions :column="2" border>
+        <el-descriptions-item label="璁惧缂栧彿">{{ detailData.uniqueCode }}</el-descriptions-item>
         <el-descriptions-item label="璁惧鍚嶇О">{{ detailData.deviceName }}</el-descriptions-item>
         <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ detailData.deviceModel }}</el-descriptions-item>
         <el-descriptions-item label="璁惧鍝佺墝">{{ detailData.deviceBrand }}</el-descriptions-item>
@@ -148,13 +158,88 @@
         <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
       </template>
     </el-dialog>
+
+    <!-- 鐘舵�佸彉鏇村璇濇 -->
+    <el-dialog v-model="statusDialog.visible" title="璁惧鐘舵�佸彉鏇寸敵璇�" width="500px" draggable>
+      <el-form label-width="100px">
+        <el-form-item label="褰撳墠鐘舵��">
+          <el-tag :type="statusDialog.row?.status == 1 ? 'success' : 'danger'">
+            {{ statusDialog.row?.status == 1 ? '鍚敤' : '鍋滅敤' }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="鐩爣鐘舵��" required>
+          <el-radio-group v-model="statusDialog.targetStatus">
+            <el-radio :label="1">鍚敤</el-radio>
+            <el-radio :label="0">鍋滅敤</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鍙樻洿鍘熷洜" required>
+          <el-input type="textarea" :rows="3" v-model="statusDialog.reason" placeholder="璇疯緭鍏ョ姸鎬佸彉鏇村師鍥�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="statusDialog.visible = false">鍙栨秷</el-button>
+        <el-button type="primary" :loading="statusDialog.loading" @click="submitStatusChange">鎻愪氦瀹℃壒</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 鐘舵�佸彉鏇磋褰曞璇濇 -->
+    <el-dialog v-model="recordDialog.visible" title="璁惧鐘舵�佸彉鏇磋褰�" width="800px" draggable>
+      <el-table v-loading="recordDialog.loading" :data="recordDialog.list" border>
+        <el-table-column label="鍙樻洿鏃堕棿" prop="createTime" width="160" />
+        <el-table-column label="鍘熺姸鎬�" width="100">
+          <template #default="scope">
+            <el-tag :type="scope.row.originalStatus == 1 ? 'success' : 'danger'">
+              {{ scope.row.originalStatus == 1 ? '鍚敤' : '鍋滅敤' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鐩爣鐘舵��" width="100">
+          <template #default="scope">
+            <el-tag :type="scope.row.targetStatus == 1 ? 'success' : 'danger'">
+              {{ scope.row.targetStatus == 1 ? '鍚敤' : '鍋滅敤' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍙樻洿鍘熷洜" prop="reason" show-overflow-tooltip />
+        <el-table-column label="鐢宠浜�" prop="createUserName" width="100" />
+        <el-table-column label="瀹℃壒鐘舵��" width="100">
+          <template #default="scope">
+            <el-tag v-if="scope.row.approvalStatus === 'PENDING'" type="warning">瀹℃壒涓�</el-tag>
+            <el-tag v-else-if="scope.row.approvalStatus === 'APPROVED'" type="success">宸查�氳繃</el-tag>
+            <el-tag v-else-if="scope.row.approvalStatus === 'REJECTED'" type="danger">宸查┏鍥�</el-tag>
+            <span v-else>{{ scope.row.approvalStatus }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="椹冲洖鍘熷洜" prop="rejectReason" show-overflow-tooltip>
+          <template #default="scope">
+            <span v-if="scope.row.approvalStatus === 'REJECTED'">{{ scope.row.rejectReason || '--' }}</span>
+            <span v-else>--</span>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div style="display: flex; justify-content: flex-end; margin-top: 15px;">
+        <el-pagination
+          v-model:current-page="recordDialog.queryParams.pageNum"
+          v-model:page-size="recordDialog.queryParams.pageSize"
+          :total="recordDialog.total"
+          layout="total, prev, pager, next"
+          @current-change="getRecordList"
+        />
+      </div>
+      <template #footer>
+        <el-button @click="recordDialog.visible = false">鍏抽棴</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
 import { usePaginationApi } from "@/hooks/usePaginationApi";
-// import { Search } from "@element-plus/icons-vue";
 import { getLedgerPage, delLedger, getLedgerById } from "@/api/equipmentManagement/ledger";
+import { listStatusChangeRecord } from "@/api/device/statusChangeRecord";
+import { saveApprovalInstance } from "@/api/officeProcessAutomation/approvalInstance";
+import { listApprovalTemplate, getApprovalTemplateDetail, TEMPLATE_TYPE_CUSTOM } from "@/api/officeProcessAutomation/approvalTemplate";
 import { onMounted, getCurrentInstance, ref, reactive } from "vue";
 import Modal from "./Modal.vue";
 import { ElMessageBox, ElMessage } from "element-plus";
@@ -204,6 +289,7 @@
 } = usePaginationApi(
   getLedgerPage,
   {
+    uniqueCode: undefined,
     deviceName: undefined,
     deviceModel: undefined,
     supplierName: undefined,
@@ -211,6 +297,10 @@
     entryDateEnd: undefined,
   },
   [
+    {
+      label: "璁惧缂栧彿",
+      prop: "uniqueCode",
+    },
     {
       label: "璁惧鍚嶇О",
       prop: "deviceName",
@@ -240,18 +330,34 @@
       prop: "number",
     },
     {
+      label: "璁惧鐘舵��",
+      prop: "status",
+      width: 100,
+      dataType: "tag",
+      formatData: (v) => v == 1 ? '鍚敤' : '鍋滅敤',
+      formatType: (v) => v == 1 ? 'success' : 'danger',
+    },
+    {
+      label: "鍚敤鏃ユ湡",
+      prop: "activationDate",
+      width: 120,
+      formatData: (v) => {
+        if (!v) return '';
+        if (v.includes(' ')) return v.split(' ')[0];
+        return v;
+      },
+    },
+    {
       label: "褰曞叆浜�",
       prop: "createUser",
     },
     {
-      label: "褰曞叆鏃ユ湡",
-      prop: "createTime",
+      label: "寤烘。鏃ユ湡",
+      prop: "filingDate",
+      width: 120,
       formatData: (v) => {
         if (!v) return '';
-        // 濡傛灉鍖呭惈鏃跺垎绉掞紝鍙彇鏃ユ湡閮ㄥ垎
-        if (v.includes(' ')) {
-          return v.split(' ')[0];
-        }
+        if (v.includes(' ')) return v.split(' ')[0];
         return v;
       },
     },
@@ -266,6 +372,18 @@
           name: "璇︽儏",
           clickFun: (row) => {
             handleDetail(row);
+          },
+        },
+        {
+          name: "鐘舵�佸彉鏇�",
+          clickFun: (row) => {
+            openStatusChange(row);
+          },
+        },
+        {
+          name: "鍙樻洿璁板綍",
+          clickFun: (row) => {
+            openRecordDialog(row);
           },
         },
 				{
@@ -303,6 +421,102 @@
     detailDialogVisible.value = true;
   }
 };
+
+const statusDialog = reactive({ visible: false, row: null, targetStatus: 1, reason: '', loading: false });
+
+const openStatusChange = (row) => {
+  statusDialog.row = row;
+  statusDialog.targetStatus = row.status == 1 ? 0 : 1; 
+  statusDialog.reason = '';
+  statusDialog.visible = true;
+};
+
+const submitStatusChange = async () => {
+  if (!statusDialog.reason.trim()) {
+    ElMessage.error("璇峰~鍐欑姸鎬佸彉鏇村師鍥�");
+    return;
+  }
+  if (statusDialog.targetStatus === statusDialog.row.status) {
+    ElMessage.warning("鐩爣鐘舵�佷笌褰撳墠鐘舵�佷竴鑷�");
+    return;
+  }
+  statusDialog.loading = true;
+  try {
+    const listRes = await listApprovalTemplate(TEMPLATE_TYPE_CUSTOM);
+    const templates = listRes.data?.records || listRes.data || [];
+    const tpl = templates.find(t => t.businessType === 19 && (t.enabled === 1 || t.enabled === true));
+    if (!tpl) {
+      ElMessage.error("鏈壘鍒板惎鐢ㄧ殑璁惧鐘舵�佸彉鏇村鎵规ā鏉�");
+      return;
+    }
+    const detailRes = await getApprovalTemplateDetail(tpl.id);
+    const detail = detailRes.data;
+    
+    const payload = {
+      templateId: detail.id,
+      templateName: detail.templateName,
+      businessType: 19,
+      templateSnapshot: JSON.stringify(detail),
+      title: `璁惧鐘舵�佸彉鏇村鎵� - ${statusDialog.row.deviceName}`,
+      reason: statusDialog.reason,
+      businessId: statusDialog.row.id,
+      formConfig: JSON.stringify({
+        targetStatus: statusDialog.targetStatus,
+        targetStatusName: statusDialog.targetStatus == 1 ? '鍚敤' : '鍋滅敤',
+        deviceId: statusDialog.row.id,
+        deviceName: statusDialog.row.deviceName,
+        reason: statusDialog.reason
+      }),
+      flowNodes: detail.flowNodes || []
+    };
+    
+    const res = await saveApprovalInstance(payload);
+    if (res.code === 200) {
+      ElMessage.success("宸插彂璧风姸鎬佸彉鏇村鎵�");
+      statusDialog.visible = false;
+      getTableData();
+    }
+  } catch (error) {
+    console.error(error);
+  } finally {
+    statusDialog.loading = false;
+  }
+};
+
+const recordDialog = reactive({
+  visible: false,
+  loading: false,
+  list: [],
+  total: 0,
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    deviceId: null
+  }
+});
+
+const openRecordDialog = (row) => {
+  recordDialog.queryParams.deviceId = row.id;
+  recordDialog.queryParams.pageNum = 1;
+  recordDialog.visible = true;
+  getRecordList();
+};
+
+const getRecordList = async () => {
+  recordDialog.loading = true;
+  try {
+    const res = await listStatusChangeRecord(recordDialog.queryParams);
+    if (res.code === 200) {
+      recordDialog.list = res.data.records;
+      recordDialog.total = res.data.total;
+    }
+  } catch (error) {
+    console.error(error);
+  } finally {
+    recordDialog.loading = false;
+  }
+};
+
 const changePage = ({ page, limit }) => {
   pagination.currentPage = page;
 	pagination.pageSize = limit;
diff --git a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
index 923dd2c..298ec84 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
@@ -47,6 +47,7 @@
 								type="date"
 								placeholder="璇烽�夋嫨"
 								clearable
+								@change="calculateValidUntil"
 							/>
 						</el-form-item>
 					</el-col>
@@ -67,6 +68,85 @@
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
+						<el-form-item label="鏈夋晥鏈熻嚦锛�" prop="validUntil">
+							<el-input
+								v-model="form.validUntil"
+								placeholder="鑷姩璁$畻"
+								disabled
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="婧簮/鏍告煡绫诲瀷锛�" prop="traceabilityType">
+							<el-input
+								v-model="form.traceabilityType"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="瀹炴柦鏈烘瀯锛�" prop="implementingAgency">
+							<el-input
+								v-model="form.implementingAgency"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="璇佷功缂栧彿锛�" prop="certificateNumber">
+							<el-input
+								v-model="form.certificateNumber"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="鏍稿績缁撴灉锛�" prop="coreResult">
+							<el-input
+								v-model="form.coreResult"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="缁撴灉纭锛�" prop="resultConfirmation">
+							<el-input
+								v-model="form.resultConfirmation"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="纭浜猴細" prop="confirmerId">
+							<el-select
+								v-model="form.confirmerId"
+								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-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
 						<el-form-item label="褰曞叆浜猴細" prop="userId">
 							<el-select
 								v-model="form.userId"
@@ -85,6 +165,8 @@
 							</el-select>
 						</el-form-item>
 					</el-col>
+				</el-row>
+				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
 							<el-date-picker
@@ -128,6 +210,7 @@
 </template>
 
 <script setup>
+import dayjs from "dayjs";
 import {ref, reactive, toRefs, getCurrentInstance} from "vue";
 import useUserStore from "@/store/modules/user.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
@@ -150,7 +233,14 @@
 		recordDate: "",
 		userId: "",
 		entryDate: "",
-    tempFileIds: []
+    tempFileIds: [],
+		traceabilityType: "",
+		implementingAgency: "",
+		certificateNumber: "",
+		coreResult: "",
+		resultConfirmation: "",
+		validUntil: "",
+		confirmerId: ""
 	},
 	rules: {
 		code: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
@@ -211,6 +301,13 @@
 	if (type === "edit") {
 		form.value.valid = row.valid;
 		form.value.recordDate = row.recordDate;
+		form.value.traceabilityType = row.traceabilityType;
+		form.value.implementingAgency = row.implementingAgency;
+		form.value.certificateNumber = row.certificateNumber;
+		form.value.coreResult = row.coreResult;
+		form.value.resultConfirmation = row.resultConfirmation;
+		form.value.validUntil = row.validUntil;
+		form.value.confirmerId = row.confirmerId;
     fileList.value = row.commonFiles;
 	}
 	if(type === "add"){
@@ -219,6 +316,14 @@
 	if(type === "verifying"){
 		form.value.valid = row.valid;
 		form.value.recordDate = row.mostDate;
+		// Initialize empty for new verifying record
+		form.value.traceabilityType = "";
+		form.value.implementingAgency = "";
+		form.value.certificateNumber = "";
+		form.value.coreResult = "";
+		form.value.resultConfirmation = "";
+		form.value.confirmerId = "";
+		calculateValidUntil();
 	}
 
 	form.value.id = row.id;
@@ -232,12 +337,14 @@
 const handleValidInput = (value) => {
 	if (value === '' || value === null || value === undefined) {
 		form.value.valid = '';
+		calculateValidUntil();
 		return;
 	}
 	// 杞崲涓哄瓧绗︿覆骞剁Щ闄ゆ墍鏈夐潪鏁板瓧瀛楃锛堝寘鎷礋鍙枫�佸皬鏁扮偣绛夛級
 	const numStr = String(value).replace(/[^0-9]/g, '');
 	if (numStr === '') {
 		form.value.valid = '';
+		calculateValidUntil();
 		return;
 	}
 	const numValue = parseInt(numStr, 10);
@@ -247,6 +354,16 @@
 	} else {
 		form.value.valid = '';
 	}
+	calculateValidUntil();
+}
+
+// 鑷姩璁$畻鏈夋晥鏈熻嚦
+const calculateValidUntil = () => {
+	if (form.value.recordDate && form.value.valid) {
+		form.value.validUntil = dayjs(form.value.recordDate).add(form.value.valid, 'day').format('YYYY-MM-DD');
+	} else {
+		form.value.validUntil = '';
+	}
 }
 
 const submitForm = () => {
diff --git a/src/views/equipmentManagement/operationManagement/index.vue b/src/views/equipmentManagement/operationManagement/index.vue
index 99c3bd1..f920bd4 100644
--- a/src/views/equipmentManagement/operationManagement/index.vue
+++ b/src/views/equipmentManagement/operationManagement/index.vue
@@ -61,9 +61,9 @@
               :type="getDeviceStatusType(scope.row.status)"
               size="small"
             >
-              <el-icon v-if="scope.row.status === '杩愯涓�'"><VideoPlay /></el-icon>
+              <el-icon v-if="String(scope.row.status) === '1'"><VideoPlay /></el-icon>
               <el-icon v-else><VideoPause /></el-icon>
-              {{ scope.row.status || '鏈煡' }}
+              {{ String(scope.row.status) === '1' ? '杩愯涓�' : '鍋滄杩愯' }}
             </el-tag>
           </template>
         </el-table-column>
@@ -126,7 +126,7 @@
             <!-- 姝e父鐘舵�佹椂鏄剧ず瀵瑰簲鐨勬搷浣滄寜閽� -->
             <template v-else>
               <el-button
-                v-if="scope.row.status === '杩愯涓�'"
+                v-if="String(scope.row.status) === '1'"
                 type="danger"
                 size="small"
                 @click="changeDeviceStatus(scope.row, '鍋滄杩愯')"
@@ -186,9 +186,9 @@
   // 鏍规嵁璁惧鐘舵�佺瓫閫�
   if (deviceFilter.value !== 'all') {
     if (deviceFilter.value === 'start') {
-      filtered = filtered.filter(device => device.status === '杩愯涓�')
+      filtered = filtered.filter(device => String(device.status) === '1')
     } else if (deviceFilter.value === 'stop') {
-      filtered = filtered.filter(device => device.status === '鍋滄杩愯')
+      filtered = filtered.filter(device => String(device.status) === '0')
     }
   }
 
@@ -264,7 +264,7 @@
   }
 
   const statusStr = String(row?.status ?? '').trim()
-  const isRunning = statusStr === '杩愯涓�' || statusStr === '1'
+  const isRunning = statusStr === '1'
   const endRaw = pickEndTime(row)
   const hasEnd = hasMeaningfulEnd(endRaw)
 
@@ -289,7 +289,7 @@
 
 // 妫�鏌ヨ澶囨槸鍚﹁秴鏃舵湭鍚姩
 const isOverdue = (device) => {
-  if (!device.planRuntimeTime || device.status === '杩愯涓�' || device.startRuntimeTime) {
+  if (!device.planRuntimeTime || String(device.status) === '1' || device.startRuntimeTime) {
     return false
   }
   
@@ -330,12 +330,12 @@
     
     // 鏇存柊璁惧鐘舵�佸拰鐩稿叧鏃堕棿瀛楁
     if (status === '鍚姩杩愯') {
-      device.status = '杩愯涓�'
+      device.status = 1
       device.startRuntimeTime = currentTime
       device.endRuntimeTime = null // 娓呯┖缁撴潫鏃堕棿
       device.runtimeDuration = null // 娓呯┖杩愯鏃堕暱
     } else {
-      device.status = '鍋滄杩愯'
+      device.status = 0
       device.endRuntimeTime = currentTime
       // 璁$畻杩愯鏃堕暱
       if (device.startRuntimeTime) {
@@ -370,9 +370,9 @@
 }
 
 const getDeviceStatusType = (status) => {
-  if (status === '杩愯涓�') {
+  if (String(status) === '1') {
     return 'success'
-  } else if (status === '鍋滄杩愯') {
+  } else if (String(status) === '0') {
     return 'danger'
   } else {
     return 'info'
diff --git a/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue b/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue
index 6d61a9f..c8b2a22 100644
--- a/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue
@@ -8,6 +8,14 @@
     @close="handleCancel"
   >
     <el-form :model="form" :rules="rules" label-width="100px">
+      <!-- 閰嶄欢浣跨敤鎯呭喌灞曠ず -->
+      <el-form-item label="閰嶄欢浣跨敤鏄庣粏" v-if="sparePartsDetails.length > 0">
+        <el-table :data="sparePartsDetails" size="small" border style="width: 100%">
+          <el-table-column prop="sparePartName" label="閰嶄欢鍚嶇О" />
+          <el-table-column prop="quantity" label="浣跨敤鏁伴噺" width="100" />
+        </el-table>
+      </el-form-item>
+
       <el-form-item label="楠屾敹浜�" prop="acceptanceName">
         <el-select
           v-model="form.acceptanceName"
@@ -50,7 +58,7 @@
 import { ref, reactive } from "vue";
 import { ElMessage } from "element-plus";
 import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { repairAcceptance } from "@/api/equipmentManagement/repair";
+import { repairAcceptance, getRepairById } from "@/api/equipmentManagement/repair";
 import dayjs from "dayjs";
 
 defineOptions({
@@ -63,6 +71,7 @@
 const loading = ref(false);
 const repairId = ref(null);
 const userList = ref([]);
+const sparePartsDetails = ref([]);
 
 const form = reactive({
   acceptanceName: undefined,
@@ -92,10 +101,16 @@
 const open = async (row) => {
   repairId.value = row.id;
   visible.value = true;
-  // 閲嶇疆琛ㄥ崟
   form.acceptanceName = undefined;
   form.acceptanceTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
   form.acceptanceRemark = undefined;
+  sparePartsDetails.value = [];
+  try {
+    const { data } = await getRepairById(row.id);
+    if (data && data.sparePartsUseListDetails) {
+      sparePartsDetails.value = data.sparePartsUseListDetails;
+    }
+  } catch(e) {}
   await loadUserList();
 };
 
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index b0b09f0..4408c31 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -14,6 +14,12 @@
       <el-form-item label="缁翠慨缁撴灉">
         <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
       </el-form-item>
+      <el-form-item label="鍘熷洜鍒嗘瀽">
+        <el-input v-model="form.reasonAnalysis" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ師鍥犲垎鏋�" />
+      </el-form-item>
+      <el-form-item label="澶勭悊鎺柦">
+        <el-input v-model="form.handlingMeasures" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ鐞嗘帾鏂�" />
+      </el-form-item>
       <el-form-item label="缁翠慨鐘舵��">
         <el-select v-model="form.status">
           <el-option label="寰呮姤淇�" :value="0"></el-option>
@@ -97,6 +103,8 @@
 const { form, resetForm } = useFormData({
   maintenanceName: undefined, // 缁翠慨鍚嶇О
   maintenanceResult: undefined, // 缁翠慨缁撴灉
+  reasonAnalysis: undefined, // 鍘熷洜鍒嗘瀽
+  handlingMeasures: undefined, // 澶勭悊鎺柦
   maintenanceTime: undefined, // 缁翠慨鏃ユ湡
   status: 0,
   sparePartsIds: [],
@@ -114,6 +122,8 @@
 const setForm = (data) => {
   form.maintenanceName = data.maintenanceName ?? userStore.nickName;
   form.maintenanceResult = data.maintenanceResult;
+  form.reasonAnalysis = data.reasonAnalysis;
+  form.handlingMeasures = data.handlingMeasures;
   form.maintenanceTime =
     data.maintenanceTime 
       ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss")
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index 4a10071..6a934c9 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -58,6 +58,18 @@
       </el-row>
       <el-row>
         <el-col :span="12">
+          <el-form-item label="鎶ヤ慨绫诲瀷">
+            <el-select v-model="form.repairType"
+                       placeholder="璇烽�夋嫨鎶ヤ慨绫诲瀷"
+                       :disabled="operationType === 'view'">
+              <el-option v-for="dict in device_repair_type"
+                         :key="dict.value"
+                         :label="dict.label"
+                         :value="Number(dict.value)"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
           <el-form-item label="缁翠慨浜�">
             <el-input v-model="form.maintenanceName"
                       placeholder="璇疯緭鍏ョ淮淇汉濮撳悕"
@@ -76,7 +88,26 @@
                          :value="1"></el-option>
               <el-option label="澶辫触"
                          :value="2"></el-option>
+              <el-option label="寰呴獙鏀�"
+                         :value="3"></el-option>
             </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="form.status !== 0">
+          <el-form-item label="缁翠慨鏃堕棿">
+            <el-input v-model="form.maintenanceTime"
+                      disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="form.status !== 0">
+        <el-col :span="24">
+          <el-form-item label="缁翠慨缁撴灉">
+            <el-input v-model="form.maintenanceResult"
+                      :rows="2"
+                      type="textarea"
+                      placeholder="鏆傛棤缁翠慨缁撴灉"
+                      :disabled="operationType === 'view'" />
           </el-form-item>
         </el-col>
       </el-row>
@@ -114,6 +145,37 @@
           </el-form-item>
         </el-col>
       </el-row>
+      <el-row v-if="form.status !== 0">
+        <el-col :span="24">
+          <el-form-item label="鍘熷洜鍒嗘瀽">
+            <el-input v-model="form.reasonAnalysis"
+                      :rows="2"
+                      type="textarea"
+                      placeholder="璇疯緭鍏ュ師鍥犲垎鏋�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="澶勭悊鎺柦">
+            <el-input v-model="form.handlingMeasures"
+                      :rows="2"
+                      type="textarea"
+                      placeholder="璇疯緭鍏ュ鐞嗘帾鏂�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <!-- 閰嶄欢浣跨敤鏄庣粏灞曠ず -->
+      <el-row v-if="sparePartsDetails.length > 0">
+        <el-col :span="24">
+          <el-form-item label="閰嶄欢浣跨敤鏄庣粏">
+            <el-table :data="sparePartsDetails" size="small" border style="width: 100%">
+              <el-table-column prop="sparePartName" label="閰嶄欢鍚嶇О" />
+              <el-table-column prop="quantity" label="浣跨敤鏁伴噺" width="100" />
+            </el-table>
+          </el-form-item>
+        </el-col>
+      </el-row>
       <el-row v-if="operationType !== 'view'"
               :gutter="30">
         <el-col :span="24">
@@ -147,6 +209,8 @@
   });
 
   const emits = defineEmits(["ok"]);
+  const { proxy } = getCurrentInstance();
+  const { device_repair_type } = proxy.useDict("device_repair_type");
 
   const id = ref();
   const visible = ref(false);
@@ -163,6 +227,7 @@
   const userStore = useUserStore();
   const deviceOptions = ref([]);
   const fileList = ref([]);
+  const sparePartsDetails = ref([]);
 
   const loadDeviceName = async () => {
     const { data } = await getDeviceLedger();
@@ -174,12 +239,17 @@
     deviceName: undefined, // 璁惧鍚嶇О
     deviceModel: undefined, // 瑙勬牸鍨嬪彿
     repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
+    repairType: undefined, // 鎶ヤ慨绫诲瀷
     repairName: userStore.nickName, // 鎶ヤ慨浜�
     remark: undefined, // 鏁呴殰鐜拌薄
+    reasonAnalysis: undefined, // 鍘熷洜鍒嗘瀽
+    handlingMeasures: undefined, // 澶勭悊鎺柦
     status: 0, // 鎶ヤ慨鐘舵��
     machineryCategory: undefined,
     storageBlobDTOs: [],
     maintenanceName: undefined, // 缁翠慨浜�
+    maintenanceTime: undefined,
+    maintenanceResult: undefined,
   });
 
   const setDeviceModel = deviceId => {
@@ -192,15 +262,21 @@
     form.deviceName = data.deviceName;
     form.deviceModel = data.deviceModel;
     form.repairTime = data.repairTime;
+    form.repairType = data.repairType;
     form.repairName = data.repairName;
     form.remark = data.remark;
+    form.reasonAnalysis = data.reasonAnalysis;
+    form.handlingMeasures = data.handlingMeasures;
     form.status = data.status;
     form.machineryCategory = data.machineryCategory;
     form.storageBlobDTOs = data.storageBlobVOs || [];
     form.maintenanceName = data.maintenanceName;
+    form.maintenanceTime = data.maintenanceTime;
+    form.maintenanceResult = data.maintenanceResult;
     form.acceptanceName = data.acceptanceName;
     form.acceptanceTime = data.acceptanceTime;
     form.acceptanceRemark = data.acceptanceRemark;
+    sparePartsDetails.value = data.sparePartsUseListDetails || [];
   };
 
   const sendForm = async () => {
@@ -234,6 +310,7 @@
     operationType.value = "add";
     visible.value = true;
     fileList.value = [];
+    sparePartsDetails.value = [];
     await nextTick();
     await loadDeviceName();
   };
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index f1573cb..b93d750 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -96,6 +96,9 @@
           <el-tag v-if="row.status === 0"
                   type="warning">寰呯淮淇�</el-tag>
         </template>
+        <template #repairTypeRef="{ row }">
+          <dict-tag :options="device_repair_type" :value="row.repairType" />
+        </template>
         <template #operation="{ row }">
           <el-button type="primary"
                      link
@@ -171,6 +174,7 @@
   });
 
   const { proxy } = getCurrentInstance();
+  const { device_repair_type } = proxy.useDict("device_repair_type");
 
   // 妯℃�佹瀹炰緥
   const repairModalRef = ref();
@@ -222,6 +226,13 @@
         prop: "repairName",
       },
       {
+        label: "鎶ヤ慨绫诲瀷",
+        align: "center",
+        prop: "repairType",
+        dataType: "slot",
+        slot: "repairTypeRef",
+      },
+      {
         label: "鐘舵��",
         align: "center",
         prop: "status",
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
index 0fcccb2..5619d67 100644
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -35,6 +35,11 @@
                   placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
                   type="text" />
       </el-form-item>
+      <el-form-item label="杩愯鐘跺喌">
+        <el-input v-model="form.runningStatus"
+                  placeholder="璇疯緭鍏ヨ繍琛岀姸鍐�"
+                  type="text" />
+      </el-form-item>
       <el-form-item label="璁惧澶囦欢">
         <el-select v-model="form.sparePartsIds"
                    :loading="loadingSparePartOptions"
@@ -104,6 +109,7 @@
     maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
     maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
     maintenanceResult: undefined, // 淇濆吇缁撴灉
+    runningStatus: undefined, // 杩愯鐘跺喌
     status: 0, // 淇濆吇鐘舵��
     sparePartsIds: [],
     storageBlobDTOs: [],
@@ -126,6 +132,7 @@
       ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
       : dayjs().format("YYYY-MM-DD HH:mm:ss");
     form.maintenanceResult = data.maintenanceResult;
+    form.runningStatus = data.runningStatus;
     form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
     // multiple 閫夋嫨鍣ㄨ姹傛暟缁勶紱鍚庣甯歌繑鍥� "1,2,3"
     if (Array.isArray(data?.sparePartsIds)) {
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
index 8a9cd98..f4608fd 100644
--- a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -57,9 +57,30 @@
       </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="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="淇濆吇绫诲瀷" prop="maintenanceType">
+        <el-select v-model="form.maintenanceType" placeholder="璇烽�夋嫨淇濆吇绫诲瀷" clearable>
+          <el-option label="鏃ュ父浣跨敤" value="1"/>
+          <el-option label="瀹氭湡淇濆吇" value="2"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鎵ц浜�" prop="executorId">
+        <el-select
+          v-model="form.executorId"
+          filterable
+          placeholder="璇烽�夋嫨鎵ц浜�"
+          clearable
+        >
+          <el-option
+            v-for="item in userList"
+            :label="item.nickName"
+            :value="item.userId"
+            :key="item.userId"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="淇濆吇浜�">
@@ -132,6 +153,8 @@
   machineryCategory: undefined,
   storageBlobDTOs: [],
   maintenancePerson: undefined, // 淇濆吇浜�
+  maintenanceType: undefined,
+  executorId: undefined
 });
 
 const setDeviceModel = (deviceId) => {
@@ -151,6 +174,8 @@
   form.status = data.status;
   form.machineryCategory = data.machineryCategory;
   form.maintenancePerson = data.maintenancePerson;
+  form.maintenanceType = data.maintenanceType;
+  form.executorId = data.executorId;
   if (data.maintenancePlanTime) {
     form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
       "YYYY-MM-DD HH:mm:ss"
diff --git a/src/views/equipmentManagement/upkeep/Form/formDia.vue b/src/views/equipmentManagement/upkeep/Form/formDia.vue
index 6856ae1..08c0a83 100644
--- a/src/views/equipmentManagement/upkeep/Form/formDia.vue
+++ b/src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -70,7 +70,7 @@
 					<el-form-item label="淇濆吇椤圭洰" prop="machineryCategory">
 						<el-input
 							v-model.trim="form.machineryCategory"
-							placeholder="璇疯緭鍏ヤ繚鍏婚」鐩�"
+							placeholder="璇疯緭鍏ュ伐浣滃唴瀹规弿杩�(淇濆吇椤圭洰)"
 							maxlength="100"
 							clearable
 						/>
@@ -84,6 +84,33 @@
 							maxlength="100"
 							clearable
 						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="淇濆吇绫诲瀷" prop="maintenanceType">
+						<el-select v-model="form.maintenanceType" placeholder="璇烽�夋嫨淇濆吇绫诲瀷" clearable>
+							<el-option label="鏃ュ父浣跨敤" value="1"/>
+							<el-option label="瀹氭湡淇濆吇" value="2"/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="鎵ц浜�" prop="executorId">
+						<el-select
+							v-model="form.executorId"
+							filterable
+							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-row>
@@ -184,13 +211,17 @@
 		time: '',
 		deviceModel: undefined, // 瑙勬牸鍨嬪彿
 		registrationDate: '',
-		maintenancePerson: '' // 淇濆吇浜�
+		maintenancePerson: '', // 淇濆吇浜�
+		maintenanceType: undefined,
+		executorId: undefined
 	},
 	rules: {
 		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
 		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
 		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }],
-		machineryCategory: [{ required: true, message: "璇疯緭鍏ヤ繚鍏婚」鐩�", trigger: "blur" }]
+		machineryCategory: [{ required: true, message: "璇疯緭鍏ヤ繚鍏婚」鐩�", trigger: "blur" }],
+		maintenanceType: [{ required: true, message: "璇烽�夋嫨淇濆吇绫诲瀷", trigger: "change" }],
+		executorId: [{ required: true, message: "璇烽�夋嫨鎵ц浜�", trigger: "change" }]
 	}
 })
 const { form, rules } = toRefs(data)
@@ -271,7 +302,9 @@
 		time: '',
 		deviceModel: undefined,
 		registrationDate: '',
-		maintenancePerson: ''
+		maintenancePerson: '',
+		maintenanceType: undefined,
+		executorId: undefined
 	}
 }
 
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 245a162..4e629a1 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -241,6 +241,7 @@
     deviceMaintenanceTaskList,
     deviceMaintenanceTaskDel,
   } from "@/api/equipmentManagement/upkeep";
+  import { userListNoPageByTenantId } from "@/api/system/user.js";
   import dayjs from "dayjs";
 
   const { proxy } = getCurrentInstance();
@@ -261,6 +262,13 @@
   const fileListDialogRef = ref(null);
   const fileDialogVisible = ref(false);
   const currentMaintenanceTaskId = ref(null);
+
+  const userList = ref([]);
+  const getUserName = (userId) => {
+    if (!userId) return "--";
+    const user = userList.value.find(u => String(u.userId) === String(userId));
+    return user ? user.nickName : userId;
+  };
 
   // 淇濆吇璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
   const filters = reactive({
@@ -304,6 +312,18 @@
       prop: "machineryCategory",
       minWidth: 120,
       formatData: cell => cell || "--",
+    },
+    {
+      label: "淇濆吇绫诲瀷",
+      prop: "maintenanceType",
+      minWidth: 100,
+      formatData: cell => (cell === "1" ? "鏃ュ父浣跨敤" : cell === "2" ? "瀹氭湡淇濆吇" : "--")
+    },
+    { 
+      prop: "executorId", 
+      label: "鎵ц浜�", 
+      minWidth: 100,
+      formatData: cell => getUserName(cell)
     },
     {
       prop: "frequencyType",
@@ -391,6 +411,18 @@
       align: "center",
       prop: "machineryCategory",
       formatData: cell => cell || "--",
+    },
+    {
+      label: "淇濆吇绫诲瀷",
+      align: "center",
+      prop: "maintenanceType",
+      formatData: cell => (cell === "1" ? "鏃ュ父浣跨敤" : cell === "2" ? "瀹氭湡淇濆吇" : "--")
+    },
+    {
+      label: "鎵ц浜�",
+      align: "center",
+      prop: "executorId",
+      formatData: cell => getUserName(cell)
     },
     // {
     //   label: "褰曞叆鏃ユ湡",
@@ -628,7 +660,9 @@
     fileDialogVisible.value = true;
   };
 
-  onMounted(() => {
+  onMounted(async () => {
+    const { data } = await userListNoPageByTenantId();
+    userList.value = data || [];
     // 鏍规嵁榛樿婵�娲荤殑 Tab 璋冪敤瀵瑰簲鐨勬煡璇㈡帴鍙�
     if (activeTab.value === "scheduled") {
       getScheduledTableData();
diff --git a/src/views/inventoryManagement/fuelCardManagement/index.vue b/src/views/inventoryManagement/fuelCardManagement/index.vue
new file mode 100644
index 0000000..f6a6d30
--- /dev/null
+++ b/src/views/inventoryManagement/fuelCardManagement/index.vue
@@ -0,0 +1,430 @@
+<template>
+  <div class="app-container">
+
+
+    <!-- 鏌ヨ鏉′欢 -->
+    <div class="search_form">
+      <div style="flex: 1; padding-right: 20px;">
+        <el-row :gutter="16">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补鍗″彿锛�</span>
+            <el-input v-model="queryParams.cardNumber" placeholder="璇疯緭鍏ュ姞娌瑰崱鍙�" clearable style="flex: 1;" @keyup.enter.native="handleQuery" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鎵�灞為儴闂細</span>
+            <el-tree-select v-model="queryParams.deptId" :data="deptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="璇烽�夋嫨閮ㄩ棬" check-strictly clearable filterable style="flex: 1;" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+            <el-button @click="resetQuery">閲嶇疆</el-button>
+          </el-col>
+        </el-row>
+      </div>
+      <div>
+        <el-button type="primary" icon="Plus" @click="handleAdd">鏂板鍔犳补鍗�</el-button>
+      </div>
+    </div>
+    <!-- 琛ㄦ牸 -->
+    <div class="table_list">
+      <el-table
+        v-loading="loading"
+        :data="tableData"
+        border
+        style="width: 100%"
+        height="calc(100vh - 22em)"
+        :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+      >
+        <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+        <el-table-column prop="cardNumber" label="鍔犳补鍗″彿" min-width="150" />
+        <el-table-column prop="deptName" label="鎵�灞為儴闂�" min-width="150" show-overflow-tooltip />
+        <el-table-column prop="issuer" label="鍙戝崱鍗曚綅" min-width="120" />
+        <el-table-column prop="initialBalance" label="鏈熷垵浣欓" min-width="100" align="right" />
+        <el-table-column prop="currentBalance" label="褰撳墠浣欓" min-width="100" align="right" />
+        <el-table-column prop="status" label="鐘舵��" min-width="100" align="center">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'ACTIVE' ? 'success' : 'danger'">
+              {{ scope.row.status === 'ACTIVE' ? '姝e父' : '娉ㄩ攢' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="澶囨敞" min-width="150" show-overflow-tooltip />
+        <el-table-column label="鎿嶄綔" fixed="right" width="200" align="center">
+          <template #default="scope">
+            <el-button type="success" link size="small" @click="handleRecharge(scope.row)">鍏呭�肩鐞�</el-button>
+            <el-button type="primary" link size="small" @click="handleUpdate(scope.row)">缂栬緫</el-button>
+            <el-button v-if="scope.row.status !== 'CANCELLED'" type="warning" link size="small" @click="handleCancel(scope.row)">娉ㄩ攢</el-button>
+            <el-button type="danger" link size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.current"
+        v-model:limit="queryParams.size"
+        @pagination="getList"
+      />
+    </div>
+<!-- 鏂板/缂栬緫寮圭獥 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="鍔犳补鍗″彿" prop="cardNumber">
+          <el-input v-model="form.cardNumber" placeholder="璇疯緭鍏ュ姞娌瑰崱鍙�" />
+        </el-form-item>
+        <el-form-item label="鎵�灞為儴闂�" prop="deptId">
+          <el-tree-select
+            v-model="form.deptId"
+            :data="deptOptions"
+            :props="{ value: 'id', label: 'label', children: 'children' }"
+            value-key="id"
+            placeholder="璇烽�夋嫨閮ㄩ棬"
+            check-strictly
+            clearable
+            filterable
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="鍙戝崱鍗曚綅" prop="issuer">
+          <el-input v-model="form.issuer" placeholder="璇疯緭鍏ュ彂鍗″崟浣�" />
+        </el-form-item>
+        <el-form-item label="鏈熷垵浣欓" prop="initialBalance" v-if="!form.id">
+          <el-input-number v-model="form.initialBalance" :precision="2" :min="0" :step="100" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio label="ACTIVE">姝e父</el-radio>
+            <el-radio label="CANCELLED">娉ㄩ攢</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鍏呭�肩鐞嗘娊灞� -->
+    <el-drawer v-model="rechargeDrawer.visible" :title="'鍏呭�肩鐞� - ' + rechargeDrawer.cardNumber" size="50%">
+      <div style="padding: 0 20px;">
+        <el-row style="margin-bottom: 15px;">
+          <el-button type="primary" icon="Plus" @click="handleAddRecharge">鏂板鍏呭��</el-button>
+        </el-row>
+        <el-table v-loading="rechargeDrawer.loading" :data="rechargeDrawer.list" border>
+          <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+          <el-table-column prop="rechargeDate" label="鍏呭�兼椂闂�" width="160" />
+          <el-table-column prop="rechargeAmount" label="鍏呭�奸噾棰�(鍏�)" width="120" align="right">
+            <template #default="scope">
+              <span style="color: #67C23A; font-weight: bold;">+{{ scope.row.rechargeAmount }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="createUserName" label="鎿嶄綔浜�" width="100" />
+          <el-table-column prop="remark" label="澶囨敞" min-width="150" show-overflow-tooltip />
+          <el-table-column label="鎿嶄綔" width="100" align="center">
+            <template #default="scope">
+              <el-button type="danger" link size="small" @click="handleDeleteRecharge(scope.row)">鍒犻櫎</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          v-show="rechargeDrawer.total > 0"
+          :total="rechargeDrawer.total"
+          v-model:page="rechargeDrawer.queryParams.current"
+          v-model:limit="rechargeDrawer.queryParams.size"
+          @pagination="getRechargeList"
+        />
+      </div>
+    </el-drawer>
+
+    <!-- 鏂板鍏呭�煎脊绐� -->
+    <el-dialog :title="rechargeDialog.title" v-model="rechargeDialog.visible" width="500px" append-to-body>
+      <el-form ref="rechargeFormRef" :model="rechargeDialog.form" :rules="rechargeDialog.rules" label-width="100px">
+        <el-form-item label="鍏呭�奸噾棰�" prop="rechargeAmount">
+          <el-input-number v-model="rechargeDialog.form.rechargeAmount" :min="0.01" :precision="2" :step="100" style="width: 100%;" placeholder="璇疯緭鍏ュ厖鍊奸噾棰�" />
+        </el-form-item>
+        <el-form-item label="鍏呭�兼棩鏈�" prop="rechargeDate">
+          <el-date-picker v-model="rechargeDialog.form.rechargeDate" type="datetime" placeholder="閫夋嫨鍏呭�兼椂闂�" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="rechargeDialog.form.remark" type="textarea" placeholder="璇疯緭鍏ュ娉ㄥ唴瀹�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitRechargeForm">纭� 瀹�</el-button>
+          <el-button @click="rechargeDialog.visible = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { listFuelCardPage, addFuelCard, updateFuelCard, delFuelCard } from '@/api/inventoryManagement/vehicle';
+import request from '@/utils/request';
+
+import { listAllFuelCard, listRecharge, addRecharge, delRecharge } from '@/api/inventoryManagement/vehicle';
+const statTotal = ref(0);
+const statActive = ref(0);
+const statCancelled = ref(0);
+const statBalance = ref(0);
+
+function getStats() {
+  listAllFuelCard().then(res => {
+    const arr = res.data || [];
+    statTotal.value = arr.length;
+    statActive.value = arr.filter(i => i.status === 'ACTIVE').length;
+    statCancelled.value = arr.filter(i => i.status === 'CANCELLED').length;
+    statBalance.value = arr.reduce((sum, item) => sum + (item.currentBalance || 0), 0);
+  });
+}
+
+
+const loading = ref(true);
+const tableData = ref([]);
+const total = ref(0);
+const open = ref(false);
+const title = ref("");
+const formRef = ref(null);
+
+const deptOptions = ref([]);
+
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  cardNumber: undefined,
+  deptId: undefined
+});
+
+const form = reactive({
+  id: undefined,
+  cardNumber: undefined,
+  deptId: undefined,
+  issuer: undefined,
+  initialBalance: 0,
+  status: 'ACTIVE',
+  remark: undefined
+});
+
+const rules = {
+  cardNumber: [{ required: true, message: "鍔犳补鍗″彿涓嶈兘涓虹┖", trigger: "blur" }],
+  deptId: [{ required: true, message: "鎵�灞為儴闂ㄤ笉鑳戒负绌�", trigger: "change" }],
+  issuer: [{ required: true, message: "鍙戝崱鍗曚綅涓嶈兘涓虹┖", trigger: "blur" }]
+};
+
+function getDicts() {
+  request({url: '/system/user/deptTree', method: 'get'}).then(res => {
+    deptOptions.value = res.data || [];
+  });
+}
+
+function getList() {
+  loading.value = true;
+  listFuelCardPage(queryParams).then(response => {
+    tableData.value = response.data.records;
+    total.value = response.data.total;
+    loading.value = false;
+  }).catch(() => {
+    loading.value = false;
+  });
+}
+
+function handleQuery() {
+  queryParams.current = 1;
+  getList();
+  getStats();
+}
+
+function resetQuery() {
+  queryParams.cardNumber = undefined;
+  queryParams.deptId = undefined;
+  handleQuery();
+}
+
+function reset() {
+  Object.assign(form, {
+    id: undefined,
+    cardNumber: undefined,
+    deptId: undefined,
+    issuer: undefined,
+    initialBalance: 0,
+    status: 'ACTIVE',
+    remark: undefined
+  });
+  if (formRef.value) formRef.value.resetFields();
+}
+
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "鏂板鍔犳补鍗�";
+}
+
+function handleUpdate(row) {
+  reset();
+  Object.assign(form, row);
+  open.value = true;
+  title.value = "淇敼鍔犳补鍗�";
+}
+
+function submitForm() {
+  formRef.value.validate(valid => {
+    if (valid) {
+      if (form.id != null) {
+        updateFuelCard(form).then(response => {
+          ElMessage.success("淇敼鎴愬姛");
+          open.value = false;
+          getList();
+  getStats();
+        });
+      } else {
+        addFuelCard(form).then(response => {
+          ElMessage.success("鏂板鎴愬姛");
+          open.value = false;
+          getList();
+  getStats();
+        });
+      }
+    }
+  });
+}
+
+function handleCancel(row) {
+  ElMessageBox.confirm('鏄惁纭娉ㄩ攢鍔犳补鍗″彿涓�"' + row.cardNumber + '"鐨勫崱鐗囷紵娉ㄩ攢鍚庤鍗′笉鑳界敤浜庢柊澧炲姞娌硅褰曪紝浣嗕綑棰濆皢淇濈暀銆�', "鎻愮ず", {
+    confirmButtonText: "纭畾娉ㄩ攢",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(function() {
+    return updateFuelCard({ id: row.id, status: 'CANCELLED' });
+  }).then(() => {
+    getList();
+  getStats();
+    ElMessage.success("娉ㄩ攢鎴愬姛");
+  });
+}
+
+function handleDelete(row) {
+  ElMessageBox.confirm('鏄惁纭鍒犻櫎鍔犳补鍗″彿涓�"' + row.cardNumber + '"鐨勬暟鎹」锛�', "璀﹀憡", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(function() {
+    return delFuelCard(row.id);
+  }).then(() => {
+    getList();
+  getStats();
+    ElMessage.success("鍒犻櫎鎴愬姛");
+  });
+}
+
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+onMounted(() => {
+  getDicts();
+  getList();
+  getStats();
+});
+
+// --- 鍏呭�肩鐞嗛�昏緫 ---
+const rechargeDrawer = reactive({
+  visible: false,
+  loading: false,
+  cardNumber: '',
+  cardId: null,
+  list: [],
+  total: 0,
+  queryParams: {
+    current: 1,
+    size: 10,
+    cardId: null
+  }
+});
+
+const rechargeDialog = reactive({
+  visible: false,
+  title: '鏂板鍏呭��',
+  form: {
+    cardId: null,
+    rechargeAmount: null,
+    rechargeDate: '',
+    remark: ''
+  },
+  rules: {
+    rechargeAmount: [{ required: true, message: '璇疯緭鍏ュ厖鍊奸噾棰�', trigger: 'blur' }],
+    rechargeDate: [{ required: true, message: '璇烽�夋嫨鍏呭�兼棩鏈�', trigger: 'change' }]
+  }
+});
+
+const rechargeFormRef = ref(null);
+
+function handleRecharge(row) {
+  rechargeDrawer.cardId = row.id;
+  rechargeDrawer.cardNumber = row.cardNumber;
+  rechargeDrawer.queryParams.cardId = row.id;
+  rechargeDrawer.visible = true;
+  getRechargeList();
+}
+
+function getRechargeList() {
+  rechargeDrawer.loading = true;
+  listRecharge(rechargeDrawer.queryParams).then(res => {
+    rechargeDrawer.list = res.data.records;
+    rechargeDrawer.total = res.data.total;
+    rechargeDrawer.loading = false;
+  }).catch(() => {
+    rechargeDrawer.loading = false;
+  });
+}
+
+function handleAddRecharge() {
+  rechargeDialog.form = {
+    cardId: rechargeDrawer.cardId,
+    rechargeAmount: undefined,
+    rechargeDate: new Date().toISOString().slice(0,19).replace('T', ' '),
+    remark: ''
+  };
+  rechargeDialog.visible = true;
+  if (rechargeFormRef.value) {
+    rechargeFormRef.value.clearValidate();
+  }
+}
+
+function submitRechargeForm() {
+  rechargeFormRef.value.validate(valid => {
+    if (valid) {
+      addRecharge(rechargeDialog.form).then(res => {
+        ElMessage.success('鍏呭�兼垚鍔�');
+        rechargeDialog.visible = false;
+        getRechargeList();
+        getList(); // 鏇存柊涓诲垪琛ㄩ噾棰�
+        getStats();
+      });
+    }
+  });
+}
+
+function handleDeleteRecharge(row) {
+  ElMessageBox.confirm('纭鍒犻櫎璇ョ瑪鍏呭�艰褰曞悧锛燂紙鍒犻櫎鍚庝綑棰濆皢鑷姩鎵e洖锛�', '鎻愮ず', { type: 'warning' }).then(() => {
+    return delRecharge(row.id);
+  }).then(() => {
+    ElMessage.success('鍒犻櫎鎴愬姛');
+    getRechargeList();
+    getList();
+    getStats();
+  });
+}
+// --- 鍏呭�肩鐞嗛�昏緫缁撴潫 ---
+
+</script>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index 2bba7d0..45bffc1 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -22,8 +22,8 @@
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <!-- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button> -->
       </div>
-    </div>
-    <div class="table_list">
+    </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)">
diff --git a/src/views/inventoryManagement/vehicleFuelManagement/index.vue b/src/views/inventoryManagement/vehicleFuelManagement/index.vue
index eaf543c..8ce40c3 100644
--- a/src/views/inventoryManagement/vehicleFuelManagement/index.vue
+++ b/src/views/inventoryManagement/vehicleFuelManagement/index.vue
@@ -1,281 +1,179 @@
 <template>
   <div class="app-container">
+
+
     <!-- 鏌ヨ鏉′欢 -->
-    <div class="search_form">
-      <div>
-        <span class="search_title">杞﹁締缂栧彿锛�</span>
-        <el-input
-          v-model="searchForm.vehicleCode"
-          style="width: 200px"
-          placeholder="璇疯緭鍏ヨ溅杈嗙紪鍙�"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-
-        <span class="search_title ml10">鍔犳补鏃堕棿锛�</span>
-        <el-date-picker
-          v-model="searchForm.dateRange"
-          type="daterange"
-          range-separator="鑷�"
-          start-placeholder="寮�濮嬫棩鏈�"
-          end-placeholder="缁撴潫鏃ユ湡"
-          value-format="YYYY-MM-DD"
-          format="YYYY-MM-DD"
-          clearable
-          @change="handleQuery"
-        />
-
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
-          鎼滅储
-        </el-button>
-        <el-button @click="resetSearch">閲嶇疆</el-button>
+        <div class="search_form">
+      <div style="flex: 1; padding-right: 20px;">
+        <el-row :gutter="16" style="margin-bottom: 16px;">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鎵�灞為儴闂細</span>
+            <el-tree-select v-model="queryParams.deptId" :data="deptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="璇烽�夋嫨閮ㄩ棬" check-strictly clearable filterable style="flex: 1;" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补杞﹁締锛�</span>
+            <el-select v-model="queryParams.vehicleId" placeholder="鎸夎溅杈嗙瓫閫�" clearable filterable style="flex: 1;">
+              <el-option v-for="item in vehicleList" :key="item.id" :label="item.plateNumber" :value="item.id" />
+            </el-select>
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补鍗★細</span>
+            <el-select v-model="queryParams.fuelCardId" placeholder="璇烽�夋嫨鍔犳补鍗�" clearable style="flex: 1;">
+              <el-option v-for="item in fuelCardList" :key="item.id" :label="item.cardNumber + ' - ' + item.issuer" :value="item.id" />
+            </el-select>
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鐘舵�侊細</span>
+            <el-select v-model="queryParams.status" placeholder="鐘舵�佺瓫閫�" clearable style="flex: 1;">
+              <el-option label="鑽夌" value="0" />
+              <el-option label="宸叉彁浜�" value="1" />
+            </el-select>
+          </el-col>
+        </el-row>
+        <el-row :gutter="16">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补鏃堕棿锛�</span>
+            <el-date-picker v-model="dateRange" type="daterange" range-separator="鑷�" start-placeholder="寮�濮�" end-placeholder="缁撴潫" value-format="YYYY-MM-DD" clearable style="flex: 1; width: 100%;" />
+          </el-col>
+          <el-col :span="18" style="display: flex; align-items: center;">
+            <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+            <el-button @click="resetQuery">閲嶇疆</el-button>
+          </el-col>
+        </el-row>
       </div>
-      <div>
-        <el-button type="primary" icon="Plus" @click="openAdd">
-          鏂板鍔犳补璁板綍
-        </el-button>
+      <div style="display: flex; align-items: flex-start; height: 100%;">
+        <el-button type="primary" icon="Plus" @click="handleAdd">鏂板鍔犳补璁板綍</el-button>
       </div>
     </div>
-
     <!-- 琛ㄦ牸 -->
     <div class="table_list">
       <el-table
+        v-loading="loading"
         :data="tableData"
         border
         style="width: 100%"
-        height="calc(100vh - 18.5em)"
+        height="calc(100vh - 22em)"
         :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
-        :row-class-name="tableRowClassName"
       >
         <el-table-column type="index" label="搴忓彿" width="60" align="center" />
-        <el-table-column
-          prop="vehicleCode"
-          label="杞﹁締缂栧彿"
-          width="130"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="plateNumber"
-          label="杞︾墝鍙风爜"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="fuelDate"
-          label="鍔犳补鏃ユ湡"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="gunNo"
-          label="娌规灙鍙�"
-          width="90"
-          align="center"
-        />
-        <el-table-column
-          prop="amount"
-          label="閲戦(鍏�)"
-          width="100"
-          align="right"
-        >
+        <el-table-column prop="fuelDate" label="鍔犳补鏃ユ湡" width="120" />
+        <el-table-column prop="deptName" label="鎵�灞為儴闂�" min-width="150" show-overflow-tooltip />
+        <el-table-column prop="plateNumber" label="鍔犳补杞﹁締(鐗岀収)" width="140" />
+        <el-table-column prop="cardNumber" label="鍔犳补鍗″彿" min-width="150" />
+        <el-table-column prop="amount" label="閲戦(鍏�)" width="100" align="right" />
+        <el-table-column prop="liters" label="鍗囨暟(L)" width="100" align="right" />
+        <el-table-column prop="startMileage" label="璧峰閲岀▼(km)" width="120" align="right" />
+        <el-table-column prop="endMileage" label="缁撴潫閲岀▼(km)" width="120" align="right" />
+        <el-table-column prop="invoiceNo" label="鍙戠エ鍙风爜" width="140" />
+        <el-table-column prop="status" label="鐘舵��" width="100" align="center">
           <template #default="scope">
-            <span>{{ scope.row.amount?.toFixed(2) }}</span>
+            <el-tag v-if="scope.row.status === '0'" type="info">鑽夌</el-tag>
+            <el-tag v-else-if="scope.row.status === '1'" type="success">宸叉彁浜�</el-tag>
+            <el-tag v-else type="info">鑽夌</el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-          prop="liters"
-          label="鍗囨暟(L)"
-          width="90"
-          align="right"
-        >
+        <el-table-column prop="remark" label="澶囨敞" min-width="150" show-overflow-tooltip />
+        <el-table-column label="鎿嶄綔" fixed="right" width="200" align="center">
           <template #default="scope">
-            <span>{{ scope.row.liters?.toFixed(2) }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="startMileage"
-          label="璧峰閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="endMileage"
-          label="缁撴潫閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="distance"
-          label="琛岄┒閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="fuelConsumption"
-          label="娌硅��(L/100km)"
-          width="130"
-          align="center"
-        >
-          <template #default="scope">
-            <span
-              :style="scope.row.isAbnormal ? 'color:#F56C6C;font-weight:600;' : ''"
-            >
-              {{ scope.row.fuelConsumption != null ? scope.row.fuelConsumption.toFixed(2) : '-' }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="avgConsumption"
-          label="杞﹁締骞冲潎娌硅��"
-          width="130"
-          align="center"
-        >
-          <template #default="scope">
-            <span>
-              {{ scope.row.avgConsumption != null ? scope.row.avgConsumption.toFixed(2) : '-' }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column label="寮傚父棰勮" width="100" align="center">
-          <template #default="scope">
-            <el-tag v-if="scope.row.isAbnormal" type="danger" size="small">
-              寮傚父
-            </el-tag>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="鎿嶄綔" fixed="right" width="140" align="center">
-          <template #default="scope">
-            <el-button
-              type="primary"
-              link
-              size="small"
-              @click="openEdit(scope.row)"
-            >
-              缂栬緫
-            </el-button>
-            <el-button
-              type="danger"
-              link
-              size="small"
-              @click="removeRow(scope.row)"
-            >
-              鍒犻櫎
-            </el-button>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="success" link size="small" @click="handleSubmitRow(scope.row)">鎻愪氦</el-button>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="primary" link size="small" @click="handleUpdate(scope.row)">缂栬緫</el-button>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="danger" link size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+            <el-button v-if="scope.row.status === '1'" type="warning" link size="small" @click="handleRevokeRow(scope.row)">鎾ゅ洖</el-button>
           </template>
         </el-table-column>
       </el-table>
-    </div>
 
-    <!-- 鏂板/缂栬緫寮圭獥 -->
-    <el-dialog
-      v-model="dialogVisible"
-      :title="dialogTitle"
-      width="640px"
-      destroy-on-close
-    >
-      <el-form
-        ref="formRef"
-        :model="form"
-        :rules="rules"
-        label-width="110px"
-        label-position="right"
-      >
+      <!-- 鍒嗛〉 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.current"
+        v-model:limit="queryParams.size"
+        @pagination="getList"
+      />
+    </div>
+<!-- 寮圭獥 -->
+    <el-dialog :title="title" v-model="open" width="640px" append-to-body>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="杞﹁締缂栧彿锛�" prop="vehicleCode">
-              <el-input
-                v-model="form.vehicleCode"
-                placeholder="璇疯緭鍏ヨ溅杈嗙紪鍙�"
-              />
+            <el-form-item label="鍔犳补杞﹁締" prop="vehicleId">
+              <el-select v-model="form.vehicleId" placeholder="璇烽�夋嫨杞﹁締(鐗岀収)" style="width: 100%" filterable>
+                <el-option
+                  v-for="item in vehicleList"
+                  :key="item.id"
+                  :label="item.plateNumber"
+                  :value="item.id"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="杞︾墝鍙风爜锛�" prop="plateNumber">
-              <el-input
-                v-model="form.plateNumber"
-                placeholder="璇疯緭鍏ヨ溅鐗屽彿鐮�"
-              />
+            <el-form-item label="鍏宠仈鍔犳补鍗�" prop="fuelCardId">
+              <el-select v-model="form.fuelCardId" placeholder="璇烽�夋嫨鍔犳补鍗�" style="width: 100%" filterable>
+                <el-option
+                  v-for="item in availableFuelCardList"
+                  :key="item.id"
+                  :label="item.cardNumber + ' - ' + item.issuer"
+                  :value="item.id"
+                />
+              </el-select>
+              <div v-if="form.fuelCardId" style="font-size: 12px; color: #999; margin-top: 5px;">
+                褰撳墠浣欓: {{ getFuelCardBalance(form.fuelCardId) }} 鍏�
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="鍔犳补鏃ユ湡锛�" prop="fuelDate">
+            <el-form-item label="鍔犳补鏃ユ湡" prop="fuelDate">
               <el-date-picker
                 v-model="form.fuelDate"
                 type="date"
                 value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                placeholder="璇烽�夋嫨鍔犳补鏃ユ湡"
+                placeholder="璇烽�夋嫨鏃ユ湡"
                 style="width: 100%"
               />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="娌规灙鍙凤細" prop="gunNo">
-              <el-input
-                v-model="form.gunNo"
-                placeholder="璇疯緭鍏ユ补鏋彿"
-              />
+            <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNo">
+              <el-input v-model="form.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="閲戦(鍏�)锛�" prop="amount">
-              <el-input-number
-                v-model="form.amount"
-                :min="0"
-                :step="0.01"
-                :precision="2"
-                placeholder="璇疯緭鍏ラ噾棰�"
-                style="width: 100%"
-              />
+            <el-form-item label="閲戦(鍏�)" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鍗囨暟(L)锛�" prop="liters">
-              <el-input-number
-                v-model="form.liters"
-                :min="0"
-                :step="0.01"
-                :precision="2"
-                placeholder="璇疯緭鍏ュ崌鏁�"
-                style="width: 100%"
-              />
+            <el-form-item label="鍗囨暟(L)" prop="liters">
+              <el-input-number v-model="form.liters" :min="0" :precision="2" :step="10" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="璧峰閲岀▼(km)锛�" prop="startMileage">
-              <el-input-number
-                v-model="form.startMileage"
-                :min="0"
-                :step="1"
-                placeholder="璇疯緭鍏ヨ捣濮嬮噷绋�"
-                style="width: 100%"
-              />
+            <el-form-item label="璧峰閲岀▼(km)" prop="startMileage">
+              <el-input-number v-model="form.startMileage" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="缁撴潫閲岀▼(km)锛�" prop="endMileage">
-              <el-input-number
-                v-model="form.endMileage"
-                :min="0"
-                :step="1"
-                placeholder="璇疯緭鍏ョ粨鏉熼噷绋�"
-                style="width: 100%"
-              />
+            <el-form-item label="缁撴潫閲岀▼(km)" prop="endMileage">
+              <el-input-number v-model="form.endMileage" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ娉ㄥ唴瀹�" />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button @click="handleCancel">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">淇� 瀛�</el-button>
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
         </div>
       </template>
     </el-dialog>
@@ -283,274 +181,229 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
+import { ref, reactive, onMounted, computed } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import request from '@/utils/request';
+import { 
+  listFuelRecord, 
+  addFuelRecord, 
+  updateFuelRecord, 
+  delFuelRecord,
+  listVehicleInfo,
+  listAllFuelCard,
+  submitFuelRecord,
+  revokeFuelRecord
+} from '@/api/inventoryManagement/vehicle';
 
-// 妯℃嫙鍔犳补璁板綍鏁版嵁
-const rawRecords = ref([
-  {
-    id: 1,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2024-12-01",
-    gunNo: "01",
-    amount: 500,
-    liters: 70,
-    startMileage: 12000,
-    endMileage: 12600,
-  },
-  {
-    id: 2,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2024-12-15",
-    gunNo: "02",
-    amount: 520,
-    liters: 72,
-    startMileage: 12600,
-    endMileage: 13250,
-  },
-  {
-    id: 3,
-    vehicleCode: "CL-202402",
-    plateNumber: "绮67890",
-    fuelDate: "2024-12-05",
-    gunNo: "03",
-    amount: 430,
-    liters: 60,
-    startMileage: 8000,
-    endMileage: 8520,
-  },
-  {
-    id: 4,
-    vehicleCode: "CL-202402",
-    plateNumber: "绮67890",
-    fuelDate: "2024-12-20",
-    gunNo: "01",
-    amount: 450,
-    liters: 63,
-    startMileage: 8520,
-    endMileage: 9000,
-  },
-  {
-    id: 5,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2025-01-05",
-    gunNo: "01",
-    amount: 700,
-    liters: 90,
-    startMileage: 13250,
-    endMileage: 13600, // 鏄庢樉寮傚父娌硅��
-  },
-]);
+const loading = ref(true);
+const tableData = ref([]);
+const total = ref(0);
+const open = ref(false);
+const title = ref("");
+const formRef = ref(null);
 
-// 鏌ヨ琛ㄥ崟
-const searchForm = reactive({
-  vehicleCode: "",
-  dateRange: [],
+const vehicleList = ref([]);
+const fuelCardList = ref([]);
+const deptOptions = ref([]);
+const dateRange = ref([]);
+
+const availableFuelCardList = computed(() => {
+  return fuelCardList.value.filter(item => item.status !== 'CANCELLED');
 });
 
-// 琛ㄦ牸鏁版嵁锛堝寘鍚绠楀瓧娈碉級
-const tableData = ref([]);
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  deptId: undefined,
+  vehicleId: undefined,
+  fuelCardId: undefined,
+  beginDate: undefined,
+  endDate: undefined
+});
 
-// 寮圭獥 & 琛ㄥ崟
-const dialogVisible = ref(false);
-const dialogTitle = ref("鏂板鍔犳补璁板綍");
-const isEdit = ref(false);
-const formRef = ref(null);
 const form = reactive({
-  id: null,
-  vehicleCode: "",
-  plateNumber: "",
-  fuelDate: "",
-  gunNo: "",
-  amount: null,
-  liters: null,
-  startMileage: null,
-  endMileage: null,
+  id: undefined,
+  vehicleId: undefined,
+  fuelCardId: undefined,
+  fuelDate: undefined,
+  amount: undefined,
+  liters: undefined,
+  startMileage: undefined,
+  endMileage: undefined,
+  invoiceNo: undefined,
+  remark: undefined
 });
 
 const rules = {
-  vehicleCode: [{ required: true, message: "璇疯緭鍏ヨ溅杈嗙紪鍙�", trigger: "blur" }],
-  plateNumber: [{ required: true, message: "璇疯緭鍏ヨ溅鐗屽彿鐮�", trigger: "blur" }],
-  fuelDate: [{ required: true, message: "璇烽�夋嫨鍔犳补鏃ユ湡", trigger: "change" }],
-  gunNo: [{ required: true, message: "璇疯緭鍏ユ补鏋彿", trigger: "blur" }],
-  amount: [{ required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur" }],
-  liters: [{ required: true, message: "璇疯緭鍏ュ崌鏁�", trigger: "blur" }],
-  startMileage: [{ required: true, message: "璇疯緭鍏ヨ捣濮嬮噷绋�", trigger: "blur" }],
-  endMileage: [{ required: true, message: "璇疯緭鍏ョ粨鏉熼噷绋�", trigger: "blur" }],
+  vehicleId: [{ required: true, message: "鍔犳补杞﹁締涓嶈兘涓虹┖", trigger: "change" }],
+  fuelCardId: [{ required: true, message: "鍔犳补鍗′笉鑳戒负绌�", trigger: "change" }],
+  fuelDate: [{ required: true, message: "鍔犳补鏃ユ湡涓嶈兘涓虹┖", trigger: "change" }],
+  amount: [{ required: true, message: "閲戦涓嶈兘涓虹┖", trigger: "blur" }]
 };
 
-// 閲嶆柊璁$畻娌硅�椼�佸钩鍧囨补鑰楀拰寮傚父棰勮
-const recomputeTable = () => {
-  const records = rawRecords.value;
-
-  // 1. 鍏堟寜杞﹁締缁熻骞冲潎娌硅��
-  const stats = {};
-  records.forEach((r) => {
-    const distance = r.endMileage - r.startMileage;
-    if (distance <= 0 || !r.liters) return;
-    const cons = (r.liters / distance) * 100; // L/100km
-    if (!stats[r.vehicleCode]) {
-      stats[r.vehicleCode] = { totalCons: 0, count: 0 };
-    }
-    stats[r.vehicleCode].totalCons += cons;
-    stats[r.vehicleCode].count += 1;
+function getDictData() {
+  request({url: '/system/user/deptTree', method: 'get'}).then(res => {
+    deptOptions.value = res.data || [];
   });
-
-  const avgMap = {};
-  Object.keys(stats).forEach((key) => {
-    avgMap[key] = stats[key].totalCons / stats[key].count;
+  listVehicleInfo({current: 1, size: 1000}).then(res => {
+    vehicleList.value = res.data.records;
   });
+  listAllFuelCard().then(res => {
+    fuelCardList.value = res.data;
+  });
+}
 
-  // 2. 鎸夌瓫閫夋潯浠惰繃婊ゅ苟琛ュ厖璁$畻瀛楁
-  const filtered = records
-    .filter((r) => {
-      if (
-        searchForm.vehicleCode &&
-        !r.vehicleCode.includes(searchForm.vehicleCode.trim())
-      ) {
-        return false;
-      }
-      if (Array.isArray(searchForm.dateRange) && searchForm.dateRange.length === 2) {
-        const [start, end] = searchForm.dateRange;
-        if (r.fuelDate < start || r.fuelDate > end) {
-          return false;
+function getFuelCardBalance(id) {
+  const c = fuelCardList.value.find(item => item.id === id);
+  return c ? c.currentBalance : 0;
+}
+
+
+const statTotalAmount = ref(0);
+const statTotalLiters = ref(0);
+
+function getStats() {
+  const query = { ...queryParams, current: 1, size: 10000 };
+  listFuelRecord(query).then(res => {
+    const arr = res.data.records || [];
+    statTotalAmount.value = arr.reduce((sum, item) => sum + (item.amount || 0), 0);
+    statTotalLiters.value = arr.reduce((sum, item) => sum + (item.liters || 0), 0);
+  });
+}
+
+function getList() {
+  loading.value = true;
+  if (dateRange.value && dateRange.value.length === 2) {
+    queryParams.beginDate = dateRange.value[0];
+    queryParams.endDate = dateRange.value[1];
+  } else {
+    queryParams.beginDate = undefined;
+    queryParams.endDate = undefined;
+  }
+  listFuelRecord(queryParams).then(response => {
+    tableData.value = response.data.records;
+    total.value = response.data.total;
+    loading.value = false;
+    getStats();
+  }).catch(() => {
+    loading.value = false;
+    getStats();
+  });
+}
+
+function handleQuery() {
+  queryParams.current = 1;
+  getList();
+}
+
+function resetQuery() {
+  queryParams.deptId = undefined;
+  queryParams.vehicleId = undefined;
+  queryParams.fuelCardId = undefined;
+  dateRange.value = [];
+  handleQuery();
+}
+
+function reset() {
+  Object.assign(form, {
+    id: undefined,
+    vehicleId: undefined,
+    fuelCardId: undefined,
+    fuelDate: undefined,
+    amount: undefined,
+    liters: undefined,
+    startMileage: undefined,
+    endMileage: undefined,
+    invoiceNo: undefined,
+    remark: undefined
+  });
+  if (formRef.value) formRef.value.resetFields();
+}
+
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "鏂板鍔犳补璁板綍";
+}
+
+function handleUpdate(row) {
+  reset();
+  Object.assign(form, row);
+  open.value = true;
+  title.value = "淇敼鍔犳补璁板綍";
+}
+
+function submitForm() {
+  formRef.value.validate(valid => {
+    if (valid) {
+      if (!form.id) {
+        const bal = getFuelCardBalance(form.fuelCardId);
+        if (bal < form.amount) {
+          ElMessage.warning("璇ュ姞娌瑰崱浣欓涓嶈冻锛佸綋鍓嶄綑棰�: " + bal);
         }
       }
-      return true;
-    })
-    .map((r) => {
-      const distance = r.endMileage - r.startMileage;
-      const fuelConsumption =
-        distance > 0 && r.liters
-          ? (r.liters / distance) * 100
-          : null;
-      const avgConsumption =
-        avgMap[r.vehicleCode] != null ? avgMap[r.vehicleCode] : null;
-      const isAbnormal =
-        avgConsumption != null &&
-        fuelConsumption != null &&
-        fuelConsumption > avgConsumption * 1.2;
-
-      return {
-        ...r,
-        distance,
-        fuelConsumption,
-        avgConsumption,
-        isAbnormal,
-      };
-    });
-
-  tableData.value = filtered;
-};
-
-// 鏌ヨ
-const handleQuery = () => {
-  recomputeTable();
-};
-
-const resetSearch = () => {
-  searchForm.vehicleCode = "";
-  searchForm.dateRange = [];
-  recomputeTable();
-};
-
-// 琛屾牱寮忥紙寮傚父楂樹寒锛�
-const tableRowClassName = ({ row }) => {
-  if (row.isAbnormal) {
-    return "row-abnormal";
-  }
-  return "";
-};
-
-// 鏂板
-const openAdd = () => {
-  dialogTitle.value = "鏂板鍔犳补璁板綍";
-  isEdit.value = false;
-  Object.assign(form, {
-    id: null,
-    vehicleCode: "",
-    plateNumber: "",
-    fuelDate: "",
-    gunNo: "",
-    amount: null,
-    liters: null,
-    startMileage: null,
-    endMileage: null,
-  });
-  dialogVisible.value = true;
-};
-
-// 缂栬緫
-const openEdit = (row) => {
-  dialogTitle.value = "缂栬緫鍔犳补璁板綍";
-  isEdit.value = true;
-  Object.assign(form, row);
-  dialogVisible.value = true;
-};
-
-// 淇濆瓨
-const handleSubmit = () => {
-  if (!formRef.value) return;
-  formRef.value.validate((valid) => {
-    if (!valid) return;
-
-    if (form.endMileage <= form.startMileage) {
-      ElMessage.warning("缁撴潫閲岀▼蹇呴』澶т簬璧峰閲岀▼");
-      return;
-    }
-
-    if (isEdit.value) {
-      const index = rawRecords.value.findIndex((r) => r.id === form.id);
-      if (index !== -1) {
-        rawRecords.value[index] = { ...form };
+      
+      if (form.id != null) {
+        updateFuelRecord(form).then(response => {
+          ElMessage.success("淇敼鎴愬姛");
+          open.value = false;
+          getList();
+          getDictData();
+        });
+      } else {
+        addFuelRecord(form).then(response => {
+          ElMessage.success("鏂板鎴愬姛");
+          open.value = false;
+          getList();
+          getDictData();
+        });
       }
-      ElMessage.success("鍔犳补璁板綍宸叉洿鏂�");
-    } else {
-      const newId = rawRecords.value.length
-        ? Math.max(...rawRecords.value.map((r) => r.id)) + 1
-        : 1;
-      rawRecords.value.push({ ...form, id: newId });
-      ElMessage.success("鍔犳补璁板綍宸叉柊澧�");
     }
-    dialogVisible.value = false;
-    recomputeTable();
   });
-};
+}
 
-const handleCancel = () => {
-  dialogVisible.value = false;
-};
-
-// 鍒犻櫎
-const removeRow = (row) => {
-  ElMessageBox.confirm("鏄惁纭鍒犻櫎璇ュ姞娌硅褰曪紵", "鍒犻櫎鎻愮ず", {
-    confirmButtonText: "纭",
+function handleDelete(row) {
+  ElMessageBox.confirm('鏄惁纭鍒犻櫎璇ヨ崏绋胯褰曪紵', "璀﹀憡", {
+    confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      rawRecords.value = rawRecords.value.filter((r) => r.id !== row.id);
-      recomputeTable();
-      ElMessage.success("鍒犻櫎鎴愬姛");
-    })
-    .catch(() => {});
-};
+    type: "warning"
+  }).then(function() {
+    return delFuelRecord(row.id);
+  }).then(() => {
+    getList();
+    getDictData();
+    ElMessage.success("鍒犻櫎鎴愬姛");
+  });
+}
+
+function cancel() {
+  open.value = false;
+  reset();
+}
 
 onMounted(() => {
-  recomputeTable();
+  getDictData();
+  getList();
 });
-</script>
 
-<style scoped lang="scss">
-.dialog-footer {
-  text-align: right;
+function handleSubmitRow(row) {
+  ElMessageBox.confirm('纭鎻愪氦璇ョ瑪鍔犳补璁板綍鍚楋紵鎻愪氦鍚庡皢浠庡姞娌瑰崱涓墸闄や綑棰�', '鎻愮ず', { type: 'warning' }).then(() => {
+    return submitFuelRecord(row.id);
+  }).then(() => {
+    ElMessage.success('鎻愪氦鎴愬姛');
+    getList();
+    getStats();
+  }).catch(() => {});
 }
 
-:deep(.row-abnormal) {
-  background-color: #fff5f5;
+function handleRevokeRow(row) {
+  ElMessageBox.confirm('纭鎾ゅ洖璇ョ瑪鍔犳补璁板綍鍚楋紵鎾ゅ洖鍚庡皢閫�杩樺姞娌瑰崱浣欓', '鎻愮ず', { type: 'warning' }).then(() => {
+    return revokeFuelRecord(row.id);
+  }).then(() => {
+    ElMessage.success('鎾ゅ洖鎴愬姛');
+    getList();
+    getStats();
+  }).catch(() => {});
 }
-</style>
 
+</script>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/vehicleManagement/index.vue b/src/views/inventoryManagement/vehicleManagement/index.vue
index 1e383c6..1d0203a 100644
--- a/src/views/inventoryManagement/vehicleManagement/index.vue
+++ b/src/views/inventoryManagement/vehicleManagement/index.vue
@@ -1,268 +1,130 @@
 <template>
   <div class="app-container">
+
     <!-- 鏌ヨ鏉′欢 -->
-    <div class="search_form">
-      <div>
-        <span class="search_title">杞︾墝鍙风爜锛�</span>
-        <el-input
-          v-model="searchForm.plateNumber"
-          style="width: 180px"
-          placeholder="璇疯緭鍏ヨ溅鐗屽彿鐮�"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-
-        <span class="search_title ml10">杞﹁締绫诲瀷锛�</span>
-        <el-select
-          v-model="searchForm.vehicleType"
-          style="width: 160px"
-          placeholder="璇烽�夋嫨杞﹁締绫诲瀷"
-          clearable
-        >
-          <el-option
-            v-for="item in vehicleTypeOptions"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-
-        <span class="search_title ml10">鎵�灞為儴闂細</span>
-        <el-select
-          v-model="searchForm.department"
-          style="width: 160px"
-          placeholder="璇烽�夋嫨鎵�灞為儴闂�"
-          clearable
-        >
-          <el-option
-            v-for="item in departmentOptions"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-
-        <span class="search_title ml10">鐘舵�侊細</span>
-        <el-select
-          v-model="searchForm.status"
-          style="width: 140px"
-          placeholder="璇烽�夋嫨鐘舵��"
-          clearable
-        >
-          <el-option
-            v-for="item in statusOptions"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-
-        <span class="search_title ml10">褰掓。鐘舵�侊細</span>
-        <el-select
-          v-model="searchForm.archived"
-          style="width: 140px"
-          placeholder="璇烽�夋嫨褰掓。鐘舵��"
-          clearable
-        >
-          <el-option label="鏈綊妗�" value="false" />
-          <el-option label="宸插綊妗�" value="true" />
-        </el-select>
-
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
-          鎼滅储
-        </el-button>
-        <el-button @click="resetSearch">閲嶇疆</el-button>
+    <div class="search_form" >
+      <div style="flex: 1; padding-right: 20px;">
+        <el-row :gutter="16">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">杞︾墝鍙风爜锛�</span>
+            <el-input v-model="queryParams.plateNumber" placeholder="璇疯緭鍏ヨ溅鐗屽彿鐮�" clearable style="flex: 1;" @keyup.enter.native="handleQuery" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鎵�灞為儴闂細</span>
+            <el-tree-select v-model="queryParams.deptId" :data="deptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="璇烽�夋嫨閮ㄩ棬" check-strictly clearable filterable style="flex: 1;" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鐘舵�侊細</span>
+            <el-select v-model="queryParams.vehicleStatus" placeholder="璇烽�夋嫨鐘舵��" clearable style="flex: 1;">
+              <el-option label="鍦ㄧ敤" value="NORMAL" />
+              <el-option label="闂茬疆" value="IDLE" />
+              <el-option label="缁翠慨" value="REPAIR" />
+            </el-select>
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+            <el-button @click="resetQuery">閲嶇疆</el-button>
+          </el-col>
+        </el-row>
       </div>
       <div>
-        <el-button type="primary" icon="Plus" @click="openAdd">鏂板杞﹁締</el-button>
+        <el-button type="primary" icon="Plus" @click="handleAdd">鏂板杞﹁締</el-button>
       </div>
     </div>
-
     <!-- 琛ㄦ牸 -->
     <div class="table_list">
       <el-table
+        v-loading="loading"
         :data="tableData"
         border
         style="width: 100%"
-        height="calc(100vh - 18.5em)"
+        height="calc(100vh - 22em)"
         :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
       >
         <el-table-column type="index" label="搴忓彿" width="60" align="center" />
-        <el-table-column
-          prop="vehicleCode"
-          label="杞﹁締缂栧彿"
-          width="140"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="plateNumber"
-          label="杞︾墝鍙风爜"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="vehicleType"
-          label="杞﹁締绫诲瀷"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="department"
-          label="鎵�灞為儴闂�"
-          width="140"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="purchaseDate"
-          label="璐疆鏃ユ湡"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="licenseNumber"
-          label="琛岄┒璇佺紪鍙�"
-          width="160"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="licenseIssueDate"
-          label="鍙戣瘉鏃ユ湡"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="licenseExpireDate"
-          label="鍒版湡鏃ユ湡"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column label="鐘舵��" width="100" align="center">
+        <el-table-column prop="plateNumber" label="杞︾墝鍙风爜" min-width="120" show-overflow-tooltip />
+        <el-table-column prop="deptName" label="鎵�灞為儴闂�" min-width="150" show-overflow-tooltip />
+        <el-table-column prop="userName" label="璐d换浜�" min-width="120" />
+        <el-table-column prop="propertyOwnership" label="浜ф潈鎵�鏈�" min-width="120" show-overflow-tooltip />
+        <el-table-column label="骞存鍒版湡鏃ユ湡" min-width="140">
           <template #default="scope">
-            <el-tag :type="statusTagType(scope.row.status)">
-              {{ scope.row.status }}
+            <span>{{ scope.row.inspectionExpireDate }}</span>
+            <el-tag v-if="isExpired(scope.row.inspectionExpireDate)" type="danger" size="small" style="margin-left:5px;">宸茶秴鏈�</el-tag>
+            <el-tag v-else-if="isExpiringSoon(scope.row.inspectionExpireDate)" type="warning" size="small" style="margin-left:5px;">鍗冲皢鍒版湡</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="淇濋櫓鍒版湡鏃ユ湡" min-width="140">
+          <template #default="scope">
+            <span>{{ scope.row.insuranceExpireDate }}</span>
+            <el-tag v-if="isExpired(scope.row.insuranceExpireDate)" type="danger" size="small" style="margin-left:5px;">宸茶秴鏈�</el-tag>
+            <el-tag v-else-if="isExpiringSoon(scope.row.insuranceExpireDate)" type="warning" size="small" style="margin-left:5px;">鍗冲皢鍒版湡</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" min-width="100" align="center">
+          <template #default="scope">
+            <el-tag :type="statusTagType(scope.row.vehicleStatus)">
+              {{ statusLabel(scope.row.vehicleStatus) }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="褰掓。鐘舵��" width="100" align="center">
-          <template #default="scope">
-            <el-tag :type="scope.row.archived ? 'info' : 'success'">
-              {{ scope.row.archived ? '宸插綊妗�' : '鏈綊妗�' }}
-            </el-tag>
-          </template>
-        </el-table-column>
+        <el-table-column prop="remark" label="澶囨敞" min-width="150" show-overflow-tooltip />
         <el-table-column label="鎿嶄綔" fixed="right" width="220" align="center">
           <template #default="scope">
-            <el-button
-              type="primary"
-              link
-              size="small"
-              @click="openEdit(scope.row)"
-            >
-              缂栬緫
-            </el-button>
-            <el-button
-              type="warning"
-              link
-              size="small"
-              :disabled="scope.row.archived"
-              @click="archiveRow(scope.row)"
-            >
-              褰掓。
-            </el-button>
-            <el-button
-              type="danger"
-              link
-              size="small"
-              @click="removeRow(scope.row)"
-            >
-              鍒犻櫎
-            </el-button>
+            <el-button type="success" link size="small" @click="handleCost(scope.row)">璐圭敤绠$悊</el-button>
+            <el-button type="primary" link size="small" @click="handleUpdate(scope.row)">缂栬緫</el-button>
+            <el-button type="danger" link size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
-    </div>
 
-    <!-- 鏂板/缂栬緫寮圭獥 -->
-    <el-dialog
-      v-model="dialogVisible"
-      :title="dialogTitle"
-      width="600px"
-      destroy-on-close
-    >
-      <el-form
-        ref="formRef"
-        :model="form"
-        :rules="rules"
-        label-width="100px"
-        label-position="right"
-      >
+      <!-- 鍒嗛〉 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.current"
+        v-model:limit="queryParams.size"
+        @pagination="getList"
+      />
+    </div>
+<!-- 鏂板/缂栬緫杞﹁締寮圭獥 -->
+    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="杞﹁締缂栧彿锛�" prop="vehicleCode">
-              <el-input v-model="form.vehicleCode" placeholder="璇疯緭鍏ヨ溅杈嗙紪鍙�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="杞︾墝鍙风爜锛�" prop="plateNumber">
+            <el-form-item label="杞︾墝鍙风爜" prop="plateNumber">
               <el-input v-model="form.plateNumber" placeholder="璇疯緭鍏ヨ溅鐗屽彿鐮�" />
             </el-form-item>
           </el-col>
-        </el-row>
-        <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="杞﹁締绫诲瀷锛�" prop="vehicleType">
-              <el-select
-                v-model="form.vehicleType"
-                placeholder="璇烽�夋嫨杞﹁締绫诲瀷"
-                clearable
-              >
-                <el-option
-                  v-for="item in vehicleTypeOptions"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎵�灞為儴闂細" prop="department">
-              <el-select
-                v-model="form.department"
-                placeholder="璇烽�夋嫨鎵�灞為儴闂�"
-                clearable
-              >
-                <el-option
-                  v-for="item in departmentOptions"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                />
-              </el-select>
+            <el-form-item label="浜ф潈鎵�鏈�" prop="propertyOwnership">
+              <el-input v-model="form.propertyOwnership" placeholder="濡�:鑷湁,绉熻祦绛�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="璐疆鏃ユ湡锛�" prop="purchaseDate">
-              <el-date-picker
-                v-model="form.purchaseDate"
-                type="date"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                placeholder="璇烽�夋嫨璐疆鏃ユ湡"
+            <el-form-item label="鎵�灞為儴闂�" prop="deptId">
+              <el-tree-select
+                v-model="form.deptId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨閮ㄩ棬"
+                check-strictly
+                clearable
+                filterable
                 style="width: 100%"
               />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鐘舵�侊細" prop="status">
-              <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
+            <el-form-item label="璐d换浜�" prop="userId">
+              <el-select v-model="form.userId" placeholder="璇烽�夋嫨璐d换浜�" style="width: 100%" filterable>
                 <el-option
-                  v-for="item in statusOptions"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.userId + ' - ' + (item.nickName || item.userName)"
+                  :value="item.userId"
                 />
               </el-select>
             </el-form-item>
@@ -270,312 +132,389 @@
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="琛岄┒璇佺紪鍙凤細" prop="licenseNumber">
-              <el-input
-                v-model="form.licenseNumber"
-                placeholder="璇疯緭鍏ヨ椹惰瘉缂栧彿"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍙戣瘉鏃ユ湡锛�" prop="licenseIssueDate">
-              <el-date-picker
-                v-model="form.licenseIssueDate"
-                type="date"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                placeholder="璇烽�夋嫨鍙戣瘉鏃ユ湡"
-                style="width: 100%"
-              />
+            <el-form-item label="鐘舵��" prop="vehicleStatus">
+              <el-select v-model="form.vehicleStatus" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
+                <el-option label="鍦ㄧ敤" value="NORMAL" />
+                <el-option label="闂茬疆" value="IDLE" />
+                <el-option label="缁翠慨" value="REPAIR" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="鍒版湡鏃ユ湡锛�" prop="licenseExpireDate">
+            <el-form-item label="骞存鍒版湡" prop="inspectionExpireDate">
               <el-date-picker
-                v-model="form.licenseExpireDate"
+                v-model="form.inspectionExpireDate"
                 type="date"
                 value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
+                placeholder="璇烽�夋嫨鍒版湡鏃ユ湡"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="淇濋櫓鍒版湡" prop="insuranceExpireDate">
+              <el-date-picker
+                v-model="form.insuranceExpireDate"
+                type="date"
+                value-format="YYYY-MM-DD"
                 placeholder="璇烽�夋嫨鍒版湡鏃ユ湡"
                 style="width: 100%"
               />
             </el-form-item>
           </el-col>
         </el-row>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button @click="handleCancel">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">淇� 瀛�</el-button>
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
         </div>
+      </template>
+    </el-dialog>
+
+    <!-- 璐圭敤绠$悊鎶藉眽 -->
+    <el-drawer v-model="costDrawer" :title="'璐圭敤绠$悊 - ' + currentVehiclePlate" size="50%">
+      <div style="padding: 20px;">
+        <div style="margin-bottom: 20px;">
+          <el-button type="primary" @click="handleAddCost">鏂板璁板綍</el-button>
+        </div>
+        <el-table v-loading="costLoading" :data="costList" border>
+          <el-table-column label="璐圭敤绫诲瀷" prop="costType">
+            <template #default="scope">
+              {{ costTypeLabel(scope.row.costType) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="閲戦(鍏�)" prop="amount" align="right" />
+          <el-table-column label="鍙戠敓鏃ユ湡" prop="costDate" />
+          <el-table-column label="澶囨敞" prop="remark" show-overflow-tooltip />
+          <el-table-column label="鎿嶄綔" width="100" align="center">
+            <template #default="scope">
+              <el-button type="danger" link size="small" @click="handleDeleteCost(scope.row)">
+                鍒犻櫎
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination
+          v-show="costTotal > 0"
+          :total="costTotal"
+          v-model:page="costQuery.current"
+          v-model:limit="costQuery.size"
+          @pagination="getCostList"
+        />
+      </div>
+    </el-drawer>
+
+    <!-- 鏂板璐圭敤寮圭獥 -->
+    <el-dialog title="鏂板璐圭敤" v-model="costOpen" width="400px" append-to-body>
+      <el-form ref="costFormRef" :model="costForm" :rules="costRules" label-width="100px">
+        <el-form-item label="璐圭敤绫诲瀷" prop="costType">
+          <el-select v-model="costForm.costType" placeholder="璇烽�夋嫨" style="width:100%">
+            <el-option label="淇濆吇" value="MAINTENANCE" />
+            <el-option label="骞存" value="INSPECTION" />
+            <el-option label="淇濋櫓" value="INSURANCE" />
+            <el-option label="缁翠慨" value="REPAIR" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="閲戦(鍏�)" prop="amount">
+          <el-input-number v-model="costForm.amount" :precision="2" :min="0" style="width:100%" />
+        </el-form-item>
+        <el-form-item label="鍙戠敓鏃ユ湡" prop="costDate">
+          <el-date-picker v-model="costForm.costDate" type="date" value-format="YYYY-MM-DD" style="width:100%" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="costForm.remark" type="textarea" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button type="primary" @click="submitCostForm">纭� 瀹�</el-button>
+        <el-button @click="costOpen = false">鍙� 娑�</el-button>
       </template>
     </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
+import { ref, reactive, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { listVehicleInfo, getWarningList, addVehicleInfo, updateVehicleInfo, delVehicleInfo } from '@/api/inventoryManagement/vehicle';
+import request from '@/utils/request';
 
-// 妯℃嫙杞﹁締鍩虹鏁版嵁
-const allVehicles = ref([
-  {
-    id: 1,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    vehicleType: "鍘㈠紡璐ц溅",
-    department: "鐗╂祦涓�閮�",
-    purchaseDate: "2022-03-15",
-    licenseNumber: "4401-2022-0001",
-    licenseIssueDate: "2022-03-10",
-    licenseExpireDate: "2026-03-10",
-    status: "鍦ㄧ敤",
-    archived: false,
-  },
-  {
-    id: 2,
-    vehicleCode: "CL-202402",
-    plateNumber: "绮67890",
-    vehicleType: "鍐疯棌杞�",
-    department: "鐗╂祦浜岄儴",
-    purchaseDate: "2021-08-01",
-    licenseNumber: "4401-2021-0123",
-    licenseIssueDate: "2021-07-28",
-    licenseExpireDate: "2025-07-28",
-    status: "缁翠慨",
-    archived: false,
-  },
-  {
-    id: 3,
-    vehicleCode: "CL-202403",
-    plateNumber: "绮11223",
-    vehicleType: "鐗靛紩杞�",
-    department: "椤圭洰杩愯緭閮�",
-    purchaseDate: "2020-05-20",
-    licenseNumber: "4401-2020-0456",
-    licenseIssueDate: "2020-05-18",
-    licenseExpireDate: "2024-05-18",
-    status: "闂茬疆",
-    archived: false,
-  },
-  {
-    id: 4,
-    vehicleCode: "CL-202404",
-    plateNumber: "绮33445",
-    vehicleType: "鍘㈠紡璐ц溅",
-    department: "璧勪骇绠$悊閮�",
-    purchaseDate: "2019-11-11",
-    licenseNumber: "4401-2019-0789",
-    licenseIssueDate: "2019-11-08",
-    licenseExpireDate: "2023-11-08",
-    status: "鍦ㄧ敤",
-    archived: true,
-  },
-]);
+const loading = ref(true);
+const tableData = ref([]);
+const total = ref(0);
+const open = ref(false);
+const title = ref("");
+const formRef = ref(null);
 
-// 涓嬫媺鏋氫妇
-const vehicleTypeOptions = [
-  { label: "鍘㈠紡璐ц溅", value: "鍘㈠紡璐ц溅" },
-  { label: "鍐疯棌杞�", value: "鍐疯棌杞�" },
-  { label: "鐗靛紩杞�", value: "鐗靛紩杞�" },
-  { label: "鍏朵粬", value: "鍏朵粬" },
-];
+const deptOptions = ref([]);
+const userList = ref([]);
 
-const departmentOptions = [
-  { label: "鐗╂祦涓�閮�", value: "鐗╂祦涓�閮�" },
-  { label: "鐗╂祦浜岄儴", value: "鐗╂祦浜岄儴" },
-  { label: "椤圭洰杩愯緭閮�", value: "椤圭洰杩愯緭閮�" },
-  { label: "璧勪骇绠$悊閮�", value: "璧勪骇绠$悊閮�" },
-];
-
-const statusOptions = [
-  { label: "鍦ㄧ敤", value: "鍦ㄧ敤" },
-  { label: "闂茬疆", value: "闂茬疆" },
-  { label: "缁翠慨", value: "缁翠慨" },
-];
-
-// 鏌ヨ琛ㄥ崟
-const searchForm = reactive({
-  plateNumber: "",
-  vehicleType: "",
-  department: "",
-  status: "",
-  archived: "",
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  plateNumber: undefined,
+  deptId: undefined,
+  vehicleStatus: undefined
 });
 
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([...allVehicles.value]);
-
-// 寮圭獥 & 琛ㄥ崟
-const dialogVisible = ref(false);
-const dialogTitle = ref("鏂板杞﹁締");
-const isEdit = ref(false);
-const formRef = ref(null);
 const form = reactive({
-  id: null,
-  vehicleCode: "",
-  plateNumber: "",
-  vehicleType: "",
-  department: "",
-  purchaseDate: "",
-  licenseNumber: "",
-  licenseIssueDate: "",
-  licenseExpireDate: "",
-  status: "鍦ㄧ敤",
-  archived: false,
+  id: undefined,
+  plateNumber: undefined,
+  propertyOwnership: undefined,
+  deptId: undefined,
+  userId: undefined,
+  vehicleStatus: 'NORMAL',
+  inspectionExpireDate: undefined,
+  insuranceExpireDate: undefined,
+  remark: undefined
 });
 
 const rules = {
-  vehicleCode: [{ required: true, message: "璇疯緭鍏ヨ溅杈嗙紪鍙�", trigger: "blur" }],
-  plateNumber: [{ required: true, message: "璇疯緭鍏ヨ溅鐗屽彿鐮�", trigger: "blur" }],
-  vehicleType: [{ required: true, message: "璇烽�夋嫨杞﹁締绫诲瀷", trigger: "change" }],
-  department: [{ required: true, message: "璇烽�夋嫨鎵�灞為儴闂�", trigger: "change" }],
-  purchaseDate: [{ required: true, message: "璇烽�夋嫨璐疆鏃ユ湡", trigger: "change" }],
-  status: [{ required: true, message: "璇烽�夋嫨鐘舵��", trigger: "change" }],
-  licenseNumber: [{ required: true, message: "璇疯緭鍏ヨ椹惰瘉缂栧彿", trigger: "blur" }],
-  licenseIssueDate: [{ required: true, message: "璇烽�夋嫨鍙戣瘉鏃ユ湡", trigger: "change" }],
+  plateNumber: [{ required: true, message: "杞︾墝鍙风爜涓嶈兘涓虹┖", trigger: "blur" }],
+  deptId: [{ required: true, message: "鎵�灞為儴闂ㄤ笉鑳戒负绌�", trigger: "change" }],
+  vehicleStatus: [{ required: true, message: "鐘舵�佷笉鑳戒负绌�", trigger: "change" }]
 };
 
-// 鏌ヨ
-const handleQuery = () => {
-  tableData.value = allVehicles.value.filter((item) => {
-    if (
-      searchForm.plateNumber &&
-      !item.plateNumber.includes(searchForm.plateNumber.trim())
-    ) {
-      return false;
-    }
-    if (searchForm.vehicleType && item.vehicleType !== searchForm.vehicleType) {
-      return false;
-    }
-    if (searchForm.department && item.department !== searchForm.department) {
-      return false;
-    }
-    if (searchForm.status && item.status !== searchForm.status) {
-      return false;
-    }
-    if (searchForm.archived !== "") {
-      const targetArchived = searchForm.archived === "true";
-      if (item.archived !== targetArchived) return false;
-    }
-    return true;
+// 瀛楀吀鑾峰彇
+function getDicts() {
+  request({url: '/system/user/deptTree', method: 'get'}).then(res => {
+    deptOptions.value = res.data || [];
   });
-};
+  request({url: '/system/user/list', method: 'get'}).then(res => {
+    userList.value = res.rows || res.data || [];
+  });
+}
 
-const resetSearch = () => {
-  searchForm.plateNumber = "";
-  searchForm.vehicleType = "";
-  searchForm.department = "";
-  searchForm.status = "";
-  searchForm.archived = "";
+
+const statTotal = ref(0);
+const statNormal = ref(0);
+const statIdle = ref(0);
+const statRepair = ref(0);
+
+function getStats() {
+  listVehicleInfo({ current: 1, size: 10000 }).then(res => {
+    const arr = res.data.records || [];
+    statTotal.value = arr.length;
+    statNormal.value = arr.filter(i => i.vehicleStatus === 'NORMAL').length;
+    statIdle.value = arr.filter(i => i.vehicleStatus === 'IDLE').length;
+    statRepair.value = arr.filter(i => i.vehicleStatus === 'REPAIR').length;
+  });
+}
+
+function getList() {
+  loading.value = true;
+  listVehicleInfo(queryParams).then(response => {
+    tableData.value = response.data.records;
+    total.value = response.data.total;
+    loading.value = false;
+  }).catch(() => {
+    loading.value = false;
+  });
+}
+
+function handleWarningList() {
+  loading.value = true;
+  getWarningList().then(response => {
+    tableData.value = response.data;
+    total.value = response.data.length;
+    loading.value = false;
+    ElMessage.info("宸插睍绀�30澶╁唴鍒版湡鐨勯璀﹁溅杈�");
+  }).catch(() => {
+    loading.value = false;
+  });
+}
+
+function handleQuery() {
+  queryParams.current = 1;
+  getList();
+  getStats();
+}
+
+function resetQuery() {
+  queryParams.plateNumber = undefined;
+  queryParams.deptId = undefined;
+  queryParams.vehicleStatus = undefined;
   handleQuery();
-};
+}
 
-// 鏂板
-const openAdd = () => {
-  dialogTitle.value = "鏂板杞﹁締";
-  isEdit.value = false;
+function reset() {
   Object.assign(form, {
-    id: null,
-    vehicleCode: "",
-    plateNumber: "",
-    vehicleType: "",
-    department: "",
-    purchaseDate: "",
-    licenseInfo: "",
-    status: "鍦ㄧ敤",
-    archived: false,
+    id: undefined,
+    plateNumber: undefined,
+    propertyOwnership: undefined,
+    deptId: undefined,
+    userId: undefined,
+    vehicleStatus: 'NORMAL',
+    inspectionExpireDate: undefined,
+    insuranceExpireDate: undefined,
+    remark: undefined
   });
-  dialogVisible.value = true;
-};
+  if (formRef.value) formRef.value.resetFields();
+}
 
-// 缂栬緫
-const openEdit = (row) => {
-  dialogTitle.value = "缂栬緫杞﹁締";
-  isEdit.value = true;
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "鏂板杞﹁締";
+}
+
+function handleUpdate(row) {
+  reset();
   Object.assign(form, row);
-  dialogVisible.value = true;
-};
+  open.value = true;
+  title.value = "淇敼杞﹁締";
+}
 
-// 淇濆瓨
-const handleSubmit = () => {
-  if (!formRef.value) return;
-  formRef.value.validate((valid) => {
-    if (!valid) return;
-    if (isEdit.value) {
-      const index = allVehicles.value.findIndex((v) => v.id === form.id);
-      if (index !== -1) {
-        allVehicles.value[index] = { ...form };
+function submitForm() {
+  formRef.value.validate(valid => {
+    if (valid) {
+      if (form.id != null) {
+        updateVehicleInfo(form).then(response => {
+          ElMessage.success("淇敼鎴愬姛");
+          open.value = false;
+          getList();
+  getStats();
+        });
+      } else {
+        addVehicleInfo(form).then(response => {
+          ElMessage.success("鏂板鎴愬姛");
+          open.value = false;
+          getList();
+  getStats();
+        });
       }
-      ElMessage.success("杞﹁締淇℃伅宸叉洿鏂�");
-    } else {
-      const newId = allVehicles.value.length
-        ? Math.max(...allVehicles.value.map((v) => v.id)) + 1
-        : 1;
-      allVehicles.value.push({ ...form, id: newId });
-      ElMessage.success("杞﹁締淇℃伅宸叉柊澧�");
     }
-    dialogVisible.value = false;
-    handleQuery();
   });
-};
+}
 
-const handleCancel = () => {
-  dialogVisible.value = false;
-};
-
-// 褰掓。
-const archiveRow = (row) => {
-  if (row.archived) return;
-  ElMessageBox.confirm(
-    "鏄惁纭灏嗚杞﹁締褰掓。锛熷綊妗e悗浠呬繚鐣欐煡璇紝涓嶅啀鍙備笌杩愯緭浠诲姟鍒嗛厤銆�",
-    "褰掓。鎻愮ず",
-    {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    }
-  )
-    .then(() => {
-      row.archived = true;
-      if (row.status === "鍦ㄧ敤") {
-        row.status = "闂茬疆";
-      }
-      ElMessage.success("杞﹁締宸插綊妗�");
-      handleQuery();
-    })
-    .catch(() => {});
-};
-
-// 鍒犻櫎
-const removeRow = (row) => {
-  ElMessageBox.confirm("鏄惁纭鍒犻櫎璇ヨ溅杈嗗熀纭�淇℃伅锛�", "鍒犻櫎鎻愮ず", {
-    confirmButtonText: "纭",
+function handleDelete(row) {
+  ElMessageBox.confirm('鏄惁纭鍒犻櫎璇ヨ溅杈嗘暟鎹紵', "璀﹀憡", {
+    confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      allVehicles.value = allVehicles.value.filter((v) => v.id !== row.id);
-      handleQuery();
-      ElMessage.success("鍒犻櫎鎴愬姛");
-    })
-    .catch(() => {});
-};
+    type: "warning"
+  }).then(function() {
+    return delVehicleInfo(row.id);
+  }).then(() => {
+    getList();
+  getStats();
+    ElMessage.success("鍒犻櫎鎴愬姛");
+  });
+}
 
-// 鐘舵�佹牱寮�
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+
+function isExpired(dateStr) {
+  if (!dateStr) return false;
+  const targetDate = new Date(dateStr).getTime();
+  const now = new Date().getTime();
+  return targetDate < now;
+}
+
+function isExpiringSoon(dateStr) {
+  if (!dateStr) return false;
+  const targetDate = new Date(dateStr).getTime();
+  const now = new Date().getTime();
+  const diffDays = (targetDate - now) / (1000 * 3600 * 24);
+  return diffDays >= 0 && diffDays <= 30;
+}
 const statusTagType = (status) => {
-  if (status === "鍦ㄧ敤") return "success";
-  if (status === "闂茬疆") return "info";
-  if (status === "缁翠慨") return "warning";
+  if (status === "NORMAL") return "success";
+  if (status === "IDLE") return "info";
+  if (status === "REPAIR") return "warning";
   return "default";
 };
-</script>
 
-<style scoped lang="scss">
-.dialog-footer {
-  text-align: right;
+const statusLabel = (status) => {
+  if (status === "NORMAL") return "鍦ㄧ敤";
+  if (status === "IDLE") return "闂茬疆";
+  if (status === "REPAIR") return "缁翠慨";
+  return status;
+};
+
+// 璐圭敤绠$悊閫昏緫
+const costDrawer = ref(false);
+const currentVehicleId = ref(null);
+const currentVehiclePlate = ref("");
+const costLoading = ref(false);
+const costList = ref([]);
+const costTotal = ref(0);
+const costQuery = reactive({ current: 1, size: 10, vehicleId: null });
+
+function costTypeLabel(type) {
+  const map = { MAINTENANCE: '淇濆吇', INSPECTION: '骞存', INSURANCE: '淇濋櫓', REPAIR: '缁翠慨' };
+  return map[type] || type;
 }
-</style>
 
+function handleCost(row) {
+  currentVehicleId.value = row.id;
+  currentVehiclePlate.value = row.plateNumber;
+  costQuery.vehicleId = row.id;
+  costDrawer.value = true;
+  getCostList();
+}
+
+function getCostList() {
+  costLoading.value = true;
+  request({ url: '/vehicle/cost/listPage', method: 'get', params: costQuery }).then(res => {
+    costList.value = res.data.records;
+    costTotal.value = res.data.total;
+    costLoading.value = false;
+  });
+}
+
+const costOpen = ref(false);
+const costFormRef = ref(null);
+const costForm = reactive({ vehicleId: null, costType: undefined, amount: undefined, costDate: undefined, remark: undefined });
+const costRules = {
+  costType: [{ required: true, message: "璐圭敤绫诲瀷涓嶈兘涓虹┖", trigger: "change" }],
+  amount: [{ required: true, message: "閲戦涓嶈兘涓虹┖", trigger: "blur" }],
+  costDate: [{ required: true, message: "鏃ユ湡涓嶈兘涓虹┖", trigger: "change" }]
+};
+
+function handleAddCost() {
+  costForm.vehicleId = currentVehicleId.value;
+  costForm.costType = undefined;
+  costForm.amount = undefined;
+  costForm.costDate = undefined;
+  costForm.remark = undefined;
+  if(costFormRef.value) costFormRef.value.resetFields();
+  costOpen.value = true;
+}
+
+function submitCostForm() {
+  costFormRef.value.validate(valid => {
+    if (valid) {
+      request({ url: '/vehicle/cost', method: 'post', data: costForm }).then(res => {
+        ElMessage.success("娣诲姞鎴愬姛");
+        costOpen.value = false;
+        getCostList();
+      });
+    }
+  });
+}
+
+function handleDeleteCost(row) {
+  ElMessageBox.confirm('纭畾鍒犻櫎璇ヨ垂鐢ㄨ褰曪紵', '鎻愮ず', { type: 'warning' }).then(() => {
+    request({ url: '/vehicle/cost/' + row.id, method: 'delete' }).then(() => {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      getCostList();
+    });
+  });
+}
+
+onMounted(() => {
+  getDicts();
+  getList();
+  getStats();
+});
+</script>
\ No newline at end of file
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
index d057f16..e6512e6 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
@@ -145,6 +145,22 @@
           </div>
         </div>
       </template>
+
+      <!-- 鐘舵�佸彉鏇村鎵硅鎯� -->
+      <template v-else-if="row.businessType === 19">
+        <div class="device-status-detail">
+          <el-divider content-position="left">璁惧鐘舵�佸彉鏇磋鎯�</el-divider>
+          <el-descriptions :column="2" border>
+            <el-descriptions-item label="璁惧鍚嶇О">{{ detailData.deviceName || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="鐩爣鐘舵��">
+              <el-tag :type="detailData.targetStatus === 1 ? 'success' : 'danger'">
+                {{ detailData.targetStatusName || "--" }}
+              </el-tag>
+            </el-descriptions-item>
+            <el-descriptions-item label="鍙樻洿鍘熷洜" :span="2">{{ detailData.reason || "--" }}</el-descriptions-item>
+          </el-descriptions>
+        </div>
+      </template>
     </div>
     <div v-if="attachmentList.length"
          class="detail-block">
@@ -199,9 +215,9 @@
   const formResolved = computed(() => resolveInstanceFormFields(props.row));
 
 
-  // 鏄惁涓虹壒娈婂鎵圭被鍨嬶紙閲囪喘銆佸彂璐с�佹姤浠凤級
+  // 鏄惁涓虹壒娈婂鎵圭被鍨嬶紙閲囪喘銆佸彂璐с�佹姤浠枫�佽澶囩姸鎬佸彉鏇达級
   const isSpecialApprovalType = computed(() => {
-    return [5, 7, 6].includes(props.row.businessType);
+    return [5, 7, 6, 19].includes(props.row.businessType);
   });
 
   // 璇︽儏鏁版嵁锛堢洿鎺ヤ娇鐢ㄤ紶鍏ョ殑 detail-data 鍙傛暟锛�
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
index 737e2de..742fc5c 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
@@ -327,6 +327,19 @@
       }
     }
     
+    // 璁惧鐘舵�佸彉鏇村鎵�
+    else if (row.businessType === 19) {
+      if (row.formConfig) {
+        try {
+          detailData.value = JSON.parse(row.formConfig);
+        } catch(e) {
+          detailData.value = {};
+        }
+      } else {
+        detailData.value = {};
+      }
+    }
+    
     // 鍏朵粬瀹℃壒绫诲瀷
     else {
       detailData.value = {};
@@ -375,6 +388,19 @@
       }
     }
 
+    // 璁惧鐘舵�佸彉鏇村鎵�
+    else if (row.businessType === 19) {
+      if (row.formConfig) {
+        try {
+          detailData.value = JSON.parse(row.formConfig);
+        } catch(e) {
+          detailData.value = {};
+        }
+      } else {
+        detailData.value = {};
+      }
+    }
+
     // 鍏朵粬瀹℃壒绫诲瀷
     else {
       detailData.value = {};
diff --git a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/components/DetailPanel.vue b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/components/DetailPanel.vue
index 4db16a7..dcd0082 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/components/DetailPanel.vue
+++ b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/components/DetailPanel.vue
@@ -11,6 +11,8 @@
     <el-descriptions-item label="鍛樺伐濮撳悕">{{ row.employeeName || row.applicantName || "鈥�" }}</el-descriptions-item>
     <el-descriptions-item label="鎶ラ攢鍘熷洜" :span="2">{{ row.reimburseReason || "鈥�" }}</el-descriptions-item>
     <el-descriptions-item label="鎶ラ攢閲戦">{{ row.applyAmount != null ? `${row.applyAmount} 鍏僠 : "鈥�" }}</el-descriptions-item>
+    <el-descriptions-item label="閮ㄩ棬">{{ row.applicantDeptName || row.deptName || "鈥�" }}</el-descriptions-item>
+    <el-descriptions-item label="浠樻鏂�">{{ row.payer || "鈥�" }}</el-descriptions-item>
     <el-descriptions-item label="鏀舵浜�">{{ row.payee || "鈥�" }}</el-descriptions-item>
     <el-descriptions-item label="鏀舵璐﹀彿">{{ row.payeeAccount || "鈥�" }}</el-descriptions-item>
     <el-descriptions-item label="寮�鎴锋敮琛�">{{ row.bankBranch || "鈥�" }}</el-descriptions-item>
diff --git a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/costReimburseUtils.js b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/costReimburseUtils.js
index 1736b3e..f42834f 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/costReimburseUtils.js
+++ b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/costReimburseUtils.js
@@ -201,6 +201,7 @@
     reimburseReason: "",
     applyAmount: undefined,
     payee: "",
+    payer: "",
     payeeAccount: "",
     bankBranch: "",
     expenseDetails: [],
@@ -295,6 +296,7 @@
     reimburseReason: raw.reimburseReason ?? "",
     applyAmount,
     payee: raw.payee ?? "",
+    payer: raw.payer ?? "",
     payeeAccount: raw.payeeAccount ?? "",
     bankBranch: raw.bankBranch ?? "",
     expenseDetails,
diff --git a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/index.vue b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/index.vue
index 661c990..a74d541 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/index.vue
+++ b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/index.vue
@@ -12,12 +12,43 @@
           :prefix-icon="Search"
           @keyup.enter="handleQuery"
         />
+        <span class="search_title" style="margin-left: 10px;">閮ㄩ棬锛�</span>
+        <el-tree-select
+          v-model="searchForm.deptId"
+          :data="deptOptions"
+          :props="{ value: 'id', label: 'label', children: 'children' }"
+          value-key="id"
+          placeholder="閫夋嫨閮ㄩ棬"
+          check-strictly
+          clearable
+          style="width: 180px"
+        />
+        <span class="search_title" style="margin-left: 10px;">椤圭洰锛�</span>
+        <el-select v-model="searchForm.expenseCategory" clearable placeholder="閫夋嫨椤圭洰" style="width: 150px">
+          <el-option
+            v-for="opt in EXPENSE_CATEGORY_OPTIONS"
+            :key="opt.value"
+            :label="opt.label"
+            :value="opt.value"
+          />
+        </el-select>
+        <span class="search_title" style="margin-left: 10px;">鐢宠鏃堕棿锛�</span>
+        <el-date-picker
+          v-model="searchForm.applyTimeRange"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="寮�濮�"
+          end-placeholder="缁撴潫"
+          value-format="YYYY-MM-DD"
+          clearable
+          style="width: 240px"
+        />
         <el-button type="primary" style="margin-left: 10px" @click="handleQuery">鎼滅储</el-button>
         <el-button @click="resetSearch">閲嶇疆</el-button>
       </div>
       <div class="search_actions">
 <!--        <el-button type="success" plain @click="handleImportClick">瀵煎叆</el-button>-->
-<!--        <el-button type="warning" plain @click="handleExport">瀵煎嚭</el-button>-->
+        <el-button type="warning" plain @click="handleExport">瀵煎嚭</el-button>
         <el-button type="primary" @click="openFormDialog('add')">鏂板璐圭敤鎶ラ攢</el-button>
       </div>
     </div>
@@ -79,12 +110,21 @@
         <el-card class="form-section" shadow="never">
           <template #header><span class="card-header-title">鍩烘湰淇℃伅</span></template>
           <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="鍛樺伐缂栧彿">
-                <el-input v-model="form.employeeNo" readonly placeholder="閫夋嫨鍛樺伐鍚庤嚜鍔ㄥ甫鍑�" />
+            <el-col :span="8">
+              <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
+                <el-tree-select
+                  v-model="form.deptId"
+                  :data="deptOptions"
+                  :props="{ value: 'id', label: 'label', children: 'children' }"
+                  value-key="id"
+                  placeholder="璇烽�夋嫨閮ㄩ棬"
+                  check-strictly
+                  style="width: 100%"
+                  @change="onDeptChange"
+                />
               </el-form-item>
             </el-col>
-            <el-col :span="12">
+            <el-col :span="8">
               <el-form-item label="鍛樺伐濮撳悕" prop="applicantId">
                 <el-select
                   v-model="form.applicantId"
@@ -105,6 +145,11 @@
                     :value="u.userId"
                   />
                 </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="鍛樺伐缂栧彿">
+                <el-input v-model="form.employeeNo" readonly placeholder="閫夋嫨鍛樺伐鍚庤嚜鍔ㄥ甫鍑�" />
               </el-form-item>
             </el-col>
           </el-row>
@@ -248,17 +293,22 @@
         <el-card class="form-section" shadow="never">
           <template #header><span class="card-header-title">鏀舵淇℃伅</span></template>
           <el-row :gutter="20">
-            <el-col :span="8">
+            <el-col :span="6">
+              <el-form-item label="浠樻鏂�" prop="payer">
+                <el-input v-model="form.payer" placeholder="璇疯緭鍏ヤ粯娆炬柟" maxlength="50" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
               <el-form-item label="鏀舵浜�" prop="payee">
                 <el-input v-model="form.payee" placeholder="璇疯緭鍏ユ敹娆句汉" maxlength="50" />
               </el-form-item>
             </el-col>
-            <el-col :span="8">
+            <el-col :span="6">
               <el-form-item label="鏀舵璐﹀彿" prop="payeeAccount">
                 <el-input v-model="form.payeeAccount" placeholder="閾惰鍗″彿" maxlength="30" />
               </el-form-item>
             </el-col>
-            <el-col :span="8">
+            <el-col :span="6">
               <el-form-item label="寮�鎴锋敮琛�" prop="bankBranch">
                 <el-input v-model="form.bankBranch" placeholder="寮�鎴锋敮琛屽叏绉�" maxlength="100" />
               </el-form-item>
@@ -404,6 +454,7 @@
   approveOpinion,
   applicantFormSearchLoading,
   applicantFormOptions,
+  deptOptions,
   flowUserOptions,
   detailTotalAmount,
   approvalRuleHint,
@@ -413,6 +464,7 @@
   remoteSearchApplicantForm,
   userSelectLabel,
   onApplicantChange,
+  onDeptChange,
   onExpenseCategoryChange,
   applyTemplate,
   onDetailAmountChange,
diff --git a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/useCostReimburse.js b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/useCostReimburse.js
index 3b90a3b..9d8b616 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/useCostReimburse.js
+++ b/src/views/officeProcessAutomation/ReimburseManage/cost-reimburse/useCostReimburse.js
@@ -7,7 +7,7 @@
   persistFinReimbursement,
 } from "@/api/officeProcessAutomation/finReimbursement.js";
 import { ElMessageBox } from "element-plus";
-import { userListNoPageByTenantId } from "@/api/system/user.js";
+import { userListNoPageByTenantId, deptTreeSelect } from "@/api/system/user.js";
 import { computed, getCurrentInstance, nextTick, onMounted, reactive, ref } from "vue";
 import {
   buildCostReimbursementSaveDto,
@@ -72,6 +72,9 @@
 
   const searchForm = reactive({
     applicantKeyword: "",
+    deptId: undefined,
+    expenseCategory: "",
+    applyTimeRange: [],
   });
   const tableLoading = ref(false);
   const page = reactive({ current: 1, size: 10, total: 0 });
@@ -79,6 +82,7 @@
   const allUsersCache = ref([]);
   const applicantFormSearchLoading = ref(false);
   const applicantFormOptions = ref([]);
+  const deptOptions = ref([]);
   const formRef = ref();
   const form = reactive(createEmptyForm());
   const formDialog = reactive({ visible: false, title: "", mode: "add", readonly: false });
@@ -151,6 +155,9 @@
     { label: "鎶ラ攢鍗曞彿", prop: "reimburseNo", width: 150 },
     { label: "鐢宠浜虹紪鍙�", prop: "applicantNo", width: 110 },
     { label: "鐢宠浜�", prop: "applicantName", minWidth: 90 },
+    { label: "閮ㄩ棬", prop: "applicantDeptName", minWidth: 100 },
+    { label: "璐圭敤绫诲瀷", prop: "expenseCategory", minWidth: 90, formatData: (v) => expenseCategoryLabel(v) },
+    { label: "浠樻鏂�", prop: "payer", minWidth: 100 },
     { label: "鎶ラ攢閲戦(鍏�)", prop: "applyAmount", width: 110 },
     { label: "鎶ラ攢鍘熷洜", prop: "reimburseReason", minWidth: 160, showOverflowTooltip: true },
     { label: "鐢宠鏃堕棿", prop: "applyTime", width: 165 },
@@ -194,6 +201,7 @@
   ]);
 
   const formRules = {
+    deptId: [{ required: true, message: "璇烽�夋嫨褰掑睘閮ㄩ棬", trigger: "change" }],
     applicantId: [{ required: true, message: "璇烽�夋嫨鍛樺伐", trigger: "change" }],
     expenseCategory: [{ required: true, message: "璇烽�夋嫨璐圭敤绫诲瀷", trigger: "change" }],
     reimburseReason: [{ required: true, message: "璇峰~鍐欐姤閿�鍘熷洜", trigger: "blur" }],
@@ -222,21 +230,39 @@
 
   async function loadUserPool() {
     try {
-      allUsersCache.value = unwrapArray(await userListNoPageByTenantId());
+      allUsersCache.value = unwrapArray(await userListNoPageByTenantId({}));
     } catch {
       allUsersCache.value = [];
+    }
+  }
+
+  function formatDeptOptions(list) {
+    return (list || []).map((d) => ({
+      ...d,
+      rawLabel: d.label,
+      label: d.label, // 閮ㄩ棬涓嬫媺涓嶈鏄剧ずid
+      children: d.children && d.children.length ? formatDeptOptions(d.children) : undefined,
+    }));
+  }
+
+  async function loadDeptOptions() {
+    try {
+      const res = await deptTreeSelect();
+      deptOptions.value = formatDeptOptions(res.data || []);
+    } catch {
+      deptOptions.value = [];
     }
   }
 
   function userSelectLabel(u) {
     const nick = u.nickName || "";
     const name = u.userName || "";
-    if (nick && name && nick !== name) return `${nick}锛�${name}锛塦;
-    return nick || name || `鐢ㄦ埛${u.userId ?? u.id ?? ""}`;
+    const empNo = employeeNoFromUser(u);
+    return `${nick || name || "鐢ㄦ埛"} - ${empNo}`;
   }
 
   function userById(id) {
-    return allUsersCache.value.find((u) => String(u.userId ?? u.id) === String(id));
+    return applicantFormOptions.value.find((u) => String(u.userId ?? u.id) === String(id));
   }
 
   function employeeNoFromUser(u) {
@@ -244,22 +270,21 @@
     return u.userName ?? u.userCode ?? u.jobNumber ?? u.workNo ?? (u.userId != null ? String(u.userId) : "");
   }
 
-  function filterUsersByQuery(query) {
-    const list = allUsersCache.value.filter(isActiveUser);
-    const q = (query || "").trim().toLowerCase();
-    if (!q) return [...list];
-    return list.filter((u) => {
-      const nick = (u.nickName || "").toLowerCase();
-      const uname = (u.userName || "").toLowerCase();
-      return nick.includes(q) || uname.includes(q);
-    });
-  }
-
   async function remoteSearchApplicantForm(query) {
     applicantFormSearchLoading.value = true;
     try {
-      if (!allUsersCache.value.length) await loadUserPool();
-      applicantFormOptions.value = filterUsersByQuery(query);
+      const q = (query || "").trim();
+      const params = {};
+      if (form.deptId) {
+        params.deptId = form.deptId;
+      }
+      if (q) {
+        params.nickName = q; // You can pass nickName to backend
+      }
+      const res = await userListNoPageByTenantId(params);
+      applicantFormOptions.value = unwrapArray(res).filter(isActiveUser);
+    } catch {
+      applicantFormOptions.value = [];
     } finally {
       applicantFormSearchLoading.value = false;
     }
@@ -271,11 +296,46 @@
       form.employeeName = u.nickName || u.userName || "";
       form.employeeNo = employeeNoFromUser(u);
       form.payee = form.payee || form.employeeName;
-      form.deptId = String(u.deptId ?? u.sysDeptId ?? "");
-      form.deptName = u.dept?.deptName ?? u.deptName ?? "";
+      const userDeptId = String(u.deptId ?? u.sysDeptId ?? "");
+      if (userDeptId && form.deptId !== userDeptId) {
+        form.deptId = userDeptId;
+        const name = findDeptLabel(deptOptions.value, userDeptId);
+        form.deptName = name || (u.dept?.deptName ?? u.deptName ?? "");
+      }
     } else {
       form.employeeName = "";
       form.employeeNo = "";
+    }
+  }
+
+  function findDeptLabel(nodes, id) {
+    if (!nodes) return null;
+    for (const node of nodes) {
+      if (String(node.id) === String(id)) return node.rawLabel || node.label;
+      if (node.children) {
+        const hit = findDeptLabel(node.children, id);
+        if (hit) return hit;
+      }
+    }
+    return null;
+  }
+
+  function onDeptChange(deptId) {
+    if (deptId) {
+      const name = findDeptLabel(deptOptions.value, deptId);
+      if (name) form.deptName = name;
+      
+      remoteSearchApplicantForm("");
+      if (form.applicantId) {
+        const u = userById(form.applicantId);
+        if (u && String(u.deptId ?? u.sysDeptId) !== String(deptId)) {
+          form.applicantId = "";
+          onApplicantChange("");
+        }
+      }
+    } else {
+      form.deptName = "";
+      remoteSearchApplicantForm("");
     }
   }
 
@@ -431,17 +491,13 @@
         proxy?.$modal?.msgError?.("鍔犺浇鎶ラ攢璇︽儏澶辫触");
         return;
       }
-      Object.assign(form, {
-        ...JSON.parse(JSON.stringify(editRow)),
-        reimbursementId: editRow.reimbursementId ?? editRow.id,
-        attachmentList: JSON.parse(JSON.stringify(editRow.attachmentList || editRow.invoiceAttachments || [])),
-        approvalFlowNodes: JSON.parse(JSON.stringify(editRow.approvalFlowNodes || [])),
-        expenseDetails: JSON.parse(JSON.stringify(editRow.expenseDetails || [])),
-      });
+      Object.assign(form, buildCostReimbursementSaveDto(editRow));
+      formDialog.title = "缂栬緫璐圭敤鎶ラ攢";
+      await remoteSearchApplicantForm("");
       const u = userById(editRow.applicantId);
-      applicantFormOptions.value = u
-        ? [u]
-        : [{ userId: editRow.applicantId, nickName: editRow.employeeName, userName: editRow.employeeNo }];
+      if (!u) {
+        applicantFormOptions.value.unshift({ userId: editRow.applicantId, nickName: editRow.employeeName, userName: editRow.applicantCode });
+      }
     } else {
       form.approvalFlowNodes = buildAutoApprovalFlow(0, "other");
       remoteSearchApplicantForm("");
@@ -532,15 +588,17 @@
   }
 
   function handleExport() {
-    const data = allRows.value;
-    const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json;charset=utf-8" });
-    const url = URL.createObjectURL(blob);
-    const a = document.createElement("a");
-    a.href = url;
-    a.download = `璐圭敤鎶ラ攢瀵煎嚭_${dayjs().format("YYYYMMDDHHmmss")}.json`;
-    a.click();
-    URL.revokeObjectURL(url);
-    proxy?.$modal?.msgSuccess?.(`宸插鍑� ${data.length} 鏉);
+    const params = buildFinReimbursementListParams({
+      page: { current: 1, size: 99999 }, // Just so the function doesn't crash, backend export ignores pagination anyway
+      searchForm,
+      reimbursementType: FIN_REIMBURSEMENT_TYPE.COST,
+    });
+    // Remove pagination parameters since export doesn't need them
+    delete params.current;
+    delete params.size;
+    delete params["page.current"];
+    delete params["page.size"];
+    proxy.download("/finReimbursement/export", params, `璐圭敤鎶ラ攢瀵煎嚭_${dayjs().format("YYYYMMDDHHmmss")}.xlsx`);
   }
 
   function handleImportClick() {
@@ -572,6 +630,7 @@
 
   onMounted(async () => {
     loadUserPool();
+    loadDeptOptions();
     await fetchList();
     const editPayload = consumeReimburseEditFromApprove();
     if (editPayload?.reimbursementId != null) {
@@ -603,6 +662,7 @@
     approveOpinion,
     applicantFormSearchLoading,
     applicantFormOptions,
+    deptOptions,
     flowUserOptions,
     detailTotalAmount,
     approvalRuleHint,
@@ -612,6 +672,7 @@
     remoteSearchApplicantForm,
     userSelectLabel,
     onApplicantChange,
+    onDeptChange,
     onExpenseCategoryChange,
     applyTemplate,
     onDetailAmountChange,
diff --git a/src/views/officeProcessAutomation/ReimburseManage/shared/finReimbursementMappers.js b/src/views/officeProcessAutomation/ReimburseManage/shared/finReimbursementMappers.js
index 2525f70..85029bc 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/shared/finReimbursementMappers.js
+++ b/src/views/officeProcessAutomation/ReimburseManage/shared/finReimbursementMappers.js
@@ -173,29 +173,61 @@
   return out;
 }
 
-/** 鏄惁瀛樺湪鍒楄〃绛涢�夋潯浠讹紙浠呯敵璇蜂汉锛� */
-export function hasActiveReimbursementSearch(searchForm = {}) {
-  return Boolean((searchForm?.applicantKeyword || "").trim());
+
+export function expenseTypeToCategory(typeLabel) {
+  const hit = EXPENSE_CATEGORY_OPTIONS.find((x) => x.label === typeLabel || x.value === typeLabel);
+  return hit?.value || typeLabel || "";
 }
 
-/** 鏈嶅姟绔湭鐢熸晥鏃讹紝鎸夌敵璇蜂汉鍋氬墠绔厹搴曠瓫閫� */
+/** 鏄惁瀛樺湪鍒楄〃绛涢�夋潯浠� */
+export function hasActiveReimbursementSearch(searchForm = {}) {
+  return Boolean(
+    (searchForm?.applicantKeyword || "").trim() ||
+    searchForm?.deptId ||
+    searchForm?.expenseCategory ||
+    (searchForm?.applyTimeRange && searchForm.applyTimeRange.length === 2)
+  );
+}
+
+/** 鏈嶅姟绔湭鐢熸晥鏃讹紝鎸夋潯浠跺仛鍓嶇鍏滃簳绛涢�� */
 export function filterReimbursementRowsBySearch(rows, searchForm = {}) {
   const list = Array.isArray(rows) ? rows : [];
-  const kw = (searchForm?.applicantKeyword || "").trim().toLowerCase();
-  if (!kw) return list;
+  let result = list;
 
-  return list.filter((row) => {
-    const parts = [
-      row.applicantName,
-      row.employeeName,
-      row.applicantNo,
-      row.applicantCode,
-      row.employeeNo,
-    ]
-      .filter((v) => v != null && v !== "")
-      .map((v) => String(v).toLowerCase());
-    return parts.some((p) => p.includes(kw));
-  });
+  const kw = (searchForm?.applicantKeyword || "").trim().toLowerCase();
+  if (kw) {
+    result = result.filter((row) => {
+      const parts = [
+        row.applicantName,
+        row.employeeName,
+        row.applicantNo,
+        row.applicantCode,
+        row.employeeNo,
+      ]
+        .filter((v) => v != null && v !== "")
+        .map((v) => String(v).toLowerCase());
+      return parts.some((p) => p.includes(kw));
+    });
+  }
+
+  if (searchForm?.deptId) {
+    result = result.filter(row => String(row.deptId) === String(searchForm.deptId));
+  }
+
+  if (searchForm?.expenseCategory) {
+    result = result.filter(row => row.expenseCategory === searchForm.expenseCategory);
+  }
+
+  if (searchForm?.applyTimeRange && searchForm.applyTimeRange.length === 2) {
+    const start = searchForm.applyTimeRange[0];
+    const end = searchForm.applyTimeRange[1];
+    result = result.filter(row => {
+      const t = (row.applyTime || row.createTime || "").substring(0, 10);
+      return t >= start && t <= end;
+    });
+  }
+
+  return result;
 }
 
 /** 鎵佸钩鍖栦负 Spring GET 鍙粦瀹氱殑 query锛坒inReimbursementDto.xxx锛屽嬁鐢ㄦ柟鎷彿锛� */
@@ -216,6 +248,10 @@
 }) {
   const dto = {
     reimbursementType,
+    deptId: searchForm.deptId || undefined,
+    expenseType: searchForm.expenseCategory ? expenseCategoryToType(searchForm.expenseCategory) : undefined,
+    createTimeStart: searchForm.applyTimeRange?.[0] || undefined,
+    createTimeEnd: searchForm.applyTimeRange?.[1] || undefined,
     ...pickApplicantQuery(searchForm),
     ...(extraDto && typeof extraDto === "object" ? extraDto : {}),
   };
@@ -227,6 +263,12 @@
     "page.size": page.size,
     ...dto,
   };
+  
+  if (searchForm.applyTimeRange && searchForm.applyTimeRange.length === 2) {
+    params["params[beginTime]"] = searchForm.applyTimeRange[0] + " 00:00:00";
+    params["params[endTime]"] = searchForm.applyTimeRange[1] + " 23:59:59";
+  }
+
   appendDotNotationQuery(params, "finReimbursementDto", dto);
   return params;
 }
@@ -319,7 +361,8 @@
     applicantName: row.applicantName || "",
     employeeNo: row.applicantCode || "",
     employeeName: row.applicantName || "",
-    applicantDeptName: row.applicantDeptName || "",
+    applicantDeptName: row.deptName || "",
+    deptId: row.deptId,
     reimburseReason: row.reason || "",
     travelStartTime: formatReimbursementDateTime(travel.startTime),
     travelEndTime: formatReimbursementDateTime(travel.endTime),
@@ -375,12 +418,14 @@
     applicantName: row.applicantName || "",
     employeeNo: row.applicantCode || "",
     employeeName: row.applicantName || "",
-    applicantDeptName: row.applicantDeptName || "",
+    applicantDeptName: row.deptName || "",
+    deptId: row.deptId,
     reimburseReason: row.reason || "",
-    expenseCategory: row.expenseType || "",
+    expenseCategory: expenseTypeToCategory(row.expenseType) || "",
     applyAmount: row.applyAmount,
     applyTime: formatReimbursementDateTime(row.createTime),
     payee: row.payeeName || "",
+    payer: row.payer || "",
     payeeAccount: row.payeeAccount || "",
     bankBranch: row.payeeBank || "",
     billStatus: row.billStatus,
@@ -846,6 +891,7 @@
     applyAmount,
     detailTotalAmount: detailTotal,
     payeeName: form.payee || "",
+    payer: form.payer || "",
     payeeAccount: form.payeeAccount || "",
     payeeBank: form.bankBranch || form.payeeBank || "",
     billStatus: "IN_APPROVAL",
diff --git a/src/views/projectManagement/Management/components/ArchiveDialog.vue b/src/views/projectManagement/Management/components/ArchiveDialog.vue
new file mode 100644
index 0000000..01f69cd
--- /dev/null
+++ b/src/views/projectManagement/Management/components/ArchiveDialog.vue
@@ -0,0 +1,175 @@
+<template>
+  <el-dialog
+    title="鏂囨。褰掓。"
+    v-model="visible"
+    width="650px"
+    destroy-on-close
+    append-to-body
+  >
+    <div class="archive-container" v-loading="loading">
+      <el-empty v-if="!loading && (!archiveGroups || archiveGroups.length === 0)" description="鏆傛棤褰掓。闄勪欢" />
+      
+      <el-collapse v-else v-model="activeNames">
+        <el-collapse-item 
+          v-for="(group, index) in archiveGroups" 
+          :key="index" 
+          :title="`${group.moduleName} (${group.files ? group.files.length : 0})`" 
+          :name="index"
+        >
+          <div class="attachment-list">
+            <div 
+              v-for="(file, fileIdx) in group.files" 
+              :key="fileIdx" 
+              class="attachment-item"
+            >
+              <el-icon class="file-icon"><Document /></el-icon>
+              <a 
+                :href="getRealUrl(file.url)" 
+                target="_blank" 
+                class="file-link"
+                :title="file.name"
+              >
+                {{ file.name }}
+              </a>
+              <el-button link type="primary" class="download-btn" @click="handleDownload(file.url, file.name)">涓嬭浇</el-button>
+            </div>
+          </div>
+        </el-collapse-item>
+      </el-collapse>
+    </div>
+    
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="visible = false">鍏抽棴</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { getProjectAttachments } from '@/api/projectManagement/project'
+import { Document } from '@element-plus/icons-vue'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  projectId: {
+    type: [Number, String],
+    default: null
+  }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const visible = ref(false)
+const loading = ref(false)
+const archiveGroups = ref([])
+const activeNames = ref([])
+
+watch(() => props.modelValue, (val) => {
+  visible.value = val
+  if (val && props.projectId) {
+    fetchAttachments()
+  } else {
+    archiveGroups.value = []
+    activeNames.value = []
+  }
+})
+
+watch(() => visible.value, (val) => {
+  emit('update:modelValue', val)
+})
+
+const fetchAttachments = async () => {
+  loading.value = true
+  try {
+    const res = await getProjectAttachments(props.projectId)
+    if (res.code === 200) {
+      archiveGroups.value = res.data || []
+      // 榛樿灞曞紑鎵�鏈夐潰鏉�
+      activeNames.value = archiveGroups.value.map((_, index) => index)
+    }
+  } catch (error) {
+    console.error('鑾峰彇闄勪欢澶辫触', error)
+  } finally {
+    loading.value = false
+  }
+}
+
+// 鑾峰彇鐪熷疄鍦板潃锛堝鐞嗗彲鑳界殑鐩稿璺緞鍓嶇紑锛�
+const getRealUrl = (url) => {
+  if (!url) return '#'
+  if (url.startsWith('http://') || url.startsWith('https://')) {
+    return url
+  }
+  return import.meta.env.VITE_APP_BASE_API + url
+}
+
+// 鎻愬彇鏂囦欢鍚�(鍏煎鏃ч�昏緫)
+const getFileName = (url) => {
+  if (!url) return '鏈煡鏂囦欢'
+  const parts = url.split('/')
+  const name = parts[parts.length - 1]
+  // 澶勭悊鍙兘鐨勬椂闂存埑鍓嶇紑
+  const nameParts = name.split('_')
+  return nameParts.length > 1 ? nameParts.slice(1).join('_') : name
+}
+
+const handleDownload = (url, name) => {
+  const realUrl = getRealUrl(url)
+  const a = document.createElement('a')
+  a.style.display = 'none'
+  a.href = realUrl
+  a.download = name || getFileName(url)
+  document.body.appendChild(a)
+  a.click()
+  document.body.removeChild(a)
+}
+</script>
+
+<style scoped>
+.archive-container {
+  min-height: 200px;
+}
+.attachment-list {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  padding: 5px 0;
+}
+.attachment-item {
+  display: flex;
+  align-items: center;
+  padding: 8px 12px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  transition: background-color 0.3s;
+}
+.attachment-item:hover {
+  background-color: #f0f2f5;
+}
+.file-icon {
+  font-size: 16px;
+  color: #909399;
+  margin-right: 8px;
+}
+.file-link {
+  flex: 1;
+  color: #606266;
+  text-decoration: none;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  margin-right: 15px;
+}
+.file-link:hover {
+  color: #409EFF;
+  text-decoration: underline;
+}
+.download-btn {
+  margin-left: auto;
+}
+</style>
diff --git a/src/views/projectManagement/Management/components/ContractListDialog.vue b/src/views/projectManagement/Management/components/ContractListDialog.vue
new file mode 100644
index 0000000..561297d
--- /dev/null
+++ b/src/views/projectManagement/Management/components/ContractListDialog.vue
@@ -0,0 +1,104 @@
+<template>
+  <el-dialog
+    title="閿�鍞悎鍚屽垪琛�"
+    v-model="visible"
+    width="800px"
+    append-to-body
+    destroy-on-close
+    @open="handleOpen"
+  >
+    <div v-loading="loading">
+      <el-table :data="tableData" border style="width: 100%">
+        <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+        <el-table-column prop="salesContractNo" label="閿�鍞悎鍚岀紪鍙�" align="center" show-overflow-tooltip />
+        <el-table-column prop="customerName" label="瀹㈡埛鍚嶇О" align="center" show-overflow-tooltip />
+      </el-table>
+      
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.current"
+        v-model:limit="queryParams.size"
+        @pagination="getList"
+      />
+    </div>
+    
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="visible = false">鍏� 闂�</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, watch, reactive } from 'vue'
+import { ledgerListPage } from '@/api/salesManagement/salesLedger'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  projectId: {
+    type: [Number, String],
+    default: null
+  }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const visible = ref(false)
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  projectId: undefined
+})
+
+watch(() => props.modelValue, (val) => {
+  visible.value = val
+})
+
+watch(visible, (val) => {
+  emit('update:modelValue', val)
+})
+
+function handleOpen() {
+  queryParams.current = 1
+  queryParams.projectId = props.projectId
+  getList()
+}
+
+function getList() {
+  if (!queryParams.projectId) {
+    tableData.value = []
+    total.value = 0
+    return
+  }
+  
+  loading.value = true
+  ledgerListPage(queryParams).then(res => {
+    const records = res?.data?.records || res?.records || res?.rows || []
+    
+    // 濡傛灉涓�鏉¤褰曚篃娌℃湁涓斿湪绗竴椤典互鍚庯紝鍙兘闇�瑕侀噸缃垎椤�
+    // 鍓嶇瑕佹眰鏄剧ず鈥滈攢鍞悎鍚岀紪鍙封�濆拰鈥滃鎴峰悕绉扳�濓紝杩欎簺瀛楁鍦� salesLedgerListPage 杩斿洖鐨勬暟鎹腑瀛樺湪
+    tableData.value = records
+    total.value = res?.data?.total || res?.total || 0
+  }).catch(() => {
+    tableData.value = []
+    total.value = 0
+  }).finally(() => {
+    loading.value = false
+  })
+}
+</script>
+
+<style scoped>
+.dialog-footer {
+  text-align: right;
+}
+</style>
diff --git a/src/views/projectManagement/Management/index.vue b/src/views/projectManagement/Management/index.vue
index 0438aef..67e51c6 100644
--- a/src/views/projectManagement/Management/index.vue
+++ b/src/views/projectManagement/Management/index.vue
@@ -56,15 +56,21 @@
         <template #projectStage="{ row }">
           <dict-tag :options="plan_status" :value="row.projectStage" />
         </template>
+        <template #salesContractCount="{ row }">
+          <el-button link type="primary" @click="handleOpenContractDialog(row)">{{ row.salesContractCount || 0 }}</el-button>
+        </template>
         <template #action="{ row }">
           <el-button link type="primary" @click="handleEdit(row)">缂栬緫</el-button>
           <el-button link type="primary" :loading="progressBtnLoadingId===row.id" @click="handleProgressReport(row)">杩涘害姹囨姤</el-button>
+          <el-button link type="primary" @click="handleArchive(row)">鏂囨。褰掓。</el-button>
           <el-button link type="primary" @click="handleDetail(row)">璇︽儏</el-button>
         </template>
       </PIMTable>
     </div>
 
     <FormDia ref="formDiaRef" @completed="getList" />
+    <ArchiveDialog v-model="archiveVisible" :project-id="archiveProjectId" />
+    <ContractListDialog v-model="contractVisible" :project-id="contractProjectId" />
     <ProgressReportDialog
       v-model="progressReportVisible"
       :project-id="progressProjectId"
@@ -82,6 +88,8 @@
 import SearchPanel from '@/components/SearchPanel/index.vue'
 import PIMTable from '@/components/PIMTable/PIMTable.vue'
 import FormDia from './components/formDia.vue'
+import ArchiveDialog from './components/ArchiveDialog.vue'
+import ContractListDialog from './components/ContractListDialog.vue'
 import ProgressReportDialog from '@/components/ProjectManagement/ProgressReportDialog.vue'
 import {
   listProject,
@@ -111,6 +119,10 @@
 const progressPlanNodes = ref([])
 const progressDefaultPlanNodeId = ref(undefined)
 const progressBtnLoadingId = ref(null)
+const archiveVisible = ref(false)
+const archiveProjectId = ref(null)
+const contractVisible = ref(false)
+const contractProjectId = ref(null)
 const submitLoading = ref(false)
 const auditLoading = ref(false)
 const reverseAuditLoading = ref(false)
@@ -154,6 +166,7 @@
   { label: '绔嬮」鏃ユ湡', prop: 'setupDate', align: 'center', width: '120' },
   { label: '椤圭洰鏉ユ簮', prop: 'projectSource', align: 'center' },
   { label: '椤圭洰鍒嗙被', prop: 'projectClassification', align: 'center' },
+  { label: '閿�鍞悎鍚屾�绘暟', prop: 'salesContractCount', align: 'center', dataType: 'slot', slot: 'salesContractCount' },
   { label: '鎿嶄綔', prop: 'action', align: 'center', width: '250', dataType: 'slot', slot: 'action', fixed: 'right' }
 ]
 
@@ -188,6 +201,7 @@
         projectType: r.planName ?? r.projectType,
         projectSource: r.source ?? r.projectSource,
         projectClassification: r.departmentName ?? r.projectClassification,
+        salesContractCount: r.salesContractCount,
         raw: r
       }))
       pagination.value.total = response?.total || response?.data?.total || 0
@@ -407,6 +421,18 @@
   formDiaRef.value?.openDialog({ operationType: 'edit', row })
 }
 
+function handleArchive(row) {
+  if (!row?.id) return
+  archiveProjectId.value = row.id
+  archiveVisible.value = true
+}
+
+function handleOpenContractDialog(row) {
+  if (!row?.id) return
+  contractProjectId.value = row.id
+  contractVisible.value = true
+}
+
 onMounted(() => {
   getList()
 })
diff --git a/src/views/projectManagement/config/index.vue b/src/views/projectManagement/config/index.vue
new file mode 100644
index 0000000..5f0aaf1
--- /dev/null
+++ b/src/views/projectManagement/config/index.vue
@@ -0,0 +1,109 @@
+<template>
+  <div class="app-container">
+    <el-card class="box-card" shadow="never">
+      <template #header>
+        <div class="card-header">
+          <span>涓氬姟鍙傛暟璁剧疆</span>
+        </div>
+      </template>
+      <el-form 
+        ref="configFormRef" 
+        :model="form" 
+        :rules="rules" 
+        label-width="240px" 
+        style="max-width: 600px; margin-top: 20px;"
+      >
+        <el-form-item label="鍚堝悓鍘熶欢绾﹀畾鍥炰紶鎻愬墠鎻愰啋澶╂暟" prop="contractReturnReminderDays">
+          <el-input-number 
+            v-model="form.contractReturnReminderDays" 
+            :min="1" 
+            :max="365" 
+            :step="1" 
+            placeholder="璇疯緭鍏ュぉ鏁�" 
+            style="width: 200px"
+          />
+          <span style="margin-left: 10px; color: #999;">澶�</span>
+        </el-form-item>
+        
+        <el-form-item>
+          <el-button type="primary" :loading="submitLoading" @click="handleSubmit">淇濆瓨璁剧疆</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script setup name="ProjectConfig">
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import { getConfig, updateConfig } from '@/api/projectManagement/config'
+
+const configFormRef = ref(null)
+const submitLoading = ref(false)
+const originalData = ref({})
+
+const form = reactive({
+  id: undefined,
+  contractReturnReminderDays: 3
+})
+
+const rules = {
+  contractReturnReminderDays: [
+    { required: true, message: '鎻愬墠鎻愰啋澶╂暟涓嶈兘涓虹┖', trigger: 'blur' }
+  ]
+}
+
+const loadData = async () => {
+  try {
+    const res = await getConfig()
+    if (res.code === 200 && res.data) {
+      Object.assign(form, res.data)
+      originalData.value = JSON.parse(JSON.stringify(res.data))
+    }
+  } catch (error) {
+    console.error('鑾峰彇閰嶇疆澶辫触:', error)
+  }
+}
+
+const handleSubmit = async () => {
+  if (!configFormRef.value) return
+  await configFormRef.value.validate(async (valid) => {
+    if (valid) {
+      submitLoading.value = true
+      try {
+        const res = await updateConfig(form)
+        if (res.code === 200) {
+          ElMessage.success('閰嶇疆鏇存柊鎴愬姛')
+          loadData()
+        }
+      } catch (error) {
+        console.error('鏇存柊閰嶇疆澶辫触:', error)
+      } finally {
+        submitLoading.value = false
+      }
+    }
+  })
+}
+
+const handleReset = () => {
+  if (originalData.value.id) {
+    Object.assign(form, originalData.value)
+  } else {
+    form.contractReturnReminderDays = 3
+  }
+}
+
+onMounted(() => {
+  loadData()
+})
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+.box-card {
+  min-height: calc(100vh - 124px);
+}
+</style>
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 94801ff..b2b271f 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -169,13 +169,57 @@
           </el-col>
         </el-row>
       </el-form>
+      <el-row class="mb8" v-if="!isViewMode">
+        <el-button type="primary" plain icon="Plus" @click="handleAddRow">鏂板涓�琛�</el-button>
+      </el-row>
       <PIMTable rowKey="id"
                 :column="tableColumn"
                 :tableData="tableData"
                 :tableLoading="tableLoading"
                 height="400">
+        <template #parameterItemSlot="{ row }">
+          <span v-if="isViewMode">{{ row.parameterItem }}</span>
+          <el-input v-else v-model="row.parameterItem" placeholder="璇疯緭鍏�" />
+        </template>
+        <template #parameterTypeSlot="{ row }">
+          <span v-if="isViewMode">{{ row.parameterType === 1 ? '鏁板瓧' : row.parameterType === 0 ? '鏂囧瓧' : '' }}</span>
+          <el-select v-else v-model="row.parameterType" @change="handleTypeChange(row)">
+            <el-option label="鏂囧瓧" :value="0" />
+            <el-option label="鏁板瓧" :value="1" />
+          </el-select>
+        </template>
+        <template #maxValueSlot="{ row }">
+          <span v-if="isViewMode">{{ row.maxValue }}</span>
+          <el-input-number v-else v-model="row.maxValue" :controls="false" :disabled="row.parameterType !== 1" style="width: 100%" />
+        </template>
+        <template #minValueSlot="{ row }">
+          <span v-if="isViewMode">{{ row.minValue }}</span>
+          <el-input-number v-else v-model="row.minValue" :controls="false" :disabled="row.parameterType !== 1" style="width: 100%" />
+        </template>
+        <template #unitSlot="{ row }">
+          <span v-if="isViewMode">{{ row.unit }}</span>
+          <el-input v-else v-model="row.unit" />
+        </template>
+        <template #standardValueSlot="{ row }">
+          <span v-if="isViewMode">{{ row.standardValue }}</span>
+          <el-input v-else v-model="row.standardValue" :disabled="row.parameterType !== 0" />
+        </template>
+        <template #controlValueSlot="{ row }">
+          <span v-if="isViewMode">{{ row.controlValue }}</span>
+          <el-input v-else v-model="row.controlValue" />
+        </template>
+        <template #operationSlot="{ row }">
+          <el-button v-if="!isViewMode" type="danger" link @click="removeRow(row)">鍒犻櫎</el-button>
+        </template>
         <template #slot="{ row }">
-          <el-input v-model="row.testValue"
+          <el-input-number v-if="row.parameterType === 1"
+                           v-model="row.testValue"
+                           :controls="false"
+                           clearable
+                           :disabled="isViewMode"
+                           style="width: 100%" />
+          <el-input v-else
+                    v-model="row.testValue"
                     clearable
                     :disabled="isViewMode" />
         </template>
@@ -203,6 +247,7 @@
     computed,
     getCurrentInstance,
     nextTick,
+    watch
   } from "vue";
   import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
   import { modelList, productTreeList } from "@/api/basicData/product.js";
@@ -267,36 +312,121 @@
   });
   const supplierList = ref([]);
   const productOptions = ref([]);
-  const tableColumn = ref([
-    {
-      label: "鎸囨爣",
-      prop: "parameterItem",
-    },
-    {
-      label: "鍗曚綅",
-      prop: "unit",
-    },
-    {
-      label: "鏍囧噯鍊�",
-      prop: "standardValue",
-    },
-    {
-      label: "鍐呮帶鍊�",
-      prop: "controlValue",
-    },
-    {
-      label: "妫�楠屽��",
-      prop: "testValue",
-      dataType: "slot",
-      slot: "slot",
-    },
-  ]);
+  const tableColumn = computed(() => {
+    const cols = [
+      {
+        label: "鎸囨爣",
+        prop: "parameterItem",
+        dataType: "slot",
+        slot: "parameterItemSlot"
+      },
+      {
+        label: "鍙傛暟绫诲瀷",
+        prop: "parameterType",
+        dataType: "slot",
+        slot: "parameterTypeSlot",
+        width: "120"
+      },
+      {
+        label: "鏈�澶у��",
+        prop: "maxValue",
+        dataType: "slot",
+        slot: "maxValueSlot",
+        width: "100"
+      },
+      {
+        label: "鏈�灏忓��",
+        prop: "minValue",
+        dataType: "slot",
+        slot: "minValueSlot",
+        width: "100"
+      },
+      {
+        label: "鍗曚綅",
+        prop: "unit",
+        dataType: "slot",
+        slot: "unitSlot",
+        width: "100"
+      },
+      {
+        label: "鏍囧噯鍊�",
+        prop: "standardValue",
+        dataType: "slot",
+        slot: "standardValueSlot"
+      },
+      {
+        label: "鍐呮帶鍊�",
+        prop: "controlValue",
+        dataType: "slot",
+        slot: "controlValueSlot"
+      },
+      {
+        label: "妫�楠屽��",
+        prop: "testValue",
+        dataType: "slot",
+        slot: "slot",
+      }
+    ];
+    if (!isViewMode.value) {
+      cols.push({
+        label: "鎿嶄綔",
+        prop: "operation",
+        dataType: "slot",
+        slot: "operationSlot",
+        width: "80",
+        fixed: "right"
+      });
+    }
+    return cols;
+  });
   const tableData = ref([]);
   const tableLoading = ref(false);
   const userList = ref([]);
   const currentProductId = ref(0);
   const testStandardOptions = ref([]); // 鎸囨爣閫夋嫨涓嬫媺妗嗘暟鎹�
   const modelOptions = ref([]);
+
+  watch(() => tableData.value, (newVal) => {
+    if (isViewMode.value) return; 
+    if (!newVal || newVal.length === 0) return;
+    
+    let passCount = 0;
+    let failCount = 0;
+    
+    newVal.forEach(item => {
+      let isPass = false;
+      const val = item.testValue;
+      
+      if (val === null || val === undefined || val === '') {
+        isPass = false; 
+      } else if (item.parameterType === 1) {
+        const numVal = Number(val);
+        const min = Number(item.minValue);
+        const max = Number(item.maxValue);
+        if (!isNaN(numVal) && numVal >= min && numVal <= max) {
+          isPass = true;
+        }
+      } else {
+        if (String(val) === String(item.standardValue)) {
+          isPass = true;
+        }
+      }
+      
+      if (isPass) {
+        passCount++;
+      } else {
+        failCount++;
+      }
+    });
+    
+    if (failCount === 0 && passCount > 0) {
+      form.value.checkResult = "鍚堟牸";
+    } else if (passCount === 0 && failCount > 0) {
+      form.value.checkResult = "涓嶅悎鏍�";
+    } else {
+      form.value.checkResult = "閮ㄥ垎鍚堟牸";
+    }
+  }, { deep: true });
 
   // 鎵撳紑寮规
   const openDialog = async (type, row) => {
@@ -533,6 +663,10 @@
           ...item,
           id: null,
         }));
+        
+        if (tableData.value.some(item => item.parameterType === null || item.parameterType === undefined)) {
+          proxy.$modal.msgWarning("鍙傛暟绫诲瀷鏈厤缃紝璇烽厤缃寚鏍囩淮鎶ゆā鏉�");
+        }
       })
       .catch(error => {
         console.error("鑾峰彇鏍囧噯鍙傛暟澶辫触:", error);
@@ -547,6 +681,36 @@
       tableData.value = res.data;
     });
   };
+
+  const handleAddRow = () => {
+    tableData.value.push({
+      parameterItem: '',
+      parameterType: 0,
+      maxValue: undefined,
+      minValue: undefined,
+      unit: '',
+      standardValue: '',
+      controlValue: '',
+      testValue: ''
+    });
+  };
+
+  const removeRow = (row) => {
+    const index = tableData.value.indexOf(row);
+    if (index !== -1) {
+      tableData.value.splice(index, 1);
+    }
+  };
+
+  const handleTypeChange = (row) => {
+    if (row.parameterType === 0) {
+      row.maxValue = undefined;
+      row.minValue = undefined;
+    } else {
+      row.standardValue = '';
+    }
+    row.testValue = '';
+  };
   // 鍏抽棴寮规
   const closeDia = () => {
     proxy.resetForm("formRef");
diff --git a/src/views/qualityManagement/finalInspection/index.vue b/src/views/qualityManagement/finalInspection/index.vue
index 4a59fa4..6c60f86 100644
--- a/src/views/qualityManagement/finalInspection/index.vue
+++ b/src/views/qualityManagement/finalInspection/index.vue
@@ -128,6 +128,7 @@
   import { ElMessageBox } from "element-plus";
   import {
     downloadQualityInspect,
+    downloadQualityInspectPdf,
     qualityInspectDel,
     qualityInspectListPage,
     qualityInspectUpdate,
@@ -315,9 +316,17 @@
         },
         {
           name: "涓嬭浇",
-          type: "text",
-          clickFun: row => {
-            downLoadFile(row);
+          type: "dropdown",
+          dropdownItems: [
+            { label: "Word鏍煎紡", command: "word" },
+            { label: "PDF鏍煎紡", command: "pdf" }
+          ],
+          commandFun: (command, row) => {
+            if (command === 'word') {
+              downLoadFile(row);
+            } else if (command === 'pdf') {
+              downLoadPdfFile(row);
+            }
           },
         },
       ],
@@ -500,7 +509,23 @@
 
       const link = document.createElement("a");
       link.href = downloadUrl;
-      link.download = "鍘熸潗鏂欐楠屾姤鍛�.docx";
+      link.download = "鍑哄巶妫�楠屾姤鍛�.docx";
+      document.body.appendChild(link);
+      link.click();
+
+      document.body.removeChild(link);
+      window.URL.revokeObjectURL(downloadUrl);
+    });
+  };
+
+  const downLoadPdfFile = row => {
+    downloadQualityInspectPdf({ id: row.id }).then(blobData => {
+      const blob = new Blob([blobData], { type: "application/pdf" });
+      const downloadUrl = window.URL.createObjectURL(blob);
+
+      const link = document.createElement("a");
+      link.href = downloadUrl;
+      link.download = "鍑哄巶妫�楠屾姤鍛�.pdf";
       document.body.appendChild(link);
       link.click();
 
diff --git a/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
index 4c958a0..6aed3dd 100644
--- a/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
+++ b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
@@ -20,9 +20,23 @@
       <el-form-item label="鍗曚綅" prop="unit">
         <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
       </el-form-item>
-      <el-form-item label="鏍囧噯鍊�" prop="standardValue">
+      <el-form-item label="鍙傛暟绫诲瀷" prop="parameterType">
+        <el-radio-group v-model="form.parameterType">
+          <el-radio :label="0">鏂囧瓧</el-radio>
+          <el-radio :label="1">鏁板瓧</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="鏍囧噯鍊�" prop="standardValue" v-if="form.parameterType === 0">
         <el-input v-model="form.standardValue" placeholder="璇疯緭鍏ユ爣鍑嗗��" />
       </el-form-item>
+      <template v-if="form.parameterType === 1">
+        <el-form-item label="鏈�澶у��" prop="maxValue">
+          <el-input-number v-model="form.maxValue" :controls="false" placeholder="璇疯緭鍏ユ渶澶у��" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="鏈�灏忓��" prop="minValue">
+          <el-input-number v-model="form.minValue" :controls="false" placeholder="璇疯緭鍏ユ渶灏忓��" style="width: 100%" />
+        </el-form-item>
+      </template>
       <el-form-item label="鍐呮帶鍊�" prop="controlValue">
         <el-input v-model="form.controlValue" placeholder="璇疯緭鍏ュ唴鎺у��" />
       </el-form-item>
@@ -52,11 +66,45 @@
 
 const formRef = ref(null)
 
-const rules = {
-  parameterItem: [{ required: true, message: '璇疯緭鍏ュ弬鏁伴」', trigger: 'blur' }],
-  unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }]
+const validateMaxValue = (rule, value, callback) => {
+  if (value === undefined || value === null || value === '') {
+    callback(new Error('璇疯緭鍏ユ渶澶у��'))
+  } else if (props.form.minValue !== undefined && props.form.minValue !== null && props.form.minValue !== '' && Number(value) < Number(props.form.minValue)) {
+    callback(new Error('鏈�澶у�间笉鑳藉皬浜庢渶灏忓��'))
+  } else {
+    if (props.form.minValue !== undefined && props.form.minValue !== null && props.form.minValue !== '') {
+      formRef.value?.clearValidate('minValue')
+    }
+    callback()
+  }
 }
 
+const validateMinValue = (rule, value, callback) => {
+  if (value === undefined || value === null || value === '') {
+    callback(new Error('璇疯緭鍏ユ渶灏忓��'))
+  } else if (props.form.maxValue !== undefined && props.form.maxValue !== null && props.form.maxValue !== '' && Number(value) > Number(props.form.maxValue)) {
+    callback(new Error('鏈�灏忓�间笉鑳藉ぇ浜庢渶澶у��'))
+  } else {
+    if (props.form.maxValue !== undefined && props.form.maxValue !== null && props.form.maxValue !== '') {
+      formRef.value?.clearValidate('maxValue')
+    }
+    callback()
+  }
+}
+
+const rules = computed(() => {
+  const baseRules = {
+    parameterItem: [{ required: true, message: '璇疯緭鍏ュ弬鏁伴」', trigger: 'blur' }],
+    unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+    parameterType: [{ required: true, message: '璇烽�夋嫨鍙傛暟绫诲瀷', trigger: 'change' }]
+  };
+  if (props.form.parameterType === 1) {
+    baseRules.maxValue = [{ required: true, validator: validateMaxValue, trigger: 'blur' }];
+    baseRules.minValue = [{ required: true, validator: validateMinValue, trigger: 'blur' }];
+  }
+  return baseRules;
+})
+
 const computedTitle = computed(() => (props.operationType === 'edit' ? '缂栬緫鏍囧噯鍙傛暟' : '鏂板鏍囧噯鍙傛暟'))
 
 const handleConfirm = () => {
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index deb3e5f..243e63f 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -122,7 +122,14 @@
         <el-table-column type="index" label="搴忓彿" width="60" align="center" />
         <el-table-column prop="parameterItem" label="鍙傛暟椤�" min-width="120" />
         <el-table-column prop="unit" label="鍗曚綅" width="80" />
+        <el-table-column prop="parameterType" label="鍙傛暟绫诲瀷" width="100">
+          <template #default="{ row }">
+            {{ row.parameterType === 1 ? '鏁板瓧' : (row.parameterType === 0 ? '鏂囧瓧' : '') }}
+          </template>
+        </el-table-column>
         <el-table-column prop="standardValue" label="鏍囧噯鍊�" min-width="120" />
+        <el-table-column prop="maxValue" label="鏈�澶у��" min-width="100" />
+        <el-table-column prop="minValue" label="鏈�灏忓��" min-width="100" />
         <el-table-column prop="controlValue" label="鍐呮帶鍊�" min-width="120" />
         <el-table-column prop="defaultValue" label="榛樿鍊�" min-width="120" />
         <el-table-column label="鎿嶄綔" width="140" fixed="right" align="center">
@@ -266,7 +273,10 @@
   id: undefined,
   parameterItem: '',
   unit: '',
+  parameterType: 0,
   standardValue: '',
+  maxValue: null,
+  minValue: null,
   controlValue: '',
   defaultValue: ''
 })
@@ -514,7 +524,10 @@
       id: undefined,
       parameterItem: '',
       unit: '',
+      parameterType: 0,
       standardValue: '',
+      maxValue: null,
+      minValue: null,
       controlValue: '',
       defaultValue: ''
     })
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 370b5f6..c82422f 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -292,6 +292,19 @@
       prop: "parameterItem",
     },
     {
+      label: "鍙傛暟绫诲瀷",
+      prop: "parameterType",
+      formatter: (row) => (row.parameterType === 1 ? "鏁板瓧" : row.parameterType === 0 ? "鏂囧瓧" : ""),
+    },
+    {
+      label: "鏈�澶у��",
+      prop: "maxValue",
+    },
+    {
+      label: "鏈�灏忓��",
+      prop: "minValue",
+    },
+    {
       label: "鍗曚綅",
       prop: "unit",
     },
@@ -581,6 +594,10 @@
           ...item,
           id: null,
         }));
+        
+        if (tableData.value.some(item => item.parameterType === null || item.parameterType === undefined)) {
+          proxy.$modal.msgWarning("鍙傛暟绫诲瀷鏈厤缃紝璇烽厤缃寚鏍囩淮鎶ゆā鏉�");
+        }
       })
       .catch(error => {
         console.error("鑾峰彇鏍囧噯鍙傛暟澶辫触:", error);
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index 595bf80..aeab1ef 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -191,6 +191,9 @@
                 :tableData="tableData"
                 :tableLoading="tableLoading"
                 height="400">
+        <template #typeSlot="{ row }">
+          {{ row.parameterType === 1 ? '鏁板瓧' : (row.parameterType === 0 ? '鏂囧瓧' : '') }}
+        </template>
         <template #slot="{ row }">
           <el-input v-model="row.testValue"
                     clearable
@@ -290,8 +293,22 @@
       prop: "unit",
     },
     {
+      label: "鍙傛暟绫诲瀷",
+      prop: "parameterType",
+      dataType: "slot",
+      slot: "typeSlot",
+    },
+    {
       label: "鏍囧噯鍊�",
       prop: "standardValue",
+    },
+    {
+      label: "鏈�澶у��",
+      prop: "maxValue",
+    },
+    {
+      label: "鏈�灏忓��",
+      prop: "minValue",
     },
     {
       label: "鍐呮帶鍊�",
@@ -546,6 +563,10 @@
           ...item,
           id: null,
         }));
+        
+        if (tableData.value.some(item => item.parameterType === null || item.parameterType === undefined)) {
+          proxy.$modal.msgWarning("鍙傛暟绫诲瀷鏈厤缃紝璇烽厤缃寚鏍囩淮鎶ゆā鏉�");
+        }
       })
       .catch(error => {
         console.error("鑾峰彇鏍囧噯鍙傛暟澶辫触:", error);
diff --git a/src/views/salesManagement/biddingManagement/index.vue b/src/views/salesManagement/biddingManagement/index.vue
index 310d0c5..6db238b 100644
--- a/src/views/salesManagement/biddingManagement/index.vue
+++ b/src/views/salesManagement/biddingManagement/index.vue
@@ -278,6 +278,7 @@
 const formRef = ref();
 
 const form = reactive({
+  id: undefined,
   projectId: "",
   projectName: "",
   bidDocName: "",
@@ -418,6 +419,7 @@
   Object.keys(form).forEach((key) => {
     form[key] = "";
   });
+  form.id = undefined;
   form.bidDocFee = undefined;
   form.bidDeposit = undefined;
 };
@@ -458,12 +460,12 @@
   dialogVisible.value = false;
 };
 
-// 涓爣鍚庡彂璧烽攢鍞悎鍚屽綍鍏ワ細璺宠浆鍚堝悓绠$悊椤碉紝鎼哄甫椤圭洰涓庢嫑鏍囧崟浣嶄俊鎭�
+// 涓爣鍚庡彂璧烽攢鍞彴璐﹀綍鍏ワ細璺宠浆閿�鍞彴璐︼紝鎼哄甫椤圭洰淇℃伅
 const handleStartContract = (row) => {
-  proxy.$tab.openPage("鍙戣捣閿�鍞悎鍚屽綍鍏�", "/salesManagement/contractManagement", {
+  proxy.$tab.openPage("閿�鍞彴璐�", "/salesManagement/salesLedger", {
+    action: "add",
     projectId: row.projectId,
     projectName: row.projectName,
-    signingUnit: row.tenderUnit,
   });
 };
 
diff --git a/src/views/salesManagement/deliveryLedger/index.vue b/src/views/salesManagement/deliveryLedger/index.vue
index 33fa45f..af41f00 100644
--- a/src/views/salesManagement/deliveryLedger/index.vue
+++ b/src/views/salesManagement/deliveryLedger/index.vue
@@ -32,6 +32,36 @@
             @change="handleQuery"
           />
         </el-form-item>
+        <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectId">
+          <el-select
+            v-model="searchForm.projectId"
+            placeholder="璇烽�夋嫨椤圭洰"
+            clearable
+            filterable
+            style="width: 200px"
+            @change="handleQuery"
+          >
+            <el-option
+              v-for="item in projectOptions"
+              :key="item.id"
+              :label="item.no + ' - ' + item.title"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍙戣揣鏃ユ湡锛�" prop="shippingDateRange">
+          <el-date-picker
+            v-model="searchForm.shippingDateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            style="width: 240px"
+            @change="handleQuery"
+            clearable
+          />
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleQuery"> 鎼滅储</el-button>
         </el-form-item>
@@ -64,6 +94,12 @@
         <el-table-column
           label="鍙戣揣璁㈠崟鍙�"
           prop="shippingNo"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="椤圭洰鍚嶇О"
+          prop="projectName"
+          min-width="150"
           show-overflow-tooltip
         />
         <el-table-column
@@ -124,14 +160,22 @@
           show-overflow-tooltip
           width="130"
         />
+        <el-table-column label="閫�璐у崟" align="center" width="140">
+          <template #default="scope">
+            <el-button v-if="scope.row.returnNoList && scope.row.returnNoList.length > 0" link type="primary" @click="openReturnNosDialog(scope.row)">
+              鏌ョ湅 {{ scope.row.returnNoList.length }} 涓��璐у崟
+            </el-button>
+            <span v-else>--</span>
+          </template>
+        </el-table-column>
         <el-table-column fixed="right" label="鎿嶄綔" width="220" align="center">
           <template #default="scope">
-            <!--            <el-button-->
-            <!--                link-->
-            <!--                type="primary"-->
-            <!--                :disabled="!isApproved(scope.row.status)"-->
-            <!--                @click="openForm('edit', scope.row)">鍙戣揣-->
-            <!--            </el-button>-->
+            <el-button
+              link
+              type="primary"
+              :disabled="scope.row.status === '瀹℃牳閫氳繃' || scope.row.status === '宸插彂璐�'"
+              @click="openForm('edit', scope.row)">琛ュ厖鍙戣揣淇℃伅
+            </el-button>
             <el-button
               link
               type="primary"
@@ -139,13 +183,13 @@
               @click="openDetail(scope.row)"
               >璇︽儏
             </el-button>
-            <!--            <el-button-->
-            <!--              link-->
-            <!--              type="danger"-->
-            <!--              :disabled="isApproving(scope.row.status)"-->
-            <!--              @click="handleDeleteSingle(scope.row)"-->
-            <!--              >鍒犻櫎-->
-            <!--            </el-button>-->
+            <el-button
+              link
+              type="danger"
+              :disabled="scope.row.status === '宸插彂璐�' || scope.row.status === '瀹℃牳閫氳繃'"
+              @click="handleDeleteSingle(scope.row)"
+              >鍒犻櫎
+            </el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -239,6 +283,56 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="鍙戣揣鍗曟嵁锛�" prop="shippingDocument">
+              <el-input
+                v-model="form.shippingDocument"
+                placeholder="璇疯緭鍏ュ彂璐у崟鎹�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="8">
+            <el-form-item label="鏄惁瀵硅处锛�" prop="isReconciled">
+              <el-switch v-model="form.isReconciled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁缁撶畻锛�" prop="isSettled">
+              <el-switch v-model="form.isSettled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁宸插紑绁細" prop="isInvoiced">
+              <el-switch v-model="form.isInvoiced" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12" v-if="form.isReconciled === 1">
+            <el-form-item label="瀵硅处鍗曞綊妗f儏鍐碉細" prop="statementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="form.statementArchivingStatus"
+                placeholder="璇疯緭鍏ュ璐﹀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.isSettled === 1">
+            <el-form-item label="缁撶畻鍗曞綊妗f儏鍐碉細" prop="settlementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="form.settlementArchivingStatus"
+                placeholder="璇疯緭鍏ョ粨绠楀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -293,6 +387,24 @@
           <el-descriptions-item label="鍑哄簱鍗曞彿" :span="2">{{
             detailRow.outboundBatches || "--"
           }}</el-descriptions-item>
+          <el-descriptions-item label="鍙戣揣鍗曟嵁">{{
+            detailRow.shippingDocument || "--"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鏄惁瀵硅处">{{
+            detailRow.isReconciled === 1 ? '鏄�' : '鍚�'
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鏄惁缁撶畻">{{
+            detailRow.isSettled === 1 ? '鏄�' : '鍚�'
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鏄惁宸插紑绁�">{{
+            detailRow.isInvoiced === 1 ? '鏄�' : '鍚�'
+          }}</el-descriptions-item>
+          <el-descriptions-item label="瀵硅处鍗曞綊妗f儏鍐�" :span="2">{{
+            detailRow.statementArchivingStatus || "--"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="缁撶畻鍗曞綊妗f儏鍐�" :span="2">{{
+            detailRow.settlementArchivingStatus || "--"
+          }}</el-descriptions-item>
         </el-descriptions>
         <el-table
           :data="getDeliveryProductInfoList()"
@@ -334,6 +446,19 @@
         </div>
       </template>
     </el-dialog>
+
+    <!-- 閫�璐у崟鍙峰脊妗� -->
+    <el-dialog v-model="returnNosDialogVisible" title="閫�璐у崟鍙峰垪琛�" width="400px" @close="closeReturnNosDialog">
+      <el-table :data="currentReturnNos" border size="small">
+        <el-table-column label="搴忓彿" type="index" width="60" align="center" />
+        <el-table-column label="閫�璐у崟鍙�" prop="returnNo" align="center" />
+      </el-table>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeReturnNosDialog">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -349,6 +474,7 @@
   getDeliveryDetail,
 } from "@/api/salesManagement/deliveryLedger.js";
 import { delLedgerFile } from "@/api/salesManagement/salesLedger.js";
+import { listProject } from "@/api/projectManagement/project.js";
 import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
 import ImagePreview from "@/components/AttachmentPreview/image/index.vue";
 
@@ -357,6 +483,7 @@
 const selectedRows = ref([]);
 const tableLoading = ref(false);
 const salesOrderOptions = ref([]);
+const projectOptions = ref([]);
 const page = reactive({
   current: 1,
   size: 100,
@@ -368,14 +495,30 @@
 const detailRow = ref(null);
 const detailProductList = ref([]);
 
+// 閫�璐у崟鍙峰脊妗�
+const returnNosDialogVisible = ref(false);
+const currentReturnNos = ref([]);
+
+const openReturnNosDialog = (row) => {
+  currentReturnNos.value = (row.returnNoList || []).map(no => ({ returnNo: no }));
+  returnNosDialogVisible.value = true;
+};
+
+const closeReturnNosDialog = () => {
+  returnNosDialogVisible.value = false;
+  currentReturnNos.value = [];
+};
+
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
 const operationType = ref("");
 const dialogFormVisible = ref(false);
 const data = reactive({
   searchForm: {
-    salesContractNo: "", // 閿�鍞鍗曞彿
-    shippingCarNumber: "", // 杞︾墝鍙�
-    expressNumber: "", // 蹇�掑崟鍙�
+    salesContractNo: undefined,
+    shippingCarNumber: undefined,
+    expressNumber: undefined,
+    projectId: undefined,
+    shippingDateRange: []
   },
   form: {
     id: null,
@@ -433,7 +576,13 @@
 
 const getList = () => {
   tableLoading.value = true;
-  deliveryLedgerListPage({ ...searchForm.value, ...page })
+  const params = { ...searchForm.value };
+  if (params.shippingDateRange && params.shippingDateRange.length === 2) {
+    params.beginShippingDate = params.shippingDateRange[0];
+    params.endShippingDate = params.shippingDateRange[1];
+  }
+  delete params.shippingDateRange;
+  deliveryLedgerListPage({ ...params, ...page })
     .then((res) => {
       tableLoading.value = false;
       tableData.value = res.data.records || [];
@@ -461,9 +610,8 @@
 
 // 鎵撳紑寮规
 const openForm = async (type, row) => {
-  // 鍙戣揣锛氫粎鈥滃鏍搁�氳繃鈥濆厑璁哥紪杈�
-  if (type === "edit" && row && !isApproved(row.status)) {
-    proxy.$modal.msgWarning("鍙湁瀹℃牳閫氳繃鐨勬暟鎹墠鍙互鍙戣揣");
+  if (type === "edit" && row && (row.status === "瀹℃牳閫氳繃" || row.status === "宸插彂璐�")) {
+    proxy.$modal.msgWarning("璇ョ姸鎬佺殑鏁版嵁涓嶅彲浠ョ紪杈戝彂璐т俊鎭�");
     return;
   }
 
@@ -479,6 +627,12 @@
       shippingCarNumber: row.shippingCarNumber ?? "",
       expressCompany: row.expressCompany ?? "",
       expressNumber: row.expressNumber ?? "",
+      shippingDocument: row.shippingDocument ?? "",
+      isReconciled: row.isReconciled ?? 0,
+      statementArchivingStatus: row.statementArchivingStatus ?? "",
+      isSettled: row.isSettled ?? 0,
+      settlementArchivingStatus: row.settlementArchivingStatus ?? "",
+      isInvoiced: row.isInvoiced ?? 0,
     };
     deliveryFileList.value = row.storageBlobVOs || [];
   }
@@ -616,7 +770,13 @@
     type: "warning",
   })
     .then(() => {
-      proxy.download("/shippingInfo/export", {}, "鍙戣揣鍙拌处.xlsx");
+      const params = { ...searchForm.value };
+      if (params.shippingDateRange && params.shippingDateRange.length === 2) {
+        params.beginShippingDate = params.shippingDateRange[0];
+        params.endShippingDate = params.shippingDateRange[1];
+      }
+      delete params.shippingDateRange;
+      proxy.download("/shippingInfo/export", params, "鍙戣揣鍙拌处.xlsx");
     })
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
@@ -866,6 +1026,7 @@
 };
 
 onMounted(() => {
+  listProject({}).then(res => projectOptions.value = res.rows || res.data.records || res.data);
   getList();
 });
 </script>
diff --git a/src/views/salesManagement/lawsuitManagement/index.vue b/src/views/salesManagement/lawsuitManagement/index.vue
index 1cd39f2..2b52310 100644
--- a/src/views/salesManagement/lawsuitManagement/index.vue
+++ b/src/views/salesManagement/lawsuitManagement/index.vue
@@ -253,6 +253,7 @@
 const fileList = ref([]);
 
 const form = reactive({
+  id: undefined,
   caseNo: "",
   projectId: "",
   projectName: "",
@@ -299,9 +300,13 @@
 
 const initProjects = async () => {
   try {
-    const res = await listProject({ pageSize: 1000 });
-    const rows = res?.rows || res?.data?.rows || [];
-    projectOptions.value = rows.map((p) => ({ label: p.projectName, value: p.id }));
+    const res = await listProject({ pageSize: 1000, current: 1, size: 1000 });
+    const rows = res?.records || res?.rows || res?.data?.records || res?.data?.rows || res?.data || [];
+    projectOptions.value = rows.map((p) => ({ 
+      label: (p.no ? p.no + ' - ' : '') + (p.title || ''), 
+      value: p.id,
+      title: p.title
+    }));
   } catch (e) {
     console.error("鍔犺浇椤圭洰鍒楄〃澶辫触", e);
   }
@@ -310,7 +315,7 @@
 const initContracts = async () => {
   try {
     const res = await contractListNoPage({});
-    const list = Array.isArray(res) ? res : res?.data ?? res?.records ?? [];
+    const list = Array.isArray(res) ? res : (res?.data?.records || res?.data || res?.records || []);
     contractOptions.value = list.map((item) => ({
       label: item.contractNo + (item.signingUnit ? `锛�${item.signingUnit}锛塦 : ""),
       value: item.id,
@@ -323,7 +328,7 @@
 
 const handleProjectChange = (val) => {
   const project = projectOptions.value.find((item) => item.value === val);
-  form.projectName = project ? project.label : "";
+  form.projectName = project ? (project.title || project.label) : "";
 };
 
 const handleContractChange = (val) => {
@@ -390,6 +395,7 @@
     form[key] = "";
   });
   form.claimAmount = undefined;
+  form.id = undefined;
 };
 
 const openForm = async (type, row) => {
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index c5e3415..72fc6a8 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -1,272 +1,610 @@
 <template>
   <div class="app-container">
-    <div class="search_form"
-         style="margin-bottom: 20px;">
-      <div>
-        <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
-        <el-input v-model="searchForm.searchText"
-                  style="width: 240px"
-                  placeholder="杈撳叆瀹㈡埛鍚嶇О鎼滅储"
-                  @change="handleQuery"
-                  clearable
-                  prefix-icon="Search" />
-        <el-button type="primary"
-                   @click="handleQuery"
-                   style="margin-left: 10px">鎼滅储</el-button>
+    <div class="search_form">
+      <el-form :model="searchForm" :inline="true">
+        <el-form-item label="椤圭洰鍚嶇О锛�">
+          <el-input
+              v-model="searchForm.projectName"
+              placeholder="璇疯緭鍏ラ」鐩悕绉�"
+              clearable
+              prefix-icon="Search"
+              style="width: 200px"
+              @change="handleSearch"
+          />
+        </el-form-item>
+        <el-form-item label="瀹㈡埛鍚嶇О锛�">
+          <el-input
+              v-model="searchForm.customerName"
+              placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+              clearable
+              prefix-icon="Search"
+              style="width: 200px"
+              @change="handleSearch"
+          />
+        </el-form-item>
+        <el-form-item label="鍚堝悓鍚嶇О锛�">
+          <el-input
+              v-model="searchForm.contractName"
+              placeholder="璇疯緭鍏ュ悎鍚屽悕绉�"
+              clearable
+              prefix-icon="Search"
+              style="width: 200px"
+              @change="handleSearch"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+  <div class="table_list">
+  <div class="app-container layout-fullscreen">
+    <!-- Search Form -->
+    <div class="summary-strip">
+      <div class="summary-stats">
+        <span>褰撳墠椤圭洰锛�<b>{{ summaryData.totalProjects || 0 }}</b> 涓�</span>
+        <span>鍏宠仈瀹㈡埛锛�<b>{{ summaryData.totalCustomers || 0 }}</b> 瀹�</span>
+        <span>鍚堝悓鎬绘暟锛�<b>{{ summaryData.totalContracts || 0 }}</b> 浠�</span>
+        <span>绛剧害鎬婚锛�<b>{{ fmtMoney(summaryData.totalAmount || 0) }}</b></span>
+        <span class="warn-summary">鈿� 绛捐瓒�30澶╂湭瀹屾垚鍥炴锛�<span>{{
+            summaryData.totalOverdueCount || 0
+          }}</span> 浠�</span>
       </div>
     </div>
-    <el-row :gutter="20">
-      <el-col :span="12">
-        <div class="table_list"
-             style="width: 100%">
-          <el-table :data="tableData"
-                    border
-                    v-loading="tableLoading"
-                    :row-key="(row) => row.customerId"
-                    show-summary
-                    :summary-method="summarizeMainTable"
-                    @row-click="rowClickMethod"
-                    highlight-current-row
-                    height="calc(100vh - 18.5em)">
-            <el-table-column align="center"
-                             label="搴忓彿"
-                             type="index"
-                             width="60" />
-            <el-table-column label="瀹㈡埛鍚嶇О"
-                             prop="customerName"
-                             show-overflow-tooltip
-                             width="200" />
-            <el-table-column label="鍚堝悓閲戦(鍏�)"
-                             prop="contractAmounts"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="鍥炴閲戦(鍏�)"
-                             prop="receiptPaymentAmount"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="閫�璐ч噾棰�(鍏�)"
-                             prop="returnAmount"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="搴旀敹閲戦(鍏�)"
-                             prop="receiptableAmount"
-                             show-overflow-tooltip
-                             width="200">
-              <template #default="{ row, column }">
-                <el-text type="danger">
-                  {{ formattedNumber(row, column, row.receiptableAmount) }}
-                </el-text>
+
+    <!-- Layout Columns -->
+    <div class="layout-columns">
+      <!-- Column 1: Projects -->
+      <div class="column-panel" v-loading="prjLoading">
+        <div class="panel-header">
+          <span>1. 椤圭洰姹囨�� ({{ prjTotal }})</span>
+        </div>
+        <div class="panel-body">
+          <div v-if="projects.length === 0" class="empty-state">鏃犲尮閰嶉」鐩�</div>
+
+          <div v-for="p in projects" :key="p.projectId"
+               class="item-card" :class="{ active: p.projectId === selectedProjectId }"
+               @click="handleSelectProject(p)">
+            <div class="card-title-row">
+              <div class="card-main-title">{{ p.projectName }}</div>
+            </div>
+            <div class="card-code">{{ p.projectCode || '鏆傛棤椤圭洰缂栧彿' }}</div>
+            <div class="meta-row" style="margin-top: 8px;">
+              <span>鎬婚: <strong>{{ fmtMoney(p.contractAmounts) }}</strong></span>
+              <span>寮�绁�: <strong>{{ fmtMoney(p.invoiceAmount) }}</strong></span>
+            </div>
+            <div class="meta-row">
+              <span>鍥炴: <strong>{{ fmtMoney(p.receiptPaymentAmount) }}</strong></span>
+              <span>搴旀敹: <strong>{{ fmtMoney(p.receiptableAmount) }}</strong></span>
+            </div>
+            <div class="meta-row">
+              <span>閫�璐�: <strong>{{ fmtMoney(p.returnAmount) }}</strong></span>
+              <span>杩涘害: <strong :class="{'text-danger': p.overdueCount > 0}">{{
+                  calcRate(p.receiptPaymentAmount, p.contractAmounts)
+                }}%</strong></span>
+            </div>
+            <div class="meta-row">
+              <span>瀹㈡埛: <strong>{{ p.customerCount || 0 }} 瀹�</strong></span>
+              <span>鍚堝悓: <strong>{{ p.contractCount || 0 }} 浠�</strong></span>
+            </div>
+            <div v-if="p.overdueCount > 0" style="margin-top: 6px;">
+              <el-tag type="danger" size="small" effect="light">鈿� {{ p.overdueCount }} 浠借秴鏈熷悎鍚�</el-tag>
+            </div>
+          </div>
+        </div>
+        <div class="panel-pagination">
+          <el-pagination background small layout="total, prev, pager, next" :total="prjTotal" :page-size="prjPage.size"
+                         v-model:current-page="prjPage.current" @current-change="handlePrjPageChange"/>
+        </div>
+      </div>
+
+      <!-- Column 2: Customers -->
+      <div class="column-panel" v-loading="custLoading">
+        <div class="panel-header">
+          <span>2. 瀹㈡埛姹囨�� ({{ custTotal }})</span>
+        </div>
+        <div class="panel-body">
+          <div v-if="!selectedProjectId" class="empty-state">璇峰厛鍦ㄥ乏渚ч�夋嫨椤圭洰</div>
+          <div v-else-if="customers.length === 0" class="empty-state">璇ラ」鐩笅鏃犲尮閰嶇殑瀹㈡埛淇℃伅</div>
+
+          <div v-for="c in customers" :key="c.customerId"
+               class="item-card" :class="{ active: c.customerId === selectedCustomerId }"
+               @click="handleSelectCustomer(c)">
+            <div class="card-title-row">
+              <div class="card-main-title">{{ c.customerName || '鏈懡鍚嶅鎴�' }}</div>
+            </div>
+            <div class="meta-row" style="margin-top: 8px;">
+              <span>绛剧害: <strong>{{ fmtMoney(c.contractAmounts) }}</strong></span>
+              <span>杩涘害: <strong :class="{'text-danger': c.overdueCount > 0}">{{
+                  calcRate(c.receiptPaymentAmount, c.contractAmounts)
+                }}%</strong></span>
+            </div>
+            <div class="meta-row">
+              <span>閫�璐�: <strong>{{ fmtMoney(c.returnAmount) }}</strong></span>
+              <span>搴旀敹: <strong>{{ fmtMoney(c.receiptableAmount) }}</strong></span>
+            </div>
+            <div class="meta-row">
+              <span>宸插洖娆�: <strong>{{ fmtMoney(c.receiptPaymentAmount) }}</strong></span>
+              <span>鍚堝悓鏁�: <strong>{{ c.contractCount || 0 }} 浠�</strong></span>
+            </div>
+            <div style="margin-top: 6px;">
+              <el-tag v-if="c.overdueCount > 0" type="danger" size="small" effect="light">鈿� {{ c.overdueCount }} 浠借秴鏈�</el-tag>
+              <el-tag v-else type="success" size="small" effect="light">姝e父灞ョ害</el-tag>
+            </div>
+          </div>
+        </div>
+        <div class="panel-pagination">
+          <el-pagination background small layout="total, prev, pager, next" :total="custTotal"
+                         :page-size="custPage.size" v-model:current-page="custPage.current"
+                         @current-change="handleCustPageChange"/>
+        </div>
+      </div>
+
+      <!-- Column 3: Contracts -->
+      <div class="column-panel" v-loading="contractLoading">
+        <div class="panel-header">
+          <span>3. 鍚堝悓鏄庣粏 ({{ contractTotal }})</span>
+        </div>
+        <div class="panel-body" style="padding: 0;">
+          <div v-if="!selectedCustomerId" class="empty-state" style="padding-top: 40px;">璇峰厛鍦ㄤ腑闂存爮閫夋嫨瀹㈡埛</div>
+          <div v-else-if="contracts.length === 0" class="empty-state" style="padding-top: 40px;">
+            璇ュ鎴蜂笅鏃犲尮閰嶇殑鍚堝悓鏄庣粏
+          </div>
+
+          <el-table v-else :data="contracts" size="small" style="width: 100%; height: 100%;" stripe
+                    :row-class-name="tableRowClassName">
+            <el-table-column label="鍚堝悓淇℃伅" min-width="160" show-overflow-tooltip>
+              <template #default="{ row }">
+                <div style="font-weight: 600; color: #0f172a;">{{
+                    row.contractName || row.salesContractNo || '鏈懡鍚�'
+                  }}
+                </div>
+                <div style="font-size: 11px; color: #64748b;">鍚堝悓缂栧彿锛歿{ row.salesContractNo }}</div>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="閲戦涓庡洖娆�" min-width="150">
+              <template #default="{ row }">
+                <div style="font-size: 12px; color: #64748b;">鎬婚: <span
+                    style="color: #0f172a; font-weight: 500;">{{ fmtMoney(row.contractAmount) }}</span></div>
+                <div :class="row.isPaymentTimeout ? 'text-danger' : ''" style="font-size: 12px; font-weight: 500;">
+                  宸插洖: {{ fmtMoney(row.receiptPaymentAmount) }}
+                  ({{ calcRate(row.receiptPaymentAmount, row.contractAmount) }}%)
+                </div>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="搴旀敹涓庨��璐�" min-width="130">
+              <template #default="{ row }">
+                <div style="font-size: 12px; color: #64748b;">搴旀敹: <span
+                    style="color: #0f172a;">{{ fmtMoney(row.receiptableAmount) }}</span></div>
+                <div style="font-size: 12px; color: #64748b;">閫�璐�: <span
+                    style="color: #0f172a;">{{ fmtMoney(row.returnAmount) }}</span></div>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="鐘舵��" width="100" align="center">
+              <template #default="{ row }">
+                <el-tag v-if="row.isPaymentTimeout" type="danger" size="small" effect="dark">瓒呮湡鏈洖</el-tag>
+                <el-tag
+                    v-else-if="(row.receiptPaymentAmount || 0) >= (row.contractAmount || 0) && (row.contractAmount || 0) > 0"
+                    type="success" size="small" effect="dark">宸茬粨娓�
+                </el-tag>
+                <el-tag v-else type="primary" size="small" effect="plain">灞ヨ涓�</el-tag>
               </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-col>
-      <el-col :span="12">
-        <div class="table_list"
-             style="width: 100%">
-          <el-table :data="receiptRecord"
-                    border
-                    :row-key="(row) => row.id"
-                    show-summary
-                    :summary-method="summarizeMainTable1"
-                    height="calc(100vh - 18.5em)">
-            <el-table-column align="center"
-                             label="搴忓彿"
-                             type="index"
-                             width="60" />
-            <el-table-column label="鍚堝悓绛捐鏃ユ湡"
-                             prop="executionDate"
-                             show-overflow-tooltip
-                             width="110" />
-            <el-table-column label="閿�鍞悎鍚屽彿"
-                             prop="salesContractNo"
-                             show-overflow-tooltip
-                             width="200" />
-            <el-table-column label="鍚堝悓閲戦(鍏�)"
-                             prop="contractAmount"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="鍥炴閲戦(鍏�)"
-                             prop="receiptPaymentAmount"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="閫�璐ч噾棰�(鍏�)"
-                             prop="returnAmount"
-                             show-overflow-tooltip
-                             :formatter="formattedNumber"
-                             width="200" />
-            <el-table-column label="搴旀敹閲戦(鍏�)"
-                             prop="receiptableAmount"
-                             show-overflow-tooltip
-                             width="200">
-              <template #default="{ row, column }">
-                <el-text type="danger">
-                  {{ formattedNumber(row, column, row.receiptableAmount) }}
-                </el-text>
-              </template>
-            </el-table-column>
-          </el-table>
-          <pagination v-show="recordTotal > 0"
-                      :total="recordTotal"
-                      layout="total, sizes, prev, pager, next, jumper"
-                      :page="recordPage.current"
-                      :limit="recordPage.size"
-                      @pagination="recordPaginationChange" />
+        <div class="panel-pagination">
+          <el-pagination background small layout="total, prev, pager, next" :total="contractTotal"
+                         :page-size="contractPage.size" v-model:current-page="contractPage.current"
+                         @current-change="handleContractPageChange"/>
         </div>
-      </el-col>
-    </el-row>
+      </div>
+
+    </div>
+  </div>
   </div>
 </template>
 
 <script setup>
-  import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
-  import {
-    customewTransactions,
-    customewTransactionsDetails,
-  } from "@/api/salesManagement/indicatorStats.js";
-  import Pagination from "../../../components/PIMTable/Pagination.vue";
-  const { proxy } = getCurrentInstance();
-  const tableData = ref([]);
-  const receiptRecord = ref([]);
-  const tableLoading = ref(false);
-  const page = reactive({
-    current: 1,
-    size: 100,
+import {onMounted, ref, reactive, toRefs} from "vue";
+import {
+  projectTransactions,
+  customewTransactions,
+  customewTransactionsDetails,
+  transactionsSummary
+} from "@/api/salesManagement/indicatorStats.js";
+
+const summaryData = ref({});
+const data = reactive({
+  searchForm: {
+    projectName: "",
+    customerName: "",
+    contractName: "",
+  },
+});
+const {searchForm} = toRefs(data);
+
+// Column 1: Projects
+const projects = ref([]);
+const prjLoading = ref(false);
+const prjTotal = ref(0);
+const prjPage = reactive({current: 1, size: 20});
+const selectedProjectId = ref(null);
+
+// Column 2: Customers
+const customers = ref([]);
+const custLoading = ref(false);
+const custTotal = ref(0);
+const custPage = reactive({current: 1, size: 20});
+const selectedCustomerId = ref(null);
+
+// Column 3: Contracts
+const contracts = ref([]);
+const contractLoading = ref(false);
+const contractTotal = ref(0);
+const contractPage = reactive({current: 1, size: 20});
+
+const getSummary = () => {
+  transactionsSummary().then(res => {
+    summaryData.value = res.data || {};
   });
-  const recordPage = reactive({
-    current: 1,
-    size: 100,
+};
+
+const handleSearch = () => {
+  prjPage.current = 1;
+  loadProjects();
+  getSummary();
+};
+
+const handleReset = () => {
+  searchForm.value = {
+    projectName: "",
+    customerName: "",
+    contractName: "",
+  };
+  handleSearch();
+};
+
+const loadProjects = () => {
+  prjLoading.value = true;
+  projectTransactions({...searchForm.value, ...prjPage}).then(res => {
+    prjLoading.value = false;
+    projects.value = res.data.records || [];
+    prjTotal.value = res.data.total || 0;
+
+    if (projects.value.length > 0) {
+      handleSelectProject(projects.value[0]);
+    } else {
+      selectedProjectId.value = null;
+      customers.value = [];
+      custTotal.value = 0;
+      contracts.value = [];
+      contractTotal.value = 0;
+    }
+  }).catch(() => {
+    prjLoading.value = false;
   });
-  const total = ref(0);
-  const recordTotal = ref(0);
-  const data = reactive({
-    searchForm: {
-      searchText: "",
-      invoiceDate: "",
-    },
+};
+
+const handleSelectProject = (prj) => {
+  selectedProjectId.value = prj.projectId;
+  custPage.current = 1;
+  loadCustomers();
+};
+
+const loadCustomers = () => {
+  if (!selectedProjectId.value) return;
+  custLoading.value = true;
+  const params = {
+    projectId: selectedProjectId.value,
+    customerName: searchForm.value.customerName,
+    contractName: searchForm.value.contractName,
+    ...custPage
+  };
+  customewTransactions(params).then(res => {
+    custLoading.value = false;
+    const records = res.data.records || res.data || [];
+    customers.value = records;
+    custTotal.value = res.data.total || records.length || 0;
+
+    if (customers.value.length > 0) {
+      handleSelectCustomer(customers.value[0]);
+    } else {
+      selectedCustomerId.value = null;
+      contracts.value = [];
+      contractTotal.value = 0;
+    }
+  }).catch(() => {
+    custLoading.value = false;
   });
-  const customerId = ref("");
-  const { searchForm } = toRefs(data);
-  const originReceiptRecord = ref([]);
-  // 鏌ヨ鍒楄〃
-  /** 鎼滅储鎸夐挳鎿嶄綔 */
-  const handleQuery = () => {
-    page.current = 1;
-    getList();
-  };
-  const paginationChange = obj => {
-    page.current = obj.page;
-    page.size = obj.limit;
-    getList();
-  };
-  const getList = () => {
-    tableLoading.value = true;
-    customewTransactions({ ...searchForm.value, ...page }).then(res => {
-      tableLoading.value = false;
-      tableData.value = res.data.records;
-      total.value = res.data.total;
-      if (tableData.value.length > 0) {
-        recordPage.current = 1;
-        customerId.value = tableData.value[0].customerId;
-        receiptPaymentList(customerId.value);
-      }
-    });
-  };
-  const formattedNumber = (row, column, cellValue) => {
-    return cellValue ? parseFloat(cellValue).toFixed(2) : "0.00";
-  };
-  // 涓昏〃鍚堣鏂规硶
-  const summarizeMainTable = param => {
-    return proxy.summarizeTable(
-      param,
-      [
-        "contractAmounts",
-        "receiptPaymentAmount",
-        "returnAmount",
-        "receiptableAmount",
-      ],
-      {
-        ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-        futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-      }
-    );
-  };
-  // 瀛愯〃鍚堣鏂规硶
-  const summarizeMainTable1 = param => {
-    var summarizeTable = proxy.summarizeTable(
-      param,
-      [
-        "contractAmount",
-        "receiptPaymentAmount",
-        "returnAmount",
-        "receiptableAmount",
-      ],
-      {
-        ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-        futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-      }
-    );
-    return summarizeTable;
-  };
+};
 
-  const receiptPaymentList = id => {
-    const param = {
-      customerId: id,
-      current: recordPage.current,
-      size: recordPage.size,
-    };
-    customewTransactionsDetails(param).then(res => {
-      if (Array.isArray(res.data)) {
-        originReceiptRecord.value = res.data;
-        recordTotal.value = res.data.length;
-        handlePagination({ page: 1, limit: recordPage.size });
-      } else {
-        receiptRecord.value = res.data.records;
-        recordTotal.value = res.data.total;
-      }
-    });
+const handleSelectCustomer = (cust) => {
+  selectedCustomerId.value = cust.customerId;
+  contractPage.current = 1;
+  loadContracts();
+};
+
+const loadContracts = () => {
+  if (!selectedCustomerId.value) return;
+  contractLoading.value = true;
+  const params = {
+    projectId: selectedProjectId.value,
+    customerId: selectedCustomerId.value,
+    contractName: searchForm.value.contractName,
+    ...contractPage
   };
-
-  // 姹囨璁板綍鍒楄〃鍒嗛〉
-  const recordPaginationChange = pagination => {
-    recordPage.current = pagination.page;
-    recordPage.size = pagination.limit;
-    receiptPaymentList(customerId.value);
-  };
-
-  const rowClickMethod = row => {
-    customerId.value = row.customerId;
-    receiptPaymentList(customerId.value);
-  };
-
-  const handlePagination = ({ page, limit }) => {
-    recordPage.current = page;
-    recordPage.size = limit;
-
-    const start = (page - 1) * limit;
-    const end = start + limit;
-
-    receiptRecord.value = originReceiptRecord.value.slice(start, end);
-  };
-
-  onMounted(() => {
-    getList();
+  customewTransactionsDetails(params).then(res => {
+    contractLoading.value = false;
+    const records = Array.isArray(res.data) ? res.data : (res.data.records || []);
+    contracts.value = records;
+    contractTotal.value = res.data.total || records.length || 0;
+  }).catch(() => {
+    contractLoading.value = false;
   });
+};
+
+const handlePrjPageChange = (val) => {
+  prjPage.current = val;
+  loadProjects();
+};
+
+const handleCustPageChange = (val) => {
+  custPage.current = val;
+  loadCustomers();
+};
+
+const handleContractPageChange = (val) => {
+  contractPage.current = val;
+  loadContracts();
+};
+
+const fmtMoney = (num) => {
+  if (num === null || num === undefined || isNaN(num)) return '楼 0.00';
+  return '楼 ' + parseFloat(num).toLocaleString('zh-CN', {minimumFractionDigits: 2, maximumFractionDigits: 2});
+};
+
+const calcRate = (paid, amount) => {
+  if (!amount || amount == 0) return '0.0';
+  const val = ((paid || 0) / amount) * 100;
+  return val.toFixed(1);
+};
+
+const getDaysFromSign = (dateStr) => {
+  if (!dateStr) return 0;
+  const sign = new Date(dateStr);
+  const now = new Date();
+  const diffTime = now - sign;
+  return Math.max(0, Math.floor(diffTime / (1000 * 60 * 60 * 24)));
+};
+
+const tableRowClassName = ({row}) => {
+  if (row.isPaymentTimeout) {
+    return 'warning-row';
+  }
+  return '';
+};
+
+onMounted(() => {
+  loadProjects();
+  getSummary();
+});
 </script>
 
-<style scoped lang="scss">
-  .table_list {
-    width: 50%;
+<style scoped>
+/* CSS Variables */
+.layout-fullscreen {
+  --bg: #f8fafc;
+  --card: #ffffff;
+  --text: #0f172a;
+  --muted: #64748b;
+  --border: #e2e8f0;
+  --primary: #2563eb;
+  --primary-50: #eff6ff;
+  --success: #16a34a;
+  --success-50: #dcfce7;
+  --warning: #d97706;
+  --danger: #dc2626;
+  --danger-50: #fef2f2;
+  --danger-border: #fecaca;
+
+  height: calc(100vh - 84px); /* Fallback height, allows container to take viewport height */
+  display: flex;
+  flex-direction: column;
+  background-color: var(--bg);
+  padding: 16px;
+  overflow: hidden; /* Hide body scroll, let columns scroll */
+}
+
+/* 椤堕儴鎼滅储 */
+.search_form {
+  background: var(--card);
+  border: 1px solid var(--border);
+  border-radius: 8px;
+  padding: 16px 20px 0 20px;
+  margin-bottom: 12px;
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
+}
+
+/* 鍔ㄦ�佺粺璁℃眹鎬绘爮 */
+.summary-strip {
+  background: var(--card);
+  border: 1px solid var(--border);
+  border-radius: 8px;
+  padding: 10px 20px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 13px;
+  flex-shrink: 0;
+}
+
+.summary-stats {
+  display: flex;
+  gap: 20px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.summary-stats b {
+  color: var(--primary);
+  font-size: 14px;
+}
+
+.warn-summary {
+  background: var(--danger-50);
+  color: var(--danger);
+  padding: 2px 8px;
+  border-radius: 4px;
+  font-weight: 600;
+  border: 1px solid var(--danger-border);
+}
+
+/* 涓夋爮鑱斿姩 */
+.layout-columns {
+  flex: 1;
+  display: grid;
+  grid-template-columns: 310px 330px 1fr;
+  gap: 16px;
+  margin-top: 16px;
+  overflow: hidden;
+}
+
+@media (max-width: 1400px) {
+  .layout-columns {
+    grid-template-columns: 280px 300px 1fr;
   }
+}
+
+@media (max-width: 1200px) {
+  .layout-columns {
+    display: flex;
+    flex-direction: column;
+    overflow-y: auto;
+  }
+
+  .layout-fullscreen {
+    overflow: auto;
+  }
+
+  .column-panel {
+    min-height: 400px;
+  }
+}
+
+.column-panel {
+  background: var(--card);
+  border: 1px solid var(--border);
+  border-radius: 8px;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
+}
+
+.panel-header {
+  padding: 12px 16px;
+  background: #f8fafc;
+  border-bottom: 1px solid var(--border);
+  font-size: 14px;
+  font-weight: 600;
+  flex-shrink: 0;
+  color: var(--text);
+}
+
+.panel-body {
+  flex: 1;
+  overflow-y: auto;
+  padding: 12px;
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.panel-pagination {
+  padding: 8px;
+  background: #ffffff;
+  border-top: 1px solid var(--border);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-shrink: 0;
+}
+
+/* 鍒楄〃鍗$墖 (椤圭洰 & 瀹㈡埛) */
+.item-card {
+  background: #ffffff;
+  border: 1px solid var(--border);
+  border-radius: 6px;
+  padding: 12px 14px;
+  cursor: pointer;
+  transition: all 0.15s;
+}
+
+.item-card:hover {
+  border-color: #cbd5e1;
+  background: #f8fafc;
+}
+
+.item-card.active {
+  border-color: var(--primary);
+  background: var(--primary-50);
+  box-shadow: 0 0 0 1px var(--primary);
+}
+
+.card-title-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 6px;
+}
+
+.card-main-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: var(--text);
+  line-height: 1.4;
+}
+
+.card-code {
+  font-size: 11px;
+  color: var(--muted);
+  background: #f1f5f9;
+  padding: 2px 6px;
+  border-radius: 4px;
+  display: inline-block;
+}
+
+.meta-row {
+  display: flex;
+  justify-content: space-between;
+  font-size: 12px;
+  color: var(--muted);
+  margin-top: 4px;
+}
+
+.meta-row strong {
+  color: var(--text);
+  font-weight: 600;
+}
+
+.text-danger {
+  color: var(--danger) !important;
+  font-weight: 700;
+}
+
+:deep(.warning-row) {
+  background-color: var(--danger-50) !important;
+}
+
+.empty-state {
+  text-align: center;
+  color: var(--muted);
+  padding: 40px 16px;
+  font-size: 13px;
+}
 </style>
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index d2e82b5..ccef759 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -188,6 +188,7 @@
           </template>
         </el-table-column>
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+
         <el-table-column
           label="閿�鍞悎鍚屽彿"
           prop="salesContractNo"
@@ -216,7 +217,14 @@
           label="浠樻鏂瑰紡"
           prop="paymentMethod"
           show-overflow-tooltip
-        />
+        >
+          <template #default="scope">
+            <dict-tag
+              :options="checkout_payment"
+              :value="scope.row.paymentMethod"
+            />
+          </template>
+        </el-table-column>
         <el-table-column
           label="鍚堝悓閲戦(鍏�)"
           prop="contractAmount"
@@ -322,6 +330,76 @@
             </el-button>
           </el-col>
         </el-row>
+
+        <el-divider content-position="left">鍏宠仈椤圭洰</el-divider>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
+              <el-select
+                v-model="form.customerId"
+                placeholder="璇烽�夋嫨"
+                clearable
+                :disabled="operationType === 'view'"
+                filterable
+              >
+                <el-option
+                  v-for="item in customerOption"
+                  :key="item.id"
+                  :label="item.customerName"
+                  :value="item.id"
+                >
+                  {{
+                    item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
+                  }}
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectId">
+              <el-select
+                v-model="form.projectId"
+                placeholder="璇烽�夋嫨椤圭洰"
+                clearable
+                filterable
+                :disabled="operationType === 'view'"
+                @focus="previousProjectId = form.projectId"
+                @change="handleProjectChange"
+              >
+                <el-option
+                  v-for="item in projectOptions"
+                  :key="item.id"
+                  :label="item.no + ' - ' + item.title"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="鍏宠仈鍚堝悓锛�" prop="associatedContractIds">
+              <el-select
+                v-model="form.associatedContractIds"
+                multiple
+                placeholder="璇烽�夋嫨鍏宠仈鍚堝悓"
+                clearable
+                filterable
+                :disabled="operationType === 'view'"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in contractOptions"
+                  :key="item.id"
+                  :label="item.contractNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-divider content-position="left">鍙拌处淇℃伅</el-divider>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
@@ -372,44 +450,11 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
-              <el-select
-                v-model="form.customerId"
-                placeholder="璇烽�夋嫨"
-                clearable
-                :disabled="operationType === 'view'"
-                filterable
-              >
-                <el-option
-                  v-for="item in customerOption"
-                  :key="item.id"
-                  :label="item.customerName"
-                  :value="item.id"
-                >
-                  {{
-                    item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
-                  }}
-                </el-option>
-              </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
-                :disabled="operationType === 'view'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
             <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
               <el-date-picker
                 style="width: 100%"
                 v-model="form.executionDate"
+                @change="(val) => { if(val) form.year = parseInt(val.substring(0, 4)) }"
                 value-format="YYYY-MM-DD"
                 format="YYYY-MM-DD"
                 type="date"
@@ -421,12 +466,19 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input
+              <el-select
                 v-model="form.paymentMethod"
-                placeholder="璇疯緭鍏�"
+                placeholder="璇烽�夋嫨浠樻鏂瑰紡"
                 clearable
                 :disabled="operationType === 'view'"
-              />
+              >
+                <el-option
+                  v-for="item in checkout_payment"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -483,13 +535,160 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="绛惧崟鍗曚綅锛�" prop="signingUnitId">
+              <el-tree-select
+                v-model="form.signingUnitId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨绛惧崟鍗曚綅"
+                check-strictly
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍔炰簨澶勶細" prop="officeId">
+              <el-tree-select
+                v-model="form.officeId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨鍔炰簨澶�"
+                check-strictly
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="缁勮礋璐d汉锛�" prop="groupLeaderId">
+              <el-select
+                v-model="form.groupLeaderId"
+                filterable
+                placeholder="璇烽�夋嫨缁勮礋璐d汉"
+                clearable
+                :disabled="operationType === 'view'"
+              >
+                <el-option
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="骞翠唤锛�">
+              <el-input
+                v-model="form.year"
+                placeholder="鑷姩鍙栫璁㈡棩鏈�"
+                disabled
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏄惁寮�鍙戠エ锛�">
+              <el-switch
+                v-model="form.isInvoice"
+                :active-value="1"
+                :inactive-value="0"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁涓爣锛�">
+              <el-switch
+                v-model="form.isBid"
+                :active-value="1"
+                :inactive-value="0"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12" v-if="form.isBid === 1">
+            <el-form-item label="涓爣浠凤細">
+              <el-input-number
+                v-model="form.bidPrice"
+                :precision="2"
+                :step="1000"
+                :min="0"
+                style="width: 100%"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.isBid !== 1">
+            <el-form-item label="鏈腑鏍囧師鍥狅細">
+              <el-input
+                v-model="form.unbidReason"
+                placeholder="璇疯緭鍏ユ湭涓爣鍘熷洜"
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓鍘熶欢绾﹀畾鍥炰紶鏃ユ湡锛�">
+              <el-date-picker
+                style="width: 100%"
+                v-model="form.contractOriginalReturnDate"
+                value-format="YYYY-MM-DD"
+                format="YYYY-MM-DD"
+                type="date"
+                placeholder="璇烽�夋嫨鏃ユ湡"
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞锛�" prop="remarks">
+              <el-input
+                v-model="form.remarks"
+                placeholder="璇疯緭鍏�"
+                clearable
+                type="textarea"
+                :rows="2"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row v-if="operationType !== 'view'" :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="salesLedgerFiles">
+              <FileUpload
+                v-model:file-list="fileList"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-divider content-position="left">浜у搧淇℃伅</el-divider>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
+          <el-form-item label="" prop="entryDate">
             <el-button
               v-if="operationType !== 'view'"
               type="primary"
               @click="openProductForm('add')"
-              >娣诲姞
+              >娣诲姞鏄庣粏
             </el-button>
             <el-button
               v-if="operationType !== 'view'"
@@ -566,30 +765,6 @@
             </template>
           </el-table-column>
         </el-table>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="澶囨敞锛�" prop="remarks">
-              <el-input
-                v-model="form.remarks"
-                placeholder="璇疯緭鍏�"
-                clearable
-                type="textarea"
-                :rows="2"
-                :disabled="operationType === 'view'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row v-if="operationType !== 'view'" :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�" prop="salesLedgerFiles">
-              <FileUpload
-                v-model:file-list="fileList"
-                :disabled="operationType === 'view'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
       </el-form>
     </FormDialog>
     <!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->
@@ -1105,6 +1280,56 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
+            <el-form-item label="鍙戣揣鍗曟嵁锛�" prop="shippingDocument">
+              <el-input
+                v-model="deliveryForm.shippingDocument"
+                placeholder="璇疯緭鍏ュ彂璐у崟鎹�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="8">
+            <el-form-item label="鏄惁瀵硅处锛�" prop="isReconciled">
+              <el-switch v-model="deliveryForm.isReconciled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁缁撶畻锛�" prop="isSettled">
+              <el-switch v-model="deliveryForm.isSettled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁宸插紑绁細" prop="isInvoiced">
+              <el-switch v-model="deliveryForm.isInvoiced" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12" v-if="deliveryForm.isReconciled === 1">
+            <el-form-item label="瀵硅处鍗曞綊妗f儏鍐碉細" prop="statementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="deliveryForm.statementArchivingStatus"
+                placeholder="璇疯緭鍏ュ璐﹀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="deliveryForm.isSettled === 1">
+            <el-form-item label="缁撶畻鍗曞綊妗f儏鍐碉細" prop="settlementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="deliveryForm.settlementArchivingStatus"
+                placeholder="璇疯緭鍏ョ粨绠楀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
             <el-form-item label="搴撳瓨锛�" prop="batchNo">
               <el-table
                 :data="deliveryForm.batchNoList"
@@ -1176,9 +1401,11 @@
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
 import { ElMessageBox, ElMessage } from "element-plus";
 import useUserStore from "@/store/modules/user";
-import { userListNoPage } from "@/api/system/user.js";
+import { userListNoPage, deptTreeSelect } from "@/api/system/user.js";
+import { listProject, getProject } from "@/api/projectManagement/project.js";
 import FormDialog from "@/components/Dialog/FormDialog.vue";
 import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+import { contractListNoPage } from "@/api/salesManagement/contractManagement.js";
 import {
   ledgerListPage,
   productList,
@@ -1208,12 +1435,15 @@
 const route = useRoute();
 const userStore = useUserStore();
 const { proxy } = getCurrentInstance();
-const { tax_rate } = proxy.useDict("tax_rate");
+const { tax_rate, checkout_payment } = proxy.useDict("tax_rate", "checkout_payment");
 const tableData = ref([]);
 const productData = ref([]);
 const selectedRows = ref([]);
 const productSelectedRows = ref([]);
 const userList = ref([]);
+const deptOptions = ref([]);
+const projectOptions = ref([]);
+const contractOptions = ref([]);
 const customerOption = ref([]);
 const productOptions = ref([]);
 const modelOptions = ref([]);
@@ -1248,6 +1478,18 @@
     maintenanceTime: "",
     productData: [],
     executionDate: "",
+    projectId: undefined,
+    associatedContractIds: [],
+
+    year: "",
+    signingUnitId: undefined,
+    officeId: undefined,
+    groupLeaderId: undefined,
+    isInvoice: 0,
+    bidPrice: undefined,
+    isBid: 0,
+    unbidReason: "",
+    contractOriginalReturnDate: "",
     hasProductionRecord: false,
     createTime: "",
   },
@@ -1323,6 +1565,51 @@
   total: 0,
 });
 const selectedQuotation = ref(null);
+
+const previousProjectId = ref(null);
+const handleProjectChange = (val) => {
+  if (productData.value && productData.value.length > 0) {
+    ElMessageBox.confirm("褰撳墠宸插綍鍏ヤ骇鍝佹槑缁嗭紝鍒囨崲椤圭洰灏嗚瑕嗙洊锛屾槸鍚︾户缁紵", "鎻愮ず", {
+      type: "warning",
+    })
+      .then(() => {
+        previousProjectId.value = val;
+        fetchAndPopulateProject(val);
+      })
+      .catch(() => {
+        form.value.projectId = previousProjectId.value;
+      });
+  } else {
+    previousProjectId.value = val;
+    fetchAndPopulateProject(val);
+  }
+};
+
+const fetchAndPopulateProject = (val) => {
+  let proj = projectOptions.value.find((p) => p.id === val);
+  form.value.projectName = proj ? proj.title : "";
+
+  if (!val) {
+    productData.value = [];
+    return;
+  }
+
+  getProject(val).then((res) => {
+    const projectInfo = res.data;
+    if (projectInfo.info && projectInfo.info.clientId) {
+      form.value.customerId = projectInfo.info.clientId;
+    }
+    if (projectInfo.salesLedgerProductList) {
+      productData.value = projectInfo.salesLedgerProductList.map((item) => ({
+        ...item,
+        id: undefined,
+        salesLedgerId: undefined
+      }));
+    } else {
+      productData.value = [];
+    }
+  });
+};
 
 // 鍙戣揣鐩稿叧
 const deliveryFormVisible = ref(false);
@@ -1423,6 +1710,12 @@
     expressCompany: "",
     expressNumber: "",
     type: "璐ц溅", // 璐ц溅, 蹇��
+    shippingDocument: "",
+    isReconciled: 0,
+    statementArchivingStatus: "",
+    isSettled: 0,
+    settlementArchivingStatus: "",
+    isInvoiced: 0,
   },
   deliveryRules: {
     shippingCarNumber: [
@@ -1750,6 +2043,9 @@
   form.value = {};
   productData.value = [];
   selectedQuotation.value = null;
+  deptTreeSelect().then(res => deptOptions.value = res.data);
+  listProject({}).then(res => projectOptions.value = res.rows || res.data.records || res.data);
+  contractListNoPage({}).then(res => contractOptions.value = res.data);
   let userLists = await userListNoPage();
   userList.value = userLists.data;
   listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
@@ -2993,13 +3289,22 @@
   let res = await userStore.getInfo();
   currentFactoryName.value = res.user.currentFactoryName;
 };
-onMounted(() => {
+onMounted(async () => {
   searchForm.salesContractNo = route.query.salesContractNo;
   getList();
   userListNoPage().then((res) => {
     userList.value = res.data;
   });
   getCurrentFactoryName();
+
+  if (route.query.action === "add") {
+    await openForm("add");
+    if (route.query.projectId) {
+      const pId = Number(route.query.projectId);
+      form.value.projectId = pId;
+      fetchAndPopulateProject(pId);
+    }
+  }
 });
 </script>
 
diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index fce764f..edd0102 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -3,7 +3,7 @@
     <el-card class="box-card">
       <!-- 鎼滅储鍖哄煙 -->
       <el-row :gutter="20" class="search-row">
-        <el-col :span="8">
+        <el-col :span="6">
           <el-input
             v-model="searchForm.quotationNo"
             placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
@@ -15,7 +15,7 @@
             </template>
           </el-input>
         </el-col>
-        <el-col :span="8">
+        <el-col :span="6">
           <el-select v-model="searchForm.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable>
 						<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
 							{{
@@ -32,7 +32,12 @@
 <!--            <el-option label="宸茶繃鏈�" value="宸茶繃鏈�"></el-option>-->
 <!--          </el-select>-->
 <!--        </el-col>-->
-        <el-col :span="8">
+        <el-col :span="6">
+          <el-select v-model="searchForm.projectId" placeholder="璇烽�夋嫨椤圭洰鍚嶇О" clearable filterable>
+            <el-option v-for="item in projectOptions" :key="item.id" :label="item.no + ' - ' + item.title" :value="item.id" />
+          </el-select>
+        </el-col>
+        <el-col :span="6">
           <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
           <el-button @click="resetSearch">閲嶇疆</el-button>
           <el-button style="float: right;" type="primary" @click="handleAdd">
@@ -52,6 +57,7 @@
       >
 				<el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column prop="quotationNo" label="鎶ヤ环鍗曞彿" />
+        <el-table-column prop="projectName" label="椤圭洰鍚嶇О" />
         <el-table-column prop="customer" label="瀹㈡埛鍚嶇О" />
         <el-table-column prop="salesperson" label="涓氬姟鍛�" width="100" />
         <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="120" />
@@ -149,6 +155,13 @@
               <el-col :span="12">
                 <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
                   <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" clearable />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="椤圭洰鍚嶇О" prop="projectId">
+                  <el-select v-model="form.projectId" placeholder="璇烽�夋嫨椤圭洰鍚嶇О" style="width: 100%" clearable filterable>
+                    <el-option v-for="item in projectOptions" :key="item.id" :label="item.no + ' - ' + item.title" :value="item.id" />
+                  </el-select>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -258,6 +271,7 @@
     <el-dialog v-model="viewDialogVisible" title="鎶ヤ环璇︽儏" width="800px">
       <el-descriptions :column="2" border>
         <el-descriptions-item label="鎶ヤ环鍗曞彿">{{ currentQuotation.quotationNo }}</el-descriptions-item>
+        <el-descriptions-item label="椤圭洰鍚嶇О">{{ currentQuotation.projectName }}</el-descriptions-item>
         <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ currentQuotation.customer }}</el-descriptions-item>
         <el-descriptions-item label="涓氬姟鍛�">{{ currentQuotation.salesperson }}</el-descriptions-item>
         <el-descriptions-item label="鎶ヤ环鏃ユ湡">{{ currentQuotation.quotationDate }}</el-descriptions-item>
@@ -303,19 +317,22 @@
 import {modelList, productTreeList} from "@/api/basicData/product.js";
 import {listCustomer} from "@/api/basicData/customer.js";
 import { userListNoPage } from "@/api/system/user.js";
+import { listProject } from "@/api/projectManagement/project.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
 const searchForm = reactive({
   quotationNo: '',
   customerId: '',
-  status: ''
+  status: '',
+  projectId: undefined
 })
 
 const quotationList = ref([])
 const userList = ref([])
 const productOptions = ref([]);
 const modelOptions  = ref([]);
+const projectOptions = ref([]);
 const pagination = reactive({
   total: 3,
   currentPage: 1,
@@ -328,6 +345,7 @@
 const form = reactive({
   quotationNo: '',
   customerId: undefined,
+  projectId: undefined,
   customer: '',
   salesperson: '',
   quotationDate: '',
@@ -396,6 +414,7 @@
   searchForm.quotationNo = ''
   searchForm.customer = ''
   searchForm.status = ''
+  searchForm.projectId = undefined
   // 閲嶇疆鍒扮涓�椤靛苟閲嶆柊鏌ヨ
   pagination.currentPage = 1
   handleSearch()
@@ -407,7 +426,15 @@
   resetForm()
   dialogVisible.value = true
   getProductOptions();
-  fetchCustomerOptions()
+  fetchCustomerOptions();
+  fetchProjectOptions();
+}
+
+const fetchProjectOptions = () => {
+  if (projectOptions.value.length > 0) return
+  listProject({current: -1,size:-1}).then((res) => {
+    projectOptions.value = res.data.records;
+  });
 }
 
 const fetchCustomerOptions = () => {
@@ -530,7 +557,8 @@
       unitPrice: product.unitPrice || 0,
       amount: product.amount || 0
     })) : [],
-    totalAmount: row.totalAmount || 0
+    totalAmount: row.totalAmount || 0,
+    projectName: row.projectName || ''
   }
   viewDialogVisible.value = true
 }
@@ -543,11 +571,13 @@
   // 鍏堝姞杞戒骇鍝佹爲鏁版嵁锛屽惁鍒� el-tree-select 鏃犳硶鍙嶆樉浜у搧鍚嶇О
   await getProductOptions()
   await fetchCustomerOptions()
+  await fetchProjectOptions()
 
   // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
   form.quotationNo = row.quotationNo || ''
   form.customer = row.customer || ''
   form.customerId = row.customerId || undefined
+  form.projectId = row.projectId || undefined
   form.salesperson = row.salesperson || ''
   form.quotationDate = row.quotationDate || ''
   form.validDate = row.validDate || ''
@@ -629,6 +659,8 @@
 
 const resetForm = () => {
   form.customer = ''
+  form.customerId = undefined
+  form.projectId = undefined
   form.salesperson = ''
   form.quotationDate = ''
   form.validDate = ''
@@ -790,6 +822,7 @@
   getUserList()
   handleSearch()
   fetchCustomerOptions()
+  fetchProjectOptions()
 })
 </script>
 

--
Gitblit v1.9.3