admin pages and menu.
This commit is contained in:
463
package-lock.json
generated
463
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -10,34 +10,34 @@
|
||||
"fmt": "prettier --write src *.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.0.10",
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@monaco-editor/loader": "^1.3.2",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"axios": "1.3.3",
|
||||
"axios": "1.3.4",
|
||||
"chart.js": "^4.2.1",
|
||||
"copy-text-to-clipboard": "^3.0.1",
|
||||
"date-fns": "^2.29.3",
|
||||
"highlight.js": "^11.7.0",
|
||||
"naive-ui": "^2.34.3",
|
||||
"party-js": "^2.2.0",
|
||||
"pinia": "^2.0.32",
|
||||
"pinia": "^2.0.33",
|
||||
"vue": "^3.2.47",
|
||||
"vue-chartjs": "^5.2.0",
|
||||
"vue-router": "^4.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/ep": "^1.1.9",
|
||||
"@types/node": "^18.14.0",
|
||||
"@iconify-json/ep": "^1.1.10",
|
||||
"@types/node": "^18.14.6",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"markdown-it-shiki": "^0.8.0",
|
||||
"monaco-editor": "^0.35.0",
|
||||
"monaco-editor": "^0.36.1",
|
||||
"prettier": "^2.8.4",
|
||||
"typescript": "^4.9.5",
|
||||
"unplugin-auto-import": "^0.14.4",
|
||||
"unplugin-auto-import": "^0.15.1",
|
||||
"unplugin-icons": "^0.15.3",
|
||||
"unplugin-vue-components": "^0.24.0",
|
||||
"unplugin-vue-components": "^0.24.1",
|
||||
"vite": "^4.1.4",
|
||||
"vite-plugin-vue-markdown": "^0.22.4",
|
||||
"vue-tsc": "^1.1.7"
|
||||
"vue-tsc": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
0
src/admin/contest/detail.vue
Normal file
0
src/admin/contest/detail.vue
Normal file
0
src/admin/contest/list.vue
Normal file
0
src/admin/contest/list.vue
Normal file
0
src/admin/contest/problems.vue
Normal file
0
src/admin/contest/problems.vue
Normal file
@@ -1,7 +1,11 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
<div class="container">1213</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.container {
|
||||
height: 200vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
0
src/admin/problem/detail.vue
Normal file
0
src/admin/problem/detail.vue
Normal file
0
src/admin/problem/list.vue
Normal file
0
src/admin/problem/list.vue
Normal file
0
src/admin/setting/conf.vue
Normal file
0
src/admin/setting/conf.vue
Normal file
0
src/admin/setting/user.vue
Normal file
0
src/admin/setting/user.vue
Normal file
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 496 B |
2
src/auto-imports.d.ts
vendored
2
src/auto-imports.d.ts
vendored
@@ -289,5 +289,5 @@ declare global {
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component,ComponentPublicInstance,ComputedRef,InjectionKey,PropType,Ref,VNode } from 'vue'
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
|
||||
}
|
||||
|
||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@@ -37,6 +37,7 @@ declare module '@vue/runtime-core' {
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutContent: typeof import('naive-ui')['NLayoutContent']
|
||||
NLayoutHeader: typeof import('naive-ui')['NLayoutHeader']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
||||
NModal: typeof import('naive-ui')['NModal']
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Problem } from "utils/types"
|
||||
import { code } from "oj/composables/code"
|
||||
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
||||
import Submit from "./Submit.vue"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
|
||||
interface Props {
|
||||
problem: Problem
|
||||
@@ -13,6 +14,7 @@ interface Props {
|
||||
const props = defineProps<Props>()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
|
||||
watch(() => code.language, reset)
|
||||
|
||||
@@ -25,6 +27,10 @@ function goSubmissions() {
|
||||
router.push({ name, query: { problem: props.problem._id } })
|
||||
}
|
||||
|
||||
function edit() {
|
||||
router.push("/admin/problem/edit/" + props.problem.id)
|
||||
}
|
||||
|
||||
const menu: DropdownOption[] = [
|
||||
{ label: "重置", key: "reset" },
|
||||
{ label: "提交信息", key: "submissions" },
|
||||
@@ -88,6 +94,7 @@ function select(key: string) {
|
||||
<n-space>
|
||||
<n-button @click="reset">重置</n-button>
|
||||
<n-button @click="goSubmissions">提交信息</n-button>
|
||||
<n-button v-if="userStore.isSuperAdmin" @click="edit">编辑</n-button>
|
||||
</n-space>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
|
||||
@@ -215,7 +215,7 @@ const columns = computed(() => {
|
||||
h(
|
||||
NButton,
|
||||
{ size: "small", onClick: () => rejudge(row.id) },
|
||||
() => "重新评分"
|
||||
() => "重新判题"
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -95,6 +95,45 @@ export const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/admin",
|
||||
component: () => import("~/shared/layout/admin.vue"),
|
||||
children: [{ path: "", component: () => import("admin/index.vue") }],
|
||||
children: [
|
||||
{ path: "", component: () => import("admin/index.vue") },
|
||||
{ path: "user", component: () => import("admin/setting/user.vue") },
|
||||
{ path: "conf", component: () => import("admin/setting/conf.vue") },
|
||||
{ path: "problems", component: () => import("admin/problem/list.vue") },
|
||||
{
|
||||
path: "problem/create",
|
||||
component: () => import("admin/problem/detail.vue"),
|
||||
},
|
||||
{
|
||||
path: "problem/:problemID/edit",
|
||||
component: () => import("admin/problem/detail.vue"),
|
||||
props: true,
|
||||
},
|
||||
{ path: "contests", component: () => import("admin/contest/list.vue") },
|
||||
{
|
||||
path: "contest/create",
|
||||
component: () => import("admin/contest/detail.vue"),
|
||||
},
|
||||
{
|
||||
path: "contest/:contestID/edit",
|
||||
component: () => import("admin/contest/detail.vue"),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "contest/:contestID/problems",
|
||||
component: () => import("admin/contest/detail.vue"),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "contest/:contestID/problem/create",
|
||||
component: () => import("admin/problem/detail.vue"),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "contest/:contestID/problem/:problemID/edit",
|
||||
component: () => import("admin/problem/detail.vue"),
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -75,7 +75,14 @@ const options = computed<Array<DropdownOption | DropdownDividerOption>>(() => [
|
||||
onClick: () => router.push("/setting"),
|
||||
},
|
||||
},
|
||||
{ label: "后台管理", key: "admin", show: userStore.isAdminRole },
|
||||
{
|
||||
label: "后台管理",
|
||||
key: "admin",
|
||||
show: userStore.isAdminRole,
|
||||
props: {
|
||||
onClick: () => router.push("/admin"),
|
||||
},
|
||||
},
|
||||
{ type: "divider" },
|
||||
{ label: "退出", key: "logout", props: { onClick: handleLogout } },
|
||||
])
|
||||
@@ -136,7 +143,7 @@ function run() {
|
||||
<n-button circle @click="toggleDark()">
|
||||
<template #icon>
|
||||
<n-icon v-if="isDark"><i-ep-sunny /></n-icon>
|
||||
<n-icon v-else> <i-ep-moon /></n-icon>
|
||||
<n-icon v-else><i-ep-moon /></n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</n-space>
|
||||
|
||||
@@ -4,7 +4,7 @@ export const monaco = ref<Monaco>()
|
||||
|
||||
export async function init() {
|
||||
loader.config({
|
||||
paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.34.1/min/vs" },
|
||||
paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.36.1/min/vs" },
|
||||
"vs/nls": { availableLanguages: { "*": "zh-cn" } },
|
||||
})
|
||||
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { MenuOption } from "naive-ui"
|
||||
import Login from "../Login.vue"
|
||||
import Signup from "../Signup.vue"
|
||||
|
||||
const options: MenuOption[] = [
|
||||
{ label: "题目", key: "problem", disabled: true },
|
||||
{ label: "题目列表", key: "problem list" },
|
||||
{ label: "创建题目", key: "create problem" },
|
||||
{ label: "用户", key: "user", disabled: true },
|
||||
{ label: "用户列表", key: "user list" },
|
||||
{ label: "导入用户", key: "user import" },
|
||||
{ label: "比赛", key: "contest", disabled: true },
|
||||
{ label: "比赛列表", key: "contest list" },
|
||||
{ label: "创建比赛", key: "create contest" },
|
||||
{ label: "其他", key: "other", disabled: true },
|
||||
{ label: "系统配置", key: "config" },
|
||||
{ label: "公告配置", key: "announcement" },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-layout>
|
||||
<n-layout-content bordered>
|
||||
<n-layout has-sider position="absolute">
|
||||
<n-layout-sider bordered :native-scrollbar="false">
|
||||
<n-menu :options="options" />
|
||||
</n-layout-sider>
|
||||
<n-layout-content :native-scrollbar="false">
|
||||
<router-view></router-view>
|
||||
</n-layout-content>
|
||||
<Login />
|
||||
<Signup />
|
||||
</n-layout>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.content {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user