168 lines
4.4 KiB
JavaScript
168 lines
4.4 KiB
JavaScript
/**
|
||
* 金额计算工具函数
|
||
* 使用整数计算避免浮点数精度问题
|
||
*/
|
||
|
||
/**
|
||
* 金额转换为分(整数)
|
||
* @param {number|string} amount - 金额(元)
|
||
* @returns {number} - 金额(分)
|
||
*/
|
||
export function yuanToCent(amount) {
|
||
if (amount === null || amount === undefined || amount === '') {
|
||
return 0
|
||
}
|
||
return Math.round(parseFloat(amount) * 100)
|
||
}
|
||
|
||
/**
|
||
* 分转换为元
|
||
* @param {number} cents - 金额(分)
|
||
* @returns {string} - 金额(元),保留两位小数
|
||
*/
|
||
export function centToYuan(cents) {
|
||
if (cents === null || cents === undefined) {
|
||
return '0.00'
|
||
}
|
||
return (cents / 100).toFixed(2)
|
||
}
|
||
|
||
/**
|
||
* 计算手续费
|
||
* @param {number|string} amount - 金额(元)
|
||
* @param {number} rate - 费率(百分比,如5表示5%)
|
||
* @returns {string} - 手续费(元),保留两位小数
|
||
*/
|
||
export function calculateFee(amount, rate) {
|
||
const amountCents = yuanToCent(amount)
|
||
const feeCents = Math.round(amountCents * rate / 100)
|
||
return centToYuan(feeCents)
|
||
}
|
||
|
||
/**
|
||
* 计算实际到账金额
|
||
* @param {number|string} amount - 金额(元)
|
||
* @param {number|string} fee - 手续费(元)
|
||
* @returns {string} - 实际金额(元),保留两位小数
|
||
*/
|
||
export function calculateActualAmount(amount, fee) {
|
||
const amountCents = yuanToCent(amount)
|
||
const feeCents = yuanToCent(fee)
|
||
const actualCents = amountCents - feeCents
|
||
return centToYuan(actualCents)
|
||
}
|
||
|
||
/**
|
||
* 金额加法
|
||
* @param {number|string} amount1 - 金额1(元)
|
||
* @param {number|string} amount2 - 金额2(元)
|
||
* @returns {string} - 结果(元),保留两位小数
|
||
*/
|
||
export function addMoney(amount1, amount2) {
|
||
const cents1 = yuanToCent(amount1)
|
||
const cents2 = yuanToCent(amount2)
|
||
return centToYuan(cents1 + cents2)
|
||
}
|
||
|
||
/**
|
||
* 金额减法
|
||
* @param {number|string} amount1 - 金额1(元)
|
||
* @param {number|string} amount2 - 金额2(元)
|
||
* @returns {string} - 结果(元),保留两位小数
|
||
*/
|
||
export function subtractMoney(amount1, amount2) {
|
||
const cents1 = yuanToCent(amount1)
|
||
const cents2 = yuanToCent(amount2)
|
||
return centToYuan(cents1 - cents2)
|
||
}
|
||
|
||
/**
|
||
* 金额乘法
|
||
* @param {number|string} amount - 金额(元)
|
||
* @param {number} multiplier - 乘数
|
||
* @returns {string} - 结果(元),保留两位小数
|
||
*/
|
||
export function multiplyMoney(amount, multiplier) {
|
||
const cents = yuanToCent(amount)
|
||
const resultCents = Math.round(cents * multiplier)
|
||
return centToYuan(resultCents)
|
||
}
|
||
|
||
/**
|
||
* 金额除法
|
||
* @param {number|string} amount - 金额(元)
|
||
* @param {number} divisor - 除数
|
||
* @returns {string} - 结果(元),保留两位小数
|
||
*/
|
||
export function divideMoney(amount, divisor) {
|
||
if (divisor === 0) {
|
||
throw new Error('除数不能为0')
|
||
}
|
||
const cents = yuanToCent(amount)
|
||
const resultCents = Math.round(cents / divisor)
|
||
return centToYuan(resultCents)
|
||
}
|
||
|
||
/**
|
||
* 格式化金额显示
|
||
* @param {number|string} amount - 金额
|
||
* @param {boolean} showSymbol - 是否显示货币符号
|
||
* @returns {string} - 格式化后的金额
|
||
*/
|
||
export function formatMoney(amount, showSymbol = true) {
|
||
if (amount === null || amount === undefined || amount === '') {
|
||
return showSymbol ? '¥0.00' : '0.00'
|
||
}
|
||
const formatted = parseFloat(amount).toFixed(2)
|
||
return showSymbol ? `¥${formatted}` : formatted
|
||
}
|
||
|
||
/**
|
||
* 验证金额格式
|
||
* @param {string} amount - 金额字符串
|
||
* @returns {boolean} - 是否有效
|
||
*/
|
||
export function validateMoney(amount) {
|
||
if (!amount) return false
|
||
const regex = /^\d+(\.\d{1,2})?$/
|
||
return regex.test(amount)
|
||
}
|
||
|
||
/**
|
||
* 限制金额输入格式
|
||
* @param {string} value - 输入值
|
||
* @returns {string} - 格式化后的值
|
||
*/
|
||
export function limitMoneyInput(value) {
|
||
// 只保留数字和小数点
|
||
value = value.replace(/[^\d.]/g, '')
|
||
|
||
// 只保留第一个小数点
|
||
const parts = value.split('.')
|
||
if (parts.length > 2) {
|
||
value = parts[0] + '.' + parts.slice(1).join('')
|
||
}
|
||
|
||
// 小数点后最多两位
|
||
if (parts[1] && parts[1].length > 2) {
|
||
value = parts[0] + '.' + parts[1].substring(0, 2)
|
||
}
|
||
|
||
return value
|
||
}
|
||
|
||
/**
|
||
* 比较金额大小
|
||
* @param {number|string} amount1 - 金额1
|
||
* @param {number|string} amount2 - 金额2
|
||
* @returns {number} - 1: amount1 > amount2, 0: 相等, -1: amount1 < amount2
|
||
*/
|
||
export function compareMoney(amount1, amount2) {
|
||
const cents1 = yuanToCent(amount1)
|
||
const cents2 = yuanToCent(amount2)
|
||
|
||
if (cents1 > cents2) return 1
|
||
if (cents1 < cents2) return -1
|
||
return 0
|
||
}
|