ACM helper

This commit is contained in:
2025-10-06 00:02:27 +08:00
parent 06146d8895
commit d2c031fbd9
10 changed files with 901 additions and 17 deletions

View File

@@ -1,5 +1,9 @@
<script lang="ts" setup>
import { deleteContestProblem, deleteProblem } from "admin/api"
import {
deleteContestProblem,
deleteProblem,
makeProblemPublic,
} from "admin/api"
import download from "utils/download"
interface Props {
@@ -7,12 +11,19 @@ interface Props {
problemDisplayID: string
}
const props = defineProps<Props>()
const emit = defineEmits(["deleted"])
const emit = defineEmits(["updated"])
const route = useRoute()
const router = useRouter()
const message = useMessage()
const isContestProblem = computed(
() => route.name === "admin contest problem list",
)
const showMakePublicModal = ref(false)
const newDisplayID = ref("")
async function handleDeleteProblem() {
try {
if (route.name === "admin contest problem list") {
@@ -21,7 +32,7 @@ async function handleDeleteProblem() {
await deleteProblem(props.problemID)
}
message.success("删除成功")
emit("deleted")
emit("updated")
} catch (err: any) {
if (err.data === "Can't delete the problem as it has submissions") {
message.error("这道题有提交之后,就不能被删除")
@@ -53,6 +64,33 @@ function goCheck() {
}
window.open(data.href, "_blank")
}
function openMakePublicModal() {
newDisplayID.value = ""
showMakePublicModal.value = true
}
async function handleMakePublic() {
if (!newDisplayID.value.trim()) {
message.error("请输入新的题目编号")
return
}
try {
await makeProblemPublic(props.problemID, newDisplayID.value.trim())
message.success("已成功转为公开题目(需要手动设置可见)")
showMakePublicModal.value = false
emit("updated") // 刷新列表
} catch (err: any) {
if (err.data === "Duplicate display ID") {
message.error("该题目编号已存在,请使用其他编号")
} else if (err.data === "Already be a public problem") {
message.error("该题目已经是公开题目")
} else {
message.error("转换失败:" + (err.data || "未知错误"))
}
}
}
</script>
<template>
<n-flex>
@@ -62,6 +100,19 @@ function goCheck() {
<n-button size="small" secondary type="info" @click="goCheck">
查看
</n-button>
<n-tooltip v-if="isContestProblem">
<template #trigger>
<n-button
size="small"
secondary
type="warning"
@click="openMakePublicModal"
>
公开
</n-button>
</template>
将此竞赛题目转为公开题目
</n-tooltip>
<n-popconfirm @positive-click="handleDeleteProblem">
<template #trigger>
<n-button secondary size="small" type="error">删除</n-button>
@@ -75,4 +126,35 @@ function goCheck() {
下载测试用例
</n-tooltip>
</n-flex>
<n-modal
v-model:show="showMakePublicModal"
preset="card"
title="转为公开题目"
style="width: 500px"
>
<n-space vertical>
<p>
将竞赛题目转为公开题目后会创建一个新的公开题目副本原题目保持不变
</p>
<n-form>
<n-form-item label="新的题目编号" required>
<n-input
v-model:value="newDisplayID"
placeholder="例如: 1001"
clearable
@keyup.enter="handleMakePublic"
/>
</n-form-item>
</n-form>
<n-alert type="info" title="提示:请输入一个未被使用的题目编号">
</n-alert>
</n-space>
<template #footer>
<n-flex justify="end">
<n-button @click="showMakePublicModal = false">取消</n-button>
<n-button type="primary" @click="handleMakePublic">确认</n-button>
</n-flex>
</template>
</n-modal>
</template>

View File

@@ -59,6 +59,7 @@ const columns: DataTableColumn<AdminProblemFiltered>[] = [
{
title: "可见",
key: "visible",
minWidth: 80,
render: (row) =>
h(NSwitch, {
value: row.visible,
@@ -70,12 +71,12 @@ const columns: DataTableColumn<AdminProblemFiltered>[] = [
{
title: "选项",
key: "actions",
width: 260,
width: 330,
render: (row) =>
h(Actions, {
problemID: row.id,
problemDisplayID: row._id,
onDeleted: listProblems,
onUpdated: listProblems,
}),
},
]