@lingxiteam/ebe-utils 0.0.25 → 0.0.29
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/es/constants.js +0 -1
- package/es/index.js +57 -38
- package/es/node/move.d.ts +1 -0
- package/es/node/move.js +7 -4
- package/es/requestQueue.d.ts +9 -0
- package/es/requestQueue.js +59 -0
- package/lib/h5public/src/components/common/PreviewFile/index.tsx +3 -7
- package/lib/h5public/src/components/factory/package.json +1 -1
- package/lib/h5public/src/components/factory/src/BlockSelect/components/CheckBox/index.tsx +14 -4
- package/lib/h5public/src/components/factory/src/BlockSelect/components/Icon/index.tsx +4 -4
- package/lib/h5public/src/components/factory/src/BlockSelect/index.tsx +13 -21
- package/lib/h5public/src/components/factory/src/Button/index.tsx +1 -0
- package/lib/h5public/src/components/factory/src/Card/index.less +11 -24
- package/lib/h5public/src/components/factory/src/Card/index.tsx +61 -22
- package/lib/h5public/src/components/factory/src/DGroup/index.less +7 -3
- package/lib/h5public/src/components/factory/src/DformFile/FormFile.tsx +17 -4
- package/lib/h5public/src/components/factory/src/DformFile/assets/closeIcon.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/default.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/fileName.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/img.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/js.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/pdf.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/ppt.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/txt.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/word.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/xls.png +0 -0
- package/lib/h5public/src/components/factory/src/DformFile/assets/zip.png +0 -0
- package/lib/h5public/src/components/factory/src/DynamicDataContainer/YieldMethod.ts +33 -0
- package/lib/h5public/src/components/factory/src/DynamicDataContainer/index.less +41 -5
- package/lib/h5public/src/components/factory/src/DynamicDataContainer/index.tsx +18 -3
- package/lib/h5public/src/components/factory/src/DynamicDataContainer/useDynamicDataContainer.ts +14 -1
- package/lib/h5public/src/components/factory/src/DynamicList/index.tsx +4 -2
- package/lib/h5public/src/components/factory/src/DynamicTable/Table.tsx +3 -1
- package/lib/h5public/src/components/factory/src/Image/BasicImage/index.tsx +36 -1
- package/lib/h5public/src/components/factory/src/StackColumn/loader.tsx +1 -1
- package/lib/h5public/src/components/factory/src/StaticTabs/index.tsx +1 -1
- package/lib/h5public/src/components/factory/src/VerificationCode/index.tsx +14 -3
- package/lib/h5public/src/components/factory/src/VideoPlayer/loader.ts +1 -1
- package/lib/h5public/src/components/factory/src/utils/CustomModule.tsx +3 -0
- package/lib/h5public/src/components/factory/src/utils/hooks/useFormItem.ts +3 -0
- package/lib/h5public/src/hooks/usePageForm.ts +29 -3
- package/lib/h5public/src/utils/native.ts +94 -0
- package/lib/h5public/yarn.lock +19383 -0
- package/lib/node/move.d.ts +1 -0
- package/lib/node/move.js +6 -3
- package/lib/pcpublic/src/components/common/PreviewFile/index.tsx +8 -0
- package/lib/pcpublic/src/components/common/PreviewFile/utils.ts +45 -0
- package/lib/pcpublic/src/components/pcfactory/package.json +1 -1
- package/lib/pcpublic/src/components/pcfactory/src/CollapsePanel/index.tsx +6 -4
- package/lib/pcpublic/src/components/pcfactory/src/DynamicDataContainer/YieldMethod.ts +33 -0
- package/lib/pcpublic/src/components/pcfactory/src/DynamicDataContainer/index.tsx +18 -3
- package/lib/pcpublic/src/components/pcfactory/src/DynamicDataContainer/useDynamicDataContainer.ts +14 -1
- package/lib/pcpublic/src/components/pcfactory/src/Img/index.tsx +34 -2
- package/lib/pcpublic/src/components/pcfactory/src/LoopList/index.tsx +9 -4
- package/lib/pcpublic/src/components/pcfactory/src/ModalSelect/BaseModalSelect.tsx +8 -1
- package/lib/pcpublic/src/components/pcfactory/src/StdUpload/index.tsx +39 -13
- package/lib/pcpublic/src/components/pcfactory/src/SuperSelect/ComSelect.tsx +22 -14
- package/lib/pcpublic/src/components/pcfactory/src/Table/FormatCell/index.tsx +12 -1
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useCMDActions.ts +54 -12
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useColumns.tsx +516 -485
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useCommon.ts +40 -2
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useDataSource.ts +3 -34
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useExpandable.tsx +1 -1
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/usePagination.ts +30 -3
- package/lib/pcpublic/src/components/pcfactory/src/Table/hooks/useRowEdit.ts +37 -13
- package/lib/pcpublic/src/components/pcfactory/src/Table/index.tsx +15 -4
- package/lib/pcpublic/src/components/pcfactory/src/Tabs/index.tsx +2 -0
- package/lib/pcpublic/src/components/pcfactory/src/Tag/index.tsx +2 -2
- package/lib/pcpublic/src/components/pcfactory/src/TreeTable/index.tsx +13 -2
- package/lib/pcpublic/src/components/pcfactory/src/styles/components/Card.less +1 -1
- package/lib/pcpublic/src/components/pcfactory/src/styles/components/FormGroup.less +8 -4
- package/lib/pcpublic/src/components/pcfactory/src/styles/components/Icon.less +4 -0
- package/lib/pcpublic/src/components/pcfactory/src/styles/components/StdUpload.less +3 -3
- package/lib/pcpublic/src/components/pcfactory/src/utils/CustomModule.tsx +3 -0
- package/lib/pcpublic/src/components/pcfactory/src/utils/common.ts +15 -0
- package/lib/pcpublic/src/hooks/usePageForm.ts +4 -3
- package/lib/pcpublic/src/utils/exportCustomData/index.tsx +723 -0
- package/lib/pcpublic/src/utils/exportCustomData/tool.ts +399 -0
- package/lib/pcpublic/src/utils/messageApi.ts +25 -20
- package/lib/pcpublic/yarn.lock +11441 -0
- package/lib/public/src/components/ProgressComp/index.tsx +4 -14
- package/lib/public/src/hooks/useBaseDataSource.ts +2 -1
- package/lib/public/src/hooks/useExportCustomDataFile.ts +4 -0
- package/lib/public/src/services/api/engine.ts +19 -0
- package/lib/public/src/services/api/index.ts +12 -0
- package/lib/public/src/utils/Context/context.tsx +1 -0
- package/lib/public/src/utils/cmd.ts +455 -0
- package/lib/public/src/utils/historytool.ts +3 -0
- package/lib/public/src/utils/lcdpBaseApi.ts +2 -2
- package/lib/public/src/utils/platform/utils/fileUtils.ts +12 -11
- package/lib/public/src/utils/polyfills.ts +4 -0
- package/lib/public/src/utils/popoverUtils.ts +56 -0
- package/lib/public/src/utils/service/baseRequest.ts +8 -8
- package/lib/public/src/utils/service/urlHelper.ts +2 -0
- package/lib/public/src/utils/useComponentHoc.ts +6 -3
- package/package.json +2 -2
|
@@ -0,0 +1,723 @@
|
|
|
1
|
+
import engineServices from '@/services/api/engine';
|
|
2
|
+
import { messageApi } from '@/utils/messageApi';
|
|
3
|
+
import { exportFileShowProgress } from './tool';
|
|
4
|
+
|
|
5
|
+
const SERVICE_SOURCE = {
|
|
6
|
+
// 服务来源
|
|
7
|
+
APP: 'app',
|
|
8
|
+
// 应用内部 & 模型生成
|
|
9
|
+
QUERY: 'query',
|
|
10
|
+
// 解析服务
|
|
11
|
+
STD: 'std',
|
|
12
|
+
// 编排服务
|
|
13
|
+
INNER: 'inner',
|
|
14
|
+
// 高代码服务
|
|
15
|
+
PLATFORM: 'platform',
|
|
16
|
+
// 平台服务
|
|
17
|
+
ATOM: 'atom',
|
|
18
|
+
// 外部服务(低代码运营平台的原子服务)
|
|
19
|
+
RHIN: 'rhin',
|
|
20
|
+
// 业务运营服务
|
|
21
|
+
SCENE: 'scene',
|
|
22
|
+
// 业务运营场景服务
|
|
23
|
+
OBJECT: 'object', // 业务对象生成服务
|
|
24
|
+
};
|
|
25
|
+
const SERVICE_CUSTOM_EXPORT_TYPE: any = {
|
|
26
|
+
query: 'customQuery', // 解析服务
|
|
27
|
+
std: 'orchestrationService', // 编排服务
|
|
28
|
+
rhin: 'externalQuery', // 外部服务(低代码运营平台的原子服务)
|
|
29
|
+
object: 'objectService', // 业务对象生成服务
|
|
30
|
+
inner: 'internalService', // 高代码服务
|
|
31
|
+
platform: 'platformService', // 平台服务
|
|
32
|
+
};
|
|
33
|
+
// 表头分组的处理保持与表格组件一致
|
|
34
|
+
const treeRootName = 'tree-root';
|
|
35
|
+
interface ExportItem {
|
|
36
|
+
// 服务类型
|
|
37
|
+
source: any;
|
|
38
|
+
// 导出字段列表
|
|
39
|
+
objectFields: string[];
|
|
40
|
+
// 配置态记录的导出字段的标题映射即excel表头的名称,
|
|
41
|
+
// 部分服务如:外部和内部,运行态不进行字段查询,无法获取到字段标题
|
|
42
|
+
nameMap: Record<string, string>;
|
|
43
|
+
// 导出字段的父节点字段,不以根节点root开头
|
|
44
|
+
parentCode?: string;
|
|
45
|
+
// 表头分组
|
|
46
|
+
customGroup: any[];
|
|
47
|
+
// 导出时入参
|
|
48
|
+
apiRequestSetParams?: any[];
|
|
49
|
+
exportType?: 'custom' | 'field' | 'temp';
|
|
50
|
+
objectFieldsCustom?: {
|
|
51
|
+
attrName: string;
|
|
52
|
+
attrCode: string;
|
|
53
|
+
fieldData: any[];
|
|
54
|
+
// 动态列导出字段对应的父节点,以根节点root开头
|
|
55
|
+
exportNode?: string;
|
|
56
|
+
[key: string]: any;
|
|
57
|
+
};
|
|
58
|
+
// 导出模板参数
|
|
59
|
+
objectFieldsTemp?: {
|
|
60
|
+
fileCode: string;
|
|
61
|
+
maxRowSize: number;
|
|
62
|
+
rows: any[];
|
|
63
|
+
};
|
|
64
|
+
// 是否是模板导出,由 exportType与objectFieldsTemp决定
|
|
65
|
+
isTemp?: boolean;
|
|
66
|
+
// 服务信息
|
|
67
|
+
serviceData?: any;
|
|
68
|
+
// 导出excel的子表表名
|
|
69
|
+
custSheetName?: string;
|
|
70
|
+
id: string;
|
|
71
|
+
// 是否是动态导出,由 exportType与objectFieldsCustom决定
|
|
72
|
+
isCustom?: boolean;
|
|
73
|
+
// 由apiRequestSetParams转化而来
|
|
74
|
+
parameters: any;
|
|
75
|
+
// 由serviceData中获取对应的服务id
|
|
76
|
+
objValue: string;
|
|
77
|
+
// 导出服务入参中的服务类型
|
|
78
|
+
objType: typeof SERVICE_CUSTOM_EXPORT_TYPE;
|
|
79
|
+
}
|
|
80
|
+
// 获取分组名称,为空的向下补全
|
|
81
|
+
const findGroupName = (groupList: string[], startIndex: number) => {
|
|
82
|
+
const list = groupList.slice(startIndex);
|
|
83
|
+
return list.find((g) => !!g) || '';
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleMergeHeader = <
|
|
87
|
+
T extends {
|
|
88
|
+
title?: string;
|
|
89
|
+
colSpanStart?: any;
|
|
90
|
+
colSpan?: number;
|
|
91
|
+
children?: T[];
|
|
92
|
+
isHidden?: boolean;
|
|
93
|
+
},
|
|
94
|
+
>(
|
|
95
|
+
columns?: Array<T>,
|
|
96
|
+
) => {
|
|
97
|
+
const getRowSpan = (col: T) => {
|
|
98
|
+
let span = 1;
|
|
99
|
+
const newCol = { ...col };
|
|
100
|
+
let current: T | null = newCol;
|
|
101
|
+
while (current !== null) {
|
|
102
|
+
if (current?.children?.length === 1) {
|
|
103
|
+
const next: T = current.children?.[0];
|
|
104
|
+
if (
|
|
105
|
+
next.title === col?.title &&
|
|
106
|
+
col?.title &&
|
|
107
|
+
!next.isHidden &&
|
|
108
|
+
(col?.colSpan || 1) === (next?.colSpan || 1)
|
|
109
|
+
) {
|
|
110
|
+
// 分组名一致,上下合并
|
|
111
|
+
span += 1;
|
|
112
|
+
next.isHidden = true;
|
|
113
|
+
current = next;
|
|
114
|
+
} else {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
...newCol,
|
|
123
|
+
rowSpan: span,
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
const recursive = (cols: T[]) => {
|
|
127
|
+
return cols.map((col) => {
|
|
128
|
+
const newCol = {
|
|
129
|
+
...col,
|
|
130
|
+
// 禁止分组向下合并(T:禁止向下合并;默认不传值就正常合并)
|
|
131
|
+
forbiddenMergeDown: 'T',
|
|
132
|
+
};
|
|
133
|
+
if (newCol?.title) {
|
|
134
|
+
const { rowSpan } = getRowSpan(newCol);
|
|
135
|
+
if (rowSpan > 1) {
|
|
136
|
+
return {
|
|
137
|
+
...newCol,
|
|
138
|
+
isHidden: undefined,
|
|
139
|
+
colSpanStart: undefined,
|
|
140
|
+
colSpan: undefined,
|
|
141
|
+
forbiddenMergeDown: undefined,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (newCol.children) {
|
|
146
|
+
newCol.children = recursive(newCol.children);
|
|
147
|
+
}
|
|
148
|
+
delete newCol.colSpan;
|
|
149
|
+
delete newCol.isHidden;
|
|
150
|
+
delete newCol.colSpanStart;
|
|
151
|
+
return newCol;
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
return recursive(columns || []);
|
|
155
|
+
};
|
|
156
|
+
const appendColumnLevel = (columnParams: any) => {
|
|
157
|
+
const { maxLen, lastLevel, column } = columnParams || {};
|
|
158
|
+
const times = new Array(maxLen - lastLevel).fill('0');
|
|
159
|
+
const newColumn = { ...column };
|
|
160
|
+
// times.reduce(p => {
|
|
161
|
+
// p.isRowSpan = 'T';
|
|
162
|
+
// const col = { ...column, isRowSpan: 'T' };
|
|
163
|
+
// // 非最后的导出列部分需要去掉key和index数据
|
|
164
|
+
// delete p.key;
|
|
165
|
+
// delete p.index;
|
|
166
|
+
// p.children = [col];
|
|
167
|
+
// return p.children[0];
|
|
168
|
+
// }, newColumn);
|
|
169
|
+
let cur = newColumn;
|
|
170
|
+
times.forEach(() => {
|
|
171
|
+
const col = { ...column };
|
|
172
|
+
// 非最后的导出列部分需要去掉key和index数据
|
|
173
|
+
delete cur.key;
|
|
174
|
+
delete cur.index;
|
|
175
|
+
cur.children = [col];
|
|
176
|
+
cur = cur.children[0];
|
|
177
|
+
});
|
|
178
|
+
return newColumn;
|
|
179
|
+
};
|
|
180
|
+
const filterSimpleType = (arr: any[], parCode = '') => {
|
|
181
|
+
let l = arr.filter(
|
|
182
|
+
(i) => !['object', 'array', 'objectArray'].includes(i.attrType),
|
|
183
|
+
);
|
|
184
|
+
if (parCode) {
|
|
185
|
+
// 编排服务导出字段的中文名,优先取描述,没有描述时再取编码
|
|
186
|
+
l = l.map((c) => ({ ...c, parentCode: parCode, name: c.name || c.code }));
|
|
187
|
+
}
|
|
188
|
+
return l;
|
|
189
|
+
};
|
|
190
|
+
const generateArrayNode = (attrs: any[], parentCode?: string) => {
|
|
191
|
+
let resList: any[] = [];
|
|
192
|
+
const attrParMap: any = {};
|
|
193
|
+
if (Array.isArray(attrs)) {
|
|
194
|
+
attrs.forEach((attr) => {
|
|
195
|
+
const code = parentCode ? `${parentCode}.${attr.code}` : attr.code;
|
|
196
|
+
attrParMap[code] = attr;
|
|
197
|
+
if (attr.children?.length) {
|
|
198
|
+
if (['array', 'objectArray'].includes(attr.attrType)) {
|
|
199
|
+
// 如果array类型的子元素是对象,则视为对象数组,取出对象的字段
|
|
200
|
+
const children =
|
|
201
|
+
attr.attrType === 'array' && attr.children[0]?.attrType === 'object'
|
|
202
|
+
? attr.children[0]?.children
|
|
203
|
+
: attr.children;
|
|
204
|
+
resList = resList.concat(filterSimpleType(children, code) || []);
|
|
205
|
+
} else if (attr.attrType === 'object') {
|
|
206
|
+
const [res, attrMap] = generateArrayNode(attr.children, code) || [];
|
|
207
|
+
resList = resList.concat(res);
|
|
208
|
+
Object.assign(attrParMap, attrMap);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return [resList, attrParMap];
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const handleMultiLevelHeader = (params: any) => {
|
|
217
|
+
const { column, leftTree, parentTreeNode, maxGroupLen } = params;
|
|
218
|
+
const { group } = params;
|
|
219
|
+
const groupLen = group.length;
|
|
220
|
+
if (Array.isArray(group) && groupLen > 0) {
|
|
221
|
+
// 标记右树从哪个节点开始至最后一个都为空(undefined/null/'')
|
|
222
|
+
let groupEmptyStartIndex = groupLen - 1;
|
|
223
|
+
while (
|
|
224
|
+
typeof group[groupEmptyStartIndex] === 'undefined' ||
|
|
225
|
+
group[groupEmptyStartIndex] === null ||
|
|
226
|
+
group[groupEmptyStartIndex] === ''
|
|
227
|
+
) {
|
|
228
|
+
// 当分组数据遍历完成 或 下一个已经不为空时,退出循环
|
|
229
|
+
if (groupEmptyStartIndex - 1 < 0 || group[groupEmptyStartIndex - 1]) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
// eslint-disable-next-line no-plusplus
|
|
233
|
+
groupEmptyStartIndex--;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 构造右树(记录左树每一层的最后一个节点):
|
|
237
|
+
let rightLevel = 1;
|
|
238
|
+
const rightTree = {
|
|
239
|
+
title: treeRootName,
|
|
240
|
+
};
|
|
241
|
+
const rightTreeLevelMap: any = {
|
|
242
|
+
0: rightTree,
|
|
243
|
+
};
|
|
244
|
+
let tempRightTree: any = rightTree;
|
|
245
|
+
// 从第一层开始,最后一层会接入列信息
|
|
246
|
+
while (rightLevel <= groupLen) {
|
|
247
|
+
// 从当前层到最后一层都为空时:直接接入列信息,并退出循环
|
|
248
|
+
if (
|
|
249
|
+
rightLevel === groupEmptyStartIndex + 1 &&
|
|
250
|
+
!group[groupEmptyStartIndex]
|
|
251
|
+
) {
|
|
252
|
+
let col = column;
|
|
253
|
+
// 当最后一级时,为了拉平与其他分组的层级,需要补全列数据节点的层级
|
|
254
|
+
if (rightLevel < maxGroupLen) {
|
|
255
|
+
col = appendColumnLevel({
|
|
256
|
+
maxLen: maxGroupLen,
|
|
257
|
+
column,
|
|
258
|
+
lastLevel: rightLevel,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
// 将列数据放入最后一层分组最后一个节点的children,即再加最后一层
|
|
262
|
+
tempRightTree.children = [col];
|
|
263
|
+
// 记录最最后一层
|
|
264
|
+
rightTreeLevelMap[rightLevel] = col;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const rightTreeCurrLevelLast: any = {
|
|
269
|
+
title: findGroupName(group, rightLevel - 1), // 为空的话,强制设置为 ''
|
|
270
|
+
// parent: tempRightTree.title === treeRootName ? leftTree : tempRightTree,
|
|
271
|
+
};
|
|
272
|
+
// 当前层为第一层时,将parent指向左树的根节点,为后续合并做准备
|
|
273
|
+
parentTreeNode.set(
|
|
274
|
+
rightTreeCurrLevelLast,
|
|
275
|
+
tempRightTree.title === treeRootName ? leftTree : tempRightTree,
|
|
276
|
+
);
|
|
277
|
+
tempRightTree.children = [rightTreeCurrLevelLast];
|
|
278
|
+
tempRightTree = rightTreeCurrLevelLast;
|
|
279
|
+
rightTreeLevelMap[rightLevel] = rightTreeCurrLevelLast;
|
|
280
|
+
// eslint-disable-next-line no-plusplus
|
|
281
|
+
rightLevel++;
|
|
282
|
+
|
|
283
|
+
// 构造到最后一层分组时:接入列信息,并退出循环
|
|
284
|
+
if (rightLevel > groupLen) {
|
|
285
|
+
let col = column;
|
|
286
|
+
// 当最后一级时,为了拉平与其他分组的层级,需要补全列数据节点的层级
|
|
287
|
+
if (rightLevel < maxGroupLen) {
|
|
288
|
+
col = appendColumnLevel({
|
|
289
|
+
maxLen: maxGroupLen,
|
|
290
|
+
column,
|
|
291
|
+
lastLevel: rightLevel,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
// 将列数据放入最后一层分组最后一个节点的children,即再加最后一层
|
|
295
|
+
rightTreeCurrLevelLast.children = [col];
|
|
296
|
+
// 记录最最后一层
|
|
297
|
+
rightTreeLevelMap[rightLevel] = col;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 分析左树(记录左树每一层的最后一个节点):
|
|
303
|
+
let leftLevel = 0;
|
|
304
|
+
const leftTreeLevelMap = {
|
|
305
|
+
[leftLevel]: leftTree,
|
|
306
|
+
};
|
|
307
|
+
let leftTreeCurrLevelLast = leftTree;
|
|
308
|
+
// 遍历左树右边侧节点(生成数据结构记录节点情况):
|
|
309
|
+
while (leftTreeCurrLevelLast?.children) {
|
|
310
|
+
// eslint-disable-next-line no-plusplus
|
|
311
|
+
leftLevel++;
|
|
312
|
+
const leftTreeCurrLevelLastChildren = leftTreeCurrLevelLast.children;
|
|
313
|
+
// 取左树当前层的最后一个
|
|
314
|
+
leftTreeCurrLevelLast =
|
|
315
|
+
leftTreeCurrLevelLastChildren[leftTreeCurrLevelLastChildren.length - 1];
|
|
316
|
+
leftTreeLevelMap[leftLevel] = leftTreeCurrLevelLast;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
for (let i = 0; i <= groupLen; i += 1) {
|
|
320
|
+
const leftTreeLast = leftTreeLevelMap[i]; // 左树第i层的最后一个
|
|
321
|
+
const current = rightTreeLevelMap[i]; // 右树第 i 层的最后一个(唯一一个)
|
|
322
|
+
if (i === 0) {
|
|
323
|
+
if (!leftTreeLast.children) {
|
|
324
|
+
leftTreeLast.children = [];
|
|
325
|
+
}
|
|
326
|
+
leftTreeLast.children.push(...(current?.children || []));
|
|
327
|
+
} else if (current && current?.title === leftTreeLast?.title) {
|
|
328
|
+
current.colSpanStart = leftTreeLast?.colSpanStart || leftTreeLast;
|
|
329
|
+
const colSpan = current?.colSpanStart?.colSpan || 1;
|
|
330
|
+
current.colSpanStart.colSpan = colSpan + 1;
|
|
331
|
+
// 被合并的单元格隐藏
|
|
332
|
+
current.isHidden = true;
|
|
333
|
+
}
|
|
334
|
+
if (current) {
|
|
335
|
+
current.colSpan = 1;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const handleParseGroups = (params: any) => {
|
|
342
|
+
const { list, groupMap, nameMap } = params;
|
|
343
|
+
const keys = Object.keys(groupMap || {});
|
|
344
|
+
if (!groupMap || !keys?.length) {
|
|
345
|
+
// 分组为空时,不处理
|
|
346
|
+
return undefined;
|
|
347
|
+
}
|
|
348
|
+
const finalGroup: any = {};
|
|
349
|
+
// 实际层级数,包含列数据级
|
|
350
|
+
let maxGroupLevel = 1;
|
|
351
|
+
keys.forEach((k) => {
|
|
352
|
+
let group = groupMap[k];
|
|
353
|
+
// 兼容旧版的分组数据
|
|
354
|
+
if (typeof group === 'string') {
|
|
355
|
+
group = [group];
|
|
356
|
+
}
|
|
357
|
+
// 兼容可能存在的空数据
|
|
358
|
+
if (group === '' || group === null || group === undefined) {
|
|
359
|
+
group = [''];
|
|
360
|
+
}
|
|
361
|
+
// 过滤掉空的配置
|
|
362
|
+
// group = group.filter((g: any) => g);
|
|
363
|
+
// 保留一个空配置,以进入构造
|
|
364
|
+
group = group.length === 0 ? [''] : group;
|
|
365
|
+
maxGroupLevel = Math.max(maxGroupLevel, group.length + 1);
|
|
366
|
+
finalGroup[k] = group;
|
|
367
|
+
});
|
|
368
|
+
// 用于表格头分组的数据结构:左树根节点,为第0层
|
|
369
|
+
const leftTree: any = {
|
|
370
|
+
title: treeRootName,
|
|
371
|
+
};
|
|
372
|
+
// 记录子级对应的父级
|
|
373
|
+
const parentTreeNode = new WeakMap();
|
|
374
|
+
list.forEach((col: any, i: number) => {
|
|
375
|
+
const group = finalGroup[col];
|
|
376
|
+
handleMultiLevelHeader({
|
|
377
|
+
leftTree,
|
|
378
|
+
column: { title: nameMap[col], key: col, index: col?.sort || i },
|
|
379
|
+
group,
|
|
380
|
+
parentTreeNode,
|
|
381
|
+
maxGroupLen: maxGroupLevel,
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
if (leftTree?.children?.length) {
|
|
385
|
+
return handleMergeHeader([...leftTree?.children]);
|
|
386
|
+
}
|
|
387
|
+
// 为空时不传出分组字段
|
|
388
|
+
return undefined;
|
|
389
|
+
};
|
|
390
|
+
const getResponseAttr = (response: {
|
|
391
|
+
code: string;
|
|
392
|
+
attrType: string;
|
|
393
|
+
children: any[];
|
|
394
|
+
}) => {
|
|
395
|
+
let list: any[] = [];
|
|
396
|
+
const attrParMap: any = {};
|
|
397
|
+
const responseType = response.code === 'root' ? response.attrType : 'object';
|
|
398
|
+
if (response.code === 'root') {
|
|
399
|
+
attrParMap.root = response;
|
|
400
|
+
}
|
|
401
|
+
const responseAttrs = response.children;
|
|
402
|
+
if (responseType === 'object') {
|
|
403
|
+
const [res, attrMap] = generateArrayNode(responseAttrs, '');
|
|
404
|
+
list = list.concat(res);
|
|
405
|
+
Object.assign(attrParMap, attrMap);
|
|
406
|
+
} else if (['objectArray', 'array'].includes(responseType)) {
|
|
407
|
+
const children =
|
|
408
|
+
response.attrType === 'array' &&
|
|
409
|
+
response.children[0]?.attrType === 'object'
|
|
410
|
+
? response.children[0]?.children
|
|
411
|
+
: responseAttrs;
|
|
412
|
+
list = filterSimpleType(children, '');
|
|
413
|
+
}
|
|
414
|
+
return { list, attrParMap };
|
|
415
|
+
};
|
|
416
|
+
// 根据配置态勾选的导出项,进行导出参数的组装
|
|
417
|
+
const getExportColumns = (
|
|
418
|
+
item: ExportItem,
|
|
419
|
+
resultList: any,
|
|
420
|
+
): Record<string, any> => {
|
|
421
|
+
const {
|
|
422
|
+
source,
|
|
423
|
+
objectFields,
|
|
424
|
+
nameMap,
|
|
425
|
+
parentCode,
|
|
426
|
+
isCustom,
|
|
427
|
+
isTemp,
|
|
428
|
+
objectFieldsTemp,
|
|
429
|
+
customGroup,
|
|
430
|
+
} = item;
|
|
431
|
+
let columns: Record<string, any> = {};
|
|
432
|
+
// 记录最新的字段和名称映射,分组表头组装时需要
|
|
433
|
+
const colNameMap = { ...nameMap };
|
|
434
|
+
switch (source) {
|
|
435
|
+
case SERVICE_SOURCE.OBJECT: {
|
|
436
|
+
const cols: any[] = [];
|
|
437
|
+
resultList.forEach((item: any) => {
|
|
438
|
+
const data = { ...item };
|
|
439
|
+
objectFields.forEach((field: any, index: any) => {
|
|
440
|
+
if (field === data.attrCode) {
|
|
441
|
+
colNameMap[data.attrCode] = data.attrName || data.attrCode;
|
|
442
|
+
if (isCustom) {
|
|
443
|
+
// 动态列导出的时候以动态列配置的字段名称解析结果为准
|
|
444
|
+
data.attrName = nameMap[data.attrCode] || data.attrName;
|
|
445
|
+
}
|
|
446
|
+
data.sort = index;
|
|
447
|
+
cols.push(data);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
columns.pickRows = cols;
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
case SERVICE_SOURCE.STD: {
|
|
455
|
+
const { list, attrParMap } = resultList;
|
|
456
|
+
let parent: any;
|
|
457
|
+
let parentChildren: any[] = [];
|
|
458
|
+
const listMap: any = {};
|
|
459
|
+
list.forEach((item: any) => {
|
|
460
|
+
const code = item.parentCode
|
|
461
|
+
? `${item.parentCode}.${item.code}`
|
|
462
|
+
: item.code;
|
|
463
|
+
listMap[code] = item;
|
|
464
|
+
});
|
|
465
|
+
// 编排类服务需要前端排序
|
|
466
|
+
objectFields.forEach((field: string | number, index: any) => {
|
|
467
|
+
if (listMap[field]) {
|
|
468
|
+
const data = { ...listMap[field] };
|
|
469
|
+
if (!parent) {
|
|
470
|
+
parent = attrParMap[data.parentCode];
|
|
471
|
+
parent.children = [];
|
|
472
|
+
parentChildren = parent.children;
|
|
473
|
+
const parentList = data.parentCode.split('.');
|
|
474
|
+
if (parentList?.length) {
|
|
475
|
+
parentList.pop();
|
|
476
|
+
// 找到所有根节点,支持多层级对象下的数组节点的导出
|
|
477
|
+
parent = parentList.reduce((p: any, _: any, i: number) => {
|
|
478
|
+
const code = parentList
|
|
479
|
+
.slice(0, parentList?.length - i)
|
|
480
|
+
.join('.');
|
|
481
|
+
const attr = attrParMap[code];
|
|
482
|
+
const newParent = {
|
|
483
|
+
...attr,
|
|
484
|
+
children: [p],
|
|
485
|
+
};
|
|
486
|
+
return newParent;
|
|
487
|
+
}, parent);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
colNameMap[data.code] = data.name || data.code;
|
|
491
|
+
if (isCustom) {
|
|
492
|
+
// 动态列导出的时候以动态列配置的字段名称解析结果为准
|
|
493
|
+
data.name = nameMap[field];
|
|
494
|
+
}
|
|
495
|
+
data.sort = index;
|
|
496
|
+
parentChildren.push(data);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
columns.pickColumns = parent ? [parent] : [];
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
case SERVICE_SOURCE.RHIN:
|
|
503
|
+
case SERVICE_SOURCE.INNER:
|
|
504
|
+
case SERVICE_SOURCE.PLATFORM: {
|
|
505
|
+
// 外部集成类由于无法在运行态调用接口获取字段参数,只能在配置态记录对应字段名称
|
|
506
|
+
let cols: any[] = [];
|
|
507
|
+
const list: any[] = [];
|
|
508
|
+
objectFields.forEach((c: string, index: any) => {
|
|
509
|
+
const fields = c?.split('.');
|
|
510
|
+
list.push({
|
|
511
|
+
code: fields?.length > 1 ? fields[fields.length - 1] : c,
|
|
512
|
+
name: nameMap[c],
|
|
513
|
+
sort: index,
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
// 高代码服务和平台服务的字段使用配置时记录的名称映射
|
|
517
|
+
if (
|
|
518
|
+
parentCode ||
|
|
519
|
+
source === SERVICE_SOURCE.INNER ||
|
|
520
|
+
source === SERVICE_SOURCE.PLATFORM
|
|
521
|
+
) {
|
|
522
|
+
const exportNode = (parentCode || '').split('.');
|
|
523
|
+
cols = exportNode.reverse().reduce((p: any, n: any, i: number) => {
|
|
524
|
+
const code = exportNode.slice(1, exportNode?.length - i).join('.');
|
|
525
|
+
if (i === 0) {
|
|
526
|
+
return [
|
|
527
|
+
{
|
|
528
|
+
code: n,
|
|
529
|
+
attrType: 'objectArray',
|
|
530
|
+
name: nameMap[code],
|
|
531
|
+
children: p,
|
|
532
|
+
},
|
|
533
|
+
];
|
|
534
|
+
}
|
|
535
|
+
return [
|
|
536
|
+
{
|
|
537
|
+
code: n,
|
|
538
|
+
attrType: 'object',
|
|
539
|
+
name: nameMap[code] || n,
|
|
540
|
+
children: p,
|
|
541
|
+
},
|
|
542
|
+
];
|
|
543
|
+
}, list);
|
|
544
|
+
} else {
|
|
545
|
+
cols = list;
|
|
546
|
+
}
|
|
547
|
+
if (parentCode) {
|
|
548
|
+
Object.keys(colNameMap).forEach((col) => {
|
|
549
|
+
if (col.includes(parentCode)) {
|
|
550
|
+
const key: string = col.split('.').pop() || '';
|
|
551
|
+
colNameMap[key] = colNameMap[col];
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
columns.pickColumns = cols;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
// SQL查询类服务
|
|
559
|
+
default: {
|
|
560
|
+
const fields = objectFields.map((c: any) => {
|
|
561
|
+
const code = c?.split('.') || [];
|
|
562
|
+
if (code?.length > 1) {
|
|
563
|
+
return code.pop();
|
|
564
|
+
}
|
|
565
|
+
return c;
|
|
566
|
+
});
|
|
567
|
+
const cols: any[] = [];
|
|
568
|
+
resultList.forEach((item: any) => {
|
|
569
|
+
const data = { ...item };
|
|
570
|
+
fields.forEach((field: any, index: any) => {
|
|
571
|
+
if (field === data.code) {
|
|
572
|
+
if (isCustom) {
|
|
573
|
+
// 动态列导出的时候以动态列配置的字段名称解析结果为准
|
|
574
|
+
data.name = nameMap[data.code] || data.name;
|
|
575
|
+
}
|
|
576
|
+
data.sort = index;
|
|
577
|
+
cols.push(data);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
columns.pickColumns = cols;
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (!isCustom && customGroup && Object.keys(customGroup)?.length > 0) {
|
|
586
|
+
// 多级出参中会记录父节点,获取分组时需要去掉父节点部分,只保留数据编码
|
|
587
|
+
let list: any[] = objectFields;
|
|
588
|
+
if (parentCode) {
|
|
589
|
+
list = list.map((col) => {
|
|
590
|
+
const code = col?.split('.');
|
|
591
|
+
if (code?.length > 1) {
|
|
592
|
+
return code.pop();
|
|
593
|
+
}
|
|
594
|
+
return code;
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
// 配置了表头分组规则的,进行头部分组组装
|
|
598
|
+
columns.groups = handleParseGroups({
|
|
599
|
+
list,
|
|
600
|
+
groupMap: customGroup,
|
|
601
|
+
nameMap: colNameMap,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
if (isTemp && objectFieldsTemp && Object.keys(objectFieldsTemp)?.length > 0) {
|
|
605
|
+
columns = {
|
|
606
|
+
...columns,
|
|
607
|
+
...objectFieldsTemp,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
return columns;
|
|
611
|
+
};
|
|
612
|
+
type ExportPathMapType = Record<'sql' | 'object' | 'multiExport', string>;
|
|
613
|
+
const exportPathMap: ExportPathMapType = {
|
|
614
|
+
sql: engineServices.exportSqlDatasApiPath(),
|
|
615
|
+
object: engineServices.exportInstsApiPath(),
|
|
616
|
+
multiExport: engineServices.exportMultiServiceResultPath(),
|
|
617
|
+
};
|
|
618
|
+
const exportCustomData = (
|
|
619
|
+
exportSheet: any = [],
|
|
620
|
+
custFileName: any,
|
|
621
|
+
selectedKeyMap: { [x: string]: any },
|
|
622
|
+
async: string,
|
|
623
|
+
) => {
|
|
624
|
+
// 获取到的服务出参列表
|
|
625
|
+
const selectedRowMap: any = {};
|
|
626
|
+
messageApi.loading('正在导出中,请稍候...', 0);
|
|
627
|
+
try {
|
|
628
|
+
const columnsReq = Object.keys(selectedKeyMap).map((type) => {
|
|
629
|
+
if (!selectedKeyMap[type] || !selectedKeyMap[type]?.length) {
|
|
630
|
+
return undefined;
|
|
631
|
+
}
|
|
632
|
+
// 获取不同类型服务的出参列表
|
|
633
|
+
let req;
|
|
634
|
+
if (type === SERVICE_SOURCE.QUERY) {
|
|
635
|
+
// SQL类型
|
|
636
|
+
req = engineServices
|
|
637
|
+
.getSqlQueryColumnsList({
|
|
638
|
+
serviceCodes: selectedKeyMap[type].join(','),
|
|
639
|
+
})
|
|
640
|
+
.then((res: any) => {
|
|
641
|
+
const m: any = {};
|
|
642
|
+
(res || []).forEach((c: any) => (m[c.serviceCode] = c.rowColumns));
|
|
643
|
+
return m;
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
if (type === SERVICE_SOURCE.OBJECT) {
|
|
647
|
+
// 对象类型
|
|
648
|
+
req = engineServices
|
|
649
|
+
.queryBusiObjectRowColumnsList({
|
|
650
|
+
busiObjectIds: selectedKeyMap[type].join(','),
|
|
651
|
+
})
|
|
652
|
+
.then((res: any) => {
|
|
653
|
+
const m: any = {};
|
|
654
|
+
(res || []).forEach((c: any) => (m[c.busiObjectId] = c.rowColumns));
|
|
655
|
+
return m;
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
if (type === SERVICE_SOURCE.STD) {
|
|
659
|
+
// 编排类服务
|
|
660
|
+
// @ts-ignore
|
|
661
|
+
req = engineServices
|
|
662
|
+
.queryServiceResponseColumnsList({
|
|
663
|
+
serviceVersionIds: (selectedKeyMap[type] || []).join(','),
|
|
664
|
+
appId: APPID,
|
|
665
|
+
})
|
|
666
|
+
.then((res: any) => {
|
|
667
|
+
const m: any = {};
|
|
668
|
+
(res || []).forEach(
|
|
669
|
+
(c: any) => (m[c.serviceVersionId] = getResponseAttr(c.response)),
|
|
670
|
+
);
|
|
671
|
+
return m;
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
if (req) {
|
|
675
|
+
req?.then((r: any) => {
|
|
676
|
+
selectedRowMap[type] = r;
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
return req;
|
|
680
|
+
});
|
|
681
|
+
Promise.all(columnsReq).then(async () => {
|
|
682
|
+
const sheetItemList = exportSheet;
|
|
683
|
+
const serviceExecuteParams = sheetItemList.map((sheet: ExportItem) => {
|
|
684
|
+
const { parameters, objValue, objType, custSheetName, source } = sheet;
|
|
685
|
+
const resultList = (selectedRowMap[source] || {})[objValue] || [];
|
|
686
|
+
const columns = getExportColumns(sheet, resultList);
|
|
687
|
+
return {
|
|
688
|
+
objValue,
|
|
689
|
+
objType,
|
|
690
|
+
parameters,
|
|
691
|
+
sheetName: custSheetName,
|
|
692
|
+
...columns,
|
|
693
|
+
};
|
|
694
|
+
});
|
|
695
|
+
const exportFileName = custFileName;
|
|
696
|
+
const fileName = `${exportFileName}.xlsx`;
|
|
697
|
+
const downloadIndex = `${fileName}_${Math.random()}`;
|
|
698
|
+
await exportFileShowProgress?.({
|
|
699
|
+
downloadIndex,
|
|
700
|
+
fileName,
|
|
701
|
+
methodType: 'POST',
|
|
702
|
+
fileOrigin: 'multiExport',
|
|
703
|
+
async,
|
|
704
|
+
params: {
|
|
705
|
+
serviceExecuteParams,
|
|
706
|
+
fileName,
|
|
707
|
+
},
|
|
708
|
+
onSuccess: () => {
|
|
709
|
+
messageApi.destroy();
|
|
710
|
+
},
|
|
711
|
+
onFail: () => {
|
|
712
|
+
messageApi.destroy();
|
|
713
|
+
messageApi.error('导出失败');
|
|
714
|
+
},
|
|
715
|
+
});
|
|
716
|
+
});
|
|
717
|
+
} catch {
|
|
718
|
+
messageApi.destroy();
|
|
719
|
+
messageApi.error('导出失败');
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
export default exportCustomData;
|