接入学生学习数据接口

This commit is contained in:
tanxin
2026-11-05 11:01:12 +08:00
parent d1d44e250e
commit af73453035
15 changed files with 336 additions and 48 deletions
+42 -21
View File
@@ -3,7 +3,7 @@
<!-- 固定顶部信息区 -->
<view class="header-panel">
<view class="header-copy">
<text class="header-greeting">下午好,王女士</text>
<text class="header-greeting">下午好,{{ parentName }}</text>
<text class="header-title">孩子今天的学习情况</text>
<text class="header-update">数据更新时间 {{ metricsUpdateText }} · 系统定时预计暂停,非实时</text>
</view>
@@ -25,7 +25,7 @@
<view class="student-identity">
<view class="student-name-row">
<text class="student-name">{{ student.name }}</text>
<text class="student-grade">{{ student.grade }}</text>
<text class="student-grade">{{ student.className }}</text>
</view>
<view class="student-level-row">
<view class="level-medal"></view>
@@ -58,7 +58,7 @@
</view>
<view class="metric-item">
<text class="metric-label">本周学习天数</text>
<text class="metric-value metric-blue">{{ metrics.learningDaysThisWeek }}/7 天</text>
<text class="metric-value metric-blue">{{ metrics.learningDaysThisWeek }}/{{ metrics.shouldStudyDaysThisWeek }} 天</text>
</view>
<view class="metric-item">
<text class="metric-label">待完成作业</text>
@@ -102,7 +102,7 @@
<view v-else-if="boundStudents.length === 0" class="student-picker-empty"><text class="student-picker-empty-text">暂无已绑定学生</text></view>
<view v-else v-for="item in boundStudents" :key="item.id" class="student-picker-item" :class="selectedStudentId === item.id ? 'student-picker-item-selected' : ''" @tap="selectStudent(item.id)">
<view class="student-picker-avatar"><image v-if="item.avatar" class="student-picker-avatar-image" :src="item.avatar" mode="aspectFill"></image><text v-else class="student-picker-avatar-text">{{ item.name.substring(0, 1) }}</text></view>
<view class="student-picker-info"><view class="student-picker-name-row"><text class="student-picker-name">{{ item.name }}</text><text class="student-picker-grade">{{ item.grade }}</text></view><text class="student-picker-detail">账号:{{ item.account }}</text><text class="student-picker-detail">学校:{{ item.school }}</text></view>
<view class="student-picker-info"><view class="student-picker-name-row"><text class="student-picker-name">{{ item.name }}</text><text class="student-picker-grade">{{ item.school }} {{ item.className }}</text></view><text class="student-picker-detail">账号:{{ item.account }}</text></view>
<view v-if="selectedStudentId === item.id" class="student-picker-check"><text class="student-picker-check-text">已选</text></view>
</view>
</scroll-view>
@@ -115,8 +115,9 @@
<script setup lang="ts">
import MainTabBar from '../../components/main-tab-bar.uvue'
import UniIcons from '../../uni_modules/uni-icons-x/components/uni-icons/uni-icons.uvue'
import { apiGetBoundStudents, apiGetStudentAlerts, apiGetStudentHomeMetrics, apiGetStudentHomeProfile, type BoundStudentSummary, type StudentAlert, type StudentAlertLevel, type StudentHomeMetrics, type StudentHomeProfile } from '../../api/student'
import { homeStudentAlerts, homeStudentMetrics, homeStudentProfile, setHomeStudentAlerts, setHomeStudentMetrics, setHomeStudentProfile } from '../../store/home'
import { apiGetBoundStudents, apiGetStudentHomeMetrics, apiGetStudentLearningWarnings, type BoundStudentSummary, type StudentAlert, type StudentAlertLevel, type StudentHomeMetrics, type StudentHomeProfile } from '../../api/student'
import { applyBoundStudent, getSavedSelectedStudent, homeStudentAlerts, homeStudentMetrics, homeStudentProfile, saveSelectedStudent, setHomeStudentAlerts, setHomeStudentMetrics } from '../../store/home'
import type { UserInfo } from '../../api/auth'
const loadingStudent = ref<StudentHomeProfile>({
id: '',
@@ -124,6 +125,7 @@
account: '',
grade: '',
school: '',
className: '',
avatar: '',
comprehensiveLevel: 'qualified'
})
@@ -135,9 +137,13 @@
const student = computed((): StudentHomeProfile => homeStudentProfile.value ?? loadingStudent.value)
const metrics = computed((): StudentHomeMetrics => homeStudentMetrics.value ?? {
studentId: '', onlineToday: false, checkedInToday: false, learningMinutesToday: 0,
accuracyToday: null, learningDaysThisWeek: 0, pendingHomeworkCount: 0, updatedAt: ''
accuracyToday: null, learningDaysThisWeek: 0, shouldStudyDaysThisWeek: 0, pendingHomeworkCount: 0, updatedAt: ''
})
const alerts = computed((): StudentAlert[] => homeStudentAlerts.value ?? [])
const parentName = computed((): string => {
const userInfo = uni.getStorageSync('userInfo') as UserInfo | null
return userInfo?.nickname || '家长'
})
const studentInitial = computed((): string => {
return student.value.name.length > 0 ? student.value.name.substring(0, 1) : '学'
@@ -165,18 +171,9 @@
})
onLoad(() => {
if (!homeStudentProfile.value || !homeStudentMetrics.value || homeStudentAlerts.value === null) {
loadHomeData()
}
loadHomeData()
})
async function loadStudentHomeProfile(studentId?: string, showLoading: boolean = true) {
const res = await apiGetStudentHomeProfile(studentId, showLoading)
if (res && res.data) {
setHomeStudentProfile(res.data)
}
}
async function loadStudentHomeMetrics(studentId: string, showLoading: boolean = true) {
const res = await apiGetStudentHomeMetrics(studentId, showLoading)
if (res && res.data) {
@@ -185,18 +182,37 @@
}
async function loadStudentAlerts(studentId: string, showLoading: boolean = true) {
const res = await apiGetStudentAlerts(studentId, 1, 20, 3, showLoading)
const res = await apiGetStudentLearningWarnings(studentId, showLoading)
if (res && res.data) {
setHomeStudentAlerts(res.data.list)
}
}
async function loadHomeData(studentId?: string, showLoading: boolean = true) {
await loadStudentHomeProfile(studentId, showLoading)
let selectedId = studentId || homeStudentProfile.value?.id || ''
if (selectedId && (!homeStudentProfile.value || homeStudentProfile.value.id !== selectedId)) {
const savedStudent = getSavedSelectedStudent()
if (savedStudent?.id === selectedId) applyBoundStudent(savedStudent)
}
if (!selectedId) {
const savedStudent = getSavedSelectedStudent()
if (savedStudent) {
selectedId = savedStudent.id
applyBoundStudent(savedStudent)
} else {
const res = await apiGetBoundStudents()
const firstStudent = res?.data?.students[0]
if (firstStudent) {
saveSelectedStudent(firstStudent)
applyBoundStudent(firstStudent)
selectedId = firstStudent.id
}
}
}
if (student.value.id) {
await Promise.all([
loadStudentHomeMetrics(student.value.id, showLoading),
loadStudentAlerts(student.value.id, showLoading)
loadStudentHomeMetrics(selectedId || student.value.id, showLoading),
loadStudentAlerts(selectedId || student.value.id, showLoading)
])
}
}
@@ -261,6 +277,11 @@
return
}
closeStudentPicker()
const selectedStudent = boundStudents.value.find((item) => item.id === selectedStudentId.value)
if (selectedStudent) {
saveSelectedStudent(selectedStudent)
applyBoundStudent(selectedStudent)
}
if (selectedStudentId.value !== student.value.id) {
await loadHomeData(selectedStudentId.value)
}