feat: 修复清除数据、语音缓存、排行榜限制,新增项目配置文件
- 修复 cloud.clearAll 静默失败导致重启后数据恢复 - 清除数据弹窗改用自定义 ui-modal 替代 wx.showModal - TTS 语音合成增加 fileID 持久化缓存,重启不再重新合成 - 排行榜限制前15名,maxRank 参数化到 config.js - 新增 config.js 统一管理版本号/更新日期/开发者/排行榜限制 - progress-ring 消除 getSystemInfoSync 弃用警告 - voice.js 增加 InnerAudioContext 错误监听 - storage/util 完善用户资料、打卡日期精度、记录日志
This commit is contained in:
+85
-36
@@ -3,6 +3,7 @@ const themeMod = require('../../utils/theme')
|
||||
const planMod = require('../../utils/plan')
|
||||
const iconsMod = require('../../utils/icons')
|
||||
const cloud = require('../../utils/cloud')
|
||||
const config = require('../../config')
|
||||
|
||||
/**
|
||||
* Build the simplified plans list shown in the settings UI by overlaying
|
||||
@@ -51,18 +52,27 @@ Page({
|
||||
voiceGuide: true,
|
||||
vibrate: true,
|
||||
icons: iconsMod.build(),
|
||||
nickName: '',
|
||||
avatarUrl: '',
|
||||
// Editor state
|
||||
showPlanEditor: false,
|
||||
editingPlanId: '',
|
||||
editingIsCustom: false,
|
||||
editingDraft: null, // { name, totalDays, startTarget, increment, cycleDays }
|
||||
editorPreview: [] // [{ day, target }, ...]
|
||||
editorPreview: [], // [{ day, target }, ...]
|
||||
// Clear-data confirmation
|
||||
showClearConfirm: false,
|
||||
// App info from config
|
||||
appVersion: config.version,
|
||||
appUpdatedAt: config.updatedAt,
|
||||
appDeveloper: config.developer
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const s = storage.getSettings()
|
||||
const theme = themeMod.getCurrentTheme()
|
||||
themeMod.applyThemeToPage(this)
|
||||
const profile = storage.getProfile()
|
||||
this.setData({
|
||||
currentPlanId: s.planId,
|
||||
voiceGuide: s.voiceGuide,
|
||||
@@ -70,7 +80,9 @@ Page({
|
||||
currentThemeId: theme.id,
|
||||
theme,
|
||||
icons: iconsMod.build(theme),
|
||||
plans: buildPlansList(storage.getCustomPlans())
|
||||
plans: buildPlansList(storage.getCustomPlans()),
|
||||
nickName: profile.nickname || '',
|
||||
avatarUrl: profile.avatarUrl || ''
|
||||
})
|
||||
},
|
||||
|
||||
@@ -81,14 +93,45 @@ Page({
|
||||
} catch (e) {}
|
||||
themeMod.applyThemeToPage(this)
|
||||
const theme = themeMod.getCurrentTheme()
|
||||
const profile = storage.getProfile()
|
||||
this.setData({
|
||||
currentThemeId: theme.id,
|
||||
theme,
|
||||
icons: iconsMod.build(theme),
|
||||
plans: buildPlansList(storage.getCustomPlans())
|
||||
plans: buildPlansList(storage.getCustomPlans()),
|
||||
nickName: profile.nickname || '',
|
||||
avatarUrl: profile.avatarUrl || ''
|
||||
})
|
||||
},
|
||||
|
||||
// --- Profile handlers ---
|
||||
|
||||
onChooseAvatar(e) {
|
||||
const avatarUrl = e.detail.avatarUrl
|
||||
if (!avatarUrl) return
|
||||
this.setData({ avatarUrl })
|
||||
const saved = storage.saveProfile({
|
||||
nickname: this.data.nickName,
|
||||
avatarUrl
|
||||
})
|
||||
this.setData({
|
||||
nickName: saved.nickname || this.data.nickName,
|
||||
avatarUrl: saved.avatarUrl
|
||||
})
|
||||
wx.showToast({ title: '头像已更新', icon: 'success', duration: 1200 })
|
||||
},
|
||||
|
||||
onNicknameBlur(e) {
|
||||
const value = (e.detail.value || '').trim()
|
||||
if (!value) return
|
||||
this.setData({ nickName: value })
|
||||
storage.saveProfile({
|
||||
nickname: value,
|
||||
avatarUrl: this.data.avatarUrl
|
||||
})
|
||||
wx.showToast({ title: '昵称已保存', icon: 'success', duration: 1200 })
|
||||
},
|
||||
|
||||
onSelectTheme(e) {
|
||||
const id = e.currentTarget.dataset.id
|
||||
const theme = themeMod.setTheme(id)
|
||||
@@ -136,47 +179,53 @@ Page({
|
||||
|
||||
onCopyWechat() {
|
||||
wx.setClipboardData({
|
||||
data: '刘承',
|
||||
data: config.developer,
|
||||
success: () => {
|
||||
wx.showToast({ title: '已复制', icon: 'success', duration: 1500 })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// Show custom confirmation instead of wx.showModal to avoid the dev-tools
|
||||
// bug where the native dialog refuses to dismiss on first tap.
|
||||
onClearData() {
|
||||
wx.showModal({
|
||||
title: '清除数据',
|
||||
content: '将删除所有训练记录和连续打卡数据,此操作不可恢复。确定继续吗?',
|
||||
confirmText: '确定清除',
|
||||
confirmColor: '#E53935',
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
wx.removeStorageSync('training_records')
|
||||
wx.removeStorageSync('current_streak')
|
||||
wx.removeStorageSync('user_settings')
|
||||
wx.removeStorageSync('app_theme')
|
||||
wx.removeStorageSync('custom_plans')
|
||||
try { await cloud.clearAll() } catch (e) {}
|
||||
wx.setStorageSync('user_settings', {
|
||||
planId: 'beginner',
|
||||
voiceGuide: true,
|
||||
vibrate: true,
|
||||
planStartDate: storage.getToday()
|
||||
})
|
||||
wx.setStorageSync('current_streak', { count: 0, lastDate: '' })
|
||||
themeMod.setTheme('orange')
|
||||
this.setData({
|
||||
currentPlanId: 'beginner',
|
||||
voiceGuide: true,
|
||||
vibrate: true,
|
||||
currentThemeId: 'orange'
|
||||
})
|
||||
themeMod.applyThemeToPage(this)
|
||||
// Reset plans list — custom_plans are gone
|
||||
this.setData({ plans: buildPlansList(storage.getCustomPlans()) })
|
||||
wx.showToast({ title: '已清除', icon: 'success', duration: 1500 })
|
||||
}
|
||||
this.setData({ showClearConfirm: true })
|
||||
},
|
||||
|
||||
onCancelClear() {
|
||||
this.setData({ showClearConfirm: false })
|
||||
},
|
||||
|
||||
onConfirmClear() {
|
||||
this.setData({ showClearConfirm: false })
|
||||
this._doClearData()
|
||||
},
|
||||
|
||||
async _doClearData() {
|
||||
wx.removeStorageSync('training_records')
|
||||
wx.removeStorageSync('current_streak')
|
||||
wx.removeStorageSync('user_settings')
|
||||
wx.removeStorageSync('app_theme')
|
||||
wx.removeStorageSync('custom_plans')
|
||||
try { await cloud.clearAll() } catch (e) {}
|
||||
wx.setStorageSync('user_settings', {
|
||||
planId: 'beginner',
|
||||
voiceGuide: true,
|
||||
vibrate: true,
|
||||
planStartDate: storage.getToday()
|
||||
})
|
||||
wx.setStorageSync('current_streak', { count: 0, lastDate: '' })
|
||||
themeMod.setTheme('orange')
|
||||
this.setData({
|
||||
currentPlanId: 'beginner',
|
||||
voiceGuide: true,
|
||||
vibrate: true,
|
||||
currentThemeId: 'orange'
|
||||
})
|
||||
themeMod.applyThemeToPage(this)
|
||||
// Reset plans list — custom_plans are gone
|
||||
this.setData({ plans: buildPlansList(storage.getCustomPlans()) })
|
||||
wx.showToast({ title: '已清除', icon: 'success', duration: 1500 })
|
||||
},
|
||||
|
||||
// -------- Plan editor --------
|
||||
|
||||
Reference in New Issue
Block a user