From 9f3bc47b98cbc51df7cfcea94d4aa0c35f40cbc5 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期二, 13 十月 2026 14:09:06 +0800
Subject: [PATCH] feat: 添加数字格式化工具,支持去掉小数末尾多余的 0 和四舍五入功能

---
 src/views/procurementManagement/procurementLedger/index.vue |   23 ++--
 src/utils/formatNumber.js                                   |   75 +++++++++++++++
 src/views/salesManagement/receiptPaymentLedger/index.vue    |   36 ++++--
 src/views/salesManagement/salesLedger/index.vue             |   36 +++---
 src/views/salesManagement/salesQuotation/index.vue          |    7 
 src/utils/summarizeTable.js                                 |   27 +++++
 src/views/financialManagement/financialStatements/index.vue |   15 ++
 src/views/procurementManagement/paymentLedger/index.vue     |   51 +++++-----
 8 files changed, 197 insertions(+), 73 deletions(-)

diff --git a/src/utils/formatNumber.js b/src/utils/formatNumber.js
new file mode 100644
index 0000000..af819be
--- /dev/null
+++ b/src/utils/formatNumber.js
@@ -0,0 +1,75 @@
+/**
+ * 鏁板瓧灞曠ず鏍煎紡鍖栧伐鍏�
+ *
+ * 璇存槑锛氬悗绔噾棰�/鏁伴噺瀛楁缁熶竴鎸� 6 浣嶅皬鏁拌繑鍥烇紙濡� 52333.580000锛夛紝
+ * 鐩存帴灞曠ず浼氬嚭鐜板ぇ閲忔棤鎰忎箟鐨勭粨灏� 0锛岃繖閲岀粺涓�鍋氬睍绀哄眰澶勭悊銆�
+ */
+
+/**
+ * 鍘绘帀灏忔暟鏈熬澶氫綑鐨� 0锛堟渶澶氫繚鐣� maxDecimals 浣嶅皬鏁帮級
+ * 渚嬶細52333.580000 -> 52333.58 锛�100.000000 -> 100 锛�0.000000 -> 0
+ *     474235.654230 -> 474235.65423
+ * @param {string|number} value 鍘熷鍊�
+ * @param {number} maxDecimals 鏈�澶氫繚鐣欑殑灏忔暟浣嶏紝榛樿 6
+ * @returns {string} 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+export const trimZeros = (value, maxDecimals = 6) => {
+  if (value === undefined || value === null || value === "") {
+    return "0";
+  }
+  const num = typeof value === "number" ? value : Number(value);
+  // 闈炴暟瀛楋紙濡� "-"銆�"--"锛夊師鏍疯繑鍥烇紝閬垮厤鎶婂崰浣嶇鏄剧ず鎴� 0
+  if (!Number.isFinite(num)) {
+    return String(value);
+  }
+  const decimals = Math.min(20, Math.max(0, Math.floor(maxDecimals)));
+  let text = num.toFixed(decimals);
+  if (decimals > 0 && text.includes(".")) {
+    text = text.replace(/0+$/, "").replace(/\.$/, "");
+  }
+  // 澶勭悊 -0.000000 杩欑被缁撴灉
+  if (text === "" || text === "-" || text === "-0") {
+    text = "0";
+  }
+  return text;
+};
+
+/**
+ * 鍥涜垗浜斿叆鍒版寚瀹氬皬鏁颁綅锛堟寜鍗佽繘鍒惰涔夛級
+ * JS 鍘熺敓鐨� toFixed 浼氬彈浜岃繘鍒舵诞鐐瑰奖鍝嶏紝渚嬪 (926163.765).toFixed(2) 寰楀埌 "926163.76"锛�
+ * 鑰屾寜鍗佽繘鍒跺洓鑸嶄簲鍏ュ簲涓� 926163.77锛岃繖閲岀粺涓�鎴愪笌鏁版嵁搴� ROUND 涓�鑷寸殑缁撴灉銆�
+ * @param {string|number} value 鍘熷鍊�
+ * @param {number} decimals 灏忔暟浣嶆暟锛岄粯璁� 2
+ * @returns {number} 鍥涜垗浜斿叆鍚庣殑鏁板瓧
+ */
+export const roundHalfUp = (value, decimals = 2) => {
+  const num = Number(value);
+  const digits = Math.min(20, Math.max(0, Math.floor(decimals)));
+  if (!Number.isFinite(num)) {
+    return 0;
+  }
+  // 绉戝璁℃暟娉曪紙濡� 1e-7锛夎蛋鍘熺敓 toFixed锛岄伩鍏嶅瓧绗︿覆鎷兼帴鍑� "1e-7e2"
+  const text = String(num);
+  if (text.includes("e") || text.includes("E")) {
+    return Number(num.toFixed(digits));
+  }
+  return Number(`${Math.round(Number(`${text}e${digits}`))}e-${digits}`);
+};
+
+/**
+ * 鍥哄畾淇濈暀鎸囧畾灏忔暟浣嶏紙涓嶈冻琛� 0锛�
+ * 渚嬶細2296268.351 -> 2296268.35 锛坉ecimals = 2锛�
+ * @param {string|number} value 鍘熷鍊�
+ * @param {number} decimals 灏忔暟浣嶆暟锛岄粯璁� 2
+ * @returns {string} 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+export const toFixedNumber = (value, decimals = 2) => {
+  const num = Number(value);
+  const digits = Math.min(20, Math.max(0, Math.floor(decimals)));
+  if (!Number.isFinite(num)) {
+    return (0).toFixed(digits);
+  }
+  const text = num.toFixed(digits);
+  // 閬垮厤鍑虹幇 "-0.00" 杩欑被璐熼浂鏄剧ず
+  return parseFloat(text) === 0 ? text.replace(/^-/, "") : text;
+};
diff --git a/src/utils/summarizeTable.js b/src/utils/summarizeTable.js
index b25cc74..cb667d2 100644
--- a/src/utils/summarizeTable.js
+++ b/src/utils/summarizeTable.js
@@ -1,8 +1,16 @@
+import { trimZeros, roundHalfUp } from "./formatNumber.js";
+
 /**
  * 閫氱敤鐨勮〃鏍煎悎璁℃柟娉�
  * @param {Object} param - 鍖呭惈琛ㄦ牸鍒楅厤缃拰鏁版嵁婧愮殑瀵硅薄
  * @param {Array<string>} summaryProps - 闇�瑕佹眹鎬荤殑瀛楁鍚嶆暟缁�
  * @param {Object} specialFormat - 鐗规畩鏍煎紡鍖栬鍒欙細瀛楁鍚� -> 鏍煎紡鍖栭�夐」锛堝鏄惁鍘绘帀灏忔暟锛�
+ *   鏀寔 { noDecimal: true }  鍙栨暣鏄剧ず
+ *        { trimZeros: true, decimalPlaces: 6 }  鏈�澶氫繚鐣� 6 浣嶅皬鏁板苟鍘绘帀鏈熬澶氫綑鐨� 0
+ *        { roundEach: 2 }  姣忚鍏堟寜 2 浣嶅皬鏁板洓鑸嶄簲鍏ュ啀姹傚拰锛�
+ *                          鐢ㄤ簬閲戦鍒楋細淇濊瘉鍚堣涓庡垪鍐呭睍绀哄�肩浉鍔犲畬鍏ㄤ竴鑷�
+ *        { formatter: fn }  鑷畾涔夋牸寮忓寲鍑芥暟锛屼紭鍏堢骇鏈�楂�
+ *        { decimalPlaces: 2 }  鍥哄畾淇濈暀 2 浣嶅皬鏁帮紙榛樿锛�
  * @returns {Array} 鍚堣琛屾暟鎹�
  */
 const summarizeTable = (param, summaryProps, specialFormat = {}) => {
@@ -15,7 +23,15 @@
     }
     const prop = column.property;
     if (summaryProps.includes(prop)) {
-      const values = data.map((item) => Number(item[prop]));
+      const rule = specialFormat[prop];
+      const values = data.map((item) => {
+        const val = Number(item[prop]);
+        // NaN 淇濇寔 NaN锛屼究浜庝笅闈㈠垽鏂�屾暣鍒楅兘涓嶆槸鏁板瓧銆�
+        if (Number.isNaN(val)) return NaN;
+        return rule && rule.roundEach != null
+          ? roundHalfUp(val, rule.roundEach)
+          : val;
+      });
       // 鍙鏈夋晥鏁板瓧杩涜姹傚拰
       if (!values.every(isNaN)) {
         const sum = values.reduce(
@@ -25,6 +41,15 @@
         if (specialFormat[prop] && specialFormat[prop].noDecimal) {
           // 濡傛灉鎸囧畾浜嗕笉闇�瑕佷繚鐣欏皬鏁帮紝鍒欑洿鎺ヨ浆鎹负鏁存暟
           sums[index] = Math.round(sum).toString();
+        } else if (
+          specialFormat[prop] &&
+          typeof specialFormat[prop].formatter === "function"
+        ) {
+          // 鑷畾涔夋牸寮忓寲鍑芥暟浼樺厛
+          sums[index] = specialFormat[prop].formatter(sum);
+        } else if (specialFormat[prop] && specialFormat[prop].trimZeros) {
+          // 鎸囧畾浜嗗幓鎺夋湯灏惧浣欑殑 0锛堟渶澶氫繚鐣� decimalPlaces 浣嶏紝榛樿 6 浣嶏級
+          sums[index] = trimZeros(sum, specialFormat[prop].decimalPlaces ?? 6);
         } else {
           // 榛樿淇濈暀涓や綅灏忔暟
           sums[index] = parseFloat(sum).toFixed(
diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
index 5dbce9b..8423b46 100644
--- a/src/views/financialManagement/financialStatements/index.vue
+++ b/src/views/financialManagement/financialStatements/index.vue
@@ -199,6 +199,7 @@
   import { QuestionFilled, TrendCharts, Sell } from "@element-plus/icons-vue";
   import Echarts from "@/components/Echarts/echarts.vue";
   import { accountStatementDetailsByMonth } from "@/api/financialManagement/financialStatements";
+  import { toFixedNumber } from "@/utils/formatNumber.js";
   import dayjs from "dayjs";
 
   const { proxy } = getCurrentInstance();
@@ -263,7 +264,11 @@
     },
   ]);
   const barYAxis = [{ type: "value", name: "閲戦 (鍏�)" }];
-  const barTooltip = { trigger: "axis", axisPointer: { type: "shadow" } };
+  const barTooltip = {
+    trigger: "axis",
+    axisPointer: { type: "shadow" },
+    valueFormatter: value => formatMoney(value),
+  };
   const barSeries = computed(() => [
     {
       name: "搴旀敹璐︽",
@@ -292,7 +297,10 @@
     },
   ]);
   const trendYAxis = [{ type: "value", name: "閲戦 (鍏�)" }];
-  const trendTooltip = { trigger: "axis" };
+  const trendTooltip = {
+    trigger: "axis",
+    valueFormatter: value => formatMoney(value),
+  };
   const trendSeries = computed(() => [
     {
       name: "鎬昏惀鏀�",
@@ -320,8 +328,9 @@
   ]);
 
   // --- 鍏敤閫昏緫 ---
+  // 閲戦缁熶竴鎸� 2 浣嶅皬鏁板睍绀猴紙涓嶅彈鎺ュ彛杩斿洖绮惧害褰卞搷锛�
   const formatMoney = val => {
-    return val;
+    return toFixedNumber(val, 2);
   };
 
   const handleDateChange = val => {
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
index 02c0b58..b14fb2c 100644
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ b/src/views/procurementManagement/paymentLedger/index.vue
@@ -49,9 +49,9 @@
             <el-table-column label="搴斾粯閲戦(鍏�)"
                              prop="payableAmount"
                              show-overflow-tooltip>
-              <template #default="{ row, column }">
+              <template #default="{ row }">
                 <el-text type="danger">
-                  {{ formattedNumber(row, column, row.payableAmount) }}
+                  {{ formatPayable(row.payableAmount) }}
                 </el-text>
               </template>
             </el-table-column>
@@ -79,7 +79,7 @@
                     @pagination="sonPaginationSearch">
             <template #payableAmountSlot="{ row }">
               <el-text type="danger">
-                {{ parseFloat(row.payableAmount).toFixed(6) }}
+                {{ formatPayable(row.payableAmount) }}
               </el-text>
             </template>
             <template #paymentActionSlot="{ row }">
@@ -100,7 +100,7 @@
         </el-form-item>
         <el-form-item label="浠樻閲戦锛�" prop="paymentAmount">
           <el-input-number style="width:100%" v-model="paymentForm.paymentAmount" :min="0" :precision="6" :max="Math.max(0,Number(currentPaymentRow.payableAmount)||0)" placeholder="璇疯緭鍏ヤ粯娆鹃噾棰�" controls-position="right" />
-          <div style="color:#e6a23c;font-size:12px;margin-top:4px">褰撳墠鍙粯娆句綑棰濓細{{ Math.max(0,Number(currentPaymentRow.payableAmount)||0).toFixed(6) }} 鍏�</div>
+          <div style="color:#e6a23c;font-size:12px;margin-top:4px">褰撳墠鍙粯娆句綑棰濓細{{ formatPayable(Math.max(0,Number(currentPaymentRow.payableAmount)||0)) }} 鍏�</div>
         </el-form-item>
         <el-form-item label="浠樻鏂瑰紡锛�" prop="paymentMethod">
           <el-select v-model="paymentForm.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width:100%" clearable>
@@ -125,6 +125,7 @@
     savePayment,
   } from "@/api/procurementManagement/paymentLedger.js";
   import Pagination from "../../../components/PIMTable/Pagination.vue";
+  import { trimZeros, roundHalfUp } from "@/utils/formatNumber.js";
 
   const tableData = ref([]);
   const tableLoading = ref(false);
@@ -169,7 +170,7 @@
       prop: "contractAmount",
       width: 200,
       formatData: params => {
-        return params ? parseFloat(params).toFixed(6) : 0;
+        return trimZeros(params, 6);
       },
     },
     {
@@ -177,7 +178,7 @@
       prop: "paymentAmount",
       width: 200,
       formatData: params => {
-        return params ? parseFloat(params).toFixed(6) : 0;
+        return trimZeros(params, 6);
       },
     },
     {
@@ -206,7 +207,7 @@
   const currentPaymentRow = ref({});
   const paymentFormRef = ref(null);
   const paymentForm = reactive({ paymentDate:"", paymentAmount:undefined, paymentMethod:"", remark:"" });
-  const validatePaymentAmount = (_,v,cb) => { if(!v) return cb(new Error("璇疯緭鍏ヤ粯娆鹃噾棰�")); const m=Math.max(0,Number(currentPaymentRow.value.payableAmount)||0); if(v>m) return cb(new Error(`浠樻閲戦涓嶈兘瓒呰繃鍙粯娆句綑棰� ${m.toFixed(6)} 鍏僠)); cb(); };
+  const validatePaymentAmount = (_,v,cb) => { if(!v) return cb(new Error("璇疯緭鍏ヤ粯娆鹃噾棰�")); const m=Math.max(0,Number(currentPaymentRow.value.payableAmount)||0); if(v>m) return cb(new Error(`浠樻閲戦涓嶈兘瓒呰繃鍙粯娆句綑棰� ${trimZeros(m, 6)} 鍏僠)); cb(); };
   const paymentRules = { paymentDate:[{required:true,message:"璇烽�夋嫨浠樻鏃ユ湡",trigger:"change"}], paymentAmount:[{required:true,validator:validatePaymentAmount,trigger:"blur"}], paymentMethod:[{required:true,message:"璇烽�夋嫨浠樻鏂瑰紡",trigger:"change"}] };
   const openPaymentDialog = r => { currentPaymentRow.value=r; paymentForm.paymentDate=""; paymentForm.paymentAmount=undefined; paymentForm.paymentMethod=""; paymentForm.remark=""; paymentDialogVisible.value=true; };
   const closePaymentDialog = () => { paymentFormRef.value?.resetFields(); paymentDialogVisible.value=false; };
@@ -218,9 +219,10 @@
       param,
       ["contractAmounts", "paymentAmount", "payableAmount"],
       {
-        contractAmounts: { decimalPlaces: 6 },
-        paymentAmount: { decimalPlaces: 6 },
-        payableAmount: { decimalPlaces: 6 },
+        contractAmounts: { decimalPlaces: 6, trimZeros: true },
+        paymentAmount: { decimalPlaces: 6, trimZeros: true },
+        // 搴斾粯閲戦閫愯鎸夊垎鍙栨暣鍚庡啀姹傚拰锛屼繚璇佸悎璁� = 鍒楀唴灞曠ず鍊间箣鍜�
+        payableAmount: { roundEach: 2, formatter: formatPayable },
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
@@ -228,26 +230,19 @@
   };
   // 瀛愯〃鍚堣鏂规硶
   const summarizeMainTable1 = param => {
-    let summarizeTable = proxy.summarizeTable(
+    return proxy.summarizeTable(
       param,
-      ["contractAmount", "invoiceAmount", "paymentAmount"],
+      ["contractAmount", "invoiceAmount", "paymentAmount", "payableAmount"],
       {
-        contractAmount: { decimalPlaces: 6 },
-        invoiceAmount: { decimalPlaces: 6 },
-        paymentAmount: { decimalPlaces: 6 },
+        contractAmount: { decimalPlaces: 6, trimZeros: true },
+        invoiceAmount: { decimalPlaces: 6, trimZeros: true },
+        paymentAmount: { decimalPlaces: 6, trimZeros: true },
+        // 搴斾粯閲戦閫愯鎸夊垎鍙栨暣鍚庡啀姹傚拰锛屼繚璇佸悎璁� = 鍒楀唴灞曠ず鍊间箣鍜�
+        payableAmount: { roundEach: 2, formatter: formatPayable },
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
     );
-    if (originalTableDataSon.value.length > 0) {
-      summarizeTable[summarizeTable.length - 1] =
-        originalTableDataSon.value[
-          originalTableDataSon.value.length - 1
-        ].payableAmount.toFixed(6);
-    } else {
-      summarizeTable[summarizeTable.length - 1] = 0.0;
-    }
-    return summarizeTable;
   };
   /** 鎼滅储鎸夐挳鎿嶄綔 */
   const handleQuery = () => {
@@ -319,11 +314,17 @@
   };
   const formattedNumber = (row, column, cellValue) => {
     if (column.property !== "supplierName") {
-      return parseFloat(cellValue).toFixed(6);
+      return trimZeros(cellValue, 6);
     } else {
       return cellValue;
     }
   };
+  // 搴斾粯閲戦鏄噾棰濆瓧娈碉紝鏈�澶氫繚鐣� 2 浣嶅皬鏁帮紙鍥涜垗浜斿叆鍒板垎锛夈��
+  // 搴斾粯閲戦 = 鍙�(鍏ュ簱閲戦, 鍚堝悓閲戦)杈冨皬鑰� 鈭� 宸蹭粯娆� 鈭� 閫�璐ч噾棰濓紝鍏朵腑鍏ュ簱閲戦鐢� 6 浣嶅皬鏁扮殑鍚◣鍗曚环绱姞鑰屾潵锛�
+  // 浼氬甫鍑恒�屽帢銆嶅強浠ヤ笅鐨勫皬鏁帮紝椤甸潰涓婄粺涓�鎸夊垎灞曠ず銆�
+  const formatPayable = value => {
+    return trimZeros(roundHalfUp(value, 2), 2);
+  };
   getList();
 </script>
 
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 05cd312..61852f4 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -761,6 +761,7 @@
   import { modelList, productTreeList } from "@/api/basicData/product.js";
   import dayjs from "dayjs";
   import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+  import { trimZeros } from "@/utils/formatNumber.js";
 
   const userStore = useUserStore();
 
@@ -1085,7 +1086,7 @@
   };
 
   const formattedNumber = (row, column, cellValue) => {
-    return parseFloat(cellValue).toFixed(6);
+    return trimZeros(cellValue, 6);
   };
   // 鏌ヨ鍒楄〃
   /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -1205,11 +1206,11 @@
         "futureTicketsAmount",
       ],
       {
-        taxInclusiveUnitPrice: { decimalPlaces: 6 },
-        taxInclusiveTotalPrice: { decimalPlaces: 6 },
-        taxExclusiveTotalPrice: { decimalPlaces: 6 },
-        ticketsAmount: { decimalPlaces: 6 },
-        futureTicketsAmount: { decimalPlaces: 6 },
+        taxInclusiveUnitPrice: { decimalPlaces: 6, trimZeros: true },
+        taxInclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
+        taxExclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
+        ticketsAmount: { decimalPlaces: 6, trimZeros: true },
+        futureTicketsAmount: { decimalPlaces: 6, trimZeros: true },
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
@@ -1279,8 +1280,8 @@
       param,
       ["contractAmount", "netContractAmount"],
       {
-        contractAmount: { decimalPlaces: 6 },
-        netContractAmount: { decimalPlaces: 6 },
+        contractAmount: { decimalPlaces: 6, trimZeros: true },
+        netContractAmount: { decimalPlaces: 6, trimZeros: true },
       }
     );
   };
@@ -1294,9 +1295,9 @@
         "taxExclusiveTotalPrice",
       ],
       {
-        taxInclusiveUnitPrice: { decimalPlaces: 6 },
-        taxInclusiveTotalPrice: { decimalPlaces: 6 },
-        taxExclusiveTotalPrice: { decimalPlaces: 6 },
+        taxInclusiveUnitPrice: { decimalPlaces: 6, trimZeros: true },
+        taxInclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
+        taxExclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
       }
     );
   };
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index 1278d72..2270a24 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -50,9 +50,9 @@
                              prop="receiptableAmount"
                              show-overflow-tooltip
                              width="200">
