| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- const AUTH_KEY = {
- album: 'albumAuthorized',
- camera: 'cameraAuthorized',
- record: 'microphoneAuthorized'
- }
- const WX_SCOPE = {
- camera: 'scope.camera',
- record: 'scope.record'
- }
- let modalOpen = false
- function t(vm, key, fallback) {
- const fn = vm && vm.$t ? vm.$t.bind(vm) : null
- if (!fn) return fallback
- try {
- const v = fn(key)
- return v && v !== key ? v : fallback
- } catch (_) {
- return fallback
- }
- }
- function isPermissionErrMsg(msg) {
- const m = String(msg || '').toLowerCase()
- return (
- m.indexOf('auth') !== -1 ||
- m.indexOf('deny') !== -1 ||
- m.indexOf('permission') !== -1 ||
- m.indexOf('authorize') !== -1 ||
- m.indexOf('不允许') !== -1 ||
- m.indexOf('拒绝') !== -1 ||
- m.indexOf('权限') !== -1
- )
- }
- export function openAppPermissionSettings() {
- if (typeof uni.openAppAuthorizeSetting === 'function') {
- uni.openAppAuthorizeSetting({})
- return
- }
- // #ifdef APP-PLUS
- try {
- const os = String(plus.os.name || '').toLowerCase()
- if (os === 'ios') {
- plus.runtime.openURL('app-settings:')
- return
- }
- } catch (_) {}
- // #endif
- if (typeof uni.openSetting === 'function') {
- uni.openSetting({})
- }
- }
- function readAppAuthorize(kind) {
- const key = AUTH_KEY[kind]
- if (!key || typeof uni.getAppAuthorizeSetting !== 'function') return 'unknown'
- try {
- const setting = uni.getAppAuthorizeSetting() || {}
- return setting[key] || 'not determined'
- } catch (_) {
- return 'unknown'
- }
- }
- function contentKeyForKind(kind) {
- if (kind === 'album') return 'dynamics.publishAlbumPermissionContent'
- if (kind === 'record') return 'dynamics.publishRecordPermissionContent'
- return 'dynamics.publishCameraPermissionContent'
- }
- export function promptMediaPermission(vm, kind) {
- if (modalOpen) return
- modalOpen = true
- uni.showModal({
- title: t(vm, 'dynamics.publishMediaPermissionTitle', '提示'),
- content: t(vm, contentKeyForKind(kind), '请在系统设置中开启相应权限后重试'),
- confirmText: t(vm, 'dynamics.publishMediaPermissionConfirm', '去设置'),
- cancelText: t(vm, 'dynamics.publishMediaPermissionCancel', '取消'),
- success: (res) => {
- modalOpen = false
- if (res.confirm) openAppPermissionSettings()
- },
- fail: () => {
- modalOpen = false
- }
- })
- }
- function ensureWeixinScope(scope, vm, kind) {
- return new Promise((resolve) => {
- uni.getSetting({
- success: (res) => {
- const auth = (res && res.authSetting) || {}
- if (auth[scope] === false) {
- promptMediaPermission(vm, kind)
- resolve(false)
- return
- }
- if (auth[scope] === true) {
- resolve(true)
- return
- }
- uni.authorize({
- scope,
- success: () => resolve(true),
- fail: () => resolve(false)
- })
- },
- fail: () => resolve(true)
- })
- })
- }
- export async function ensureMediaPermission(vm, kinds) {
- const list = Array.isArray(kinds) ? kinds : [kinds]
- for (let i = 0; i < list.length; i++) {
- const kind = list[i]
- // #ifdef MP-WEIXIN
- if (kind === 'camera' || kind === 'record') {
- const scope = WX_SCOPE[kind]
- const ok = await ensureWeixinScope(scope, vm, kind)
- if (!ok) return false
- continue
- }
- // 微信小程序读相册由 chooseImage/chooseVideo 触发,fail 回调兜底
- continue
- // #endif
- const status = readAppAuthorize(kind)
- if (status === 'denied') {
- promptMediaPermission(vm, kind)
- return false
- }
- }
- return true
- }
- function wrapMediaFail(vm, kind, fail) {
- return (err) => {
- if (isPermissionErrMsg(err && err.errMsg)) {
- // 首次拒绝仅静默结束,下次点击时由 ensureMediaPermission 检测 denied 再引导去设置
- return
- }
- if (typeof fail === 'function') fail(err)
- }
- }
- export function showMediaSourceSheet(vm, options = {}) {
- const { type = 'image', onAlbum, onCamera } = options
- const isVideo = type === 'video'
- uni.showActionSheet({
- itemList: [
- t(vm, 'dynamics.publishPickAlbum', '从相册选择'),
- t(
- vm,
- isVideo ? 'dynamics.publishPickCameraVideo' : 'dynamics.publishPickCamera',
- isVideo ? '拍摄视频' : '拍照'
- )
- ],
- success: (res) => {
- if (res.tapIndex === 0 && onAlbum) onAlbum()
- else if (res.tapIndex === 1 && onCamera) onCamera()
- }
- })
- }
- export async function chooseImageWithPermission(vm, source, options = {}) {
- const kind = source === 'camera' ? 'camera' : 'album'
- const ok = await ensureMediaPermission(vm, kind)
- if (!ok) return
- const { fail, ...rest } = options
- uni.chooseImage({
- ...rest,
- sourceType: [source],
- fail: wrapMediaFail(vm, kind, fail)
- })
- }
- export async function chooseVideoWithPermission(vm, source, options = {}) {
- const kinds = source === 'camera' ? ['camera', 'record'] : ['album']
- const ok = await ensureMediaPermission(vm, kinds)
- if (!ok) return
- const { fail, ...rest } = options
- const failKind = source === 'camera' ? 'camera' : 'album'
- uni.chooseVideo({
- ...rest,
- sourceType: [source],
- fail: wrapMediaFail(vm, failKind, fail)
- })
- }
|