kydc/settings/settings.js
2026-05-13 15:42:18 +08:00

152 lines
4.7 KiB
JavaScript

const appContext = require('../../utils/app-context.js')
const difficultyOptions = [
{ label: '简单', value: 'easy' },
{ label: '普通', value: 'normal' },
{ label: '困难', value: 'hard' },
]
const reviewOrderOptions = [
{ label: '顺序复习', value: 'sequential' },
{ label: '随机复习', value: 'shuffle' },
]
function normalizeSettings(settings) {
return {
blank_count: Number(settings?.blank_count || 2),
blank_difficulty: settings?.blank_difficulty || 'normal',
review_order: settings?.review_order || 'sequential',
auto_next_question: Number(settings?.auto_next_question || 0),
show_answer_after_submit: Number(settings?.show_answer_after_submit || 0),
}
}
Page({
data: {
settings: null,
loading: false,
error: '',
difficultyOptions,
reviewOrderOptions,
difficultyIndex: 1,
reviewOrderIndex: 0,
difficultyLabel: '普通',
reviewOrderLabel: '顺序复习',
},
onShow() {
this.loadSettings()
},
syncDerivedState(settings) {
const nextSettings = normalizeSettings(settings)
const difficultyIndex = difficultyOptions.findIndex((item) => item.value === nextSettings.blank_difficulty)
const reviewOrderIndex = reviewOrderOptions.findIndex((item) => item.value === nextSettings.review_order)
const safeDifficultyIndex = difficultyIndex >= 0 ? difficultyIndex : 1
const safeReviewOrderIndex = reviewOrderIndex >= 0 ? reviewOrderIndex : 0
this.setData({
settings: nextSettings,
difficultyIndex: safeDifficultyIndex,
difficultyLabel: difficultyOptions[safeDifficultyIndex].label,
reviewOrderIndex: safeReviewOrderIndex,
reviewOrderLabel: reviewOrderOptions[safeReviewOrderIndex].label,
})
},
loadSettings() {
const app = appContext.withApp()
if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
if (appContext.isUnauthorizedResponse(res)) {
appContext.handleUnauthorized()
return
}
const ok = res.statusCode >= 200 && res.statusCode < 300 && res.data?.code === 0
if (!ok) {
this.setData({ error: res.data?.detail || res.data?.message || '设置加载失败' })
return
}
this.syncDerivedState(res.data?.data || null)
},
fail: () => this.setData({ error: '设置加载失败' }),
complete: () => this.setData({ loading: false }),
})
},
onBlankCountInput(e) {
const value = Number(e.detail.value || 0)
this.setData({
settings: {
...normalizeSettings(this.data.settings),
blank_count: Number.isFinite(value) ? value : 0,
},
})
},
onDifficultyChange(e) {
const index = Number(e.detail.value)
const option = difficultyOptions[index] || difficultyOptions[1]
this.setData({
difficultyIndex: index,
difficultyLabel: option.label,
settings: {
...normalizeSettings(this.data.settings),
blank_difficulty: option.value,
},
})
},
onReviewOrderChange(e) {
const index = Number(e.detail.value)
const option = reviewOrderOptions[index] || reviewOrderOptions[0]
this.setData({
reviewOrderIndex: index,
reviewOrderLabel: option.label,
settings: {
...normalizeSettings(this.data.settings),
review_order: option.value,
},
})
},
toggleSetting(e) {
const key = e.currentTarget.dataset.key
const settings = normalizeSettings(this.data.settings)
settings[key] = settings[key] ? 0 : 1
this.setData({ settings })
},
save() {
const app = appContext.withApp()
if (!app.globalData.authToken) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
const settings = normalizeSettings(this.data.settings)
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
method: 'PUT',
header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken },
data: settings,
success: (res) => {
if (appContext.isUnauthorizedResponse(res)) {
appContext.handleUnauthorized()
return
}
const ok = res.statusCode >= 200 && res.statusCode < 300 && res.data?.code === 0
if (!ok) {
wx.showToast({ title: res.data?.detail || res.data?.message || '保存失败', icon: 'none' })
return
}
this.syncDerivedState(res.data?.data || settings)
wx.showToast({ title: '已保存', icon: 'success' })
},
fail: () => wx.showToast({ title: '保存失败', icon: 'none' }),
})
},
})