problem submission tab,
This commit is contained in:
100
src/oj/problem/components/ProblemSubmission.vue
Normal file
100
src/oj/problem/components/ProblemSubmission.vue
Normal 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>
|
||||
@@ -10,6 +10,9 @@ const ProblemContent = defineAsyncComponent(
|
||||
const ProblemInfo = defineAsyncComponent(
|
||||
() => import("./components/ProblemInfo.vue")
|
||||
)
|
||||
const ProblemSubmission = defineAsyncComponent(
|
||||
() => import("./components/ProblemSubmission.vue")
|
||||
)
|
||||
|
||||
interface Props {
|
||||
problemID: string
|
||||
@@ -51,6 +54,9 @@ onBeforeUnmount(() => {
|
||||
<n-tab-pane name="info" tab="题目统计">
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="submission" tab="我的提交">
|
||||
<ProblemSubmission />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-scrollbar>
|
||||
<n-tabs v-else default-value="content" type="segment">
|
||||
@@ -63,6 +69,9 @@ onBeforeUnmount(() => {
|
||||
<n-tab-pane name="info" tab="题目统计">
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="submission" tab="我的提交">
|
||||
<ProblemSubmission />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-gi>
|
||||
<n-gi v-if="isDesktop">
|
||||
|
||||
@@ -65,16 +65,6 @@ onMounted(init)
|
||||
</n-space>
|
||||
</n-alert>
|
||||
<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
|
||||
class="code"
|
||||
:language="LANGUAGE_FORMAT_VALUE[submission.language]"
|
||||
@@ -82,6 +72,9 @@ onMounted(init)
|
||||
show-line-numbers
|
||||
/>
|
||||
</n-card>
|
||||
<n-button type="primary" @click="handleCopy(submission!.code)">
|
||||
{{ copied ? "成功复制" : "复制代码" }}
|
||||
</n-button>
|
||||
<n-data-table
|
||||
v-if="submission.info && submission.info.data"
|
||||
:columns="columns"
|
||||
@@ -94,8 +87,4 @@ onMounted(init)
|
||||
.code {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.copyBtn {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Submission } from "utils/types"
|
||||
import { adminRejudge, getSubmissions } from "oj/api"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
import { LANGUAGE_SHOW_VALUE } from "~/utils/constants"
|
||||
|
||||
interface Query {
|
||||
username: string
|
||||
@@ -136,9 +137,7 @@ const columns = computed(() => {
|
||||
{
|
||||
text: true,
|
||||
type: "info",
|
||||
onClick: () => {
|
||||
router.push("/submission/" + row.id)
|
||||
},
|
||||
onClick: () => router.push("/submission/" + row.id),
|
||||
},
|
||||
() => row.id.slice(0, 12)
|
||||
)
|
||||
@@ -191,7 +190,12 @@ const columns = computed(() => {
|
||||
width: 120,
|
||||
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: "用户",
|
||||
key: "username",
|
||||
|
||||
@@ -18,6 +18,7 @@ const active = computed(() => {
|
||||
const path = route.path.split("/")[1] || "problem"
|
||||
return !["user", "setting"].includes(path) ? path : ""
|
||||
})
|
||||
const hiddenTitle = computed(() => isMobile.value && route.name === "learn")
|
||||
|
||||
async function handleLogout() {
|
||||
await logout()
|
||||
@@ -98,7 +99,7 @@ function goHome() {
|
||||
<template>
|
||||
<n-space justify="space-between" 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 }}
|
||||
</div>
|
||||
<n-menu
|
||||
|
||||
Reference in New Issue
Block a user