feat(voice): 语音参数移入 config.js + 设置页男女声切换

- config: 新增 tts.female/male 两组参数(voiceType/volume/speed),
  直接改数字即可调音色,无需改逻辑代码
- storage: getSettings 兜底 voiceGender(旧用户迁移为女声)
- voice: 新增 _getTtsParams 读 config+性别;缓存 key 含完整参数,
  改音色/音量/性别自动重新合成,无需手动清缓存
- settings: 训练偏好加"语音音色"segmented(女声/男声)
- tts 云函数: _synthesize 用传入 opts 合成;_upload 路径含 voiceType
  (男/女不同文件);需重新部署

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 10:08:09 +08:00
parent dd9cd1859c
commit a7ed017267
7 changed files with 118 additions and 20 deletions
+15
View File
@@ -53,6 +53,11 @@ Page({
currentPlanId: 'beginner',
voiceGuide: true,
vibrate: true,
voiceGender: 'female',
voiceGenderOptions: [
{ key: 'female', name: '女声' },
{ key: 'male', name: '男声' }
],
icons: iconsMod.build(),
nickName: '',
avatarUrl: '',
@@ -86,6 +91,7 @@ Page({
currentPlanId: s.planId,
voiceGuide: s.voiceGuide,
vibrate: s.vibrate,
voiceGender: s.voiceGender || 'female',
currentThemeId: theme.id,
theme,
icons: iconsMod.build(theme),
@@ -238,6 +244,15 @@ Page({
this.setData({ vibrate: e.detail.value })
},
onSelectVoiceGender(e) {
const key = e.currentTarget.dataset.key
if (key === this.data.voiceGender) return
const s = storage.getSettings()
s.voiceGender = key
storage.saveSettings(s)
this.setData({ voiceGender: key })
},
onCopyWechat() {
wx.setClipboardData({
data: config.developer,
+15
View File
@@ -118,6 +118,21 @@
</view>
<switch checked="{{voiceGuide}}" bindchange="onToggleVoice" color="{{theme.primary}}"/>
</view>
<view class="setting-row">
<view class="setting-left">
<image class="setting-icon" src="{{icons.voiceFill}}" mode="aspectFit"></image>
<text class="setting-label">语音音色</text>
</view>
<view class="segmented">
<view
class="segmented-item {{voiceGender === item.key ? 'active' : ''}}"
wx:for="{{voiceGenderOptions}}"
wx:key="key"
data-key="{{item.key}}"
bindtap="onSelectVoiceGender"
>{{item.name}}</view>
</view>
</view>
<view class="setting-row">
<view class="setting-left">
<image class="setting-icon" src="{{icons.notificationFill}}" mode="aspectFit"></image>
+21
View File
@@ -178,6 +178,27 @@
.setting-row:last-child { border-bottom: none; }
/* ---- segmented control (语音音色等二选一) ---- */
.segmented {
display: flex;
background: var(--bg-soft);
border-radius: 12rpx;
padding: 4rpx;
}
.segmented-item {
padding: 10rpx 28rpx;
font-size: 24rpx;
color: var(--text-secondary);
border-radius: 8rpx;
transition: background 0.2s ease, color 0.2s ease;
}
.segmented-item.active {
background: var(--card-bg);
color: var(--primary);
font-weight: 600;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08);
}
.setting-left {
display: flex;
align-items: center;