Files
ClassFeedback/.claude/memory/temp/_pre_inject/1400.html

884 lines
46 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>第1周周六下午CSP04班课评</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;600&display=swap');
:root {
--coral: #e85d4c;
--coral-light: #f5a99e;
--coral-dark: #c44738;
--amber: #f0a84a;
--amber-light: #f5d08a;
--ink: #2c2420;
--ink-soft: #5a524e;
--paper: #faf6f1;
--paper-warm: #f5efe8;
--cream: #fffdf9;
--border: #e8e0d8;
--shadow-soft: rgba(44, 36, 32, 0.06);
--shadow-medium: rgba(44, 36, 32, 0.10);
--shadow-card: rgba(44, 36, 32, 0.08);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--paper);
min-height: 100vh;
color: var(--ink);
background-image:
radial-gradient(circle at 20% 50%, rgba(240, 168, 74, 0.03) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(232, 93, 76, 0.02) 0%, transparent 50%),
radial-gradient(circle at 50% 80%, rgba(240, 168, 74, 0.02) 0%, transparent 40%);
}
.topbar {
position: sticky;
top: 0;
z-index: 100;
background: rgba(250, 246, 241, 0.92);
border-bottom: 1px solid var(--border);
padding: 14px 28px;
display: flex;
justify-content: space-between;
align-items: center;
}
.topbar-title {
font-family: 'Noto Serif SC', serif;
font-size: 1.05em;
font-weight: 600;
color: var(--ink);
letter-spacing: 0.5px;
}
.topbar-meta {
font-size: 0.8em;
color: var(--ink-soft);
margin-top: 2px;
}
.topbar-actions {
display: flex;
gap: 10px;
}
.btn {
padding: 8px 18px;
border-radius: 10px;
font-size: 0.85em;
font-weight: 500;
cursor: pointer;
transition: all 0.25s ease;
border: none;
font-family: inherit;
}
.btn-outline {
background: transparent;
border: 1.5px solid var(--border);
color: var(--ink-soft);
}
.btn-outline:hover {
border-color: var(--coral);
color: var(--coral);
background: rgba(232, 93, 76, 0.05);
}
.btn-success {
background: var(--coral);
color: white;
}
.btn-success:hover {
background: var(--coral-dark);
}
.main {
max-width: 680px;
margin: 0 auto;
padding: 28px 20px 160px;
position: relative;
}
.course-hero {
background: linear-gradient(135deg, var(--cream) 0%, var(--paper-warm) 100%);
border-radius: 20px;
padding: 36px 32px 32px;
margin-bottom: 24px;
border: 1px solid var(--border);
position: relative;
overflow: hidden;
box-shadow: 0 2px 8px var(--shadow-soft), 0 8px 32px var(--shadow-card);
}
.course-hero::before {
content: '';
position: absolute;
top: -60px;
right: -40px;
width: 180px;
height: 180px;
border-radius: 50%;
background: radial-gradient(circle, rgba(232, 93, 76, 0.08) 0%, transparent 70%);
}
.course-hero::after {
content: '';
position: absolute;
bottom: -40px;
left: -30px;
width: 140px;
height: 140px;
border-radius: 50%;
background: radial-gradient(circle, rgba(240, 168, 74, 0.06) 0%, transparent 70%);
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 6px;
background: linear-gradient(135deg, var(--coral) 0%, var(--amber) 100%);
color: white;
font-size: 0.75em;
font-weight: 600;
padding: 6px 16px;
border-radius: 20px;
margin-bottom: 16px;
position: relative;
z-index: 1;
letter-spacing: 0.5px;
}
.hero-title {
font-family: 'Noto Serif SC', serif;
font-size: 2.2em;
font-weight: 700;
color: var(--ink);
line-height: 1.3;
margin-bottom: 8px;
position: relative;
z-index: 1;
letter-spacing: 2px;
}
.hero-subtitle {
font-size: 0.95em;
color: var(--ink-soft);
margin-bottom: 20px;
position: relative;
z-index: 1;
}
.hero-divider {
width: 60px;
height: 3px;
background: linear-gradient(90deg, var(--coral), var(--amber));
border-radius: 2px;
margin-bottom: 20px;
position: relative;
z-index: 1;
}
.hero-info {
display: flex;
flex-wrap: wrap;
gap: 16px;
position: relative;
z-index: 1;
}
.hero-info-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.85em;
color: var(--ink-soft);
}
.hero-info-item .icon { font-size: 1.1em; }
.goals-section {
background: var(--cream);
border-radius: 16px;
padding: 24px;
margin-bottom: 28px;
border: 1px solid var(--border);
box-shadow: 0 2px 12px var(--shadow-soft);
}
.goals-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
}
.goals-title {
font-family: 'Noto Serif SC', serif;
font-size: 1em;
font-weight: 600;
color: var(--ink);
display: flex;
align-items: center;
gap: 8px;
}
.goals-title .title-icon { font-size: 1.2em; }
.goals-toggle {
font-size: 0.78em;
color: var(--ink-soft);
cursor: pointer;
background: var(--paper-warm);
border: 1px solid var(--border);
font-family: inherit;
padding: 5px 12px;
border-radius: 8px;
transition: all 0.2s ease;
}
.goals-toggle:hover {
background: var(--coral);
color: white;
border-color: var(--coral);
}
.goals-list {
list-style: none;
display: block;
}
.goals-list.collapsed { display: none; }
.goals-list li {
padding: 12px 16px;
background: var(--paper);
border-radius: 10px;
margin-bottom: 10px;
font-size: 0.9em;
color: var(--ink-soft);
display: flex;
align-items: flex-start;
gap: 12px;
border-left: 3px solid transparent;
transition: all 0.2s ease;
}
.goals-list li:hover {
border-left-color: var(--coral);
background: var(--cream);
transform: translateX(4px);
}
.goals-list li:last-child { margin-bottom: 0; }
.goal-num {
background: linear-gradient(135deg, var(--coral) 0%, var(--amber) 100%);
color: white;
width: 26px;
height: 26px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.78em;
font-weight: 600;
flex-shrink: 0;
margin-top: 1px;
}
.goal-text { flex: 1; line-height: 1.6; }
.cards-slider-wrapper {
position: relative;
border-radius: 16px;
margin-bottom: 20px;
overflow: hidden;
}
.cards-slider {
position: relative;
min-height: 300px;
}
.student-card { display: none; }
.student-card.active { display: block; position: relative; pointer-events: auto; }
.student-card:hover {
box-shadow: 0 8px 32px var(--shadow-medium);
}
.card-header {
padding: 18px 24px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border);
background: linear-gradient(135deg, rgba(250, 246, 241, 0.5) 0%, rgba(245, 239, 232, 0.5) 100%);
border-radius: 16px 16px 0 0;
}
.student-name {
font-family: 'Noto Serif SC', serif;
font-size: 1.15em;
font-weight: 600;
color: var(--ink);
letter-spacing: 1px;
}
.card-badge {
font-size: 0.75em;
padding: 5px 12px;
border-radius: 20px;
font-weight: 500;
}
.badge-normal { background: #e8f5e9; color: #2e7d32; }
.badge-makeup { background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%); color: #e65100; }
.badge-absent { background: #fce4ec; color: #c2185b; }
.card-body { padding: 24px; }
.feedback-content {
font-size: 0.92em;
line-height: 2;
color: var(--ink-soft);
margin-bottom: 20px;
}
.feedback-content[contenteditable="true"] { outline: none; border: 2px dashed transparent; border-radius: 10px; padding: 10px; margin: -10px; transition: all 0.2s ease; }
.feedback-content[contenteditable="true"]:hover { border-color: var(--border); background: var(--paper); }
.feedback-content[contenteditable="true"]:focus { border-color: var(--coral); background: rgba(232, 93, 76, 0.03); }
.side-nav-btn {
position: fixed;
top: 50%;
transform: translateY(-50%);
z-index: 90;
width: 52px;
height: 80px;
border: none;
background: rgba(250, 246, 241, 0.85);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.4em;
color: var(--ink-soft);
transition: all 0.3s ease;
box-shadow: 0 4px 16px var(--shadow-medium);
}
.side-nav-btn:hover:not(:disabled) { background: var(--cream); color: var(--coral); width: 60px; box-shadow: 0 6px 24px rgba(232, 93, 76, 0.15); }
.side-nav-btn:disabled { opacity: 0.25; cursor: not-allowed; }
.side-nav-btn.prev-btn { left: 0; border-radius: 0 12px 12px 0; border-right: 1px solid var(--border); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding-right: 4px; }
.side-nav-btn.next-btn { right: 0; border-radius: 12px 0 0 12px; border-left: 1px solid var(--border); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding-left: 4px; }
.side-nav-btn .arrow { transition: transform 0.3s ease; }
.side-nav-btn:hover .arrow.prev-arrow { transform: translateX(-3px); }
.side-nav-btn:hover .arrow.next-arrow { transform: translateX(3px); }
.nav-controls { display: flex; justify-content: center; align-items: center; gap: 20px; margin-bottom: 16px; }
.page-indicator { font-family: 'Noto Serif SC', serif; font-size: 0.95em; color: var(--ink-soft); font-weight: 500; min-width: 70px; text-align: center; letter-spacing: 1px; }
.progress-dots { display: flex; justify-content: center; gap: 10px; margin-top: 4px; }
.progress-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); cursor: pointer; transition: all 0.3s ease; position: relative; }
.progress-dot.active { background: var(--coral); width: 28px; border-radius: 4px; }
.progress-dot:hover:not(.active) { background: var(--coral-light); transform: scale(1.3); }
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: rgba(250, 246, 241, 0.95);
border-top: 1px solid var(--border);
padding: 14px 24px;
display: flex;
justify-content: center;
gap: 12px;
z-index: 100;
}
.toast {
position: fixed;
bottom: 80px;
left: 50%;
transform: translateX(-50%) translateY(20px);
background: var(--ink);
color: white;
padding: 12px 28px;
border-radius: 10px;
font-size: 0.85em;
opacity: 0;
transition: all 0.3s ease;
pointer-events: none;
z-index: 200;
box-shadow: 0 4px 16px rgba(0,0,0,0.15);
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.edit-mode-badge {
display: none;
position: fixed;
top: 80px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
color: #92400e;
padding: 8px 20px;
border-radius: 20px;
font-size: 0.8em;
font-weight: 500;
z-index: 200;
border: 1px solid #fcd34d;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.edit-mode-badge.show { display: block; }
.footer { text-align: center; padding: 36px 20px; color: #bbb; font-size: 0.78em; font-family: 'Noto Serif SC', serif; letter-spacing: 1px; }
.oj-section { margin-top: 20px; border-radius: 12px; border: 1px solid var(--border); overflow: hidden; background: var(--paper); }
.oj-header { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: linear-gradient(135deg, rgba(232, 93, 76, 0.06) 0%, rgba(240, 168, 74, 0.04) 100%); border-bottom: 1px solid var(--border); font-size: 0.85em; font-weight: 600; color: var(--ink); }
.oj-table { width: 100%; border-collapse: collapse; font-size: 0.82em; }
.oj-table thead th { padding: 10px 14px; text-align: left; font-weight: 600; color: var(--ink-soft); background: var(--cream); border-bottom: 1px solid var(--border); font-size: 0.9em; }
.oj-table thead th:first-child { width: 45%; }
.oj-table thead th:nth-child(2) { width: 18%; }
.oj-table thead th:nth-child(3) { width: 16%; text-align: center; }
.oj-table thead th:last-child { width: 21%; text-align: center; }
.oj-table tbody td { padding: 10px 14px; border-bottom: 1px solid rgba(232, 228, 222, 0.5); color: var(--ink); vertical-align: middle; }
.oj-table tbody tr:last-child td { border-bottom: none; }
.oj-table tbody tr:hover td { background: rgba(232, 93, 76, 0.02); }
.oj-status { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 20px; font-size: 0.88em; font-weight: 500; }
.oj-status.ac { background: #e8f5e9; color: #2e7d32; }
.oj-status.wa { background: #fff3e0; color: #e65100; }
.oj-status.re { background: #fce4ec; color: #c2185b; }
.oj-status.tle { background: #e3f2fd; color: #1565c0; }
.oj-status.pending { background: #f5f5f5; color: #9e9e9e; }
.oj-status-icon { font-size: 1.1em; line-height: 1; }
.oj-submit-count { text-align: center; font-weight: 500; color: var(--ink-soft); }
.oj-submit-count.highlight { color: var(--coral); font-weight: 600; }
.oj-pattern { text-align: center; font-size: 0.9em; color: var(--ink-soft); }
.oj-summary { display: flex; align-items: center; gap: 12px; padding: 10px 16px; background: var(--cream); border-top: 1px solid var(--border); font-size: 0.82em; color: var(--ink-soft); }
.oj-summary .oj-summary-item { display: flex; align-items: center; gap: 4px; }
.oj-summary .oj-summary-num { font-weight: 600; color: var(--ink); }
@media (max-width: 768px){
.hero-title { font-size: 1.7em; }
.side-nav-btn { width: 40px; height: 60px; font-size: 1.1em; }
.main { padding: 20px 16px 160px; }
.course-hero { padding: 28px 20px 24px; }
.oj-table { font-size: 0.78em; }
.oj-table tbody td, .oj-table thead th { padding: 8px 10px; }
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<div class="topbar">
<div>
<div class="topbar-title">第1周 · CSP04班课评</div>
<div class="topbar-meta">2026年9月5日 · 《基础回顾·OJ五题精讲》 · 橙子老师</div>
</div>
<div class="topbar-actions">
<button class="btn btn-outline" onclick="toggleEdit()" id="editBtn">✏️ 编辑</button>
<button class="btn btn-outline" onclick="exportText()">📋 导出</button>
</div>
</div>
<!-- 编辑模式提示 -->
<div class="edit-mode-badge" id="editBadge">📝 编辑模式 · 点击文字即可修改</div>
<!-- 侧边翻页按钮 -->
<button class="side-nav-btn prev-btn" id="sidePrevBtn" onclick="prevCard()" title="上一张">
<span class="arrow prev-arrow">‹</span>
</button>
<button class="side-nav-btn next-btn" id="sideNextBtn" onclick="nextCard()" title="下一张">
<span class="arrow next-arrow">›</span>
</button>
<!-- 主内容 -->
<div class="main">
<!-- 课程封面区域 -->
<div class="course-hero">
<div class="hero-badge">📚 本周课程</div>
<h1 class="hero-title">《基础回顾·OJ五题精讲》</h1>
<p class="hero-subtitle">C++信息奥赛 · 第1课</p>
<div class="hero-divider"></div>
<div class="hero-info">
<div class="hero-info-item"><span class="icon">📅</span><span>2026年9月5日</span></div>
<div class="hero-info-item"><span class="icon">⏰</span><span>周六 14:00-16:00</span></div>
<div class="hero-info-item"><span class="icon">👩‍🏫</span><span>橙子老师</span></div>
</div>
</div>
<!-- 学习目标 -->
<div class="goals-section">
<div class="goals-header">
<span class="goals-title"><span class="title-icon">🎯</span>本周知识点</span>
<button class="goals-toggle" onclick="toggleGoals()">收起</button>
</div>
<ul class="goals-list" id="goalsList"><li><span class="goal-num">1</span><span class="goal-text">字符串处理与回文判断(ASCII大小写转换、双指针)</span></li><li><span class="goal-num">2</span><span class="goal-text">数组有序去重(快慢指针)</span></li><li><span class="goal-num">3</span><span class="goal-text">进制转换(除K取余、映射表0123456789ABCDEF)</span></li><li><span class="goal-num">4</span><span class="goal-text">二进制与位运算(拆位数1、2的幂/幸运数)</span></li><li><span class="goal-num">5</span><span class="goal-text">模拟与状态标记(约瑟夫报数游戏)</span></li></ul>
</div>
<!-- 学生卡片滑动区 -->
<div class="cards-slider-wrapper">
<div class="cards-slider" id="cardsSlider">
<div class="student-card active">
<div class="card-header">
<span class="student-name">郑子煜</span>
<span class="card-badge badge-normal">正常上课</span>
</div>
<div class="card-body">
<div class="feedback-content" data-student="郑子煜">新学期第一课态度认真、跟住老师节奏;尝试回文串和进制数位两道题都还差一点没通,假期后基础需要重新拾起,多复习基础概念、留意语法细节会更稳~</div>
<div class="oj-section" data-oj-section="郑子煜">
<div class="oj-header"><span>📊</span><span>OJ 做题数据 · 题目解析与错因</span></div>
<table class="oj-table">
<thead><tr><th>题目</th><th>状态</th><th style="text-align:center">提交次数</th><th style="text-align:center">思考模式</th><th>解析 / 为什么错</th></tr></thead>
<tbody><tr><td>S0401P1 小杨的回文串</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>CE</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>编译错误——分号/括号/变量名等语法细节未检查,先在本地编译通过</td></tr><tr><td>S0401P2 小杨有序去重</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P3 小杨的进制数位</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count">1</td><td class="oj-pattern">遇到困难</td><td>答案错误——进制转换"除K取余、余数倒序拼+0特判"细节未掌握</td></tr><tr><td>S0401A6 基础回顾-选择</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401A7 基础回顾-判断</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P4 小杨的幸运数字</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P5 小杨的报数游戏</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr></tbody>
</table>
<div class="oj-summary">
<div class="oj-summary-item"><span>完成:</span><span class="oj-summary-num">0/2</span></div>
<div class="oj-summary-item"><span>AC:</span><span class="oj-summary-num">0</span></div>
<div class="oj-summary-item"><span>总提交:</span><span class="oj-summary-num">3</span></div>
</div>
</div>
</div>
</div><div class="student-card">
<div class="card-header">
<span class="student-name">张雨禾</span>
<span class="card-badge badge-normal">正常上课</span>
</div>
<div class="card-body">
<div class="feedback-content" data-student="张雨禾">专注、坐得住,态度认真;尝试5题共10次提交,仅进制数位一次通过,其余多为审题粗心和语法小错,每天复习、写完自查会更好~</div>
<div class="oj-section" data-oj-section="张雨禾">
<div class="oj-header"><span>📊</span><span>OJ 做题数据 · 题目解析与错因</span></div>
<table class="oj-table">
<thead><tr><th>题目</th><th>状态</th><th style="text-align:center">提交次数</th><th style="text-align:center">思考模式</th><th>解析 / 为什么错</th></tr></thead>
<tbody><tr><td>S0401P1 小杨的回文串</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>答案错误——先数原串大小写个数再转,别转完再统计</td></tr><tr><td>S0401P2 小杨有序去重</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>CE</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>编译错误——语法细节未检查</td></tr><tr><td>S0401P3 小杨的进制数位</td><td><span class="oj-status ac"><span class="oj-status-icon">✓</span>AC</span></td><td class="oj-submit-count">1</td><td class="oj-pattern">一气呵成</td><td>进制数位一次过,掌握扎实</td></tr><tr><td>S0401A6 基础回顾-选择</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">3</td><td class="oj-pattern">反复调试</td><td>答案错误——选择/判断题多审题粗心、概念没记牢</td></tr><tr><td>S0401A7 基础回顾-判断</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>答案错误——判断题细节记牢</td></tr><tr><td>S0401P4 小杨的幸运数字</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P5 小杨的报数游戏</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr></tbody>
</table>
<div class="oj-summary">
<div class="oj-summary-item"><span>完成:</span><span class="oj-summary-num">1/5</span></div>
<div class="oj-summary-item"><span>AC:</span><span class="oj-summary-num">1</span></div>
<div class="oj-summary-item"><span>总提交:</span><span class="oj-summary-num">10</span></div>
</div>
</div>
</div>
</div><div class="student-card">
<div class="card-header">
<span class="student-name">苏俊宇</span>
<span class="card-badge badge-normal">正常上课</span>
</div>
<div class="card-body">
<div class="feedback-content" data-student="苏俊宇">认真专注,逻辑思维出色;回文串、有序去重两题一次通过、一气呵成,基础很扎实!把这份思路多落实到手上,再多写几题会更棒~</div>
<div class="oj-section" data-oj-section="苏俊宇">
<div class="oj-header"><span>📊</span><span>OJ 做题数据 · 题目解析与错因</span></div>
<table class="oj-table">
<thead><tr><th>题目</th><th>状态</th><th style="text-align:center">提交次数</th><th style="text-align:center">思考模式</th><th>解析 / 为什么错</th></tr></thead>
<tbody><tr><td>S0401P1 小杨的回文串</td><td><span class="oj-status ac"><span class="oj-status-icon">✓</span>AC</span></td><td class="oj-submit-count">1</td><td class="oj-pattern">一气呵成</td><td>回文判断一次过,思路清晰</td></tr><tr><td>S0401P2 小杨有序去重</td><td><span class="oj-status ac"><span class="oj-status-icon">✓</span>AC</span></td><td class="oj-submit-count">1</td><td class="oj-pattern">一气呵成</td><td>快慢指针去重一次过,掌握扎实</td></tr><tr><td>S0401P3 小杨的进制数位</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401A6 基础回顾-选择</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401A7 基础回顾-判断</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P4 小杨的幸运数字</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P5 小杨的报数游戏</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr></tbody>
</table>
<div class="oj-summary">
<div class="oj-summary-item"><span>完成:</span><span class="oj-summary-num">2/2</span></div>
<div class="oj-summary-item"><span>AC:</span><span class="oj-summary-num">2</span></div>
<div class="oj-summary-item"><span>总提交:</span><span class="oj-summary-num">2</span></div>
</div>
</div>
</div>
</div><div class="student-card">
<div class="card-header">
<span class="student-name">鲍佳音</span>
<span class="card-badge badge-normal">正常上课</span>
</div>
<div class="card-body">
<div class="feedback-content" data-student="鲍佳音">欢迎佳音加入CSP04班!第一次上课就很投入、态度认真;主动尝试5题共10次提交,进制数位一次通过,思维底子不错,继续加油~</div>
<div class="oj-section" data-oj-section="鲍佳音">
<div class="oj-header"><span>📊</span><span>OJ 做题数据 · 题目解析与错因</span></div>
<table class="oj-table">
<thead><tr><th>题目</th><th>状态</th><th style="text-align:center">提交次数</th><th style="text-align:center">思考模式</th><th>解析 / 为什么错</th></tr></thead>
<tbody><tr><td>S0401P1 小杨的回文串</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>答案错误——先数原串大小写个数再转</td></tr><tr><td>S0401P2 小杨有序去重</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>答案错误——快慢指针细节待练</td></tr><tr><td>S0401P3 小杨的进制数位</td><td><span class="oj-status ac"><span class="oj-status-icon">✓</span>AC</span></td><td class="oj-submit-count">1</td><td class="oj-pattern">一气呵成</td><td>进制数位一次过,基础不错</td></tr><tr><td>S0401A6 基础回顾-选择</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">3</td><td class="oj-pattern">反复调试</td><td>答案错误——概念/审题细节</td></tr><tr><td>S0401A7 基础回顾-判断</td><td><span class="oj-status wa"><span class="oj-status-icon">✗</span>WA</span></td><td class="oj-submit-count highlight">2</td><td class="oj-pattern">遇到困难</td><td>答案错误——判断题细节</td></tr><tr><td>S0401P4 小杨的幸运数字</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr><tr><td>S0401P5 小杨的报数游戏</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>未提交(课上未做)</td></tr></tbody>
</table>
<div class="oj-summary">
<div class="oj-summary-item"><span>完成:</span><span class="oj-summary-num">1/5</span></div>
<div class="oj-summary-item"><span>AC:</span><span class="oj-summary-num">1</span></div>
<div class="oj-summary-item"><span>总提交:</span><span class="oj-summary-num">10</span></div>
</div>
</div>
</div>
</div><div class="student-card">
<div class="card-header">
<span class="student-name">卢华琛</span>
<span class="card-badge badge-absent">请假</span>
</div>
<div class="card-body">
<div class="feedback-content" data-student="卢华琛">本周因事请假未到课。请在家复习上学期基础知识,有空到OJ看看《基础回顾》题目,为下节课做好准备;如需补课可联系老师安排。</div>
<div class="oj-section" data-oj-section="卢华琛">
<div class="oj-header"><span>📊</span><span>OJ 做题数据 · 题目解析与错因</span></div>
<table class="oj-table">
<thead><tr><th>题目</th><th>状态</th><th style="text-align:center">提交次数</th><th style="text-align:center">思考模式</th><th>解析 / 为什么错</th></tr></thead>
<tbody><tr><td>S0401P1 小杨的回文串</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401P2 小杨有序去重</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401P3 小杨的进制数位</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401A6 基础回顾-选择</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401A7 基础回顾-判断</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401P4 小杨的幸运数字</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr><tr><td>S0401P5 小杨的报数游戏</td><td><span class="oj-status pending">未提交</span></td><td class="oj-submit-count">0</td><td class="oj-pattern">-</td><td>请假未到课</td></tr></tbody>
</table>
<div class="oj-summary">
<div class="oj-summary-item"><span>完成:</span><span class="oj-summary-num">0/0</span></div>
<div class="oj-summary-item"><span>AC:</span><span class="oj-summary-num">0</span></div>
<div class="oj-summary-item"><span>总提交:</span><span class="oj-summary-num">0</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 导航控制 -->
<div class="nav-controls">
<span class="page-indicator" id="pageIndicator">1 / N</span>
</div>
<!-- 进度点 -->
<div class="progress-dots" id="progressDots">
<div class="progress-dot active" onclick="goToCard(0)"></div><div class="progress-dot" onclick="goToCard(1)"></div><div class="progress-dot" onclick="goToCard(2)"></div><div class="progress-dot" onclick="goToCard(3)"></div><div class="progress-dot" onclick="goToCard(4)"></div>
</div>
<div class="footer">穹狼科创 · CSP04班 · 橙子老师</div>
</div>
<!-- 底部操作栏 -->
<div class="bottom-bar" id="bottomBar" style="display: none;">
<button class="btn btn-outline" onclick="cancelEdit()">取消</button>
<button class="btn btn-success" onclick="saveEdit()">✓ 保存修改</button>
</div>
<!-- 提示条 -->
<div class="toast" id="toast"></div>
<script>
let currentCard = 0;
const totalCards = 5;
const allCards = document.querySelectorAll('.student-card');
const sidePrevBtn = document.getElementById('sidePrevBtn');
const sideNextBtn = document.getElementById('sideNextBtn');
const pageIndicator = document.getElementById('pageIndicator');
const progressDots = document.querySelectorAll('.progress-dot');
function updateSlider() {
allCards.forEach(function(card, i) {
card.classList.remove('active', 'prev');
if (i === currentCard) { card.classList.add('active'); }
else if (i < currentCard) { card.classList.add('prev'); }
});
pageIndicator.textContent = (currentCard + 1) + ' / ' + totalCards;
sidePrevBtn.disabled = currentCard === 0;
sideNextBtn.disabled = currentCard === totalCards - 1;
progressDots.forEach(function(dot, i) { dot.classList.toggle('active', i === currentCard); });
}
function nextCard() { if (currentCard < totalCards - 1) { currentCard++; updateSlider(); } }
function prevCard() { if (currentCard > 0) { currentCard--; updateSlider(); } }
function goToCard(i) { currentCard = i; updateSlider(); }
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowLeft') prevCard();
if (e.key === 'ArrowRight') nextCard();
});
var touchStartX = 0;
var sliderEl = document.getElementById('cardsSlider');
sliderEl.addEventListener('touchstart', function(e) { touchStartX = e.changedTouches[0].screenX; });
sliderEl.addEventListener('touchend', function(e) {
var dx = e.changedTouches[0].screenX;
if (touchStartX - dx > 50) nextCard();
if (dx - touchStartX > 50) prevCard();
});
updateSlider();
function toggleGoals() {
var list = document.getElementById('goalsList');
var btn = document.querySelector('.goals-toggle');
list.classList.toggle('collapsed');
btn.textContent = list.classList.contains('collapsed') ? '展开' : '收起';
}
var originalContent = {};
var originalMetrics = {};
var isEditMode = false;
function toggleEdit() {
isEditMode = !isEditMode;
var feedbacks = document.querySelectorAll('.feedback-content');
var metricComments = document.querySelectorAll('.metric-comment');
var starRatings = document.querySelectorAll('.star-rating');
var editBtn = document.getElementById('editBtn');
var editBadge = document.getElementById('editBadge');
var bottomBar = document.getElementById('bottomBar');
if (isEditMode) {
feedbacks.forEach(function(el) { originalContent[el.dataset.student] = el.innerHTML; });
metricComments.forEach(function(el) {
var key = el.closest('.student-card').querySelector('.student-name').textContent + '-' + el.dataset.metricComment;
originalMetrics[key] = { text: el.innerHTML, score: 0 };
});
starRatings.forEach(function(el) {
var key = el.closest('.student-card').querySelector('.student-name').textContent + '-' + el.closest('.metric-item').dataset.metric;
if (originalMetrics[key]) originalMetrics[key].score = el.dataset.score;
});
feedbacks.forEach(function(el) { el.contentEditable = true; });
metricComments.forEach(function(el) { el.contentEditable = true; });
starRatings.forEach(function(el) { el.classList.add('editable'); });
editBtn.textContent = '✏️ 退出编辑';
editBadge.classList.add('show');
bottomBar.style.display = 'flex';
showToast('编辑模式已开启,点击文字或星星即可修改');
} else {
feedbacks.forEach(function(el) { el.contentEditable = false; });
metricComments.forEach(function(el) { el.contentEditable = false; });
starRatings.forEach(function(el) { el.classList.remove('editable'); });
editBtn.textContent = '✏️ 编辑';
editBadge.classList.remove('show');
bottomBar.style.display = 'none';
}
}
function saveEdit() {
isEditMode = false;
document.querySelectorAll('.feedback-content').forEach(function(el) { el.contentEditable = false; });
document.querySelectorAll('.metric-comment').forEach(function(el) { el.contentEditable = false; });
document.querySelectorAll('.star-rating').forEach(function(el) { el.classList.remove('editable'); });
document.getElementById('editBtn').textContent = '✏️ 编辑';
document.getElementById('editBadge').classList.remove('show');
document.getElementById('bottomBar').style.display = 'none';
originalContent = {};
originalMetrics = {};
showToast('✓ 修改已保存');
}
function cancelEdit() {
isEditMode = false;
document.querySelectorAll('.feedback-content').forEach(function(el) {
if (originalContent[el.dataset.student]) el.innerHTML = originalContent[el.dataset.student];
el.contentEditable = false;
});
document.querySelectorAll('.metric-comment').forEach(function(el) {
var key = el.closest('.student-card').querySelector('.student-name').textContent + '-' + el.dataset.metricComment;
if (originalMetrics[key]) el.innerHTML = originalMetrics[key].text;
el.contentEditable = false;
});
document.querySelectorAll('.star-rating').forEach(function(el) {
var key = el.closest('.student-card').querySelector('.student-name').textContent + '-' + el.closest('.metric-item').dataset.metric;
if (originalMetrics[key]) setStarRating(el, parseInt(originalMetrics[key].score));
el.classList.remove('editable');
});
document.getElementById('editBtn').textContent = '✏️ 编辑';
document.getElementById('editBadge').classList.remove('show');
document.getElementById('bottomBar').style.display = 'none';
originalContent = {};
originalMetrics = {};
showToast('已恢复原始内容');
}
function exportText() {
var text = '第1周周六下午CSP04班课评\n';
text += '2026年9月5日 · 《基础回顾·OJ五题精讲》 · 橙子老师\n';
text += '═══════════════════════════════════════\n\n';
text += '🎯 本周知识点\n';
text += '─────────────────────────────────────\n';
text += '1. 字符串处理与回文判断(ASCII大小写转换、双指针)\n2. 数组有序去重(快慢指针)\n3. 进制转换(除K取余、映射表0123456789ABCDEF)\n4. 二进制与位运算(拆位数1、2的幂/幸运数)\n5. 模拟与状态标记(约瑟夫报数游戏)\n\n';
text += '═══════════════════════════════════════\n\n';
document.querySelectorAll('.student-card').forEach(function(card) {
var name = card.querySelector('.student-name').textContent;
var badge = card.querySelector('.card-badge').textContent;
var feedback = card.querySelector('.feedback-content').innerText;
text += '【' + name + '】' + badge + '\n';
text += '─────────────────────────────────\n';
text += feedback + '\n\n';
card.querySelectorAll('.metric-item').forEach(function(m) {
var label = m.querySelector('.metric-label').textContent;
var rating = m.querySelector('.star-rating');
var score = parseInt(rating.dataset.score);
var scoreLabels = ['未评', '⭐', '⭐⭐', '⭐⭐⭐', '⭐⭐⭐⭐', '⭐⭐⭐⭐⭐'];
var stars = scoreLabels[score] || '未评';
var comment = m.querySelector('.metric-comment').innerText.trim();
if (comment === '点击编辑评语...') comment = '';
text += ' ' + label + ':' + stars;
if (comment) text += '(' + comment + ')';
text += '\n';
});
text += '\n';
});
navigator.clipboard.writeText(text).then(function() {
showToast('✓ 已复制到剪贴板,可直接粘贴发送');
}).catch(function() {
var ta = document.createElement('textarea');
ta.value = text; document.body.appendChild(ta); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
showToast('✓ 已复制到剪贴板');
});
}
function showToast(msg) {
var toast = document.getElementById('toast');
toast.textContent = msg;
toast.classList.add('show');
setTimeout(function() { toast.classList.remove('show'); }, 2000);
}
</script>
</body>
</html>