diff --git a/apps/web/src/oj/problem/components/ResultPane.vue b/apps/web/src/oj/problem/components/ResultPane.vue
new file mode 100644
index 0000000..978f896
--- /dev/null
+++ b/apps/web/src/oj/problem/components/ResultPane.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
diff --git a/apps/web/src/oj/problem/components/ResultTabLabel.vue b/apps/web/src/oj/problem/components/ResultTabLabel.vue
new file mode 100644
index 0000000..478121b
--- /dev/null
+++ b/apps/web/src/oj/problem/components/ResultTabLabel.vue
@@ -0,0 +1,60 @@
+
+
+
+
+ 结果
+
+
+
+
+
diff --git a/apps/web/src/oj/problem/components/SubmissionEffects.vue b/apps/web/src/oj/problem/components/SubmissionEffects.vue
index 6114280..717b5ea 100644
--- a/apps/web/src/oj/problem/components/SubmissionEffects.vue
+++ b/apps/web/src/oj/problem/components/SubmissionEffects.vue
@@ -73,9 +73,8 @@ function settleReview() {
function closeCommentPanel() {
commentPanel.value = false
- // 点评价弹窗时,结果面板会当成「点了外面」收起来 —— 而「下一题」就在面板里
- // (LessonNext),评价完得把它重新打开
- submissionStore.showResult = true
+ // 「下一题」在结果页签里(LessonNext),评价完回到那里 —— 学生点评之前可能切去看了题目
+ submissionStore.revealResult()
settleReview()
}
diff --git a/apps/web/src/oj/problem/components/SubmitCode.vue b/apps/web/src/oj/problem/components/SubmitCode.vue
index b00338d..f7b98cb 100644
--- a/apps/web/src/oj/problem/components/SubmitCode.vue
+++ b/apps/web/src/oj/problem/components/SubmitCode.vue
@@ -1,6 +1,5 @@
-
-
-
-
-
-
-
-
-
- {{ buttonState.label }}
-
-
-
-
-
-
-
-
-
-
-
- 上次结果
+
+
+
+
+
+ {{ buttonState.label }}
diff --git a/apps/web/src/oj/problem/detail.vue b/apps/web/src/oj/problem/detail.vue
index 7e5092e..68cb644 100644
--- a/apps/web/src/oj/problem/detail.vue
+++ b/apps/web/src/oj/problem/detail.vue
@@ -11,6 +11,7 @@ import { useSubmissionStore } from "oj/store/submission"
import { useFlowchartStore } from "oj/store/flowchart"
// 判完之后该发生的事(烟花、点评、回题单)。静态引入:它得在第一次判完之前就挂好
import SubmissionEffects from "./components/SubmissionEffects.vue"
+import ResultTabLabel from "./components/ResultTabLabel.vue"
// 抽成具名 loader,便于进页面时与接口并行预取编辑器 chunk。
// 题库、比赛、题单三种入口用的是同一个编辑器:原来比赛和题单用的是另一个精简版,
@@ -25,6 +26,7 @@ const ProblemSubmission = defineAsyncComponent(() => import("./components/Proble
const ProblemReaction = defineAsyncComponent(() => import("./components/ProblemReaction.vue"))
const ProblemFlowchart = defineAsyncComponent(() => import("./components/ProblemFlowchart.vue"))
const MyFlowchartTab = defineAsyncComponent(() => import("./components/MyFlowchartTab.vue"))
+const ResultPane = defineAsyncComponent(() => import("./components/ResultPane.vue"))
interface Props {
problemID: string
@@ -55,13 +57,15 @@ const canShowFlowchart = computed(
)
const tabOptions = computed(() => {
+ // 桌面上「结果」紧跟在「题目」后面;手机上编辑器也是一个页签,「结果」排在「代码」后面
const options: string[] = ["content"]
+ if (!isMobile.value) options.push("result")
if (canShowFlowchart.value) {
options.push("flowchart")
}
if (isMobile.value) {
- options.push("editor")
+ options.push("editor", "result")
}
options.push("info")
if (!contestID) {
@@ -93,6 +97,18 @@ watch(currentTab, (tab) => {
})
})
+// 交上去、或者语法检查没过:切到「结果」。提交按钮在编辑器那边,页签归这一页管
+const submissionStore = useSubmissionStore()
+watch(
+ () => submissionStore.resultSeq,
+ () => {
+ currentTab.value = "result"
+ },
+)
+
+// 结果页签的标题带状态图标(ResultTabLabel),n-tab-pane 的 tab 接受渲染函数
+const resultTab = () => h(ResultTabLabel)
+
watch(
() => myFlowchartStore.showing,
(showing) => {
@@ -175,9 +191,13 @@ watch(
-
+
+
+
+
+
@@ -210,9 +230,12 @@ watch(
-
+
+
+
+
@@ -234,7 +257,7 @@ watch(
-
+
@@ -243,6 +266,9 @@ watch(
+
+
+
diff --git a/apps/web/src/oj/store/submission.ts b/apps/web/src/oj/store/submission.ts
index 3f48d04..a4040a3 100644
--- a/apps/web/src/oj/store/submission.ts
+++ b/apps/web/src/oj/store/submission.ts
@@ -12,7 +12,7 @@ import type { SubmitCodePayload } from "utils/types"
/**
* 题目页上「这一次提交」的全部状态:正在跟的那条提交、判题跟踪(WebSocket + 轮询)、
- * 提交前语法检查的错误、结果面板开没开、5 秒冷却、AI 提示。
+ * 提交前语法检查的错误、5 秒冷却、AI 提示。
*
* 原来它们都长在提交按钮那个组件(SubmitCode)里,而那个组件在编辑器的工具栏里 ——
* 手机上交完切到「描述」页签(Naive 的页签默认切走即卸载)、桌面切到「题目 / 自测」
@@ -30,8 +30,14 @@ export const useSubmissionStore = defineStore("submission", () => {
const monitor = useSubmissionMonitor()
const hint = useSubmissionHint()
- /** 结果面板开着没有。放 store 里是为了按钮组件卸了再挂回来,面板还是原来的开合 */
- const showResult = ref(false)
+ /**
+ * 有新结果要给学生看了(交上去、或者语法检查没过)就 +1。题目页看着它把左栏切到
+ * 「结果」页签 —— store 不管页签,只说「该看结果了」。
+ */
+ const resultSeq = ref(0)
+ function revealResult() {
+ resultSeq.value++
+ }
const isFormatting = ref(false)
const isSubmittingRequest = ref(false)
@@ -73,7 +79,7 @@ export const useSubmissionStore = defineStore("submission", () => {
if (errorCode(e) === "syntax-error") {
// 仅 Python 会出现:message 是 CPython 的报错原文,交给 PythonErrorExplain 翻译
syntaxErrorInfo.value = errorMessage(e)
- showResult.value = true
+ revealResult()
return
}
// server-error / 网络异常:格式化工具问题,静默降级,提交原代码
@@ -111,19 +117,18 @@ export const useSubmissionStore = defineStore("submission", () => {
// 3. 启动冷却 + 监控
startCooldown()
monitor.startMonitoring(res.submissionId)
- showResult.value = true
+ revealResult()
} finally {
isSubmittingRequest.value = false
}
}
/**
- * 收掉这一道题的所有东西:结果面板、语法错误、还在跟的那条提交、AI 提示。
+ * 收掉这一道题的所有东西:语法错误、还在跟的那条提交、AI 提示。
* 提交本身照常判完落库,只是这边不再跟 —— 不然上一道还在判的那条判完,
* 会把**新题**标成已解决。
*/
function reset() {
- showResult.value = false
syntaxErrorInfo.value = ""
monitor.reset()
hint.clearHint()
@@ -147,7 +152,8 @@ export const useSubmissionStore = defineStore("submission", () => {
judging: monitor.judging,
pending: monitor.pending,
submitting: monitor.submitting,
- showResult,
+ resultSeq,
+ revealResult,
isFormatting,
isSubmittingRequest,
syntaxErrorInfo,