-              <template #default="{ row, column }">
+              <template #default="{ row }">
                 <el-text type="danger">
-                  {{ formattedNumber(row, column, row.receiptableAmount) }}
+                  {{ formatReceivable(row.receiptableAmount) }}
                 </el-text>
               </template>
             </el-table-column>
@@ -100,9 +100,9 @@
                              prop="receiptableAmount"
                              show-overflow-tooltip
                              width="200">
-              <template #default="{ row, column }">
+              <template #default="{ row }">
                 <el-text type="danger">
-                  {{ formattedNumber(row, column, row.receiptableAmount) }}
+                  {{ formatReceivable(row.receiptableAmount) }}
                 </el-text>
               </template>
             </el-table-column>
@@ -156,6 +156,7 @@
     saveReceiptPayment,
   } from "@/api/salesManagement/indicatorStats.js";
   import Pagination from "../../../components/PIMTable/Pagination.vue";
+  import { trimZeros } from "@/utils/formatNumber.js";
   const { proxy } = getCurrentInstance();
   const tableData = ref([]);
   const receiptRecord = ref([]);
@@ -184,7 +185,7 @@
   const currentRow = ref({});
   const receiptFormRef = ref(null);
   const receiptForm = reactive({ paymentDate:"", paymentAmount:undefined, paymentMethod:"", remark:"" });
