feat(文件管理): 文件管理部分接口

This commit is contained in:
baiqi 2023-10-31 14:46:03 +08:00 committed by 刘瑞斌
parent 6a375e5e9f
commit fdbd90c8a0
11 changed files with 148 additions and 66 deletions

View File

@ -17,6 +17,11 @@ export default mergeConfig(
changeOrigin: true, changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/front/, ''), rewrite: (path: string) => path.replace(/^\/front/, ''),
}, },
'/file': {
target: 'http://172.16.200.18:8081/',
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/front\/file/, ''),
},
'/base-display': { '/base-display': {
target: 'http://172.16.200.18:8081/', target: 'http://172.16.200.18:8081/',
changeOrigin: true, changeOrigin: true,

View File

@ -183,7 +183,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// authenticationScheme: 'Bearer', // authenticationScheme: 'Bearer',
authenticationScheme: '', authenticationScheme: '',
baseURL: `${window.location.origin}/${import.meta.env.VITE_API_BASE_URL as string}`, baseURL: `${window.location.origin}/${import.meta.env.VITE_API_BASE_URL as string}`,
timeout: 30 * 1000, timeout: 60 * 1000,
headers: { 'Content-Type': ContentTypeEnum.JSON }, headers: { 'Content-Type': ContentTypeEnum.JSON },
// 如果是form-data格式 // 如果是form-data格式
// headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED }, // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },

View File

@ -6,11 +6,13 @@ import {
DeleteModuleUrl, DeleteModuleUrl,
DownloadFileUrl, DownloadFileUrl,
FilePageUrl, FilePageUrl,
GetFileDetailUrl,
GetFileTypesUrl, GetFileTypesUrl,
GetModuleCountUrl, GetModuleCountUrl,
GetModuleUrl, GetModuleUrl,
MoveModuleUrl, MoveModuleUrl,
ReuploadFileUrl, ReuploadFileUrl,
ToggleJarFileUrl,
UpdateFileUrl, UpdateFileUrl,
UpdateModuleUrl, UpdateModuleUrl,
UploadFileUrl, UploadFileUrl,
@ -20,6 +22,7 @@ import type { CommonList } from '@/models/common';
import type { import type {
AddModuleParams, AddModuleParams,
BatchFileApiParams, BatchFileApiParams,
FileDetail,
FileItem, FileItem,
FileListQueryParams, FileListQueryParams,
ModuleCount, ModuleCount,
@ -100,3 +103,13 @@ export function deleteModule(id: string) {
export function getFileTypes(id: string) { export function getFileTypes(id: string) {
return MSR.get<string[]>({ url: GetFileTypesUrl, params: id }); return MSR.get<string[]>({ url: GetFileTypesUrl, params: id });
} }
// 获取文件详情
export function getFileDetail(id: string) {
return MSR.get<FileDetail>({ url: GetFileDetailUrl, params: id });
}
// jar文件启用禁用
export function toggleJarFileStatus(id: string, status: boolean) {
return MSR.get({ url: `${ToggleJarFileUrl}/${id}/${status}` });
}

View File

@ -14,3 +14,5 @@ export const GetModuleCountUrl = '/project/file/module/count'; // 模块统计
export const OriginImgUrl = '/file/preview/original'; // 预览图片文件接口-原图 export const OriginImgUrl = '/file/preview/original'; // 预览图片文件接口-原图
export const CompressImgUrl = '/file/preview/compressed'; // 预览图片文件接口-缩略图 export const CompressImgUrl = '/file/preview/compressed'; // 预览图片文件接口-缩略图
export const GetFileTypesUrl = '/project/file/type'; // 获取文件类型集合 export const GetFileTypesUrl = '/project/file/type'; // 获取文件类型集合
export const GetFileDetailUrl = '/project/file/get'; // 查看文件详情
export const ToggleJarFileUrl = '/project/file/jar-file-status'; // jar 文件启用禁用

View File

@ -65,12 +65,12 @@
visible: boolean; visible: boolean;
title: string; title: string;
width: number; width: number;
detailId: string | number; // id detailId: string; // id
detailIndex: number; // detailIndex: number; //
tableData: any[]; // tableData: any[]; //
pagination?: MsPaginationI; // pagination?: MsPaginationI; //
pageChange: (page: number) => Promise<void>; // pageChange: (page: number) => Promise<void>; //
getDetailFunc: (id: string | number) => Promise<any>; // getDetailFunc: (id: string) => Promise<any>; //
}>(); }>();
const emit = defineEmits(['update:visible', 'loaded']); const emit = defineEmits(['update:visible', 'loaded']);
@ -95,7 +95,7 @@
const loading = ref(false); const loading = ref(false);
const detail = ref<any>({}); const detail = ref<any>({});
const activeDetailId = ref<string | number>(props.detailId); const activeDetailId = ref<string>(props.detailId);
async function initDetail() { async function initDetail() {
try { try {

View File

@ -7,8 +7,11 @@
<a-image <a-image
v-if="fileType === 'image'" v-if="fileType === 'image'"
:src="props.url" :src="props.url"
fit="contain"
class="absolute top-0 h-full w-full" class="absolute top-0 h-full w-full"
:preview="false" :preview="false"
width="100%"
height="100%"
hide-footer hide-footer
/> />
<MsIcon <MsIcon

View File

@ -153,8 +153,8 @@
const handleMouseMove = (_event: MouseEvent) => { const handleMouseMove = (_event: MouseEvent) => {
if (resizing.value) { if (resizing.value) {
const newWidth = initialWidth + (startX - _event.clientX); // + const newWidth = initialWidth + (startX - _event.clientX); // +
if (newWidth >= (props.width || 480) && newWidth <= window.innerWidth * 0.8) { if (newWidth >= (props.width || 480) && newWidth <= window.innerWidth * 0.9) {
// width48080% // width48090%
drawerWidth.value = newWidth; drawerWidth.value = newWidth;
} }
} }
@ -215,6 +215,7 @@
.handle { .handle {
@apply absolute left-0 top-0 flex h-full items-center; @apply absolute left-0 top-0 flex h-full items-center;
z-index: 1;
width: 8px; width: 8px;
background-color: var(--color-neutral-3); background-color: var(--color-neutral-3);
cursor: col-resize; cursor: col-resize;

View File

@ -21,6 +21,15 @@ export interface FileItem {
updateTime: number; updateTime: number;
previewSrc: string; // 预览地址 previewSrc: string; // 预览地址
size: number; size: number;
enable: boolean; // jar文件启用禁用
}
// 文件详情
export interface FileDetail extends FileItem {
projectId: string;
moduleName: string; // 所属模块名
moduleId: string;
createUser: string;
createTime: number;
} }
// 上传文件参数 // 上传文件参数
export interface UploadFileParams { export interface UploadFileParams {

View File

@ -7,7 +7,7 @@
:title="t('project.fileManagement.detail')" :title="t('project.fileManagement.detail')"
:detail-id="props.fileId" :detail-id="props.fileId"
:detail-index="props.activeFileIndex" :detail-index="props.activeFileIndex"
:get-detail-func="async () => ({})" :get-detail-func="getFileDetail"
:pagination="props.pagination" :pagination="props.pagination"
:table-data="props.tableData" :table-data="props.tableData"
:page-change="props.pageChange" :page-change="props.pageChange"
@ -56,9 +56,9 @@
</a-space> </a-space>
</a-skeleton> </a-skeleton>
<template v-else> <template v-else>
<div class="mb-[16px] w-[102px]"> <div class="mb-[16px] h-[102px] w-[102px]">
<a-spin :loading="replaceLoading"> <a-spin class="h-full w-full" :loading="replaceLoading">
<MsPreviewCard <MsThumbnailCard
mode="hover" mode="hover"
:type="detail?.fileType" :type="detail?.fileType"
:url="`${CompressImgUrl}/${userStore.id}/${detail.id}`" :url="`${CompressImgUrl}/${userStore.id}/${detail.id}`"
@ -75,7 +75,7 @@
<template #value="{ item }"> <template #value="{ item }">
<div class="flex flex-wrap items-center"> <div class="flex flex-wrap items-center">
<a-tooltip <a-tooltip
:content="(item.value as string)" :content="`${item.value}`"
:mouse-enter-delay="300" :mouse-enter-delay="300"
:disabled="item.value === undefined || item.value === null || item.value?.toString() === ''" :disabled="item.value === undefined || item.value === null || item.value?.toString() === ''"
mini mini
@ -91,7 +91,11 @@
<template v-if="item.key === 'name'"> <template v-if="item.key === 'name'">
<popConfirm <popConfirm
mode="fileRename" mode="fileRename"
:field-config="{ placeholder: t('project.fileManagement.fileNamePlaceholder') }" :field-config="{
field: detail.name,
placeholder: t('project.fileManagement.fileNamePlaceholder'),
}"
:node-id="detail.id"
:all-names="[]" :all-names="[]"
@rename-finish="detailDrawerRef?.initDetail" @rename-finish="detailDrawerRef?.initDetail"
> >
@ -117,6 +121,7 @@
maxLength: 250, maxLength: 250,
isTextArea: true, isTextArea: true,
}" }"
:node-id="detail.id"
:all-names="[]" :all-names="[]"
@update-desc-finish="detailDrawerRef?.initDetail" @update-desc-finish="detailDrawerRef?.initDetail"
> >
@ -189,15 +194,15 @@
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import { getFileEnum } from '@/components/pure/ms-upload/iconMap'; import { getFileEnum } from '@/components/pure/ms-upload/iconMap';
import MsDetailDrawer from '@/components/business/ms-detail-drawer/index.vue'; import MsDetailDrawer from '@/components/business/ms-detail-drawer/index.vue';
import MsPreviewCard from '@/components/business/ms-thumbnail-card/index.vue'; import MsThumbnailCard from '@/components/business/ms-thumbnail-card/index.vue';
import popConfirm from './popConfirm.vue'; import popConfirm from './popConfirm.vue';
import { reuploadFile, updateFile } from '@/api/modules/project-management/fileManagement'; import { getFileDetail, reuploadFile, updateFile } from '@/api/modules/project-management/fileManagement';
import { CompressImgUrl, OriginImgUrl } from '@/api/requrls/project-management/fileManagement'; import { CompressImgUrl, OriginImgUrl } from '@/api/requrls/project-management/fileManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useLocale from '@/locale/useLocale'; import useLocale from '@/locale/useLocale';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { downloadUrlFile } from '@/utils'; import { downloadUrlFile, formatFileSize } from '@/utils';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
@ -249,11 +254,13 @@
} }
const fileType = ref('unknown'); const fileType = ref('unknown');
const renameTitle = ref(''); //
function loadedFile(detail: any) { function loadedFile(detail: any) {
if (detail.fileType) { if (detail.fileType) {
fileType.value = getFileEnum(`/${detail.fileType.toLowerCase()}`); fileType.value = getFileEnum(`/${detail.fileType.toLowerCase()}`);
} }
renameTitle.value = detail.name;
fileDescriptions.value = [ fileDescriptions.value = [
{ {
label: t('project.fileManagement.name'), label: t('project.fileManagement.name'),
@ -271,15 +278,15 @@
}, },
{ {
label: t('project.fileManagement.size'), label: t('project.fileManagement.size'),
value: detail.size, value: formatFileSize(detail.size),
}, },
{ {
label: t('project.fileManagement.creator'), label: t('project.fileManagement.creator'),
value: detail.creator, value: detail.createUser,
}, },
{ {
label: t('project.fileManagement.fileModule'), label: t('project.fileManagement.fileModule'),
value: detail.fileModule, value: detail.moduleName,
key: 'fileModule', key: 'fileModule',
}, },
{ {

View File

@ -92,6 +92,9 @@
() => props.fieldConfig?.field, () => props.fieldConfig?.field,
(val) => { (val) => {
form.value.field = val || ''; form.value.field = val || '';
},
{
deep: true,
} }
); );
@ -177,10 +180,12 @@
} }
} }
function reset() { function reset(val: boolean) {
if (!val) {
form.value.field = ''; form.value.field = '';
formRef.value?.resetFields(); formRef.value?.resetFields();
} }
}
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped></style>

View File

@ -50,12 +50,15 @@
</a-button> </a-button>
</a-tooltip> </a-tooltip>
</template> </template>
<template #size="{ record }">
<span>{{ formatFileSize(record.size) }}</span>
</template>
<template #action="{ record }"> <template #action="{ record }">
<MsButton type="text" class="mr-[8px]" @click="handleDownload(record)"> <MsButton type="text" class="mr-[8px]" @click="handleDownload(record)">
{{ t('project.fileManagement.download') }} {{ t('project.fileManagement.download') }}
</MsButton> </MsButton>
<MsTableMoreAction <MsTableMoreAction
:list="record.fileType === 'jar' ? jarFileActions : normalFileActions" :list="record.fileType === 'jar' ? getJarFileActions(record) : normalFileActions"
@select="handleMoreActionSelect($event, record)" @select="handleMoreActionSelect($event, record)"
/> />
</template> </template>
@ -88,7 +91,7 @@
:type="item.fileType" :type="item.fileType"
:url="`${CompressImgUrl}/${userStore.id}/${item.id}`" :url="`${CompressImgUrl}/${userStore.id}/${item.id}`"
:footer-text="item.name" :footer-text="item.name"
:more-actions="item.fileType === 'JAR' ? jarFileActions : normalFileActions" :more-actions="item.fileType === 'JAR' ? getJarFileActions(item) : normalFileActions"
@click="openFileDetail(item.id, index)" @click="openFileDetail(item.id, index)"
@action-select="handleMoreActionSelect($event, item)" @action-select="handleMoreActionSelect($event, item)"
/> />
@ -293,6 +296,7 @@
downloadFile, downloadFile,
getFileList, getFileList,
getFileTypes, getFileTypes,
toggleJarFileStatus,
updateFile, updateFile,
uploadFile, uploadFile,
} from '@/api/modules/project-management/fileManagement'; } from '@/api/modules/project-management/fileManagement';
@ -303,7 +307,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import useAsyncTaskStore from '@/store/modules/app/asyncTask'; import useAsyncTaskStore from '@/store/modules/app/asyncTask';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { characterLimit, downloadByteFile } from '@/utils'; import { characterLimit, downloadByteFile, formatFileSize } from '@/utils';
import type { FileItem, FileListQueryParams } from '@/models/projectManagement/file'; import type { FileItem, FileListQueryParams } from '@/models/projectManagement/file';
import { RouteEnum } from '@/enums/routeEnum'; import { RouteEnum } from '@/enums/routeEnum';
@ -343,6 +347,7 @@
const res = await getFileTypes(appStore.currentProjectId); const res = await getFileTypes(appStore.currentProjectId);
tableFileTypeOptions.value = res; tableFileTypeOptions.value = res;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} finally { } finally {
fileTypeLoading.value = false; fileTypeLoading.value = false;
@ -376,14 +381,19 @@
}, },
]; ];
function getJarFileActions(record: FileItem) {
const jarFileActions: ActionsItem[] = [ const jarFileActions: ActionsItem[] = [
{ {
label: 'project.fileManagement.move', label: 'project.fileManagement.move',
eventTag: 'move', eventTag: 'move',
}, },
{
label: 'common.enable',
eventTag: 'toggle',
},
{ {
label: 'common.disable', label: 'common.disable',
eventTag: 'disabled', eventTag: 'toggle',
}, },
{ {
isDivider: true, isDivider: true,
@ -394,6 +404,11 @@
danger: true, danger: true,
}, },
]; ];
if (record.enable) {
return jarFileActions.filter((e) => e.label !== 'common.enable');
}
return jarFileActions.filter((e) => e.label !== 'common.disable');
}
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
@ -407,6 +422,11 @@
dataIndex: 'fileType', dataIndex: 'fileType',
width: 90, width: 90,
}, },
{
title: 'project.fileManagement.size',
dataIndex: 'size',
slotName: 'size',
},
{ {
title: 'project.fileManagement.tag', title: 'project.fileManagement.tag',
dataIndex: 'tags', dataIndex: 'tags',
@ -722,9 +742,11 @@
} }
/** /**
* 禁用 jar 文件 * 启用/禁用 jar 文件
*/ */
function disabledFile(record: FileItem) { async function toggleJarFile(record: FileItem) {
if (record.enable) {
//
openModal({ openModal({
type: 'warning', type: 'warning',
title: t('project.fileManagement.disabledFileTipTitle', { name: characterLimit(record.name) }), title: t('project.fileManagement.disabledFileTipTitle', { name: characterLimit(record.name) }),
@ -734,6 +756,7 @@
maskClosable: false, maskClosable: false,
onBeforeOk: async () => { onBeforeOk: async () => {
try { try {
await toggleJarFileStatus(record.id, !record.enable);
Message.success(t('common.disableSuccess')); Message.success(t('common.disableSuccess'));
if (showType.value === 'card') { if (showType.value === 'card') {
cardListRef.value?.reload(); cardListRef.value?.reload();
@ -747,6 +770,20 @@
}, },
hideCancel: false, hideCancel: false,
}); });
} else {
try {
await toggleJarFileStatus(record.id, !record.enable);
Message.success(t('common.enableSuccess'));
if (showType.value === 'card') {
cardListRef.value?.reload();
} else {
loadList();
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
} }
/** /**
@ -763,8 +800,8 @@
case 'delete': case 'delete':
delFile(record, false); delFile(record, false);
break; break;
case 'disabled': case 'toggle':
disabledFile(record); toggleJarFile(record);
break; break;
default: default:
break; break;