From 8e05cb601d7ef74d9387513a405e45a951e2036e Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 23 Jan 2023 16:20:37 +0800 Subject: [PATCH] contest list. --- package-lock.json | 1 + package.json | 1 + src/components.d.ts | 1 + src/oj/api.ts | 15 ++ src/oj/contest/components/ContestTitle.vue | 21 +++ src/oj/contest/list.vue | 162 ++++++++++++++++++++- src/oj/problem/components/Panel.vue | 4 +- src/oj/rank/list.vue | 67 ++++++++- src/oj/submission/detail.vue | 2 +- src/oj/submission/list.vue | 4 +- src/routes.ts | 2 - src/utils/constants.ts | 30 ++-- src/utils/functions.ts | 25 ++++ src/utils/types.ts | 56 +++++++ 14 files changed, 360 insertions(+), 31 deletions(-) create mode 100644 src/oj/contest/components/ContestTitle.vue diff --git a/package-lock.json b/package-lock.json index 3bcecf6..174834e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@vueuse/integrations": "^9.11.0", "axios": "1.2.2", "copy-text-to-clipboard": "^3.0.1", + "date-fns": "^2.29.3", "highlight.js": "^11.7.0", "naive-ui": "^2.34.3", "party-js": "^2.2.0", diff --git a/package.json b/package.json index 43331a3..a4bcd03 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@vueuse/integrations": "^9.11.0", "axios": "1.2.2", "copy-text-to-clipboard": "^3.0.1", + "date-fns": "^2.29.3", "highlight.js": "^11.7.0", "naive-ui": "^2.34.3", "party-js": "^2.2.0", diff --git a/src/components.d.ts b/src/components.d.ts index 97da2da..37cd397 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -10,6 +10,7 @@ declare module '@vue/runtime-core' { IEpBell: typeof import('~icons/ep/bell')['default'] IEpCaretRight: typeof import('~icons/ep/caret-right')['default'] IEpLoading: typeof import('~icons/ep/loading')['default'] + IEpLock: typeof import('~icons/ep/lock')['default'] NAlert: typeof import('naive-ui')['NAlert'] NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] diff --git a/src/oj/api.ts b/src/oj/api.ts index 7546dac..1e51113 100644 --- a/src/oj/api.ts +++ b/src/oj/api.ts @@ -92,3 +92,18 @@ export function adminRejudge(id: string) { params: { id }, }) } + +export function getRank(offset: number, limit: number) { + return http.get("user_rank", { + params: { offset, limit, rule: "acm" }, + }) +} + +export function getContestList(query: { + offset: number + limit: number + keyword: string + status: string +}) { + return http.get("contests", { params: query }) +} diff --git a/src/oj/contest/components/ContestTitle.vue b/src/oj/contest/components/ContestTitle.vue new file mode 100644 index 0000000..82d38a4 --- /dev/null +++ b/src/oj/contest/components/ContestTitle.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/oj/contest/list.vue b/src/oj/contest/list.vue index 8474813..d352f7a 100644 --- a/src/oj/contest/list.vue +++ b/src/oj/contest/list.vue @@ -1,5 +1,161 @@ - + + + + diff --git a/src/oj/problem/components/Panel.vue b/src/oj/problem/components/Panel.vue index ec18b59..32d60ee 100644 --- a/src/oj/problem/components/Panel.vue +++ b/src/oj/problem/components/Panel.vue @@ -8,7 +8,7 @@ import { submissionMemoryFormat, submissionTimeFormat } from "utils/functions" import { Problem, Submission, SubmitCodePayload } from "utils/types" import { getSubmission, submitCode } from "oj/api" import SubmissionResultTag from "../../../shared/SubmissionResultTag.vue" -import { DataTableColumn } from "naive-ui" +import type { DataTableColumn } from "naive-ui" const problem = inject>("problem") @@ -235,9 +235,9 @@ const tabProps = { diff --git a/src/oj/rank/list.vue b/src/oj/rank/list.vue index df04077..1a86630 100644 --- a/src/oj/rank/list.vue +++ b/src/oj/rank/list.vue @@ -1,11 +1,72 @@ diff --git a/src/oj/submission/detail.vue b/src/oj/submission/detail.vue index d84c15d..f80a7ab 100644 --- a/src/oj/submission/detail.vue +++ b/src/oj/submission/detail.vue @@ -54,7 +54,7 @@ onMounted(init) 提交时间:{{ parseTime(submission.create_time) }} 语言:{{ submission.language }} - 提交人 {{ submission.username }} + 用户 {{ submission.username }} diff --git a/src/oj/submission/list.vue b/src/oj/submission/list.vue index 8bd84e3..c597b0b 100644 --- a/src/oj/submission/list.vue +++ b/src/oj/submission/list.vue @@ -172,7 +172,7 @@ const columns = computed(() => { }, { title: "语言", key: "language", width: 100 }, { - title: "提交者", + title: "用户", key: "username", minWidth: 120, render: (row) => @@ -206,7 +206,7 @@ const columns = computed(() => { - + diff --git a/src/routes.ts b/src/routes.ts index b67e430..8b8b6e6 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -13,7 +13,6 @@ export const routes = [ { path: "submission", component: () => import("oj/submission/list.vue"), - meta: { requiresAuth: true }, }, { path: "submission/:submissionID", @@ -23,7 +22,6 @@ export const routes = [ { path: "contest", component: () => import("oj/contest/list.vue"), - meta: { requiresAuth: true }, }, { path: "contest/:contestID", diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 8c40310..2f57c86 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -70,32 +70,26 @@ export const JUDGE_STATUS: { }, } -export const CONTEST_STATUS = { - NOT_START: "1", - UNDERWAY: "0", - ENDED: "-1", -} - -export const CONTEST_STATUS_REVERSE = { +export const CONTEST_STATUS: { + [key in "1" | "-1" | "0"]: { + name: string + type: "error" | "success" | "warning" + } +} = { "1": { - name: "Not Started", - color: "yellow", + name: "未开始", + type: "warning", }, "0": { - name: "Underway", - color: "green", + name: "进行中", + type: "success", }, "-1": { - name: "Ended", - color: "red", + name: "已结束", + type: "error", }, } -export const RULE_TYPE = { - ACM: "ACM", - OI: "OI", -} - export const CONTEST_TYPE = { PUBLIC: "Public", PRIVATE: "Password Protected", diff --git a/src/utils/functions.ts b/src/utils/functions.ts index 201dc07..4eeec94 100644 --- a/src/utils/functions.ts +++ b/src/utils/functions.ts @@ -1,3 +1,4 @@ +import { intervalToDuration } from "date-fns" import { STORAGE_KEY } from "./constants" export function getACRate(acCount: number, totalCount: number) { @@ -40,6 +41,30 @@ export function parseTime(utc: Date, format = "YYYY年M月D日") { return time.value } +export function duration(start: Date, end: Date): string { + const duration = intervalToDuration({ + start: Date.parse(start.toString()), + end: Date.parse(end.toString()), + }) + let result = "" + if (duration.years) { + result += duration.years + "年" + } + if (duration.months) { + result += duration.months + "月" + } + if (duration.days) { + result += duration.days + "天" + } + if (duration.hours) { + result += duration.hours + "小时" + } + if (duration.minutes) { + result += duration.minutes + "分钟" + } + return result +} + export function submissionMemoryFormat(memory: number | string | undefined) { if (memory === undefined) return "--" // 1048576 = 1024 * 1024 diff --git a/src/utils/types.ts b/src/utils/types.ts index 99d3c67..b299325 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -115,3 +115,59 @@ export interface SubmissionListPayload { limit: number offset: number } + +export interface Rank { + id: number + user: { + id: number + username: string + real_name: null + } + acm_problems_status: { + problems: { + [key: string]: { + _id: string + status: number + } + } + contest_problems?: { + [key: string]: { + [key: string]: { + _id: string + status: number + } + } + } + } + oi_problems_status: {} + real_name: null | string + avatar: string + blog: null + mood: null | string + github: null + school: null | string + major: null | string + language: null | string + accepted_number: number + total_score: number + submission_number: number +} + +export interface Contest { + id: number + created_by: { + id: number + username: string + real_name: null + } + status: "-1" | "0" | "1" + contest_type: "Password Protected" | "Public" + title: string + description: string + real_time_rank: boolean + rule_type: "ACM" + start_time: Date + end_time: Date + create_time: Date + last_update_time: Date +}