884 lines
46 KiB
HTML
884 lines
46 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>第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>
|