problem submission tab,

This commit is contained in:
2023-04-23 11:53:47 +08:00
parent 387ef0999b
commit 3f7125f39f
5 changed files with 122 additions and 19 deletions

View File

@@ -0,0 +1,100 @@
<script lang="ts" setup>
import { useUserStore } from "~/shared/store/user"
import { Submission } from "~/utils/types"
import { parseTime } from "~/utils/functions"
import { LANGUAGE_SHOW_VALUE } from "~/utils/constants"
import { getSubmissions } from "~/oj/api"
import { isDesktop } from "~/shared/composables/breakpoints"
import SubmissionResultTag from "~/shared/SubmissionResultTag.vue"
import Pagination from "~/shared/Pagination.vue"
import { NButton } from "naive-ui"
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
const columns: DataTableColumn<Submission>[] = [
{
title: "提交时间",
key: "create_time",
width: 200,
render: (row) =>
parseTime(
row.create_time,
isDesktop ? "YYYY-MM-DD hh:mm:ss" : "M-D hh:mm"
),
},
{
title: "编号",
key: "id",
minWidth: 160,
render: (row) => {
if (row.show_link) {
return h(
NButton,
{
text: true,
type: "info",
onClick: () => {
const data = router.resolve("/submission/" + row.id)
window.open(data.href, "_blank")
},
},
() => row.id.slice(0, 12)
)
} else {
return row.id.slice(0, 12)
}
},
},
{
title: "状态",
key: "status",
width: 140,
render: (row) => h(SubmissionResultTag, { result: row.result }),
},
{
title: "语言",
key: "language",
width: 100,
render: (row) => LANGUAGE_SHOW_VALUE[row.language],
},
]
const submissions = ref<Submission[]>([])
const total = ref(0)
const query = reactive({
limit: 10,
page: 1,
})
async function listSubmissions() {
const offset = query.limit * (query.page - 1)
const res = await getSubmissions({
...query,
myself: "1",
offset,
problem_id: <string>route.params.problemID ?? "",
contest_id: <string>route.params.contestID ?? "",
})
submissions.value = res.data.results
total.value = res.data.total
}
onMounted(listSubmissions)
watch(query, listSubmissions)
</script>
<template>
<n-data-table
v-if="userStore.isAuthed"
striped
:columns="columns"
:data="submissions"
/>
<Pagination
v-if="userStore.isAuthed"
:total="total"
v-model:limit="query.limit"
v-model:page="query.page"
/>
<n-alert type="error" v-if="!userStore.isAuthed" title="请先登录" />
</template>

View File

@@ -10,6 +10,9 @@ const ProblemContent = defineAsyncComponent(
const ProblemInfo = defineAsyncComponent( const ProblemInfo = defineAsyncComponent(
() => import("./components/ProblemInfo.vue") () => import("./components/ProblemInfo.vue")
) )
const ProblemSubmission = defineAsyncComponent(
() => import("./components/ProblemSubmission.vue")
)
interface Props { interface Props {
problemID: string problemID: string
@@ -51,6 +54,9 @@ onBeforeUnmount(() => {
<n-tab-pane name="info" tab="题目统计"> <n-tab-pane name="info" tab="题目统计">
<ProblemInfo /> <ProblemInfo />
</n-tab-pane> </n-tab-pane>
<n-tab-pane name="submission" tab="我的提交">
<ProblemSubmission />
</n-tab-pane>
</n-tabs> </n-tabs>
</n-scrollbar> </n-scrollbar>
<n-tabs v-else default-value="content" type="segment"> <n-tabs v-else default-value="content" type="segment">
@@ -63,6 +69,9 @@ onBeforeUnmount(() => {
<n-tab-pane name="info" tab="题目统计"> <n-tab-pane name="info" tab="题目统计">
<ProblemInfo /> <ProblemInfo />
</n-tab-pane> </n-tab-pane>
<n-tab-pane name="submission" tab="我的提交">
<ProblemSubmission />
</n-tab-pane>
</n-tabs> </n-tabs>
</n-gi> </n-gi>
<n-gi v-if="isDesktop"> <n-gi v-if="isDesktop">

View File

@@ -65,16 +65,6 @@ onMounted(init)
</n-space> </n-space>
</n-alert> </n-alert>
<n-card embedded> <n-card embedded>
<n-space justify="end">
<n-button
quaternary
class="copyBtn"
type="primary"
@click="handleCopy(submission!.code)"
>
{{ copied ? "已复制" : "复制代码" }}
</n-button>
</n-space>
<n-code <n-code
class="code" class="code"
:language="LANGUAGE_FORMAT_VALUE[submission.language]" :language="LANGUAGE_FORMAT_VALUE[submission.language]"
@@ -82,6 +72,9 @@ onMounted(init)
show-line-numbers show-line-numbers
/> />
</n-card> </n-card>
<n-button type="primary" @click="handleCopy(submission!.code)">
{{ copied ? "成功复制" : "复制代码" }}
</n-button>
<n-data-table <n-data-table
v-if="submission.info && submission.info.data" v-if="submission.info && submission.info.data"
:columns="columns" :columns="columns"
@@ -94,8 +87,4 @@ onMounted(init)
.code { .code {
font-size: 20px; font-size: 20px;
} }
.copyBtn {
margin-bottom: 16px;
}
</style> </style>

View File

@@ -12,6 +12,7 @@ import { Submission } from "utils/types"
import { adminRejudge, getSubmissions } from "oj/api" import { adminRejudge, getSubmissions } from "oj/api"
import { isDesktop } from "~/shared/composables/breakpoints" import { isDesktop } from "~/shared/composables/breakpoints"
import { useUserStore } from "~/shared/store/user" import { useUserStore } from "~/shared/store/user"
import { LANGUAGE_SHOW_VALUE } from "~/utils/constants"
interface Query { interface Query {
username: string username: string
@@ -136,9 +137,7 @@ const columns = computed(() => {
{ {
text: true, text: true,
type: "info", type: "info",
onClick: () => { onClick: () => router.push("/submission/" + row.id),
router.push("/submission/" + row.id)
},
}, },
() => row.id.slice(0, 12) () => row.id.slice(0, 12)
) )
@@ -191,7 +190,12 @@ const columns = computed(() => {
width: 120, width: 120,
render: (row) => submissionMemoryFormat(row.statistic_info.memory_cost), render: (row) => submissionMemoryFormat(row.statistic_info.memory_cost),
}, },
{ title: "语言", key: "language", width: 120 }, {
title: "语言",
key: "language",
width: 120,
render: (row) => LANGUAGE_SHOW_VALUE[row.language],
},
{ {
title: "用户", title: "用户",
key: "username", key: "username",

View File

@@ -18,6 +18,7 @@ const active = computed(() => {
const path = route.path.split("/")[1] || "problem" const path = route.path.split("/")[1] || "problem"
return !["user", "setting"].includes(path) ? path : "" return !["user", "setting"].includes(path) ? path : ""
}) })
const hiddenTitle = computed(() => isMobile.value && route.name === "learn")
async function handleLogout() { async function handleLogout() {
await logout() await logout()
@@ -98,7 +99,7 @@ function goHome() {
<template> <template>
<n-space justify="space-between" align="center"> <n-space justify="space-between" align="center">
<n-space align="center"> <n-space align="center">
<div v-if="isDesktop" class="websiteTitle" @click="goHome"> <div v-if="!hiddenTitle" class="websiteTitle" @click="goHome">
{{ configStore.config?.website_name }} {{ configStore.config?.website_name }}
</div> </div>
<n-menu <n-menu