效果 直接打开资源管理器,然后选择文件后直接上传,返回上传结果
自己写一个 fileSys.ts 文件
export default function fileSys(token: any, accept: string[] = [], size: number = 10) {
// 打开文件管理器
function openFileManager() {
const permissionStatus = (plus.android as any).checkPermission(
'android.permission.READ_EXTERNAL_STORAGE',
)
if (permissionStatus !== 0) {
console.log('权限未授权,正在请求权限')
;(plus.android as any).requestPermissions(
['android.permission.READ_EXTERNAL_STORAGE'],
function () {
console.log('权限请求成功')
// 打开文件系统
const main: any = plus.android.runtimeMainActivity()
const IntentClass: any = plus.android.importClass('android.content.Intent')
const intent = new IntentClass(IntentClass.ACTION_GET_CONTENT)
intent.setType('*/*')
intent.addCategory(IntentClass.CATEGORY_OPENABLE)
main.startActivityForResult(intent, 1001)
},
function () {
console.log('权限请求失败')
},
)
} else {
console.log('权限已经授予')
}
}
// 处理回调结果
const result = ref()
function onActivityResult(requestCode: number, resultCode: any, data: any) {
if (requestCode === 1001 && resultCode === -1) {
const uri = data.getData()
const filePath = getFilePathFromContentUri(uri)
// console.log('filePath: ', filePath)
if (!filePath) return
uni.showLoading({
title: '文件上传中...',
mask: true,
})
const uploadTask = uni.uploadFile({
url: import.meta.env.VITE_SERVER_BASEURL + '/resource/oss/upload',
header: {
'Content-Type': 'multipart/form-data',
clientid: import.meta.env.VITE_APP_CLIENT_ID,
Authorization: 'Bearer ' + token,
},
name: 'file',
filePath,
success: (uploadFileRes) => {
const d: any = uploadFileRes.data
if (d) {
try {
const data = JSON.parse(d)
if (data.code === 200) {
result.value = data.data
}
} catch (error) {
console.log('返回结果错误')
}
}
},
fail: (err) => {
uni.hideLoading()
console.log(err)
},
})
uploadTask.onProgressUpdate(({ progress }) => {
if (progress === 100) uni.hideLoading()
})
}
}
function getFilePathFromContentUri(uri: any) {
const context: any = plus.android.runtimeMainActivity()
const ContentResolver: any = plus.android.importClass('android.content.ContentResolver')
const Cursor: any = plus.android.importClass('android.database.Cursor')
const resolver = context.getContentResolver()
const cursor = resolver.query(uri, null, null, null, null)
if (cursor != null && cursor.moveToFirst()) {
// 获取文件名
const nameIndex = cursor.getColumnIndex('_display_name')
const fileName = cursor.getString(nameIndex)
// 获取文件大小
const sizeIndex = cursor.getColumnIndex('_size')
const fileSize = cursor.getLong(sizeIndex) / 1024 / 1024 // 转换为 MB
cursor.close()
// 文件格式验证
const fileType = fileName.split('.').pop()
if (fileType && accept.length > 0) {
const lowerType = fileType.toLowerCase()
if (!accept.includes(lowerType)) {
uni.showModal({
title: '提示',
content: `请上传${accept.join('/')}格式的文件`,
showCancel: false,
mask: true,
})
return ''
}
}
// 文件大小验证
if (!fileSize) {
uni.showModal({
title: '提示',
content: `${fileName}为空文件!`,
showCancel: false,
mask: true,
})
return ''
}
if (fileSize > size) {
uni.showModal({
title: '提示',
content: `文件过大,单个文件最大为${size}M`,
showCancel: false,
mask: true,
})
return ''
}
return uri.toString()
}
console.log('无法访问文件')
return ''
}
// 注册 onActivityResult 监听器
function registerActivityResultListener() {
const main: any = plus.android.runtimeMainActivity()
main.onActivityResult = function (requestCode: any, resultCode: any, data: any) {
onActivityResult(requestCode, resultCode, data)
}
}
// 初始化时注册回调监听器
registerActivityResultListener()
return {
openFileManager,
result,
}
}
外部使用
<script lang="ts" setup>
import fileSys from './fileSys'
const reShowFileList = ref<any[]>([])
// #ifdef APP
const { openFileManager, result } = fileSys(userInfo.token, props.accept, props.maxSize)
watch(
() => result.value,
(obj) => {
// obj 为上传接口返回的数据
if (obj) {
// reShowFileList 为回显的附件数组
reShowFileList.value.push({
name: obj.fileName,
status: 'success',
url: obj.url,
})
}
},
{ immediate: true, deep: true },
)
// #endif
const imgType = ['jpg', 'png', 'jpeg', 'webp', 'gif']
// beforeChoose 是一个上传前置的方法 具体可参照
// https://wot-design-uni.cn/component/upload.html#%E4%B8%8A%E4%BC%A0%E5%89%8D%E7%BD%AE%E5%A4%84%E7%90%86
function beforeChoose({ resolve }: { resolve: any }) {
// #ifdef APP
if (props.accept.filter((i) => !imgType.includes(i)).length) {
openFileManager()
return resolve(false)
} else {
resolve(true)
}
// #endif
// #ifdef WEB || H5
resolve(true)
// #endif
}
</script>
<template>
<wd-upload
v-model:file-list="reShowFileList"
:before-choose="beforeChoose"
></wd-upload>
<template>