update
Deploy / deploy (push) Canceled after 0s

This commit is contained in:
xuyue committed 2026-09-27 19:36:28 +08:00
1 parent 23844ae301
commit d25b5dbe6d
268 files changed
+3684 -8861

No files matched your search

@@ -8,11 +8,7 @@ const contestStore = useContestStore()
</script>
<template>
<n-popover
v-if="contestStore.contest"
placement="bottom-end"
:show-arrow="false"
>
<n-popover v-if="contestStore.contest" placement="bottom-end" :show-arrow="false">
<template #trigger>
<n-button>
<template #icon>
@@ -35,18 +35,11 @@ const options: DropdownOption[] = [
<template>
<div v-if="contestMenuVisible">
<n-flex v-if="isDesktop">
<n-button :type="getCurrentType('problems')" @click="goto('problems')">
比赛题目
</n-button>
<n-button
:type="getCurrentType('submissions')"
@click="goto('submissions')"
>
<n-button :type="getCurrentType('problems')" @click="goto('problems')"> 比赛题目 </n-button>
<n-button :type="getCurrentType('submissions')" @click="goto('submissions')">
提交信息
</n-button>
<n-button :type="getCurrentType('rank')" @click="goto('rank')">
比赛排名
</n-button>
<n-button :type="getCurrentType('rank')" @click="goto('rank')"> 比赛排名 </n-button>
</n-flex>
<n-dropdown v-else :options="options" @select="goto">
<n-button>菜单</n-button>
@@ -17,15 +17,7 @@ import {
} from "chart.js"
import type { ContestRank } from "utils/types"
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
)
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend)
interface Props {
ranks: ContestRank[]
+4 -18
View File
@@ -17,10 +17,7 @@ const { isDesktop } = useBreakpoints()
const password = ref("")
async function check() {
const error = await contestStore.checkPassword(
props.contestID,
password.value,
)
const error = await contestStore.checkPassword(props.contestID, password.value)
if (error === "too-many-password-attempts") {
message.error("密码错误次数太多,请 10 分钟后再试")
} else if (!contestStore.access) {
@@ -44,10 +41,7 @@ onMounted(() => {
onBeforeUnmount(contestStore.clear)
const passwordFormVisible = computed(
() =>
contestStore.isPrivate &&
!contestStore.access &&
!contestStore.isContestAdmin,
() => contestStore.isPrivate && !contestStore.access && !contestStore.isContestAdmin,
)
</script>
@@ -70,17 +64,9 @@ const passwordFormVisible = computed(
<ContestMenu />
</n-flex>
</n-flex>
<n-form
:inline="isDesktop"
label-placement="left"
v-if="passwordFormVisible"
>
<n-form :inline="isDesktop" label-placement="left" v-if="passwordFormVisible">
<n-form-item label="需要输入密码才能看到题目">
<n-input
name="ContestPassword"
type="password"
v-model:value="password"
/>
<n-input name="ContestPassword" type="password" v-model:value="password" />
</n-form-item>
<n-form-item>
<n-button @click="check" :disabled="!password">确认</n-button>
+4 -21
View File
@@ -134,18 +134,10 @@ function rowProps(row: Contest) {
<n-space>
<n-form :show-feedback="false" label-placement="left" inline>
<n-form-item label="比赛状态">
<n-select
style="width: 120px"
:options="options"
v-model:value="query.status"
/>
<n-select style="width: 120px" :options="options" v-model:value="query.status" />
</n-form-item>
<n-form-item label="标签">
<n-select
style="width: 120px"
:options="tags"
v-model:value="query.tag"
/>
<n-select style="width: 120px" :options="tags" v-model:value="query.tag" />
</n-form-item>
</n-form>
<n-form :show-feedback="false" label-placement="left" inline>
@@ -165,16 +157,7 @@ function rowProps(row: Contest) {
</n-form-item>
</n-form>
</n-space>
<n-data-table
:bordered="false"
:columns="columns"
:data="data"
:row-props="rowProps"
/>
<n-data-table :bordered="false" :columns="columns" :data="data" :row-props="rowProps" />
</n-flex>
<Pagination
v-model:limit="query.limit"
v-model:page="query.page"
:total="total"
/>
<Pagination v-model:limit="query.limit" v-model:page="query.page" :total="total" />
</template>
+8 -33
View File
@@ -53,10 +53,7 @@ const columns = ref<DataTableColumn<ContestRank>[]>([
render: (_, index) => index + (query.page - 1) * query.limit + 1,
},
{
title: renderTableTitle(
"用户",
"streamline-emojis:smiling-face-with-sunglasses",
),
title: renderTableTitle("用户", "streamline-emojis:smiling-face-with-sunglasses"),
key: "username",
width: 120,
fixed: "left",
@@ -73,10 +70,7 @@ const columns = ref<DataTableColumn<ContestRank>[]>([
),
},
{
title: renderTableTitle(
"正确数/总提交",
"streamline-ultimate-color:color-palette",
),
title: renderTableTitle("正确数/总提交", "streamline-ultimate-color:color-palette"),
key: "submission",
width: 140,
align: "center",
@@ -147,16 +141,9 @@ async function addColumns() {
]
}
if (status.error_number) {
errorNumber = h(
"span",
{ style: "margin: 0" },
`(-${status.error_number})`,
)
errorNumber = h("span", { style: "margin: 0" }, `(-${status.error_number})`)
}
return h("div", { class: "oj-time-with-modal" }, [
acTime,
errorNumber,
])
return h("div", { class: "oj-time-with-modal" }, [acTime, errorNumber])
}
},
cellProps: (row) => {
@@ -244,10 +231,7 @@ async function downloadExcel() {
level = "一等奖"
} else if (rank1 <= exportForm.first + exportForm.second) {
level = "二等奖"
} else if (
rank1 <=
exportForm.first + exportForm.second + exportForm.third
) {
} else if (rank1 <= exportForm.first + exportForm.second + exportForm.third) {
level = "三等奖"
} else {
level = "参与奖"
@@ -255,8 +239,7 @@ async function downloadExcel() {
return { 用户名: rank.user.username, 等级: level }
})
const csv =
"用户名,等级\n" + rows.map((r) => `${r.用户名},${r.等级}`).join("\n")
const csv = "用户名,等级\n" + rows.map((r) => `${r.用户名},${r.等级}`).join("\n")
const blob = new Blob(["" + csv], { type: "text/csv;charset=utf-8" })
const url = URL.createObjectURL(blob)
const a = document.createElement("a")
@@ -294,13 +277,7 @@ onMounted(() => {
<LineChart :ranks="chart" :problems="problems" v-if="chart.length > 0" />
<!-- 排名表格 -->
<n-data-table
striped
:single-line="false"
:scroll-x="1200"
:columns="columns"
:data="data"
/>
<n-data-table striped :single-line="false" :scroll-x="1200" :columns="columns" :data="data" />
<n-space justify="end" align="center">
<n-form
label-placement="left"
@@ -347,9 +324,7 @@ onMounted(() => {
</n-form>
<template #action>
<n-button @click="showExportModal = false">取消</n-button>
<n-button type="primary" :loading="exportLoading" @click="downloadExcel">
下载 CSV
</n-button>
<n-button type="primary" :loading="exportLoading" @click="downloadExcel"> 下载 CSV </n-button>
</template>
</n-modal>
</template>