@skyfox2000/webui 1.4.17 → 1.4.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/lib/utils/export-table.d.ts +1 -1
- package/lib/webui.es.js +1087 -1093
- package/package.json +1 -1
- package/src/utils/export-table.ts +91 -70
package/package.json
CHANGED
|
@@ -11,13 +11,92 @@ import { LoginExpiredError, useUserInfo } from '@/stores/userInfo';
|
|
|
11
11
|
// 表格列类型定义 (适配 ant-design-vue)
|
|
12
12
|
export interface TableColumn {
|
|
13
13
|
title: string;
|
|
14
|
-
dataIndex?: string;
|
|
14
|
+
dataIndex?: string | string[];
|
|
15
15
|
key?: string;
|
|
16
16
|
visible?: boolean; // 是否显示列
|
|
17
17
|
export?: boolean; // 是否导出列
|
|
18
18
|
customRender?: (options: { text: any; record: Record<string, any>; index: number; column: TableColumn }) => any;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* 将 dataIndex 转换为字符串形式
|
|
23
|
+
* 如果是数组则转换为点号连接的字符串,否则直接返回原值或空字符串
|
|
24
|
+
* @param dataIndex 列的 dataIndex
|
|
25
|
+
*/
|
|
26
|
+
const toString = (dataIndex: string | string[] | undefined): string => {
|
|
27
|
+
if (!dataIndex) return '';
|
|
28
|
+
if (Array.isArray(dataIndex)) {
|
|
29
|
+
return dataIndex.join('.');
|
|
30
|
+
}
|
|
31
|
+
return dataIndex;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 准备 CSV 字段配置
|
|
36
|
+
* @param columns 需要导出的列配置
|
|
37
|
+
*/
|
|
38
|
+
const getFields = (columns: TableColumn[]) => {
|
|
39
|
+
return columns.map((col) => ({
|
|
40
|
+
label: col.title,
|
|
41
|
+
value: toString(col.dataIndex) || col.key || '',
|
|
42
|
+
}));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 处理数据行,应用自定义渲染
|
|
47
|
+
* @param data 原始数据
|
|
48
|
+
* @param columns 列配置
|
|
49
|
+
*/
|
|
50
|
+
const processData = <T extends Record<string, any>>(data: T[], columns: TableColumn[]) => {
|
|
51
|
+
return data.map((row, index) => {
|
|
52
|
+
const newRow: Record<string, any> = { ...row };
|
|
53
|
+
|
|
54
|
+
columns.forEach((col) => {
|
|
55
|
+
const field = toString(col.dataIndex) || col.key;
|
|
56
|
+
if (!field) return;
|
|
57
|
+
|
|
58
|
+
// 应用自定义渲染
|
|
59
|
+
if (col.customRender) {
|
|
60
|
+
newRow[field] = col.customRender({
|
|
61
|
+
text: row[field],
|
|
62
|
+
record: row,
|
|
63
|
+
index: index,
|
|
64
|
+
column: col,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return newRow;
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 生成并下载 CSV 文件
|
|
74
|
+
* @param fileName 文件名
|
|
75
|
+
* @param fields CSV 字段配置
|
|
76
|
+
* @param data 处理后的数据
|
|
77
|
+
*/
|
|
78
|
+
const downloadCSV = async <T extends Record<string, any>>(
|
|
79
|
+
fileName: string,
|
|
80
|
+
fields: Array<{ label: string; value: string }>,
|
|
81
|
+
data: T[],
|
|
82
|
+
) => {
|
|
83
|
+
try {
|
|
84
|
+
const mod = await import('@json2csv/plainjs');
|
|
85
|
+
const JSON2CSVParser = mod.Parser;
|
|
86
|
+
|
|
87
|
+
// 生成 CSV 内容
|
|
88
|
+
const parser = new JSON2CSVParser({ fields });
|
|
89
|
+
const csvContent = parser.parse(data);
|
|
90
|
+
|
|
91
|
+
// 创建并下载文件
|
|
92
|
+
const blob = new Blob([`\uFEFF${csvContent}`], { type: 'text/csv' });
|
|
93
|
+
downloadBlob(blob, fileName);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error('导出失败:', error);
|
|
96
|
+
message.error('文件导出失败,请稍后重试');
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
21
100
|
/**
|
|
22
101
|
* 导出选中行数据为 CSV 文件
|
|
23
102
|
* @param fileName 文件名(支持 {YYYY}、{YY}、{MM}、{DD}、{HH}、{mm}、{ss} 时间格式)
|
|
@@ -30,8 +109,6 @@ export const exportSelectedRows = async <T extends Record<string, any>>(
|
|
|
30
109
|
selectRows: T[],
|
|
31
110
|
) => {
|
|
32
111
|
try {
|
|
33
|
-
const mod = await import('@json2csv/plainjs');
|
|
34
|
-
const JSON2CSVParser = mod.Parser;
|
|
35
112
|
// 1. 处理文件名中的日期格式
|
|
36
113
|
const processedFileName = formatFileName(fileName);
|
|
37
114
|
|
|
@@ -39,42 +116,15 @@ export const exportSelectedRows = async <T extends Record<string, any>>(
|
|
|
39
116
|
const exportColumns = columns.filter((col) => col.visible !== false && col.export !== false);
|
|
40
117
|
|
|
41
118
|
// 3. 准备 CSV 字段配置
|
|
42
|
-
const fields = exportColumns
|
|
43
|
-
label: col.title,
|
|
44
|
-
value: col.dataIndex || col.key || '',
|
|
45
|
-
}));
|
|
119
|
+
const fields = getFields(exportColumns);
|
|
46
120
|
|
|
47
121
|
// 4. 处理数据行
|
|
48
|
-
const processedData = selectRows
|
|
49
|
-
const newRow: Record<string, any> = { ...row };
|
|
50
|
-
|
|
51
|
-
exportColumns.forEach((col) => {
|
|
52
|
-
const field = col.dataIndex || col.key;
|
|
53
|
-
if (!field) return;
|
|
54
|
-
|
|
55
|
-
// 应用自定义渲染
|
|
56
|
-
if (col.customRender) {
|
|
57
|
-
newRow[field] = col.customRender({
|
|
58
|
-
text: row[field],
|
|
59
|
-
record: row,
|
|
60
|
-
index: index,
|
|
61
|
-
column: col,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
return newRow;
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// 5. 生成 CSV 内容
|
|
69
|
-
const parser = new JSON2CSVParser({ fields });
|
|
70
|
-
const csvContent = parser.parse(processedData);
|
|
122
|
+
const processedData = processData(selectRows, exportColumns);
|
|
71
123
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
downloadBlob(blob, processedFileName);
|
|
124
|
+
// 5. 生成 CSV 内容并下载
|
|
125
|
+
await downloadCSV(processedFileName, fields, processedData);
|
|
75
126
|
} catch (error) {
|
|
76
127
|
console.error('导出失败:', error);
|
|
77
|
-
// throw new Error('文件导出失败,请稍后重试');
|
|
78
128
|
message.error('文件导出失败,请稍后重试');
|
|
79
129
|
}
|
|
80
130
|
};
|
|
@@ -96,8 +146,6 @@ export const exportResults = async <T extends Record<string, any>>(
|
|
|
96
146
|
url: IUrlInfo,
|
|
97
147
|
) => {
|
|
98
148
|
try {
|
|
99
|
-
const mod = await import('@json2csv/plainjs');
|
|
100
|
-
const JSON2CSVParser = mod.Parser;
|
|
101
149
|
// 1. 处理文件名中的日期格式
|
|
102
150
|
const processedFileName = formatFileName(fileName);
|
|
103
151
|
|
|
@@ -105,10 +153,7 @@ export const exportResults = async <T extends Record<string, any>>(
|
|
|
105
153
|
const exportColumns = columns.filter((col) => col.visible !== false);
|
|
106
154
|
|
|
107
155
|
// 3. 准备 CSV 字段配置
|
|
108
|
-
const fields = exportColumns
|
|
109
|
-
label: col.title,
|
|
110
|
-
value: col.dataIndex || col.key || '',
|
|
111
|
-
}));
|
|
156
|
+
const fields = getFields(exportColumns);
|
|
112
157
|
|
|
113
158
|
// 4. 获取数据
|
|
114
159
|
let pageCtrl = gridCtrl.page;
|
|
@@ -118,39 +163,16 @@ export const exportResults = async <T extends Record<string, any>>(
|
|
|
118
163
|
if (url.authorize === undefined) url.authorize = pageCtrl.authorize;
|
|
119
164
|
|
|
120
165
|
gridCtrl.isGridLoading.value = true;
|
|
121
|
-
return httpPost<T>(url, newParams).then((result: ApiResponse<T> | null) => {
|
|
166
|
+
return httpPost<T>(url, newParams).then(async (result: ApiResponse<T> | null) => {
|
|
122
167
|
gridCtrl.isGridLoading.value = false;
|
|
123
168
|
if (result?.status === ResStatus.SUCCESS) {
|
|
124
169
|
if (result.data) {
|
|
125
170
|
// 5. 处理数据行
|
|
126
171
|
let results = result.data as unknown as T[];
|
|
127
|
-
const processedData = results
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const field = col.dataIndex || col.key;
|
|
132
|
-
if (!field) return;
|
|
133
|
-
|
|
134
|
-
// 应用自定义渲染
|
|
135
|
-
if (col.customRender) {
|
|
136
|
-
newRow[field] = col.customRender({
|
|
137
|
-
text: row[field],
|
|
138
|
-
record: row,
|
|
139
|
-
index: index,
|
|
140
|
-
column: col,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
return newRow;
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// 5. 生成 CSV 内容
|
|
148
|
-
const parser = new JSON2CSVParser({ fields });
|
|
149
|
-
const csvContent = parser.parse(processedData);
|
|
150
|
-
|
|
151
|
-
// 6. 创建并下载文件
|
|
152
|
-
const blob = new Blob([`\uFEFF${csvContent}`], { type: 'text/csv' });
|
|
153
|
-
downloadBlob(blob, processedFileName);
|
|
172
|
+
const processedData = processData(results, exportColumns);
|
|
173
|
+
|
|
174
|
+
// 6. 生成 CSV 内容并下载
|
|
175
|
+
await downloadCSV(processedFileName, fields, processedData);
|
|
154
176
|
}
|
|
155
177
|
} else if (result?.errno == LoginExpiredError) {
|
|
156
178
|
const userInfoStore = useUserInfo();
|
|
@@ -161,10 +183,9 @@ export const exportResults = async <T extends Record<string, any>>(
|
|
|
161
183
|
});
|
|
162
184
|
} catch (error) {
|
|
163
185
|
console.error('导出失败:', error);
|
|
164
|
-
// throw new Error('文件导出失败,请稍后重试');
|
|
165
186
|
message.error('文件导出失败,请稍后重试');
|
|
166
187
|
}
|
|
167
188
|
};
|
|
168
189
|
|
|
169
190
|
// 后端处理
|
|
170
|
-
// 下载文件或二进制输出文件
|
|
191
|
+
// 下载文件或二进制输出文件
|