feat: 封装下载hooks
This commit is contained in:
parent
824974e904
commit
0c3ea2dc86
@ -9,3 +9,4 @@ export { useBoolean, useLoading, useCountDown, useContext, useSvgIconRender, use
|
||||
|
||||
export * from './use-signal';
|
||||
export * from './use-table';
|
||||
export type { LoadingApiInst } from './use-loading';
|
||||
|
@ -1,5 +1,12 @@
|
||||
import type { Ref } from 'vue';
|
||||
import useBoolean from './use-boolean';
|
||||
|
||||
export interface LoadingApiInst {
|
||||
loading: Ref<boolean>;
|
||||
startLoading: () => void;
|
||||
endLoading: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loading
|
||||
*
|
||||
|
@ -202,6 +202,9 @@ importers:
|
||||
|
||||
packages/materials:
|
||||
dependencies:
|
||||
'@sa/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../hooks
|
||||
'@sa/utils':
|
||||
specifier: workspace:*
|
||||
version: link:../utils
|
||||
|
@ -1,11 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { createTextVNode, defineComponent } from 'vue';
|
||||
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui';
|
||||
import { useLoading } from '@sa/hooks';
|
||||
|
||||
defineOptions({
|
||||
name: 'AppProvider'
|
||||
});
|
||||
|
||||
const loading = useLoading(false);
|
||||
|
||||
const ContextHolder = defineComponent({
|
||||
name: 'ContextHolder',
|
||||
setup() {
|
||||
@ -14,6 +17,7 @@ const ContextHolder = defineComponent({
|
||||
window.$dialog = useDialog();
|
||||
window.$message = useMessage();
|
||||
window.$notification = useNotification();
|
||||
window.$loading = loading;
|
||||
}
|
||||
|
||||
register();
|
||||
@ -24,16 +28,18 @@ const ContextHolder = defineComponent({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NLoadingBarProvider>
|
||||
<NDialogProvider>
|
||||
<NNotificationProvider>
|
||||
<NMessageProvider>
|
||||
<ContextHolder />
|
||||
<slot></slot>
|
||||
</NMessageProvider>
|
||||
</NNotificationProvider>
|
||||
</NDialogProvider>
|
||||
</NLoadingBarProvider>
|
||||
<NSpin class="h-full" content-class="h-full" :show="loading.loading.value">
|
||||
<NLoadingBarProvider>
|
||||
<NDialogProvider>
|
||||
<NNotificationProvider>
|
||||
<NMessageProvider>
|
||||
<ContextHolder />
|
||||
<slot></slot>
|
||||
</NMessageProvider>
|
||||
</NNotificationProvider>
|
||||
</NDialogProvider>
|
||||
</NLoadingBarProvider>
|
||||
</NSpin>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
@ -6,3 +6,10 @@ export const yesOrNoRecord: Record<CommonType.YesOrNo, App.I18n.I18nKey> = {
|
||||
};
|
||||
|
||||
export const yesOrNoOptions = transformRecordToOption(yesOrNoRecord);
|
||||
|
||||
export const errorCodeRecord: Record<CommonType.ErrorCode, string> = {
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
default: '系统未知错误,请反馈给管理员'
|
||||
};
|
||||
|
102
src/hooks/business/download.ts
Normal file
102
src/hooks/business/download.ts
Normal file
@ -0,0 +1,102 @@
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { getServiceBaseURL } from '@/utils/service';
|
||||
import { errorCodeRecord } from '@/constants/common';
|
||||
|
||||
export function useDownload() {
|
||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
||||
|
||||
function downloadByData(data: BlobPart, filename: string, type: string = 'application/octet-stream') {
|
||||
const blobData = [data];
|
||||
const blob = new Blob(blobData, { type });
|
||||
|
||||
const blobURL = window.URL.createObjectURL(blob);
|
||||
const tempLink = document.createElement('a');
|
||||
tempLink.style.display = 'none';
|
||||
tempLink.href = blobURL;
|
||||
tempLink.setAttribute('download', filename);
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.setAttribute('target', '_blank');
|
||||
}
|
||||
document.body.appendChild(tempLink);
|
||||
tempLink.click();
|
||||
document.body.removeChild(tempLink);
|
||||
window.URL.revokeObjectURL(blobURL);
|
||||
}
|
||||
|
||||
function download(url: string, params: any, fileName: string) {
|
||||
window.$loading?.startLoading();
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const now = new Date().getTime();
|
||||
const formData = new FormData();
|
||||
Object.keys(params).forEach(key => formData.append(key, params[key]));
|
||||
fetch(`${baseURL}${url}?t=${now}`, {
|
||||
method: 'post',
|
||||
body: formData,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
.then(async response => {
|
||||
if (response.headers.get('Content-Type')?.includes('application/json')) {
|
||||
const res = await response.json();
|
||||
const code = res.code as CommonType.ErrorCode;
|
||||
throw new Error(errorCodeRecord[code] || res.msg || errorCodeRecord.default);
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(data => downloadByData(data, fileName, 'application/zip'))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
}
|
||||
|
||||
function oss(ossId: CommonType.IdType) {
|
||||
window.$loading?.startLoading();
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const url = `/resource/oss/download/${ossId}`;
|
||||
const now = new Date().getTime();
|
||||
let fileName = String(`${ossId}-${now}`);
|
||||
fetch(`${baseURL}${url}?t=${now}`, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!
|
||||
}
|
||||
})
|
||||
.then(async response => {
|
||||
fileName = String(response.headers.get('Download-Filename'));
|
||||
return response.blob();
|
||||
})
|
||||
.then(data => downloadByData(data, fileName))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
}
|
||||
|
||||
function zip(url: string, fileName: string) {
|
||||
window.$loading?.startLoading();
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const now = new Date().getTime();
|
||||
fetch(`${baseURL}${url}${url.includes('?') ? '&' : '?'}t=${now}`, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!
|
||||
}
|
||||
})
|
||||
.then(async response => response.blob())
|
||||
.then(data => downloadByData(data, fileName, 'application/zip'))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
}
|
||||
|
||||
return {
|
||||
oss,
|
||||
zip,
|
||||
download
|
||||
};
|
||||
}
|
@ -65,3 +65,37 @@ export function fetchGetGenDbList(params?: Api.Tool.GenTableDbSearchParams) {
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/** 同步数据库 */
|
||||
export function fetchSynchGenDbList(tableId: CommonType.IdType) {
|
||||
return request<Api.Tool.GenTableDbList>({
|
||||
url: `/tool/gen/synchDb/${tableId}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/** 预览代码 */
|
||||
export function fetchGetGenPreview(tableId: CommonType.IdType) {
|
||||
return request<Api.Tool.GenTableDbList>({
|
||||
url: `/tool/gen/preview/${tableId}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/** 生成代码(自定义路径) */
|
||||
export function fetchGenCode(tableId: CommonType.IdType) {
|
||||
return request<Api.Tool.GenTableDbList>({
|
||||
url: `/tool/gen/genCode/${tableId}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量生成代码 */
|
||||
export function fetchBatchGenCode(tableIds: CommonType.IdType[]) {
|
||||
const tableIdStr = tableIds.join(',');
|
||||
return request<Api.Tool.GenTableDbList>({
|
||||
url: '/tool/gen/genCode/',
|
||||
method: 'get',
|
||||
params: { tableIdStr }
|
||||
});
|
||||
}
|
||||
|
3
src/typings/common.d.ts
vendored
3
src/typings/common.d.ts
vendored
@ -28,4 +28,7 @@ declare namespace CommonType {
|
||||
|
||||
/** The id type */
|
||||
type IdType = string | number;
|
||||
|
||||
/** The res error code */
|
||||
type ErrorCode = '401' | '403' | '404' | 'default';
|
||||
}
|
||||
|
2
src/typings/global.d.ts
vendored
2
src/typings/global.d.ts
vendored
@ -12,6 +12,8 @@ declare global {
|
||||
$message?: import('naive-ui').MessageProviderInst;
|
||||
/** Notification instance */
|
||||
$notification?: import('naive-ui').NotificationProviderInst;
|
||||
/** Content loading */
|
||||
$loading?: import('@sa/hooks').LoadingApiInst;
|
||||
}
|
||||
|
||||
interface ViewTransition {
|
||||
|
@ -2,17 +2,25 @@
|
||||
import { NButton, NPopconfirm, NTooltip } from 'naive-ui';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { ref } from 'vue';
|
||||
import { fetchBatchDeleteGenTable, fetchGetGenDataNames, fetchGetGenTableList } from '@/service/api';
|
||||
import {
|
||||
fetchBatchDeleteGenTable,
|
||||
fetchGenCode,
|
||||
fetchGetGenDataNames,
|
||||
fetchGetGenTableList,
|
||||
fetchSynchGenDbList
|
||||
} from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||
import { useDownload } from '@/hooks/business/download';
|
||||
import GenTableSearch from './modules/gen-table-search.vue';
|
||||
import TableImportDrawer from './modules/table-import-drawer.vue';
|
||||
import GenTableOperateDrawer from './modules/gen-table-operate-drawer.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { zip } = useDownload();
|
||||
const { bool: importVisible, setTrue: openImportVisible } = useBoolean();
|
||||
|
||||
const {
|
||||
@ -101,13 +109,19 @@ const {
|
||||
tooltipContent={$t('common.edit')}
|
||||
onClick={() => edit(row.tableId!)}
|
||||
/>
|
||||
<ButtonIcon type="primary" text icon="ep:refresh" tooltipContent="同步" onClick={() => edit(row.tableId!)} />
|
||||
<ButtonIcon
|
||||
type="primary"
|
||||
text
|
||||
icon="ep:refresh"
|
||||
tooltipContent="同步"
|
||||
onClick={() => refresh(row.tableId!)}
|
||||
/>
|
||||
<ButtonIcon
|
||||
type="primary"
|
||||
text
|
||||
icon="ep:download"
|
||||
tooltipContent="生成代码"
|
||||
onClick={() => edit(row.tableId!)}
|
||||
onClick={() => handleGenCode(row)}
|
||||
/>
|
||||
<NTooltip placement="bottom">
|
||||
{{
|
||||
@ -152,8 +166,6 @@ async function handleBatchDelete() {
|
||||
// request
|
||||
const { error } = await fetchBatchDeleteGenTable(checkedRowKeys.value);
|
||||
if (error) return;
|
||||
window.$message?.success('删除成功');
|
||||
|
||||
onBatchDeleted();
|
||||
}
|
||||
|
||||
@ -161,8 +173,6 @@ async function handleDelete(id: CommonType.IdType) {
|
||||
// request
|
||||
const { error } = await fetchBatchDeleteGenTable([id]);
|
||||
if (error) return;
|
||||
window.$message?.success('删除成功');
|
||||
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
@ -170,11 +180,32 @@ function edit(id: CommonType.IdType) {
|
||||
handleEdit('tableId', id);
|
||||
}
|
||||
|
||||
async function refresh(id: CommonType.IdType) {
|
||||
// request
|
||||
const { error } = await fetchSynchGenDbList(id);
|
||||
if (error) return;
|
||||
window.$message?.success('同步成功');
|
||||
}
|
||||
|
||||
function handleImport() {
|
||||
openImportVisible();
|
||||
}
|
||||
|
||||
function handleGenCode() {}
|
||||
async function handleGenCode(row?: Api.Tool.GenTable) {
|
||||
const tableIds = row?.tableId || checkedRowKeys.value.join(',');
|
||||
if (!tableIds || tableIds === '') {
|
||||
window.$message?.error('请选择要生成的数据');
|
||||
return;
|
||||
}
|
||||
// request
|
||||
if (row?.genType === '1') {
|
||||
const { error } = await fetchGenCode(row.tableId!);
|
||||
if (error) return;
|
||||
window.$message?.success('生成成功');
|
||||
} else {
|
||||
await zip(`/tool/gen/batchGenCode?tableIdStr=${tableIds}`, `ruoyi-${new Date().getTime()}.zip`);
|
||||
}
|
||||
}
|
||||
|
||||
const dataNameOptions = ref<CommonType.Option[]>([]);
|
||||
|
||||
@ -207,7 +238,13 @@ getDataNames();
|
||||
@refresh="getData"
|
||||
>
|
||||
<template #prefix>
|
||||
<NButton :disabled="checkedRowKeys.length === 0" size="small" ghost type="primary" @click="handleGenCode">
|
||||
<NButton
|
||||
:disabled="checkedRowKeys.length === 0"
|
||||
size="small"
|
||||
ghost
|
||||
type="primary"
|
||||
@click="() => handleGenCode()"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-ic-round-download class="text-icon" />
|
||||
</template>
|
||||
|
@ -129,6 +129,7 @@ async function handleSubmit() {
|
||||
|
||||
watch(visible, () => {
|
||||
if (visible.value) {
|
||||
genTableInfo.value = undefined;
|
||||
tab.value = 'dragTable';
|
||||
getDeptOptions();
|
||||
getGenTableInfo();
|
||||
|
Loading…
Reference in New Issue
Block a user