chore: initialize qiming workspace repository
This commit is contained in:
262
qiming-mobile/utils/permissionHelper.uts
Normal file
262
qiming-mobile/utils/permissionHelper.uts
Normal file
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* 权限处理工具类
|
||||
* 用于处理H5端的各种权限请求和状态检测
|
||||
*/
|
||||
import { t } from "@/utils/i18n";
|
||||
|
||||
// 权限状态类型
|
||||
export type PermissionState = 'granted' | 'denied' | 'prompt' | 'unknown'
|
||||
|
||||
// 权限类型
|
||||
export type PermissionType = 'microphone' | 'camera' | 'geolocation' | 'notifications'
|
||||
|
||||
/**
|
||||
* 权限管理器类
|
||||
*/
|
||||
export class PermissionManager {
|
||||
private static instance: PermissionManager | null = null
|
||||
|
||||
private constructor() {}
|
||||
|
||||
/**
|
||||
* 获取单例实例
|
||||
*/
|
||||
static getInstance(): PermissionManager {
|
||||
if (!PermissionManager.instance) {
|
||||
PermissionManager.instance = new PermissionManager()
|
||||
}
|
||||
return PermissionManager.instance
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限状态
|
||||
* @param permissionType 权限类型
|
||||
* @returns 权限状态
|
||||
*/
|
||||
async checkPermission(permissionType: PermissionType): Promise<PermissionState> {
|
||||
// #ifdef H5
|
||||
try {
|
||||
if (navigator.permissions && navigator.permissions.query) {
|
||||
const permission = await navigator.permissions.query({ name: permissionType as PermissionName })
|
||||
return permission.state
|
||||
} else {
|
||||
// 如果不支持 permissions API,尝试获取权限来检测状态
|
||||
return await this.checkPermissionByRequest(permissionType)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`检查${permissionType}权限失败:`, error)
|
||||
return 'unknown'
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
return 'granted' // 非H5平台默认有权限
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过请求权限来检测权限状态
|
||||
* @param permissionType 权限类型
|
||||
* @returns 权限状态
|
||||
*/
|
||||
private async checkPermissionByRequest(permissionType: PermissionType): Promise<PermissionState> {
|
||||
// #ifdef H5
|
||||
try {
|
||||
switch (permissionType) {
|
||||
case 'microphone': // 麦克风
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
||||
stream.getTracks().forEach(track => track.stop())
|
||||
return 'granted' // 允许
|
||||
case 'camera': // 摄像头
|
||||
const videoStream = await navigator.mediaDevices.getUserMedia({ video: true })
|
||||
videoStream.getTracks().forEach(track => track.stop())
|
||||
return 'granted' // 允许
|
||||
default: // 其他
|
||||
return 'unknown' // 未知
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error.name === 'NotAllowedError') {
|
||||
return 'denied' // 拒绝
|
||||
} else {
|
||||
return 'prompt' // 提示
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
return 'granted'
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求权限
|
||||
* @param permissionType 权限类型
|
||||
* @returns 是否成功获取权限
|
||||
*/
|
||||
async requestPermission(permissionType: PermissionType): Promise<boolean> {
|
||||
// #ifdef H5
|
||||
try {
|
||||
switch (permissionType) {
|
||||
case 'microphone': // 麦克风
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
||||
stream.getTracks().forEach(track => track.stop())
|
||||
return true
|
||||
case 'camera': // 摄像头
|
||||
const videoStream = await navigator.mediaDevices.getUserMedia({ video: true })
|
||||
videoStream.getTracks().forEach(track => track.stop())
|
||||
return true
|
||||
default: // 其他
|
||||
return false // 失败
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(`请求${permissionType}权限失败:`, error)
|
||||
return false
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
return true
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听权限状态变化
|
||||
* @param permissionType 权限类型
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
async watchPermission(permissionType: PermissionType, callback: (state: PermissionState) => void): Promise<void> {
|
||||
// #ifdef H5
|
||||
try {
|
||||
if (navigator.permissions && navigator.permissions.query) {
|
||||
const permission = await navigator.permissions.query({ name: permissionType as PermissionName })
|
||||
permission.onchange = () => {
|
||||
callback(permission.state)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`监听${permissionType}权限变化失败:`, error)
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示权限引导弹窗
|
||||
* @param permissionType 权限类型
|
||||
*/
|
||||
showPermissionGuide(permissionType: PermissionType): void {
|
||||
const guides = {
|
||||
microphone: {
|
||||
title: t("Mobile.Permission.microphoneTitle"),
|
||||
description: t("Mobile.Permission.microphoneDescription"),
|
||||
steps: [
|
||||
t("Mobile.Permission.stepClickLock"),
|
||||
t("Mobile.Permission.stepAllowMicrophone"),
|
||||
t("Mobile.Permission.stepRefreshRetryRecord")
|
||||
]
|
||||
},
|
||||
camera: {
|
||||
title: t("Mobile.Permission.cameraTitle"),
|
||||
description: t("Mobile.Permission.cameraDescription"),
|
||||
steps: [
|
||||
t("Mobile.Permission.stepClickLock"),
|
||||
t("Mobile.Permission.stepAllowCamera"),
|
||||
t("Mobile.Permission.stepRefreshRetryPhoto")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
const guide = guides[permissionType]
|
||||
if (guide) {
|
||||
uni.showModal({
|
||||
title: guide.title,
|
||||
content: t("Mobile.Permission.guideContent", {
|
||||
description: guide.description,
|
||||
steps: guide.steps.map((step, index) => `${index + 1}. ${step}`).join('\n'),
|
||||
}),
|
||||
showCancel: true,
|
||||
cancelText: t("Mobile.Common.cancel"),
|
||||
confirmText: t("Mobile.Permission.gotIt"),
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('用户确认了权限引导')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否支持权限API
|
||||
* @returns 是否支持
|
||||
*/
|
||||
isPermissionAPISupported(): boolean {
|
||||
// #ifdef H5
|
||||
return !!(navigator.permissions && navigator.permissions.query)
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
return false
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 麦克风权限专用工具函数
|
||||
*/
|
||||
export class MicrophonePermissionHelper {
|
||||
private static manager = PermissionManager.getInstance()
|
||||
|
||||
/**
|
||||
* 检查麦克风权限状态
|
||||
*/
|
||||
static async check(): Promise<PermissionState> {
|
||||
return await this.manager.checkPermission('microphone')
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求麦克风权限
|
||||
*/
|
||||
static async request(): Promise<boolean> {
|
||||
return await this.manager.requestPermission('microphone')
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听麦克风权限变化
|
||||
*/
|
||||
static async watch(callback: (state: PermissionState) => void): Promise<void> {
|
||||
return await this.manager.watchPermission('microphone', callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示麦克风权限引导
|
||||
*/
|
||||
static showGuide(): void {
|
||||
this.manager.showPermissionGuide('microphone')
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保麦克风权限可用
|
||||
* @param showGuide 是否显示权限引导
|
||||
* @returns 是否成功获取权限
|
||||
*/
|
||||
static async ensure(showGuide: boolean = true): Promise<boolean> {
|
||||
// Always attempt to request permission first
|
||||
const success = await this.request()
|
||||
if (success) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If request fails, check the current state
|
||||
const state = await this.check()
|
||||
|
||||
// Show guide if denied and showGuide is true
|
||||
if (showGuide && state === 'denied') {
|
||||
this.showGuide()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 导出默认实例
|
||||
export default PermissionManager.getInstance()
|
||||
Reference in New Issue
Block a user