Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(uploader): 新增accept配置 #217

Merged
merged 2 commits into from Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/components/dentry/uploader.md
Expand Up @@ -243,6 +243,7 @@ setup() {
| size-type | [是否压缩所选文件](https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseMedia.html) | Array | `['original','compressed']` |
| media-type`仅支持WEAPP` | [选择文件类型](https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseMedia.html) | Array | `['image', 'video', 'mix']` |
| max-duration`仅支持WEAPP` | 拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 60s 之间。不限制相册。 | Number | 10 |
| accept | 允许上传的文件类型 |String | `['image','media','video','all']`
| headers | 设置上传的请求头部 | object | `{}` |
| data | 附加上传的信息 formData | object | `{}` |
| xhr-state | 接口响应的成功状态(status)值 | Number | `200` |
Expand Down
9 changes: 9 additions & 0 deletions example/src/pages/demo/dentry/uploader/index.vue
Expand Up @@ -3,6 +3,7 @@ import type { ProgressStatus } from 'nutui-uniapp'
import { ref } from 'vue'

const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'

const progressPercentage = ref<string | number>(0)
const formData = {
custom: 'test',
Expand Down Expand Up @@ -189,6 +190,14 @@ function beforeXhrUpload(UploadFile: any, options: any) {
禁用状态
</h2>
<nut-uploader disabled />
<h2 class="title">
文件类型 - 视频
</h2>
<nut-uploader :url="uploadUrl" accept="video" />
<h2 class="title">
文件类型 - 全部
</h2>
<nut-uploader :url="uploadUrl" accept="all" />
</div>
</template>

Expand Down
2 changes: 1 addition & 1 deletion packages/nutui/components/uploader/uploader.vue
Expand Up @@ -134,7 +134,7 @@ function readFile(files: ChooseFile[]) {
fileItem.type = fileType!
fileItem.formData = props.data
if (props.isPreview)
fileItem.url = fileType === 'video' ? file.thumbTempFilePath : filepath
fileItem.url = fileType === 'video' ? file.url : filepath

fileList.value.push(fileItem)
executeUpload(fileItem, index)
Expand Down
102 changes: 91 additions & 11 deletions packages/nutui/components/uploader/use-uploader.ts
Expand Up @@ -18,6 +18,46 @@ interface UniChooseFileSuccessCallbackResult {
} & File)[]
}

interface UniChooseImageSuccessCallbackResult extends UniChooseFileSuccessCallbackResult {

}

interface UniChooseVideoSuccessCallbackResult {
/**
* 本地文件路径
*/
tempFilePath?: string
/**
* 本地文件,一个 File 对象
*/
tempFile: ({
path: string
size: number
name: string
type: string
} & File)
/**
* 选定视频的时间长度,单位为s
*/
duration: number
/**
* 选定视频的数据量大小
*/
size: number
/**
* 返回选定视频的高
*/
height: number
/**
* 返回选定视频的宽
*/
width: number
/**
* 包含扩展名的文件名称
*/
name: string
}

export interface ChooseFile {
size: number
type?: FileType
Expand All @@ -39,7 +79,7 @@ function omitProps<T>(obj: T, keys: string[]) {
return omit(obj as unknown as Record<string, unknown>, keys)
}

function formatImage(res: UniChooseFileSuccessCallbackResult): ChooseFile[] {
function formatImage(res: UniChooseImageSuccessCallbackResult): ChooseFile[] {
return res.tempFiles.map(item => ({
...omitProps(item, ['path']),
type: 'image',
Expand All @@ -50,6 +90,17 @@ function formatImage(res: UniChooseFileSuccessCallbackResult): ChooseFile[] {
}))
}

function formatVideo(res: UniChooseVideoSuccessCallbackResult): ChooseFile[] {
return [{
...omitProps(res.tempFile, ['path']),
type: 'video',
url: res.tempFilePath,
thumb: res.tempFilePath,
size: res.tempFile.size,
name: res.tempFile.name || 'video',
}]
}

function formatMedia(res: UniApp.ChooseMediaSuccessCallbackResult & { name?: string }): ChooseFile[] {
return res.tempFiles.map(item => ({
...omitProps(item, ['fileType', 'thumbTempFilePath', 'tempFilePath']),
Expand All @@ -72,11 +123,12 @@ export interface ChooseFileOptions {
}

export function chooseFile({
accept,
multiple,
maxDuration,
sizeType,
camera,
}: ChooseFileOptions, props: UploaderProps, fileList: any[]): Promise<ChooseFile[]> {
}: ChooseFileOptions, props: UploaderProps, fileList: any[]): Promise<ChooseFile[] | ChooseFile> {
return new Promise((resolve, reject) => {
// chooseMedia 目前只支持微信小程序原生,其余端全部使用 chooseImage API
// #ifdef MP-WEIXIN
Expand All @@ -102,15 +154,43 @@ export function chooseFile({
// #endif

// #ifndef MP-WEIXIN
uni.chooseImage({
// 选择数量
count: props.multiple ? (props.maximum as number) * 1 - props.fileList.length : 1,
// 可以指定是原图还是压缩图,默认二者都有
sizeType,
sourceType: props.sourceType,
success: res => resolve(formatImage(res as UniChooseFileSuccessCallbackResult)),
fail: reject,
})
if (accept === 'image') {
uni.chooseImage({
// 选择数量
count: props.multiple ? (props.maximum as number) * 1 - props.fileList.length : 1,
// 可以指定是原图还是压缩图,默认二者都有
sizeType,
sourceType: props.sourceType,
success: (res) => {
resolve(formatImage(res as UniChooseFileSuccessCallbackResult))
},
fail: reject,
})
}
else if (accept === 'video') {
uni.chooseVideo({
sourceType: props.sourceType,
success: (res) => {
resolve(formatVideo(res as UniChooseVideoSuccessCallbackResult))
},
fail: reject,
})
}
else if (accept === 'all') {
uni.chooseFile({
type: 'all',
// 选择数量
count: props.multiple ? (props.maximum as number) * 1 - props.fileList.length : 1,
// 可以指定是原图还是压缩图,默认二者都有
sizeType,
sourceType: props.sourceType,
success: (res) => {
resolve(formatImage(res as UniChooseFileSuccessCallbackResult))
},
fail: reject,
})
}

// #endif
})
}
Expand Down