submission list.

This commit is contained in:
2023-01-14 22:05:28 +08:00
parent b568539610
commit a62f744a9a
8 changed files with 82 additions and 45 deletions

View File

@@ -15,6 +15,7 @@
"@vueuse/core": "^9.10.0", "@vueuse/core": "^9.10.0",
"@vueuse/integrations": "^9.10.0", "@vueuse/integrations": "^9.10.0",
"axios": "^1.2.2", "axios": "^1.2.2",
"copy-text-to-clipboard": "^3.0.1",
"element-plus": "^2.2.28", "element-plus": "^2.2.28",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"party-js": "^2.2.0", "party-js": "^2.2.0",

7
pnpm-lock.yaml generated
View File

@@ -9,6 +9,7 @@ specifiers:
'@vueuse/core': ^9.10.0 '@vueuse/core': ^9.10.0
'@vueuse/integrations': ^9.10.0 '@vueuse/integrations': ^9.10.0
axios: ^1.2.2 axios: ^1.2.2
copy-text-to-clipboard: ^3.0.1
element-plus: ^2.2.28 element-plus: ^2.2.28
monaco-editor: ^0.34.1 monaco-editor: ^0.34.1
normalize.css: ^8.0.1 normalize.css: ^8.0.1
@@ -31,6 +32,7 @@ dependencies:
'@vueuse/core': 9.10.0_vue@3.2.45 '@vueuse/core': 9.10.0_vue@3.2.45
'@vueuse/integrations': 9.10.0_axios@1.2.2+vue@3.2.45 '@vueuse/integrations': 9.10.0_axios@1.2.2+vue@3.2.45
axios: 1.2.2 axios: 1.2.2
copy-text-to-clipboard: 3.0.1
element-plus: 2.2.28_vue@3.2.45 element-plus: 2.2.28_vue@3.2.45
normalize.css: 8.0.1 normalize.css: 8.0.1
party-js: 2.2.0 party-js: 2.2.0
@@ -722,6 +724,11 @@ packages:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: false dev: false
/copy-text-to-clipboard/3.0.1:
resolution: {integrity: sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==}
engines: {node: '>=12'}
dev: false
/cross-spawn/7.0.3: /cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'} engines: {node: '>= 8'}

View File

@@ -66,11 +66,27 @@ export function getSubmission(id: string) {
} }
export function submissionExists(problemID: number) { export function submissionExists(problemID: number) {
return http.get("submission_exists", { return useAxios(
params: { problem_id: problemID }, "submission_exists",
}) { params: { problem_id: problemID } },
http,
{ immediate: false }
)
} }
export function submitCode(data: SubmitCodePayload) { export function submitCode(data: SubmitCodePayload) {
return http.post("submission", data) return http.post("submission", data)
} }
export function listSubmissions(params: {
myself: "1" | "0"
result: string
username: string
page: number
contest_id: string
problem_id: string
limit: number
offset: number
}) {
return useAxios("submissions", { params }, http)
}

View File

