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

---
 src/utils/summarizeTable.js |  116 +++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 79 insertions(+), 37 deletions(-)

diff --git a/src/utils/summarizeTable.js b/src/utils/summarizeTable.js
index e24d99f..cb667d2 100644
--- a/src/utils/summarizeTable.js
+++ b/src/utils/summarizeTable.js
@@ -1,48 +1,90 @@
+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 = {}) => {
-    const { columns, data } = param;
-    const sums = [];
-    columns.forEach((column, index) => {
-        if (index === 0) {
-            sums[index] = '鍚堣';
-            return;
-        }
-        const prop = column.property;
-        if (summaryProps.includes(prop)) {
-            const values = data.map(item => Number(item[prop]));
-            // 鍙鏈夋晥鏁板瓧杩涜姹傚拰
-            if (!values.every(isNaN)) {
-                const sum = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0);
-                if (specialFormat[prop] && specialFormat[prop].noDecimal) {
-                    // 濡傛灉鎸囧畾浜嗕笉闇�瑕佷繚鐣欏皬鏁帮紝鍒欑洿鎺ヨ浆鎹负鏁存暟
-                    sums[index] = Math.round(sum).toString();
-                } else {
-                    // 榛樿淇濈暀涓や綅灏忔暟
-                    sums[index] = parseFloat(sum).toFixed(specialFormat[prop]?.decimalPlaces ?? 2);
-                }
-            } else {
-                sums[index] = '';
-            }
+  const { columns, data } = param;
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = "鍚堣";
+      return;
+    }
+    const prop = column.property;
+    if (summaryProps.includes(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(
+          (acc, val) => (!isNaN(val) ? acc + val : acc),
+          0
+        );
+        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] = '';
+          // 榛樿淇濈暀涓や綅灏忔暟
+          sums[index] = parseFloat(sum).toFixed(
+            specialFormat[prop]?.decimalPlaces ?? 2
+          );
         }
-    });
-    return sums;
-}
-// 涓嶅惈绋庢�讳环璁$畻
-const calculateTaxExclusiveTotalPrice = (taxInclusiveTotalPrice, taxRate) => {
-    const taxRateDecimal = taxRate / 100;
-    return (taxInclusiveTotalPrice / (1 + taxRateDecimal)).toFixed(2);
-}
-// 鍚◣鎬讳环璁$畻
-const calculateTaxIncludeTotalPrice = (taxInclusiveUnitPrice, quantity) => {
-    return (taxInclusiveUnitPrice * quantity).toFixed(2);
-}
+      } else {
+        sums[index] = "";
+      }
+    } else {
+      sums[index] = "";
+    }
+  });
+  return sums;
+};
+// 涓嶅惈绋庢�讳环璁$畻锛宒ecimals 涓轰繚鐣欏皬鏁颁綅鏁帮紙閿�鍞�/閲囪喘鐩稿叧椤甸潰浼� 6锛�
+const calculateTaxExclusiveTotalPrice = (
+  taxInclusiveTotalPrice,
+  taxRate,
+  decimals = 2
+) => {
+  const taxRateDecimal = taxRate / 100;
+  return (taxInclusiveTotalPrice / (1 + taxRateDecimal)).toFixed(decimals);
+};
+// 鍚◣鎬讳环璁$畻锛宒ecimals 涓轰繚鐣欏皬鏁颁綅鏁帮紙閿�鍞�/閲囪喘鐩稿叧椤甸潰浼� 6锛�
+const calculateTaxIncludeTotalPrice = (
+  taxInclusiveUnitPrice,
+  quantity,
+  decimals = 2
+) => {
+  return (taxInclusiveUnitPrice * quantity).toFixed(decimals);
+};
 // 瀵煎嚭鍑芥暟渚涘叾浠栨枃浠朵娇鐢�
-export { summarizeTable, calculateTaxExclusiveTotalPrice ,calculateTaxIncludeTotalPrice};
+export {
+  summarizeTable,
+  calculateTaxExclusiveTotalPrice,
+  calculateTaxIncludeTotalPrice,
+};

--
Gitblit v1.9.3