mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-25 07:57:18 +08:00
feat: 新增后台全量导出excel
This commit is contained in:
parent
61a980a37d
commit
bc4d29cba0
@ -42,6 +42,15 @@ export const getOperationLogListApi = (params?: OperationLogsQuery) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const exportOperationLogExcelApi = (
|
||||
params: OperationLogsQuery,
|
||||
fileName: string
|
||||
) => {
|
||||
return http.download("/logs/operationLogs/excel", fileName, {
|
||||
params
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteOperationLogApi = (data: Array<number>) => {
|
||||
return http.request<ResponseData<void>>("delete", "/logs/operationLogs", {
|
||||
params: {
|
||||
|
@ -16,6 +16,7 @@ import { message } from "../message";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { router } from "@/router";
|
||||
import { removeToken } from "@/utils/auth";
|
||||
import { downloadByData } from "@pureadmin/utils";
|
||||
// console.log("Utils:" + router);
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
@ -104,7 +105,34 @@ class PureHttp {
|
||||
private httpInterceptorsResponse(): void {
|
||||
const instance = PureHttp.axiosInstance;
|
||||
instance.interceptors.response.use(
|
||||
(response: PureHttpResponse) => {
|
||||
async (response: PureHttpResponse) => {
|
||||
let code = undefined;
|
||||
let msg = undefined;
|
||||
|
||||
// 后台返回的二进制流
|
||||
if (response.data instanceof Blob) {
|
||||
// 返回二进制流的时候 可能出错 这时候返回的错误是Json格式
|
||||
if (response.data.type === "application/json") {
|
||||
const text = await this.readBlobAsText(response.data);
|
||||
const json = JSON.parse(text);
|
||||
// 提取错误消息中的code和msg
|
||||
code = json.code;
|
||||
msg = json.msg;
|
||||
} else {
|
||||
NProgress.done();
|
||||
return response.data;
|
||||
}
|
||||
// 正常的返回类型 直接获取code和msg字段
|
||||
} else {
|
||||
code = response.data.code;
|
||||
msg = response.data.msg;
|
||||
}
|
||||
|
||||
// 如果不存在code说明后端格式有问题
|
||||
if (!code) {
|
||||
msg = "服务器返回数据结构有误";
|
||||
}
|
||||
|
||||
// 请求返回失败时,有业务错误时,弹出错误提示
|
||||
if (response.data.code !== 0) {
|
||||
// token失效时弹出过期提示
|
||||
@ -126,12 +154,12 @@ class PureHttp {
|
||||
message("取消重新登录", { type: "info" });
|
||||
});
|
||||
NProgress.done();
|
||||
return Promise.reject(response.data.msg);
|
||||
return Promise.reject(msg);
|
||||
} else {
|
||||
// 其余情况弹出错误提示框
|
||||
message(response.data.msg, { type: "error" });
|
||||
message(msg, { type: "error" });
|
||||
NProgress.done();
|
||||
return Promise.reject(response.data.msg);
|
||||
return Promise.reject(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,6 +228,19 @@ class PureHttp {
|
||||
});
|
||||
}
|
||||
|
||||
/** 从二进制流中读取文本 */
|
||||
async readBlobAsText(blob: Blob): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const text = reader.result as string;
|
||||
resolve(text);
|
||||
};
|
||||
reader.onerror = reject;
|
||||
reader.readAsText(blob, "UTF-8");
|
||||
});
|
||||
}
|
||||
|
||||
/** 单独抽离的post工具函数 */
|
||||
public post<T, P>(
|
||||
url: string,
|
||||
@ -217,6 +258,54 @@ class PureHttp {
|
||||
): Promise<P> {
|
||||
return this.request<P>("get", url, params, config);
|
||||
}
|
||||
|
||||
/** download文件方法 从后端获取文件流 */
|
||||
public download(
|
||||
url: string,
|
||||
fileName: string,
|
||||
params?: AxiosRequestConfig
|
||||
): void {
|
||||
this.get(url, params, {
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
responseType: "blob"
|
||||
}).then((data: Blob) => {
|
||||
downloadByData(data, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
// .post(url, params, {
|
||||
// transformRequest: [params => encodeURIParams(params)],
|
||||
// headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
// responseType: "blob"
|
||||
// })
|
||||
// .then(async data => {
|
||||
// const isLogin = await isBlobData(data);
|
||||
// if (isLogin) {
|
||||
// const blob = new Blob([data]);
|
||||
// saveAs(blob, filename);
|
||||
// } else {
|
||||
// const resText = await data.text();
|
||||
// const rspObj = JSON.parse(resText);
|
||||
// const errMsg =
|
||||
// errorCode[rspObj.code] || rspObj.msg || errorCode.default;
|
||||
// ElMessage.error(errMsg);
|
||||
// }
|
||||
// downloadLoadingInstance.close();
|
||||
// })
|
||||
// .catch(r => {
|
||||
// console.error(r);
|
||||
// ElMessage.error("下载文件出现错误,请联系管理员!");
|
||||
// downloadLoadingInstance.close();
|
||||
// });
|
||||
|
||||
// axios
|
||||
// .get("https://pure-admin.github.io/pure-admin-doc/img/pure.png", {
|
||||
// responseType: "blob"
|
||||
// })
|
||||
// .then(({ data }) => {
|
||||
// downloadByData(data, "test-data.png");
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
export const http = new PureHttp();
|
||||
|
@ -9,7 +9,7 @@ import View from "@iconify-icons/ep/view";
|
||||
import Search from "@iconify-icons/ep/search";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
// 这个导入声明好长 看看如何优化
|
||||
// TODO 这个导入声明好长 看看如何优化
|
||||
import { CommonUtils } from "../../../../utils/common";
|
||||
|
||||
/** 组件name最好和菜单表中的router_name一致 */
|
||||
@ -35,6 +35,7 @@ const {
|
||||
multipleSelection,
|
||||
onSearch,
|
||||
resetForm,
|
||||
exportAllExcel,
|
||||
openDialog,
|
||||
getOperationLogList,
|
||||
handleDelete,
|
||||
@ -147,11 +148,7 @@ const {
|
||||
@click="CommonUtils.exportExcel(columns, dataList, '操作日志列表')"
|
||||
>单页导出</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="CommonUtils.exportExcel(columns, dataList, '操作日志列表')"
|
||||
>全部导出</el-button
|
||||
>
|
||||
<el-button type="primary" @click="exportAllExcel">全部导出</el-button>
|
||||
</template>
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
<pure-table
|
||||
|
@ -3,10 +3,14 @@ import descriptionForm from "../description.vue";
|
||||
import { message } from "@/utils/message";
|
||||
import { addDialog, closeDialog } from "@/components/ReDialog";
|
||||
import { ElMessageBox, Sort } from "element-plus";
|
||||
import { OperationLogsQuery, getOperationLogListApi } from "@/api/system/log";
|
||||
import {
|
||||
OperationLogsQuery,
|
||||
getOperationLogListApi,
|
||||
deleteOperationLogApi,
|
||||
exportOperationLogExcelApi
|
||||
} from "@/api/system/log";
|
||||
import { reactive, ref, onMounted, h, toRaw } from "vue";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { deleteOperationLogApi } from "@/api/system/log";
|
||||
import { CommonUtils } from "@/utils/common";
|
||||
|
||||
const operationLogStatusMap =
|
||||
@ -154,13 +158,23 @@ export function useOperationLogHook() {
|
||||
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||
CommonUtils.fillTimeRangeParams(searchFormParams, timeRange.value);
|
||||
|
||||
const { data } = await getOperationLogListApi(toRaw(searchFormParams));
|
||||
const { data } = await getOperationLogListApi(
|
||||
toRaw(searchFormParams)
|
||||
).finally(() => {
|
||||
pageLoading.value = false;
|
||||
});
|
||||
dataList.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
pageLoading.value = false;
|
||||
}, 500);
|
||||
async function exportAllExcel(sort: Sort = defaultSort) {
|
||||
if (sort != null) {
|
||||
CommonUtils.fillSortParams(searchFormParams, sort);
|
||||
}
|
||||
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||
CommonUtils.fillTimeRangeParams(searchFormParams, timeRange.value);
|
||||
|
||||
exportOperationLogExcelApi(toRaw(searchFormParams), "操作日志.xls");
|
||||
}
|
||||
|
||||
async function handleDelete(row) {
|
||||
@ -244,6 +258,7 @@ export function useOperationLogHook() {
|
||||
timeRange,
|
||||
multipleSelection,
|
||||
onSearch,
|
||||
exportAllExcel,
|
||||
// exportExcel,
|
||||
getOperationLogList,
|
||||
resetForm,
|
||||
|
@ -153,14 +153,14 @@ export function useNoticeHook() {
|
||||
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||
|
||||
pageLoading.value = true;
|
||||
const { data } = await getSystemNoticeListApi(toRaw(searchFormParams));
|
||||
const { data } = await getSystemNoticeListApi(
|
||||
toRaw(searchFormParams)
|
||||
).finally(() => {
|
||||
pageLoading.value = false;
|
||||
});
|
||||
|
||||
dataList.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
|
||||
setTimeout(() => {
|
||||
pageLoading.value = false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function handleDelete(row) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user