From b14316b9192cc70625247aab653fa8baf531f09c Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Wed, 8 Oct 2025 00:46:49 +0800 Subject: [PATCH] batch update --- rsbuild.config.ts | 2 +- src/App.vue | 1 - src/admin/contest/helper.vue | 4 +- src/main.ts | 24 +- src/oj/ai/analysis.vue | 4 +- src/oj/ai/components/SolvedTable.vue | 4 +- src/oj/announcement/list.vue | 5 +- src/oj/composables/code.ts | 11 - src/oj/composables/problem.ts | 3 - src/oj/composables/syncStatus.ts | 22 +- src/oj/contest/components/ContestMenu.vue | 4 +- src/oj/contest/detail.vue | 4 +- src/oj/contest/list.vue | 5 +- src/oj/learn/index.vue | 6 +- src/oj/problem/components/ContestEditor.vue | 32 +- src/oj/problem/components/EditorForTest.vue | 43 +- src/oj/problem/components/Form.vue | 22 +- src/oj/problem/components/ProblemComment.vue | 5 +- src/oj/problem/components/ProblemContent.vue | 11 +- src/oj/problem/components/ProblemEditor.vue | 32 +- src/oj/problem/components/ProblemInfo.vue | 32 +- .../problem/components/ProblemSubmission.vue | 55 ++- .../problem/components/SubmissionResult.vue | 199 ++++---- src/oj/problem/components/Submit.vue | 18 +- src/oj/problem/composables/useFireworks.ts | 439 +++++++++--------- .../composables/useSubmissionMonitor.ts | 344 +++++++------- src/oj/problem/detail.vue | 33 +- src/oj/problem/list.vue | 5 +- src/oj/store/code.ts | 94 ++++ src/oj/store/problem.ts | 66 +++ src/oj/submission/detail.vue | 8 +- src/oj/submission/list.vue | 4 +- src/oj/user/index.vue | 4 +- src/shared/components/CodeEditor.vue | 1 - src/shared/components/Header.vue | 29 +- src/shared/components/Login.vue | 47 +- src/shared/components/MarkdownEditor.vue | 1 - src/shared/components/Pagination.vue | 4 +- src/shared/components/Signup.vue | 64 ++- src/shared/components/SyncCodeEditor.vue | 5 +- src/shared/composables/breakpoints.ts | 22 +- src/shared/composables/modal.ts | 2 - src/shared/composables/pagination.ts | 4 + src/shared/composables/switchScreen.ts | 18 - src/shared/composables/sync.ts | 6 + src/shared/composables/websocket.ts | 19 +- src/shared/store/authModal.ts | 170 +++++++ src/shared/store/screenMode.ts | 34 ++ 48 files changed, 1236 insertions(+), 735 deletions(-) delete mode 100644 src/oj/composables/code.ts delete mode 100644 src/oj/composables/problem.ts create mode 100644 src/oj/store/code.ts create mode 100644 src/oj/store/problem.ts delete mode 100644 src/shared/composables/modal.ts delete mode 100644 src/shared/composables/switchScreen.ts create mode 100644 src/shared/store/authModal.ts create mode 100644 src/shared/store/screenMode.ts diff --git a/rsbuild.config.ts b/rsbuild.config.ts index 26c5d2b..1191e3b 100644 --- a/rsbuild.config.ts +++ b/rsbuild.config.ts @@ -14,7 +14,7 @@ export default defineConfig(({ envMode }) => { target: rawPublicVars["PUBLIC_OJ_URL"], changeOrigin: true, } - + const wsProxyConfig = { target: rawPublicVars["PUBLIC_WS_URL"], ws: true, diff --git a/src/App.vue b/src/App.vue index 1cfb4cd..0392757 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,6 @@ import { darkTheme, dateZhCN, zhCN } from "naive-ui" import "normalize.css" import "./index.css" - const isDark = useDark() // 延迟加载 highlight.js,避免阻塞首屏 diff --git a/src/admin/contest/helper.vue b/src/admin/contest/helper.vue index 462b0a0..1b6505e 100644 --- a/src/admin/contest/helper.vue +++ b/src/admin/contest/helper.vue @@ -4,7 +4,7 @@ import { parseTime } from "utils/functions" import { getACMHelperList, getContest, updateACMHelperChecked } from "../api" import { getSubmission, getSubmissions } from "oj/api" import SubmissionDetail from "oj/submission/detail.vue" -import { isDesktop } from "shared/composables/breakpoints" +import { useBreakpoints } from "shared/composables/breakpoints" interface Props { contestID: string @@ -28,6 +28,8 @@ interface HelperItem { const props = defineProps() const message = useMessage() +const { isDesktop } = useBreakpoints() + const submissions = ref([]) const contestStartTime = ref(null) const query = reactive({ diff --git a/src/main.ts b/src/main.ts index afa4b8b..e6b67d0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,19 +8,29 @@ import storage from "utils/storage" import App from "./App.vue" import { admins, ojs } from "./routes" -import { toggleLogin } from "./shared/composables/modal" -import { useUserStore } from "./shared/store/user" - const router = createRouter({ history: createWebHistory(), routes: [ojs, admins], }) +const pinia = createPinia() + +// 创建 app 并安装插件 +const app = createApp(App) +app.use(pinia) +app.use(router) + +// 现在可以安全地使用 Store +import { useAuthModalStore } from "./shared/store/authModal" +import { useUserStore } from "./shared/store/user" + +const authStore = useAuthModalStore() + router.beforeEach(async (to, from, next) => { // 检查是否需要认证 if (to.matched.some((record) => record.meta.requiresAuth)) { if (!storage.get(STORAGE_KEY.AUTHED)) { - toggleLogin(true) + authStore.openLoginModal() next("/") return } @@ -34,7 +44,7 @@ router.beforeEach(async (to, from, next) => { ) ) { if (!storage.get(STORAGE_KEY.AUTHED)) { - toggleLogin(true) + authStore.openLoginModal() next("/") return } @@ -66,10 +76,6 @@ router.beforeEach(async (to, from, next) => { next() }) -const pinia = createPinia() -const app = createApp(App) -app.use(router) -app.use(pinia) app.mount("#app") if (!!import.meta.env.PUBLIC_ICONIFY_URL) { diff --git a/src/oj/ai/analysis.vue b/src/oj/ai/analysis.vue index 3b4ebeb..a0814f8 100644 --- a/src/oj/ai/analysis.vue +++ b/src/oj/ai/analysis.vue @@ -50,7 +50,7 @@ @@ -45,8 +55,8 @@ const changeLanguage = (v: LANGUAGE) => {
diff --git a/src/oj/problem/components/EditorForTest.vue b/src/oj/problem/components/EditorForTest.vue index aafb1af..429082b 100644 --- a/src/oj/problem/components/EditorForTest.vue +++ b/src/oj/problem/components/EditorForTest.vue @@ -1,6 +1,7 @@ - - - - - + + + + + diff --git a/src/oj/problem/components/Submit.vue b/src/oj/problem/components/Submit.vue index dca7e88..11faa6e 100644 --- a/src/oj/problem/components/Submit.vue +++ b/src/oj/problem/components/Submit.vue @@ -1,14 +1,15 @@ @@ -108,9 +111,9 @@ watch(isMobile, (value) => { - + @@ -146,11 +149,11 @@ watch(isMobile, (value) => { - + - + diff --git a/src/oj/problem/list.vue b/src/oj/problem/list.vue index 473f66b..53d4d6d 100644 --- a/src/oj/problem/list.vue +++ b/src/oj/problem/list.vue @@ -8,7 +8,7 @@ import { ProblemFiltered } from "utils/types" import { getProblemTagList } from "shared/api" import Hitokoto from "shared/components/Hitokoto.vue" import Pagination from "shared/components/Pagination.vue" -import { isDesktop } from "shared/composables/breakpoints" +import { useBreakpoints } from "shared/composables/breakpoints" import { usePagination } from "shared/composables/pagination" import { useUserStore } from "shared/store/user" import { renderTableTitle } from "utils/renders" @@ -38,6 +38,9 @@ const difficultyOptions = [ const router = useRouter() const userStore = useUserStore() + +const { isDesktop } = useBreakpoints() + const problems = ref([]) const total = ref(0) const tags = ref([]) diff --git a/src/oj/store/code.ts b/src/oj/store/code.ts new file mode 100644 index 0000000..ccf6009 --- /dev/null +++ b/src/oj/store/code.ts @@ -0,0 +1,94 @@ +import { defineStore } from "pinia" +import { STORAGE_KEY } from "utils/constants" +import storage from "utils/storage" +import { Code, LANGUAGE } from "utils/types" + +/** + * 代码编辑器状态管理 Store + * 管理全局的代码、输入、输出状态 + */ +export const useCodeStore = defineStore("code", () => { + // ==================== 状态 ==================== + const code = reactive({ + value: "", + language: storage.get(STORAGE_KEY.LANGUAGE) || "Python3", + }) + + const input = ref("") + const output = ref("") + + // ==================== 计算属性 ==================== + const isEmpty = computed(() => code.value.trim() === "") + + // ==================== 操作 ==================== + /** + * 设置代码内容 + */ + function setCode(value: string) { + code.value = value + } + + /** + * 设置编程语言 + */ + function setLanguage(language: LANGUAGE) { + code.language = language + storage.set(STORAGE_KEY.LANGUAGE, language) + } + + /** + * 设置输入 + */ + function setInput(value: string) { + input.value = value + } + + /** + * 设置输出 + */ + function setOutput(value: string) { + output.value = value + } + + /** + * 重置所有状态 + */ + function reset() { + code.value = "" + input.value = "" + output.value = "" + } + + /** + * 清空输出 + */ + function clearOutput() { + output.value = "" + } + + // 监听语言变化,保存到本地存储 + watch( + () => code.language, + (newLanguage) => { + storage.set(STORAGE_KEY.LANGUAGE, newLanguage) + }, + ) + + return { + // 状态 + code, + input, + output, + + // 计算属性 + isEmpty, + + // 操作 + setCode, + setLanguage, + setInput, + setOutput, + reset, + clearOutput, + } +}) diff --git a/src/oj/store/problem.ts b/src/oj/store/problem.ts new file mode 100644 index 0000000..7430643 --- /dev/null +++ b/src/oj/store/problem.ts @@ -0,0 +1,66 @@ +import { defineStore } from "pinia" +import { Problem } from "utils/types" + +/** + * 题目状态管理 Store + * 管理当前题目的信息 + */ +export const useProblemStore = defineStore("problem", () => { + // ==================== 状态 ==================== + const problem = ref(null) + + // ==================== 计算属性 ==================== + const hasProblem = computed(() => problem.value !== null) + + const problemId = computed(() => problem.value?._id ?? null) + + const problemTitle = computed(() => problem.value?.title ?? "") + + const difficulty = computed(() => problem.value?.difficulty ?? "") + + const languages = computed(() => problem.value?.languages ?? []) + + const isACed = computed(() => problem.value?.my_status === 0) + + // ==================== 操作 ==================== + /** + * 设置当前题目 + */ + function setProblem(newProblem: Problem | null) { + problem.value = newProblem + } + + /** + * 清空当前题目 + */ + function clearProblem() { + problem.value = null + } + + /** + * 更新题目的部分字段 + */ + function updateProblem(updates: Partial) { + if (problem.value) { + problem.value = { ...problem.value, ...updates } + } + } + + return { + // 状态 + problem, + + // 计算属性 + hasProblem, + problemId, + problemTitle, + difficulty, + languages, + isACed, + + // 操作 + setProblem, + clearProblem, + updateProblem, + } +}) diff --git a/src/oj/submission/detail.vue b/src/oj/submission/detail.vue index 504b6ef..d09acf1 100644 --- a/src/oj/submission/detail.vue +++ b/src/oj/submission/detail.vue @@ -14,7 +14,7 @@ import { } from "utils/functions" import { Submission } from "utils/types" import SubmissionResultTag from "shared/components/SubmissionResultTag.vue" -import { isDesktop, isMobile } from "shared/composables/breakpoints" +import { useBreakpoints } from "shared/composables/breakpoints" const props = defineProps<{ submissionID: string @@ -26,6 +26,8 @@ const props = defineProps<{ const router = useRouter() const message = useMessage() +const { isMobile, isDesktop } = useBreakpoints() + const submission = ref() async function init() { @@ -69,7 +71,7 @@ function copyToCat() { async function copyToProblem() { const success = await copyToClipboard(submission.value!.code) if (success) { - message.success("代码复制成功") + message.success("代码复制成功,需要手动粘贴到题目") } else { message.error("代码复制失败") } @@ -115,7 +117,7 @@ onMounted(init) 复制到自测猫 - 回到题目 + 复制回到题目 diff --git a/src/oj/submission/list.vue b/src/oj/submission/list.vue index 16c2f15..88f96f9 100644 --- a/src/oj/submission/list.vue +++ b/src/oj/submission/list.vue @@ -6,7 +6,7 @@ import { parseTime } from "utils/functions" import { LANGUAGE, SubmissionListItem } from "utils/types" import Pagination from "shared/components/Pagination.vue" import SubmissionResultTag from "shared/components/SubmissionResultTag.vue" -import { isDesktop, isMobile } from "shared/composables/breakpoints" +import { useBreakpoints } from "shared/composables/breakpoints" import { usePagination } from "shared/composables/pagination" import { useUserStore } from "shared/store/user" import { LANGUAGE_SHOW_VALUE } from "utils/constants" @@ -30,6 +30,8 @@ const router = useRouter() const userStore = useUserStore() const message = useMessage() +const { isMobile, isDesktop } = useBreakpoints() + const submissions = ref([]) const total = ref(0) const todayCount = ref(0) diff --git a/src/oj/user/index.vue b/src/oj/user/index.vue index 461dc2f..c39a325 100644 --- a/src/oj/user/index.vue +++ b/src/oj/user/index.vue @@ -2,7 +2,7 @@ import { Icon } from "@iconify/vue" import { NH2, NH3 } from "naive-ui" import { getProfile } from "shared/api" -import { isDesktop } from "shared/composables/breakpoints" +import { useBreakpoints } from "shared/composables/breakpoints" import { durationToDays, parseTime } from "utils/functions" import { Profile } from "utils/types" import { getMetrics } from "../api" @@ -18,6 +18,8 @@ const learnDuration = ref("") const [loading, toggle] = useToggle() const [show, toggleShow] = useToggle(false) +const { isDesktop } = useBreakpoints() + async function init() { toggle(true) try { diff --git a/src/shared/components/CodeEditor.vue b/src/shared/components/CodeEditor.vue index 01a204f..8a3bbff 100644 --- a/src/shared/components/CodeEditor.vue +++ b/src/shared/components/CodeEditor.vue @@ -7,7 +7,6 @@ import type { Extension } from "@codemirror/state" import { LANGUAGE } from "utils/types" import { oneDark } from "../themes/oneDark" import { smoothy } from "../themes/smoothy" - interface Props { language?: LANGUAGE fontSize?: number diff --git a/src/shared/components/Header.vue b/src/shared/components/Header.vue index 09fba53..9508686 100644 --- a/src/shared/components/Header.vue +++ b/src/shared/components/Header.vue @@ -1,20 +1,27 @@