add contest problems.

This commit is contained in:
2023-03-30 23:18:31 +08:00
parent 451e8d7c70
commit 70a4b67b58
10 changed files with 378 additions and 176 deletions

View File

@@ -41,7 +41,16 @@ function goEdit() {
}
function goCheck() {
const data = router.resolve("/problem/" + props.problemDisplayID)
let data = router.resolve("/problem/" + props.problemDisplayID)
if (route.name === "admin contest problem list") {
data = router.resolve({
name: "contest problem",
params: {
contestID: route.params.contestID,
problemID: props.problemDisplayID,
},
})
}
window.open(data.href, "_blank")
}
</script>

View File

@@ -0,0 +1,44 @@
<script setup lang="ts">
import { addProblemForContest } from "~/admin/api"
interface Props {
problemID: number
contestID: string
}
const props = defineProps<Props>()
const emit = defineEmits(["added"])
const message = useMessage()
const displayID = ref("")
async function addProblem() {
if (!displayID.value) return
try {
await addProblemForContest(
props.contestID,
props.problemID,
displayID.value
)
emit("added")
} catch (err: any) {
if (err.data === "Duplicate display id in this contest") {
message.error("显示编号重复了,请重新写一个")
} else {
message.error(err.data)
}
}
}
</script>
<template>
<n-popconfirm :show-icon="false" @positive-click="addProblem">
<template #trigger>
<n-button secondary size="small" type="primary">+</n-button>
</template>
<n-space vertical>
<span>请输入在这场比赛中的显示编号</span>
<n-input autofocus v-model:value="displayID" />
</n-space>
</n-popconfirm>
</template>
<style scoped></style>

View File

@@ -0,0 +1,90 @@
<script lang="ts" setup>
import { DataTableColumn } from "naive-ui"
import { getProblemList } from "~/admin/api"
import { AdminProblemFiltered } from "~/utils/types"
import Pagination from "~/shared/Pagination.vue"
import AddButton from "./AddButton.vue"
interface Props {
show: boolean
count: number
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: "update:show", value: boolean): void
(e: "change"): void
}>()
const route = useRoute()
const query = reactive({
page: 1,
limit: 10,
keyword: "",
})
const total = ref(0)
const problems = shallowRef<AdminProblemFiltered[]>([])
const columns: DataTableColumn<AdminProblemFiltered>[] = [
{ title: "编号", key: "_id", width: 80 },
{ title: "标题", key: "title" },
{
title: "选项",
key: "add",
render: (row) =>
h(AddButton, {
problemID: row.id,
contestID: <string>route.params.contestID,
onAdded: () => emit("change"),
}),
width: 60,
},
]
async function getList() {
const offset = (query.page - 1) * query.limit
const res = await getProblemList(
offset,
query.limit,
query.keyword,
"",
"ACM"
)
total.value = res.total
problems.value = res.results
}
watch(
() => props.show,
(value) => {
if (value) getList()
}
)
watch(query, getList, { deep: true })
</script>
<template>
<n-modal
:mask-closable="false"
:show="props.show"
preset="card"
style="width: 600px"
title="从题库中添加"
@close="$emit('update:show', false)"
>
<n-input
class="search"
v-model:value="query.keyword"
placeholder="搜索标题或编号"
/>
<n-data-table size="small" :columns="columns" :data="problems" />
<Pagination
:total="total"
v-model:limit="query.limit"
v-model:page="query.page"
/>
</n-modal>
</template>
<style scoped>
.search {
margin-bottom: 20px;
}
</style>