feat: add file management API and UI components for file operations
parent
2df8440f6f
commit
19c50c2729
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { type PageParam, requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
export namespace FileApi {
|
||||||
|
export interface FilePageReqVO extends PageParam {
|
||||||
|
path?: string;
|
||||||
|
type?: string;
|
||||||
|
createTime?: Date[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件预签名地址 Response VO
|
||||||
|
export interface FilePresignedUrlRespVO {
|
||||||
|
// 文件配置编号
|
||||||
|
configId: number;
|
||||||
|
// 文件上传 URL
|
||||||
|
uploadUrl: string;
|
||||||
|
// 文件 URL
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询文件列表
|
||||||
|
export function getFilePage(params: FileApi.FilePageReqVO) {
|
||||||
|
return requestClient.get('/infra/file/page', { params });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除文件
|
||||||
|
export function deleteFile(id: number) {
|
||||||
|
return requestClient.delete(`/infra/file/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件预签名地址
|
||||||
|
export function getFilePresignedUrl(path: string) {
|
||||||
|
return requestClient.get<FileApi.FilePresignedUrlRespVO>(
|
||||||
|
'/infra/file/presigned-url',
|
||||||
|
{ params: { path } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createFile(data: any) {
|
||||||
|
return requestClient.post('/infra/file/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
export function uploadFile(data: any) {
|
||||||
|
return requestClient.upload('/infra/file/upload', data);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
|
import { uploadFormSchema } from '../file.data';
|
||||||
|
|
||||||
|
const [Modal] = useVbenModal({
|
||||||
|
title: '上传文件',
|
||||||
|
});
|
||||||
|
const [Form] = useVbenForm({
|
||||||
|
schema: uploadFormSchema,
|
||||||
|
showDefaultActions: false,
|
||||||
|
handleSubmit: async (_values) => {},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal>
|
||||||
|
<Form />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
import type { VxeGridProps } from '@vben/plugins/vxe-table';
|
||||||
|
|
||||||
|
import type { VbenFormProps } from '#/adapter/form';
|
||||||
|
|
||||||
|
import { type FileApi, uploadFile } from '#/api/infra/file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件 表格查询表单配置
|
||||||
|
*/
|
||||||
|
export const formSchema: VbenFormProps['schema'] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件 表格配置
|
||||||
|
*/
|
||||||
|
export const tableColumns: VxeGridProps<FileApi.FilePageReqVO>['columns'] = [
|
||||||
|
{
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'checkbox',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'seq',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{ field: 'name', title: '文件名称' },
|
||||||
|
{ field: 'path', title: '文件路径' },
|
||||||
|
{ field: 'url', title: '文件 URL' },
|
||||||
|
{ field: 'type', title: '文件类型' },
|
||||||
|
{ field: 'size', title: '文件大小' },
|
||||||
|
{ field: 'createTime', title: '创建时间' },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件 编辑表单配置
|
||||||
|
*/
|
||||||
|
export const editFormSchema: VbenFormProps['schema'] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件 上传表单配置
|
||||||
|
*/
|
||||||
|
export const uploadFormSchema: VbenFormProps['schema'] = [
|
||||||
|
{
|
||||||
|
fieldName: 'file',
|
||||||
|
label: '文件',
|
||||||
|
component: 'ApiUpload',
|
||||||
|
componentProps: {
|
||||||
|
api: uploadFile,
|
||||||
|
uploadMode: 'file',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent, reactive } from 'vue';
|
||||||
|
|
||||||
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { useVbenVxeGrid, type VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
import { getFilePage } from '#/api/infra/file';
|
||||||
|
import { ActionButtons } from '#/components/action-buttons';
|
||||||
|
|
||||||
|
import { tableColumns } from './file.data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格配置
|
||||||
|
*/
|
||||||
|
const gridOptions = reactive<any>({
|
||||||
|
columns: tableColumns,
|
||||||
|
height: 'auto',
|
||||||
|
checkboxConfig: {
|
||||||
|
reserve: true,
|
||||||
|
highlight: true,
|
||||||
|
// labelField: 'id',
|
||||||
|
},
|
||||||
|
rowConfig: {
|
||||||
|
keyField: 'id',
|
||||||
|
},
|
||||||
|
proxyConfig: {
|
||||||
|
ajax: {
|
||||||
|
query: async (e, params) => {
|
||||||
|
const data = await getFilePage({
|
||||||
|
pageNo: e.page.currentPage,
|
||||||
|
pageSize: e.page.pageSize,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as VxeGridProps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格事件
|
||||||
|
*/
|
||||||
|
const gridEvents = reactive<any>({});
|
||||||
|
|
||||||
|
// 使用表格组件
|
||||||
|
const [Grid] = useVbenVxeGrid({
|
||||||
|
gridOptions,
|
||||||
|
gridEvents,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 上传表单组件
|
||||||
|
*/
|
||||||
|
const [UploadForm, uploadFormApi] = useVbenModal({
|
||||||
|
connectedComponent: defineAsyncComponent(
|
||||||
|
() => import('./components/upload-form.vue'),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleUpload = () => {
|
||||||
|
uploadFormApi.open();
|
||||||
|
};
|
||||||
|
const handleView = (_row: any) => {};
|
||||||
|
const handleEdit = (_row: any) => {};
|
||||||
|
const handleDelete = (_row: any) => {};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Page auto-content-height>
|
||||||
|
<Grid>
|
||||||
|
<template #toolbar-actions>
|
||||||
|
<ActionButtons
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
type: 'primary',
|
||||||
|
label: '上传文件',
|
||||||
|
icon: 'ant-design:plus-outlined',
|
||||||
|
onClick: handleUpload,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<ActionButtons
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
label: '查看',
|
||||||
|
icon: 'ant-design:eye-outlined',
|
||||||
|
onClick: () => handleView(row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
icon: 'ant-design:edit-outlined',
|
||||||
|
onClick: () => handleEdit(row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
onClick: () => handleDelete(row),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Grid>
|
||||||
|
<UploadForm />
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
Loading…
Reference in New Issue