fix: 关闭 AI 跟练震动并修复结束重复记录等问题
- 去掉倒计时、计数、评分和调整目标次数时的震动 - 手动结束训练不再重入 finish,避免同一次训练记两条历史 - 领练模式倒计时中暂停后恢复,直接重新倒计时,不再卡在站位 - 摄像头识别随时失败都切到领练模式,不再只在就绪后 1.5 秒检查一次
This commit is contained in:
@@ -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)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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, {
|
||||
|
||||
Reference in New Issue
Block a user