✨ feat: 添加五子棋主页
This commit is contained in:
parent
008290e3fd
commit
9ede5bdef9
35
src/App.vue
35
src/App.vue
@ -12,21 +12,24 @@
|
||||
:router="true"
|
||||
>
|
||||
<el-menu-item index="/">首页</el-menu-item>
|
||||
<el-sub-menu v-if="userStore.logined" class="festival-menu" index="festival">
|
||||
<el-sub-menu class="festival-menu" index="festival">
|
||||
<template #title>社团文化节</template>
|
||||
<festival-menu-item src="/2048.png" title="2048" to="/2048" />
|
||||
<festival-menu-item src="/gobang.svg" title="五子棋" to="/gobang" />
|
||||
<festival-menu-item
|
||||
v-if="userStore.logined"
|
||||
src="/gobang.svg"
|
||||
title="五子棋"
|
||||
to="/gobang"
|
||||
/>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
<div class="app-header-user flex center" v-loading="userStore.initializing">
|
||||
<template v-if="!userStore.initializing">
|
||||
<template v-if="userInfo && userInfo.id !== -1">
|
||||
<!-- 仅收紧类型 -->
|
||||
<template v-if="userInfo && userStore.logined">
|
||||
<el-dropdown>
|
||||
<div class="app-header-user__inner flex align-center">
|
||||
<el-avatar :icon="userInfo.avatar ?? undefined"></el-avatar>
|
||||
<div class="app-header-user__username">
|
||||
{{ userInfo.name }}
|
||||
</div>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
@ -34,6 +37,9 @@
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="app-header-user__username">
|
||||
{{ userInfo.name }}
|
||||
</div>
|
||||
</template>
|
||||
<el-button type="primary" v-else @click="showLoginRegisterDialog = true">登录</el-button>
|
||||
</template>
|
||||
@ -56,7 +62,6 @@
|
||||
min-height: 100vh;
|
||||
}
|
||||
.app-header {
|
||||
--header-height: 50px;
|
||||
--el-header-height: var(--header-height);
|
||||
--el-loading-spinner-size: 30px;
|
||||
background-color: white;
|
||||
@ -75,7 +80,6 @@
|
||||
}
|
||||
.app-main {
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
}
|
||||
.app-header-user {
|
||||
@ -94,15 +98,13 @@
|
||||
.app-router-view-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
.app-router-component__wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
import { CloseBold } from '@element-plus/icons-vue';
|
||||
import type { AxiosError } from 'axios';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { onMounted, provide, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { provide, ref } from 'vue';
|
||||
import axiosInstance, { type RawResp } from './api/index';
|
||||
import FestivalMenuItem from './components/FestivalMenuItem.vue';
|
||||
import LoginRegisterDialog, {
|
||||
@ -112,7 +114,6 @@ import LoginRegisterDialog, {
|
||||
import { loginResponseSchema, registerResponseSchema } from './schemas/response';
|
||||
import { usePageStore } from './stores/page.js';
|
||||
import { useUserStore } from './stores/user';
|
||||
import { storeToRefs } from 'pinia';
|
||||
const userStore = useUserStore();
|
||||
const { userInfo } = storeToRefs(userStore);
|
||||
const pageStore = usePageStore();
|
||||
@ -151,8 +152,8 @@ async function logout() {
|
||||
userStore.token = null;
|
||||
await userStore.updateSelfUserInfo(true);
|
||||
}
|
||||
onMounted(() => {
|
||||
userStore.token = null;
|
||||
userStore.updateSelfUserInfo(true);
|
||||
});
|
||||
// onMounted(() => {
|
||||
// userStore.token = null;
|
||||
// userStore.updateSelfUserInfo(true);
|
||||
// });
|
||||
</script>
|
||||
|
@ -3,14 +3,16 @@
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--header-height: 50px;
|
||||
}
|
||||
body {
|
||||
background-color: rgb(244, 246, 249);
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
min-width: 100vw;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.flex {
|
||||
display: flex !important;
|
||||
@ -31,3 +33,7 @@ body {
|
||||
@extend .justify-center;
|
||||
@extend .align-center;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
permissionId?: RoutePermissionId;
|
||||
shouldLogin?: boolean;
|
||||
routeId?: number;
|
||||
}
|
||||
}
|
||||
const routes: RouteRecordRaw[] = [
|
||||
@ -31,13 +32,10 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/2048',
|
||||
component: () => import('@/views/Game2048Page.vue'),
|
||||
meta: {
|
||||
shouldLogin: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/gobang',
|
||||
component: () => import('@/views/Game2048Page.vue'),
|
||||
component: () => import('@/views/GobangPage.vue'),
|
||||
meta: {
|
||||
shouldLogin: true,
|
||||
},
|
||||
@ -66,7 +64,7 @@ router.beforeEach(async (to) => {
|
||||
const succeed = await userStore.updateSelfUserInfo(true);
|
||||
if (!succeed) {
|
||||
if (permissionId === undefined) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
return pageStore.createTempErrorRoute(
|
||||
{
|
||||
@ -89,6 +87,7 @@ router.beforeEach(async (to) => {
|
||||
} finally {
|
||||
pageStore.removeRouteId(to);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
router.afterEach((to) => {
|
||||
const pageStore = usePageStore();
|
||||
|
@ -23,14 +23,15 @@ export const useUserStore = defineStore('user', () => {
|
||||
const logined = computed(() => userInfo.value && userInfo.value.id !== -1);
|
||||
watch(
|
||||
userInfo,
|
||||
(info) => {
|
||||
initializing.value = !!info;
|
||||
() => {
|
||||
router.push({ path: router.currentRoute.value.fullPath, force: true });
|
||||
},
|
||||
{ flush: 'sync' },
|
||||
);
|
||||
async function updateSelfUserInfo(showErrorMessage: boolean): Promise<boolean> {
|
||||
initializing.value = true;
|
||||
console.log('called');
|
||||
|
||||
try {
|
||||
const raw = await axiosInstance
|
||||
.get<RawResp>('/api/user/info')
|
||||
|
39
src/views/GobangPage.vue
Normal file
39
src/views/GobangPage.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<el-main class="gobang-page__wrapper">
|
||||
<el-container>
|
||||
<el-header class="gobang-page-header flex align-center">
|
||||
<div class="gobang-page-header__title">五子棋</div>
|
||||
<el-button type="primary">单人游戏</el-button>
|
||||
</el-header>
|
||||
<el-main class="gobang-page-main"></el-main>
|
||||
</el-container>
|
||||
</el-main>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.gobang-page__wrapper {
|
||||
background-color: white;
|
||||
}
|
||||
.gobang-page-header__title {
|
||||
font-size: 25px;
|
||||
font-weight: bold;
|
||||
margin-right: auto;
|
||||
}
|
||||
.gobang-page-header {
|
||||
--el-header-height: var(--header-height);
|
||||
background-color: white;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
</style>
|
||||
<script lang="ts" setup>
|
||||
import { useWebSocket } from '@vueuse/core';
|
||||
import { ref } from 'vue';
|
||||
interface Room {}
|
||||
interface GobangRespPart<N extends string, P extends object> {
|
||||
name: N;
|
||||
payload: P;
|
||||
}
|
||||
type GobangResp = GobangRespPart<'RoomInfo', { roomId: string; rooms: Room[] }>;
|
||||
const rooms = ref<Room[]>();
|
||||
// const { data } = useWebSocket<GobangResp>(`ws://127.0.0.1:58080/chess/${token}`);
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user