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-signal';
|
||||||
export * from './use-table';
|
export * from './use-table';
|
||||||
|
export type { LoadingApiInst } from './use-loading';
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
|
import type { Ref } from 'vue';
|
||||||
import useBoolean from './use-boolean';
|
import useBoolean from './use-boolean';
|
||||||
|
|
||||||
|
export interface LoadingApiInst {
|
||||||
|
loading: Ref<boolean>;
|
||||||
|
startLoading: () => void;
|
||||||
|
endLoading: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loading
|
* Loading
|
||||||
*
|
*
|
||||||
|
@ -202,6 +202,9 @@ importers:
|
|||||||
|
|
||||||
packages/materials:
|
packages/materials:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@sa/hooks':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../hooks
|
||||||
'@sa/utils':
|
'@sa/utils':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../utils
|
version: link:../utils
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { createTextVNode, defineComponent } from 'vue';
|
import { createTextVNode, defineComponent } from 'vue';
|
||||||
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui';
|
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui';
|
||||||
|
import { useLoading } from '@sa/hooks';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'AppProvider'
|
name: 'AppProvider'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const loading = useLoading(false);
|
||||||
|
|
||||||
const ContextHolder = defineComponent({
|
const ContextHolder = defineComponent({
|
||||||
name: 'ContextHolder',
|
name: 'ContextHolder',
|
||||||
setup() {
|
setup() {
|
||||||
@ -14,6 +17,7 @@ const ContextHolder = defineComponent({
|
|||||||
window.$dialog = useDialog();
|
window.$dialog = useDialog();
|
||||||
window.$message = useMessage();
|
window.$message = useMessage();
|
||||||
window.$notification = useNotification();
|
window.$notification = useNotification();
|
||||||
|
window.$loading = loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
register();
|
register();
|
||||||
@ -24,16 +28,18 @@ const ContextHolder = defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NLoadingBarProvider>
|
<NSpin class="h-full" content-class="h-full" :show="loading.loading.value">
|
||||||
<NDialogProvider>
|
<NLoadingBarProvider>
|
||||||
<NNotificationProvider>
|
<NDialogProvider>
|
||||||
<NMessageProvider>
|
<NNotificationProvider>
|
||||||
<ContextHolder />
|
<NMessageProvider>
|
||||||
<slot></slot>
|
<ContextHolder />
|
||||||
</NMessageProvider>
|
<slot></slot>
|
||||||
</NNotificationProvider>
|
</NMessageProvider>
|
||||||
</NDialogProvider>
|
</NNotificationProvider>
|
||||||
</NLoadingBarProvider>
|
</NDialogProvider>
|
||||||
|
</NLoadingBarProvider>
|
||||||
|
</NSpin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@ -6,3 +6,10 @@ export const yesOrNoRecord: Record<CommonType.YesOrNo, App.I18n.I18nKey> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const yesOrNoOptions = transformRecordToOption(yesOrNoRecord);
|
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
|
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 */
|
/** The id type */
|
||||||
type IdType = string | number;
|
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;
|
$message?: import('naive-ui').MessageProviderInst;
|
||||||
/** Notification instance */
|
/** Notification instance */
|
||||||
$notification?: import('naive-ui').NotificationProviderInst;
|
$notification?: import('naive-ui').NotificationProviderInst;
|
||||||
|
/** Content loading */
|
||||||
|
$loading?: import('@sa/hooks').LoadingApiInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ViewTransition {
|
interface ViewTransition {
|
||||||
|
@ -2,17 +2,25 @@
|
|||||||
import { NButton, NPopconfirm, NTooltip } from 'naive-ui';
|
import { NButton, NPopconfirm, NTooltip } from 'naive-ui';
|
||||||
import { useBoolean } from '@sa/hooks';
|
import { useBoolean } from '@sa/hooks';
|
||||||
import { ref } from 'vue';
|
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 { $t } from '@/locales';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||||
import SvgIcon from '@/components/custom/svg-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 GenTableSearch from './modules/gen-table-search.vue';
|
||||||
import TableImportDrawer from './modules/table-import-drawer.vue';
|
import TableImportDrawer from './modules/table-import-drawer.vue';
|
||||||
import GenTableOperateDrawer from './modules/gen-table-operate-drawer.vue';
|
import GenTableOperateDrawer from './modules/gen-table-operate-drawer.vue';
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
const { zip } = useDownload();
|
||||||
const { bool: importVisible, setTrue: openImportVisible } = useBoolean();
|
const { bool: importVisible, setTrue: openImportVisible } = useBoolean();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -101,13 +109,19 @@ const {
|
|||||||
tooltipContent={$t('common.edit')}
|
tooltipContent={$t('common.edit')}
|
||||||
onClick={() => edit(row.tableId!)}
|
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
|
<ButtonIcon
|
||||||
type="primary"
|
type="primary"
|
||||||
text
|
text
|
||||||
icon="ep:download"
|
icon="ep:download"
|
||||||
tooltipContent="生成代码"
|
tooltipContent="生成代码"
|
||||||
onClick={() => edit(row.tableId!)}
|
onClick={() => handleGenCode(row)}
|
||||||
/>
|
/>
|
||||||
<NTooltip placement="bottom">
|
<NTooltip placement="bottom">
|
||||||
{{
|
{{
|
||||||
@ -152,8 +166,6 @@ async function handleBatchDelete() {
|
|||||||
// request
|
// request
|
||||||
const { error } = await fetchBatchDeleteGenTable(checkedRowKeys.value);
|
const { error } = await fetchBatchDeleteGenTable(checkedRowKeys.value);
|
||||||
if (error) return;
|
if (error) return;
|
||||||
window.$message?.success('删除成功');
|
|
||||||
|
|
||||||
onBatchDeleted();
|
onBatchDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,8 +173,6 @@ async function handleDelete(id: CommonType.IdType) {
|
|||||||
// request
|
// request
|
||||||
const { error } = await fetchBatchDeleteGenTable([id]);
|
const { error } = await fetchBatchDeleteGenTable([id]);
|
||||||
if (error) return;
|
if (error) return;
|
||||||
window.$message?.success('删除成功');
|
|
||||||
|
|
||||||
onDeleted();
|
onDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +180,32 @@ function edit(id: CommonType.IdType) {
|
|||||||
handleEdit('tableId', id);
|
handleEdit('tableId', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refresh(id: CommonType.IdType) {
|
||||||
|
// request
|
||||||
|
const { error } = await fetchSynchGenDbList(id);
|
||||||
|
if (error) return;
|
||||||
|
window.$message?.success('同步成功');
|
||||||
|
}
|
||||||
|
|
||||||
function handleImport() {
|
function handleImport() {
|
||||||
openImportVisible();
|
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[]>([]);
|
const dataNameOptions = ref<CommonType.Option[]>([]);
|
||||||
|
|
||||||
@ -207,7 +238,13 @@ getDataNames();
|
|||||||
@refresh="getData"
|
@refresh="getData"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<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>
|
<template #icon>
|
||||||
<icon-ic-round-download class="text-icon" />
|
<icon-ic-round-download class="text-icon" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -129,6 +129,7 @@ async function handleSubmit() {
|
|||||||
|
|
||||||
watch(visible, () => {
|
watch(visible, () => {
|
||||||
if (visible.value) {
|
if (visible.value) {
|
||||||
|
genTableInfo.value = undefined;
|
||||||
tab.value = 'dragTable';
|
tab.value = 'dragTable';
|
||||||
getDeptOptions();
|
getDeptOptions();
|
||||||
getGenTableInfo();
|
getGenTableInfo();
|
||||||
|
Loading…
Reference in New Issue
Block a user