From e539f9450a016b3dab11aeb5780a129ce37ae19b Mon Sep 17 00:00:00 2001
From: yuetsh <517252939@qq.com>
Date: Tue, 31 Mar 2026 07:41:35 -0600
Subject: [PATCH] refactor
---
src/components/Challenge.vue | 27 +++++++++++++--
src/components/Task.vue | 66 +++++++++++++++++++-----------------
src/components/Toolbar.vue | 7 ++--
src/components/Tutorial.vue | 27 ++-------------
src/pages/ChallengeHome.vue | 1 +
src/pages/Home.vue | 8 ++---
src/store/panel.ts | 5 +++
src/store/task.ts | 5 +--
src/store/tutorial.ts | 23 +++++++++++--
src/utils/type.ts | 2 ++
10 files changed, 101 insertions(+), 70 deletions(-)
create mode 100644 src/store/panel.ts
diff --git a/src/components/Challenge.vue b/src/components/Challenge.vue
index 84630c5..9efd655 100644
--- a/src/components/Challenge.vue
+++ b/src/components/Challenge.vue
@@ -6,14 +6,20 @@
v-for="item in challenges"
:key="item.display"
hoverable
- class="challenge-card"
+ :class="['challenge-card', { submitted: item.submitted }]"
@click="select(item)"
>
- {{ item.title }}
+
+ ✓
+ {{ item.title }}
+
- {{ item.score }}分
+
+ {{ item.score }} 分
+ 及格 {{ item.pass_score }} 分
+
@@ -47,4 +53,19 @@ onMounted(async () => {
.challenge-card {
cursor: pointer;
}
+
+.challenge-card.submitted {
+ background-color: #f6ffed;
+ border-color: #b7eb8f;
+}
+
+.check-icon {
+ color: #52c41a;
+ font-size: 14px;
+ font-weight: bold;
+}
+
+.submitted-title {
+ color: #888;
+}
diff --git a/src/components/Task.vue b/src/components/Task.vue
index 1fa9e33..20c71b0 100644
--- a/src/components/Task.vue
+++ b/src/components/Task.vue
@@ -21,18 +21,11 @@
-
+
-
+ {{ progressText }}
+
@@ -56,16 +49,16 @@
-
+
diff --git a/src/components/Toolbar.vue b/src/components/Toolbar.vue
index 89856ea..0eaefbc 100644
--- a/src/components/Toolbar.vue
+++ b/src/components/Toolbar.vue
@@ -31,8 +31,9 @@ import { computed, h } from "vue"
import { Icon } from "@iconify/vue"
import { authed, roleNormal, roleSuper, user } from "../store/user"
import { loginModal } from "../store/modal"
-import { show, tutorialSize, step } from "../store/tutorial"
-import { taskId, taskTab } from "../store/task"
+import { show, panelSize } from "../store/panel"
+import { step } from "../store/tutorial"
+import { taskId } from "../store/task"
import { Account } from "../api"
import { Role } from "../utils/type"
import { router } from "../router"
@@ -90,7 +91,7 @@ const menu = computed(() => [
function showTutorial() {
show.value = true
- tutorialSize.value = 2 / 5
+ panelSize.value = 2 / 5
}
function clickMenu(name: string) {
diff --git a/src/components/Tutorial.vue b/src/components/Tutorial.vue
index 0e05d8b..dc4f955 100644
--- a/src/components/Tutorial.vue
+++ b/src/components/Tutorial.vue
@@ -7,7 +7,7 @@ import { marked } from "marked"
import copyFn from "copy-text-to-clipboard"
import { css, html, js, tab } from "../store/editors"
import { Tutorial } from "../api"
-import { step } from "../store/tutorial"
+import { step, tutorialIds } from "../store/tutorial"
import { taskId } from "../store/task"
import { useRouter } from "vue-router"
@@ -33,32 +33,9 @@ marked.use({
})
const router = useRouter()
-const tutorialIds = ref([])
const content = ref("")
const $content = useTemplateRef("$content")
-const prevDisabled = () => {
- const i = tutorialIds.value.indexOf(step.value)
- return i <= 0
-}
-
-const nextDisabled = () => {
- const i = tutorialIds.value.indexOf(step.value)
- return i === tutorialIds.value.length - 1
-}
-
-function prev() {
- const i = tutorialIds.value.indexOf(step.value)
- step.value = tutorialIds.value[i - 1] as number
-}
-
-function next() {
- const i = tutorialIds.value.indexOf(step.value)
- step.value = tutorialIds.value[i + 1] as number
-}
-
-defineExpose({ tutorialIds, prevDisabled, nextDisabled, prev, next })
-
async function prepare() {
tutorialIds.value = await Tutorial.listDisplay()
if (!tutorialIds.value.length) {
@@ -73,7 +50,7 @@ async function prepare() {
async function render() {
const data = await Tutorial.get(step.value)
taskId.value = data.task_ptr
- const merged = `# #${data.display} ${data.title}\n${data.content}`
+ const merged = `# ${data.display}. ${data.title}\n${data.content}`
content.value = await marked.parse(merged, { async: true })
}
diff --git a/src/pages/ChallengeHome.vue b/src/pages/ChallengeHome.vue
index d9b3b54..e002c0f 100644
--- a/src/pages/ChallengeHome.vue
+++ b/src/pages/ChallengeHome.vue
@@ -134,6 +134,7 @@ function clearAll() {
function back() {
disconnectPrompt()
+ taskId.value = 0
router.push({ name: "home-challenge-list" })
}
diff --git a/src/pages/Home.vue b/src/pages/Home.vue
index dea3272..cc1d6d5 100644
--- a/src/pages/Home.vue
+++ b/src/pages/Home.vue
@@ -1,6 +1,6 @@
0) show.value = true
}
function hide() {
- tutorialSize.value = 0
+ panelSize.value = 0
show.value = false
}
diff --git a/src/store/panel.ts b/src/store/panel.ts
new file mode 100644
index 0000000..9fa600b
--- /dev/null
+++ b/src/store/panel.ts
@@ -0,0 +1,5 @@
+// client/src/store/panel.ts
+import { ref } from "vue"
+
+export const show = ref(true)
+export const panelSize = ref(2 / 5)
diff --git a/src/store/task.ts b/src/store/task.ts
index 4fbdc69..d778b4c 100644
--- a/src/store/task.ts
+++ b/src/store/task.ts
@@ -1,8 +1,9 @@
import { ref } from "vue"
import { TASK_TYPE } from "../utils/const"
-const urlParams = new URLSearchParams(window.location.search)
-const currentTask = (urlParams.get("task") as TASK_TYPE) ?? TASK_TYPE.Tutorial
+const currentTask = window.location.pathname.startsWith("/challenge")
+ ? TASK_TYPE.Challenge
+ : TASK_TYPE.Tutorial
export const taskTab = ref(currentTask)
export const taskId = ref(0)
diff --git a/src/store/tutorial.ts b/src/store/tutorial.ts
index 5a1799a..330cca5 100644
--- a/src/store/tutorial.ts
+++ b/src/store/tutorial.ts
@@ -4,6 +4,25 @@ const urlParams = new URLSearchParams(window.location.search)
const currentStep = urlParams.get("step") ?? "1"
export const step = ref(Number(currentStep))
+export const tutorialIds = ref([])
-export const show = ref(true)
-export const tutorialSize = ref(2 / 5)
+export function prevDisabled(): boolean {
+ const i = tutorialIds.value.indexOf(step.value)
+ return i <= 0
+}
+
+export function nextDisabled(): boolean {
+ const i = tutorialIds.value.indexOf(step.value)
+ return i === -1 || i === tutorialIds.value.length - 1
+}
+
+export function prev(): void {
+ const i = tutorialIds.value.indexOf(step.value)
+ if (i > 0) step.value = tutorialIds.value[i - 1] as number
+}
+
+export function next(): void {
+ const i = tutorialIds.value.indexOf(step.value)
+ if (i !== -1 && i < tutorialIds.value.length - 1)
+ step.value = tutorialIds.value[i + 1] as number
+}
diff --git a/src/utils/type.ts b/src/utils/type.ts
index 1224f63..f648169 100644
--- a/src/utils/type.ts
+++ b/src/utils/type.ts
@@ -47,6 +47,8 @@ export interface ChallengeSlim {
display: number
title: string
score: number
+ pass_score: number | null
+ submitted: boolean
is_public: boolean
}