631 lines
63 KiB
HTML
631 lines
63 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>学情分析报告 - 用户15868 Level1 Unit1</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||
background-color: #f0f2f5;
|
||
padding: 24px;
|
||
color: #333;
|
||
}
|
||
.container { max-width: 1200px; margin: 0 auto; }
|
||
.header {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
padding: 32px;
|
||
border-radius: 16px;
|
||
margin-bottom: 24px;
|
||
}
|
||
.header h1 { font-size: 28px; margin-bottom: 8px; }
|
||
.header .meta { font-size: 14px; opacity: 0.9; }
|
||
.card {
|
||
background: white;
|
||
border-radius: 12px;
|
||
padding: 24px;
|
||
margin-bottom: 20px;
|
||
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
||
}
|
||
.card h2 {
|
||
font-size: 18px;
|
||
color: #333;
|
||
margin-bottom: 20px;
|
||
border-left: 4px solid #667eea;
|
||
padding-left: 12px;
|
||
}
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||
gap: 16px;
|
||
margin-bottom: 24px;
|
||
}
|
||
.stat-item {
|
||
background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%);
|
||
padding: 20px;
|
||
border-radius: 12px;
|
||
text-align: center;
|
||
}
|
||
.stat-item .label { font-size: 13px; color: #888; margin-bottom: 8px; }
|
||
.stat-item .value { font-size: 28px; font-weight: 700; color: #333; }
|
||
.stat-item .value.green { color: #52c41a; }
|
||
.stat-item .value.orange { color: #fa8c16; }
|
||
.stat-item .value.blue { color: #1890ff; }
|
||
.stat-item .value.purple { color: #722ed1; }
|
||
.chart-container { height: 400px; width: 100%; }
|
||
.chart-row {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
gap: 20px;
|
||
}
|
||
@media (max-width: 1024px) {
|
||
.chart-row { grid-template-columns: 1fr; }
|
||
}
|
||
.lesson-nav {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 16px;
|
||
margin-bottom: 24px;
|
||
}
|
||
.lesson-card {
|
||
background: white;
|
||
border: 2px solid #e8e8e8;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
text-align: center;
|
||
}
|
||
.lesson-card:hover {
|
||
border-color: #667eea;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
|
||
}
|
||
.lesson-card.active {
|
||
border-color: #667eea;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
}
|
||
.lesson-card .lesson-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
margin-bottom: 12px;
|
||
}
|
||
.lesson-card .lesson-time {
|
||
font-size: 13px;
|
||
opacity: 0.9;
|
||
line-height: 1.6;
|
||
}
|
||
.lesson-card .lesson-time .time-label {
|
||
opacity: 0.7;
|
||
}
|
||
.lesson-card .lesson-stats {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 16px;
|
||
margin-top: 12px;
|
||
padding-top: 12px;
|
||
border-top: 1px solid rgba(102, 126, 234, 0.2);
|
||
font-size: 13px;
|
||
}
|
||
.lesson-card.active .lesson-stats {
|
||
border-top-color: rgba(255, 255, 255, 0.3);
|
||
}
|
||
.lesson-card .lesson-stats .stat {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
.lesson-card .lesson-stats .stat-label {
|
||
font-size: 11px;
|
||
opacity: 0.7;
|
||
margin-bottom: 2px;
|
||
}
|
||
.lesson-card .lesson-stats .stat-value {
|
||
font-weight: 600;
|
||
font-size: 14px;
|
||
}
|
||
.lesson-card .lesson-stats .stat-value.oops { color: #fa541c; }
|
||
.lesson-card .lesson-stats .stat-value.wrong { color: #f5222d; }
|
||
.lesson-card.active .lesson-stats .stat-value.oops,
|
||
.lesson-card.active .lesson-stats .stat-value.wrong { color: #ffccc7; }
|
||
.lesson-detail { display: none; }
|
||
.lesson-detail.active { display: block; }
|
||
.knowledge-section { margin-bottom: 20px; }
|
||
.knowledge-section h3 {
|
||
font-size: 15px;
|
||
color: #555;
|
||
margin-bottom: 12px;
|
||
}
|
||
.word-list, .pattern-list {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10px;
|
||
}
|
||
.word-tag {
|
||
background: #e6f7ff;
|
||
border: 1px solid #91d5ff;
|
||
border-radius: 8px;
|
||
padding: 8px 16px;
|
||
font-size: 14px;
|
||
}
|
||
.word-tag .en { font-weight: 600; color: #1890ff; }
|
||
.word-tag .cn { color: #666; margin-left: 6px; }
|
||
.word-tag .pos { color: #999; font-size: 12px; margin-left: 4px; }
|
||
.pattern-tag {
|
||
background: #fff7e6;
|
||
border: 1px solid #ffd591;
|
||
border-radius: 8px;
|
||
padding: 10px 16px;
|
||
font-size: 14px;
|
||
flex: 1 1 300px;
|
||
}
|
||
.pattern-tag .en { font-weight: 600; color: #fa8c16; }
|
||
.pattern-tag .cn { color: #666; display: block; margin-top: 4px; font-size: 13px; }
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 14px;
|
||
}
|
||
table th {
|
||
background: #f5f7fa;
|
||
padding: 12px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
color: #555;
|
||
border-bottom: 2px solid #e8e8e8;
|
||
}
|
||
table td {
|
||
padding: 10px 12px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
table tr:hover td { background: #fafafa; }
|
||
.badge {
|
||
display: inline-block;
|
||
padding: 2px 10px;
|
||
border-radius: 10px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
.badge.perfect { background: #f6ffed; color: #52c41a; border: 1px solid #b7eb8f; }
|
||
.badge.good { background: #e6f7ff; color: #1890ff; border: 1px solid #91d5ff; }
|
||
.badge.oops { background: #fff2e8; color: #fa541c; border: 1px solid #ffbb96; }
|
||
.badge.correct { background: #f6ffed; color: #52c41a; border: 1px solid #b7eb8f; }
|
||
.badge.wrong { background: #fff1f0; color: #f5222d; border: 1px solid #ffa39e; }
|
||
.audio-btn {
|
||
cursor: pointer;
|
||
margin-left: 6px;
|
||
font-size: 16px;
|
||
vertical-align: middle;
|
||
opacity: 0.7;
|
||
transition: opacity 0.2s;
|
||
}
|
||
.audio-btn:hover { opacity: 1; }
|
||
.audio-btn.playing { opacity: 1; color: #1890ff; }
|
||
.time-info {
|
||
display: flex;
|
||
gap: 20px;
|
||
margin-bottom: 16px;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
.time-info span { display: flex; align-items: center; gap: 6px; }
|
||
.raw-data {
|
||
background: #f8f9fa;
|
||
padding: 16px;
|
||
border-radius: 8px;
|
||
font-family: "SF Mono", "Fira Code", monospace;
|
||
font-size: 12px;
|
||
max-height: 400px;
|
||
overflow-y: auto;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="header">
|
||
<h1>📚 学情分析报告</h1>
|
||
<div class="meta">
|
||
用户ID:15868 | Level 1 | Unit 1 | 生成时间:2026-04-02 18:07:28
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>📊 总览</h2>
|
||
<div class="stats-grid" id="stats-grid"></div>
|
||
</div>
|
||
|
||
<div class="chart-row">
|
||
<div class="card">
|
||
<h2>📈 互动组件表现</h2>
|
||
<div id="interactive-chart" class="chart-container"></div>
|
||
</div>
|
||
<div class="card">
|
||
<h2>📝 巩固练习正确率</h2>
|
||
<div id="exercise-chart" class="chart-container"></div>
|
||
</div>
|
||
<div class="card">
|
||
<h2>🎯 能力训练正确率</h2>
|
||
<div id="ability-chart" class="chart-container"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>📖 课程详情</h2>
|
||
<div class="lesson-nav" id="lesson-nav"></div>
|
||
<div id="lesson-details"></div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>🎯 能力训练</h2>
|
||
<table id="ability-training-table">
|
||
<thead>
|
||
<tr>
|
||
<th>#</th>
|
||
<th>来源</th>
|
||
<th>题型</th>
|
||
<th>标题</th>
|
||
<th>题目详情</th>
|
||
<th>子题目情况</th>
|
||
<th>结果</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ability-training-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const data = {"code": 200, "data": {"ability_training": [{"detail": "听一段关于问候的日常对话,回答5个相关问题", "question_id": "at_001", "result": "perfect", "source": "Lesson 1", "sub_question_correct": 5, "sub_question_count": 5, "title": "听力理解 - 日常对话", "type": "听力"}, {"detail": "阅读一篇关于数字的小故事,回答6个理解性问题", "question_id": "at_002", "result": "good", "source": "Lesson 2", "sub_question_correct": 5, "sub_question_count": 6, "title": "阅读理解 - 数字故事", "type": "阅读"}, {"audio": "https://audio.valavala.com/at_003.mp3", "detail": "根据图片提示,用英文描述物品的颜色,共4道小题", "question_id": "at_003", "result": "good", "source": "Lesson 3", "sub_question_correct": 3, "sub_question_count": 4, "title": "口语表达 - 描述颜色", "type": "口语"}, {"detail": "根据提示写一篇关于家庭的短文,包含8个要点", "question_id": "at_004", "result": "oops", "source": "Lesson 4", "sub_question_correct": 6, "sub_question_count": 8, "title": "写作练习 - 我的家庭", "type": "写作"}, {"detail": "听各种动物的声音,辨识并写出对应的英文单词", "question_id": "at_005", "result": "good", "source": "Lesson 5", "sub_question_correct": 4, "sub_question_count": 5, "title": "听力理解 - 动物声音", "type": "听力"}, {"detail": "阅读单元主题文章,回答7个综合性理解问题", "question_id": "at_006", "result": "perfect", "source": "单元挑战", "sub_question_correct": 7, "sub_question_count": 7, "title": "综合阅读 - Hello World", "type": "阅读"}, {"audio": "https://audio.valavala.com/at_007.mp3", "detail": "进行完整的自我介绍,包含问候、姓名、年龄、喜欢的颜色、家庭成员、宠物等8个要点", "question_id": "at_007", "result": "oops", "source": "单元挑战", "sub_question_correct": 5, "sub_question_count": 8, "title": "口语表达 - 自我介绍", "type": "口语"}, {"detail": "根据图片提示,写一篇关于教室的短文,描述颜色、数字、物品等", "question_id": "at_008", "result": "good", "source": "单元挑战", "sub_question_correct": 5, "sub_question_count": 6, "title": "写作练习 - 我的教室", "type": "写作"}, {"detail": "听综合对话,涵盖本单元所有知识点,回答5个问题", "question_id": "at_009", "result": "good", "source": "单元挑战", "sub_question_correct": 4, "sub_question_count": 5, "title": "综合听力 - 单元回顾", "type": "听力"}], "data": "hello world", "lessons": [{"completion_time": "2024-01-15T09:25:30Z", "consolidation_completion_time": "2024-01-15T09:40:00Z", "consolidation_entry_time": "2024-01-15T09:26:00Z", "consolidation_exercises": [{"detail": "听录音,从A、B、C三个选项中选择听到的单词", "exercise_id": "ce_001", "is_correct": true, "knowledge": "hello", "type": "单词听选"}, {"detail": "根据中文意思,写出对应的英文单词:你好", "exercise_id": "ce_002", "is_correct": true, "knowledge": "hello", "type": "单词拼写"}, {"detail": "将单词 goodbye 与对应的图片匹配", "exercise_id": "ce_003", "is_correct": false, "knowledge": "goodbye", "type": "图文匹配"}, {"detail": "用正确的单词填空:Hello, my ______ is Tom.", "exercise_id": "ce_004", "is_correct": true, "knowledge": "Hello, my name is [name].", "type": "句型填空"}, {"detail": "初次见面时,应该说:A. Hello B. Goodbye C. Hi", "exercise_id": "ce_005", "is_correct": true, "knowledge": "hello", "type": "情景选择"}, {"detail": "将下列单词排列成正确的句子:name / my / is / Hello", "exercise_id": "ce_006", "is_correct": true, "knowledge": "Hello, my name is [name].", "type": "句子排序"}, {"detail": "听对话,回答问题:他们正在做什么?", "exercise_id": "ce_007", "is_correct": false, "knowledge": "Nice to meet you.", "type": "听力理解"}, {"audio": "https://audio.valavala.com/ce_008.mp3", "detail": "听录音,选择包含 /eɪ/ 音的单词", "exercise_id": "ce_008", "is_correct": true, "knowledge": "name", "type": "发音选择"}, {"detail": "将下列句子翻译成英文:很高兴认识你。", "exercise_id": "ce_009", "is_correct": true, "knowledge": "Nice to meet you.", "type": "翻译练习"}, {"detail": "补全对话:A: Hello! B: ______!", "exercise_id": "ce_010", "is_correct": true, "knowledge": "hello", "type": "对话补全"}, {"detail": "将单词按问候语和非问候语分类", "exercise_id": "ce_011", "is_correct": false, "knowledge": "hello", "type": "单词分类"}, {"detail": "将 Hello 转换为同义词", "exercise_id": "ce_012", "is_correct": true, "knowledge": "hi", "type": "句型转换"}, {"detail": "将单词与对应的中文意思连线", "exercise_id": "ce_013", "is_correct": true, "knowledge": "goodbye", "type": "连线匹配"}, {"detail": "判断句子是否正确:Goodbye 用于告别时说。", "exercise_id": "ce_014", "is_correct": true, "knowledge": "goodbye", "type": "判断正误"}, {"detail": "选择合适的单词填空:______ to meet you. (Nice/Fine/Good)", "exercise_id": "ce_015", "is_correct": true, "knowledge": "Nice to meet you.", "type": "选词填空"}, {"audio": "https://audio.valavala.com/ce_016.mp3", "detail": "听录音,判断是哪个单词", "exercise_id": "ce_016", "is_correct": false, "knowledge": "hi", "type": "语音辨识"}, {"detail": "阅读短文,选择合适的问候语填入空格", "exercise_id": "ce_017", "is_correct": true, "knowledge": "hello", "type": "完形填空"}, {"detail": "完成本课知识的综合测验题", "exercise_id": "ce_018", "is_correct": true, "knowledge": "Nice to meet you.", "type": "综合测验"}], "entry_time": "2024-01-15T09:00:00Z", "interactive_components": [{"audio": "https://audio.valavala.com/ic_001.mp3", "component_id": "ic_001", "detail": "请跟读单词 hello,注意发音准确", "knowledge": "hello", "type": "单词跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_002.mp3", "component_id": "ic_002", "detail": "请跟读单词 hi,注意语调自然", "knowledge": "hi", "type": "单词跟读", "user_result": "good"}, {"component_id": "ic_003", "detail": "听录音,选择正确的单词 goodbye", "knowledge": "goodbye", "type": "单词听选", "user_result": "perfect"}, {"component_id": "ic_004", "detail": "根据发音,拼写出单词 name", "knowledge": "name", "type": "单词拼写", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_005.mp3", "component_id": "ic_005", "detail": "请跟读句型:Hello, my name is [name]", "knowledge": "Hello, my name is [name].", "type": "句型跟读", "user_result": "perfect"}, {"component_id": "ic_006", "detail": "替换名字,完成句子:Hello, my name is ______", "knowledge": "Hello, my name is [name].", "type": "句型替换练习", "user_result": "oops"}, {"audio": "https://audio.valavala.com/ic_007.mp3", "component_id": "ic_007", "detail": "在情景中与角色进行打招呼对话", "knowledge": "Hello, my name is [name].", "type": "情景对话", "user_result": "good"}, {"component_id": "ic_008", "detail": "听录音,选择正确的问候回应", "knowledge": "Nice to meet you.", "type": "听力理解", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_009.mp3", "component_id": "ic_009", "detail": "请说出单词 hi", "knowledge": "hi", "type": "语音识别", "user_result": "good"}, {"component_id": "ic_010", "detail": "将单词与对应的图片进行匹配", "knowledge": "hello", "type": "图文匹配", "user_result": "perfect"}, {"component_id": "ic_011", "detail": "听录音,选择正确的回应", "knowledge": "Nice to meet you.", "type": "句型听选", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_012.mp3", "component_id": "ic_012", "detail": "扮演角色进行自我介绍对话", "knowledge": "Hello, my name is [name].", "type": "角色扮演", "user_result": "perfect"}, {"component_id": "ic_013", "detail": "将单词按正确顺序排列成句子", "knowledge": "Hello, my name is [name].", "type": "单词排序", "user_result": "oops"}, {"audio": "https://audio.valavala.com/ic_014.mp3", "component_id": "ic_014", "detail": "练习疑问句和陈述句的语调区别", "knowledge": "Nice to meet you.", "type": "发音练习", "user_result": "good"}, {"component_id": "ic_015", "detail": "在句子中填入正确的单词", "knowledge": "name", "type": "单词填空", "user_result": "perfect"}, {"component_id": "ic_016", "detail": "根据情景选择最合适的回应", "knowledge": "Nice to meet you.", "type": "情景判断", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_017.mp3", "component_id": "ic_017", "detail": "完成完整的打招呼和自我介绍对话", "knowledge": "Hello, my name is [name].", "type": "综合对话", "user_result": "perfect"}, {"component_id": "ic_018", "detail": "完成本课知识点的综合复习测验", "knowledge": "Nice to meet you.", "type": "复习测验", "user_result": "good"}], "knowledge_points": {"sentence_patterns": [{"example": "Hello, my name is Tom.", "meaning": "你好,我的名字是[名字]。", "pattern": "Hello, my name is [name]."}, {"example": "Nice to meet you too.", "meaning": "很高兴认识你。", "pattern": "Nice to meet you."}], "words": [{"meaning": "你好", "pos": "int.", "word": "hello"}, {"meaning": "嗨", "pos": "int.", "word": "hi"}, {"meaning": "再见", "pos": "int.", "word": "goodbye"}, {"meaning": "名字", "pos": "n.", "word": "name"}]}, "lesson_id": 1, "lesson_name": "Lesson 1: Greetings"}, {"completion_time": "2024-01-16T10:30:15Z", "consolidation_completion_time": "2024-01-16T10:50:00Z", "consolidation_entry_time": "2024-01-16T10:31:00Z", "consolidation_exercises": [{"detail": "听录音,选择听到的数字单词", "exercise_id": "ce_201", "is_correct": true, "knowledge": "one", "type": "单词听选"}, {"detail": "根据中文写出英文数字:三", "exercise_id": "ce_202", "is_correct": true, "knowledge": "three", "type": "单词拼写"}, {"detail": "将数字 ten 与对应的数量图匹配", "exercise_id": "ce_203", "is_correct": true, "knowledge": "ten", "type": "图文匹配"}, {"detail": "填空:How old are you? I am ______.", "exercise_id": "ce_204", "is_correct": false, "knowledge": "How old are you? I am [number].", "type": "句型填空"}, {"detail": "听数字,计算并选择正确答案:2+3=?", "exercise_id": "ce_205", "is_correct": true, "knowledge": "two", "type": "听力计算"}, {"detail": "排列句子:you / How / are / old", "exercise_id": "ce_206", "is_correct": true, "knowledge": "How old are you? I am [number].", "type": "句子排序"}, {"detail": "听对话,回答问题:男孩几岁?", "exercise_id": "ce_207", "is_correct": true, "knowledge": "How old are you? I am [number].", "type": "听力理解"}, {"detail": "将下列数字按从小到大排列", "exercise_id": "ce_208", "is_correct": true, "knowledge": "one", "type": "数字排序"}, {"detail": "翻译:我有三本书。", "exercise_id": "ce_209", "is_correct": false, "knowledge": "I have [number] [noun].", "type": "翻译练习"}, {"detail": "补全对话:A: How old are you? B: ______", "exercise_id": "ce_210", "is_correct": true, "knowledge": "How old are you? I am [number].", "type": "对话补全"}, {"detail": "选择正确的数字单词拼写", "exercise_id": "ce_211", "is_correct": true, "knowledge": "two", "type": "数字识别"}, {"detail": "Mary有2个苹果,Tom有3个,共有几个?", "exercise_id": "ce_212", "is_correct": true, "knowledge": "I have [number] [noun].", "type": "数学应用"}, {"detail": "将数字与英文单词连线", "exercise_id": "ce_213", "is_correct": true, "knowledge": "three", "type": "连线匹配"}, {"detail": "判断:one 表示数字 1。", "exercise_id": "ce_214", "is_correct": true, "knowledge": "one", "type": "判断正误"}, {"detail": "选择正确数字填空:I have ______ (one/two/three) pens.", "exercise_id": "ce_215", "is_correct": true, "knowledge": "I have [number] [noun].", "type": "选词填空"}, {"detail": "根据读音写出数字单词", "exercise_id": "ce_216", "is_correct": false, "knowledge": "ten", "type": "数字书写"}, {"detail": "阅读短文,填入正确的数字单词", "exercise_id": "ce_217", "is_correct": true, "knowledge": "three", "type": "完形填空"}, {"detail": "完成数字单元综合测验", "exercise_id": "ce_218", "is_correct": true, "knowledge": "How old are you? I am [number].", "type": "综合测验"}], "entry_time": "2024-01-16T10:00:00Z", "interactive_components": [{"audio": "https://audio.valavala.com/ic_201.mp3", "component_id": "ic_201", "detail": "请跟读数字 one", "knowledge": "one", "type": "单词跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_202.mp3", "component_id": "ic_202", "detail": "请跟读数字 two", "knowledge": "two", "type": "单词跟读", "user_result": "perfect"}, {"component_id": "ic_203", "detail": "听录音,选择正确的数字 three", "knowledge": "three", "type": "单词听选", "user_result": "good"}, {"component_id": "ic_204", "detail": "根据发音,拼写出数字 ten", "knowledge": "ten", "type": "单词拼写", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_205.mp3", "component_id": "ic_205", "detail": "请跟读句型:How old are you?", "knowledge": "How old are you? I am [number].", "type": "句型跟读", "user_result": "good"}, {"component_id": "ic_206", "detail": "将数字按从小到大排序", "knowledge": "one", "type": "数字排序练习", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_207.mp3", "component_id": "ic_207", "detail": "在情景中询问和回答年龄", "knowledge": "How old are you? I am [number].", "type": "情景对话", "user_result": "good"}, {"component_id": "ic_208", "detail": "听录音,写出听到的数字", "knowledge": "three", "type": "听力理解", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_209.mp3", "component_id": "ic_209", "detail": "请说出数字 three", "knowledge": "three", "type": "语音识别", "user_result": "good"}, {"component_id": "ic_210", "detail": "将数字单词与对应的数量匹配", "knowledge": "ten", "type": "图文匹配", "user_result": "perfect"}, {"component_id": "ic_211", "detail": "计算并写出英文结果:1+2=?", "knowledge": "three", "type": "数学计算", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_212.mp3", "component_id": "ic_212", "detail": "扮演角色介绍自己的年龄", "knowledge": "How old are you? I am [number].", "type": "角色扮演", "user_result": "perfect"}, {"component_id": "ic_213", "detail": "按顺序接出下一个数字单词", "knowledge": "one", "type": "数字接龙", "user_result": "oops"}, {"component_id": "ic_214", "detail": "听写数字单词 one 到 ten", "knowledge": "ten", "type": "听写练习", "user_result": "good"}, {"component_id": "ic_215", "detail": "用正确的数字填空:I have ______ books.", "knowledge": "I have [number] [noun].", "type": "句型填空", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_216.mp3", "component_id": "ic_216", "detail": "看到数字快速说出英文", "knowledge": "two", "type": "快速反应", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_217.mp3", "component_id": "ic_217", "detail": "完成关于数字的完整对话", "knowledge": "How old are you? I am [number].", "type": "综合对话", "user_result": "perfect"}, {"component_id": "ic_218", "detail": "完成数字知识点的综合复习", "knowledge": "I have [number] [noun].", "type": "复习测验", "user_result": "good"}], "knowledge_points": {"sentence_patterns": [{"example": "How old are you? I am five.", "meaning": "你几岁了?我[数字]岁。", "pattern": "How old are you? I am [number]."}, {"example": "I have three books.", "meaning": "我有[数字]个[名词]。", "pattern": "I have [number] [noun]."}], "words": [{"meaning": "一", "pos": "num.", "word": "one"}, {"meaning": "二", "pos": "num.", "word": "two"}, {"meaning": "三", "pos": "num.", "word": "three"}, {"meaning": "十", "pos": "num.", "word": "ten"}]}, "lesson_id": 2, "lesson_name": "Lesson 2: Numbers"}, {"completion_time": "2024-01-17T09:45:20Z", "consolidation_completion_time": "2024-01-17T10:05:00Z", "consolidation_entry_time": "2024-01-17T09:46:00Z", "consolidation_exercises": [{"detail": "听录音,选择听到的颜色单词", "exercise_id": "ce_301", "is_correct": true, "knowledge": "red", "type": "单词听选"}, {"detail": "根据中文写出颜色英文:红色", "exercise_id": "ce_302", "is_correct": true, "knowledge": "red", "type": "单词拼写"}, {"detail": "将 green 与绿色图片匹配", "exercise_id": "ce_303", "is_correct": true, "knowledge": "green", "type": "图文匹配"}, {"detail": "填空:What color is it? It is ______.", "exercise_id": "ce_304", "is_correct": true, "knowledge": "What color is it? It is [color].", "type": "句型填空"}, {"detail": "选择天空的颜色:A. blue B. red C. green", "exercise_id": "ce_305", "is_correct": true, "knowledge": "blue", "type": "颜色识别"}, {"detail": "排列句子:is / it / What / color", "exercise_id": "ce_306", "is_correct": true, "knowledge": "What color is it? It is [color].", "type": "句子排序"}, {"detail": "听描述,选择正确的物品颜色", "exercise_id": "ce_307", "is_correct": false, "knowledge": "yellow", "type": "听力理解"}, {"detail": "红色加黄色变成什么颜色?", "exercise_id": "ce_308", "is_correct": true, "knowledge": "red", "type": "颜色混合"}, {"detail": "翻译:我喜欢蓝色。", "exercise_id": "ce_309", "is_correct": true, "knowledge": "I like [color].", "type": "翻译练习"}, {"detail": "补全对话:A: What color is it? B: ______", "exercise_id": "ce_310", "is_correct": true, "knowledge": "What color is it? It is [color].", "type": "对话补全"}, {"detail": "将红色物品圈出来", "exercise_id": "ce_311", "is_correct": true, "knowledge": "red", "type": "物品分类"}, {"detail": "苹果通常是什么颜色?", "exercise_id": "ce_312", "is_correct": true, "knowledge": "red", "type": "颜色联想"}, {"detail": "将颜色与对应物品连线", "exercise_id": "ce_313", "is_correct": true, "knowledge": "green", "type": "连线匹配"}, {"detail": "判断:yellow 是黄色。", "exercise_id": "ce_314", "is_correct": true, "knowledge": "yellow", "type": "判断正误"}, {"detail": "The sky is ______ (red/blue/green).", "exercise_id": "ce_315", "is_correct": true, "knowledge": "blue", "type": "选词填空"}, {"detail": "根据读音写出颜色单词", "exercise_id": "ce_316", "is_correct": false, "knowledge": "yellow", "type": "颜色书写"}, {"detail": "阅读短文,填入正确的颜色单词", "exercise_id": "ce_317", "is_correct": true, "knowledge": "green", "type": "完形填空"}, {"detail": "完成颜色单元综合测验", "exercise_id": "ce_318", "is_correct": true, "knowledge": "I like [color].", "type": "综合测验"}], "entry_time": "2024-01-17T09:15:00Z", "interactive_components": [{"audio": "https://audio.valavala.com/ic_301.mp3", "component_id": "ic_301", "detail": "请跟读颜色单词 red", "knowledge": "red", "type": "单词跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_302.mp3", "component_id": "ic_302", "detail": "请跟读颜色单词 blue", "knowledge": "blue", "type": "单词跟读", "user_result": "good"}, {"component_id": "ic_303", "detail": "听录音,选择正确的颜色单词", "knowledge": "green", "type": "单词听选", "user_result": "perfect"}, {"component_id": "ic_304", "detail": "根据发音,拼写出颜色单词 yellow", "knowledge": "yellow", "type": "单词拼写", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_305.mp3", "component_id": "ic_305", "detail": "请跟读句型:What color is it?", "knowledge": "What color is it? It is [color].", "type": "句型跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_306.mp3", "component_id": "ic_306", "detail": "看图片,说出颜色名称", "knowledge": "red", "type": "颜色识别练习", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_307.mp3", "component_id": "ic_307", "detail": "在情景中询问物品颜色", "knowledge": "What color is it? It is [color].", "type": "情景对话", "user_result": "good"}, {"component_id": "ic_308", "detail": "听录音,选择听到的颜色", "knowledge": "green", "type": "听力理解", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_309.mp3", "component_id": "ic_309", "detail": "请说出颜色 green", "knowledge": "green", "type": "语音识别", "user_result": "oops"}, {"component_id": "ic_310", "detail": "将颜色单词与对应颜色块匹配", "knowledge": "yellow", "type": "图文匹配", "user_result": "perfect"}, {"component_id": "ic_311", "detail": "蓝色加黄色变成什么颜色?", "knowledge": "green", "type": "颜色混合", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_312.mp3", "component_id": "ic_312", "detail": "扮演角色描述周围物品颜色", "knowledge": "What color is it? It is [color].", "type": "角色扮演", "user_result": "perfect"}, {"component_id": "ic_313", "detail": "将物品按颜色分类", "knowledge": "red", "type": "颜色分类", "user_result": "good"}, {"component_id": "ic_314", "detail": "听指令给图片涂上正确的颜色", "knowledge": "blue", "type": "涂色游戏", "user_result": "perfect"}, {"component_id": "ic_315", "detail": "用颜色填空:I like ______.", "knowledge": "I like [color].", "type": "句型填空", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_316.mp3", "component_id": "ic_316", "detail": "看到颜色快速说出英文", "knowledge": "yellow", "type": "快速反应", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_317.mp3", "component_id": "ic_317", "detail": "完成关于颜色的完整对话", "knowledge": "What color is it? It is [color].", "type": "综合对话", "user_result": "good"}, {"component_id": "ic_318", "detail": "完成颜色知识点的综合复习", "knowledge": "I like [color].", "type": "复习测验", "user_result": "perfect"}], "knowledge_points": {"sentence_patterns": [{"example": "What color is it? It is red.", "meaning": "这是什么颜色?这是[颜色]。", "pattern": "What color is it? It is [color]."}, {"example": "I like blue.", "meaning": "我喜欢[颜色]。", "pattern": "I like [color]."}], "words": [{"meaning": "红色", "pos": "n./adj.", "word": "red"}, {"meaning": "蓝色", "pos": "n./adj.", "word": "blue"}, {"meaning": "绿色", "pos": "n./adj.", "word": "green"}, {"meaning": "黄色", "pos": "n./adj.", "word": "yellow"}]}, "lesson_id": 3, "lesson_name": "Lesson 3: Colors"}, {"completion_time": "2024-01-18T14:35:10Z", "consolidation_completion_time": "2024-01-18T14:55:00Z", "consolidation_entry_time": "2024-01-18T14:36:00Z", "consolidation_exercises": [{"detail": "听录音,选择听到的家庭成员单词", "exercise_id": "ce_401", "is_correct": true, "knowledge": "father", "type": "单词听选"}, {"detail": "根据中文写出英文:爸爸", "exercise_id": "ce_402", "is_correct": true, "knowledge": "father", "type": "单词拼写"}, {"detail": "将 mother 与妈妈图片匹配", "exercise_id": "ce_403", "is_correct": true, "knowledge": "mother", "type": "图文匹配"}, {"detail": "填空:This is my ______ (father/mother/brother).", "exercise_id": "ce_404", "is_correct": true, "knowledge": "This is my [family member].", "type": "句型填空"}, {"detail": "Tom是爸爸的son,Tom是爸爸的什么人?", "exercise_id": "ce_405", "is_correct": false, "knowledge": "brother", "type": "关系识别"}, {"detail": "排列句子:is / This / my / mother", "exercise_id": "ce_406", "is_correct": true, "knowledge": "This is my [family member].", "type": "句子排序"}, {"detail": "听对话,回答问题:他们是什么关系?", "exercise_id": "ce_407", "is_correct": true, "knowledge": "Who is he/she? He/She is my [family member].", "type": "听力理解"}, {"detail": "爸爸的爸爸叫什么?", "exercise_id": "ce_408", "is_correct": true, "knowledge": "father", "type": "家庭关系"}, {"detail": "翻译:这是我的姐姐。", "exercise_id": "ce_409", "is_correct": true, "knowledge": "sister", "type": "翻译练习"}, {"detail": "补全对话:A: Who is he? B: ______", "exercise_id": "ce_410", "is_correct": true, "knowledge": "Who is he/she? He/She is my [family member].", "type": "对话补全"}, {"detail": "根据描述选择正确的家庭成员", "exercise_id": "ce_411", "is_correct": true, "knowledge": "brother", "type": "家庭识别"}, {"detail": "将人物与正确的称呼配对", "exercise_id": "ce_412", "is_correct": true, "knowledge": "sister", "type": "角色配对"}, {"detail": "将家庭成员与中文意思连线", "exercise_id": "ce_413", "is_correct": true, "knowledge": "mother", "type": "连线匹配"}, {"detail": "判断:brother 可以是哥哥也可以是弟弟。", "exercise_id": "ce_414", "is_correct": true, "knowledge": "brother", "type": "判断正误"}, {"detail": "She is my ______ (father/mother/sister).", "exercise_id": "ce_415", "is_correct": true, "knowledge": "sister", "type": "选词填空"}, {"detail": "根据读音写出家庭成员单词", "exercise_id": "ce_416", "is_correct": false, "knowledge": "mother", "type": "单词书写"}, {"detail": "阅读短文,填入正确的家庭成员单词", "exercise_id": "ce_417", "is_correct": true, "knowledge": "father", "type": "完形填空"}, {"detail": "完成家庭单元综合测验", "exercise_id": "ce_418", "is_correct": true, "knowledge": "This is my [family member].", "type": "综合测验"}], "entry_time": "2024-01-18T14:00:00Z", "interactive_components": [{"audio": "https://audio.valavala.com/ic_401.mp3", "component_id": "ic_401", "detail": "请跟读家庭成员单词 father", "knowledge": "father", "type": "单词跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_402.mp3", "component_id": "ic_402", "detail": "请跟读家庭成员单词 mother", "knowledge": "mother", "type": "单词跟读", "user_result": "perfect"}, {"component_id": "ic_403", "detail": "听录音,选择正确的家庭成员单词", "knowledge": "brother", "type": "单词听选", "user_result": "good"}, {"component_id": "ic_404", "detail": "根据发音,拼写出 sister", "knowledge": "sister", "type": "单词拼写", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_405.mp3", "component_id": "ic_405", "detail": "请跟读句型:This is my father.", "knowledge": "This is my [family member].", "type": "句型跟读", "user_result": "good"}, {"component_id": "ic_406", "detail": "将单词与对应的家庭成员图片配对", "knowledge": "father", "type": "家庭成员配对", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_407.mp3", "component_id": "ic_407", "detail": "在情景中介绍自己的家庭成员", "knowledge": "This is my [family member].", "type": "情景对话", "user_result": "good"}, {"component_id": "ic_408", "detail": "听录音,指出说话者在说谁", "knowledge": "Who is he/she? He/She is my [family member].", "type": "听力理解", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_409.mp3", "component_id": "ic_409", "detail": "请说出家庭成员 mother", "knowledge": "mother", "type": "语音识别", "user_result": "good"}, {"component_id": "ic_410", "detail": "根据描述绘制家庭树", "knowledge": "father", "type": "家庭树绘制", "user_result": "oops"}, {"audio": "https://audio.valavala.com/ic_411.mp3", "component_id": "ic_411", "detail": "练习问句:Who is he/she?", "knowledge": "Who is he/she? He/She is my [family member].", "type": "问答练习", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_412.mp3", "component_id": "ic_412", "detail": "扮演角色向朋友介绍家人", "knowledge": "This is my [family member].", "type": "角色扮演", "user_result": "perfect"}, {"component_id": "ic_413", "detail": "理解家庭成员之间的关系", "knowledge": "brother", "type": "家庭成员关系", "user_result": "good"}, {"component_id": "ic_414", "detail": "听指令指出对应的家人图片", "knowledge": "sister", "type": "听指令指认", "user_result": "perfect"}, {"component_id": "ic_415", "detail": "填空:Who is she? ______ is my mother.", "knowledge": "Who is he/she? He/She is my [family member].", "type": "句型填空", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_416.mp3", "component_id": "ic_416", "detail": "看家庭相册照片,描述家人", "knowledge": "This is my [family member].", "type": "家庭相册描述", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_417.mp3", "component_id": "ic_417", "detail": "完成关于家庭的完整对话", "knowledge": "This is my [family member].", "type": "综合对话", "user_result": "perfect"}, {"component_id": "ic_418", "detail": "完成家庭知识点的综合复习", "knowledge": "Who is he/she? He/She is my [family member].", "type": "复习测验", "user_result": "good"}], "knowledge_points": {"sentence_patterns": [{"example": "This is my father.", "meaning": "这是我的[家庭成员]。", "pattern": "This is my [family member]."}, {"example": "Who is he? He is my brother.", "meaning": "他/她是谁?他/她是我的[家庭成员]。", "pattern": "Who is he/she? He/She is my [family member]."}], "words": [{"meaning": "爸爸", "pos": "n.", "word": "father"}, {"meaning": "妈妈", "pos": "n.", "word": "mother"}, {"meaning": "兄弟", "pos": "n.", "word": "brother"}, {"meaning": "姐妹", "pos": "n.", "word": "sister"}]}, "lesson_id": 4, "lesson_name": "Lesson 4: Family"}, {"completion_time": "2024-01-19T10:05:45Z", "consolidation_completion_time": "2024-01-19T10:25:00Z", "consolidation_entry_time": "2024-01-19T10:06:00Z", "consolidation_exercises": [{"detail": "听录音,选择听到的动物单词", "exercise_id": "ce_501", "is_correct": true, "knowledge": "cat", "type": "单词听选"}, {"detail": "根据中文写出英文:猫", "exercise_id": "ce_502", "is_correct": true, "knowledge": "cat", "type": "单词拼写"}, {"detail": "将 dog 与狗的图片匹配", "exercise_id": "ce_503", "is_correct": true, "knowledge": "dog", "type": "图文匹配"}, {"detail": "填空:It is a ______ (cat/dog/bird).", "exercise_id": "ce_504", "is_correct": true, "knowledge": "It is a [animal].", "type": "句型填空"}, {"detail": "看局部图,猜是什么动物?", "exercise_id": "ce_505", "is_correct": false, "knowledge": "bird", "type": "动物识别"}, {"detail": "排列句子:is / It / a / cat", "exercise_id": "ce_506", "is_correct": true, "knowledge": "It is a [animal].", "type": "句子排序"}, {"detail": "听描述,选择正确的动物", "exercise_id": "ce_507", "is_correct": true, "knowledge": "dog", "type": "听力理解"}, {"detail": "选出会飞的动物", "exercise_id": "ce_508", "is_correct": true, "knowledge": "bird", "type": "动物分类"}, {"detail": "翻译:我喜欢狗。", "exercise_id": "ce_509", "is_correct": true, "knowledge": "I like [animal]s.", "type": "翻译练习"}, {"detail": "补全对话:A: What's this? B: ______", "exercise_id": "ce_510", "is_correct": true, "knowledge": "It is a [animal].", "type": "对话补全"}, {"detail": "鱼生活在哪里?", "exercise_id": "ce_511", "is_correct": true, "knowledge": "fish", "type": "动物习性"}, {"audio": "https://audio.valavala.com/ce_512.mp3", "detail": "听叫声,选择动物", "exercise_id": "ce_512", "is_correct": true, "knowledge": "cat", "type": "声音辨识"}, {"detail": "将动物与中文意思连线", "exercise_id": "ce_513", "is_correct": true, "knowledge": "fish", "type": "连线匹配"}, {"detail": "判断:bird 会飞。", "exercise_id": "ce_514", "is_correct": true, "knowledge": "bird", "type": "判断正误"}, {"detail": "I like ______ (cat/cats/fishs).", "exercise_id": "ce_515", "is_correct": false, "knowledge": "I like [animal]s.", "type": "选词填空"}, {"detail": "根据读音写出动物单词", "exercise_id": "ce_516", "is_correct": true, "knowledge": "dog", "type": "单词书写"}, {"detail": "阅读短文,填入正确的动物单词", "exercise_id": "ce_517", "is_correct": true, "knowledge": "cat", "type": "完形填空"}, {"detail": "完成动物单元综合测验", "exercise_id": "ce_518", "is_correct": true, "knowledge": "I like [animal]s.", "type": "综合测验"}], "entry_time": "2024-01-19T09:30:00Z", "interactive_components": [{"audio": "https://audio.valavala.com/ic_501.mp3", "component_id": "ic_501", "detail": "请跟读动物单词 cat,注意短元音", "knowledge": "cat", "type": "单词跟读", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_502.mp3", "component_id": "ic_502", "detail": "请跟读动物单词 dog", "knowledge": "dog", "type": "单词跟读", "user_result": "good"}, {"component_id": "ic_503", "detail": "听录音,选择正确的动物单词", "knowledge": "bird", "type": "单词听选", "user_result": "perfect"}, {"component_id": "ic_504", "detail": "根据发音,拼写出 fish", "knowledge": "fish", "type": "单词拼写", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_505.mp3", "component_id": "ic_505", "detail": "请跟读句型:It is a cat.", "knowledge": "It is a [animal].", "type": "句型跟读", "user_result": "perfect"}, {"component_id": "ic_506", "detail": "听动物叫声,选择正确的动物", "knowledge": "cat", "type": "动物声音辨识", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_507.mp3", "component_id": "ic_507", "detail": "在情景中谈论自己喜欢的动物", "knowledge": "I like [animal]s.", "type": "情景对话", "user_result": "oops"}, {"component_id": "ic_508", "detail": "听录音,描述动物特征", "knowledge": "It is a [animal].", "type": "听力理解", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_509.mp3", "component_id": "ic_509", "detail": "请说出动物 bird", "knowledge": "bird", "type": "语音识别", "user_result": "good"}, {"component_id": "ic_510", "detail": "将动物单词与对应图片匹配", "knowledge": "dog", "type": "图文匹配", "user_result": "perfect"}, {"component_id": "ic_511", "detail": "将动物分为天上飞的和地上跑的", "knowledge": "bird", "type": "动物分类", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_512.mp3", "component_id": "ic_512", "detail": "扮演角色在动物园谈论动物", "knowledge": "It is a [animal].", "type": "角色扮演", "user_result": "perfect"}, {"component_id": "ic_513", "detail": "将动物与其习性特点配对", "knowledge": "fish", "type": "动物习性配对", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_514.mp3", "component_id": "ic_514", "detail": "听指令模仿动物的叫声和动作", "knowledge": "cat", "type": "听指令模仿", "user_result": "perfect"}, {"component_id": "ic_515", "detail": "用动物填空:I like ______.", "knowledge": "I like [animal]s.", "type": "句型填空", "user_result": "good"}, {"audio": "https://audio.valavala.com/ic_516.mp3", "component_id": "ic_516", "detail": "看到动物图片快速说出英文", "knowledge": "dog", "type": "快速反应", "user_result": "perfect"}, {"audio": "https://audio.valavala.com/ic_517.mp3", "component_id": "ic_517", "detail": "完成关于动物的完整对话", "knowledge": "I like [animal]s.", "type": "综合对话", "user_result": "good"}, {"component_id": "ic_518", "detail": "完成动物知识点的综合复习", "knowledge": "It is a [animal].", "type": "复习测验", "user_result": "perfect"}], "knowledge_points": {"sentence_patterns": [{"example": "It is a cat.", "meaning": "这是一只[动物]。", "pattern": "It is a [animal]."}, {"example": "I like dogs.", "meaning": "我喜欢[动物]。", "pattern": "I like [animal]s."}], "words": [{"meaning": "猫", "pos": "n.", "word": "cat"}, {"meaning": "狗", "pos": "n.", "word": "dog"}, {"meaning": "鸟", "pos": "n.", "word": "bird"}, {"meaning": "鱼", "pos": "n.", "word": "fish"}]}, "lesson_id": 5, "lesson_name": "Lesson 5: Animals"}], "level": 1, "role_id": 88888, "summary": {"completed_lessons": 1, "mastery_rate": 0.85, "study_duration_minutes": 25, "total_consolidation_exercises": 18, "total_interactive_components": 18, "total_lessons": 5}, "unit": 1, "unit_name": "Unit 1: Hello World"}, "msg": "", "traceID": "f951907fbe5062f2c4f1ce1dd8dd5def"};
|
||
|
||
// 兼容:data可能直接就是lessons数组,也可能有外层包装
|
||
const lessons = data.lessons || data.data?.lessons || (Array.isArray(data) ? data : []);
|
||
const summary = data.summary || data.data?.summary || null;
|
||
|
||
// ==================== 总览统计 ====================
|
||
const statsGrid = document.getElementById('stats-grid');
|
||
const totalLessons = lessons.length;
|
||
let totalInteractive = 0, totalExercises = 0;
|
||
let totalStudyDuration = 0; // 单元学习时长(分钟)
|
||
let unitStartTime = null, unitEndTime = null;
|
||
|
||
lessons.forEach(lesson => {
|
||
const ics = lesson.interactive_components || lesson.interactiveComponents || [];
|
||
const ces = lesson.consolidation_exercises || lesson.consolidationExercises || [];
|
||
totalInteractive += ics.length;
|
||
totalExercises += ces.length;
|
||
|
||
// 计算每个lesson的学习时长
|
||
const entryTime = lesson.entry_time || lesson.entryTime;
|
||
const completionTime = lesson.completion_time || lesson.completionTime;
|
||
const consolidationEntry = lesson.consolidation_entry_time || lesson.consolidationEntryTime;
|
||
const consolidationCompletion = lesson.consolidation_completion_time || lesson.consolidationCompletionTime;
|
||
|
||
if (entryTime && completionTime) {
|
||
const lessonDuration = (new Date(completionTime) - new Date(entryTime)) / (1000 * 60);
|
||
if (lessonDuration > 0) totalStudyDuration += lessonDuration;
|
||
}
|
||
if (consolidationEntry && consolidationCompletion) {
|
||
const consolidationDuration = (new Date(consolidationCompletion) - new Date(consolidationEntry)) / (1000 * 60);
|
||
if (consolidationDuration > 0) totalStudyDuration += consolidationDuration;
|
||
}
|
||
|
||
// 记录单元开始和结束时间
|
||
if (entryTime) {
|
||
const entryDate = new Date(entryTime);
|
||
if (!unitStartTime || entryDate < unitStartTime) unitStartTime = entryDate;
|
||
}
|
||
if (consolidationCompletion) {
|
||
const completionDate = new Date(consolidationCompletion);
|
||
if (!unitEndTime || completionDate > unitEndTime) unitEndTime = completionDate;
|
||
}
|
||
});
|
||
|
||
// 计算单元长度(从第1个lesson进入到第5个lesson巩固完成)
|
||
let unitLengthStr = '-';
|
||
if (unitStartTime && unitEndTime) {
|
||
const unitLengthMs = unitEndTime - unitStartTime;
|
||
const unitLengthMinutes = Math.round(unitLengthMs / (1000 * 60));
|
||
const days = Math.floor(unitLengthMinutes / (24 * 60));
|
||
const hours = Math.floor((unitLengthMinutes % (24 * 60)) / 60);
|
||
const minutes = unitLengthMinutes % 60;
|
||
if (days > 0) {
|
||
unitLengthStr = `${days}天${hours}小时${minutes}分钟`;
|
||
} else if (hours > 0) {
|
||
unitLengthStr = `${hours}小时${minutes}分钟`;
|
||
} else {
|
||
unitLengthStr = `${minutes}分钟`;
|
||
}
|
||
}
|
||
|
||
// 格式化学习时长
|
||
let studyDurationStr = '-';
|
||
if (totalStudyDuration > 0) {
|
||
const studyHours = Math.floor(totalStudyDuration / 60);
|
||
const studyMinutes = Math.round(totalStudyDuration % 60);
|
||
if (studyHours > 0) {
|
||
studyDurationStr = `${studyHours}小时${studyMinutes}分钟`;
|
||
} else {
|
||
studyDurationStr = `${studyMinutes}分钟`;
|
||
}
|
||
}
|
||
|
||
const statsItems = [
|
||
{ label: '单元学习时长', value: studyDurationStr, cls: 'purple' },
|
||
{ label: '总互动次数', value: totalInteractive, cls: 'blue' },
|
||
{ label: '总练习题数', value: totalExercises, cls: 'green' },
|
||
{ label: '单元长度', value: unitLengthStr, cls: 'orange' }
|
||
];
|
||
statsItems.forEach(item => {
|
||
const div = document.createElement('div');
|
||
div.className = 'stat-item';
|
||
div.innerHTML = `<div class="label">${item.label}</div><div class="value ${item.cls}">${item.value}</div>`;
|
||
statsGrid.appendChild(div);
|
||
});
|
||
|
||
// ==================== 互动组件柱状图(按课程,三段堆叠) ====================
|
||
const interactiveChart = echarts.init(document.getElementById('interactive-chart'));
|
||
const lessonLabels = lessons.map((l, i) => l.lesson_name || l.lessonName || `Lesson ${i + 1}`);
|
||
const perfectCounts = [];
|
||
const goodCounts = [];
|
||
const oopsCounts = [];
|
||
|
||
lessons.forEach(lesson => {
|
||
const ics = lesson.interactive_components || lesson.interactiveComponents || [];
|
||
let perfect = 0, good = 0, oops = 0;
|
||
ics.forEach(ic => {
|
||
const r = (ic.user_result || ic.userResult || '').toLowerCase();
|
||
if (r === 'perfect') perfect++;
|
||
else if (r === 'good') good++;
|
||
else if (r === 'oops') oops++;
|
||
});
|
||
perfectCounts.push(perfect);
|
||
goodCounts.push(good);
|
||
oopsCounts.push(oops);
|
||
});
|
||
|
||
interactiveChart.setOption({
|
||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||
legend: { bottom: 10, data: ['Perfect', 'Good', 'Oops'] },
|
||
grid: { left: '3%', right: '4%', bottom: '15%', top: '5%', containLabel: true },
|
||
xAxis: { type: 'category', data: lessonLabels, axisLabel: { rotate: 20, fontSize: 12 } },
|
||
yAxis: { type: 'value' },
|
||
color: ['#52c41a', '#1890ff', '#fa541c'],
|
||
series: [
|
||
{ name: 'Perfect', type: 'bar', stack: 'total', data: perfectCounts, itemStyle: { borderRadius: [0, 0, 4, 4] } },
|
||
{ name: 'Good', type: 'bar', stack: 'total', data: goodCounts, itemStyle: { borderRadius: [0, 0, 0, 0] } },
|
||
{ name: 'Oops', type: 'bar', stack: 'total', data: oopsCounts, itemStyle: { borderRadius: [4, 4, 0, 0] } }
|
||
]
|
||
});
|
||
|
||
// ==================== 巩固练习柱状图(按课程,两段堆叠) ====================
|
||
const exerciseChart = echarts.init(document.getElementById('exercise-chart'));
|
||
const correctCounts = [];
|
||
const wrongCounts = [];
|
||
|
||
lessons.forEach(lesson => {
|
||
const ces = lesson.consolidation_exercises || lesson.consolidationExercises || [];
|
||
let correct = 0, wrong = 0;
|
||
ces.forEach(ce => {
|
||
if (ce.is_correct === true || ce.isCorrect === true) correct++;
|
||
else wrong++;
|
||
});
|
||
correctCounts.push(correct);
|
||
wrongCounts.push(wrong);
|
||
});
|
||
|
||
exerciseChart.setOption({
|
||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||
legend: { bottom: 10, data: ['正确', '错误'] },
|
||
grid: { left: '3%', right: '4%', bottom: '15%', top: '5%', containLabel: true },
|
||
xAxis: { type: 'category', data: lessonLabels, axisLabel: { rotate: 20, fontSize: 12 } },
|
||
yAxis: { type: 'value' },
|
||
color: ['#52c41a', '#f5222d'],
|
||
series: [
|
||
{ name: '正确', type: 'bar', stack: 'total', data: correctCounts, itemStyle: { borderRadius: [0, 0, 4, 4] } },
|
||
{ name: '错误', type: 'bar', stack: 'total', data: wrongCounts, itemStyle: { borderRadius: [4, 4, 0, 0] } }
|
||
]
|
||
});
|
||
|
||
// ==================== 能力训练饼图 ====================
|
||
const abilityTraining = data.ability_training || data.abilityTraining || [];
|
||
let perfectCount = 0, goodCount = 0, oopsCount = 0;
|
||
abilityTraining.forEach(at => {
|
||
const result = (at.result || '').toLowerCase();
|
||
if (result === 'perfect') perfectCount++;
|
||
else if (result === 'good') goodCount++;
|
||
else if (result === 'oops') oopsCount++;
|
||
});
|
||
|
||
const abilityChart = echarts.init(document.getElementById('ability-chart'));
|
||
abilityChart.setOption({
|
||
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
|
||
legend: { bottom: 10, data: ['Perfect', 'Good', 'Oops'] },
|
||
color: ['#52c41a', '#1890ff', '#fa541c'],
|
||
series: [{
|
||
name: '能力训练结果',
|
||
type: 'pie',
|
||
radius: ['40%', '70%'],
|
||
center: ['50%', '45%'],
|
||
avoidLabelOverlap: false,
|
||
itemStyle: { borderRadius: 8, borderColor: '#fff', borderWidth: 2 },
|
||
label: { show: true, formatter: '{b}: {c}' },
|
||
data: [
|
||
{ value: perfectCount, name: 'Perfect' },
|
||
{ value: goodCount, name: 'Good' },
|
||
{ value: oopsCount, name: 'Oops' }
|
||
]
|
||
}]
|
||
});
|
||
const navContainer = document.getElementById('lesson-nav');
|
||
const detailContainer = document.getElementById('lesson-details');
|
||
|
||
lessons.forEach((lesson, idx) => {
|
||
// 大方块导航卡片
|
||
const card = document.createElement('div');
|
||
card.className = 'lesson-card' + (idx === 0 ? ' active' : '');
|
||
card.onclick = () => switchTab(idx);
|
||
|
||
const entryTime = lesson.entry_time || lesson.entryTime || '-';
|
||
const completionTime = lesson.completion_time || lesson.completionTime || '-';
|
||
const lessonName = lesson.lesson_name || lesson.lessonName || `Lesson ${idx + 1}`;
|
||
|
||
// 计算统计数据
|
||
const icsForStats = lesson.interactive_components || lesson.interactiveComponents || [];
|
||
const cesForStats = lesson.consolidation_exercises || lesson.consolidationExercises || [];
|
||
let oopsCount = 0;
|
||
icsForStats.forEach(ic => {
|
||
const r = (ic.user_result || ic.userResult || '').toLowerCase();
|
||
if (r === 'oops') oopsCount++;
|
||
});
|
||
const oopsRate = icsForStats.length > 0 ? Math.round(oopsCount / icsForStats.length * 100) : 0;
|
||
|
||
let wrongCount = 0;
|
||
cesForStats.forEach(ce => {
|
||
if (ce.is_correct !== true && ce.isCorrect !== true) wrongCount++;
|
||
});
|
||
const wrongRate = cesForStats.length > 0 ? Math.round(wrongCount / cesForStats.length * 100) : 0;
|
||
|
||
card.innerHTML = `
|
||
<div class="lesson-title">${lessonName}</div>
|
||
<div class="lesson-time">
|
||
<div><span class="time-label">进入:</span>${formatTime(entryTime)}</div>
|
||
<div><span class="time-label">完成:</span>${formatTime(completionTime)}</div>
|
||
</div>
|
||
<div class="lesson-stats">
|
||
<div class="stat">
|
||
<span class="stat-label">Oops率</span>
|
||
<span class="stat-value oops">${oopsRate}%</span>
|
||
</div>
|
||
<div class="stat">
|
||
<span class="stat-label">错误率</span>
|
||
<span class="stat-value wrong">${wrongRate}%</span>
|
||
</div>
|
||
</div>
|
||
`;
|
||
navContainer.appendChild(card);
|
||
|
||
// 详情区域
|
||
const detail = document.createElement('div');
|
||
detail.className = 'lesson-detail' + (idx === 0 ? ' active' : '');
|
||
detail.id = `lesson-${idx}`;
|
||
|
||
const kp = lesson.knowledge_points || lesson.knowledgePoints || {};
|
||
const words = kp.words || [];
|
||
const patterns = kp.sentence_patterns || kp.sentencePatterns || [];
|
||
const ics = lesson.interactive_components || lesson.interactiveComponents || [];
|
||
const ces = lesson.consolidation_exercises || lesson.consolidationExercises || [];
|
||
|
||
let html = `
|
||
<div class="knowledge-section">
|
||
<h3>📗 单词 (${words.length}个)</h3>
|
||
<div class="word-list">
|
||
${words.map(w => `<div class="word-tag"><span class="en">${w.word}</span><span class="cn">${w.meaning}</span><span class="pos">${w.pos || ''}</span></div>`).join('')}
|
||
</div>
|
||
</div>
|
||
<div class="knowledge-section">
|
||
<h3>📘 句型 (${patterns.length}个)</h3>
|
||
<div class="pattern-list">
|
||
${patterns.map(p => `<div class="pattern-tag"><span class="en">${p.pattern}</span><span class="cn">${p.meaning}</span></div>`).join('')}
|
||
</div>
|
||
</div>
|
||
<div class="knowledge-section">
|
||
<h3>🎯 互动组件 (${ics.length}个)</h3>
|
||
<table>
|
||
<thead><tr><th>#</th><th>题型</th><th>知识点</th><th>详情</th><th>结果</th></tr></thead>
|
||
<tbody>
|
||
${ics.map((ic, i) => {
|
||
const result = (ic.user_result || ic.userResult || '').toLowerCase();
|
||
const cls = result === 'perfect' ? 'perfect' : result === 'good' ? 'good' : 'oops';
|
||
const kpText = ic.knowledge || '-';
|
||
const audioBtn = ic.audio ? `<span class="audio-btn" onclick="playAudio('${ic.audio}', this)" title="播放录音">🔊</span>` : '';
|
||
return `<tr><td>${i + 1}</td><td>${ic.type}</td><td>${kpText}</td><td>${ic.detail}</td><td><span class="badge ${cls}">${result}</span>${audioBtn}</td></tr>`;
|
||
}).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="knowledge-section">
|
||
<h3>📝 学习巩固 (${ces.length}题)</h3>
|
||
<table>
|
||
<thead><tr><th>#</th><th>题型</th><th>知识点</th><th>详情</th><th>结果</th></tr></thead>
|
||
<tbody>
|
||
${ces.map((ce, i) => {
|
||
const correct = ce.is_correct === true || ce.isCorrect === true;
|
||
const kpText = ce.knowledge || '-';
|
||
const audioBtn = ce.audio ? `<span class="audio-btn" onclick="playAudio('${ce.audio}', this)" title="播放录音">🔊</span>` : '';
|
||
return `<tr><td>${i + 1}</td><td>${ce.type}</td><td>${kpText}</td><td>${ce.detail}</td><td><span class="badge ${correct ? 'correct' : 'wrong'}">${correct ? '✓ 正确' : '✗ 错误'}</span>${audioBtn}</td></tr>`;
|
||
}).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
`;
|
||
detail.innerHTML = html;
|
||
detailContainer.appendChild(detail);
|
||
});
|
||
|
||
let currentAudio = null;
|
||
function playAudio(url, el) {
|
||
if (currentAudio) {
|
||
currentAudio.pause();
|
||
currentAudio = null;
|
||
document.querySelectorAll('.audio-btn.playing').forEach(b => b.classList.remove('playing'));
|
||
}
|
||
const audio = new Audio(url);
|
||
currentAudio = audio;
|
||
el.classList.add('playing');
|
||
audio.play().catch(() => {});
|
||
audio.onended = () => { el.classList.remove('playing'); currentAudio = null; };
|
||
audio.onerror = () => { el.classList.remove('playing'); currentAudio = null; };
|
||
}
|
||
|
||
function switchTab(idx) {
|
||
document.querySelectorAll('.lesson-card').forEach((c, i) => c.classList.toggle('active', i === idx));
|
||
document.querySelectorAll('.lesson-detail').forEach((d, i) => d.classList.toggle('active', i === idx));
|
||
}
|
||
|
||
function formatTime(t) {
|
||
if (!t || t === '-') return '-';
|
||
try {
|
||
const d = new Date(t);
|
||
return d.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||
} catch { return t; }
|
||
}
|
||
|
||
// ==================== 能力训练展示 ====================
|
||
const abilityTbody = document.getElementById('ability-training-tbody');
|
||
|
||
abilityTraining.forEach((at, idx) => {
|
||
const tr = document.createElement('tr');
|
||
const result = (at.result || '').toLowerCase();
|
||
const badgeCls = result === 'perfect' ? 'perfect' : result === 'good' ? 'good' : 'oops';
|
||
const subQuestionInfo = `${at.sub_question_correct || 0}/${at.sub_question_count || 0}`;
|
||
|
||
const atAudioBtn = at.audio ? `<span class="audio-btn" onclick="playAudio('${at.audio}', this)" title="播放录音">🔊</span>` : '';
|
||
|
||
tr.innerHTML = `
|
||
<td>${idx + 1}</td>
|
||
<td>${at.source || '-'}</td>
|
||
<td>${at.type || '-'}</td>
|
||
<td>${at.title || '-'}</td>
|
||
<td>${at.detail || '-'}</td>
|
||
<td>${subQuestionInfo}</td>
|
||
<td><span class="badge ${badgeCls}">${result}</span>${atAudioBtn}</td>
|
||
`;
|
||
abilityTbody.appendChild(tr);
|
||
});
|
||
|
||
// 响应式
|
||
window.addEventListener('resize', () => {
|
||
interactiveChart.resize();
|
||
exerciseChart.resize();
|
||
abilityChart.resize();
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|