添加提交详情页

This commit is contained in:
2025-04-26 19:59:15 +08:00
parent b1fcecb9d4
commit ea1b114dd2
4 changed files with 89 additions and 7 deletions

View File

@@ -4,6 +4,9 @@
<n-flex>
<n-button quaternary @click="download" :disabled="!showDL">下载</n-button>
<n-button quaternary @click="open">全屏</n-button>
<n-button quaternary v-if="props.submissionId" @click="copyLink">
复制链接
</n-button>
<n-flex v-if="!!submission.id">
<n-button quaternary @click="emits('showCode')">查看代码</n-button>
<n-popover v-if="submission.my_score === 0">
@@ -21,21 +24,24 @@
<script lang="ts" setup>
import { watchDebounced } from "@vueuse/core"
import { computed, onMounted, useTemplateRef } from "vue"
import { Icon } from "@iconify/vue"
import { useRouter } from "vue-router"
import { Submission } from "../api"
import { submission } from "../store/submission"
import { useMessage } from "naive-ui"
import copy from "copy-text-to-clipboard"
interface Props {
html: string
css: string
js: string
submissionId?: string
}
const props = defineProps<Props>()
const emits = defineEmits(["afterScore", "showCode"])
const message = useMessage()
const router = useRouter()
const iframe = useTemplateRef<HTMLIFrameElement>("iframe")
const showDL = computed(() => props.html || props.css || props.js)
@@ -80,11 +86,24 @@ function download() {
}
function open() {
const newTab = window.open("/usercontent.html")
if (!newTab) return
newTab.document.open()
newTab.document.write(getContent())
newTab.document.close()
if (props.submissionId) {
const data = router.resolve({
name: "submission",
params: { id: props.submissionId },
})
window.open(data.href, "_blank")
} else {
const newTab = window.open("/usercontent.html")
if (!newTab) return
newTab.document.open()
newTab.document.write(getContent())
newTab.document.close()
}
}
function copyLink() {
copy(`${document.location.origin}/submission/${props.submissionId}`)
message.success("该提交的链接已复制")
}
async function updateScore(score: number) {

51
src/pages/Submission.vue Normal file
View File

@@ -0,0 +1,51 @@
<script lang="ts" setup>
import { onMounted, defineProps, useTemplateRef } from "vue"
import { Submission } from "../api"
import type { SubmissionAll } from "../utils/type"
interface Props {
id: string
}
const props = defineProps<Props>()
const iframe = useTemplateRef<HTMLIFrameElement>("iframe")
async function init() {
const submission: SubmissionAll = await Submission.get(props.id)
if (!iframe.value) return
const doc = iframe.value.contentDocument
if (doc) {
doc.open()
doc.write(`<!DOCTYPE html>
<html lang="zh-Hans-CN">
<head>
<meta charset="UTF-8" />
<title>预览</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>${submission.css}</style>
<link rel="stylesheet" href="/normalize.min.css" />
<script src="/jquery.min.js"><\/script>
</head>
<body>
${submission.html}
<script type="module">${submission.js}<\/script>
</body>
</html>`)
doc.close()
}
}
onMounted(init)
</script>
<template>
<iframe class="iframe" ref="iframe"></iframe>
</template>
<style scoped>
.iframe {
width: 100%;
height: 100%;
border: none;
outline: none;
}
</style>

View File

@@ -32,6 +32,7 @@
:html="html"
:css="css"
:js="js"
:submission-id="submission.id"
@after-score="afterScore"
@show-code="codeModal = true"
/>
@@ -128,7 +129,11 @@ const columns: DataTableColumn<SubmissionOut>[] = [
render: (row) =>
h(
NButton,
{ quaternary: true, onClick: () => getSubmissionByID(row.id) },
{
quaternary: submission.value.id !== row.id,
type: submission.value.id === row.id ? "primary" : "default",
onClick: () => getSubmissionByID(row.id),
},
() => "查看",
),
},
@@ -190,5 +195,6 @@ onUnmounted(() => {
.container {
padding: 10px;
box-sizing: border-box;
height: calc(100% - 43px);
}
</style>

View File

@@ -11,6 +11,12 @@ const routes = [
name: "submissions",
component: () => import("./pages/Submissions.vue"),
},
{
path: "/submission/:id",
name: "submission",
component: () => import("./pages/Submission.vue"),
props: true
},
{
path: "/dashboard",
name: "dashboard",