feat(TUICallKit-Vue3): 迁入节拍器与练一练训练模块

之前误将训练模块加在 uniapp 项目,实际目标项目是 TUICallKit-Vue3
(甄养堂主小程序壳),整体迁入:

- hooks/useMetronome.ts  节拍器(音频实例池+预热,无冷启动延迟)
- hooks/useTrainingSession.ts  训练 Session 状态机
- hooks/useVoiceCoach.ts  语音教练队列
- hooks/useTrainingBgm.ts  训练/休息 BGM 切换+渐变
- pages/training/index.vue  练一练主页(器械跟练)
- pages/training/metronome.vue  独立节拍器(老人友好版,
  中央圆即开始/暂停按钮,纯 CSS 几何 icon,大字大按钮)
- pages/training/components/exercise-anim.vue  CSS 动作动画
- pages/training/exercises.ts  5 个器械动作预设
- static/training/audio/*.mp3  3 种 click 音色(MIT 协议)
- scripts/generate-voice.mjs  MiMo TTS 批量生成语音脚本
- pages.json 注册 pages/training/index 与 pages/training/metronome
- 「我的」页加 DevTrainingEntry 悬浮入口,生产环境自动隐藏

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-25 11:28:55 +08:00
co-authored by Cursor
parent e5d0d7db93
commit 2beace89f4
19 changed files with 2423 additions and 19 deletions
-14
View File
@@ -160,20 +160,6 @@
"navigationBarTitleText": "头像裁剪",
"navigationBarBackgroundColor": "#000000"
}
},
{
"path": "pages/training/index",
"style": {
"navigationBarTitleText": "练一练"
}
},
{
"path": "pages/training/metronome",
"style": {
"navigationBarTitleText": "节拍器",
"navigationBarBackgroundColor": "#0f172a",
"navigationBarTextStyle": "white"
}
}
],
"subPackages": [{
-3
View File
@@ -87,8 +87,6 @@
<MpPrivacyPopup></MpPrivacyPopup>
<!-- #endif -->
<dev-training-entry />
<tabbar/>
</view>
</template>
@@ -98,7 +96,6 @@ import {getIndex} from '@/api/shop'
import {onLoad, onPageScroll} from "@dcloudio/uni-app";
import {computed, reactive, ref} from 'vue'
import {useAppStore} from '@/stores/app'
import DevTrainingEntry from '@/components/dev-training-entry/index.vue'
// #ifdef MP
import MpPrivacyPopup from './component/mp-privacy-popup.vue'
-2
View File
@@ -25,7 +25,6 @@
<w-user-banner :content="item.content" :styles="item.styles" />
</template>
</view>
<dev-training-entry />
<tabbar />
</view>
</template>
@@ -36,7 +35,6 @@ import { useUserStore } from '@/stores/user'
import { onShow } from '@dcloudio/uni-app'
import { storeToRefs } from 'pinia'
import { reactive } from 'vue'
import DevTrainingEntry from '@/components/dev-training-entry/index.vue'
const state = reactive<{
meta: any[]
pages: any[]