-  const validatePaymentAmount = (_,v,cb) => { if(!v) return cb(new Error("璇疯緭鍏ュ洖娆鹃噾棰�")); const m=Math.max(0,(Number(currentRow.value.receiptableAmount)||0)-(Number(currentRow.value.receiptPaymentAmount)||0)); if(v>m) return cb(new Error(`鍥炴閲戦涓嶈兘瓒呰繃鍙洖娆句綑棰� ${m.toFixed(6)} 鍏僠)); cb(); };
+  const validatePaymentAmount = (_,v,cb) => { if(!v) return cb(new Error("璇疯緭鍏ュ洖娆鹃噾棰�")); const m=Math.max(0,(Number(currentRow.value.receiptableAmount)||0)-(Number(currentRow.value.receiptPaymentAmount)||0)); if(v>m) return cb(new Error(`鍥炴閲戦涓嶈兘瓒呰繃鍙洖娆句綑棰� ${trimZeros(m, 6)} 鍏僠)); cb(); };
   const receiptRules = { paymentDate:[{required:true,message:"璇烽�夋嫨鍥炴鏃ユ湡",trigger:"change"}], paymentAmount:[{required:true,validator:validatePaymentAmount,trigger:"blur"}], paymentMethod:[{required:true,message:"璇烽�夋嫨鍥炴鏂瑰紡",trigger:"change"}] };
   const openReceiptDialog = r => { currentRow.value=r; receiptForm.paymentDate=""; receiptForm.paymentAmount=undefined; receiptForm.paymentMethod=""; receiptForm.remark=""; receiptDialogVisible.value=true; };
   const closeReceiptDialog = () => { receiptFormRef.value?.resetFields(); receiptDialogVisible.value=false; };
