458 lines
15 KiB
JavaScript
458 lines
15 KiB
JavaScript
import { showAlert } from '@/utils/message.js'
|
||
|
||
|
||
// 验证是否有网络
|
||
export const isNetwork=()=>{
|
||
return new Promise((resolve, reject) => {
|
||
uni.getNetworkType({
|
||
success: function (res) {
|
||
resolve(res.networkType)
|
||
},fail:function(err){
|
||
reject(err)
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 打开网络设置
|
||
export const openNetworkSettings = () => {
|
||
// 根据不同平台打开网络设置
|
||
// #ifdef APP-PLUS
|
||
// App端
|
||
const platform = uni.getSystemInfoSync().platform;
|
||
if (platform === 'ios') {
|
||
// iOS打开设置页面
|
||
plus.runtime.openURL('App-Prefs:root')
|
||
} else if (platform === 'android') {
|
||
// Android打开网络设置
|
||
// 方式1:使用原生API
|
||
const main = plus.android.runtimeMainActivity()
|
||
const Intent = plus.android.importClass('android.content.Intent')
|
||
const Settings = plus.android.importClass('android.provider.Settings')
|
||
const intent = new Intent(Settings.ACTION_WIFI_SETTINGS)
|
||
main.startActivity(intent)
|
||
|
||
// 方式2:使用scheme(某些设备可能不支持)
|
||
// plus.runtime.openURL('android.settings.WIFI_SETTINGS')
|
||
}
|
||
// #endif
|
||
|
||
// #ifdef H5
|
||
// H5端无法直接跳转系统设置,只能提示
|
||
uni.showToast({
|
||
title: '请手动打开网络设置',
|
||
icon: 'none'
|
||
})
|
||
// #endif
|
||
|
||
// #ifdef MP-WEIXIN
|
||
// 微信小程序无法跳转系统设置,可以引导用户检查网络
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '请检查手机网络或WiFi连接',
|
||
showCancel: false
|
||
})
|
||
// #endif
|
||
}
|
||
|
||
// 递归算法
|
||
export const initTree = (arr, parentId = '0', id) => {
|
||
const tree = [];
|
||
arr.filter(item => item.parentId === parentId).forEach(item => {
|
||
const children = initTree(arr, item[id]);
|
||
if (children.length > 0) {
|
||
item.children = children;
|
||
}
|
||
tree.push(item);
|
||
});
|
||
return tree;
|
||
}
|
||
|
||
|
||
// 安卓异步调用
|
||
export const requestAndroidPermissionAsync = (systemInfo, permissions) => {
|
||
return new Promise((resolve, reject) => {
|
||
// if (uni.getSystemInfoSync().platform !== 'android') {
|
||
// resolve({ granted: true, nonSystem: true })
|
||
// return
|
||
// }
|
||
plus.android.requestPermissions(permissions, (result) => {
|
||
showAlert("result=>" + JSON.stringify(result))
|
||
// const granted = Object.values(result.granted).every(Boolean);
|
||
|
||
let granted = false;
|
||
if (systemInfo.osVersion < 13) {
|
||
granted = result.granted.length == 2
|
||
} else if (systemInfo.osVersion == 13) {
|
||
granted = result.granted.length == 3
|
||
} else {
|
||
granted = result.granted.length == 1
|
||
}
|
||
resolve({ ...result, granted })
|
||
|
||
}, (error) => {
|
||
reject(error)
|
||
})
|
||
})
|
||
}
|
||
|
||
|
||
// 安卓同步调用
|
||
export const requestAndroidPermission = (systemInfo) => {
|
||
let granted = false;
|
||
const Manifest = plus.android.importClass("android.Manifest");
|
||
const MainActivity = plus.android.runtimeMainActivity();
|
||
if (systemInfo.osVersion < 13) { // 安卓系统版本
|
||
let permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||
let perStatus = 0;
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
if (perStatus == 2) {
|
||
granted = true
|
||
} else {
|
||
granted = false //"当前文件保存权限被关闭,请到设置中开启才能继续后续操作"
|
||
goPermission();//调用授权方法去授权
|
||
}
|
||
|
||
} else if (systemInfo.osVersion == 13) {
|
||
let permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES);
|
||
let perStatus = 0;
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.READ_MEDIA_VIDEO);
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.READ_MEDIA_AUDIO);
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
if (perStatus == 3) {
|
||
granted = true
|
||
} else {
|
||
granted = false //"当前文件保存权限被关闭,请到设置中开启才能继续后续操作"
|
||
goPermission();//调用授权方法去授权
|
||
}
|
||
} else {
|
||
let permissionStatus = MainActivity.checkSelfPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED);
|
||
let perStatus = 0;
|
||
if (permissionStatus === 0) {
|
||
perStatus++;
|
||
}
|
||
if (perStatus == 1) {
|
||
granted = true
|
||
} else {
|
||
granted = false //"当前文件保存权限被关闭,请到设置中开启才能继续后续操作"
|
||
goPermission();//调用授权方法去授权
|
||
}
|
||
}
|
||
|
||
return granted
|
||
|
||
}
|
||
|
||
// 弹窗跳授权页面
|
||
const goPermission = () => {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: "请进行设备授权",
|
||
cancelText: '去授权',
|
||
confirmText: '已授权',
|
||
success: function (res) {
|
||
if (res.confirm) {
|
||
uni.reLaunch({
|
||
url: '/pages/loading/loading',
|
||
});
|
||
} else if (res.cancel) {
|
||
jumpAuthPermission();
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 跳转授权按钮
|
||
const jumpAuthPermission=()=>{
|
||
var main = plus.android.runtimeMainActivity();
|
||
var Intent = plus.android.importClass('android.content.Intent');
|
||
var Uri = plus.android.importClass('android.net.Uri');
|
||
var pkg = main.getPackageName();
|
||
var intent = new Intent('android.settings.APPLICATION_DETAILS_SETTINGS');
|
||
intent.setData(Uri.parse('package:' + pkg));
|
||
main.startActivity(intent);
|
||
setTimeout(()=>{
|
||
uni.reLaunch({
|
||
url: '/pages/loading/loading',
|
||
});
|
||
},500)
|
||
}
|
||
|
||
// 跳转授权
|
||
const jumpAuthPermission2 = () => {
|
||
let main = plus.android.runtimeMainActivity();
|
||
let Intent = plus.android.importClass('android.content.Intent');
|
||
let Uri = plus.android.importClass('android.net.Uri');
|
||
let Build = plus.android.importClass('android.os.Build');
|
||
let Settings = plus.android.importClass('android.provider.Settings');
|
||
let PackageManager = plus.android.importClass('android.content.pm.PackageManager');
|
||
let pkg = main.getPackageName();
|
||
|
||
let intent = new Intent();
|
||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||
|
||
try {
|
||
showAlert(Build.VERSION.SDK_INT)
|
||
// 尝试直接跳转到存储权限设置(Android 13+ 支持)
|
||
if (Build.VERSION.SDK_INT >= 33) {
|
||
// Android 13+ 尝试直接打开存储权限页面
|
||
intent.setAction(Settings.ACTION_MANAGE_APP_PERMISSIONS);
|
||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, pkg);
|
||
// 指定权限类型为存储(需要Android 13+支持)
|
||
intent.putExtra(Settings.EXTRA_PERMISSION_NAME, "android.permission.READ_EXTERNAL_STORAGE");
|
||
}
|
||
// Android 11-12 尝试直接跳转到权限列表
|
||
else if (Build.VERSION.SDK_INT >= 30) {
|
||
intent.setAction(Settings.ACTION_MANAGE_APP_PERMISSIONS);
|
||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, pkg);
|
||
|
||
}
|
||
// Android 6.0-10 跳转到应用详情页(用户需手动点击权限)
|
||
else if (Build.VERSION.SDK_INT >= 23) {
|
||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||
let uri = Uri.fromParts("package", pkg, null);
|
||
intent.setData(uri);
|
||
}
|
||
// 低版本系统
|
||
else {
|
||
intent.setAction(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
|
||
}
|
||
|
||
showAlert("main=>"+main)
|
||
showAlert("intent=>"+intent)
|
||
main.startActivity(intent);
|
||
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/loading/loading',
|
||
});
|
||
}, 1000)
|
||
|
||
} catch (e) {
|
||
showAlert(e)
|
||
// 异常情况下降级处理
|
||
console.error("跳转存储权限页面失败,使用备用方案", e);
|
||
let fallbackIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||
fallbackIntent.setData(Uri.parse('package:' + pkg));
|
||
fallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||
main.startActivity(fallbackIntent);
|
||
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/loading/loading',
|
||
});
|
||
}, 1000)
|
||
}
|
||
|
||
}
|
||
|
||
// 判断文件是图片还是视频
|
||
export const getFileType = (filePathOrName) => {
|
||
// 从路径或文件名中提取扩展名
|
||
let suffix = '';
|
||
try {
|
||
suffix = filePathOrName.split('.').pop().toLowerCase();
|
||
} catch (err) {
|
||
return 'unknown';
|
||
}
|
||
|
||
// 定义常见的图片和视频扩展名
|
||
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
|
||
const videoExtensions = ['mp4', 'mov', 'avi', 'm4v', '3gp', 'mpeg', 'mkv', 'wmv'];
|
||
|
||
if (imageExtensions.includes(suffix)) {
|
||
return 'image';
|
||
} else if (videoExtensions.includes(suffix)) {
|
||
return 'video';
|
||
} else {
|
||
return 'other';
|
||
}
|
||
}
|
||
|
||
// 计算图片的新尺寸
|
||
const calculateNewSize = (originalWidth, originalHeight)=>{
|
||
const MAX_SIZE = 1920;
|
||
let newWidth = originalWidth;
|
||
let newHeight = originalHeight;
|
||
// 如果宽或高超过最大尺寸,进行等比缩放
|
||
if (originalWidth > MAX_SIZE || originalHeight > MAX_SIZE) {
|
||
if (originalWidth > originalHeight) {
|
||
// 宽图
|
||
newWidth = MAX_SIZE;
|
||
newHeight = Math.round((originalHeight * MAX_SIZE) / originalWidth);
|
||
} else {
|
||
// 高图或方图
|
||
newHeight = MAX_SIZE;
|
||
newWidth = Math.round((originalWidth * MAX_SIZE) / originalHeight);
|
||
}
|
||
}
|
||
// console.log('调整后尺寸:', newWidth, 'x', newHeight);
|
||
return {
|
||
width: newWidth,
|
||
height: newHeight
|
||
};
|
||
}
|
||
|
||
// 图片压缩处理tempFilePaths
|
||
export const compressImageUni = (file) => {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
console.log("compressImageUni=>file=>",file)
|
||
uni.getImageInfo({
|
||
src: file,
|
||
success: function (image) {
|
||
const newSize = calculateNewSize(image.width, image.height);
|
||
console.log("调整后的尺寸=>",newSize)
|
||
|
||
uni.compressImage({
|
||
src: file,
|
||
compressedWidth:newSize.width,
|
||
compressedHeight:newSize.height,
|
||
quality: 100, // 压缩质量 (0-100)
|
||
success: (res) => {
|
||
// console.log('压缩成功,临时路径:', res.tempFilePath);
|
||
resolve(res.tempFilePath)
|
||
},
|
||
fail: (err) => {
|
||
console.log('压缩失败:', err);
|
||
reject(err)
|
||
}
|
||
});
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.log('压缩失败:', error);
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
// H5 获取视频第一帧
|
||
const getFirstFrameInH5 = (videoPath) => {
|
||
return new Promise((resolve, reject) => {
|
||
const video = document.createElement('video')
|
||
video.src = videoPath
|
||
video.crossOrigin = 'anonymous'
|
||
|
||
video.addEventListener('loadeddata', () => {
|
||
video.currentTime = 0.1
|
||
})
|
||
|
||
video.addEventListener('seeked', () => {
|
||
const canvas = document.createElement('canvas')
|
||
const ctx = canvas.getContext('2d')
|
||
canvas.width = video.videoWidth
|
||
canvas.height = video.videoHeight
|
||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||
|
||
const dataUrl = canvas.toDataURL('image/jpeg', 0.8)
|
||
resolve(dataUrl)
|
||
})
|
||
video.addEventListener('error', reject)
|
||
})
|
||
}
|
||
|
||
// App平台获取第一帧(Android/iOS)
|
||
const getFirstFrameInApp = (videoPath) => {
|
||
return new Promise((resolve, reject) => {
|
||
// 方法1:使用原生VideoPlayer(推荐)
|
||
// #ifdef APP-PLUS
|
||
try {
|
||
const videoPlayer = plus.video.createVideoPlayer('firstFramePlayer', {
|
||
src: videoPath,
|
||
autoplay: false,
|
||
controls: false,
|
||
showLoading: false,
|
||
showProgress: false
|
||
})
|
||
|
||
// 监听视频准备完成
|
||
videoPlayer.addEventListener('loadeddata', () => {
|
||
// 截图
|
||
videoPlayer.snapshot({
|
||
format: 'jpg',
|
||
quality: 80
|
||
}, (res) => {
|
||
// res.target 是图片临时路径
|
||
console.log('截图成功:', res)
|
||
resolve(res.target)
|
||
|
||
// 销毁播放器
|
||
videoPlayer.close()
|
||
}, (error) => {
|
||
console.error('截图失败:', error)
|
||
reject(error)
|
||
videoPlayer.close()
|
||
})
|
||
}, false)
|
||
|
||
videoPlayer.addEventListener('error', (error) => {
|
||
console.error('视频加载失败:', error)
|
||
reject(error)
|
||
videoPlayer.close()
|
||
})
|
||
|
||
} catch (error) {
|
||
console.error('创建VideoPlayer失败:', error)
|
||
|
||
// 方法2:备用方案,使用HTML5 video(如果原生方法失败)
|
||
// showAppVideo.value = true
|
||
// showAppCanvas.value = true
|
||
|
||
// // 等待DOM更新后获取元素
|
||
// setTimeout(() => {
|
||
// const video = document.getElementById('appVideo')
|
||
// const canvas = document.getElementById('appCanvas')
|
||
// const ctx = canvas.getContext('2d')
|
||
|
||
// video.onloadedmetadata = () => {
|
||
// canvas.width = video.videoWidth
|
||
// canvas.height = video.videoHeight
|
||
|
||
// video.onseeked = () => {
|
||
// ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||
// const dataUrl = canvas.toDataURL('image/jpeg', 0.8)
|
||
|
||
// // 清理
|
||
// showAppVideo.value = false
|
||
// showAppCanvas.value = false
|
||
|
||
// resolve(dataUrl)
|
||
// }
|
||
// video.currentTime = 0.1
|
||
// }
|
||
// video.onerror = reject
|
||
// }, 100)
|
||
}
|
||
// #endif
|
||
})
|
||
}
|
||
|
||
// 获取视频第一帧(跨平台处理)
|
||
export const getVideoFirstFrame = (videoPath) => {
|
||
return new Promise((resolve, reject) => {
|
||
// #ifdef H5
|
||
// H5平台使用canvas
|
||
getFirstFrameInH5(videoPath).then(resolve).catch(reject)
|
||
// #endif
|
||
|
||
// #ifdef APP-PLUS
|
||
// App平台使用plus.video
|
||
getFirstFrameInApp(videoPath).then(resolve).catch(reject)
|
||
// #endif
|
||
})
|
||
} |