mirror of
https://github.com/ZeroCatDev/Classworks.git
synced 2026-03-21 09:13:10 +00:00
feat: 添加麦克风权限状态提示,优化噪音监测体验
This commit is contained in:
parent
787c95ca18
commit
41dc2c5251
@ -83,6 +83,48 @@
|
||||
<v-tabs-window v-model="activeTab">
|
||||
<!-- ==================== 实时监测 ==================== -->
|
||||
<v-tabs-window-item value="realtime">
|
||||
<!-- 麦克风不可用提示 -->
|
||||
<v-alert
|
||||
v-if="micPermissionState === 'denied'"
|
||||
type="error"
|
||||
variant="tonal"
|
||||
class="ma-4 mb-0"
|
||||
prominent
|
||||
>
|
||||
<template #prepend>
|
||||
<v-icon
|
||||
icon="mdi-microphone-off"
|
||||
size="28"
|
||||
/>
|
||||
</template>
|
||||
<div class="text-subtitle-2 font-weight-bold mb-1">
|
||||
麦克风权限被拒绝
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
浏览器已拒绝麦克风访问,无法进行噪音监测。请在浏览器地址栏左侧的锁图标中重新授予麦克风权限,然后刷新页面。
|
||||
</div>
|
||||
</v-alert>
|
||||
<v-alert
|
||||
v-else-if="micPermissionState === 'unavailable'"
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
class="ma-4 mb-0"
|
||||
prominent
|
||||
>
|
||||
<template #prepend>
|
||||
<v-icon
|
||||
icon="mdi-microphone-question"
|
||||
size="28"
|
||||
/>
|
||||
</template>
|
||||
<div class="text-subtitle-2 font-weight-bold mb-1">
|
||||
未检测到麦克风
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
当前设备未检测到麦克风硬件,无法进行噪音监测。请连接麦克风后刷新页面重试。
|
||||
</div>
|
||||
</v-alert>
|
||||
|
||||
<!-- 分贝仪表区 -->
|
||||
<div class="noise-dashboard pa-5">
|
||||
<div class="d-flex align-center justify-center">
|
||||
@ -344,6 +386,7 @@
|
||||
prepend-icon="mdi-play"
|
||||
size="large"
|
||||
class="px-6"
|
||||
:disabled="micPermissionState === 'denied' || micPermissionState === 'unavailable'"
|
||||
@click="$emit('start')"
|
||||
>
|
||||
开始监测
|
||||
@ -1006,6 +1049,7 @@ export default {
|
||||
lastSlice: { type: Object, default: null },
|
||||
history: { type: Array, default: () => [] },
|
||||
isMonitoring: { type: Boolean, default: false },
|
||||
micPermissionState: { type: String, default: '' },
|
||||
sessionActive: { type: Boolean, default: false },
|
||||
sessionData: { type: Object, default: null },
|
||||
reportMeta: { type: Object, default: () => ({ dates: {} }) },
|
||||
|
||||
@ -39,7 +39,36 @@
|
||||
style="min-width: 80px;"
|
||||
@click.stop="onNoiseClick"
|
||||
>
|
||||
|
||||
<!-- 无麦克风权限提示 -->
|
||||
<template v-if="micPermissionState === 'denied'">
|
||||
<v-icon
|
||||
color="error"
|
||||
size="24"
|
||||
>
|
||||
mdi-microphone-off
|
||||
</v-icon>
|
||||
<div
|
||||
class="text-caption text-error mt-1"
|
||||
style="white-space: nowrap; font-size: 10px;"
|
||||
>
|
||||
权限被拒绝
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="micPermissionState === 'unavailable'">
|
||||
<v-icon
|
||||
color="warning"
|
||||
size="24"
|
||||
>
|
||||
mdi-microphone-question
|
||||
</v-icon>
|
||||
<div
|
||||
class="text-caption text-warning mt-1"
|
||||
style="white-space: nowrap; font-size: 10px;"
|
||||
>
|
||||
无麦克风
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div
|
||||
class="noise-side-db font-weight-bold"
|
||||
:class="`text-${noiseDbColor}`"
|
||||
@ -61,6 +90,7 @@
|
||||
>
|
||||
点击开启
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
@ -80,6 +110,7 @@
|
||||
:last-slice="noiseLastSlice"
|
||||
:history="noiseHistory"
|
||||
:is-monitoring="noiseMonitoring"
|
||||
:mic-permission-state="micPermissionState"
|
||||
:session-active="noiseSessionActive"
|
||||
:session-data="noiseSessionData"
|
||||
:report-meta="noiseReportMeta"
|
||||
@ -749,6 +780,7 @@ export default {
|
||||
noiseCurrentDateReports: [], // 当前日期的报告列表
|
||||
// 麦克风权限引导
|
||||
showMicPermissionDialog: false,
|
||||
micPermissionState: '', // 'granted' | 'prompt' | 'denied' | 'unavailable'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -925,6 +957,7 @@ export default {
|
||||
this.noiseHistory = noiseService.getHistory()
|
||||
// 检查麦克风权限状态
|
||||
const micState = await this.checkMicPermission()
|
||||
this.micPermissionState = micState
|
||||
if (micState === 'granted') {
|
||||
// 已授权 → 正常流程
|
||||
this.loadNoiseSessionConfig().then(() => {
|
||||
@ -939,7 +972,7 @@ export default {
|
||||
this.showMicPermissionDialog = true
|
||||
}
|
||||
}
|
||||
// denied → 什么也不做
|
||||
// denied / unavailable → 不自动启动,micPermissionState 已记录
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
@ -1124,7 +1157,13 @@ export default {
|
||||
// ===== 麦克风权限引导 =====
|
||||
async checkMicPermission() {
|
||||
try {
|
||||
if (!navigator.permissions || !navigator.permissions.query) return 'granted' // 不支持 Permissions API 时视为已授权
|
||||
// 先检查是否有麦克风硬件
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
|
||||
const devices = await navigator.mediaDevices.enumerateDevices()
|
||||
const hasMic = devices.some(d => d.kind === 'audioinput')
|
||||
if (!hasMic) return 'unavailable'
|
||||
}
|
||||
if (!navigator.permissions || !navigator.permissions.query) return 'granted'
|
||||
const result = await navigator.permissions.query({ name: 'microphone' })
|
||||
return result.state // 'granted' | 'prompt' | 'denied'
|
||||
} catch {
|
||||
@ -1139,6 +1178,8 @@ export default {
|
||||
this.startSessionCheck()
|
||||
// 调用 startNoise 触发浏览器权限弹框
|
||||
await this.startNoise()
|
||||
// 重新检查状态
|
||||
this.micPermissionState = await this.checkMicPermission()
|
||||
},
|
||||
dismissMicPermission() {
|
||||
this.showMicPermissionDialog = false
|
||||
@ -1202,6 +1243,10 @@ export default {
|
||||
this.noiseHistory = []
|
||||
},
|
||||
onNoiseClick() {
|
||||
if (this.micPermissionState === 'denied' || this.micPermissionState === 'unavailable') {
|
||||
this.showNoiseDetail = true
|
||||
return
|
||||
}
|
||||
if (!this.noiseMonitoring) {
|
||||
this.startNoise()
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user