@indfnd/utils 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +247 -0
- package/dist/ind-utils.es.js +10831 -0
- package/dist/ind-utils.umd.cjs +36 -0
- package/global.d.ts +8 -0
- package/package.json +63 -0
- package/src/api/com.ts +8 -0
- package/src/api/index.ts +5 -0
- package/src/api/item.ts +20 -0
- package/src/api/platform/dict.ts +59 -0
- package/src/api/platform/index.ts +4 -0
- package/src/api/platform/menu.ts +44 -0
- package/src/api/platform/oss.ts +8 -0
- package/src/api/platform/user.ts +29 -0
- package/src/api/user.ts +8 -0
- package/src/config/base.config.ts +47 -0
- package/src/config/dev.config.ts +5 -0
- package/src/config/index.ts +11 -0
- package/src/config/prod.config.ts +5 -0
- package/src/index.ts +3 -0
- package/src/utils/cache/dict-cache.ts +11 -0
- package/src/utils/cache/index.ts +3 -0
- package/src/utils/cache/permission-cache.ts +15 -0
- package/src/utils/cache/user-cache.ts +15 -0
- package/src/utils/date.ts +57 -0
- package/src/utils/enum.ts +133 -0
- package/src/utils/event.ts +53 -0
- package/src/utils/excel.js +642 -0
- package/src/utils/half-year.ts +53 -0
- package/src/utils/index.ts +18 -0
- package/src/utils/is-type.ts +164 -0
- package/src/utils/mime-type.ts +67 -0
- package/src/utils/number.ts +144 -0
- package/src/utils/quarter.ts +58 -0
- package/src/utils/request/axios.extends.ts +9 -0
- package/src/utils/request/cache-rules.ts +19 -0
- package/src/utils/request/content-type.ts +16 -0
- package/src/utils/request/index.ts +20 -0
- package/src/utils/request/interceptors.ts +99 -0
- package/src/utils/request/url-params.ts +18 -0
- package/src/utils/sm3/index.ts +29 -0
- package/src/utils/sm3/sm3.ts +238 -0
- package/src/utils/storage.ts +51 -0
- package/src/utils/table.ts +252 -0
- package/src/utils/token.ts +57 -0
- package/src/utils/uuid.ts +10 -0
- package/src/utils/validate.ts +149 -0
- package/types/api/com.d.ts +2 -0
- package/types/api/com.d.ts.map +1 -0
- package/types/api/index.d.ts +5 -0
- package/types/api/index.d.ts.map +1 -0
- package/types/api/item.d.ts +5 -0
- package/types/api/item.d.ts.map +1 -0
- package/types/api/platform/dict.d.ts +4 -0
- package/types/api/platform/dict.d.ts.map +1 -0
- package/types/api/platform/index.d.ts +5 -0
- package/types/api/platform/index.d.ts.map +1 -0
- package/types/api/platform/menu.d.ts +17 -0
- package/types/api/platform/menu.d.ts.map +1 -0
- package/types/api/platform/oss.d.ts +2 -0
- package/types/api/platform/oss.d.ts.map +1 -0
- package/types/api/platform/user.d.ts +17 -0
- package/types/api/platform/user.d.ts.map +1 -0
- package/types/api/user.d.ts +2 -0
- package/types/api/user.d.ts.map +1 -0
- package/types/config/base.config.d.ts +31 -0
- package/types/config/base.config.d.ts.map +1 -0
- package/types/config/dev.config.d.ts +4 -0
- package/types/config/dev.config.d.ts.map +1 -0
- package/types/config/index.d.ts +61 -0
- package/types/config/index.d.ts.map +1 -0
- package/types/config/prod.config.d.ts +4 -0
- package/types/config/prod.config.d.ts.map +1 -0
- package/types/index.d.ts +4 -0
- package/types/index.d.ts.map +1 -0
- package/types/utils/cache/dict-cache.d.ts +3 -0
- package/types/utils/cache/dict-cache.d.ts.map +1 -0
- package/types/utils/cache/index.d.ts +3 -0
- package/types/utils/cache/index.d.ts.map +1 -0
- package/types/utils/cache/permission-cache.d.ts +4 -0
- package/types/utils/cache/permission-cache.d.ts.map +1 -0
- package/types/utils/cache/user-cache.d.ts +4 -0
- package/types/utils/cache/user-cache.d.ts.map +1 -0
- package/types/utils/date.d.ts +4 -0
- package/types/utils/date.d.ts.map +1 -0
- package/types/utils/enum.d.ts +90 -0
- package/types/utils/enum.d.ts.map +1 -0
- package/types/utils/event.d.ts +17 -0
- package/types/utils/event.d.ts.map +1 -0
- package/types/utils/excel.d.ts +48 -0
- package/types/utils/excel.d.ts.map +1 -0
- package/types/utils/half-year.d.ts +6 -0
- package/types/utils/half-year.d.ts.map +1 -0
- package/types/utils/index.d.ts +18 -0
- package/types/utils/index.d.ts.map +1 -0
- package/types/utils/is-type.d.ts +34 -0
- package/types/utils/is-type.d.ts.map +1 -0
- package/types/utils/mime-type.d.ts +68 -0
- package/types/utils/mime-type.d.ts.map +1 -0
- package/types/utils/number.d.ts +20 -0
- package/types/utils/number.d.ts.map +1 -0
- package/types/utils/quarter.d.ts +7 -0
- package/types/utils/quarter.d.ts.map +1 -0
- package/types/utils/request/axios.extends.d.ts +9 -0
- package/types/utils/request/axios.extends.d.ts.map +1 -0
- package/types/utils/request/cache-rules.d.ts +7 -0
- package/types/utils/request/cache-rules.d.ts.map +1 -0
- package/types/utils/request/content-type.d.ts +9 -0
- package/types/utils/request/content-type.d.ts.map +1 -0
- package/types/utils/request/index.d.ts +8 -0
- package/types/utils/request/index.d.ts.map +1 -0
- package/types/utils/request/interceptors.d.ts +4 -0
- package/types/utils/request/interceptors.d.ts.map +1 -0
- package/types/utils/request/url-params.d.ts +8 -0
- package/types/utils/request/url-params.d.ts.map +1 -0
- package/types/utils/sm3/index.d.ts +7 -0
- package/types/utils/sm3/index.d.ts.map +1 -0
- package/types/utils/sm3/sm3.d.ts +3 -0
- package/types/utils/sm3/sm3.d.ts.map +1 -0
- package/types/utils/storage.d.ts +8 -0
- package/types/utils/storage.d.ts.map +1 -0
- package/types/utils/table.d.ts +56 -0
- package/types/utils/table.d.ts.map +1 -0
- package/types/utils/token.d.ts +3 -0
- package/types/utils/token.d.ts.map +1 -0
- package/types/utils/uuid.d.ts +5 -0
- package/types/utils/uuid.d.ts.map +1 -0
- package/types/utils/validate.d.ts +9 -0
- package/types/utils/validate.d.ts.map +1 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 左补0到指定长度
|
|
3
|
+
*/
|
|
4
|
+
function leftPad(input, num) {
|
|
5
|
+
if (input.length >= num) return input
|
|
6
|
+
|
|
7
|
+
return new Array(num - input.length + 1).join('0') + input
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 二进制转化为十六进制
|
|
12
|
+
*/
|
|
13
|
+
function binary2hex(binary) {
|
|
14
|
+
const binaryLength = 8
|
|
15
|
+
let hex = ''
|
|
16
|
+
for (let i = 0; i < binary.length / binaryLength; i++) {
|
|
17
|
+
hex += leftPad(parseInt(binary.substr(i * binaryLength, binaryLength), 2).toString(16), 2)
|
|
18
|
+
}
|
|
19
|
+
return hex
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 十六进制转化为二进制
|
|
24
|
+
*/
|
|
25
|
+
function hex2binary(hex) {
|
|
26
|
+
const hexLength = 2
|
|
27
|
+
let binary = ''
|
|
28
|
+
for (let i = 0; i < hex.length / hexLength; i++) {
|
|
29
|
+
binary += leftPad(parseInt(hex.substr(i * hexLength, hexLength), 16).toString(2), 8)
|
|
30
|
+
}
|
|
31
|
+
return binary
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 普通字符串转化为二进制
|
|
36
|
+
*/
|
|
37
|
+
function str2binary(str) {
|
|
38
|
+
let binary = ''
|
|
39
|
+
for (const ch of str) {
|
|
40
|
+
binary += leftPad(ch.codePointAt(0).toString(2), 8)
|
|
41
|
+
}
|
|
42
|
+
return binary
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 循环左移
|
|
47
|
+
*/
|
|
48
|
+
function rol(str, n) {
|
|
49
|
+
return str.substring(n % str.length) + str.substr(0, n % str.length)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 二进制运算
|
|
54
|
+
*/
|
|
55
|
+
function binaryCal(x, y, method) {
|
|
56
|
+
const a = x || ''
|
|
57
|
+
const b = y || ''
|
|
58
|
+
const result = []
|
|
59
|
+
let prevResult
|
|
60
|
+
|
|
61
|
+
for (let i = a.length - 1; i >= 0; i--) {
|
|
62
|
+
// 大端
|
|
63
|
+
prevResult = method(a[i], b[i], prevResult)
|
|
64
|
+
result[i] = prevResult[0]
|
|
65
|
+
}
|
|
66
|
+
return result.join('')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 二进制异或运算
|
|
71
|
+
*/
|
|
72
|
+
function xor(x, y) {
|
|
73
|
+
return binaryCal(x, y, (a, b) => [a === b ? '0' : '1'])
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 二进制与运算
|
|
78
|
+
*/
|
|
79
|
+
function and(x, y) {
|
|
80
|
+
return binaryCal(x, y, (a, b) => [a === '1' && b === '1' ? '1' : '0'])
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 二进制或运算
|
|
85
|
+
*/
|
|
86
|
+
function or(x, y) {
|
|
87
|
+
return binaryCal(x, y, (a, b) => [a === '1' || b === '1' ? '1' : '0']) // a === '0' && b === '0' ? '0' : '1'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 二进制与运算
|
|
92
|
+
*/
|
|
93
|
+
function add(x, y) {
|
|
94
|
+
const result = binaryCal(x, y, (a, b, prevResult) => {
|
|
95
|
+
const carry = prevResult ? prevResult[1] : '0' || '0'
|
|
96
|
+
|
|
97
|
+
// a,b不等时,carry不变,结果与carry相反
|
|
98
|
+
// a,b相等时,结果等于原carry,新carry等于a
|
|
99
|
+
if (a !== b) return [carry === '0' ? '1' : '0', carry]
|
|
100
|
+
|
|
101
|
+
return [carry, a]
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
return result
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 二进制非运算
|
|
109
|
+
*/
|
|
110
|
+
function not(x) {
|
|
111
|
+
return binaryCal(x, undefined, (a) => [a === '1' ? '0' : '1'])
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function calMulti(method) {
|
|
115
|
+
return (...arr) => arr.reduce((prev, curr) => method(prev, curr))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 压缩函数中的置换函数 P1(X) = X xor (X <<< 9) xor (X <<< 17)
|
|
120
|
+
*/
|
|
121
|
+
function P0(X) {
|
|
122
|
+
return calMulti(xor)(X, rol(X, 9), rol(X, 17))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 消息扩展中的置换函数 P1(X) = X xor (X <<< 15) xor (X <<< 23)
|
|
127
|
+
*/
|
|
128
|
+
function P1(X) {
|
|
129
|
+
return calMulti(xor)(X, rol(X, 15), rol(X, 23))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function FF(X, Y, Z, j) {
|
|
133
|
+
return j >= 0 && j <= 15 ? calMulti(xor)(X, Y, Z) : calMulti(or)(and(X, Y), and(X, Z), and(Y, Z))
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function GG(X, Y, Z, j) {
|
|
137
|
+
return j >= 0 && j <= 15 ? calMulti(xor)(X, Y, Z) : or(and(X, Y), and(not(X), Z))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function T(j) {
|
|
141
|
+
return j >= 0 && j <= 15 ? hex2binary('79cc4519') : hex2binary('7a879d8a')
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 压缩函数
|
|
146
|
+
*/
|
|
147
|
+
function CF(V, Bi) {
|
|
148
|
+
// 消息扩展
|
|
149
|
+
const wordLength = 32
|
|
150
|
+
const W = []
|
|
151
|
+
const M = [] // W'
|
|
152
|
+
|
|
153
|
+
// 将消息分组B划分为16个字W0, W1,…… ,W15 (字为长度为32的比特串)
|
|
154
|
+
for (let i = 0; i < 16; i++) {
|
|
155
|
+
W.push(Bi.substr(i * wordLength, wordLength))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// W[j] <- P1(W[j−16] xor W[j−9] xor (W[j−3] <<< 15)) xor (W[j−13] <<< 7) xor W[j−6]
|
|
159
|
+
for (let j = 16; j < 68; j++) {
|
|
160
|
+
W.push(
|
|
161
|
+
calMulti(xor)(
|
|
162
|
+
P1(calMulti(xor)(W[j - 16], W[j - 9], rol(W[j - 3], 15))),
|
|
163
|
+
rol(W[j - 13], 7),
|
|
164
|
+
W[j - 6],
|
|
165
|
+
),
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// W′[j] = W[j] xor W[j+4]
|
|
170
|
+
for (let j = 0; j < 64; j++) {
|
|
171
|
+
M.push(xor(W[j], W[j + 4]))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 压缩
|
|
175
|
+
const wordRegister = [] // 字寄存器
|
|
176
|
+
for (let j = 0; j < 8; j++) {
|
|
177
|
+
wordRegister.push(V.substr(j * wordLength, wordLength))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
let A = wordRegister[0]
|
|
181
|
+
let B = wordRegister[1]
|
|
182
|
+
let C = wordRegister[2]
|
|
183
|
+
let D = wordRegister[3]
|
|
184
|
+
let E = wordRegister[4]
|
|
185
|
+
let F = wordRegister[5]
|
|
186
|
+
let G = wordRegister[6]
|
|
187
|
+
let H = wordRegister[7]
|
|
188
|
+
|
|
189
|
+
// 中间变量
|
|
190
|
+
let SS1
|
|
191
|
+
let SS2
|
|
192
|
+
let TT1
|
|
193
|
+
let TT2
|
|
194
|
+
for (let j = 0; j < 64; j++) {
|
|
195
|
+
SS1 = rol(calMulti(add)(rol(A, 12), E, rol(T(j), j)), 7)
|
|
196
|
+
SS2 = xor(SS1, rol(A, 12))
|
|
197
|
+
|
|
198
|
+
TT1 = calMulti(add)(FF(A, B, C, j), D, SS2, M[j])
|
|
199
|
+
TT2 = calMulti(add)(GG(E, F, G, j), H, SS1, W[j])
|
|
200
|
+
|
|
201
|
+
D = C
|
|
202
|
+
C = rol(B, 9)
|
|
203
|
+
B = A
|
|
204
|
+
A = TT1
|
|
205
|
+
H = G
|
|
206
|
+
G = rol(F, 19)
|
|
207
|
+
F = E
|
|
208
|
+
E = P0(TT2)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return xor([A, B, C, D, E, F, G, H].join(''), V)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function sm3(str) {
|
|
215
|
+
const binary = str2binary(str)
|
|
216
|
+
|
|
217
|
+
// 填充
|
|
218
|
+
const len = binary.length
|
|
219
|
+
|
|
220
|
+
// k是满足len + 1 + k = 448mod512的最小的非负整数
|
|
221
|
+
let k = len % 512
|
|
222
|
+
|
|
223
|
+
// 如果 448 <= (512 % len) < 512,需要多补充 (len % 448) 比特'0'以满足总比特长度为512的倍数
|
|
224
|
+
k = k >= 448 ? 512 - (k % 448) - 1 : 448 - k - 1
|
|
225
|
+
|
|
226
|
+
const m = `${binary}1${leftPad('', k)}${leftPad(len.toString(2), 64)}`.toString() // k个0
|
|
227
|
+
|
|
228
|
+
// 迭代压缩
|
|
229
|
+
const n = (len + k + 65) / 512
|
|
230
|
+
|
|
231
|
+
let V = hex2binary('7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e')
|
|
232
|
+
for (let i = 0; i <= n - 1; i++) {
|
|
233
|
+
const B = m.substr(512 * i, 512)
|
|
234
|
+
V = CF(V, B)
|
|
235
|
+
}
|
|
236
|
+
return binary2hex(V)
|
|
237
|
+
}
|
|
238
|
+
export default sm3
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// ============ SessionStorage ============
|
|
2
|
+
export const getSessionStorage = (key: string) => {
|
|
3
|
+
const value = sessionStorage.getItem(key)
|
|
4
|
+
if (value) {
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(value)
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return value
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return value
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const setSessionStorage = (key: string, value: any) => {
|
|
15
|
+
if (typeof value !== 'string') {
|
|
16
|
+
value = JSON.stringify(value)
|
|
17
|
+
}
|
|
18
|
+
sessionStorage.setItem(key, value)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const removeSessionStorage = (key: string) => {
|
|
22
|
+
return sessionStorage.removeItem(key)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function clearSessionStorage() {
|
|
26
|
+
sessionStorage.clear()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ============ LocalStorage ============
|
|
30
|
+
export const getLocalStorage = (key: string) => {
|
|
31
|
+
const value = localStorage.getItem(key)
|
|
32
|
+
if (value) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(value)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return value
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return value
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const setLocalStorage = (key: string, value: any) => {
|
|
43
|
+
if (typeof value !== 'string') {
|
|
44
|
+
value = JSON.stringify(value)
|
|
45
|
+
}
|
|
46
|
+
localStorage.setItem(key, value)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const removeLocalStorage = (key: string) => {
|
|
50
|
+
return localStorage.removeItem(key)
|
|
51
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: huxuetong
|
|
3
|
+
* @Date: 2023-10-27 15:05:25
|
|
4
|
+
* @Last Modified by: huxuetong
|
|
5
|
+
* @Last Modified time: 2024-01-08 22:58:03
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import _ from 'lodash'
|
|
9
|
+
|
|
10
|
+
const GROUP_SEP = '__'
|
|
11
|
+
const VALUE_SEP = '--'
|
|
12
|
+
|
|
13
|
+
interface ColumnGroup {
|
|
14
|
+
// key和title配套使用,用于非动态数据的列分组,如销量、销额等
|
|
15
|
+
key?: string
|
|
16
|
+
title?: string
|
|
17
|
+
|
|
18
|
+
// keyProp、titleProp、titleFormatter配套使用,用于和动态数据有关的列分组,如工业、卷烟等
|
|
19
|
+
keyProp?: string
|
|
20
|
+
titleProp?: string
|
|
21
|
+
titleFormatter?: (title: string) => string
|
|
22
|
+
|
|
23
|
+
// 每层分组表头下继续分组
|
|
24
|
+
children?: ColumnGroup[]
|
|
25
|
+
[propName: string]: any
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface row2columnOption {
|
|
29
|
+
// 组织后表格列定义key对应属性名称
|
|
30
|
+
keyPropName?: string
|
|
31
|
+
// 组织后表格列定义title对应属性名称
|
|
32
|
+
titlePropName?: string
|
|
33
|
+
// 组织列定义 key 的前缀
|
|
34
|
+
keyPrefix?: string
|
|
35
|
+
// 组织列定义 key 的后缀
|
|
36
|
+
keyLastSuffix?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface Column {
|
|
40
|
+
key?: string
|
|
41
|
+
title?: string
|
|
42
|
+
children?: Column[]
|
|
43
|
+
[propName: string]: any
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface row2columnResult {
|
|
47
|
+
columns: Column[]
|
|
48
|
+
data: Array<any>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 根据各层分组定义组织出表头
|
|
52
|
+
function renderColumnTree(
|
|
53
|
+
data: Array<any>,
|
|
54
|
+
columnGroup: ColumnGroup,
|
|
55
|
+
option: row2columnOption = {},
|
|
56
|
+
): Column | Column[] {
|
|
57
|
+
const { key, keyProp, title, titleProp, titleFormatter, children, ...args } = columnGroup
|
|
58
|
+
const {
|
|
59
|
+
keyPropName = 'key',
|
|
60
|
+
titlePropName = 'title',
|
|
61
|
+
keyPrefix = '',
|
|
62
|
+
keyLastSuffix = '',
|
|
63
|
+
} = option
|
|
64
|
+
|
|
65
|
+
// 动态列
|
|
66
|
+
if (keyProp) {
|
|
67
|
+
const columnGroupData = _.uniqBy(data, columnGroup.keyProp)
|
|
68
|
+
return columnGroupData.map((item) => {
|
|
69
|
+
const columnTitle = titleFormatter ? titleFormatter(item[titleProp]) : item[titleProp]
|
|
70
|
+
|
|
71
|
+
// 不是最后一层,继续组织tree
|
|
72
|
+
if (children && children.length) {
|
|
73
|
+
// 前缀加__ 和下一层做分割
|
|
74
|
+
const prefix = `${keyPrefix}${keyProp}${VALUE_SEP}${item[keyProp]}${GROUP_SEP}`
|
|
75
|
+
const columnChildren = children.map((child) => {
|
|
76
|
+
return renderColumnTree(data, child, { ...option, keyPrefix: prefix })
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
...args,
|
|
81
|
+
[titlePropName]: columnTitle,
|
|
82
|
+
children: _.flatten(columnChildren), // 多层动态列下,上面的层级拿到的是个二维数组,flatten一下
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 最后一层 返回key、title
|
|
87
|
+
const suffix = keyLastSuffix ? `${GROUP_SEP}${keyLastSuffix}` : ''
|
|
88
|
+
return {
|
|
89
|
+
...args,
|
|
90
|
+
[keyPropName]: `${keyPrefix}${keyProp}${VALUE_SEP}${item[keyProp]}${suffix}`,
|
|
91
|
+
[titlePropName]: columnTitle,
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 非动态列 不是最后一层
|
|
97
|
+
if (children && children.length) {
|
|
98
|
+
// 非动态列的下一层一般都是在一行数据上的,所以拼接key时不加__做不同层级的分割,而是和下一层一起作为属性名
|
|
99
|
+
const prefix = `${keyPrefix}${key}`
|
|
100
|
+
const columnChildren = children.map((child) => {
|
|
101
|
+
return renderColumnTree(data, child, { ...option, keyPrefix: prefix })
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
return { ...args, [titlePropName]: title, children: _.flatten(columnChildren) }
|
|
105
|
+
}
|
|
106
|
+
return { ...args, [keyPropName]: `${keyPrefix}${key}`, [titlePropName]: title }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 获取最后一层的表头
|
|
110
|
+
function getLeafColumns(columns: Column[] = []): Column[] {
|
|
111
|
+
if (!columns || !columns.length) return []
|
|
112
|
+
return columns.reduce((rlt, column) => {
|
|
113
|
+
if (column.children) {
|
|
114
|
+
return [...rlt, ...getLeafColumns(column.children)]
|
|
115
|
+
} else {
|
|
116
|
+
return [...rlt, column]
|
|
117
|
+
}
|
|
118
|
+
}, [] as Column[])
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 组织行转列结果的每一行数据
|
|
122
|
+
function renderRowData(data: Array<any>, keys: string[]) {
|
|
123
|
+
if (!keys.length) return
|
|
124
|
+
const key = keys[0]
|
|
125
|
+
keys = keys.slice(1)
|
|
126
|
+
|
|
127
|
+
if (key.includes(VALUE_SEP) && keys.length) {
|
|
128
|
+
// 这个分组是动态列的分组,且不是最后一层
|
|
129
|
+
const [keyProp, keyValue] = key.split(VALUE_SEP)
|
|
130
|
+
// 一层一层往下找,筛选符合该分组的数据
|
|
131
|
+
const matchData = _.filter(data, { [keyProp]: keyValue })
|
|
132
|
+
return renderRowData(matchData, keys)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (keys.length) {
|
|
136
|
+
console.error('怎么会不是最后一层分组呢,请联系开发人员查看!')
|
|
137
|
+
}
|
|
138
|
+
// 最后一层,固定指标,赋值
|
|
139
|
+
const value = data?.[0]?.[key]
|
|
140
|
+
return value
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 行转列公共方法
|
|
145
|
+
* ! 目前是根据非动态列下全是非动态列的分组来组织的,若动态列和非动态列相互穿插分组,那就糟糕了
|
|
146
|
+
*
|
|
147
|
+
* @param data 所有行数据
|
|
148
|
+
* @param columnGroups 分组定义
|
|
149
|
+
* @param rowKey 行转列目标结果的行主键
|
|
150
|
+
* @param option 一些参数
|
|
151
|
+
* @returns 行转列后的表头和数据
|
|
152
|
+
*/
|
|
153
|
+
export function row2column(
|
|
154
|
+
data: Array<any> = [],
|
|
155
|
+
columnGroups: ColumnGroup[] = [],
|
|
156
|
+
rowKey: string,
|
|
157
|
+
option: row2columnOption = {},
|
|
158
|
+
): row2columnResult {
|
|
159
|
+
// 组织表头
|
|
160
|
+
const columns = _.flatten<Column>(
|
|
161
|
+
columnGroups.map((group) => renderColumnTree(data, group, option)),
|
|
162
|
+
)
|
|
163
|
+
const leafColumns = getLeafColumns(columns)
|
|
164
|
+
|
|
165
|
+
// 组织数据
|
|
166
|
+
const rowKeyUniqData = _.uniqBy(data, rowKey)
|
|
167
|
+
const groupData = _.groupBy(data, rowKey)
|
|
168
|
+
const rltData = rowKeyUniqData.map((item) => {
|
|
169
|
+
const rowGroupData = groupData[item[rowKey]] || []
|
|
170
|
+
const newItem = { ...item }
|
|
171
|
+
|
|
172
|
+
leafColumns.forEach((column) => {
|
|
173
|
+
const columnKey: string = column[option.keyPropName || 'key']
|
|
174
|
+
const keys = columnKey.split(GROUP_SEP) || []
|
|
175
|
+
const value = renderRowData(rowGroupData, keys)
|
|
176
|
+
newItem[columnKey] = value
|
|
177
|
+
// 去掉原始数据的字段
|
|
178
|
+
delete newItem[keys[keys.length - 1]]
|
|
179
|
+
})
|
|
180
|
+
return newItem
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
return { data: rltData, columns }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// -----------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
// 将每一行转回行数据
|
|
189
|
+
function flattenRowData(
|
|
190
|
+
rowData = {},
|
|
191
|
+
leafColumns: Column[] = [],
|
|
192
|
+
option: row2columnOption = {},
|
|
193
|
+
): Array<any> {
|
|
194
|
+
const rlt = []
|
|
195
|
+
// 取出所有非动态列
|
|
196
|
+
const newItem = {}
|
|
197
|
+
const keys = Object.keys(rowData)
|
|
198
|
+
keys.forEach((key) => {
|
|
199
|
+
if (!key.includes(GROUP_SEP)) {
|
|
200
|
+
newItem[key] = rowData[key]
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
leafColumns.forEach((column) => {
|
|
205
|
+
const cellData = {}
|
|
206
|
+
const columnKey: string = column[option.keyPropName || 'key']
|
|
207
|
+
|
|
208
|
+
if (columnKey.includes(GROUP_SEP)) {
|
|
209
|
+
// 动态列
|
|
210
|
+
const keys = columnKey.split(GROUP_SEP)
|
|
211
|
+
keys.forEach((key, idx) => {
|
|
212
|
+
if (key.includes(VALUE_SEP) && keys.length) {
|
|
213
|
+
// 这个分组是动态列的分组,且不是最后一层
|
|
214
|
+
const [keyProp, keyValue] = key.split(VALUE_SEP)
|
|
215
|
+
cellData[keyProp] = keyValue
|
|
216
|
+
} else if (keys.length !== idx + 1) {
|
|
217
|
+
console.error('columns有问题,请检查!')
|
|
218
|
+
} else {
|
|
219
|
+
// 如果结果集里有该分组对应的数据,在其中加上这个列对应的指标数据,如果没有,增加一条该分组的数据
|
|
220
|
+
const item = _.find(rlt, cellData)
|
|
221
|
+
if (!item) {
|
|
222
|
+
rlt.push({ ...newItem, ...cellData, [key]: rowData[columnKey] })
|
|
223
|
+
} else {
|
|
224
|
+
item[key] = rowData[columnKey]
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
return rlt
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 从行转列的数据转回行数据
|
|
236
|
+
*
|
|
237
|
+
* @param data 行转列后数据
|
|
238
|
+
* @param columns 行转列后的列定义
|
|
239
|
+
* @param option 一些参数
|
|
240
|
+
* @returns 行数据
|
|
241
|
+
*/
|
|
242
|
+
export function flattenRow2ColumnData(
|
|
243
|
+
data: Array<any> = [],
|
|
244
|
+
columns: Column[] = [],
|
|
245
|
+
option: row2columnOption = {},
|
|
246
|
+
): Array<any> {
|
|
247
|
+
const leafColumns = getLeafColumns(columns)
|
|
248
|
+
return data.reduce(
|
|
249
|
+
(rlt, rowData) => [...rlt, ...flattenRowData(rowData, leafColumns, option)],
|
|
250
|
+
[],
|
|
251
|
+
)
|
|
252
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getLocalStorage, getSessionStorage, setLocalStorage } from './storage'
|
|
2
|
+
|
|
3
|
+
const TOKEN_KEY = 'v8-token'
|
|
4
|
+
|
|
5
|
+
const TOKEN_KEY_IBP = 'lambo-token'
|
|
6
|
+
|
|
7
|
+
// 要从门户跳转过来,sessionStorage不能带token过来,改成localStorage
|
|
8
|
+
export function setToken(token: string) {
|
|
9
|
+
setLocalStorage(TOKEN_KEY, token)
|
|
10
|
+
Cookie.set('TOKEN_KEY', token, 1)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getToken(): string | boolean {
|
|
14
|
+
let token = getSessionStorage(TOKEN_KEY_IBP)
|
|
15
|
+
if (!token) {
|
|
16
|
+
token = Cookie.get('lambo-sso-key')
|
|
17
|
+
}
|
|
18
|
+
if (!token) {
|
|
19
|
+
token = Cookie.get('TOKEN_KEY')
|
|
20
|
+
}
|
|
21
|
+
if (!token) {
|
|
22
|
+
token = getLocalStorage(TOKEN_KEY)
|
|
23
|
+
}
|
|
24
|
+
return token || false
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const Cookie = {
|
|
28
|
+
set: function (key: string, value: string, exdays: number) {
|
|
29
|
+
//校验Key, key中不能有等号【=】
|
|
30
|
+
if (key.indexOf('=') !== -1) {
|
|
31
|
+
throw new Error('Cookie不支持key中使用等号【=】, key:' + key)
|
|
32
|
+
}
|
|
33
|
+
let exdate = new Date() // 获取时间
|
|
34
|
+
exdate.setTime(exdate.getTime() + 24 * 60 * 60 * 1000 * exdays) // 保存的天数
|
|
35
|
+
// 字符串拼接cookie
|
|
36
|
+
// eslint-disable-next-line camelcase
|
|
37
|
+
window.document.cookie = key + '=' + value + ';path=/;expires=' + exdate.toGMTString()
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
get: function (key: string) {
|
|
41
|
+
if (document.cookie.length > 0) {
|
|
42
|
+
// 这里显示的格式需要切割一下自己可输出看下
|
|
43
|
+
var arr = document.cookie.split('; ')
|
|
44
|
+
for (let i = 0; i < arr.length; i++) {
|
|
45
|
+
let arr2 = arr[i].split('=') // 再次切割
|
|
46
|
+
// 判断查找相对应的值
|
|
47
|
+
if (arr2[0] === key) {
|
|
48
|
+
var value = arr2[1]
|
|
49
|
+
for (let j = 2; j < arr2.length; j++) {
|
|
50
|
+
value += '=' + arr2[j]
|
|
51
|
+
}
|
|
52
|
+
return value
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
}
|