From ee14e4065c0a20e4c5ac769ecafde89a3130da52 Mon Sep 17 00:00:00 2001
From: yuetsh <517252939@qq.com>
Date: Thu, 21 May 2026 02:12:11 -0600
Subject: [PATCH] update
---
src/oj/contest/pages/rank.vue | 106 +++++++++++++++++++++++++++++++++-
1 file changed, 105 insertions(+), 1 deletion(-)
diff --git a/src/oj/contest/pages/rank.vue b/src/oj/contest/pages/rank.vue
index dd575ae..3c28370 100644
--- a/src/oj/contest/pages/rank.vue
+++ b/src/oj/contest/pages/rank.vue
@@ -8,7 +8,7 @@ import Pagination from "shared/components/Pagination.vue"
import { usePagination } from "shared/composables/pagination"
import { ContestStatus } from "utils/constants"
import { renderTableTitle } from "utils/renders"
-import { ContestRank, ProblemFiltered } from "utils/types"
+import type { ContestRank, ProblemFiltered } from "utils/types"
import AcAndSubmission from "../components/AcAndSubmission.vue"
import LineChart from "../components/LineChart.vue"
@@ -190,6 +190,78 @@ async function addColumns() {
}
}
+// 导出弹窗
+const showExportModal = ref(false)
+const exportLoading = ref(false)
+const exportForm = reactive({
+ first: 0,
+ second: 0,
+ third: 0,
+})
+
+watch(
+ () => total.value,
+ (val) => {
+ if (val > 0) {
+ exportForm.first = Math.round(val * 0.1)
+ exportForm.second = Math.round(val * 0.2)
+ exportForm.third = Math.round(val * 0.3)
+ }
+ },
+)
+
+function openExportModal() {
+ if (total.value > 0) {
+ exportForm.first = Math.round(total.value * 0.1)
+ exportForm.second = Math.round(total.value * 0.2)
+ exportForm.third = Math.round(total.value * 0.3)
+ }
+ showExportModal.value = true
+}
+
+async function downloadExcel() {
+ exportLoading.value = true
+ try {
+ const res = await getContestRank(props.contestID, {
+ limit: total.value || 10000,
+ offset: 0,
+ force_refresh: "1",
+ })
+ const allRanks: ContestRank[] = res.data.results
+
+ const rows = allRanks.map((rank, index) => {
+ const rank1 = index + 1
+ let level = ""
+ if (rank1 <= exportForm.first) {
+ level = "一等奖"
+ } else if (rank1 <= exportForm.first + exportForm.second) {
+ level = "二等奖"
+ } else if (
+ rank1 <=
+ exportForm.first + exportForm.second + exportForm.third
+ ) {
+ level = "三等奖"
+ } else {
+ level = "参与奖"
+ }
+ return { 用户名: rank.user.username, 等级: level }
+ })
+
+ 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")
+ a.href = url
+ a.download = `${contestStore.contest?.title ?? "contest"}获奖情况.csv`
+ a.click()
+ URL.revokeObjectURL(url)
+ showExportModal.value = false
+ } finally {
+ exportLoading.value = false
+ }
+}
+
// 监听分页参数变化
watch([() => query.page, () => query.limit], listRanks)
watch(autoRefresh, (checked) => (checked ? resume() : pause()))
@@ -223,6 +295,13 @@ onMounted(() => {
+
+ 导出数据
+
{
@update:page="(page: number) => (query.page = page)"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+
+ 下载 CSV
+
+
+