- grades: 拆分 batch-grade-entry (457→374) + grade-record-list (523→231),新增 4 个子组件 - attendance: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - error-book: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - elective: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - 删除 12 个重复组件,新增 app 层 filter 组件就近放置 - tsc 零错误,lint 无新增错误
274 lines
19 KiB
HTML
274 lines
19 KiB
HTML
<h2>课文锚点时间线布局</h2>
|
||
<p class="subtitle">课文作为主轴,节点锚定到课文位置,形成教学流程时间线</p>
|
||
|
||
<div class="mockup">
|
||
<div class="mockup-header">备课编辑器 — 课文锚点时间线</div>
|
||
<div class="mockup-body" style="padding:0;">
|
||
<div style="font-family:monospace;font-size:12px;line-height:1.6;">
|
||
<!-- 顶部工具栏 -->
|
||
<div style="background:#1e293b;color:#e2e8f0;padding:8px 12px;display:flex;justify-content:space-between;align-items:center;">
|
||
<div style="display:flex;align-items:center;gap:8px;">
|
||
<span>📖</span>
|
||
<span style="font-weight:bold;">秋天(第一课时)</span>
|
||
<span style="background:#334155;padding:2px 8px;border-radius:3px;font-size:10px;">语文 · 一年级上册 · 第一单元</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px;">
|
||
<span style="font-size:10px;color:#94a3b8;">💾 已保存 · 2 分钟前</span>
|
||
<span style="background:#334155;padding:4px 8px;border-radius:3px;font-size:10px;">📋 版本历史</span>
|
||
<span style="background:#3b82f6;padding:4px 12px;border-radius:3px;font-size:10px;">💾 保存</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主体:左课文 + 右节点时间线 -->
|
||
<div style="display:grid;grid-template-columns:1fr 320px;gap:0;background:#fff;min-height:480px;">
|
||
|
||
<!-- 左侧:课文正文区(带锚点 gutter) -->
|
||
<div style="display:grid;grid-template-columns:32px 1fr;background:#fffbeb;border-right:1px solid #e2e8f0;">
|
||
|
||
<!-- 锚点 gutter(显示锚点标记) -->
|
||
<div style="background:#fef3c7;border-right:1px solid #fde68a;position:relative;">
|
||
<!-- 锚点标记 -->
|
||
<div style="position:absolute;top:60px;left:4px;background:#3b82f6;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">1</div>
|
||
<div style="position:absolute;top:140px;left:4px;background:#f59e0b;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">2</div>
|
||
<div style="position:absolute;top:200px;left:4px;background:#0ea5e9;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">3</div>
|
||
<div style="position:absolute;top:280px;left:4px;background:#ec4899;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">4</div>
|
||
<div style="position:absolute;top:360px;left:4px;background:#22c55e;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">5</div>
|
||
</div>
|
||
|
||
<!-- 课文内容 -->
|
||
<div style="padding:16px 20px;font-size:13px;color:#78350f;line-height:2;position:relative;">
|
||
<div style="font-size:16px;font-weight:bold;color:#92400e;text-align:center;margin-bottom:16px;">秋天</div>
|
||
|
||
<p style="margin:0 0 12px 0;">
|
||
<span style="background:#dbeafe;border-bottom:2px solid #3b82f6;padding:1px 2px;">天气凉了,树叶黄了,</span>
|
||
一片片叶子从树上落下来。
|
||
</p>
|
||
<p style="margin:0 0 12px 0;">
|
||
<span style="background:#fef3c7;border-bottom:2px solid #f59e0b;padding:1px 2px;">天空那么蓝,那么高。</span>
|
||
一群大雁往南飞,
|
||
</p>
|
||
<p style="margin:0 0 12px 0;">
|
||
<span style="background:#e0f2fe;border-bottom:2px solid #0ea5e9;padding:1px 2px;">一会儿排成个"人"字,</span>
|
||
<span style="background:#fce7f3;border-bottom:2px solid #ec4899;padding:1px 2px;">一会儿排成个"一"字。</span>
|
||
</p>
|
||
<p style="margin:0 0 12px 0;">
|
||
<span style="background:#dcfce7;border-bottom:2px solid #22c55e;padding:1px 2px;">啊!秋天来了!</span>
|
||
</p>
|
||
|
||
<!-- 拖放提示 -->
|
||
<div style="margin-top:24px;padding:8px;border:1px dashed #cbd5e1;border-radius:4px;text-align:center;font-size:10px;color:#94a3b8;">
|
||
💡 选中文字可"关联节点",或从右侧拖动节点到课文某字前
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧:节点时间线 -->
|
||
<div style="background:#f8fafc;padding:12px;overflow-y:auto;">
|
||
<div style="font-size:10px;color:#64748b;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;">教学流程时间线</div>
|
||
|
||
<!-- 已锚定节点(按课文位置排序) -->
|
||
<div style="display:flex;flex-direction:column;gap:6px;">
|
||
|
||
<!-- 节点 1:导入(锚定到"天气凉了") -->
|
||
<div style="background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:4px;padding:8px;cursor:pointer;">
|
||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">1</span>
|
||
<span style="font-size:11px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#64748b;background:#eff6ff;padding:4px 6px;border-radius:3px;">
|
||
"天气凉了,树叶黄了" → 提问:你见过秋天的树叶吗?
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 节点 2:文本研习(锚定到"天空那么蓝") -->
|
||
<div style="background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:4px;padding:8px;cursor:pointer;">
|
||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">2</span>
|
||
<span style="font-size:11px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#64748b;background:#fffbeb;padding:4px 6px;border-radius:3px;">
|
||
"天空那么蓝,那么高" → 赏析:叠词的运用
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 节点 3:新授(锚定到"人字") -->
|
||
<div style="background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:4px;padding:8px;cursor:pointer;">
|
||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">3</span>
|
||
<span style="font-size:11px;font-weight:bold;color:#075985;">📚 新授</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#64748b;background:#f0f9ff;padding:4px 6px;border-radius:3px;">
|
||
"一会儿排成个'人'字" → 讲解:大雁南飞
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 节点 4:练习(锚定到"一字") -->
|
||
<div style="background:#fff;border:1px solid #ec4899;border-left:3px solid #ec4899;border-radius:4px;padding:8px;cursor:pointer;">
|
||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||
<span style="background:#ec4899;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">4</span>
|
||
<span style="font-size:11px;font-weight:bold;color:#9f1239;">✏️ 练习</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#64748b;background:#fdf2f8;padding:4px 6px;border-radius:3px;">
|
||
"一会儿排成个'一'字" → 3 道题
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 节点 5:小结(锚定到"秋天来了") -->
|
||
<div style="background:#fff;border:1px solid #22c55e;border-left:3px solid #22c55e;border-radius:4px;padding:8px;cursor:pointer;">
|
||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">5</span>
|
||
<span style="font-size:11px;font-weight:bold;color:#166534;">📌 小结</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#64748b;background:#f0fdf4;padding:4px 6px;border-radius:3px;">
|
||
"啊!秋天来了!" → 总结全文
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 分隔线 -->
|
||
<div style="border-top:1px dashed #cbd5e1;margin:8px 0;padding-top:8px;">
|
||
<div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:1px;margin-bottom:6px;">未锚定节点</div>
|
||
</div>
|
||
|
||
<!-- 未锚定节点 -->
|
||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||
<div style="display:flex;align-items:center;gap:6px;">
|
||
<span style="font-size:11px;font-weight:bold;color:#1e3a8a;">🎯 教学目标</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||
<div style="display:flex;align-items:center;gap:6px;">
|
||
<span style="font-size:11px;font-weight:bold;color:#92400e;">⭐ 重难点</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||
<div style="display:flex;align-items:center;gap:6px;">
|
||
<span style="font-size:11px;font-weight:bold;color:#a855f7;">🏠 作业</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">课后</span>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||
<div style="display:flex;align-items:center;gap:6px;">
|
||
<span style="font-size:11px;font-weight:bold;color:#6366f1;">📋 板书设计</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||
<div style="display:flex;align-items:center;gap:6px;">
|
||
<span style="font-size:11px;font-weight:bold;color:#64748b;">💭 教学反思</span>
|
||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">课后</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加节点按钮 -->
|
||
<div style="border:1px dashed #94a3b8;border-radius:4px;padding:8px;text-align:center;font-size:10px;color:#64748b;cursor:pointer;margin-top:4px;">
|
||
+ 添加节点
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section" style="margin-top:24px;">
|
||
<h3>核心交互:两种锚定方式</h3>
|
||
<div class="split">
|
||
<div class="mockup">
|
||
<div class="mockup-header">方式 1:拖动节点到课文某字前</div>
|
||
<div class="mockup-body" style="padding:16px;font-family:monospace;font-size:12px;">
|
||
<div style="display:flex;gap:12px;">
|
||
<div style="background:#f8fafc;padding:8px;border-radius:4px;">
|
||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">右侧节点</div>
|
||
<div style="background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;padding:6px;border-radius:3px;cursor:grab;font-size:10px;">💡 导入</div>
|
||
</div>
|
||
<div style="font-size:18px;color:#94a3b8;align-self:center;">→</div>
|
||
<div style="background:#fffbeb;padding:8px;border-radius:4px;flex:1;">
|
||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">课文</div>
|
||
<div style="font-size:11px;color:#78350f;line-height:1.8;">
|
||
天气凉了,<span style="background:#dbeafe;border:2px dashed #3b82f6;padding:1px 2px;border-radius:2px;">|</span>树叶黄了,<br>
|
||
一片片叶子从树上落下来。
|
||
</div>
|
||
<div style="font-size:9px;color:#3b82f6;margin-top:4px;">💡 节点锚定到此位置</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mockup">
|
||
<div class="mockup-header">方式 2:选中文字 → 关联节点</div>
|
||
<div class="mockup-body" style="padding:16px;font-family:monospace;font-size:12px;">
|
||
<div style="background:#fffbeb;padding:8px;border-radius:4px;margin-bottom:8px;">
|
||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">1. 选中文字</div>
|
||
<div style="font-size:11px;color:#78350f;line-height:1.8;">
|
||
<span style="background:#fef08a;">天空那么蓝,那么高</span>。
|
||
</div>
|
||
</div>
|
||
<div style="font-size:18px;color:#94a3b8;text-align:center;">↓</div>
|
||
<div style="background:#f8fafc;padding:8px;border-radius:4px;margin-top:8px;">
|
||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">2. 弹出菜单选择节点</div>
|
||
<div style="display:flex;gap:4px;flex-wrap:wrap;">
|
||
<span style="background:#fff;border:1px solid #3b82f6;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">💡 导入</span>
|
||
<span style="background:#fff;border:1px solid #f59e0b;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📝 文本研习</span>
|
||
<span style="background:#fff;border:1px solid #0ea5e9;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📚 新授</span>
|
||
<span style="background:#fff;border:1px solid #ec4899;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">✏️ 练习</span>
|
||
<span style="background:#fff;border:1px solid #22c55e;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📌 小结</span>
|
||
<span style="background:#fff;border:1px dashed #94a3b8;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">+ 新建节点</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section" style="margin-top:24px;">
|
||
<h3>数据模型:锚点(Anchor)</h3>
|
||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.6;">
|
||
<div style="color:#94a3b8;">// 节点锚点 — 记录节点与课文位置的关联</div>
|
||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">NodeAnchor</span> {</div>
|
||
<div> nodeId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联的节点 ID</span></div>
|
||
<div> type: <span style="color:#10b981;">"point"</span> | <span style="color:#10b981;">"range"</span>; <span style="color:#64748b;">// 点锚点 or 范围锚点</span></div>
|
||
<div> start: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 课文纯文本偏移量(字符)</span></div>
|
||
<div> end?: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// range 锚点的结束偏移</span></div>
|
||
<div> textPreview?: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 锚定文字预览(便于回显)</span></div>
|
||
<div>}</div>
|
||
<br>
|
||
<div style="color:#94a3b8;">// LessonPlanDocument 扩展</div>
|
||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">LessonPlanDocument</span> {</div>
|
||
<div> version: <span style="color:#10b981;">3</span>; <span style="color:#64748b;">// 升级到 v3</span></div>
|
||
<div> nodes: <span style="color:#3b82f6;">LessonPlanNode</span>[];</div>
|
||
<div> edges: <span style="color:#3b82f6;">LessonPlanEdge</span>[]; <span style="color:#64748b;">// 保留:节点间连线</span></div>
|
||
<div> anchors: <span style="color:#3b82f6;">NodeAnchor</span>[]; <span style="color:#64748b;">// 新增:节点与课文的锚点</span></div>
|
||
<div>}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>这个设计的优势</h3>
|
||
<div class="pros-cons">
|
||
<div class="pros">
|
||
<h4>优势</h4>
|
||
<ul>
|
||
<li><strong>教学流程可视化</strong>:节点按课文位置排序,天然形成时间线</li>
|
||
<li><strong>节点与课文强关联</strong>:每个节点对应课文的哪部分一目了然</li>
|
||
<li><strong>双模式锚定</strong>:拖动(点锚点)+ 选文字(范围锚点)</li>
|
||
<li><strong>保留连线能力</strong>:节点间仍可连线(如"导入→新授"流程线)</li>
|
||
<li><strong>未锚定节点</strong>:目标/重难点/作业/板书/反思等全局节点不强制锚定</li>
|
||
</ul>
|
||
</div>
|
||
<div class="cons">
|
||
<h4>需要注意</h4>
|
||
<ul>
|
||
<li>课文偏移量需基于纯文本(Markdown 渲染后需映射)</li>
|
||
<li>课文内容变更后锚点可能失效(需重新定位或提示)</li>
|
||
<li>数据结构升级到 v3,需迁移现有 v2 数据</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|