study-analysis.xiaoban/output/study_report_12345_L1_U1_20260402162938.html

424 lines
44 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学情分析报告 - 用户12345 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;
gap: 20px;
}
@media (max-width: 768px) {
.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-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; }
.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">
用户ID12345 &nbsp;|&nbsp; Level 1 &nbsp;|&nbsp; Unit 1 &nbsp;|&nbsp; 生成时间2026-04-02 16:29:38
</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>
<div class="card">
<h2>📖 课程详情</h2>
<div class="lesson-nav" id="lesson-nav"></div>
<div id="lesson-details"></div>
</div>
<div class="card">
<h2>🔍 原始数据</h2>
<div class="raw-data" id="raw-data"></div>
</div>
</div>
<script>
const data = {"role_id": 12345, "level": 1, "unit": 1, "unit_name": "Unit 1: Hello World", "lessons": [{"lesson_id": 1, "lesson_name": "Lesson 1: Greetings", "entry_time": "2024-01-15T09:00:00Z", "completion_time": "2024-01-15T09:25:30Z", "knowledge_points": {"words": [{"word": "hello", "meaning": "你好", "pos": "int."}, {"word": "hi", "meaning": "嗨", "pos": "int."}, {"word": "goodbye", "meaning": "再见", "pos": "int."}, {"word": "name", "meaning": "名字", "pos": "n."}], "sentence_patterns": [{"pattern": "Hello, my name is [name].", "meaning": "你好,我的名字是[名字]。", "example": "Hello, my name is Tom."}, {"pattern": "Nice to meet you.", "meaning": "很高兴认识你。", "example": "Nice to meet you too."}]}, "interactive_components": [{"component_id": "ic_001", "title": "单词跟读 - hello", "detail": "请跟读单词 hello注意发音准确", "user_result": "perfect"}, {"component_id": "ic_002", "title": "单词跟读 - hi", "detail": "请跟读单词 hi注意语调自然", "user_result": "good"}, {"component_id": "ic_003", "title": "单词听选 - goodbye", "detail": "听录音,选择正确的单词 goodbye", "user_result": "perfect"}, {"component_id": "ic_004", "title": "单词拼写 - name", "detail": "根据发音,拼写出单词 name", "user_result": "good"}, {"component_id": "ic_005", "title": "句型跟读 - Hello, my name is...", "detail": "请跟读句型Hello, my name is [name]", "user_result": "perfect"}, {"component_id": "ic_006", "title": "句型替换练习", "detail": "替换名字完成句子Hello, my name is ______", "user_result": "oops"}, {"component_id": "ic_007", "title": "情景对话 - 打招呼", "detail": "在情景中与角色进行打招呼对话", "user_result": "good"}, {"component_id": "ic_008", "title": "听力理解 - 问候语", "detail": "听录音,选择正确的问候回应", "user_result": "perfect"}, {"component_id": "ic_009", "title": "语音识别 - hi", "detail": "请说出单词 hi", "user_result": "good"}, {"component_id": "ic_010", "title": "图文匹配 - 单词", "detail": "将单词与对应的图片进行匹配", "user_result": "perfect"}, {"component_id": "ic_011", "title": "句型听选 - Nice to meet you", "detail": "听录音,选择正确的回应", "user_result": "good"}, {"component_id": "ic_012", "title": "角色扮演 - 自我介绍", "detail": "扮演角色进行自我介绍对话", "user_result": "perfect"}, {"component_id": "ic_013", "title": "单词排序 - 句子组成", "detail": "将单词按正确顺序排列成句子", "user_result": "oops"}, {"component_id": "ic_014", "title": "发音练习 - 语调训练", "detail": "练习疑问句和陈述句的语调区别", "user_result": "good"}, {"component_id": "ic_015", "title": "单词填空 - 补全句子", "detail": "在句子中填入正确的单词", "user_result": "perfect"}, {"component_id": "ic_016", "title": "情景判断 - 选择回应", "detail": "根据情景选择最合适的回应", "user_result": "good"}, {"component_id": "ic_017", "title": "综合对话 - 完整对话", "detail": "完成完整的打招呼和自我介绍对话", "user_result": "perfect"}, {"component_id": "ic_018", "title": "复习测验 - 本课回顾", "detail": "完成本课知识点的综合复习测验", "user_result": "good"}], "consolidation_exercises": [{"exercise_id": "ce_001", "type": "单词听选", "detail": "听录音从A、B、C三个选项中选择听到的单词", "is_correct": true}, {"exercise_id": "ce_002", "type": "单词拼写", "detail": "根据中文意思,写出对应的英文单词:你好", "is_correct": true}, {"exercise_id": "ce_003", "type": "图文匹配", "detail": "将单词 goodbye 与对应的图片匹配", "is_correct": false}, {"exercise_id": "ce_004", "type": "句型填空", "detail": "用正确的单词填空Hello, my ______ is Tom.", "is_correct": true}, {"exercise_id": "ce_005", "type": "情景选择", "detail": "初次见面时应该说A. Hello B. Goodbye C. Hi", "is_correct": true}, {"exercise_id": "ce_006", "type": "句子排序", "detail": "将下列单词排列成正确的句子name / my / is / Hello", "is_correct": true}, {"exercise_id": "ce_007", "type": "听力理解", "detail": "听对话,回答问题:他们正在做什么?", "is_correct": false}, {"exercise_id": "ce_008", "type": "发音选择", "detail": "听录音,选择包含 /eɪ/ 音的单词", "is_correct": true}, {"exercise_id": "ce_009", "type": "翻译练习", "detail": "将下列句子翻译成英文:很高兴认识你。", "is_correct": true}, {"exercise_id": "ce_010", "type": "对话补全", "detail": "补全对话A: Hello! B: ______!", "is_correct": true}, {"exercise_id": "ce_011", "type": "单词分类", "detail": "将单词按问候语和非问候语分类", "is_correct": false}, {"exercise_id": "ce_012", "type": "句型转换", "detail": "将 Hello 转换为同义词", "is_correct": true}, {"exercise_id": "ce_013", "type": "连线匹配", "detail": "将单词与对应的中文意思连线", "is_correct": true}, {"exercise_id": "ce_014", "type": "判断正误", "detail": "判断句子是否正确Goodbye 用于告别时说。", "is_correct": true}, {"exercise_id": "ce_015", "type": "选词填空", "detail": "选择合适的单词填空______ to meet you. (Nice/Fine/Good)", "is_correct": true}, {"exercise_id": "ce_016", "type": "语音辨识", "detail": "听录音,判断是哪个单词", "is_correct": false}, {"exercise_id": "ce_017", "type": "完形填空", "detail": "阅读短文,选择合适的问候语填入空格", "is_correct": true}, {"exercise_id": "ce_018", "type": "综合测验", "detail": "完成本课知识的综合测验题", "is_correct": true}]}, {"lesson_id": 2, "lesson_name": "Lesson 2: Numbers", "entry_time": "2024-01-16T10:00:00Z", "completion_time": "2024-01-16T10:30:15Z", "knowledge_points": {"words": [{"word": "one", "meaning": "一", "pos": "num."}, {"word": "two", "meaning": "二", "pos": "num."}, {"word": "three", "meaning": "三", "pos": "num."}, {"word": "ten", "meaning": "十", "pos": "num."}], "sentence_patterns": [{"pattern": "How old are you? I am [number].", "meaning": "你几岁了?我[数字]岁。", "example": "How old are you? I am five."}, {"pattern": "I have [number] [noun].", "meaning": "我有[数字]个[名词]。", "example": "I have three books."}]}, "interactive_components": [{"component_id": "ic_201", "title": "单词跟读 - one", "detail": "请跟读数字 one", "user_result": "perfect"}, {"component_id": "ic_202", "title": "单词跟读 - two", "detail": "请跟读数字 two", "user_result": "perfect"}, {"component_id": "ic_203", "title": "单词听选 - three", "detail": "听录音,选择正确的数字 three", "user_result": "good"}, {"component_id": "ic_204", "title": "单词拼写 - ten", "detail": "根据发音,拼写出数字 ten", "user_result": "perfect"}, {"component_id": "ic_205", "title": "句型跟读 - How old are you?", "detail": "请跟读句型How old are you?", "user_result": "good"}, {"component_id": "ic_206", "title": "数字排序练习", "detail": "将数字按从小到大排序", "user_result": "perfect"}, {"component_id": "ic_207", "title": "情景对话 - 询问年龄", "detail": "在情景中询问和回答年龄", "user_result": "good"}, {"component_id": "ic_208", "title": "听力理解 - 数字辨识", "detail": "听录音,写出听到的数字", "user_result": "perfect"}, {"component_id": "ic_209", "title": "语音识别 - three", "detail": "请说出数字 three", "user_result": "good"}, {"component_id": "ic_210", "title": "图文匹配 - 数字", "detail": "将数字单词与对应的数量匹配", "user_result": "perfect"}, {"component_id": "ic_211", "title": "数学计算 - 英文表达", "detail": "计算并写出英文结果1+2=?", "user_result": "good"}, {"component_id": "ic_212", "title": "角色扮演 - 自我介绍年龄", "detail": "扮演角色介绍自己的年龄", "user_result": "perfect"}, {"component_id": "ic_213", "title": "数字接龙", "detail": "按顺序接出下一个数字单词", "user_result": "oops"}, {"component_id": "ic_214", "title": "听写练习 - 数字", "detail": "听写数字单词 one 到 ten", "user_result": "good"}, {"component_id": "ic_215", "title": "句型填空 - I have...", "detail": "用正确的数字填空I have ______ books.", "user_result": "perfect"}, {"component_id": "ic_216", "title": "快速反应 - 数字", "detail": "看到数字快速说出英文", "user_result": "good"}, {"component_id": "ic_217", "title": "综合对话 - 数字问答", "detail": "完成关于数字的完整对话", "user_result": "perfect"}, {"component_id": "ic_218", "title": "复习测验 - 数字单元", "detail": "完成数字知识点的综合复习", "user_result": "good"}], "consolidation_exercises": [{"exercise_id": "ce_201", "type": "单词听选", "detail": "听录音,选择听到的数字单词", "is_correct": true}, {"exercise_id": "ce_202", "type": "单词拼写", "detail": "根据中文写出英文数字:三", "is_correct": true}, {"exercise_id": "ce_203", "type": "图文匹配", "detail": "将数字 ten 与对应的数量图匹配", "is_correct": true}, {"exercise_id": "ce_204", "type": "句型填空", "detail": "填空How old are you? I am ______.", "is_correct": false}, {"exercise_id": "ce_205", "type": "听力计算", "detail": "听数字计算并选择正确答案2+3=?", "is_correct": true}, {"exercise_id": "ce_206", "type": "句子排序", "detail": "排列句子you / How / are / old", "is_correct": true}, {"exercise_id": "ce_207", "type": "听力理解", "detail": "听对话,回答问题:男孩几岁?", "is_correct": true}, {"exercise_id": "ce_208", "type": "数字排序", "detail": "将下列数字按从小到大排列", "is_correct": true}, {"exercise_id": "ce_209", "type": "翻译练习", "detail": "翻译:我有三本书。", "is_correct": false}, {"exercise_id": "ce_210", "type": "对话补全", "detail": "补全对话A: How old are you? B: ______", "is_correct": true}, {"exercise_id": "ce_211", "type": "数字识别", "detail": "选择正确的数字单词拼写", "is_correct": true}, {"exercise_id": "ce_212", "type": "数学应用", "detail": "Mary有2个苹果Tom有3个共有几个", "is_correct": true}, {"exercise_id": "ce_213", "type": "连线匹配", "detail": "将数字与英文单词连线", "is_correct": true}, {"exercise_id": "ce_214", "type": "判断正误", "detail": "判断one 表示数字 1。", "is_correct": true}, {"exercise_id": "ce_215", "type": "选词填空", "detail": "选择正确数字填空I have ______ (one/two/three) pens.", "is_correct": true}, {"exercise_id": "ce_216", "type": "数字书写", "detail": "根据读音写出数字单词", "is_correct": false}, {"exercise_id": "ce_217", "type": "完形填空", "detail": "阅读短文,填入正确的数字单词", "is_correct": true}, {"exercise_id": "ce_218", "type": "综合测验", "detail": "完成数字单元综合测验", "is_correct": true}]}, {"lesson_id": 3, "lesson_name": "Lesson 3: Colors", "entry_time": "2024-01-17T09:15:00Z", "completion_time": "2024-01-17T09:45:20Z", "knowledge_points": {"words": [{"word": "red", "meaning": "红色", "pos": "n./adj."}, {"word": "blue", "meaning": "蓝色", "pos": "n./adj."}, {"word": "green", "meaning": "绿色", "pos": "n./adj."}, {"word": "yellow", "meaning": "黄色", "pos": "n./adj."}], "sentence_patterns": [{"pattern": "What color is it? It is [color].", "meaning": "这是什么颜色?这是[颜色]。", "example": "What color is it? It is red."}, {"pattern": "I like [color].", "meaning": "我喜欢[颜色]。", "example": "I like blue."}]}, "interactive_components": [{"component_id": "ic_301", "title": "单词跟读 - red", "detail": "请跟读颜色单词 red", "user_result": "perfect"}, {"component_id": "ic_302", "title": "单词跟读 - blue", "detail": "请跟读颜色单词 blue", "user_result": "good"}, {"component_id": "ic_303", "title": "单词听选 - green", "detail": "听录音,选择正确的颜色单词", "user_result": "perfect"}, {"component_id": "ic_304", "title": "单词拼写 - yellow", "detail": "根据发音,拼写出颜色单词 yellow", "user_result": "good"}, {"component_id": "ic_305", "title": "句型跟读 - What color...", "detail": "请跟读句型What color is it?", "user_result": "perfect"}, {"component_id": "ic_306", "title": "颜色识别练习", "detail": "看图片,说出颜色名称", "user_result": "perfect"}, {"component_id": "ic_307", "title": "情景对话 - 询问颜色", "detail": "在情景中询问物品颜色", "user_result": "good"}, {"component_id": "ic_308", "title": "听力理解 - 颜色辨识", "detail": "听录音,选择听到的颜色", "user_result": "perfect"}, {"component_id": "ic_309", "title": "语音识别 - green", "detail": "请说出颜色 green", "user_result": "oops"}, {"component_id": "ic_310", "title": "图文匹配 - 颜色", "detail": "将颜色单词与对应颜色块匹配", "user_result": "perfect"}, {"component_id": "ic_311", "title": "颜色混合 - 英文表达", "detail": "蓝色加黄色变成什么颜色?", "user_result": "good"}, {"component_id": "ic_312", "title": "角色扮演 - 描述物品颜色", "detail": "扮演角色描述周围物品颜色", "user_result": "perfect"}, {"component_id": "ic_313", "title": "颜色分类", "detail": "将物品按颜色分类", "user_result": "good"}, {"component_id": "ic_314", "title": "涂色游戏", "detail": "听指令给图片涂上正确的颜色", "user_result": "perfect"}, {"component_id": "ic_315", "title": "句型填空 - I like...", "detail": "用颜色填空I like ______.", "user_result": "good"}, {"component_id": "ic_316", "title": "快速反应 - 颜色", "detail": "看到颜色快速说出英文", "user_result": "perfect"}, {"component_id": "ic_317", "title": "综合对话 - 颜色问答", "detail": "完成关于颜色的完整对话", "user_result": "good"}, {"component_id": "ic_318", "title": "复习测验 - 颜色单元", "detail": "完成颜色知识点的综合复习", "user_result": "perfect"}], "consolidation_exercises": [{"exercise_id": "ce_301", "type": "单词听选", "detail": "听录音,选择听到的颜色单词", "is_correct": true}, {"exercise_id": "ce_302", "type": "单词拼写", "detail": "根据中文写出颜色英文:红色", "is_correct": true}, {"exercise_id": "ce_303", "type": "图文匹配", "detail": "将 green 与绿色图片匹配", "is_correct": true}, {"exercise_id": "ce_304", "type": "句型填空", "detail": "填空What color is it? It is ______.", "is_correct": true}, {"exercise_id": "ce_305", "type": "颜色识别", "detail": "选择天空的颜色A. blue B. red C. green", "is_correct": true}, {"exercise_id": "ce_306", "type": "句子排序", "detail": "排列句子is / it / What / color", "is_correct": true}, {"exercise_id": "ce_307", "type": "听力理解", "detail": "听描述,选择正确的物品颜色", "is_correct": false}, {"exercise_id": "ce_308", "type": "颜色混合", "detail": "红色加黄色变成什么颜色?", "is_correct": true}, {"exercise_id": "ce_309", "type": "翻译练习", "detail": "翻译:我喜欢蓝色。", "is_correct": true}, {"exercise_id": "ce_310", "type": "对话补全", "detail": "补全对话A: What color is it? B: ______", "is_correct": true}, {"exercise_id": "ce_311", "type": "物品分类", "detail": "将红色物品圈出来", "is_correct": true}, {"exercise_id": "ce_312", "type": "颜色联想", "detail": "苹果通常是什么颜色?", "is_correct": true}, {"exercise_id": "ce_313", "type": "连线匹配", "detail": "将颜色与对应物品连线", "is_correct": true}, {"exercise_id": "ce_314", "type": "判断正误", "detail": "判断yellow 是黄色。", "is_correct": true}, {"exercise_id": "ce_315", "type": "选词填空", "detail": "The sky is ______ (red/blue/green).", "is_correct": true}, {"exercise_id": "ce_316", "type": "颜色书写", "detail": "根据读音写出颜色单词", "is_correct": false}, {"exercise_id": "ce_317", "type": "完形填空", "detail": "阅读短文,填入正确的颜色单词", "is_correct": true}, {"exercise_id": "ce_318", "type": "综合测验", "detail": "完成颜色单元综合测验", "is_correct": true}]}, {"lesson_id": 4, "lesson_name": "Lesson 4: Family", "entry_time": "2024-01-18T14:00:00Z", "completion_time": "2024-01-18T14:35:10Z", "knowledge_points": {"words": [{"word": "father", "meaning": "爸爸", "pos": "n."}, {"word": "mother", "meaning": "妈妈", "pos": "n."}, {"word": "brother", "meaning": "兄弟", "pos": "n."}, {"word": "sister", "meaning": "姐妹", "pos": "n."}], "sentence_patterns": [{"pattern": "This is my [family member].", "meaning": "这是我的[家庭成员]。", "example": "This is my father."}, {"pattern": "Who is he/she? He/She is my [family member].", "meaning": "他/她是谁?他/她是我的[家庭成员]。", "example": "Who is he? He is my brother."}]}, "interactive_components": [{"component_id": "ic_401", "title": "单词跟读 - father", "detail": "请跟读家庭成员单词 father", "user_result": "perfect"}, {"component_id": "ic_402", "title": "单词跟读 - mother", "detail": "请跟读家庭成员单词 mother", "user_result": "perfect"}, {"component_id": "ic_403", "title": "单词听选 - brother", "detail": "听录音,选择正确的家庭成员单词", "user_result": "good"}, {"component_id": "ic_404", "title": "单词拼写 - sister", "detail": "根据发音,拼写出 sister", "user_result": "perfect"}, {"component_id": "ic_405", "title": "句型跟读 - This is my...", "detail": "请跟读句型This is my father.", "user_result": "good"}, {"component_id": "ic_406", "title": "家庭成员配对", "detail": "将单词与对应的家庭成员图片配对", "user_result": "perfect"}, {"component_id": "ic_407", "title": "情景对话 - 介绍家人", "detail": "在情景中介绍自己的家庭成员", "user_result": "good"}, {"component_id": "ic_408", "title": "听力理解 - 家庭成员", "detail": "听录音,指出说话者在说谁", "user_result": "perfect"}, {"component_id": "ic_409", "title": "语音识别 - mother", "detail": "请说出家庭成员 mother", "user_result": "good"}, {"component_id": "ic_410", "title": "家庭树绘制", "detail": "根据描述绘制家庭树", "user_result": "oops"}, {"component_id": "ic_411", "title": "问答练习 - Who is...", "detail": "练习问句Who is he/she?", "user_result": "good"}, {"component_id": "ic_412", "title": "角色扮演 - 介绍家庭", "detail": "扮演角色向朋友介绍家人", "user_result": "perfect"}, {"component_id": "ic_413", "title": "家庭成员关系", "detail": "理解家庭成员之间的关系", "user_result": "good"}, {"component_id": "ic_414", "title": "听指令指认", "detail": "听指令指出对应的家人图片", "user_result": "perfect"}, {"component_id": "ic_415", "title": "句型填空 - He/She is...", "detail": "填空Who is she? ______ is my mother.", "user_result": "perfect"}, {"component_id": "ic_416", "title": "家庭相册描述", "detail": "看家庭相册照片,描述家人", "user_result": "good"}, {"component_id": "ic_417", "title": "综合对话 - 家庭介绍", "detail": "完成关于家庭的完整对话", "user_result": "perfect"}, {"component_id": "ic_418", "title": "复习测验 - 家庭单元", "detail": "完成家庭知识点的综合复习", "user_result": "good"}], "consolidation_exercises": [{"exercise_id": "ce_401", "type": "单词听选", "detail": "听录音,选择听到的家庭成员单词", "is_correct": true}, {"exercise_id": "ce_402", "type": "单词拼写", "detail": "根据中文写出英文:爸爸", "is_correct": true}, {"exercise_id": "ce_403", "type": "图文匹配", "detail": "将 mother 与妈妈图片匹配", "is_correct": true}, {"exercise_id": "ce_404", "type": "句型填空", "detail": "填空This is my ______ (father/mother/brother).", "is_correct": true}, {"exercise_id": "ce_405", "type": "关系识别", "detail": "Tom是爸爸的sonTom是爸爸的什么人", "is_correct": false}, {"exercise_id": "ce_406", "type": "句子排序", "detail": "排列句子is / This / my / mother", "is_correct": true}, {"exercise_id": "ce_407", "type": "听力理解", "detail": "听对话,回答问题:他们是什么关系?", "is_correct": true}, {"exercise_id": "ce_408", "type": "家庭关系", "detail": "爸爸的爸爸叫什么?", "is_correct": true}, {"exercise_id": "ce_409", "type": "翻译练习", "detail": "翻译:这是我的姐姐。", "is_correct": true}, {"exercise_id": "ce_410", "type": "对话补全", "detail": "补全对话A: Who is he? B: ______", "is_correct": true}, {"exercise_id": "ce_411", "type": "家庭识别", "detail": "根据描述选择正确的家庭成员", "is_correct": true}, {"exercise_id": "ce_412", "type": "角色配对", "detail": "将人物与正确的称呼配对", "is_correct": true}, {"exercise_id": "ce_413", "type": "连线匹配", "detail": "将家庭成员与中文意思连线", "is_correct": true}, {"exercise_id": "ce_414", "type": "判断正误", "detail": "判断brother 可以是哥哥也可以是弟弟。", "is_correct": true}, {"exercise_id": "ce_415", "type": "选词填空", "detail": "She is my ______ (father/mother/sister).", "is_correct": true}, {"exercise_id": "ce_416", "type": "单词书写", "detail": "根据读音写出家庭成员单词", "is_correct": false}, {"exercise_id": "ce_417", "type": "完形填空", "detail": "阅读短文,填入正确的家庭成员单词", "is_correct": true}, {"exercise_id": "ce_418", "type": "综合测验", "detail": "完成家庭单元综合测验", "is_correct": true}]}, {"lesson_id": 5, "lesson_name": "Lesson 5: Animals", "entry_time": "2024-01-19T09:30:00Z", "completion_time": "2024-01-19T10:05:45Z", "knowledge_points": {"words": [{"word": "cat", "meaning": "猫", "pos": "n."}, {"word": "dog", "meaning": "狗", "pos": "n."}, {"word": "bird", "meaning": "鸟", "pos": "n."}, {"word": "fish", "meaning": "鱼", "pos": "n."}], "sentence_patterns": [{"pattern": "It is a [animal].", "meaning": "这是一只[动物]。", "example": "It is a cat."}, {"pattern": "I like [animal]s.", "meaning": "我喜欢[动物]。", "example": "I like dogs."}]}, "interactive_components": [{"component_id": "ic_501", "title": "单词跟读 - cat", "detail": "请跟读动物单词 cat注意短元音", "user_result": "perfect"}, {"component_id": "ic_502", "title": "单词跟读 - dog", "detail": "请跟读动物单词 dog", "user_result": "good"}, {"component_id": "ic_503", "title": "单词听选 - bird", "detail": "听录音,选择正确的动物单词", "user_result": "perfect"}, {"component_id": "ic_504", "title": "单词拼写 - fish", "detail": "根据发音,拼写出 fish", "user_result": "good"}, {"component_id": "ic_505", "title": "句型跟读 - It is a...", "detail": "请跟读句型It is a cat.", "user_result": "perfect"}, {"component_id": "ic_506", "title": "动物声音辨识", "detail": "听动物叫声,选择正确的动物", "user_result": "good"}, {"component_id": "ic_507", "title": "情景对话 - 谈论宠物", "detail": "在情景中谈论自己喜欢的动物", "user_result": "oops"}, {"component_id": "ic_508", "title": "听力理解 - 动物描述", "detail": "听录音,描述动物特征", "user_result": "perfect"}, {"component_id": "ic_509", "title": "语音识别 - bird", "detail": "请说出动物 bird", "user_result": "good"}, {"component_id": "ic_510", "title": "图文匹配 - 动物", "detail": "将动物单词与对应图片匹配", "user_result": "perfect"}, {"component_id": "ic_511", "title": "动物分类", "detail": "将动物分为天上飞的和地上跑的", "user_result": "good"}, {"component_id": "ic_512", "title": "角色扮演 - 去动物园", "detail": "扮演角色在动物园谈论动物", "user_result": "perfect"}, {"component_id": "ic_513", "title": "动物习性配对", "detail": "将动物与其习性特点配对", "user_result": "good"}, {"component_id": "ic_514", "title": "听指令模仿", "detail": "听指令模仿动物的叫声和动作", "user_result": "perfect"}, {"component_id": "ic_515", "title": "句型填空 - I like...", "detail": "用动物填空I like ______.", "user_result": "good"}, {"component_id": "ic_516", "title": "快速反应 - 动物", "detail": "看到动物图片快速说出英文", "user_result": "perfect"}, {"component_id": "ic_517", "title": "综合对话 - 动物问答", "detail": "完成关于动物的完整对话", "user_result": "good"}, {"component_id": "ic_518", "title": "复习测验 - 动物单元", "detail": "完成动物知识点的综合复习", "user_result": "perfect"}], "consolidation_exercises": [{"exercise_id": "ce_501", "type": "单词听选", "detail": "听录音,选择听到的动物单词", "is_correct": true}, {"exercise_id": "ce_502", "type": "单词拼写", "detail": "根据中文写出英文:猫", "is_correct": true}, {"exercise_id": "ce_503", "type": "图文匹配", "detail": "将 dog 与狗的图片匹配", "is_correct": true}, {"exercise_id": "ce_504", "type": "句型填空", "detail": "填空It is a ______ (cat/dog/bird).", "is_correct": true}, {"exercise_id": "ce_505", "type": "动物识别", "detail": "看局部图,猜是什么动物?", "is_correct": false}, {"exercise_id": "ce_506", "type": "句子排序", "detail": "排列句子is / It / a / cat", "is_correct": true}, {"exercise_id": "ce_507", "type": "听力理解", "detail": "听描述,选择正确的动物", "is_correct": true}, {"exercise_id": "ce_508", "type": "动物分类", "detail": "选出会飞的动物", "is_correct": true}, {"exercise_id": "ce_509", "type": "翻译练习", "detail": "翻译:我喜欢狗。", "is_correct": true}, {"exercise_id": "ce_510", "type": "对话补全", "detail": "补全对话A: What's this? B: ______", "is_correct": true}, {"exercise_id": "ce_511", "type": "动物习性", "detail": "鱼生活在哪里?", "is_correct": true}, {"exercise_id": "ce_512", "type": "声音辨识", "detail": "听叫声,选择动物", "is_correct": true}, {"exercise_id": "ce_513", "type": "连线匹配", "detail": "将动物与中文意思连线", "is_correct": true}, {"exercise_id": "ce_514", "type": "判断正误", "detail": "判断bird 会飞。", "is_correct": true}, {"exercise_id": "ce_515", "type": "选词填空", "detail": "I like ______ (cat/cats/fishs).", "is_correct": false}, {"exercise_id": "ce_516", "type": "单词书写", "detail": "根据读音写出动物单词", "is_correct": true}, {"exercise_id": "ce_517", "type": "完形填空", "detail": "阅读短文,填入正确的动物单词", "is_correct": true}, {"exercise_id": "ce_518", "type": "综合测验", "detail": "完成动物单元综合测验", "is_correct": true}]}], "summary": {"total_lessons": 5, "completed_lessons": 1, "total_interactive_components": 18, "total_consolidation_exercises": 18, "mastery_rate": 0.85, "study_duration_minutes": 25}};
// 兼容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, totalPerfect = 0, totalGood = 0, totalOops = 0;
let totalExercises = 0, totalCorrect = 0;
lessons.forEach(lesson => {
const ics = lesson.interactive_components || lesson.interactiveComponents || [];
const ces = lesson.consolidation_exercises || lesson.consolidationExercises || [];
totalInteractive += ics.length;
ics.forEach(ic => {
const r = (ic.user_result || ic.userResult || '').toLowerCase();
if (r === 'perfect') totalPerfect++;
else if (r === 'good') totalGood++;
else if (r === 'oops') totalOops++;
});
totalExercises += ces.length;
ces.forEach(ce => {
if (ce.is_correct === true || ce.isCorrect === true) totalCorrect++;
});
});
const exerciseAccuracy = totalExercises > 0 ? Math.round(totalCorrect / totalExercises * 100) : 0;
const interactiveScore = totalInteractive > 0 ? Math.round((totalPerfect * 3 + totalGood * 2 + totalOops * 1) / (totalInteractive * 3) * 100) : 0;
const statsItems = [
{ label: '课程数', value: totalLessons, cls: 'blue' },
{ label: '互动组件总数', value: totalInteractive, cls: 'purple' },
{ label: 'Perfect 次数', value: totalPerfect, cls: 'green' },
{ label: 'Good 次数', value: totalGood, cls: 'blue' },
{ label: 'Oops 次数', value: totalOops, cls: 'orange' },
{ label: '巩固题总数', value: totalExercises, cls: 'purple' },
{ label: '巩固正确率', value: exerciseAccuracy + '%', cls: 'green' },
{ label: '互动综合得分', value: interactiveScore + '%', cls: 'blue' }
];
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'));
interactiveChart.setOption({
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
legend: { bottom: 10 },
color: ['#52c41a', '#1890ff', '#fa541c'],
series: [{
type: 'pie',
radius: ['40%', '65%'],
avoidLabelOverlap: true,
itemStyle: { borderRadius: 8, borderColor: '#fff', borderWidth: 2 },
label: { show: true, fontSize: 14 },
data: [
{ value: totalPerfect, name: 'Perfect' },
{ value: totalGood, name: 'Good' },
{ value: totalOops, name: 'Oops' }
]
}]
});
// ==================== 巩固练习柱状图(按课程) ====================
const exerciseChart = echarts.init(document.getElementById('exercise-chart'));
const lessonLabels = lessons.map((l, i) => l.lesson_name || l.lessonName || `Lesson ${i + 1}`);
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 },
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: [4, 4, 0, 0] } },
{ name: '错误', type: 'bar', stack: 'total', data: wrongCounts, itemStyle: { borderRadius: [4, 4, 0, 0] } }
]
});
// ==================== 课程详情导航 ====================
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}`;
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>
`;
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></tr></thead>
<tbody>
${ics.map((ic, i) => {
const result = (ic.user_result || ic.userResult || '').toLowerCase();
const cls = result === 'perfect' ? 'perfect' : result === 'good' ? 'good' : 'oops';
return `<tr><td>${i + 1}</td><td>${ic.title}</td><td>${ic.detail}</td><td><span class="badge ${cls}">${result}</span></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></tr></thead>
<tbody>
${ces.map((ce, i) => {
const correct = ce.is_correct === true || ce.isCorrect === true;
return `<tr><td>${i + 1}</td><td>${ce.type}</td><td>${ce.detail}</td><td><span class="badge ${correct ? 'correct' : 'wrong'}">${correct ? '✓ 正确' : '✗ 错误'}</span></td></tr>`;
}).join('')}
</tbody>
</table>
</div>
`;
detail.innerHTML = html;
detailContainer.appendChild(detail);
});
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; }
}
// 原始数据
document.getElementById('raw-data').textContent = JSON.stringify(data, null, 2);
// 响应式
window.addEventListener('resize', () => {
interactiveChart.resize();
exerciseChart.resize();
});
</script>
</body>
</html>