@cfmm/umi-plugins-ui-v2 0.0.14 → 0.0.16

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 (41) hide show
  1. package/dist/cjs/components/CrudTable.tpl +117 -72
  2. package/dist/cjs/locales/en-US.d.ts +1 -0
  3. package/dist/cjs/locales/enUS/common.d.ts +1 -0
  4. package/dist/cjs/locales/enUS/common.js +1 -0
  5. package/dist/cjs/locales/enUS/index.d.ts +1 -0
  6. package/dist/cjs/locales/th-TH.d.ts +1 -0
  7. package/dist/cjs/locales/zh-CN.d.ts +1 -0
  8. package/dist/cjs/locales/zh-TW.d.ts +1 -0
  9. package/dist/cjs/locales/zhCN/common.d.ts +1 -0
  10. package/dist/cjs/locales/zhCN/common.js +1 -0
  11. package/dist/cjs/locales/zhCN/index.d.ts +1 -0
  12. package/dist/cjs/locales/zhTW/common.d.ts +1 -0
  13. package/dist/cjs/locales/zhTW/common.js +1 -0
  14. package/dist/cjs/locales/zhTW/index.d.ts +1 -0
  15. package/dist/cjs/types/CrudTableTypes.d.ts +1 -1
  16. package/dist/cjs/types/CrudTableTypes.js +1 -1
  17. package/dist/cjs/utils/excelHelper.tpl +41 -17
  18. package/dist/cjs/utils/importHelper.tpl +50 -11
  19. package/dist/cjs/utils/utils.tpl +11 -1
  20. package/dist/cjs/writeTmpFile/writeTypes.js +1 -1
  21. package/dist/esm/components/CrudTable.tpl +117 -72
  22. package/dist/esm/locales/en-US.d.ts +1 -0
  23. package/dist/esm/locales/enUS/common.d.ts +1 -0
  24. package/dist/esm/locales/enUS/common.js +1 -0
  25. package/dist/esm/locales/enUS/index.d.ts +1 -0
  26. package/dist/esm/locales/th-TH.d.ts +1 -0
  27. package/dist/esm/locales/zh-CN.d.ts +1 -0
  28. package/dist/esm/locales/zh-TW.d.ts +1 -0
  29. package/dist/esm/locales/zhCN/common.d.ts +1 -0
  30. package/dist/esm/locales/zhCN/common.js +1 -0
  31. package/dist/esm/locales/zhCN/index.d.ts +1 -0
  32. package/dist/esm/locales/zhTW/common.d.ts +1 -0
  33. package/dist/esm/locales/zhTW/common.js +1 -0
  34. package/dist/esm/locales/zhTW/index.d.ts +1 -0
  35. package/dist/esm/types/CrudTableTypes.d.ts +1 -1
  36. package/dist/esm/types/CrudTableTypes.js +1 -1
  37. package/dist/esm/utils/excelHelper.tpl +41 -17
  38. package/dist/esm/utils/importHelper.tpl +50 -11
  39. package/dist/esm/utils/utils.tpl +11 -1
  40. package/dist/esm/writeTmpFile/writeTypes.js +1 -1
  41. package/package.json +1 -1
