neo-cmp-cli 1.13.17 → 1.13.18
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/dist/index2.js +1 -1
- package/dist/neo/env.js +1 -1
- package/dist/neo/pushCmp.js +1 -1
- package/dist/package.json.js +1 -1
- package/package.json +3 -2
- package/template/asset-manage-template/docs/README.md +1 -232
- package/template/echarts-custom-cmp-template/package.json +1 -1
- package/template/neo-bi-cmps/package.json +1 -1
- package/template/neo-bi-cmps/src/components/targetNumber__c/model.ts +1 -1
- package/template/neo-custom-cmp-template/docs/README.md +0 -231
- package/template/neo-custom-cmp-template/package.json +1 -1
- package/template/neo-h5-cmps/src/components/entityList__c/index.tsx +1 -2
- package/template/neo-h5-cmps/src/components/entityTabs__c/index.tsx +1 -1
- package/template/neo-h5-cmps/src/components/globalSearchInput__c/index.tsx +1 -1
- package/template/neo-h5-cmps/src/components/openChatPageBtn__c/index.tsx +1 -2
- package/template/neo-pipeline-cmps/neo.config.js +11 -0
- package/template/neo-pipeline-cmps/src/assets/css/common.scss +16 -16
- package/template/neo-pipeline-cmps/src/assets/css/mixin.scss +5 -5
- package/template/neo-pipeline-cmps/src/components/filterBar__c/README.md +9 -9
- package/template/neo-pipeline-cmps/src/components/filterBar__c/common.scss +5 -5
- package/template/neo-pipeline-cmps/src/components/filterBar__c/index.tsx +47 -46
- package/template/neo-pipeline-cmps/src/components/filterBar__c/model.ts +13 -11
- package/template/neo-pipeline-cmps/src/components/filterBar__c/style.scss +1 -1
- package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/README.md +17 -17
- package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/index.tsx +23 -22
- package/template/neo-pipeline-cmps/src/components/pipelineFunnel__c/model.ts +18 -17
- package/template/neo-pipeline-cmps/src/components/showHealthResult__c/index.tsx +33 -26
- package/template/neo-pipeline-cmps/src/components/showHealthResult__c/model.ts +9 -9
- package/template/neo-pipeline-cmps/src/components/simpleTable__c/README.md +53 -54
- package/template/neo-pipeline-cmps/src/components/simpleTable__c/common.scss +5 -5
- package/template/neo-pipeline-cmps/src/components/simpleTable__c/index.tsx +70 -68
- package/template/neo-pipeline-cmps/src/components/simpleTable__c/model.ts +41 -41
- package/template/neo-pipeline-cmps/src/components/simpleTable__c/style.scss +2 -3
- package/template/neo-pipeline-cmps/src/components/stageSwitch__c/README.md +15 -15
- package/template/neo-pipeline-cmps/src/components/stageSwitch__c/index.tsx +35 -33
- package/template/neo-pipeline-cmps/src/components/stageSwitch__c/model.ts +16 -15
- package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/README.md +18 -18
- package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/index.tsx +20 -20
- package/template/neo-pipeline-cmps/src/components/stageTimeChart__c/model.ts +21 -18
- package/template/neo-pipeline-cmps/src/utils/common.ts +14 -14
- package/template/neo-pipeline-cmps/src/utils/filter2chartFilter.ts +21 -23
- package/template/neo-pipeline-cmps/src/utils/filterBar.ts +14 -14
- package/template/neo-pipeline-cmps/src/utils/pipelineFunnel.ts +5 -5
- package/template/neo-pipeline-cmps/src/utils/queryByCustomSQL.ts +26 -22
- package/template/neo-pipeline-cmps/src/utils/requestDebounce.ts +3 -3
- package/template/neo-pipeline-cmps/src/utils/simpleTable.tsx +31 -26
- package/template/neo-pipeline-cmps/src/utils/stageSwitch.ts +1 -1
- package/template/neo-pipeline-cmps/src/utils/stageTimeChart.ts +5 -5
- package/template/neo-pipeline-cmps/src/utils/targetNumber.ts +2 -2
- package/template/neo-web-form/package.json +1 -1
- package/template/neo-web-form/src/components/batchAddTable__c/index.tsx +161 -41
- package/template/neo-web-form/src/components/batchAddTable__c/model.ts +4 -2
- package/template/react-custom-cmp-template/package.json +1 -1
- package/template/asset-manage-template/src/utils/axiosFetcher.ts +0 -37
- package/template/asset-manage-template/src/utils/queryObjectData.ts +0 -112
- package/template/asset-manage-template/src/utils/xobjects.ts +0 -162
- package/template/neo-custom-cmp-template/src/utils/axiosFetcher.ts +0 -37
- package/template/neo-custom-cmp-template/src/utils/queryObjectData.ts +0 -112
- package/template/neo-custom-cmp-template/src/utils/xobjects.ts +0 -162
- package/template/neo-h5-cmps/src/utils/axiosFetcher.ts +0 -37
- package/template/neo-h5-cmps/src/utils/queryObjectData.ts +0 -112
- package/template/neo-h5-cmps/src/utils/xobjects.ts +0 -167
- package/template/neo-order-cmps/src/utils/axiosFetcher.ts +0 -37
- package/template/neo-order-cmps/src/utils/queryObjectData.ts +0 -112
- package/template/neo-order-cmps/src/utils/xobjects.ts +0 -162
- package/template/neo-web-entity-grid/src/utils/axiosFetcher.ts +0 -37
- package/template/neo-web-entity-grid/src/utils/queryObjectData.ts +0 -112
- package/template/neo-web-entity-grid/src/utils/xobjects.ts +0 -167
- package/template/neo-web-form/src/utils/axiosFetcher.ts +0 -37
- package/template/neo-web-form/src/utils/queryObjectData.ts +0 -112
- package/template/neo-web-form/src/utils/xobjects.ts +0 -167
|
@@ -83,6 +83,14 @@ interface BatchAddTableState {
|
|
|
83
83
|
entityTypeList: any[];
|
|
84
84
|
submitting: boolean;
|
|
85
85
|
modalVisible: boolean;
|
|
86
|
+
/** Excel 导入 loading 状态 */
|
|
87
|
+
importLoading: boolean;
|
|
88
|
+
/** 导入进度信息 */
|
|
89
|
+
importProgress: { current: number; total: number } | null;
|
|
90
|
+
/** 当前页码 */
|
|
91
|
+
currentPage: number;
|
|
92
|
+
/** 每页条数 */
|
|
93
|
+
pageSize: number;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
let rowKeySeed = 0;
|
|
@@ -145,6 +153,10 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
145
153
|
entityTypeList: [],
|
|
146
154
|
submitting: false,
|
|
147
155
|
modalVisible: false,
|
|
156
|
+
importLoading: false,
|
|
157
|
+
importProgress: null,
|
|
158
|
+
currentPage: 1,
|
|
159
|
+
pageSize: 100,
|
|
148
160
|
};
|
|
149
161
|
this.loadFieldList = this.loadFieldList.bind(this);
|
|
150
162
|
this.getEntityTypeList = this.getEntityTypeList.bind(this);
|
|
@@ -279,9 +291,14 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
279
291
|
message.warning('暂无可用字段');
|
|
280
292
|
return;
|
|
281
293
|
}
|
|
282
|
-
this.
|
|
283
|
-
|
|
284
|
-
|
|
294
|
+
const { rows, pageSize } = this.state;
|
|
295
|
+
const newRows = [...rows, emptyRowForFields(visible)];
|
|
296
|
+
// 计算新增后的最后一页页码
|
|
297
|
+
const lastPage = Math.ceil(newRows.length / pageSize);
|
|
298
|
+
this.setState({
|
|
299
|
+
rows: newRows,
|
|
300
|
+
currentPage: lastPage,
|
|
301
|
+
});
|
|
285
302
|
}
|
|
286
303
|
|
|
287
304
|
handleCellChange(rowKey: string, apiKey: string, value: any) {
|
|
@@ -418,67 +435,125 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
418
435
|
message.success('模板已下载');
|
|
419
436
|
}
|
|
420
437
|
|
|
438
|
+
/**
|
|
439
|
+
* 分批处理导入数据,避免大数据量阻塞 UI
|
|
440
|
+
*/
|
|
441
|
+
private async processImportData(
|
|
442
|
+
rowsAoA: any[][],
|
|
443
|
+
fields: FieldInfo[],
|
|
444
|
+
colMap: Record<string, number>,
|
|
445
|
+
entityTypeList: any[],
|
|
446
|
+
onProgress: (current: number, total: number) => void,
|
|
447
|
+
): Promise<RowRecord[]> {
|
|
448
|
+
const newRows: RowRecord[] = [];
|
|
449
|
+
const total = rowsAoA.length - 1; // 排除表头
|
|
450
|
+
const batchSize = 100; // 每批处理 100 行
|
|
451
|
+
|
|
452
|
+
for (let r = 1; r < rowsAoA.length; r++) {
|
|
453
|
+
const line = rowsAoA[r];
|
|
454
|
+
if (!line || !line.some((c) => c !== '' && c != null)) continue;
|
|
455
|
+
|
|
456
|
+
const row: RowRecord = { _rowKey: nextRowKey() };
|
|
457
|
+
fields.forEach((f) => {
|
|
458
|
+
const idx = colMap[f.apiKey];
|
|
459
|
+
const raw = idx !== undefined ? line[idx] : undefined;
|
|
460
|
+
row[f.apiKey] = this.parseImportedCell(f, raw, entityTypeList);
|
|
461
|
+
});
|
|
462
|
+
newRows.push(row);
|
|
463
|
+
|
|
464
|
+
// 每处理 batchSize 行,让出主线程并更新进度
|
|
465
|
+
if (r % batchSize === 0) {
|
|
466
|
+
onProgress(r - 1, total);
|
|
467
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
onProgress(total, total);
|
|
472
|
+
return newRows;
|
|
473
|
+
}
|
|
474
|
+
|
|
421
475
|
handleImportBeforeUpload(file: File) {
|
|
422
476
|
const fields = this.getVisibleFields();
|
|
423
477
|
if (!fields.length) {
|
|
424
478
|
message.warning('暂无可用字段');
|
|
425
479
|
return false;
|
|
426
480
|
}
|
|
481
|
+
|
|
482
|
+
// 设置导入 loading 状态
|
|
483
|
+
this.setState({
|
|
484
|
+
importLoading: true,
|
|
485
|
+
importProgress: { current: 0, total: 0 },
|
|
486
|
+
});
|
|
487
|
+
|
|
427
488
|
const reader = new FileReader();
|
|
428
|
-
reader.onload = (e) => {
|
|
489
|
+
reader.onload = async (e) => {
|
|
429
490
|
try {
|
|
430
|
-
const data = new Uint8Array(e.target?.result as ArrayBuffer);
|
|
431
|
-
const wb = XLSX.read(data, { type: 'array', cellDates: true });
|
|
432
|
-
const sheetName = wb.SheetNames[0];
|
|
491
|
+
const data = new Uint8Array(e.target?.result as ArrayBuffer);
|
|
492
|
+
const wb = XLSX.read(data, { type: 'array', cellDates: true });
|
|
493
|
+
const sheetName = wb.SheetNames[0];
|
|
433
494
|
if (!sheetName) {
|
|
434
495
|
message.error('Excel 中未找到工作表');
|
|
496
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
435
497
|
return;
|
|
436
498
|
}
|
|
437
|
-
const sheet = wb.Sheets[sheetName];
|
|
438
|
-
const rowsAoA: any[][] = XLSX.utils.sheet_to_json(sheet, {
|
|
439
|
-
header: 1,
|
|
440
|
-
raw: true,
|
|
441
|
-
defval: '',
|
|
442
|
-
}) as any[][];
|
|
499
|
+
const sheet = wb.Sheets[sheetName];
|
|
500
|
+
const rowsAoA: any[][] = XLSX.utils.sheet_to_json(sheet, {
|
|
501
|
+
header: 1,
|
|
502
|
+
raw: true,
|
|
503
|
+
defval: '',
|
|
504
|
+
}) as any[][];
|
|
443
505
|
if (!rowsAoA.length) {
|
|
444
506
|
message.error('Excel 内容为空');
|
|
507
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
445
508
|
return;
|
|
446
509
|
}
|
|
447
510
|
const headerRow = rowsAoA[0] || [];
|
|
448
|
-
const colMap = this.buildHeaderIndexMap(headerRow, fields);
|
|
449
|
-
const missing = fields.filter((f) => colMap[f.apiKey] === undefined);
|
|
511
|
+
const colMap = this.buildHeaderIndexMap(headerRow, fields);
|
|
512
|
+
const missing = fields.filter((f) => colMap[f.apiKey] === undefined);
|
|
450
513
|
if (missing.length) {
|
|
451
514
|
message.error(
|
|
452
515
|
`表头无法匹配字段:${missing.map((m) => m.label).join('、')}`,
|
|
453
516
|
);
|
|
517
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
454
518
|
return;
|
|
455
519
|
}
|
|
456
520
|
const { entityTypeList } = this.state;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
|
|
521
|
+
|
|
522
|
+
// 使用分批处理解析数据
|
|
523
|
+
const newRows = await this.processImportData(
|
|
524
|
+
rowsAoA,
|
|
525
|
+
fields,
|
|
526
|
+
colMap,
|
|
527
|
+
entityTypeList,
|
|
528
|
+
(current, total) => {
|
|
529
|
+
this.setState({ importProgress: { current, total } });
|
|
530
|
+
},
|
|
531
|
+
);
|
|
532
|
+
|
|
469
533
|
if (!newRows.length) {
|
|
470
534
|
message.warning('未解析到有效数据行');
|
|
535
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
471
536
|
return;
|
|
472
537
|
}
|
|
538
|
+
|
|
473
539
|
this.setState((prev) => ({
|
|
474
540
|
rows: [...prev.rows, ...newRows],
|
|
541
|
+
importLoading: false,
|
|
542
|
+
importProgress: null,
|
|
543
|
+
// 导入完成后跳转到第一页,展示新导入的数据
|
|
544
|
+
currentPage: 1,
|
|
475
545
|
}));
|
|
476
546
|
message.success(`已导入 ${newRows.length} 行`);
|
|
477
547
|
} catch (err) {
|
|
478
548
|
console.error(err);
|
|
479
549
|
message.error('解析 Excel 失败');
|
|
550
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
480
551
|
}
|
|
481
552
|
};
|
|
553
|
+
reader.onerror = () => {
|
|
554
|
+
message.error('读取文件失败');
|
|
555
|
+
this.setState({ importLoading: false, importProgress: null });
|
|
556
|
+
};
|
|
482
557
|
reader.readAsArrayBuffer(file);
|
|
483
558
|
return false;
|
|
484
559
|
}
|
|
@@ -556,7 +631,13 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
556
631
|
const cloned = this.cloneRowRecord(record, fields);
|
|
557
632
|
const newRows = [...this.state.rows];
|
|
558
633
|
newRows.splice(idx + 1, 0, cloned);
|
|
559
|
-
|
|
634
|
+
// 计算复制行所在的页码
|
|
635
|
+
const { pageSize, currentPage } = this.state;
|
|
636
|
+
const copiedRowIndex = idx + 1;
|
|
637
|
+
const copiedRowPage = Math.floor(copiedRowIndex / pageSize) + 1;
|
|
638
|
+
// 如果复制的行不在当前页,跳转到复制的行所在页
|
|
639
|
+
const newPage = copiedRowPage !== currentPage ? copiedRowPage : currentPage;
|
|
640
|
+
this.setState({ rows: newRows, currentPage: newPage });
|
|
560
641
|
message.success('已在本行下方复制一行');
|
|
561
642
|
}
|
|
562
643
|
|
|
@@ -566,10 +647,22 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
566
647
|
if (newRows.length === 0 && fields.length) {
|
|
567
648
|
newRows.push(emptyRowForFields(fields));
|
|
568
649
|
}
|
|
569
|
-
|
|
650
|
+
// 删除后重新计算当前页码,避免当前页超出范围
|
|
651
|
+
const { pageSize, currentPage } = this.state;
|
|
652
|
+
const totalPages = Math.ceil(newRows.length / pageSize) || 1;
|
|
653
|
+
const newCurrentPage = Math.min(currentPage, totalPages);
|
|
654
|
+
this.setState({ rows: newRows, currentPage: newCurrentPage });
|
|
570
655
|
message.success('已删除该行');
|
|
571
656
|
}
|
|
572
657
|
|
|
658
|
+
/** 分页变化处理 */
|
|
659
|
+
handlePageChange = (page: number, pageSize?: number) => {
|
|
660
|
+
this.setState({
|
|
661
|
+
currentPage: page,
|
|
662
|
+
...(pageSize ? { pageSize } : {}),
|
|
663
|
+
} as BatchAddTableState);
|
|
664
|
+
};
|
|
665
|
+
|
|
573
666
|
openModal() {
|
|
574
667
|
this.setState({ modalVisible: true });
|
|
575
668
|
}
|
|
@@ -819,7 +912,7 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
819
912
|
}
|
|
820
913
|
|
|
821
914
|
render() {
|
|
822
|
-
const { loading, error, rows, submitting, title } = this.state;
|
|
915
|
+
const { loading, error, rows, submitting, title, importLoading, importProgress, currentPage, pageSize } = this.state;
|
|
823
916
|
const { tableTitle, className, data } = this.props;
|
|
824
917
|
const curAmisData = data || {};
|
|
825
918
|
const systemInfo = curAmisData.__NeoSystemInfo || {};
|
|
@@ -876,6 +969,11 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
876
969
|
),
|
|
877
970
|
});
|
|
878
971
|
|
|
972
|
+
// 计算分页数据
|
|
973
|
+
const startIndex = (currentPage - 1) * pageSize;
|
|
974
|
+
const endIndex = startIndex + pageSize;
|
|
975
|
+
const paginatedRows = rows.slice(startIndex, endIndex);
|
|
976
|
+
|
|
879
977
|
const displayTitle =
|
|
880
978
|
tableTitle || title || '批量新增数据';
|
|
881
979
|
const batchImportButtonTitle =
|
|
@@ -967,14 +1065,16 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
967
1065
|
accept=".xlsx,.xls"
|
|
968
1066
|
showUploadList={false}
|
|
969
1067
|
beforeUpload={this.handleImportBeforeUpload}
|
|
1068
|
+
disabled={importLoading}
|
|
970
1069
|
>
|
|
971
1070
|
<Button
|
|
972
1071
|
size="small"
|
|
973
1072
|
className="batch-add-modal-toolbar-btn"
|
|
974
1073
|
icon={<UploadOutlined />}
|
|
975
|
-
|
|
1074
|
+
loading={importLoading}
|
|
1075
|
+
disabled={!xObjectApiKey || !fields.length || importLoading}
|
|
976
1076
|
>
|
|
977
|
-
Excel 导入
|
|
1077
|
+
{importLoading ? '导入中...' : 'Excel 导入'}
|
|
978
1078
|
</Button>
|
|
979
1079
|
</Upload>
|
|
980
1080
|
</Space>
|
|
@@ -1008,15 +1108,35 @@ export default class BatchAddTable extends React.PureComponent<
|
|
|
1008
1108
|
/>
|
|
1009
1109
|
) : (
|
|
1010
1110
|
<div className="table-wrap">
|
|
1011
|
-
<
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
size="
|
|
1019
|
-
|
|
1111
|
+
<Spin
|
|
1112
|
+
spinning={importLoading}
|
|
1113
|
+
tip={
|
|
1114
|
+
importProgress
|
|
1115
|
+
? `正在加载导入数据... (${importProgress.current}/${importProgress.total})`
|
|
1116
|
+
: '正在加载导入数据...'
|
|
1117
|
+
}
|
|
1118
|
+
size="large"
|
|
1119
|
+
>
|
|
1120
|
+
<Table
|
|
1121
|
+
rowKey="_rowKey"
|
|
1122
|
+
columns={columns as any}
|
|
1123
|
+
dataSource={paginatedRows}
|
|
1124
|
+
pagination={{
|
|
1125
|
+
current: currentPage,
|
|
1126
|
+
pageSize: pageSize,
|
|
1127
|
+
total: rows.length,
|
|
1128
|
+
showSizeChanger: true,
|
|
1129
|
+
showQuickJumper: true,
|
|
1130
|
+
pageSizeOptions: ['50', '100', '200', '500'],
|
|
1131
|
+
showTotal: (total) => `共 ${total} 条`,
|
|
1132
|
+
onChange: this.handlePageChange,
|
|
1133
|
+
onShowSizeChange: this.handlePageChange,
|
|
1134
|
+
}}
|
|
1135
|
+
scroll={{ x: 'max-content', y: 'calc(100vh - 400px)' }}
|
|
1136
|
+
bordered
|
|
1137
|
+
size="small"
|
|
1138
|
+
/>
|
|
1139
|
+
</Spin>
|
|
1020
1140
|
</div>
|
|
1021
1141
|
)}
|
|
1022
1142
|
</Spin>
|
|
@@ -21,7 +21,7 @@ export class BatchAddTableModel {
|
|
|
21
21
|
batchImportButtonTitle: '批量导入',
|
|
22
22
|
batchImportButtonAlign: 'right',
|
|
23
23
|
xObjectDataApi: {
|
|
24
|
-
xObjectApiKey: 'opportunityProduct',
|
|
24
|
+
xObjectApiKey: 'opportunityProduct', // 商机明细
|
|
25
25
|
fields: [],
|
|
26
26
|
},
|
|
27
27
|
};
|
|
@@ -31,7 +31,8 @@ export class BatchAddTableModel {
|
|
|
31
31
|
apiKey: 'onSubmit',
|
|
32
32
|
label: '点击提交',
|
|
33
33
|
helpText: '点击提交按钮时触发,事件参数包含当前表格中所有行数据',
|
|
34
|
-
|
|
34
|
+
/*
|
|
35
|
+
eventParams:
|
|
35
36
|
[{
|
|
36
37
|
"apiKey": "eventParam",
|
|
37
38
|
"children":
|
|
@@ -42,6 +43,7 @@ export class BatchAddTableModel {
|
|
|
42
43
|
"label": "事件入参",
|
|
43
44
|
"type": "Object"
|
|
44
45
|
}],
|
|
46
|
+
*/
|
|
45
47
|
eventParams:
|
|
46
48
|
'[{"apiKey":"eventParam","children":[{"apiKey":"xObjectApiKey","label":"实体 API Key","type":"String"},{"apiKey":"rows","label":"表格数据列表","type":"Array"}],"label":"事件入参","type":"Object"}]',
|
|
47
49
|
},
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import axios from 'axios'; // https://www.axios-http.cn/docs/intro
|
|
2
|
-
|
|
3
|
-
// 创建基于 axios 的 fetcher 函数
|
|
4
|
-
const axiosFetcher = async (options: any) => {
|
|
5
|
-
try {
|
|
6
|
-
const config = {
|
|
7
|
-
...options,
|
|
8
|
-
method: options?.method || 'GET',
|
|
9
|
-
data: options?.data || {},
|
|
10
|
-
headers: {
|
|
11
|
-
'Content-Type': 'application/json',
|
|
12
|
-
...options?.headers,
|
|
13
|
-
},
|
|
14
|
-
timeout: options?.timeout || 30000,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
if (config?.method === 'GET') {
|
|
18
|
-
config.params = options?.data || {};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const response = await axios(config);
|
|
22
|
-
return response?.data || {};
|
|
23
|
-
} catch (error) {
|
|
24
|
-
if (error.response) {
|
|
25
|
-
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
|
|
26
|
-
console.error('接口请求报错 / 接口服务异常:', error.message);
|
|
27
|
-
} else if (error.request) {
|
|
28
|
-
// 请求已经成功发起,但没有收到响应
|
|
29
|
-
console.error('接口请求报错 / 接口未正常响应:', error.message);
|
|
30
|
-
} else {
|
|
31
|
-
console.error('接口请求报错:', error, ',请求参数:', options);
|
|
32
|
-
}
|
|
33
|
-
throw error;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export default axiosFetcher;
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import axiosFetcher from '$utils/axiosFetcher';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 这里存放通用查询类 Open API
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/** 将 where 规范为 SQL 片段:字符串直接使用;数组用 and 拼接各条件 */
|
|
8
|
-
function normalizeWhere(where: unknown): string {
|
|
9
|
-
if (where == null || where === '') {
|
|
10
|
-
return '';
|
|
11
|
-
}
|
|
12
|
-
if (typeof where === 'string') {
|
|
13
|
-
return where.trim();
|
|
14
|
-
}
|
|
15
|
-
if (Array.isArray(where)) {
|
|
16
|
-
return where
|
|
17
|
-
.map((part) => (part == null ? '' : String(part).trim()))
|
|
18
|
-
.filter(Boolean)
|
|
19
|
-
.join(' and ');
|
|
20
|
-
}
|
|
21
|
-
return '';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 获取业务对象数据列表
|
|
25
|
-
export const queryXObjectData = async (options?: any) => {
|
|
26
|
-
const apiUrl = '/rest/data/v2/query';
|
|
27
|
-
const curOptions = options || {};
|
|
28
|
-
const xObjectApiKey = curOptions.xObjectApiKey || '';
|
|
29
|
-
const fields = curOptions.fields || [];
|
|
30
|
-
const page = curOptions.page || 1;
|
|
31
|
-
const pageSize = curOptions.pageSize || 10;
|
|
32
|
-
|
|
33
|
-
// 自动添加 objectId 字段
|
|
34
|
-
if (!fields.includes('id')) {
|
|
35
|
-
fields.push('id');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 计算分页偏移量
|
|
39
|
-
const offset = (page - 1) * pageSize;
|
|
40
|
-
|
|
41
|
-
// 构建 SQL 查询
|
|
42
|
-
let querySql = `select ${fields.join(',')} from ${xObjectApiKey}`;
|
|
43
|
-
|
|
44
|
-
// 添加排序条件(如果有的话)
|
|
45
|
-
if (curOptions.orderBy) {
|
|
46
|
-
querySql += ` order by ${curOptions.orderBy}`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 添加过滤条件(如果有的话)
|
|
51
|
-
* 支持的操作符包括:=、!=、like、not like、not in、is not null、is null、>、<、<>、>=、<=、in、between ... and ...。
|
|
52
|
-
* 对于 =、like 和 in 有以下说明:
|
|
53
|
-
* “=” 作为字符串的条件时,表示精确匹配。例如,查询条件 city = '北京',将返回 city 字段值严格等于 "北京" 的所有记录。
|
|
54
|
-
* "like" 作为字符串的条件时,需要使用"%" 通配符进行模糊匹配。例如,city like‘北京%',将返回 city 字段值以 "北京" 开头的所有记录。
|
|
55
|
-
* 目前仅支持将通配符“%” 放到已知内容之后的查询方式,例如,不支持 city like ‘% 北京'的查询方式。
|
|
56
|
-
* 当 SQL 查询中包含“%”等特殊字符时,需要对 SQL 进行 URL 编码处理。
|
|
57
|
-
* 支持"in",但不包括子查询。
|
|
58
|
-
* 支持的逻辑运算符包括:and、or。
|
|
59
|
-
*
|
|
60
|
-
* `where` 可为字符串,或字符串数组(多项默认以 and 连接,等价于手写 `a and b`)。
|
|
61
|
-
*/
|
|
62
|
-
const whereClause = normalizeWhere(curOptions.where);
|
|
63
|
-
console.log('whereClause:', whereClause);
|
|
64
|
-
if (whereClause) {
|
|
65
|
-
querySql += ` where ${whereClause}`;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (curOptions.page || curOptions.pageSize) {
|
|
69
|
-
// 添加分页限制
|
|
70
|
-
querySql += ` limit ${pageSize} offset ${offset}`;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const config = {
|
|
75
|
-
url: apiUrl,
|
|
76
|
-
method: 'GET',
|
|
77
|
-
data: {
|
|
78
|
-
q: querySql,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const resultData = await axiosFetcher(config);
|
|
83
|
-
|
|
84
|
-
if (resultData.code === 200) {
|
|
85
|
-
const { records, totalSize } = resultData.result || {};
|
|
86
|
-
return {
|
|
87
|
-
status: true,
|
|
88
|
-
code: resultData.code,
|
|
89
|
-
msg: resultData.msg || '获取业务对象数据列表成功',
|
|
90
|
-
totalSize,
|
|
91
|
-
data: records || [],
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
status: false,
|
|
97
|
-
code: resultData.code,
|
|
98
|
-
msg: resultData.msg || '获取业务对象数据列表失败',
|
|
99
|
-
data: [],
|
|
100
|
-
};
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.error('获取业务对象数据列表失败:', error);
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
status: false,
|
|
106
|
-
msg: error.msg || error.message || '获取业务对象数据列表失败',
|
|
107
|
-
data: [],
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export default queryXObjectData;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { message } from 'antd';
|
|
2
|
-
import axiosFetcher from './axiosFetcher';
|
|
3
|
-
|
|
4
|
-
// 获取业务类型列表
|
|
5
|
-
export const getEntityTypeList = async (
|
|
6
|
-
xObjectApiKey: string,
|
|
7
|
-
options?: any,
|
|
8
|
-
) => {
|
|
9
|
-
const curOptions = options || {};
|
|
10
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}/busiType`;
|
|
11
|
-
try {
|
|
12
|
-
const config = {
|
|
13
|
-
...curOptions,
|
|
14
|
-
url: apiUrl,
|
|
15
|
-
method: 'GET',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const result = await axiosFetcher(config);
|
|
19
|
-
return result;
|
|
20
|
-
} catch (error) {
|
|
21
|
-
console.error('获取业务类型失败:', error);
|
|
22
|
-
message.error('获取业务类型失败。');
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// 获取对象列表
|
|
28
|
-
export const getEntityList = async (options?: any) => {
|
|
29
|
-
const curOptions = options || {};
|
|
30
|
-
const custom = curOptions.custom || false; // 默认获取标准对象列表
|
|
31
|
-
const active = curOptions.active || true; // 仅获取有权限的对象
|
|
32
|
-
const apiUrl = `/rest/metadata/v2.0/xobjects/filter?custom=${custom}&active=${active}`;
|
|
33
|
-
try {
|
|
34
|
-
const config = {
|
|
35
|
-
...curOptions,
|
|
36
|
-
url: apiUrl,
|
|
37
|
-
method: 'GET',
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const result = await axiosFetcher(config);
|
|
41
|
-
return result;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error('获取对象列表失败:', error);
|
|
44
|
-
message.error('获取对象列表失败。');
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// 创建业务数据
|
|
50
|
-
export const createXObject = async (xObjectApiKey: string, options: any) => {
|
|
51
|
-
const curOptions = options || {};
|
|
52
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}`;
|
|
53
|
-
const formData = curOptions.data || {};
|
|
54
|
-
try {
|
|
55
|
-
const config = {
|
|
56
|
-
...options,
|
|
57
|
-
url: apiUrl,
|
|
58
|
-
method: curOptions.method || 'GET',
|
|
59
|
-
data: {
|
|
60
|
-
data: formData,
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const result = await axiosFetcher(config);
|
|
65
|
-
return result;
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error('创建业务数据失败:', error);
|
|
68
|
-
throw error;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// 获取业务对象描述
|
|
73
|
-
export const getXObjectDesc = async (xObjectApiKey: string, options?: any) => {
|
|
74
|
-
const curOptions = options || {};
|
|
75
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}/description`;
|
|
76
|
-
try {
|
|
77
|
-
const config = {
|
|
78
|
-
...options,
|
|
79
|
-
url: apiUrl,
|
|
80
|
-
method: curOptions.method || 'GET',
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const result = await axiosFetcher(config);
|
|
84
|
-
return result;
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.error('获取业务对象描述:', error);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// 更新业务数据
|
|
92
|
-
export const updateXObject = async (
|
|
93
|
-
xObjectApiKey: string,
|
|
94
|
-
objectId: string,
|
|
95
|
-
options: any,
|
|
96
|
-
) => {
|
|
97
|
-
const curOptions = options || {};
|
|
98
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}/${objectId}`;
|
|
99
|
-
const formData = curOptions.data || {};
|
|
100
|
-
try {
|
|
101
|
-
const config = {
|
|
102
|
-
...curOptions,
|
|
103
|
-
url: apiUrl,
|
|
104
|
-
method: curOptions.method || 'PATCH',
|
|
105
|
-
data: {
|
|
106
|
-
data: formData,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const result = await axiosFetcher(config);
|
|
111
|
-
return result;
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.error('更新业务数据失败:', error);
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// 获取业务数据信息
|
|
119
|
-
export const getXObject = async (
|
|
120
|
-
xObjectApiKey: string,
|
|
121
|
-
objectId: string,
|
|
122
|
-
options?: any,
|
|
123
|
-
) => {
|
|
124
|
-
const curOptions = options || {};
|
|
125
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}/${objectId}`;
|
|
126
|
-
try {
|
|
127
|
-
const config = {
|
|
128
|
-
...curOptions,
|
|
129
|
-
url: apiUrl,
|
|
130
|
-
method: curOptions.method || 'GET',
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const result = await axiosFetcher(config);
|
|
134
|
-
return result;
|
|
135
|
-
} catch (error) {
|
|
136
|
-
console.error('获取业务数据信息失败:', error);
|
|
137
|
-
throw error;
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
// 删除业务数据
|
|
142
|
-
export const deleteXObject = async (
|
|
143
|
-
xObjectApiKey: string,
|
|
144
|
-
objectId: string,
|
|
145
|
-
options?: any,
|
|
146
|
-
) => {
|
|
147
|
-
const curOptions = options || {};
|
|
148
|
-
const apiUrl = `/rest/data/v2.0/xobjects/${xObjectApiKey}/${objectId}`;
|
|
149
|
-
try {
|
|
150
|
-
const config = {
|
|
151
|
-
...curOptions,
|
|
152
|
-
url: apiUrl,
|
|
153
|
-
method: curOptions.method || 'DELETE',
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
const result = await axiosFetcher(config);
|
|
157
|
-
return result;
|
|
158
|
-
} catch (error) {
|
|
159
|
-
console.error('删除业务数据:', error);
|
|
160
|
-
throw error;
|
|
161
|
-
}
|
|
162
|
-
};
|