diff --git a/src/components/ExportCustomModal/index.vue b/src/components/ExportCustomModal/index.vue
new file mode 100644
index 00000000..eb329347
--- /dev/null
+++ b/src/components/ExportCustomModal/index.vue
@@ -0,0 +1,458 @@
+
+
+
+
+
+
+
+
+
{{ t('common.preview') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts
index 086079c6..45602161 100644
--- a/src/i18n/locales/en-US.ts
+++ b/src/i18n/locales/en-US.ts
@@ -41,6 +41,11 @@ export default {
columnSetText: 'Column Setting',
columnSetTitle: 'Column Display / Sorting',
sizeText: 'Density',
+ preview:'Preview',
+ exportCustom:'Custom Export',
+ exportColumns:'Column Definition',
+ resetToDefault:'Reset to default columns',
+ exportDefault:'Export',
size: {
default: 'Default',
middle: 'Medium',
diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts
index d5baaafd..eef4d3c0 100644
--- a/src/i18n/locales/zh-CN.ts
+++ b/src/i18n/locales/zh-CN.ts
@@ -41,6 +41,10 @@ export default {
columnSetText: '列设置',
columnSetTitle: '列展示/排序',
sizeText: '密度',
+ exportCustom:'自定义导出',
+ exportColumns:'列定义',
+ resetToDefault:'重置为默认列',
+ exportDefault:'全部导出',
size: {
default: '默认',
middle: '中等',
diff --git a/src/views/dashboard/sgwcCDR/index.vue b/src/views/dashboard/sgwcCDR/index.vue
index 6bd82c48..6a8ee626 100644
--- a/src/views/dashboard/sgwcCDR/index.vue
+++ b/src/views/dashboard/sgwcCDR/index.vue
@@ -22,6 +22,8 @@ import saveAs from 'file-saver';
import { useClipboard } from '@vueuse/core';
import dayjs, { type Dayjs } from 'dayjs';
import { dayjsRanges } from '@/hooks/useRangePicker';
+import ExportCustomModal from '@/components/ExportCustomModal/index.vue';
+import * as XLSX from 'xlsx';
const { copy } = useClipboard({ legacy: true });
const { t } = useI18n();
const ws = new WS();
@@ -397,9 +399,243 @@ function fnExportList() {
});
}
+/**自定义导出 - 先获取后端数据来确定可用列 */
+function fnExportCustom() {
+ if (modalState.confirmLoading || tablePagination.total === 0) return;
+
+ modalState.confirmLoading = true;
+ const hide = message.loading(t('common.loading'), 0);
+
+ // 先获取后端标准格式的完整数据
+ const querys = toRaw(queryParams);
+ querys.pageNum = 1;
+ querys.pageSize = Math.min(tablePagination.total, 10); // 只获取前10条用于分析列结构
+ querys.startTime = Number(querys.startTime);
+ querys.endTime = Number(querys.endTime);
+
+ exportSGWCDataCDR(querys)
+ .then(res => {
+ if (res.code === RESULT_CODE_SUCCESS) {
+ // 解析后端Excel文件,获取可用的列
+ parseExcelColumns(res.data);
+ } else {
+ message.error({
+ content: `${res.msg}`,
+ duration: 3,
+ });
+ }
+ })
+ .catch(error => {
+ console.error('Export error:', error);
+ message.error({
+ content: t('common.operateError'),
+ duration: 3,
+ });
+ })
+ .finally(() => {
+ hide();
+ modalState.confirmLoading = false;
+ });
+}
+
+/**解析Excel获取可用的列信息 */
+function parseExcelColumns(excelBlob: Blob) {
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ try {
+ const data = new Uint8Array(e.target?.result as ArrayBuffer);
+ const workbook = XLSX.read(data, { type: 'array' });
+
+ // 获取第一个工作表
+ const firstSheetName = workbook.SheetNames[0];
+ const worksheet = workbook.Sheets[firstSheetName];
+
+ // 将工作表转换为JSON格式
+ const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
+
+ if (jsonData.length === 0) {
+ message.error(t('common.noData'));
+ return;
+ }
+
+ // 获取表头(第一行)
+ const headers = jsonData[0] as string[];
+ const dataRows = jsonData.slice(1, 4); // 取前3行作为示例数据
+
+ // 构建可用列配置
+ const availableColumns = headers.map((header, index) => ({
+ key: `col_${index}`,
+ title: header,
+ originalTitle: header,
+ dataIndex: `col_${index}`,
+ columnIndex: index,
+ visible: true
+ }));
+
+ exportAvailableColumns.value = availableColumns;
+
+ // 构建示例数据
+ const sampleData = dataRows.map((row: any) => {
+ const obj: any = { id: Math.random() };
+ headers.forEach((header, index) => {
+ obj[`col_${index}`] = row[index] || '';
+ });
+ return obj;
+ });
+
+ exportSampleData.value = sampleData;
+
+ // 打开自定义导出对话框
+ exportCustomVisible.value = true;
+
+ } catch (error) {
+ console.error('Parse Excel error:', error);
+ message.error(t('common.operateError'));
+ }
+ };
+
+ reader.readAsArrayBuffer(excelBlob);
+}
+
+/**处理自定义导出确认 */
+function handleExportCustomConfirm(config: any[]) {
+ exportCustomConfig.value = config;
+ modalState.confirmLoading = true;
+ const hide = message.loading(t('common.loading'), 0);
+
+ // 先获取后端标准格式的完整数据
+ const querys = toRaw(queryParams);
+ querys.pageNum = 1;
+ querys.pageSize = tablePagination.total;
+ querys.startTime = Number(querys.startTime);
+ querys.endTime = Number(querys.endTime);
+
+ exportSGWCDataCDR(querys)
+ .then(res => {
+ if (res.code === RESULT_CODE_SUCCESS) {
+ // 后端返回标准格式数据后,在前端进行自定义处理
+ processCustomExport(res.data, config);
+ message.success({
+ content: t('common.operateOk'),
+ duration: 3,
+ });
+ } else {
+ message.error({
+ content: `${res.msg}`,
+ duration: 3,
+ });
+ }
+ })
+ .catch(error => {
+ console.error('Export error:', error);
+ message.error({
+ content: t('common.operateError'),
+ duration: 3,
+ });
+ })
+ .finally(() => {
+ hide();
+ modalState.confirmLoading = false;
+ });
+}
+
+/**处理自定义导出 - 基于后端数据在前端自定义处理 */
+function processCustomExport(excelBlob: Blob, config: any[]) {
+ // 读取后端返回的Excel文件
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ try {
+ const data = new Uint8Array(e.target?.result as ArrayBuffer);
+ const workbook = XLSX.read(data, { type: 'array' });
+
+ // 获取第一个工作表
+ const firstSheetName = workbook.SheetNames[0];
+ const worksheet = workbook.Sheets[firstSheetName];
+
+ // 将工作表转换为JSON格式
+ const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
+
+ if (jsonData.length === 0) {
+ message.error(t('common.noData'));
+ return;
+ }
+
+ // 获取表头(第一行)
+ const originalHeaders = jsonData[0] as string[];
+ const dataRows = jsonData.slice(1);
+
+ // 根据配置处理数据
+ const processedData = processDataWithConfig(originalHeaders, dataRows, config);
+
+ // 生成新的Excel文件
+ generateCustomExcelFile(processedData);
+
+ } catch (error) {
+ console.error('Process custom export error:', error);
+ message.error(t('common.operateError'));
+ }
+ };
+
+ reader.readAsArrayBuffer(excelBlob);
+}
+
+/**根据配置处理数据 */
+function processDataWithConfig(originalHeaders: string[], dataRows: any[], config: any[]) {
+ // 获取可见的列配置
+ const visibleColumns = config.filter(col => col.visible);
+
+ // 处理表头
+ const newHeaders = visibleColumns.map(col => col.title);
+
+ // 处理数据行 - 使用columnIndex直接访问
+ const newDataRows = dataRows.map(row => {
+ return visibleColumns.map(col => {
+ // 使用columnIndex字段直接访问对应列的数据
+ const columnIndex = col.columnIndex;
+ return columnIndex !== undefined ? (row[columnIndex] || '') : '';
+ });
+ });
+
+ return {
+ headers: newHeaders,
+ data: newDataRows
+ };
+}
+
+/**生成自定义Excel文件 */
+function generateCustomExcelFile(processedData: { headers: string[], data: any[] }) {
+ // 创建工作簿
+ const wb = XLSX.utils.book_new();
+
+ // 准备Excel数据
+ const excelData = [processedData.headers, ...processedData.data];
+
+ // 创建工作表
+ const ws = XLSX.utils.aoa_to_sheet(excelData);
+
+ // 设置列宽
+ const colWidths = processedData.headers.map(() => ({ wch: 20 }));
+ ws['!cols'] = colWidths;
+
+ // 添加工作表到工作簿
+ XLSX.utils.book_append_sheet(wb, ws, 'SGWC CDR');
+
+ // 生成Excel文件并下载
+ const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
+ const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+
+ saveAs(blob, `sgwc_cdr_custom_export_${Date.now()}.xlsx`);
+}
+
/**实时数据开关 */
const realTimeData = ref(false);
+/**自定义导出配置 */
+const exportCustomVisible = ref(false);
+const exportCustomConfig = ref([]);
+const exportAvailableColumns = ref([]);
+const exportSampleData = ref([]);
+
/**
* 实时数据
*/
@@ -619,10 +855,25 @@ onBeforeUnmount(() => {
{{ t('common.deleteText') }}
-
-
- {{ t('common.export') }}
-
+
+
+
+ {{ t('common.export') }}
+
+
+
+
+
+
+ {{ t('common.exportDefault') }}
+
+
+
+ {{ t('common.exportCustom') }}
+
+
+
+
@@ -830,6 +1081,14 @@ onBeforeUnmount(() => {
+
+
+