From c75027743ea7c3ecc2d0885f01d11d2ad78679a3 Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期五, 23 十月 2026 14:23:26 +0800
Subject: [PATCH] Merge branch 'yxh' of http://116.62.18.175:6699/r/~yxh/opo-web

---
 src/assets/styles/index.scss                                       |    9 
 src/views/project/travelexpenseapply/edit.vue                      |   51 
 vue.config.js                                                      |    4 
 src/views/project/organallocation/index0.vue                       |    7 
 src/views/project/donorcharge/donorchargedetail/index.vue          |   45 
 src/layout/index.vue                                               |   16 
 src/views/project/register/index.vue                               |  351 ++
 src/views/project/donatefinishcheck/index.vue                      |   21 
 src/views/project/reimbursementpayee/index.vue                     |    3 
 src/store/modules/settings.js                                      |    3 
 src/views/monitor/logininfor/index.vue                             |    3 
 src/views/monitor/operlog/index.vue                                |    3 
 src/assets/styles/ruoyi.scss                                       |   11 
 src/views/project/travelexpensecheck/index.vue                     |   85 
 src/views/system/costmaintenance/index.vue                         |    1 
 src/views/project/donateorganstatics/index.vue                     |    1 
 src/views/project/reimbursement/index.vue                          |    3 
 src/views/monitor/job/log.vue                                      |    3 
 src/views/project/donateorgan/index.vue                            |    7 
 src/views/home/components/line2Chart/index.vue                     |    8 
 src/assets/styles/tokens.scss                                      |   98 
 src/settings.js                                                    |   89 
 src/views/home/components/BarChartH/index.vue                      |    8 
 src/utils/theme.js                                                 |  172 +
 src/assets/styles/tokens.css                                       |   91 
 src/assets/styles/element-variables.scss                           |   68 
 src/views/tool/gen/index.vue                                       |    3 
 src/views/project/reimbursementdetail/index.vue                    |    3 
 src/views/project/DonationEvaluation/index.vue                     |    1 
 src/api/project/fund.js                                            |   10 
 src/views/system/role/index.vue                                    |    3 
 src/views/home/components/BarChart3/index.vue                      |    8 
 src/views/project/tallage/index.vue                                |   17 
 src/views/project/statistics/applyStatistics/index.vue             |   51 
 src/views/system/menu/index.vue                                    |    3 
 src/views/project/ethicalReview/index.vue                          |    3 
 src/views/project/donateconsolationfund/index.vue                  |    3 
 src/views/system/dict/data.vue                                     |    3 
 src/views/tool/gen/importTable.vue                                 |    3 
 src/views/project/fund/officeExpenseApply/index.vue                |   40 
 src/views/project/fundcheck/performanceCheck/index.vue             |    5 
 src/views/project/organization/index.vue                           |    3 
 src/views/project/donateannexrequirement/index.vue                 |    3 
 src/assets/styles/variables.scss                                   |   22 
 src/views/project/donatefollowup/index.vue                         |    5 
 public/index.html                                                  |    2 
 src/assets/styles/sidebar.scss                                     |   46 
 src/views/system/dept/index.vue                                    |    3 
 src/views/system/medicalevalustion/index.vue                       |    3 
 src/views/project/documentfiles/index.vue                          |  118 
 src/views/project/unitCost/index.vue                               |    3 
 src/utils/request.js                                               |   24 
 src/views/system/student/index.vue                                 |    3 
 src/views/project/fundcheck/medicalCostCheck/index.vue             |   53 
 src/components/ThemePicker/index.vue                               |   21 
 src/views/project/donatefinish/index.vue                           |    7 
 src/api/project/register.js                                        |   27 
 src/utils/fileNameCheck.js                                         |  153 +
 src/views/project/itemexpense/index.vue                            |   18 
 src/views/project/donatebaseinfo/index.vue                         |  115 
 src/views/project/financesubject/index.vue                         |    3 
 src/views/system/class/index.vue                                   |    3 
 src/views/project/donateannex/index.vue                            |    1 
 src/views/project/fund/performancedetails/index.vue                |  475 ++
 src/views/home/components/line1Chart/index.vue                     |    8 
 src/views/project/relativesconfirmation/index.vue                  |   17 
 src/views/project/funddetail/index.vue                             |    3 
 src/views/system/role/authUser.vue                                 |    3 
 src/views/project/organallocation/index.vue                        |    3 
 src/views/project/tallage/computingBill/index.vue                  |   25 
 src/views/project/donationdetails/index.vue                        |  214 +
 src/views/system/post/index.vue                                    |    3 
 src/views/project/travelexpenseapply/travelexpensedetail/index.vue |  272 +
 src/views/home/components/MapChart/index.vue                       |    8 
 README.md                                                          |    9 
 src/views/project/donorcharge/donorcharge/index.vue                |    7 
 src/main.js                                                        |   11 
 src/views/project/DonationProcess/index.vue                        |   15 
 src/views/system/grade/index.vue                                   |    3 
 src/views/system/notice/index.vue                                  |    3 
 src/views/project/externalperson/index.vue                         |  113 
 src/assets/styles/theme-runtime.scss                               |  270 +
 src/layout/components/Settings/index.vue                           |   49 
 src/views/system/dict/index.vue                                    |    3 
 src/views/project/unitCost/particulars/index.vue                   |   27 
 src/views/project/travelexpensedeal/index.vue                      |    1 
 src/views/system/config/index.vue                                  |    3 
 src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue        |   60 
 src/views/project/statistics/caseStatistics/index.vue              |   51 
 src/views/project/donatereview/index.vue                           |   23 
 src/utils/money.js                                                 |  240 +
 src/views/project/fund/applyDetail0/index.vue                      |   99 
 src/views/project/donorcharge/organcharge/index.vue                |    3 
 src/views/system/role/selectUser.vue                               |    3 
 src/views/project/statistics/performanceStaristics/index.vue       |   51 
 build/checkMoney.js                                                |  148 +
 src/views/project/travelexpenseapply/index.vue                     | 1360 ++-------
 src/views/project/donationwitness/index.vue                        |   29 
 src/views/project/components/annexupload/index.vue                 |    2 
 src/views/project/fundflow/index.vue                               |    5 
 src/views/monitor/job/index.vue                                    |    3 
 src/views/project/fund/medicalCostApply/index.vue                  |  538 +--
 src/views/project/statistics/chargeStatistics/index.vue            |   51 
 src/views/project/fund/index.vue                                   |    3 
 src/views/home/components/BarChart2/index.vue                      |    8 
 src/views/monitor/online/index.vue                                 |    3 
 src/views/home/components/BarChart/index.vue                       |    8 
 src/views/home/components/lineChart/index.vue                      |   10 
 src/views/project/fund/performanceApply/index.vue                  |    3 
 src/views/project/fundcheck/officeExpenseCheck/index.vue           |   53 
 src/views/project/medicalevaluation/index.vue                      |    7 
 src/views/project/fundflowrule/index.vue                           |    1 
 src/views/project/fundstatistics/index.vue                         |    3 
 src/views/system/user/index.vue                                    |    3 
 src/views/project/fund/applyDetail/index.vue                       |  761 +++-
 src/views/project/fund/expertFeeApply/index.vue                    |  495 ++-
 src/views/project/fund/ethicalExpertFeeApply/index.vue             |  476 +-
 src/assets/styles/element-override.scss                            |  365 ++
 package.json                                                       |    5 
 src/views/project/fundcheck/expertFeeCheck/index.vue               |   44 
 src/views/project/distributedetail/index.vue                       |    3 
 121 files changed, 5,307 insertions(+), 3,108 deletions(-)

diff --git a/README.md b/README.md
index 19ff2bb..4ceed42 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,9 @@
 ## 寮�鍙�
 
+> 鏈洰褰� `opo-web/` 鍗� PC 鍓嶇宸ョ▼鏍圭洰褰曪紙鍘熻嫢渚濇ā鏉垮悕涓� `ruoyi-ui`锛屾澶勫凡鏀瑰悕锛夈��
+> 浠ヤ笅鍛戒护**鍧囧湪 `opo-web/` 涓嬫墽琛�**銆�
+
 ```bash
-# 鍏嬮殕椤圭洰
-git clone https://gitee.com/y_project/RuoYi-Vue
-
-# 杩涘叆椤圭洰鐩綍
-cd ruoyi-ui
-
 # 瀹夎渚濊禆
 npm install
 
diff --git a/build/checkMoney.js b/build/checkMoney.js
new file mode 100644
index 0000000..790b862
--- /dev/null
+++ b/build/checkMoney.js
@@ -0,0 +1,148 @@
+#!/usr/bin/env node
+/**
+ * 閲戦绮惧害妫�鏌ワ紙闃插鍙戦棬绂侊級
+ *
+ * 鑳屾櫙锛氶噾棰濇诞鐐圭疮鍔犲湪鏈」鐩弽澶嶅紩鍙戠嚎涓婇棶棰橈紝鍏稿瀷鐥囩姸鏄�
+ * 銆屽悎璁″涓嶄笂銆嶃�屽嚭鐜� -0.00銆嶃�岄噾棰濆甫涓�闀夸覆灏忔暟銆嶃�傛牴鍥犳槸 JS 鐨� Number
+ * 鏄� IEEE-754 鍙岀簿搴︽诞鐐癸紝瀵� 2 浣嶅皬鏁伴噾棰濆仛 + - * 浼氬紩鍏ヤ簩杩涘埗鑸嶅叆璇樊锛�
+ * 涓旇宸細闅忔槑缁嗘潯鏁扮疮绉紙瀹炴祴绾� 39% 鐨勫鏄庣粏缁勫悎浼氬嚭鐜板熬宸級銆�
+ *
+ * 鍥犳绾﹀畾锛氶噾棰濊繍绠椾竴寰嬩娇鐢� @/utils/money锛堝唴閮ㄥ熀浜� decimal.js锛屽崄杩涘埗绮剧‘杩愮畻锛夈��
+ *
+ * 鏈剼鏈壂鎻� src 涓嬬殑 .js / .vue锛屾壘鍑恒�岀枒浼煎閲戦鍋氭诞鐐圭疮鍔犮�嶇殑鍐欐硶骞舵姤閿欓��鍑猴紝
+ * 浠ヤ究鍦ㄦ彁浜ゅ墠鎷︿綇鍥炲綊銆傚缓璁寕鍒� pre-commit 鎴� CI銆�
+ *
+ * 鐢ㄦ硶锛�
+ *   node build/checkMoney.js
+ * 鎴� npm run check:money
+ *
+ * 鑻ョ‘璁ゆ煇澶勬槸璇姤锛堜緥濡傜疮鍔犵殑涓嶆槸閲戦锛岃�屾槸鏁伴噺銆佸ぉ鏁扮瓑锛夛紝
+ * 鍦ㄨ琛屼笂鏂瑰姞娉ㄩ噴锛�// money-check-ignore
+ */
+const fs = require("fs");
+const path = require("path");
+
+const SRC_DIR = path.resolve(__dirname, "../src");
+const IGNORE_COMMENT = "money-check-ignore";
+
+// 鍗遍櫓鍐欐硶锛氬 parseFloat 缁撴灉鍋氱疮鍔狅紝鎴栦互 parseFloat 鐩镐箻鍚庡弬涓庣疮鍔�
+const RULES = [
+  {
+    id: "float-accumulate",
+    // 褰㈠ totalFee += parseFloat(...)
+    pattern: /\+=\s*parseFloat\s*\(/,
+    message: "瀵� parseFloat 缁撴灉鍋氱疮鍔狅紝閲戦浼氱疮绉诞鐐硅宸�"
+  },
+  {
+    id: "float-subtract-assign",
+    // 褰㈠ totalFee -= parseFloat(...)
+    pattern: /-=\s*parseFloat\s*\(/,
+    message: "瀵� parseFloat 缁撴灉鍋氬噺娉曠疮鍔狅紝閲戦浼氱疮绉诞鐐硅宸�"
+  },
+  {
+    id: "float-text-math",
+    // 褰㈠ a = (parseFloat(x) - parseFloat(y)).toFixed(2)
+    pattern: /=\s*\(?\s*parseFloat\s*\([^)]*\)\s*[-+*]\s*parseFloat\s*\(/,
+    message: "parseFloat 涔嬮棿鐩存帴鍋氱畻鏈繍绠楀啀鏍煎紡鍖栵紝缁撴灉鍙兘甯︽诞鐐瑰熬宸�"
+  }
+];
+
+// 鎺掗櫎绗笁鏂瑰簱涓庢瀯寤轰骇鐗╋紝浠呮鏌ヤ笟鍔℃簮鐮�
+const EXCLUDE_DIRS = [
+  path.join(SRC_DIR, "echarts"), // echarts 绗笁鏂瑰簱婧愮爜
+  path.join(SRC_DIR, "assets")
+];
+
+// 鍏佽鐨勫啓娉曪細杩欎簺鏄鍗曚釜鍊肩殑鍚堟硶鎬�/闆跺�兼牎楠岋紝涓嶆瀯鎴愮疮鍔狅紝涓嶄細鏀惧ぇ璇樊
+const ALLOW = [/parseFloat\([^)]*\)\s*==\s*0/, /parseFloat\([^)]*\)\s*!=\s*0/];
+
+function walk(dir, out) {
+  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
+    const full = path.join(dir, entry.name);
+    if (entry.isDirectory()) {
+      if (entry.name === "node_modules") continue;
+      if (EXCLUDE_DIRS.indexOf(full) >= 0) continue;
+      walk(full, out);
+    } else if (/\.(js|vue)$/.test(entry.name)) {
+      out.push(full);
+    }
+  }
+  return out;
+}
+
+function checkFile(file) {
+  const lines = fs.readFileSync(file, "utf8").split(/\r?\n/);
+  const hits = [];
+  let inBlockComment = false;
+
+  lines.forEach((line, idx) => {
+    const code = line.trim();
+
+    // 璺熻釜璺ㄨ鍧楁敞閲婏細鍧楁敞閲婁腑鐨勪唬鐮佷笉鍙備笌妫�鏌ワ紙閬垮厤瀵瑰凡娉ㄩ噴鎺夌殑浠g爜璇姤锛�
+    if (inBlockComment) {
+      if (code.indexOf("*/") >= 0) inBlockComment = false;
+      return;
+    }
+    if (code.indexOf("/*") === 0) {
+      if (code.indexOf("*/") < 0) inBlockComment = true;
+      return;
+    }
+    // 琛屾敞閲�
+    if (code.indexOf("//") === 0 || code.indexOf("*") === 0) return;
+    // 鍏佽鐨勫啓娉曪細鍗曚釜鍊肩殑鍚堟硶鎬�/闆跺�兼牎楠�
+    if (ALLOW.some((re) => re.test(line))) return;
+    // 鏄惧紡璇姤鏍囪
+    const prev = idx > 0 ? lines[idx - 1] : "";
+    if (prev.indexOf(IGNORE_COMMENT) >= 0) return;
+
+    RULES.forEach((rule) => {
+      if (rule.pattern.test(line)) {
+        hits.push({ line: idx + 1, id: rule.id, message: rule.message, code: code.slice(0, 120) });
+      }
+    });
+  });
+
+  return hits;
+}
+
+function main() {
+  if (!fs.existsSync(SRC_DIR)) {
+    console.error(`鎵句笉鍒版簮鐮佺洰褰曪細${SRC_DIR}`);
+    process.exit(1);
+  }
+
+  const files = walk(SRC_DIR, []);
+  let total = 0;
+  const report = [];
+
+  files.forEach((file) => {
+    const hits = checkFile(file);
+    if (hits.length) {
+      total += hits.length;
+      report.push({ file: path.relative(path.resolve(__dirname, ".."), file), hits });
+    }
+  });
+
+  if (total === 0) {
+    console.log(`閲戦绮惧害妫�鏌ラ�氳繃锛堝凡鎵弿 ${files.length} 涓枃浠讹級`);
+    process.exit(0);
+  }
+
+  console.error("閲戦绮惧害妫�鏌ユ湭閫氳繃锛氬彂鐜扮枒浼奸噾棰濇诞鐐圭疮鍔燶n");
+  report.forEach(({ file, hits }) => {
+    console.error(`  ${file}`);
+    hits.forEach((h) => {
+      console.error(`    L${h.line}  [${h.id}] ${h.message}`);
+      console.error(`           ${h.code}`);
+    });
+    console.error("");
+  });
+  console.error("璇锋敼鐢� @/utils/money 鎻愪緵鐨勬柟娉曪紝渚嬪锛�");
+  console.error('  import { moneySum, moneyAdd, moneyMul, moneyRound } from "@/utils/money";');
+  console.error("  const total = moneyRound(moneySum(list, \"amount\"));");
+  console.error("  閲戦鐩哥瓑姣旇緝鐢� moneyEq()锛屼笉瑕佺敤 parseFloat(...) == 鎴� ===銆�");
+  console.error("  纭睘璇姤鏃讹紝鍦ㄨ琛屼笂鏂瑰姞娉ㄩ噴 // money-check-ignore");
+  process.exit(1);
+}
+
+main();
diff --git a/package.json b/package.json
index d4c726f..015116b 100644
--- a/package.json
+++ b/package.json
@@ -5,11 +5,12 @@
   "author": "娴欐睙浜ュ皵鏃朵俊鎭鎶�鏈夐檺鍏徃",
   "license": "MIT",
   "scripts": {
-    "dev": "vue-cli-service serve",
+    "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
     "preview": "node build/index.js --preview",
-    "lint": "eslint --ext .js,.vue src"
+    "lint": "eslint --ext .js,.vue src",
+    "check:money": "node build/checkMoney.js"
   },
   "husky": {
     "hooks": {
diff --git a/public/index.html b/public/index.html
index 925455c..257b020 100644
--- a/public/index.html
+++ b/public/index.html
@@ -174,7 +174,7 @@
     }
 
     #loader-wrapper .load_title {
-      font-family: 'Open Sans';
+      font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
       color: #FFF;
       font-size: 19px;
       width: 100%;
diff --git a/src/api/project/fund.js b/src/api/project/fund.js
index 92f64cc..3608fb9 100644
--- a/src/api/project/fund.js
+++ b/src/api/project/fund.js
@@ -160,6 +160,16 @@
   })
 }
 
+// 涓撳鍔冲姟璐癸細淇濆瓨鍓嶇殑璐圭敤鎺у埗鏍¢獙锛堝共璺戯紝涓嶈惤搴擄級
+// 杩斿洖 { errors: [闃绘柇鎬т俊鎭痌, warnings: [鎻愮ず淇℃伅], blocked: 鏄惁闃绘柇 }
+export function validateExpertFee(data) {
+  return request({
+    url: '/project/fund/validateExpertFee',
+    method: 'post',
+    data: data
+  })
+}
+
 // 浼︾悊涓撳璐规墦鍗�
 export function getdownloadLL(id) {
   return request({
diff --git a/src/api/project/register.js b/src/api/project/register.js
new file mode 100644
index 0000000..ca08933
--- /dev/null
+++ b/src/api/project/register.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍣ㄥ畼鍘诲鍒楄〃锛堟暟鎹簮锛氳鍥� v_service_donateorgan_register锛�
+export function listRegister(query) {
+  return request({
+    url: '/project/register/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ鍣ㄥ畼鍘诲璇︾粏
+export function getRegister(id) {
+  return request({
+    url: '/project/register/' + id,
+    method: 'get'
+  })
+}
+
+// 瀵煎嚭鍣ㄥ畼鍘诲鍒楄〃
+export function exportRegister(query) {
+  return request({
+    url: '/project/register/export',
+    method: 'get',
+    params: query
+  })
+}
diff --git a/src/assets/styles/element-override.scss b/src/assets/styles/element-override.scss
new file mode 100644
index 0000000..513143a
--- /dev/null
+++ b/src/assets/styles/element-override.scss
@@ -0,0 +1,365 @@
+// ============================================================
+// 缁勪欢榛樿澶栬锛堥潤鎬佷护鐗屽眰锛�
+// ------------------------------------------------------------
+// 鐩殑锛氫笉鏀逛换浣曚笟鍔¢〉闈㈡ā鏉匡紝鐢ㄥ叏灞�鏍峰紡鎶� Element 鐨勯粯璁よ鎰�
+//       缁熶竴鎴�"绱у噾銆佹竻鐖姐�佷笓涓�"鐨勪竴濂椼��
+// 閲嶇偣锛氳〃鏍硷紙鏂戦┈绾�/鍘荤珫绾�/琛ㄥご搴曡壊锛夈�佽〃鍗曘�佹寜閽�佸脊绐椼�佹爣绛俱��
+// 椤哄簭锛氬繀椤绘櫄浜� element-ui 涓� ruoyi.scss锛堣 main.js锛夈��
+// ============================================================
+
+// ---------- 鍏ㄥ眬鎺掔増 ----------
+body {
+  font-family: var(--opo-font-family-base);
+  font-size: var(--opo-font-size-base);
+  color: var(--opo-text-primary);
+  background-color: var(--opo-bg-page);
+}
+
+// 瑕嗙洊 index.scss 閲岀殑 label { font-weight: 700 }
+label {
+  font-weight: 400;
+}
+
+.app-container {
+  // 2026-10-22锛氱粺涓�鏀剁揣涓� 8/12/12锛堝師 12/16锛夛紝鍏ㄧ珯鍒楄〃椤典竴鑷�
+  padding: 8px 12px 12px;
+}
+
+// 鏁板瓧绫诲瓧娈碉紙閲戦/缂栧彿/韬唤璇侊級鍙敤姝ょ被鑾峰緱绛夊鏁板瓧
+.opo-number {
+  font-family: var(--opo-font-family-number);
+  font-variant-numeric: tabular-nums;
+}
+
+// ---------- 琛ㄦ牸 ----------
+// 2026-10-22锛氭暟鎹瀛楀彿涓庤〃澶寸粺涓�锛�14px / 甯歌瀛楅噸锛�
+// 娉ㄦ剰锛氬叏灞� size=small 浼氳姣忎釜琛ㄦ牸甯︿笂 .el-table--small锛�
+// Element 鐢ㄥ畠鎶婂瓧鍙峰啓鍥� 12px銆佸崟鍏冩牸 padding 鍐欏洖 8px锛�
+// 鎵�浠ヨ繖閲屽繀椤诲悓鏃舵彁楂橀�夋嫨鍣ㄧ壒寮傛�э紝鍚﹀垯浼氳鍘嬪洖鍘汇��
+.el-table,
+.el-table.el-table--small,
+.el-table.el-table--medium,
+.el-table.el-table--mini,
+.el-table.el-table--large {
+  color: var(--opo-text-primary);
+  font-size: var(--opo-font-size-sm);
+}
+
+.el-table {
+  th,
+  th.el-table__cell {
+    background-color: var(--opo-bg-thead) !important;
+    color: var(--opo-text-primary);
+    // 琛ㄥご涓嶅姞绮楋紙2026-10-22 鍙嶉锛�
+    font-weight: 400;
+    font-size: var(--opo-font-size-sm);
+    height: 40px;
+    padding: 0;
+  }
+
+  td,
+  td.el-table__cell,
+  &.el-table--small td.el-table__cell,
+  &.el-table--medium td.el-table__cell,
+  &.el-table--mini td.el-table__cell {
+    padding: 9px 0;
+    // 琛屽垎闅旂嚎锛�2026-10-22 鍐嶅姞娣变竴妗o級
+    border-bottom: 1px solid var(--opo-table-border, #c8cfd8);
+  }
+
+  // 琛ㄦ牸搴曢儴閭f潯绾�
+  &::before {
+    background-color: var(--opo-table-border, #c8cfd8);
+  }
+
+  // 甯﹁竟妗嗙殑琛ㄦ牸锛屽妗嗙嚎
+  &.el-table--border {
+    border-color: var(--opo-table-border, #c8cfd8);
+  }
+
+  .cell {
+    line-height: 23px;
+  }
+
+  // 琛ㄥご涓庡唴瀹瑰尯鐨勫垎闅旂嚎锛堟瘮琛岀嚎鍐嶆繁涓�鐐癸紝浣滀负鍒嗙晫锛�
+  .el-table__header-wrapper th {
+    border-bottom: 1px solid var(--opo-table-border-strong, #b7c0cc);
+  }
+
+  // 鏂戦┈绾癸細鐢� CSS 瀹炵幇锛屾棤闇�缁� 162 涓〃鏍奸�愪釜鍔� stripe 灞炴��
+  .el-table__body tr:nth-child(2n) > td,
+  .el-table__body tr:nth-child(2n) > td.el-table__cell {
+    background-color: var(--opo-bg-stripe);
+  }
+
+  // 榧犳爣琛岄珮浜紙瑕嗙洊鏂戦┈绾癸紱Element 榛樿 hover 鑹插亸鐏帮級
+  .el-table__body tr:hover > td,
+  .el-table__body tr:hover > td.el-table__cell {
+    background-color: var(--opo-primary-light-95, #f5f9fd);
+  }
+
+  // 鍘绘帀绔栫嚎锛歜order 灞炴�т粛淇濈暀鍦ㄦā鏉块噷锛岃繖閲屽彧璁╁畠鍦ㄨ瑙変笂娑堝け
+  &.el-table--border td,
+  &.el-table--border th,
+  &.el-table--border th.el-table__cell,
+  &.el-table--border td.el-table__cell {
+    border-right: none;
+  }
+
+  &.el-table--border::after,
+  &.el-table--group::after {
+    display: none;
+  }
+
+  .el-table__empty-text {
+    color: var(--opo-text-placeholder);
+    font-size: var(--opo-font-size-sm);
+  }
+}
+
+// 闇�瑕�"寮虹綉鏍肩嚎"鐨勬槑缁嗗綍鍏ヨ〃锛氭ā鏉夸笂鍔� class="table-bordered" 鍗冲彲鎭㈠
+.el-table.table-bordered {
+  border: 1px solid var(--opo-table-border, #c8cfd8);
+
+  td,
+  th,
+  td.el-table__cell,
+  th.el-table__cell {
+    border-right: 1px solid var(--opo-table-border, #c8cfd8);
+  }
+}
+
+// 琛ㄦ牸鍐呮寜閽洿绱у噾锛岄伩鍏嶆妸琛屾拺楂�
+.el-table .el-button--mini,
+.el-table .el-button--small {
+  padding: 5px 8px;
+}
+
+// ---------- 琛ㄥ崟 ----------
+// 鏌ヨ鏉′欢/琛ㄥ崟鏁翠綋鏀剁揣锛欵lement 榛樿 margin-bottom 22px锛岃璺濇槑鏄惧亸澶�
+.el-form-item {
+  margin-bottom: 12px;
+
+  &__label {
+    font-weight: 400;
+    color: var(--opo-text-regular);
+    // 鏍囩淇濇寔 14px锛氭煡璇㈠尯澶ч噺浣跨敤 label-width="68px"/"70px"锛�
+    // 鏍囩鑻ラ殢姝f枃鍗囧埌 16px锛�4 涓瓧锛堝"鎹愮尞妗堜緥"锛夊氨浼氭崲琛屻�佽楂樼炕鍊�
+    font-size: var(--opo-font-size-sm);
+    padding-right: 8px;
+    line-height: 32px;
+  }
+
+  &__content {
+    line-height: 32px;
+    min-height: 32px;
+  }
+
+  &.is-required:not(.is-no-asterisk) > .el-form-item__label:before {
+    color: var(--opo-danger);
+  }
+
+  &__error {
+    font-size: var(--opo-font-size-xs);
+    line-height: 1.4;
+    padding-top: 2px;
+  }
+}
+
+// 妯悜鎺掑垪鐨勬煡璇㈡潯浠跺啀绱у噾涓�妗�
+.el-form--inline .el-form-item {
+  margin-right: 12px;
+  margin-bottom: 8px;
+}
+
+// ---------- 绱у噾鏌ヨ鍖猴紙opt-in锛� ----------
+// 鐢ㄦ硶锛氱粰鏌ヨ鐢ㄧ殑 el-form 鍔� class="opo-query-form"锛堝垪琛ㄩ〉缁熶竴绾﹀畾锛�
+// 琛岃窛 8鈫�4px銆佹爣绛句笌鎺т欢瀵归綈銆佹渶鍚庝竴琛岋紙鎼滅储/閲嶇疆锛夊幓鎺変笅杈硅窛
+.opo-query-form {
+  // 鏌ヨ鏉′欢涓庝笅鏂�"鏂板/瀵煎嚭"宸ュ叿鏍忥紙瀵硅〃鏍肩殑鎿嶄綔锛変箣闂寸暀鍑洪棿璺�
+  margin-bottom: 12px;
+
+  .el-form-item {
+    margin-right: 8px;
+    margin-bottom: 4px;
+  }
+
+  .el-form-item__label {
+    line-height: 32px;
+    padding-right: 6px;
+  }
+
+  .el-form-item__content {
+    line-height: 32px;
+    min-height: 32px;
+  }
+
+  // 鏈�鍚庝竴琛岄�氬父鏄�"鎼滅储/閲嶇疆"锛屼笉鍐嶉澶栫暀鐧�
+  > .el-row:last-child .el-form-item {
+    margin-bottom: 0;
+  }
+}
+
+// 绱ц窡鏌ヨ鍖轰箣鍚庣殑宸ュ叿鏍忚锛堟柊澧�/瀵煎嚭锛夛細璐磋繎琛ㄦ牸锛屼笌鏌ヨ鍖虹敱 margin-bottom 闅斿紑
+.opo-query-form + .el-row.mb8 {
+  margin-bottom: 4px;
+}
+
+// 椤甸潰閲岀殑鏌ヨ鍖哄父鍖呭湪鍗$墖鎴� el-row 涓紝鍘绘帀澶氫綑鐨勫灞傜暀鐧�
+.el-card__body > .el-form:first-child,
+.el-card__body > .el-row:first-child .el-form {
+  margin-bottom: 0;
+}
+
+.el-input__inner,
+.el-textarea__inner {
+  border-radius: var(--opo-radius-base);
+  color: var(--opo-text-primary);
+
+  &::placeholder {
+    color: var(--opo-text-placeholder);
+  }
+}
+
+// ---------- 鎸夐挳 ----------
+.el-button {
+  border-radius: var(--opo-radius-base);
+  font-weight: 400;
+
+  [class*='el-icon-'] + span {
+    margin-left: 4px;
+  }
+}
+
+// 灏�/杩蜂綘鎸夐挳鐨勫瓧鍙峰湪 Element 閲屾槸纭紪鐮� 12px锛岄殢姝f枃涓�璧蜂笂璋冿紙2026-10-22 鍐嶅ぇ涓�鍙� 鈫� 16px锛�
+.el-button--small,
+.el-button--mini {
+  font-size: var(--opo-font-size-base);
+}
+
+// ---------- 寮圭獥 ----------
+.el-dialog {
+  border-radius: var(--opo-radius-lg);
+  box-shadow: var(--opo-shadow-lg);
+  overflow: hidden;
+
+  &__header {
+    padding: 16px 20px 12px;
+    border-bottom: 1px solid var(--opo-border-light);
+  }
+
+  &__title {
+    font-size: var(--opo-font-size-lg);
+    font-weight: 600;
+    color: var(--opo-text-primary);
+  }
+
+  &__body {
+    padding: 16px 20px;
+    color: var(--opo-text-regular);
+  }
+
+  &__footer {
+    padding: 12px 20px 16px;
+    border-top: 1px solid var(--opo-border-light);
+  }
+}
+
+.el-drawer__header {
+  padding: 16px 20px;
+  margin-bottom: 0;
+  border-bottom: 1px solid var(--opo-border-light);
+  color: var(--opo-text-primary);
+  font-weight: 600;
+}
+
+// ---------- 鏍囩 ----------
+.el-tag {
+  border-radius: var(--opo-radius-sm);
+  font-size: var(--opo-font-size-xs);
+}
+
+// ---------- 鍗$墖 ----------
+.el-card {
+  border-radius: var(--opo-radius-lg);
+  border-color: var(--opo-border-light);
+  box-shadow: var(--opo-shadow-sm) !important;
+
+  &__header {
+    padding: 14px 16px 10px;
+    border-bottom: 1px solid var(--opo-border-light);
+    font-weight: 600;
+    color: var(--opo-text-primary);
+  }
+
+  &__body {
+    padding: 12px 16px;
+  }
+}
+
+// ---------- 鍒嗛〉 ----------
+// Element 鎶婂垎椤垫枃瀛楀啓姝� 13px銆佸瓧閲� 700锛屽拰 16px 鐨勮〃鏍兼鏂囦笉鎼� 鈫� 缁熶竴 14px/甯歌
+.el-pagination {
+  font-weight: 400;
+  color: var(--opo-text-regular);
+  font-size: var(--opo-font-size-sm);
+
+  button,
+  span:not([class*='suffix']) {
+    font-size: var(--opo-font-size-sm);
+  }
+
+  .el-pager li {
+    font-size: var(--opo-font-size-sm);
+  }
+}
+
+.pagination-container {
+  margin-top: 12px;
+  height: auto;
+  padding: 8px 16px !important;
+}
+
+// ---------- 闈㈠寘灞� / 椤电 ----------
+.el-breadcrumb {
+  font-size: var(--opo-font-size-sm);
+
+  &__inner,
+  &__inner a {
+    font-weight: 400 !important;
+    color: var(--opo-text-secondary);
+  }
+
+  &__item:last-child .el-breadcrumb__inner {
+    color: var(--opo-text-primary);
+  }
+}
+
+// ---------- 鎻愮ず / 娑堟伅 ----------
+.el-message {
+  border-radius: var(--opo-radius-base);
+  box-shadow: var(--opo-shadow-md);
+}
+
+.el-tooltip__popper {
+  font-size: var(--opo-font-size-xs);
+}
+
+// ---------- 婊氬姩鏉★紙瑙傛劅缁嗚妭锛� ----------
+::-webkit-scrollbar {
+  width: 8px;
+  height: 8px;
+}
+
+::-webkit-scrollbar-thumb {
+  background-color: rgba(0, 0, 0, 0.18);
+  border-radius: var(--opo-radius-pill);
+
+  &:hover {
+    background-color: rgba(0, 0, 0, 0.28);
+  }
+}
+
+::-webkit-scrollbar-track {
+  background-color: transparent;
+}
diff --git a/src/assets/styles/element-variables.scss b/src/assets/styles/element-variables.scss
index 8b7a48e..39da0fb 100644
--- a/src/assets/styles/element-variables.scss
+++ b/src/assets/styles/element-variables.scss
@@ -1,23 +1,61 @@
 /**
-* I think element-ui's default theme color is too light for long-term use.
-* So I modified the default color and you can modify it to your liking.
-**/
+ * Element UI 涓婚鍙橀噺锛堢紪璇戞湡锛�
+ * ------------------------------------------------------------
+ * 鍝佺墝涓昏壊锛氬彇鑷� src/assets/logo/OPO_Logo.png 鍦嗙幆闈� #0E768F
+ * 鍗遍櫓鑹诧細  鍙栬嚜鍚屽浘蹇冨舰鐜孩 #CD1D4E锛堢櫧瀛楀姣斿害 5.41锛屼紭浜庡師 #F56C6C 鐨� 3.4锛�
+ *
+ * 璇存槑锛氳繖閲屽喅瀹�"缂栬瘧杩� CSS 鐨勯粯璁ょ毊鑲�"锛�
+ *      杩愯鏃舵崲鑲ょ敱 assets/styles/theme-runtime.scss + utils/theme.js 璐熻矗锛�
+ *      浜岃�呴�氳繃 CSS 鍙橀噺 --opo-primary* 琛旀帴銆�
+ */
 
-/* theme color */
-$--color-primary: #1890ff;
-$--color-success: #13ce66;
-$--color-warning: #ffba00;
-$--color-danger: #ff4949;
-// $--color-info: #1E1E1E;
+/* ---------- 涓婚鑹� ---------- */
+$--color-primary: #0E768F;
+$--color-success: #67C23A;
+$--color-warning: #E6A23C;
+$--color-danger: #CD1D4E;
+$--color-info: #909399;
+
+/* ---------- 鏂囧瓧 ---------- */
+$--color-text-primary: #1F2937;
+$--color-text-regular: #4B5563;
+$--color-text-secondary: #6B7280;
+$--color-text-placeholder: #9CA3AF;
+
+/* ---------- 杈规 ---------- */
+$--border-color-base: #E5E7EB;
+$--border-color-light: #F0F2F5;
+$--border-color-lighter: #F5F7FA;
+$--border-color-extra-light: #FAFBFC;
+
+/* ---------- 鑳屾櫙 ---------- */
+$--background-color-base: #F5F7FA;
+
+/* ---------- 鍦嗚 ---------- */
+$--border-radius-base: 4px;
+$--border-radius-small: 2px;
+
+/* ---------- 瀛楀彿锛�2026-10-22 鏁翠綋涓婅皟涓�鍙凤級 ---------- */
+$--font-size-extra-large: 22px;
+$--font-size-large: 20px;
+$--font-size-medium: 18px;
+$--font-size-base: 16px;
+$--font-size-small: 14px;
+$--font-size-extra-small: 13px;
+
+/* 鎸夐挳瀛楀彿榛樿鍦ㄥ皬灏哄閲岃纭紪鐮佹垚 12px锛屼竴骞朵笂璋� */
+$--button-font-size: 16px;
+$--button-medium-font-size: 16px;
+$--button-small-font-size: 14px;
+$--button-mini-font-size: 14px;
+
+/* 渚ц竟鏍忚彍鍗曞瓧鍙凤紙2026-10-22 鐢� 18px 鍥炶皟涓�鍙凤級 */
+$--menu-item-font-size: 16px;
 
 $--button-font-weight: 400;
 
-// $--color-text-regular: #1f2d3d;
-
-$--border-color-light: #dfe4ed;
-$--border-color-lighter: #e6ebf5;
-
-$--table-border:1px solid#dfe6ec;
+/* ---------- 琛ㄦ牸 ---------- */
+$--table-border: 1px solid #E5E7EB;
 
 /* icon font path, required */
 $--font-path: '~element-ui/lib/theme-chalk/fonts';
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index 49eb8c9..0a7ad3e 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -10,11 +10,12 @@
   -moz-osx-font-smoothing: grayscale;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  font-family: $opo-font-family-base;
 }
 
+// 琛ㄥ崟鏍囩涓嶅啀鍏ㄥ眬鍔犵矖锛堝師鏉� 700 璁╂墍鏈夐〉闈㈡樉寰楀緢"閲�"锛�
 label {
-  font-weight: 700;
+  font-weight: 400;
 }
 
 html {
@@ -103,8 +104,8 @@
   border-radius: 2px;
   display: block;
   line-height: 32px;
-  font-size: 16px;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+  font-size: $opo-font-size-lg;
+  font-family: $opo-font-family-base;
   color: #2c3e50;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index 8fe1961..cc33197 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -3,6 +3,9 @@
  * Copyright (c) 2019 ruoyi
  */
 
+/* 璁捐浠ょ墝锛堟湰鏂囦欢涓虹嫭绔嬪叆鍙o紝闇�鑷寮曞叆鍙橀噺锛� */
+@import './tokens.scss';
+
  /** 鍩虹閫氱敤 **/
 .pt5 {
 	padding-top: 5px;
@@ -75,10 +78,10 @@
 	.el-table__header-wrapper, .el-table__fixed-header-wrapper {
 		th {
 			word-break: break-word;
-			background-color: #f8f8f9;
-			color: #515a6e;
+			background-color: $opo-bg-thead;
+			color: $opo-text-primary;
 			height: 40px;
-			font-size: 13px;
+			font-size: $opo-font-size-sm;
 		}
 	}
 	.el-table__body-wrapper {
@@ -137,7 +140,7 @@
 /** 琛ㄦ牸鏇村鎿嶄綔涓嬫媺鏍峰紡 */
 .el-table .el-dropdown-link {
 	cursor: pointer;
-	color: #409EFF;
+	color: var(--opo-primary, #0E768F);
 	margin-left: 5px;
 }
 
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index bb91f3f..f28a921 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -67,17 +67,23 @@
       width: 100% !important;
     }
 
+    // 鑿滃崟瀛楀彿锛氭瘮姝f枃澶т袱鍙凤紙姝f枃 16px 鈫� 鑿滃崟 18px锛�
+    .el-menu-item,
+    .el-submenu__title {
+      font-size: $opo-font-size-menu;
+    }
+
     .el-menu-item, .el-submenu__title {
       overflow: hidden !important;
       text-overflow: ellipsis !important;
       white-space: nowrap !important;
     }
 
-    // menu hover
+    // menu hover锛堟繁鑹插簳涓婄敤閫忕櫧锛屽師鏉� rgba(0,0,0,.06) 鍦ㄦ繁鑹蹭笂鐪嬩笉鍑烘潵锛�
     .submenu-title-noDropdown,
     .el-submenu__title {
       &:hover {
-        background-color: rgba(0, 0, 0, 0.06) !important;
+        background-color: rgba(255, 255, 255, 0.08) !important;
       }
     }
 
@@ -90,7 +96,7 @@
       min-width: $base-sidebar-width !important;
 
       &:hover {
-        background-color: rgba(0, 0, 0, 0.06) !important;
+        background-color: rgba(255, 255, 255, 0.08) !important;
       }
     }
 
@@ -101,6 +107,36 @@
       &:hover {
         background-color: $base-sub-menu-hover !important;
       }
+    }
+
+    // ---- 褰撳墠閫変腑鑿滃崟楂樹寒 ----
+    // 鍘熺姸锛欵lement 缂栬瘧鍑虹殑 .el-menu-item.is-active 鏄富鑹叉枃瀛楋紝
+    // 鍦ㄥ悓鏍锋槸闈掕壊鐨勬繁鑹蹭晶杈规爮涓婂嚑涔庣湅涓嶈 鈫� 鏀逛负"鍝佺墝闈掑疄搴� + 鐧藉瓧 + 宸︿晶浜潯"
+    & .el-menu-item.is-active {
+      position: relative;
+      color: #ffffff !important;
+      background-color: $opo-primary !important;
+      font-weight: 500;
+
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        top: 0;
+        bottom: 0;
+        width: 3px;
+        background-color: #ffffff;
+      }
+
+      &:hover {
+        background-color: $opo-primary !important;
+      }
+    }
+
+    // 鐖剁骇鍒嗙粍鍙槸"鍖呭惈閫変腑椤�"锛岀敤寮变竴鐐圭殑搴曡壊锛岄伩鍏嶅拰鍙跺瓙椤逛竴鏍烽噸
+    & .el-submenu.is-active > .el-submenu__title {
+      background-color: rgba(255, 255, 255, 0.1) !important;
+      color: #ffffff !important;
     }
   }
 
@@ -198,8 +234,8 @@
   .nest-menu .el-submenu>.el-submenu__title,
   .el-menu-item {
     &:hover {
-      // you can use $subMenuHover
-      background-color: rgba(0, 0, 0, 0.06) !important;
+      // 娣辫壊鑿滃崟鐢ㄩ�忕櫧瑕嗙洊
+      background-color: rgba(255, 255, 255, 0.08) !important;
     }
   }
 
diff --git a/src/assets/styles/theme-runtime.scss b/src/assets/styles/theme-runtime.scss
new file mode 100644
index 0000000..233599c
--- /dev/null
+++ b/src/assets/styles/theme-runtime.scss
@@ -0,0 +1,270 @@
+// ============================================================
+// 杩愯鏃朵富棰樺眰锛圕SS 鍙橀噺娑堣垂鏂癸級
+// ------------------------------------------------------------
+// Element UI 2.x 鐨勪富棰樿壊鏄� SCSS 缂栬瘧鏈熷父閲忥紝鏃犳硶鍦ㄨ繍琛屾椂淇敼銆�
+// 鏈枃浠朵笉鏀� Element 婧愮爜锛屽彧"閲嶅啓鐢ㄥ埌涓昏壊鐨勯�夋嫨鍣�"锛屽�兼敼涓�
+// var(--opo-primary*)锛涜繖浜涘彉閲忕敱 utils/theme.js 鍦ㄥ垏鎹㈢毊鑲ゆ椂鍐欏叆
+// :root锛屽洜姝ゆ崲鑲ゆ棤闇�閲嶆柊缂栬瘧銆佹棤闇�鍒锋柊椤甸潰銆�
+//
+// 瑕嗙洊椤哄簭寰堝叧閿細鏈枃浠跺繀椤诲湪 element-ui 涓� ruoyi.scss 涔嬪悗寮曞叆
+// 锛堣 main.js 鐨� import 椤哄簭锛夈��
+// 瑕嗙洊鑼冨洿锛氭寜閽�/閾炬帴/杈撳叆/鍗曢�夊閫夊紑鍏�/Tabs/鍒嗛〉/琛ㄦ牸/姝ラ鏉�/
+//          鏃ユ湡/涓嬫媺/鍔犺浇/杩涘害锛屽叾浣欑粍浠舵寜闇�琛ュ厖銆�
+// ============================================================
+
+$opo-fallback: #0E768F;
+
+// ---------- 鎸夐挳 ----------
+.el-button--primary {
+  background-color: var(--opo-primary, #{$opo-fallback});
+  border-color: var(--opo-primary, #{$opo-fallback});
+  color: #fff;
+
+  &:hover,
+  &:focus {
+    background-color: var(--opo-primary-hover, #{$opo-fallback});
+    border-color: var(--opo-primary-hover, #{$opo-fallback});
+    color: #fff;
+  }
+
+  &:active {
+    background-color: var(--opo-primary-active, #{$opo-fallback});
+    border-color: var(--opo-primary-active, #{$opo-fallback});
+    color: #fff;
+  }
+
+  &.is-disabled,
+  &.is-disabled:hover,
+  &.is-disabled:focus,
+  &.is-disabled:active {
+    background-color: var(--opo-primary-light-5, #{$opo-fallback});
+    border-color: var(--opo-primary-light-5, #{$opo-fallback});
+    color: #fff;
+  }
+
+  &.is-plain {
+    background-color: var(--opo-primary-light-9, #fff);
+    border-color: var(--opo-primary-light-5, #{$opo-fallback});
+    color: var(--opo-primary, #{$opo-fallback});
+
+    &:hover,
+    &:focus,
+    &:active {
+      background-color: var(--opo-primary, #{$opo-fallback});
+      border-color: var(--opo-primary, #{$opo-fallback});
+      color: #fff;
+    }
+  }
+}
+
+.el-button--text {
+  color: var(--opo-primary, #{$opo-fallback});
+
+  &:hover,
+  &:focus {
+    color: var(--opo-primary-hover, #{$opo-fallback});
+  }
+
+  &.is-disabled,
+  &.is-disabled:hover {
+    color: var(--opo-primary-light-5, #{$opo-fallback});
+  }
+}
+
+// 榛樿鎸夐挳 hover 鏃堕�忓嚭鍝佺墝鑹诧紙鍘熸潵鏄竴鐗囩伆锛�
+.el-button--default:hover,
+.el-button--default:focus {
+  color: var(--opo-primary, #{$opo-fallback});
+  border-color: var(--opo-primary-light-5, #{$opo-fallback});
+  background-color: var(--opo-primary-light-9, #fff);
+}
+
+// ---------- 閾炬帴 ----------
+.el-link.el-link--primary {
+  color: var(--opo-primary, #{$opo-fallback});
+
+  &:hover {
+    color: var(--opo-primary-light-3, #{$opo-fallback});
+  }
+}
+
+// ---------- 杈撳叆绫� ----------
+.el-input__inner:focus,
+.el-textarea__inner:focus,
+.el-input__inner:hover {
+  border-color: var(--opo-primary-light-5, #{$opo-fallback});
+}
+
+.el-input__inner:focus,
+.el-textarea__inner:focus {
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-select .el-input.is-focus .el-input__inner,
+.el-select .el-input__inner:focus {
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-select-dropdown__item.selected {
+  color: var(--opo-primary, #{$opo-fallback});
+  font-weight: 600;
+}
+
+.el-input-number__decrease:hover,
+.el-input-number__increase:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 鍗曢�� / 澶嶉�� ----------
+.el-radio__input.is-checked .el-radio__inner,
+.el-checkbox__input.is-checked .el-checkbox__inner,
+.el-checkbox__input.is-indeterminate .el-checkbox__inner {
+  border-color: var(--opo-primary, #{$opo-fallback});
+  background-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-radio__input.is-checked + .el-radio__label,
+.el-checkbox__input.is-checked + .el-checkbox__label {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-radio-button__orig-radio:checked + .el-radio-button__inner,
+.el-checkbox-button__orig-radio:checked + .el-checkbox-button__inner {
+  background-color: var(--opo-primary, #{$opo-fallback});
+  border-color: var(--opo-primary, #{$opo-fallback});
+  box-shadow: -1px 0 0 0 var(--opo-primary, #{$opo-fallback});
+  color: #fff;
+}
+
+// ---------- 寮�鍏� ----------
+.el-switch.is-checked .el-switch__core {
+  border-color: var(--opo-primary, #{$opo-fallback});
+  background-color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- Tabs ----------
+.el-tabs__item.is-active,
+.el-tabs__item:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-tabs__active-bar {
+  background-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
+  color: var(--opo-primary, #{$opo-fallback});
+  border-bottom-color: transparent;
+}
+
+// ---------- 鍒嗛〉 ----------
+.el-pager li.active,
+.el-pager li:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-pagination.is-background .el-pager li:not(.disabled).active {
+  background-color: var(--opo-primary, #{$opo-fallback});
+  color: #fff;
+}
+
+.el-pagination button:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 琛ㄦ牸 ----------
+.el-table .ascending .sort-caret.ascending {
+  border-bottom-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-table .descending .sort-caret.descending {
+  border-top-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-table__body tr.current-row > td {
+  background-color: var(--opo-primary-light-9, #fff) !important;
+}
+
+.el-table--enable-row-hover .el-table__body tr:hover > td {
+  background-color: var(--opo-primary-light-95, #f5f9fd) !important;
+}
+
+// ---------- 姝ラ鏉� ----------
+.el-step__head.is-process {
+  color: var(--opo-primary, #{$opo-fallback});
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-step__title.is-process {
+  color: var(--opo-primary, #{$opo-fallback});
+  font-weight: 600;
+}
+
+.el-step__head.is-finish {
+  color: var(--opo-primary, #{$opo-fallback});
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-step__title.is-finish {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 鏃ユ湡 / 鏃堕棿 ----------
+.el-date-table td.today span {
+  color: var(--opo-primary, #{$opo-fallback});
+  font-weight: 700;
+}
+
+.el-date-table td.current:not(.disabled) span {
+  background-color: var(--opo-primary, #{$opo-fallback});
+  color: #fff;
+}
+
+.el-date-table td.available:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-date-picker__header-label.active,
+.el-date-picker__header-label:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 涓嬫媺 / 寮瑰嚭鑿滃崟锛堝彧浣滅敤浜庡脊鍑哄眰锛岄伩鍏嶅奖鍝嶆繁鑹蹭晶杈规爮锛� ----------
+.el-dropdown-menu__item:not(.is-disabled):hover,
+.el-dropdown-menu__item:focus {
+  color: var(--opo-primary, #{$opo-fallback});
+  background-color: var(--opo-primary-light-9, #fff);
+}
+
+.el-menu--popup .el-menu-item.is-active,
+.el-menu--popup .el-menu-item:hover {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 绾ц仈 ----------
+.el-cascader .el-input.is-focus .el-input__inner {
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-cascader-node.in-active-path,
+.el-cascader-node.is-active {
+  color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 鍔犺浇 / 杩涘害 ----------
+.el-loading-spinner .path {
+  stroke: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-progress-bar__inner {
+  background-color: var(--opo-primary, #{$opo-fallback});
+}
+
+// ---------- 婊戝潡 ----------
+.el-slider__bar {
+  background-color: var(--opo-primary, #{$opo-fallback});
+}
+
+.el-slider__button {
+  border-color: var(--opo-primary, #{$opo-fallback});
+}
diff --git a/src/assets/styles/tokens.css b/src/assets/styles/tokens.css
new file mode 100644
index 0000000..c25caef
--- /dev/null
+++ b/src/assets/styles/tokens.css
@@ -0,0 +1,91 @@
+/* ============================================================
+ * 璁捐浠ょ墝 路 CSS 鑷畾涔夊睘鎬�
+ * 杩愯鏃舵崲鑲ゅ彧闇�鏀瑰姩 --opo-primary 鍙婂叾娲剧敓鑹查樁锛堢敱 utils/theme.js 娉ㄥ叆锛�
+ * 杩欓噷鐨勫�兼槸"鍝佺墝闈�"榛樿鍊硷紱JS 娉ㄥ叆鐨� inline style 浼氳鐩� :root
+ * ============================================================ */
+:root {
+  /* 鍝佺墝鑹诧紙榛樿锛歄PO_Logo 鍦嗙幆闈掞級 */
+  --opo-primary: #0E768F;
+  --opo-primary-hover: #0D6A81;
+  --opo-primary-active: #0B5E72;
+  --opo-primary-light-3: #569FB1;
+  --opo-primary-light-5: #87BBC7;
+  --opo-primary-light-7: #B7D6DD;
+  --opo-primary-light-8: #CFE4E9;
+  --opo-primary-light-9: #E7F1F4;
+  --opo-primary-light-95: #F3F8F9;
+  --opo-primary-dark-2: #0B5E72;
+
+  /* 璇箟鑹� */
+  --opo-success: #67C23A;
+  --opo-success-light: #F0F9EB;
+  --opo-warning: #E6A23C;
+  --opo-warning-light: #FDF6EC;
+  --opo-danger: #CD1D4E;
+  --opo-danger-light: #FBEBEF;
+  --opo-info: #909399;
+  --opo-info-light: #F4F4F5;
+
+  /* 涓�ц壊 */
+  --opo-text-primary: #1F2937;
+  --opo-text-regular: #4B5563;
+  --opo-text-secondary: #6B7280;
+  --opo-text-placeholder: #9CA3AF;
+  --opo-border-base: #E5E7EB;
+  --opo-border-light: #F0F2F5;
+  --opo-border-lighter: #F5F7FA;
+  --opo-bg-page: #F5F7FA;
+  --opo-bg-card: #FFFFFF;
+  --opo-bg-hover: #F5F9FD;
+  --opo-bg-stripe: #FAFBFC;
+  --opo-bg-thead: #F5F7FA;
+
+  /* 琛ㄦ牸妗嗙嚎锛堟瘮閫氱敤杈规鏇存繁锛� */
+  --opo-table-border: #C8CFD8;
+  --opo-table-border-strong: #B7C0CC;
+
+  /* 渚ц竟鏍� */
+  --opo-sidebar-bg: #0A4655;
+  --opo-sidebar-sub-bg: #083B47;
+  --opo-sidebar-hover: rgba(14, 118, 143, 0.28);
+  --opo-sidebar-text: rgba(255, 255, 255, 0.72);
+  --opo-sidebar-text-active: #FFFFFF;
+
+  /* 瀛楀彿锛�2026-10-22 鏁翠綋涓婅皟涓�鍙凤細姝f枃 14鈫�16锛� */
+  --opo-font-size-display: 34px;
+  --opo-font-size-h1: 26px;
+  --opo-font-size-h2: 20px;
+  --opo-font-size-lg: 18px;
+  --opo-font-size-base: 16px;
+  --opo-font-size-sm: 14px;
+  --opo-font-size-xs: 13px;
+  --opo-font-size-menu: 16px;
+
+  /* 瀛椾綋锛堜笉瑕佺敤 -apple-system 鎵撳ご锛學indows 涓婁細鍙樻垚 Segoe UI锛屾暟瀛楁樉灏忥級 */
+  --opo-font-family-base: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "寰蒋闆呴粦",
+    "Helvetica Neue", Arial, sans-serif;
+  --opo-font-family-number: "DIN Alternate", "SF Mono", "Roboto Mono", Consolas, "Courier New", monospace;
+
+  /* 闂磋窛 */
+  --opo-space-1: 4px;
+  --opo-space-2: 8px;
+  --opo-space-3: 12px;
+  --opo-space-4: 16px;
+  --opo-space-5: 24px;
+  --opo-space-6: 32px;
+
+  /* 鍦嗚 */
+  --opo-radius-sm: 2px;
+  --opo-radius-base: 4px;
+  --opo-radius-lg: 8px;
+  --opo-radius-pill: 999px;
+
+  /* 闃村奖 */
+  --opo-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
+  --opo-shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
+  --opo-shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);
+
+  /* 鎺т欢楂樺害 */
+  --opo-control-height-small: 32px;
+  --opo-control-height-base: 36px;
+}
diff --git a/src/assets/styles/tokens.scss b/src/assets/styles/tokens.scss
new file mode 100644
index 0000000..852df0d
--- /dev/null
+++ b/src/assets/styles/tokens.scss
@@ -0,0 +1,98 @@
+// ============================================================
+// 璁捐浠ょ墝锛圖esign Tokens锛壜� SCSS 鍙橀噺
+// 鍝佺墝鑹插彇鑷� src/assets/logo/OPO_Logo.png 鍦嗙幆闈� #0E768F
+// 璇存槑瑙侊細鏂规-鍓嶇鐣岄潰瑙嗚浼樺寲鏂规.md
+// 绾﹀畾锛氫笟鍔℃牱寮忎竴寰嬪紩鐢ㄨ繖閲岀殑鍙橀噺锛岀姝㈠啀鍐欒8鑹插��
+// ============================================================
+
+// ---------- 鍝佺墝鑹诧紙闈掞級 ----------
+$opo-primary:          #0E768F;
+$opo-primary-hover:    #0D6A81;
+$opo-primary-active:   #0B5E72;
+$opo-primary-light-3:  #569FB1;
+$opo-primary-light-5:  #87BBC7;
+$opo-primary-light-7:  #B7D6DD;
+$opo-primary-light-8:  #CFE4E9;
+$opo-primary-light-9:  #E7F1F4;
+$opo-primary-light-95: #F3F8F9;
+$opo-primary-dark-2:   #0B5E72;
+
+// ---------- 璇箟鑹� ----------
+$opo-success:       #67C23A;
+$opo-success-light: #F0F9EB;
+$opo-warning:       #E6A23C;
+$opo-warning-light: #FDF6EC;
+$opo-danger:        #CD1D4E;
+$opo-danger-light:  #FBEBEF;
+$opo-info:          #909399;
+$opo-info-light:    #F4F4F5;
+
+// ---------- 涓�ц壊 ----------
+$opo-text-primary:     #1F2937;
+$opo-text-regular:     #4B5563;
+$opo-text-secondary:   #6B7280;
+$opo-text-placeholder: #9CA3AF;
+$opo-border-base:      #E5E7EB;
+$opo-border-light:     #F0F2F5;
+$opo-border-lighter:   #F5F7FA;
+$opo-bg-page:          #F5F7FA;
+$opo-bg-card:          #FFFFFF;
+$opo-bg-hover:         #F5F9FD;
+$opo-bg-stripe:        #FAFBFC;
+$opo-bg-thead:         #F5F7FA;
+
+// ---------- 琛ㄦ牸妗嗙嚎锛堟瘮閫氱敤杈规鏇存繁锛屼究浜庣湅娓呭垎鍒�/鍒嗚锛� ----------
+$opo-table-border:        #C8CFD8;
+$opo-table-border-strong: #B7C0CC;
+
+// ---------- 渚ц竟鏍忥紙涓庡搧鐗岄潚鍚屾棌锛� ----------
+$opo-sidebar-bg:          #0A4655;
+$opo-sidebar-sub-bg:      #083B47;
+$opo-sidebar-hover:       rgba(14, 118, 143, 0.28);
+$opo-sidebar-text:        rgba(255, 255, 255, 0.72);
+$opo-sidebar-text-active: #FFFFFF;
+
+// ---------- 瀛楀彿锛�2026-10-22 鏁翠綋涓婅皟涓�鍙凤細姝f枃 14鈫�16锛� ----------
+$opo-font-size-display: 34px;
+$opo-font-size-h1:      26px;
+$opo-font-size-h2:      20px;
+$opo-font-size-lg:      18px;
+$opo-font-size-base:    16px;
+$opo-font-size-sm:      14px;
+$opo-font-size-xs:      13px;
+$opo-font-size-menu:    16px;  // 渚ц竟鏍忚彍鍗曪紙2026-10-22 鐢� 18px 鍥炶皟涓�鍙凤級
+
+// ---------- 琛岄珮 ----------
+$opo-line-height-base:    22px;
+$opo-line-height-heading: 1.3;
+
+// ---------- 瀛椾綋 ----------
+// 娉ㄦ剰锛氫笉瑕佺敤 -apple-system / BlinkMacSystemFont 鎵撳ご鈥斺�擶indows 涓� Chrome 浼氳В鏋愭垚 Segoe UI锛�
+// 瀵艰嚧鏁板瓧/鑻辨枃璧� Segoe UI锛堟瘮涓枃缁嗐�佹樉灏忥級锛屼腑鏂囧洖閫�寰蒋闆呴粦锛屽悓涓�琛岄噷瀛楀彿瑙傛劅涓嶄竴鑷淬��
+// 杩欓噷鎸�"骞冲彴鏈夊垯鐢ㄣ�佹病鏈夊垯閫�鍒板井杞泤榛�"鐨勯『搴忥紝淇濊瘉涓嫳鏂囧悓鏃忋��
+$opo-font-family-base:   "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "寰蒋闆呴粦",
+                         "Helvetica Neue", Arial, sans-serif;
+$opo-font-family-number: "DIN Alternate", "SF Mono", "Roboto Mono", Consolas, "Courier New", monospace;
+
+// ---------- 闂磋窛锛�8 鐐规爡鏍硷級 ----------
+$opo-space-1: 4px;
+$opo-space-2: 8px;
+$opo-space-3: 12px;
+$opo-space-4: 16px;
+$opo-space-5: 24px;
+$opo-space-6: 32px;
+
+// ---------- 鍦嗚 ----------
+$opo-radius-sm:   2px;
+$opo-radius-base: 4px;
+$opo-radius-lg:   8px;
+$opo-radius-pill: 999px;
+
+// ---------- 闃村奖 ----------
+$opo-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
+$opo-shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
+$opo-shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);
+
+// ---------- 鎺т欢楂樺害 ----------
+$opo-control-height-small:  32px;
+$opo-control-height-base:   36px;
diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss
index 4ea177a..b85dc47 100644
--- a/src/assets/styles/variables.scss
+++ b/src/assets/styles/variables.scss
@@ -1,3 +1,6 @@
+// 璁捐浠ょ墝锛堥鑹�/瀛楀彿/闂磋窛/鍦嗚/闃村奖/瀛椾綋鐨勫敮涓�鏉ユ簮锛�
+@import './tokens.scss';
+
 // base color
 $blue:#324157;
 $light-blue:#3A71A8;
@@ -10,22 +13,21 @@
 
 // 榛樿鑿滃崟涓婚椋庢牸
 //鑿滃崟瀛椾綋棰滆壊
-$base-menu-color:#fff;
+$base-menu-color:$opo-sidebar-text;
 //閫夊畾瀛愬垪琛ㄦ椂鎵�鍦ㄥ垪琛ㄧ殑瀛椾綋棰滆壊
-// f4f4f5
-$base-menu-color-active:#fff;
-//鏁翠綋鑳屾櫙棰滆壊#0187B1
-$base-menu-background:#394d74;
+$base-menu-color-active:$opo-sidebar-text-active;
+//鏁翠綋鑳屾櫙棰滆壊锛堜笌鍝佺墝闈掑悓鏃忕殑娣遍潚锛�
+$base-menu-background:$opo-sidebar-bg;
 //鏍囬瀛椾綋棰滆壊
 $base-logo-title-color: #ffffff;
 //
 $base-menu-light-color:rgba(0,0,0,.70);
 $base-menu-light-background:#ffffff;
 $base-logo-light-title-color: #001529;
-//鍒楄〃鑳屾櫙棰滆壊1f2d3d
-$base-sub-menu-background:#394d74;
-//
-$base-sub-menu-hover:#a76ac3;
+//鍒楄〃鑳屾櫙棰滆壊
+$base-sub-menu-background:$opo-sidebar-sub-bg;
+//瀛愯彍鍗曟偓鍋滆壊锛堝師鏉ユ槸鏃犲叧鑱旂殑绱壊 #a76ac3锛�
+$base-sub-menu-hover:$opo-sidebar-hover;
 
 // 鑷畾涔夋殫鑹茶彍鍗曢鏍�
 /**
@@ -42,7 +44,7 @@
 $base-sub-menu-hover:#001528;
 */
 
-$base-sidebar-width: 200px;
+$base-sidebar-width: 220px;
 
 // the :export directive is the magic sauce for webpack
 // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
diff --git a/src/components/ThemePicker/index.vue b/src/components/ThemePicker/index.vue
index 1714e1f..83e030e 100644
--- a/src/components/ThemePicker/index.vue
+++ b/src/components/ThemePicker/index.vue
@@ -1,7 +1,7 @@
 <template>
   <el-color-picker
     v-model="theme"
-    :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
+    :predefine="['#0E768F', '#CD1D4E', '#409EFF', '#1B8E70', '#7B61FF', '#E6843C', '#304156', '#212121']"
     class="theme-picker"
     popper-class="theme-picker-dropdown"
   />
@@ -42,8 +42,12 @@
 
   methods: {
     async setTheme(val) {
-      const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
       if (typeof val !== 'string') return
+      // 鍏堥�氱煡澶栧眰锛氫富棰樿壊鐢� CSS 鍙橀噺灞傦紙utils/theme.js锛夌珛鍗崇敓鏁堛��
+      // 鍘熸潵鐨勫疄鐜拌绛� CDN 鎷夊彇 theme-chalk 瀹屾垚鍚庢墠 emit锛屽唴缃戞媺涓嶅埌 unpkg
+      // 鏃� Promise 姘镐笉 resolve锛屽鑷�"鏀逛富棰樻病鏈変换浣曞弽搴�"銆�
+      this.$emit('change', val)
+      const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
       const themeCluster = this.getThemeCluster(val.replace('#', ''))
       const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
 
@@ -81,8 +85,6 @@
         if (typeof innerText !== 'string') return
         style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
       })
-
-      this.$emit('change', val)
     },
 
     updateStyle(style, oldCluster, newCluster) {
@@ -96,12 +98,19 @@
     getCSSString(url, variable) {
       return new Promise(resolve => {
         const xhr = new XMLHttpRequest()
+        const done = () => resolve()
         xhr.onreadystatechange = () => {
-          if (xhr.readyState === 4 && xhr.status === 200) {
-            this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
+          if (xhr.readyState === 4) {
+            if (xhr.status === 200) {
+              this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
+            }
             resolve()
           }
         }
+        // 鍐呯綉/鏃犲缃戞椂蹇�熷け璐ワ紝閬垮厤 Promise 鎮寕瀵艰嚧鎹㈣偆鍗′綇
+        xhr.onerror = done
+        xhr.ontimeout = done
+        xhr.timeout = 4000
         xhr.open('GET', url)
         xhr.send()
       })
diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue
index 7cd2979..fc5d99f 100644
--- a/src/layout/components/Settings/index.vue
+++ b/src/layout/components/Settings/index.vue
@@ -36,6 +36,21 @@
           <span>涓婚棰滆壊</span>
           <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
         </div>
+
+        <div class="drawer-item">
+          <span>棰勮鐨偆</span>
+          <div class="opo-preset-list">
+            <span
+              v-for="p in presets"
+              :key="p.color"
+              class="opo-preset-item"
+              :class="{ 'is-active': isCurrent(p.color) }"
+              :style="{ backgroundColor: p.color }"
+              :title="p.name"
+              @click="themeChange(p.color)"
+            />
+          </div>
+        </div>
       </div>
 
       <el-divider/>
@@ -77,13 +92,15 @@
 
 <script>
 import ThemePicker from '@/components/ThemePicker'
+import { PRESETS, applyTheme, setStoredTheme } from '@/utils/theme'
 
 export default {
   components: { ThemePicker },
   data() {
     return {
       theme: this.$store.state.settings.theme,
-      sideTheme: this.$store.state.settings.sideTheme
+      sideTheme: this.$store.state.settings.sideTheme,
+      presets: PRESETS
     };
   },
   computed: {
@@ -147,12 +164,18 @@
     },
   },
   methods: {
+    isCurrent(color) {
+      return !!this.theme && String(this.theme).toUpperCase() === String(color).toUpperCase();
+    },
     themeChange(val) {
       this.$store.dispatch('settings/changeSetting', {
         key: 'theme',
         value: val
       })
       this.theme = val;
+      // 绔嬪嵆鐢熸晥骞惰浣忥細涓嶄緷璧� ThemePicker 浠� CDN 鎷夊彇 theme-chalk
+      applyTheme(val);
+      setStoredTheme(val);
     },
     handleTheme(val) {
       this.$store.dispatch('settings/changeSetting', {
@@ -252,5 +275,29 @@
     .drawer-switch {
       float: right
     }
+
+    // 棰勮鐨偆鑹插潡
+    .opo-preset-list {
+      display: flex;
+      align-items: center;
+      flex-wrap: wrap;
+      margin-top: 8px;
+    }
+
+    .opo-preset-item {
+      display: inline-block;
+      width: 22px;
+      height: 22px;
+      margin-right: 10px;
+      border-radius: 4px;
+      cursor: pointer;
+      border: 2px solid transparent;
+      box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
+
+      &.is-active {
+        border-color: #1F2937;
+        box-shadow: 0 0 0 2px rgba(31, 41, 55, 0.18);
+      }
+    }
   }
 </style>
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 214d86f..c56206e 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
+  <div :class="classObj" class="app-wrapper">
     <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
     <sidebar class="sidebar-container"/>
     <div :class="{hasTagsView:needTagsView}" class="main-container">
@@ -21,6 +21,7 @@
 import ResizeMixin from './mixin/ResizeHandler'
 import { mapState } from 'vuex'
 import variables from '@/assets/styles/variables.scss'
+import { applyTheme, setStoredTheme } from '@/utils/theme'
 
 export default {
   name: 'Layout',
@@ -54,7 +55,20 @@
       return variables;
     }
   },
+  created() {
+    // 杩涘叆 Layout 鏃跺簲鐢ㄥ綋鍓嶄富棰樿壊锛堝苟璁颁綇閫夋嫨锛�
+    this.applyCurrentTheme()
+  },
+  watch: {
+    theme(val) {
+      this.applyCurrentTheme()
+      setStoredTheme(val)
+    }
+  },
   methods: {
+    applyCurrentTheme() {
+      applyTheme(this.theme)
+    },
     handleClickOutside() {
       this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
     }
diff --git a/src/main.js b/src/main.js
index 60b8011..6ecaa60 100644
--- a/src/main.js
+++ b/src/main.js
@@ -10,10 +10,14 @@
 import Cookies from 'js-cookie'
 
 import Element from 'element-ui'
+import '@/assets/styles/tokens.css' // 璁捐浠ょ墝锛圕SS 鍙橀噺锛屼緵杩愯鏃舵崲鑲わ級
 import './assets/styles/element-variables.scss'
 
 import '@/assets/styles/index.scss' // global css
 import '@/assets/styles/ruoyi.scss' // ruoyi css
+// 杩愯鏃朵富棰樺眰 + 缁勪欢榛樿澶栬锛氬繀椤绘櫄浜� element-ui 涓� ruoyi.scss锛屽惁鍒欒鐩栦笉鐢熸晥
+import '@/assets/styles/theme-runtime.scss'
+import '@/assets/styles/element-override.scss'
 import App from './App'
 import store from './store'
 import router from './router'
@@ -27,6 +31,8 @@
 import { getConfigKey } from "@/api/system/config";
 import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
 import dataV from '@jiaminghi/data-view';//dataV
+// 涓婚鑹茶繍琛屾椂锛圕SS 鍙橀噺娉ㄥ叆锛�
+import { applyTheme, getStoredTheme, DEFAULT_PRIMARY } from '@/utils/theme'
 // 鍒嗛〉缁勪欢
 import Pagination from "@/components/Pagination";
 // 鑷畾涔夎〃鏍煎伐鍏风粍浠�
@@ -102,9 +108,12 @@
  */
 
 Vue.use(Element, {
-  size: Cookies.get('size') || 'medium' // set element-ui default size
+  size: Cookies.get('size') || 'small' // set element-ui default size锛堝師 medium锛屾敼涓� small 鎻愬崌淇℃伅瀵嗗害锛�
 })
 
+// 鍚姩鍗冲簲鐢ㄥ凡淇濆瓨鐨勪富棰樿壊锛堢櫥褰曢〉绛変笉浣跨敤 Layout 鐨勯〉闈篃鑳界敓鏁堬級
+applyTheme(getStoredTheme() || DEFAULT_PRIMARY)
+
 Vue.config.productionTip = false
 
 new Vue({
diff --git a/src/settings.js b/src/settings.js
index 466d7a2..fe2d2d7 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -5,9 +5,10 @@
   sideTheme: 'theme-dark',
 
   /**
-   * 鏄惁绯荤粺甯冨眬閰嶇疆
+   * 鏄惁绯荤粺甯冨眬閰嶇疆锛堝彸涓嬭榻胯疆闈㈡澘锛�
+   * 鍘熶负 false锛屽鑷�"涓婚棰滆壊 / 棰勮鐨偆"鍏ュ彛瀵圭敤鎴蜂笉鍙 鈫� 鏀逛负 true
    */
-  showSettings: false,
+  showSettings: true,
 
   /**
    * 鏄惁鏄剧ず椤堕儴瀵艰埅
@@ -40,87 +41,5 @@
    * The default is only used in the production env
    * If you want to also use it in dev, you can pass ['production', 'development']
    */
-  errorLog: 'production',
-  // vscode榛樿鍚敤浜嗘牴鎹枃浠剁被鍨嬭嚜鍔ㄨ缃畉absize鐨勯�夐」
-
-  "editor.detectIndentation": false,
-
-  // 閲嶆柊璁惧畾tabsize
-
-  "editor.tabSize": 2,
-
-  // #姣忔淇濆瓨鐨勬椂鍊欒嚜鍔ㄦ牸寮忓寲
-
-  "editor.formatOnSave": true,
-
-  // #姣忔淇濆瓨鐨勬椂鍊欏皢浠g爜鎸塭slint鏍煎紡杩涜淇
-
-  "eslint.autoFixOnSave": true,
-
-  "tslint.autoFixOnSave": true,
-
-  // 娣诲姞 vue 鏀寔
-
-  "eslint.validate": [
-
-    "javascript",
-
-    "javascriptreact",
-
-    {
-
-      "language": "vue",
-
-      "autoFix": true
-
-    }
-
-  ],
-
-  // #鍘绘帀浠g爜缁撳熬鐨勫垎鍙�
-
-  "prettier.semi": true,
-
-  // #浣跨敤甯﹀紩鍙锋浛浠e弻寮曞彿
-
-  "prettier.singleQuote": true,
-
-  // #璁╁嚱鏁�(鍚�)鍜屽悗闈㈢殑鎷彿涔嬮棿鍔犱釜绌烘牸
-
-  "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
-
-  // #杩欎釜鎸夌敤鎴疯嚜韬範鎯�夋嫨
-
-  "vetur.format.defaultFormatter.html": "js-beautify-html",
-
-  // #璁﹙ue涓殑js鎸夌紪杈戝櫒鑷甫鐨則s鏍煎紡杩涜鏍煎紡鍖�
-
-  "vetur.format.defaultFormatter.js": "vscode-typescript",
-
-  "vetur.format.defaultFormatterOptions": {
-
-    "js-beautify-html": {
-
-      "wrap_attributes": "force-aligned"
-
-      // #vue缁勪欢涓環tml浠g爜鏍煎紡鍖栨牱寮�
-
-    }
-
-  },
-
-  // 鏍煎紡鍖杝tylus, 闇�瀹夎Manta's Stylus Supremacy鎻掍欢
-
-  "stylusSupremacy.insertColons": false, // 鏄惁鎻掑叆鍐掑彿
-
-  "stylusSupremacy.insertSemicolons": false, // 鏄惁鎻掑叆鍒嗗ソ
-
-  "stylusSupremacy.insertBraces": false, // 鏄惁鎻掑叆澶ф嫭鍙�
-
-  "stylusSupremacy.insertNewLineAroundImports": false, // import涔嬪悗鏄惁鎹㈣
-
-  "stylusSupremacy.insertNewLineAroundBlocks": false,
-
-  "javascript.format.insertSpaceAfterConstructor": true // 涓や釜閫夋嫨鍣ㄤ腑鏄惁鎹㈣
+  errorLog: 'production'
 }
-
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
index 5f36d8e..4252d2b 100644
--- a/src/store/modules/settings.js
+++ b/src/store/modules/settings.js
@@ -1,11 +1,12 @@
 import defaultSettings from '@/settings'
+import { DEFAULT_PRIMARY, getStoredTheme } from '@/utils/theme'
 
 const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
 
 const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
 const state = {
   title: '',
-  theme: storageSetting.theme || '#409EFF',
+  theme: storageSetting.theme || getStoredTheme() || DEFAULT_PRIMARY,
   sideTheme: storageSetting.sideTheme || sideTheme,
   showSettings: showSettings,
   topNav:  storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
diff --git a/src/utils/fileNameCheck.js b/src/utils/fileNameCheck.js
new file mode 100644
index 0000000..2554490
--- /dev/null
+++ b/src/utils/fileNameCheck.js
@@ -0,0 +1,153 @@
+/**
+ * 鎶ラ攢鍗曢檮浠舵枃浠跺悕瑙勮寖鏍¢獙锛�2026-10-15锛�
+ *
+ * 涓氬姟鍙e緞锛堜笟鍔℃柟纭锛夛細
+ *   1. 蹇呴』鍖呭惈涓枃锛堣嚦灏� 1 涓眽瀛楋級鈥斺��"涓烘柟渚挎煡楠岄檮浠讹紝璇风敤涓枃瑙勮寖鍛藉悕闄勪欢锛�"
+ *   2. 鍘绘帀鎵╁睍鍚嶅悗鐨勪富骞诧紝鎸夊瓧绗︽暟璁$畻涓嶈兘瓒呰繃 20 涓瓧鈥斺��"涓烘柟渚挎煡楠岄檮浠讹紝闄勪欢鍚嶅瓧闀垮害涓嶈兘瓒呰繃20涓瓧锛�"
+ *   3. 涓嶈兘鍖呭惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗�
+ *   4. 鍚屼竴鏄庣粏琛屽唴涓嶈兘閲嶅悕锛堟瘮杈冩椂蹇界暐鎵╁睍鍚嶅ぇ灏忓啓涓庨灏剧┖鏍硷級
+ *
+ * 浣跨敤鍦烘櫙锛�
+ *   - 涓婁紶鎴愬姛鍥炶皟锛氫笉鍚堟牸 鈫� 寮规彁绀轰笖涓嶅姞鍏ュ垪琛紱
+ *   - 淇濆瓨/鎻愪氦鍓嶏細璋冪敤 checkDetails 缁熶竴鏍¢獙锛屼笉鍚堟牸鍒欐嫤涓嬩笉鍏佽淇濆瓨锛�
+ *   - 鍚庣淇濆瓨鎺ュ彛鍙︽湁鍚屽彛寰勭殑浜屾鏍¢獙锛堥槻姝㈢粫杩囧墠绔級銆�
+ */
+
+/** 涓诲共锛堝幓鎵╁睍鍚嶏級鏈�澶у瓧绗︽暟 */
+export const MAX_MAIN_LENGTH = 20;
+
+/** 姹夊瓧 */
+const RE_CHINESE = /[\u4e00-\u9fa5]/;
+
+/** 闈炴硶瀛楃锛氱┖鏍硷紙鍚悇绫荤┖鐧斤級+ / \ : * ? " < > | # % */
+const RE_ILLEGAL = /[\s/\\:*?"<>|#%]/;
+
+export const MSG_NO_CHINESE = "涓烘柟渚挎煡楠岄檮浠讹紝璇风敤涓枃瑙勮寖鍛藉悕闄勪欢锛�";
+export const MSG_TOO_LONG = "涓烘柟渚挎煡楠岄檮浠讹紝闄勪欢鍚嶅瓧闀垮害涓嶈兘瓒呰繃20涓瓧锛�";
+export const MSG_ILLEGAL = '涓烘柟渚挎煡楠岄檮浠讹紝闄勪欢鍚嶄笉鑳藉寘鍚┖鏍煎強 / \\ : * ? " < > | # % 绛夌壒娈婂瓧绗︼紒';
+export const MSG_DUPLICATE = "涓烘柟渚挎煡楠岄檮浠讹紝鍚屼竴琛屽唴涓嶈兘鏈夐噸鍚嶇殑闄勪欢锛�";
+
+/**
+ * 鍙栦富骞诧紙鍘绘帀鏈�鍚庝竴涓墿灞曞悕锛�
+ * @param {string} fileName 鍘熷鏂囦欢鍚�
+ * @returns {string} 涓诲共
+ */
+export function mainName(fileName) {
+  const s = (fileName || "").trim();
+  const i = s.lastIndexOf(".");
+  return i > 0 ? s.substring(0, i) : s;
+}
+
+/**
+ * 鍗曚釜鏂囦欢鍚嶆牎楠�
+ * @param {string} fileName 鍘熷鏂囦欢鍚�
+ * @returns {{ok: boolean, msg: string, main: string}}
+ */
+export function checkFileName(fileName) {
+  const name = (fileName || "").trim();
+  if (!name) {
+    return { ok: false, msg: MSG_NO_CHINESE, main: "" };
+  }
+  if (RE_ILLEGAL.test(name)) {
+    return { ok: false, msg: MSG_ILLEGAL, main: mainName(name) };
+  }
+  const main = mainName(name);
+  if (!RE_CHINESE.test(main)) {
+    return { ok: false, msg: MSG_NO_CHINESE, main };
+  }
+  // 鎸夊瓧绗︽暟璁★紙鐢ㄦ墿灞曡繍绠楃鎸夌爜鐐硅鏁帮紝涓枃/瀛楁瘝/鏁板瓧/鍏ㄨ鍚勮 1锛�
+  if ([...main].length > MAX_MAIN_LENGTH) {
+    return { ok: false, msg: MSG_TOO_LONG, main };
+  }
+  return { ok: true, msg: "", main };
+}
+
+/** 鍙栭檮浠堕」鏄剧ず鍚嶏紙涓嶅悓椤甸潰瀛楁鍚嶅彲鑳芥槸 name / fileName锛屽彇涓嶅埌灏辫繑鍥炵┖涓茶〃绀�"涓嶅垽鏂�"锛� */
+function itemName(item) {
+  if (!item) return "";
+  if (typeof item === "string") return item;
+  return item.name || item.fileName || "";
+}
+
+/**
+ * 涓�缁勯檮浠舵牎楠岋紙鍚悓琛岄噸鍚嶏級
+ * @param {Array} list 闄勪欢鏁扮粍锛屽厓绱犲舰濡� {name, url}
+ * @returns {{ok: boolean, msg: string, index: number}}
+ */
+export function checkFileList(list) {
+  const arr = list || [];
+  const seen = {};
+  for (let i = 0; i < arr.length; i++) {
+    const name = itemName(arr[i]);
+    if (!name) continue; // 鍙栦笉鍒板師鏂囦欢鍚嶅垯涓嶅垽鏂紝閬垮厤璇嫤
+    const r = checkFileName(name);
+    if (!r.ok) {
+      return { ok: false, msg: r.msg, index: i };
+    }
+    const key = name.trim().toLowerCase();
+    if (seen[key]) {
+      return { ok: false, msg: MSG_DUPLICATE, index: i };
+    }
+    seen[key] = true;
+  }
+  return { ok: true, msg: "", index: -1 };
+}
+
+/**
+ * 淇濆瓨鍓嶆牎楠屾暣鍗曟槑缁嗭紙鍙戠エ + 闄勪欢锛�
+ * @param {Array} details 鏄庣粏琛屾暟缁勶紝琛屽唴鍚� invoicefilesList / annexfilesList锛堟暟缁勶級
+ * @returns {{ok: boolean, msg: string}}
+ */
+export function checkDetails(details) {
+  const rows = details || [];
+  for (let i = 0; i < rows.length; i++) {
+    const groups = [
+      { label: "鍙戠エ", list: rows[i] && rows[i].invoicefilesList },
+      { label: "闄勪欢", list: rows[i] && rows[i].annexfilesList }
+    ];
+    for (let g = 0; g < groups.length; g++) {
+      const arr = groups[g].list || [];
+      const seen = {};
+      for (let j = 0; j < arr.length; j++) {
+        const name = itemName(arr[j]);
+        if (!name) continue;
+        const r = checkFileName(name);
+        if (!r.ok) {
+          return {
+            ok: false,
+            msg:
+              "闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細绗�" + (i + 1) + "琛岀" + (j + 1) +
+              "涓紙" + name + "锛夆�斺��" + r.msg
+          };
+        }
+        const key = name.trim().toLowerCase();
+        if (seen[key]) {
+          return {
+            ok: false,
+            msg:
+              "闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細绗�" + (i + 1) + "琛岀" + (j + 1) +
+              "涓紙" + name + "锛夆�斺��" + MSG_DUPLICATE
+          };
+        }
+        seen[key] = true;
+      }
+    }
+  }
+  return { ok: true, msg: "" };
+}
+
+/**
+ * 鏁村崟閲屾墍鏈夐檮浠讹紙涓嶅垎琛岋級鐨勬墎骞虫牎楠岋紝渚涘彧鏈夊崟涓枃浠跺垪琛ㄧ殑椤甸潰浣跨敤
+ * @param {Array} lists 澶氫釜闄勪欢鏁扮粍
+ * @returns {{ok: boolean, msg: string}}
+ */
+export function checkAllLists(lists) {
+  const all = lists || [];
+  for (let i = 0; i < all.length; i++) {
+    const r = checkFileList(all[i]);
+    if (!r.ok) {
+      return { ok: false, msg: r.msg };
+    }
+  }
+  return { ok: true, msg: "" };
+}
diff --git a/src/utils/money.js b/src/utils/money.js
new file mode 100644
index 0000000..a8d93b1
--- /dev/null
+++ b/src/utils/money.js
@@ -0,0 +1,240 @@
+/**
+ * 閲戦璁$畻宸ュ叿
+ *
+ * 鑳屾櫙锛氭湰绯荤粺閲戦涓�寰嬩互銆屽厓銆嶄负鍗曚綅銆佷繚鐣� 2 浣嶅皬鏁帮紝灞炶储鍔℃暟鎹��
+ * JS 鐨� Number 鏄� IEEE-754 鍙岀簿搴︽诞鐐癸紝鐩存帴鍋氬姞鍑忎箻浼氬紩鍏ヤ簩杩涘埗鑸嶅叆璇樊锛�
+ * 鍏稿瀷琛ㄧ幇锛�
+ *   0.1 + 0.2        -> 0.30000000000000004
+ *   1.1 * 3          -> 3.3000000000000003
+ *   0.3 - 0.2 - 0.1  -> -2.7755575615628914e-17   锛堥��璐�/鎵g◣鐩稿噺鍚庢畫鐣欏熬宸級
+ * 杩欑被灏惧樊瀵艰嚧銆屽悎璁″涓嶄笂銆嶃�岄噾棰濇樉绀轰负 -0銆嶃�岀浉绛夊垽鏂け璐ャ�嶇瓑绾夸笂闂锛�
+ * 涓斾細闅忓崟鎹祦杞鍐欏叆鏁版嵁搴擄紝浜嬪悗闅句互杩芥函銆�
+ *
+ * 鍥犳锛氭墍鏈夐噾棰濊繍绠楃粺涓�璧版湰妯″潡锛岀姝㈢洿鎺ュ閲戦浣跨敤 + - * / 涓� parseFloat 绱姞銆�
+ * 鍐呴儴鍩轰簬 decimal.js锛坧ackage.json 宸插紩鍏ワ級锛屼繚璇佸崄杩涘埗绮剧‘杩愮畻銆�
+ *
+ * 鐢ㄦ硶绀轰緥锛�
+ *   import { moneySum, moneyMul, moneySub, moneyRound, moneyEq } from "@/utils/money";
+ *
+ *   // 绱姞鏄庣粏锛堣繃婊ら潪鏁板瓧涓庣┖鍊硷紝涓嶄細鎶� NaN 浼犳煋缁欏悎璁★級
+ *   const total = moneySum(this.rbDetails, "amount");
+ *
+ *   // 鍗曚环 脳 鏁伴噺
+ *   const preTax = moneyMul(row.price, row.quantity);
+ *
+ *   // 绋庡墠 - 鎵g◣ = 绋庡悗
+ *   const afterTax = moneySub(row.amount, row.taxamount);
+ *
+ *   // 钀藉簱/灞曠ず鍓嶇粺涓�淇濈暀 2 浣嶏紙鍥涜垗浜斿叆锛�
+ *   this.form.amountrequested = moneyRound(total);
+ *
+ *   // 閲戦姣旇緝锛堝嬁鐢� == / === 鎴� parseFloat 鍚庣浉鍑忥級
+ *   if (!moneyEq(sumOfPayees, this.form.amountrequested)) { ... }
+ */
+import Decimal from 'decimal.js'
+
+/** 閲戦淇濈暀灏忔暟浣� */
+export const MONEY_SCALE = 2
+
+/**
+ * 杞负 Decimal锛涙棤娉曡瘑鍒殑鍊硷紙绌轰覆/undefined/null/NaN/闈炴暟瀛楋級涓�寰嬫寜 0 澶勭悊銆�
+ * 鎸� 0 澶勭悊鑰岄潪鎶涢敊锛屾槸涓轰簡淇濇寔鏃㈡湁椤甸潰銆�!isNaN(parseFloat(x)) 鎵嶇疮鍔犮�嶇殑琛屼负锛�
+ * 鍚屾椂閬垮厤 NaN 姹℃煋鏁存潯鍚堣閾俱��
+ *
+ * @param {string|number|Decimal|null|undefined} value
+ * @returns {Decimal}
+ */
+export function toMoney(value) {
+  if (value === null || value === undefined || value === '') {
+    return new Decimal(0)
+  }
+  if (value instanceof Decimal) {
+    return value
+  }
+  let d
+  try {
+    d = new Decimal(value)
+  } catch (e) {
+    return new Decimal(0)
+  }
+  return d.isFinite() ? d : new Decimal(0)
+}
+
+/**
+ * 鍒ゆ柇鏄惁涓烘湁鏁堥噾棰濓紙鍙弬涓庤绠楋級銆傜敤浜庡師鏈� !isNaN(parseFloat(x)) 鐨勬牎楠屽満鏅��
+ *
+ * @param {*} value
+ * @returns {boolean}
+ */
+export function isValidMoney(value) {
+  if (value === null || value === undefined || value === '') {
+    return false
+  }
+  if (value instanceof Decimal) {
+    return value.isFinite()
+  }
+  if (typeof value === 'number') {
+    return Number.isFinite(value)
+  }
+  const s = String(value).trim()
+  if (s === '') {
+    return false
+  }
+  try {
+    return new Decimal(s).isFinite()
+  } catch (e) {
+    return false
+  }
+}
+
+/**
+ * 绱姞姹傚拰銆�
+ *
+ * @param {Array} list 寰呯疮鍔犵殑鏁扮粍
+ * @param {string|Function} [selector] 鍙栭噾棰濈殑鏂瑰紡锛�
+ *        瀛楃涓� -> 鍙栬椤圭殑璇ュ睘鎬у悕锛屽 "amount"锛�
+ *        鍑芥暟   -> 鐢ㄨ繑鍥炲�硷紝濡� (item) => item.detail && item.detail.amount锛�
+ *        鐪佺暐   -> 鐩存帴绱姞鏁扮粍鍏冪礌鏈韩銆�
+ * @returns {number} 姹傚拰缁撴灉锛圢umber锛屼究浜庤祴鍊肩粰琛ㄥ崟瀛楁锛�
+ */
+export function moneySum(list, selector) {
+  if (!Array.isArray(list) || list.length === 0) {
+    return 0
+  }
+  let acc = new Decimal(0)
+  for (let i = 0; i < list.length; i++) {
+    const raw =
+      selector === undefined
+        ? list[i]
+        : typeof selector === 'function'
+          ? selector(list[i])
+          : list[i][selector]
+    acc = acc.plus(toMoney(raw))
+  }
+  return acc.toNumber()
+}
+
+/**
+ * 姹傚拰鍚庝繚鐣� 2 浣嶅皬鏁帮紙浼樺厛鍦ㄥ睍绀�/钀藉簱鏃朵娇鐢級銆�
+ */
+export function moneySumRound(list, selector) {
+  return roundNumber(moneySum(list, selector))
+}
+
+/**
+ * 绮剧‘鍔犳硶銆傛敮鎸佸鍙傛暟鎴栨暟缁勶細moneyAdd(1.1, 2.2) / moneyAdd([1.1, 2.2])
+ */
+export function moneyAdd(...args) {
+  const list = args.length === 1 && Array.isArray(args[0]) ? args[0] : args
+  let acc = new Decimal(0)
+  list.forEach((v) => {
+    acc = acc.plus(toMoney(v))
+  })
+  return acc.toNumber()
+}
+
+/**
+ * 绮剧‘鍑忔硶 a - b锛堝彲浼犲涓細a - b - c锛�
+ */
+export function moneySub(a, ...rest) {
+  let acc = toMoney(a)
+  rest.forEach((v) => {
+    acc = acc.minus(toMoney(v))
+  })
+  return acc.toNumber()
+}
+
+/**
+ * 绮剧‘涔樻硶锛堝崟浠� 脳 鏁伴噺銆侀噾棰� 脳 绋庣巼锛�
+ */
+export function moneyMul(a, ...rest) {
+  let acc = toMoney(a)
+  rest.forEach((v) => {
+    acc = acc.times(toMoney(v))
+  })
+  return acc.toNumber()
+}
+
+/**
+ * 绮剧‘闄ゆ硶锛堥噾棰� 梅 鏁伴噺锛夛紝divideBy 涓� 0 鏃惰繑鍥� 0锛屼笉浜х敓 Infinity
+ */
+export function moneyDiv(a, b) {
+  const divisor = toMoney(b)
+  if (divisor.isZero()) {
+    return 0
+  }
+  return toMoney(a).div(divisor).toNumber()
+}
+
+/**
+ * 閲戦鏄惁鐩哥瓑锛堝崄杩涘埗绮剧‘姣旇緝锛屼笉鍙楁诞鐐瑰熬宸奖鍝嶏級銆�
+ * 浼氳嚜鍔ㄥ綊涓�鍖栧埌 2 浣嶏紝閬垮厤 100 涓� 100.001 杩欑被杈圭晫璇垽銆�
+ *
+ * @returns {boolean}
+ */
+export function moneyEq(a, b) {
+  return roundDecimal(a).eq(roundDecimal(b))
+}
+
+/**
+ * 閲戦澶у皬姣旇緝锛歛 > b 杩斿洖 1锛宎 < b 杩斿洖 -1锛岀浉绛夎繑鍥� 0
+ */
+export function moneyCmp(a, b) {
+  return roundDecimal(a).cmp(roundDecimal(b))
+}
+
+/**
+ * 淇濈暀 2 浣嶅皬鏁板苟杩斿洖 Number锛堝洓鑸嶄簲鍏ワ紝ROUND_HALF_UP锛夈��
+ * 鐢ㄤ簬璧嬪�肩粰琛ㄥ崟瀛楁銆佸弬涓庡悗绔氦浜掋��
+ *
+ * @param {*} value
+ * @param {number} [scale=2]
+ * @returns {number}
+ */
+export function moneyRound(value, scale = MONEY_SCALE) {
+  return roundDecimal(value, scale).toNumber()
+}
+
+/**
+ * 淇濈暀 2 浣嶅皬鏁板苟杩斿洖瀛楃涓诧紙鐢ㄤ簬閲戦灞曠ず锛岄伩鍏嶅ぇ棰濇椂鍑虹幇绉戝璁℃暟娉曪級銆�
+ *
+ * @param {*} value
+ * @param {number} [scale=2]
+ * @returns {string}
+ */
+export function moneyText(value, scale = MONEY_SCALE) {
+  return roundDecimal(value, scale).toFixed(scale)
+}
+
+/**
+ * 淇濈暀 2 浣嶅皬鏁板苟杩斿洖 Decimal锛屼緵鍚庣画缁х画绮剧‘杩愮畻
+ */
+export function moneyDecimal(value, scale = MONEY_SCALE) {
+  return roundDecimal(value, scale)
+}
+
+function roundDecimal(value, scale = MONEY_SCALE) {
+  return toMoney(value).toDecimalPlaces(scale, Decimal.ROUND_HALF_UP)
+}
+
+// moneySum 鍐呴儴宸茶繑鍥� Number锛岃繖閲岀粺涓�璧板悓涓�濂楀洓鑸嶄簲鍏�
+function roundNumber(value) {
+  return roundDecimal(value).toNumber()
+}
+
+export default {
+  MONEY_SCALE,
+  toMoney,
+  isValidMoney,
+  moneySum,
+  moneySumRound,
+  moneyAdd,
+  moneySub,
+  moneyMul,
+  moneyDiv,
+  moneyEq,
+  moneyCmp,
+  moneyRound,
+  moneyText,
+  moneyDecimal
+}
diff --git a/src/utils/request.js b/src/utils/request.js
index d0a5db3..0755ac6 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -104,22 +104,24 @@
     console.log('err' + error)
     let { message } = error;
     if (message == "Network Error") {
-      // message = "鍚庣鎺ュ彛杩炴帴寮傚父";
-      console.log("Network Erro",message);
+      message = "鍚庣鎺ュ彛杩炴帴寮傚父";
     }
     else if (message.includes("timeout")) {
-      // message = "绯荤粺鎺ュ彛璇锋眰瓒呮椂";
-      console.log("timeout",message);
+      message = "绯荤粺鎺ュ彛璇锋眰瓒呮椂";
     }
     else if (message.includes("Request failed with status code")) {
-      // message = "绯荤粺鎺ュ彛" + message.substr(message.length - 3) + "寮傚父";
-      console.log("Request failed with status code",message);
+      // 浼樺厛灞曠ず鍚庣杩斿洖鐨勫叿浣撳師鍥狅紙濡�"鍖婚櫌鍗忓弸绯荤粺鎺ユ敹澶辫触锛屾湰娆″鎵规湭鐢熸晥锛岃绋嶅悗閲嶆柊瀹℃壒"锛�
+      const data = error.response && error.response.data;
+      const backendMsg = data && (data.msg || data.message);
+      message = backendMsg || ("绯荤粺鎺ュ彛" + message.substr(message.length - 3) + "寮傚父");
     }
-    // Message({
-    //   message: message,
-    //   type: 'error',
-    //   duration: 10* 1000
-    // })
+    // 2026-10-09 鎭㈠閿欒鎻愮ず锛氬師鏉ヨ繖閲屾槸娉ㄩ噴鐘舵�侊紝瀵艰嚧璇锋眰鍙戠敓 HTTP 绾ч敊璇椂
+    // 椤甸潰浠�涔堥兘涓嶆彁绀猴紙璋冪敤鏂圭殑 .then 涓嶄細鎵ц锛夛紝鐢ㄦ埛鐪嬩笉鍒板け璐ュ師鍥�
+    Message({
+      message: message,
+      type: 'error',
+      duration: 5 * 1000
+    })
     return Promise.reject(error)
   }
 )
diff --git a/src/utils/theme.js b/src/utils/theme.js
new file mode 100644
index 0000000..3a778f9
--- /dev/null
+++ b/src/utils/theme.js
@@ -0,0 +1,172 @@
+/**
+ * 涓婚鑹茶繍琛屾椂璁$畻涓庡簲鐢�
+ * ---------------------------------------------------------------
+ * 鑳屾櫙锛欵lement UI 2.x 鐨勪富棰樿壊鏄� SCSS 缂栬瘧鏈熷父閲忥紝杩愯鏃舵棤娉曟敼鍔紱
+ *      鍘熸湁 ThemePicker 渚濊禆 unpkg CDN 鎷夊彇 theme-chalk 鍐嶅瓧绗︿覆鏇挎崲锛�
+ *      鍐呯綉鐜鎷変笉鍒� CSS锛屽鑷�"鏀逛富棰樻病鍙嶅簲"銆�
+ * 鍋氭硶锛氱敱浠绘剰涓昏壊鎺ㄥ嚭涓�濂楄壊闃讹紙hover / active / light-3~95锛夛紝
+ *      鍐欏叆 :root 鐨� CSS 鍙橀噺锛泃heme-runtime.scss 鐢� var() 娑堣垂杩欎簺鍙橀噺锛�
+ *      浠庤�屽疄鐜�"涓�娆$紪璇戙�佽繍琛屾椂鎹㈣偆銆侀〉闈笉鍒锋柊"銆�
+ */
+
+/** 榛樿涓昏壊锛歄PO_Logo.png 鍦嗙幆闈� */
+export const DEFAULT_PRIMARY = '#0E768F'
+
+/** localStorage 閿紙涓庡竷灞�璁剧疆鍒嗗紑锛岄伩鍏嶄簰鐩歌鐩栵級 */
+const STORAGE_KEY = 'opo-theme'
+
+/** 棰勮鐨偆 */
+export const PRESETS = [
+  { name: '鍝佺墝闈�', color: '#0E768F' },
+  { name: '鐜孩', color: '#CD1D4E' },
+  { name: 'Element 钃�', color: '#409EFF' },
+  { name: '鍙惰娊缁�', color: '#1B8E70' },
+  { name: '绱�', color: '#7B61FF' },
+  { name: '姗�', color: '#E6843C' }
+]
+
+const WHITE = [255, 255, 255]
+const BLACK = [0, 0, 0]
+
+function clamp(v) {
+  return Math.max(0, Math.min(255, Math.round(v)))
+}
+
+/** #abc / #aabbcc 鈫� [r,g,b]锛涢潪娉曡繑鍥� null */
+export function hexToRgb(hex) {
+  if (typeof hex !== 'string') return null
+  let h = hex.trim().replace(/^#/, '')
+  if (h.length === 3) {
+    h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]
+  }
+  if (!/^[0-9a-fA-F]{6}$/.test(h)) return null
+  return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)]
+}
+
+/** [r,g,b] 鈫� #RRGGBB */
+export function rgbToHex(rgb) {
+  return (
+    '#' +
+    rgb
+      .map(function (v) {
+        const s = clamp(v).toString(16)
+        return s.length === 1 ? '0' + s : s
+      })
+      .join('')
+      .toUpperCase()
+  )
+}
+
+/**
+ * 娣疯壊锛歸eight 涓虹洰鏍囪壊鍗犳瘮锛�0~1锛�
+ * mix([14,118,143], WHITE, 0.3) 鈮� 30% 鐧� + 70% 涓昏壊
+ */
+export function mix(rgb, target, weight) {
+  const w = Math.max(0, Math.min(1, weight))
+  return [
+    clamp(rgb[0] * (1 - w) + target[0] * w),
+    clamp(rgb[1] * (1 - w) + target[1] * w),
+    clamp(rgb[2] * (1 - w) + target[2] * w)
+  ]
+}
+
+function channelLum(v) {
+  const c = v / 255
+  return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
+}
+
+/** 鐩稿浜害锛圵CAG锛� */
+export function luminance(rgb) {
+  return 0.2126 * channelLum(rgb[0]) + 0.7152 * channelLum(rgb[1]) + 0.0722 * channelLum(rgb[2])
+}
+
+/** 涓庣櫧鑹茬殑瀵规瘮搴︼紝鐢ㄤ簬鍒ゆ柇鐧藉瓧鏄惁鍙 */
+export function contrastWithWhite(rgb) {
+  return 1.05 / (luminance(rgb) + 0.05)
+}
+
+/**
+ * 鐢变富鑹叉帹鍏ㄥ鑹查樁
+ * 娣辫壊涓昏壊锛堜寒搴︿綆锛塰over 鐢�"鍔犳繁"锛屾祬鑹蹭富鑹� hover 鐢�"鍙樻祬"锛�
+ * 淇濊瘉 hover 鎬佺殑鐧藉瓧瀵规瘮搴︿笉浼氭帀涓嬪幓銆�
+ */
+export function buildScale(primary) {
+  const base = hexToRgb(primary) || hexToRgb(DEFAULT_PRIMARY)
+  const isDark = luminance(base) < 0.4
+
+  const hover = isDark ? mix(base, BLACK, 0.1) : mix(base, WHITE, 0.2)
+  const active = isDark ? mix(base, BLACK, 0.2) : mix(base, WHITE, 0.32)
+
+  return {
+    primary: rgbToHex(base),
+    hover: rgbToHex(hover),
+    active: rgbToHex(active),
+    light3: rgbToHex(mix(base, WHITE, 0.3)),
+    light5: rgbToHex(mix(base, WHITE, 0.5)),
+    light7: rgbToHex(mix(base, WHITE, 0.7)),
+    light8: rgbToHex(mix(base, WHITE, 0.8)),
+    light9: rgbToHex(mix(base, WHITE, 0.9)),
+    light95: rgbToHex(mix(base, WHITE, 0.95)),
+    dark2: rgbToHex(mix(base, BLACK, 0.2)),
+    isDark: isDark,
+    contrastWithWhite: Number(contrastWithWhite(base).toFixed(2))
+  }
+}
+
+/** 鎶婅壊闃跺啓鍏� :root 鐨� CSS 鍙橀噺锛坱heme-runtime.scss 娑堣垂锛� */
+export function applyTheme(primary) {
+  const scale = buildScale(primary || DEFAULT_PRIMARY)
+  if (typeof document === 'undefined') return scale
+
+  const root = document.documentElement
+  const map = {
+    '--opo-primary': scale.primary,
+    '--opo-primary-hover': scale.hover,
+    '--opo-primary-active': scale.active,
+    '--opo-primary-light-3': scale.light3,
+    '--opo-primary-light-5': scale.light5,
+    '--opo-primary-light-7': scale.light7,
+    '--opo-primary-light-8': scale.light8,
+    '--opo-primary-light-9': scale.light9,
+    '--opo-primary-light-95': scale.light95,
+    '--opo-primary-dark-2': scale.dark2
+  }
+  Object.keys(map).forEach(function (k) {
+    root.style.setProperty(k, map[k])
+  })
+  // 渚涗釜鍒渶瑕佺煡閬�"褰撳墠鏄惁娣辫壊涓昏壊"鐨勫満鏅娇鐢�
+  root.setAttribute('data-opo-dark-primary', scale.isDark ? '1' : '0')
+  return scale
+}
+
+/** 璇诲彇涓婃閫夋嫨鐨勪富鑹� */
+export function getStoredTheme() {
+  try {
+    return localStorage.getItem(STORAGE_KEY)
+  } catch (e) {
+    return null
+  }
+}
+
+/** 璁颁綇閫夋嫨 */
+export function setStoredTheme(color) {
+  try {
+    localStorage.setItem(STORAGE_KEY, color)
+  } catch (e) {
+    /* 蹇界暐闅愮妯″紡绛夊紓甯� */
+  }
+}
+
+export default {
+  DEFAULT_PRIMARY: DEFAULT_PRIMARY,
+  PRESETS: PRESETS,
+  applyTheme: applyTheme,
+  buildScale: buildScale,
+  getStoredTheme: getStoredTheme,
+  setStoredTheme: setStoredTheme,
+  hexToRgb: hexToRgb,
+  rgbToHex: rgbToHex,
+  mix: mix,
+  luminance: luminance,
+  contrastWithWhite: contrastWithWhite
+}
diff --git a/src/views/home/components/BarChart/index.vue b/src/views/home/components/BarChart/index.vue
index 0ac9b80..7d042ab 100644
--- a/src/views/home/components/BarChart/index.vue
+++ b/src/views/home/components/BarChart/index.vue
@@ -37,8 +37,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/BarChart2/index.vue b/src/views/home/components/BarChart2/index.vue
index 02bf911..66baeea 100644
--- a/src/views/home/components/BarChart2/index.vue
+++ b/src/views/home/components/BarChart2/index.vue
@@ -37,8 +37,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/BarChart3/index.vue b/src/views/home/components/BarChart3/index.vue
index dfc94a7..f80e664 100644
--- a/src/views/home/components/BarChart3/index.vue
+++ b/src/views/home/components/BarChart3/index.vue
@@ -37,8 +37,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/BarChartH/index.vue b/src/views/home/components/BarChartH/index.vue
index 94526c6..1037ab8 100644
--- a/src/views/home/components/BarChartH/index.vue
+++ b/src/views/home/components/BarChartH/index.vue
@@ -41,8 +41,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/MapChart/index.vue b/src/views/home/components/MapChart/index.vue
index a1fc886..8f1b89c 100644
--- a/src/views/home/components/MapChart/index.vue
+++ b/src/views/home/components/MapChart/index.vue
@@ -41,8 +41,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/line1Chart/index.vue b/src/views/home/components/line1Chart/index.vue
index 5e81580..e85e3db 100644
--- a/src/views/home/components/line1Chart/index.vue
+++ b/src/views/home/components/line1Chart/index.vue
@@ -37,8 +37,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/line2Chart/index.vue b/src/views/home/components/line2Chart/index.vue
index 44d6f89..ad87db4 100644
--- a/src/views/home/components/line2Chart/index.vue
+++ b/src/views/home/components/line2Chart/index.vue
@@ -37,8 +37,16 @@
   data() {
     return {
       options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null,
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart,
   },
diff --git a/src/views/home/components/lineChart/index.vue b/src/views/home/components/lineChart/index.vue
index 2fc89be..e2c33f5 100644
--- a/src/views/home/components/lineChart/index.vue
+++ b/src/views/home/components/lineChart/index.vue
@@ -36,9 +36,17 @@
   },
   data() {
     return {
-      options: {}
+      options: {},
+      // 鑷姩杞挱瀹氭椂鍣ㄥ彞鏌勶紱涓嶆竻鐞嗕細鍦ㄧ粍浠堕攢姣佸悗缁х画瑙﹀彂锛屽鑷村宸查攢姣佸疄渚嬫搷浣�
+      intervalId: null
     };
   },
+  beforeDestroy() {
+    if (this.intervalId !== null) {
+      clearInterval(this.intervalId);
+      this.intervalId = null;
+    }
+  },
   components: {
     Echart
   },
diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue
index 06b939d..616c9e1 100644
--- a/src/views/monitor/job/index.vue
+++ b/src/views/monitor/job/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="浠诲姟鍚嶇О" prop="jobName">
         <el-input
           v-model="queryParams.jobName"
diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue
index 44efe5f..e7130a9 100644
--- a/src/views/monitor/job/log.vue
+++ b/src/views/monitor/job/log.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="浠诲姟鍚嶇О" prop="jobName">
         <el-input
           v-model="queryParams.jobName"
diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue
index 6341419..bff4736 100644
--- a/src/views/monitor/logininfor/index.vue
+++ b/src/views/monitor/logininfor/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
         <el-input
           v-model="queryParams.ipaddr"
diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue
index 509fbe5..902666a 100644
--- a/src/views/monitor/online/index.vue
+++ b/src/views/monitor/online/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
       <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
         <el-input
           v-model="queryParams.ipaddr"
diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue
index 0aee4a6..cf405c7 100644
--- a/src/views/monitor/operlog/index.vue
+++ b/src/views/monitor/operlog/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="绯荤粺妯″潡" prop="title">
         <el-input
           v-model="queryParams.title"
diff --git a/src/views/project/DonationEvaluation/index.vue b/src/views/project/DonationEvaluation/index.vue
index ffd55b7..33fc4c2 100644
--- a/src/views/project/DonationEvaluation/index.vue
+++ b/src/views/project/DonationEvaluation/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/project/DonationProcess/index.vue b/src/views/project/DonationProcess/index.vue
index ad48d97..bc7925a 100644
--- a/src/views/project/DonationProcess/index.vue
+++ b/src/views/project/DonationProcess/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -690,16 +691,10 @@
         this.queryParams.reporterno = this.reportervalue;
       }
 
-      if (this.starttime != "") {
-        this.queryParams.starttime = this.starttime;
-      } else {
-        this.queryParams.starttime = "";
-      }
-      if (this.endtime != "") {
-        this.queryParams.endtime = this.endtime;
-      } else {
-        this.queryParams.endtime = "";
-      }
+      // 鏈�夋椂闂磋寖鍥存椂浼� null锛氱┖涓蹭細璁╁悗绔嫾鍑� `donatetime >= ''`锛�
+      // MySQL 涓ユ牸妯″紡浼氭姤 Incorrect DATETIME value: ''锛堣 CHANGELOG 2026-10-22锛�
+      this.queryParams.starttime = this.starttime || null;
+      this.queryParams.endtime = this.endtime || null;
       console.log(this.queryParams);
 
       listDonationProcess(this.queryParams).then(response => {
diff --git a/src/views/project/components/annexupload/index.vue b/src/views/project/components/annexupload/index.vue
index 718dd8f..970afe6 100644
--- a/src/views/project/components/annexupload/index.vue
+++ b/src/views/project/components/annexupload/index.vue
@@ -123,7 +123,7 @@
               clearable
               size="small"
               v-model="uploadtime"
-              type="datetime"
+              type="datetime" format="yyyy-MM-dd HH:mm"
               value-format="yyyy-MM-dd HH:mm:ss"
               placeholder="璇烽�夋嫨涓婁紶鏃堕棿"
             >
diff --git a/src/views/project/distributedetail/index.vue b/src/views/project/distributedetail/index.vue
index 60f494f..a488757 100644
--- a/src/views/project/distributedetail/index.vue
+++ b/src/views/project/distributedetail/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鏀剁泭浜哄鍚� 瀹跺睘鎴栦笓瀹�" prop="beneficiaryname">
         <el-input
           v-model="queryParams.beneficiaryname"
diff --git a/src/views/project/documentfiles/index.vue b/src/views/project/documentfiles/index.vue
index 64bf2be..fe30533 100644
--- a/src/views/project/documentfiles/index.vue
+++ b/src/views/project/documentfiles/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -273,7 +274,7 @@
                 size="small"
                 style="width: 220px"
                 v-model="form.uploadtime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
               >
               </el-date-picker>
@@ -331,7 +332,6 @@
               <el-input v-model="form.fileurl" placeholder="璇疯緭鍏ユ枃浠跺湴鍧�" />
             </el-form-item> -->
             <el-form-item label="鏂囦欢涓婁紶" align="left" prop="fileurl">
-              <!-- <file-upload ref="fileUpload" :fileType=fileType :limit="1" :on-success="handleUploadSuccess"></file-upload> -->
               <el-upload
                 size="mini"
                 class="upload-demo"
@@ -460,7 +460,6 @@
         fileurl: null,
         status: null,
       },
-      fileType: ["png", "jpg", "jpeg", "doc", "xls", "ppt", "txt", "pdf"],
       // 琛ㄥ崟鍙傛暟
       form: {},
       // 琛ㄥ崟鏍¢獙
@@ -469,8 +468,9 @@
       //鏂囦欢鍒楄〃
       fileList: [],
        baseUrl: process.env.VUE_APP_BASE_API,
-      // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload",
+      // 鏀跨瓥鏂囦欢涓婁紶鎺ュ彛锛�2026-10-09锛氭敼鐢ㄦā鍧椾笓灞炴帴鍙o紝鍏佽浠绘剰鏂囦欢绫诲瀷锛�
+      // 閫氱敤 /common/upload 浠嶆寜鎵╁睍鍚嶇櫧鍚嶅崟鏍¢獙锛屼笉閫傜敤浜庢湰妯″潡锛�
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/project/documentfiles/upload",
       //涓婁紶闄勪欢璇锋眰澶�
       headers: {
         Authorization: "Bearer " + getToken(),
@@ -659,34 +659,100 @@
     download() {
       let list = this.fileList;
       if (list.length > 0) {
-        let downUrl = list[0].url;
-        const link = document.createElement("a");
-        link.href = this.baseUrl + downUrl;
-        link.setAttribute("download", this.getFileName(list[0].name));
-        document.body.appendChild(link);
-        link.click();
+        this.saveFile(list[0].url, this.getFileName(list[0].name, list[0].url));
       } else {
         this.$modal.msgWarning("鏈幏鍙栧埌鏂囦欢鍦板潃锛岃纭");
       }
     },
     handleDownload(row) {
       if (row.fileurl != "" && row.fileurl != null) {
-        const link = document.createElement("a");
-        link.href = this.baseUrl + row.fileurl;
-        link.setAttribute("download", this.getFileName(row.fileurl));
-        document.body.appendChild(link);
-        link.click();
+        this.saveFile(
+          row.fileurl,
+          this.getFileName(row.filename, row.fileurl, row.filename)
+        );
       } else {
         this.$modal.msgWarning("鏈幏鍙栧埌鏂囦欢鍦板潃锛岃纭");
       }
     },
-    // 鑾峰彇鏂囦欢鍚嶇О
-    getFileName(name) {
-      if (name.lastIndexOf("/") > -1) {
-        return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
-      } else {
-        return "";
+
+    /**
+     * 涓嬭浇鏂囦欢锛堝繀椤诲甫閴存潈锛夈��
+     *
+     * 鑳屾櫙锛�/profile/** 闈欐�佽祫婧愭湭鍦� SecurityConfig 涓斁琛岋紙anyRequest().authenticated()锛夛紝
+     * 鑰屽悗绔� TokenService 鍙粠璇锋眰澶� Authorization 鍙� token銆�
+     * 鍥犳鐢� <a href> 鐩存帴璺宠浆涓嬭浇涓嶄細鎼哄甫 token锛屾湇鍔$杩斿洖 401锛岃〃鐜颁负鈥滅偣涓嬭浇娌″弽搴�/涓嬩笉鍒版枃浠垛�濄��
+     * 杩欓噷鏀逛负 fetch 甯� Authorization 澶村彇鍥炴枃浠舵祦锛屽啀鐢� blob 鏈湴鍙﹀瓨銆�
+     *
+     * @param {string} fileUrl 鏂囦欢鍦板潃锛堝簱涓瓨鐨勬槸 /profile/upload/... 鐩稿璺緞锛�
+     * @param {string} fileName 鍙﹀瓨涓虹殑鏂囦欢鍚�
+     */
+    saveFile(fileUrl, fileName) {
+      if (!fileUrl) {
+        this.$modal.msgWarning("鏈幏鍙栧埌鏂囦欢鍦板潃锛岃纭");
+        return;
       }
+      // 鍏煎鍘嗗彶鏁版嵁涓凡鏄粷瀵瑰湴鍧�鐨勬儏鍐碉紝閬垮厤閲嶅鎷兼帴
+      const isAbsolute = /^https?:\/\//i.test(fileUrl);
+      const url = isAbsolute ? fileUrl : this.baseUrl + fileUrl;
+
+      this.$modal.loading("姝e湪涓嬭浇鏂囦欢锛岃鑰愬績绛夊緟锛�");
+      fetch(url, {
+        method: "get",
+        headers: { Authorization: "Bearer " + getToken() },
+      })
+        .then((response) => {
+          if (!response.ok) {
+            // 401/403/404 蹇呴』鏄惧紡鎻愮ず锛屽惁鍒欎細涓嬪埌涓�涓唴瀹逛负閿欒椤电殑鏂囦欢
+            throw new Error("HTTP " + response.status);
+          }
+          return response.blob();
+        })
+        .then((blob) => {
+          const blobUrl = window.URL.createObjectURL(blob);
+          const link = document.createElement("a");
+          link.href = blobUrl;
+          link.setAttribute("download", fileName || "涓嬭浇鏂囦欢");
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+          window.URL.revokeObjectURL(blobUrl);
+        })
+        .catch((err) => {
+          console.error("鏂囦欢涓嬭浇澶辫触锛�" + url, err);
+          this.$modal.msgError("鏂囦欢涓嬭浇澶辫触锛岃纭鏂囦欢鏄惁瀛樺湪鎴栫櫥褰曟槸鍚﹁繃鏈�");
+        })
+        .finally(() => {
+          this.$modal.closeLoading();
+        });
+    },
+
+    /**
+     * 鑾峰彇鍙﹀瓨涓虹殑鏂囦欢鍚嶃��
+     *
+     * 浼樺厛绾э細甯︽墿灞曞悕鐨勫師濮嬫枃浠跺悕 > 鏂囦欢鍦板潃鏈 > 鏂囨。鏍囬銆�
+     * 涔嬫墍浠ヤ笉鐩存帴鐢� form.filename锛氳瀛楁鍦ㄨ〃鍗曚腑鍙墜宸ョ紪杈戯紙濡傗�滀汉浣撳櫒瀹樼Щ妞嶆潯渚嬧�濓級锛�
+     * 涓嶅甫鎵╁睍鍚嶏紝鐩存帴鐢ㄤ綔鍙﹀瓨鍚嶄細瀵艰嚧绯荤粺鏃犳硶璇嗗埆鎵撳紑鏂瑰紡銆�
+     *
+     * @param {string} storedName 鍘熷鏂囦欢鍚嶏紙濡� form.filename 涓瓨鐨� xxx.docx锛�
+     * @param {string} fileUrl 鏂囦欢鍦板潃
+     * @param {string} title 澶囩敤鍚嶇О锛堟枃妗f爣棰橈級
+     */
+    getFileName(storedName, fileUrl, title) {
+      const hasExt = (name) => !!name && name.lastIndexOf(".") > -1;
+
+      if (hasExt(storedName)) {
+        return storedName;
+      }
+
+      const source = fileUrl || "";
+      if (source.lastIndexOf("/") > -1) {
+        const fromUrl = source.slice(source.lastIndexOf("/") + 1);
+        if (fromUrl) {
+          return fromUrl;
+        }
+      }
+
+      return title || storedName || "涓嬭浇鏂囦欢";
     },
 
     //鏂囦欢涓婁紶鎴愬姛鍥炶皟
@@ -698,7 +764,8 @@
         this.$modal.msgSuccess(response.msg);
         this.fileList.push({ name: response.fileName, url: response.fileName });
       } else {
-        console.log(response.msg);;
+        // 2026-10-09锛氫笂浼犲け璐ュ繀椤绘彁绀恒�傚師鏉ュ彧 console.log锛岀敤鎴风湅涓嶅埌澶辫触鍘熷洜锛堣〃鐜颁负"鐐逛簡娌″弽搴�"锛�
+        this.$modal.msgError(response.msg || "涓婁紶澶辫触锛岃閲嶈瘯");
       }
       //console.log("涓婁紶鏂囦欢鍚庯細" + JSON.stringify(this.fileList));
     },
@@ -716,9 +783,10 @@
     handleExceed() {
       this.$message.error(`涓婁紶鏂囦欢鏁伴噺宸茶秴杩�!`);
     },
-    // 涓婁紶澶辫触
+    // 涓婁紶澶辫触锛圚TTP 灞傞敊璇紝濡傜櫥褰曡繃鏈熴�佺綉缁滃紓甯革級
     handleUploadError(err) {
-      this.$message.error("涓婁紶澶辫触, 璇烽噸璇�" + JSON.stringify(err));
+      const msg = (err && (err.msg || err.message)) || "";
+      this.$modal.msgError("涓婁紶澶辫触锛岃閲嶈瘯" + (msg ? "锛�" + msg : ""));
     },
   },
 };
diff --git a/src/views/project/donateannex/index.vue b/src/views/project/donateannex/index.vue
index 9a28fff..4c3e9ce 100644
--- a/src/views/project/donateannex/index.vue
+++ b/src/views/project/donateannex/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/project/donateannexrequirement/index.vue b/src/views/project/donateannexrequirement/index.vue
index 71adb2b..d234df4 100644
--- a/src/views/project/donateannexrequirement/index.vue
+++ b/src/views/project/donateannexrequirement/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-row>
         <el-col :span="6">
           <el-form-item label="闄勪欢缂栧彿" prop="annexno">
diff --git a/src/views/project/donatebaseinfo/index.vue b/src/views/project/donatebaseinfo/index.vue
index bb566f6..c524778 100644
--- a/src/views/project/donatebaseinfo/index.vue
+++ b/src/views/project/donatebaseinfo/index.vue
@@ -3,16 +3,17 @@
     <el-form
       :model="queryParams"
       ref="queryForm"
+      class="opo-query-form"
       :inline="true"
       v-show="showSearch"
       label-width="70px"
     >
       <el-row :gutter="8">
         <el-col :span="5">
-          <el-form-item label="濮撳悕" prop="name">
+          <el-form-item label="鎹愮尞鑰�" prop="name">
             <el-input
               v-model="queryParams.name"
-              placeholder="璇疯緭鍏ュ鍚�"
+              placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
               clearable
               size="small"
               @keyup.enter.native="handleQuery"
@@ -46,24 +47,25 @@
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="9">
-          <el-form-item label="妗堜緥鏃堕棿">
-            <el-date-picker
-              style="width: 100%"
-              v-model="selecttime"
-              type="monthrange"
-              range-separator="鑷�"
-              start-placeholder="寮�濮嬫湀浠�"
-              end-placeholder="缁撴潫鏈堜唤"
-              value-format="yyyy-MM-dd"
-              @change="getTimeList"
+       <el-col :span="6">
+          <el-form-item label="鎶ュ憡浜�">
+            <el-select
+              v-model="queryParams.reporterno"
+              placeholder="璇烽�夋嫨鎶ュ憡浜�"
             >
-            </el-date-picker>
+              <el-option
+                v-for="item in reportlist"
+                :key="item.index"
+                :label="item.reportername"
+                :value="item.reporterno"
+              >
+              </el-option>
+            </el-select>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row :gutter="8">
-        <el-col :span="5">
+        <el-col :span="6">
           <el-form-item label="鎹愮尞杩涘害" prop="workflow">
             <el-select
               v-model="queryParams.workflow"
@@ -80,23 +82,23 @@
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="5">
-          <el-form-item label="鎶ュ憡浜�">
-            <el-select
-              v-model="queryParams.reporterno"
-              placeholder="璇烽�夋嫨鎶ュ憡浜�"
+         <el-col :span="9">
+          <el-form-item label="妗堜緥鏃堕棿">
+            <el-date-picker
+              style="width: 100%"
+              v-model="selecttime"
+              type="monthrange"
+              range-separator="鑷�"
+              start-placeholder="寮�濮嬫湀浠�"
+              end-placeholder="缁撴潫鏈堜唤"
+              value-format="yyyy-MM-dd"
+              @change="getTimeList"
             >
-              <el-option
-                v-for="item in reportlist"
-                :key="item.index"
-                :label="item.reportername"
-                :value="item.reporterno"
-              >
-              </el-option>
-            </el-select>
+            </el-date-picker>
           </el-form-item>
         </el-col>
-        <el-col :span="5">
+        
+        <el-col :span="6">
           <el-form-item label="鏄惁缁堟">
             <el-select
               v-model="queryParams.terminationCase"
@@ -112,19 +114,8 @@
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="9">
-          <el-form-item label="绫嶈疮">
-            <div>
-              <li_area_select
-                ref="areaSelect"
-                v-model="searchAddress"
-              ></li_area_select>
-            </div>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="4">
+        <!-- 鎼滅储/閲嶇疆绱ц窡鏌ヨ鏉′欢锛堜笌"妗堜緥璇勪及"椤典竴鑷达級 -->
+        <el-col :span="6">
           <el-form-item>
             <el-button
               type="primary"
@@ -206,7 +197,7 @@
         label="鎹愮尞缂栧彿"
         align="center"
         prop="donorno"
-        width="200"
+        width="100"
       />
       <el-table-column label="濮撳悕" align="center" prop="name" width="100" />
       <el-table-column label="鎬у埆" align="center" prop="sex" width="100">
@@ -233,9 +224,9 @@
       <el-table-column
         label="鍖荤枟鏈烘瀯"
         align="center"
-        prop="treatmenthospitalname"
+        prop="treatmenthospitalname" width="220"
       />
-      <el-table-column label="琛�鍨�" align="center" prop="bloodtype" width="100">
+      <el-table-column label="琛�鍨�" align="center" prop="bloodtype" width="80">
         <template slot-scope="scope">
           <dict-tag
             :options="dict.type.sys_BloodType"
@@ -263,7 +254,7 @@
         prop="reportername"
         width="100"
       />
-      <!--
+      
          <el-table-column
         label="鐜版墍鍦ㄥ湴甯�"
         align="center"
@@ -283,7 +274,7 @@
           />
         </template>
       </el-table-column>
-      -->
+     
       <el-table-column
         label="鎹愮尞杩涘害"
         align="center"
@@ -304,7 +295,7 @@
         label="鎿嶄綔"
         align="center"
         class-name="small-padding fixed-width"
-        fixed="right"
+        fixed="right" width="200"
       >
         <template slot-scope="scope">
           <el-button
@@ -863,7 +854,7 @@
                   size="small"
                   style="width: 190px"
                   v-model="form.contacttime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎶ュ憡鏃堕棿"
                 >
@@ -920,7 +911,7 @@
                   size="small"
                   style="width: 190px"
                   v-model="form.reporttime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎶ュ憡鏃堕棿"
                 >
@@ -1663,19 +1654,16 @@
         this.queryParams.reportno = this.reportervalue;
       }
 
-      if (this.starttime != "") {
-        this.queryParams.starttime = this.starttime;
-      } else {
-        this.queryParams.starttime = "";
-      }
-      if (this.endtime != "") {
-        this.queryParams.endtime = this.endtime;
-      } else {
-        this.queryParams.endtime = "";
-      }
-      this.queryParams.residenceprovince = this.$refs.areaSelect.getSheng();
-      this.queryParams.residencecity = this.$refs.areaSelect.getShi();
-      this.queryParams.residencetown = this.$refs.areaSelect.getQu();
+      // 鏈�夋嫨鏃堕棿鑼冨洿鏃跺繀椤讳紶 null锛氫紶绌轰覆浼氳鍚庣鎷煎嚭 `donatetime >= ''`锛�
+      // MySQL 涓ユ牸妯″紡浼氭姤 Incorrect DATETIME value: ''锛屽鑷村垪琛ㄦ煡涓嶅嚭鏉ャ��
+      // request.js 鍙細鎷兼帴闈� null/undefined 鐨勫弬鏁帮紝鎵�浠� null 绛変簬"涓嶅甫璇ユ潯浠�"銆�
+      this.queryParams.starttime = this.starttime || null;
+      this.queryParams.endtime = this.endtime || null;
+      // 鏌ヨ鏉′欢閲岀殑"绫嶈疮"宸茬Щ闄わ紝涓嶅啀浠� areaSelect 缁勪欢鍙栧�硷紱
+      // 缃┖浠ユ竻鎺夊彲鑳芥畫鐣欑殑鏃ф潯浠讹紙鍙傛暟涓� null 鏃朵笉浼氳鎷艰繘璇锋眰锛�
+      this.queryParams.residenceprovince = null;
+      this.queryParams.residencecity = null;
+      this.queryParams.residencetown = null;
       console.log(this.queryParams);
 
       listDonatebaseinfo(this.queryParams).then(response => {
@@ -2086,6 +2074,7 @@
 </script>
 
 <style scoped>
+/* 鏌ヨ鍖鸿璺濄�侀〉闈㈠唴杈硅窛銆佸伐鍏锋爮闂磋窛宸叉彁鍗囦负鍏ㄥ眬瑙勫垯锛�.opo-query-form / .app-container锛夛紝姝ゅ涓嶅啀鍗曠嫭瑕嗙洊 */
 ::v-deep .el-dialog__header {
   padding-top: 40px !important;
   margin: auto !important;
diff --git a/src/views/project/donateconsolationfund/index.vue b/src/views/project/donateconsolationfund/index.vue
index 5c6f221..d9c91ff 100644
--- a/src/views/project/donateconsolationfund/index.vue
+++ b/src/views/project/donateconsolationfund/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -635,7 +636,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.createTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
               >
diff --git a/src/views/project/donatefinish/index.vue b/src/views/project/donatefinish/index.vue
index 8911505..bb31efb 100644
--- a/src/views/project/donatefinish/index.vue
+++ b/src/views/project/donatefinish/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -308,8 +309,8 @@
                 clearable
                 size="small"
                 v-model="form.completetime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨瀹屾垚鏃堕棿"
               >
               </el-date-picker>
@@ -378,7 +379,7 @@
                     size="small"
                     style="width: 90%"
                     v-model="scope.row.transplanttime"
-                    type="date"
+                    type="date" format="yyyy-MM-dd"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鍣ㄥ畼绉绘鏃堕棿"
                   >
diff --git a/src/views/project/donatefinishcheck/index.vue b/src/views/project/donatefinishcheck/index.vue
index b33269b..6682c90 100644
--- a/src/views/project/donatefinishcheck/index.vue
+++ b/src/views/project/donatefinishcheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -250,8 +251,8 @@
                 clearable
                 size="small"
                 v-model="form.completetime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨瀹屾垚鏃堕棿"
               >
               </el-date-picker>
@@ -320,7 +321,7 @@
                     size="small"
                     style="width: 90%"
                     v-model="scope.row.transplanttime"
-                    type="date"
+                    type="date" format="yyyy-MM-dd"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鍣ㄥ畼鑾峰彇鏃堕棿"
                   >
@@ -897,16 +898,10 @@
       // this.queryParams.residenceprovince = this.$refs.areaSelect.getSheng();
       // this.queryParams.residencecity = this.$refs.areaSelect.getShi();
       // this.queryParams.residencetown = this.$refs.areaSelect.getQu();
-       if (this.starttime != "") {
-        this.queryParams.starttime = this.starttime;
-      } else {
-        this.queryParams.starttime = "";
-      }
-      if (this.endtime != "") {
-        this.queryParams.endtime = this.endtime;
-      } else {
-        this.queryParams.endtime = "";
-      }
+      // 鏈�夋椂闂磋寖鍥存椂浼� null锛氱┖涓蹭細璁╁悗绔嫾鍑� `donatetime >= ''`锛�
+      // MySQL 涓ユ牸妯″紡浼氭姤 Incorrect DATETIME value: ''锛堣 CHANGELOG 2026-10-22锛�
+      this.queryParams.starttime = this.starttime || null;
+      this.queryParams.endtime = this.endtime || null;
       // this.queryParams.residenceprovince = this.$refs.areaSelect.getSheng();
       // this.queryParams.residencecity = this.$refs.areaSelect.getShi();
       // this.queryParams.residencetown = this.$refs.areaSelect.getQu();
diff --git a/src/views/project/donatefollowup/index.vue b/src/views/project/donatefollowup/index.vue
index efaef54..f3348f8 100644
--- a/src/views/project/donatefollowup/index.vue
+++ b/src/views/project/donatefollowup/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -339,8 +340,8 @@
                 clearable
                 size="small"
                 v-model="form.followuptime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闅忚鏃堕棿"
               >
               </el-date-picker>
diff --git a/src/views/project/donateorgan/index.vue b/src/views/project/donateorgan/index.vue
index 822b024..c12c2ad 100644
--- a/src/views/project/donateorgan/index.vue
+++ b/src/views/project/donateorgan/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="70px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="70px">
       <el-row>
         <el-col :span="6">
           <el-form-item label="鍣ㄥ畼鍚嶇О" prop="organno">
@@ -360,7 +361,7 @@
         <el-row>
           <el-col :span="12">
             <el-form-item label="鑾峰彇鏃堕棿" prop="organgettime">
-              <el-date-picker clearable size="medium" v-model="form.organgettime" type="date" disabled
+              <el-date-picker clearable size="medium" v-model="form.organgettime" type="date" format="yyyy-MM-dd" disabled
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鍣ㄥ畼鑾峰彇鏃堕棿">
               </el-date-picker>
             </el-form-item>
@@ -410,7 +411,7 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="绉绘鏃堕棿" prop="transplanttime">
-              <el-date-picker clearable size="medium" v-model="form.transplanttime" type="date"
+              <el-date-picker clearable size="medium" v-model="form.transplanttime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨绉绘鏃堕棿" disabled>
               </el-date-picker>
             </el-form-item>
diff --git a/src/views/project/donateorganstatics/index.vue b/src/views/project/donateorganstatics/index.vue
index ca1fe68..fd9b8ca 100644
--- a/src/views/project/donateorganstatics/index.vue
+++ b/src/views/project/donateorganstatics/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/project/donatereview/index.vue b/src/views/project/donatereview/index.vue
index 9f06523..6fb27c5 100644
--- a/src/views/project/donatereview/index.vue
+++ b/src/views/project/donatereview/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -395,9 +396,9 @@
                 clearable
                 size="small"
                 v-model="form.birthday"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 style="width: 174px"
-                value-format="yyyy:MM:dd HH:mm:ss"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鍑虹敓鏃ユ湡"
               >
               </el-date-picker>
@@ -756,8 +757,8 @@
                 clearable
                 size="small"
                 v-model="form.reporttime"
-                type="date"
-                value-format="yyyy-MM-dd  HH:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鎶ュ憡鏃堕棿"
               >
               </el-date-picker>
@@ -1115,16 +1116,10 @@
       // this.queryParams.residenceprovince = this.$refs.areaSelect.getSheng();
       // this.queryParams.residencecity = this.$refs.areaSelect.getShi();
       // this.queryParams.residencetown = this.$refs.areaSelect.getQu();
-       if (this.starttime != "") {
-        this.queryParams.starttime = this.starttime;
-      } else {
-        this.queryParams.starttime = "";
-      }
-      if (this.endtime != "") {
-        this.queryParams.endtime = this.endtime;
-      } else {
-        this.queryParams.endtime = "";
-      }
+      // 鏈�夋椂闂磋寖鍥存椂浼� null锛氱┖涓蹭細璁╁悗绔嫾鍑� `donatetime >= ''`锛�
+      // MySQL 涓ユ牸妯″紡浼氭姤 Incorrect DATETIME value: ''锛堣 CHANGELOG 2026-10-22锛�
+      this.queryParams.starttime = this.starttime || null;
+      this.queryParams.endtime = this.endtime || null;
       listDonatebaseinfo(this.queryParams).then((response) => {
         console.log("getlist", response.rows);
         this.donatebaseinfoList = response.rows;
diff --git a/src/views/project/donationdetails/index.vue b/src/views/project/donationdetails/index.vue
index 42ecc25..be05831 100644
--- a/src/views/project/donationdetails/index.vue
+++ b/src/views/project/donationdetails/index.vue
@@ -3,7 +3,7 @@
     <div class="left-course" :class="{ 'left-collapsed': isLeftCollapsed }">
       <div class="postfilx">
         <div class="title">
-          宸ヤ綔杩涚▼
+          妗堜緥杩涚▼
           <el-button
             class="collapse-btn"
             @click="toggleLeftCollapse"
@@ -221,7 +221,7 @@
                     clearable
                     size="small"
                     v-model="form.reporttime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鎶ュ憡鏃ユ湡"
                   >
@@ -267,7 +267,7 @@
                     clearable
                     size="small"
                     v-model="form.birthday"
-                    type="date"
+                    type="date" format="yyyy-MM-dd"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鍑虹敓鏃ユ湡"
                   >
@@ -779,7 +779,7 @@
                   size="small"
                   style="width: 190px"
                   v-model="form.contacttime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎶ュ憡鏃堕棿"
                 >
@@ -862,7 +862,7 @@
                   clearable
                   size="small"
                   v-model="medicineform.hospitalassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨闄㈢骇璇勪及鏃堕棿"
                 >
@@ -915,7 +915,7 @@
                   clearable
                   size="small"
                   v-model="medicineform.provincialassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鐪佺骇璇勪及鏃堕棿"
                 >
@@ -969,7 +969,7 @@
                   clearable
                   size="small"
                   v-model="medicineform.coreteamassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="璇勪及鏃堕棿"
                 >
@@ -1388,7 +1388,7 @@
                   clearable
                   size="small"
                   v-model="ethicform.conclusiontime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨缁撹鏃堕棿"
                 >
@@ -1478,7 +1478,7 @@
                         size="small"
                         style="width: 100%"
                         v-model="scope.row.applicanttime"
-                        type="datetime"
+                        type="datetime" format="yyyy-MM-dd HH:mm"
                         value-format="yyyy-MM-dd HH:mm:ss"
                         placeholder="閫夋嫨鍒嗛厤鎺ユ敹鏃堕棿"
                       >
@@ -1658,7 +1658,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.deathtime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨姝讳骸鏃堕棿"
                 >
@@ -1697,7 +1697,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.operationbegtime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎵嬫湳寮�濮嬫椂闂�"
                 >
@@ -1714,7 +1714,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.operationendtime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎵嬫湳缁撴潫鏃堕棿"
                 >
@@ -1733,7 +1733,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.coordinatorInOperating"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎵嬫湳寮�濮嬫椂闂�"
                 >
@@ -1750,7 +1750,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.coordinatorOutOperating"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎵嬫湳缁撴潫鏃堕棿"
                 >
@@ -1767,7 +1767,7 @@
                 <el-date-picker
                   clearable
                   v-model="witnessform.coordinatorSignTime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鎵嬫湳缁撴潫鏃堕棿"
                 >
@@ -1794,7 +1794,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.abdominalaortacannulatime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鑵逛富鍔ㄨ剦鎻掔鏃堕棿"
                   >
@@ -1811,7 +1811,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.abdominalaortaperfusiontime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨鑵逛富鍔ㄨ剦鐏屾敞鏃堕棿"
                   >
@@ -1828,7 +1828,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.portalveincannulatime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨闂ㄩ潤鑴夎剦鎻掔鏃堕棿"
                   >
@@ -1845,7 +1845,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.portalveinperfusiontime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨闂ㄩ潤鑴夌亴娉ㄦ椂闂�"
                   >
@@ -1864,7 +1864,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.pulmonaryarterycannulatime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨闂ㄩ潤鑴夋彃绠℃椂闂�"
                   >
@@ -1881,7 +1881,7 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.pulmonaryarteryperfusiontime"
-                    type="datetime"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
                     value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨闂ㄩ潤鑴夌亴娉ㄦ椂闂�"
                   >
@@ -1898,8 +1898,8 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.aortacannulatime"
-                    type="datetime"
-                    value-format="yyyy-MM-dd  HH:mm:ss"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
+                    value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨涓诲姩鑴夋彃绠℃椂闂�"
                   >
                   </el-date-picker>
@@ -1915,8 +1915,8 @@
                   <el-date-picker
                     clearable
                     v-model="witnessform.aortaperfusiontime"
-                    type="datetime"
-                    value-format="yyyy-MM-dd  HH:mm:ss"
+                    type="datetime" format="yyyy-MM-dd HH:mm"
+                    value-format="yyyy-MM-dd HH:mm:ss"
                     placeholder="閫夋嫨涓诲姩鑴夌亴娉ㄦ椂闂�"
                   >
                   </el-date-picker>
@@ -2028,7 +2028,7 @@
                         size="small"
                         style="width: 100%"
                         v-model="scope.row.organStartTime"
-                        type="datetime"
+                        type="datetime" format="yyyy-MM-dd HH:mm"
                         value-format="yyyy-MM-dd HH:mm:ss"
                         placeholder="璇疯緭鍏ヨ幏鍙栧紑濮嬫椂闂�"
                       >
@@ -2048,7 +2048,7 @@
                         size="small"
                         style="width: 100%"
                         v-model="scope.row.organgettime"
-                        type="datetime"
+                        type="datetime" format="yyyy-MM-dd HH:mm"
                         value-format="yyyy-MM-dd HH:mm:ss"
                         placeholder="璇疯緭鍏ュ櫒瀹樼浣撴椂闂�"
                       >
@@ -2450,8 +2450,8 @@
                   clearable
                   size="small"
                   v-model="accomplishform.completetime"
-                  type="date"
-                  value-format="yyyy-MM-dd hh:mm:ss"
+                  type="date" format="yyyy-MM-dd"
+                  value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨瀹屾垚鏃堕棿"
                 >
                 </el-date-picker>
@@ -3485,7 +3485,12 @@
       this.isLeftCollapsed = !this.isLeftCollapsed;
     },
     /** 淇濆瓨涓昏〃鎸夐挳 */
-    submitForm() {
+    submitForm(fromProcess) {
+      // 淇濆瓨闃查噸锛氶潪"娴佺▼鎺ㄨ繘"瑙﹀彂鐨勪繚瀛橈紝2 绉掑唴鐨勯噸澶嶇偣鍑荤洿鎺ュ拷鐣ワ紙闃叉閲嶅鎻掑叆锛�
+      if (!fromProcess && !this.canSave()) {
+        this.$modal.msgWarning("璇峰嬁閲嶅鎻愪氦");
+        return;
+      }
       this.$refs["form"].validate(valid => {
         console.log("鎻愪氦鐨勬暟鎹滑锛�", this.form);
         if (valid) {
@@ -3495,14 +3500,21 @@
             "YYYY-MM-DD HH:mm:ss"
           );
 
-          this.form.diseasetype = this.form.diseasetype.join(",");
-
-          this.form.infectious = this.form.infectious.join(",");
-          this.form.selfwill = this.form.selfwill.join(",");
-          this.form.othercases = this.form.othercases.join(",");
-          this.form.infosources = this.form.infosources.join(",");
-          this.form.kinship = this.form.kinship.join(",");
-          this.form.patientstate = this.form.patientstate.join(",");
+          // 澶氶�夊瓧娈佃浆瀛楃涓诧細骞傜瓑澶勭悊锛堝凡鏄瓧绗︿覆鏃朵繚鎸佸師鏍凤級锛�
+          // 閬垮厤"淇濆瓨鎴愬姛鍚庢湭閲嶆柊鍔犺浇鍐嶆淇濆瓨"鏃舵姏 join is not a function
+          [
+            "diseasetype",
+            "infectious",
+            "selfwill",
+            "othercases",
+            "infosources",
+            "kinship",
+            "patientstate"
+          ].forEach(key => {
+            if (Array.isArray(this.form[key])) {
+              this.form[key] = this.form[key].join(",");
+            }
+          });
           this.form.registerprovince = this.$refs.registerSelect.getSheng();
           this.form.registerprovincename = this.registerAddresss.sheng;
 
@@ -3584,6 +3596,11 @@
     },
     // 淇濆瓨浜岀骇琛ㄦ寜閽�
     Savethedetails() {
+      // 淇濆瓨闃查噸锛�2 绉掑唴鐨勯噸澶嶇偣鍑荤洿鎺ュ拷鐣ワ紙闃叉閲嶅鎻掑叆锛�
+      if (!this.canSave()) {
+        this.$modal.msgWarning("璇峰嬁閲嶅鎻愪氦");
+        return;
+      }
       console.log(this.actives);
       if (this.actives == 1) {
         this.medicineform.infoid = this.infoid;
@@ -3594,14 +3611,19 @@
               updateMedicalevaluation(this.medicineform).then(response => {
                 this.$modal.msgSuccess("鍖诲璇勪及淇℃伅淇敼鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             } else {
               addMedicalevaluation(this.medicineform).then(response => {
+                // 鍥炲~涓婚敭锛氬惁鍒欎笅娆′繚瀛樹粛璧�"鏂板"锛屼細浜х敓閲嶅琛�
+                if (response && response.data && response.data.id) {
+                  this.medicineform.id = response.data.id;
+                }
                 this.$modal.msgSuccess("鍖诲璇勪及淇℃伅鏂板鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             }
-            this.Processvalidation();
           }
         });
       } else if (this.actives == 2) {
@@ -3621,17 +3643,22 @@
               updateRelativesconfirmation(this.affirmform).then(response => {
                 this.$modal.msgSuccess("鎹愮尞纭淇℃伅淇敼鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             } else {
               this.affirmform.residenceprovincename = this.defultAddresss.sheng;
               this.affirmform.residencecityname = this.defultAddresss.shi;
               this.affirmform.residencetownname = this.defultAddresss.qu;
               addRelativesconfirmation(this.affirmform).then(response => {
+                // 鍥炲~涓婚敭锛氬惁鍒欎笅娆′繚瀛樹粛璧�"鏂板"锛屼細浜х敓閲嶅琛�
+                if (response && response.data && response.data.id) {
+                  this.affirmform.id = response.data.id;
+                }
                 this.$modal.msgSuccess("鎹愮尞纭淇℃伅鏂板鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             }
-            this.Processvalidation();
           }
         });
       } else if (this.actives == 3) {
@@ -3644,15 +3671,20 @@
               updateEthicalreviewopinions(this.ethicform).then(res => {
                 this.$modal.msgSuccess("浼︾悊瀹℃煡淇℃伅淇敼鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             } else {
               //addDonateflowchart(this.ethicform).then(response => {
               addEthicalreviewopinions(this.ethicform).then(res => {
+                // 鍥炲~涓婚敭锛氬惁鍒欎笅娆′繚瀛樹粛璧�"鏂板"锛屼細浜х敓閲嶅琛�
+                if (res && res.data && res.data.id) {
+                  this.ethicform.id = res.data.id;
+                }
                 this.$modal.msgSuccess("浼︾悊瀹℃煡淇℃伅鏂板鎴愬姛");
                 this.$modal.closeLoading();
+                this.Processvalidation();
               });
             }
-            this.Processvalidation();
           }
         });
       } else if (this.actives == 4) {
@@ -3672,6 +3704,12 @@
             }
           });
           saveDonateorgan(this.allocateddata).then(res => {
+            // 鍥炲~涓婚敭锛氬悗绔凡鎸�"鍚屼竴妗堜緥鍚屼竴鍣ㄥ畼"鍋� upsert锛屽洖濉悗鍓嶇涓嶄細鍐嶈鍒や负鏂板
+            if (res && res.data && res.data.length === this.allocateddata.length) {
+              res.data.forEach((row, i) => {
+                this.allocateddata[i].id = row.id;
+              });
+            }
             if (res.code == 200) {
               this.$modal.msgSuccess("鍣ㄥ畼鎹愮尞鍒嗛厤淇℃伅淇濆瓨鎴愬姛锛�");
               this.$modal.closeLoading();
@@ -3720,7 +3758,12 @@
                 });
                 //淇濆瓨鍣ㄥ畼鑾峰彇琛ㄦ暟鎹�
                 saveDonationwitnessorgan(this.procureddata).then(res => {
-                  if (res == 200) {
+                  if (res && res.data && res.data.length === this.procureddata.length) {
+                    res.data.forEach((row, i) => {
+                      this.procureddata[i].id = row.id;
+                    });
+                  }
+                  if (res.code == 200) {
                     this.$modal.msgSuccess("鎹愮尞鍣ㄥ畼鑾峰彇淇℃伅淇濆瓨鎴愬姛锛�");
                   }
                   this.$modal.closeLoading();
@@ -3729,6 +3772,10 @@
             } else {
               addDonationwitness(this.witnessform).then(response => {
                 if (response.code === 200) {
+                  // 鍥炲~涓婚敭锛氬惁鍒欎笅娆′繚瀛樹粛璧�"鏂板"
+                  if (response.data && response.data.id) {
+                    this.witnessform.id = response.data.id;
+                  }
                   this.$modal.msgSuccess("鑾峰彇瑙佽瘉淇℃伅鏂板鎴愬姛");
                   this.form.donationcategory = this.witnessform.donationcategory;
                   let data = JSON.parse(JSON.stringify(this.form));
@@ -3747,7 +3794,12 @@
                   });
                   //淇濆瓨鍣ㄥ畼鑾峰彇琛ㄦ暟鎹�
                   saveDonationwitnessorgan(this.procureddata).then(res => {
-                    if (res == 200) {
+                    if (res && res.data && res.data.length === this.procureddata.length) {
+                      res.data.forEach((row, i) => {
+                        this.procureddata[i].id = row.id;
+                      });
+                    }
+                    if (res.code == 200) {
                       this.$modal.msgSuccess("鎹愮尞鍣ㄥ畼鑾峰彇淇℃伅淇濆瓨鎴愬姛锛�");
                     }
                     this.$modal.closeLoading();
@@ -3782,7 +3834,12 @@
               updateDonatecompletioninfo(this.accomplishform).then(response => {
                 this.$modal.msgSuccess("瀹屾垚鐧昏淇℃伅淇敼鎴愬姛");
                 saveDonatecomporgan(this.transplantdata).then(res => {
-                  if (res == 200) {
+                  if (res && res.data && res.data.length === this.transplantdata.length) {
+                    res.data.forEach((row, i) => {
+                      this.transplantdata[i].id = row.id;
+                    });
+                  }
+                  if (res.code == 200) {
                     this.$modal.msgSuccess("鎹愮尞鍣ㄥ畼鐧昏淇℃伅淇濆瓨鎴愬姛锛�");
                   } else {
                     this.$modal.msgSuccess(res.msg);
@@ -3792,8 +3849,17 @@
               });
             } else {
               addDonatecompletioninfo(this.accomplishform).then(response => {
+                // 鍥炲~涓婚敭锛氬惁鍒欎笅娆′繚瀛樹粛璧�"鏂板"
+                if (response && response.data && response.data.id) {
+                  this.accomplishform.id = response.data.id;
+                }
                 this.$modal.msgSuccess("瀹屾垚鐧昏鎴愬姛");
                 saveDonatecomporgan(this.transplantdata).then(res => {
+                  if (res && res.data && res.data.length === this.transplantdata.length) {
+                    res.data.forEach((row, i) => {
+                      this.transplantdata[i].id = row.id;
+                    });
+                  }
                   if (res.code == 200) {
                     this.$modal.msgSuccess("鎹愮尞鍣ㄥ畼鐧昏淇℃伅淇濆瓨鎴愬姛锛�");
                   } else {
@@ -4130,6 +4196,15 @@
         console.log("宸插埌杈炬渶澶у��");
       }
     },
+    // 淇濆瓨闃查噸锛�2 绉掑唴閲嶅鐐瑰嚮瑙嗕负閲嶅鎻愪氦
+    canSave() {
+      const now = Date.now();
+      if (this.saveLockAt && now - this.saveLockAt < 2000) {
+        return false;
+      }
+      this.saveLockAt = now;
+      return true;
+    },
     // 鏇存敼杩涚▼鏁堥獙
     Processvalidation() {
       if (this.form.workflow + 1 == this.actives) {
@@ -4137,15 +4212,12 @@
           this.form.workflow++;
         } else {
         }
-        this.submitForm();
-        // this.GetAttacheddata();
+        // 鐢�"淇濆瓨浜岀骇琛�"瑙﹀彂鐨勪繚瀛橈紝涓嶅弬涓庨槻閲嶏紙鍚﹀垯浼氳 canSave 鎷︽帀锛�
+        this.submitForm(true);
       } else if (this.form.workflow > this.actives) {
-        this.submitForm();
-        // Modifydonationattachment(this.donatelist).then(res => {});
-        // this.GetAttacheddata();
+        this.submitForm(true);
       } else {
-        this.submitForm();
-        // this.$modal.msgWarning("璇峰厛瀹屾垚鍓嶉儴姝ラ");
+        this.submitForm(true);
         return;
       }
     },
@@ -4462,21 +4534,21 @@
 <style lang="scss" scoped>
 .particularsdiv {
   display: flex;
-  background-color: #f5f7fa;
+  background-color: var(--opo-bg-page, #f5f7fa);
   height: 100vh;
   overflow: hidden;
   transition: all 0.3s ease;
 
-  // 宸︿晶宸ヤ綔杩涚▼鏍�
+  // 宸︿晶宸ヤ綔杩涚▼鏍忥紙2026-10-22锛氬幓鎺夊簳鑹诧紝鍙暀涓�鏉″垎闅旂嚎锛涙爣棰樻枃瀛楁敼鍝佺墝闈掞級
   .left-course {
-    background: #fff;
+    background: transparent;
     width: 220px;
     min-width: 220px;
     text-align: center;
     margin: 0;
     padding: 0;
     height: 100%;
-    box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
+    border-right: 1px solid var(--opo-border-base, #e5e7eb);
     transition: all 0.3s ease;
     position: relative;
     z-index: 100;
@@ -4511,10 +4583,10 @@
       flex-direction: column;
 
       .title {
-        background: #22a2c3;
+        background: transparent;
         margin-bottom: 0;
         padding: 15px 10px;
-        color: #fff;
+        color: var(--opo-primary, #0e768f);
         font-size: 16px;
         font-weight: 600;
         display: flex;
@@ -4524,11 +4596,13 @@
         transition: all 0.3s ease;
         min-height: 54px; // 纭繚鏍囬鍖哄煙鏈夊浐瀹氶珮搴�
         box-sizing: border-box;
+        border-bottom: 1px solid var(--opo-border-base, #e5e7eb);
 
         .collapse-btn {
-          background: rgba(255, 255, 255, 0.2);
-          border: none;
-          color: #fff;
+          // 鏍囬搴曡壊鍘绘帀鍚庯紝鎸夐挳鏀逛负娴呴潚鎻忚竟椋庢牸锛岄伩鍏嶇櫧搴曠櫧瀛楃湅涓嶈
+          background: var(--opo-primary-light-9, #e7f1f4);
+          border: 1px solid var(--opo-primary-light-7, #b7d6dd);
+          color: var(--opo-primary, #0e768f);
           width: 32px; // 绋嶅井澧炲ぇ纭繚鍙偣鍑诲尯鍩�
           height: 32px;
           padding: 0;
@@ -4540,7 +4614,8 @@
           flex-shrink: 0; // 闃叉鎸夐挳琚帇缂�
 
           &:hover {
-            background: rgba(255, 255, 255, 0.3);
+            background: var(--opo-primary-light-7, #b7d6dd);
+            border-color: var(--opo-primary, #0e768f);
             transform: scale(1.1);
           }
 
@@ -4608,7 +4683,7 @@
   }
 }
 
-// 姝ラ鏍峰紡浼樺寲
+// 姝ラ鏍峰紡浼樺寲锛堥厤鑹茬粺涓�鍒扮郴缁熷搧鐗岃壊锛歵eal #0E768F锛�
 ::v-deep .el-steps {
   &.el-steps--vertical {
     height: 100%;
@@ -4618,27 +4693,28 @@
 
       .el-step__head {
         &.is-finish {
-          color: #22a2c3;
-          border-color: #22a2c3;
+          color: var(--opo-primary, #0e768f);
+          border-color: var(--opo-primary, #0e768f);
         }
       }
 
       .el-step__title {
-        font-size: 14px;
+        font-size: var(--opo-font-size-sm);
         font-weight: 600;
 
         &.is-finish {
-          color: #22a2c3;
+          color: var(--opo-primary, #0e768f);
         }
       }
 
       .el-step__description {
-        font-size: 12px;
-        color: #666;
+        font-size: var(--opo-font-size-xs);
+        // 鎻忚堪鏂囧瓧缁熶竴鐢ㄤ腑鎬х伆锛岄伩鍏嶆暣鍧楅潰鏉胯鍝佺墝鑹叉饭娌�
+        color: var(--opo-text-secondary, #6b7280);
         line-height: 1.5;
 
         &.is-finish {
-          color: #22a2c3;
+          color: var(--opo-text-regular, #4b5563);
         }
 
         p {
diff --git a/src/views/project/donationwitness/index.vue b/src/views/project/donationwitness/index.vue
index cacd679..828e00f 100644
--- a/src/views/project/donationwitness/index.vue
+++ b/src/views/project/donationwitness/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -467,7 +468,7 @@
               <el-date-picker
                 clearable
                 v-model="form.deathtime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨姝讳骸鏃堕棿"
               >
@@ -492,7 +493,7 @@
               <el-date-picker
                 clearable
                 v-model="form.operationbegtime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鎵嬫湳寮�濮嬫椂闂�"
               >
@@ -504,7 +505,7 @@
               <el-date-picker
                 clearable
                 v-model="form.operationendtime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鎵嬫湳缁撴潫鏃堕棿"
               >
@@ -525,7 +526,7 @@
               <el-date-picker
                 clearable
                 v-model="form.abdominalaortacannulatime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鑵逛富鍔ㄨ剦鎻掔鏃堕棿"
               >
@@ -541,7 +542,7 @@
               <el-date-picker
                 clearable
                 v-model="form.abdominalaortaperfusiontime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鑵逛富鍔ㄨ剦鐏屾敞鏃堕棿"
               >
@@ -563,7 +564,7 @@
               <el-date-picker
                 clearable
                 v-model="form.portalveincannulatime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闂ㄩ潤鑴夎剦鎻掔鏃堕棿"
               >
@@ -579,7 +580,7 @@
               <el-date-picker
                 clearable
                 v-model="form.portalveinperfusiontime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闂ㄩ潤鑴夌亴娉ㄦ椂闂�"
               >
@@ -600,7 +601,7 @@
               <el-date-picker
                 clearable
                 v-model="form.pulmonaryarterycannulatime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闂ㄩ潤鑴夋彃绠℃椂闂�"
               >
@@ -616,7 +617,7 @@
               <el-date-picker
                 clearable
                 v-model="form.pulmonaryarteryperfusiontime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闂ㄩ潤鑴夌亴娉ㄦ椂闂�"
               >
@@ -634,8 +635,8 @@
               <el-date-picker
                 clearable
                 v-model="form.aortacannulatime"
-                type="datetime"
-                value-format="yyyy-MM-dd  HH:mm:ss"
+                type="datetime" format="yyyy-MM-dd HH:mm"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨涓诲姩鑴夌亴娉ㄦ椂闂�"
               >
               </el-date-picker>
@@ -650,8 +651,8 @@
               <el-date-picker
                 clearable
                 v-model="form.aortaperfusiontime"
-                type="datetime"
-                value-format="yyyy-MM-dd  HH:mm:ss"
+                type="datetime" format="yyyy-MM-dd HH:mm"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨涓诲姩鑴夌亴娉ㄦ椂闂�"
               >
               </el-date-picker>
@@ -707,7 +708,7 @@
                   size="small"
                   style="width: 100%"
                   v-model="scope.row.organgettime"
-                  type="datetime"
+                  type="datetime" format="yyyy-MM-dd HH:mm"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鍣ㄥ畼鑾峰彇鏃堕棿"
                 >
diff --git a/src/views/project/donorcharge/donorcharge/index.vue b/src/views/project/donorcharge/donorcharge/index.vue
index a45d009..969d259 100644
--- a/src/views/project/donorcharge/donorcharge/index.vue
+++ b/src/views/project/donorcharge/donorcharge/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
       <el-form-item label="鎹愮尞濮撳悕" prop="name">
         <el-input v-model="queryParams.name" placeholder="璇疯緭鍏ュ鍚�" clearable size="small"
           @keyup.enter.native="handleQuery" />
@@ -152,7 +153,7 @@
             </el-table-column>
             <el-table-column prop="amounttime" align="center" label="鎺ユ敹鏃堕棿" width="120">
               <template slot-scope="scope">
-                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date"
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="鎺ユ敹鏃堕棿">
                 </el-date-picker> </template>
             </el-table-column>
@@ -163,7 +164,7 @@
             </el-table-column>
             <el-table-column prop="amounttime" align="center" label="鏀舵鏃堕棿" width="120">
               <template slot-scope="scope">
-                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date"
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="鏀舵鏃堕棿" @blur="getdays(scope.row)">
                 </el-date-picker> </template>
             </el-table-column>
diff --git a/src/views/project/donorcharge/donorchargedetail/index.vue b/src/views/project/donorcharge/donorchargedetail/index.vue
index 953e979..e4b94c7 100644
--- a/src/views/project/donorcharge/donorchargedetail/index.vue
+++ b/src/views/project/donorcharge/donorchargedetail/index.vue
@@ -179,7 +179,7 @@
                   size="small"
                   style="width: 100%"
                   v-model="scope.row.amounttime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="瀹炴敹鏃堕棿"
                 >
@@ -242,7 +242,7 @@
                   size="small"
                   style="width: 100%"
                   v-model="scope.row.organtime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="绉绘鏃堕棿"
                 >
@@ -294,6 +294,7 @@
 import Li_area_select from "@/components/Address";
 import { getUserProfile } from "@/api/system/user";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyRound } from "@/utils/money";
 import debounce from "lodash/debounce";
 export default {
   components: {
@@ -667,27 +668,23 @@
     submitForm: debounce(function(data) {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          //鏍¢獙銆佽垂鐢ㄥ悎璁�
-          let ChargeSum = 0;
-          let ChargeamountSum = 0;
+          //鏍¢獙銆佽垂鐢ㄥ悎璁★紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛�
           let organname = "";
 
           try {
             for (let i = 0; i < this.donorchargeorgans.length; i++) {
               organname += this.donorchargeorgans[i].organname + ",";
-              if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
-                ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
-              }
-              if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
-                ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
-              }
             }
             this.form.donateorgan = organname.substring(
               0,
               organname.lastIndexOf(",")
             );
-            this.form.chargeamount = ChargeSum.toFixed(2);
-            this.form.chargeamounted = ChargeamountSum.toFixed(2);
+            this.form.chargeamount = moneyRound(
+              moneySum(this.donorchargeorgans, "organcharge")
+            ).toFixed(2);
+            this.form.chargeamounted = moneyRound(
+              moneySum(this.donorchargeorgans, "amount")
+            ).toFixed(2);
           } catch {}
 
           //淇濆瓨
@@ -728,24 +725,16 @@
       });
     }, 500),
 
-    //璁$畻璐圭敤鍚堣
+    //璁$畻璐圭敤鍚堣锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛�
     chargeSum() {
-      let ChargeSum = 0;
-      let ChargeamountSum = 0;
-
       //璐圭敤鍚堣
       try {
-        for (let i = 0; i < this.donorchargeorgans.length; i++) {
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
-            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
-          }
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
-            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
-          }
-        }
-
-        this.form.chargeamount = ChargeSum.toFixed(2);
-        this.form.chargeamounted = ChargeamountSum.toFixed(2);
+        this.form.chargeamount = moneyRound(
+          moneySum(this.donorchargeorgans, "organcharge")
+        ).toFixed(2);
+        this.form.chargeamounted = moneyRound(
+          moneySum(this.donorchargeorgans, "amount")
+        ).toFixed(2);
       } catch {}
     },
 
diff --git a/src/views/project/donorcharge/organcharge/index.vue b/src/views/project/donorcharge/organcharge/index.vue
index e0eabc3..32d8dc2 100644
--- a/src/views/project/donorcharge/organcharge/index.vue
+++ b/src/views/project/donorcharge/organcharge/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鍣ㄥ畼缂栫爜" prop="organcode">
         <el-input
           v-model="queryParams.organcode"
diff --git a/src/views/project/ethicalReview/index.vue b/src/views/project/ethicalReview/index.vue
index 3eb4d3e..ab43674 100644
--- a/src/views/project/ethicalReview/index.vue
+++ b/src/views/project/ethicalReview/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -292,7 +293,7 @@
                 clearable
                 size="small"
                 v-model="form.createTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨缁撹鏃堕棿"
               >
diff --git a/src/views/project/externalperson/index.vue b/src/views/project/externalperson/index.vue
index c818a8a..cbc851f 100644
--- a/src/views/project/externalperson/index.vue
+++ b/src/views/project/externalperson/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
 
       <el-form-item label="璐﹀彿绫诲埆" prop="usertype">
         <el-select v-model="queryParams.usertype" placeholder="璇烽�夋嫨璐﹀彿绫诲埆" clearable size="small">
@@ -47,9 +48,10 @@
 
     <el-table v-loading="loading" :data="externalpersonList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="璐﹀彿绫诲埆" align="center" prop="usertype">
+      <el-table-column label="璐﹀彿绫诲埆" align="center" prop="usertype" width="220">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_UserType" :value="scope.row.usertype" />
+          <dict-tag v-for="t in splitUserType(scope.row.usertype)" :key="t"
+            :options="dict.type.sys_UserType" :value="t" />
         </template>
       </el-table-column>
       <el-table-column label="璐﹀彿缂栧彿" align="center" prop="userno" />
@@ -90,7 +92,7 @@
       <el-form ref="form" :model="form" :rules="rules" label-width="120px">
         <el-row>
           <el-col :span="12"><el-form-item label="璐﹀彿绫诲埆" prop="usertype">
-              <el-select v-model="form.usertype" placeholder="璇烽�夋嫨璐﹀彿绫诲埆">
+              <el-select v-model="form.usertype" multiple collapse-tags placeholder="璇烽�夋嫨璐﹀彿绫诲埆锛堝彲澶氶�夛級">
                 <el-option v-for="dict in dict.type.sys_UserType" :key="dict.value" :label="dict.label"
                   :value="dict.value"></el-option>
               </el-select>
@@ -109,8 +111,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鍚敤鐘舵��" prop="userstatus" :disabled="ismanager == false">
-              <el-radio-group v-model="form.userstatus">
+            <el-form-item label="鍚敤鐘舵��" prop="userstatus" >
+              <el-radio-group v-model="form.userstatus" :disabled="!ismanager">
                 <el-radio v-for="dict in dict.type.sys_0_1" :key="dict.value" :label="parseInt(dict.value)">{{
                   dict.label
                 }}</el-radio>
@@ -118,14 +120,14 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row v-if="form.usertype != 'org'">
+        <el-row v-if="!isUnitForm">
           <el-col :span="24">
             <el-form-item label="韬唤璇佸彿" prop="idcardno">
               <el-input v-model="form.idcardno" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" />
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row v-if="form.usertype != 'org'"><el-col :span="12">
+        <el-row v-if="!isUnitForm"><el-col :span="12">
             <el-form-item label="鎬у埆" prop="sex">
               <el-select v-model="form.sex" placeholder="璇烽�夋嫨鎬у埆">
                 <el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label"
@@ -140,7 +142,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row v-if="form.usertype != 'org'">
+        <el-row v-if="!isUnitForm">
           <el-col :span="12">
             <el-form-item label="鎵�鍦ㄥ崟浣�" prop="unitname">
               <el-select v-model="form.unitno" placeholder="鎵�鍦ㄥ崟浣�" clearable filterable allow-create style="width: 100%">
@@ -253,6 +255,9 @@
         usertype: null
       },
 
+      //鏄惁鏄笓瀹惰垂鐨凮PO瀹℃壒浜哄憳
+      ismanager: false,
+      
       // 鏌ヨ鏈�鏂板簭鍙峰弬鏁�
       seqnoParams: {
         businessType: "externalperson",
@@ -269,7 +274,19 @@
           { required: true, message: "璇疯緭鍏ヨ处鎴峰悕绉�", trigger: "blur" }
         ],
         idcardno: [
-          { required: true, message: "璇疯緭鍏ヨ韩浠借瘉鍙风爜", trigger: "blur" }
+          {
+            //璐﹀彿绫诲埆涓�"鍗曚綅鏈烘瀯"鏃舵棤闇�韬唤璇佸彿
+            validator: (rule, value, callback) => {
+              if (this.hasUserType(this.form.usertype, "org")) {
+                return callback();
+              }
+              if (!value || !String(value).trim()) {
+                return callback(new Error("璇疯緭鍏ヨ韩浠借瘉鍙风爜"));
+              }
+              return callback();
+            },
+            trigger: "blur"
+          }
         ],
         bankcardno: [
           { required: true, message: "璇疯緭鍏ラ摱琛岃处鍙�", trigger: "blur" }
@@ -277,10 +294,14 @@
         depositbank: [
           { required: true, message: "璇疯緭鍏ュ紑鎴烽摱琛�", trigger: "blur" }
         ]
-      },
-      //鏄惁鏄笓瀹惰垂鐨凮PO瀹℃壒浜哄憳
-      ismanager: false
+      },      
     };
+  },
+  computed: {
+    /** 琛ㄥ崟鏄惁閫夋嫨浜�"鍗曚綅鏈烘瀯"锛堣处鍙风被鍒负澶氬�硷紝鍚� org 鍗充负鍗曚綅锛� */
+    isUnitForm() {
+      return this.hasUserType(this.form.usertype, "org");
+    }
   },
   created() {
     this.getUserProfile();
@@ -291,17 +312,32 @@
   methods: {
     //鑾峰彇褰撳墠鐢ㄦ埛淇℃伅
     getUserProfile() {
-      getUserProfile().then(res => {
-        if (
-          res.data.userName == "admin" ||
-          res.data.userName == "053" ||
-          res.data.userName == "047"
-        ) {
-          this.ismanager = true;
-        } else {
-          this.ismanager = false;
-        }
+      getUserProfile().then(res => {        
+        const managerList = ["admin", "048", "047"];
+        this.ismanager = managerList.includes(res.data.userName);
       });
+    },
+
+    /** 浜哄憳绫诲瀷锛堝鍊硷紝閫楀彿鍒嗛殧锛夎浆鏁扮粍 */
+    splitUserType(usertype) {
+      if (!usertype) {
+        return [];
+      }
+      if (Array.isArray(usertype)) {
+        return usertype;
+      }
+      return String(usertype)
+        .split(",")
+        .map(t => t.trim())
+        .filter(t => t);
+    },
+    /** 浜哄憳绫诲瀷鏁扮粍杞�楀彿鍒嗛殧瀛楃涓� */
+    joinUserType(usertype) {
+      return Array.isArray(usertype) ? usertype.join(",") : usertype;
+    },
+    /** 浜哄憳绫诲瀷鏄惁鍖呭惈鎸囧畾绫诲瀷锛堝 org = 鍗曚綅鏈烘瀯锛� */
+    hasUserType(usertype, code) {
+      return this.splitUserType(usertype).indexOf(code) > -1;
     },
 
     /** 鏌ヨ鍗曚綅銆佷汉鍛樿处鍙峰垪琛� */
@@ -337,7 +373,7 @@
         userno: null,
         username: null,
         userstatus: 0,
-        usertype: null,
+        usertype: [],
         personnelunitno: null,
         delFlag: null,
         createBy: null,
@@ -389,6 +425,8 @@
       const id = row.id || this.ids;
       getExternalperson(id).then(response => {
         this.form = response.data;
+        //璐﹀彿绫诲埆涓哄鍊硷紙閫楀彿鍒嗛殧锛夛紝琛ㄥ崟鐢ㄦ暟缁勫洖鏄�
+        this.form.usertype = this.splitUserType(response.data.usertype);
         this.open = true;
         this.title = "浜哄憳/鍗曚綅璐﹀彿淇℃伅淇敼";
       });
@@ -402,6 +440,8 @@
             if (res.organizationid == this.form.unitno)
               this.form.unitname = res.organizationname;
           });
+          //璐﹀彿绫诲埆涓哄鍊硷細鎻愪氦鍓嶈浆鍥為�楀彿鍒嗛殧鐨勫瓧绗︿覆
+          this.form.usertype = this.joinUserType(this.form.usertype);
           console.log(this.form);
           if (this.form.id != null) {
             updateExternalperson(this.form).then(response => {
@@ -411,15 +451,8 @@
               this.getList();
             });
           } else {
-            //妫�鏌ヨ韩浠借瘉鍞竴
-            getInfoByIDCardNo(this.form.idcardno).then(res => {
-              if (res.data.length > 1) {
-                this.$modal.msgWarning("韬唤璇佸彿淇℃伅宸茶鐧昏锛岃妫�鏌ヨ韩浠借瘉鍙凤紒"
-                );
-                return;
-              }
-
-              //淇濆瓨淇℃伅
+            //淇濆瓨淇℃伅锛堝崟浣嶈处鍙锋病鏈夎韩浠借瘉鍙凤紝璺宠繃韬唤璇佹煡閲嶏級
+            const saveNew = () => {
               getOnlyCode(this.seqnoParams).then(res => {
                 this.form.userno = res.data.currentvalue;
 
@@ -430,7 +463,21 @@
                   this.getList();
                 });
               });
+            };
 
+            if (!this.form.idcardno || !String(this.form.idcardno).trim()) {
+              saveNew();
+              return;
+            }
+
+            //妫�鏌ヨ韩浠借瘉鍞竴
+            getInfoByIDCardNo(this.form.idcardno).then(res => {
+              if (res.data.length > 1) {
+                this.$modal.msgWarning("韬唤璇佸彿淇℃伅宸茶鐧昏锛岃妫�鏌ヨ韩浠借瘉鍙凤紒"
+                );
+                return;
+              }
+              saveNew();
             });
           }
         }
diff --git a/src/views/project/financesubject/index.vue b/src/views/project/financesubject/index.vue
index 210c95c..026c0bc 100644
--- a/src/views/project/financesubject/index.vue
+++ b/src/views/project/financesubject/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="椤圭洰绫诲瀷" prop="itemtype">
         <el-select v-model="queryParams.itemtype" placeholder="璇烽�夋嫨椤圭洰绫诲瀷" clearable size="small">
           <el-option v-for="dict in dict.type.sys_ConsolationType" :key="dict.value" :label="dict.label"
diff --git a/src/views/project/fund/applyDetail/index.vue b/src/views/project/fund/applyDetail/index.vue
index 60c5e5c..b4b6494 100644
--- a/src/views/project/fund/applyDetail/index.vue
+++ b/src/views/project/fund/applyDetail/index.vue
@@ -12,7 +12,7 @@
           </el-col>
           <el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-              <el-date-picker clearable :disabled="true" style="width: 100%" v-model="form.applyTime" type="date"
+              <el-date-picker clearable :disabled="true" style="width: 100%" v-model="form.applyTime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鏃�   鏈�">
               </el-date-picker>
             </el-form-item>
@@ -68,15 +68,7 @@
             <el-form-item label="鎹愮尞妗堜緥" prop="name">
               <el-input :disabled="true" v-model="form.donorname" placeholder="璇疯緭鍏ユ崘鐚�呭鍚�" />
             </el-form-item>
-          </el-col>
-          <el-col :span="4">
-            <div style="margin-left: 10px;">
-              <dict-tag
-                :options="dict.type.sys_DonationStatus"
-                :value="form.invoicecount"
-              />
-            </div>
-          </el-col>
+          </el-col>          
           <el-col :span="10">
             <el-form-item label="鐢宠璇存槑" prop="remark">
               <el-input v-model="form.remark" placeholder="鐢宠璇存槑" />
@@ -229,8 +221,9 @@
               v-if="businessType == '1' || businessType == '2'">
               <template slot-scope="scope">
                 <el-form-item label-width="0">
-                  <el-input :disabled="userprofile.nickName != '闄堟厱鍗�'" v-model.number="scope.row.idcardno"
-                    @input="tableParValueChange1(scope.row)" placeholder="韬唤璇佸彿" />
+                  <el-input :disabled="userprofile.nickName != '闄堟厱鍗�' || scope.row.isunit == 1"
+                    :placeholder="scope.row.isunit == 1 ? '鍗曚綅鏃犻渶濉啓' : '韬唤璇佸彿'"
+                    v-model.number="scope.row.idcardno" @input="tableParValueChange1(scope.row)" />
                 </el-form-item>
               </template>
             </el-table-column>
@@ -690,13 +683,19 @@
     </el-dialog>
 
     <!-- 鎵归噺閫夊彇 -->
-    <el-dialog title="鎵归噺鐢熸垚鏄庣粏淇℃伅" :visible.sync="batchdialogVisible" width="30%">
+    <el-dialog title="鎵归噺鐢熸垚鏄庣粏淇℃伅" :visible.sync="batchdialogVisible" width="35%">
+      <div style="margin-bottom: 12px">
+        <el-input v-model="personKeyword" clearable size="small" prefix-icon="el-icon-search"
+          placeholder="杈撳叆 濮撳悕 / 鍗曚綅 / 宸ュ彿 / 韬唤璇佸悗4浣� 绛涙煡" style="width: 330px" />
+        <span style="margin-left: 10px; color: #909399; font-size: 12px">鍏� {{ filteredCityOptions.length }} 浜�</span>
+      </div>
       <div style="max-height: 300px; overflow-y: auto">
-        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">鍏ㄩ��</el-checkbox>
+        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">鍏ㄩ�夛紙褰撳墠绛涙煡缁撴灉锛�</el-checkbox>
         <div style="margin: 15px 0;"></div>
         <el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
-          <el-checkbox border v-for="city in cityOptions" :label="city" :key="city.reportNo">{{ city.reportName
-          }}</el-checkbox>
+          <el-checkbox border v-for="city in filteredCityOptions" :label="city"
+            :key="city.reportNo + '_' + city.reportName">{{ city.reportName
+            }}{{ city.unitname ? " 路 " + city.unitname : "" }}</el-checkbox>
         </el-checkbox-group>
       </div>
 
@@ -736,6 +735,7 @@
   addorupdateFund,
   ManualCalculation,
   getdetailsByItemId,
+  validateExpertFee,
   listbypower
 } from "@/api/project/fund";
 
@@ -786,6 +786,8 @@
 import Li_area_select from "@/components/Address";
 import OrgSelecter from "@/views/project/components/orgselect";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyMul, moneySub, moneyRound } from "@/utils/money";
+import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
 import CustomImageViewer from "@/components/CustomImageViewer"; // 鏍规嵁浣犵殑璺緞璋冩暣
 
 export default {
@@ -822,9 +824,10 @@
         return callback();
       }
       const regex = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}([0-9]|X)$/;
-      if (regex.test(value)) {
-      } else {
-        callback(new Error("韬唤璇佸彿鐮佹牸寮忛敊璇�"));
+      // 2026-10-19锛氭牸寮忎笉鍚堟硶绔嬪嵆鏃╅��銆傚師鏉ュ啓鎴� if/else 浣� else 閲屾病鏈� return锛�
+      // 浼氱户缁線涓嬭蛋寮傛鏌ラ噸锛屽鑷� callback 琚皟鐢ㄤ袱娆°��"韬唤璇佸彿鐮佹牸寮忛敊璇�"琚悗缁粨鏋滆鐩栥��
+      if (!regex.test(value)) {
+        return callback(new Error("韬唤璇佸彿鐮佹牸寮忛敊璇�"));
       }
 
       // 2. 璋冪敤鍚庣鎺ュ彛杩涜閲嶅鎬ф牎楠�
@@ -881,6 +884,8 @@
       // 缃戠粶璇锋眰澶�
       Networkheader: null,
       batchdialogVisible: false,
+      //鎵归噺褰曞叆寮规鐨勭瓫鏌ュ叧閿瓧
+      personKeyword: "",
       itemlist: [],
       cityOptions: [],
       checkAll: false,
@@ -955,6 +960,10 @@
       },
 
       dialogrules: {
+        // 2026-10-19锛氳处鎴峰悕绉帮紙璐︽埛鏉ユ簮=浠庤处鎴峰簱 鏃剁殑涓嬫媺锛変篃鏄繀杈撻」
+        accountname: [
+          { required: true, message: "璇烽�夋嫨璐︽埛鍚嶇О", trigger: "change" }
+        ],
         usertype: [
           { required: true, message: "璇疯緭鍏ヨ处鎴风被鍨�", trigger: "blur" }
         ],
@@ -963,7 +972,23 @@
         ],
         unitTaxNo: [{ required: true, message: "璇疯緭鍏ョ◣鍙�", trigger: "blur" }],
         idcardno: [
-          { required: true, message: '璇疯緭鍏ヨ韩浠借瘉鍙�', trigger: 'blur' },
+          {
+            // 2026-10-19锛氬姞 required 鏍囪鍙负璁� el-form-item 鏍囧嚭蹇呰緭鏄熷彿锛圗lement 鐨� isRequired 鍙 rule.required锛夈��
+            // 鏈鍒欏甫 validator锛宎sync-validator 鐨� getValidationMethod 浼氱洿鎺ヨ繑鍥炶 validator銆佽烦杩囧唴寤� required 妫�鏌ワ紝
+            // 鎵�浠ユ牎楠岃涓轰笌鏀瑰姩鍓嶅畬鍏ㄤ竴鑷达紱鍙﹀**涓嶈兘鍔� message**锛屽惁鍒欎細瑕嗙洊涓嬮潰鑷畾涔� validator 鐨勬姤閿欐枃妗堛��
+            required: true,
+            // 璐︽埛绫诲瀷閫夋嫨"鍗曚綅鏈烘瀯"鏃朵笉闇�瑕佽韩浠借瘉鍙�
+            validator: (rule, value, callback) => {
+              if (this.hasUserType(this.accountselectform.usertype, "org")) {
+                return callback();
+              }
+              if (!value || !String(value).trim()) {
+                return callback(new Error("璇疯緭鍏ヨ韩浠借瘉鍙�"));
+              }
+              return callback();
+            },
+            trigger: "blur"
+          },
           // 娣诲姞鑷畾涔夋牎楠岃鍒�
           { validator: validateIdCard, trigger: 'blur' }
         ],
@@ -1125,7 +1150,16 @@
   },
 
   //鐩戝惉灞炴�� 绫讳技浜巇ata姒傚康
-  computed: {},
+  computed: {
+    //鎵归噺褰曞叆寮规锛氭寜鍏抽敭瀛楋紙濮撳悕/鍗曚綅/宸ュ彿/韬唤璇佸悗4浣嶏級绛涙煡鍚庣殑鍊欓�変汉
+    filteredCityOptions() {
+      const kw = (this.personKeyword || "").trim().toLowerCase();
+      if (!kw) {
+        return this.cityOptions;
+      }
+      return this.cityOptions.filter(item => this.personMatchKeyword(item, kw));
+    }
+  },
   //鐩戞帶data涓殑鏁版嵁鍙樺寲
   watch: {},
   //鏂规硶闆嗗悎
@@ -1529,6 +1563,11 @@
     },
     /** 鎻愪氦鎸夐挳 */
     submitForm: debounce(function () {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -1537,6 +1576,31 @@
       this.$refs["form"].validate(valid => {
         if (valid) {
           this.formData = this.form;
+
+          // 涓撳鍔冲姟璐逛笓鐢細9 鏉¤垂鐢ㄦ帶鍒惰鍒欐牎楠岋紙鏍¢獙涓嶉�氳繃涓嶅厑璁镐繚瀛橈級
+          if (this.businessType == "1") {
+            this.$modal.loading("姝e湪鏍¢獙涓撳鍔冲姟璐圭敤锛岃绋嶅�欙紒");
+            this.checkExpertFeeRules("淇濆瓨").then((allowed) => {
+              this.$modal.closeLoading();
+              if (allowed) {
+                this.doSubmitForm();
+              }
+            });
+            return;
+          }
+
+          this.doSubmitForm();
+        }
+      });
+    }, 500),
+
+    /**
+     * 淇濆瓨鐢宠鍗曠殑瀹為檯钀藉簱閫昏緫銆�
+     *
+     * 浠� submitForm 涓媶鍑猴紝渚夸簬鍦ㄤ笓瀹跺姵鍔¤垂瑙勫垯鏍¢獙閫氳繃鍚庡啀鎵ц锛�
+     * 鍏朵粬涓氬姟绫诲瀷鐢� submitForm 鐩存帴璋冪敤锛岃涓轰笌鎷嗗垎鍓嶄竴鑷淬��
+     */
+    doSubmitForm() {
 
           //淇濆瓨鍓嶆牎楠屾暟鎹�
           for (let k = 0; k < this.rbDetails.length; k++) {
@@ -1607,7 +1671,7 @@
               let tempDetail = this.rbDetails[j];
               if (
                 isNaN(parseFloat(tempDetail.amount)) ||
-                parseFloat(tempDetail.amount) == 0
+                moneyRound(tempDetail.amount) == 0
               ) {
                 this.$modal.msgWarning(
                   "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
@@ -1622,7 +1686,7 @@
               let tempDetail = this.rbDetails[j];
               if (
                 isNaN(parseFloat(tempDetail.amount)) ||
-                parseFloat(tempDetail.amount) == 0
+                moneyRound(tempDetail.amount) == 0
               ) {
                 this.$modal.msgWarning(
                   "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
@@ -1633,7 +1697,7 @@
               }
               if (
                 isNaN(parseFloat(tempDetail.taxamount)) ||
-                parseFloat(tempDetail.taxamount) == 0
+                moneyRound(tempDetail.taxamount) == 0
               ) {
                 tempDetail.taxedamount = parseFloat(tempDetail.amount);
               } else {
@@ -1735,9 +1799,84 @@
           //鍏抽棴绐楀彛
           this.loading = false;
           // this.getfundList();
-        }
+    },
+
+    /**
+     * 涓撳鍔冲姟璐� 9 鏉¤垂鐢ㄦ帶鍒惰鍒欐牎楠岋紙鎻愪氦鍓嶆嫤鎴級銆�
+     *
+     * 閫傜敤鑼冨洿锛歜usinessType === '1'锛堜笓瀹跺姵鍔¤垂鐢宠鍗曪級锛屼笌鍚庣 applytype === '1' 瀵瑰簲銆�
+     * 鍏朵粬涓氬姟绫诲瀷锛堜鸡鐞嗕笓瀹惰垂銆佸尰瀛︽垚鏈�佸姙鍏垂鐢級涓嶆牎楠岋紝鐩存帴鏀捐銆�
+     *
+     * 鏍¢獙鍙e緞锛堝悓涓�鎹愮尞妗堜緥 infoid 涓嬬疮璁★級鐢卞悗绔粺涓�瀹炵幇锛�
+     *   errors   闃绘柇鍨嬶細鎻愮ず杩濆弽鐨勫叿浣撹鍒欙紝涓嶅厑璁哥户缁繚瀛�/瀹℃牳
+     *   warnings 鎻愮ず鍨嬶細浠呮彁閱掔粡鍔炰汉澶勭悊锛堣鍒� 5銆�6锛夛紝闇�浜屾纭鍚庢墠缁х画
+     *
+     * @param {string} action 褰撳墠鍔ㄤ綔锛岀敤浜庢嫾鎺ユ彁绀烘枃妗堬紙濡傗�滀繚瀛樷�濃�滄彁浜ゅ鏍糕�濓級
+     * @returns {Promise<boolean>} true 鍏佽缁х画锛宖alse 闃绘缁х画
+     */
+    checkExpertFeeRules(action) {
+      if (this.businessType != "1") {
+        return Promise.resolve(true);
+      }
+      // 鍚庣鎸夈�屾渚嬪唴宸叉湁鍗曟嵁 + 鏈鎻愪氦鏄庣粏銆嶅悎骞惰绠楋紝纭繚灏氭湭钀藉簱鐨勬槑缁嗕篃鍙備笌鏍¢獙
+      const payload = Object.assign({}, this.form, {
+        applytype: this.form.applytype || "1",
+        serviceFunddetails: this.rbDetails,
       });
-    }, 500),
+      // 鎺掓煡鐢細鑳界洿鎺ヤ粠鎺у埗鍙扮湅鍒板埌搴曢�佷簡浠�涔堬紝浠ュ強鍚庣鍒ゅ畾浜嗕粈涔�
+      console.log("[涓撳璐规牎楠宂 鎻愪氦鏍¢獙", action, {
+        businessType: this.businessType,
+        applytype: payload.applytype,
+        infoid: payload.infoid,
+        fundId: payload.id,
+        鏄庣粏: (this.rbDetails || []).map((d) => ({
+          itemid: d.itemid,
+          amount: d.amount,
+          taxedamount: d.taxedamount,
+          鍦烘櫙: d.servicesscopename,
+        })),
+      });
+         
+      return validateExpertFee(payload)
+        .then((res) => {
+          const errors = (res && res.errors) || [];
+          const warnings = (res && res.warnings) || [];
+          console.log("[涓撳璐规牎楠宂 鍚庣杩斿洖", { errors, warnings });
+
+          // 1) 闃绘柇鍨嬶細鍒楀嚭杩濆弽鐨勫叿浣撹鍒欙紝涓嶅厑璁哥户缁�
+          //    鐢ㄥ脊绐楄�岄潪杞绘彁绀猴細閿欒鍙兘鏈夊鏉★紝杞绘彁绀轰細鎸ゆ垚涓�琛屼笖寰堝揩娑堝け
+          if (errors.length > 0) {
+            this.$modal.alertError(
+              "涓撳鍔冲姟璐圭敤涓嶇鍚堜互涓嬭瀹氾紝鏃犳硶" +
+                action +
+                "锛歕n\n" +
+                errors.map((msg, i) => i + 1 + ". " + msg).join("\n\n")
+            );
+            return false;
+          }
+
+          // 2) 鎻愮ず鍨嬶細闇�缁忓姙浜虹‘璁ゅ悗鎵嶈兘缁х画锛堝綋鍓嶈鍒� 5銆�6 宸叉敼涓虹‖鎷︽埅锛屾鍒嗘敮淇濈暀澶囩敤锛�
+          if (warnings.length > 0) {
+            const confirmText =
+              "涓撳鍔冲姟璐圭敤瀛樺湪浠ヤ笅闂锛岃纭鏄惁缁х画" +
+              action +
+              "锛焅n\n" +
+              warnings.map((msg, i) => i + 1 + ". " + msg).join("\n\n");
+            return this.$modal
+              .confirm(confirmText)
+              .then(() => true)
+              .catch(() => false);
+          }
+
+          return true;
+        })
+        .catch((err) => {
+          // 鎺ュ彛寮傚父鏃舵寜鈥滀笉闃绘柇鈥濆鐞嗭紝閬垮厤鏍¢獙鏈嶅姟涓嶅彲鐢ㄥ鑷村畬鍏ㄦ棤娉曟姤閿�锛�
+          // 鍚庣 addOrUpdateNew / checkFund 浠嶆湁鍚屾牱鐨勭‖鎷︽埅鍏滃簳銆�
+          console.error("涓撳鍔冲姟璐硅鍒欐牎楠屾帴鍙h皟鐢ㄥけ璐�", err);
+          return true;
+        });
+    },
 
     checksubmit() {
       //妫�鏌ユ槸鍚︽敹鍒扮焊璐ㄦ潗鏂�
@@ -1769,8 +1908,19 @@
         return;
       }
 
-      this.Savenow();
-      console.log("淇濆瓨骞跺鎵�");
+      // 涓撳鍔冲姟璐逛笓鐢細9 鏉¤垂鐢ㄦ帶鍒惰鍒欐牎楠岋紙浠呭鏍搁�氳繃鏃舵嫤鎴級
+      const needExpertFeeCheck = this.checkObj.flowlevelone == 1;
+      const expertFeePromise = needExpertFeeCheck
+        ? this.checkExpertFeeRules("鎻愪氦瀹℃牳")
+        : Promise.resolve(true);
+
+      expertFeePromise.then((allowed) => {
+        if (!allowed) {
+          return;
+        }
+        this.Savenow();
+        console.log("淇濆瓨骞跺鎵�");
+      });
     },
 
     // 杩炵画瀹℃壒锛氳幏鍙栧綋鍓嶄笟鍔$被鍨嬩笅鐨勫緟瀹℃壒鍒楄〃
@@ -1879,6 +2029,19 @@
       });
     },
 
+    /** 浜哄憳绫诲瀷锛堝鍊硷紝閫楀彿鍒嗛殧锛夋槸鍚﹀寘鍚寚瀹氱被鍨嬶紱org = 鍗曚綅鏈烘瀯 */
+    hasUserType(usertype, code) {
+      if (!usertype) {
+        return false;
+      }
+      return (
+        String(usertype)
+          .split(",")
+          .map(t => t.trim())
+          .indexOf(code) > -1
+      );
+    },
+    /** 鍙楃泭浜�/璐︽埛鏄惁涓�"鍗曚綅"锛堜汉鍛樼被鍨嬪惈 org锛� */
     //鑾峰彇涓撳銆佸崟浣嶆満鏋勭殑璐︽埛鍒楄〃
     getAccountList() {
       listExternalperson().then(res => {
@@ -1887,7 +2050,7 @@
         for (let j = 0; j < res.rows.length; j++) {
           //鍗曚綅璐﹀彿鍒楄〃
           if (res.rows[j].userstatus == "1") {
-            if (res.rows[j].usertype == "org") {
+            if (this.hasUserType(res.rows[j].usertype, "org")) {
               this.accountlist.push({
                 id: res.rows[j].id,
                 userno: res.rows[j].userno,
@@ -1898,6 +2061,7 @@
                 bankcardno: res.rows[j].bankcardno,
                 unitno: res.rows[j].unitno,
                 unitname: res.rows[j].unitname,
+                usertype: res.rows[j].usertype,
                 userid:
                   res.rows[j].username + "锛�" + res.rows[j].bankcardno + "锛�"
               });
@@ -1912,6 +2076,7 @@
                 bankcardno: res.rows[j].bankcardno,
                 unitno: res.rows[j].unitno,
                 unitname: res.rows[j].unitname,
+                usertype: res.rows[j].usertype,
                 userid:
                   res.rows[j].username + "锛�" + res.rows[j].idcardno + "锛�"
               });
@@ -2105,14 +2270,13 @@
 
     //璁$畻涓◣锛歵ype(A:宸茬煡绋庡墠閲戦锛岃绠楃◣鍚庨噾棰濓紱B锛氬凡鐭ョ◣鍚庨噾棰濓紝璁$畻绋庡墠閲戦)
     calculateTax(row, type) {
-      let targetValue = 0;
       for (let i = 0; i < this.rbDetails.length; i++) {
         if (!this.rbDetails[i].amount) {
           this.rbDetails[i].amount = 0;
         }
-        targetValue += parseFloat(this.rbDetails[i].amount); // 鍋囪姣忎釜瀵硅薄涓殑鐗瑰畾鍊煎瓨鍌ㄥ湪'specificValue'灞炴�т笅
       }
-      this.form.pretaxcost = targetValue;
+      // 鍚堣閲戦蹇呴』绮剧‘绱姞锛屽惁鍒欎細鍐欏叆 form.pretaxcost 骞惰惤搴�
+      this.form.pretaxcost = moneySum(this.rbDetails, "amount");
     },
 
     //瀵煎叆鎵�鏈夐」鐩�
@@ -2186,6 +2350,11 @@
     },
     // 鎺ュ彈鎻愰啋绔嬪埢淇濆瓨
     Savenow() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -2193,192 +2362,198 @@
       this.Savereminder = false;
       this.Reminderquantity = 0;
       this.totalquantity = 0;
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          this.formData = this.form;
 
-          //淇濆瓨鍓嶆牎楠屾暟鎹�
-          for (let k = 0; k < this.rbDetails.length; k++) {
-            let tempDetail = this.rbDetails[k];
-            if (tempDetail.itemid == null) {
-              this.$modal.msgWarning(
-                "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                (k + 1).toString() +
-                "琛岀殑鏈嶅姟椤圭洰鏈�夋嫨锛岃鍏堥�夋嫨鏈嶅姟椤圭洰鍚庡啀鎻愪氦淇濆瓨锛�"
-              );
-              return;
-            }
-
-            if (this.businessType == "1") {
-              if (tempDetail.servicesscope == null) {
-                this.$modal.msgWarning(
-                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                  (k + 1).toString() +
-                  "琛岀殑璐圭敤璇存槑鏈�夋嫨,璇烽�夋嫨璐圭敤璇存槑鍚庡啀鎻愪氦淇濆瓨锛�"
-                );
-                return;
-              }
-
-              if (tempDetail.beneficiaryno == null) {
-                this.$modal.msgWarning(
-                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                  (k + 1).toString() +
-                  "琛岀殑浜哄憳濮撳悕涓虹┖,璇烽�夋嫨浜哄憳鍚庡啀鎻愪氦淇濆瓨锛�"
-                );
-                return;
-              }
-              if (tempDetail.unitname == null) {
-                this.$modal.msgWarning(
-                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                  (k + 1).toString() +
-                  "琛岀殑涓撳鍗曚綅涓虹┖,璇烽�夋嫨鍗曚綅鍚庡啀鎻愪氦淇濆瓨锛�"
-                );
-                return;
-              }
-            }
-          }
-
-          //澶勭悊鏄庣粏
-          for (let i = 0; i < this.rbDetails.length; i++) {
-            let tempDetail = this.rbDetails[i];
-            //鑾峰彇鏈嶅姟椤圭洰鏄庣粏
-            let tempitemlist = tempDetail.itemlist;
-            let itemIndex = tempitemlist.findIndex(
-              item => tempDetail.itemid == item.id
-            );
-            if (itemIndex > -1) {
-              tempDetail.itemname = tempitemlist[itemIndex].itemName;
-              tempDetail.itemid = tempitemlist[itemIndex].id;
-            }
-
-            //鑾峰彇applytypename銆佹湇鍔¤垂鐢ㄥぇ绫�
-            let applytypeIndex = this.rowfeeItemTypes.findIndex(
-              item => tempDetail.applytype == item.value
-            );
-            if (applytypeIndex > -1) {
-              tempDetail.applytypename = this.rowfeeItemTypes[
-                applytypeIndex
-              ].label;
-              tempDetail.subjecttype = this.rowfeeItemTypes[
-                applytypeIndex
-              ].subjecttype;
-              tempDetail.subjecttypename = this.rowfeeItemTypes[
-                applytypeIndex
-              ].subjecttypename;
-            }
-            this.rbDetails[i] = tempDetail;
-          }
-          //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣锛岀◣鍓嶉噾棰濓紙amount锛夈�佹墸绋庨噾棰濓紙taxamount锛夈�佺◣鍚庨噾棰濓紙taxedamount锛�
-          if (this.businessType == "2") {
-            for (let j = 0; j < this.rbDetails.length; j++) {
-              let tempDetail = this.rbDetails[j];
-              if (
-                isNaN(parseFloat(tempDetail.amount)) ||
-                parseFloat(tempDetail.amount) == 0
-              ) {
-                this.$modal.msgWarning(
-                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                  (j + 1).toString() +
-                  "琛岀殑閲戦鏈緭鍏ワ紝璇峰厛杈撳叆閲戦鍚庡啀鎻愪氦淇濆瓨锛�"
-                );
-                return;
-              }
-            }
-          } else if (this.businessType == "3" || this.businessType == "4") {
-            for (let j = 0; j < this.rbDetails.length; j++) {
-              let tempDetail = this.rbDetails[j];
-              if (
-                isNaN(parseFloat(tempDetail.amount)) ||
-                parseFloat(tempDetail.amount) == 0
-              ) {
-                this.$modal.msgWarning(
-                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
-                  (j + 1).toString() +
-                  "琛岀殑閲戦鏈緭鍏ワ紝璇峰厛杈撳叆閲戦鍚庡啀鎻愪氦淇濆瓨锛�"
-                );
-                return;
-              }
-              if (
-                isNaN(parseFloat(tempDetail.taxamount)) ||
-                parseFloat(tempDetail.taxamount) == 0
-              ) {
-                tempDetail.taxedamount = parseFloat(tempDetail.amount);
-              } else {
-                tempDetail.taxedamount =
-                  parseFloat(tempDetail.amount) +
-                  parseFloat(tempDetail.taxamount);
-              }
-            }
-          }
-
-          //淇濆瓨鏁版嵁
-          this.loading = true;
-          this.form.serviceFunddetails = 0;
-          this.rbDetails.map(item => {
-            this.form.serviceFunddetails += item.amount;
-          });
-          this.form.serviceFunddetails = this.rbDetails;
-
-          if (this.form.id != null) {
-          } else {
-            this.form.recordstatus = -1;
-          }
-
-          addorupdateFund(this.form).then(response => {
-            if (response.code === 200) {
-              this.$modal.msgSuccess("鐢宠鍗曚繚瀛樻垚鍔燂紒");
-              // 闈炴彁閱掔姸鎬佷笅鎵ц瀹℃壒瑙e喅寮傛璋冪敤寤惰繜闂
-              if (!this.Savereminder) {
-                let checkFundObj = {
-                  // fundid: this.checkObj.fundid,
-                  fundid: this.curId,
-                  flowconclusion: this.checkObj.flowlevelone,
-                  flowcontent: this.checkObj.flowconclusion
-                };
-                this.$modal.loading("姝e湪鎻愪氦瀹℃牳锛岃绋嶅�欙紒");
-                checkfund(checkFundObj).then(res => {
-                  if (res.code == 200) {
-                    //鍏抽棴绐楀彛
-                    this.$modal.closeLoading();
-                    this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
-                    // 杩炵画瀹℃壒锛氳闂槸鍚︾户缁鎵逛笅涓�鍗�
-                    this.continueOrExit();
-                  } else {
-                    this.$modal.closeLoading();
-
-                    if (res.msg) {
-                      this.$modal.msgError("鎿嶄綔澶辫");
-                    } else {
-                      this.$modal.msgError(res.msg);
-                    }
-                  }
-                });
-              }
-              this.Getnetworkheader();
-              this.getroute();
-              this.getAccountList();
-              this.getUserList();
-              this.getUserProfile();
-            } else {
-              this.$modal.msgError("鐢宠鍗曚繚瀛樺け璐ワ細" + response.msg);
-            }
-          });
-
-          //鍏抽棴绐楀彛
-          this.loading = false;
-          // this.getfundList();
+      // 涓撳鍔冲姟璐逛笓鐢細9 鏉¤垂鐢ㄦ帶鍒惰鍒欐牎楠岋紙鏍¢獙涓嶉�氳繃涓嶅厑璁歌惤搴擄級
+      this.checkExpertFeeRules("淇濆瓨").then((allowed) => {
+        if (!allowed) {
+          return;
         }
+
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            this.formData = this.form;
+
+            //淇濆瓨鍓嶆牎楠屾暟鎹�
+            for (let k = 0; k < this.rbDetails.length; k++) {
+              let tempDetail = this.rbDetails[k];
+              if (tempDetail.itemid == null) {
+                this.$modal.msgWarning(
+                  "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                  (k + 1).toString() +
+                  "琛岀殑鏈嶅姟椤圭洰鏈�夋嫨锛岃鍏堥�夋嫨鏈嶅姟椤圭洰鍚庡啀鎻愪氦淇濆瓨锛�"
+                );
+                return;
+              }
+
+              if (this.businessType == "1") {
+                if (tempDetail.servicesscope == null) {
+                  this.$modal.msgWarning(
+                    "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                    (k + 1).toString() +
+                    "琛岀殑璐圭敤璇存槑鏈�夋嫨,璇烽�夋嫨璐圭敤璇存槑鍚庡啀鎻愪氦淇濆瓨锛�"
+                  );
+                  return;
+                }
+
+                if (tempDetail.beneficiaryno == null) {
+                  this.$modal.msgWarning(
+                    "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                    (k + 1).toString() +
+                    "琛岀殑浜哄憳濮撳悕涓虹┖,璇烽�夋嫨浜哄憳鍚庡啀鎻愪氦淇濆瓨锛�"
+                  );
+                  return;
+                }
+                if (tempDetail.unitname == null) {
+                  this.$modal.msgWarning(
+                    "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                    (k + 1).toString() +
+                    "琛岀殑涓撳鍗曚綅涓虹┖,璇烽�夋嫨鍗曚綅鍚庡啀鎻愪氦淇濆瓨锛�"
+                  );
+                  return;
+                }
+              }
+            }
+
+            //澶勭悊鏄庣粏
+            for (let i = 0; i < this.rbDetails.length; i++) {
+              let tempDetail = this.rbDetails[i];
+              //鑾峰彇鏈嶅姟椤圭洰鏄庣粏
+              let tempitemlist = tempDetail.itemlist;
+              let itemIndex = tempitemlist.findIndex(
+                item => tempDetail.itemid == item.id
+              );
+              if (itemIndex > -1) {
+                tempDetail.itemname = tempitemlist[itemIndex].itemName;
+                tempDetail.itemid = tempitemlist[itemIndex].id;
+              }
+
+              //鑾峰彇applytypename銆佹湇鍔¤垂鐢ㄥぇ绫�
+              let applytypeIndex = this.rowfeeItemTypes.findIndex(
+                item => tempDetail.applytype == item.value
+              );
+              if (applytypeIndex > -1) {
+                tempDetail.applytypename = this.rowfeeItemTypes[
+                  applytypeIndex
+                ].label;
+                tempDetail.subjecttype = this.rowfeeItemTypes[
+                  applytypeIndex
+                ].subjecttype;
+                tempDetail.subjecttypename = this.rowfeeItemTypes[
+                  applytypeIndex
+                ].subjecttypename;
+              }
+              this.rbDetails[i] = tempDetail;
+            }
+            //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣锛岀◣鍓嶉噾棰濓紙amount锛夈�佹墸绋庨噾棰濓紙taxamount锛夈�佺◣鍚庨噾棰濓紙taxedamount锛�
+            if (this.businessType == "2") {
+              for (let j = 0; j < this.rbDetails.length; j++) {
+                let tempDetail = this.rbDetails[j];
+                if (
+                  isNaN(parseFloat(tempDetail.amount)) ||
+                  moneyRound(tempDetail.amount) == 0
+                ) {
+                  this.$modal.msgWarning(
+                    "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                    (j + 1).toString() +
+                    "琛岀殑閲戦鏈緭鍏ワ紝璇峰厛杈撳叆閲戦鍚庡啀鎻愪氦淇濆瓨锛�"
+                  );
+                  return;
+                }
+              }
+            } else if (this.businessType == "3" || this.businessType == "4") {
+              for (let j = 0; j < this.rbDetails.length; j++) {
+                let tempDetail = this.rbDetails[j];
+                if (
+                  isNaN(parseFloat(tempDetail.amount)) ||
+                  moneyRound(tempDetail.amount) == 0
+                ) {
+                  this.$modal.msgWarning(
+                    "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
+                    (j + 1).toString() +
+                    "琛岀殑閲戦鏈緭鍏ワ紝璇峰厛杈撳叆閲戦鍚庡啀鎻愪氦淇濆瓨锛�"
+                  );
+                  return;
+                }
+                if (
+                  isNaN(parseFloat(tempDetail.taxamount)) ||
+                  moneyRound(tempDetail.taxamount) == 0
+                ) {
+                  tempDetail.taxedamount = parseFloat(tempDetail.amount);
+                } else {
+                  tempDetail.taxedamount =
+                    parseFloat(tempDetail.amount) +
+                    parseFloat(tempDetail.taxamount);
+                }
+              }
+            }
+
+            //淇濆瓨鏁版嵁
+            this.loading = true;
+            this.form.serviceFunddetails = 0;
+            this.rbDetails.map(item => {
+              this.form.serviceFunddetails += item.amount;
+            });
+            this.form.serviceFunddetails = this.rbDetails;
+
+            if (this.form.id != null) {
+            } else {
+              this.form.recordstatus = -1;
+            }
+
+            addorupdateFund(this.form).then(response => {
+              if (response.code === 200) {
+                this.$modal.msgSuccess("鐢宠鍗曚繚瀛樻垚鍔燂紒");
+                // 闈炴彁閱掔姸鎬佷笅鎵ц瀹℃壒瑙e喅寮傛璋冪敤寤惰繜闂
+                if (!this.Savereminder) {
+                  let checkFundObj = {
+                    // fundid: this.checkObj.fundid,
+                    fundid: this.curId,
+                    flowconclusion: this.checkObj.flowlevelone,
+                    flowcontent: this.checkObj.flowconclusion
+                  };
+                  this.$modal.loading("姝e湪鎻愪氦瀹℃牳锛岃绋嶅�欙紒");
+                  checkfund(checkFundObj).then(res => {
+                    if (res.code == 200) {
+                      //鍏抽棴绐楀彛
+                      this.$modal.closeLoading();
+                      this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
+                      // 杩炵画瀹℃壒锛氳闂槸鍚︾户缁鎵逛笅涓�鍗�
+                      this.continueOrExit();
+                    } else {
+                      this.$modal.closeLoading();
+
+                      this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
+                    }
+                  });
+                }
+                this.Getnetworkheader();
+                this.getroute();
+                this.getAccountList();
+                this.getUserList();
+                this.getUserProfile();
+              } else {
+                this.$modal.msgError("鐢宠鍗曚繚瀛樺け璐ワ細" + response.msg);
+              }
+            });
+
+            //鍏抽棴绐楀彛
+            this.loading = false;
+            // this.getfundList();
+          }
+        });
       });
     },
     handleCheckAllChange(val) {
-      this.checkedCities = val ? this.cityOptions : [];
+      this.checkedCities = val ? this.filteredCityOptions.slice() : [];
       this.isIndeterminate = false;
     },
     handleCheckedCitiesChange(value) {
       let checkedCount = value.length;
-      this.checkAll = checkedCount === this.cityOptions.length;
+      this.checkAll =
+        this.filteredCityOptions.length > 0 &&
+        checkedCount === this.filteredCityOptions.length;
       this.isIndeterminate =
-        checkedCount > 0 && checkedCount < this.cityOptions.length;
+        checkedCount > 0 && checkedCount < this.filteredCityOptions.length;
     },
     // 鎵嬪姩璁$畻
     Manualcalculationfn() {
@@ -2414,19 +2589,85 @@
     // 鎵归噺褰曞叆鐐瑰嚮
     Batchentry() {
       // ethical
+      this.personKeyword = "";
+      this.checkedCities = [];
+      this.checkAll = false;
+      this.isIndeterminate = false;
       listReportname("ethical").then(res => {
         this.cityOptions = res.data;
       });
       this.batchdialogVisible = true;
     },
+    /**
+     * 鏄庣粏琛屾槸鍚︿负銆岀┖璁板綍銆嶏細鏈嶅姟椤圭洰銆佷笓瀹躲�佷笓瀹舵墍鍦ㄥ崟浣� 鏄惁閮戒负绌�
+     * 鐢ㄤ簬鎵归噺褰曞叆涓撳鏃跺垽鏂�"澶嶇敤鏈�鍚庝竴琛�"杩樻槸"杩藉姞鏂拌"
+     */
+    isBlankDetailRow(row) {
+      if (!row) {
+        return false;
+      }
+      const isEmpty = v =>
+        v === null || v === undefined || String(v).trim() === "";
+      return (
+        isEmpty(row.itemid) &&
+        isEmpty(row.beneficiaryname) &&
+        isEmpty(row.unitno) &&
+        isEmpty(row.unitname)
+      );
+    },
+    /** 鎵归噺褰曞叆寮规锛氬鍚�/鍗曚綅/宸ュ彿/韬唤璇佸悗4浣� 鍛戒腑鍒ゆ柇 */
+    personMatchKeyword(item, kw) {
+      const idcard = String(item.idcrad || "");
+      return (
+        String(item.reportName || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        String(item.unitname || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        String(item.reportNo || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        (idcard.length >= 4 && idcard.slice(-4).indexOf(kw) > -1)
+      );
+    },
     // 纭褰曞叆
     BatchentryFn() {
+      // 鏄庣粏涓凡鏈夌殑浜哄憳濮撳悕锛岀敤浜庨噸澶嶆彁閱�
+      const existed = {};
+      this.rbDetails.forEach(row => {
+        if (row.beneficiaryname) {
+          existed[String(row.beneficiaryname).trim()] = true;
+        }
+      });
+
+      // 2026-10-22锛氫慨姝�"瀵煎叆鍚庤〃鏍煎鍑轰竴琛岀┖璁板綍"銆�
+      // 瑙勫垯锛氬厛鐪嬫渶鍚庝竴鏉¤褰曪紝鑻ュ畠鐨�"鏈嶅姟椤圭洰 / 涓撳 / 涓撳鎵�鍦ㄥ崟浣�"閮芥槸绌虹殑锛�
+      // 璇存槑鏄竴鏉$┖璁板綍锛屽氨浠庤繖涓�琛屽紑濮嬪~锛涘惁鍒欒拷鍔犳柊琛屻��
+      let writeIndex = this.rbDetails.length;
+      if (
+        writeIndex > 0 &&
+        this.isBlankDetailRow(this.rbDetails[writeIndex - 1])
+      ) {
+        writeIndex -= 1;
+      }
+
+      const duplicated = [];
       this.checkedCities.forEach(item => {
+        const nameKey = String(item.reportName || "").trim();
+        if (nameKey && existed[nameKey]) {
+          duplicated.push(item.reportName);
+          return;
+        }
+        if (nameKey) {
+          existed[nameKey] = true;
+        }
         let rowData = {
           orderno: null,
           fundid: null,
           beneficiaryname: item.reportName,
           beneficiaryno: item.reportNo,
+          isunit: 0,
           unitname: item.unitname,
           unitno: null,
           uintuserno: null,
@@ -2469,13 +2710,25 @@
           annexfiles: null
         };
 
-        this.rbDetails.push(rowData);
+        if (writeIndex < this.rbDetails.length) {
+          // 澶嶇敤鏈�鍚庨偅鏉$┖璁板綍
+          this.rbDetails.splice(writeIndex, 1, rowData);
+        } else {
+          this.rbDetails.push(rowData);
+        }
+        writeIndex++;
       });
-      for (let i = 0; i < this.checkedCities.length + 1; i++) {
+      for (let i = 0; i < this.rbDetails.length; i++) {
         this.rbDetails[i].orderno = i + 1;
       }
       this.calculateTax();
       this.batchdialogVisible = false;
+      this.checkedCities = [];
+      if (duplicated.length) {
+        this.$modal.msgWarning(
+          "浠ヤ笅浜哄憳鍦ㄦ槑缁嗕腑宸插瓨鍦紝宸茶烦杩囬噸澶嶆坊鍔狅細" + duplicated.join("銆�")
+        );
+      }
     },
     //鏂板涓�琛�
     addRow(rowIndex) {
@@ -2485,6 +2738,7 @@
         fundid: null,
         beneficiaryname: null,
         beneficiaryno: null,
+        isunit: 0,
         unitname: null,
         itemdescribe: null,
         unitno: null,
@@ -2581,33 +2835,32 @@
         });
       //鍏ㄩ儴鍒犻櫎鍚庢坊鍔犱竴鏉℃柊琛�
     },
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee(row) {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.rbDetails.length; i++) {
+          const detail = this.rbDetails[i];
           let totalFee = 0;
           let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.rbDetails[i].amount))) {
-              totalFee += parseFloat(this.rbDetails[i].amount);
-              taxFee += parseFloat(this.rbDetails[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneySub(totalFee, -parseFloat(detail.amount));
+              taxFee = moneySub(taxFee, -parseFloat(detail.amount));
             }
-            if (!isNaN(parseFloat(this.rbDetails[i].taxamount))) {
-              totalFee -= parseFloat(this.rbDetails[i].taxamount);
-              taxFee -= parseFloat(this.rbDetails[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
+              taxFee = moneySub(taxFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3 || this.form.applytype == 4) {
             //鍗曚环*鏁伴噺=绋庡墠閲戦
             if (
-              !isNaN(parseFloat(this.rbDetails[i].price)) &&
-              !isNaN(parseFloat(this.rbDetails[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.rbDetails[i].price) *
-                parseFloat(this.rbDetails[i].quantity);
-              this.rbDetails[i].amount = totalFee;
+              totalFee = moneyMul(detail.price, detail.quantity);
+              detail.amount = totalFee;
             }
           }
 
@@ -2616,9 +2869,10 @@
           //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
           // }
 
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
+      const allSum = moneyRound(moneySum(detailsArr));
       // this.form.amountrequested = allSum.toFixed(2);
       // this.$forceUpdate();
     },
@@ -2719,7 +2973,43 @@
       }
     },
 
+    /**
+     * 2026-10-15锛氫笂浼犳椂鏍¢獙闄勪欢鏂囦欢鍚嶏紙涓氬姟瑕佹眰锛氫笉鍚堟牸绔嬪嵆鎻愮ず涓斾笉鍔犲叆鍒楄〃锛夈��
+     * 瑙勫垯涓庡悗绔� AttachmentNameValidator 鍚屽彛寰勶細蹇呴』鍚腑鏂� / 鍘绘帀鎵╁睍鍚嶅悗涓诲共 鈮�20 瀛� /
+     * 涓嶅惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗︺��
+     */
+    checkUploadFileName(file) {
+      const raw = file && file.raw ? file.raw.name : file && file.name;
+      const r = checkFileName(raw);
+      if (!r.ok) {
+        this.$modal.msgError(r.msg);
+        return false;
+      }
+      return true;
+    },
+
+    /**
+     * 2026-10-15锛氫繚瀛樺墠鏍¢獙鏁村崟鏄庣粏闄勪欢鏂囦欢鍚嶏紙鍚悓涓�琛屽唴閲嶅悕锛夈��
+     * 鍙e緞锛堜笟鍔$‘璁わ級锛氬彧鏍¢獙"鏈鍙樻洿"鐨勯檮浠垛�斺�旇�佸崟鎹噷宸插瓨鍦ㄧ殑涓嶅悎瑙勯檮浠跺悕涓嶈兘鎶婁繚瀛樺崱姝�
+     * 锛堝惁鍒欒�佸崟鎹敼涓�涓噾棰濋兘瀛樹笉杩涘幓锛夈�傚悗绔寜 id 璇绘棫璁板綍鏀捐鍘嗗彶闄勪欢锛涘墠绔嬁涓嶅埌"鍝簺鏄巻鍙�"
+     * 鐨勬潈濞佷俊鎭紝鍥犳**浠呮柊澧炲崟鎹�**鍋氫繚瀛樺墠鎷︽埅锛岀紪杈戣�佸崟鎹椂鏂板鐨勪笉鍚堣闄勪欢鐢卞悗绔簩娆℃牎楠屾嫤涓嬨��
+     */
+    checkDetailFileNames() {
+      if (this.form && this.form.id) {
+        return true;
+      }
+      const c = checkDetails(this.rbDetails);
+      if (!c.ok) {
+        this.$modal.msgError(c.msg);
+        return false;
+      }
+      return true;
+    },
+
     uploadSccess(response, file, fileList) {
+      if (!this.checkUploadFileName(file)) {
+        return;
+      }
       this.rbDetails;
       const config = {
         headers: { Authorization: "Bearer " + this.ICDtoken }
@@ -3093,6 +3383,10 @@
     //涓撳/鍖荤枟鏈烘瀯/璐圭敤鎶ラ攢鏈烘瀯閫夋嫨
     confirmSelectionDialog() {
       this.$refs["accountselectform"].validate(valid => {
+        // 2026-10-19锛氬師鏉ユ病鏈夊垽鏂� valid锛屾牎楠屽け璐ヤ篃鐓ф牱寰�涓嬭蛋銆佺収鏍蜂繚瀛橈紙鏄熷彿/绾㈠瓧褰㈠悓铏氳锛�
+        if (!valid) {
+          return;
+        }
         let tempIndex = this.accountselectform.index;
         if (this.selectionType == "account") {
           if (this.accountfrom == "1") {
@@ -3121,11 +3415,13 @@
                   this.rbDetails[tempIndex].phone = res.telephone;
 
                   if (res.usertype == "org") {
+                    this.$set(this.rbDetails[tempIndex], "isunit", 1);
                     this.rbDetails[tempIndex].idcardno = "";
                     this.rbDetails[tempIndex].title = "";
                     this.rbDetails[tempIndex].unitno = "";
                     this.rbDetails[tempIndex].unitname = "";
                   } else {
+                    this.$set(this.rbDetails[tempIndex], "isunit", 0);
                     this.rbDetails[tempIndex].idcardno = res.idcardno;
                     this.rbDetails[tempIndex].title = res.title;
                     this.rbDetails[tempIndex].unitno = parseInt(res.unitno);
@@ -3231,12 +3527,14 @@
                       this.rbDetails[tempIndex].bankcardno = res.bankcardno;
                       this.rbDetails[tempIndex].phone = res.telephone;
 
-                      if (res.usertype == "org") {
+                      if (this.hasUserType(res.usertype, "org")) {
+                        this.$set(this.rbDetails[tempIndex], "isunit", 1);
                         this.rbDetails[tempIndex].idcardno = "";
                         this.rbDetails[tempIndex].title = "";
                         this.rbDetails[tempIndex].unitno = "";
                         this.rbDetails[tempIndex].unitname = "";
                       } else {
+                        this.$set(this.rbDetails[tempIndex], "isunit", 0);
                         this.rbDetails[tempIndex].idcardno = res.idcardno;
                         this.rbDetails[tempIndex].title = res.title;
                         this.rbDetails[tempIndex].unitno = parseInt(res.unitno);
@@ -3321,7 +3619,9 @@
 
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�
   mounted() {
-    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
+    // 瀛樹綇鍚屼竴涓紩鐢紝鍚﹀垯 removeEventListener 浼犳柊绠ご鍑芥暟鏃犳硶鐪熸绉婚櫎锛屼細娉勬紡鐩戝惉鍣�
+    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
+    window.addEventListener("beforeunload", this._beforeUnloadHandler);
     this.getUserList();
     let apiaccountselectform = this.accountselectform;
     let apiform = this.form;
@@ -3337,7 +3637,10 @@
   updated() { }, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪悗
   beforeDestroy() { }, //鐢熷懡鍛ㄦ湡 - 閿�姣佷箣鍓�
   destroyed() {
-    window.removeEventListener("beforeunload", e => this.beforeunloadFn(e));
+    if (this._beforeUnloadHandler) {
+      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
+      this._beforeUnloadHandler = null;
+    }
   }, //鐢熷懡鍛ㄦ湡 - 閿�姣佸畬鎴�
   activated() { } //濡傛灉椤甸潰鏈塳eep-alive缂撳瓨鍔熻兘锛岃繖涓嚱鏁颁細瑙﹀彂
 };
diff --git a/src/views/project/fund/applyDetail0/index.vue b/src/views/project/fund/applyDetail0/index.vue
index 9671250..90a2988 100644
--- a/src/views/project/fund/applyDetail0/index.vue
+++ b/src/views/project/fund/applyDetail0/index.vue
@@ -11,7 +11,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.createTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
               >
@@ -1227,6 +1227,8 @@
 import Li_area_select from "@/components/Address";
 import OrgSelecter from "@/views/project/components/orgselect";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
+import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
 
 export default {
   //import寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
@@ -1844,6 +1846,11 @@
     },
     /** 鎻愪氦鎸夐挳 */
     submitForm: debounce(function() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -2103,11 +2110,7 @@
           this.$store.dispatch("tagsView/delView", this.$route);
           this.$router.go(-1);
         } else {
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -2526,6 +2529,11 @@
     },
     // 鎺ュ彈鎻愰啋绔嬪埢淇濆瓨
     Savenow() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -2876,32 +2884,28 @@
       }
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛�
     sumTotalFee(row) {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.rbDetails.length; i++) {
+          const detail = this.rbDetails[i];
           let totalFee = 0;
-          let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.rbDetails[i].amount))) {
-              totalFee += parseFloat(this.rbDetails[i].amount);
-              taxFee += parseFloat(this.rbDetails[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.rbDetails[i].taxamount))) {
-              totalFee -= parseFloat(this.rbDetails[i].taxamount);
-              taxFee -= parseFloat(this.rbDetails[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3 || this.form.applytype == 4) {
             //鍗曚环*鏁伴噺=绋庡墠閲戦
             if (
-              !isNaN(parseFloat(this.rbDetails[i].price)) &&
-              !isNaN(parseFloat(this.rbDetails[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.rbDetails[i].price) *
-                parseFloat(this.rbDetails[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
               this.rbDetails[i].amount = totalFee;
             }
           }
@@ -2911,10 +2915,10 @@
           //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
           // }
 
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
-      // this.form.amountrequested = allSum.toFixed(2);
+      // this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
       // this.$forceUpdate();
     },
 
@@ -3005,7 +3009,43 @@
     //     console.log(response.msg);
     //   }
     // },
+    /**
+     * 2026-10-15锛氫笂浼犳椂鏍¢獙闄勪欢鏂囦欢鍚嶏紙涓氬姟瑕佹眰锛氫笉鍚堟牸绔嬪嵆鎻愮ず涓斾笉鍔犲叆鍒楄〃锛夈��
+     * 瑙勫垯涓庡悗绔� AttachmentNameValidator 鍚屽彛寰勶細蹇呴』鍚腑鏂� / 鍘绘帀鎵╁睍鍚嶅悗涓诲共 鈮�20 瀛� /
+     * 涓嶅惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗︺��
+     */
+    checkUploadFileName(file) {
+      const raw = file && file.raw ? file.raw.name : file && file.name;
+      const r = checkFileName(raw);
+      if (!r.ok) {
+        this.$modal.msgError(r.msg);
+        return false;
+      }
+      return true;
+    },
+
+    /**
+     * 2026-10-15锛氫繚瀛樺墠鏍¢獙鏁村崟鏄庣粏闄勪欢鏂囦欢鍚嶏紙鍚悓涓�琛屽唴閲嶅悕锛夈��
+     * 鍙e緞锛堜笟鍔$‘璁わ級锛氬彧鏍¢獙"鏈鍙樻洿"鐨勯檮浠垛�斺�旇�佸崟鎹噷宸插瓨鍦ㄧ殑涓嶅悎瑙勯檮浠跺悕涓嶈兘鎶婁繚瀛樺崱姝�
+     * 锛堝惁鍒欒�佸崟鎹敼涓�涓噾棰濋兘瀛樹笉杩涘幓锛夈�傚悗绔寜 id 璇绘棫璁板綍鏀捐鍘嗗彶闄勪欢锛涘墠绔嬁涓嶅埌"鍝簺鏄巻鍙�"
+     * 鐨勬潈濞佷俊鎭紝鍥犳**浠呮柊澧炲崟鎹�**鍋氫繚瀛樺墠鎷︽埅锛岀紪杈戣�佸崟鎹椂鏂板鐨勪笉鍚堣闄勪欢鐢卞悗绔簩娆℃牎楠屾嫤涓嬨��
+     */
+    checkDetailFileNames() {
+      if (this.form && this.form.id) {
+        return true;
+      }
+      const c = checkDetails(this.rbDetails);
+      if (!c.ok) {
+        this.$modal.msgError(c.msg);
+        return false;
+      }
+      return true;
+    },
+
     uploadSccess(response, file, fileList) {
+      if (!this.checkUploadFileName(file)) {
+        return;
+      }
       this.rbDetails;
 
       //鑾峰彇绁ㄦ嵁淇℃伅浣嶇疆
@@ -3279,13 +3319,13 @@
 
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�
   mounted() {
-    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
+    // 瀛樹綇鍚屼竴涓紩鐢紝鍚﹀垯 removeEventListener 浼犳柊绠ご鍑芥暟鏃犳硶鐪熸绉婚櫎锛屼細娉勬紡鐩戝惉鍣�
+    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
+    window.addEventListener("beforeunload", this._beforeUnloadHandler);
     this.getUserList();
     this.getUserProfile();
     let apifunddetailForm = this.funddetailForm;
     let apiform = this.form;
-    console.log(apiform);
-    console.log(apifunddetailForm);
 
     // this.getFeeUnitList();
   },
@@ -3294,7 +3334,12 @@
   beforeMount() {}, //鐢熷懡鍛ㄦ湡 - 鎸傝浇涔嬪墠
   beforeUpdate() {}, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪墠
   updated() {}, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪悗
-  beforeDestroy() {}, //鐢熷懡鍛ㄦ湡 - 閿�姣佷箣鍓�
+  beforeDestroy() {
+    if (this._beforeUnloadHandler) {
+      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
+      this._beforeUnloadHandler = null;
+    }
+  }, //鐢熷懡鍛ㄦ湡 - 閿�姣佷箣鍓�
   destroyed() {}, //鐢熷懡鍛ㄦ湡 - 閿�姣佸畬鎴�
   activated() {} //濡傛灉椤甸潰鏈塳eep-alive缂撳瓨鍔熻兘锛岃繖涓嚱鏁颁細瑙﹀彂
 };
diff --git a/src/views/project/fund/ethicalExpertFeeApply/index.vue b/src/views/project/fund/ethicalExpertFeeApply/index.vue
index ab8dad1..c6a74c6 100644
--- a/src/views/project/fund/ethicalExpertFeeApply/index.vue
+++ b/src/views/project/fund/ethicalExpertFeeApply/index.vue
@@ -1,122 +1,67 @@
 <!--  -->
 <template>
   <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryForm"
-      :inline="true"
-      label-width="70px"
-    >
-      <el-row align="left">
-        <el-col :span="6">
-          <el-form-item label="濮撳悕" prop="name">
-            <el-input
-              v-model="queryParams.name"
-              placeholder="璇疯緭鍏ュ鍚�"
-              clearable
-              size="small"
-              @keyup.enter.native="handleQuery"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="6">
-          <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
-            <el-select
-              v-model="queryParams.recordstate"
-              placeholder="璇烽�夋嫨璁板綍鐘舵��"
-              clearable
-              size="small"
-            >
-              <el-option
-                v-for="dict in dict.type.sys_DonationStatus"
-                :key="dict.value"
-                :label="dict.label"
-                :value="dict.value"
-              />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="6">
-          <el-form-item label="鎹愮尞鑰�" prop="name">
-            <el-input
-              v-model="queryParams.donorname"
-              placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
-              clearable
-              size="small"
-              @keyup.enter.native="handleQuery"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="6">
-          <el-button
-            type="primary"
-            icon="el-icon-search"
-            size="mini"
-            @click="handleQuery"
-            >鎼滅储</el-button
-          >
-          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
-            >閲嶇疆</el-button
-          >
-        </el-col>
-      </el-row>
-    </el-form>
     <el-row>
-      <el-col :span="6">
-        <el-card shadow="never">
-          <!-- 鎹愮尞妗堜緥鍒楄〃 -->
-          <el-row>
-            <el-col :span="10">
-              <el-row type="flex" :gutter="10" align="right" class="mb8">
-              </el-row>
-            </el-col>
-          </el-row>
-          <el-table
-            v-loading="loading"
-            border
-            highlight-current-row
-            :data="donatebaseinfoList"
-            @row-click="selectDonotor"
-          >
-            <!-- <el-table-column label="鎹愮尞缂栧彿" align="center" prop="donorno" /> -->
-            <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
-              <template slot-scope="scope">
-                <dict-tag
-                  :options="dict.type.sys_DonationStatus"
-                  :value="scope.row.recordstate"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column label="濮撳悕" align="center" prop="name" />
-          </el-table>
-          <pagination
-            v-show="total > 0"
-            :total="total"
-            small
-            :page.sync="queryParams.pageNum"
-            :limit.sync="queryParams.pageSize"
-            @pagination="getBaseInfoList"
-          />
-        </el-card>
-      </el-col>
-      <el-col :span="18">
+      <el-col :span="24">
         <el-card shadow="naver">
           <el-form ref="infoform" label-width="100px">
-            <el-row :gutter="4" align="right" class="mb8">
-              <el-col :span="9">
-                <el-form-item label="鎹愮尞缂栧彿">
-                  <el-input
-                    v-model="curCase.donorno"
-                    :disabled="true"
-                  ></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :span="9">
-                <el-form-item label="濮撳悕">
-                  <el-input v-model="curCase.name" :disabled="true"></el-input>
-                </el-form-item>
-              </el-col>
-            </el-row>
+            <!-- 鎶ラ攢鍗曠瓫閫夛細鎹愮尞鑰呫�佸鎵圭姸鎬� -->
+            <el-form
+              class="opo-query-form"
+              :model="fundQueryParam"
+              ref="fundQueryForm"
+              :inline="true"
+              label-width="82px"
+            >
+              <el-row>
+                <el-col :span="6">
+                  <el-form-item label="鎹愮尞鑰�" prop="donorname">
+                    <el-input
+                      v-model="fundQueryParam.donorname"
+                      placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+                      clearable
+                      size="small"
+                      @keyup.enter.native="handleQueryFund"
+                    />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label="瀹℃壒鐘舵��" prop="recordstatus">
+                    <el-select
+                      v-model="fundQueryParam.recordstatus"
+                      placeholder="璇烽�夋嫨瀹℃壒鐘舵��"
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                    >
+                      <el-option
+                        v-for="dict in dict.type.sys_recordstatus"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="Number(dict.value)"
+                      />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label-width="10px">
+                    <el-button
+                      type="primary"
+                      icon="el-icon-search"
+                      size="small"
+                      @click="handleQueryFund"
+                      >鎼滅储</el-button
+                    >
+                    <el-button
+                      icon="el-icon-refresh"
+                      size="small"
+                      @click="resetFundQuery"
+                      >閲嶇疆</el-button
+                    >
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
             <el-row :gutter="10" class="mb8">
               <el-col :span="1.5">
                 <el-button
@@ -198,6 +143,13 @@
                     />
                   </template>
                 </el-table-column>
+                <el-table-column
+                  label="鎹愮尞鑰�"
+                  align="center"
+                  prop="donorname"
+                  width="110px"
+                  show-overflow-tooltip
+                />
                 <!--
                 <el-table-column label="鑱旂郴鐢佃瘽" align="center" prop="phone" width="150px" />
                 <el-table-column label="宸ヤ綔鍗曚綅" align="center" prop="unitname" width="220px" />
@@ -261,11 +213,119 @@
                   </template>
                 </el-table-column>
               </el-table>
+              <!-- 鏈�夋嫨妗堜緥鏃跺睍绀鸿鐧诲綍浜哄叏閮ㄤ鸡鐞嗗鏌ュ崟鎹紝瓒呰繃涓�椤靛彲鐢ㄥ垎椤电炕鐪� -->
+              <pagination
+                v-show="fundTotal > 0"
+                :total="fundTotal"
+                small
+                :page.sync="fundQueryParam.pageNum"
+                :limit.sync="fundQueryParam.pageSize"
+                @pagination="listFundData"
+              />
             </el-row>
           </el-form>
         </el-card>
       </el-col>
     </el-row>
+
+    <!-- 鏂板鐢宠鍗曞墠鍏堥�夋嫨鎹愮尞妗堜緥锛堝師宸︿晶妗堜緥鍒楄〃绉诲埌杩欓噷锛� -->
+    <el-dialog
+      title="閫夋嫨鎹愮尞妗堜緥"
+      :visible.sync="caseDialogVisible"
+      width="760px"
+      append-to-body
+    >
+      <el-form
+        class="opo-query-form"
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="70px"
+      >
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="濮撳悕" prop="name">
+              <el-input
+                v-model="queryParams.name"
+                placeholder="璇疯緭鍏ュ鍚�"
+                clearable
+                size="small"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
+              <el-select
+                v-model="queryParams.recordstate"
+                placeholder="璇烽�夋嫨璁板綍鐘舵��"
+                clearable
+                size="small"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="dict in dict.type.sys_DonationStatus"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label-width="10px">
+              <el-button
+                type="primary"
+                icon="el-icon-search"
+                size="small"
+                @click="handleQuery"
+                >鎼滅储</el-button
+              >
+              <el-button icon="el-icon-refresh" size="small" @click="resetQuery"
+                >閲嶇疆</el-button
+              >
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-table
+        ref="caseTable"
+        v-loading="loading"
+        border
+        height="380"
+        highlight-current-row
+        :data="donatebaseinfoList"
+        @row-click="selectDonotor"
+      >
+        <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_DonationStatus"
+              :value="scope.row.recordstate"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="濮撳悕" align="center" prop="name" />
+        <el-table-column label="鎿嶄綔" align="center" width="90">
+          <template slot-scope="scope">
+            <el-button type="text" size="mini" @click="selectDonotor(scope.row)"
+              >閫夋嫨</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        small
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getBaseInfoList"
+      />
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="caseDialogVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
 
     <!-- 娣诲姞鎴栦慨鏀硅垂鐢ㄧ敵璇峰崟 -->
     <el-dialog
@@ -284,7 +344,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
               >
@@ -960,6 +1020,7 @@
 import { getUserProfile } from "@/api/system/user";
 import { listFundflow } from "@/api/project/fundflow";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   //import寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
@@ -1011,11 +1072,19 @@
       },
       fundQueryParam: {
         pageNum: 1,
-        pageSize: 100,
+        pageSize: 10,
         infoid: null,
         applytype: "2",
-        createBy: null
+        createBy: null,
+        // 鎶ラ攢鍗曠瓫閫夋潯浠�
+        donorname: null,
+        recordstatus: null
       },
+      // 鍙充晶鎶ラ攢鍗曟�绘暟锛堢敤浜庡垎椤碉級
+      fundTotal: 0,
+      // 銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛堟柊澧炵敵璇峰崟鏃朵娇鐢級
+      caseDialogVisible: false,
+      casePickerMode: "",
       // 琛ㄥ崟鍙傛暟
       form: {},
       // 琛ㄥ崟鏍¢獙
@@ -1102,55 +1171,23 @@
     },
     /** 鏂板鎸夐挳鎿嶄綔 */
     handleAdd() {
-      if (this.curCase.id) {
-        this.$router.push({
-          path: "/finance/applyDetail/",
-          query: {
-            id: 0,
-            businessType: "2",
-            operationType: "add",
-            curCase: this.curCase
-          }
-        });
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [
-            h("span", null, "璇峰湪宸﹁竟鐨勬崘鐚渚嬭〃閫夋嫨闇�瑕佹搷浣滅殑妗堜緥锛�")
-          ])
-        });
-      }
-      return;
+      // 鏂板鐢宠鍗曪細鍏堝脊鍑恒�岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇
+      this.casePickerMode = "add";
+      this.caseDialogVisible = true;
+      this.getBaseInfoList();
+    },
 
-      if (this.curCase.id) {
-        this.istrue += 2;
-        this.reset();
-        this.dialogOpen = true;
-        this.title = "娣诲姞璐圭敤鐢宠";
-        this.dialogType = "edit";
-        this.queryParams.params = {};
-
-        this.form.infoid = this.curCase.id;
-        this.form.donorno = this.curCase.donorno;
-        this.form.donorname = this.curCase.name;
-        this.form.username = this.defaultperson.nickName;
-        this.form.userno = this.defaultperson.userName;
-
-        this.form.deptmentname = this.defaultperson.dept.deptName;
-        this.form.deptmentno = this.defaultperson.dept.deptId;
-        this.form.managername = this.defaultperson.dept.leader;
-        // this.form.createTime = nowdate;
-        //this.open = true;
-        //this.initFundApplyForm();
-        this.fundDetailArr = [];
-        this.fundflowList = [];
-        this.addRow();
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [h("span", null, "璇峰厛閫夋嫨宸︽柟鎹愮尞妗堜緥 ")])
-        });
-      }
+    /** 鎼哄甫宸查�夋渚嬭烦杞埌鐢宠鍗曞~鍐欓〉 */
+    goApplyAdd() {
+      this.$router.push({
+        path: "/finance/applyDetail/",
+        query: {
+          id: 0,
+          businessType: "2",
+          operationType: "add",
+          curCase: this.curCase
+        }
+      });
     },
     /** 淇敼鎸夐挳鎿嶄綔 */
     handleUpdate(row) {
@@ -1360,15 +1397,11 @@
             // } catch {
             //   tempDetail.unitname = tempDetail.unitno;
             // }
-            if (!isNaN(parseFloat(tempDetail.amount))) {
-              totalPreTaxAmount += parseFloat(tempDetail.amount);
-              totalAmount += parseFloat(tempDetail.amount);
-            }
-            if (!isNaN(parseFloat(tempDetail.taxedamount))) {
-              totalAfterTaxAmount += parseFloat(tempDetail.taxedamount);
-              totalAmount += parseFloat(tempDetail.taxedamount);
-            }
           }
+          //閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞
+          totalPreTaxAmount = moneySum(this.fundDetailArr, "amount");
+          totalAfterTaxAmount = moneySum(this.fundDetailArr, "taxedamount");
+          totalAmount = moneyAdd(totalPreTaxAmount, totalAfterTaxAmount);
           try {
             this.form.unitname = this.$refs.orgSelecter.getOptionByValue(
               this.form.unitno
@@ -1498,18 +1531,60 @@
     //鐐瑰嚮鎹愮尞妗堜緥鍒楄〃瑙﹀彂鏂规硶
     selectDonotor(row, column, event) {
       this.curCase = row;
-      this.getfundList();
+      if (this.casePickerMode === "add") {
+        // 浠庛�屾柊澧炵敵璇峰崟銆嶈繘鍏ワ細閫夊畬妗堜緥鐩存帴璺冲埌鐢宠鍗曞~鍐欓〉
+        this.casePickerMode = "";
+        this.caseDialogVisible = false;
+        this.goApplyAdd();
+      }
+    },
+
+    /** 鎸夊綋鍓� fundQueryParam 鏌ヨ鍙充晶鎶ラ攢鍗曞垪琛� */
+    listFundData() {
+      this.loading = true;
+      listFund(this.fundQueryParam).then(response => {
+        this.loading = false;
+        this.donateconsolationfundList = response.rows;
+        this.fundTotal = response.total;
+      });
+    },
+
+    /** 鎶ラ攢鍗曠瓫閫夛細鎼滅储 */
+    handleQueryFund() {
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
+    },
+
+    /** 鎶ラ攢鍗曠瓫閫夛細閲嶇疆锛堟竻绌烘潯浠朵笌宸查�夋渚嬶紝鍥炲埌璇ョ櫥褰曚汉鍏ㄩ儴鍗曟嵁锛� */
+    resetFundQuery() {
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.getAllfundList();
+    },
+
+    /** 妫�绱㈠叏閮細鍙栨秷妗堜緥閫夋嫨涓庣瓫閫夋潯浠讹紝鏌ヨ褰撳墠鐧诲綍浜虹殑鍏ㄩ儴浼︾悊瀹℃煡鍗曟嵁 */
+    getAllfundList() {
+      this.curCase = {};
+      if (this.$refs.caseTable) {
+        this.$refs.caseTable.setCurrentRow();
+      }
+      this.reset();
+      this.fundQueryParam.infoid = null;
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
     },
 
     //鑾峰彇妗堜緥涓撳璐圭敤鐢宠鍗�
     getfundList() {
-      this.loading = true;
       this.reset();
+      // 閫変腑妗堜緥鍚庢寜妗堜緥灞曠ず锛屽悓鏃舵竻鎺夊垪琛ㄧ瓫閫夋潯浠讹紝閬垮厤涓や釜鏉′欢鍙犲姞瀵艰嚧绌哄垪琛�
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
       this.fundQueryParam.infoid = this.curCase.id;
-      listFund(this.fundQueryParam).then(response => {
-        this.loading = false;
-        this.donateconsolationfundList = response.rows;
-      });
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
     },
 
     select(row) {
@@ -1736,49 +1811,45 @@
         });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee() {
-      let allSum = 0;
+      const detailsArr = [];
       let preTaxSum = 0;
       let taxedSum = 0;
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetailArr.length; i++) {
+          const detail = this.fundDetailArr[i];
           let totalFee = 0;
-          let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
-              totalFee += parseFloat(this.fundDetailArr[i].amount);
-              taxFee += parseFloat(this.fundDetailArr[i].amount);
-              preTaxSum += parseFloat(this.fundDetailArr[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              preTaxSum = moneyAdd(preTaxSum, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
-              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
             }
             //taxedamount
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxedamount))) {
-              taxedSum += parseFloat(this.fundDetailArr[i].taxedamount);
+            if (!isNaN(parseFloat(detail.taxedamount))) {
+              taxedSum = moneyAdd(taxedSum, detail.taxedamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
-              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetailArr[i].price) *
-                parseFloat(this.fundDetailArr[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           // if (!isNaN(parseFloat(taxFee))) {
           //   this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
           // }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
-      this.form.amountrequested = allSum.toFixed(2);
-      this.form.pretaxcost = preTaxSum.toFixed(2);
-      this.form.taxedcost = taxedSum.toFixed(2);
+      this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
+      this.form.pretaxcost = moneyRound(preTaxSum).toFixed(2);
+      this.form.taxedcost = moneyRound(taxedSum).toFixed(2);
       this.$forceUpdate();
     },
 
@@ -2064,10 +2135,11 @@
   //鐢熷懡鍛ㄦ湡 - 鍒涘缓瀹屾垚锛堝彲浠ヨ闂綋鍓峵his瀹炰緥锛�
   created() {
     this.getUnitList();
-    this.getList();
-    this.getBaseInfoList();
+    // 妗堜緥鍒楄〃宸茬Щ鍏ャ�岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛屾墦寮�瀵硅瘽妗嗘椂鍐嶆煡璇�
     this.getlistUser();
     this.getCurFundType();
+    // 棣栧睆灞曠ず褰撳墠鐧诲綍浜虹殑鍏ㄩ儴浼︾悊瀹℃煡鍗曟嵁
+    this.getAllfundList();
   },
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�
   mounted() {
diff --git a/src/views/project/fund/expertFeeApply/index.vue b/src/views/project/fund/expertFeeApply/index.vue
index e3bc9f3..0cd2053 100644
--- a/src/views/project/fund/expertFeeApply/index.vue
+++ b/src/views/project/fund/expertFeeApply/index.vue
@@ -2,119 +2,66 @@
 <template>
   <div class="app-container">
     <el-row>
-      <el-col :span="6">
-        <el-card shadow="never">
-          <!-- 鎹愮尞妗堜緥鍒楄〃 -->
-          <el-row>
-            <el-col :span="10">
-              <el-row type="flex" :gutter="10" align="right" class="mb8">
-              </el-row>
-            </el-col>
-          </el-row>
-          <div>
-            <el-form
-              :model="queryParams"
-              ref="queryForm"
-              :inline="true"
-              label-width="70px"
-            >
-              <el-form-item label="濮撳悕" prop="name">
-                <el-input
-                  v-model="queryParams.name"
-                  placeholder="璇疯緭鍏ュ鍚�"
-                  clearable
-                  size="small"
-                  @keyup.enter.native="handleQuery"
-                />
-              </el-form-item>
-              <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
-                <el-select
-                  v-model="queryParams.recordstate"
-                  placeholder="璇烽�夋嫨璁板綍鐘舵��"
-                  clearable
-                  size="small"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_DonationStatus"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                  />
-                </el-select>
-              </el-form-item>
-              <div style="float: right; margin-bottom: 10px;">
-                <el-button
-                  type="primary"
-                  icon="el-icon-search"
-                  size="mini"
-                  @click="handleQuery"
-                  >鎼滅储</el-button
-                >
-                <el-button
-                  icon="el-icon-refresh"
-                  size="mini"
-                  @click="resetQuery"
-                  >閲嶇疆</el-button
-                >
-              </div>
-            </el-form>
-          </div>
-          <el-table
-            v-loading="loading"
-            highlight-current-row
-            :data="donatebaseinfoList"
-            @row-click="selectDonotor"
-          >
-            <!-- <el-table-column label="鎹愮尞缂栧彿" align="center" prop="donorno" /> -->
-            <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
-              <template slot-scope="scope">
-                <dict-tag
-                  :options="dict.type.sys_DonationStatus"
-                  :value="scope.row.recordstate"
-                  :key="dict.value"
-                />
-                <!-- :label="dict.label" -->
-              </template>
-            </el-table-column>
-            <el-table-column label="濮撳悕" align="center" prop="name" />
-          </el-table>
-          <pagination
-            v-show="total > 0"
-            :total="total"
-            small
-            :page.sync="queryParams.pageNum"
-            :limit.sync="queryParams.pageSize"
-            @pagination="getBaseInfoList"
-          />
-        </el-card>
-      </el-col>
-      <el-col :span="18">
+      <el-col :span="24">
         <el-card shadow="naver">
           <el-form ref="infoform" label-width="100px">
-            <el-row :gutter="4" align="right" class="mb8">
-              <el-col :span="7">
-                <el-form-item label="鎹愮尞缂栧彿">
-                  <el-input
-                    v-model="curCase.donorno"
-                    :disabled="true"
-                  ></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="濮撳悕">
-                  <el-input v-model="curCase.name" :disabled="true"></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :span="3">
-                <el-button
-                  type="primary"
-                  icon="el-icon-search"
-                  size="mini"
-                  @click="allgetfundList"
-                  >妫�绱㈠叏閮�</el-button
-                >
-              </el-col>
-            </el-row>
+            <!-- 鎶ラ攢鍗曠瓫閫夛細鎹愮尞鑰呫�佸鎵圭姸鎬� -->
+            <el-form
+              class="opo-query-form"
+              :model="fundQueryParam"
+              ref="fundQueryForm"
+              :inline="true"
+              label-width="82px"
+            >
+              <el-row>
+                <el-col :span="6">
+                  <el-form-item label="鎹愮尞鑰�" prop="donorname">
+                    <el-input
+                      v-model="fundQueryParam.donorname"
+                      placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+                      clearable
+                      size="small"
+                      @keyup.enter.native="handleQueryFund"
+                    />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label="瀹℃壒鐘舵��" prop="recordstatus">
+                    <el-select
+                      v-model="fundQueryParam.recordstatus"
+                      placeholder="璇烽�夋嫨瀹℃壒鐘舵��"
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                    >
+                      <el-option
+                        v-for="dict in dict.type.sys_recordstatus"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="Number(dict.value)"
+                      />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label-width="10px">
+                    <el-button
+                      type="primary"
+                      icon="el-icon-search"
+                      size="small"
+                      @click="handleQueryFund"
+                      >鎼滅储</el-button
+                    >
+                    <el-button
+                      icon="el-icon-refresh"
+                      size="small"
+                      @click="resetFundQuery"
+                      >閲嶇疆</el-button
+                    >
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
             <el-row :gutter="10" class="mb8">
               <el-col :span="1.5">
                 <el-button
@@ -268,6 +215,8 @@
                     <!-- v-hasPermi="['project:expretfund:download']" -->
                   </template>
                 </el-table-column>
+                <!-- 2026-10-22锛氭寜瑕佹眰闅愯棌銆屽姛鑳姐�嶅垪锛堢嚎涓嬫姤閿�锛夛紝闇�瑕佹椂鍙栨秷娉ㄩ噴鍗冲彲鎭㈠ -->
+                <!--
                 <el-table-column
                   fixed="right"
                   align="center"
@@ -287,12 +236,121 @@
                     >
                   </template>
                 </el-table-column>
+                -->
               </el-table>
+              <!-- 鏈�夋嫨妗堜緥鏃跺睍绀鸿鐧诲綍浜哄叏閮ㄤ笓瀹跺姵鍔″崟鎹紝瓒呰繃涓�椤靛彲鐢ㄥ垎椤电炕鐪� -->
+              <pagination
+                v-show="fundTotal > 0"
+                :total="fundTotal"
+                small
+                :page.sync="fundQueryParam.pageNum"
+                :limit.sync="fundQueryParam.pageSize"
+                @pagination="listFundData"
+              />
             </el-row>
           </el-form>
         </el-card>
       </el-col>
     </el-row>
+
+    <!-- 鏂板鐢宠鍗曞墠鍏堥�夋嫨鎹愮尞妗堜緥锛堝師宸︿晶妗堜緥鍒楄〃绉诲埌杩欓噷锛� -->
+    <el-dialog
+      title="閫夋嫨鎹愮尞妗堜緥"
+      :visible.sync="caseDialogVisible"
+      width="760px"
+      append-to-body
+    >
+      <el-form
+        class="opo-query-form"
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="70px"
+      >
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="濮撳悕" prop="name">
+              <el-input
+                v-model="queryParams.name"
+                placeholder="璇疯緭鍏ュ鍚�"
+                clearable
+                size="small"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
+              <el-select
+                v-model="queryParams.recordstate"
+                placeholder="璇烽�夋嫨璁板綍鐘舵��"
+                clearable
+                size="small"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="dict in dict.type.sys_DonationStatus"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label-width="10px">
+              <el-button
+                type="primary"
+                icon="el-icon-search"
+                size="small"
+                @click="handleQuery"
+                >鎼滅储</el-button
+              >
+              <el-button icon="el-icon-refresh" size="small" @click="resetQuery"
+                >閲嶇疆</el-button
+              >
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-table
+        ref="caseTable"
+        v-loading="loading"
+        border
+        height="380"
+        highlight-current-row
+        :data="donatebaseinfoList"
+        @row-click="selectDonotor"
+      >
+        <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_DonationStatus"
+              :value="scope.row.recordstate"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="濮撳悕" align="center" prop="name" />
+        <el-table-column label="鎿嶄綔" align="center" width="90">
+          <template slot-scope="scope">
+            <el-button type="text" size="mini" @click="selectDonotor(scope.row)"
+              >閫夋嫨</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        small
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getBaseInfoList"
+      />
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="caseDialogVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
 
     <!-- 娣诲姞鎴栦慨鏀硅垂鐢ㄧ敵璇峰崟 -->
     <el-dialog
@@ -317,7 +375,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
               >
@@ -1112,7 +1170,8 @@
   getdownloadYX,
   getdownloadBX,
   addorupdateFund,
-  getdetailsByItemId
+  getdetailsByItemId,
+  validateExpertFee
 } from "@/api/project/fund";
 
 import {
@@ -1159,6 +1218,7 @@
 import OrgSelecter from "@/views/project/components/orgselect";
 import elementIcons from "../../../components/icons/element-icons";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   //import寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
@@ -1212,11 +1272,16 @@
       },
       fundQueryParam: {
         pageNum: 1,
-        pageSize: 100,
+        pageSize: 10,
         infoid: null,
         applytype: "1",
-        createBy: null
+        createBy: null,
+        // 鎶ラ攢鍗曠瓫閫夋潯浠�
+        donorname: null,
+        recordstatus: null
       },
+      // 鍙充晶鎶ラ攢鍗曟�绘暟锛堢敤浜庡垎椤碉級
+      fundTotal: 0,
       // 琛ㄥ崟鍙傛暟
       form: {},
       //鎵�鏈変汉鍛樿〃
@@ -1265,6 +1330,9 @@
       donatebaseinfoList: [],
       //褰撳墠閫変腑鎹愮尞妗堜緥
       curCase: {},
+      // 銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛堟柊澧炵敵璇峰崟鏃朵娇鐢級
+      caseDialogVisible: false,
+      casePickerMode: "",
       //鏄惁鏄剧ず璐圭敤鐢宠寮圭獥
       dialogOpen: false,
       // title: "",
@@ -1360,11 +1428,12 @@
   watch: {},
   //鐢熷懡鍛ㄦ湡 - 鍒涘缓瀹屾垚锛堝彲浠ヨ闂綋鍓峵his瀹炰緥锛�
   created() {
-    this.getList();
-    this.getBaseInfoList();
+    // 妗堜緥鍒楄〃宸茬Щ鍏ャ�岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛屾墦寮�瀵硅瘽妗嗘椂鍐嶆煡璇�
     this.getCurFundType();
     this.getUserList();
     this.getUnitList();
+    // 棣栧睆灞曠ず褰撳墠鐧诲綍浜虹殑鍏ㄩ儴涓撳鍔冲姟鍗曟嵁
+    this.allgetfundList();
   },
 
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�
@@ -1408,57 +1477,24 @@
       });
     },
 
-    /** 鏂板鎸夐挳鎿嶄綔 */
+    /** 鏂板鎸夐挳鎿嶄綔锛氬厛寮瑰嚭銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇 */
     handleAdd() {
-      if (this.curCase.id) {
-        this.$router.push({
-          path: "/finance/applyDetail/",
-          query: {
-            id: 0,
-            businessType: "1",
-            operationType: "add",
-            curCase: this.curCase
-          }
-        });
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [
-            h("span", null, "璇峰湪宸﹁竟鐨勬崘鐚渚嬭〃閫夋嫨闇�瑕佹搷浣滅殑妗堜緥锛�")
-          ])
-        });
-      }
-      return;
+      this.casePickerMode = "add";
+      this.caseDialogVisible = true;
+      this.getBaseInfoList();
+    },
 
-      if (this.curCase.id) {
-        this.istrue += 2;
-        this.reset();
-        this.queryParams.params = {};
-        this.form.infoid = this.curCase.id;
-        this.form.donorno = this.curCase.donorno;
-        this.form.donorname = this.curCase.name;
-
-        this.form.username = this.defaultperson.nickName;
-        this.form.userno = this.defaultperson.userName;
-        this.form.phone = this.defaultperson.phonenumber;
-        this.form.deptmentname = this.defaultperson.dept.deptName;
-        this.form.deptmentno = this.defaultperson.dept.deptId;
-        this.form.managername = this.defaultperson.dept.leader;
-
-        // this.form.createTime = nowdate;
-        //this.open = true;
-        //this.initFundApplyForm();
-        this.fundDetails = [];
-        this.addRow();
-        this.dialogOpen = true;
-        this.dialogType = "edit";
-        this.title = "璐圭敤鐢宠";
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [h("span", null, "璇峰厛閫夋嫨宸︽柟鎹愮尞妗堜緥 ")])
-        });
-      }
+    /** 鎼哄甫宸查�夋渚嬭烦杞埌鐢宠鍗曞~鍐欓〉 */
+    goApplyAdd() {
+      this.$router.push({
+        path: "/finance/applyDetail/",
+        query: {
+          id: 0,
+          businessType: "1",
+          operationType: "add",
+          curCase: this.curCase
+        }
+      });
     },
 
     /** 淇敼鎸夐挳鎿嶄綔 */
@@ -1824,21 +1860,37 @@
             // });
           }
 
-          addorupdateFund(this.form).then(response => {
-            if (response.code === 200) {
-              this.selectDonotor(this.curCase);
-              this.$modal.msgSuccess("涓撳鍔冲姟璐逛繚瀛樻垚鍔燂紒");
-            } else {
-              this.$modal.msgError("涓撳鍔冲姟璐逛繚瀛樺け璐ワ細" + response.msg);
-            }
-          });
+          // 淇濆瓨鍓嶅厛鍋氫笓瀹跺姵鍔¤垂 9 鏉¤垂鐢ㄦ帶鍒舵牎楠岋紙鍚屼竴妗堜緥绱锛�
+          validateExpertFee(this.form).then(valid => {
+            const errors = (valid && valid.errors) || [];
+            const warnings = (valid && valid.warnings) || [];
 
-          //鍏抽棴绐楀彛
-          this.loading = false;
-          this.dialogOpen = false;
-          // this.getfundList();
-          this.getList();
-          this.selectDonotor(this.curCase);
+            // warnings锛堣鍒� 5銆�6锛変粎鎻愮ず锛屼笉闃绘柇淇濆瓨
+            if (warnings.length > 0) {
+              this.$modal.msgWarning(warnings.join("锛�"));
+            }
+
+            // errors 闃绘柇淇濆瓨锛屼繚鐣欑獥鍙h缁忓姙浜哄厛淇
+            if (errors.length > 0) {
+              this.$modal.msgError(errors.join("锛�"));
+              this.loading = false;
+              return;
+            }
+
+            addorupdateFund(this.form).then(response => {
+              if (response.code === 200) {
+                //鍏抽棴绐楀彛
+                this.loading = false;
+                this.dialogOpen = false;
+                this.selectDonotor(this.curCase);
+                this.$modal.msgSuccess("涓撳鍔冲姟璐逛繚瀛樻垚鍔燂紒");
+                this.getList();
+              } else {
+                this.$modal.msgError("涓撳鍔冲姟璐逛繚瀛樺け璐ワ細" + response.msg);
+                this.loading = false;
+              }
+            });
+          });
         }
       });
     },
@@ -2152,25 +2204,57 @@
     //鐐瑰嚮鎹愮尞妗堜緥鍒楄〃瑙﹀彂鏂规硶
     selectDonotor(row, column, event) {
       this.curCase = row;
-      this.getfundList();
+      if (this.casePickerMode === "add") {
+        // 浠庛�屾柊澧炵敵璇峰崟銆嶈繘鍏ワ細閫夊畬妗堜緥鐩存帴璺冲埌鐢宠鍗曞~鍐欓〉
+        this.casePickerMode = "";
+        this.caseDialogVisible = false;
+        this.goApplyAdd();
+      }
     },
     allgetfundList() {
-      this.loading = true;
+      // 妫�绱㈠叏閮細鍙栨秷宸︿晶妗堜緥閫夋嫨涓庣瓫閫夋潯浠讹紝鏌ヨ褰撳墠鐧诲綍浜虹殑鍏ㄩ儴涓撳鍔冲姟鍗曟嵁
+      this.curCase = {};
+      if (this.$refs.caseTable) {
+        this.$refs.caseTable.setCurrentRow();
+      }
       this.reset();
       this.fundQueryParam.infoid = null;
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
+    },
+    /** 鎶ラ攢鍗曠瓫閫夛細鎼滅储 */
+    handleQueryFund() {
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
+    },
+    /** 鎶ラ攢鍗曠瓫閫夛細閲嶇疆锛堟竻绌烘潯浠朵笌宸查�夋渚嬶紝鍥炲埌璇ョ櫥褰曚汉鍏ㄩ儴鍗曟嵁锛� */
+    resetFundQuery() {
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.allgetfundList();
+    },
+    /**
+     * 鎸夊綋鍓� fundQueryParam 鏌ヨ鍙充晶鎶ラ攢鍗曞垪琛�
+     * infoid 涓虹┖ = 褰撳墠鐧诲綍浜虹殑鍏ㄩ儴璇ョ被鍨嬪崟鎹紱鏈夊�� = 鎸囧畾妗堜緥
+     */
+    listFundData() {
+      this.loading = true;
       listFund(this.fundQueryParam).then(response => {
         this.loading = false;
         this.donateconsolationfundList = response.rows;
+        this.fundTotal = response.total;
       });
     },
     getfundList() {
-      this.loading = true;
       this.reset();
+      // 閫変腑妗堜緥鍚庢寜妗堜緥灞曠ず锛屽悓鏃舵竻鎺夊垪琛ㄧ瓫閫夋潯浠讹紝閬垮厤涓や釜鏉′欢鍙犲姞瀵艰嚧绌哄垪琛�
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
       this.fundQueryParam.infoid = this.curCase.id;
-      listFund(this.fundQueryParam).then(response => {
-        this.loading = false;
-        this.donateconsolationfundList = response.rows;
-      });
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
     },
 
     //瀵煎叆鎵�鏈夐」鐩�
@@ -2451,43 +2535,34 @@
     //璁$畻涓◣
     calculateTax() {},
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛�
     sumTotalFee(row) {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetails.length; i++) {
+          const detail = this.fundDetails[i];
           let totalFee = 0;
-          let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
-              totalFee += parseFloat(this.fundDetails[i].amount);
-              taxFee += parseFloat(this.fundDetails[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetails[i].taxamount);
-              taxFee -= parseFloat(this.fundDetails[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetails[i].price)) &&
-              !isNaN(parseFloat(this.fundDetails[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetails[i].price) *
-                parseFloat(this.fundDetails[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
-
-          //绋庡墠銆佺◣鍚庨渶瑕佺嫭绔嬪綍鍏�
-          // if (!isNaN(parseFloat(taxFee))) {
-          //   this.fundDetails[i].taxedamount = taxFee.toFixed(2);
-          // }
-
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
-      // this.form.amountrequested = allSum.toFixed(2);
+      // 鍚堣浠嶅湪纭鍙e緞鍚庡惎鐢紱鍏堜繚璇佽绠楁湰韬槸绮剧‘鐨�
+      // this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
       // this.$forceUpdate();
     },
 
diff --git a/src/views/project/fund/index.vue b/src/views/project/fund/index.vue
index 06e5d2c..8d366b8 100644
--- a/src/views/project/fund/index.vue
+++ b/src/views/project/fund/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鎹愮尞鑰呯紪鍙�" prop="donorno">
         <el-input v-model="queryParams.donorno" placeholder="璇疯緭鍏ユ崘鐚�呯紪鍙�" clearable size="small"
           @keyup.enter.native="handleQuery" />
diff --git a/src/views/project/fund/medicalCostApply/index.vue b/src/views/project/fund/medicalCostApply/index.vue
index 208cc78..dc2a2e0 100644
--- a/src/views/project/fund/medicalCostApply/index.vue
+++ b/src/views/project/fund/medicalCostApply/index.vue
@@ -2,253 +2,94 @@
 <template>
   <div class="app-container">
     <el-row>
-      <el-col :span="6">
-        <el-card shadow="never">
-          <!-- 鎹愮尞妗堜緥鍒楄〃 -->
-          <el-row>
-            <el-col :span="10">
-              <el-row type="flex" :gutter="10" align="right" class="mb8">
-              </el-row>
-            </el-col>
-          </el-row>
-          <div>
-            <el-form
-              :model="queryParams"
-              ref="queryForm"
-              :inline="true"
-              label-width="70px"
-            >
-              <el-form-item label="濮撳悕" prop="name">
-                <el-input
-                  v-model="queryParams.name"
-                  placeholder="璇疯緭鍏ュ鍚�"
-                  clearable
-                  size="small"
-                  @keyup.enter.native="handleQuery"
-                />
-              </el-form-item>
-              <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
-                <el-select
-                  v-model="queryParams.recordstate"
-                  placeholder="璇烽�夋嫨璁板綍鐘舵��"
-                  clearable
-                  size="small"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_DonationStatus"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                  />
-                </el-select>
-              </el-form-item>
-              <div style="float: right; margin-bottom: 10px;">
-                <el-button
-                  type="primary"
-                  icon="el-icon-search"
-                  size="mini"
-                  @click="handleQuery"
-                  >鎼滅储</el-button
-                >
-                <el-button
-                  icon="el-icon-refresh"
-                  size="mini"
-                  @click="resetQuery"
-                  >閲嶇疆</el-button
-                >
-              </div>
-            </el-form>
-          </div>
-          <el-table
-            v-loading="loading"
-            border
-            highlight-current-row
-            :data="donatebaseinfoList"
-            @row-click="selectDonotor"
-          >
-            <!-- <el-table-column label="鎹愮尞缂栧彿" align="center" prop="donorno" /> -->
-            <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
-              <template slot-scope="scope">
-                <dict-tag
-                  :options="dict.type.sys_DonationStatus"
-                  :value="scope.row.recordstate"
-                />
-              </template>
-            </el-table-column>
-            <el-table-column label="濮撳悕" align="center" prop="name" />
-          </el-table>
-          <pagination
-            v-show="total > 0"
-            :total="total"
-            small
-            :page.sync="queryParams.pageNum"
-            :limit.sync="queryParams.pageSize"
-            @pagination="getBaseInfoList"
-          />
-        </el-card>
-      </el-col>
-      <el-col :span="18">
+      <el-col :span="24">
         <el-card shadow="naver">
           <el-form ref="infoform" label-width="100px">
-            <el-row :gutter="4" align="right" class="mb8">
-              <el-col :span="9">
-                <el-form-item label="鎹愮尞缂栧彿">
-                  <el-input
-                    v-model="curCase.donorno"
-                    :disabled="true"
-                  ></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :span="9">
-                <el-form-item label="濮撳悕">
-                  <el-input v-model="curCase.name" :disabled="true"></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col> </el-col>
-            </el-row>
+            <!-- 鎶ラ攢鍗曠瓫閫夛細鎹愮尞鑰呫�佸鎵圭姸鎬� -->
+            <el-form class="opo-query-form" :model="fundQueryParam" ref="fundQueryForm" :inline="true"
+              label-width="82px">
+              <el-row>
+                <el-col :span="6">
+                  <el-form-item label="鎹愮尞鑰�" prop="donorname">
+                    <el-input v-model="fundQueryParam.donorname" placeholder="璇疯緭鍏ユ崘鐚�呭鍚�" clearable size="small"
+                      @keyup.enter.native="handleQueryFund" />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label="瀹℃壒鐘舵��" prop="recordstatus">
+                    <el-select v-model="fundQueryParam.recordstatus" placeholder="璇烽�夋嫨瀹℃壒鐘舵��" clearable size="small"
+                      style="width: 100%">
+                      <el-option v-for="dict in dict.type.sys_recordstatus" :key="dict.value" :label="dict.label"
+                        :value="Number(dict.value)" />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="6">
+                  <el-form-item label-width="10px">
+                    <el-button type="primary" icon="el-icon-search" size="small" @click="handleQueryFund">鎼滅储</el-button>
+                    <el-button icon="el-icon-refresh" size="small" @click="resetFundQuery">閲嶇疆</el-button>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
             <el-row :gutter="10" class="mb8">
               <el-col :span="1.5">
-                <el-button
-                  type="primary"
-                  plain
-                  icon="el-icon-plus"
-                  size="mini"
-                  @click="handleAdd"
-                  v-hasPermi="['project:medicalfund:add']"
-                  >鏂板鐢宠鍗�</el-button
-                >
+                <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                  v-hasPermi="['project:medicalfund:add']">鏂板鐢宠鍗�</el-button>
               </el-col>
             </el-row>
             <el-row>
-              <el-table
-                v-loading="loading"
-                border
-                :data="donateconsolationfundList"
-                :row-class-name="rowClassName"
-              >
-                <el-table-column
-                  label="鐢宠鏃ユ湡"
-                  align="center"
-                  prop="applyTime"
-                  width="150px"
-                >
+              <el-table v-loading="loading" border :data="donateconsolationfundList" :row-class-name="rowClassName">
+                <el-table-column label="鐢宠鏃ユ湡" align="center" prop="applyTime" width="150px">
                   <template slot-scope="scope">
                     <span>{{
                       parseTime(scope.row.applyTime, "{y}-{m}-{d}")
                     }}</span>
                   </template>
                 </el-table-column>
-                <el-table-column
-                  label="鐢宠浜�"
-                  align="center"
-                  prop="username"
-                  width="120px"
-                />
-                <el-table-column
-                  label="鐢宠閲戦"
-                  align="center"
-                  prop="pretaxcost"
-                  width="200px"
-                />
-                <el-table-column
-                  label="鎵�灞炵粍鍒�"
-                  align="center"
-                  prop="deptmentname"
-                  width="220px"
-                />
-                <el-table-column
-                  label="缁勯暱"
-                  align="center"
-                  prop="managername"
-                  width="200px"
-                />
-                <el-table-column
-                  label="瀹℃牳鐘舵��"
-                  align="center"
-                  prop="recordstatus"
-                >
+                <el-table-column label="缁忓姙浜�" align="center" prop="username" width="120px" />
+                <el-table-column label="鐢宠閲戦" align="center" prop="pretaxcost" width="200px" />
+                <el-table-column label="瀹℃牳鐘舵��" align="center" prop="recordstatus">
                   <template slot-scope="scope">
-                    <dict-tag
-                      :options="dict.type.sys_recordstatus"
-                      :value="scope.row.recordstatus"
-                    />
+                    <dict-tag :options="dict.type.sys_recordstatus" :value="scope.row.recordstatus" />
                   </template>
                 </el-table-column>
-                <el-table-column
-                  label="鏉愭枡棰勫鐘舵��"
-                  width="140"
-                  align="center"
-                  prop="checkstatus"
-                >
+                <el-table-column label="鏉愭枡棰勫鐘舵��" width="140" align="center" prop="checkstatus">
                   <template slot-scope="scope">
-                    <dict-tag
-                      :options="dict.type.sys_stage_type"
-                      :value="scope.row.checkstatus"
-                    />
+                    <dict-tag :options="dict.type.sys_stage_type" :value="scope.row.checkstatus" />
                   </template>
                 </el-table-column>
+                <el-table-column label="鎹愮尞鑰�" align="center" prop="donorname" show-overflow-tooltip />
+                <el-table-column label="鎵�灞炵粍鍒�" align="center" prop="deptmentname"/>
+                <el-table-column label="缁勯暱" align="center" prop="managername" />
                 <!--
                   <el-table-column label="鑱旂郴鐢佃瘽" align="center" prop="phone" width="150px" />
                 <el-table-column label="宸ヤ綔鍗曚綅" align="center" prop="unitname" width="150px" />
                 -->
-                <el-table-column
-                  label="鎿嶄綔"
-                  fixed="right"
-                  align="center"
-                  class-name="small-padding fixed-width"
-                  width="280px"
-                >
+                <el-table-column label="鎿嶄綔" fixed="right" align="center" class-name="small-padding fixed-width"
+                  width="280px">
                   <template slot-scope="scope">
-                    <el-button
-                      v-if="
-                        scope.row.recordstatus == -1 ||
-                          scope.row.recordstatus == 1
-                      "
-                      size="mini"
-                      type="text"
-                      icon="el-icon-edit"
-                      @click="handleup(scope.row)"
-                      >涓婃姤</el-button
-                    >
-                    <el-button
-                      v-if="
-                        scope.row.recordstatus == -1 ||
-                          scope.row.recordstatus == 1
-                      "
-                      size="mini"
-                      type="text"
-                      icon="el-icon-edit"
-                      @click="handleUpdate(scope.row)"
-                      >淇敼</el-button
-                    >
-                    <el-button
-                      size="mini"
-                      type="text"
-                      icon="el-icon-view"
-                      @click="handleDetail(scope.row)"
-                      >鏌ョ湅</el-button
-                    >
-                    <el-button
-                      v-if="
-                        scope.row.recordstatus == -1 ||
-                          scope.row.recordstatus == 1
-                      "
-                      size="mini"
-                      type="text"
-                      @click="handleDelete(scope.row)"
-                      ><span class="button-delete"
-                        ><i class="el-icon-delete"></i>鍒犻櫎</span
-                      ></el-button
-                    >
-                    <el-button
-                      size="mini"
-                      type="text"
-                      icon="el-icon-download"
-                      @click="mixExport(scope.row.id)"
-                      >涓嬭浇</el-button
-                    >
+                    <el-button v-if="
+                      scope.row.recordstatus == -1 ||
+                      scope.row.recordstatus == 1
+                    " size="mini" type="text" icon="el-icon-edit" @click="handleup(scope.row)">涓婃姤</el-button>
+                    <el-button v-if="
+                      scope.row.recordstatus == -1 ||
+                      scope.row.recordstatus == 1
+                    " size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">淇敼</el-button>
+                    <el-button size="mini" type="text" icon="el-icon-view"
+                      @click="handleDetail(scope.row)">鏌ョ湅</el-button>
+                    <el-button v-if="
+                      scope.row.recordstatus == -1 ||
+                      scope.row.recordstatus == 1
+                    " size="mini" type="text" @click="handleDelete(scope.row)"><span class="button-delete"><i
+                          class="el-icon-delete"></i>鍒犻櫎</span></el-button>
+                    <el-button size="mini" type="text" icon="el-icon-download"
+                      @click="mixExport(scope.row.id)">涓嬭浇</el-button>
                   </template>
                 </el-table-column>
+                <!-- 2026-10-22锛氭寜瑕佹眰闅愯棌銆屽姛鑳姐�嶅垪锛堢嚎涓嬫姤閿�锛夛紝闇�瑕佹椂鍙栨秷娉ㄩ噴鍗冲彲鎭㈠ -->
+                <!--
                 <el-table-column
                   fixed="right"
                   align="center"
@@ -268,12 +109,64 @@
                     >
                   </template>
                 </el-table-column>
+                -->
               </el-table>
+              <!-- 鏈�夋嫨妗堜緥鏃跺睍绀鸿鐧诲綍浜哄叏閮ㄥ尰瀛︽垚鏈崟鎹紝瓒呰繃涓�椤靛彲鐢ㄥ垎椤电炕鐪� -->
+              <pagination v-show="fundTotal > 0" :total="fundTotal" small :page.sync="fundQueryParam.pageNum"
+                :limit.sync="fundQueryParam.pageSize" @pagination="listFundData" />
             </el-row>
           </el-form>
         </el-card>
       </el-col>
     </el-row>
+
+    <!-- 鏂板鐢宠鍗曞墠鍏堥�夋嫨鎹愮尞妗堜緥锛堝師宸︿晶妗堜緥鍒楄〃绉诲埌杩欓噷锛� -->
+    <el-dialog title="閫夋嫨鎹愮尞妗堜緥" :visible.sync="caseDialogVisible" width="760px" append-to-body>
+      <el-form class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" label-width="70px">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="濮撳悕" prop="name">
+              <el-input v-model="queryParams.name" placeholder="璇疯緭鍏ュ鍚�" clearable size="small"
+                @keyup.enter.native="handleQuery" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞杩涘害" prop="recordstate">
+              <el-select v-model="queryParams.recordstate" placeholder="璇烽�夋嫨璁板綍鐘舵��" clearable size="small"
+                style="width: 100%">
+                <el-option v-for="dict in dict.type.sys_DonationStatus" :key="dict.value" :label="dict.label"
+                  :value="dict.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label-width="10px">
+              <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">鎼滅储</el-button>
+              <el-button icon="el-icon-refresh" size="small" @click="resetQuery">閲嶇疆</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-table ref="caseTable" v-loading="loading" border height="380" highlight-current-row :data="donatebaseinfoList"
+        @row-click="selectDonotor">
+        <el-table-column label="鎹愮尞杩涘害" align="center" prop="recordstate">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.sys_DonationStatus" :value="scope.row.recordstate" />
+          </template>
+        </el-table-column>
+        <el-table-column label="濮撳悕" align="center" prop="name" />
+        <el-table-column label="鎿嶄綔" align="center" width="90">
+          <template slot-scope="scope">
+            <el-button type="text" size="mini" @click="selectDonotor(scope.row)">閫夋嫨</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="total > 0" :total="total" small :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize" @pagination="getBaseInfoList" />
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="caseDialogVisible = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -335,6 +228,7 @@
 import { getUserProfile } from "@/api/system/user";
 import { listFundflow } from "@/api/project/fundflow";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   //import寮曞叆鐨勭粍浠堕渶瑕佹敞鍏ュ埌瀵硅薄涓墠鑳戒娇鐢�
@@ -385,10 +279,13 @@
 
       fundQueryParam: {
         pageNum: 1,
-        pageSize: 100,
+        pageSize: 10,
         infoid: null,
         applytype: "3",
-        createBy: null
+        createBy: null,
+        // 鎶ラ攢鍗曠瓫閫夋潯浠�
+        donorname: null,
+        recordstatus: null
       },
       // 琛ㄥ崟鍙傛暟
       form: {},
@@ -410,6 +307,9 @@
       donatebaseinfoList: [],
       //褰撳墠閫変腑鎹愮尞妗堜緥
       curCase: {},
+      // 銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛堟柊澧炵敵璇峰崟鏃朵娇鐢級
+      caseDialogVisible: false,
+      casePickerMode: "",
       //鏄惁鏄剧ず璐圭敤鐢宠寮圭獥
       dialogOpen: false,
       // title: "",
@@ -418,6 +318,8 @@
 
       // 鎹愮尞浜洪亾鎱伴棶閲戣〃鏍兼暟鎹�
       donateconsolationfundList: [],
+      // 鍙充晶鎶ラ攢鍗曟�绘暟锛堢敤浜庡垎椤碉級
+      fundTotal: 0,
 
       //鏄庣粏璁板綍
       fundDetails: [],
@@ -471,11 +373,12 @@
   watch: {},
   //鐢熷懡鍛ㄦ湡 - 鍒涘缓瀹屾垚锛堝彲浠ヨ闂綋鍓峵his瀹炰緥锛�
   created() {
-    this.getList();
-    this.getBaseInfoList();
+    // 妗堜緥鍒楄〃宸茬Щ鍏ャ�岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛屾墦寮�瀵硅瘽妗嗘椂鍐嶆煡璇�
     this.getCurFundType();
     this.getlistUser();
     // this.getUnitList();
+    // 棣栧睆灞曠ず褰撳墠鐧诲綍浜虹殑鍏ㄩ儴鍖诲鎴愭湰鍗曟嵁
+    this.getAllfundList();
   },
 
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�
@@ -484,13 +387,13 @@
     this.getUsermsg();
   },
 
-  beforeCreate() {}, //鐢熷懡鍛ㄦ湡 - 鍒涘缓涔嬪墠
-  beforeMount() {}, //鐢熷懡鍛ㄦ湡 - 鎸傝浇涔嬪墠
-  beforeUpdate() {}, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪墠
-  updated() {}, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪悗
-  beforeDestroy() {}, //鐢熷懡鍛ㄦ湡 - 閿�姣佷箣鍓�
-  destroyed() {}, //鐢熷懡鍛ㄦ湡 - 閿�姣佸畬鎴�
-  activated() {}, //濡傛灉椤甸潰鏈塳eep-alive缂撳瓨鍔熻兘锛岃繖涓嚱鏁颁細瑙﹀彂
+  beforeCreate() { }, //鐢熷懡鍛ㄦ湡 - 鍒涘缓涔嬪墠
+  beforeMount() { }, //鐢熷懡鍛ㄦ湡 - 鎸傝浇涔嬪墠
+  beforeUpdate() { }, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪墠
+  updated() { }, //鐢熷懡鍛ㄦ湡 - 鏇存柊涔嬪悗
+  beforeDestroy() { }, //鐢熷懡鍛ㄦ湡 - 閿�姣佷箣鍓�
+  destroyed() { }, //鐢熷懡鍛ㄦ湡 - 閿�姣佸畬鎴�
+  activated() { }, //濡傛灉椤甸潰鏈塳eep-alive缂撳瓨鍔熻兘锛岃繖涓嚱鏁颁細瑙﹀彂
 
   //鏂规硶闆嗗悎
   methods: {
@@ -499,7 +402,7 @@
       this.queryParams.pageNum = 1;
       this.getList();
     },
-    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    /** 閲嶇疆鎸夐挳鎿嶄綔锛堟渚嬮�夋嫨瀵硅瘽妗嗗唴鐨勬渚嬫煡璇級 */
     resetQuery() {
       this.daterangeReporttime = [];
 
@@ -536,55 +439,24 @@
       });
     },
 
-    /** 鏂板鎸夐挳鎿嶄綔 */
+    /** 鏂板鎸夐挳鎿嶄綔锛氬厛寮瑰嚭銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇 */
     handleAdd() {
-      if (this.curCase.id) {
-        this.$router.push({
-          path: "/finance/applyDetail/",
-          query: {
-            id: 0,
-            businessType: "3",
-            operationType: "add",
-            curCase: this.curCase,
-          }
-        });
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [
-            h("span", null, "璇峰湪宸﹁竟鐨勬崘鐚渚嬭〃閫夋嫨闇�瑕佹搷浣滅殑妗堜緥锛�")
-          ])
-        });
-      }
-      return;
+      this.casePickerMode = "add";
+      this.caseDialogVisible = true;
+      this.getBaseInfoList();
+    },
 
-      if (this.curCase.id) {
-        this.istrue += 2;
-        this.reset();
-        this.queryParams.params = {};
-        this.form.donorno = this.curCase.donorno;
-        this.form.name = this.curCase.name;
-        this.form.infoid = this.curCase.id;
-        this.form.username = this.defaultperson.nickName;
-        this.form.userno = this.defaultperson.userName;
-        this.form.deptmentname = this.defaultperson.dept.deptName;
-        this.form.deptmentno = this.defaultperson.dept.deptId;
-        this.form.managername = this.defaultperson.dept.leader;
-
-        // this.form.createTime = nowdate;
-        //this.open = true;
-        //this.initFundApplyForm();
-        this.fundDetails = [];
-        this.addRow();
-        this.dialogOpen = true;
-        this.title = "娣诲姞璐圭敤鐢宠";
-        this.dialogType = "edit";
-      } else {
-        const h = this.$createElement;
-        this.$message({
-          message: h("p", null, [h("span", null, "璇峰厛閫夋嫨宸︽柟鎹愮尞妗堜緥 ")])
-        });
-      }
+    /** 鎼哄甫宸查�夋渚嬭烦杞埌鐢宠鍗曞~鍐欓〉 */
+    goApplyAdd() {
+      this.$router.push({
+        path: "/finance/applyDetail/",
+        query: {
+          id: 0,
+          businessType: "3",
+          operationType: "add",
+          curCase: this.curCase,
+        }
+      });
     },
     /** 淇敼鎸夐挳鎿嶄綔 */
     handleUpdate(row) {
@@ -615,8 +487,8 @@
         //闄勪欢澶勭悊
         this.fileList = this.form.annexbankcard
           ? this.form.annexbankcard
-              .split(",")
-              .map(item => ({ url: item, name: item }))
+            .split(",")
+            .map(item => ({ url: item, name: item }))
           : [];
 
         getownFundDetail(id).then(async res => {
@@ -662,8 +534,8 @@
         //闄勪欢澶勭悊
         this.fileList = this.form.annexbankcard
           ? this.form.annexbankcard
-              .split(",")
-              .map(item => ({ url: item, name: item }))
+            .split(",")
+            .map(item => ({ url: item, name: item }))
           : [];
 
         listFundflow(listFundflowparams).then(res => {
@@ -691,7 +563,7 @@
       const ids = row.id || this.ids;
       this.$modal
         .confirm("鏄惁纭鍒犻櫎璇ヨ褰曪紵")
-        .then(function() {
+        .then(function () {
           return delFund(ids);
         })
         .then(() => {
@@ -705,7 +577,7 @@
           this.getfundList();
           this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
 
     /** 涓婃姤鎸夐挳鎿嶄綔 */
@@ -884,20 +756,68 @@
       });
     },
 
-    //鐐瑰嚮鎹愮尞妗堜緥鍒楄〃瑙﹀彂鏂规硶
+    //鐐瑰嚮鎹愮尞妗堜緥鍒楄〃瑙﹀彂鏂规硶锛堟渚嬪垪琛ㄥ凡绉诲叆銆岄�夋嫨鎹愮尞妗堜緥銆嶅璇濇锛�
     selectDonotor(row, column, event) {
       this.curCase = row;
-      this.getfundList();
+      if (this.casePickerMode === "add") {
+        // 浠庛�屾柊澧炵敵璇峰崟銆嶈繘鍏ワ細閫夊畬妗堜緥鐩存帴璺冲埌鐢宠鍗曞~鍐欓〉
+        this.casePickerMode = "";
+        this.caseDialogVisible = false;
+        this.goApplyAdd();
+      }
     },
 
     getfundList() {
-      this.loading = true;
       this.reset();
+      // 閫変腑妗堜緥鍚庢寜妗堜緥灞曠ず锛屽悓鏃舵竻鎺夊垪琛ㄧ瓫閫夋潯浠讹紝閬垮厤涓や釜鏉′欢鍙犲姞瀵艰嚧绌哄垪琛�
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
       this.fundQueryParam.infoid = this.curCase.id;
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
+    },
+
+    /**
+     * 鎸夊綋鍓� fundQueryParam 鏌ヨ鍙充晶鎶ラ攢鍗曞垪琛�
+     * infoid 涓虹┖ = 褰撳墠鐧诲綍浜虹殑鍏ㄩ儴璇ョ被鍨嬪崟鎹紱鏈夊�� = 鎸囧畾妗堜緥
+     */
+    listFundData() {
+      this.loading = true;
       listFund(this.fundQueryParam).then(response => {
         this.loading = false;
         this.donateconsolationfundList = response.rows;
+        this.fundTotal = response.total;
       });
+    },
+
+    /** 鎶ラ攢鍗曠瓫閫夛細鎼滅储 */
+    handleQueryFund() {
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
+    },
+
+    /** 鎶ラ攢鍗曠瓫閫夛細閲嶇疆锛堟竻绌烘潯浠朵笌宸查�夋渚嬶紝鍥炲埌璇ョ櫥褰曚汉鍏ㄩ儴鍗曟嵁锛� */
+    resetFundQuery() {
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.getAllfundList();
+    },
+
+    /**
+     * 妫�绱㈠叏閮細鍙栨秷宸︿晶妗堜緥閫夋嫨涓庣瓫閫夋潯浠讹紝鏌ヨ褰撳墠鐧诲綍浜虹殑鍏ㄩ儴鍖诲鎴愭湰鍗曟嵁
+     */
+    getAllfundList() {
+      this.curCase = {};
+      // 鍚屾椂娓呮帀宸︿晶妗堜緥鍒楄〃鐨勯珮浜�変腑鎬�
+      if (this.$refs.caseTable) {
+        this.$refs.caseTable.setCurrentRow();
+      }
+      this.reset();
+      this.fundQueryParam.infoid = null;
+      this.fundQueryParam.donorname = null;
+      this.fundQueryParam.recordstatus = null;
+      this.fundQueryParam.pageNum = 1;
+      this.listFundData();
     },
 
     // 鍙栨秷鎸夐挳
@@ -1091,9 +1011,9 @@
                   tempData.itemid = tempItemArr[itemIndex].id;
                 }
                 if (tempData.id > 0) {
-                  updateFunddetail(tempData).then(response2 => {});
+                  updateFunddetail(tempData).then(response2 => { });
                 } else {
-                  addFunddetail(tempData).then(response2 => {});
+                  addFunddetail(tempData).then(response2 => { });
                 }
               }
             });
@@ -1190,41 +1110,40 @@
         });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee(row) {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetails.length; i++) {
+          const detail = this.fundDetails[i];
           let totalFee = 0;
           let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
-              totalFee += parseFloat(this.fundDetails[i].amount);
-              taxFee += parseFloat(this.fundDetails[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              taxFee = moneyAdd(taxFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetails[i].taxamount);
-              taxFee -= parseFloat(this.fundDetails[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
+              taxFee = moneySub(taxFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetails[i].price)) &&
-              !isNaN(parseFloat(this.fundDetails[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetails[i].price) *
-                parseFloat(this.fundDetails[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           if (!isNaN(parseFloat(taxFee))) {
-            this.fundDetails[i].taxedamount = taxFee.toFixed(2);
+            this.fundDetails[i].taxedamount = moneyRound(taxFee).toFixed(2);
           }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
       //this.form.amountrequested = allSum.toFixed(2);
-      this.$set(this.form, "amountrequested", allSum.toFixed(2));
+      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
       //this.$forceUpdate();
     },
 
@@ -1397,7 +1316,7 @@
     },
 
     //鏂囦欢涓婁紶
-    handleUploadError() {},
+    handleUploadError() { },
 
     handleremove(file) {
       this.fileList.splice(this.fileList.indexOf(file), 1);
@@ -1479,6 +1398,7 @@
 .button-delete {
   color: rgb(236, 69, 69);
 }
+
 ::v-deep.el-table .error-row {
   background: #fcebeb;
 }
diff --git a/src/views/project/fund/officeExpenseApply/index.vue b/src/views/project/fund/officeExpenseApply/index.vue
index ac02615..dc6fc04 100644
--- a/src/views/project/fund/officeExpenseApply/index.vue
+++ b/src/views/project/fund/officeExpenseApply/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -225,7 +226,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
               >
@@ -1709,41 +1710,40 @@
         });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee(row) {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetails.length; i++) {
+          const detail = this.fundDetails[i];
           let totalFee = 0;
           let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetails[i].amount))) {
-              totalFee += parseFloat(this.fundDetails[i].amount);
-              taxFee += parseFloat(this.fundDetails[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              taxFee = moneyAdd(taxFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetails[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetails[i].taxamount);
-              taxFee -= parseFloat(this.fundDetails[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
+              taxFee = moneySub(taxFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetails[i].price)) &&
-              !isNaN(parseFloat(this.fundDetails[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetails[i].price) *
-                parseFloat(this.fundDetails[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           if (!isNaN(parseFloat(taxFee))) {
-            this.fundDetails[i].taxedamount = taxFee.toFixed(2);
+            this.fundDetails[i].taxedamount = moneyRound(taxFee).toFixed(2);
           }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
       //this.form.amountrequested = allSum.toFixed(2);
-      this.$set(this.form, "amountrequested", allSum.toFixed(2));
+      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
       //this.$forceUpdate();
     },
 
@@ -1929,7 +1929,9 @@
       if (response.code == 200) {
         this.form.filename = file.raw.name;
         this.$modal.msgSuccess(response.msg);
-        this.fileList.push({ name: response.fileName, url: response.fileName });
+        // 2026-10-15锛氬垪琛ㄩ噷鐨� name 鐢ㄦ搷浣滀汉鐨勫師濮嬫枃浠跺悕锛屼笉瑕佺敤 response.fileName锛堥偅鏄瓨鍌ㄨ矾寰勶級銆�
+        // 淇濆瓨鏃跺彧鍥炲啓 url锛坒orm.annexbankcard 瀛樼殑鏄�楀彿鎷兼帴鐨� url锛夛紝鎵�浠ヨ繖閲屽彧褰卞搷涓婁紶妗嗙殑鏄剧ず銆�
+        this.fileList.push({ name: file.raw.name, url: response.fileName });
       } else {
         console.log(response.msg);
       }
diff --git a/src/views/project/fund/performanceApply/index.vue b/src/views/project/fund/performanceApply/index.vue
index 1b20cc1..84ab9c7 100644
--- a/src/views/project/fund/performanceApply/index.vue
+++ b/src/views/project/fund/performanceApply/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -53,7 +54,7 @@
           <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
             <el-date-picker
               format="yyyy-MM-dd"
-              value-format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd HH:mm:ss"
               v-model="queryParams.value1"
               type="daterange"
               range-separator="鑷�"
diff --git a/src/views/project/fund/performancedetails/index.vue b/src/views/project/fund/performancedetails/index.vue
index 5454ea9..3b5c533 100644
--- a/src/views/project/fund/performancedetails/index.vue
+++ b/src/views/project/fund/performancedetails/index.vue
@@ -11,7 +11,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
                 :disabled="true"
@@ -115,7 +115,7 @@
                 icon="el-icon-download"
                 size="small"
                 @click="Batchentry"
-                >鎵归噺褰曞叆浜哄憳</el-button
+                >鎵归噺瀵煎叆缁╂晥浜哄憳</el-button
               >
             </div>
           </el-col>
@@ -266,7 +266,7 @@
             <el-table-column
               prop="beneficiaryname"
               align="center"
-              label="缁╂晥浜哄憳鎴栧崟浣�"
+              label="缁╂晥浜哄憳/鍗曚綅"
               width="250"
             >
               <template slot-scope="scope">
@@ -283,13 +283,33 @@
               </template>
             </el-table-column>
             <el-table-column
+              prop="isunit"
+              align="center"
+              label="浜哄憳绫诲埆"
+              width="100"
+            >
+              <template slot-scope="scope">
+                <el-tag
+                  :type="scope.row.isunit == 1 ? 'warning' : 'success'"
+                  size="mini"
+                  >{{ scope.row.isunit == 1 ? "鍗曚綅" : "涓汉" }}</el-tag
+                >
+              </template>
+            </el-table-column>
+            <el-table-column
               prop="idcardno"
               align="center"
               label="韬唤璇佸彿"
               width="200"
             >
               <template slot-scope="scope">
-                <el-input v-model="scope.row.idcardno" placeholder="韬唤璇佸彿" />
+                <el-input
+                  v-model="scope.row.idcardno"
+                  :disabled="scope.row.isunit == 1"
+                  :placeholder="
+                    scope.row.isunit == 1 ? '鍗曚綅鏃犻渶濉啓' : '韬唤璇佸彿'
+                  "
+                />
               </template>
             </el-table-column>
 
@@ -470,34 +490,43 @@
       :visible.sync="showSelectionDialog"
       :close-on-click-modal="false"
       :title="'缁╂晥浜哄憳锛堝惈鎵�鍦ㄥ崟浣嶏級璐﹀彿閫夋嫨'"
-      width="500px"
+      width="560px"
       style="text-align: center"
       v-loading="loading"
     >
       <el-form ref="funddetailForm" :model="funddetailForm">
         <el-row>
-          <el-form-item label="璇疯緭鍏ラ�夋嫨锛�" prop="unitno" label-width="120px">
+          <el-form-item label="绛涙煡浜哄憳锛�" prop="userKey" label-width="120px">
             <el-select
-              v-model="funddetailForm.userName"
+              v-model="funddetailForm.userKey"
               filterable
-              remote
-              reserve-keyword
+              clearable
               allow-create
               default-first-option
-              placeholder="璇疯緭鍏ュ鍚嶆垨鍗曚綅鍚嶇О"
-              :remote-method="remoteMethod"
-              :loading="loadingperformance"
+              :filter-method="filterPersonOption"
+              placeholder="杈撳叆 濮撳悕 / 鍗曚綅 / 宸ュ彿 / 韬唤璇佸悗4浣� 绛涙煡锛屼篃鍙洿鎺ヨ緭鍏ュ鍚�"
               style="width: 100%"
             >
               <el-option
                 v-for="item in optionsperformance"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
+                :key="item.id"
+                :label="personOptionLabel(item)"
+                :value="item.id"
               >
+                <span style="float: left">{{ item.username }}</span>
+                <span style="float: right; color: #8492a6; font-size: 13px">
+                  {{
+                    item.isUnitPerson ? "鍗曚綅" : "宸ュ彿 " + (item.userno || "-")
+                  }}{{ item.unitname ? " 路 " + item.unitname : "" }}
+                </span>
               </el-option>
             </el-select>
           </el-form-item>
+        </el-row>
+        <el-row style="text-align: left; padding-left: 120px">
+          <span style="color: #909399; font-size: 12px">
+            鍊欓�変负浜哄憳绫诲瀷鍚�屽弬涓庣哗鏁堛�嶇殑浜哄憳锛涢�変腑鍚庤韩浠借瘉鍙枫�侀摱琛岃处鍙风瓑鑷姩甯﹀嚭锛屽崟浣嶄负鍗曚綅鐨勮涓嶆牎楠岃韩浠借瘉鍙枫��
+          </span>
         </el-row>
       </el-form>
       <span slot="footer" class="dialog-footer">
@@ -798,12 +827,25 @@
           <el-radio-button :label="70">骞村害缁╂晥</el-radio-button>
         </el-radio-group>
       </div>
+      <div style="margin-bottom: 12px; margin-left: 10px;">
+        <el-input
+          v-model="personKeyword"
+          clearable
+          size="small"
+          prefix-icon="el-icon-search"
+          placeholder="杈撳叆 濮撳悕 / 鍗曚綅 / 宸ュ彿 / 韬唤璇佸悗4浣� 绛涙煡"
+          style="width: 330px"
+        />
+        <span style="margin-left: 10px; color: #909399; font-size: 12px">
+          鍏� {{ filteredCityOptions.length }} 浜�
+        </span>
+      </div>
       <div style="max-height: 330px; overflow-y: auto">
         <el-checkbox
           :indeterminate="isIndeterminate"
           v-model="checkAll"
           @change="handleCheckAllChange"
-          >鍏ㄩ��</el-checkbox
+          >鍏ㄩ�夛紙褰撳墠绛涙煡缁撴灉锛�</el-checkbox
         >
         <div style="margin: 15px 0;"></div>
         <el-checkbox-group
@@ -812,10 +854,11 @@
         >
           <el-checkbox
             border
-            v-for="city in cityOptions"
+            v-for="city in filteredCityOptions"
             :label="city"
-            :key="city.userNo"
-            >{{ city.userName }}</el-checkbox
+            :key="city.id"
+            >{{ city.username }}{{ city.isUnitPerson ? "锛堝崟浣嶏級" : ""
+            }}{{ city.unitname ? " 路 " + city.unitname : "" }}</el-checkbox
           >
         </el-checkbox-group>
       </div>
@@ -859,7 +902,6 @@
   listOrganization,
   getOrganization,
   listReportname,
-  listperformance,
   listUser
 } from "@/api/project/organization";
 
@@ -876,6 +918,8 @@
 import Li_area_select from "@/components/Address";
 import OrgSelecter from "@/views/project/components/orgselect";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd, moneySub, moneyRound } from "@/utils/money";
+import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
 import CustomImageViewer from "@/components/CustomImageViewer";
 
 export default {
@@ -930,7 +974,10 @@
       feeUnitList: [],
       batchdialogVisible: false,
       itemlist: [],
+      //缁╂晥浜哄憳鍊欓�夛紙浜哄憳绫诲瀷鍚�屽弬涓庣哗鏁堛�嶇殑浜哄憳锛屾潵鑷� service_externalperson锛�
       cityOptions: [],
+      //鎵归噺褰曞叆寮规鐨勭瓫鏌ュ叧閿瓧
+      personKeyword: "",
       checkAll: false,
       checkedCities: [],
       Personnelforname: null,
@@ -1063,6 +1110,7 @@
 
       funddetailForm: {
         index: null,
+        userKey: null,
         userName: null,
         beneficiaryname: null,
         beneficiaryno: null,
@@ -1198,7 +1246,16 @@
   },
 
   //鐩戝惉灞炴�� 绫讳技浜巇ata姒傚康
-  computed: {},
+  computed: {
+    //鎵归噺褰曞叆寮规锛氭寜鍏抽敭瀛楋紙濮撳悕/鍗曚綅/宸ュ彿/韬唤璇佸悗4浣嶏級绛涙煡鍚庣殑鍊欓�変汉
+    filteredCityOptions() {
+      const kw = (this.personKeyword || "").trim().toLowerCase();
+      if (!kw) {
+        return this.cityOptions;
+      }
+      return this.cityOptions.filter(item => this.personMatchKeyword(item, kw));
+    }
+  },
   //鐩戞帶data涓殑鏁版嵁鍙樺寲
   watch: {},
   //鏂规硶闆嗗悎
@@ -1604,6 +1661,11 @@
     },
     /** 鎻愪氦鎸夐挳 */
     submitForm: debounce(function() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -1624,7 +1686,12 @@
               );
               return;
             }
-            if (tempDetail.idcardno == null) {
+            // 鍗曚綅琛岋紙isunit=1锛変笉闇�瑕佽韩浠借瘉鍙�
+            if (
+              tempDetail.isunit != 1 &&
+              (tempDetail.idcardno == null ||
+                String(tempDetail.idcardno).trim() === "")
+            ) {
               this.$modal.msgWarning(
                 "鏈嶅姟椤圭洰琛ㄤ腑锛岀" +
                   (k + 1).toString() +
@@ -1652,6 +1719,22 @@
                 return;
               }
             }
+          }
+
+          //鏄庣粏閲嶅鏍¢獙锛氬悓涓�浜哄憳/鍗曚綅涓嶅厑璁稿嚭鐜板琛�
+          const detailNameMap = {};
+          for (let k = 0; k < this.rbDetails.length; k++) {
+            const nm = String(this.rbDetails[k].beneficiaryname || "").trim();
+            if (!nm) {
+              continue;
+            }
+            if (detailNameMap[nm]) {
+              this.$modal.msgWarning(
+                "鏈嶅姟椤圭洰琛ㄤ腑锛屼汉鍛樺悕绉帮細" + nm + " 閲嶅锛岃鏍稿鍚庡啀鎻愪氦淇濆瓨锛�"
+              );
+              return;
+            }
+            detailNameMap[nm] = true;
           }
 
           //澶勭悊鏄庣粏
@@ -1808,11 +1891,7 @@
           this.$router.go(-1);
         } else {
           this.$modal.closeLoading();
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1865,7 +1944,7 @@
         this.personlist = res.rows;
         for (let j = 0; j < this.personlist.length; j++) {
           //鑾峰彇璐圭敤鎶ラ攢鏈烘瀯鍒楄〃
-          if (this.personlist[j].usertype == "org") {
+          if (this.hasUserType(this.personlist[j].usertype, "org")) {
             this.feeUnitList.push({
               id: this.personlist[j].id,
               reportNo: this.personlist[j].userno,
@@ -1876,7 +1955,7 @@
             });
           }
           //涓撳浜哄憳鍒楄〃
-          else if (res.rows[j].usertype == "expert") {
+          else if (this.hasUserType(res.rows[j].usertype, "expert")) {
             this.expertlist.push({
               expertNo: this.personlist[j].id,
               exportName: this.personlist[j].username
@@ -2065,9 +2144,8 @@
       }
     },
 
-    //绋庡墠鎵g◣绠楃◣鍚�
+    //绋庡墠鎵g◣绠楃◣鍚庯紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛�
     chargeSum(row, type) {
-      let targetValue = 0;
       for (let i = 0; i < this.rbDetails.length; i++) {
         if (!this.rbDetails[i].amount) {
           this.rbDetails[i].amount = 0;
@@ -2075,17 +2153,16 @@
         if (!this.rbDetails[i].taxamount) {
           this.rbDetails[i].taxamount = 0;
         }
-        this.rbDetails[i].taxedamount = (
-          parseFloat(this.rbDetails[i].amount) -
-          parseFloat(this.rbDetails[i].taxamount)
+        //绋庡墠 - 鎵g◣ = 绋庡悗锛堟诞鐐圭浉鍑忎細娈嬬暀鏋佸皬灏惧樊锛屽鑷村嚭鐜� -0.00锛�
+        this.rbDetails[i].taxedamount = moneySub(
+          this.rbDetails[i].amount,
+          this.rbDetails[i].taxamount
         ).toFixed(2);
-        targetValue += parseFloat(this.rbDetails[i].amount); // 鍋囪姣忎釜瀵硅薄涓殑鐗瑰畾鍊煎瓨鍌ㄥ湪'specificValue'灞炴�т笅
-        console.log(this.rbDetails[i].taxedamount, "鍚堣");
       }
-      console.log(targetValue, "鍚堣");
-      this.form.pretaxcost = targetValue;
+      //鍚堣蹇呴』绮剧‘绱姞锛屽惁鍒欎細鍐欏叆 form.pretaxcost 骞惰惤搴�
+      this.form.pretaxcost = moneySum(this.rbDetails, "amount");
     },
-    //绋庡悗鎵g◣绠楃◣鍓�
+    //绋庡悗鎵g◣绠楃◣鍓嶏紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛�
     queenchargeSum(row, type) {
       for (let i = 0; i < this.rbDetails.length; i++) {
         if (!this.rbDetails[i].amount) {
@@ -2094,9 +2171,10 @@
         if (!this.rbDetails[i].taxamount) {
           this.rbDetails[i].taxamount = 0;
         }
-        this.rbDetails[i].amount =
-          parseFloat(this.rbDetails[i].taxamount) +
-          parseFloat(this.rbDetails[i].taxedamount);
+        //鎵g◣ + 绋庡悗 = 绋庡墠锛堝繀椤荤簿纭浉鍔犲苟褰掍竴鍖栧埌 2 浣嶏紝鍚﹀垯浼氭畫鐣欓暱灏忔暟锛�
+        this.rbDetails[i].amount = moneyRound(
+          moneyAdd(this.rbDetails[i].taxamount, this.rbDetails[i].taxedamount)
+        );
       }
     },
 
@@ -2106,6 +2184,11 @@
     },
     // 鎺ュ彈鎻愰啋绔嬪埢淇濆瓨
     Savenow() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -2151,6 +2234,22 @@
                 return;
               }
             }
+          }
+
+          //鏄庣粏閲嶅鏍¢獙锛氬悓涓�浜哄憳/鍗曚綅涓嶅厑璁稿嚭鐜板琛�
+          const detailNameMap = {};
+          for (let k = 0; k < this.rbDetails.length; k++) {
+            const nm = String(this.rbDetails[k].beneficiaryname || "").trim();
+            if (!nm) {
+              continue;
+            }
+            if (detailNameMap[nm]) {
+              this.$modal.msgWarning(
+                "鏈嶅姟椤圭洰琛ㄤ腑锛屼汉鍛樺悕绉帮細" + nm + " 閲嶅锛岃鏍稿鍚庡啀鎻愪氦淇濆瓨锛�"
+              );
+              return;
+            }
+            detailNameMap[nm] = true;
           }
 
           //澶勭悊鏄庣粏
@@ -2239,16 +2338,18 @@
         }
       });
     },
-    // 鍏ㄩ��
+    // 鍏ㄩ�夛紙鎸夊綋鍓嶇瓫鏌ョ粨鏋滐級
     handleCheckAllChange(val) {
-      this.checkedCities = val ? this.cityOptions : [];
+      this.checkedCities = val ? this.filteredCityOptions.slice() : [];
       this.isIndeterminate = false;
     },
     handleCheckedCitiesChange(value) {
       let checkedCount = value.length;
-      this.checkAll = checkedCount === this.cityOptions.length;
+      this.checkAll =
+        this.filteredCityOptions.length > 0 &&
+        checkedCount === this.filteredCityOptions.length;
       this.isIndeterminate =
-        checkedCount > 0 && checkedCount < this.cityOptions.length;
+        checkedCount > 0 && checkedCount < this.filteredCityOptions.length;
     },
     // 鎵嬪姩璁$畻
     Manualcalculationfn() {
@@ -2273,18 +2374,107 @@
     },
     // 鎵归噺褰曞叆鐐瑰嚮
     Batchentry() {
-      // ethical
-      this.listperformance();
+      this.personKeyword = "";
+      this.checkedCities = [];
+      this.checkAll = false;
+      this.isIndeterminate = false;
       this.batchdialogVisible = true;
     },
+    /**
+     * 杞藉叆缁╂晥浜哄憳鍊欓�夈��
+     * 鏀归�犲墠鍙栬嚜浜哄憳鍒嗙粍琛紙service_externalperson_group锛実roup_id=1锛夛紱
+     * 2026-09-27 璧锋敼涓恒�屼汉鍛樼被鍨嬶紙UserType锛屽彲澶氶�夛級鍚� 鍙備笌缁╂晥銆嶇殑澶栧洿浜哄憳璐︽埛锛�
+     * 涓嶅啀渚濊禆鍒嗙粍琛ㄣ��
+     */
     listperformance() {
-      listperformance(1).then(res => {
-        this.cityOptions = res.data;
-        this.listperformancea = [];
-        this.listperformancea = this.cityOptions.map(item => {
-          return { value: item.userName, label: item.userName };
-        });
+      listExternalperson({
+        usertype: "performance",
+        pageNum: 1,
+        pageSize: 10000
+      }).then(res => {
+        const rows = res.rows || [];
+        this.cityOptions = rows
+          //鍙繚鐣欏惎鐢ㄨ处鍙凤紙涓庢敼閫犲墠鍒嗙粍琛ㄦ帴鍙g殑 userstatus=1 鍙e緞涓�鑷达級銆�
+          //娉ㄦ剰锛歋erviceExternalperson 瀹炰綋娌℃湁 del_flag 瀛楁锛屾帴鍙d笉杩斿洖璇ュ瓧娈碉紝
+          //涓嶈兘鐢ㄥ畠鍋氳繃婊わ紝鍚﹀垯 undefined == 0 浼氭妸鍏ㄩ儴鍊欓�変汉婊ょ┖銆�
+          .filter(
+            item =>
+              item.userstatus === undefined ||
+              item.userstatus === null ||
+              item.userstatus == 1
+          )
+          .map(item => {
+            return Object.assign({}, item, {
+              isUnitPerson: this.hasUserType(item.usertype, "org")
+            });
+          });
       });
+    },
+    /** 浜哄憳绫诲瀷锛堝鍊硷紝閫楀彿鍒嗛殧锛夋槸鍚﹀寘鍚寚瀹氱被鍨� */
+    hasUserType(usertype, code) {
+      if (!usertype) {
+        return false;
+      }
+      return (
+        String(usertype)
+          .split(",")
+          .map(t => t.trim())
+          .indexOf(code) > -1
+      );
+    },
+    /** 鍏抽敭瀛楀懡涓垽鏂細濮撳悕 / 鍗曚綅 / 宸ュ彿 / 韬唤璇佸悗4浣� */
+    personMatchKeyword(item, kw) {
+      const idcard = String(item.idcardno || "");
+      return (
+        String(item.username || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        String(item.unitname || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        String(item.userno || "")
+          .toLowerCase()
+          .indexOf(kw) > -1 ||
+        (idcard.length >= 4 && idcard.slice(-4).indexOf(kw) > -1)
+      );
+    },
+    /** 璇嗗埆浜哄憳绫诲埆锛氬崟浣嶏紙浜哄憳绫诲瀷鍚� org锛夎繕鏄釜浜� */
+    isUnitPerson(item) {
+      return !!(item && this.hasUserType(item.usertype, "org"));
+    },
+    /** 閫夋嫨妗嗕笅鎷夐」鏂囨锛氬鍚嶏紙鍗曚綅锛� */
+    personOptionLabel(item) {
+      return (
+        (item.username || "") +
+        (item.unitname ? "锛�" + item.unitname + "锛�" : "") +
+        (item.isUnitPerson ? " - 鍗曚綅" : "")
+      );
+    },
+    /** 閫夋嫨妗嗗�欓�夛細绌哄叧閿瓧杩斿洖鍏ㄩ儴锛屽惁鍒欐寜鍏抽敭瀛楃瓫鏌� */
+    filterPersonCandidates(kw) {
+      if (!kw) {
+        return this.cityOptions.slice();
+      }
+      return this.cityOptions.filter(item => this.personMatchKeyword(item, kw));
+    },
+    /** 閫夋嫨妗嗘湰鍦扮瓫鏌ワ紙濮撳悕/鍗曚綅/宸ュ彿/韬唤璇佸悗4浣嶏級 */
+    filterPersonOption(query) {
+      const kw = (query || "").trim().toLowerCase();
+      this.optionsperformance = this.filterPersonCandidates(kw);
+      // 宸查�変腑椤硅淇濈暀鍦ㄤ笅鎷夐噷锛屽惁鍒欏洖鏄句細绌虹櫧
+      const picked = this.getPickedPerson(this.funddetailForm.userKey);
+      if (picked && this.optionsperformance.indexOf(picked) === -1) {
+        this.optionsperformance = [picked].concat(this.optionsperformance);
+      }
+    },
+    /** 鎸夊敮涓�閿紙浜哄憳 ID锛夊彇鍊欓�夛紱鎵嬪伐杈撳叆鐨勫鍚嶈繑鍥� null */
+    getPickedPerson(key) {
+      if (key === null || key === undefined || key === "") {
+        return null;
+      }
+      return (
+        this.cityOptions.find(item => String(item.id) === String(key)) || null
+      );
     },
     // 纭褰曞叆
     BatchentryFn() {
@@ -2292,23 +2482,42 @@
       if (!this.rbDetails[0].applytype) {
         this.rbDetails = [];
       }
+      // 鏄庣粏涓凡鏈夌殑浜哄憳濮撳悕锛岀敤浜庨噸澶嶆彁閱掞紙涓庝鸡鐞嗕笓瀹惰垂椤电殑鍒ら噸鍙e緞涓�鑷达級
+      const existed = {};
+      this.rbDetails.forEach(row => {
+        if (row.beneficiaryname) {
+          existed[String(row.beneficiaryname).trim()] = true;
+        }
+      });
+
+      const duplicated = [];
       this.checkedCities.forEach(item => {
+        const nameKey = String(item.username || "").trim();
+        if (nameKey && existed[nameKey]) {
+          duplicated.push(item.username);
+          return;
+        }
+        if (nameKey) {
+          existed[nameKey] = true;
+        }
+        const isunit = this.isUnitPerson(item);
         let rowData = {
           orderno: null,
           fundid: null,
-          beneficiaryname: item.userName,
-          beneficiaryno: item.usertNo,
+          beneficiaryname: item.username,
+          beneficiaryno: item.userno,
+          isunit: isunit ? 1 : 0,
           unitname: item.unitname,
-          unitno: null,
+          unitno: item.unitno,
           uintuserno: null,
           title: item.title,
           idcardtype: null,
-          idcardno: item.idcrad,
+          idcardno: isunit ? "" : item.idcardno,
           sex: null,
           familyrelations: null,
-          phone: null,
-          depositbank: item.depositBank,
-          bankcardno: item.bankCardNo,
+          phone: item.telephone,
+          depositbank: item.depositbank,
+          bankcardno: item.bankcardno,
           branchbankname: item.branchbankname,
           annexbankcard: null,
           annexregistform: null,
@@ -2351,6 +2560,11 @@
       this.calculateTax();
       this.batchdialogVisible = false;
       this.checkedCities = [];
+      if (duplicated.length) {
+        this.$modal.msgWarning(
+          "浠ヤ笅浜哄憳鍦ㄦ槑缁嗕腑宸插瓨鍦紝宸茶烦杩囬噸澶嶆坊鍔狅細" + duplicated.join("銆�")
+        );
+      }
       console.log(this.rowfeeItemTypes);
     },
     //鏂板涓�琛�
@@ -2361,6 +2575,7 @@
         fundid: null,
         beneficiaryname: null,
         beneficiaryno: null,
+        isunit: 0,
         unitname: null,
         unitno: null,
         uintuserno: null,
@@ -2460,64 +2675,78 @@
         });
       //鍏ㄩ儴鍒犻櫎鍚庢坊鍔犱竴鏉℃柊琛�
     },
-    //涓撳/鍖荤枟鏈烘瀯/璐圭敤鎶ラ攢鏈烘瀯閫夋嫨
+    //缁╂晥浜哄憳/鍗曚綅閫夋嫨锛氭墦寮�鏃堕濉綋鍓嶈宸查�変汉鍛橈紝閬垮厤"鐩存帴纭畾"鎶婂凡鏈夊鍚嶆竻绌�
     ShowDetailDialog(spoce, showType) {
       this.spocewl = spoce;
       this.selectionType = showType;
-      this.selectionType = this.experthear;
-      this.expertfrom = "1";
       this.funddetailForm.index = spoce.$index;
       this.funddetailForm.beneficiaryno = spoce.row.beneficiaryno;
       this.funddetailForm.beneficiaryname = spoce.row.beneficiaryname;
       this.funddetailForm.unitno = spoce.row.unitno;
       this.funddetailForm.unitname = spoce.row.unitname;
-      this.funddetailForm.expertname = "";
-      this.funddetailForm.expertidcardno = "";
-      this.funddetailForm.expertunitno = "";
-      this.funddetailForm.expertunitname = "";
-      this.funddetailForm.experttitle = "";
-      this.funddetailForm.expertdepositbank = "";
-      this.funddetailForm.expertbankcardno = "";
+      //褰撳墠琛屽凡閫変汉鍛樼殑鍥炲~锛氬厛鎸変汉鍛樼紪鍙峰尮閰嶏紝鍖归厤涓嶅埌鍐嶆寜濮撳悕鍖归厤
+      let cur =
+        this.cityOptions.find(
+          item => String(item.userno) === String(spoce.row.beneficiaryno)
+        ) || null;
+      if (!cur && spoce.row.beneficiaryname) {
+        cur =
+          this.cityOptions.find(
+            item => item.username === spoce.row.beneficiaryname
+          ) || null;
+      }
+      this.funddetailForm.userKey = cur
+        ? cur.id
+        : spoce.row.beneficiaryname || null;
+      this.funddetailForm.userName = spoce.row.beneficiaryname || null;
+      //鎵撳紑鏃跺睍绀哄叏閲忓�欓�夛紝渚夸簬鐩存帴娴忚绛涙煡
+      this.optionsperformance = this.cityOptions.slice();
       this.showSelectionDialog = true;
     },
 
-    //涓撳/鍖荤枟鏈烘瀯/璐圭敤鎶ラ攢鏈烘瀯閫夋嫨
+    /**
+     * 纭畾閫夋嫨锛氭寜鍞竴閿紙浜哄憳 ID锛夊尮閰嶅�欓�夛紝
+     * 鑷姩甯﹀嚭韬唤璇佸彿銆侀摱琛岃处鍙枫�佸紑鎴烽摱琛屻�佺數璇濄�佽亴绉般�佷汉鍛樼紪鍙枫�佸崟浣嶏紱
+     * 鍗曚綅锛堜汉鍛樼被鍨嬪惈 org锛変笉鍐欒韩浠借瘉鍙凤紱鎵嬪伐杈撳叆鐨勫鍚嶄笉鍋氬甫鍑恒��
+     */
     ConfirmDetailDialog() {
-      let tempIndex = this.funddetailForm.index;
-      let tempExpertName = this.funddetailForm.userName;
-      let singleDetail = this.rbDetails[tempIndex];
+      const tempIndex = this.funddetailForm.index;
+      const singleDetail = this.rbDetails[tempIndex];
+      const key = this.funddetailForm.userKey;
 
-      //浠庝笓瀹跺垪琛ㄨ幏鍙栦俊鎭�
-      this.cityOptions.map(res => {
-        if (tempExpertName == res.userName) {
-          singleDetail.beneficiaryno = res.userno;
-          singleDetail.bankcardno = res.bankCardNo;
-          singleDetail.branchbankname = res.branchbankname;
-          singleDetail.depositbank = res.depositBank;
-          singleDetail.idcardno = res.idcardNo;
-          singleDetail.phone = res.telephone;
-          singleDetail.title = res.title;
-          singleDetail.unitname = res.unitname;
-          singleDetail.unitno = parseInt(res.unitno);
-        }
-      });
-      singleDetail.beneficiaryname = tempExpertName;
-      this.rbDetails[tempIndex] = singleDetail;
-      this.showSelectionDialog = false;
-    },
-    remoteMethod(query) {
-      console.log(this.listperformancea);
-      if (query !== "") {
-        this.loadingperformance = true;
-        setTimeout(() => {
-          this.loadingperformance = false;
-          this.optionsperformance = this.listperformancea.filter(item => {
-            return item.label.toLowerCase().indexOf(query.toLowerCase()) > -1;
-          });
-        }, 200);
-      } else {
-        this.optionsperformance = [];
+      if (key === null || key === undefined || key === "") {
+        this.$modal.msgWarning("璇峰厛绛涙煡骞堕�夋嫨缁╂晥浜哄憳锛屾垨鐩存帴杈撳叆浜哄憳濮撳悕锛�");
+        return;
       }
+
+      const person = this.getPickedPerson(key);
+      if (person) {
+        // 鍛戒腑浜哄憳搴擄細鑷姩甯﹀嚭鍏ㄩ儴淇℃伅
+        const isunit = this.isUnitPerson(person);
+        singleDetail.beneficiaryname = person.username;
+        singleDetail.beneficiaryno = person.userno;
+        singleDetail.isunit = isunit ? 1 : 0;
+        singleDetail.idcardno = isunit ? "" : person.idcardno;
+        singleDetail.bankcardno = person.bankcardno;
+        singleDetail.branchbankname = person.branchbankname;
+        singleDetail.depositbank = person.depositbank;
+        singleDetail.phone = person.telephone;
+        singleDetail.title = person.title;
+        singleDetail.unitname = person.unitname;
+        singleDetail.unitno = person.unitno;
+      } else {
+        // 鎵嬪伐杈撳叆鐨勪汉鍛橈細鍙啓濮撳悕锛岃韩浠借瘉鍙�/閾惰璐﹀彿鐢辩粡鍔炰汉濉啓
+        singleDetail.beneficiaryname = String(key);
+        singleDetail.isunit = 0;
+        this.$modal.msgWarning(
+          "浜哄憳搴撲腑鏈壘鍒般��" +
+            key +
+            "銆嶏紝宸叉寜鎵嬪伐褰曞叆澶勭悊锛岃鑷濉啓韬唤璇佸彿銆侀摱琛岃处鍙风瓑淇℃伅銆�"
+        );
+      }
+
+      this.$set(this.rbDetails, tempIndex, singleDetail);
+      this.showSelectionDialog = false;
     },
     handleUploadError() {},
     remove(file, fileList) {
@@ -2541,7 +2770,43 @@
         this.Networkheader = string.slice(0, index + 4); // 鎴彇8032鍙婂叾鍓嶉儴瀛楃
       }
     },
+    /**
+     * 2026-10-15锛氫笂浼犳椂鏍¢獙闄勪欢鏂囦欢鍚嶏紙涓氬姟瑕佹眰锛氫笉鍚堟牸绔嬪嵆鎻愮ず涓斾笉鍔犲叆鍒楄〃锛夈��
+     * 瑙勫垯涓庡悗绔� AttachmentNameValidator 鍚屽彛寰勶細蹇呴』鍚腑鏂� / 鍘绘帀鎵╁睍鍚嶅悗涓诲共 鈮�20 瀛� /
+     * 涓嶅惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗︺��
+     */
+    checkUploadFileName(file) {
+      const raw = file && file.raw ? file.raw.name : file && file.name;
+      const r = checkFileName(raw);
+      if (!r.ok) {
+        this.$modal.msgError(r.msg);
+        return false;
+      }
+      return true;
+    },
+
+    /**
+     * 2026-10-15锛氫繚瀛樺墠鏍¢獙鏁村崟鏄庣粏闄勪欢鏂囦欢鍚嶏紙鍚悓涓�琛屽唴閲嶅悕锛夈��
+     * 鍙e緞锛堜笟鍔$‘璁わ級锛氬彧鏍¢獙"鏈鍙樻洿"鐨勯檮浠垛�斺�旇�佸崟鎹噷宸插瓨鍦ㄧ殑涓嶅悎瑙勯檮浠跺悕涓嶈兘鎶婁繚瀛樺崱姝�
+     * 锛堝惁鍒欒�佸崟鎹敼涓�涓噾棰濋兘瀛樹笉杩涘幓锛夈�傚悗绔寜 id 璇绘棫璁板綍鏀捐鍘嗗彶闄勪欢锛涘墠绔嬁涓嶅埌"鍝簺鏄巻鍙�"
+     * 鐨勬潈濞佷俊鎭紝鍥犳**浠呮柊澧炲崟鎹�**鍋氫繚瀛樺墠鎷︽埅锛岀紪杈戣�佸崟鎹椂鏂板鐨勪笉鍚堣闄勪欢鐢卞悗绔簩娆℃牎楠屾嫤涓嬨��
+     */
+    checkDetailFileNames() {
+      if (this.form && this.form.id) {
+        return true;
+      }
+      const c = checkDetails(this.rbDetails);
+      if (!c.ok) {
+        this.$modal.msgError(c.msg);
+        return false;
+      }
+      return true;
+    },
+
     uploadSccess(response, file, fileList) {
+      if (!this.checkUploadFileName(file)) {
+        return;
+      }
       this.rbDetails;
       const config = {
         headers: { Authorization: "Bearer " + this.ICDtoken }
diff --git a/src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue b/src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue
index d882563..4b31bfd 100644
--- a/src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue
+++ b/src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
       <el-row>
         <el-col :span="5">
           <el-form-item label="鎹愮尞妗堜緥" prop="donorname" style="float: left">
@@ -41,7 +42,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd"
+            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd HH:mm:ss"
               v-model="applyTime" type="daterange" range-separator="鑷�" start-placeholder="鐢宠寮�濮嬫棩鏈�"
               end-placeholder="鐢宠缁撴潫鏃ユ湡" @keyup.enter.native="flowconclusion">
             </el-date-picker>
@@ -311,7 +312,7 @@
           <el-col :span="7">
             <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
               <!-- <el-input v-model="form.donorno" placeholder="璇疯緭鍏ョ敵璇锋棩鏈�" /> -->
-              <el-date-picker clearable style="width: 100%" v-model="form.applyTime" type="date"
+              <el-date-picker clearable style="width: 100%" v-model="form.applyTime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
@@ -362,7 +363,7 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="dundcheck" v-if="dialogType == 'edit'">瀹℃牳</el-button>
+        <el-button type="primary" :loading="checkSubmitLoading" :disabled="checkSubmitLoading" @click="dundcheck" v-if="dialogType == 'edit'">瀹℃牳</el-button>
         <el-button @click="cancel">鍙栨秷</el-button>
       </div>
     </el-dialog>
@@ -437,6 +438,7 @@
 
 // 瀵煎叆鏈湴瀛樺偍鐨勬柟娉�
 import { setItem, grtItem, removeItem } from "@/utils/storage.js";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   components: {
@@ -460,6 +462,7 @@
   ],
   data() {
     return {
+      checkSubmitLoading: false,
       arrr2: [],
       arrr3: [],
       //璐圭敤绫诲瀷鏁扮粍
@@ -692,6 +695,7 @@
       });
     },
     dundcheck() {
+      if (this.checkSubmitLoading) return;
       // this.$em
 
       //console.log("1234567", this.form.flowlevelone, this.form.flowconclusion);
@@ -708,7 +712,9 @@
         this.$modal.msgError("璇烽�夋嫨瀹℃牳缁撹!");
         return;
       }
+      this.checkSubmitLoading = true;
       checkfund(checkfundobj).then(res => {
+        this.checkSubmitLoading = false;
         if (res.code == 200) {
           console.log("瀹℃牳璐圭敤", res);
           this.dialogOpen = false;
@@ -717,11 +723,7 @@
           this.getlistbypower();
         } else {
           this.dialogOpen = false;
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1469,49 +1471,45 @@
       });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee() {
-      let allSum = 0;
+      const detailsArr = [];
       let preTaxSum = 0;
       let taxedSum = 0;
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetailArr.length; i++) {
+          const detail = this.fundDetailArr[i];
           let totalFee = 0;
-          let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
-              totalFee += parseFloat(this.fundDetailArr[i].amount);
-              taxFee += parseFloat(this.fundDetailArr[i].amount);
-              preTaxSum += parseFloat(this.fundDetailArr[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              preTaxSum = moneyAdd(preTaxSum, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
-              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
             }
             //taxedamount
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxedamount))) {
-              taxedSum += parseFloat(this.fundDetailArr[i].taxedamount);
+            if (!isNaN(parseFloat(detail.taxedamount))) {
+              taxedSum = moneyAdd(taxedSum, detail.taxedamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
-              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetailArr[i].price) *
-                parseFloat(this.fundDetailArr[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           // if (!isNaN(parseFloat(taxFee))) {
           //   this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
           // }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
-      this.form.amountrequested = allSum.toFixed(2);
-      this.form.pretaxcost = preTaxSum.toFixed(2);
-      this.form.taxedcost = taxedSum.toFixed(2);
+      this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
+      this.form.pretaxcost = moneyRound(preTaxSum).toFixed(2);
+      this.form.taxedcost = moneyRound(taxedSum).toFixed(2);
       this.$forceUpdate();
       console.log(this.form);
     },
diff --git a/src/views/project/fundcheck/expertFeeCheck/index.vue b/src/views/project/fundcheck/expertFeeCheck/index.vue
index a25bc43..4bddc41 100644
--- a/src/views/project/fundcheck/expertFeeCheck/index.vue
+++ b/src/views/project/fundcheck/expertFeeCheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
       <el-row>
         <el-col :span="5">
           <el-form-item label="鎹愮尞妗堜緥" prop="donorname" style="float: left">
@@ -48,7 +49,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
-            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd"
+            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd HH:mm:ss"
               v-model="createTime" type="daterange" range-separator="鑷�" start-placeholder="鐢宠寮�濮嬫棩鏈�"
               end-placeholder="鐢宠缁撴潫鏃ユ湡" @keyup.enter.native="flowconclusion">
             </el-date-picker>
@@ -157,7 +158,7 @@
           <el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
               <!-- <el-input v-model="form.donorno" placeholder="璇疯緭鍏ョ敵璇锋棩鏈�" /> -->
-              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date"
+              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
@@ -397,7 +398,7 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="dundcheck" v-if="dialogType == 'edit'">淇濆瓨</el-button>
+        <el-button type="primary" :loading="checkSubmitLoading" :disabled="checkSubmitLoading" @click="dundcheck" v-if="dialogType == 'edit'">淇濆瓨</el-button>
         <el-button @click="cancel">鍙栨秷</el-button>
       </div>
     </el-dialog>
@@ -421,7 +422,8 @@
   checkfund,
   listbypower,
   addFundSharedInfo,
-  TotalcalculationFn
+  TotalcalculationFn,
+  validateExpertFee
 } from "@/api/project/fund";
 import {
   onelistFunds,
@@ -494,6 +496,7 @@
   ],
   data() {
     return {
+      checkSubmitLoading: false,
       arrr2: [],
       arrr3: [],
       personlist: [],
@@ -723,6 +726,7 @@
       });
     },
     dundcheck() {
+      if (this.checkSubmitLoading) return;
       // this.$em
 
       let checkfundobj = {
@@ -738,18 +742,38 @@
         this.$modal.msgError("璇烽�夋嫨瀹℃牳缁撹!");
         return;
       }
+
+      // 瀹℃牳鈥滈�氳繃鈥濆墠锛氬厛鍋氫笓瀹跺姵鍔¤垂 9 鏉¤垂鐢ㄦ帶鍒舵牎楠岋紙涓庡悗绔嫤鎴悓鍙e緞锛�
+      if (checkfundobj.flowconclusion == 1) {
+        validateExpertFee({ id: this.form.id }).then(valid => {
+          const errors = (valid && valid.errors) || [];
+          const warnings = (valid && valid.warnings) || [];
+          if (warnings.length > 0) {
+            this.$modal.msgWarning(warnings.join("锛�"));
+          }
+          if (errors.length > 0) {
+            this.$modal.msgError("涓嶈兘瀹℃牳閫氳繃锛�" + errors.join("锛�"));
+            return;
+          }
+          this.doCheckfund(checkfundobj);
+        });
+        return;
+      }
+      // 涓嶉�氳繃锛氭棤闇�鏍¢獙闄愰
+      this.doCheckfund(checkfundobj);
+    },
+    doCheckfund(checkfundobj) {
+      this.checkSubmitLoading = true;
       checkfund(checkfundobj).then(res => {
+        this.checkSubmitLoading = false;
         if (res.code == 200) {
           this.reset();
           this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
           this.getlistbypower();
           this.dialogOpen = false;
         } else {
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          // 鍚庣杩斿洖鐨勫叿浣撳師鍥狅紙濡傝秴闄愰锛変紭鍏堝睍绀�
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫");
         }
       });
     },
diff --git a/src/views/project/fundcheck/medicalCostCheck/index.vue b/src/views/project/fundcheck/medicalCostCheck/index.vue
index 464203a..415efc9 100644
--- a/src/views/project/fundcheck/medicalCostCheck/index.vue
+++ b/src/views/project/fundcheck/medicalCostCheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
       <el-row align="left">
         <el-col :span="5">
           <el-form-item label="鎹愮尞妗堜緥" prop="donorname" style="float: left">
@@ -48,7 +49,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
-            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd"
+            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd HH:mm:ss"
               v-model="createTime" type="daterange" range-separator="鑷�" start-placeholder="鐢宠寮�濮嬫棩鏈�"
               end-placeholder="鐢宠缁撴潫鏃ユ湡" @keyup.enter.native="flowconclusion">
             </el-date-picker>
@@ -145,7 +146,7 @@
           <el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
               <!-- <el-input v-model="form.donorno" placeholder="璇疯緭鍏ョ敵璇锋棩鏈�" /> -->
-              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date"
+              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
@@ -421,7 +422,7 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="dundcheck" v-if="dialogType == 'edit'">纭</el-button>
+        <el-button type="primary" :loading="checkSubmitLoading" :disabled="checkSubmitLoading" @click="dundcheck" v-if="dialogType == 'edit'">纭</el-button>
         <el-button @click="cancel">鍙栨秷</el-button>
       </div>
     </el-dialog>
@@ -496,6 +497,7 @@
 import { listDept } from "@/api/system/dept";
 import { getToken } from "@/utils/auth";
 import { setItem, grtItem, removeItem } from "@/utils/storage.js";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   components: {
@@ -519,6 +521,7 @@
   ],
   data() {
     return {
+      checkSubmitLoading: false,
       arrr2: [],
       arrr3: [],
       //璐圭敤绫诲瀷鏁扮粍
@@ -730,6 +733,7 @@
       });
     },
     dundcheck() {
+      if (this.checkSubmitLoading) return;
       // this.$em
       this.dialogOpen = false;
       let checkfundobj = {
@@ -737,17 +741,15 @@
         flowcontent: this.newobj.flowconclusion,
         fundid: this.newobj.fundid
       };
+      this.checkSubmitLoading = true;
       checkfund(checkfundobj).then(res => {
+        this.checkSubmitLoading = false;
         if (res.code == 200) {
           this.reset();
           this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
           this.getlistbypower();
         } else {
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1443,41 +1445,40 @@
       // });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee() {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetailArr.length; i++) {
+          const detail = this.fundDetailArr[i];
           let totalFee = 0;
           let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
-              totalFee += parseFloat(this.fundDetailArr[i].amount);
-              taxFee += parseFloat(this.fundDetailArr[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              taxFee = moneyAdd(taxFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
-              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
+              taxFee = moneySub(taxFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
-              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetailArr[i].price) *
-                parseFloat(this.fundDetailArr[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           if (!isNaN(parseFloat(taxFee))) {
-            this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
+            this.fundDetailArr[i].taxedamount = moneyRound(taxFee).toFixed(2);
           }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
       //this.form.amountrequested = allSum.toFixed(2);
-      this.$set(this.form, "amountrequested", allSum.toFixed(2));
+      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
       //this.$forceUpdate();
     },
 
diff --git a/src/views/project/fundcheck/officeExpenseCheck/index.vue b/src/views/project/fundcheck/officeExpenseCheck/index.vue
index 45b6ac6..68a8220 100644
--- a/src/views/project/fundcheck/officeExpenseCheck/index.vue
+++ b/src/views/project/fundcheck/officeExpenseCheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
       <el-row align="left">
         <el-col :span="5">
           <el-form-item label="鎹愮尞妗堜緥" prop="donorname" style="float: left">
@@ -48,7 +49,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
-            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd"
+            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd HH:mm:ss"
               v-model="createTime" type="daterange" range-separator="鑷�" start-placeholder="鐢宠寮�濮嬫棩鏈�"
               end-placeholder="鐢宠缁撴潫鏃ユ湡" @keyup.enter.native="flowconclusion">
             </el-date-picker>
@@ -148,7 +149,7 @@
           <el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
               <!-- <el-input v-model="form.donorno" placeholder="璇疯緭鍏ョ敵璇锋棩鏈�" /> -->
-              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date"
+              <el-date-picker clearable style="width: 100%" v-model="form.createTime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
@@ -424,7 +425,7 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="dundcheck" v-if="dialogType == 'edit'">纭</el-button>
+        <el-button type="primary" :loading="checkSubmitLoading" :disabled="checkSubmitLoading" @click="dundcheck" v-if="dialogType == 'edit'">纭</el-button>
         <el-button @click="cancel">鍙栨秷</el-button>
       </div>
     </el-dialog>
@@ -499,6 +500,7 @@
 import { listDept } from "@/api/system/dept";
 import { getToken } from "@/utils/auth";
 import { setItem, grtItem, removeItem } from "@/utils/storage.js";
+import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
 
 export default {
   components: {
@@ -522,6 +524,7 @@
   ],
   data() {
     return {
+      checkSubmitLoading: false,
       arrr2: [],
       arrr3: [],
       //璐圭敤绫诲瀷鏁扮粍
@@ -735,6 +738,7 @@
       });
     },
     dundcheck() {
+      if (this.checkSubmitLoading) return;
       // this.$em
       this.dialogOpen = false;
       let checkfundobj = {
@@ -742,17 +746,15 @@
         flowcontent: this.newobj.flowconclusion,
         fundid: this.newobj.fundid
       };
+      this.checkSubmitLoading = true;
       checkfund(checkfundobj).then(res => {
+        this.checkSubmitLoading = false;
         if (res.code == 200) {
           this.reset();
           this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
           this.getlistbypower();
         } else {
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1448,41 +1450,40 @@
       // });
     },
 
-    //璁$畻鎬婚噾棰�
+    //璁$畻鎬婚噾棰濓紙閲戦涓�寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee() {
-      let allSum = 0;
+      const detailsArr = [];
       if (this.form.applytype != null) {
         for (let i = 0; i < this.fundDetailArr.length; i++) {
+          const detail = this.fundDetailArr[i];
           let totalFee = 0;
           let taxFee = 0;
           if (this.form.applytype == 1 || this.form.applytype == 2) {
-            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-            if (!isNaN(parseFloat(this.fundDetailArr[i].amount))) {
-              totalFee += parseFloat(this.fundDetailArr[i].amount);
-              taxFee += parseFloat(this.fundDetailArr[i].amount);
+            //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣锛氱◣鍓� - 鎵g◣
+            if (!isNaN(parseFloat(detail.amount))) {
+              totalFee = moneyAdd(totalFee, detail.amount);
+              taxFee = moneyAdd(taxFee, detail.amount);
             }
-            if (!isNaN(parseFloat(this.fundDetailArr[i].taxamount))) {
-              totalFee -= parseFloat(this.fundDetailArr[i].taxamount);
-              taxFee -= parseFloat(this.fundDetailArr[i].taxamount);
+            if (!isNaN(parseFloat(detail.taxamount))) {
+              totalFee = moneySub(totalFee, detail.taxamount);
+              taxFee = moneySub(taxFee, detail.taxamount);
             }
           } else if (this.form.applytype == 3) {
             if (
-              !isNaN(parseFloat(this.fundDetailArr[i].price)) &&
-              !isNaN(parseFloat(this.fundDetailArr[i].quantity))
+              !isNaN(parseFloat(detail.price)) &&
+              !isNaN(parseFloat(detail.quantity))
             ) {
-              totalFee +=
-                parseFloat(this.fundDetailArr[i].price) *
-                parseFloat(this.fundDetailArr[i].quantity);
+              totalFee = moneyMul(detail.price, detail.quantity);
             }
           }
           if (!isNaN(parseFloat(taxFee))) {
-            this.fundDetailArr[i].taxedamount = taxFee.toFixed(2);
+            this.fundDetailArr[i].taxedamount = moneyRound(taxFee).toFixed(2);
           }
-          allSum += totalFee;
+          detailsArr.push(totalFee);
         }
       }
       //this.form.amountrequested = allSum.toFixed(2);
-      this.$set(this.form, "amountrequested", allSum.toFixed(2));
+      this.$set(this.form, "amountrequested", moneyRound(moneySum(detailsArr)).toFixed(2));
       //this.$forceUpdate();
     },
 
diff --git a/src/views/project/fundcheck/performanceCheck/index.vue b/src/views/project/fundcheck/performanceCheck/index.vue
index 25e804d..a91e77e 100644
--- a/src/views/project/fundcheck/performanceCheck/index.vue
+++ b/src/views/project/fundcheck/performanceCheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
       <el-row align="left">
         <el-col :span="5">
           <el-form-item label="棰勫鐘舵��" prop="checkstatus" style="float: left">
@@ -34,7 +35,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
-            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd" v-model="createTime"
+            <el-date-picker format="yyyy-MM-dd" @change="selectapplication" value-format="yyyy-MM-dd HH:mm:ss" v-model="createTime"
               type="daterange" range-separator="鑷�" start-placeholder="鐢宠寮�濮嬫棩鏈�" end-placeholder="鐢宠缁撴潫鏃ユ湡"
               @keyup.enter.native="flowconclusion">
             </el-date-picker>
diff --git a/src/views/project/funddetail/index.vue b/src/views/project/funddetail/index.vue
index 5c18378..bca48aa 100644
--- a/src/views/project/funddetail/index.vue
+++ b/src/views/project/funddetail/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="涓撳濮撳悕" prop="beneficiaryname">
         <el-input v-model="queryParams.beneficiaryname" placeholder="璇疯緭鍏ヤ笓瀹跺鍚�" clearable size="small"
           @keyup.enter.native="handleQuery" />
diff --git a/src/views/project/fundflow/index.vue b/src/views/project/fundflow/index.vue
index ea3836b..446e86c 100644
--- a/src/views/project/fundflow/index.vue
+++ b/src/views/project/fundflow/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <!-- <el-form-item label="璐圭敤缂栧彿锛屽樊鏃呰垂鍏宠仈琛╯ervice_reimbursement ID; 璐圭敤鍏宠仈璐圭敤琛╯ervice_fund鐨処D" prop="fundid">
         <el-input
           v-model="queryParams.fundid"
@@ -31,7 +32,7 @@
         <el-form-item label="鐢宠鏃ユ湡" prop="createTime">
         <el-date-picker
           format="yyyy-MM-dd"
-          value-format="yyyy-MM-dd hh:mm:ss"
+          value-format="yyyy-MM-dd HH:mm:ss"
           v-model="queryParams.createTime"
           type="date"
           placeholder="璇烽�夋嫨鐢宠鏃ユ湡"
diff --git a/src/views/project/fundflowrule/index.vue b/src/views/project/fundflowrule/index.vue
index 402cf69..1c5541f 100644
--- a/src/views/project/fundflowrule/index.vue
+++ b/src/views/project/fundflowrule/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/project/fundstatistics/index.vue b/src/views/project/fundstatistics/index.vue
index 35195cc..585ce95 100644
--- a/src/views/project/fundstatistics/index.vue
+++ b/src/views/project/fundstatistics/index.vue
@@ -3,7 +3,8 @@
   <div class="app-container">
     <el-col :span="24" v-if="showType == 'list'">
       <el-card shadow="never">
-        <el-form :model="queryParams" ref="queryForm" :inline="true">
+        <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true">
           <el-form-item label="濮撳悕" prop="name">
             <el-input
               v-model="queryParams.name"
diff --git a/src/views/project/itemexpense/index.vue b/src/views/project/itemexpense/index.vue
index e7303c7..17442ab 100644
--- a/src/views/project/itemexpense/index.vue
+++ b/src/views/project/itemexpense/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鏈嶅姟椤圭洰ID" prop="itemid">
         <el-input
           v-model="queryParams.itemid"
@@ -97,6 +98,13 @@
       <el-table-column label="璐圭敤閲戦" align="center" prop="expense" />
       <el-table-column label="璐圭敤璇存槑" align="center" prop="expensedescribe" />
       <el-table-column label="鍚敤鐘舵��" align="center" prop="usestate" />
+      <el-table-column label="鏍¢獙妯″紡" align="center" prop="validateMode" width="110">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.validateMode == 3" type="danger">涓嶆牎楠�</el-tag>
+          <el-tag v-else-if="scope.row.validateMode == 2" type="warning">鏍¢獙鎻愰啋</el-tag>
+          <el-tag v-else>寮哄埗鏍¢獙</el-tag>
+        </template>
+      </el-table-column>
       <el-table-column label="澶囨敞" align="center" prop="remark" />
       <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
@@ -140,6 +148,13 @@
         </el-form-item>
         <el-form-item label="鍚敤鐘舵��" prop="usestate">
           <el-input v-model="form.usestate" placeholder="璇疯緭鍏ュ惎鐢ㄧ姸鎬�" />
+        </el-form-item>
+        <el-form-item label="鏍¢獙妯″紡" prop="validateMode">
+          <el-select v-model="form.validateMode" placeholder="璇烽�夋嫨涓撳璐规牎楠屾ā寮�" style="width: 100%">
+            <el-option label="寮哄埗鏍¢獙锛堜笉閫氳繃涓嶈兘淇濆瓨锛�" :value="1" />
+            <el-option label="鏍¢獙鎻愰啋锛堜粎鎻愰啋锛屽厑璁镐繚瀛橈級" :value="2" />
+            <el-option label="涓嶆牎楠岋紙璺宠繃閲戦绫绘牎楠岋級" :value="3" />
+          </el-select>
         </el-form-item>
         <el-form-item label="澶囨敞" prop="remark">
           <el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" />
@@ -222,6 +237,7 @@
         expense: null,
         expensedescribe: null,
         usestate: null,
+        validateMode: 1,
         remark: null,
         delFlag: null,
         createBy: null,
diff --git a/src/views/project/medicalevaluation/index.vue b/src/views/project/medicalevaluation/index.vue
index 257e87d..aed7410 100644
--- a/src/views/project/medicalevaluation/index.vue
+++ b/src/views/project/medicalevaluation/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -410,7 +411,7 @@
                   clearable
                   size="small"
                   v-model="form.hospitalassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨闄㈢骇璇勪及鏃堕棿"
                 >
@@ -463,7 +464,7 @@
                   clearable
                   size="small"
                   v-model="form.provincialassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨鐪佺骇璇勪及鏃堕棿"
                 >
@@ -517,7 +518,7 @@
                   clearable
                   size="small"
                   v-model="form.coreteamassesstime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="璇勪及鏃堕棿"
                 >
diff --git a/src/views/project/organallocation/index.vue b/src/views/project/organallocation/index.vue
index 9af341f..8060a6f 100644
--- a/src/views/project/organallocation/index.vue
+++ b/src/views/project/organallocation/index.vue
@@ -3,6 +3,7 @@
   <div class="app-container">
     <!-- 鎼滅储鏉′欢 -->
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -337,7 +338,7 @@
                 size="small"
                 style="width: 100%"
                 v-model="form.applicanttime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鎺ユ敹鏃堕棿"
               >
diff --git a/src/views/project/organallocation/index0.vue b/src/views/project/organallocation/index0.vue
index 7b1d4c8..5805f7e 100644
--- a/src/views/project/organallocation/index0.vue
+++ b/src/views/project/organallocation/index0.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="70px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="70px">
       <el-row>
         <el-col :span="6">
           <el-form-item label="鎹愮尞鑰�" prop="name">
@@ -198,7 +199,7 @@
         <el-row>
           <el-col :span="12">
             <el-form-item label="鑾峰彇鏃堕棿" prop="organgettime">
-              <el-date-picker clearable size="medium" v-model="form.organgettime" type="date" disabled
+              <el-date-picker clearable size="medium" v-model="form.organgettime" type="date" format="yyyy-MM-dd" disabled
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鍣ㄥ畼鑾峰彇鏃堕棿">
               </el-date-picker>
             </el-form-item>
@@ -248,7 +249,7 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="绉绘鏃堕棿" prop="transplanttime">
-              <el-date-picker clearable size="medium" v-model="form.transplanttime" type="date"
+              <el-date-picker clearable size="medium" v-model="form.transplanttime" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨绉绘鏃堕棿" disabled>
               </el-date-picker>
             </el-form-item>
diff --git a/src/views/project/organization/index.vue b/src/views/project/organization/index.vue
index 7cb588f..9cf2ee0 100644
--- a/src/views/project/organization/index.vue
+++ b/src/views/project/organization/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -272,7 +273,7 @@
                 clearable
                 size="small"
                 v-model="form.registertime"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨娉ㄥ唽鏃堕棿"
               >
diff --git a/src/views/project/register/index.vue b/src/views/project/register/index.vue
new file mode 100644
index 0000000..cfac46a
--- /dev/null
+++ b/src/views/project/register/index.vue
@@ -0,0 +1,351 @@
+<template>
+  <div class="app-container">
+    <!-- 鏌ヨ鏉′欢锛氭寜閽揣璺熸潯浠朵箣鍚庯紙涓庢渚嬭瘎浼伴〉椋庢牸涓�鑷达級 -->
+    <el-form
+      class="opo-query-form"
+      :model="queryParams"
+      ref="queryForm"
+      :inline="true"
+      v-show="showSearch"
+      label-width="82px"
+    >
+      <el-row>
+        <el-col :span="6">
+          <el-form-item label="鎹愮尞鑰�" prop="name">
+            <el-input
+              v-model="queryParams.name"
+              placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+              clearable
+              size="small"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="璇佷欢鍙风爜" prop="idcardno">
+            <el-input
+              v-model="queryParams.idcardno"
+              placeholder="璇疯緭鍏ヨ瘉浠跺彿鐮�"
+              clearable
+              size="small"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="鍣ㄥ畼绫诲埆" prop="organno">
+            <el-select
+              v-model="queryParams.organno"
+              placeholder="璇烽�夋嫨鍣ㄥ畼绫诲埆"
+              clearable
+              size="small"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="dict in dict.type.sys_Organ"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="鑾峰彇鐘舵��" prop="organstate">
+            <el-select
+              v-model="queryParams.organstate"
+              placeholder="璇烽�夋嫨鑾峰彇鐘舵��"
+              clearable
+              size="small"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="dict in dict.type.sys_organstate"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="6">
+          <el-form-item label="鍣ㄥ畼缂栧彿" prop="organnumber">
+            <el-input
+              v-model="queryParams.organnumber"
+              placeholder="璇疯緭鍏ュ櫒瀹樼紪鍙�"
+              clearable
+              size="small"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="绉绘鏈烘瀯" prop="transplanthospitalname">
+            <el-input
+              v-model="queryParams.transplanthospitalname"
+              placeholder="璇疯緭鍏ョЩ妞嶆満鏋勫悕绉�"
+              clearable
+              size="small"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="绉绘浜�" prop="acceptname">
+            <el-input
+              v-model="queryParams.acceptname"
+              placeholder="璇疯緭鍏ョЩ妞嶄汉濮撳悕"
+              clearable
+              size="small"
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label-width="10px">
+            <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="el-icon-refresh" size="small" @click="resetQuery">閲嶇疆</el-button>
+            <el-button
+              type="warning"
+              plain
+              icon="el-icon-download"
+              size="small"
+              :loading="exportLoading"
+              @click="handleExport"
+              v-hasPermi="['project:register:export']"
+            >瀵煎嚭</el-button>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="mb8">
+        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      </el-row>
+    </el-form>
+
+    <el-table v-loading="loading" :data="registerList" :border="true">
+      <el-table-column label="鎹愮尞鑰呯紪鍙�" align="center" prop="donorno" width="200" show-overflow-tooltip />
+      <el-table-column label="濮撳悕" align="center" prop="name" width="90" show-overflow-tooltip />
+      <el-table-column label="鎬у埆" align="center" prop="sex" width="70">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex" />
+        </template>
+      </el-table-column>
+      <el-table-column label="骞撮緞" align="center" width="80">
+        <template slot-scope="scope">
+          <span v-if="scope.row.age">{{ scope.row.age }}{{ scope.row.ageunit }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="鍣ㄥ畼绫诲埆" align="center" prop="organname" width="90" show-overflow-tooltip />
+      <el-table-column label="鍣ㄥ畼缂栧彿" align="center" prop="organnumber" width="130" show-overflow-tooltip />
+      <el-table-column label="鑾峰彇鐘舵��" align="center" prop="organstate" width="100">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_organstate" :value="scope.row.organstate" />
+        </template>
+      </el-table-column>
+      <el-table-column label="鑾峰彇鏃堕棿" align="center" prop="organgettime" width="150">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.organgettime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="鑾峰彇鏈烘瀯" align="center" prop="gainhospitalname" min-width="180" show-overflow-tooltip />
+      <el-table-column label="绉绘鏈烘瀯" align="center" prop="transplanthospitalname" min-width="180" show-overflow-tooltip />
+      <el-table-column label="绉绘鍖荤敓" align="center" prop="transplantdoct" width="100" show-overflow-tooltip />
+      <el-table-column label="绉绘鏃堕棿" align="center" prop="transplanttime" width="150">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.transplanttime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" align="center" width="90" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+            v-hasPermi="['project:register:query']"
+          >璇︽儏</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 璇︽儏锛氬彧璇诲睍绀哄叏閮ㄥ瓧娈� -->
+    <el-dialog title="鍣ㄥ畼鍘诲璇︽儏" :visible.sync="open" width="900px" append-to-body>
+      <div v-loading="detailLoading" class="register-detail">
+        <el-divider content-position="left">鎹愮尞鑰呬俊鎭�</el-divider>
+        <el-descriptions :column="3" size="small" border>
+          <el-descriptions-item label="濮撳悕">{{ detail.name }}</el-descriptions-item>
+          <el-descriptions-item label="鎬у埆">{{ dictLabel("sys_user_sex", detail.sex) }}</el-descriptions-item>
+          <el-descriptions-item label="骞撮緞">
+            <span v-if="detail.age">{{ detail.age }}{{ detail.ageunit }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="璇佷欢鍙风爜">{{ detail.idcardno }}</el-descriptions-item>
+          <el-descriptions-item label="鍑虹敓鏃ユ湡">{{ parseTime(detail.birthday, "{y}-{m}-{d}") }}</el-descriptions-item>
+          <el-descriptions-item label="鑱旂郴鐢佃瘽">{{ detail.phone }}</el-descriptions-item>
+          <el-descriptions-item label="鐜颁綇鍦板潃" :span="3">{{ detail.residenceaddress }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞鑰呯紪鍙�">{{ detail.donorno }}</el-descriptions-item>
+        </el-descriptions>
+
+        <el-divider content-position="left">鍣ㄥ畼淇℃伅</el-divider>
+        <el-descriptions :column="3" size="small" border>
+          <el-descriptions-item label="鍣ㄥ畼绫诲埆">{{ detail.organname }}</el-descriptions-item>
+          <el-descriptions-item label="鍣ㄥ畼缂栧彿">{{ detail.organnumber }}</el-descriptions-item>
+          <el-descriptions-item label="鑾峰彇鐘舵��">
+            {{ dictLabel("sys_organstate", detail.organstate) }}
+          </el-descriptions-item>
+          <el-descriptions-item label="鑾峰彇鏃堕棿">{{ parseTime(detail.organgettime) }}</el-descriptions-item>
+          <el-descriptions-item label="鑾峰彇鍖荤敓" :span="2">{{ detail.organgetdoct }}</el-descriptions-item>
+          <el-descriptions-item label="鑾峰彇鏈烘瀯" :span="2">{{ detail.gainhospitalname }}</el-descriptions-item>
+          <el-descriptions-item label="绉绘鏈烘瀯" :span="2">{{ detail.transplanthospitalname }}</el-descriptions-item>
+          <el-descriptions-item label="绉绘鍖荤敓">{{ detail.transplantdoct }}</el-descriptions-item>
+          <el-descriptions-item label="绉绘鏃堕棿" :span="2">{{ parseTime(detail.transplanttime) }}</el-descriptions-item>
+        </el-descriptions>
+
+        <el-divider content-position="left">鐢宠涓庡鏍�</el-divider>
+        <el-descriptions :column="3" size="small" border>
+          <el-descriptions-item label="鐢宠浜�">{{ detail.applicantusername }}</el-descriptions-item>
+          <el-descriptions-item label="鐢宠鏃堕棿" :span="2">{{ parseTime(detail.applicanttime) }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃牳浜�">{{ detail.checkusername }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃牳鏃堕棿" :span="2">{{ parseTime(detail.checktime) }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃牳鎰忚" :span="3">{{ detail.checksuggestion }}</el-descriptions-item>
+        </el-descriptions>
+
+        <el-divider content-position="left">绉绘浜轰俊鎭�</el-divider>
+        <el-descriptions :column="3" size="small" border>
+          <el-descriptions-item label="濮撳悕">{{ detail.acceptname }}</el-descriptions-item>
+          <el-descriptions-item label="鎬у埆">{{ dictLabel("sys_user_sex", detail.acceptsex) }}</el-descriptions-item>
+          <el-descriptions-item label="骞撮緞">
+            <span v-if="detail.acceptage">{{ detail.acceptage }}{{ detail.acceptageunit }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="璇佷欢鍙风爜">{{ detail.acceptidcard }}</el-descriptions-item>
+          <el-descriptions-item label="鑱旂郴鐢佃瘽" :span="2">{{ detail.acceptphone }}</el-descriptions-item>
+          <el-descriptions-item label="鐜颁綇鍦板潃" :span="3">{{ detail.acceptresidenceaddress }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="open = false">鍏� 闂�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listRegister, getRegister, exportRegister } from "@/api/project/register";
+
+export default {
+  name: "Register",
+  dicts: ["sys_Organ", "sys_organstate", "sys_user_sex", "sys_AgeUnit"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 璇︽儏鍔犺浇
+      detailLoading: false,
+      // 瀵煎嚭閬僵灞�
+      exportLoading: false,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鍣ㄥ畼鍘诲鍒楄〃
+      registerList: [],
+      // 璇︽儏寮圭獥
+      open: false,
+      detail: {},
+      // 鏌ヨ鍙傛暟锛堝潎闇�涓庡悗绔� queryList / Mapper 鏀寔鐨勬潯浠朵竴鑷达級
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: null,
+        idcardno: null,
+        organno: null,
+        organstate: null,
+        organnumber: null,
+        transplanthospitalname: null,
+        acceptname: null
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 鏌ヨ鍣ㄥ畼鍘诲鍒楄〃 */
+    getList() {
+      this.loading = true;
+      listRegister(this.queryParams).then(response => {
+        this.registerList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 璇︽儏鎸夐挳鎿嶄綔 */
+    handleDetail(row) {
+      this.detail = {};
+      this.open = true;
+      this.detailLoading = true;
+      getRegister(row.id).then(response => {
+        this.detail = response.data || {};
+        this.detailLoading = false;
+      }).catch(() => {
+        this.detailLoading = false;
+      });
+    },
+    /** 瀛楀吀缈昏瘧锛堟ā鏉块噷鐢紝閬垮厤澶氫釜 dict-tag 宓屽锛� */
+    dictLabel(type, value) {
+      const list = this.dict.type[type] || [];
+      const item = list.find(d => String(d.value) === String(value));
+      return item ? item.label : value;
+    },
+    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
+    handleExport() {
+      this.$modal
+        .confirm("鏄惁纭瀵煎嚭鍣ㄥ畼鍘诲鏁版嵁锛�")
+        .then(() => {
+          this.exportLoading = true;
+          return exportRegister(this.queryParams);
+        })
+        .then(response => {
+          this.$download.name(response.msg);
+          this.exportLoading = false;
+        })
+        .catch(() => {
+          this.exportLoading = false;
+        });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.register-detail >>> .el-divider--horizontal {
+  margin: 12px 0 14px;
+}
+.register-detail >>> .el-divider__text {
+  color: var(--opo-primary, #0e768f);
+  font-size: var(--opo-font-size-sm, 14px);
+}
+.register-detail >>> .el-descriptions-item__label {
+  color: var(--opo-text-secondary, #6b7280);
+  width: 90px;
+}
+</style>
diff --git a/src/views/project/reimbursement/index.vue b/src/views/project/reimbursement/index.vue
index 232e0c3..925099e 100644
--- a/src/views/project/reimbursement/index.vue
+++ b/src/views/project/reimbursement/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鍒涘缓鑰�" prop="createBy">
         <el-input
           v-model="queryParams.createBy"
diff --git a/src/views/project/reimbursementdetail/index.vue b/src/views/project/reimbursementdetail/index.vue
index be5864d..1fbc503 100644
--- a/src/views/project/reimbursementdetail/index.vue
+++ b/src/views/project/reimbursementdetail/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鍒涘缓浜�" prop="createBy">
         <el-input
           v-model="queryParams.createBy"
diff --git a/src/views/project/reimbursementpayee/index.vue b/src/views/project/reimbursementpayee/index.vue
index 9d5d82e..efa84e1 100644
--- a/src/views/project/reimbursementpayee/index.vue
+++ b/src/views/project/reimbursementpayee/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="璧勯噾鐢宠涓昏〃ID" prop="rbid">
         <el-input
           v-model="queryParams.rbid"
diff --git a/src/views/project/relativesconfirmation/index.vue b/src/views/project/relativesconfirmation/index.vue
index 16104e2..16d116d 100644
--- a/src/views/project/relativesconfirmation/index.vue
+++ b/src/views/project/relativesconfirmation/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -588,8 +589,8 @@
                   clearable
                   size="small"
                   v-model="form.signdate"
-                  type="date"
-                  value-format="yyyy-MM-dd hh:mm:ss"
+                  type="date" format="yyyy-MM-dd"
+                  value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="閫夋嫨绛惧瓧鏃ユ湡"
                 >
                 </el-date-picker>
@@ -745,8 +746,8 @@
                 size="small"
                 style="width: 310px"
                 v-model="evaluationForm.hospitalassesstime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨闄㈢骇璇勪及鏃堕棿"
               >
               </el-date-picker>
@@ -792,8 +793,8 @@
                 size="small"
                 style="width: 310px"
                 v-model="evaluationForm.provincialassesstime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="閫夋嫨鐪佺骇璇勪及鏃堕棿"
               >
               </el-date-picker>
@@ -840,8 +841,8 @@
                 size="small"
                 style="width: 310px"
                 v-model="evaluationForm.coreteamassesstime"
-                type="date"
-                value-format="yyyy-MM-dd hh:mm:ss"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="璇勪及鏃堕棿"
               >
               </el-date-picker>
diff --git a/src/views/project/statistics/applyStatistics/index.vue b/src/views/project/statistics/applyStatistics/index.vue
index 8e32401..447eb92 100644
--- a/src/views/project/statistics/applyStatistics/index.vue
+++ b/src/views/project/statistics/applyStatistics/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -265,48 +266,14 @@
         this.queryParams.pabegtime = this.selecttime[0];
         this.queryParams.paendtime = this.selecttime[1];
         // if (this.queryParams.paendtime == this.queryParams.pabegtime) {
-        let num = Number(this.queryParams.paendtime.slice(5, 7));
-        if (num < 9) {
-          let mon = Number(this.queryParams.paendtime.slice(6, 7));
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "0" +
-            (mon + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
-        // this.queryParams.paendtime=this.queryParams.paendtime.slice(0,5)骞�
-        else if (num >= 10) {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            (num + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        } else {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "10" +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
+        // 缁撴潫鏃堕棿鍙�"鎵�閫夌粨鏉熸湀鐨勬鏈� 1 鍙�"锛屼互鍖呭惈鏁翠釜缁撴潫鏈堛��
+        // 鍘熷疄鐜版妸鏈堜唤 +1 鍚庣洿鎺ユ嫾瀛楃涓诧紝12 鏈堜細寰楀埌 13 鏈堬紙2026-13-01锛夛紝
+        // MySQL 鎶� Incorrect datetime value锛屽瓨鍌ㄨ繃绋嬬洿鎺� 500銆�
+        this.queryParams.paendtime = this.$moment(this.queryParams.paendtime)
+          .startOf("month")
+          .add(1, "month")
+          .format("YYYY-MM")
+          .concat("-01 00:00:00");
         this.queryParams.pabegtime =
           this.queryParams.pabegtime + " " + "00" + ":" + "00" + ":" + "00";
         // }
diff --git a/src/views/project/statistics/caseStatistics/index.vue b/src/views/project/statistics/caseStatistics/index.vue
index caaa5de..7a48431 100644
--- a/src/views/project/statistics/caseStatistics/index.vue
+++ b/src/views/project/statistics/caseStatistics/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -271,48 +272,14 @@
         this.queryParams.pabegtime = this.selecttime[0];
         this.queryParams.paendtime = this.selecttime[1];
         // if (this.queryParams.paendtime == this.queryParams.pabegtime) {
-        let num = Number(this.queryParams.paendtime.slice(5, 7));
-        if (num < 9) {
-          let mon = Number(this.queryParams.paendtime.slice(6, 7));
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "0" +
-            (mon + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
-        // this.queryParams.paendtime=this.queryParams.paendtime.slice(0,5)骞�
-        else if (num >= 10) {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            (num + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        } else {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "10" +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
+        // 缁撴潫鏃堕棿鍙�"鎵�閫夌粨鏉熸湀鐨勬鏈� 1 鍙�"锛屼互鍖呭惈鏁翠釜缁撴潫鏈堛��
+        // 鍘熷疄鐜版妸鏈堜唤 +1 鍚庣洿鎺ユ嫾瀛楃涓诧紝12 鏈堜細寰楀埌 13 鏈堬紙2026-13-01锛夛紝
+        // MySQL 鎶� Incorrect datetime value锛屽瓨鍌ㄨ繃绋嬬洿鎺� 500銆�
+        this.queryParams.paendtime = this.$moment(this.queryParams.paendtime)
+          .startOf("month")
+          .add(1, "month")
+          .format("YYYY-MM")
+          .concat("-01 00:00:00");
         this.queryParams.pabegtime =
           this.queryParams.pabegtime + " " + "00" + ":" + "00" + ":" + "00";
         // }
diff --git a/src/views/project/statistics/chargeStatistics/index.vue b/src/views/project/statistics/chargeStatistics/index.vue
index 61a46fd..9046ff8 100644
--- a/src/views/project/statistics/chargeStatistics/index.vue
+++ b/src/views/project/statistics/chargeStatistics/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -289,48 +290,14 @@
         this.queryParams.pabegtime = this.selecttime[0];
         this.queryParams.paendtime = this.selecttime[1];
         // if (this.queryParams.paendtime == this.queryParams.pabegtime) {
-        let num = Number(this.queryParams.paendtime.slice(5, 7));
-        if (num < 9) {
-          let mon = Number(this.queryParams.paendtime.slice(6, 7));
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "0" +
-            (mon + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
-        // this.queryParams.paendtime=this.queryParams.paendtime.slice(0,5)骞�
-        else if (num >= 10) {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            (num + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        } else {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "10" +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
+        // 缁撴潫鏃堕棿鍙�"鎵�閫夌粨鏉熸湀鐨勬鏈� 1 鍙�"锛屼互鍖呭惈鏁翠釜缁撴潫鏈堛��
+        // 鍘熷疄鐜版妸鏈堜唤 +1 鍚庣洿鎺ユ嫾瀛楃涓诧紝12 鏈堜細寰楀埌 13 鏈堬紙2026-13-01锛夛紝
+        // MySQL 鎶� Incorrect datetime value锛屽瓨鍌ㄨ繃绋嬬洿鎺� 500銆�
+        this.queryParams.paendtime = this.$moment(this.queryParams.paendtime)
+          .startOf("month")
+          .add(1, "month")
+          .format("YYYY-MM")
+          .concat("-01 00:00:00");
         this.queryParams.pabegtime =
           this.queryParams.pabegtime + " " + "00" + ":" + "00" + ":" + "00";
         // }
diff --git a/src/views/project/statistics/performanceStaristics/index.vue b/src/views/project/statistics/performanceStaristics/index.vue
index 715eb80..85267d8 100644
--- a/src/views/project/statistics/performanceStaristics/index.vue
+++ b/src/views/project/statistics/performanceStaristics/index.vue
@@ -2,6 +2,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -277,48 +278,14 @@
         this.queryParams.pabegtime = this.selecttime[0];
         this.queryParams.paendtime = this.selecttime[1];
         // if (this.queryParams.paendtime == this.queryParams.pabegtime) {
-        let num = Number(this.queryParams.paendtime.slice(5, 7));
-        if (num < 9) {
-          let mon = Number(this.queryParams.paendtime.slice(6, 7));
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "0" +
-            (mon + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
-        // this.queryParams.paendtime=this.queryParams.paendtime.slice(0,5)骞�
-        else if (num >= 10) {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            (num + 1) +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        } else {
-          this.queryParams.paendtime =
-            this.queryParams.paendtime.slice(0, 5) +
-            "10" +
-            "-" +
-            "01" +
-            " " +
-            "00" +
-            ":" +
-            "00" +
-            ":" +
-            "00";
-        }
+        // 缁撴潫鏃堕棿鍙�"鎵�閫夌粨鏉熸湀鐨勬鏈� 1 鍙�"锛屼互鍖呭惈鏁翠釜缁撴潫鏈堛��
+        // 鍘熷疄鐜版妸鏈堜唤 +1 鍚庣洿鎺ユ嫾瀛楃涓诧紝12 鏈堜細寰楀埌 13 鏈堬紙2026-13-01锛夛紝
+        // MySQL 鎶� Incorrect datetime value锛屽瓨鍌ㄨ繃绋嬬洿鎺� 500銆�
+        this.queryParams.paendtime = this.$moment(this.queryParams.paendtime)
+          .startOf("month")
+          .add(1, "month")
+          .format("YYYY-MM")
+          .concat("-01 00:00:00");
         this.queryParams.pabegtime =
           this.queryParams.pabegtime + " " + "00" + ":" + "00" + ":" + "00";
         // }
diff --git a/src/views/project/tallage/computingBill/index.vue b/src/views/project/tallage/computingBill/index.vue
index 50bcbba..dbf2747 100644
--- a/src/views/project/tallage/computingBill/index.vue
+++ b/src/views/project/tallage/computingBill/index.vue
@@ -43,7 +43,7 @@
               <el-date-picker
                 v-model="form.taxedtime"
                 value-format="yyyy-MM-dd HH:mm:ss"
-                type="datetime"
+                type="datetime" format="yyyy-MM-dd HH:mm"
                 :disabled="true"
                 placeholder="閫夋嫨鏃堕棿"
               >
@@ -298,6 +298,7 @@
             <el-row :gutter="20">
               <!--鐢ㄦ埛鏁版嵁-->
               <el-form
+                class="opo-query-form"
                 :model="patientqueryParams"
                 ref="queryForm"
                 size="small"
@@ -570,6 +571,7 @@
 import Li_area_select from "@/components/Address";
 import { getUserProfile } from "@/api/system/user";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyRound } from "@/utils/money";
 import {
   ExpertfeeListnb,
   getFundtax,
@@ -1110,23 +1112,16 @@
         this.$modal.msgError("娉ㄦ剰瀹炴敹閲戦涓嶇瓑浜庡簲鏀堕噾棰濓紝璇锋牳瀵规暟鎹紒");
       }
     },
-    //淇敼瀹炴敹鎴栧簲鏀跺悗瑙﹀彂
+    //淇敼瀹炴敹鎴栧簲鏀跺悗瑙﹀彂锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛�
     chargeSum() {
-      let ChargeSum = 0;
-      let ChargeamountSum = 0;
-
       //璐圭敤鍚堣
       try {
-        for (let i = 0; i < this.donorchargeorgans.length; i++) {
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
-            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
-          }
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
-            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
-          }
-        }
-        this.form.receivableamount = ChargeSum.toFixed(2);
-        this.form.receivedamount = ChargeamountSum.toFixed(2);
+        this.form.receivableamount = moneyRound(
+          moneySum(this.donorchargeorgans, "organcharge")
+        ).toFixed(2);
+        this.form.receivedamount = moneyRound(
+          moneySum(this.donorchargeorgans, "amount")
+        ).toFixed(2);
       } catch {}
     },
 
diff --git a/src/views/project/tallage/index.vue b/src/views/project/tallage/index.vue
index f15f1b6..1d1c38c 100644
--- a/src/views/project/tallage/index.vue
+++ b/src/views/project/tallage/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
@@ -82,7 +83,7 @@
         label="鐢宠鏃ユ湡"
         align="center"
         prop="createTime"
-        width="180"
+        width="140"
       >
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span>
@@ -91,16 +92,16 @@
       <!-- <el-table-column label="缁忓姙浜�" align="center" prop="username" /> -->
       <el-table-column
         label="鐢宠鍗曞彿"
-        width="180"
+        width="160"
         align="center"
         prop="applyno"
       />
 
-      <el-table-column label="绋庡墠閲戦" align="center" prop="pretaxamount">
+      <el-table-column label="绋庡墠閲戦" align="center" prop="pretaxamount" width="100" > 
       </el-table-column>
-      <el-table-column label="鎵g◣閲戦" align="center" prop="taxMoney" />
-      <el-table-column label="绋庡悗閲戦" align="center" prop="taxedamount" />
-      <el-table-column label="鏄惁绠楃◣" width="180" align="center" prop="istax">
+      <el-table-column label="鎵g◣閲戦" align="center" prop="taxMoney" width="100" />
+      <el-table-column label="绋庡悗閲戦" align="center" prop="taxedamount" width="100" />
+      <el-table-column label="鏄惁绠楃◣" align="center" prop="istax" width="90" >
         <template slot-scope="scope">
           <dict-tag
             :options="dict.type.sys_0_1"
@@ -111,12 +112,12 @@
       <!-- <el-table-column label="鎬婚噾棰�" align="center" prop="taxamount" /> -->
 
       <el-table-column label="绠楃◣鏃堕棿" align="center" prop="taxedtime" />
-      <el-table-column label="浠樻鐘舵��" align="center" prop="isdistribute">
+      <el-table-column label="浠樻鐘舵��" align="center" prop="isdistribute" width="100" >
         <template slot-scope="scope">
           <span>{{ scope.row.isdistribute == "0" ? "鏈粯娆�" : "宸蹭粯娆�" }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="浠樻鏃ユ湡" align="center" prop="riqi" />
+      <el-table-column label="浠樻鏃ユ湡" align="center" prop="riqi" width="120" />
       <el-table-column label="鎿嶄綔" width="280" align="center">
         <template slot-scope="scope">
           <el-button
diff --git a/src/views/project/travelexpenseapply/edit.vue b/src/views/project/travelexpenseapply/edit.vue
index d888db5..4674f41 100644
--- a/src/views/project/travelexpenseapply/edit.vue
+++ b/src/views/project/travelexpenseapply/edit.vue
@@ -63,7 +63,7 @@
                 </el-col>
                 <el-col :span="7">
                     <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-                        <el-date-picker style="width: 100%" v-model="form.applyTime" type="date"
+                        <el-date-picker style="width: 100%" v-model="form.applyTime" type="date" format="yyyy-MM-dd"
                             value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
                         </el-date-picker>
                     </el-form-item>
@@ -101,7 +101,7 @@
                     <el-table-column prop="starttime" slot="" label="鍑哄彂鏃ユ湡" fixed align="center" width="150">
                         <template slot-scope="scope">
                             <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.starttime"
-                                type="date" value-format="yyyy-MM-dd HH:mm:ss" placeholder="鍑哄彂鏃ユ湡"
+                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" placeholder="鍑哄彂鏃ユ湡"
                                 @change="getStandard(scope.row)">
                             </el-date-picker>
                         </template>
@@ -115,7 +115,7 @@
                     <el-table-column prop="endtime" slot="" label="鍒拌揪鏃ユ湡" align="center" width="150" fixed>
                         <template slot-scope="scope">
                             <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.endtime"
-                                type="date" value-format="yyyy-MM-dd HH:mm:ss" placeholder="鍒拌揪鏃ユ湡">
+                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" placeholder="鍒拌揪鏃ユ湡">
                             </el-date-picker>
                         </template>
                     </el-table-column>
@@ -340,6 +340,7 @@
 } from "@/api/project/organization";
 import { listDonatebaseinfo } from "@/api/project/donatebaseinfo";
 import { getToken } from "@/utils/auth";
+import { moneySum } from "@/utils/money";
 export default {
     data() {
         return {
@@ -673,41 +674,25 @@
                     //鍑犵偣鍙栨秷鐨勬彁绀�
                 });
         },
-        //璁$畻璐圭敤鍚堣
+        //璁$畻璐圭敤鍚堣锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
         sumTotalFee() {
-            let allSum = 0;
             try {
                 for (let i = 0; i < this.applicationDetailArr.length; i++) {
-                    let totalFee = 0;
+                    const row = this.applicationDetailArr[i];
                     //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].trafficexpense))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].trafficexpense);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].cityfee))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].cityfee);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].hotelexpense))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].hotelexpense);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].otherexpense))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].otherexpense);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].foodexpenses))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].foodexpenses);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].foodallowance))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].foodallowance);
-                    }
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].otherfeeamount))) {
-                        totalFee += parseFloat(this.applicationDetailArr[i].otherfeeamount);
-                    }
-                    this.applicationDetailArr[i].total = parseFloat(totalFee).toFixed(2);
-                    this.$set(this.applicationDetailArr, i, this.applicationDetailArr[i]);
-                    if (!isNaN(parseFloat(this.applicationDetailArr[i].total))) {
-                        allSum += parseFloat(this.applicationDetailArr[i].total);
-                    }
+                    const totalFee = moneySum([
+                        row.trafficexpense,
+                        row.cityfee,
+                        row.hotelexpense,
+                        row.otherexpense,
+                        row.foodexpenses,
+                        row.foodallowance,
+                        row.otherfeeamount
+                    ]);
+                    row.total = totalFee.toFixed(2);
+                    this.$set(this.applicationDetailArr, i, row);
                 }
-                this.form.amountrequested = allSum.toFixed(2);
+                this.form.amountrequested = moneySum(this.applicationDetailArr, "total").toFixed(2);
                 this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
             } catch { }
         },
diff --git a/src/views/project/travelexpenseapply/index.vue b/src/views/project/travelexpenseapply/index.vue
index 89d2c2f..66ca263 100644
--- a/src/views/project/travelexpenseapply/index.vue
+++ b/src/views/project/travelexpenseapply/index.vue
@@ -1,12 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
-      :model="queryParams"
-      ref="queryForm"
-      :inline="true"
-      v-show="showSearch"
-      label-width="68px"
-    >
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-row>
         <!--
         <el-col :span="6">
@@ -18,53 +13,25 @@
 -->
         <el-col :span="6">
           <el-form-item label="缁忓姙浜�" prop="username">
-            <el-input
-              v-model="queryParams.username"
-              placeholder="璇疯緭鍏ョ粡鍔炰汉"
-              clearable
-              size="small"
-              @keyup.enter.native="handleQuery"
-            />
+            <el-input v-model="queryParams.username" placeholder="璇疯緭鍏ョ粡鍔炰汉" clearable size="small"
+              @keyup.enter.native="handleQuery" />
           </el-form-item>
         </el-col>
         <el-col :span="8">
           <el-form-item label="鎶ラ攢鏃ユ湡" prop="applyTime">
-            <el-date-picker
-              format="yyyy-MM-dd"
-              value-format="yyyy-MM-dd"
-              v-model="value1"
-              type="daterange"
-              @blur="onpick"
-              range-separator="鑷�"
-              start-placeholder="鎶ラ攢寮�濮嬫棩鏈�"
-              end-placeholder="鎶ラ攢缁撴潫鏃ユ湡"
-              @keyup.enter.native="handleQuery"
-            >
+            <el-date-picker format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" v-model="value1" type="daterange"
+              @change="selecttime" range-separator="鑷�" start-placeholder="鎶ラ攢寮�濮嬫棩鏈�" end-placeholder="鎶ラ攢缁撴潫鏃ユ湡"
+              @keyup.enter.native="handlQuery">
             </el-date-picker>
           </el-form-item>
-        </el-col>
+        </el-col>      
         <el-col :span="6">
           <el-form-item label="瀹℃牳鐘舵��" prop="recordstatus">
-            <el-input
-              v-model="queryParams.recordstatus"
-              placeholder="璇烽�夋嫨瀹℃牳鐘舵��"
-              clearable
-              size="small"
-              v-if="0"
-              @keyup.enter.native="handleQuery"
-            />
-            <el-select
-              v-model="queryParams.recordstatus"
-              placeholder="璇烽�夋嫨瀹℃牳鐘舵��"
-              clearable
-              size="small"
-            >
-              <el-option
-                v-for="dict in dict.type.sys_recordstatus"
-                :key="dict.value"
-                :label="dict.label"
-                :value="dict.value"
-              />
+            <el-input v-model="queryParams.recordstatus" placeholder="璇烽�夋嫨瀹℃牳鐘舵��" clearable size="small" v-if="0"
+              @keyup.enter.native="handleQuery" />
+            <el-select v-model="queryParams.recordstatus" placeholder="璇烽�夋嫨瀹℃牳鐘舵��" clearable size="small">
+              <el-option v-for="dict in dict.type.sys_recordstatus" :key="dict.value" :label="dict.label"
+                :value="dict.value" />
             </el-select>
           </el-form-item>
         </el-col>
@@ -72,27 +39,14 @@
       <el-row>
         <el-col :span="6">
           <el-form-item label="鎹愮尞鑰�" prop="name">
-            <el-input
-              v-model="queryParams.donorname"
-              placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
-              clearable
-              size="small"
-              @keyup.enter.native="handleQuery"
-            />
+            <el-input v-model="queryParams.donorname" placeholder="璇疯緭鍏ユ崘鐚�呭鍚�" clearable size="small"
+              @keyup.enter.native="handleQuery" />
           </el-form-item>
         </el-col>
         <el-col :span="4">
           <el-form-item>
-            <el-button
-              type="primary"
-              icon="el-icon-search"
-              size="mini"
-              @click="handleQuery"
-              >鎼滅储</el-button
-            >
-            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
-              >閲嶇疆</el-button
-            >
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
           </el-form-item>
         </el-col>
       </el-row>
@@ -100,104 +54,48 @@
 
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
-        <el-button type="primary" plain icon="el-icon-plus" @click="handleAdd"
-          >鏂板</el-button
-        >
+        <el-button type="primary" plain icon="el-icon-plus" @click="handleAdd">鏂板</el-button>
         <!-- v-hasPermi="['project:funddetail:add']" -->
       </el-col>
       <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-download"
-          :loading="exportLoading"
-          @click="handleExport"
-          >瀵煎嚭</el-button
-        >
+        <el-button type="warning" plain icon="el-icon-download" :loading="exportLoading"
+          @click="handleExport">瀵煎嚭</el-button>
       </el-col>
       <!-- v-hasPermi="['project:funddetail:export']" -->
-      <right-toolbar
-        :showSearch.sync="showSearch"
-        @queryTable="getList"
-      ></right-toolbar>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table
-      :row-class-name="rowClassName"
-      v-loading="loading"
-      :data="reimbursementList"
-      @selection-change="handleSelectionChange"
-    >
+    <el-table :row-class-name="rowClassName" v-loading="loading" :data="reimbursementList"
+      @selection-change="handleSelectionChange">
       <!-- <el-table-column type="selection" width="55" align="center" /> 
       <el-table-column label="鎶ラ攢浜虹被鍒�" width="120" align="center" prop="costtype">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.sys_travelexpensebelong" :value="scope.row.costtype" />
         </template>
-      </el-table-column>-->
-      <el-table-column
-        label="鐢宠鏃堕棿"
-        width="150"
-        align="center"
-        prop="applyTime"
-      >
+</el-table-column>-->
+      <el-table-column label="鐢宠鏃堕棿" width="120" align="center" prop="applyTime">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.applyTime, "{y}-{m}-{d}") }}</span>
         </template>
       </el-table-column>
-      <el-table-column
-        label="瀹℃牳鐘舵��"
-        align="center"
-        prop="recordstatus"
-        width="160"
-      >
+      <el-table-column label="瀹℃牳鐘舵��" align="center" prop="recordstatus" width="140">
         <template slot-scope="scope">
-          <dict-tag
-            :options="dict.type.sys_recordstatus"
-            :value="scope.row.recordstatus"
-          />
+          <dict-tag :options="dict.type.sys_recordstatus" :value="scope.row.recordstatus" />
         </template>
       </el-table-column>
-      <el-table-column
-        label="鏉愭枡棰勫鐘舵��"
-        width="140"
-        align="center"
-        prop="checkstatus"
-      >
+      <el-table-column label="鏉愭枡棰勫鐘舵��" width="140" align="center" prop="checkstatus">
         <template slot-scope="scope">
-          <dict-tag
-            :options="dict.type.sys_stage_type"
-            :value="scope.row.checkstatus"
-          />
+          <dict-tag :options="dict.type.sys_stage_type" :value="scope.row.checkstatus" />
         </template>
       </el-table-column>
-      <el-table-column
-        label="缁忓姙浜�"
-        width="150"
-        align="center"
-        prop="username"
-      />
+      <el-table-column label="缁忓姙浜�" width="100" align="center" prop="username" />
       <!--
       <el-table-column label="鍑哄樊浜�" width="180" align="center" prop="travelers">
       </el-table-column>-->
-      <el-table-column
-        label="鎶ラ攢閲戦"
-        width="150"
-        align="center"
-        prop="amountrequested"
-      >
+      <el-table-column label="鎶ラ攢閲戦" width="120" align="center" prop="amountrequested">
       </el-table-column>
-      <el-table-column
-        label="鎵�灞炵粍鍒�"
-        width="150"
-        align="center"
-        prop="deptmentname"
-      />
-      <el-table-column
-        label="缁勯暱"
-        width="150"
-        align="center"
-        prop="managername"
-      />
+      <el-table-column label="鎵�灞炵粍鍒�" width="120" align="center" prop="deptmentname" />
+      <el-table-column label="缁勯暱" width="100" align="center" prop="managername" />
       <el-table-column label="鍑哄樊浜嬬敱" align="center" prop="reason" />
       <!-- <el-table-column label="鑱旂郴鐢佃瘽" width="120" align="center" prop="phone">
       </el-table-column>
@@ -207,130 +105,55 @@
       </el-table-column>
       <el-table-column label="鎶ラ攢鍚堣" align="center" prop="financechecher"/>-->
       <!-- <el-table-column label="璐㈠姟瀹℃牳" width="120" align="center" prop="financechecher" /> -->
-      <el-table-column
-        label="鎹愮尞鑰�"
-        width="150"
-        align="center"
-        prop="donorname"
-      />
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        fixed="right"
-        width="300"
-        class-name="small-padding fixed-width"
-      >
+      <el-table-column label="鎹愮尞鑰�" width="100" align="center" prop="donorname" />
+      <el-table-column label="鎿嶄綔" align="center" fixed="right" width="300" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-          <el-button
-            v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1"
-            size="mini"
-            type="text"
-            icon="el-icon-upload2"
-            @click="handleup(scope.row)"
-            >涓婃姤</el-button
-          >
-          <el-button
-            v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1"
-            size="mini"
-            type="text"
-            icon="el-icon-edit"
-            @click="handleUpdate(scope.row)"
-            >淇敼</el-button
-          >
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-view"
-            @click="handleDetail(scope.row)"
-            >鏌ョ湅</el-button
-          >
+          <el-button v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1" size="mini" type="text"
+            icon="el-icon-upload2" @click="handleup(scope.row)">涓婃姤</el-button>
+          <el-button v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1" size="mini" type="text"
+            icon="el-icon-edit" @click="handleUpdate(scope.row)">淇敼</el-button>
+          <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(scope.row)">鏌ョ湅</el-button>
           <!-- v-hasPermi="['project:funddetail:edit']" -->
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-download"
-            @click="gettable(scope.row)"
-          >
+          <el-button size="mini" type="text" icon="el-icon-download" @click="gettable(scope.row)">
             涓嬭浇
           </el-button>
           <!-- v-hasPermi="['project:funddetail:edit']" -->
-          <el-button
-            v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1"
-            size="mini"
-            type="text"
-            @click="handleDelete(scope.row)"
-            ><span class="button-delete"
-              ><i class="el-icon-delete"></i>鍒犻櫎</span
-            ></el-button
-          >
+          <el-button v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1" size="mini" type="text"
+            @click="handleDelete(scope.row)"><span class="button-delete"><i
+                class="el-icon-delete"></i>鍒犻櫎</span></el-button>
           <!-- v-hasPermi="['project:funddetail:remove']" -->
         </template>
       </el-table-column>
-      <el-table-column fixed="right" align="center" width="120" label="鍔熻兘">
+      <el-table-column fixed="right" align="center" width="120" label="鍔熻兘" v-if="false">
         <template slot-scope="scope">
-          <el-button size="mini" v-if="scope.row.uploadStates == 1"
-            >绾夸笅宸叉姤閿�</el-button
-          >
-          <el-button
-            size="mini"
-            type="success"
-            v-else-if="scope.row.uploadStates == 0"
-            @click="Dooffline('1', scope.row)"
-            >绾夸笅鎶ラ攢</el-button
-          >
+          <el-button size="mini" v-if="scope.row.uploadStates == 1">绾夸笅宸叉姤閿�</el-button>
+          <el-button size="mini" type="success" v-else-if="scope.row.uploadStates == 0"
+            @click="Dooffline('1', scope.row)">绾夸笅鎶ラ攢</el-button>
         </template>
       </el-table-column>
     </el-table>
     <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
 
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
-      @pagination="getList"
-    />
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+      @pagination="getList" />
 
     <!-- 娣诲姞鎴栦慨鏀硅垂鐢ㄧ敵璇锋槑缁嗗璇濇 -->
-    <el-dialog
-      :title="title"
-      :visible.sync="open"
-      :close-on-click-modal="false"
-      width="1400px"
-      append-to-body
-      @close="reset"
-    >
+    <el-dialog :title="title" :visible.sync="open" :close-on-click-modal="false" width="1400px" append-to-body
+      @close="reset">
       <el-form ref="form" :model="form" :rules="rules" label-width="120px">
-        <el-row
-          ><el-col :span="5">
+        <el-row><el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.applyTime"
-                type="date"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                placeholder="鐢宠鏃ユ湡"
-              >
+              <el-date-picker style="width: 100%" v-model="form.applyTime" type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
           </el-col>
           <el-col :span="5">
             <el-form-item label="缁忓姙浜�" prop="username">
-              <el-select
-                v-model="form.username"
-                clearable
-                filterable
-                allow-create
-                ref="getReportname"
-                default-first-option
-                placeholder="璇烽�夋嫨"
-              >
-                <el-option
-                  v-for="item in personsList"
-                  :key="item.reportNo"
-                  :label="item.reportName"
-                  :value="item.reportName"
-                >
+              <el-select v-model="form.username" clearable filterable allow-create ref="getReportname"
+                default-first-option placeholder="璇烽�夋嫨">
+                <el-option v-for="item in personsList" :key="item.reportNo" :label="item.reportName"
+                  :value="item.reportName">
                 </el-option>
               </el-select>
             </el-form-item>
@@ -355,18 +178,8 @@
           </el-col>
           <el-col :span="5">
             <el-form-item label="鎹愮尞鑰�" prop="infoid">
-              <el-select
-                v-model="form.infoid"
-                @change="selectbaseinfo"
-                filterable
-                placeholder="璇烽�夋嫨鎹愮尞鑰�"
-              >
-                <el-option
-                  v-for="item in baselist"
-                  :key="item.index"
-                  :label="item.name"
-                  :value="item.infoid"
-                >
+              <el-select v-model="form.infoid" @change="selectbaseinfo" filterable placeholder="璇烽�夋嫨鎹愮尞鑰�">
+                <el-option v-for="item in baselist" :key="item.index" :label="item.name" :value="item.infoid">
                 </el-option>
               </el-select>
             </el-form-item>
@@ -375,36 +188,17 @@
         <el-row style="margin-top: 10px">
           <el-col :span="5">
             <el-form-item label="鎶ラ攢閲戦" prop="amountrequested">
-              <el-input
-                :disabled="true"
-                v-model="form.amountrequested"
-                placeholder="鎶ラ攢鍚堣閲戦"
-              />
+              <el-input :disabled="true" v-model="form.amountrequested" placeholder="鎶ラ攢鍚堣閲戦" />
             </el-form-item>
           </el-col>
           <el-col :span="10">
             <el-form-item label="澶у啓閲戦" prop="bigstrmoney">
-              <el-input
-                :disabled="true"
-                v-model="form.bigstrmoney"
-                placeholder="鎶ラ攢澶у啓閲戦"
-              />
-            </el-form-item> </el-col
-          ><el-col :span="5">
+              <el-input :disabled="true" v-model="form.bigstrmoney" placeholder="鎶ラ攢澶у啓閲戦" />
+            </el-form-item> </el-col><el-col :span="5">
             <el-form-item label="瀹℃牳鐘舵��" prop="flowlevel">
-              <el-select
-                v-model="form.recordstatus"
-                placeholder="璇烽�夋嫨瀹℃牳鐘舵��"
-                clearable
-                :disabled="true"
-                size="small"
-              >
-                <el-option
-                  v-for="dict in dict.type.sys_recordstatus"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
+              <el-select v-model="form.recordstatus" placeholder="璇烽�夋嫨瀹℃牳鐘舵��" clearable :disabled="true" size="small">
+                <el-option v-for="dict in dict.type.sys_recordstatus" :key="dict.value" :label="dict.label"
+                  :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
@@ -511,263 +305,117 @@
         </el-row>
         <el-row>
           <el-table :data="rbDetails" border highlight-current-row>
-            <el-table-column
-              prop="orderno"
-              slot=""
-              label="搴忓彿"
-              align="center"
-              fixed
-              width="65"
-            >
+            <el-table-column prop="orderno" slot="" label="搴忓彿" align="center" fixed width="65">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.orderno" placeholder="搴忓彿" />
               </template>
             </el-table-column>
             <!--涓婚敭銆佸涓嶅睍绀�-->
-            <el-table-column
-              prop="id"
-              slot=""
-              label="涓婚敭"
-              align="center"
-              fixed
-              width="95"
-              v-if="false"
-            >
+            <el-table-column prop="id" slot="" label="涓婚敭" align="center" fixed width="95" v-if="false">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.id" placeholder="id" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="rbid"
-              slot=""
-              label="澶栭敭"
-              align="center"
-              fixed
-              width="95"
-              v-if="false"
-            >
+            <el-table-column prop="rbid" slot="" label="澶栭敭" align="center" fixed width="95" v-if="false">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.rbid" placeholder="rbid" />
               </template>
             </el-table-column>
 
-            <el-table-column
-              prop="persontype"
-              slot=""
-              label="浜哄憳绫诲埆"
-              align="center"
-              fixed
-              width="130"
-            >
+            <el-table-column prop="persontype" slot="" label="浜哄憳绫诲埆" align="center" fixed width="130">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.persontype"
-                  value-key="value"
-                  placeholder="浜哄憳绫诲埆"
-                  @change="getPersons(scope.row)"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_travelexpensebelong"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.label"
-                  ></el-option>
+                <el-select v-model="scope.row.persontype" value-key="value" placeholder="浜哄憳绫诲埆"
+                  @change="getPersons(scope.row)">
+                  <el-option v-for="dict in dict.type.sys_travelexpensebelong" :key="dict.value" :label="dict.label"
+                    :value="dict.label"></el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="personname"
-              slot=""
-              label="璐圭敤浜哄憳"
-              align="center"
-              fixed
-              width="110"
-            >
+            <el-table-column prop="personname" slot="" label="璐圭敤浜哄憳" align="center" fixed width="110">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.personname"
-                  clearable
-                  filterable
-                  allow-create
-                  default-first-option
-                  placeholder="璇烽�夋嫨"
-                  @focus1="getPersons(scope.row)"
-                >
-                  <el-option
-                    v-for="item in personsSel"
-                    :key="item.reportNo"
-                    :label="item.reportName"
-                    :value="item.reportName"
-                  >
+                <el-select v-model="scope.row.personname" clearable filterable allow-create default-first-option
+                  placeholder="璇烽�夋嫨" @focus1="getPersons(scope.row)">
+                  <el-option v-for="item in personsSel" :key="item.reportNo" :label="item.reportName"
+                    :value="item.reportName">
                   </el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="starttime"
-              slot=""
-              label="寮�濮嬫棩鏈�"
-              fixed
-              align="center"
-              width="150"
-            >
+            <el-table-column prop="starttime" slot="" label="寮�濮嬫棩鏈�" fixed align="center" width="150">
               <template slot-scope="scope">
-                <el-date-picker
-                  :picker-options="{
-                    disabledDate: time => {
-                      if (scope.row.endtime) {
-                        return (
-                          time.getTime() >
-                          new Date(scope.row.endtime.replace(/-/g, '/'))
-                        );
-                      }
+                <el-date-picker :picker-options="{
+                  disabledDate: time => {
+                    if (scope.row.endtime) {
+                      return (
+                        time.getTime() >
+                        new Date(scope.row.endtime.replace(/-/g, '/'))
+                      );
                     }
-                  }"
-                  clearable
-                  size="small"
-                  style="width: 100%"
-                  v-model="scope.row.starttime"
-                  type="date"
-                  value-format="yyyy-MM-dd HH:mm:ss"
-                  placeholder="寮�濮嬫棩鏈�"
-                  @blur="getdays(scope.row)"
-                >
+                  }
+                }" clearable size="small" style="width: 100%" v-model="scope.row.starttime" type="date" format="yyyy-MM-dd"
+                  value-format="yyyy-MM-dd HH:mm:ss" placeholder="寮�濮嬫棩鏈�" @blur="getdays(scope.row)">
                 </el-date-picker>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="endtime"
-              slot=""
-              label="缁撴潫鏃ユ湡"
-              align="center"
-              fixed
-              width="150"
-            >
+            <el-table-column prop="endtime" slot="" label="缁撴潫鏃ユ湡" align="center" fixed width="150">
               <template slot-scope="scope">
-                <el-date-picker
-                  :picker-options="{
-                    disabledDate: time => {
-                      if (scope.row.starttime) {
-                        return (
-                          time.getTime() <
-                          new Date(scope.row.starttime.replace(/-/g, '/'))
-                        );
-                      }
+                <el-date-picker :picker-options="{
+                  disabledDate: time => {
+                    if (scope.row.starttime) {
+                      return (
+                        time.getTime() <
+                        new Date(scope.row.starttime.replace(/-/g, '/'))
+                      );
                     }
-                  }"
-                  clearable
-                  size="small"
-                  style="width: 100%"
-                  v-model="scope.row.endtime"
-                  type="date"
-                  value-format="yyyy-MM-dd HH:mm:ss"
-                  placeholder="缁撴潫鏃ユ湡"
-                  @blur="getdays(scope.row)"
-                >
+                  }
+                }" clearable size="small" style="width: 100%" v-model="scope.row.endtime" type="date" format="yyyy-MM-dd"
+                  value-format="yyyy-MM-dd HH:mm:ss" placeholder="缁撴潫鏃ユ湡" @blur="getdays(scope.row)">
                 </el-date-picker>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="departure"
-              slot=""
-              label="鍑哄彂鍦�"
-              align="center"
-              width="100"
-            >
+            <el-table-column prop="departure" slot="" label="鍑哄彂鍦�" align="center" width="100">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.departure" placeholder="鍑哄彂鍦�" />
               </template>
             </el-table-column>
-            <el-table-column
-              label="鍒拌揪鍦�"
-              prop="destination"
-              align="center"
-              width="140"
-            >
+            <el-table-column label="鍒拌揪鍦�" prop="destination" align="center" width="140">
               <template slot-scope="scope">
                 <!--  <el-input v-model="scope.row.destination" placeholder="鍒拌揪鍦�" @blur="getallowance(scope.row)" /> -->
-                <el-select
-                  filterable
-                  allow-create
-                  v-model="scope.row.destination"
-                  value-key="value"
-                  placeholder="鍒拌揪鍦�"
-                  @change="getallowance(scope.row)"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_area_name"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.label"
-                  ></el-option>
+                <el-select filterable allow-create v-model="scope.row.destination" value-key="value" placeholder="鍒拌揪鍦�"
+                  @change="getallowance(scope.row)">
+                  <el-option v-for="dict in dict.type.sys_area_name" :key="dict.value" :label="dict.label"
+                    :value="dict.label"></el-option>
                 </el-select>
               </template>
             </el-table-column>
             <el-table-column prop="days" label="澶╂暟" width="65" align="center">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.days"
-                  @blur="getallowance(scope.row)"
-                  placeholder="澶╂暟"
-                />
+                <el-input v-model="scope.row.days" @blur="getallowance(scope.row)" placeholder="澶╂暟" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="traffictype"
-              label="鍑哄彂浜ら�氬伐鍏�"
-              align="center"
-              width="100"
-            >
+            <el-table-column prop="traffictype" label="鍑哄彂浜ら�氬伐鍏�" align="center" width="100">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.traffictype"
-                  placeholder="鍑哄彂浜ら�氬伐鍏�"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_traffictype"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.label"
-                  ></el-option>
+                <el-select v-model="scope.row.traffictype" placeholder="鍑哄彂浜ら�氬伐鍏�">
+                  <el-option v-for="dict in dict.type.sys_traffictype" :key="dict.value" :label="dict.label"
+                    :value="dict.label"></el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="traffictype2"
-              label="杩斿洖浜ら�氬伐鍏�"
-              align="center"
-              width="100"
-            >
+            <el-table-column prop="traffictype2" label="杩斿洖浜ら�氬伐鍏�" align="center" width="100">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.traffictype2"
-                  placeholder="杩斿洖浜ら�氬伐鍏�"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_traffictype"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.label"
-                  ></el-option>
+                <el-select v-model="scope.row.traffictype2" placeholder="杩斿洖浜ら�氬伐鍏�">
+                  <el-option v-for="dict in dict.type.sys_traffictype" :key="dict.value" :label="dict.label"
+                    :value="dict.label"></el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="trafficexpense"
-              label="浜ら�氳垂"
-              align="center"
-              width="80"
-            >
+            <el-table-column prop="trafficexpense" label="浜ら�氳垂" align="center" width="80">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.trafficexpense"
-                  placeholder="浜ら�氳垂"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.trafficexpense" placeholder="浜ら�氳垂" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
             <!--
@@ -782,144 +430,70 @@
               </template>
             </el-table-column>
                                                                                                                                       -->
-            <el-table-column
-              prop="hotelexpense"
-              label="浣忓璐�"
-              align="center"
-              width="80"
-            >
+            <el-table-column prop="hotelexpense" label="浣忓璐�" align="center" width="80">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.hotelexpense"
-                  placeholder="浣忓璐�"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.hotelexpense" placeholder="浣忓璐�" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
 
-            <el-table-column
-              prop="foodexpenses"
-              label="椁愯垂鎶ラ攢"
-              align="center"
-              width="80"
-            >
+            <el-table-column prop="foodexpenses" label="椁愯垂鎶ラ攢" align="center" width="80">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.foodexpenses"
-                  placeholder="浼欓璐规姤閿�"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.foodexpenses" placeholder="浼欓璐规姤閿�" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="foodallowance"
-              label="浼欓琛ュ姪"
-              align="center"
-              width="80"
-            >
+            <el-table-column prop="foodallowance" label="浼欓琛ュ姪" align="center" width="80">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.foodallowance"
-                  placeholder="浼欓璐硅ˉ鍔�"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.foodallowance" placeholder="浼欓璐硅ˉ鍔�" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="otherexpense"
-              label="鍏潅璐硅ˉ鍔�"
-              align="center"
-              width="80"
-            >
+            <el-table-column prop="otherexpense" label="鍏潅璐硅ˉ鍔�" align="center" width="80">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.otherexpense"
-                  placeholder="鏉傝垂"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.otherexpense" placeholder="鏉傝垂" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
 
-            <el-table-column
-              prop="otherfeeamount"
-              label="鍏朵粬璐圭敤"
-              align="center"
-              width="90"
-            >
+            <el-table-column prop="otherfeeamount" label="鍏朵粬璐圭敤" align="center" width="90">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.otherfeeamount"
-                  placeholder="鍏朵粬璐圭敤"
-                  @blur="
-                    val => {
-                      sumRowFee(scope.row);
-                    }
-                  "
-                />
+                <el-input v-model="scope.row.otherfeeamount" placeholder="鍏朵粬璐圭敤" @blur="
+                  val => {
+                    sumRowFee(scope.row);
+                  }
+                " />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="departure"
-              slot=""
-              label="鍏朵粬璐圭敤璇存槑"
-              align="center"
-              width="120"
-            >
+            <el-table-column prop="departure" slot="" label="鍏朵粬璐圭敤璇存槑" align="center" width="120">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.otherfeedesc"
-                  placeholder="鍏朵粬璐圭敤璇存槑"
-                />
+                <el-input v-model="scope.row.otherfeedesc" placeholder="鍏朵粬璐圭敤璇存槑" />
               </template>
             </el-table-column>
 
-            <el-table-column
-              prop="total"
-              label="鍚堣"
-              align="center"
-              width="110"
-            >
+            <el-table-column prop="total" label="鍚堣" align="center" width="110">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.total" placeholder="鍚堣" />
               </template>
             </el-table-column>
-            <el-table-column
-              fixed="right"
-              label="鎿嶄綔"
-              align="center"
-              width="120"
-              v-if="dialogType == 'edit'"
-            >
+            <el-table-column fixed="right" label="鎿嶄綔" align="center" width="120" v-if="dialogType == 'edit'">
               <template slot-scope="scope">
-                <el-button
-                  type="text"
-                  size="mini"
-                  @click="addDetailRow(scope.$index)"
-                  >鏂板</el-button
-                >
-                <el-button
-                  @click.native.prevent="
-                    deleteDetailRow(scope.$index, rbDetails, scope.row)
-                  "
-                  type="text"
-                  size="small"
-                >
+                <el-button type="text" size="mini" @click="addDetailRow(scope.$index)">鏂板</el-button>
+                <el-button @click.native.prevent="
+                  deleteDetailRow(scope.$index, rbDetails, scope.row)
+                  " type="text" size="small">
                   鍒犻櫎
                 </el-button>
               </template>
@@ -931,192 +505,75 @@
         </el-row>
         <el-row style="margin-top: 30px">
           <el-table :data="rbPayees" border highlight-current-row>
-            <el-table-column
-              prop="orderno"
-              slot=""
-              label="搴忓彿"
-              align="center"
-              fixed
-              width="65"
-            >
+            <el-table-column prop="orderno" slot="" label="搴忓彿" align="center" fixed width="65">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.orderno" placeholder="搴忓彿" />
               </template>
             </el-table-column>
 
             <!--涓婚敭銆佸閿笉灞曠ず-->
-            <el-table-column
-              prop="id"
-              slot=""
-              label="涓婚敭"
-              align="center"
-              fixed
-              width="95"
-              v-if="false"
-            >
+            <el-table-column prop="id" slot="" label="涓婚敭" align="center" fixed width="95" v-if="false">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.id" placeholder="id" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="rbid"
-              slot=""
-              label="澶栭敭"
-              align="center"
-              fixed
-              width="95"
-              v-if="false"
-            >
+            <el-table-column prop="rbid" slot="" label="澶栭敭" align="center" fixed width="95" v-if="false">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.rbid" placeholder="rbid" />
               </template>
             </el-table-column>
 
-            <el-table-column
-              prop="persontype"
-              slot=""
-              label="浜哄憳绫诲埆"
-              align="center"
-              fixed
-              width="130"
-            >
+            <el-table-column prop="persontype" slot="" label="浜哄憳绫诲埆" align="center" fixed width="130">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.persontype"
-                  value-key="value"
-                  placeholder="浜哄憳绫诲埆"
-                  @change="getPersons(scope.row)"
-                >
-                  <el-option
-                    v-for="dict in dict.type.sys_travelexpensebelong"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.label"
-                  ></el-option>
+                <el-select v-model="scope.row.persontype" value-key="value" placeholder="浜哄憳绫诲埆"
+                  @change="getPersons(scope.row)">
+                  <el-option v-for="dict in dict.type.sys_travelexpensebelong" :key="dict.value" :label="dict.label"
+                    :value="dict.label"></el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="personname"
-              slot=""
-              label="鏀舵浜�"
-              align="center"
-              fixed
-              width="110"
-            >
+            <el-table-column prop="personname" slot="" label="鏀舵浜�" align="center" fixed width="110">
               <template slot-scope="scope">
-                <el-select
-                  v-model="scope.row.personname"
-                  clearable
-                  filterable
-                  allow-create
-                  ref="getReportname"
-                  default-first-option
-                  placeholder="璇烽�夋嫨"
-                  @change="getAccountinfo2(scope.row, scope.row.persontype)"
-                >
-                  <el-option
-                    v-for="item in personsSel"
-                    :key="item.reportNo"
-                    :label="item.reportName"
-                    :value="item.reportName"
-                  >
+                <el-select v-model="scope.row.personname" clearable filterable allow-create ref="getReportname"
+                  default-first-option placeholder="璇烽�夋嫨" @change="getAccountinfo2(scope.row, scope.row.persontype)">
+                  <el-option v-for="item in personsSel" :key="item.reportNo" :label="item.reportName"
+                    :value="item.reportName">
                   </el-option>
                 </el-select>
               </template>
             </el-table-column>
-            <el-table-column
-              prop="bankname"
-              slot=""
-              label="閾惰鍚嶇О"
-              align="center"
-              fixed
-              width="200"
-            >
+            <el-table-column prop="bankname" slot="" label="閾惰鍚嶇О" align="center" fixed width="200">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.bankname" placeholder="閾惰鍚嶇О" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="bankcardno"
-              slot=""
-              label="閾惰鍗″彿"
-              align="center"
-              fixed
-              width="200"
-            >
+            <el-table-column prop="bankcardno" slot="" label="閾惰鍗″彿" align="center" fixed width="200">
               <template slot-scope="scope">
-                <el-input
-                  v-model="scope.row.bankcardno"
-                  placeholder="閾惰鍗″彿"
-                />
+                <el-input v-model="scope.row.bankcardno" placeholder="閾惰鍗″彿" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="amount"
-              slot=""
-              label="鎵撴閲戦"
-              align="center"
-              fixed
-              width="130"
-            >
+            <el-table-column prop="amount" slot="" label="鎵撴閲戦" align="center" fixed width="130">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.amount" placeholder="鎵撴閲戦" />
               </template>
             </el-table-column>
-            <el-table-column
-              prop="remark"
-              slot=""
-              label="璇锋璇存槑"
-              align="center"
-              fixed
-              width="280"
-            >
+            <el-table-column prop="remark" slot="" label="璇锋璇存槑" align="center" fixed width="280">
               <template slot-scope="scope">
                 <el-input v-model="scope.row.remark" placeholder="璇存槑" />
-              </template> </el-table-column
-            ><el-table-column
-              prop="paiddate"
-              slot=""
-              label="鎵撴鏃ユ湡"
-              fixed
-              align="center"
-              width="150"
-            >
+              </template> </el-table-column><el-table-column prop="paiddate" slot="" label="鎵撴鏃ユ湡" fixed align="center"
+              width="150">
               <template slot-scope="scope">
-                <el-date-picker
-                  clearable
-                  size="small"
-                  style="width: 100%"
-                  v-model="scope.row.paiddate"
-                  type="date"
-                  value-format="yyyy-MM-dd HH:mm:ss"
-                  placeholder="鎵撴鏃ユ湡"
-                  :disabled="true"
-                >
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.paiddate" type="date" format="yyyy-MM-dd"
+                  value-format="yyyy-MM-dd HH:mm:ss" placeholder="鎵撴鏃ユ湡" :disabled="true">
                 </el-date-picker>
               </template>
             </el-table-column>
-            <el-table-column
-              label="鎿嶄綔"
-              align="center"
-              width="100"
-              v-if="dialogType == 'edit'"
-            >
+            <el-table-column label="鎿嶄綔" align="center" width="100" v-if="dialogType == 'edit'">
               <template slot-scope="scope">
-                <el-button
-                  type="text"
-                  size="mini"
-                  @click="addPayeeRow(scope.$index)"
-                  >鏂板</el-button
-                >
-                <el-button
-                  @click.native.prevent="
-                    deletePayeeRow(scope.$index, rbPayees, scope.row)
-                  "
-                  type="text"
-                  size="small"
-                >
+                <el-button type="text" size="mini" @click="addPayeeRow(scope.$index)">鏂板</el-button>
+                <el-button @click.native.prevent="
+                  deletePayeeRow(scope.$index, rbPayees, scope.row)
+                  " type="text" size="small">
                   鍒犻櫎
                 </el-button>
               </template>
@@ -1163,76 +620,30 @@
                                                                                               -->
             <el-form-item label="鏂囦欢涓婁紶" align="left" prop="annexfiles">
               <!-- <file-upload ref="fileUpload" :fileType=fileType :limit="1" :on-success="handleUploadSuccess"></file-upload> -->
-              <el-upload
-                size="mini"
-                class="upload-demo"
-                :action="uploadFileUrl"
-                :file-list="fileList"
-                multiple
-                :limit="20"
-                :headers="headers"
-                :on-success="
-                  (response, file, fileList) =>
+              <el-upload size="mini" class="upload-demo" :action="uploadFileUrl" :file-list="fileList" multiple
+                :limit="20" :headers="headers" :on-success="(response, file, fileList) =>
                     uploadSccess(response, file, fileList)
-                "
-                :on-preview="downFile"
-                :disabled="dialogType == 'detail'"
-                :on-error="handleUploadError"
-                :on-exceed="handleExceed"
-                :on-remove="remove"
-                accept="image/*,.pdf"
-              >
-                <el-button
-                  :disabled="dialogType == 'detail'"
-                  size="small"
-                  type="primary"
-                  >涓婁紶</el-button
-                >
+                  " :on-preview="downFile" :disabled="dialogType == 'detail'" :on-error="handleUploadError"
+                :on-exceed="handleExceed" :on-remove="remove" accept="image/*,.pdf">
+                <el-button :disabled="dialogType == 'detail'" size="small" type="primary">涓婁紶</el-button>
               </el-upload>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row v-if="dialogType == 'detail'">
           <el-table :data="fundflowList" border>
-            <el-table-column
-              label="瀹℃牳浜�"
-              align="center"
-              width="120"
-              prop="checkusername"
-            />
-            <el-table-column
-              label="瀹℃牳鏃ユ湡"
-              align="center"
-              width="160"
-              prop="createTime"
-            />
-            <el-table-column
-              label="瀹℃牳缁撴灉"
-              align="center"
-              width="200"
-              prop="flowconclusion"
-              ><template slot-scope="scope"
-                ><span v-if="scope.row.flowconclusion == 1">閫氳繃</span
-                ><span v-if="scope.row.flowconclusion == 2"
-                  >涓嶉�氳繃</span
-                ></template
-              >
+            <el-table-column label="瀹℃牳浜�" align="center" width="120" prop="checkusername" />
+            <el-table-column label="瀹℃牳鏃ユ湡" align="center" width="160" prop="createTime" />
+            <el-table-column label="瀹℃牳缁撴灉" align="center" width="200" prop="flowconclusion"><template
+                slot-scope="scope"><span v-if="scope.row.flowconclusion == 1">閫氳繃</span><span
+                  v-if="scope.row.flowconclusion == 2">涓嶉�氳繃</span></template>
             </el-table-column>
-            <el-table-column
-              label="瀹℃牳澶囨敞"
-              align="center"
-              prop="flowcontent"
-            />
+            <el-table-column label="瀹℃牳澶囨敞" align="center" prop="flowcontent" />
           </el-table>
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button
-          type="primary"
-          @click="submitForm"
-          v-if="dialogType == 'edit'"
-          >淇� 瀛�</el-button
-        >
+        <el-button type="primary" :loading="saveLoading" @click="submitForm" v-if="dialogType == 'edit'">淇� 瀛�</el-button>
         <el-button @click="cancel">鍙� 娑�</el-button>
       </div>
     </el-dialog>
@@ -1277,6 +688,7 @@
 import { addorupdateFund } from "@/api/project/fund";
 import { listReportname, listUser } from "@/api/project/organization";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyAdd } from "@/utils/money";
 export default {
   components: {
     Treeselect,
@@ -1328,6 +740,8 @@
       loading: true,
       // 瀵煎嚭閬僵灞�
       exportLoading: false,
+      // 淇濆瓨鎸夐挳 loading锛岄槻姝㈤噸澶嶆彁浜�
+      saveLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -1348,17 +762,10 @@
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        itemname: null,
-        itemtype: null,
+        costtype: null,
+        donorname: null,
         starttime: null,
-        remark: null,
-        departure: null,
         endtime: null,
-        destination: null,
-        uploadFlag: null,
-        uploadTime: null,
-        // orderByColumn: "createTime",
-        orderByColumn: "id",
         isAsc: "desc"
       },
       queryParams2: {
@@ -1457,7 +864,9 @@
   },
 
   methods: {
-    handleUploadError() {},
+   
+
+    handleUploadError() { },
 
     remove(file) {
       this.fileList.splice(this.fileList.indexOf(file), 1);
@@ -1596,7 +1005,7 @@
         row.days = (
           Math.floor(
             Math.abs(Date.parse(row.starttime) - Date.parse(row.endtime)) /
-              (1000 * 3600 * 24)
+            (1000 * 3600 * 24)
           ) + 1
         ).toString();
       } else {
@@ -1618,9 +1027,9 @@
         if (tempStr == "鏉窞") {
           row.otherexpense = "";
         } else if (
-          tempStr == "鏉窞-妗愬簮" ||
-          tempStr == "鏉窞-寤哄痉" ||
-          tempStr == "鏉窞-娣冲畨"
+          tempStr.includes("妗愬簮") ||
+          tempStr.includes("寤哄痉") ||
+          tempStr.includes("娣冲畨")
         ) {
           row.otherexpense = (parseInt(row.days) * 60).toString();
         } else {
@@ -1751,11 +1160,7 @@
         }
       });
     },
-
-    onpick(e) {
-      // console.log(e,this.value1)
-    },
-
+ 
     gettable(e) {
       const id = e.id;
       getdownload(e.id).then(res => {
@@ -1934,19 +1339,26 @@
 
       //鑾峰彇鎶ラ攢涓讳俊鎭�
       const id = row.id || this.ids;
-      getReimbursement(id).then(response => {
-        this.form = response.data;
-        this.fileList = this.form.annexfiles
-          ? this.form.annexfiles
+      getReimbursement(id)
+        .then(async response => {
+          this.form = response.data;
+          this.fileList = this.form.annexfiles
+            ? this.form.annexfiles
               .split(",")
               .map(item => ({ url: item, name: item }))
-          : [];
-        this.form.recordstatus = response.data.recordstatus + "";
+            : [];
+          this.form.recordstatus = response.data.recordstatus + "";
 
-        let ids = response.data.id;
-        //鑾峰彇鎶ラ攢鏄庣粏淇℃伅
-        getReimbursementdetaillist(ids).then(res => {
-          this.rbDetails = res.data;
+          const ids = response.data.id;
+          this.queryParamsPayee.rbid = ids;
+
+          //鏄庣粏涓庢墦娆句俊鎭簰涓嶄緷璧栵紝骞跺彂鑾峰彇锛屽噺灏戠瓑寰呮椂闂�
+          const [detailRes, payeeRes] = await Promise.all([
+            getReimbursementdetaillist(ids),
+            listReimbursementpayee(this.queryParamsPayee)
+          ]);
+
+          this.rbDetails = detailRes.data;
           if (this.rbDetails.length == 0) {
             this.addDetailRow(0);
           }
@@ -1965,17 +1377,15 @@
 
           //瀹炴椂鍚堣閲戦
           //this.sumTotalFee();
-        });
 
-        //鑾峰彇鎶ラ攢鎵撴淇℃伅
-        this.queryParamsPayee.rbid = ids;
-        listReimbursementpayee(this.queryParamsPayee).then(res => {
-          this.rbPayees = res.rows;
+          this.rbPayees = payeeRes.rows;
           if (this.rbPayees.length == 0) {
             this.addPayeeRow(0);
           }
+        })
+        .catch(() => {
+          this.$modal.msgError("鎶ラ攢鍗曚俊鎭姞杞藉け璐ワ紝璇烽噸璇曪紒");
         });
-      });
     },
 
     /** 鏌ョ湅鎸夐挳鎿嶄綔 */
@@ -1992,59 +1402,56 @@
       this.open = true;
       const id = row.id || this.ids;
 
-      getReimbursement(id).then(response => {
-        this.form = response.data;
-        //闄勪欢
-        this.fileList = this.form.annexfiles
-          ? this.form.annexfiles
+      getReimbursement(id)
+        .then(async response => {
+          this.form = response.data;
+          //闄勪欢
+          this.fileList = this.form.annexfiles
+            ? this.form.annexfiles
               .split(",")
               .map(item => ({ url: item, name: item }))
-          : [];
+            : [];
 
-        //瀹℃牳鐘舵��
-        this.form.recordstatus = response.data.recordstatus + "";
+          //瀹℃牳鐘舵��
+          this.form.recordstatus = response.data.recordstatus + "";
 
-        let ids = response.data.id;
-        let listFundflowparams = {
-          fundid: row.id,
-          fundtype: 1
-        };
-        listFundflow(listFundflowparams).then(res => {
-          this.fundflowList = res.rows;
-        });
+          const ids = response.data.id;
+          const listFundflowparams = {
+            fundid: row.id,
+            fundtype: 1
+          };
+          this.queryParamsPayee.rbid = ids;
 
-        //鎶ラ攢鏄庣粏
-        getReimbursementdetaillist(ids).then(res => {
-          this.rbDetails = res.data;
-          /*
-          for (let i = 0; i < this.rbDetails.length; i++) {
-            this.rbDetails[i].index = i;
-            this.rbDetails[i].searchAddress = {
-              sheng: this.rbDetails[i].travelprovincename,
-              shi: this.rbDetails[i].travelcityname,
-              qu: this.rbDetails[i].traveltownname,
-            };
-          }
-          */
-        });
+          //璧勯噾娴佹按銆佹姤閿�鏄庣粏銆佹墦娆句俊鎭簰涓嶄緷璧栵紝骞跺彂鑾峰彇
+          const [fundflowRes, detailRes, payeeRes] = await Promise.all([
+            listFundflow(listFundflowparams),
+            getReimbursementdetaillist(ids),
+            listReimbursementpayee(this.queryParamsPayee)
+          ]);
 
-        if (this.rbDetails.length > 0) this.sumTotalFee();
+          this.fundflowList = fundflowRes.rows;
+          this.rbDetails = detailRes.data;
 
-        //浠樻淇℃伅
-        this.queryParamsPayee.rbid = ids;
-        listReimbursementpayee(this.queryParamsPayee).then(res => {
-          this.rbPayees = res.rows;
+          //鏄庣粏鍔犺浇瀹屾垚鍚庡啀璁$畻鍚堣锛屼慨澶嶅師浠g爜鍦ㄦ槑缁嗚繑鍥炲墠灏� sumTotalFee 鐨勭珵鎬侀棶棰�
+          if (this.rbDetails.length > 0) this.sumTotalFee();
+
+          //浠樻淇℃伅
+          this.rbPayees = payeeRes.rows;
           if (this.rbPayees.length == 0) {
             this.addPayeeRow(0);
           }
+        })
+        .catch(() => {
+          this.$modal.msgError("鎶ラ攢鍗曚俊鎭姞杞藉け璐ワ紝璇烽噸璇曪紒");
         });
-      });
     },
 
     /** 鎻愪氦鎸夐挳 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
+      //闃叉閲嶅鎻愪氦锛氫繚瀛樹腑鐩存帴蹇界暐鍐嶆鐐瑰嚮
+      if (this.saveLoading) return;
+      this.$refs["form"].validate(async valid => {
+        if (!valid) return;
           /**
            let indexErrTime = this.rbDetails.findIndex((item) => {
              if (item.endtime && item.starttime) {
@@ -2101,6 +1508,8 @@
           }
           */
 
+          try {
+          this.saveLoading = true;
           //闄勪欢鏂囦欢澶勭悊
           let list = this.fileList;
           if (list.length > 0) {
@@ -2126,83 +1535,90 @@
           const rbDetails = [...this.rbDetails];
           const rbPayees = [...this.rbPayees];
           if (this.form.id != null) {
-            updateReimbursement(this.form)
-              .then(res => {
-                //淇濆瓨鏄庣粏
-                for (let i = 0; i < rbDetails.length; i++) {
-                  if (rbDetails[i].rbid != null) {
-                    updateReimbursementdetail(rbDetails[i]);
-                  } else {
-                    //rbid鍏宠仈涓昏〃Id
-                    rbDetails[i].rbid = this.form.id;
-                    addReimbursementdetail(rbDetails[i]);
-                  }
-                }
+            //绗�1姝ワ細鏇存柊涓昏〃锛屾垚鍔熷悗鍐嶅鐞嗗瓙琛�
+            await updateReimbursement(this.form);
 
-                //淇濆瓨璐︽埛
-                for (let i = 0; i < rbPayees.length; i++) {
-                  if (rbPayees[i].rbid != null) {
-                    updateReimbursementpayee(rbPayees[i]);
-                  } else {
-                    //rbid鍏宠仈涓昏〃Id
-                    rbPayees[i].rbid = this.form.id;
-                    addReimbursementpayee(rbPayees[i]);
-                  }
+            //绗�2姝ワ細骞跺彂淇濆瓨鏄庣粏锛岀瓑寰呭叏閮ㄥ畬鎴愶紝浠讳竴澶辫触鍒欒蛋 catch 鎻愮ず
+            await Promise.all(
+              rbDetails.map(detail => {
+                if (detail.rbid != null) {
+                  return updateReimbursementdetail(detail);
                 }
-
-                this.$modal.msgSuccess("淇敼鎶ラ攢鍗曚繚瀛樻垚鍔�!");
-                this.open = false;
-                this.getList();
+                //rbid鍏宠仈涓昏〃Id
+                detail.rbid = this.form.id;
+                return addReimbursementdetail(detail);
               })
-              .catch(err => {
-                this.$modal.msgError("淇敼鎶ラ攢鍗曚繚瀛樺け璐ワ紒");
-              });
+            );
+
+            //绗�3姝ワ細骞跺彂淇濆瓨璐︽埛
+            await Promise.all(
+              rbPayees.map(payee => {
+                if (payee.rbid != null) {
+                  return updateReimbursementpayee(payee);
+                }
+                //rbid鍏宠仈涓昏〃Id
+                payee.rbid = this.form.id;
+                return addReimbursementpayee(payee);
+              })
+            );
+
+            this.$modal.msgSuccess("淇敼鎶ラ攢鍗曚繚瀛樻垚鍔�!");
           } else {
             this.form.recordstatus = -1;
-            addReimbursement(this.form)
-              .then(response => {
-                //淇濆瓨鏄庣粏
-                for (let i = 0; i < rbDetails.length; i++) {
-                  //rbid鍏宠仈涓昏〃Id
-                  rbDetails[i].rbid = response.data;
-                  addReimbursementdetail(rbDetails[i]);
-                }
+            //绗�1姝ワ細鏂板涓昏〃锛岃繑鍥炰富琛↖d
+            const response = await addReimbursement(this.form);
 
-                //淇濆瓨璐﹀彿
-                for (let i = 0; i < rbPayees.length; i++) {
-                  //rbid鍏宠仈涓昏〃Id
-                  rbPayees[i].rbid = response.data;
-                  addReimbursementpayee(rbPayees[i]);
-                }
-
-                this.$modal.msgSuccess("鏂板鎶ラ攢鍗曚繚瀛樻垚鍔�!");
-                this.open = false;
-                this.getList();
+            //绗�2姝ワ細骞跺彂淇濆瓨鏄庣粏
+            await Promise.all(
+              rbDetails.map(detail => {
+                //rbid鍏宠仈涓昏〃Id
+                detail.rbid = response.data;
+                return addReimbursementdetail(detail);
               })
-              .catch(err => {
-                this.$modal.msgError("鏂板鎶ラ攢鍗曚繚瀛樺け璐ワ紒");
-              });
+            );
+
+            //绗�3姝ワ細骞跺彂淇濆瓨璐﹀彿
+            await Promise.all(
+              rbPayees.map(payee => {
+                //rbid鍏宠仈涓昏〃Id
+                payee.rbid = response.data;
+                return addReimbursementpayee(payee);
+              })
+            );
+
+            this.$modal.msgSuccess("鏂板鎶ラ攢鍗曚繚瀛樻垚鍔�!");
+          }
+
+          //鎵�鏈変繚瀛樻楠ゅ叏閮ㄦ垚鍔熷悗鎵嶅叧闂脊绐楀苟鍒锋柊鍒楄〃
+          this.open = false;
+          this.getList();
+          } catch (err) {
+            this.$modal.msgError("鎶ラ攢鍗曚繚瀛樺け璐ワ紝璇烽噸璇曪紒");
+          } finally {
+            this.saveLoading = false;
           }
         }
-      });
+      );
     },
 
     /** 鍒犻櫎鎸夐挳鎿嶄綔 */
     handleDelete(row) {
       const ids = row.id || this.ids;
-      console.log(ids);
       this.$modal
         .confirm("鏄惁纭鍒犻櫎璇ユ潯璁板綍锛�")
-        .then(function() {
+        .then(function () {
           // 鍒犻櫎details鍐呯殑鏁版嵁
           return delReimbursement(ids);
         })
         .then(() => {
-          delReimbursementdetail(ids);
+          //绛夊緟鏄庣粏鍒犻櫎瀹屾垚鍚庡啀鍒锋柊鍒楄〃锛岄伩鍏嶅垪琛ㄥ埛鏂版椂鏄庣粏灏氭湭鍒犻櫎
+          return delReimbursementdetail(ids);
+        })
+        .then(() => {
           this.getList();
           this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
 
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
@@ -2218,7 +1634,10 @@
           this.$download.name(response.msg);
           this.exportLoading = false;
         })
-        .catch(() => {});
+        .catch(() => {
+          //澶辫触鏃朵篃瑕佸浣� loading锛屽惁鍒欐寜閽案涔呰浆鍦�
+          this.exportLoading = false;
+        });
     },
 
     //鏂板涓�琛�
@@ -2399,109 +1818,32 @@
     },
 
     //璁$畻涓�琛屽悎璁�
-    //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣
+    //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛�
     sumRowFee(row) {
-      let totalFee = 0;
-      if (!isNaN(parseFloat(row.trafficexpense))) {
-        totalFee += parseFloat(row.trafficexpense);
-      }
-      if (!isNaN(parseFloat(row.cityfee))) {
-        totalFee += parseFloat(row.cityfee);
-      }
-      if (!isNaN(parseFloat(row.hotelexpense))) {
-        totalFee += parseFloat(row.hotelexpense);
-      }
-      if (!isNaN(parseFloat(row.otherexpense))) {
-        totalFee += parseFloat(row.otherexpense);
-      }
-      if (!isNaN(parseFloat(row.foodexpenses))) {
-        totalFee += parseFloat(row.foodexpenses);
-      }
-      if (!isNaN(parseFloat(row.foodallowance))) {
-        totalFee += parseFloat(row.foodallowance);
-      }
-      if (!isNaN(parseFloat(row.otherfeeamount))) {
-        totalFee += parseFloat(row.otherfeeamount);
-      }
-      row.total = totalFee;
+      row.total = moneySum([
+        row.trafficexpense,
+        row.cityfee,
+        row.hotelexpense,
+        row.otherexpense,
+        row.foodexpenses,
+        row.foodallowance,
+        row.otherfeeamount
+      ]);
 
-      /*
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].trafficexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].trafficexpense);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].cityfee))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].cityfee);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].hotelexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].hotelexpense);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].otherexpense);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodexpenses))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].foodexpenses);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodallowance))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].foodallowance);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherfeeamount))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].otherfeeamount);
-      }
-      this.rbDetails[rowIndex].total = parseFloat(totalFee).toFixed(2);
-      this.$set(this.rbDetails, rowIndex, this.rbDetails[rowIndex]);
-      */
       //閲嶆柊璁$畻鏁翠釜鎶ラ攢鍗曠殑鍚堣
       this.sumTotalFee();
     },
 
     //璁$畻璐圭敤鍚堣
     sumTotalFee() {
-      let allSum = 0;
-
-      //鎹愮尞鑰呭灞炶垂鐢�
-      if (!isNaN(parseFloat(this.form.donoramount))) {
-        allSum += parseFloat(this.form.donoramount);
-      }
-
       //鎶ラ攢鏄庣粏璐圭敤
       try {
-        for (let i = 0; i < this.rbDetails.length; i++) {
-          /*
-          let totalFee = 0;
-          //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
-            totalFee += parseFloat(this.rbDetails[i].total);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
-            totalFee += parseFloat(this.rbDetails[i].cityfee);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].otherexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
-            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
-            totalFee += parseFloat(this.rbDetails[i].foodallowance);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
-            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
-          }
-          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
-          this.$set(this.rbDetails, i, this.rbDetails[i]);
-          */
-
-          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
-            allSum += parseFloat(this.rbDetails[i].total);
-          }
-        }
-
-        this.form.amountrequested = allSum.toFixed(2);
+        this.form.amountrequested = moneyAdd(
+          moneySum(this.rbDetails, "total"),
+          this.form.donoramount
+        ).toFixed(2);
         this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
-      } catch {}
+      } catch { }
     },
 
     //閲戦鏁板瓧杞崲鎴愬ぇ鍐�
@@ -2623,9 +1965,11 @@
   background: #e8f4ff !important;
   /* color:whitesmoke; */
 }
+
 .button-delete {
   color: rgb(236, 69, 69);
 }
+
 ::v-deep.el-table .error-row {
   background: #fcebeb;
 }
diff --git a/src/views/project/travelexpenseapply/travelexpensedetail/index.vue b/src/views/project/travelexpenseapply/travelexpensedetail/index.vue
index 4a13d16..62443b8 100644
--- a/src/views/project/travelexpenseapply/travelexpensedetail/index.vue
+++ b/src/views/project/travelexpenseapply/travelexpensedetail/index.vue
@@ -9,7 +9,7 @@
               <el-date-picker
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
                 :disabled="true"
@@ -369,7 +369,7 @@
                   size="small"
                   style="width: 100%"
                   v-model="scope.row.starttime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="寮�濮嬫棩鏈�"
                   @blur="getdays(scope.row)"
@@ -401,7 +401,7 @@
                   size="small"
                   style="width: 100%"
                   v-model="scope.row.endtime"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="缁撴潫鏃ユ湡"
                   @blur="getdays(scope.row)"
@@ -848,7 +848,7 @@
             <!--
             <el-table-column prop="paiddate" slot="" label="鎵撴鏃ユ湡" fixed align="center" width="150">
               <template slot-scope="scope">
-                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.paiddate" type="date"
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.paiddate" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="鎵撴鏃ユ湡" :disabled="true">
                 </el-date-picker>
               </template>
@@ -1305,6 +1305,8 @@
 import { listReportname, listUser } from "@/api/project/organization";
 import { getToken } from "@/utils/auth";
 import debounce from "lodash/debounce";
+import { moneySum, moneyAdd, moneyRound } from "@/utils/money";
+import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
 export default {
   components: {
     Treeselect,
@@ -1689,7 +1691,43 @@
     },
 
     //鏂囦欢涓婁紶鎴愬姛鍥炶皟
+    /**
+     * 2026-10-15锛氫笂浼犳椂鏍¢獙闄勪欢鏂囦欢鍚嶏紙涓氬姟瑕佹眰锛氫笉鍚堟牸绔嬪嵆鎻愮ず涓斾笉鍔犲叆鍒楄〃锛夈��
+     * 瑙勫垯涓庡悗绔� AttachmentNameValidator 鍚屽彛寰勶細蹇呴』鍚腑鏂� / 鍘绘帀鎵╁睍鍚嶅悗涓诲共 鈮�20 瀛� /
+     * 涓嶅惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗︺��
+     */
+    checkUploadFileName(file) {
+      const raw = file && file.raw ? file.raw.name : file && file.name;
+      const r = checkFileName(raw);
+      if (!r.ok) {
+        this.$modal.msgError(r.msg);
+        return false;
+      }
+      return true;
+    },
+
+    /**
+     * 2026-10-15锛氫繚瀛樺墠鏍¢獙鏁村崟鏄庣粏闄勪欢鏂囦欢鍚嶏紙鍚悓涓�琛屽唴閲嶅悕锛夈��
+     * 鍙e緞锛堜笟鍔$‘璁わ級锛氬彧鏍¢獙"鏈鍙樻洿"鐨勯檮浠垛�斺�旇�佸崟鎹噷宸插瓨鍦ㄧ殑涓嶅悎瑙勯檮浠跺悕涓嶈兘鎶婁繚瀛樺崱姝�
+     * 锛堝惁鍒欒�佸崟鎹敼涓�涓噾棰濋兘瀛樹笉杩涘幓锛夈�傚悗绔寜 id 璇绘棫璁板綍鏀捐鍘嗗彶闄勪欢锛涘墠绔嬁涓嶅埌"鍝簺鏄巻鍙�"
+     * 鐨勬潈濞佷俊鎭紝鍥犳**浠呮柊澧炲崟鎹�**鍋氫繚瀛樺墠鎷︽埅锛岀紪杈戣�佸崟鎹椂鏂板鐨勪笉鍚堣闄勪欢鐢卞悗绔簩娆℃牎楠屾嫤涓嬨��
+     */
+    checkDetailFileNames() {
+      if (this.form && this.form.id) {
+        return true;
+      }
+      const c = checkDetails(this.rbDetails);
+      if (!c.ok) {
+        this.$modal.msgError(c.msg);
+        return false;
+      }
+      return true;
+    },
+
     uploadSccess(response, file, fileList) {
+      if (!this.checkUploadFileName(file)) {
+        return;
+      }
       this.rbDetails;
       const config = {
         headers: { Authorization: "Bearer " + this.ICDtoken }
@@ -1710,14 +1748,11 @@
                 name: file.name,
                 url: URL.createObjectURL(blob)
               });
-              // console.log(file.response.url);
-              // console.log(file);
-
-              this.pdfimgsrcList.push(file.response.url);
-              this.fileListto.push({
-                name: file.response.fileName,
-                url: file.response.url
-              });
+              // 2026-10-15锛氬垹闄よ繖閲岀殑绗簩娆� push銆傚師鏉ヤ竴娆′笂浼犱細鍚� fileListto / pdfimgsrcList
+              // 鍚勫啓涓ゆ潯锛屼笖绗簩鏉$殑 name 鍙栫殑鏄� file.response.fileName锛堝瓨鍌ㄨ矾寰勶級锛涜�� remove()
+              // 浼氭妸鏁翠釜 fileListto 鍥炲啓鍒� rbDetails[atpresent].annexfilesList锛屽鑷存槑缁嗛檮浠堕噷
+              // 娣峰叆璺緞褰㈡�佺殑 name锛岃闄勪欢鏂囦欢鍚嶆牎楠岃鎷︼紙鍓嶇娌℃湁"璺緞褰㈡�佽烦杩�"璞佸厤锛夛紝
+              // 鍚屾椂绁ㄦ嵁鍒楄〃浼氬鍑轰竴琛屻��
               console.log(URL.createObjectURL(blob), "ur杞崲");
             })
             .catch(error => {
@@ -2146,9 +2181,9 @@
           if (tempStr == "鏉窞") {
             row.otherexpense = "";
           } else if (
-            tempStr == "鏉窞-妗愬簮" ||
-            tempStr == "鏉窞-寤哄痉" ||
-            tempStr == "鏉窞-娣冲畨"
+            tempStr.includes("妗愬簮") ||
+          tempStr.includes("寤哄痉") ||
+          tempStr.includes("娣冲畨")
           ) {
             row.otherexpense = (parseInt(row.days) * 60).toString();
           } else {
@@ -2537,7 +2572,7 @@
             .map(item => ({ url: item, name: item }))
           : [];
         //瀹℃牳鐘舵��
-        this.form.recordstatus = response.data.recordstatus + "";
+        this.form.recordstatus = this.toStatusText(response.data.recordstatus, "-1");
         let ids = response.data.id;
         let listFundflowparams = {
           fundid: ids,
@@ -2548,14 +2583,19 @@
         });
 
         //鎶ラ攢鏄庣粏
-        getReimbursementdetaillist(ids).then(res => {
-          this.rbDetails = res.data;
-          //鍚堣璐圭敤
-          // if (this.rbDetails.length > 0) this.sumTotalFee();
-          for (let i = 0; i < this.rbDetails.length; i++) {
-            this.sumRowFee(this.rbDetails[i]);
-          }
-        });
+        getReimbursementdetaillist(ids)
+          .then(res => {
+            this.rbDetails = this.normalizeDetailList(res);
+            //鍚堣璐圭敤
+            // if (this.rbDetails.length > 0) this.sumTotalFee();
+            for (let i = 0; i < this.rbDetails.length; i++) {
+              this.sumRowFee(this.rbDetails[i]);
+            }
+          })
+          .catch(err => {
+            this.rbDetails = [];
+            console.error("鑾峰彇鎶ラ攢鏄庣粏澶辫触,id=" + ids, err);
+          });
 
         //浠樻淇℃伅
         this.queryParamsPayee.rbid = ids;
@@ -2591,7 +2631,8 @@
       getReimbursement(id).then(response => {
         this.form = response.data;
         console.log(this.form.checkstatus, "checkstatus");
-        this.form.checkstatus = this.form.checkstatus.toString();
+        // checkstatus 鍦ㄥ簱涓彲涓虹┖锛堥瀹$姸鎬佸皻鏈骇鐢熸椂锛夛紝鐩存帴 toString 浼氭姏 TypeError 涓柇鍚庣画鍙栨暟
+        this.form.checkstatus = this.toStatusText(this.form.checkstatus, "-1");
 
         //绁ㄦ嵁
         this.fileListto = this.form.annexfiles
@@ -2618,16 +2659,22 @@
         });
 
         //鎶ラ攢鏄庣粏
-        getReimbursementdetaillist(ids).then(res => {
-          this.rbDetails = res.data;
-          console.log(this.rbDetails);
+        getReimbursementdetaillist(ids)
+          .then(res => {
+            this.rbDetails = this.normalizeDetailList(res);
+            console.log("鎶ラ攢鏄庣粏琛屾暟锛�", this.rbDetails.length, this.rbDetails);
 
-          //鍚堣璐圭敤
-          // if (this.rbDetails.length > 0) this.sumTotalFee();
-          for (let i = 0; i < this.rbDetails.length; i++) {
-            this.sumRowFee(this.rbDetails[i]);
-          }
-        });
+            //鍚堣璐圭敤
+            // if (this.rbDetails.length > 0) this.sumTotalFee();
+            for (let i = 0; i < this.rbDetails.length; i++) {
+              this.sumRowFee(this.rbDetails[i]);
+            }
+          })
+          .catch(err => {
+            // 鍙栨暟澶辫触鏃朵笉鍐嶉潤榛橈細缃┖骞舵墦鍑哄師鍥狅紝閬垮厤鈥滄帴鍙f湁鏁版嵁浣嗛〉闈㈢┖鐧解�濇棤浠庢帓鏌�
+            this.rbDetails = [];
+            console.error("鑾峰彇鎶ラ攢鏄庣粏澶辫触,id=" + ids, err);
+          });
 
         //浠樻淇℃伅
         this.queryParamsPayee.rbid = ids;
@@ -2680,11 +2727,7 @@
           this.continueOrExit();
         } else {
           this.$modal.closeLoading();
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -2751,6 +2794,11 @@
 
     /** 鎻愪氦淇濆瓨鎸夐挳 */
     submitForm: debounce(function (data) {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       this.$refs["form"].validate(valid => {
         if (valid) {
           //绁ㄦ嵁鏂囦欢澶勭悊
@@ -2974,6 +3022,11 @@
     },
     // 鎺ュ彈鎻愰啋绔嬪埢淇濆瓨
     Savenow() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       this.Savereminder = false;
       this.Reminderquantity = 0;
       this.totalquantity = 0;
@@ -3250,108 +3303,71 @@
         });
     },
 
-    //璁$畻涓�琛屽悎璁�
-    //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣
-    sumRowFee(row) {
-      let totalFee = 0;
-      if (!isNaN(parseFloat(row.trafficexpense))) {
-        totalFee += parseFloat(row.trafficexpense);
+    /**
+     * 鐘舵�佺被瀛楁杞瓧绗︿覆锛堟帴鍙e彲鑳借繑鍥� null锛夈��
+     *
+     * 鑳屾櫙锛歝heckstatus銆乺ecordstatus 绛夊湪搴撲腑鍙┖锛屾棭鏈熺洿鎺ヨ皟鐢� .toString()
+     * 浼氭姏 TypeError 骞朵腑鏂叾鍚庣殑鍙栨暟閫昏緫锛岃〃鐜颁负鈥滄帴鍙e凡鏈夋暟鎹絾鏄庣粏鍖虹┖鐧解�濄��
+     *
+     * @param {*} value 鍘熷鐘舵�佸��
+     * @param {string} fallback 涓虹┖鏃剁殑鍏滃簳鍊�
+     * @returns {string}
+     */
+    toStatusText(value, fallback) {
+      if (value === null || value === undefined || value === "") {
+        return fallback;
       }
-      if (!isNaN(parseFloat(row.cityfee))) {
-        totalFee += parseFloat(row.cityfee);
-      }
-      if (!isNaN(parseFloat(row.hotelexpense))) {
-        totalFee += parseFloat(row.hotelexpense);
-      }
-      if (!isNaN(parseFloat(row.otherexpense))) {
-        totalFee += parseFloat(row.otherexpense);
-      }
-      if (!isNaN(parseFloat(row.foodexpenses))) {
-        totalFee += parseFloat(row.foodexpenses);
-      }
-      if (!isNaN(parseFloat(row.foodallowance))) {
-        totalFee += parseFloat(row.foodallowance);
-      }
-      if (!isNaN(parseFloat(row.otherfeeamount))) {
-        totalFee += parseFloat(row.otherfeeamount);
-      }
-      row.total = totalFee.toFixed(2);
+      return String(value);
+    },
 
-      /*
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].trafficexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].trafficexpense);
+    /**
+     * 缁熶竴浠庢槑缁嗘帴鍙e搷搴斾腑鍙栧嚭鏁扮粍銆�
+     *
+     * 姝e父涓� AjaxResult 鐨� data 鏁扮粍锛涜嫢鍚庣鏀逛负鍒嗛〉缁撴瀯锛坱otal + rows锛夛紝
+     * res.data 灏嗕笉鏄暟缁勶紝鐩存帴缁戝畾鍒� el-table 浼氬鑷粹�滄湁鏁版嵁浣嗕笉鏄剧ず鈥濄��
+     *
+     * @param {Object} res 鎺ュ彛鍘熷鍝嶅簲
+     * @returns {Array} 鏄庣粏鏁扮粍锛堝紓甯告椂涓虹┖鏁扮粍锛屼笉浼氳琛ㄦ牸鎷垮埌闈炴暟缁勶級
+     */
+    normalizeDetailList(res) {
+      if (!res) {
+        return [];
       }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].cityfee))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].cityfee);
+      if (Array.isArray(res.data)) {
+        return res.data;
       }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].hotelexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].hotelexpense);
+      if (Array.isArray(res.rows)) {
+        return res.rows;
       }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherexpense))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].otherexpense);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodexpenses))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].foodexpenses);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].foodallowance))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].foodallowance);
-      }
-      if (!isNaN(parseFloat(this.rbDetails[rowIndex].otherfeeamount))) {
-        totalFee += parseFloat(this.rbDetails[rowIndex].otherfeeamount);
-      }
-      this.rbDetails[rowIndex].total = parseFloat(totalFee).toFixed(2);
-      this.$set(this.rbDetails, rowIndex, this.rbDetails[rowIndex]);
-      */
+      return [];
+    },
+
+    //璁$畻涓�琛屽悎璁�
+    //璁$畻褰撳墠琛屾姤閿�鍐呭璐圭敤鍚堣锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛�
+    sumRowFee(row) {
+      const totalFee = moneySum([
+        row.trafficexpense,
+        row.cityfee,
+        row.hotelexpense,
+        row.otherexpense,
+        row.foodexpenses,
+        row.foodallowance,
+        row.otherfeeamount
+      ]);
+      row.total = moneyRound(totalFee).toFixed(2);
+
       //閲嶆柊璁$畻鏁翠釜鎶ラ攢鍗曠殑鍚堣
       this.sumTotalFee();
     },
 
     //璁$畻璐圭敤鍚堣
     sumTotalFee() {
-      let allSum = 0;
-
-      //鎹愮尞鑰呭灞炶垂鐢�
-      if (!isNaN(parseFloat(this.form.donoramount))) {
-        allSum += parseFloat(this.form.donoramount);
-      }
-
       //鎶ラ攢鏄庣粏璐圭敤
       try {
-        for (let i = 0; i < this.rbDetails.length; i++) {
-          /*
-          let totalFee = 0;
-          //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
-            totalFee += parseFloat(this.rbDetails[i].total);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
-            totalFee += parseFloat(this.rbDetails[i].cityfee);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].otherexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
-            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
-            totalFee += parseFloat(this.rbDetails[i].foodallowance);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
-            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
-          }
-          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
-          this.$set(this.rbDetails, i, this.rbDetails[i]);
-          */
-
-          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
-            allSum += parseFloat(this.rbDetails[i].total);
-          }
-        }
-
-        this.form.amountrequested = allSum.toFixed(2);
+        this.form.amountrequested = moneyAdd(
+          moneySum(this.rbDetails, "total"),
+          this.form.donoramount
+        ).toFixed(2);
         this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
       } catch { }
     },
diff --git a/src/views/project/travelexpensecheck/index.vue b/src/views/project/travelexpensecheck/index.vue
index 5fcc7c6..8cbfa53 100644
--- a/src/views/project/travelexpensecheck/index.vue
+++ b/src/views/project/travelexpensecheck/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
       <el-row>
         <el-col :span="5">
           <el-form-item label="鎹愮尞妗堜緥" prop="name">
@@ -33,7 +34,16 @@
           </el-form-item>
         </el-col>
       </el-row>
-      <el-row>
+      <el-row> <el-col :span="5">
+          <el-form-item label="鎶ラ攢绫诲埆" prop="costtype">
+            <el-input v-model="queryParams.costtype" placeholder="璇烽�夋嫨鎶ラ攢绫诲埆" clearable size="small" v-if="0"
+              @keyup.enter.native="handleQuery" />
+            <el-select v-model="queryParams.costtype" placeholder="璇烽�夋嫨鎶ラ攢绫诲埆" clearable size="small">
+              <el-option v-for="dict in dict.type.sys_travelexpensebelong" :key="dict.value" :label="dict.label"
+                :value="dict.label" />
+            </el-select>
+          </el-form-item>
+        </el-col>
         <el-col :span="5">
           <el-form-item label="缁忓姙浜�" prop="username">
             <el-input v-model="queryParams.username" placeholder="璇疯緭鍏ユ姤閿�浜�" clearable size="small"
@@ -46,9 +56,11 @@
               @keyup.enter.native="handleQuery" />
           </el-form-item>
         </el-col>
+      </el-row>
+      <el-row>
         <el-col :span="8">
           <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-            <el-date-picker format="yyyy-MM-dd" value-format="yyyy-MM-dd" v-model="value1" type="daterange"
+            <el-date-picker format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" v-model="value1" type="daterange"
               @blur="onpick" range-separator="鑷�" start-placeholder="鎶ラ攢鐢宠寮�濮嬫棩鏈�" end-placeholder="鎶ラ攢鐢宠缁撴潫鏃ユ湡"
               @keyup.enter.native="handleQuery">
             </el-date-picker>
@@ -145,7 +157,7 @@
         <el-row>
           <el-col :span="5">
             <el-form-item label="鐢宠鏃ユ湡" prop="applyTime">
-              <el-date-picker style="width: 100%" v-model="form.applyTime" :disabled="true" type="date"
+              <el-date-picker style="width: 100%" v-model="form.applyTime" :disabled="true" type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss" placeholder="鐢宠鏃ユ湡">
               </el-date-picker>
             </el-form-item>
@@ -293,7 +305,7 @@
                       );
                     }
                   }
-                }" clearable size="small" style="width: 100%" v-model="scope.row.starttime" type="date"
+                }" clearable size="small" style="width: 100%" v-model="scope.row.starttime" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="寮�濮嬫棩鏈�" @blur="getallowance(scope.row)">
                 </el-date-picker>
               </template>
@@ -309,7 +321,7 @@
                       );
                     }
                   }
-                }" clearable size="small" style="width: 100%" v-model="scope.row.endtime" type="date"
+                }" clearable size="small" style="width: 100%" v-model="scope.row.endtime" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="缁撴潫鏃ユ湡" @blur="getallowance(scope.row)">
                 </el-date-picker>
               </template>
@@ -537,7 +549,7 @@
               </template> </el-table-column><el-table-column prop="paiddate" slot="" label="鎵撴鏃ユ湡" fixed align="center"
               width="150">
               <template slot-scope="scope">
-                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.paiddate" type="date"
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.paiddate" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="鎵撴鏃ユ湡" :disabled="true"
                   @blur="getallowance(scope.row)">
                 </el-date-picker>
@@ -564,7 +576,7 @@
               <!-- <file-upload ref="fileUpload" :fileType=fileType :limit="1" :on-success="handleUploadSuccess"></file-upload> -->
               <el-upload size="mini" class="upload-demo" :action="uploadFileUrl" :file-list="fileList" multiple
                 :limit="20" :headers="headers" :on-success="(response, file, fileList) =>
-                    uploadSccess(response, file, fileList)
+                  uploadSccess(response, file, fileList)
                   " :on-preview="downFile" :disabled="dialogType == 'detail'" :on-error="handleUploadError"
                 :on-exceed="handleExceed" :on-remove="remove" accept="image/*,.pdf">
                 <el-button :disabled="dialogType == 'detail'" size="small" type="primary">涓婁紶</el-button>
@@ -606,7 +618,7 @@
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="checksubmit" v-if="dialogType == 'edit'">淇� 瀛�</el-button>
+        <el-button type="primary" :loading="checkSubmitLoading" :disabled="checkSubmitLoading" @click="checksubmit" v-if="dialogType == 'edit'">淇� 瀛�</el-button>
         <el-button @click="cancel">鍙� 娑�</el-button>
       </div>
     </el-dialog>
@@ -667,6 +679,7 @@
 import { getUserProfile } from "@/api/system/user";
 import { getToken } from "@/utils/auth";
 import { setItem, grtItem, removeItem } from "@/utils/storage.js";
+import { moneySum } from "@/utils/money";
 
 export default {
   components: {
@@ -684,6 +697,7 @@
   ],
   data() {
     return {
+      checkSubmitLoading: false,
       checkObj: {
         flowlevelone: null,
         flowconclusion: null,
@@ -834,6 +848,7 @@
     },
 
     checksubmit() {
+      if (this.checkSubmitLoading) return;
       let checkfundobj = {
         flowconclusion: this.checkObj.flowlevelone,
         flowcontent: this.checkObj.flowconclusion,
@@ -849,7 +864,9 @@
         return;
       }
 
+      this.checkSubmitLoading = true;
       checkfund(checkfundobj).then(res => {
+        this.checkSubmitLoading = false;
         if (res.code == 200) {
           this.reset();
           this.open = false;
@@ -857,11 +874,7 @@
           this.$modal.msgSuccess("瀹℃牳瀹屾垚!");
         } else {
           this.open = false;
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1283,41 +1296,25 @@
         });
     },
 
-    //璁$畻璐圭敤鍚堣
+    //璁$畻璐圭敤鍚堣锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛岀姝� parseFloat 绱姞锛�
     sumTotalFee(scope) {
-      let allSum = 0;
       try {
         for (let i = 0; i < this.rbDetails.length; i++) {
-          let totalFee = 0;
+          const row = this.rbDetails[i];
           //璁$畻褰撳墠鎶ラ攢鍐呭璐圭敤鍚堣
-          if (!isNaN(parseFloat(this.rbDetails[i].trafficexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].trafficexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].cityfee))) {
-            totalFee += parseFloat(this.rbDetails[i].cityfee);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].hotelexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].hotelexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherexpense))) {
-            totalFee += parseFloat(this.rbDetails[i].otherexpense);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodexpenses))) {
-            totalFee += parseFloat(this.rbDetails[i].foodexpenses);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].foodallowance))) {
-            totalFee += parseFloat(this.rbDetails[i].foodallowance);
-          }
-          if (!isNaN(parseFloat(this.rbDetails[i].otherfeeamount))) {
-            totalFee += parseFloat(this.rbDetails[i].otherfeeamount);
-          }
-          this.rbDetails[i].total = parseFloat(totalFee).toFixed(2);
-          this.$set(this.rbDetails, scope.$index, this.rbDetails[i]);
-          if (!isNaN(parseFloat(this.rbDetails[i].total))) {
-            allSum += parseFloat(this.rbDetails[i].total);
-          }
+          const totalFee = moneySum([
+            row.trafficexpense,
+            row.cityfee,
+            row.hotelexpense,
+            row.otherexpense,
+            row.foodexpenses,
+            row.foodallowance,
+            row.otherfeeamount
+          ]);
+          row.total = totalFee.toFixed(2);
+          this.$set(this.rbDetails, scope.$index, row);
         }
-        this.form.amountrequested = allSum.toFixed(2);
+        this.form.amountrequested = moneySum(this.rbDetails, "total").toFixed(2);
         this.form.bigstrmoney = this.convertCurrency(this.form.amountrequested);
       } catch { }
     },
diff --git a/src/views/project/travelexpensedeal/index.vue b/src/views/project/travelexpensedeal/index.vue
index 13bbf91..90705e9 100644
--- a/src/views/project/travelexpensedeal/index.vue
+++ b/src/views/project/travelexpensedeal/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/project/unitCost/index.vue b/src/views/project/unitCost/index.vue
index 11d4e41..1793730 100644
--- a/src/views/project/unitCost/index.vue
+++ b/src/views/project/unitCost/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
       <el-form-item label="鍖荤枟鏈烘瀯" prop="name">
         <el-input v-model="queryParams.name" placeholder="璇疯緭鍏ュ尰鐤楁満鏋�" clearable size="small"
           @keyup.enter.native="handleQuery" />
diff --git a/src/views/project/unitCost/particulars/index.vue b/src/views/project/unitCost/particulars/index.vue
index 8947231..2c237ca 100644
--- a/src/views/project/unitCost/particulars/index.vue
+++ b/src/views/project/unitCost/particulars/index.vue
@@ -198,7 +198,7 @@
                   style="width: 100%"
                   v-model="scope.row.receiveTime"
                   :disabled="true"
-                  type="date"
+                  type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss"
                   placeholder="鎺ユ敹鏃ユ湡"
                 >
@@ -257,7 +257,7 @@
             </el-table-column>
             <el-table-column prop="amounttime" align="center" label="鏀舵鏃ユ湡" width="200">
               <template slot-scope="scope">
-                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date"
+                <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.amounttime" type="date" format="yyyy-MM-dd"
                   value-format="yyyy-MM-dd HH:mm:ss" placeholder="鏀舵鏃ユ湡">
                 </el-date-picker>
               </template>
@@ -329,6 +329,7 @@
             <el-row :gutter="20">
               <!--鐢ㄦ埛鏁版嵁-->
               <el-form
+                class="opo-query-form"
                 :model="patientqueryParams"
                 ref="queryForm"
                 size="small"
@@ -575,6 +576,7 @@
 import Li_area_select from "@/components/Address";
 import { getUserProfile } from "@/api/system/user";
 import { getToken } from "@/utils/auth";
+import { moneySum, moneyRound } from "@/utils/money";
 import debounce from "lodash/debounce";
 export default {
   components: {
@@ -1089,23 +1091,16 @@
         this.$modal.msgError("娉ㄦ剰瀹炴敹閲戦涓嶇瓑浜庡簲鏀堕噾棰濓紝璇锋牳瀵规暟鎹紒");
       }
     },
-    //淇敼瀹炴敹鎴栧簲鏀跺悗瑙﹀彂
+    //淇敼瀹炴敹鎴栧簲鏀跺悗瑙﹀彂锛堥噾棰濅竴寰嬭蛋绮剧‘杩愮畻锛�
     chargeSum() {
-      let ChargeSum = 0;
-      let ChargeamountSum = 0;
-
       //璐圭敤鍚堣
       try {
-        for (let i = 0; i < this.donorchargeorgans.length; i++) {
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].organcharge))) {
-            ChargeSum += parseFloat(this.donorchargeorgans[i].organcharge);
-          }
-          if (!isNaN(parseFloat(this.donorchargeorgans[i].amount))) {
-            ChargeamountSum += parseFloat(this.donorchargeorgans[i].amount);
-          }
-        }
-        this.form.receivableamount = ChargeSum.toFixed(2);
-        this.form.receivedamount = ChargeamountSum.toFixed(2);
+        this.form.receivableamount = moneyRound(
+          moneySum(this.donorchargeorgans, "organcharge")
+        ).toFixed(2);
+        this.form.receivedamount = moneyRound(
+          moneySum(this.donorchargeorgans, "amount")
+        ).toFixed(2);
       } catch {}
     },
 
diff --git a/src/views/system/class/index.vue b/src/views/system/class/index.vue
index 0d5542a..01dc17e 100644
--- a/src/views/system/class/index.vue
+++ b/src/views/system/class/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鐝骇鍚嶇О" prop="className">
         <el-input
           v-model="queryParams.className"
diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue
index efb6961..8bfda52 100644
--- a/src/views/system/config/index.vue
+++ b/src/views/system/config/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鍙傛暟鍚嶇О" prop="configName">
         <el-input
           v-model="queryParams.configName"
diff --git a/src/views/system/costmaintenance/index.vue b/src/views/system/costmaintenance/index.vue
index 633105e..d4e0e74 100644
--- a/src/views/system/costmaintenance/index.vue
+++ b/src/views/system/costmaintenance/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
     <el-form
+      class="opo-query-form"
       :model="queryParams"
       ref="queryForm"
       :inline="true"
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
index f9c7741..bde65df 100644
--- a/src/views/system/dept/index.vue
+++ b/src/views/system/dept/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
       <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
         <el-input
           v-model="queryParams.deptName"
diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue
index 422c1b7..a592515 100644
--- a/src/views/system/dict/data.vue
+++ b/src/views/system/dict/data.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="瀛楀吀鍚嶇О" prop="dictType">
         <el-select v-model="queryParams.dictType" size="small">
           <el-option
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
index 5aedf1e..ec5bf40 100644
--- a/src/views/system/dict/index.vue
+++ b/src/views/system/dict/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="瀛楀吀鍚嶇О" prop="dictName">
         <el-input
           v-model="queryParams.dictName"
diff --git a/src/views/system/grade/index.vue b/src/views/system/grade/index.vue
index 02720d5..9792303 100644
--- a/src/views/system/grade/index.vue
+++ b/src/views/system/grade/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="骞寸骇鍚嶇О" prop="gradeName">
         <el-input
           v-model="queryParams.gradeName"
diff --git a/src/views/system/medicalevalustion/index.vue b/src/views/system/medicalevalustion/index.vue
index a6bafe1..ee80ff6 100644
--- a/src/views/system/medicalevalustion/index.vue
+++ b/src/views/system/medicalevalustion/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="濮撳悕" prop="name">
         <el-input
           v-model="queryParams.name"
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index a89e1ee..72938e4 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
       <el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
         <el-input
           v-model="queryParams.menuName"
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue
index 22b2ad5..c0c2c9b 100644
--- a/src/views/system/notice/index.vue
+++ b/src/views/system/notice/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="鍏憡鏍囬" prop="noticeTitle">
         <el-input
           v-model="queryParams.noticeTitle"
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
index e206968..db21544 100644
--- a/src/views/system/post/index.vue
+++ b/src/views/system/post/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="宀椾綅缂栫爜" prop="postCode">
         <el-input
           v-model="queryParams.postCode"
diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue
index 624f689..f41b830 100644
--- a/src/views/system/role/authUser.vue
+++ b/src/views/system/role/authUser.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-     <el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
+     <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
       <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
         <el-input
           v-model="queryParams.userName"
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index 6fc0f99..79a481a 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" v-show="showSearch" :inline="true">
       <el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
         <el-input
           v-model="queryParams.roleName"
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index 3e0e124..a9d914e 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -1,7 +1,8 @@
 <template>
   <!-- 鎺堟潈鐢ㄦ埛 -->
   <el-dialog title="閫夋嫨鐢ㄦ埛" :visible.sync="visible" width="800px" top="5vh" append-to-body>
-    <el-form :model="queryParams" ref="queryForm" :inline="true">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true">
       <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
         <el-input
           v-model="queryParams.userName"
diff --git a/src/views/system/student/index.vue b/src/views/system/student/index.vue
index bd94eb2..6503cf2 100644
--- a/src/views/system/student/index.vue
+++ b/src/views/system/student/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="瀛︾敓鍚嶇О" prop="studentName">
         <el-input
           v-model="queryParams.studentName"
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index a3c0426..8a47b62 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -27,7 +27,8 @@
       </el-col>
       <!--鐢ㄦ埛鏁版嵁-->
       <el-col :span="20" :xs="24">
-        <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+        <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
           <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
             <el-input
               v-model="queryParams.userName"
diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue
index 068755f..3e29550 100644
--- a/src/views/tool/gen/importTable.vue
+++ b/src/views/tool/gen/importTable.vue
@@ -1,7 +1,8 @@
 <template>
   <!-- 瀵煎叆琛� -->
   <el-dialog title="瀵煎叆琛�" :visible.sync="visible" width="800px" top="5vh" append-to-body>
-    <el-form :model="queryParams" ref="queryForm" :inline="true">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true">
       <el-form-item label="琛ㄥ悕绉�" prop="tableName">
         <el-input
           v-model="queryParams.tableName"
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
index 646decf..ae8808a 100644
--- a/src/views/tool/gen/index.vue
+++ b/src/views/tool/gen/index.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      class="opo-query-form" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="琛ㄥ悕绉�" prop="tableName">
         <el-input
           v-model="queryParams.tableName"
diff --git a/vue.config.js b/vue.config.js
index 8f72f61..1c1ae17 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -33,8 +33,8 @@
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        // target:`http://localhost:8080`,
-        target:`http://192.168.100.10:8081`,
+        target:`http://localhost:8080`,
+        // target:`http://192.168.100.110:8080`,
         // target:`http://192.168.100.137:8080`,
         // target: `https://slb.hospitalstar.com:9093`,
         changeOrigin: true,

--
Gitblit v1.9.3