@@ -214,7 +215,18 @@
     });
   };
   const formattedNumber = (row, column, cellValue) => {
-    return cellValue ? parseFloat(cellValue).toFixed(6) : "0.000000";
+    return trimZeros(cellValue, 6);
+  };
+  // 搴旀敹閲戦 = 宸插嚭搴撻噾棰� 鈭� 宸查��璐ф 鈭� 宸插洖娆鹃噾棰濄��
+  // 鍑哄簱閲戦鐢� 6 浣嶅皬鏁扮殑鍚◣鍗曚环绱姞鑰屾潵锛屼細娈嬬暀銆屽垎銆嶄互涓嬬殑闆跺ご锛堝 0.0045銆�0.004锛夛紝
+  // 鑰屽洖娆炬槸鎸夊垎褰曞叆鐨勬暣鏁伴噾棰濓紝鐩稿噺鍚庡氨浼氬嚭鐜拌繖浜涙棤鎰忎箟鐨勫熬宸��
+  // 搴旀敹閲戦鏈韩鍙簿纭埌鍒嗭紝鍒嗕互涓嬬殑灏惧樊涓嶈鍏ワ紝缁熶竴鎸� 0 灞曠ず锛堝悗绔� SQL 涔熷仛浜嗗悓鏍峰鐞嗭級銆�
+  const formatReceivable = value => {
+    const num = Number(value);
+    if (!Number.isFinite(num) || Math.abs(num) < 0.01) {
+      return "0";
+    }
+    return trimZeros(num, 6);
   };
   // 涓昏〃鍚堣鏂规硶
   const summarizeMainTable = param => {
@@ -222,9 +234,9 @@
       param,
       ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"],
       {
-        invoiceTotal: { decimalPlaces: 6 },
-        receiptPaymentAmount: { decimalPlaces: 6 },
-        unReceiptPaymentAmount: { decimalPlaces: 6 },
+        invoiceTotal: { decimalPlaces: 6, trimZeros: true },
+        receiptPaymentAmount: { decimalPlaces: 6, trimZeros: true },
+        unReceiptPaymentAmount: { decimalPlaces: 6, trimZeros: true },
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
@@ -236,9 +248,9 @@
       param,
       ["contractAmount", "receiptPaymentAmount", "receiptableAmount"],
       {
-        contractAmount: { decimalPlaces: 6 },
-        receiptPaymentAmount: { decimalPlaces: 6 },
-        receiptableAmount: { decimalPlaces: 6 },
+        contractAmount: { decimalPlaces: 6, trimZeros: true },
+        receiptPaymentAmount: { decimalPlaces: 6, trimZeros: true },
+        receiptableAmount: { formatter: formatReceivable },
         ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
         futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
       }
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 86deb71..93d5ef6 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -654,7 +654,7 @@
           align="right"
         >
           <template #default="scope">
-            {{ Number(scope.row.totalAmount ?? 0).toFixed(6) }}
+            {{ trimZeros(scope.row.totalAmount, 6) }}
           </template>
         </el-table-column>
         <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
@@ -959,9 +959,11 @@
                       <td>{{ product.productCategory || "" }}</td>
                       <td>{{ product.specificationModel || "" }}</td>
                       <td>{{ product.unit || "" }}</td>
-                      <td>{{ product.taxInclusiveUnitPrice || "0" }}</td>
-                      <td>{{ product.quantity || "0" }}</td>
-                      <td>{{ product.taxInclusiveTotalPrice || "0" }}</td>
+                      <td>{{ trimZeros(product.taxInclusiveUnitPrice, 6) }}</td>
+                      <td>{{ trimZeros(product.quantity, 6) }}</td>
+                      <td>
+                        {{ trimZeros(product.taxInclusiveTotalPrice, 6) }}
+                      </td>
                     </tr>
                     <tr v-if="!item.products || item.products.length === 0">
                       <td colspan="6" style="text-align: center; color: #999">
@@ -1188,6 +1190,7 @@
 import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
 import { getCurrentDate } from "@/utils/index.js";
+import { trimZeros } from "@/utils/formatNumber.js";
 import { listCustomer } from "@/api/basicData/customer.js";
 
 const FileList = defineAsyncComponent(() =>
@@ -1531,10 +1534,7 @@
   });
 };
 const formattedNumber = (row, column, cellValue) => {
-  if (cellValue === undefined || cellValue === null || cellValue === "") {
-    return "0.000000";
-  }
-  return parseFloat(cellValue).toFixed(6);
+  return trimZeros(cellValue, 6);
 };
 const findLedgerRecordByRow = (row) => {
   if (!row) return null;
@@ -1694,9 +1694,9 @@
     param,
     ["contractAmount", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"],
     {
-      contractAmount: { decimalPlaces: 6 },
-      taxInclusiveTotalPrice: { decimalPlaces: 6 },
-      taxExclusiveTotalPrice: { decimalPlaces: 6 },
+      contractAmount: { decimalPlaces: 6, trimZeros: true },
+      taxInclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
+      taxExclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
     }
   );
 };
