/
index.ts
166 lines (152 loc) · 4.72 KB
/
index.ts
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import type { InternalNamePath, NamePath } from 'antd/es/form/interface';
import dayjs from 'dayjs';
import get from 'rc-util/lib/utils/get';
import { isNil } from '../isNil';
import type { ProFieldValueType } from '../typing';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
dayjs.extend(quarterOfYear);
type DateFormatter =
| 'number'
| 'string'
| ((value: dayjs.Dayjs, valueType: string) => string | number)
| false;
export const dateFormatterMap = {
time: 'HH:mm:ss',
timeRange: 'HH:mm:ss',
date: 'YYYY-MM-DD',
dateWeek: 'YYYY-wo',
dateMonth: 'YYYY-MM',
dateQuarter: 'YYYY-[Q]Q',
dateYear: 'YYYY',
dateRange: 'YYYY-MM-DD',
dateTime: 'YYYY-MM-DD HH:mm:ss',
dateTimeRange: 'YYYY-MM-DD HH:mm:ss',
};
function isObject(o: any) {
return Object.prototype.toString.call(o) === '[object Object]';
}
export function isPlainObject(o: { constructor: any }) {
if (isObject(o) === false) return false;
// If has modified constructor
const ctor = o.constructor;
if (ctor === undefined) return true;
// If has modified prototype
const prot = ctor.prototype;
if (isObject(prot) === false) return false;
// If constructor does not have an Object-specific method
if (prot.hasOwnProperty('isPrototypeOf') === false) {
return false;
}
// Most likely a plain Object
return true;
}
/**
* 一个比较hack的moment判断工具
* @param value
* @returns
*/
const isMoment = (value: any) => !!value?._isAMomentObject;
/**
* 根据不同的格式转化 dayjs
*
* @param value
* @param dateFormatter
* @param valueType
*/
export const convertMoment = (
value: dayjs.Dayjs,
dateFormatter: string | ((value: dayjs.Dayjs, valueType: string) => string | number) | false,
valueType: string,
) => {
if (!dateFormatter) {
return value;
}
if (dayjs.isDayjs(value) || isMoment(value)) {
if (dateFormatter === 'number') {
return value.valueOf();
}
if (dateFormatter === 'string') {
return value.format(dateFormatterMap[valueType] || 'YYYY-MM-DD HH:mm:ss');
}
if (typeof dateFormatter === 'string' && dateFormatter !== 'string') {
return value.format(dateFormatter);
}
if (typeof dateFormatter === 'function') {
return dateFormatter(value, valueType);
}
}
return value;
};
/**
* 这里主要是来转化一下数据 将 dayjs 转化为 string 将 all 默认删除
*
* @param value
* @param dateFormatter
* @param proColumnsMap
*/
export const conversionMomentValue = <T extends {} = any>(
value: T,
dateFormatter: DateFormatter,
valueTypeMap: Record<
string,
| {
valueType: ProFieldValueType;
dateFormat: string;
}
| any
>,
omitNil?: boolean,
parentKey?: NamePath,
): T => {
const tmpValue = {} as T;
if (typeof window === 'undefined') return value;
// 如果 value 是 string | null | Blob类型 其中之一,直接返回
// 形如 {key: [File, File]} 的表单字段当进行第二次递归时会导致其直接越过 typeof value !== 'object' 这一判断 https://github.com/ant-design/pro-components/issues/2071
if (typeof value !== 'object' || isNil(value) || value instanceof Blob || Array.isArray(value)) {
return value;
}
Object.keys(value as Record<string, any>).forEach((key) => {
const namePath: InternalNamePath = parentKey ? ([parentKey, key].flat(1) as string[]) : [key];
const valueFormatMap = get(valueTypeMap, namePath) || 'text';
let valueType: ProFieldValueType = 'text';
let dateFormat: string | undefined;
if (typeof valueFormatMap === 'string') {
valueType = valueFormatMap as ProFieldValueType;
} else if (valueFormatMap) {
valueType = valueFormatMap.valueType;
dateFormat = valueFormatMap.dateFormat;
}
const itemValue = (value as Record<string, any>)[key];
if (isNil(itemValue) && omitNil) {
return;
}
// 处理嵌套的情况
if (
isPlainObject(itemValue) &&
// 不是数组
!Array.isArray(itemValue) &&
// 不是 dayjs
!dayjs.isDayjs(itemValue) &&
// 不是 moment
!isMoment(itemValue)
) {
tmpValue[key] = conversionMomentValue(itemValue, dateFormatter, valueTypeMap, omitNil, [key]);
return;
}
// 处理 FormList 的 value
if (Array.isArray(itemValue)) {
tmpValue[key] = itemValue.map((arrayValue, index) => {
if (dayjs.isDayjs(arrayValue) || isMoment(itemValue)) {
return convertMoment(arrayValue, dateFormat || dateFormatter, valueType);
}
return conversionMomentValue(arrayValue, dateFormatter, valueTypeMap, omitNil, [
key,
`${index}`,
]);
});
return;
}
tmpValue[key] = convertMoment(itemValue, dateFormat || dateFormatter, valueType);
});
return tmpValue;
};