feat:完善 file 上传
							parent
							
								
									49632697a0
								
							
						
					
					
						commit
						6a76844bde
					
				| 
						 | 
				
			
			@ -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 { InfraFileApi } from '#/api/infra/file';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,21 @@ import { getRangePickerDefaultProps } from '#/utils/date';
 | 
			
		|||
 | 
			
		||||
const { hasAccessByCodes } = useAccess();
 | 
			
		||||
 | 
			
		||||
/** 表单的字段 */
 | 
			
		||||
export function useFormSchema(): VbenFormSchema[] {
 | 
			
		||||
  return [
 | 
			
		||||
    {
 | 
			
		||||
      fieldName: 'file',
 | 
			
		||||
      label: '文件上传',
 | 
			
		||||
      component: 'Upload',
 | 
			
		||||
      rules: 'required',
 | 
			
		||||
      componentProps: {
 | 
			
		||||
        placeholder: '请选择要上传的文件',
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 列表的搜索表单 */
 | 
			
		||||
export function useGridFormSchema(): VbenFormSchema[] {
 | 
			
		||||
  return [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import type { InfraFileApi } from '#/api/infra/file';
 | 
			
		|||
 | 
			
		||||
import { Page, useVbenModal } from '@vben/common-ui';
 | 
			
		||||
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 { $t } from '#/locales';
 | 
			
		||||
| 
						 | 
				
			
			@ -123,8 +123,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
 | 
			
		|||
    <Grid table-title="文件列表">
 | 
			
		||||
      <template #toolbar-tools>
 | 
			
		||||
        <Button type="primary" @click="onUpload">
 | 
			
		||||
          <Plus class="size-5" />
 | 
			
		||||
          {{ $t('ui.actionTitle.upload', ['文件']) }}
 | 
			
		||||
          <Upload class="size-5" />
 | 
			
		||||
          上传图片
 | 
			
		||||
        </Button>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template #file-content="{ row }">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,96 +1,65 @@
 | 
			
		|||
<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 { 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 { uploadFile } from '#/api/infra/file';
 | 
			
		||||
import { $t } from '#/locales';
 | 
			
		||||
 | 
			
		||||
import { useFormSchema } from '../data';
 | 
			
		||||
 | 
			
		||||
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({
 | 
			
		||||
  layout: 'horizontal',
 | 
			
		||||
  schema: formSchema,
 | 
			
		||||
  schema: useFormSchema(),
 | 
			
		||||
  showDefaultActions: false,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 模态框实例
 | 
			
		||||
const [Modal, modalApi] = useVbenModal({
 | 
			
		||||
  async onConfirm() {
 | 
			
		||||
    const { valid } = await formApi.validate();
 | 
			
		||||
    if (!valid) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (fileList.value.length === 0) {
 | 
			
		||||
      message.error('请上传文件');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    modalApi.lock();
 | 
			
		||||
    // 提交表单
 | 
			
		||||
    const data = await formApi.getValues();
 | 
			
		||||
    try {
 | 
			
		||||
      const formData = new FormData();
 | 
			
		||||
      formData.append('file', fileList.value[0].originFileObj);
 | 
			
		||||
      formData.append('path', uploadData.value.path);
 | 
			
		||||
 | 
			
		||||
      await uploadFile(formData);
 | 
			
		||||
 | 
			
		||||
      await uploadFile(data);
 | 
			
		||||
      // 关闭并提示
 | 
			
		||||
      await modalApi.close();
 | 
			
		||||
      emit('success');
 | 
			
		||||
      message.success({
 | 
			
		||||
        content: $t('ui.actionMessage.uploadSuccess'),
 | 
			
		||||
        content: $t('ui.actionMessage.operationSuccess'),
 | 
			
		||||
        key: 'action_process_msg',
 | 
			
		||||
      });
 | 
			
		||||
    } finally {
 | 
			
		||||
      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>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <Modal :title="getTitle">
 | 
			
		||||
    <Form class="mx-4" />
 | 
			
		||||
  <Modal title="上传图片">
 | 
			
		||||
    <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>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 { InfraFileConfigApi } from '#/api/infra/file-config';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue