add website config.
This commit is contained in:
5
src/components.d.ts
vendored
5
src/components.d.ts
vendored
@@ -23,10 +23,10 @@ declare module '@vue/runtime-core' {
|
|||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
|
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
|
||||||
NCode: typeof import('naive-ui')['NCode']
|
NCode: typeof import("naive-ui")["NCode"]
|
||||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
NDataTable: typeof import('naive-ui')['NDataTable']
|
NDataTable: typeof import('naive-ui')['NDataTable']
|
||||||
NDatePicker: typeof import('naive-ui')['NDatePicker']
|
NDatePicker: typeof import("naive-ui")["NDatePicker"]
|
||||||
NDescriptions: typeof import('naive-ui')['NDescriptions']
|
NDescriptions: typeof import('naive-ui')['NDescriptions']
|
||||||
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
|
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
|
||||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||||
@@ -42,6 +42,7 @@ declare module '@vue/runtime-core' {
|
|||||||
NInput: typeof import('naive-ui')['NInput']
|
NInput: typeof import('naive-ui')['NInput']
|
||||||
NLayout: typeof import('naive-ui')['NLayout']
|
NLayout: typeof import('naive-ui')['NLayout']
|
||||||
NLayoutContent: typeof import('naive-ui')['NLayoutContent']
|
NLayoutContent: typeof import('naive-ui')['NLayoutContent']
|
||||||
|
NLayoutFooter: typeof import('naive-ui')['NLayoutFooter']
|
||||||
NLayoutHeader: typeof import('naive-ui')['NLayoutHeader']
|
NLayoutHeader: typeof import('naive-ui')['NLayoutHeader']
|
||||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ function filterResult(result: Problem) {
|
|||||||
return newResult
|
return newResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getWebsiteConfig() {
|
||||||
|
return http.get("website")
|
||||||
|
}
|
||||||
|
|
||||||
export async function getProblemList(
|
export async function getProblemList(
|
||||||
offset = 0,
|
offset = 0,
|
||||||
limit = 10,
|
limit = 10,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const options = {
|
|||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.chart {
|
.chart {
|
||||||
height: 400px;
|
height: 500px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { Submission } from "utils/types"
|
|||||||
import { adminRejudge, getSubmissions } from "oj/api"
|
import { adminRejudge, getSubmissions } from "oj/api"
|
||||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||||
import { useUserStore } from "~/shared/store/user"
|
import { useUserStore } from "~/shared/store/user"
|
||||||
|
import { useConfigStore } from "~/shared/store/config"
|
||||||
|
|
||||||
interface Query {
|
interface Query {
|
||||||
username: string
|
username: string
|
||||||
@@ -25,6 +26,7 @@ interface Query {
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
const configStore = useConfigStore()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const submissions = ref([])
|
const submissions = ref([])
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { logout } from "./api"
|
import { logout } from "./api"
|
||||||
import { useUserStore } from "./store/user"
|
import { useUserStore } from "./store/user"
|
||||||
|
import { useConfigStore } from "./store/config"
|
||||||
import { isDark, toggleDark } from "~/shared/composables/dark"
|
import { isDark, toggleDark } from "~/shared/composables/dark"
|
||||||
import { toggleLogin, toggleSignup } from "~/shared/composables/modal"
|
import { toggleLogin, toggleSignup } from "~/shared/composables/modal"
|
||||||
import type {
|
import type {
|
||||||
@@ -9,10 +10,11 @@ import type {
|
|||||||
DropdownDividerOption,
|
DropdownDividerOption,
|
||||||
} from "naive-ui"
|
} from "naive-ui"
|
||||||
import { RouterLink } from "vue-router"
|
import { RouterLink } from "vue-router"
|
||||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
||||||
import { code } from "~/shared/composables/learn"
|
import { code } from "~/shared/composables/learn"
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
const configStore = useConfigStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const active = computed(() => {
|
const active = computed(() => {
|
||||||
@@ -26,10 +28,14 @@ async function handleLogout() {
|
|||||||
router.replace("/")
|
router.replace("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(userStore.getMyProfile)
|
onMounted(() => {
|
||||||
|
userStore.getMyProfile()
|
||||||
|
configStore.getConfig()
|
||||||
|
})
|
||||||
|
|
||||||
const menus = computed<MenuOption[]>(() => [
|
const menus = computed<MenuOption[]>(() => [
|
||||||
{
|
{
|
||||||
|
show: false,
|
||||||
label: () =>
|
label: () =>
|
||||||
h(RouterLink, { to: "/learn/step-1" }, { default: () => "自学" }),
|
h(RouterLink, { to: "/learn/step-1" }, { default: () => "自学" }),
|
||||||
key: "learn",
|
key: "learn",
|
||||||
@@ -90,12 +96,23 @@ function run() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-space v-if="isDesktop" justify="space-between" align="center">
|
<n-space justify="space-between" align="center">
|
||||||
<n-menu mode="horizontal" :options="menus" :value="active" />
|
<n-space align="center">
|
||||||
<n-space>
|
<div class="websiteTitle">{{ configStore.config?.website_name }}</div>
|
||||||
|
<n-menu
|
||||||
|
v-if="isDesktop"
|
||||||
|
mode="horizontal"
|
||||||
|
:options="menus"
|
||||||
|
:value="active"
|
||||||
|
/>
|
||||||
|
</n-space>
|
||||||
|
<n-space align="center">
|
||||||
<n-button v-if="$route.name === 'learn'" type="primary" @click="run">
|
<n-button v-if="$route.name === 'learn'" type="primary" @click="run">
|
||||||
运行
|
运行
|
||||||
</n-button>
|
</n-button>
|
||||||
|
<n-dropdown v-if="isMobile" :options="menus" trigger="click">
|
||||||
|
<n-button>菜单</n-button>
|
||||||
|
</n-dropdown>
|
||||||
<div v-if="userStore.isFinished">
|
<div v-if="userStore.isFinished">
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
v-if="userStore.isAuthed"
|
v-if="userStore.isAuthed"
|
||||||
@@ -104,9 +121,14 @@ function run() {
|
|||||||
>
|
>
|
||||||
<n-button>{{ userStore.user!.username }}</n-button>
|
<n-button>{{ userStore.user!.username }}</n-button>
|
||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
<n-space v-else>
|
<n-space align="center" v-else>
|
||||||
<n-button @click="toggleLogin(true)">登录</n-button>
|
<n-button @click="toggleLogin(true)">登录</n-button>
|
||||||
<n-button @click="toggleSignup(true)">注册</n-button>
|
<n-button
|
||||||
|
v-if="configStore.config?.allow_register"
|
||||||
|
@click="toggleSignup(true)"
|
||||||
|
>
|
||||||
|
注册
|
||||||
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</div>
|
</div>
|
||||||
<n-button circle @click="toggleDark()">
|
<n-button circle @click="toggleDark()">
|
||||||
@@ -117,33 +139,11 @@ function run() {
|
|||||||
</n-button>
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-space>
|
</n-space>
|
||||||
<n-space v-else justify="end">
|
|
||||||
<n-button v-if="$route.name === 'learn'" type="primary" @click="run">
|
|
||||||
运行
|
|
||||||
</n-button>
|
|
||||||
<n-dropdown v-if="userStore.isAuthed" :options="options" trigger="click">
|
|
||||||
<n-button>{{ userStore.user!.username }}</n-button>
|
|
||||||
</n-dropdown>
|
|
||||||
<n-space v-else>
|
|
||||||
<n-button @click="toggleLogin(true)">登录</n-button>
|
|
||||||
<n-button @click="toggleSignup(true)">注册</n-button>
|
|
||||||
</n-space>
|
|
||||||
<n-dropdown :options="menus" trigger="click">
|
|
||||||
<n-button>
|
|
||||||
<template #icon>
|
|
||||||
<n-icon>
|
|
||||||
<i-ep-menu />
|
|
||||||
</n-icon>
|
|
||||||
</template>
|
|
||||||
</n-button>
|
|
||||||
</n-dropdown>
|
|
||||||
<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>
|
|
||||||
</template>
|
|
||||||
</n-button>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.websiteTitle {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
import Login from "../Login.vue"
|
import Login from "../Login.vue"
|
||||||
import Signup from "../Signup.vue"
|
import Signup from "../Signup.vue"
|
||||||
import Header from "../Header.vue"
|
import Header from "../Header.vue"
|
||||||
|
import { useConfigStore } from "../store/config"
|
||||||
|
|
||||||
|
const configStore = useConfigStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -12,6 +15,7 @@ import Header from "../Header.vue"
|
|||||||
<n-layout-content content-style="padding: 16px; overflow-x: initial">
|
<n-layout-content content-style="padding: 16px; overflow-x: initial">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</n-layout-content>
|
</n-layout-content>
|
||||||
|
<p class="footer">{{ configStore.config?.website_footer }}</p>
|
||||||
<Login />
|
<Login />
|
||||||
<Signup />
|
<Signup />
|
||||||
</n-layout>
|
</n-layout>
|
||||||
@@ -21,4 +25,8 @@ import Header from "../Header.vue"
|
|||||||
.header {
|
.header {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
14
src/shared/store/config.ts
Normal file
14
src/shared/store/config.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { getWebsiteConfig } from "~/oj/api"
|
||||||
|
import { WebsiteConfig } from "~/utils/types"
|
||||||
|
|
||||||
|
export const useConfigStore = defineStore("config", () => {
|
||||||
|
const config = ref<WebsiteConfig>()
|
||||||
|
async function getConfig() {
|
||||||
|
const res = await getWebsiteConfig()
|
||||||
|
config.value = res.data
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
config,
|
||||||
|
getConfig,
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user