学生端:目录 + 居中限宽正文 + 可收起的示例代码栏;目录改成三态圆点, 顶部加总进度;上一课/下一课栏桌面端固定在底部。 教师端:汇总卡片、学生状态标签与筛选(未开始/7 天没学/只读不练等)、 最后学习补「N 天前」、按练习表加「没人一次对/多数人卡住」提示。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c228b164cf
commit
20a6ddc79c
7 files changed
+498
-188
No files matched your search
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import { TUTORIAL_READ_SECONDS } from "@oj2/contract"
|
||||
import type { TutorialProgress } from "utils/types"
|
||||
|
||||
const props = defineProps<{
|
||||
titles: { id: number; title: string }[]
|
||||
progress: Record<number, TutorialProgress>
|
||||
traced: boolean
|
||||
}>()
|
||||
|
||||
const stats = computed(() => {
|
||||
const rows = props.titles.map((t) => props.progress[t.id])
|
||||
const read = rows.filter(
|
||||
(p) => p && p.totalSeconds >= TUTORIAL_READ_SECONDS,
|
||||
).length
|
||||
const solved = rows.reduce((n, p) => n + (p?.exerciseSolved ?? 0), 0)
|
||||
const total = rows.reduce((n, p) => n + (p?.exerciseTotal ?? 0), 0)
|
||||
return { read, solved, total }
|
||||
})
|
||||
|
||||
const percent = computed(() =>
|
||||
props.titles.length
|
||||
? Math.round((stats.value.read / props.titles.length) * 100)
|
||||
: 0,
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="traced && titles.length" class="summary">
|
||||
<n-progress
|
||||
type="line"
|
||||
:percentage="percent"
|
||||
:height="8"
|
||||
:show-indicator="false"
|
||||
status="success"
|
||||
/>
|
||||
<n-text depth="3" class="numbers">
|
||||
已读 {{ stats.read }}/{{ titles.length }} 课
|
||||
<template v-if="stats.total">
|
||||
· 练一练 {{ stats.solved }}/{{ stats.total }}
|
||||
</template>
|
||||
</n-text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.summary {
|
||||
padding: 4px 10px 12px;
|
||||
}
|
||||
.numbers {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user