@@ -1710,9 +1710,9 @@
       "taxExclusiveTotalPrice",
     ],
     {
-      taxInclusiveUnitPrice: { decimalPlaces: 6 },
-      taxInclusiveTotalPrice: { decimalPlaces: 6 },
-      taxExclusiveTotalPrice: { decimalPlaces: 6 },
+      taxInclusiveUnitPrice: { decimalPlaces: 6, trimZeros: true },
+      taxInclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
+      taxExclusiveTotalPrice: { decimalPlaces: 6, trimZeros: true },
     }
   );
 };
@@ -2535,7 +2535,7 @@
   const total = products.reduce((sum, product) => {
     return sum + (parseFloat(product.quantity) || 0);
   }, 0);
-  return total.toFixed(6);
+  return trimZeros(total, 6);
 };
 
 // 璁$畻浜у搧鎬婚噾棰�
@@ -2544,7 +2544,7 @@
   const total = products.reduce((sum, product) => {
     return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
   }, 0);
-  return total.toFixed(6);
+  return trimZeros(total, 6);
 };
 
 // 鐢ㄤ簬鎵撳嵃鐨勮绠楀嚱鏁�
@@ -2553,7 +2553,7 @@
   const total = products.reduce((sum, product) => {
     return sum + (parseFloat(product.quantity) || 0);
   }, 0);
