Files
contract-review/front/src/hooks/common/download.ts
2026-01-30 14:25:12 +08:00

250 lines
7.4 KiB
TypeScript

import { onBeforeUnmount } from 'vue';
import axios from 'axios';
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
import type { MessageReactive } from 'naive-ui';
import type { MessageApiInjection } from 'naive-ui/es/message/src/MessageProvider';
import { useLoading } from '@sa/hooks';
import { getAuthorization } from '@/service/request/shared';
interface MimeMap {
xlsx: string;
zip: string;
oss: string;
}
const mimeMap: MimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
zip: 'application/zip',
oss: 'application/octet-stream'
};
const baseUrl = import.meta.env.VITE_SERVICE_BASE_URL;
export function useDownLoadFile() {
let messageReactive: MessageReactive | undefined | null;
const { loading, startLoading, endLoading } = useLoading();
function paramsGetToUrl(url: string, params: Record<string, any> | null): string {
let urlparams = url;
if (params) {
urlparams = `${url}?`;
for (const propName of Object.keys(params)) {
const value = params[propName];
const part = `${encodeURIComponent(propName)}=`;
if (value !== null && typeof value !== 'undefined') {
if (typeof value === 'object') {
// eslint-disable-next-line max-depth
for (const key of Object.keys(value)) {
// eslint-disable-next-line max-depth
if (value[key] !== null && typeof value[key] !== 'undefined') {
const par = `${propName}[${key}]`;
const subPart = `${encodeURIComponent(par)}=`;
urlparams += `${subPart + encodeURIComponent(value[key])}&`;
}
}
} else {
urlparams += `${part + encodeURIComponent(value)}&`;
}
}
}
urlparams = urlparams.slice(0, -1);
}
return baseUrl + urlparams;
}
function getPostParams(params: Record<string, any> | null) {
const dataParams: Record<string, any> = {}; // 用于存放请求体数据
// get请求映射params参数
if (params) {
for (const propName of Object.keys(params)) {
const value = params[propName];
if (value !== null && typeof value !== 'undefined') {
if (typeof value === 'object') {
// eslint-disable-next-line max-depth
for (const key of Object.keys(value)) {
// eslint-disable-next-line max-depth
if (value[key] !== null && typeof value[key] !== 'undefined') {
const nestedKey = `${propName}[${key}]`;
dataParams[nestedKey] = value[key];
}
}
} else {
dataParams[propName] = value;
}
}
}
}
return dataParams;
}
function handleRequest(config: AxiosRequestConfig, mine: keyof MimeMap, filename: string) {
createMessage('warning', '正在导出中,请稍后...');
axios(config)
.then(res => {
resolveBlob(res, mine, filename);
})
.catch(err => {
createMessage('error', err.message);
endLoading();
});
}
function downLoadOss(ossId: string | number = '', filename: string = '') {
handleRequest(
{
method: 'get',
url: `${baseUrl}/system/oss/download/${ossId}`,
responseType: 'blob',
headers: { Authorization: getAuthorization() }
},
'oss',
filename
);
}
function downLoadZip(url: string, filename: string = '') {
handleRequest(
{
method: 'get',
url: baseUrl + url,
responseType: 'blob',
headers: { Authorization: getAuthorization() }
},
'zip',
filename
);
}
function downLoadZipPost(url: string, params: Record<string, any> | null = null, filename: string = '') {
handleRequest(
{
method: 'post',
url: baseUrl + url,
data: getPostParams(params),
responseType: 'blob',
headers: {
Authorization: getAuthorization(),
'Content-Type': 'application/json;charset=utf-8' // 设置请求体类型
}
},
'zip',
filename
);
}
function downLoadExcel(url: string, params: Record<string, any> | null = null, filename: string = '') {
handleRequest(
{
method: 'get',
url: paramsGetToUrl(url, params),
responseType: 'blob',
headers: {
Authorization: getAuthorization()
}
},
'xlsx',
filename
);
}
function downLoadExcelPost(url: string, params: Record<string, any> | null = null, filename: string = '') {
handleRequest(
{
method: 'post',
url: baseUrl + url,
data: getPostParams(params),
responseType: 'blob',
headers: {
Authorization: getAuthorization(),
'Content-Type': 'application/json;charset=utf-8' // 设置请求体类型
}
},
'xlsx',
filename
);
}
function resolveBlob(res: AxiosResponse, mime: keyof MimeMap, filename: string) {
const mimeType = mimeMap[mime];
if (res.headers['content-type'].includes('application/json')) {
const fileReader = new FileReader();
fileReader.readAsText(new Blob([res.data], { type: 'application/octet-stream' }), 'utf-8');
fileReader.onload = () => {
try {
const result = JSON.parse(fileReader.result as string);
if (result.code === 500) {
removeMessage();
messageReactive = window.$message?.error(`导出失败:${result.msg}`, { duration: 0 });
}
} catch {
removeMessage();
messageReactive = window.$message?.error(`系统错误,请联系管理员`, { duration: 0 });
}
};
endLoading();
setTimeout(() => {
removeMessage();
}, 3000);
return;
}
const aLink = document.createElement('a');
const blob = new Blob([res.data], { type: mimeType });
// //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
const patt = /filename=([^;]+\.[^.;]+);*/;
const contentDisposition = decodeURI(res.headers['content-disposition']);
const result = patt.exec(contentDisposition);
// var fileName = result[1]
// fileName = fileName.replace(/\"/g, '')
let fileName: string | undefined = '';
if (filename) {
fileName = filename;
} else {
fileName = result?.[1];
fileName = fileName?.replace(/"/g, '');
}
aLink.style.display = 'none';
aLink.href = URL.createObjectURL(blob);
aLink.setAttribute('download', decodeURI(typeof fileName === 'string' ? fileName : '')); // 设置下载文件名称
document.body.appendChild(aLink);
aLink.click();
URL.revokeObjectURL(aLink.href); // 清除引用
document.body.removeChild(aLink);
createMessage('success', '导出成功');
endLoading();
setTimeout(() => {
removeMessage();
}, 3000);
}
// 创建消息框
function createMessage(type: keyof MessageApiInjection, message: string) {
startLoading();
removeMessage();
messageReactive = window.$message?.[type](message, { duration: 0 }) as MessageReactive;
}
// 移出消息框
function removeMessage() {
if (messageReactive) {
messageReactive.destroy();
messageReactive = null;
}
}
onBeforeUnmount(() => {
removeMessage();
});
return {
loading,
downLoadOss,
downLoadZip,
downLoadZipPost,
downLoadExcel,
downLoadExcelPost
};
}