@bit-sun/business-component 4.2.0-alpha.3 → 4.2.0-alpha.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.
Files changed (138) hide show
  1. package/.fatherrc.ts +1 -1
  2. package/.umirc.ts +13 -9
  3. package/dist/components/Business/AddSelectBusiness/index.d.ts +3 -4
  4. package/dist/components/Business/BsLayouts/Components/AllFunc/drawContent.d.ts +1 -2
  5. package/dist/components/Business/BsLayouts/Components/ChooseStore/index.d.ts +1 -2
  6. package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.d.ts +1 -1
  7. package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/leftTree.d.ts +1 -1
  8. package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/rightTree.d.ts +2 -2
  9. package/dist/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/DrawContent.d.ts +1 -2
  10. package/dist/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/customMenuHeader.d.ts +1 -2
  11. package/dist/components/Business/BsLayouts/Components/CustomerMenu/index.d.ts +1 -1
  12. package/dist/components/Business/BsLayouts/Components/GlobalHeader/index.d.ts +1 -2
  13. package/dist/components/Business/BsLayouts/Components/RightContent/LoginModal.d.ts +1 -2
  14. package/dist/components/Business/BsLayouts/index.d.ts +1 -1
  15. package/dist/components/Business/BsSulaQueryTable/SearchItemSetting.d.ts +5 -5
  16. package/dist/components/Business/BsSulaQueryTable/index.d.ts +1 -2
  17. package/dist/components/Business/BsSulaQueryTable/setting.d.ts +6 -6
  18. package/dist/components/Business/BsSulaQueryTable/utils.d.ts +14 -15
  19. package/dist/components/Business/CommodityEntry/index.d.ts +1 -2
  20. package/dist/components/Business/CommonAlert/index.d.ts +1 -2
  21. package/dist/components/Business/CommonGuideWrapper/index.d.ts +3 -3
  22. package/dist/components/Business/DetailPageWrapper/index.d.ts +12 -12
  23. package/dist/components/Business/HomePageWrapper/index.d.ts +1 -2
  24. package/dist/components/Business/ImportExport/ExportButton/ModalTitle.d.ts +11 -0
  25. package/dist/components/Business/ImportExport/ExportButton/TemplatePicker.d.ts +13 -0
  26. package/dist/components/Business/ImportExport/ExportButton/index.d.ts +15 -0
  27. package/dist/components/Business/ImportExport/ImportWizard/Preview.d.ts +11 -0
  28. package/dist/components/Business/ImportExport/ImportWizard/index.d.ts +15 -0
  29. package/dist/components/Business/ImportExport/TaskDrawer/index.d.ts +15 -0
  30. package/dist/components/Business/ImportExport/TaskProgress/index.d.ts +15 -0
  31. package/dist/components/Business/ImportExport/businessFunction.d.ts +15 -0
  32. package/dist/components/Business/ImportExport/index.d.ts +14 -0
  33. package/dist/components/Business/ImportExport/sceneCapability.d.ts +20 -0
  34. package/dist/components/Business/ImportExport/services/importExport.d.ts +22 -0
  35. package/dist/components/Business/ImportExport/services/routing.d.ts +8 -0
  36. package/dist/components/Business/ImportExport/types.d.ts +134 -0
  37. package/dist/components/Business/ItemPropertySelector/index.d.ts +1 -2
  38. package/dist/components/Business/JsonQueryTable/components/FieldsModifyModal.d.ts +1 -2
  39. package/dist/components/Business/JsonQueryTable/components/FieldsSettingsTable.d.ts +1 -2
  40. package/dist/components/Business/JsonQueryTable/components/Formula.d.ts +1 -2
  41. package/dist/components/Business/JsonQueryTable/components/MaintainOptions.d.ts +1 -2
  42. package/dist/components/Business/JsonQueryTable/drawer/index.d.ts +1 -2
  43. package/dist/components/Business/PropertyModal/index.d.ts +1 -2
  44. package/dist/components/Business/PropertyModal/propertyGroup.d.ts +1 -1
  45. package/dist/components/Business/SearchSelect/index.d.ts +1 -1
  46. package/dist/components/Business/StateFlow/index.d.ts +1 -2
  47. package/dist/components/Business/SystemLog/index.d.ts +78 -0
  48. package/dist/components/Business/TreeSearchSelect/index.d.ts +1 -1
  49. package/dist/components/Business/TrialCalculation/index.d.ts +15 -0
  50. package/dist/components/Business/columnSettingTable/columnSetting.d.ts +6 -6
  51. package/dist/components/Business/columnSettingTable/components/TableSumComponent.d.ts +1 -2
  52. package/dist/components/Business/columnSettingTable/index.d.ts +3 -3
  53. package/dist/components/Business/columnSettingTable/sulaSettingTable.d.ts +3 -3
  54. package/dist/components/Business/columnSettingTable/utils.d.ts +1 -2
  55. package/dist/components/Business/moreTreeTable/FixedScrollBar.d.ts +1 -1
  56. package/dist/components/Common/ParagraphCopier/index.d.ts +1 -1
  57. package/dist/components/Common/Section/index.d.ts +1 -1
  58. package/dist/components/Functional/AddSelect/index.d.ts +1 -2
  59. package/dist/components/Functional/AuthButton/index.d.ts +1 -2
  60. package/dist/components/Functional/DataImport/index.d.ts +3 -3
  61. package/dist/components/Functional/DataValidation/index.d.ts +5 -5
  62. package/dist/components/Functional/ExportFunctions/ExportIcon/index.d.ts +1 -2
  63. package/dist/components/Functional/QueryMutipleInput/index.d.ts +1 -2
  64. package/dist/components/Functional/QueryMutipleSelect/index.d.ts +1 -2
  65. package/dist/components/Functional/SearchSelect/index.d.ts +1 -1
  66. package/dist/components/Functional/SearchSelect/pagination.d.ts +22 -0
  67. package/dist/components/Functional/SearchSelect/utils.d.ts +2 -3
  68. package/dist/components/Functional/TreeSearchSelect/index.d.ts +1 -2
  69. package/dist/components/Solution/RuleComponent/CustomPlugin/CustomSelector/CustomSelectorModal.d.ts +1 -1
  70. package/dist/components/Solution/RuleComponent/CustomPlugin/CustomSelector/index.d.ts +1 -2
  71. package/dist/components/Solution/RuleComponent/Formula.d.ts +1 -2
  72. package/dist/components/Solution/RuleComponent/InnerSelect.d.ts +1 -2
  73. package/dist/components/Solution/RuleComponent/RenderCompItem.d.ts +1 -2
  74. package/dist/components/Solution/RuleSetter/RuleInstance.d.ts +1 -2
  75. package/dist/components/Solution/RuleSetter/baseRule.d.ts +1 -1
  76. package/dist/components/Solution/RuleSetter/index.d.ts +1 -1
  77. package/dist/index.d.ts +5 -0
  78. package/dist/index.esm.js +5397 -1220
  79. package/dist/index.js +5417 -1213
  80. package/dist/plugin/TableColumnSetting/index.d.ts +5 -5
  81. package/dist/utils/TableUtils.d.ts +18 -19
  82. package/dist/utils/auth.d.ts +4 -0
  83. package/dist/utils/utils.d.ts +41 -0
  84. package/docs/error-record.md +52 -0
  85. package/docs/flow-control-readme.md +283 -0
  86. package/docs/task-records/2026-07-31-import-export-extraction.md +81 -0
  87. package/package.json +1 -1
  88. package/src/components/Business/AddSelectBusiness/index.tsx +3 -2
  89. package/src/components/Business/BsSulaQueryTable/index.md +57 -4
  90. package/src/components/Business/BsSulaQueryTable/index.tsx +174 -10
  91. package/src/components/Business/BsSulaQueryTable/setting.tsx +6 -0
  92. package/src/components/Business/DetailPageWrapper/index.tsx +81 -1
  93. package/src/components/Business/DetailPageWrapper/readme.md +89 -0
  94. package/src/components/Business/ImportExport/ExportButton/ModalTitle.tsx +27 -0
  95. package/src/components/Business/ImportExport/ExportButton/TemplatePicker.tsx +424 -0
  96. package/src/components/Business/ImportExport/ExportButton/index.module.less +382 -0
  97. package/src/components/Business/ImportExport/ExportButton/index.tsx +273 -0
  98. package/src/components/Business/ImportExport/ImportWizard/Preview.tsx +129 -0
  99. package/src/components/Business/ImportExport/ImportWizard/index.module.less +360 -0
  100. package/src/components/Business/ImportExport/ImportWizard/index.tsx +679 -0
  101. package/src/components/Business/ImportExport/TaskDrawer/index.tsx +285 -0
  102. package/src/components/Business/ImportExport/TaskProgress/index.tsx +267 -0
  103. package/src/components/Business/ImportExport/businessFunction.ts +29 -0
  104. package/src/components/Business/ImportExport/index.md +104 -0
  105. package/src/components/Business/ImportExport/index.tsx +208 -0
  106. package/src/components/Business/ImportExport/sceneCapability.ts +28 -0
  107. package/src/components/Business/ImportExport/services/importExport.ts +208 -0
  108. package/src/components/Business/ImportExport/services/routing.ts +21 -0
  109. package/src/components/Business/ImportExport/types.ts +180 -0
  110. package/src/components/Business/SearchSelect/BusinessUtils.tsx +704 -48
  111. package/src/components/Business/SearchSelect/index.md +2 -2
  112. package/src/components/Business/SystemLog/index.md +37 -0
  113. package/src/components/Business/SystemLog/index.tsx +87 -0
  114. package/src/components/Business/TrialCalculation/PathDisplay.less +93 -0
  115. package/src/components/Business/TrialCalculation/PathDisplay_README.md +77 -0
  116. package/src/components/Business/TrialCalculation/index.tsx +322 -0
  117. package/src/components/Business/columnSettingTable/index.tsx +7 -6
  118. package/src/components/Business/columnSettingTable/sulaSettingTable.tsx +23 -22
  119. package/src/components/Functional/AddSelect/index.tsx +95 -1
  120. package/src/components/Functional/DataValidation/index.tsx +31 -9
  121. package/src/components/Functional/QueryMutipleSelect/index.tsx +2 -2
  122. package/src/components/Functional/SearchSelect/index.md +109 -0
  123. package/src/components/Functional/SearchSelect/index.tsx +99 -17
  124. package/src/components/Functional/SearchSelect/pagination.ts +57 -0
  125. package/src/components/Functional/SearchSelect/utils.tsx +28 -18
  126. package/src/components/Functional/TreeSearchSelect/index.tsx +2 -1
  127. package/src/components/Solution/RuleComponent/README.md +187 -0
  128. package/src/components/Solution/RuleComponent/RenderCompItem.tsx +9 -1
  129. package/src/components/Solution/RuleComponent/RenderCompItem_README.md +189 -0
  130. package/src/components/Solution/RuleComponent/RuleField.md +63 -0
  131. package/src/components/Solution/RuleComponent/index.js +237 -8
  132. package/src/components/Solution/RuleComponent/ruleFiled.js +46 -6
  133. package/src/components/Solution/RuleSetter/README.md +97 -0
  134. package/src/index.ts +9 -0
  135. package/src/typings/umi.d.ts +9 -0
  136. package/src/utils/LocalstorageUtils.ts +1 -1
  137. package/src/utils/auth.ts +39 -2
  138. package/src/utils/utils.ts +41 -1
