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
|
|||
|
|
}
|