refactor axios.

This commit is contained in:
2023-01-08 14:42:54 +08:00
parent 7bea386dbc
commit e306e6b463
16 changed files with 270 additions and 113 deletions

View File

@@ -1,12 +1,14 @@
import { getACRate } from "./../utils/functions"
import { DIFFICULTY } from "./../utils/constants"
import { Problem, LANGUAGE } from "./../utils/types"
import http from "./../utils/http"
import { useAxios } from "@vueuse/integrations/useAxios"
function filterResult(result: any) {
function filterResult(result: Problem) {
const newResult: any = {
displayID: result._id,
_id: result._id,
title: result.title,
difficulty: DIFFICULTY[<"Low" | "Mid" | "High">result.difficulty],
difficulty: DIFFICULTY[result.difficulty],
tags: result.tags,
submission: result.submission_number,
rate: getACRate(result.accepted_number, result.submission_number),
@@ -46,7 +48,7 @@ export async function getProblemList(
}
export function getProblemTagList() {
return http.get("problem/tags")
return useAxios<{ id: number; name: string }[]>("problem/tags", http)
}
export function getRandomProblemID() {
@@ -54,11 +56,20 @@ export function getRandomProblemID() {
}
export function getProblem(id: string) {
return http.get("problem", {
params: { problem_id: id },
return useAxios<Problem>("problem", { params: { problem_id: id } }, http)
}
export function getSubmission(id: string) {
return http.get("submission", {
params: { id },
})
}
export function getWebsite() {
return http.get("website")
export function submitCode(data: {
problem_id: number
contest_id?: number
language: LANGUAGE
code: string
}) {
return http.post("submission", data)
}

View File

@@ -35,11 +35,11 @@ onMounted(userStore.getMyProfile)
<el-menu-item index="/status">提交</el-menu-item>
<el-menu-item index="/rank">排名</el-menu-item>
</el-menu>
<div v-if="userStore.isLoaded && !userStore.isAuthed" class="actions">
<div v-if="userStore.isFinished && !userStore.isAuthed" class="actions">
<el-button @click="loginStore.show">登录</el-button>
<el-button @click="signupStore.show">注册</el-button>
</div>
<div v-if="userStore.isLoaded && userStore.isAuthed" class="actions">
<div v-if="userStore.isFinished && userStore.isAuthed" class="actions">
<el-dropdown @command="handleDropdown">
<el-button>{{ userStore.user.username }}</el-button>
<template #dropdown>

View File

@@ -1,29 +1,28 @@
<script lang="ts" setup>
import loader, { Monaco } from "@monaco-editor/loader"
import { ref, onBeforeUnmount, onMounted, watch, reactive } from "vue"
import { ref, onBeforeUnmount, onMounted, watch, reactive, computed } from "vue"
import {
LANGUAGE,
LANGUAGE_LABEL,
LANGUAGE_VALUE,
SOURCES,
} from "../../../utils/constants"
import { isMobile } from "../../../utils/breakpoints"
import { submitCode } from "../../api"
import { Problem } from "../../../utils/types"
const { problem } = defineProps<{
problem: {
languages: Array<LANGUAGE>
template: { [key in LANGUAGE]?: string }
}
const { problem, contestID = "" } = defineProps<{
contestID?: string
problemID?: string
problem: Problem
}>()
const state = reactive({
values: ref({ ...SOURCES }),
language: problem.languages[0] || "C",
isMobile,
submissionId: "",
})
const monacoEditorRef = ref()
let monaco: Monaco
function reset() {
@@ -34,9 +33,7 @@ function reset() {
}
}
onMounted(() => {
init()
})
onMounted(init)
onBeforeUnmount(() => {
monaco.editor.getModels().forEach((model) => model.dispose())
@@ -77,6 +74,29 @@ async function init() {
state.values[state.language] = monaco.editor.getModels()[0].getValue()
})
}
const submitDisabled = computed(() => {
const code = state.values[state.language]
return (
code.trim() === "" ||
code === problem.template[state.language] ||
code === SOURCES[state.language]
)
})
async function submit() {
const data = {
problem_id: problem.id,
language: state.language,
code: state.values[state.language],
}
if (contestID) {
//@ts-ignore
data.contest_id = parseInt(contestID)
}
const res = await submitCode(data)
state.submissionId = res.data.submission_id
}
</script>
<template>
@@ -107,7 +127,9 @@ async function init() {
<el-form class="actions">
<el-form-item>
<el-button>运行</el-button>
<el-button type="primary">提交</el-button>
<el-button type="primary" :disabled="submitDisabled" @click="submit">
提交
</el-button>
</el-form-item>
</el-form>
</template>

View File

@@ -1,5 +1,7 @@
<script setup lang="ts">
const { problem } = defineProps(["problem"])
import { Problem } from "../../../utils/types"
const { problem } = defineProps<{ problem: Problem }>()
</script>
<template>

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import { DIFFICULTY } from "../../../utils/constants"
import { getACRate, getTagColor } from "../../../utils/functions"
import { getACRate, getTagColor, parseTime } from "../../../utils/functions"
import { isDesktop } from "../../../utils/breakpoints"
import { Problem } from "../../../utils/types"
const { problem } = defineProps(["problem"])
const { problem } = defineProps<{ problem: Problem }>()
</script>
<template>
@@ -14,19 +15,20 @@ const { problem } = defineProps(["problem"])
<el-descriptions-item label="出题人">
{{ problem.created_by.username }}
</el-descriptions-item>
<el-descriptions-item label="难度">
<el-tag disable-transitions :type="getTagColor(problem.difficulty)">
{{ DIFFICULTY[<"Low" | "Mid" | "High">problem.difficulty] }}
</el-tag>
<el-descriptions-item label="创建时间">
{{ parseTime(problem.create_time) }}
</el-descriptions-item>
<el-descriptions-item label="时间限制">
{{ problem.time_limit }}毫秒
</el-descriptions-item>
<el-descriptions-item label="内存限制">
{{ problem.memory_limit }}MB
</el-descriptions-item>
<el-descriptions-item label="类型">
{{ problem.rule_type }}
<el-descriptions-item label="难度">
<el-tag disable-transitions :type="getTagColor(problem.difficulty)">
{{ DIFFICULTY[problem.difficulty] }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="提交正确">

View File

@@ -1,39 +1,19 @@
<script setup lang="ts">
import { onMounted, ref } from "vue"
import { useRoute } from "vue-router"
import Editor from "./components/editor.vue"
import ProblemContent from "./components/problem-content.vue"
import ProblemInfo from "./components/problem-info.vue"
import { getProblem } from "../api"
import { isDesktop, isMobile } from "../../utils/breakpoints"
const route = useRoute()
const contestID = route.params.contestID as string
const problemID = route.params.problemID as string
const problem = ref({
_id: "",
created_by: {},
io_mode: {},
languages: [],
samples: [],
statistic_info: {},
tags: [],
template: {},
})
async function init() {
const res = await getProblem(problemID)
problem.value = res.data
}
onMounted(() => {
init()
})
const { problemID = "", contestID = "" } = defineProps<{
problemID?: string
contestID?: string
}>()
const { data: problem, isFinished } = getProblem(problemID)
</script>
<template>
<el-row v-if="problem._id">
<el-row v-if="isFinished && problem">
<el-col :span="isDesktop ? 12 : 24">
<el-tabs type="border-card">
<el-tab-pane label="题目描述">

View File

@@ -17,9 +17,10 @@ const router = useRouter()
const route = useRoute()
const userStore = useUserStore()
const problems = ref([])
const tags = ref(<{ id: number; name: string }[]>[])
const total = ref(0)
const { data: tags } = getProblemTagList()
const query = reactive({
keyword: route.query.keyword || "",
difficulty: route.query.difficulty || "",
@@ -28,11 +29,6 @@ const query = reactive({
limit: parseInt(<string>route.query.limit) || 10,
})
async function listTags() {
const res = await getProblemTagList()
tags.value = res.data
}
async function listProblems() {
query.keyword = route.query.keyword || ""
query.difficulty = route.query.difficulty || ""
@@ -77,7 +73,7 @@ async function getRandom() {
}
function goProblem(row: any) {
router.push("/problem/" + row.displayID)
router.push("/problem/" + row._id)
}
watch(() => query.page, routePush)
@@ -98,12 +94,9 @@ watch(
)
// TODO: 这里会在登录时候执行两次有BUG
watch(() => userStore.isLoaded && userStore.isAuthed, listProblems)
watch(() => userStore.isFinished && userStore.isAuthed, listProblems)
onMounted(() => {
listTags()
listProblems()
})
onMounted(listProblems)
</script>
<template>
@@ -158,11 +151,7 @@ onMounted(() => {
/></el-icon>
</template>
</el-table-column>
<el-table-column
prop="displayID"
label="编号"
:width="isDesktop ? 100 : 60"
/>
<el-table-column prop="_id" label="编号" :width="isDesktop ? 100 : 60" />
<el-table-column prop="title" label="标题" />
<el-table-column label="难度" width="100">
<template #default="scope">