feat(比赛): 比赛页一页看题目和自己的名次;排名竞争感做足、结束有领奖台;老师考试中看全班、考完看成绩;新建比赛一屏做完
Deploy / deploy (push) Canceled after 0s

- 学生比赛页(设计稿 B):左边题目带几人做对、谁最先做对;右边我第几名、5 分钟里升了几名、再做对 1 道能到第几名、我前后的人
- 期中、期末考试中只有自己的进度,写明「排名考完公布」,题目页的排名入口也藏起来
- 排名页:按班筛、名次变化、最先做对的深绿格、自己那行钉住;结束后前三名领奖台 + 我的成绩卡;排名曲线和学生的「导出数据」去掉
- 老师的「全班情况」:卡在一道题、15 分钟没交的放最上面,没进来的人对上看板的请假;考完变「成绩」,点格子看代码、标看过了(代替后台审核页),导出成绩
- 比赛列表:进行中的一大块「接着比」,已结束的写我第几名,前三带奖杯
- 新建比赛:默认 10 分钟后开始,时长点按钮,搜题号把题加进来自动编号、拖动排顺序

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-09 20:58:59 +08:00
1 parent b94e028ff4
commit 151bbdcb50
19 files changed
+3768 -743

No files matched your search

@@ -0,0 +1,65 @@
<script setup lang="ts">
import { isExamTag } from "@oj2/contract"
import { useThemeVars } from "naive-ui"
import { useTone } from "oj/submission/composables/tone"
import { CONTEST_STATUS, ContestStatus } from "utils/constants"
/**
* 比赛的两个小标:状态(进行中 / 未开始 / 已结束)和类型(练习 / 期中 / 期末)。
* 进行中绿、未开始琥珀、已结束灰;期中期末用浅红底 —— 学生一眼知道「这场是考试,排名考完才有」
*/
const props = defineProps<{ status?: ContestStatus; tag?: string }>()
const theme = useThemeVars()
const tone = useTone()
const style = computed(() => {
if (props.status !== undefined) {
const kind =
props.status === ContestStatus.underway
? "success"
: props.status === ContestStatus.not_started
? "warning"
: "default"
const t = tone(kind)
return { color: t.color, background: t.background, border: "1px solid transparent" }
}
if (props.tag && isExamTag(props.tag)) {
const t = tone("error")
return { color: t.color, background: t.background, border: "1px solid transparent" }
}
return {
color: theme.value.textColor3,
background: "transparent",
border: `1px solid ${theme.value.borderColor}`,
}
})
const text = computed(() =>
props.status !== undefined ? CONTEST_STATUS[props.status]?.name : props.tag,
)
</script>
<template>
<span class="badge" :class="{ strong: status === ContestStatus.underway }" :style="style">{{
text
}}</span>
</template>
<style scoped>
.badge {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 8px;
box-sizing: border-box;
border-radius: 3px;
font-size: 12px;
white-space: nowrap;
flex-shrink: 0;
}
.strong {
font-weight: 600;
}
</style>