style(题目): 题目页照设计稿「机房(方案 B)」重排——顶满的两栏、带底色的上下文条、下划线页签、新的结果和题面样式
Deploy / deploy (push) Canceled after 0s

原来实施时只照了设计文档,没对照设计稿,一路套 Naive 现成的分段页签、提示框、单选组,
功能对了、样子差很多。这次逐块对着设计稿的画板改:

- 两栏顶满内容区,中间一条 1px 分隔线;上下文条、页签行、工具栏下面各一道分隔线
- 上下文条:课堂浅绿、题单浅蓝、比赛浅黄三种底色;‹ › 是不带边框的箭头;比赛的题号是方角、
  做错的是红色 ✕;手机上不摆一排题号,写「这节课 做完 2/5 · 这是第 3 道」配 44px 的箭头
- 「题目 / 结果」是下划线页签,右边「统计 / 点评 / 我的提交」是胶囊按钮
- 抽屉盖住整个左栏(连上下文条、页签行),顶上有自己的「我的提交 / 统计 / 点评」页签,Esc 能关
- 结果页签:三个分段是胶囊,选中的深色实心、带时间(「提交结果 · 10:42」);标题是圆形图标 +
  大字 + 灰字(「答案错误 在例子 1 上就错了」),不再套整块彩色提示框;答错的对比三栏并排、
  只把不一样的那几个字标红;「题目要求的输出」是一行小字;「让 AI 分析我的代码」是描边按钮;
  答对后的「下一题」是浅绿卡片里 44px 的大按钮
- 工具栏:语言、运行例子(描边)、提交(实心,就叫「提交」)靠左,求助、⋯ 推到最右;
  交对之后「提交」变成绿色描边;协作条换成设计稿的深蓝
- 题面:标题下「简单 · 还没交过」,流程图过关的加「流程图 A 级」;代码要求压成一行;
  小标题不带图标;输入、输出左右两栏;参考流程图是一行可以点开的条;例子表带「例子 1」和「复制」
- 去掉「限时 1 秒」:执行时间、内存对中职学生只会添迷惑(和设计稿不同,用户定的)
- 我的提交:一整块带框的列表,结果用彩色文字;展开的代码先露 5 行;题单锁住的几次合成一行
- 错在隐藏测试点时「去自己输入」给的数跳过例子里出现过的

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-09-28 20:04:20 +08:00
1 parent 83b6b7a81a
commit 1fd9bf67c2
17 files changed
+1800 -706

No files matched your search

@@ -10,7 +10,7 @@ import { useUserStore } from "shared/store/user"
import storage from "utils/storage"
import type { LANGUAGE } from "utils/types"
import { Icon } from "@iconify/vue"
import { NFlex } from "naive-ui"
import { NFlex, useThemeVars } from "naive-ui"
import SubmitCode from "./SubmitCode.vue"
import { useProblemPageContext } from "../composables/problemPageContext"
import { statisticsOpen, useEditorMenu } from "../composables/editorMenu"
@@ -44,6 +44,7 @@ const mode = computed({
})
const { isDesktop } = useBreakpoints()
const theme = useThemeVars()
/**
* 「运行例子」:用题目里的例子试跑(Judge0),结果在左栏「结果」页签。顶替原来题面里
@@ -119,8 +120,8 @@ const toggleHelp = () => {
* 所以次要的按钮收进「更多」、「写代码 / 画流程图」缩短一点(设计文档 5.4)。语言下拉不收:
* 窄于 120px 时图标和「Python」会被挤成两行
*/
const toolbarRef = useTemplateRef<{ $el: HTMLElement }>("toolbarRef")
const { width: toolbarWidth } = useElementSize(() => toolbarRef.value?.$el)
const toolbarRef = useTemplateRef<HTMLElement>("toolbarRef")
const { width: toolbarWidth } = useElementSize(toolbarRef)
const narrow = computed(() => isDesktop.value && toolbarWidth.value > 0 && toolbarWidth.value < 600)
/** 「课堂统计」常驻在工具栏上:桌面、而且放得下 */
const statisticsInline = computed(() => isDesktop.value && !narrow.value)
@@ -152,7 +153,8 @@ const changeLanguage = (v: LANGUAGE) => {
</script>
<template>
<n-flex ref="toolbarRef" align="center" :size="narrow ? 8 : 12">
<!-- 设计稿:语言、运行例子、提交靠左;求助、课堂统计、⋯ 推到最右 -->
<div ref="toolbarRef" class="toolbar" :class="{ narrow }">
<!-- 协作中的老师不会落到画图:求助入口本身就排掉了流程图 -->
<n-radio-group v-if="canDraw && !showCollabBar" v-model:value="mode" :size="buttonSize">
<n-radio-button value="code">{{ narrow ? "代码" : "写代码" }}</n-radio-button>
@@ -174,6 +176,8 @@ const changeLanguage = (v: LANGUAGE) => {
<n-button
v-if="canRunSamples && isDesktop"
:size="buttonSize"
type="primary"
ghost
:loading="samplesRunning"
:disabled="!codeStore.code.value.trim()"
@click="submissionStore.runSamples()"
@@ -185,6 +189,22 @@ const changeLanguage = (v: LANGUAGE) => {
<SubmitCode v-else-if="isDesktop" />
<div class="spacer" />
<n-button
v-if="showHelpButton"
:size="buttonSize"
:type="helpButtonType"
:secondary="collabStore.helpStatus !== 'idle'"
:disabled="collabStore.helpStatus === 'active'"
:title="helpButtonTitle"
class="help"
@click="toggleHelp"
>
<span v-if="collabStore.helpStatus === 'active'" class="dot" aria-hidden="true" />
{{ helpButtonText }}
</n-button>
<n-button
v-if="statisticsInline && userStore.isTeacherOrAbove"
:size="buttonSize"
@@ -200,20 +220,44 @@ const changeLanguage = (v: LANGUAGE) => {
:options="menuOptions"
@select="handleMenuSelect"
>
<n-button :size="buttonSize" :title="narrow ? '更多' : undefined">
{{ narrow ? "⋯" : "更多" }}
<n-button :size="buttonSize" class="more" aria-label="更多:去自测猫、复制代码、重置代码……">
⋯
</n-button>
</n-dropdown>
<n-button
v-if="showHelpButton"
:size="buttonSize"
:type="helpButtonType"
:disabled="collabStore.helpStatus === 'active'"
:title="helpButtonTitle"
@click="toggleHelp"
>
{{ helpButtonText }}
</n-button>
</n-flex>
</div>
</template>
<style scoped>
.toolbar {
height: 48px;
flex: none;
box-sizing: border-box;
padding: 0 14px;
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid v-bind("theme.dividerColor");
}
.toolbar.narrow {
gap: 6px;
padding: 0 10px;
}
.spacer {
flex: 1 1 0;
}
.more {
width: 34px;
padding: 0;
}
.help .dot {
width: 8px;
height: 8px;
margin-right: 6px;
border-radius: 50%;
background-color: v-bind("theme.successColor");
}
</style>