@@ -4,7 +4,6 @@ import { SOURCES } from "utils/constants"
import { Problem } from "utils/types" import { Problem } from "utils/types"
import Monaco from "~/shared/Monaco/index.vue" import Monaco from "~/shared/Monaco/index.vue"
import { useCodeStore } from "oj/store/code" import { useCodeStore } from "oj/store/code"
import { submissionExists } from "oj/api"
import SubmitPanel from "./SubmitPanel.vue" import SubmitPanel from "./SubmitPanel.vue"
import TestcasePanel from "./TestcasePanel.vue" import TestcasePanel from "./TestcasePanel.vue"
@@ -22,7 +21,6 @@ code.value = props.problem.template[code.language] || SOURCES[code.language]
const tab = ref("test") const tab = ref("test")
const submitPanelRef = ref<{ submit: Function }>() const submitPanelRef = ref<{ submit: Function }>()
const [tried] = useToggle()
watch(() => code.language, reset) watch(() => code.language, reset)
@@ -34,15 +32,6 @@ function change(value: string) {
code.value = value code.value = value
} }
onMounted(() => {
checkIfTried()
})
async function checkIfTried() {
const res = await submissionExists(props.problem.id)
tried.value = res.data
}
function onTab(pane: TabsPaneContext) { function onTab(pane: TabsPaneContext) {
if (pane.paneName === "submit") { if (pane.paneName === "submit") {
submitPanelRef && submitPanelRef.value!.submit() submitPanelRef && submitPanelRef.value!.submit()
@@ -62,6 +51,9 @@ function onTab(pane: TabsPaneContext) {
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="reset">重置</el-button> <el-button @click="reset">重置</el-button>
<el-button @click="$router.push(`/status?problem=${problem.id}`)">
提交信息
</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<Monaco <Monaco

View File

@@ -1,9 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { Flag, CloseBold, Select } from "@element-plus/icons-vue" import { Flag, CloseBold, Select, CopyDocument } from "@element-plus/icons-vue"
import copy from "copy-text-to-clipboard"
import { useCodeStore } from "oj/store/code" import { useCodeStore } from "oj/store/code"
import { SOURCES } from "utils/constants" import { SOURCES } from "utils/constants"
import { Problem } from "utils/types" import { Problem } from "utils/types"
import { createTestSubmission } from "utils/judge" import { createTestSubmission } from "utils/judge"
import { submissionExists } from "oj/api"
interface Props { interface Props {
problem: Problem problem: Problem
@@ -16,7 +18,12 @@ type Sample = Problem["samples"][number] & {
} }
const props = defineProps<Props>() const props = defineProps<Props>()
const route = useRoute()
const contestID = <string>route.params.contestID
const { data: hasSolved, execute } = submissionExists(props.problem.id)
if (contestID) {
execute()
}
const samples = ref<Sample[]>( const samples = ref<Sample[]>(
props.problem.samples.map((sample, index) => ({ props.problem.samples.map((sample, index) => ({
...sample, ...sample,
@@ -77,6 +84,16 @@ const type = (status: Sample["status"]) =>
</script> </script>
<template> <template>
<el-alert
v-if="problem.my_status === 0 || (contestID && hasSolved)"
type="success"
:closable="false"
center
title="🎉 本 题 已 经 被 你 解 决 啦"
effect="dark"
>
</el-alert>
<h1>{{ problem.title }}</h1> <h1>{{ problem.title }}</h1>
<p class="title">描述</p> <p class="title">描述</p>
<div class="content" v-html="problem.description"></div> <div class="content" v-html="problem.description"></div>
@@ -107,10 +124,22 @@ const type = (status: Sample["status"]) =>
></el-button> ></el-button>
</el-space> </el-space>
<el-descriptions border direction="vertical" :column="2"> <el-descriptions border direction="vertical" :column="2">
<el-descriptions-item width="50%" label="输入"> <el-descriptions-item width="50%">
<template #label>
<el-space>
<span>输入</span>
<el-icon @click="copy(sample.input)"><CopyDocument /> </el-icon>
</el-space>
</template>
<div class="testcase">{{ sample.input }}</div> <div class="testcase">{{ sample.input }}</div>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item width="50%" label="输出"> <el-descriptions-item width="50%">
<template #label>
<el-space>
<span>输出</span>
<el-icon @click="copy(sample.output)"><CopyDocument /> </el-icon>
</el-space>
</template>
<div class="testcase">{{ sample.output }}</div> <div class="testcase">{{ sample.output }}</div>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="运行结果" v-if="sample.status === 'failed'"> <el-descriptions-item label="运行结果" v-if="sample.status === 'failed'">
@@ -131,6 +160,7 @@ const type = (status: Sample["status"]) =>
margin: 24px 0 16px 0; margin: 24px 0 16px 0;
color: var(--el-color-primary); color: var(--el-color-primary);
} }
.testcaseTitle { .testcaseTitle {
margin-bottom: 24px; margin-bottom: 24px;
} }

View File

@@ -1,18 +0,0 @@
<script setup lang="ts">
import Pagination from "~/shared/Pagination/index.vue"
const query = reactive({
page: 1,
limit: 10,
})
const total = ref(100)
</script>
<template>
<el-table max-height="calc(100vh - 171px)"></el-table>
<Pagination
:total="total"
v-model:limit="query.limit"
v-model:page="query.page"
/>
</template>
<style scoped></style>

View File

@@ -2,9 +2,9 @@
import Editor from "./components/Editor.vue" import Editor from "./components/Editor.vue"
import ProblemContent from "./components/ProblemContent.vue" import ProblemContent from "./components/ProblemContent.vue"
import ProblemInfo from "./components/ProblemInfo.vue" import ProblemInfo from "./components/ProblemInfo.vue"
import SubmissionList from "./components/SubmissionList.vue"
import { getProblem } from "oj/api" import { getProblem } from "oj/api"
import { isDesktop, isMobile } from "~/shared/composables/breakpoints" import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
import { TabsPaneContext } from "element-plus"
interface Props { interface Props {
problemID: string problemID: string
@@ -16,7 +16,6 @@ const props = withDefaults(defineProps<Props>(), {
}) })
const { data: problem, isFinished } = getProblem(props.problemID) const { data: problem, isFinished } = getProblem(props.problemID)
provide("problem", readonly(problem)) provide("problem", readonly(problem))
</script> </script>
@@ -33,11 +32,8 @@ provide("problem", readonly(problem))
<el-tab-pane v-if="isMobile" label="代码编辑" lazy> <el-tab-pane v-if="isMobile" label="代码编辑" lazy>
<Editor :problem="problem" /> <Editor :problem="problem" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="提交列表" lazy>
<SubmissionList />
</el-tab-pane>
<el-tab-pane label="比赛信息" v-if="props.contestID" lazy></el-tab-pane> <el-tab-pane label="比赛信息" v-if="props.contestID" lazy></el-tab-pane>
<el-tab-pane label="统计信息" lazy> <el-tab-pane label="题目信息" lazy>
<ProblemInfo :problem="problem" /> <ProblemInfo :problem="problem" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

View File

@@ -1,5 +1,18 @@
<script setup lang="ts"></script> <script setup lang="ts">
import Pagination from "~/shared/Pagination/index.vue"
<template>status list</template>
const query = reactive({
page: 1,
limit: 10,
})
const total = ref(100)
</script>
<template>
<el-table max-height="calc(100vh - 171px)"></el-table>
<Pagination
:total="total"
v-model:limit="query.limit"
v-model:page="query.page"
/>
</template>
<style scoped></style> <style scoped></style>