From c695217afe3e482bf2b87fc9d48a8a2c08db26f9 Mon Sep 17 00:00:00 2001 From: long <452591453@qq.com> Date: Sat, 31 Oct 2026 10:34:48 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=B3=E9=97=AD=20AI=20=E8=B7=9F?= =?UTF-8?q?=E7=BB=83=E9=9C=87=E5=8A=A8=E5=B9=B6=E4=BF=AE=E5=A4=8D=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E9=87=8D=E5=A4=8D=E8=AE=B0=E5=BD=95=E7=AD=89=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 去掉倒计时、计数、评分和调整目标次数时的震动 - 手动结束训练不再重入 finish,避免同一次训练记两条历史 - 领练模式倒计时中暂停后恢复,直接重新倒计时,不再卡在站位 - 摄像头识别随时失败都切到领练模式,不再只在就绪后 1.5 秒检查一次 --- .../training/pages/components/pose-intro.vue | 5 +--- TUICallKit-Vue3/training/pages/pose-coach.vue | 25 ++++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/TUICallKit-Vue3/training/pages/components/pose-intro.vue b/TUICallKit-Vue3/training/pages/components/pose-intro.vue index 4404feb65..a5c3f3d1c 100644 --- a/TUICallKit-Vue3/training/pages/components/pose-intro.vue +++ b/TUICallKit-Vue3/training/pages/components/pose-intro.vue @@ -104,10 +104,7 @@ const minutes = computed(() => { function change(dir: 1 | -1) { const [lo, hi] = props.exercise.repRange const next = Math.min(hi, Math.max(lo, props.target + dir * props.exercise.repStep)) - if (next !== props.target) { - emit('update:target', next) - uni.vibrateShort({ type: 'light' } as any) - } + if (next !== props.target) emit('update:target', next) } diff --git a/TUICallKit-Vue3/training/pages/pose-coach.vue b/TUICallKit-Vue3/training/pages/pose-coach.vue index 125b02066..5ebdbb13c 100644 --- a/TUICallKit-Vue3/training/pages/pose-coach.vue +++ b/TUICallKit-Vue3/training/pages/pose-coach.vue @@ -479,12 +479,19 @@ function startStage(m: 'vision' | 'sim' | 'guided') { function onCameraReady() { if (mode.value !== 'vision') return camera.start() - setTimeout(() => { - const s = camera.status.value - if (s === 'unsupported' || s === 'error') fallbackToGuided('当前手机暂不支持动作识别,已切换为领练模式') - }, 1500) } +// VisionKit 启动、取帧失败是异步回调,可能晚于任何固定等待时间;随时失败随时切到领练,不会卡在站位。 +// 同步触发:再来一次时状态会在同一轮里 unsupported → starting → unsupported,默认异步合并后看不到变化 +watch( + () => camera.status.value, + (s) => { + if (stage.value !== 'camera' || mode.value !== 'vision') return + if (s === 'unsupported' || s === 'error') fallbackToGuided('当前手机暂不支持动作识别,已切换为领练模式') + }, + { flush: 'sync' }, +) + function onCameraError() { camera.onCameraError(null) fallbackToGuided('摄像头不可用,已切换为领练模式') @@ -541,18 +548,15 @@ function onEvent(e: SessionEvent) { break case 'countdown': voice.speak(String(e.n), 'high') - uni.vibrateShort({ type: 'light' } as any) break case 'rep': { if (mode.value === 'guided') { - // 领练模式不评分:只报数和轻震动 - uni.vibrateShort({ type: 'light' } as any) + // 领练模式不评分:只报数 if (shouldSpeakCount(e.count)) voice.speak(String(e.count), 'count') break } const text = e.grade === 'perfect' ? '完美' : e.grade === 'good' ? '不错' : '加油' Object.assign(pop, { key: pop.key + 1, text, score: e.score, grade: e.grade }) - uni.vibrateShort({ type: e.grade === 'perfect' ? 'medium' : 'light' } as any) if (e.tip) { showTip(e.tip, e.joints ?? []) voice.speak(e.tip, 'high') @@ -648,11 +652,14 @@ function onPause() { function onResume() { if (!session) return handle(session.resume(Date.now())) + // 倒计时中暂停,恢复后会回到站位;领练模式没有识别、站位永远过不去,直接重新倒计时 + if (mode.value === 'guided' && session.phase === 'framing') startGuided() } function finish() { if (!session || stage.value !== 'camera') return - handle(session.finish()) + // 只改状态、不派发 done 事件:done 的处理就是调用 finish,派发会重入,同一次训练记两条历史 + session.finish() const s = summarize(session, ex.value.netMet) if (mode.value === 'guided') { Object.assign(s, {