@bit-sun/business-component 4.2.0-alpha.28 → 4.2.0-alpha.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.
Files changed (44) hide show
  1. package/.fatherrc.ts +1 -1
  2. package/dist/components/Business/ImportExport/ExportButton/ModalTitle.d.ts +11 -0
  3. package/dist/components/Business/ImportExport/ExportButton/TemplatePicker.d.ts +13 -0
  4. package/dist/components/Business/ImportExport/ExportButton/index.d.ts +15 -0
  5. package/dist/components/Business/ImportExport/ImportWizard/Preview.d.ts +11 -0
  6. package/dist/components/Business/ImportExport/ImportWizard/index.d.ts +15 -0
  7. package/dist/components/Business/ImportExport/TaskDrawer/index.d.ts +15 -0
  8. package/dist/components/Business/ImportExport/TaskProgress/index.d.ts +15 -0
  9. package/dist/components/Business/ImportExport/businessFunction.d.ts +15 -0
  10. package/dist/components/Business/ImportExport/index.d.ts +14 -0
  11. package/dist/components/Business/ImportExport/sceneCapability.d.ts +20 -0
  12. package/dist/components/Business/ImportExport/services/importExport.d.ts +22 -0
  13. package/dist/components/Business/ImportExport/services/routing.d.ts +8 -0
  14. package/dist/components/Business/ImportExport/types.d.ts +134 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.esm.js +2465 -10
  17. package/dist/index.js +2484 -7
  18. package/dist/utils/auth.d.ts +4 -0
  19. package/docs/error-record.md +52 -0
  20. package/docs/task-records/2026-07-31-import-export-extraction.md +73 -0
  21. package/package.json +1 -1
  22. package/src/components/Business/AddSelectBusiness/index.tsx +1 -1
  23. package/src/components/Business/ImportExport/ExportButton/ModalTitle.tsx +27 -0
  24. package/src/components/Business/ImportExport/ExportButton/TemplatePicker.tsx +424 -0
  25. package/src/components/Business/ImportExport/ExportButton/index.module.less +382 -0
  26. package/src/components/Business/ImportExport/ExportButton/index.tsx +273 -0
  27. package/src/components/Business/ImportExport/ImportWizard/Preview.tsx +129 -0
  28. package/src/components/Business/ImportExport/ImportWizard/index.module.less +360 -0
  29. package/src/components/Business/ImportExport/ImportWizard/index.tsx +679 -0
  30. package/src/components/Business/ImportExport/TaskDrawer/index.tsx +285 -0
  31. package/src/components/Business/ImportExport/TaskProgress/index.tsx +267 -0
  32. package/src/components/Business/ImportExport/businessFunction.ts +29 -0
  33. package/src/components/Business/ImportExport/index.md +104 -0
  34. package/src/components/Business/ImportExport/index.tsx +170 -0
  35. package/src/components/Business/ImportExport/sceneCapability.ts +28 -0
  36. package/src/components/Business/ImportExport/services/importExport.ts +208 -0
  37. package/src/components/Business/ImportExport/services/routing.ts +21 -0
  38. package/src/components/Business/ImportExport/types.ts +180 -0
  39. package/src/components/Business/SearchSelect/BusinessUtils.tsx +1 -1
  40. package/src/components/Functional/SearchSelect/utils.tsx +0 -1
  41. package/src/index.ts +2 -1
  42. package/src/typings/umi.d.ts +9 -0
  43. package/src/utils/LocalstorageUtils.ts +1 -1
  44. package/src/utils/auth.ts +39 -2
@@ -0,0 +1,170 @@
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
+ * 统一承载导入、快速导出、模板导出和文件任务入口。
23
+ */
24
+ export const ImportExportActions: React.FC<ImportExportActionsProps> = ({
25
+ config,
26
+ services: serviceOverrides,
27
+ importCode,
28
+ quickExportCode,
29
+ templateExportCode,
30
+ taskCenterPath = '/configure/importExport/taskCenter',
31
+ showTaskDrawer = true,
32
+ onNavigateTaskCenter,
33
+ }) => {
34
+ const [importVisible, setImportVisible] = useState(false);
35
+ const [importRouteLoading, setImportRouteLoading] = useState(false);
36
+ const [importContext, setImportContext] =
37
+ useState<ImportExportRequestContext>();
38
+ const [tasks, setTasks] = useState<FileTask[]>([]);
39
+ const services = useMemo(
40
+ () => resolveImportExportServices(serviceOverrides),
41
+ [serviceOverrides],
42
+ );
43
+ const showImport = !!authFunc(importCode);
44
+ const showQuickExport = !!authFunc(quickExportCode);
45
+ const showTemplateExport = !!authFunc(templateExportCode);
46
+ const authCodes = {
47
+ importCode,
48
+ quickExportCode,
49
+ templateExportCode,
50
+ };
51
+ const taskBusinessFunctionCodes = Array.from(
52
+ new Set(
53
+ [
54
+ resolveBusinessFunctionCode('IMPORT', authCodes),
55
+ resolveBusinessFunctionCode('EXPORT', authCodes),
56
+ ].filter(Boolean),
57
+ ),
58
+ );
59
+
60
+ /**
61
+ * 解析当前操作使用的业务功能和服务上下文。
62
+ */
63
+ const resolveRequestContext = async (
64
+ operationType: ImportExportOperationType,
65
+ ) => {
66
+ const businessFunctionCode = resolveBusinessFunctionCode(
67
+ operationType,
68
+ authCodes,
69
+ );
70
+ if (!businessFunctionCode) {
71
+ message.warning(BUSINESS_FUNCTION_UNAVAILABLE);
72
+ return undefined;
73
+ }
74
+ try {
75
+ const response = await services.resolveBusinessFunction(
76
+ businessFunctionCode,
77
+ );
78
+ const resolved = response?.data?.data || response?.data || response;
79
+ if (!resolved?.serviceContext || Number(resolved.status) !== 1) {
80
+ throw new Error(BUSINESS_FUNCTION_UNAVAILABLE);
81
+ }
82
+ return createRequestContext(
83
+ config,
84
+ businessFunctionCode,
85
+ resolved.serviceContext as string,
86
+ operationType,
87
+ );
88
+ } catch (error) {
89
+ message.warning(BUSINESS_FUNCTION_UNAVAILABLE);
90
+ return undefined;
91
+ }
92
+ };
93
+
94
+ const openImport = async () => {
95
+ setImportRouteLoading(true);
96
+ try {
97
+ const context = await resolveRequestContext('IMPORT');
98
+ if (!context) return;
99
+ setImportContext(context);
100
+ setImportVisible(true);
101
+ } finally {
102
+ setImportRouteLoading(false);
103
+ }
104
+ };
105
+
106
+ const addTask = useCallback((task: FileTask) => {
107
+ if (!task?.taskId) return;
108
+ setTasks((items) => [
109
+ task,
110
+ ...items.filter((item) => item.taskId !== task.taskId),
111
+ ]);
112
+ }, []);
113
+
114
+ return (
115
+ <>
116
+ <Space>
117
+ {showImport && (
118
+ <Button loading={importRouteLoading} onClick={openImport}>
119
+ 导入
120
+ </Button>
121
+ )}
122
+ {(showQuickExport || showTemplateExport) && (
123
+ <ExportButton
124
+ config={config}
125
+ services={services}
126
+ resolveRequestContext={() => resolveRequestContext('EXPORT')}
127
+ showQuickExport={showQuickExport}
128
+ showTemplateExport={showTemplateExport}
129
+ onTaskCreated={addTask}
130
+ />
131
+ )}
132
+ {showTaskDrawer && (
133
+ <TaskDrawer
134
+ businessFunctionCodes={taskBusinessFunctionCodes}
135
+ services={services}
136
+ taskCenterPath={taskCenterPath}
137
+ onNavigateTaskCenter={onNavigateTaskCenter}
138
+ />
139
+ )}
140
+ </Space>
141
+ {importContext && (
142
+ <ImportWizard
143
+ visible={importVisible}
144
+ context={importContext}
145
+ documentName={config.documentName}
146
+ services={services}
147
+ onClose={() => setImportVisible(false)}
148
+ onTaskCreated={addTask}
149
+ />
150
+ )}
151
+ <TaskProgress
152
+ tasks={tasks}
153
+ services={services}
154
+ taskCenterPath={taskCenterPath}
155
+ onNavigateTaskCenter={onNavigateTaskCenter}
156
+ onTaskUpdated={addTask}
157
+ onClose={() => setTasks([])}
158
+ />
159
+ </>
160
+ );
161
+ };
162
+
163
+ export { default as ImportWizard } from './ImportWizard';
164
+ export { default as ExportButton } from './ExportButton';
165
+ export { default as TaskProgress } from './TaskProgress';
166
+ export { default as TaskDrawer } from './TaskDrawer';
167
+ export * from './types';
168
+ export * from './services/importExport';
169
+ export * from './sceneCapability';
170
+ 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
+ };
@@ -940,7 +940,7 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
940
940
  ...selectConfigProps,
