feat: 封装下载hooks

This commit is contained in:
xlsea 2024-09-05 11:06:30 +08:00
parent 824974e904
commit 0c3ea2dc86
11 changed files with 222 additions and 19 deletions

View File

@ -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';

View File

@ -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
*

View File

@ -202,6 +202,9 @@ importers:
packages/materials:
dependencies:
'@sa/hooks':
specifier: workspace:*
version: link:../hooks
'@sa/utils':
specifier: workspace:*
version: link:../utils

View File

@ -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>

View File

@ -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: '系统未知错误,请反馈给管理员'
};

View 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
};
}

View File

@ -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 }
});
}

View File

@ -28,4 +28,7 @@ declare namespace CommonType {
/** The id type */
type IdType = string | number;
/** The res error code */
type ErrorCode = '401' | '403' | '404' | 'default';
}

View File

@ -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 {

View File

@ -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>

View File

@ -129,6 +129,7 @@ async function handleSubmit() {
watch(visible, () => {
if (visible.value) {
genTableInfo.value = undefined;
tab.value = 'dragTable';
getDeptOptions();
getGenTableInfo();