util.ts
2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
export function bindMethods<T extends object>(instance: T): void {
const prototype = Object.getPrototypeOf(instance);
const propertyNames = Object.getOwnPropertyNames(prototype);
propertyNames.forEach((propertyName) => {
const descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
const propertyValue = instance[propertyName as keyof T];
if (
typeof propertyValue === 'function' &&
propertyName !== 'constructor' &&
descriptor &&
!descriptor.get &&
!descriptor.set
) {
instance[propertyName as keyof T] = propertyValue.bind(instance);
}
});
}
/**
* 获取嵌套对象的字段值
* @param obj - 要查找的对象
* @param path - 用于查找字段的路径,使用小数点分隔
* @returns 字段值,或者未找到时返回 undefined
*/
export function getNestedValue<T>(obj: T, path: string): any {
if (typeof path !== 'string' || path.length === 0) {
throw new Error('Path must be a non-empty string');
}
// 把路径字符串按 "." 分割成数组
const keys = path.split('.') as (number | string)[];
let current: any = obj;
for (const key of keys) {
if (current === null || current === undefined) {
return undefined;
}
current = current[key as keyof typeof current];
}
return current;
}
/**
* 分转元 + 千分位格式化(TS 严格模式安全)
* @param amount 分
* @param decimals 小数位,默认 2
*/
export function fenToYuan(
amount: bigint | number | string,
decimals: number = 2,
): string {
if (amount === null || amount === undefined || amount === '') {
return (0).toFixed(decimals);
}
const num = Number(amount);
if (Number.isNaN(num)) {
return (0).toFixed(decimals);
}
const isNegative = num < 0;
const yuan = Math.abs(num) / 100;
const fixed = yuan.toFixed(decimals);
// 👇 关键修复点
const parts = fixed.split('.');
const integer = parts[0] ?? '0';
const decimal = parts[1];
const thousand = integer.replaceAll(/\B(?=(\d{3})+(?!\d))/g, ',');
return `${isNegative ? '-' : ''}${thousand}${decimal ? `.${decimal}` : ''}`;
}