diff --git a/apps/example/src/views/component_example/file_upload/_demo2.vue b/apps/example/src/views/component_example/file_upload/_demo2.vue old mode 100755 new mode 100644 index c80d1e99..daa0dcd4 --- a/apps/example/src/views/component_example/file_upload/_demo2.vue +++ b/apps/example/src/views/component_example/file_upload/_demo2.vue @@ -5,6 +5,21 @@ const files = ref([ { name: 'logo.svg', size: 1024 * 1024, url: 'https://fantastic-admin.hurui.me/logo.svg' }, ]) +function beforeUpload(file: File) { + const isPng = file.type === 'image/png' + const isLt200K = file.size <= 200 * 1024 + + if (!isPng) { + faToast.error('只能上传 PNG 文件') + return false + } + if (!isLt200K) { + faToast.error('文件大小不能超过 200KB') + return false + } + return true +} + function handleSuccess() { faToast.success('模拟上传成功') } @@ -21,9 +36,8 @@ function handleClick(fileItem: FileItem) { v-model="files" action="/fake/upload" :after-upload="(response) => response.data.url" + :before-upload="beforeUpload" multiple - :ext="['png']" - :size="200 * 1024" :max="5" @on-success="handleSuccess" @on-click="handleClick" diff --git a/apps/example/src/views/component_example/file_upload/_demo4.vue b/apps/example/src/views/component_example/file_upload/_demo4.vue new file mode 100644 index 00000000..e10b9596 --- /dev/null +++ b/apps/example/src/views/component_example/file_upload/_demo4.vue @@ -0,0 +1,30 @@ + + + diff --git a/apps/example/src/views/component_example/file_upload/_demo5.vue b/apps/example/src/views/component_example/file_upload/_demo5.vue new file mode 100644 index 00000000..2263d584 --- /dev/null +++ b/apps/example/src/views/component_example/file_upload/_demo5.vue @@ -0,0 +1,26 @@ + + + diff --git a/apps/example/src/views/component_example/file_upload/index.vue b/apps/example/src/views/component_example/file_upload/index.vue index 3d92696b..aa6c9dbd 100755 --- a/apps/example/src/views/component_example/file_upload/index.vue +++ b/apps/example/src/views/component_example/file_upload/index.vue @@ -2,6 +2,8 @@ import Demo1 from './_demo1.vue' import Demo2 from './_demo2.vue' import Demo3 from './_demo3.vue' +import Demo4 from './_demo4.vue' +import Demo5 from './_demo5.vue' diff --git a/packages/components/index.ts b/packages/components/index.ts index 3df5f6c4..b05cc63c 100755 --- a/packages/components/index.ts +++ b/packages/components/index.ts @@ -11,7 +11,7 @@ export * from './src/drawer/index' export { default as FaDrawer } from './src/drawer/index.vue' export { default as FaDropdown } from './src/dropdown/index.vue' export { default as FaFileUpload } from './src/file-upload/index.vue' -export type { FileItem } from './src/file-upload/index.vue' +export type { FileItem, FileUploadRequestOptions } from './src/file-upload/index.vue' export { default as FaFixedBar } from './src/fixed-bar/index.vue' export { default as FaHoverCard } from './src/hover-card/index.vue' export { default as FaIcon } from './src/icon/index.vue' diff --git a/packages/components/src/file-upload/README.md b/packages/components/src/file-upload/README.md index 5e97fa59..4bff65a2 100644 --- a/packages/components/src/file-upload/README.md +++ b/packages/components/src/file-upload/README.md @@ -1,40 +1,52 @@ # FaFileUpload 文件上传 -支持拖拽、点击和粘贴上传的文件上传组件,带进度显示和文件管理功能。 +支持拖拽、点击、粘贴、自定义上传请求和文件夹上传的文件上传组件,带进度显示和文件管理功能。 ## 使用场景 -- 头像/图片上传 - 附件文件上传 - 批量文件上传 - 资料文件上传 - 证据/凭证上传 - 文档上传 +- 文件夹批量上传 ## Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| -| `action` | `string` | **必需** | 上传接口地址 | -| `method` | `string` | `'post'` | 请求方法 | -| `headers` | `Headers \| Record` | `{}` | 请求头 | -| `data` | `Record` | `{}` | 额外表单数据 | -| `name` | `string` | `'file'` | 文件字段名 | -| `afterUpload` | `(response: any) => string \| Promise` | - | 上传成功后的处理函数,返回文件 URL | -| `multiple` | `boolean` | `false` | 是否支持多选 | -| `ext` | `string[]` | `[]` | 允许的文件扩展名 | -| `size` | `number` | `10485760` (10MB) | 单个文件大小限制(字节) | -| `max` | `number` | `0` (无限制) | 最大上传数量 | -| `hideTips` | `boolean` | `false` | 是否隐藏提示信息 | +| `action` | `string` | `''` | 默认上传请求地址,使用 `httpRequest` 时可不传 | +| `method` | `string` | `'post'` | 默认上传请求方法 | +| `headers` | `Headers \| Record` | `{}` | 默认上传请求头 | +| `data` | `Record` | `{}` | 默认上传附加表单数据 | +| `name` | `string` | `'file'` | 默认上传文件字段名 | +| `afterUpload` | `(response: any) => string \| Promise` | - | 上传成功后从响应中提取文件 URL | +| `beforeUpload` | `(file: File) => boolean \| Promise` | - | 上传前钩子,返回 `false` 时跳过该文件 | +| `httpRequest` | `(options: FileUploadRequestOptions) => any \| Promise` | - | 自定义上传请求,返回值会传给 `afterUpload` 和 `onSuccess` | +| `multiple` | `boolean` | `false` | 是否支持多选文件 | +| `max` | `number` | `0` | 最大上传数量,`0` 表示不限制 | +| `directory` | `boolean` | `false` | 是否选择文件夹;启用后只能选择文件夹,文件夹内文件会扁平化上传 | | `disabled` | `boolean` | `false` | 是否禁用 | +```ts +interface FileUploadRequestOptions { + action: string + method: string + headers: Headers | Record + data: Record + name: string + file: File + onProgress: (percent: number) => void +} +``` + ### Model | 名称 | 类型 | 说明 | |------|------|------| | `modelValue` | `FileItem[]` | 已上传的文件列表(必需) | -### FileItem 接口 +### FileItem ```ts interface FileItem { @@ -62,7 +74,7 @@ interface FileItem { ## 粘贴上传 -将鼠标移入当前组件,或通过 `Tab` 聚焦当前组件后,可直接按 `Ctrl+V` / `Cmd+V` 粘贴剪贴板中的文件。粘贴上传会复用组件现有的数量、格式和大小校验逻辑。 +将鼠标移入当前组件,或通过 `Tab` 聚焦当前组件后,可直接按 `Ctrl+V` / `Cmd+V` 粘贴剪贴板中的文件。启用 `directory` 后,粘贴上传不可用。 ## 示例 @@ -70,134 +82,17 @@ interface FileItem { ```vue +import type { FileItem } from '@fantastic-admin/components' - -``` - -### 基础上传 - -```vue - - - -``` - -### 限制文件类型 - -```vue - - - -``` - -### 限制文件大小 - -```vue - - - -``` - -### 限制上传数量 - -```vue - - - -``` - -### 多选上传 - -```vue - - - -``` - -### 带额外参数 - -```vue - - - -``` - -### 处理上传结果 - -```vue -