@@ -18,6 +18,10 @@ export interface ColumnProcessOptions<T> {
18
18
 
19
19
  export type DataRowGenerator = () => Promise<any[]>;
20
20
 
21
+ export type CfProColumns<T = any, ValueType = 'text'> = ProColumns<T, ValueType> & {
22
+ hideInExport?: boolean;
23
+ };
24
+
21
25
  // 延时函数
22
26
  // eslint-disable-next-line no-promise-executor-return
23
27
  export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -38,9 +42,9 @@ export const extractTextFromJSX = (
38
42
  React.Children.forEach(jsx, (child) => {
39
43
  if (React.isValidElement(child)) {
40
44
  if (typeof child.props.children === 'string' || typeof jsx === 'number' || Array.isArray(child.props.children)) {
41
- if(Array.isArray(child.props.children)) {
45
+ if (Array.isArray(child.props.children)) {
42
46
  textArray.push(child.props.children.join(' '));
43
- }else {
47
+ } else {
44
48
  textArray.push(child.props.children);
45
49
  }
46
50
  } else {
@@ -167,6 +171,7 @@ export const genExcel = (
167
171
  */
168
172
  return workBook.xlsx.writeBuffer();
169
173
  })
174
+ // @ts-ignore
170
175
  .then((blob: Blob) => {
171
176
  /**
172
177
  * 下载文件
@@ -515,19 +520,22 @@ export const convertNumberToCellName = (cellIndex: number): string => {
515
520
  * @param param 列,变更属性,过滤值
516
521
  * @returns
517
522
  */
518
- export const getExportColumns = <T>({
523
+ export const getExportColumns = <T = any>({
519
524
  columns = [],
520
525
  columnsStateMap = {},
521
526
  filters = [],
522
527
  }: {
523
- columns: ProColumns<T>[];
528
+ columns: CfProColumns<T>[];
524
529
  columnsStateMap?: Record<string, ColumnsState>;
525
530
  filters?: any[];
526
531
  }): ProColumns<T>[] => {
532
+ // 只处理显示的子列
527
533
  const filterList = columns.filter((item) => {
534
+ const hideInExport = item.hideInExport ?? item.hideInTable;
535
+
528
536
  return (
529
537
  // 排除隐藏在表格的列
530
- !item.hideInTable &&
538
+ !hideInExport &&
531
539
  // 排除主动过滤的列
532
540
  !filters.includes(item.dataIndex) &&
533
541
  // 排除在于columnsStateMap中且columnsStateMapp[item.dataIndex].show为false的列(排除表格右上角工具隐藏的列)
@@ -596,10 +604,14 @@ export const getExportColumnsWithGroupSupport = <T>(options: ColumnProcessOption
596
604
 
597
605
  /**
598
606
  * 检查列是否应该显示
607
+ * 检查列是否应该出现在导出中
608
+ * hideInExport 未配置时回退到 hideInTable,保持向后兼容
599
609
  */
600
- const shouldShowColumn = (column: ProColumns<T>): boolean => {
610
+ const shouldShowColumn = (column: CfProColumns<T>): boolean => {
611
+ const hideInExport = column.hideInExport ?? column.hideInTable;
612
+
601
613
  return (
602
- !column.hideInTable &&
614
+ !hideInExport &&
603
615
  !filters.includes(column.dataIndex) &&
604
616
  (!columnsStateMap[column.dataIndex as string] || (columnsStateMap[column.dataIndex as string]?.show ?? true))
605
617
  );
@@ -711,6 +723,25 @@ const getFormatValue = (value: any, type: ProColumns<any>['valueType'], getLocal
711
723
  return newValue;
712
724
  };
713
725
 
726
+ export interface GetExportValueForColumnsOptions<T> {
727
+ columns: ProColumns<T>[];
728
+ data: readonly T[];
729
+ /** 获取本地日期时间 */
730
+ getLocalDate?: (date: any) => string | undefined;
731
+ /** 处理百分比 */
732
+ handlePercentChange?: (percent: number) => void;
733
+ /** 获取render中的节点文本Arr,使用textArrJoin字符拼接 */
734
+ textArrJoin?: string;
735
+ /** 每次切割条数 */
736
+ batchSize?: number;
737
+ /** 进度更新间隔,默认每1000条数据更新一次 */
738
+ progressUpdateInterval?: number;
739
+ /** 批处理间的延迟时间,避免UI阻塞 */
740
+ delayMs?: number;
741
+ /** 是否需要处理中划线的字段(空值字段) */
742
+ needHandleCenterlineValue?: boolean;
743
+ }
744
+
714
745
  /**
715
746
  * 根据取值的columns,获取需要导出的数据
716
747
  * @param columns 取值的列(过滤排序后)特殊类型如百分比,日期需要定义valueType
@@ -735,16 +766,8 @@ export const getExportValueForColumns = async <T = any>({
735
766
  batchSize = 500,
736
767
  progressUpdateInterval = batchSize * 2, // 进度更新间隔,默认每次切割条数的2倍
737
768
  delayMs = 30, // 批处理间的延迟时间
738
- }: {
739
- columns: ProColumns<T>[];
740
- data: readonly T[];
741
- getLocalDate?: (date: any) => string | undefined;
742
- handlePercentChange?: (percent: number) => void;
743
- textArrJoin?: string;
744
- batchSize?: number;
745
- progressUpdateInterval?: number;
746
- delayMs?: number;
747
- }): Promise<any[]> => {
769
+ needHandleCenterlineValue,
770
+ }: GetExportValueForColumnsOptions<T>): Promise<any[]> => {
748
771
  // 1. 参数校验
749
772
  if (!columns.length || !data.length) return Promise.resolve([]);
750
773
 
@@ -802,6 +825,7 @@ export const getExportValueForColumns = async <T = any>({
802
825
  const { text, textArray } = extractTextFromJSX(value);
803
826
  value = textArrJoin ? textArray.join(textArrJoin) : text;
804
827
  }
828
+ value = needHandleCenterlineValue ? (value === '-' ? null : value) : value;
805
829
 
806
830
  rowValues.push(value);
807
831
  }
@@ -145,12 +145,26 @@ function convertIndexedPropertiesToArrays(obj: Record<string, any>): any {
145
145
  * @returns
146
146
  */
147
147
  export const handleImportExeclCellValue = (value: unknown, type?: string) => {
148
- if (!value) return;
148
+ if (!value && value !== 0 && value !== '0') return;
149
149
 
150
150
  if (type === 'parenthesisCode') {
151
- return getParenthesisValue(value as string);
151
+ const newValue = getParenthesisValue(value as string);
152
+ return typeof newValue === 'string' ? newValue.trim() : newValue;
152
153
  }
153
- if (value instanceof Date || (type === 'date' && typeof value === 'string')) {
154
+ if (value instanceof Date || (type === 'date' && typeof value === 'string')) {
155
+ if (value instanceof Date) {
156
+ const corrected = new Date(value);
157
+ const seconds = corrected.getSeconds();
158
+
159
+ // 修正读取execl日期精度问题,如果秒数大于10,加1分钟并清零分钟和秒
160
+ if (seconds > 10) {
161
+ corrected.setMinutes(corrected.getMinutes() + 1);
162
+ corrected.setSeconds(0, 0); // 清零秒和毫秒
163
+ }
164
+
165
+ const dateStr = dayjs.utc(corrected).format(UTC_FORMAT);
166
+ return dateStr;
167
+ }
154
168
  return dayjs.utc(value).format(UTC_FORMAT);
155
169
  }
156
170
  if (typeof value === 'string') {
@@ -164,21 +178,34 @@ export const handleImportExeclCellValue = (value: unknown, type?: string) => {
164
178
  * @param keys [] | string,为对象属性名,数组类型并且
165
179
  * @param value 属性值
166
180
  * @param obj 嵌套对象
181
+ * @param options
182
+ * @param options.needHandleUnderlineKey 是否需要处理下划线code
183
+ * @param options.needHandleCenterlineValue 是否需要处理中划线的字段(空值字段)
167
184
  * @returns (['a', 'b', 'c'], 1, {}) => {a: { b: {c : 1} } }
168
185
  */
169
- export const createNestedObjectAndSetValue = (keys: string | string[], value: any, obj: Record<string, any>, needHandleUnderline = true) => {
186
+ export const createNestedObjectAndSetValue = (
187
+ keys: string | string[],
188
+ value: any,
189
+ obj: Record<string, any>,
190
+ options: Omit<HandleImportListOptions, 'hasRowNum'>
191
+ ) => {
170
192
  if (!keys.length) return obj;
171
193
  // 过滤没有定义code的字段
172
194
  if (typeof keys === 'string' && keys.startsWith('__EMPTY')) return obj;
173
195
 
196
+ const { needHandleUnderlineKey = true, needHandleCenterlineValue = true } = options;
197
+
174
198
  //为了不改变原对象
175
199
  const cloneObj = { ...obj };
176
200
  // 当前操作的嵌套对象层级,从外到内
177
201
  let current: any = cloneObj;
178
202
  // 如果keys是字符串,转为数组
179
- const newKeys = typeof keys === 'string' ? needHandleUnderline ? keys.split('_') : [keys] : keys;
203
+ const newKeys = typeof keys === 'string' ? (needHandleUnderlineKey ? keys.split('_') : [keys]) : keys;
180
204
  // 最后一个键下标
181
205
  const lastIndex = newKeys.length - 1;
206
+ // 处理中划线的字段(空值字段)
207
+ const handleValue = needHandleCenterlineValue ? (value === '-' ? null : value) : value;
208
+
182
209
  // 转为嵌套对象
183
210
  newKeys.forEach((key) => {
184
211
  if (current[key] === undefined) {
@@ -188,13 +215,13 @@ export const createNestedObjectAndSetValue = (keys: string | string[], value: an
188
215
  if (key === newKeys[lastIndex]) {
189
216
  // 判断是不是要取单元格括号中的code
190
217
  const handleKey = key.split('?');
191
- if (handleKey.length === 2 && value) {
218
+ if (handleKey.length === 2 && handleValue) {
192
219
  // 取出单元格中的code并删除原有带?的字段,使用?前的字符串作为字段名,?后的作为识别类型
193
- current[handleKey[0]] = handleImportExeclCellValue(value, parse(handleKey[1])?.type as string);
220
+ current[handleKey[0]] = handleImportExeclCellValue(handleValue, parse(handleKey[1])?.type as string);
194
221
  delete current[key];
195
222
  } else {
196
223
  // 处理导入单元格的值
197
- current[key] = handleImportExeclCellValue(value);
224
+ current[key] = handleImportExeclCellValue(handleValue);
198
225
  }
199
226
  } else {
200
227
  // 移动到下一层级
@@ -217,14 +244,26 @@ export const createNestedObjectAndSetValue = (keys: string | string[], value: an
217
244
  return convertIndexedPropertiesToArrays(cloneObj);
218
245
  };
219
246
 
247
+ export interface HandleImportListOptions {
248
+ /** 是否添加表格行号 */
249
+ hasRowNum?: boolean;
250
+ /** 是否需要处理下划线code */
251
+ needHandleUnderlineKey?: boolean;
252
+ /** 是否需要处理中划线的字段(空值字段) */
253
+ needHandleCenterlineValue?: boolean;
254
+ }
255
+
220
256
  /**
221
257
  * 处理execl导入的数据
222
258
  * @param {T[]} list 列表
223
259
  * @param {number} hasRowNum 是否添加表格行号
224
260
  * @returns {T[]} list
225
261
  */
226
- export const handleImportList = <T extends Record<string, any> = any[]>(list: T[], options: { hasRowNum?: boolean, needHandleUnderline?: boolean } = {}): T[] => {
227
- const { hasRowNum = true, needHandleUnderline = true } = options;
262
+ export const handleImportList = <T extends Record<string, any> = any[]>(
263
+ list: T[],
264
+ options: HandleImportListOptions = {},
265
+ ): T[] => {
266
+ const { hasRowNum = true, ...restOptions } = options;
228
267
 
229
268
  list.shift();
230
269
  const newList: T[] = list.map((item: any, idx) => {
@@ -235,7 +274,7 @@ export const handleImportList = <T extends Record<string, any> = any[]>(list: T[
235
274
  }
236
275
  // 处理获取到的数据转换成需要的格式
237
276
  Object.entries(item).forEach((entry) => {
238
- newObj = createNestedObjectAndSetValue(entry[0], entry[1], newObj, needHandleUnderline);
277
+ newObj = createNestedObjectAndSetValue(entry[0], entry[1], newObj, restOptions);
239
278
  });
240
279
  return newObj;
241
280
  });
@@ -115,4 +115,14 @@ export function arrayToTree<T, R = T>(
115
115
  }
116
116
 
117
117
  return result as unknown as R[];
118
- }
118
+ }
119
+
120
+ /**
121
+ * 提取括号中的值
122
+ * @param str
123
+ * @returns
124
+ */
125
+ export const getParenthesisValue = (str: string) => {
126
+ const matches = str.match(/\((.*?)\)/);
127
+ return matches ? matches[1] : null;
128
+ };
@@ -8,5 +8,5 @@ var _types = require("../types");
8
8
  // 修改方法,不再尝试读取外部文件
9
9
  var _default = exports.default = {
10
10
  path: 'types.d.ts',
11
- content: "\n import React from 'react';\n import { ModalProps, DrawerProps, SelectProps, DatePickerProps, UploadProps, UploadFile, TooltipProps, ButtonProps, TabsProps, SwitchProps, FloatButtonProps, StepsProps, FlexProps, TagProps } from 'antd';\n import { PresetColorType, PresetStatusColorType } from \"antd/lib/_util/colors\";\n import { AutoCompleteProps } from 'antd/es/auto-complete';\n import { RangePickerProps } from 'antd/lib/date-picker';\n import { LiteralUnion } from \"antd/lib/_util/type\";\n import { IconComponentProps } from '@ant-design/icons/lib/components/Icon';\n import { ActionType, ProFormItemProps, ProColumns, ProTableProps, DrawerFormProps, ModalFormProps, PageContainerProps, ProFormInstance } from '@ant-design/pro-components';\n import dayjs, { OpUnitType } from 'dayjs';\n import { IEditorConfig, IToolbarConfig } from '@wangeditor/editor';\n import type { DragEndEvent } from '@dnd-kit/core';\n import { fileTypeMap } from './components'; \n\n\n ".concat(_types.servicesTypes, "\n\n ").concat(_types.HighlightStrTypes, "\n\n ").concat(_types.DropdownButtonTypes, "\n\n ").concat(_types.DynamicIconTypes, "\n\n ").concat(_types.MyFooterToolbarTypes, "\n\n ").concat(_types.QrCodeModalTypes, "\n\n ").concat(_types.MenuFooterTypes, "\n\n ").concat(_types.EditMultiLangFormTypes, "\n\n ").concat(_types.MySelectTypes, "\n\n ").concat(_types.MySelectLangTypes, "\n\n ").concat(_types.PermissionSelectTypes, "\n\n ").concat(_types.DataPermissionSelectTypes, "\n\n ").concat(_types.DatePickerTypes, "\n\n ").concat(_types.RandomAvatarTypes, "\n\n ").concat(_types.RefDrawerFormTypes, "\n\n ").concat(_types.ViewTableItemDrawerTypes, "\n\n ").concat(_types.WangEditorTypes, "\n\n ").concat(_types.MyPageContainerTypes, "\n\n ").concat(_types.MyTagListTypes, "\n\n ").concat(_types.VolumeFormItemTypes, "\n\n ").concat(_types.ImportExeclTypes, "\n\n ").concat(_types.MyUploadTypes, "\n\n ").concat(_types.ReportTableTypes, "\n\n ").concat(_types.DicDropDownListTypes, "\n\n ").concat(_types.ActionLogDrawerTypes, "\n\n ").concat(_types.DndTabsTypes, "\n\n ").concat(_types.ImportDataUploadTypes, "\n\n ").concat(_types.AvatarDropdownTypes, "\n\n ").concat(_types.HeaderSearchTypes, "\n\n ").concat(_types.ThemeSwitchTypes, "\n\n ").concat(_types.GlobalHeaderTypes, "\n\n ").concat(_types.KeepAliveTabsTypes, "\n\n ").concat(_types.ExportPageWrapperTypes, "\n\n ").concat(_types.MySetpsTypes, "\n\n ").concat(_types.CrudTableTypes, "\n\n ").concat(_types.DndTagTypes, "\n ")
11
+ content: "\n import React from 'react';\n import { ModalProps, DrawerProps, SelectProps, DatePickerProps, UploadProps, UploadFile, TooltipProps, ButtonProps, TabsProps, SwitchProps, FloatButtonProps, StepsProps, FlexProps, TagProps } from 'antd';\n import { PresetColorType, PresetStatusColorType } from \"antd/lib/_util/colors\";\n import { AutoCompleteProps } from 'antd/es/auto-complete';\n import { RangePickerProps } from 'antd/lib/date-picker';\n import { LiteralUnion } from \"antd/lib/_util/type\";\n import { IconComponentProps } from '@ant-design/icons/lib/components/Icon';\n import { ActionType, ProFormItemProps, ProColumns, ProTableProps, DrawerFormProps, ModalFormProps, PageContainerProps, ProFormInstance } from '@ant-design/pro-components';\n import dayjs, { OpUnitType } from 'dayjs';\n import { IEditorConfig, IToolbarConfig } from '@wangeditor/editor';\n import type { DragEndEvent } from '@dnd-kit/core';\n import { fileTypeMap } from './components'; \n import { ExcelExportOptions } from './utils/excelHelper';\n import { HandleImportListOptions } from './utils/importHelper';\n\n\n ".concat(_types.servicesTypes, "\n\n ").concat(_types.HighlightStrTypes, "\n\n ").concat(_types.DropdownButtonTypes, "\n\n ").concat(_types.DynamicIconTypes, "\n\n ").concat(_types.MyFooterToolbarTypes, "\n\n ").concat(_types.QrCodeModalTypes, "\n\n ").concat(_types.MenuFooterTypes, "\n\n ").concat(_types.EditMultiLangFormTypes, "\n\n ").concat(_types.MySelectTypes, "\n\n ").concat(_types.MySelectLangTypes, "\n\n ").concat(_types.PermissionSelectTypes, "\n\n ").concat(_types.DataPermissionSelectTypes, "\n\n ").concat(_types.DatePickerTypes, "\n\n ").concat(_types.RandomAvatarTypes, "\n\n ").concat(_types.RefDrawerFormTypes, "\n\n ").concat(_types.ViewTableItemDrawerTypes, "\n\n ").concat(_types.WangEditorTypes, "\n\n ").concat(_types.MyPageContainerTypes, "\n\n ").concat(_types.MyTagListTypes, "\n\n ").concat(_types.VolumeFormItemTypes, "\n\n ").concat(_types.ImportExeclTypes, "\n\n ").concat(_types.MyUploadTypes, "\n\n ").concat(_types.ReportTableTypes, "\n\n ").concat(_types.DicDropDownListTypes, "\n\n ").concat(_types.ActionLogDrawerTypes, "\n\n ").concat(_types.DndTabsTypes, "\n\n ").concat(_types.ImportDataUploadTypes, "\n\n ").concat(_types.AvatarDropdownTypes, "\n\n ").concat(_types.HeaderSearchTypes, "\n\n ").concat(_types.ThemeSwitchTypes, "\n\n ").concat(_types.GlobalHeaderTypes, "\n\n ").concat(_types.KeepAliveTabsTypes, "\n\n ").concat(_types.ExportPageWrapperTypes, "\n\n ").concat(_types.MySetpsTypes, "\n\n ").concat(_types.CrudTableTypes, "\n\n ").concat(_types.DndTagTypes, "\n ")
12
12
  };
@@ -16,7 +16,7 @@ import {
16
16
  LangInfoItem,
17
17
  RefDrawerFormRefType,
18
18
  } from '../types';
19
- import { genExcel, genExcelAdvanced, getExportColumns, getExportValueForColumns } from '../utils/excelHelper';
19
+ import { genExcelAdvanced, getExportColumns, getExportValueForColumns } from '../utils/excelHelper';
20
20
  import { handleImportList, showCheckErrorTips } from '../utils/importHelper';
21
21
  import ActionLogDrawer from './ActionLogDrawer';
22
22
  import CreateForm from './AddDrawerForm';
@@ -69,6 +69,8 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
69
69
  updateConfig = {},
70
70
  actionColumnConfig = {} as CrudTableConfig['actionColumnConfig'],
71
71
  downloadTemplate = {},
72
+ exportExcel = {},
73
+ importData = {},
72
74
 
73
75
  onAdd,
74
76
  onView,
@@ -177,6 +179,7 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
177
179
  },
178
180
  );
179
181
 
182
+ // 选择多语言字段
180
183
  const handleSelectMultiLangField = useMemoizedFn(async (multiLang: CrudTableConfig['multiLang']) => {
181
184
  if (!multiLang?.fields) return;
182
185
 
@@ -190,7 +193,10 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
190
193
 
191
194
  await new Promise((resolve) => {
192
195
  Modal.confirm({
193
- title: '导出多语言数据',
196
+ title: formatMessage({
197
+ id: 'cfmmUI.common.button.exportMultiLang.title',
198
+ defaultMessage: '请选择需要导出的字段',
199
+ }),
194
200
  content: (
195
201
  <div>
196
202
  <Radio.Group
@@ -285,29 +291,41 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
285
291
  }
286
292
 
287
293
  // 处理导入数据,正确赋值字段以及转格式
288
- const newList = handleImportList<ExportMultiLangListItem>(list, { needHandleUnderline: false });
294
+ const newList = multiLang.handleImportList
295
+ ? multiLang.handleImportList(list, { needHandleUnderlineKey: false })
296
+ : handleImportList<ExportMultiLangListItem>(list, { needHandleUnderlineKey: false });
289
297
 
290
298
  // 导入校验提示
291
- // const errorMessageList = checkImportExecl(newList);
292
- // if (errorMessageList.length) {
293
- // showCheckErrorTips(errorMessageList);
294
- // return Promise.resolve({ success: false });
295
- // }
296
-
297
- const result = await doAction(
298
- 'IMPORT',
299
- {
299
+ const errorMessageList = multiLang.checkImportExecl?.(newList);
300
+ if (errorMessageList?.length) {
301
+ multiLang.showCheckErrorTips?.(errorMessageList) ?? showCheckErrorTips(errorMessageList);
302
+ return Promise.resolve({ success: false });
303
+ }
304
+
305
+ let result;
306
+
307
+ if (multiLang.submit) {
308
+ result = await multiLang.submit({
300
309
  tableName: tableName,
301
310
  columnName: columnName,
302
- i18nDataList: newList.filter((item) => item.en_US || item.zh_CN || item.zh_TW || item.th_TH),
303
- },
304
- {
305
- actionFn: importMultiLangList,
306
- showMsg: false,
307
- },
308
- );
311
+ list: newList,
312
+ });
313
+ } else {
314
+ result = await doAction(
315
+ 'IMPORT',
316
+ {
317
+ tableName: tableName,
318
+ columnName: columnName,
319
+ i18nDataList: newList.filter((item) => item.en_US || item.zh_CN || item.zh_TW || item.th_TH),
320
+ },
321
+ {
322
+ actionFn: importMultiLangList,
323
+ showMsg: false,
324
+ },
325
+ );
326
+ }
309
327
 
310
- if (result.success) {
328
+ if (result?.success) {
311
329
  actionRef.current?.reload();
312
330
  }
313
331
  return result;
@@ -332,7 +350,7 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
332
350
 
333
351
  setLoading(true);
334
352
  const result = await queryList<T[]>(processedParams, {
335
- queryFn: apis.query,
353
+ queryFn: apis.queryExportData ? apis.queryExportData : apis.query,
336
354
  });
337
355
  setLoading(false);
338
356
 
@@ -510,7 +528,9 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
510
528
  if (!apis.importData && !interceptors.importData?.submitImportListData) return;
511
529
 
512
530
  // 处理导入数据,正确赋值字段以及转格式
513
- const newList = interceptors.importData?.request?.(list) ?? handleImportList<T>(list);
531
+ const newList =
532
+ interceptors.importData?.request?.(list, importData?.handleImportListOptions) ??
533
+ handleImportList<T>(list, importData?.handleImportListOptions);
514
534
 
515
535
  // 导入校验提示
516
536
  const errorMessageList = interceptors.importData?.checkImportExecl?.(newList) || [];
@@ -539,6 +559,9 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
539
559
  * 下载数据为Excel
540
560
  */
541
561
  const handleDownloadExcel = async () => {
562
+ if (exportExcel?.handleDownloadExcel) {
563
+ return exportExcel.handleDownloadExcel(columns, columnsStateMap);
564
+ }
542
565
  const result = await handleSearchAll();
543
566
  if (!result.success || result.error || !result.data) {
544
567
  return;
@@ -548,7 +571,8 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
548
571
 
549
572
  setDownloadButtonLoading(true);
550
573
 
551
- const exportColums = getExportColumns<T>({ columns, columnsStateMap });
574
+ const getExportColumnsFn = exportExcel.getExportColumns ?? getExportColumns;
575
+ const exportColums = getExportColumnsFn<T>({ columns, columnsStateMap });
552
576
 
553
577
  //固定列名
554
578
  let columnsName: any[] = exportColums.map((item) => item.title).filter(Boolean);
@@ -558,45 +582,61 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
558
582
  defaultMessage: '数据列表',
559
583
  });
560
584
 
585
+ const codeList = exportColums.map((item) => item.dataIndex as string).filter(Boolean);
586
+
561
587
  //创建导出Excel
562
- genExcel(fileName + '.xlsx', 'sheet1', columnsName, function () {
563
- //生成数据
564
- return new Promise((resolve) => {
565
- //所有数据行
566
- getExportValueForColumns({
567
- columns: exportColums,
568
- data: result.data,
569
- getLocalDate,
570
- handlePercentChange,
571
- })
572
- .then((allRows) => {
573
- if (allRows.length > MAX_DOWNLOAD) {
574
- Modal.warning({
575
- title: formatMessage({ id: 'common.download.exceed.max.title', defaultMessage: `下载数据过大提醒` }),
576
- content: formatMessage(
577
- {
578
- id: 'common.download.exceed.max.tips',
579
- defaultMessage: `超出最大下载数据 ${MAX_DOWNLOAD} 条,超出部分请重新下载`,
580
- },
581
- {
582
- count: MAX_DOWNLOAD,
583
- },
584
- ),
585
- onOk: () => resolve(allRows.slice(0, MAX_DOWNLOAD)),
586
- });
587
- } else {
588
- resolve(allRows);
589
- }
588
+ genExcelAdvanced(
589
+ fileName + '.xlsx',
590
+ 'sheet1',
591
+ columnsName,
592
+ function () {
593
+ //生成数据
594
+ return new Promise((resolve) => {
595
+ //所有数据行
596
+ getExportValueForColumns({
597
+ columns: exportColums,
598
+ data: result.data,
599
+ getLocalDate,
600
+ handlePercentChange,
601
+ ...(exportExcel.getExportValueForColumnsOptions ?? {}),
590
602
  })
591
- .catch((err) => console.log('err', err))
592
- .finally(() => {
593
- timer.current = setTimeout(() => {
594
- setDownloadButtonLoading(false);
595
- setPercent(0);
596
- }, 2000);
597
- });
598
- });
599
- });
603
+ .then((allRows) => {
604
+ if (allRows.length > MAX_DOWNLOAD) {
605
+ Modal.warning({
606
+ title: formatMessage({ id: 'common.download.exceed.max.title', defaultMessage: `下载数据过大提醒` }),
607
+ content: formatMessage(
608
+ {
609
+ id: 'common.download.exceed.max.tips',
610
+ defaultMessage: `超出最大下载数据 ${MAX_DOWNLOAD} 条,超出部分请重新下载`,
611
+ },
612
+ {
613
+ count: MAX_DOWNLOAD,
614
+ },
615
+ ),
616
+ onOk: () => resolve(allRows.slice(0, MAX_DOWNLOAD)),
617
+ });
618
+ } else {
619
+ resolve(allRows);
620
+ }
621
+ })
622
+ .catch((err) => console.log('err', err))
623
+ .finally(() => {
624
+ timer.current = setTimeout(() => {
625
+ setDownloadButtonLoading(false);
626
+ setPercent(0);
627
+ }, 2000);
628
+ });
629
+ });
630
+ },
631
+ {
632
+ codeColumns: codeList,
633
+ title: fileName,
634
+ notice: [
635
+ formatMessage({ id: 'cfmmUI.common.button.exportMultiLang.notice', defaultMessage: '请勿修改表格结构' }),
636
+ ],
637
+ ...(exportExcel.genExcelAdvancedOptions ?? {}),
638
+ },
639
+ );
600
640
  };
601
641
 
602
642
  /**
@@ -863,12 +903,28 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
863
903
  </a>
864
904
  ),
865
905
  },
906
+ {
907
+ auth: getAuthorityFn(defaultAuthCodes.export),
908
+ key: 'export',
909
+ disabled: !tableList.length || loading,
910
+ label: (
911
+ <a onClick={handleDownloadExcel} key="export">
912
+ <CloudDownloadOutlined style={{ marginRight: 6 }} />
913
+ {formatMessage({ id: 'cfmmUI.common.button.exportData', defaultMessage: '导出数据' })}
914
+ </a>
915
+ ),
916
+ },
866
917
  {
867
918
  auth:
868
919
  getAuthorityFn(defaultAuthCodes.import) && (apis.importData || interceptors.importData?.submitImportListData),
869
920
  key: 'import',
870
921
  label: (
871
- <ImportExecl key="importMaterial" rangeStart={{ c: 0, r: 2 }} onChange={importListData}>
922
+ <ImportExecl
923
+ key="importListData"
924
+ rangeStart={{ c: 0, r: 2 }}
925
+ onChange={importListData}
926
+ {...(importData?.attributes || {})}
927
+ >
872
928
  <div style={{ color: !actionLoading ? 'rgba(0, 0, 0, 0.88)' : 'rgba(0, 0, 0, 0.25)' }}>
873
929
  <UploadOutlined style={{ marginRight: 8 }} />
874
930
  {formatMessage({ id: 'cfmmUI.common.button.importData', defaultMessage: '导入数据' })}
@@ -876,17 +932,6 @@ function CrudTable<T extends Record<string, any>, U = {}, C = {}>(
876
932
  </ImportExecl>
877
933
  ),
878
934
  },
879
- {
880
- auth: getAuthorityFn(defaultAuthCodes.export),
881
- key: 'export',
882
- disabled: !tableList.length || loading,
883
- label: (
884
- <a onClick={handleDownloadExcel} key="export">
885
- <CloudDownloadOutlined style={{ marginRight: 6 }} />
886
- {formatMessage({ id: 'cfmmUI.common.button.exportData', defaultMessage: '导出数据' })}
887
- </a>
888
- ),
889
- },
890
935
  ];
891
936
 
892
937
  allButtons = handleTableButtonList(allButtons);
@@ -126,6 +126,7 @@ declare const _default: {
126
126
  "cfmmUI.common.button.importData": string;
127
127
  "cfmmUI.common.button.exportData": string;
128
128
  'cfmmUI.common.button.exportMultiLang.notice': string;
129
+ "cfmmUI.common.button.exportMultiLang.title": string;
129
130
  'cfmmUI.action.create.waitingMessage': string;
130
131
  'cfmmUI.action.update.waitingMessage': string;
131
132
  'cfmmUI.action.delete.waitingMessage': string;
@@ -26,6 +26,7 @@ declare const _default: {
26
26
  "cfmmUI.common.button.importData": string;
27
27
  "cfmmUI.common.button.exportData": string;
28
28
  'cfmmUI.common.button.exportMultiLang.notice': string;
29
+ "cfmmUI.common.button.exportMultiLang.title": string;
29
30
  'cfmmUI.action.create.waitingMessage': string;
30
31
  'cfmmUI.action.update.waitingMessage': string;
31
32
  'cfmmUI.action.delete.waitingMessage': string;
@@ -28,6 +28,7 @@ export default {
28
28
  "cfmmUI.common.button.importData": "Import Data",
29
29
  "cfmmUI.common.button.exportData": "Export Data",
30
30
  'cfmmUI.common.button.exportMultiLang.notice': 'Please do not modify the table structure',
31
+ "cfmmUI.common.button.exportMultiLang.title": "Please select the fields to export",
31
32
  //操作提示
32
33
  'cfmmUI.action.create.waitingMessage': 'Being Added',
33
34
  'cfmmUI.action.update.waitingMessage': 'Be Modifying',
@@ -126,6 +126,7 @@ declare const _default: {
126
126
  "cfmmUI.common.button.importData": string;
127
127
  "cfmmUI.common.button.exportData": string;
128
128
  'cfmmUI.common.button.exportMultiLang.notice': string;
129
+ "cfmmUI.common.button.exportMultiLang.title": string;
129
130
  'cfmmUI.action.create.waitingMessage': string;
130
131
  'cfmmUI.action.update.waitingMessage': string;
131
132
  'cfmmUI.action.delete.waitingMessage': string;
@@ -126,6 +126,7 @@ declare const _default: {
126
126
  "cfmmUI.common.button.importData": string;
127
127
  "cfmmUI.common.button.exportData": string;
128
128
  'cfmmUI.common.button.exportMultiLang.notice': string;
129
+ "cfmmUI.common.button.exportMultiLang.title": string;
129
130
  'cfmmUI.action.create.waitingMessage': string;
130
131
  'cfmmUI.action.update.waitingMessage': string;
131
132
  'cfmmUI.action.delete.waitingMessage': string;
@@ -126,6 +126,7 @@ declare const _default: {
126
126
  "cfmmUI.common.button.importData": string;
127
127
  "cfmmUI.common.button.exportData": string;
128
128
  "cfmmUI.common.button.exportMultiLang.notice": string;
129
+ "cfmmUI.common.button.exportMultiLang.title": string;
129
130
  "cfmmUI.action.create.waitingMessage": string;
130
131
  "cfmmUI.action.update.waitingMessage": string;
131
132
  "cfmmUI.action.delete.waitingMessage": string;
@@ -125,6 +125,7 @@ declare const _default: {
125
125
  "cfmmUI.common.button.importData": string;
126
126
  "cfmmUI.common.button.exportData": string;
127
127
  "cfmmUI.common.button.exportMultiLang.notice": string;
128
+ "cfmmUI.common.button.exportMultiLang.title": string;
128
129
  "cfmmUI.action.create.waitingMessage": string;
129
130
  "cfmmUI.action.update.waitingMessage": string;
130
131
  "cfmmUI.action.delete.waitingMessage": string;
@@ -26,6 +26,7 @@ declare const _default: {
26
26
  "cfmmUI.common.button.importData": string;
27
27
  "cfmmUI.common.button.exportData": string;
28
28
  "cfmmUI.common.button.exportMultiLang.notice": string;
29
+ "cfmmUI.common.button.exportMultiLang.title": string;
29
30
  "cfmmUI.action.create.waitingMessage": string;
30
31
  "cfmmUI.action.update.waitingMessage": string;
31
32
  "cfmmUI.action.delete.waitingMessage": string;
@@ -28,6 +28,7 @@ export default {
28
28
  "cfmmUI.common.button.importData": "导入数据",
29
29
  "cfmmUI.common.button.exportData": "导出数据",
30
30
  "cfmmUI.common.button.exportMultiLang.notice": "请勿修改表格结构",
31
+ "cfmmUI.common.button.exportMultiLang.title": "请选择需要导出的字段",
31
32
  //操作提示
32
33
  "cfmmUI.action.create.waitingMessage": "正在新增",
33
34
  "cfmmUI.action.update.waitingMessage": "正在修改",
@@ -126,6 +126,7 @@ declare const _default: {
126
126
  "cfmmUI.common.button.importData": string;
127
127
  "cfmmUI.common.button.exportData": string;
128
128
  "cfmmUI.common.button.exportMultiLang.notice": string;
129
+ "cfmmUI.common.button.exportMultiLang.title": string;
129
130
  "cfmmUI.action.create.waitingMessage": string;
130
131
  "cfmmUI.action.update.waitingMessage": string;
131
132
  "cfmmUI.action.delete.waitingMessage": string;