mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-09 20:57:17 +08:00
refactor: 优化导出下载功能
This commit is contained in:
@@ -12,3 +12,11 @@ export function listLog(query: System.LogQuery) {
|
||||
export function getLog(id: string) {
|
||||
return http.get<System.LogDetailResp>(`${BASE_URL}/${id}`)
|
||||
}
|
||||
/** @desc 导出日志列表 */
|
||||
export function exportLog(query: System.LogQuery) {
|
||||
return http.download<any>(`${BASE_URL}/export/login`, query)
|
||||
}
|
||||
/**@desc 导出操作日志 */
|
||||
export function exportOperateLog(query: System.LogQuery) {
|
||||
return http.download<any>(`${BASE_URL}/export/operation`, query)
|
||||
}
|
@@ -7,3 +7,4 @@ export * from './modules/useForm'
|
||||
export * from './modules/useDevice'
|
||||
export * from './modules/useBreakpoint'
|
||||
export * from './modules/useBreakpointIndex'
|
||||
export * from './modules/useDownload'
|
||||
|
55
src/hooks/modules/useDownload.ts
Normal file
55
src/hooks/modules/useDownload.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Message, Notification } from '@arco-design/web-vue'
|
||||
/**
|
||||
* @description 接收数据流生成 blob,创建链接,下载文件
|
||||
* @param {Function} api 导出表格的api方法 (必传)
|
||||
* @param {String} tempName 导出的文件名 (必传)
|
||||
* @param {Object} params 导出的参数 (默认{})
|
||||
* @param {Boolean} isNotify 是否有导出消息提示 (默认为 true)
|
||||
* @param {String} fileType 导出的文件格式 (默认为.xlsx)
|
||||
* */
|
||||
interface NavigatorWithMsSaveOrOpenBlob extends Navigator {
|
||||
msSaveOrOpenBlob(blob: Blob, fileName: string): void
|
||||
}
|
||||
export const useDownload = async (
|
||||
api: (param: any) => Promise<any>,
|
||||
tempName: string = '',
|
||||
params: any = {},
|
||||
isNotify = true,
|
||||
fileType = '.xlsx'
|
||||
) => {
|
||||
try {
|
||||
const res = await api(params)
|
||||
if (res.headers['content-disposition']) {
|
||||
tempName = decodeURI(res.headers['content-disposition'].split(';')[1].split('=')[1]);
|
||||
} else {
|
||||
tempName = tempName ? tempName : new Date().getTime() + fileType
|
||||
}
|
||||
if (isNotify && !res?.code) {
|
||||
Notification.warning({
|
||||
title: '温馨提示',
|
||||
content: '如果数据庞大会导致下载缓慢哦,请您耐心等待!'
|
||||
})
|
||||
}
|
||||
if (res.status !== 200 || res.data === null || !(res.data instanceof Blob)) {
|
||||
Message.error('导出失败,请稍后再试!')
|
||||
return
|
||||
}
|
||||
const blob = new Blob([res.data])
|
||||
// 兼容 edge 不支持 createObjectURL 方法
|
||||
if ('msSaveOrOpenBlob' in (navigator as unknown as NavigatorWithMsSaveOrOpenBlob)) {
|
||||
; (window.navigator as unknown as NavigatorWithMsSaveOrOpenBlob).msSaveOrOpenBlob(blob, tempName + fileType)
|
||||
}
|
||||
const blobUrl = window.URL.createObjectURL(blob)
|
||||
const exportFile = document.createElement('a')
|
||||
exportFile.style.display = 'none'
|
||||
exportFile.download = tempName
|
||||
exportFile.href = blobUrl
|
||||
document.body.appendChild(exportFile)
|
||||
exportFile.click()
|
||||
// 去除下载对 url 的影响
|
||||
document.body.removeChild(exportFile)
|
||||
window.URL.revokeObjectURL(blobUrl)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
@@ -61,7 +61,9 @@ http.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
const { data } = response
|
||||
const { success, code, msg } = data
|
||||
|
||||
if(response.request.responseType==='blob'){
|
||||
return response
|
||||
}
|
||||
// 成功
|
||||
if (success) {
|
||||
NProgress.done()
|
||||
@@ -122,6 +124,7 @@ const requestNative = <T = unknown>(config: AxiosRequestConfig): Promise<AxiosRe
|
||||
return new Promise((resolve, reject) => {
|
||||
http
|
||||
.request<T>(config)
|
||||
.then((res: AxiosResponse) => resolve(res))
|
||||
.catch((err: { msg: string }) => reject(err))
|
||||
})
|
||||
}
|
||||
@@ -173,5 +176,13 @@ const del = <T = any>(url: string, params?: object, config?: AxiosRequestConfig)
|
||||
...config
|
||||
})
|
||||
}
|
||||
|
||||
export default { get, post, put, patch, del, request, requestNative }
|
||||
const download = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<AxiosResponse> => {
|
||||
return requestNative({
|
||||
method: 'get',
|
||||
url,
|
||||
responseType: 'blob',
|
||||
params,
|
||||
...config
|
||||
})
|
||||
}
|
||||
export default { get, post, put, patch, del, request, requestNative,download }
|
||||
|
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
<template #custom-right>
|
||||
<a-tooltip content="导出">
|
||||
<a-button>
|
||||
<a-button @click="onExportFile">
|
||||
<template #icon>
|
||||
<icon-download />
|
||||
</template>
|
||||
@@ -45,13 +45,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listLog } from '@/apis'
|
||||
import { listLog,exportLog } from '@/apis'
|
||||
import type { TableInstance } from '@arco-design/web-vue'
|
||||
import DateRangePicker from '@/components/DateRangePicker/index.vue'
|
||||
import { useTable } from '@/hooks'
|
||||
|
||||
import {useDownload} from '@/hooks'
|
||||
defineOptions({ name: 'LoginLog' })
|
||||
|
||||
const filterChange = (values,record)=>{
|
||||
try {
|
||||
const slotName = columns[values.split('_').pop()].slotName as string
|
||||
@@ -96,7 +95,10 @@ const columns: TableInstance['columns'] = [
|
||||
{ title: '浏览器', dataIndex: 'browser', ellipsis: true, tooltip: true },
|
||||
{ title: '终端系统', dataIndex: 'os', ellipsis: true, tooltip: true }
|
||||
]
|
||||
|
||||
//导出登录日志
|
||||
const onExportFile = ()=>{
|
||||
useDownload(exportLog,'',queryForm)
|
||||
}
|
||||
const queryForm = reactive({
|
||||
module: '登录',
|
||||
ip: undefined,
|
||||
|
@@ -22,7 +22,7 @@
|
||||
<a-button @click="reset">重置</a-button>
|
||||
</template>
|
||||
<template #custom-right>
|
||||
<a-tooltip content="导出">
|
||||
<a-tooltip content="导出" @click="onExportFile">
|
||||
<a-button>
|
||||
<template #icon>
|
||||
<icon-download />
|
||||
@@ -56,11 +56,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listLog, type LogResp } from '@/apis'
|
||||
import { listLog, type LogResp,exportOperateLog } from '@/apis'
|
||||
import type { TableInstance } from '@arco-design/web-vue'
|
||||
import DateRangePicker from '@/components/DateRangePicker/index.vue'
|
||||
import OperationLogDetailDrawer from './OperationLogDetailDrawer.vue'
|
||||
import { useTable } from '@/hooks'
|
||||
import { useDownload, useTable } from '@/hooks'
|
||||
|
||||
defineOptions({ name: 'OperationLog' })
|
||||
const filterChange = (values,record)=>{
|
||||
@@ -109,7 +109,10 @@ const columns: TableInstance['columns'] = [
|
||||
{ title: '浏览器', dataIndex: 'browser', ellipsis: true, tooltip: true },
|
||||
{ title: '终端系统', dataIndex: 'os', ellipsis: true, tooltip: true }
|
||||
]
|
||||
|
||||
//导出操作日志
|
||||
const onExportFile = ()=>{
|
||||
useDownload(exportOperateLog,'',queryForm)
|
||||
}
|
||||
const queryForm = reactive({
|
||||
description: undefined,
|
||||
ip: undefined,
|
||||
|
Reference in New Issue
Block a user