remove useAxios.
This commit is contained in:
@@ -29,4 +29,39 @@ function change(value: string) {
|
||||
</n-grid>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style>
|
||||
.__layout-dark .shiki-light {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.__layout .shiki-dark {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shiki .highlighted {
|
||||
background: #7f7f7f20;
|
||||
display: block;
|
||||
margin: 0 -1rem;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.markdown-body code[v-pre] {
|
||||
font-size: 20px;
|
||||
font-family: "SF Mono", Monaco, Menlo, Consolas, "Ubuntu Mono",
|
||||
"Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
counter-reset: step;
|
||||
counter-increment: step 0;
|
||||
}
|
||||
|
||||
.markdown-body code[v-pre] .line:not(:last-child)::before {
|
||||
content: counter(step);
|
||||
counter-increment: step;
|
||||
width: 1rem;
|
||||
margin-right: 1.5rem;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
color: rgba(115, 138, 148, 0.4);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
# 11
|
||||
|
||||
## 1
|
||||
|
||||
哈哈
|
||||
|
||||
```c {3-4}
|
||||
#include<stdio.h>
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
123
|
||||
|
||||
@@ -19,7 +19,6 @@ router.beforeEach((to, from, next) => {
|
||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||
if (!storage.get(STORAGE_KEY.AUTHED)) {
|
||||
toggleLogin(true)
|
||||
next("/")
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useAxios } from "@vueuse/integrations/useAxios"
|
||||
import http from "utils/http"
|
||||
import { getACRate } from "utils/functions"
|
||||
import { DIFFICULTY } from "utils/constants"
|
||||
@@ -53,7 +52,7 @@ export async function getProblemList(
|
||||
}
|
||||
|
||||
export function getProblemTagList() {
|
||||
return useAxios<{ id: number; name: string }[]>("problem/tags", http)
|
||||
return http.get("problem/tags")
|
||||
}
|
||||
|
||||
export function getRandomProblemID() {
|
||||
@@ -61,7 +60,7 @@ export function getRandomProblemID() {
|
||||
}
|
||||
|
||||
export function getProblem(id: string) {
|
||||
return useAxios<Problem>("problem", { params: { problem_id: id } }, http)
|
||||
return http.get("problem", { params: { problem_id: id } })
|
||||
}
|
||||
|
||||
export function getSubmission(id: string) {
|
||||
@@ -71,12 +70,7 @@ export function getSubmission(id: string) {
|
||||
}
|
||||
|
||||
export function submissionExists(problemID: number) {
|
||||
return useAxios(
|
||||
"submission_exists",
|
||||
{ params: { problem_id: problemID } },
|
||||
http,
|
||||
{ immediate: false }
|
||||
)
|
||||
return http.get("submission_exists", { params: { problem_id: problemID } })
|
||||
}
|
||||
|
||||
export function submitCode(data: SubmitCodePayload) {
|
||||
@@ -107,3 +101,7 @@ export function getContestList(query: {
|
||||
}) {
|
||||
return http.get("contests", { params: query })
|
||||
}
|
||||
|
||||
export function getContest(id: string) {
|
||||
return http.get("contest", { params: { id } })
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>contest detail</template>
|
||||
<template></template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -126,9 +126,9 @@ function rowProps(row: Contest) {
|
||||
v-model:value="query.status"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-form-item label="搜索比赛标题">
|
||||
<n-input
|
||||
placeholder="关键字"
|
||||
placeholder="输入后回车"
|
||||
v-model:value="query.keyword"
|
||||
@change="search"
|
||||
/>
|
||||
|
||||
@@ -23,10 +23,14 @@ const route = useRoute()
|
||||
const contestID = <string>route.params.contestID
|
||||
const theme = useThemeVars()
|
||||
const style = computed(() => "color: " + theme.value.primaryColor)
|
||||
const { data: hasSolved, execute } = submissionExists(props.problem.id)
|
||||
if (contestID) {
|
||||
execute()
|
||||
}
|
||||
const solved = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
if (contestID) {
|
||||
checkSubmisson()
|
||||
}
|
||||
})
|
||||
|
||||
const samples = ref<Sample[]>(
|
||||
props.problem.samples.map((sample, index) => ({
|
||||
...sample,
|
||||
@@ -45,6 +49,12 @@ const disabled = computed(
|
||||
code.value === SOURCES[code.language]
|
||||
)
|
||||
)
|
||||
|
||||
async function checkSubmisson() {
|
||||
const res = await submissionExists(props.problem.id)
|
||||
solved.value = res.data
|
||||
}
|
||||
|
||||
async function test(sample: Sample, index: number) {
|
||||
samples.value = samples.value.map((sample) => {
|
||||
if (sample.id === index) {
|
||||
@@ -87,7 +97,7 @@ const type = (status: ProblemStatus) =>
|
||||
|
||||
<template>
|
||||
<n-alert
|
||||
v-if="problem.my_status === 0 || (contestID && hasSolved)"
|
||||
v-if="problem.my_status === 0 || (contestID && solved)"
|
||||
type="success"
|
||||
title="🎉 本 题 已 经 被 你 解 决 啦"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { getProblem } from "oj/api"
|
||||
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
||||
import { Problem } from "utils/types"
|
||||
|
||||
const Editor = defineAsyncComponent(() => import("./components/Editor.vue"))
|
||||
const Panel = defineAsyncComponent(() => import("./components/Panel.vue"))
|
||||
@@ -19,13 +20,18 @@ interface Props {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
contestID: "",
|
||||
})
|
||||
const problem = ref<Problem>()
|
||||
|
||||
const { data: problem, isFinished } = getProblem(props.problemID)
|
||||
async function init() {
|
||||
const res = await getProblem(props.problemID)
|
||||
problem.value = res.data
|
||||
}
|
||||
onMounted(init)
|
||||
provide("problem", readonly(problem))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-grid v-if="isFinished && problem" x-gap="16" :cols="2">
|
||||
<n-grid v-if="problem" x-gap="16" :cols="2">
|
||||
<n-gi :span="isDesktop ? 1 : 2">
|
||||
<n-tabs default-value="content">
|
||||
<n-tab-pane name="content" tab="题目描述">
|
||||
|
||||
@@ -39,12 +39,11 @@ const theme = useThemeVars()
|
||||
const userStore = useUserStore()
|
||||
const problems = ref<ProblemFiltered[]>([])
|
||||
const total = ref(0)
|
||||
|
||||
const { data } = getProblemTagList()
|
||||
const tags = ref<{ id: number; name: string }[]>([])
|
||||
|
||||
const tagOptions = computed(() => [
|
||||
{ label: "全部", value: "" },
|
||||
...(data.value?.map((t) => ({ label: t.name, value: t.name })) || []),
|
||||
...(tags.value?.map((t) => ({ label: t.name, value: t.name })) || []),
|
||||
])
|
||||
|
||||
const query = reactive<Query>({
|
||||
@@ -73,6 +72,11 @@ async function listProblems() {
|
||||
problems.value = res.results
|
||||
}
|
||||
|
||||
async function listTags() {
|
||||
const res = await getProblemTagList()
|
||||
tags.value = res.data
|
||||
}
|
||||
|
||||
function routerPush() {
|
||||
router.push({
|
||||
path: route.path,
|
||||
@@ -115,13 +119,16 @@ watch(
|
||||
// TODO: 这里会在登录时候执行两次,有BUG
|
||||
watch(() => userStore.isFinished && userStore.isAuthed, listProblems)
|
||||
|
||||
onMounted(listProblems)
|
||||
onMounted(() => {
|
||||
listProblems()
|
||||
listTags()
|
||||
})
|
||||
|
||||
const columns: DataTableColumn<ProblemFiltered>[] = [
|
||||
{
|
||||
title: "状态",
|
||||
key: "status",
|
||||
width: 80,
|
||||
width: 60,
|
||||
render: (row) => {
|
||||
if (row.status === "passed") {
|
||||
return h(NIcon, { color: theme.value.successColor }, () => h(Select))
|
||||
|
||||
@@ -22,14 +22,14 @@ const columns: DataTableColumn<Rank>[] = [
|
||||
{
|
||||
title: "排名",
|
||||
key: "index",
|
||||
minWidth: 60,
|
||||
width: 100,
|
||||
render: (_, index) =>
|
||||
h("span", {}, index + (query.page - 1) * query.limit + 1),
|
||||
},
|
||||
{
|
||||
title: "用户",
|
||||
key: "username",
|
||||
minWidth: 100,
|
||||
width: 200,
|
||||
render: (row) =>
|
||||
h(
|
||||
NButton,
|
||||
@@ -38,12 +38,12 @@ const columns: DataTableColumn<Rank>[] = [
|
||||
),
|
||||
},
|
||||
{ title: "骚话", key: "mood", minWidth: 200 },
|
||||
{ title: "已解决", key: "accepted_number", minWidth: 80 },
|
||||
{ title: "提交数", key: "submission_number", minWidth: 80 },
|
||||
{ title: "已解决", key: "accepted_number", width: 100 },
|
||||
{ title: "提交数", key: "submission_number", width: 100 },
|
||||
{
|
||||
title: "正确率",
|
||||
key: "rate",
|
||||
minWidth: 80,
|
||||
width: 100,
|
||||
render: (row) => getACRate(row.accepted_number, row.submission_number),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -18,6 +18,7 @@ export const routes = [
|
||||
path: "submission/:submissionID",
|
||||
component: () => import("oj/submission/detail.vue"),
|
||||
props: true,
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "contest",
|
||||
|
||||
@@ -6,6 +6,8 @@ import type { FormRules } from "naive-ui"
|
||||
|
||||
const userStore = useUserStore()
|
||||
const loginRef = ref()
|
||||
const [isLoading] = useToggle()
|
||||
const error = ref()
|
||||
const form = reactive({
|
||||
username: "",
|
||||
password: "",
|
||||
@@ -17,13 +19,21 @@ const rules: FormRules = {
|
||||
{ min: 6, max: 20, message: "长度在6到20位之间", trigger: "input" },
|
||||
],
|
||||
}
|
||||
const { isLoading, error, execute } = login(form)
|
||||
|
||||
const msg = computed(() => error.value && "用户名或密码不正确")
|
||||
|
||||
async function submit() {
|
||||
loginRef.value?.validate(async (errors: FormRules | undefined) => {
|
||||
if (!errors) {
|
||||
await execute()
|
||||
try {
|
||||
error.value = null
|
||||
isLoading.value = true
|
||||
await login(form)
|
||||
} catch (err) {
|
||||
error.value = err
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
if (!error.value) {
|
||||
toggleLogin(false)
|
||||
userStore.getMyProfile()
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import { useAxios } from "@vueuse/integrations/useAxios"
|
||||
import http from "utils/http"
|
||||
|
||||
export function login(data: { username: string; password: string }) {
|
||||
return useAxios("login", { method: "post", data }, http, {
|
||||
immediate: false,
|
||||
})
|
||||
return http.post("login", data)
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return http.get("logout")
|
||||
}
|
||||
|
||||
export function getUserInfo(username: string) {
|
||||
return useAxios("profile", { params: { username } }, http, {
|
||||
immediate: false,
|
||||
})
|
||||
export function getProfile(username: string = "") {
|
||||
return http.get("profile", { params: { username } })
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { PROBLEM_PERMISSION, STORAGE_KEY, USER_TYPE } from "utils/constants"
|
||||
import storage from "utils/storage"
|
||||
import { getUserInfo } from "../api"
|
||||
import { getProfile } from "../api"
|
||||
|
||||
export const useUserStore = defineStore("user", () => {
|
||||
const { data: profile, isFinished, execute } = getUserInfo("")
|
||||
const profile = ref()
|
||||
const [isFinished] = useToggle(false)
|
||||
const user = computed(() => profile?.value?.user ?? {})
|
||||
const isAuthed = computed(() => !!user.value.email)
|
||||
const isAdminRole = computed(
|
||||
@@ -19,7 +20,10 @@ export const useUserStore = defineStore("user", () => {
|
||||
)
|
||||
|
||||
async function getMyProfile() {
|
||||
await execute()
|
||||
isFinished.value = false
|
||||
const res = await getProfile()
|
||||
profile.value = res.data
|
||||
isFinished.value = true
|
||||
storage.set(STORAGE_KEY.AUTHED, !!user.value.email)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,49 @@
|
||||
export interface Profile {
|
||||
id: number
|
||||
user: User
|
||||
real_name: string
|
||||
acm_problems_status: {
|
||||
problems: {
|
||||
[key: string]: {
|
||||
_id: string
|
||||
status: number
|
||||
}
|
||||
}
|
||||
}
|
||||
oi_problems_status: {
|
||||
problems: {
|
||||
[key: string]: {
|
||||
_id: string
|
||||
score: number
|
||||
status: number
|
||||
}
|
||||
}
|
||||
}
|
||||
avatar: string
|
||||
blog: null
|
||||
mood: string
|
||||
github: string
|
||||
school: string
|
||||
major: string
|
||||
language: string
|
||||
accepted_number: number
|
||||
total_score: number
|
||||
submission_number: number
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
username: string
|
||||
email: string
|
||||
admin_type: string
|
||||
problem_permission: string
|
||||
create_time: Date
|
||||
last_login: Date
|
||||
two_factor_auth: boolean
|
||||
open_api: boolean
|
||||
is_disabled: boolean
|
||||
}
|
||||
|
||||
export type LANGUAGE =
|
||||
| "C"
|
||||
| "C++"
|
||||
|
||||
Reference in New Issue
Block a user