前后端导出数据功能调试

This commit is contained in:
zhangtao
2024-12-12 19:43:03 +08:00
parent dd7f2b0a46
commit fda2b07b54
12 changed files with 228 additions and 129 deletions
+10 -5
View File
@@ -24,10 +24,15 @@ export function deleteLog(query) {
});
}
export function exportLog(body) {
export function exportLog(query) {
return request({
url: "/api/v1/system/log/export",
method: "post",
data: body,
});
url: '/api/v1/system/log/export',
method: 'post',
data: query,
responseType: 'blob',
// headers: {
// 'Content-Type': 'application/json',
// 'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
// }
})
}
+42 -23
View File
@@ -123,8 +123,8 @@
<script lang="ts" setup>
import { ref, reactive, onMounted, h } from 'vue';
import type { TableColumnsType } from 'ant-design-vue';
import { SearchOutlined, DownOutlined} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { SearchOutlined, DownOutlined, DownloadOutlined } from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';
import type { searchDataType, tableDataType, creatorType } from './types'
import PageHeader from '@/components/PageHeader.vue';
import { getLogList, deleteLog, exportLog } from '@/api/system/log'
@@ -336,28 +336,47 @@ const handleSelectorModalEvent = (selectedSelectorRowKeys?: creatorType['id'][],
/** 导出按钮操作 */
const handleExport = () => {
// 构建查询参数
const params = {
...queryState,
page_no: 1,
page_size: pagination.total // 导出所有数据
};
Modal.confirm({
title: '警告',
content: '是否确认导出所有日志数据?',
onOk() {
const body = {
...queryState,
page_no: 1,
page_size: pagination.total
};
message.loading('正在导出数据,请稍候...', 0);
// 调用 exportLog 接口
exportLog(params).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `log_${new Date().getTime()}.xlsx`; // 设置下载文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
message.success('导出成功');
}).catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
return exportLog(body).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log("blob", blob);
// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition'];
let fileName = '系统日志.xlsx';
if (contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (fileNameMatch) {
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
console.log(fileName);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
message.destroy();
message.success('导出成功');
}).catch((error) => {
message.destroy();
console.error('导出错误:', error);
message.error('文件处理失败');
});
},
onCancel() {
message.info('已取消导出');
}
});
};
+60 -37
View File
@@ -10,7 +10,8 @@
<a-row>
<a-col flex="0 1 450px">
<a-form-item name="name" label="名称" style="max-width: 300px;">
<a-input v-model:value="queryState.notice_title" placeholder="请输入标题" allowClear></a-input>
<a-input v-model:value="queryState.notice_title" placeholder="请输入标题"
allowClear></a-input>
</a-form-item>
</a-col>
<a-col flex="0 1 450px">
@@ -37,13 +38,9 @@
<a-card title="公告通知列表" :bordered="false" :headStyle="{ borderBottom: 'none', padding: '20px 24px' }"
:bodyStyle="{ padding: '0 24px', minHeight: 'calc(100vh - 400px)' }">
<template #extra>
<a-button type="primary"
:icon="h(PlusOutlined)"
@click="modalHandle('create')"
<a-button type="primary" :icon="h(PlusOutlined)" @click="modalHandle('create')"
style="margin-right: 10px;">新建</a-button>
<a-button type="primary"
:icon="h(DownOutlined)"
@click="handleExport"
<a-button type="primary" :icon="h(DownOutlined)" @click="handleExport"
style="margin-right: 10px;">导出
</a-button>
<a-dropdown>
@@ -61,7 +58,7 @@
<DownOutlined />
</a-button>
</a-dropdown>
</template>
<a-table :rowKey="record => record.id" :columns="columns" :data-source="dataSource"
:row-selection="rowSelection" :loading="tableLoading" @change="handleTableChange"
@@ -105,7 +102,8 @@
<a-modal v-model:open="openModal" @ok="handleModalSumbit" :width="800" :destroyOnClose="true"
:confirmLoading="modalSubmitLoading" style="top: 30px">
<template #title>
<span>{{ modalTitle === 'create' ? '新建公告通知' : (modalTitle === 'view' ? '查看公告通知' : '修改公告通知') }}</span>
<span>{{ modalTitle === 'create' ? '新建公告通知' : (modalTitle === 'view' ? '查看公告通知' : '修改公告通知')
}}</span>
</template>
<div v-if="modalTitle === 'view'">
<a-spin :spinning="detailStateLoading">
@@ -115,15 +113,18 @@
detailState.index + 1 }}</a-descriptions-item>
<a-descriptions-item label="标题">{{ detailState.notice_title }}</a-descriptions-item>
<a-descriptions-item label="类型">
<a-tag :color="detailState.notice_type === 1 ? '#108ee9' : '#f8e231'">{{ detailState.notice_type === 1 ? '通知' : '公告' }}</a-tag>
<a-tag :color="detailState.notice_type === 1 ? '#108ee9' : '#f8e231'">{{
detailState.notice_type
=== 1 ? '通知' : '公告' }}</a-tag>
</a-descriptions-item>
<a-descriptions-item label="内容">{{ detailState.notice_content }}</a-descriptions-item>
<a-descriptions-item label="状态">
<a-badge :color="detailState.available ? 'green' : 'red'" />{{ detailState.available ?
'启用' :
'禁用' }}
'启用' :
'禁用' }}
</a-descriptions-item>
<a-descriptions-item label="创建人">{{ detailState.creator ? detailState.creator.name : '-' }}</a-descriptions-item>
<a-descriptions-item label="创建人">{{ detailState.creator ? detailState.creator.name : '-'
}}</a-descriptions-item>
<a-descriptions-item label="创建时间">{{ detailState.created_at }}</a-descriptions-item>
<a-descriptions-item label="修改时间">{{ detailState.updated_at }}</a-descriptions-item>
<a-descriptions-item label="备注" :span="2">{{ detailState.description
@@ -144,7 +145,8 @@
</a-radio-group>
</a-form-item>
<a-form-item name="notice_content" label="内容" :rules="[{ required: true, message: '请输入内容' }]">
<a-input v-model:value="createState.notice_content" placeholder="请输入内容" allowClear></a-input>
<a-input v-model:value="createState.notice_content" placeholder="请输入内容"
allowClear></a-input>
</a-form-item>
<a-form-item name="available" label="状态" :rules="[{ required: true, message: '请选择状态' }]">
<a-radio-group v-model:value="createState.available">
@@ -171,7 +173,8 @@
</a-radio-group>
</a-form-item>
<a-form-item name="notice_content" label="内容" :rules="[{ required: true, message: '请输入内容' }]">
<a-input v-model:value="updateState.notice_content" placeholder="请输入内容" allowClear></a-input>
<a-input v-model:value="updateState.notice_content" placeholder="请输入内容"
allowClear></a-input>
</a-form-item>
<a-form-item name="available" label="状态" :rules="[{ required: true, message: '请选择状态' }]">
<a-radio-group v-model:value="updateState.available">
@@ -197,7 +200,7 @@ import type { TableColumnsType, MenuProps } from 'ant-design-vue';
import { PlusOutlined, DownOutlined, CheckOutlined, StopOutlined } from '@ant-design/icons-vue';
import { cloneDeep, isEmpty } from '@/utils/util';
import PageHeader from '@/components/PageHeader.vue';
import { getNoticeList, createNotice, updateNotice, deleteNotice, batchAvailableNotice, exportNotice} from '@/api/system/notice'
import { getNoticeList, createNotice, updateNotice, deleteNotice, batchAvailableNotice, exportNotice } from '@/api/system/notice'
import type { searchDataType, tableDataType } from './types'
import XLSX from 'xlsx';
@@ -478,30 +481,50 @@ const handleModalSumbit = () => {
})
}
}
// 导出按钮操作
const handleExport = () => {
// 构建查询参数
const params = {
...queryState,
page_no: 1,
page_size: pagination.total // 导出所有数据
};
Modal.confirm({
title: '警告',
content: '是否确认导出所有公告通知数据?',
onOk() {
const body = {
...queryState,
page_no: 1,
page_size: pagination.total
};
message.loading('正在导出数据,请稍候...', 0);
// 调用 exportLog 接口
exportNotice(params).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `notice_${new Date().getTime()}.xlsx`; // 设置下载文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
message.success('导出成功');
}).catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
return exportNotice(body).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log("blob", blob);
// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition'];
let fileName = '公告通知.xlsx';
if (contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (fileNameMatch) {
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
console.log(fileName);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
message.destroy();
message.success('导出成功');
}).catch((error) => {
message.destroy();
console.error('导出错误:', error);
message.error('文件处理失败');
});
},
onCancel() {
message.info('已取消导出');
}
});
};
+42 -23
View File
@@ -455,31 +455,50 @@ const handleModalSumbit = () => {
}
}
/** 导出按钮操作 */
// 导出按钮操作
const handleExport = () => {
// 构建查询参数
const params = {
...queryState,
page_no: 1,
page_size: pagination.total // 导出所有数据
};
Modal.confirm({
title: '警告',
content: '是否确认导出所有岗位数据?',
onOk() {
const body = {
...queryState,
page_no: 1,
page_size: pagination.total
};
message.loading('正在导出数据,请稍候...', 0);
// 调用 exportLog 接口
exportPosition(params).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `position_${new Date().getTime()}.xlsx`; // 设置下载文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
message.success('导出成功');
}).catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
});
return exportPosition(body).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log("blob", blob);
// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition'];
let fileName = '岗位.xlsx';
if (contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (fileNameMatch) {
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
console.log(fileName);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
message.destroy();
message.success('导出成功');
}).catch((error) => {
message.destroy();
console.error('导出错误:', error);
message.error('文件处理失败');
});
},
onCancel() {
message.info('已取消导出');
}
});
};
</script>
+43 -24
View File
@@ -464,33 +464,52 @@ const handleModalSumbit = () => {
}
}
/** 导出按钮操作 */
const handleExport = () => {
// 构建查询参数
const params = {
...queryState,
page_no: 1,
page_size: pagination.total // 导出所有数据
};
// 调用 exportLog 接口
exportRole(params).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `role_${new Date().getTime()}.xlsx`; // 设置下载文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
message.success('导出成功');
}).catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
// 导出按钮操作
const handleExport = () => {
Modal.confirm({
title: '警告',
content: '是否确认导出所有角色数据?',
onOk() {
const body = {
...queryState,
page_no: 1,
page_size: pagination.total
};
message.loading('正在导出数据,请稍候...', 0);
return exportRole(body).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log("blob", blob);
// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition'];
let fileName = '角色.xlsx';
if (contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (fileNameMatch) {
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
console.log(fileName);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
message.destroy();
message.success('导出成功');
}).catch((error) => {
message.destroy();
console.error('导出错误:', error);
message.error('文件处理失败');
});
},
onCancel() {
message.info('已取消导出');
}
});
};
// 授权弹窗事件
const handlePermissionDrawerEvent = () => loadingData();
</script>
+26 -7
View File
@@ -820,23 +820,42 @@ const handleExport = () => {
title: '警告',
content: '是否确认导出所有用户数据?',
onOk() {
const params = {
const body = {
...queryState,
page_no: 1,
page_size: pagination.total
};
return exportUser(params).then(response => {
const blob = new Blob([response], { type: 'application/vnd.ms-excel' });
message.loading('正在导出数据,请稍候...', 0);
return exportUser(body).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log("blob", blob);
// 从响应头获取文件名
const contentDisposition = response.headers['content-disposition'];
let fileName = '用户.xlsx';
if (contentDisposition) {
const fileNameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
if (fileNameMatch) {
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
console.log(fileName);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `用户数据_${new Date().getTime()}.xlsx`;
link.download = fileName;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(url);
message.destroy();
message.success('导出成功');
}).catch(() => {
message.error('导出失败');
}).catch((error) => {
message.destroy();
console.error('导出错误:', error);
message.error('文件处理失败');
});
},
onCancel() {
message.info('已取消导出');
}
});
};