ai-clone/frontend-ai/utils/permission.js
2026-03-05 14:29:21 +08:00

214 lines
6.0 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.

/**
* 权限管理工具类
* 用于统一处理应用权限请求和管理
*/
class PermissionManager {
/**
* 确保权限已授予
* @param {String} permissionType - 权限类型,如 'record'(录音权限)
* @param {Object} options - 配置选项
* @param {String} options.permissionName - 权限名称,用于提示用户
* @param {String} options.reason - 权限用途说明
* @param {Boolean} options.showGuide - 是否显示引导提示
* @returns {Promise<Boolean>} 返回是否已授予权限
*/
static async ensurePermission(permissionType, options = {}) {
const {
permissionName = '权限',
reason = '使用相关功能',
showGuide = true
} = options;
// #ifdef APP-PLUS
return new Promise((resolve) => {
// APP环境使用plus API
if (typeof plus === 'undefined') {
console.warn('[PermissionManager] plus API不可用');
resolve(false);
return;
}
// 根据权限类型映射到plus权限常量
let permission = null;
if (permissionType === 'record' || permissionType === 'microphone') {
permission = 'RECORD_AUDIO';
} else if (permissionType === 'camera') {
permission = 'CAMERA';
} else if (permissionType === 'location') {
permission = 'ACCESS_FINE_LOCATION';
} else {
console.warn(`[PermissionManager] 未知的权限类型: ${permissionType}`);
resolve(false);
return;
}
// 检查权限状态
plus.android.checkPermission(permission, (result) => {
if (result === 1) {
// 已授权
resolve(true);
} else {
// 未授权,请求权限
plus.android.requestPermission(
permission,
(result) => {
if (result === 1) {
// 用户同意授权
resolve(true);
} else {
// 用户拒绝授权
if (showGuide) {
uni.showModal({
title: `需要${permissionName}权限`,
content: `${reason}需要${permissionName}权限才能使用。\n\n请前往:\n手机设置 → 应用管理 → 忆境 → 权限管理 → 开启${permissionName}权限`,
confirmText: '我知道了',
showCancel: false
});
}
resolve(false);
}
},
(error) => {
console.error(`[PermissionManager] 请求${permissionName}权限失败:`, error);
if (showGuide) {
uni.showModal({
title: `需要${permissionName}权限`,
content: `${reason}需要${permissionName}权限才能使用。\n\n请前往:\n手机设置 → 应用管理 → 时光意境 → 权限管理 → 开启${permissionName}权限`,
confirmText: '我知道了',
showCancel: false
});
}
resolve(false);
}
);
}
}, (error) => {
console.error(`[PermissionManager] 检查${permissionName}权限失败:`, error);
resolve(false);
});
});
// #endif
// #ifndef APP-PLUS
// 非APP环境H5、小程序等使用uni-app的权限API
return new Promise((resolve) => {
// 小程序和H5使用不同的权限检查方式
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
// 小程序环境
const scopeMap = {
'record': 'scope.record',
'microphone': 'scope.record',
'camera': 'scope.camera',
'location': 'scope.userLocation'
};
const scope = scopeMap[permissionType] || 'scope.record';
uni.getSetting({
success: (res) => {
if (res.authSetting[scope]) {
// 已授权
resolve(true);
} else if (res.authSetting[scope] === false) {
// 已拒绝,引导用户去设置
if (showGuide) {
uni.showModal({
title: `需要${permissionName}权限`,
content: `请在设置中开启${permissionName}权限`,
confirmText: '去设置',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting({
success: (settingRes) => {
resolve(settingRes.authSetting[scope] || false);
},
fail: () => {
resolve(false);
}
});
} else {
resolve(false);
}
}
});
} else {
resolve(false);
}
} else {
// 未授权过,请求授权
uni.authorize({
scope: scope,
success: () => {
resolve(true);
},
fail: () => {
if (showGuide) {
uni.showModal({
title: `需要${permissionName}权限`,
content: `请允许使用${permissionName}进行${reason}`,
confirmText: '去设置',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting({
success: (settingRes) => {
resolve(settingRes.authSetting[scope] || false);
},
fail: () => {
resolve(false);
}
});
} else {
resolve(false);
}
}
});
} else {
resolve(false);
}
}
});
}
},
fail: () => {
// 获取设置失败默认返回false
resolve(false);
}
});
// #endif
// #ifdef H5
// H5环境使用浏览器API
if (permissionType === 'record' || permissionType === 'microphone') {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ audio: true })
.then((stream) => {
// 立即停止流,只是检查权限
stream.getTracks().forEach(track => track.stop());
resolve(true);
})
.catch((error) => {
if (showGuide) {
alert(`需要${permissionName}权限\n\n${reason}需要${permissionName}权限才能使用。\n\n请在浏览器设置中允许访问${permissionName}`);
}
resolve(false);
});
} else {
if (showGuide) {
alert(`您的浏览器不支持${permissionName}功能`);
}
resolve(false);
}
} else {
resolve(false);
}
// #endif
});
// #endif
}
}
export default PermissionManager;