-  return total.toFixed(6);
+  return trimZeros(total, 6);
 };
 
 const getTotalAmountForPrint = (products) => {
@@ -2561,7 +2561,7 @@
   const total = products.reduce((sum, product) => {
     return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
   }, 0);
-  return total.toFixed(6);
+  return trimZeros(total, 6);
 };
 
 const mathNum = () => {
diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index 6c9443b..a2c7482 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -65,7 +65,7 @@
         </el-table-column>
         <el-table-column prop="totalAmount" label="鎶ヤ环閲戦" width="120">
           <template #default="scope">
-            楼{{ scope.row.totalAmount.toFixed(6) }}
+            楼{{ trimZeros(scope.row.totalAmount, 6) }}
           </template>
         </el-table-column>
         <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
@@ -267,7 +267,7 @@
 <!--          <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>-->
 <!--        </el-descriptions-item>-->
         <el-descriptions-item label="鎶ヤ环鎬婚" :span="2">
-          <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">楼{{ currentQuotation.totalAmount?.toFixed(6) }}</span>
+          <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">楼{{ trimZeros(currentQuotation.totalAmount, 6) }}</span>
         </el-descriptions-item>
       </el-descriptions>
 
@@ -279,7 +279,7 @@
           <el-table-column prop="unit" label="鍗曚綅" />
           <el-table-column prop="unitPrice" label="鍗曚环">
             <template #default="scope">
-              楼{{ scope.row.unitPrice.toFixed(6) }}
+              楼{{ trimZeros(scope.row.unitPrice, 6) }}
             </template>
           </el-table-column>
         </el-table>
@@ -303,6 +303,7 @@
 import {modelList, productTreeList} from "@/api/basicData/product.js";
 import {listCustomer} from "@/api/basicData/customer.js";
 import { userListNoPage } from "@/api/system/user.js";
+import { trimZeros } from "@/utils/formatNumber.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)

--
Gitblit v1.9.3