941
941
  }
942
942
  const tableSearchForm = handleHiddenFields([
943
- { name: 'qp-code-in', label: 'SKC编码', type: 'multipleQueryInput' },
943
+ { name: 'qp-code-like', label: 'SKC编码' },
944
944
  { name: 'qp-skcName-like', label: 'SKC名称' },
945
945
  { name: 'qp-itemName-like', label: '商品名称' },
946
946
  { name: 'qp-colorName-in', type: 'select', label: '颜色', field: {
@@ -207,7 +207,6 @@ export const convertOrderNo = (params: any) => {
207
207
  'qp-skuCode-in',
208
208
  'qp-eancode-in',
209
209
  'qp-itemCode-in',
210
- 'qp-code-in',
211
210
  ];
212
211
  for (let i = 0; i < arr.length; i++) {
213
212
  if (params[arr[i]]) {
package/src/index.ts CHANGED
@@ -55,4 +55,5 @@ export { default as ExtendedCollapse } from './components/Common/ExtendedCollaps
55
55
  export { default as Section } from './components/Common/Section';
56
56
  export { default as ParagraphCopier } from './components/Common/ParagraphCopier';
57
57
 
58
- export { default as SystemLog } from './components/Business/SystemLog';
58
+ export { default as SystemLog } from './components/Business/SystemLog';
59
+ export * from './components/Business/ImportExport';
@@ -0,0 +1,9 @@
1
+ declare module 'umi' {
2
+ /**
3
+ * 宿主 Umi 项目提供的请求函数。
4
+ */
5
+ export const request: (
6
+ url: string,
7
+ options?: Record<string, any>,
8
+ ) => Promise<any>;
9
+ }
@@ -1,4 +1,4 @@
1
- import ENUM from '@/utils/enumConfig';
1
+ import ENUM from './enumConfig';
2
2
 
3
3
  const resposne =()=> JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.USER_INFO) || '{}');
4
4
 
package/src/utils/auth.ts CHANGED
@@ -1,4 +1,41 @@
1
- import { getMenuAuthDataKey } from '@/utils/LocalstorageUtils';
1
+ import { getLimitMenuDataKey, getMenuAuthDataKey } from './LocalstorageUtils';
2
+
3
+ /**
4
+ * 根据上游权限编码获取关联的导入导出业务功能编码。
5
+ */
6
+ export const getRelationTemplateCode = (authCode: string): string => {
7
+ if (!authCode) return '';
8
+
9
+ let menuData: any[] = [];
10
+ try {
11
+ const storedMenuData = JSON.parse(
12
+ localStorage.getItem(getLimitMenuDataKey()) || '[]',
13
+ );
14
+ menuData = Array.isArray(storedMenuData) ? storedMenuData : [];
15
+ } catch (error) {
16
+ return '';
17
+ }
18
+
19
+ let buttonDataList: any[] = [];
20
+ /**
21
+ * 递归收集叶子菜单下的按钮配置。
22
+ */
23
+ const collectButtons = (items: any[]) => {
24
+ items.forEach((item: any) => {
25
+ if (item?.children?.length) {
26
+ collectButtons(item.children);
27
+ } else {
28
+ buttonDataList = [...buttonDataList, ...(item?.buttons || [])];
29
+ }
30
+ });
31
+ };
32
+ collectButtons(menuData);
33
+
34
+ return (
35
+ buttonDataList.find((item) => item.bizCode === authCode)
36
+ ?.relationExcelTemplateCode || ''
37
+ );
38
+ };
2
39
 
3
40
  // 判断某个按钮/菜单 是否有权限,返回布尔值
4
41
  export const authFunc = (code: string) => {
@@ -36,4 +73,4 @@ export const handleJudgeAuthButtons = (buttonCodeArray: any[]) => {
36
73
  export const shouldUseAuth = () => {
37
74
  // @ts-ignore
38
75
  return window.__POWERED_BY_WUJIE__ ? true : false;
39
- };
76
+ };