今日学习

This commit is contained in:
hexi
2026-11-10 11:25:04 +08:00
parent 08711b7628
commit ed134f0e99
3 changed files with 312 additions and 25 deletions
+145 -5
View File
@@ -71,13 +71,16 @@ export type TodayLearningCourse = {
time: string
subject: string
content: string
stageName: string
checkedIn: boolean
statusText: string
}
export type TodayLearningScore = {
accuracy: number
yesterdayAccuracy: number
change: number
accuracy: number | null
yesterdayAccuracy: number | null
change: number | null
hasYesterdayData: boolean
}
export type TodayLearningPoint = {
@@ -86,6 +89,64 @@ export type TodayLearningPoint = {
points: number
}
/** 接口原始结构:今日学习概览 */
export type ParentTodayLearningOverview = {
StudyDurationMinute: number
AnswerDurationMinute: number
AnswerQuestionCount: number
CompletedPackCount: number
TotalPackCount: number
OvercomeKnowledgePointCount: number
IsCheckedIn: boolean
CheckInStatusName: string
}
/** 接口原始结构:今日课节与打卡 */
export type ParentTodayCourseItem = {
CourseId: string
BaseSubjectId: string
BaseSubjectName: string
CourseName: string
StudyStage: number
StudyStageName: string
PlanStartTime: string
PlanEndTime: string
TimeText: string
IsCheckedIn: boolean
CheckInStatusName: string
}
/** 接口原始结构:正确率对比 */
export type ParentTodayAccuracyComparison = {
TodayAccuracyRate: number | null
YesterdayAccuracyRate: number | null
AccuracyRateDiff: number | null
HasYesterdayData: boolean
}
/** 接口原始结构:积分明细 */
export type ParentTodayPointItem = {
Type: number
Name: string
Points: number
}
/** 接口原始结构:今日获得积分 */
export type ParentTodayPointResult = {
TotalPoints: number
Items: ParentTodayPointItem[]
}
/** 接口原始结构:今日学习情况 */
export type ParentTodayLearningSituationResult = {
UserId: string
Date: string
Overview: ParentTodayLearningOverview
Courses: ParentTodayCourseItem[]
Accuracy: ParentTodayAccuracyComparison
Points: ParentTodayPointResult
}
export type StudyReportSubject = {
id: string
name: string
@@ -200,6 +261,7 @@ export type TodayLearningDetail = {
studentName: string
dateText: string
checkedIn: boolean
checkInStatusName: string
learningMinutes: number
answerMinutes: number
answerCount: number
@@ -491,10 +553,88 @@ export function apiGetStudentLearningWarnings(studentId: string, showLoading: bo
}
/**
* 获取学生今日学习详情及课程打卡记录。
* 获取学生今日学习情况。
* 接口字段为 PascalCase,这里统一转换为页面使用的驼峰结构。
*/
export function apiGetTodayLearningDetail(studentId: string, showLoading: boolean = true): Promise<ApiResponse<TodayLearningDetail> | null> {
return get<TodayLearningDetail>(`/api/parent/today-learning?studentId=${studentId}`, undefined, { showLoading })
return get<ParentTodayLearningSituationResult>(`/api/v1/ParentLearningSituation/GetToday?userId=${encodeURIComponent(studentId)}`, undefined, { showLoading }).then((res) => {
if (!res || !res.data) return null
const data = res.data
const overview = data.Overview
const accuracy = data.Accuracy
const points = data.Points
const courses: TodayLearningCourse[] = (Array.isArray(data.Courses) ? data.Courses : []).map((course: ParentTodayCourseItem) => {
const checkedIn = Boolean(course.IsCheckedIn)
return {
id: String(course.CourseId ?? ''),
time: course.TimeText || formatTodayLearningTime(course.PlanStartTime),
subject: course.BaseSubjectName || '',
content: course.CourseName || '',
stageName: course.StudyStageName || '',
checkedIn,
statusText: course.CheckInStatusName || (checkedIn ? '已打卡' : '未打卡')
}
})
const pointDetails: TodayLearningPoint[] = (Array.isArray(points?.Items) ? points.Items : []).map((item: ParentTodayPointItem) => ({
id: String(item.Type ?? ''),
label: item.Name || '其他积分',
points: Number(item.Points) || 0
}))
return {
code: res.code,
message: res.message,
data: {
studentId: String(data.UserId ?? studentId),
studentName: '',
dateText: formatTodayLearningDateText(data.Date),
checkedIn: Boolean(overview?.IsCheckedIn),
checkInStatusName: overview?.CheckInStatusName || (overview?.IsCheckedIn ? '已打卡' : '未打卡'),
learningMinutes: Number(overview?.StudyDurationMinute) || 0,
answerMinutes: Number(overview?.AnswerDurationMinute) || 0,
answerCount: Number(overview?.AnswerQuestionCount) || 0,
completedPackages: Number(overview?.CompletedPackCount) || 0,
totalPackages: Number(overview?.TotalPackCount) || 0,
masteredPoints: Number(overview?.OvercomeKnowledgePointCount) || 0,
courses,
score: {
accuracy: toNullableNumber(accuracy?.TodayAccuracyRate),
yesterdayAccuracy: toNullableNumber(accuracy?.YesterdayAccuracyRate),
change: toNullableNumber(accuracy?.AccuracyRateDiff),
hasYesterdayData: Boolean(accuracy?.HasYesterdayData)
},
pointsTotal: Number(points?.TotalPoints) || 0,
pointDetails
}
}
})
}
function toNullableNumber(value: number | null | undefined): number | null {
if (value === null || value === undefined) return null
return Number(value)
}
function formatTodayLearningTime(value: string | null | undefined): string {
if (!value) return '--'
const text = String(value)
return text.length >= 16 ? text.substring(11, 16) : text
}
function formatTodayLearningDateText(value: string | null | undefined): string {
if (!value) return ''
const text = String(value)
if (text.length < 10) return text
const year = Number(text.substring(0, 4))
const month = Number(text.substring(5, 7))
const day = Number(text.substring(8, 10))
return `${month}月${day}日 ${weekdayName(year, month, day)}`
}
function weekdayName(year: number, month: number, day: number): string {
const offsets = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
const adjustedYear = month < 3 ? year - 1 : year
const index = (adjustedYear + Math.floor(adjustedYear / 4) - Math.floor(adjustedYear / 100) + Math.floor(adjustedYear / 400) + offsets[month - 1] + day) % 7
return ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][index]
}
/**