Files
ojnext/src/oj/submission/detail.vue
yuetsh 7d8eff4ee8
Some checks failed
Deploy / deploy (build, debian, 22, /root/OJDeploy/data/clientnext) (push) Has been cancelled
Deploy / deploy (build:staging, school, 8822, /root/OJ/data/dist) (push) Has been cancelled
fix
2026-05-07 01:46:43 -06:00

165 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { getSubmission } from "oj/api"
import {
JUDGE_STATUS,
LANGUAGE_FORMAT_VALUE,
LANGUAGE_SHOW_VALUE,
} from "utils/constants"
import {
parseTime,
submissionMemoryFormat,
submissionTimeFormat,
utoa,
copyToClipboard,
} from "utils/functions"
import { Submission } from "utils/types"
import SubmissionResultTag from "shared/components/SubmissionResultTag.vue"
import { useBreakpoints } from "shared/composables/breakpoints"
const props = defineProps<{
submissionID: string
problemID?: string
submission?: Submission
hideList?: boolean
}>()
const route = useRoute()
const router = useRouter()
const message = useMessage()
const { isMobile, isDesktop } = useBreakpoints()
const submission = ref<Submission>()
const loading = ref(false)
async function init() {
submission.value = props.submission
if (submission.value) return
loading.value = true
const res = await getSubmission(props.submissionID)
submission.value = res.data
loading.value = false
}
const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
{ title: "测试用例", key: "test_case" },
{
title: "测试状态",
key: "result",
render: (row) => h(SubmissionResultTag, { result: row.result }),
},
{
title: "占用内存",
key: "memory",
render: (row) => submissionMemoryFormat(row.memory),
},
{
title: "执行耗时",
key: "real_time",
render: (row) => submissionTimeFormat(row.real_time),
},
]
function copyToCat() {
const lang = LANGUAGE_FORMAT_VALUE[submission.value!.language]
const data = {
lang,
code: submission.value!.code,
input: "",
}
const base64 = utoa(JSON.stringify(data))
const url = `${import.meta.env.PUBLIC_CODE_URL}?share=${encodeURIComponent(base64)}`
window.open(url, "_blank")
}
async function copyToProblem() {
const success = await copyToClipboard(submission.value!.code)
if (success) {
message.success("代码复制成功,需要手动粘贴到题目")
} else {
message.error("代码复制失败")
}
const contestID = submission.value!.contest
const problemSetId = (route.params.problemSetId as string) ?? ""
if (contestID) {
// 竞赛题目
router.push({
name: "contest problem",
params: {
contestID: String(contestID),
problemID: props.problemID,
},
})
} else if (problemSetId) {
// 题单题目
router.push({
name: "problemset problem",
params: {
problemSetId: problemSetId,
problemID: props.problemID,
},
})
} else {
// 普通题目
router.push({
name: "problem",
params: {
problemID: props.problemID,
},
})
}
}
onMounted(init)
</script>
<template>
<n-flex vertical v-if="submission" :size="24">
<n-flex :vertical="isMobile" justify="space-between">
<n-alert
style="flex: 1"
:type="JUDGE_STATUS[submission.result]['type']"
:title="JUDGE_STATUS[submission.result]['name']"
>
<n-flex>
<span>提交时间{{ parseTime(submission.create_time) }}</span>
<span>编程语言{{ LANGUAGE_SHOW_VALUE[submission.language] }}</span>
<span>用户{{ submission.username }}</span>
</n-flex>
</n-alert>
<n-flex :vertical="isDesktop" justify="center">
<n-button secondary @click="copyToCat">复制到自测猫</n-button>
<n-button secondary @click="copyToProblem">复制回到题目</n-button>
</n-flex>
</n-flex>
<n-card embedded>
<n-code
class="code"
:language="LANGUAGE_FORMAT_VALUE[submission.language]"
:code="submission.code"
show-line-numbers
/>
</n-card>
<n-data-table
v-if="!hideList && submission.info && submission.info.data"
:columns="columns"
:data="submission.info.data"
/>
</n-flex>
<n-spin v-else :show="loading" class="loading-container"> </n-spin>
</template>
<style scoped>
.code {
font-size: 20px;
overflow: auto;
}
.loading-container {
min-height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
</style>