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:
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user