把 is_text/image/video_file 公开给外部使用
This commit is contained in:
parent
08b6c3e31a
commit
e11583b284
91
unitool.js
91
unitool.js
@ -10,15 +10,6 @@ const my = {
|
|||||||
// getCurrentPages() 在 topWindow/App.vue 里有可能为空,所以用 getApp().$store 更安全. 20230513: 发现在微信小程序模拟器里,getApp().$store.state 未定义,所以还是用 globalThis.wo?.ss
|
// getCurrentPages() 在 topWindow/App.vue 里有可能为空,所以用 getApp().$store 更安全. 20230513: 发现在微信小程序模拟器里,getApp().$store.state 未定义,所以还是用 globalThis.wo?.ss
|
||||||
return globalThis.wo?.ss?.i18n?.mylang || getApp()?.$store?.state?.i18n?.mylang
|
return globalThis.wo?.ss?.i18n?.mylang || getApp()?.$store?.state?.i18n?.mylang
|
||||||
},
|
},
|
||||||
isTextFile (ext = '') {
|
|
||||||
return (wo.envar.textExtensionList || ['txt', 'text']).includes(ext.replace(/^\./, '').toLowerCase())
|
|
||||||
},
|
|
||||||
isImageFile (ext = '') {
|
|
||||||
return (wo.envar.imageExtensionList || ['jpg', 'jpeg', 'png', 'gif', 'webp', 'image']).includes(ext.replace(/^\./, '').toLowerCase())
|
|
||||||
},
|
|
||||||
isVideoFile (ext = '') {
|
|
||||||
return (wo.envar.videoExtensionList || ['avi', 'mp4', 'mov', 'wmv', 'video']).includes(ext.replace(/^\./, '').toLowerCase())
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -46,6 +37,19 @@ module.exports = {
|
|||||||
// uniTag: { GREY: 'default', YELLOW: 'warning', BLUE: 'primary', GREEN: 'success', RED: 'error', PURPLE: 'royal' },
|
// uniTag: { GREY: 'default', YELLOW: 'warning', BLUE: 'primary', GREEN: 'success', RED: 'error', PURPLE: 'royal' },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
is_text_file (fileName = '') {
|
||||||
|
const ext = /\./.test(fileName) ? fileName.split('.').pop().toLowerCase() : ''
|
||||||
|
return (wo.envar.textExtensionList || ['txt', 'text']).includes(ext)
|
||||||
|
},
|
||||||
|
is_image_file (fileName = '') {
|
||||||
|
const ext = /\./.test(fileName) ? fileName.split('.').pop().toLowerCase() : ''
|
||||||
|
return (wo.envar.imageExtensionList || ['jpg', 'jpeg', 'png', 'gif', 'webp', 'image']).includes(ext)
|
||||||
|
},
|
||||||
|
is_video_file (fileName = '') {
|
||||||
|
const ext = /\./.test(fileName) ? fileName.split('.').pop().toLowerCase() : ''
|
||||||
|
return (wo.envar.videoExtensionList || ['avi', 'mp4', 'mov', 'wmv', 'video']).includes(ext)
|
||||||
|
},
|
||||||
|
|
||||||
thisPage () {
|
thisPage () {
|
||||||
return this.__page__
|
return this.__page__
|
||||||
? this // constructor.name==='VueComponent' 只在 development 环境有用,在 production 环境会被简化成 'o'。
|
? this // constructor.name==='VueComponent' 只在 development 环境有用,在 production 环境会被简化成 'o'。
|
||||||
@ -59,8 +63,8 @@ module.exports = {
|
|||||||
getCurrentPages()?.pop()?.i18nText // 如果不是挂载到 Vue.prototype 而是 挂载到 wo 下调用,那么 this.i18nText 就不存在了。因此通过 pageNow.i18nText 访问。
|
getCurrentPages()?.pop()?.i18nText // 如果不是挂载到 Vue.prototype 而是 挂载到 wo 下调用,那么 this.i18nText 就不存在了。因此通过 pageNow.i18nText 访问。
|
||||||
return (
|
return (
|
||||||
i18nText?.[my.langNow()] ||
|
i18nText?.[my.langNow()] ||
|
||||||
i18nText?.earth ||
|
i18nText?.earTH ||
|
||||||
i18nText?.default ||
|
i18nText?.defauLT ||
|
||||||
i18nText?.enUS ||
|
i18nText?.enUS ||
|
||||||
(['string', 'number', 'boolean'].includes(typeof i18nText) ? i18nText : '')
|
(['string', 'number', 'boolean'].includes(typeof i18nText) ? i18nText : '')
|
||||||
) // 必须检测是否标量值,如果直接返回 i18nText 可能返回{}等,导致依赖于返回空值的前端出错
|
) // 必须检测是否标量值,如果直接返回 i18nText 可能返回{}等,导致依赖于返回空值的前端出错
|
||||||
@ -310,6 +314,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async pickupFile2Server ({
|
async pickupFile2Server ({
|
||||||
|
fileDragged,
|
||||||
mediaType = 'image', // could be: image, video, array of supported extensions, anything else
|
mediaType = 'image', // could be: image, video, array of supported extensions, anything else
|
||||||
count = 1,
|
count = 1,
|
||||||
sizeType = ['original', 'compressed'],
|
sizeType = ['original', 'compressed'],
|
||||||
@ -322,7 +327,14 @@ module.exports = {
|
|||||||
// 有的管理后台不需要登录就允许上传,例如 cmctoy。因此不要在这里依赖登录状态。
|
// 有的管理后台不需要登录就允许上传,例如 cmctoy。因此不要在这里依赖登录状态。
|
||||||
|
|
||||||
let filePath, fileSize, filePicked
|
let filePath, fileSize, filePicked
|
||||||
if (mediaType === 'image') {
|
if (fileDragged?.size) {
|
||||||
|
fileSize = fileDragged.size
|
||||||
|
filePath = fileDragged.filePath
|
||||||
|
filePicked = fileDragged
|
||||||
|
if (!mediaType) {
|
||||||
|
mediaType = this.is_image_file(fileDragged.name) ? 'image' : this.is_video_file(fileDragged.name) ? 'video' : 'file'
|
||||||
|
}
|
||||||
|
} else if (mediaType === 'image') {
|
||||||
let [errorChoose, { tempFilePaths, tempFiles } = {}] = await uni.chooseImage({ count, sizeType, sourceType })
|
let [errorChoose, { tempFilePaths, tempFiles } = {}] = await uni.chooseImage({ count, sizeType, sourceType })
|
||||||
if (errorChoose) {
|
if (errorChoose) {
|
||||||
return {
|
return {
|
||||||
@ -378,15 +390,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileName = filePicked?.name || filePath?.split?.('/')?.pop?.() // filePicked.name is available in WEB only. on the other hand, filePath 在 WEB 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名。
|
const fileName = filePicked?.name || filePath?.split?.('/')?.pop?.() // filePicked.name is available in WEB only. on the other hand, filePath 在 WEB 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名。
|
||||||
const fileExt = fileName?.split?.('.')?.pop?.()?.toLowerCase?.()
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// #ifndef APP
|
// #ifndef APP
|
||||||
// 20240830 luk: 在 App 上,就相信 iOS/Android,不检查文件后缀名。
|
// 20240830 luk: 在 App 上,就相信 iOS/Android,不检查文件后缀名。
|
||||||
(mediaType === 'image' && !my.isImageFile(fileExt)) ||
|
(mediaType === 'image' && !this.is_image_file(fileName)) ||
|
||||||
(mediaType === 'video' && !my.isVideoFile(fileExt)) ||
|
(mediaType === 'video' && !this.is_video_file(fileName)) ||
|
||||||
// #endif
|
// #endif
|
||||||
(Array.isArray(mediaType) && !mediaType?.includes?.('.' + fileExt))
|
(Array.isArray(mediaType) && !mediaType?.includes?.(/\./.test(fileName) ? '.' + fileName?.split?.('.')?.pop?.()?.toLowerCase?.() : ''))
|
||||||
) {
|
) {
|
||||||
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '不支持的文件类型:\n' + fileName, enUS: 'Unsupported file type:\n' + fileName } }
|
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '不支持的文件类型:\n' + fileName, enUS: 'Unsupported file type:\n' + fileName } }
|
||||||
}
|
}
|
||||||
@ -415,6 +426,11 @@ module.exports = {
|
|||||||
// 不知为何,uni.uploadFile返回的 data 是字符串而不是对象
|
// 不知为何,uni.uploadFile返回的 data 是字符串而不是对象
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(data)
|
data = JSON.parse(data)
|
||||||
|
if (fileDragged?.name) {
|
||||||
|
// 20241020 不知为何,通过拖拽的文件上传后,得到的结果里 originalname 形如 "file-1729354713176" 而不是真正的原始文件名,也不包含后缀。为了保持一致,这里强行重新设置
|
||||||
|
data.originalnameSystem = data.originalname
|
||||||
|
data.originalname = fileDragged.name
|
||||||
|
}
|
||||||
} catch (exp) {
|
} catch (exp) {
|
||||||
return {
|
return {
|
||||||
_state: 'BER_FAIL_RESPONSE_JSON_MALFORMED',
|
_state: 'BER_FAIL_RESPONSE_JSON_MALFORMED',
|
||||||
@ -435,14 +451,27 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async pickupFile2Cloud ({ mediaType = 'image', count = 1, sizeType = ['original', 'compressed'], sourceType = ['album', 'camera'], maxDuration } = {}) {
|
async pickupFile2Cloud ({
|
||||||
|
fileDragged,
|
||||||
|
mediaType = 'image',
|
||||||
|
count = 1,
|
||||||
|
sizeType = ['original', 'compressed'],
|
||||||
|
sourceType = ['album', 'camera'],
|
||||||
|
maxDuration,
|
||||||
|
} = {}) {
|
||||||
// 有的管理后台不需要登录就允许上传,例如 cmctoy。因此不要在这里依赖登录状态。
|
// 有的管理后台不需要登录就允许上传,例如 cmctoy。因此不要在这里依赖登录状态。
|
||||||
// if (!uni.getStorageSync('_passtoken')) {
|
// if (!uni.getStorageSync('_passtoken')) {
|
||||||
// return { _state: 'USER_OFFLINE', errMsg: 'offline user cannot upload files' }
|
// return { _state: 'USER_OFFLINE', errMsg: 'offline user cannot upload files' }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let filePath, cloudPath, fileSize, filePicked
|
let filePath, cloudPath, fileSize, filePicked
|
||||||
if (mediaType === 'image') {
|
let random = crypto.randomBytes(16).toString('hex')
|
||||||
|
if (fileDragged?.size) {
|
||||||
|
fileSize = fileDragged.size
|
||||||
|
filePath = fileDragged.filePath
|
||||||
|
filePicked = fileDragged
|
||||||
|
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}_${path.extname(fileDragged.name || { image: '.jpg', video: '.mp4' }[mediaType] || '')}` // tempFile and name are H5 only
|
||||||
|
} else if (mediaType === 'image') {
|
||||||
let [errorChoose, { tempFilePaths, tempFiles } = {}] = await uni.chooseImage({ count, sizeType, sourceType })
|
let [errorChoose, { tempFilePaths, tempFiles } = {}] = await uni.chooseImage({ count, sizeType, sourceType })
|
||||||
if (errorChoose) {
|
if (errorChoose) {
|
||||||
return {
|
return {
|
||||||
@ -453,16 +482,14 @@ module.exports = {
|
|||||||
fileSize = tempFiles?.[0]?.size
|
fileSize = tempFiles?.[0]?.size
|
||||||
filePicked = tempFiles?.[0]
|
filePicked = tempFiles?.[0]
|
||||||
filePath = tempFilePaths?.[0] // 在 H5 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。// 在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名
|
filePath = tempFilePaths?.[0] // 在 H5 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。// 在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名
|
||||||
let random = crypto.randomBytes(16).toString('hex')
|
|
||||||
// #ifndef WEB
|
// #ifndef WEB
|
||||||
// let [errorGetImageInfo, { path, width, height, orientation, type }] = await uni.getImageInfo({ src: filePath })
|
// let [errorGetImageInfo, { path, width, height, orientation, type }] = await uni.getImageInfo({ src: filePath })
|
||||||
// cloudPath = path // 完整路径,包含后缀名。形如 file:///var/mobile/Containers/Data/Application/55A76332-44F5-4D5F-A9F6-3F857D584883/Documents/Pandora/apps/D064A425A8BEC13F9D8F741B98B37BC5/doc/uniapp_temp_1598593902955/compressed/1598593925815.png
|
// cloudPath = path // 完整路径,包含后缀名。形如 file:///var/mobile/Containers/Data/Application/55A76332-44F5-4D5F-A9F6-3F857D584883/Documents/Pandora/apps/D064A425A8BEC13F9D8F741B98B37BC5/doc/uniapp_temp_1598593902955/compressed/1598593925815.png
|
||||||
cloudPath = `APP_${wo.envar.clientInfo.osName}_${random}${path.extname(filePath || '')}`
|
cloudPath = `APP_${wo.envar.clientInfo.osName}_${random}${path.extname(filePath || '.jpg')}`
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef WEB
|
// #ifdef WEB
|
||||||
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}${path.extname(tempFiles?.[0]?.name || '')}` // name is available in H5 only. 只包含文件名和后缀名,不包含路径。
|
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}${path.extname(tempFiles?.[0]?.name || '.jpg')}` // name is available in H5 only. 只包含文件名和后缀名,不包含路径。
|
||||||
// #endif
|
// #endif
|
||||||
if (!path.extname(cloudPath)) cloudPath += '.jpg'
|
|
||||||
} else if (mediaType === 'video') {
|
} else if (mediaType === 'video') {
|
||||||
let [errorChoose, { tempFilePath, tempFile, duration, size, width, height, name }] = await uni.chooseVideo({ sourceType, maxDuration })
|
let [errorChoose, { tempFilePath, tempFile, duration, size, width, height, name }] = await uni.chooseVideo({ sourceType, maxDuration })
|
||||||
if (errorChoose) {
|
if (errorChoose) {
|
||||||
@ -474,16 +501,14 @@ module.exports = {
|
|||||||
fileSize = size
|
fileSize = size
|
||||||
filePicked = tempFile
|
filePicked = tempFile
|
||||||
filePath = tempFilePath // 在 iOS 上形如 "file:///var/mobile/Containers/Data/Application/55A76332-44F5-4D5F-A9F6-3F857D584883/Documents/Pandora/apps/26B43CD2F587D37FC6799108434A6F84/doc/uniapp_temp_1598596171580/gallery/IMG_3082.MOV"
|
filePath = tempFilePath // 在 iOS 上形如 "file:///var/mobile/Containers/Data/Application/55A76332-44F5-4D5F-A9F6-3F857D584883/Documents/Pandora/apps/26B43CD2F587D37FC6799108434A6F84/doc/uniapp_temp_1598596171580/gallery/IMG_3082.MOV"
|
||||||
let random = crypto.randomBytes(16).toString('hex')
|
|
||||||
// #ifndef WEB
|
// #ifndef WEB
|
||||||
cloudPath = `APP_${wo.envar.clientInfo.osName}_${random}_dur${duration}${path.extname(filePath || '')}`
|
cloudPath = `APP_${wo.envar.clientInfo.osName}_${random}_dur${duration}${path.extname(filePath || '.mp4')}`
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef WEB
|
// #ifdef WEB
|
||||||
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}_dur${duration}${path.extname(name || '')}` // tempFile and name are H5 only
|
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}_dur${duration}${path.extname(name || '.mp4')}` // tempFile and name are H5 only
|
||||||
// #endif
|
// #endif
|
||||||
// iOS 上测试,filePath 为 *.MOV,而阿里云只允许 *.mp4, 所以默认添加 .mp4 后缀。参见 https://uniapp.dcloud.net.cn/uniCloud/storage?id=clouduploadfile
|
// iOS 上测试,filePath 为 *.MOV,而阿里云只允许 *.mp4, 所以默认添加 .mp4 后缀。参见 https://uniapp.dcloud.net.cn/uniCloud/storage?id=clouduploadfile
|
||||||
// 20200915测试,阿里云支持上传 *.mov 了。
|
// 20200915测试,阿里云支持上传 *.mov 了。
|
||||||
if (!path.extname(cloudPath)) cloudPath += '.mp4'
|
|
||||||
} else {
|
} else {
|
||||||
// #ifdef WEB
|
// #ifdef WEB
|
||||||
// https://uniapp.dcloud.net.cn/uniCloud/storage.html#uploadfile
|
// https://uniapp.dcloud.net.cn/uniCloud/storage.html#uploadfile
|
||||||
@ -503,6 +528,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
fileSize = tempFiles?.[0]?.size
|
fileSize = tempFiles?.[0]?.size
|
||||||
filePicked = tempFiles?.[0]
|
filePicked = tempFiles?.[0]
|
||||||
|
filePath = tempFilePaths?.[0]
|
||||||
|
cloudPath = `WEB_${wo.envar.clientInfo.osName}_${random}${path.extname(tempFiles?.[0]?.name || '')}` // name is available in H5 only. 只包含文件名和后缀名,不包含路径。
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef WEB
|
// #ifndef WEB
|
||||||
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '请切换到网页端上传文件!', enUS: 'Please switch to WebApp to upload files.' } }
|
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '请切换到网页端上传文件!', enUS: 'Please switch to WebApp to upload files.' } }
|
||||||
@ -520,15 +547,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileName = filePicked?.name || filePath?.split?.('/')?.pop?.() // filePicked.name is available in WEB only. on the other hand, filePath 在 WEB 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名。
|
const fileName = filePicked?.name || filePath?.split?.('/')?.pop?.() // filePicked.name is available in WEB only. on the other hand, filePath 在 WEB 上并不是文件路径名,而是类似 "blob:http://localhost:8080/f0d3e54d-0694-4803-8097-641d76a10b0d“。在 iOS 上是 "_doc/uniapp_temp_1598593902955/compressed/1598593925815.png", 有时还包含从 file:/// 开始的完整路径名。
|
||||||
const fileExt = fileName?.split?.('.')?.pop?.()?.toLowerCase?.()
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// #ifndef APP
|
// #ifndef APP
|
||||||
// 20240830 luk: 在 App 上,就相信 iOS/Android,不检查文件后缀名。
|
// 20240830 luk: 在 App 上,就相信 iOS/Android,不检查文件后缀名。
|
||||||
(mediaType === 'image' && !my.isImageFile(fileExt)) ||
|
(mediaType === 'image' && !this.is_image_file(fileName)) ||
|
||||||
(mediaType === 'video' && !my.isVideoFile(fileExt)) ||
|
(mediaType === 'video' && !this.is_video_file(fileName)) ||
|
||||||
// #endif
|
// #endif
|
||||||
(Array.isArray(mediaType) && !mediaType?.includes?.('.' + fileExt))
|
(Array.isArray(mediaType) && !mediaType?.includes?.(/\./.test(fileName) ? '.' + fileName?.split?.('.')?.pop?.()?.toLowerCase?.() : ''))
|
||||||
) {
|
) {
|
||||||
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '不支持的文件类型:\n' + fileName, enUS: 'Unsupported file type:\n' + fileName } }
|
return { _state: 'UNSUPPORTED_FILETYPE', _msg: { zhCN: '不支持的文件类型:\n' + fileName, enUS: 'Unsupported file type:\n' + fileName } }
|
||||||
}
|
}
|
||||||
@ -568,6 +594,7 @@ module.exports = {
|
|||||||
|
|
||||||
async pickupFile ({
|
async pickupFile ({
|
||||||
baseType = globalThis.wo?.envar?.baseTypeDefault || BASE_TYPE_DEFAULT,
|
baseType = globalThis.wo?.envar?.baseTypeDefault || BASE_TYPE_DEFAULT,
|
||||||
|
fileDragged,
|
||||||
mediaType = 'image', // could be image, video, array of supported extensions, anything else // 20240502 todo: rename to pickupFileType
|
mediaType = 'image', // could be image, video, array of supported extensions, anything else // 20240502 todo: rename to pickupFileType
|
||||||
count = 1,
|
count = 1,
|
||||||
sizeType = ['original', 'compressed'],
|
sizeType = ['original', 'compressed'],
|
||||||
@ -579,9 +606,9 @@ module.exports = {
|
|||||||
name = 'file',
|
name = 'file',
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (/^UNICLOUD/.test(baseType)) {
|
if (/^UNICLOUD/.test(baseType)) {
|
||||||
return await this.pickupFile2Cloud({ mediaType, count, sizeType, sourceType, maxDuration })
|
return await this.pickupFile2Cloud({ fileDragged, mediaType, count, sizeType, sourceType, maxDuration })
|
||||||
} else if (baseType === 'SERVER') {
|
} else if (baseType === 'SERVER') {
|
||||||
return await this.pickupFile2Server({ mediaType, count, sizeType, sourceType, maxDuration, url, header, formData, name })
|
return await this.pickupFile2Server({ fileDragged, mediaType, count, sizeType, sourceType, maxDuration, url, header, formData, name })
|
||||||
} else {
|
} else {
|
||||||
return { _state: 'CLEINT_FAIL_UNKNOWN_WOBASE_TYPE', baseType, _msg: { zhCN: '不支持的后台类型。', enUS: 'Unsupported base type.' } }
|
return { _state: 'CLEINT_FAIL_UNKNOWN_WOBASE_TYPE', baseType, _msg: { zhCN: '不支持的后台类型。', enUS: 'Unsupported base type.' } }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user