mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-25 16:07:19 +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>) => {
|
export const deleteOperationLogApi = (data: Array<number>) => {
|
||||||
return http.request<ResponseData<void>>("delete", "/logs/operationLogs", {
|
return http.request<ResponseData<void>>("delete", "/logs/operationLogs", {
|
||||||
params: {
|
params: {
|
||||||
|
@ -16,6 +16,7 @@ import { message } from "../message";
|
|||||||
import { ElMessageBox } from "element-plus";
|
import { ElMessageBox } from "element-plus";
|
||||||
import { router } from "@/router";
|
import { router } from "@/router";
|
||||||
import { removeToken } from "@/utils/auth";
|
import { removeToken } from "@/utils/auth";
|
||||||
|
import { downloadByData } from "@pureadmin/utils";
|
||||||
// console.log("Utils:" + router);
|
// console.log("Utils:" + router);
|
||||||
|
|
||||||
const { VITE_APP_BASE_API } = import.meta.env;
|
const { VITE_APP_BASE_API } = import.meta.env;
|
||||||
@ -104,7 +105,34 @@ class PureHttp {
|
|||||||
private httpInterceptorsResponse(): void {
|
private httpInterceptorsResponse(): void {
|
||||||
const instance = PureHttp.axiosInstance;
|
const instance = PureHttp.axiosInstance;
|
||||||
instance.interceptors.response.use(
|
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) {
|
if (response.data.code !== 0) {
|
||||||
// token失效时弹出过期提示
|
// token失效时弹出过期提示
|
||||||
@ -126,12 +154,12 @@ class PureHttp {
|
|||||||
message("取消重新登录", { type: "info" });
|
message("取消重新登录", { type: "info" });
|
||||||
});
|
});
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
return Promise.reject(response.data.msg);
|
return Promise.reject(msg);
|
||||||
} else {
|
} else {
|
||||||
// 其余情况弹出错误提示框
|
// 其余情况弹出错误提示框
|
||||||
message(response.data.msg, { type: "error" });
|
message(msg, { type: "error" });
|
||||||
NProgress.done();
|
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工具函数 */
|
/** 单独抽离的post工具函数 */
|
||||||
public post<T, P>(
|
public post<T, P>(
|
||||||
url: string,
|
url: string,
|
||||||
@ -217,6 +258,54 @@ class PureHttp {
|
|||||||
): Promise<P> {
|
): Promise<P> {
|
||||||
return this.request<P>("get", url, params, config);
|
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();
|
export const http = new PureHttp();
|
||||||
|
@ -9,7 +9,7 @@ import View from "@iconify-icons/ep/view";
|
|||||||
import Search from "@iconify-icons/ep/search";
|
import Search from "@iconify-icons/ep/search";
|
||||||
import Refresh from "@iconify-icons/ep/refresh";
|
import Refresh from "@iconify-icons/ep/refresh";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
// 这个导入声明好长 看看如何优化
|
// TODO 这个导入声明好长 看看如何优化
|
||||||
import { CommonUtils } from "../../../../utils/common";
|
import { CommonUtils } from "../../../../utils/common";
|
||||||
|
|
||||||
/** 组件name最好和菜单表中的router_name一致 */
|
/** 组件name最好和菜单表中的router_name一致 */
|
||||||
@ -35,6 +35,7 @@ const {
|
|||||||
multipleSelection,
|
multipleSelection,
|
||||||
onSearch,
|
onSearch,
|
||||||
resetForm,
|
resetForm,
|
||||||
|
exportAllExcel,
|
||||||
openDialog,
|
openDialog,
|
||||||
getOperationLogList,
|
getOperationLogList,
|
||||||
handleDelete,
|
handleDelete,
|
||||||
@ -147,11 +148,7 @@ const {
|
|||||||
@click="CommonUtils.exportExcel(columns, dataList, '操作日志列表')"
|
@click="CommonUtils.exportExcel(columns, dataList, '操作日志列表')"
|
||||||
>单页导出</el-button
|
>单页导出</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button type="primary" @click="exportAllExcel">全部导出</el-button>
|
||||||
type="primary"
|
|
||||||
@click="CommonUtils.exportExcel(columns, dataList, '操作日志列表')"
|
|
||||||
>全部导出</el-button
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-slot="{ size, dynamicColumns }">
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
<pure-table
|
<pure-table
|
||||||
|
@ -3,10 +3,14 @@ import descriptionForm from "../description.vue";
|
|||||||
import { message } from "@/utils/message";
|
import { message } from "@/utils/message";
|
||||||
import { addDialog, closeDialog } from "@/components/ReDialog";
|
import { addDialog, closeDialog } from "@/components/ReDialog";
|
||||||
import { ElMessageBox, Sort } from "element-plus";
|
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 { reactive, ref, onMounted, h, toRaw } from "vue";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import { deleteOperationLogApi } from "@/api/system/log";
|
|
||||||
import { CommonUtils } from "@/utils/common";
|
import { CommonUtils } from "@/utils/common";
|
||||||
|
|
||||||
const operationLogStatusMap =
|
const operationLogStatusMap =
|
||||||
@ -154,13 +158,23 @@ export function useOperationLogHook() {
|
|||||||
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||||
CommonUtils.fillTimeRangeParams(searchFormParams, timeRange.value);
|
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;
|
dataList.value = data.rows;
|
||||||
pagination.total = data.total;
|
pagination.total = data.total;
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
async function exportAllExcel(sort: Sort = defaultSort) {
|
||||||
pageLoading.value = false;
|
if (sort != null) {
|
||||||
}, 500);
|
CommonUtils.fillSortParams(searchFormParams, sort);
|
||||||
|
}
|
||||||
|
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||||
|
CommonUtils.fillTimeRangeParams(searchFormParams, timeRange.value);
|
||||||
|
|
||||||
|
exportOperationLogExcelApi(toRaw(searchFormParams), "操作日志.xls");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDelete(row) {
|
async function handleDelete(row) {
|
||||||
@ -244,6 +258,7 @@ export function useOperationLogHook() {
|
|||||||
timeRange,
|
timeRange,
|
||||||
multipleSelection,
|
multipleSelection,
|
||||||
onSearch,
|
onSearch,
|
||||||
|
exportAllExcel,
|
||||||
// exportExcel,
|
// exportExcel,
|
||||||
getOperationLogList,
|
getOperationLogList,
|
||||||
resetForm,
|
resetForm,
|
||||||
|
@ -153,14 +153,14 @@ export function useNoticeHook() {
|
|||||||
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
CommonUtils.fillPaginationParams(searchFormParams, pagination);
|
||||||
|
|
||||||
pageLoading.value = true;
|
pageLoading.value = true;
|
||||||
const { data } = await getSystemNoticeListApi(toRaw(searchFormParams));
|
const { data } = await getSystemNoticeListApi(
|
||||||
|
toRaw(searchFormParams)
|
||||||
|
).finally(() => {
|
||||||
|
pageLoading.value = false;
|
||||||
|
});
|
||||||
|
|
||||||
dataList.value = data.rows;
|
dataList.value = data.rows;
|
||||||
pagination.total = data.total;
|
pagination.total = data.total;
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
pageLoading.value = false;
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDelete(row) {
|
async function handleDelete(row) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user