mrr.sj.front/utils/per.js

309 lines
8.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// permissionUtils.js
/**
* 统一权限检测工具
* 支持平台APP(Android/iOS)、微信小程序、H5
*/
export default {
/**
* 检查权限状态
* @param {String} permission 权限类型
* @param {String} description 权限描述(仅APP端需要)
* @returns {Promise<Object>}
* - granted: 是否已授权
* - firstRequest: 是否第一次请求
* - canRequest: 是否可以请求(用户未永久拒绝)
*/
async checkPermission(permission, description = '') {
// #ifdef APP-PLUS
return await this._checkAppPermission(permission, description);
// #endif
// #ifdef MP-WEIXIN
return await this._checkMpPermission(permission);
// #endif
// #ifdef H5
// H5默认返回已授权实际权限由浏览器控制
return { granted: true, firstRequest: false, canRequest: false };
// #endif
},
/**
* APP端权限检查
*/
async _checkAppPermission(permission, description) {
// Android和iOS通用权限映射
const permissionMap = {
'camera': {
android: 'android.permission.CAMERA',
ios: 'camera'
},
'location': {
android: 'android.permission.ACCESS_FINE_LOCATION',
ios: 'location'
},
'phone': {
android: 'android.permission.CALL_PHONE',
ios: 'phone'
},
'photo_library': {
android: [
'android.permission.READ_EXTERNAL_STORAGE',
'android.permission.WRITE_EXTERNAL_STORAGE'
],
ios: 'photo_library',
}
// 添加其他需要的权限...
};
const platformPerm = permissionMap[permission];
if (!platformPerm) {
console.error('不支持的权限类型:', permission);
return { granted: false, firstRequest: false, canRequest: false };
}
// #ifdef APP-PLUS
if (plus.os.name === 'Android') {
return this._checkAndroidPermission(platformPerm.android);
}else {
return this._checkIosPermission(platformPerm.ios, description);
}
// #endif
return { granted: false, firstRequest: false, canRequest: false };
},
/**
* Android权限检查
*/
async _checkAndroidPermission(permission) {
return new Promise((resolve) => {
plus.android.requestPermissions(
Array.isArray(permission) ? permission : [permission],
(e) => {
console.log(`perm_${permission}`,e)
// 第一次请求标记
const firstRequest = !plus.storage.getItem(`perm_${permission}`);
if (firstRequest) {
plus.storage.setItem(`perm_${permission}`, '1');
}
if(e.deniedPresent.length !== 0) {
plus.storage.setItem(`perm_${permission}_no`, '2');
}
if(e.granted.length !== 0) {
plus.storage.removeItem(`perm_${permission}_no`, '2');
}
resolve({
granted: e.granted.length !== 0,
firstRequest,
canRequest: true // Android可以重复请求
});
},
(e) => {
resolve({
granted: false,
firstRequest: false,
canRequest: true
});
}
);
});
},
/**
* iOS权限检查
*/
async _checkIosPermission(permission, description) {
try {
let status;
switch (permission) {
case 'camera':
status = plus.ios.invoke('AVCaptureDevice', 'authorizationStatusForMediaType:', 'vide');
break;
case 'location':
const locationManager = plus.ios.newObject('CLLocationManager');
status = plus.ios.invoke(locationManager, 'authorizationStatus');
plus.ios.deleteObject(locationManager);
break;
// 其他权限处理...
default:
return { granted: false, firstRequest: false, canRequest: false };
}
// iOS授权状态
// 0: 未决定(第一次)
// 1: 受限
// 2: 已拒绝
// 3: 已授权
return {
granted: status === 3,
firstRequest: status === 0,
canRequest: status !== 2 // 不是永久拒绝
};
} catch (e) {
console.error('iOS权限检查错误:', e);
return { granted: false, firstRequest: false, canRequest: false };
}
},
/**
* 小程序权限检查
*/
async _checkMpPermission(permission) {
// 小程序scope映射
const scopeMap = {
'camera': 'scope.camera',
'location': 'scope.userLocation',
'record': 'scope.record',
// 其他小程序权限...
};
const scope = scopeMap[permission];
if (!scope) {
return { granted: false, firstRequest: false, canRequest: false };
}
return new Promise((resolve) => {
uni.getSetting({
success(res) {
const authSetting = res.authSetting;
resolve({
granted: authSetting[scope] === true,
firstRequest: authSetting[scope] === undefined,
canRequest: authSetting[scope] !== false // 不是拒绝状态
});
},
fail() {
resolve({ granted: false, firstRequest: false, canRequest: false });
}
});
});
},
/**
* 请求权限
*/
async requestPermission(permission, description = '') {
const { granted, firstRequest, canRequest } = await this.checkPermission(permission, description);
if (granted) return true;
if (!canRequest) return false;
// #ifdef APP-PLUS
return this._requestAppPermission(permission, description);
// #endif
// #ifdef MP-WEIXIN
return this._requestMpPermission(permission);
// #endif
// #ifdef H5
return false; // H5无法主动请求权限
// #endif
},
/**
* APP端请求权限
*/
async _requestAppPermission(permission, description) {
// #ifdef APP-PLUS && ANDROID
return new Promise((resolve) => {
plus.android.requestPermissions(
[permission],
(e) => resolve(e.denied.length === 0),
() => resolve(false)
);
});
// #endif
// #ifdef APP-PLUS && IOS
return new Promise((resolve) => {
switch (permission) {
case 'camera':
plus.ios.invoke('AVCaptureDevice', 'requestAccessForMediaType:completionHandler:', 'vide', (granted) => {
resolve(granted);
});
break;
case 'location':
const locationManager = plus.ios.newObject('CLLocationManager');
plus.ios.invoke(locationManager, 'requestWhenInUseAuthorization');
// iOS定位权限需要监听变化
setTimeout(() => {
const status = plus.ios.invoke(locationManager, 'authorizationStatus');
plus.ios.deleteObject(locationManager);
resolve(status === 3 || status === 4);
}, 300);
break;
default:
resolve(false);
}
});
// #endif
return false;
},
/**
* 小程序请求权限
*/
async _requestMpPermission(permission) {
const scopeMap = {
'camera': 'scope.camera',
'location': 'scope.userLocation',
'record': 'scope.record',
};
const scope = scopeMap[permission];
if (!scope) return false;
return new Promise((resolve) => {
uni.authorize({
scope,
success: () => resolve(true),
fail: () => resolve(false)
});
});
},
/**
* 打开系统设置页
*/
openSystemSettings() {
// #ifdef APP-PLUS
if (plus.os.name === 'Android') {
const Intent = plus.android.importClass('android.content.Intent');
const Settings = plus.android.importClass('android.provider.Settings');
const Uri = plus.android.importClass('android.net.Uri');
const mainActivity = plus.android.runtimeMainActivity();
const intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
const uri = Uri.fromParts('package', mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
} else {
const UIApplication = plus.ios.import('UIApplication');
const NSURL = plus.ios.import('NSURL');
const url = NSURL.URLWithString('app-settings:');
const application = UIApplication.sharedApplication();
if (plus.ios.invoke(application, 'canOpenURL:', url)) {
plus.ios.invoke(application, 'openURL:', url);
}
plus.ios.deleteObject(url);
plus.ios.deleteObject(application);
}
// #endif
// #ifdef MP-WEIXIN
uni.openSetting();
// #endif
// #ifdef H5
console.log('H5无法打开系统设置');
// #endif
}
};