@@ -16,12 +16,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { Submission } from "~/utils/types"
|
||||
import { SubmissionListItem } from "~/utils/types"
|
||||
|
||||
interface Props {
|
||||
submission: Submission
|
||||
submission: SubmissionListItem
|
||||
}
|
||||
const router = useRouter()
|
||||
const props = defineProps<Props>()
|
||||
defineEmits(["showCode"])
|
||||
|
||||
|
||||
@@ -1,38 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import copy from "copy-text-to-clipboard"
|
||||
import { createMessage, getSubmission } from "oj/api"
|
||||
import qs from "query-string"
|
||||
import { getSubmission } from "oj/api"
|
||||
import { JUDGE_STATUS, LANGUAGE_FORMAT_VALUE } from "utils/constants"
|
||||
import {
|
||||
parseTime,
|
||||
submissionMemoryFormat,
|
||||
submissionTimeFormat,
|
||||
utoa,
|
||||
} from "utils/functions"
|
||||
import { Submission } from "utils/types"
|
||||
import SubmissionResultTag from "~/shared/components/SubmissionResultTag.vue"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
|
||||
const TextEditor = defineAsyncComponent(
|
||||
() => import("~/shared/components/TextEditor.vue"),
|
||||
)
|
||||
|
||||
const props = defineProps<{
|
||||
submissionID: string
|
||||
problemID?: string
|
||||
submission?: Submission
|
||||
hideList?: boolean
|
||||
}>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const systemMessage = useMessage()
|
||||
const submission = ref<Submission>()
|
||||
const message = ref<string>("")
|
||||
const [copied, toggle] = useToggle()
|
||||
const [showBox, toggleBox] = useToggle()
|
||||
const { start } = useTimeoutFn(() => toggle(false), 1000, { immediate: false })
|
||||
const router = useRouter()
|
||||
|
||||
const canWriteMessage = computed(
|
||||
() =>
|
||||
userStore.isSuperAdmin && userStore.user!.id !== submission.value?.user_id,
|
||||
)
|
||||
const submission = ref<Submission>()
|
||||
|
||||
async function init() {
|
||||
submission.value = props.submission
|
||||
@@ -41,24 +29,6 @@ async function init() {
|
||||
submission.value = res.data
|
||||
}
|
||||
|
||||
function handleCopy(v: string) {
|
||||
copy(v)
|
||||
toggle(true)
|
||||
start()
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
if (!message.value || message.value === "<p><br></p>") return
|
||||
const data = {
|
||||
message: message.value,
|
||||
recipient: submission.value!.user_id,
|
||||
submission: submission.value!.id,
|
||||
}
|
||||
await createMessage(data)
|
||||
systemMessage.success("消息发送成功")
|
||||
message.value = ""
|
||||
}
|
||||
|
||||
const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
|
||||
{ title: "测试用例", key: "test_case" },
|
||||
{
|
||||
@@ -78,21 +48,55 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
|
||||
},
|
||||
]
|
||||
|
||||
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 = qs.stringifyUrl({
|
||||
url: import.meta.env.PUBLIC_CODE_URL,
|
||||
query: {
|
||||
share: base64,
|
||||
},
|
||||
})
|
||||
window.open(url, "_blank")
|
||||
}
|
||||
|
||||
function copyToProblem() {
|
||||
router.push({
|
||||
name: "problem",
|
||||
params: {
|
||||
contestID: submission.value!.contest,
|
||||
problemID: props.problemID,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(init)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex vertical v-if="submission" :size="24">
|
||||
<n-alert
|
||||
:type="JUDGE_STATUS[submission.result]['type']"
|
||||
:title="JUDGE_STATUS[submission.result]['name']"
|
||||
>
|
||||
<n-flex>
|
||||
<span>提交时间:{{ parseTime(submission.create_time) }}</span>
|
||||
<span>编程语言:{{ submission.language }}</span>
|
||||
<span>用户:{{ submission.username }}</span>
|
||||
<n-flex 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>编程语言:{{ submission.language }}</span>
|
||||
<span>用户:{{ submission.username }}</span>
|
||||
</n-flex>
|
||||
</n-alert>
|
||||
<n-flex vertical>
|
||||
<n-button secondary @click="copyToCat">复制到自测猫</n-button>
|
||||
<n-button secondary @click="copyToProblem">回到题目</n-button>
|
||||
</n-flex>
|
||||
</n-alert>
|
||||
</n-flex>
|
||||
<n-card embedded>
|
||||
<n-code
|
||||
class="code"
|
||||
@@ -101,24 +105,6 @@ onMounted(init)
|
||||
show-line-numbers
|
||||
/>
|
||||
</n-card>
|
||||
<n-flex>
|
||||
<n-button v-if="!hideList" @click="handleCopy(submission!.code)">
|
||||
{{ copied ? "成功复制" : "复制代码" }}
|
||||
</n-button>
|
||||
<n-button v-if="canWriteMessage" @click="toggleBox(!showBox)">
|
||||
{{ showBox ? "关闭" : "打开" }}文本框
|
||||
</n-button>
|
||||
<n-button v-if="canWriteMessage && showBox" @click="sendMessage">
|
||||
发送消息
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<TextEditor
|
||||
title=""
|
||||
simple
|
||||
v-if="showBox && canWriteMessage"
|
||||
v-model:value="message"
|
||||
:min-height="200"
|
||||
/>
|
||||
<n-data-table
|
||||
v-if="!hideList && submission.info && submission.info.data"
|
||||
:columns="columns"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { NButton, NH2, NText } from "naive-ui"
|
||||
import { adminRejudge, getSubmissions, getTodaySubmissionCount } from "oj/api"
|
||||
import { filterEmptyValue, parseTime } from "utils/functions"
|
||||
import { LANGUAGE, Submission } from "utils/types"
|
||||
import { LANGUAGE, SubmissionListItem } from "utils/types"
|
||||
import Pagination from "~/shared/components/Pagination.vue"
|
||||
import SubmissionResultTag from "~/shared/components/SubmissionResultTag.vue"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
@@ -29,7 +29,7 @@ const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
const message = useMessage()
|
||||
|
||||
const submissions = ref([])
|
||||
const submissions = ref<SubmissionListItem[]>([])
|
||||
const total = ref(0)
|
||||
const todayCount = ref(0)
|
||||
const query = reactive<Query>({
|
||||
@@ -42,6 +42,7 @@ const query = reactive<Query>({
|
||||
language: <LANGUAGE | "">route.query.language ?? "",
|
||||
})
|
||||
const submissionID = ref("")
|
||||
const problemDisplayID = ref("")
|
||||
const [statisticPanel, toggleStatisticPanel] = useToggle(false)
|
||||
const [codePanel, toggleCodePanel] = useToggle(false)
|
||||
|
||||
@@ -130,7 +131,7 @@ async function rejudge(submissionID: string) {
|
||||
listSubmissions()
|
||||
}
|
||||
|
||||
function problemClicked(row: Submission) {
|
||||
function problemClicked(row: SubmissionListItem) {
|
||||
if (route.name === "contest submissions") {
|
||||
const path = router.resolve({
|
||||
name: "contest problem",
|
||||
@@ -144,9 +145,10 @@ function problemClicked(row: Submission) {
|
||||
}
|
||||
}
|
||||
|
||||
function showCodePanel(id: string) {
|
||||
function showCodePanel(id: string, problem: string) {
|
||||
toggleCodePanel(true)
|
||||
submissionID.value = id
|
||||
problemDisplayID.value = problem
|
||||
}
|
||||
|
||||
watch(() => query.page, routerPush)
|
||||
@@ -178,7 +180,7 @@ watch(
|
||||
)
|
||||
|
||||
const columns = computed(() => {
|
||||
const res: DataTableColumn<Submission>[] = [
|
||||
const res: DataTableColumn<SubmissionListItem>[] = [
|
||||
{
|
||||
title: renderTableTitle("提交时间", "noto:seven-oclock"),
|
||||
key: "create_time",
|
||||
@@ -192,7 +194,7 @@ const columns = computed(() => {
|
||||
render: (row) =>
|
||||
h(SubmissionLink, {
|
||||
submission: row,
|
||||
onShowCode: () => showCodePanel(row.id),
|
||||
onShowCode: () => showCodePanel(row.id, row.problem),
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -347,7 +349,11 @@ const columns = computed(() => {
|
||||
:content-style="{ overflow: 'auto' }"
|
||||
title="代码详情"
|
||||
>
|
||||
<SubmissionDetail :submissionID="submissionID" hideList />
|
||||
<SubmissionDetail
|
||||
:problemID="problemDisplayID"
|
||||
:submissionID="submissionID"
|
||||
hideList
|
||||
/>
|
||||
</n-modal>
|
||||
</template>
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user