js:金额显示转换 分转元 去除尾部的0
生活随笔
收集整理的這篇文章主要介紹了
js:金额显示转换 分转元 去除尾部的0
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 需求
- 思路
- 方法實現
- 2023-06-06補充
- 總結整理
需求
- 數據庫里邊存儲的金額采用精確到分 的整數存儲,原因是浮點數精度會丟失
- 用戶界面需要轉換為以元 為單位的數值顯示
- 需要做分到元的轉換,需要省略小數部分尾部的0,例如:9.00 只顯示 9
- 當然從高考數學嚴謹的角度看,這個需求是不合理的,保留小數點表示的數值的精確度,當然battle不過產品就只能按人家的需求來。
思路
剛開始,思路的是通過整除10取余的方式判斷尾部是否有小數,再進行轉換,處理起來比較繁瑣;
后來,又發現可以使用lodash.trimEnd方法去除尾部的.0,發現整數的0也會被去掉,出現顯示bug
最后,發現一個比較簡單的方式,js浮點數轉為字符串后,小數點部分會自動處理掉,就滿足了需求了
方法實現
/*** 金額轉換:分 轉 元* @param {*} money* @returns*/ function format_money(money) {return money * 0.01 + ''; }測試
// 元:900 -> 9 console.log(format_money(900)); // 9// 角:10 -> 0.1 console.log(format_money(10)); // 0.1// 分:1 -> 0.01 console.log(format_money(1)); // 0.01舉一反三
如果需求是輸入不是固定的小數位呢,也要求實現這樣的效果,可以根據要求是否使用保留小數位,
總之,原理就是:浮點數轉字符串
/*** 去除浮點數尾部的0* @param {Number} number* @returns*/ function format_number(number){return number + ''; }console.log(format_number(9.00000)); // 9console.log(format_number(9.10000)); // 9.1console.log(format_number(9.02000)); // 9.02console.log(format_number(9.00300)); // 9.0032023-06-06補充
上面的實現方法有問題
money.js
export function formatMoneyV2(money) {return money * 0.01 + ""; }money.test.js
import { formatMoneyV2 } from "./money.js";// test formatMoneyV2 test("formatMoneyV2", function () {expect(formatMoneyV2(100)).toBe("1");expect(formatMoneyV2(10000)).toBe("100");expect(formatMoneyV2(10001)).toBe("100.01");expect(formatMoneyV2(10021)).not.toBe("100.21"); // 100.21000000000001expect(formatMoneyV2(10030)).toBe("100.3"); });使用如上測試用例,會發現10021 這個值,并沒有格式化成期待的樣子,而是出現了很長的浮點值
當然還有將用戶輸入的字符串,解析為金額回傳給服務器
export function parseMoneyV2(money) {return Number.parseInt(money * 100); }測試
import { parseMoneyV2 } from "./money.js";// test parseMoneyV2 test("parseMoneyV2", function () {expect(parseMoneyV2("10")).toBe(1000);expect(parseMoneyV2("10.1")).toBe(1010);expect(parseMoneyV2("10.12")).not.toBe(1012); // 1011.9999999999999expect(parseMoneyV2("10.13")).toBe(1013);expect(parseMoneyV2("1")).toBe(100);expect(parseMoneyV2("1.1")).toBe(110);expect(parseMoneyV2("1.11")).toBe(111); });經測試,10.12 變為浮點型后是1011.9999999999999,再轉為整型就成了1011 ,和所期待的值就不一樣了
總結整理
經過業務總結,整合一個工具類,分別實現:
- 將后端傳過來的數字格式化為字符串,用于前端顯示,
- 將用戶輸入的字符串解析為數字,用于提交數據給后端
- 實現一個驗證用戶輸入的正則校驗,用戶表單校驗
money-util.js
/*** 輸入整型貨幣數值,單位為分,返回以元為單位的顯示值* @param {Integer} money* @returns {String}*/ export function formatMoney(money) {// 為 null / 0 返回 空字符串if (!money) {return "";}let money_label = "";if (money % 100 == 0) {// 保留零位money_label = (money * 0.01).toFixed(0);} else if (money % 10 == 0) {// 保留一位money_label = (money * 0.01).toFixed(1);} else {// 保留兩位money_label = (money * 0.01).toFixed(2);}return money_label; }/*** 將金額格式以元為單位的字符串轉為分為單位的整數* @param {String} money* @returns {Integer}*/ export function parseMoney(money) {if (!validateMoney(money)) {return 0;}return Math.round(money * 100); }/*** 驗證一個字符串是否為以元為單位的金額格式* 整數* 一位小數* 兩位小數* @param {String} value* @returns {Boolean}*/ export function validateMoney(value) {if (typeof value != "string") {return false;}const re = /^\d+(\.\d{1,2})?$/;return re.test(value); }測試用例 money.test.js
import { formatMoney, validateMoney, parseMoney } from "./money-util.js";// test formatMoney test("formatMoney", function () {expect(formatMoney(null)).toBe("");expect(formatMoney(0)).toBe("");expect(formatMoney(100)).toBe("1");expect(formatMoney(10000)).toBe("100");expect(formatMoney(10001)).toBe("100.01");expect(formatMoney(10021)).toBe("100.21");expect(formatMoney(10030)).toBe("100.3"); });// test validateMoney test("validateMoney", function () {expect(validateMoney(null)).toBe(false);expect(validateMoney(0)).toBe(false);expect(validateMoney("")).toBe(false);expect(validateMoney("xx")).toBe(false);expect(validateMoney("10")).toBe(true);expect(validateMoney("10.")).toBe(false);expect(validateMoney("10.1")).toBe(true);expect(validateMoney("10.12")).toBe(true);expect(validateMoney("10.123")).toBe(false); });// test parseMoney test("parseMoney", function () {expect(parseMoney("0")).toBe(0);expect(parseMoney("")).toBe(0);expect(parseMoney(null)).toBe(0);expect(parseMoney(0)).toBe(0);expect(parseMoney("10")).toBe(1000);expect(parseMoney("10.1")).toBe(1010);expect(parseMoney("10.12")).toBe(1012);expect(parseMoney("10.13")).toBe(1013);expect(parseMoney("1")).toBe(100);expect(parseMoney("1.1")).toBe(110);expect(parseMoney("1.11")).toBe(111); });總結
以上是生活随笔為你收集整理的js:金额显示转换 分转元 去除尾部的0的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 需求变更申请表
- 下一篇: ERR_PNPM_META_FETCH_