feat: establish teaching feedback mini program

Connect student profiles, defaults, and feedback records to the Rust API. Configure the WeChat AppID, custom tab bar, and local development workflow for version 0.1.0.
This commit is contained in:
2026-07-15 15:36:51 +08:00
commit 0a07538dce
37 changed files with 2550 additions and 0 deletions

97
pages/records/index.ts Normal file
View File

@@ -0,0 +1,97 @@
import {
deleteFeedbackRecord,
getApiErrorMessage,
listFeedbackRecords,
listProfiles
} from '../../utils/api'
import type { FeedbackRecord, StudentProfile } from '../../utils/types'
type PickerEvent = { detail: { value: string | number } }
type FeedbackRecordView = FeedbackRecord & { profileName: string }
Page({
data: {
profiles: [] as StudentProfile[],
records: [] as FeedbackRecordView[],
profileOptions: ['全部学生'],
selectedProfileIndex: 0,
loading: false,
deletingId: '',
errorMessage: ''
},
onShow() {
this.getTabBar()?.setData({ selected: 2 })
void this.loadData()
},
async loadData() {
this.setData({ loading: true, errorMessage: '' })
try {
const profiles = await listProfiles()
const selectedProfile = profiles[this.data.selectedProfileIndex - 1]
const records = await listFeedbackRecords(selectedProfile?.id)
this.setData({
profiles,
profileOptions: ['全部学生', ...profiles.map((profile) => profile.name)],
selectedProfileIndex: selectedProfile ? this.data.selectedProfileIndex : 0,
records: this.withProfileNames(records, profiles)
})
} catch (error) {
this.setData({ errorMessage: getApiErrorMessage(error) })
} finally {
this.setData({ loading: false })
}
},
withProfileNames(records: FeedbackRecord[], profiles: StudentProfile[]): FeedbackRecordView[] {
return records.map((record) => ({
...record,
profileName: profiles.find((profile) => profile.id === record.profileId)?.name || '未关联学生'
}))
},
retryLoad() {
void this.loadData()
},
async onProfileChange(event: PickerEvent) {
const selectedProfileIndex = Number(event.detail.value)
const profile = this.data.profiles[selectedProfileIndex - 1]
this.setData({ selectedProfileIndex, loading: true, errorMessage: '' })
try {
const records = await listFeedbackRecords(profile?.id)
this.setData({ records: this.withProfileNames(records, this.data.profiles) })
} catch (error) {
this.setData({ errorMessage: getApiErrorMessage(error) })
} finally {
this.setData({ loading: false })
}
},
deleteRecord(event: WechatMiniprogram.TouchEvent) {
const { id } = event.currentTarget.dataset as { id: string }
wx.showModal({
title: '删除反馈记录',
content: '删除后无法恢复,确认继续吗?',
confirmColor: '#D14343',
success: async (result) => {
if (!result.confirm) return
this.setData({ deletingId: id })
try {
await deleteFeedbackRecord(id)
this.setData({ records: this.data.records.filter((record) => record.id !== id) })
wx.showToast({ title: '记录已删除', icon: 'success' })
} catch (error) {
wx.showToast({ title: getApiErrorMessage(error), icon: 'none' })
} finally {
this.setData({ deletingId: '' })
}
}
})
},
goFeedback() {
wx.switchTab({ url: '/pages/feedback/index' })
}
})