From 78a2d843351aa67dadf76c6e7e414bbba273d362 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Wed, 4 Mar 2026 00:04:45 +0800 Subject: [PATCH] update --- components.d.ts | 4 +- src/api.ts | 33 ++- src/components/Challenge.vue | 76 ++++- src/components/Editors.vue | 98 +++++-- src/components/Task.vue | 273 ++++-------------- src/components/{Corner.vue => Toolbar.vue} | 34 +-- src/components/Tutorial.vue | 203 +++++++++++++ src/components/submissions/NameWithFilter.vue | 1 - src/pages/Challenge.vue | 1 - src/pages/ChallengeEditor.vue | 182 ++++++++++++ src/pages/Dashboard.vue | 7 +- src/pages/Submissions.vue | 43 +-- .../{Tutorial.vue => TutorialEditor.vue} | 2 +- src/router.ts | 14 +- src/store/task.ts | 1 + src/utils/helper.ts | 10 +- src/utils/type.ts | 15 + 17 files changed, 687 insertions(+), 310 deletions(-) rename src/components/{Corner.vue => Toolbar.vue} (78%) create mode 100644 src/components/Tutorial.vue delete mode 100644 src/components/submissions/NameWithFilter.vue delete mode 100644 src/pages/Challenge.vue create mode 100644 src/pages/ChallengeEditor.vue rename src/pages/{Tutorial.vue => TutorialEditor.vue} (98%) diff --git a/components.d.ts b/components.d.ts index bd742c4..3fe1446 100644 --- a/components.d.ts +++ b/components.d.ts @@ -12,13 +12,11 @@ export {} declare module 'vue' { export interface GlobalComponents { Challenge: typeof import('./src/components/Challenge.vue')['default'] - Corner: typeof import('./src/components/Corner.vue')['default'] Editor: typeof import('./src/components/Editor.vue')['default'] Editors: typeof import('./src/components/Editors.vue')['default'] Login: typeof import('./src/components/Login.vue')['default'] MarkdownEditor: typeof import('./src/components/dashboard/MarkdownEditor.vue')['default'] NAlert: typeof import('naive-ui')['NAlert'] - NameWithFilter: typeof import('./src/components/submissions/NameWithFilter.vue')['default'] NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] NCode: typeof import('naive-ui')['NCode'] @@ -53,6 +51,8 @@ declare module 'vue' { RouterView: typeof import('vue-router')['RouterView'] Task: typeof import('./src/components/Task.vue')['default'] TaskTitle: typeof import('./src/components/submissions/TaskTitle.vue')['default'] + Toolbar: typeof import('./src/components/Toolbar.vue')['default'] + Tutorial: typeof import('./src/components/Tutorial.vue')['default'] UserActions: typeof import('./src/components/dashboard/UserActions.vue')['default'] } } diff --git a/src/api.ts b/src/api.ts index d63032b..05aab71 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,6 +1,6 @@ import axios from "axios" import { router } from "./router" -import type { TutorialIn } from "./utils/type" +import type { TutorialIn, ChallengeIn } from "./utils/type" import { BASE_URL, STORAGE_KEY } from "./utils/const" const http = axios.create({ @@ -100,6 +100,37 @@ export const Tutorial = { }, } +export const Challenge = { + async list() { + const res = await http.get("/challenge/list") + return res.data + }, + + async createOrUpdate(payload: ChallengeIn) { + const res = await http.post("/challenge/", payload) + return res.data + }, + + async togglePublic(display: number) { + const res = await http.put(`/challenge/public/${display}`) + return res.data + }, + + async remove(display: number) { + await http.delete(`/challenge/${display}`) + }, + + async get(display: number) { + const res = await http.get(`/challenge/${display}`) + return res.data + }, + + async listDisplay() { + const res = await http.get("/challenge/display") + return res.data + }, +} + export const Submission = { async create( taskId: number, diff --git a/src/components/Challenge.vue b/src/components/Challenge.vue index 0cd8f41..bd3bc85 100644 --- a/src/components/Challenge.vue +++ b/src/components/Challenge.vue @@ -1,14 +1,86 @@ diff --git a/src/components/Editors.vue b/src/components/Editors.vue index f9872ec..a92a458 100644 --- a/src/components/Editors.vue +++ b/src/components/Editors.vue @@ -67,7 +67,11 @@ @@ -79,12 +83,16 @@ import * as cssParser from "prettier/parser-postcss" import * as babelParser from "prettier/parser-babel" import * as estreeParser from "prettier/plugins/estree" import Editor from "./Editor.vue" -import Corner from "./Corner.vue" +import Toolbar from "./Toolbar.vue" import { html, css, js, tab, size, reset } from "../store/editors" -import { NCode, useDialog } from "naive-ui" -import { h } from "vue" +import { taskId } from "../store/task" +import { Submission } from "../api" +import { NCode, useDialog, useMessage } from "naive-ui" +import { h, ref } from "vue" const dialog = useDialog() +const message = useMessage() +const submitLoading = ref(false) function changeTab(name: string) { tab.value = name @@ -94,30 +102,34 @@ function changeSize(num: number) { size.value = num } +async function formatCode() { + const [htmlFormatted, cssFormatted, jsFormatted] = await Promise.all([ + prettier.format(html.value, { + parser: "html", + //@ts-ignore + plugins: [htmlParser, babelParser, estreeParser, cssParser], + tabWidth: 4, + }), + prettier.format(css.value, { + parser: "css", + plugins: [cssParser], + tabWidth: 4, + }), + prettier.format(js.value, { + parser: "babel", + //@ts-ignore + plugins: [babelParser, estreeParser], + tabWidth: 2, + }), + ]) + html.value = htmlFormatted + css.value = cssFormatted + js.value = jsFormatted +} + async function format() { try { - const [htmlFormatted, cssFormatted, jsFormatted] = await Promise.all([ - prettier.format(html.value, { - parser: "html", - //@ts-ignore - plugins: [htmlParser, babelParser, estreeParser, cssParser], - tabWidth: 4, - }), - prettier.format(css.value, { - parser: "css", - plugins: [cssParser], - tabWidth: 4, - }), - prettier.format(js.value, { - parser: "babel", - //@ts-ignore - plugins: [babelParser, estreeParser], - tabWidth: 2, - }), - ]) - html.value = htmlFormatted - css.value = cssFormatted - js.value = jsFormatted + await formatCode() } catch (err: any) { dialog.error({ title: "格式化失败", @@ -126,6 +138,40 @@ async function format() { }) } } + +async function doSubmit() { + try { + await Submission.create(taskId.value, { + html: html.value, + css: css.value, + js: js.value, + }) + message.success("提交成功") + } catch (err) { + message.error("提交失败") + } +} + +async function formatAndSubmit() { + submitLoading.value = true + try { + await formatCode() + await doSubmit() + } catch (err: any) { + dialog.warning({ + title: "代码整理失败", + content: () => h(NCode, { code: err.message }), + positiveText: "忽略并提交", + negativeText: "取消", + style: { width: "auto" }, + onPositiveClick: async () => { + await doSubmit() + }, + }) + } finally { + submitLoading.value = false + } +} - diff --git a/src/components/Corner.vue b/src/components/Toolbar.vue similarity index 78% rename from src/components/Corner.vue rename to src/components/Toolbar.vue index f94302e..012a02b 100644 --- a/src/components/Corner.vue +++ b/src/components/Toolbar.vue @@ -10,7 +10,7 @@ secondary :disabled="submitDisabled" :loading="submitLoading" - @click="submit" + @click="emit('submit')" > 提交 @@ -29,23 +29,21 @@ + diff --git a/src/components/submissions/NameWithFilter.vue b/src/components/submissions/NameWithFilter.vue deleted file mode 100644 index cc340bc..0000000 --- a/src/components/submissions/NameWithFilter.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/pages/Challenge.vue b/src/pages/Challenge.vue deleted file mode 100644 index c80b7a5..0000000 --- a/src/pages/Challenge.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/pages/ChallengeEditor.vue b/src/pages/ChallengeEditor.vue new file mode 100644 index 0000000..01c49ee --- /dev/null +++ b/src/pages/ChallengeEditor.vue @@ -0,0 +1,182 @@ + + + diff --git a/src/pages/Dashboard.vue b/src/pages/Dashboard.vue index 39e49db..b5104dd 100644 --- a/src/pages/Dashboard.vue +++ b/src/pages/Dashboard.vue @@ -26,9 +26,12 @@ import { goHome } from "../utils/helper" const menu = [ { label: "教程", - route: { name: "tutorial", params: { display: step.value } }, + route: { name: "tutorial-editor", params: { display: step.value } }, + }, + { + label: "挑战", + route: { name: "challenge-editor", params: { display: 0 } }, }, - { label: "挑战", route: { name: "challenge" } }, { label: "用户", route: { name: "user-manage", params: { page: 1 } } }, { label: "提交", route: { name: "submissions", params: { page: 1 } } }, ] diff --git a/src/pages/Submissions.vue b/src/pages/Submissions.vue index ebdcf5f..2e9f4ee 100644 --- a/src/pages/Submissions.vue +++ b/src/pages/Submissions.vue @@ -1,5 +1,5 @@