diff --git a/apps/web/src/App.vue b/apps/web/src/App.vue index 76fc1ab..3770664 100644 --- a/apps/web/src/App.vue +++ b/apps/web/src/App.vue @@ -28,7 +28,9 @@ const hljsInstance = ref(null) const loadHighlightJS = async () => { if (hljsInstance.value) return hljsInstance.value - const [hljs, c, cpp, python, java, javascript, go, sql] = await Promise.all([ + // 逐个取 .default,不要在 Promise.all 后面 map —— 那样元组会塌成 + // (HLJSApi | LanguageFn)[],每个元素都变成联合类型,hljs 上就找不到方法了 + const [core, c, cpp, python, java, javascript, go, sql] = await Promise.all([ import("highlight.js/lib/core"), import("highlight.js/lib/languages/c"), import("highlight.js/lib/languages/cpp"), @@ -37,15 +39,16 @@ const loadHighlightJS = async () => { import("highlight.js/lib/languages/javascript"), import("highlight.js/lib/languages/go"), import("highlight.js/lib/languages/sql"), - ]).then((modules) => modules.map((m) => m.default)) + ]) + const hljs = core.default - hljs.registerLanguage("c", c) - hljs.registerLanguage("python", python) - hljs.registerLanguage("cpp", cpp) - hljs.registerLanguage("java", java) - hljs.registerLanguage("javascript", javascript) - hljs.registerLanguage("go", go) - hljs.registerLanguage("sql", sql) + hljs.registerLanguage("c", c.default) + hljs.registerLanguage("python", python.default) + hljs.registerLanguage("cpp", cpp.default) + hljs.registerLanguage("java", java.default) + hljs.registerLanguage("javascript", javascript.default) + hljs.registerLanguage("go", go.default) + hljs.registerLanguage("sql", sql.default) hljsInstance.value = hljs return hljs diff --git a/apps/web/src/admin/api.ts b/apps/web/src/admin/api.ts index e9a6d70..bdc21e9 100644 --- a/apps/web/src/admin/api.ts +++ b/apps/web/src/admin/api.ts @@ -2,11 +2,13 @@ import api2 from "utils/api2" import { toProblemListItem } from "admin/transforms" import type { AcTrend, + AdminProblemSetProgress, BatchProblemTagResponse, GenerateSqlTestCaseResponse, RenameTagResponse, SqlTestCaseScript, AcmHelperItem, + SubmissionInfo, AdminAiReport, AdminAiReportList, StuckProblem, @@ -36,7 +38,6 @@ import type { ProblemSetBadge, ProblemSetList, ProblemSetProblem, - ProblemSetProgressList, TutorialListItem, } from "utils/types" @@ -476,7 +477,11 @@ export function makeProblemPublic(id: number, displayId: string) { // 比赛辅助检查 export function getACMHelperList(contestId: number) { - return api2.get(`admin/contests/${contestId}/acm-helper`) + // acInfo 在契约里是 Record(acm_contest_rank 的 JSONB 原文), + // 组件侧按 SubmissionInfo 读,收窄放在这里 + return api2.get< + Array & { acInfo: SubmissionInfo }> + >(`admin/contests/${contestId}/acm-helper`) } export function updateACMHelperChecked( @@ -652,8 +657,9 @@ export function deleteProblemSetBadge(problemSetId: number, badgeId: number) { } // 题单进度管理 API +// 注意:返回的是裸数组,不是分页信封 —— 和 oj 侧的 /user-progress 不同 export function getProblemSetProgress(problemSetId: number) { - return api2.get( + return api2.get( `admin/problem-sets/${problemSetId}/progress`, ) } diff --git a/apps/web/src/admin/problemset/detail.vue b/apps/web/src/admin/problemset/detail.vue index 7b2c883..9d393af 100644 --- a/apps/web/src/admin/problemset/detail.vue +++ b/apps/web/src/admin/problemset/detail.vue @@ -4,7 +4,7 @@ import type { ProblemSet, ProblemSetProblem, ProblemSetBadge, - ProblemSetProgress, + AdminProblemSetProgress, } from "utils/types" import { getProblemSetDetail, @@ -37,7 +37,7 @@ const problemSetId = computed(() => Number(route.params.problemSetId)) const problemSet = ref(null) const problems = ref([]) const badges = ref([]) -const progress = ref([]) +const progress = ref([]) // 模态框状态 const showAddProblemModal = ref(false) diff --git a/apps/web/src/admin/setting/config.vue b/apps/web/src/admin/setting/config.vue index 925d739..8387af1 100644 --- a/apps/web/src/admin/setting/config.vue +++ b/apps/web/src/admin/setting/config.vue @@ -6,7 +6,7 @@ import { CLASS_NAME_RE, } from "utils/constants" import { parseTime } from "utils/functions" -import type { Server } from "utils/types" +import type { OrphanTestCase, Server, WebsiteConfig } from "utils/types" import { useConfigStore } from "shared/store/config" import { useConfigWebSocket } from "shared/composables/websocket" import { @@ -98,8 +98,8 @@ const serverColumns: DataTableColumn[] = [ width: 100, }, { title: "IP", key: "ip", width: 140 }, - { title: "判题机版本", key: "judger_version", width: 100 }, - { title: "服务器 URL", key: "service_url", width: 200 }, + { title: "判题机版本", key: "judgerVersion", width: 100 }, + { title: "服务器 URL", key: "serviceUrl", width: 200 }, { title: "上一次心跳", key: "last_heartbeat", @@ -114,14 +114,14 @@ const serverColumns: DataTableColumn[] = [ }, ] -const testcases = ref([]) +const testcases = ref([]) const token = ref("") const servers = ref([]) const abnormalServers = computed(() => servers.value.filter((item) => item.status === "abnormal"), ) -const websiteConfig = reactive({ +const websiteConfig = reactive({ websiteBaseUrl: import.meta.env.PUBLIC_OJ_URL, websiteName: "判题狗", websiteNameShortcut: "判题狗", diff --git a/apps/web/src/admin/tutorial/components/ExerciseManager.vue b/apps/web/src/admin/tutorial/components/ExerciseManager.vue index 6197073..74aa1d9 100644 --- a/apps/web/src/admin/tutorial/components/ExerciseManager.vue +++ b/apps/web/src/admin/tutorial/components/ExerciseManager.vue @@ -427,7 +427,7 @@ function typeTagType(type: ExerciseType) { () diff --git a/apps/web/src/main.ts b/apps/web/src/main.ts index e84d4f2..200f371 100644 --- a/apps/web/src/main.ts +++ b/apps/web/src/main.ts @@ -26,7 +26,7 @@ import { useUserStore } from "./shared/store/user" const authStore = useAuthModalStore() -router.beforeEach(async (to, from, next) => { +router.beforeEach(async (to, _from, next) => { // 检查是否需要认证 if (to.matched.some((record) => record.meta.requiresAuth)) { if (!storage.get(STORAGE_KEY.AUTHED)) { diff --git a/apps/web/src/oj/ai/components/DurationChart.vue b/apps/web/src/oj/ai/components/DurationChart.vue index 7331939..2039f12 100644 --- a/apps/web/src/oj/ai/components/DurationChart.vue +++ b/apps/web/src/oj/ai/components/DurationChart.vue @@ -60,10 +60,6 @@ const title = computed(() => { const data = computed>(() => { return { labels: aiStore.durationData.map((duration) => { - let prefix = "周" - if (duration.unit === "months") { - prefix = "月" - } return [ parseTime(duration.start, "M月D日"), parseTime(duration.end, "M月D日"), diff --git a/apps/web/src/oj/ai/components/EfficiencyChart.vue b/apps/web/src/oj/ai/components/EfficiencyChart.vue index 1659a98..0e724e6 100644 --- a/apps/web/src/oj/ai/components/EfficiencyChart.vue +++ b/apps/web/src/oj/ai/components/EfficiencyChart.vue @@ -9,7 +9,7 @@