feat:完善 file 上传

pull/71/head
YunaiV 2025-04-07 19:27:50 +08:00
parent 49632697a0
commit 6a76844bde
4 changed files with 45 additions and 61 deletions

View File

@ -1,4 +1,4 @@
import { type VbenFormSchema, z } from '#/adapter/form'; import { type VbenFormSchema } from '#/adapter/form';
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
import type { InfraFileApi } from '#/api/infra/file'; import type { InfraFileApi } from '#/api/infra/file';
@ -7,6 +7,21 @@ import { getRangePickerDefaultProps } from '#/utils/date';
const { hasAccessByCodes } = useAccess(); const { hasAccessByCodes } = useAccess();
/** 表单的字段 */
export function useFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'file',
label: '文件上传',
component: 'Upload',
rules: 'required',
componentProps: {
placeholder: '请选择要上传的文件',
},
}
];
}
/** 列表的搜索表单 */ /** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] { export function useGridFormSchema(): VbenFormSchema[] {
return [ return [

View File

@ -4,7 +4,7 @@ import type { InfraFileApi } from '#/api/infra/file';
import { Page, useVbenModal } from '@vben/common-ui'; import { Page, useVbenModal } from '@vben/common-ui';
import { Button, message, Image } from 'ant-design-vue'; import { Button, message, Image } from 'ant-design-vue';
import { Plus } from '@vben/icons'; import { Upload } from '@vben/icons';
import Form from './modules/form.vue'; import Form from './modules/form.vue';
import { $t } from '#/locales'; import { $t } from '#/locales';
@ -123,8 +123,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
<Grid table-title=""> <Grid table-title="">
<template #toolbar-tools> <template #toolbar-tools>
<Button type="primary" @click="onUpload"> <Button type="primary" @click="onUpload">
<Plus class="size-5" /> <Upload class="size-5" />
{{ $t('ui.actionTitle.upload', ['文件']) }} 上传图片
</Button> </Button>
</template> </template>
<template #file-content="{ row }"> <template #file-content="{ row }">

View File

@ -1,96 +1,65 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { InfraFileApi } from '#/api/infra/file'; import type { FileType } from 'ant-design-vue/es/upload/interface';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { Upload, Button } from 'ant-design-vue';
import { computed, ref } from 'vue'; import { $t } from '#/locales';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { uploadFile } from '#/api/infra/file'; import { uploadFile } from '#/api/infra/file';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
const fileList = ref<any[]>([]);
const uploadData = ref({ path: '' });
//
const formSchema = [
{
fieldName: 'file',
component: 'Upload',
label: '文件上传',
componentProps: {
fileList: fileList.value,
name: 'file',
maxCount: 1,
accept: '.jpg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx',
beforeUpload: (file: File) => {
uploadData.value.path = file.name;
return false; //
},
onChange: ({ fileList }: any) => {
fileList.value = fileList;
},
},
rules: 'required',
},
];
//
const [Form, formApi] = useVbenForm({ const [Form, formApi] = useVbenForm({
layout: 'horizontal', layout: 'horizontal',
schema: formSchema, schema: useFormSchema(),
showDefaultActions: false, showDefaultActions: false,
}); });
//
const [Modal, modalApi] = useVbenModal({ const [Modal, modalApi] = useVbenModal({
async onConfirm() { async onConfirm() {
const { valid } = await formApi.validate(); const { valid } = await formApi.validate();
if (!valid) { if (!valid) {
return; return;
} }
if (fileList.value.length === 0) {
message.error('请上传文件');
return;
}
modalApi.lock(); modalApi.lock();
// //
const data = await formApi.getValues();
try { try {
const formData = new FormData(); await uploadFile(data);
formData.append('file', fileList.value[0].originFileObj);
formData.append('path', uploadData.value.path);
await uploadFile(formData);
// //
await modalApi.close(); await modalApi.close();
emit('success'); emit('success');
message.success({ message.success({
content: $t('ui.actionMessage.uploadSuccess'), content: $t('ui.actionMessage.operationSuccess'),
key: 'action_process_msg', key: 'action_process_msg',
}); });
} finally { } finally {
modalApi.lock(false); modalApi.lock(false);
fileList.value = [];
} }
}, }
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
return;
}
//
fileList.value = [];
uploadData.value = { path: '' };
},
}); });
const getTitle = computed(() => $t('ui.actionTitle.upload', ['文件'])); /** 上传前 */
function beforeUpload(file: FileType) {
formApi.setFieldValue('file', file);
return false;
}
</script> </script>
<template> <template>
<Modal :title="getTitle"> <Modal title="上传图片">
<Form class="mx-4" /> <Form class="mx-4">
<template #file>
<div class="w-full">
<Upload :max-count="1" accept=".jpg,.png,.gif,.webp" :beforeUpload="beforeUpload">
<Button type="primary"> 选择图片 </Button>
</Upload>
</div>
</template>
</Form>
</Modal> </Modal>
</template> </template>

View File

@ -1,4 +1,4 @@
import { type VbenFormSchema, z } from '#/adapter/form'; import type { VbenFormSchema } from '#/adapter/form';
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
import type { InfraFileConfigApi } from '#/api/infra/file-config'; import type { InfraFileConfigApi } from '#/api/infra/file-config';