@@ -0,0 +1,208 @@
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
+ import { Button, Space, message } from 'antd';
3
+ import ExportButton from './ExportButton';
4
+ import ImportWizard from './ImportWizard';
5
+ import TaskDrawer from './TaskDrawer';
6
+ import TaskProgress from './TaskProgress';
7
+ import type {
8
+ FileTask,
9
+ ImportExportActionsProps,
10
+ ImportExportOperationType,
11
+ ImportExportRequestContext,
12
+ } from './types';
13
+ import { createRequestContext } from './types';
14
+ import { resolveBusinessFunctionCode } from './businessFunction';
15
+ import { resolveImportExportServices } from './services/importExport';
16
+ import { authFunc } from '@/utils';
17
+
18
+ const BUSINESS_FUNCTION_UNAVAILABLE =
19
+ '业务功能未配置或已停用,请联系管理员维护业务功能档案';
20
+
21
+ /** 主应用向无界子应用注入的任务中心跳转能力。 */
22
+ interface TaskCenterHostWindow extends Window {
23
+ __POWERED_BY_WUJIE__?: boolean;
24
+ $wujie?: {
25
+ props?: {
26
+ jump?: (route: {
27
+ pathname: string;
28
+ state: { thisHideInMenuDoNotClose: boolean };
29
+ }) => void;
30
+ };
31
+ };
32
+ }
33
+
34
+ /**
35
+ * 默认跳转到主应用中的任务中心。
36
+ *
37
+ * 无界子应用通过主应用注入的跳转能力切换页面;独立运行时打开主应用地址。
38
+ */
39
+ const defaultNavigateTaskCenter = (path: string) => {
40
+ const hostWindow = window as TaskCenterHostWindow;
41
+ const jump = hostWindow.$wujie?.props?.jump;
42
+ if (hostWindow.__POWERED_BY_WUJIE__ && typeof jump === 'function') {
43
+ jump({
44
+ pathname: path,
45
+ state: {
46
+ thisHideInMenuDoNotClose: true,
47
+ },
48
+ });
49
+ return;
50
+ }
51
+
52
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
53
+ hostWindow.open(
54
+ `${hostWindow.location.origin}/main-project-front/#${normalizedPath}`,
55
+ '_blank',
56
+ );
57
+ };
58
+
59
+ /**
60
+ * 统一承载导入、快速导出、模板导出和文件任务入口。
61
+ */
62
+ export const ImportExportActions: React.FC<ImportExportActionsProps> = ({
63
+ config,
64
+ services: serviceOverrides,
65
+ importCode,
66
+ quickExportCode,
67
+ templateExportCode,
68
+ taskCenterPath = '/configure/importExport/taskCenter',
69
+ showTaskDrawer = true,
70
+ onNavigateTaskCenter = defaultNavigateTaskCenter,
71
+ }) => {
72
+ const [importVisible, setImportVisible] = useState(false);
73
+ const [importRouteLoading, setImportRouteLoading] = useState(false);
74
+ const [importContext, setImportContext] =
75
+ useState<ImportExportRequestContext>();
76
+ const [tasks, setTasks] = useState<FileTask[]>([]);
77
+ const services = useMemo(
78
+ () => resolveImportExportServices(serviceOverrides),
79
+ [serviceOverrides],
80
+ );
81
+ const showImport = !!authFunc(importCode);
82
+ const showQuickExport = !!authFunc(quickExportCode);
83
+ const showTemplateExport = !!authFunc(templateExportCode);
84
+ const authCodes = {
85
+ importCode,
86
+ quickExportCode,
87
+ templateExportCode,
88
+ };
89
+ const taskBusinessFunctionCodes = Array.from(
90
+ new Set(
91
+ [
92
+ resolveBusinessFunctionCode('IMPORT', authCodes),
93
+ resolveBusinessFunctionCode('EXPORT', authCodes),
94
+ ].filter(Boolean),
95
+ ),
96
+ );
97
+
98
+ /**
99
+ * 解析当前操作使用的业务功能和服务上下文。
100
+ */
101
+ const resolveRequestContext = async (
102
+ operationType: ImportExportOperationType,
103
+ ) => {
104
+ const businessFunctionCode = resolveBusinessFunctionCode(
105
+ operationType,
106
+ authCodes,
107
+ );
108
+ if (!businessFunctionCode) {
109
+ message.warning(BUSINESS_FUNCTION_UNAVAILABLE);
110
+ return undefined;
111
+ }
112
+ try {
113
+ const response = await services.resolveBusinessFunction(
114
+ businessFunctionCode,
115
+ );
116
+ const resolved = response?.data?.data || response?.data || response;
117
+ if (!resolved?.serviceContext || Number(resolved.status) !== 1) {
118
+ throw new Error(BUSINESS_FUNCTION_UNAVAILABLE);
119
+ }
120
+ return createRequestContext(
121
+ config,
122
+ businessFunctionCode,
123
+ resolved.serviceContext as string,
124
+ operationType,
125
+ );
126
+ } catch (error) {
127
+ message.warning(BUSINESS_FUNCTION_UNAVAILABLE);
128
+ return undefined;
129
+ }
130
+ };
131
+
132
+ const openImport = async () => {
133
+ setImportRouteLoading(true);
134
+ try {
135
+ const context = await resolveRequestContext('IMPORT');
136
+ if (!context) return;
137
+ setImportContext(context);
138
+ setImportVisible(true);
139
+ } finally {
140
+ setImportRouteLoading(false);
141
+ }
142
+ };
143
+
144
+ const addTask = useCallback((task: FileTask) => {
145
+ if (!task?.taskId) return;
146
+ setTasks((items) => [
147
+ task,
148
+ ...items.filter((item) => item.taskId !== task.taskId),
149
+ ]);
150
+ }, []);
151
+
152
+ return (
153
+ <>
154
+ <Space>
155
+ {showImport && (
156
+ <Button loading={importRouteLoading} onClick={openImport}>
157
+ 导入
158
+ </Button>
159
+ )}
160
+ {(showQuickExport || showTemplateExport) && (
161
+ <ExportButton
162
+ config={config}
163
+ services={services}
164
+ resolveRequestContext={() => resolveRequestContext('EXPORT')}
165
+ showQuickExport={showQuickExport}
166
+ showTemplateExport={showTemplateExport}
167
+ onTaskCreated={addTask}
168
+ />
169
+ )}
170
+ {showTaskDrawer && (
171
+ <TaskDrawer
172
+ businessFunctionCodes={taskBusinessFunctionCodes}
173
+ services={services}
174
+ taskCenterPath={taskCenterPath}
175
+ onNavigateTaskCenter={onNavigateTaskCenter}
176
+ />
177
+ )}
178
+ </Space>
179
+ {importContext && (
180
+ <ImportWizard
181
+ visible={importVisible}
182
+ context={importContext}
183
+ documentName={config.documentName}
184
+ services={services}
185
+ onClose={() => setImportVisible(false)}
186
+ onTaskCreated={addTask}
187
+ />
188
+ )}
189
+ <TaskProgress
190
+ tasks={tasks}
191
+ services={services}
192
+ taskCenterPath={taskCenterPath}
193
+ onNavigateTaskCenter={onNavigateTaskCenter}
194
+ onTaskUpdated={addTask}
195
+ onClose={() => setTasks([])}
196
+ />
197
+ </>
198
+ );
199
+ };
200
+
201
+ export { default as ImportWizard } from './ImportWizard';
202
+ export { default as ExportButton } from './ExportButton';
203
+ export { default as TaskProgress } from './TaskProgress';
204
+ export { default as TaskDrawer } from './TaskDrawer';
205
+ export * from './types';
206
+ export * from './services/importExport';
207
+ export * from './sceneCapability';
208
+ export * from './businessFunction';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 导入导出场景能力开关。
3
+ */
4
+ export interface SceneCapabilityConfig {
5
+ multiSheet?: boolean;
6
+ horizontalExport?: boolean;
7
+ largeFile?: boolean;
8
+ }
9
+
10
+ /**
11
+ * 判断是否启用多工作表能力。
12
+ */
13
+ export const isMultiSheetEnabled = (config?: SceneCapabilityConfig): boolean =>
14
+ config?.multiSheet === true;
15
+
16
+ /**
17
+ * 判断是否启用横向导出能力。
18
+ */
19
+ export const isHorizontalExportEnabled = (
20
+ config?: SceneCapabilityConfig,
21
+ ): boolean => config?.horizontalExport === true;
22
+
23
+ /**
24
+ * 判断是否启用大文件导出能力。
25
+ */
26
+ export const isLargeFileExportEnabled = (
27
+ config?: SceneCapabilityConfig,
28
+ ): boolean => config?.largeFile === true;
@@ -0,0 +1,208 @@
1
+ import { request as umiRequest } from 'umi';
2
+ import type { ImportExportRequest, ImportExportServices } from '../types';
3
+ import { buildSdkUrl } from './routing';
4
+ export { buildSdkUrl, normalizeServiceContext } from './routing';
5
+
6
+ const CONFIG_PREFIX = '/basic/import-export';
7
+ const BUSINESS_FUNCTION_PREFIX = '/basic/business-functions';
8
+ const OSS_UPLOAD_URL = '/basic/upload';
9
+
10
+ export const concurrentLimitCode = 'IE-COM-CONCURRENT-FILE-LIMIT';
11
+
12
+ /**
13
+ * 使用业务项目提供的请求函数创建完整导入导出服务。
14
+ *
15
+ * 请求函数由消费方注入,以复用其鉴权、租户和异常处理拦截器。
16
+ */
17
+ export const createImportExportServices = (
18
+ request: ImportExportRequest,
19
+ overrides: Partial<ImportExportServices> = {},
20
+ ): ImportExportServices => {
21
+ if (typeof request !== 'function') {
22
+ throw new Error('创建导入导出服务时必须提供请求函数');
23
+ }
24
+
25
+ const services: ImportExportServices = {
26
+ resolveBusinessFunction: (businessFunctionCode) =>
27
+ request(
28
+ `${BUSINESS_FUNCTION_PREFIX}/${encodeURIComponent(
29
+ businessFunctionCode,
30
+ )}/resolve`,
31
+ { method: 'GET' },
32
+ ),
33
+ queryTemplates: (data) =>
34
+ request(`${CONFIG_PREFIX}/templates/query`, {
35
+ method: 'POST',
36
+ data,
37
+ }),
38
+ queryTemplateFields: (data) =>
39
+ request(`${CONFIG_PREFIX}/fields/candidates`, {
40
+ method: 'POST',
41
+ data,
42
+ }),
43
+ uploadFile: (file) => {
44
+ const formData = new FormData();
45
+ formData.append('file', file);
46
+ return request(OSS_UPLOAD_URL, { method: 'POST', data: formData });
47
+ },
48
+ downloadTemplate: (templateCode, data) =>
49
+ request(
50
+ `${CONFIG_PREFIX}/templates/${encodeURIComponent(
51
+ templateCode,
52
+ )}/download`,
53
+ {
54
+ method: 'GET',
55
+ params: data,
56
+ responseType: 'blob',
57
+ },
58
+ ),
59
+ previewImport: (serviceContext, data) =>
60
+ request(buildSdkUrl(serviceContext, '/imports/preview'), {
61
+ method: 'POST',
62
+ data,
63
+ }),
64
+ executeImport: (serviceContext, data) =>
65
+ request(buildSdkUrl(serviceContext, '/imports/execute'), {
66
+ method: 'POST',
67
+ data,
68
+ }),
69
+ downloadValidationErrorFile: (serviceContext, data) =>
70
+ request(buildSdkUrl(serviceContext, '/imports/error-file'), {
71
+ method: 'POST',
72
+ data,
73
+ }),
74
+ quickExport: (serviceContext, data) =>
75
+ request(buildSdkUrl(serviceContext, '/exports/quick'), {
76
+ method: 'POST',
77
+ data,
78
+ }),
79
+ templateExport: (serviceContext, data) =>
80
+ request(buildSdkUrl(serviceContext, '/exports/template'), {
81
+ method: 'POST',
82
+ data,
83
+ }),
84
+ queryRecentTasks: (data) =>
85
+ request(`${CONFIG_PREFIX}/tasks/recent`, {
86
+ method: 'POST',
87
+ data,
88
+ }),
89
+ queryTask: (serviceContext, taskCode) => {
90
+ if (!taskCode) {
91
+ return Promise.reject(new Error('taskId is required'));
92
+ }
93
+ return request(buildSdkUrl(serviceContext, '/tasks/progress'), {
94
+ method: 'POST',
95
+ data: { taskId: taskCode },
96
+ });
97
+ },
98
+ };
99
+
100
+ return {
101
+ ...services,
102
+ ...overrides,
103
+ };
104
+ };
105
+
106
+ /**
107
+ * 使用宿主项目的 Umi 请求实例创建默认导入导出服务。
108
+ */
109
+ export const defaultImportExportServices = createImportExportServices(
110
+ (url, options) => umiRequest(url, options),
111
+ );
112
+
113
+ /**
114
+ * 将业务侧差异服务合并到默认导入导出服务。
115
+ */
116
+ export const resolveImportExportServices = (
117
+ overrides?: Partial<ImportExportServices>,
118
+ ): ImportExportServices => ({
119
+ ...defaultImportExportServices,
120
+ ...(overrides || {}),
121
+ });
122
+
123
+ export const unwrapResponse = <T = any>(response: any): T =>
124
+ (response?.data?.data || response?.data || response) as T;
125
+
126
+ export const getItems = <T = any>(response: any): T[] => {
127
+ const data: any = unwrapResponse(response);
128
+ return data?.records || data?.items || data?.list || [];
129
+ };
130
+
131
+ export const normalizeTask = (task: any) => {
132
+ const attributes = task?.attributes || {};
133
+ const result = task?.result || {};
134
+ const taskStatus = task?.taskStatus || task?.status || attributes?.status;
135
+ const completedCount =
136
+ attributes?.successCount != null || attributes?.failedCount != null
137
+ ? Number(attributes?.successCount || 0) +
138
+ Number(attributes?.failedCount || 0)
139
+ : undefined;
140
+ const terminal = [
141
+ 'SUCCESS',
142
+ 'PARTIAL_SUCCESS',
143
+ 'PASSED',
144
+ 'COMPLETED_WITH_ERRORS',
145
+ 'FAILED',
146
+ 'CANCELLED',
147
+ ].includes(taskStatus);
148
+ return {
149
+ ...task,
150
+ taskId: task?.taskId || result?.taskId || task?.taskCode,
151
+ taskType:
152
+ task?.taskType || attributes?.taskType || attributes?.operationType,
153
+ taskStatus,
154
+ progress: task?.progress ?? attributes?.percent,
155
+ processedCount:
156
+ task?.processedCount ??
157
+ task?.processedRows ??
158
+ attributes?.processedCount ??
159
+ completedCount ??
160
+ result?.rowCount,
161
+ totalCount:
162
+ task?.totalCount ??
163
+ task?.totalRows ??
164
+ attributes?.totalCount ??
165
+ (terminal ? completedCount ?? result?.rowCount : undefined),
166
+ elapsedSeconds: task?.elapsedSeconds ?? task?.durationSeconds,
167
+ successCount:
168
+ task?.successCount ??
169
+ task?.successRows ??
170
+ attributes?.successCount ??
171
+ result?.rowCount,
172
+ failedCount:
173
+ task?.failedCount ?? task?.failedRows ?? attributes?.failedCount,
174
+ skippedCount: task?.skippedCount ?? task?.skippedRows,
175
+ operatorName: task?.operatorName ?? task?.operator,
176
+ fileName: task?.fileName ?? result?.objectKey,
177
+ createdTime: task?.createdTime ?? task?.createTime,
178
+ resultDownloadUrl:
179
+ task?.resultDownloadUrl || task?.resultFileUrl || result?.fileUrl,
180
+ errorDownloadUrl: task?.errorDownloadUrl || task?.errorFileUrl,
181
+ errorMessage: task?.errorMessage ?? attributes?.errorMessage,
182
+ };
183
+ };
184
+
185
+ const taskTypeNames: Record<string, string> = {
186
+ IMPORT_VALIDATION: '导入校验',
187
+ IMPORT_EXECUTION: '导入执行',
188
+ IMPORT: '导入执行',
189
+ EXPORT: '导出',
190
+ TEMPLATE_DOWNLOAD: '模板下载',
191
+ };
192
+
193
+ export const taskTypeName = (taskType?: string) =>
194
+ taskTypeNames[String(taskType || '').toUpperCase()] || '文件任务';
195
+
196
+ export const isConcurrentLimit = (response: any) => {
197
+ const candidates = [
198
+ response,
199
+ response?.data,
200
+ response?.response,
201
+ response?.response?.data,
202
+ ];
203
+ return candidates.some(
204
+ (item) =>
205
+ item?.code === concurrentLimitCode ||
206
+ String(item?.message || item?.msg || '').includes(concurrentLimitCode),
207
+ );
208
+ };
@@ -0,0 +1,21 @@
1
+ const SDK_PREFIX = '/import-export';
2
+
3
+ /**
4
+ * 校验并规范化业务功能服务上下文。
5
+ */
6
+ export const normalizeServiceContext = (serviceContext: string) => {
7
+ const value = String(serviceContext || '').trim();
8
+ if (
9
+ !/^\/[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*$/.test(value) ||
10
+ value.includes('..')
11
+ ) {
12
+ throw new Error('业务功能服务上下文配置无效');
13
+ }
14
+ return value.replace(/\/+$/, '');
15
+ };
16
+
17
+ /**
18
+ * 拼接导入导出 SDK 接口地址。
19
+ */
20
+ export const buildSdkUrl = (serviceContext: string, path: string) =>
21
+ `${normalizeServiceContext(serviceContext)}${SDK_PREFIX}${path}`;
@@ -0,0 +1,180 @@
1
+ /**
2
+ * 导入导出的操作类型。
3
+ */
4
+ export type ImportExportOperationType = 'IMPORT' | 'EXPORT';
5
+
6
+ /**
7
+ * 导入导出功能的业务侧配置。
8
+ */
9
+ export interface ImportExportConfig {
10
+ documentName: string;
11
+ getQueryParams?: () => Record<string, any>;
12
+ getResultCount?: () => number | undefined;
13
+ }
14
+
15
+ /**
16
+ * 业务功能解析结果。
17
+ */
18
+ export interface ImportExportBusinessFunction {
19
+ functionCode: string;
20
+ functionName?: string;
21
+ serviceName: string;
22
+ serviceContext: string;
23
+ status: number;
24
+ }
25
+
26
+ /**
27
+ * 一次导入或导出操作所需的请求上下文。
28
+ */
29
+ export interface ImportExportRequestContext {
30
+ businessFunctionCode: string;
31
+ serviceContext: string;
32
+ operationType: ImportExportOperationType;
33
+ conditions?: Record<string, any>;
34
+ }
35
+
36
+ /**
37
+ * 导入导出模板摘要。
38
+ */
39
+ export interface ImportExportTemplate {
40
+ templateCode: string;
41
+ templateName: string;
42
+ visibility?: 'PUBLIC' | 'PERSONAL';
43
+ businessFunctionCode?: string;
44
+ defaultFlag?: boolean;
45
+ enabled?: boolean;
46
+ metadataEntityCode?: string;
47
+ fieldCount?: number;
48
+ fieldNames?: string[];
49
+ }
50
+
51
+ /**
52
+ * 模板字段定义。
53
+ */
54
+ export interface ImportExportTemplateField {
55
+ fieldCode: string;
56
+ displayName?: string;
57
+ mapped?: boolean;
58
+ required?: boolean;
59
+ groupKey?: boolean;
60
+ fieldStatus?: string;
61
+ }
62
+
63
+ /**
64
+ * 导入导出异步任务。
65
+ */
66
+ export interface FileTask {
67
+ taskId: string;
68
+ taskType: string;
69
+ templateName?: string;
70
+ taskStatus: string;
71
+ progress?: number;
72
+ processedCount?: number;
73
+ totalCount?: number;
74
+ elapsedSeconds?: number;
75
+ successCount?: number;
76
+ failedCount?: number;
77
+ skippedCount?: number;
78
+ operatorName?: string;
79
+ fileName?: string;
80
+ createdTime?: string;
81
+ resultDownloadUrl?: string;
82
+ errorDownloadUrl?: string;
83
+ errorMessage?: string;
84
+ serviceContext?: string;
85
+ }
86
+
87
+ /**
88
+ * 业务项目请求函数需要支持的最小请求参数。
89
+ */
90
+ export interface ImportExportRequestOptions {
91
+ method: 'GET' | 'POST';
92
+ data?: any;
93
+ params?: Record<string, any>;
94
+ responseType?: 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData';
95
+ }
96
+
97
+ /**
98
+ * 由业务项目注入的请求函数。
99
+ */
100
+ export type ImportExportRequest = (
101
+ url: string,
102
+ options: ImportExportRequestOptions,
103
+ ) => Promise<any>;
104
+
105
+ /**
106
+ * 导入导出流程依赖的后端服务集合。
107
+ */
108
+ export interface ImportExportServices {
109
+ resolveBusinessFunction: (businessFunctionCode: string) => Promise<any>;
110
+ queryTemplates: (data: Record<string, any>) => Promise<any>;
111
+ queryTemplateFields: (data: Record<string, any>) => Promise<any>;
112
+ uploadFile: (file: File) => Promise<any>;
113
+ downloadTemplate: (
114
+ templateCode: string,
115
+ data: Record<string, any>,
116
+ ) => Promise<any>;
117
+ previewImport: (
118
+ serviceContext: string,
119
+ data: Record<string, any>,
120
+ ) => Promise<any>;
121
+ executeImport: (
122
+ serviceContext: string,
123
+ data: Record<string, any>,
124
+ ) => Promise<any>;
125
+ downloadValidationErrorFile: (
126
+ serviceContext: string,
127
+ data: Record<string, any>,
128
+ ) => Promise<any>;
129
+ quickExport: (
130
+ serviceContext: string,
131
+ data: Record<string, any>,
132
+ ) => Promise<any>;
133
+ templateExport: (
134
+ serviceContext: string,
135
+ data: Record<string, any>,
136
+ ) => Promise<any>;
137
+ queryRecentTasks: (data: Record<string, any>) => Promise<any>;
138
+ queryTask: (serviceContext: string, taskCode: string) => Promise<any>;
139
+ }
140
+
141
+ /**
142
+ * 导入导出操作区属性。
143
+ */
144
+ export interface ImportExportActionsProps {
145
+ /** 导入导出业务配置。 */
146
+ config: ImportExportConfig;
147
+ /** 导入导出服务集合。 */
148
+ services?: Partial<ImportExportServices>;
149
+ /** 导入按钮权限编码。 */
150
+ importCode: string;
151
+ /** 快速导出按钮权限编码。 */
152
+ quickExportCode: string;
153
+ /** 模板导出按钮权限编码。 */
154
+ templateExportCode: string;
155
+ /** 任务中心路由。 */
156
+ taskCenterPath?: string;
157
+ /** 是否显示最近任务入口。 */
158
+ showTaskDrawer?: boolean;
159
+ /** 覆盖默认任务中心跳转行为。 */
160
+ onNavigateTaskCenter?: (path: string) => void;
161
+ }
162
+
163
+ /**
164
+ * 根据业务配置和后端服务上下文生成一次导入或导出请求上下文。
165
+ */
166
+ export const createRequestContext = (
167
+ config: ImportExportConfig,
168
+ businessFunctionCode: string,
169
+ serviceContext: string,
170
+ operationType: ImportExportOperationType,
171
+ ): ImportExportRequestContext => {
172
+ return {
173
+ businessFunctionCode,
174
+ serviceContext,
175
+ operationType,
176
+ ...(operationType === 'EXPORT'
177
+ ? { conditions: config.getQueryParams?.() || {} }
178
+ : {}),
179
+ };
180
+ };