3 changed files with 139 additions and 6 deletions
@ -0,0 +1,103 @@ |
|||||||
|
/** |
||||||
|
* numberUtil |
||||||
|
* 前端数值统一处理工具 |
||||||
|
* |
||||||
|
* 适配后端: |
||||||
|
* int / Integer |
||||||
|
* double / Double |
||||||
|
* BigDecimal(序列化后通常是 string) |
||||||
|
*/ |
||||||
|
const numberUtil = { |
||||||
|
|
||||||
|
/** |
||||||
|
* 基础:转 Number |
||||||
|
* - 支持 string / number |
||||||
|
* - BigDecimal(JSON) -> string -> number |
||||||
|
*/ |
||||||
|
toNumber(val) { |
||||||
|
if (val === null || val === undefined || val === '') return null; |
||||||
|
const n = Number(val); |
||||||
|
return Number.isNaN(n) ? null : n; |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 转 Number,空值给默认值(常用于金额) |
||||||
|
*/ |
||||||
|
toNumberOr(val, defaultVal = 0) { |
||||||
|
const n = this.toNumber(val); |
||||||
|
return n === null ? defaultVal : n; |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 专用于整数(int / long) |
||||||
|
* "1.0" -> 1 |
||||||
|
* 1.9 -> 1 |
||||||
|
*/ |
||||||
|
toInt(val) { |
||||||
|
const n = this.toNumber(val); |
||||||
|
return n === null ? null : Math.trunc(n); |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 专用于金额(double / BigDecimal) |
||||||
|
* 默认保留 2 位 |
||||||
|
*/ |
||||||
|
toDecimal(val, scale = 2) { |
||||||
|
const n = this.toNumber(val); |
||||||
|
if (n === null) return null; |
||||||
|
return Number(n.toFixed(scale)); |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否是合法数值(string / number) |
||||||
|
*/ |
||||||
|
isNumber(val) { |
||||||
|
if (val === null || val === undefined || val === '') return false; |
||||||
|
return !Number.isNaN(Number(val)); |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 性别归一化(int / string 都支持) |
||||||
|
* 0 / "0" -> 0 |
||||||
|
* 1 / "1" -> 1 |
||||||
|
*/ |
||||||
|
normalizeSex(val) { |
||||||
|
const n = this.toInt(val); |
||||||
|
return n === 0 || n === 1 ? n : null; |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 是 / 否 类型(radio / checkbox 常用) |
||||||
|
* 支持:0/1, "0"/"1", true/false |
||||||
|
*/ |
||||||
|
normalizeYesNo(val) { |
||||||
|
if (val === true || val === 'true') return 1; |
||||||
|
if (val === false || val === 'false') return 0; |
||||||
|
const n = this.toInt(val); |
||||||
|
return n === 0 || n === 1 ? n : null; |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* BigDecimal 场景:保证回传给后端的是 string |
||||||
|
* 避免 JS 精度问题 |
||||||
|
*/ |
||||||
|
toBigDecimalString(val, scale = 2) { |
||||||
|
const n = this.toNumber(val); |
||||||
|
if (n === null) return null; |
||||||
|
return n.toFixed(scale); |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 金额安全相加(避免 null) |
||||||
|
*/ |
||||||
|
sum(list, field) { |
||||||
|
if (!Array.isArray(list)) return 0; |
||||||
|
return list.reduce((total, item) => { |
||||||
|
const v = item?.[field]; |
||||||
|
const n = this.toNumber(v); |
||||||
|
return total + (n ?? 0); |
||||||
|
}, 0); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
export default numberUtil; |
||||||
Loading…
Reference in new issue