From 790384fb8e0e1541181f5cdfb51133b3778df197 Mon Sep 17 00:00:00 2001 From: Litrix Date: Tue, 24 Dec 2024 20:42:51 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20fix:=20=E4=B8=8E=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E6=8E=A5=E5=8F=A3=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 +- index.html | 2 +- public/favicon.ico | Bin 4286 -> 0 bytes public/favicon.svg | 27 +++++ public/gobang.svg | 33 +++++- src/App.vue | 11 +- src/api/index.ts | 27 ++--- src/components/app/LoginRegisterDialog.vue | 2 +- src/components/user/UserMenu.vue | 38 +++++++ src/env.ts | 6 +- src/schemas/response.ts | 20 ++-- src/stores/user.ts | 2 + src/utils/game-socket.ts | 2 +- src/views/GobangPlayPage.vue | 45 +++----- src/views/MainPage.vue | 21 ++-- src/views/user/UserEditPage.vue | 64 ++++++----- src/views/user/UserPage.vue | 124 ++++++++++----------- 17 files changed, 261 insertions(+), 166 deletions(-) delete mode 100644 public/favicon.ico create mode 100644 public/favicon.svg create mode 100644 src/components/user/UserMenu.vue diff --git a/.env b/.env index 95cc584..f1d830a 100644 --- a/.env +++ b/.env @@ -1,3 +1,4 @@ VITE_REQUEST_BASE_URL=https://wzpmc.cn:18080 -# VITE_WEBSOCKET_BASE_URL=ws://172.16.114.84:58080 +# VITE_REQUEST_BASE_URL=http://172.16.114.84:58082 VITE_WEBSOCKET_BASE_URL=wss://wzpmc.cn:18080 +# VITE_WEBSOCKET_BASE_URL=ws://172.16.114.84:58082 diff --git a/index.html b/index.html index 571618d..c56af0e 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + 社团展示系统 diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index df36fcfb72584e00488330b560ebcf34a41c64c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kevtV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{TKxD#iCLfl2vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..48f3876 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/public/gobang.svg b/public/gobang.svg index 83bb4ad..22b1e94 100644 --- a/public/gobang.svg +++ b/public/gobang.svg @@ -1 +1,32 @@ - \ No newline at end of file + + + + + + + + + + + + + + diff --git a/src/App.vue b/src/App.vue index 2a0138f..0f17399 100644 --- a/src/App.vue +++ b/src/App.vue @@ -100,7 +100,9 @@ display: flex; } .app-router-component { - --el-main-padding: 0; + &:not(.keep-padding) { + --el-main-padding: 0; + } } .app-router-view-enter-active, .app-router-view-leave-active { @@ -113,7 +115,7 @@ } diff --git a/src/api/index.ts b/src/api/index.ts index ab52281..0552134 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,18 +1,10 @@ import { REQUEST_BASE_URL } from '@/env'; -import { - userInfoRespSchema, - userInfoRespSchemaNullable, - type AnyRespSchema, - type SucceedRespOf, - type SucceedUserInfoResp, - type SucceedUserInfoRespNullable, -} from '@/schemas/response'; +import { userInfoRespSchema, type AnyRespSchema, type SucceedRespOf } from '@/schemas/response'; import { useUserStore } from '@/stores/user'; -import type { Nullable, Override } from '@/utils/types'; +import type { Override } from '@/utils/types'; import axios, { type AxiosError, type AxiosRequestConfig, type Method } from 'axios'; import { ElMessage } from 'element-plus'; import type { z } from 'zod'; - export const axiosInstance = axios.create({ baseURL: REQUEST_BASE_URL, }); @@ -25,7 +17,7 @@ axiosInstance.interceptors.request.use((config) => { // 自动获取响应中的token. axiosInstance.interceptors.response.use((response) => { const userStore = useUserStore(); - const authorization = response.headers['set-authorization'] as string | undefined; + const authorization = response.headers['add-authorization'] as string | undefined; if (authorization) { console.log(123); userStore.token = authorization; @@ -47,7 +39,7 @@ export function parseRawResp( if (!raw) return; const resp = schema.parse(raw); if (resp.type === 'error') { - ElMessage.error(errorMessage(errorDescription, resp.code, resp.msg)); + ElMessage.error(errorMessage(errorDescription, resp.status, resp.msg)); return; } return resp as any; @@ -69,18 +61,13 @@ export async function request( errorDescription, ); } -export async function getUserInfo(): Promise; -export async function getUserInfo(userID: number): Promise; export async function getUserInfo(userID?: number) { let url = '/api/user/info'; if (userID !== undefined) { url += `/${userID}`; } - const resp = await request( - url, - userID !== undefined ? userInfoRespSchemaNullable : userInfoRespSchema, - ); + const resp = await request(url, userInfoRespSchema, { errorDescription: '获取用户信息失败' }); return resp; } -export const getAvatarURL = (avatar: Nullable) => - (avatar && `${import.meta.env.VITE_REQUEST_BASE_URL}/api/user/avatar/${avatar}`) ?? undefined; +export const getAvatarURL = (avatar: string | undefined) => + avatar && `${REQUEST_BASE_URL}/api/user/avatar/${avatar}`; diff --git a/src/components/app/LoginRegisterDialog.vue b/src/components/app/LoginRegisterDialog.vue index ac20220..b3a7813 100644 --- a/src/components/app/LoginRegisterDialog.vue +++ b/src/components/app/LoginRegisterDialog.vue @@ -167,7 +167,7 @@ const show = defineModel({ default: false }); const loginRegisterDialogActiveName = ref('login'); const loginFormRef = ref(); const loginFormData = reactive({ - username: 'wubaopu2', + username: 'wubaopu1', password: '123456', verifyImage: 'none' as VerifyImagePath, verifyCode: '', diff --git a/src/components/user/UserMenu.vue b/src/components/user/UserMenu.vue new file mode 100644 index 0000000..9ec816f --- /dev/null +++ b/src/components/user/UserMenu.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/env.ts b/src/env.ts index 4402e17..0835bd7 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,4 +1,6 @@ -// export const DEV = import.meta.env.DEV; -export const DEV = false; +export const DEV = import.meta.env.DEV; export const REQUEST_BASE_URL = import.meta.env.VITE_REQUEST_BASE_URL; export const WEBSOCKET_BASE_URL = import.meta.env.VITE_WEBSOCKET_BASE_URL; +interface A { + a(this: HTMLElement & A): this; +} diff --git a/src/schemas/response.ts b/src/schemas/response.ts index 9b3e88f..db11d4c 100644 --- a/src/schemas/response.ts +++ b/src/schemas/response.ts @@ -4,9 +4,9 @@ function createRespSchema(data: T) { return z.union([ z .object({ - code: z.number().min(200).max(299), + status: z.number().min(200).max(299), msg: z.string(), - time: z.coerce.date(), + timestamp: z.coerce.date(), }) .extend({ data: data }) .transform((raw) => @@ -16,9 +16,9 @@ function createRespSchema(data: T) { ), z .object({ - code: z.number(), + status: z.number(), msg: z.string(), - time: z.coerce.date(), + timestamp: z.coerce.date(), }) .transform((raw) => Object.assign(raw, { @@ -32,8 +32,6 @@ export type SucceedRespOf = Extract; export type ErrorRespOf = Exclude, T>; export type AnyRespSchema = ReturnType; export const ordinarySchema = createRespSchema(z.literal(true)); -export const loginRespSchema = ordinarySchema; -export const registerRespSchema = ordinarySchema; export const idAndNameSchema = z.object({ id: z.number(), name: z.string(), @@ -43,20 +41,20 @@ const authSchema = idAndNameSchema.extend({ permissions: idAndNameSchema.array(), }); const userInfoDataSchema = idAndNameSchema.extend({ - avatar: z.nullable(z.string()), + avatar: z.optional(z.string()), auth: authSchema, - club: z.nullable( + club: z.optional( idAndNameSchema.extend({ commit: z.string(), - auth: authSchema, }), ), + chubAuth: z.optional(authSchema), }); export const userInfoRespSchema = createRespSchema(userInfoDataSchema); -export const userInfoRespSchemaNullable = createRespSchema(userInfoDataSchema.nullable()); export type SucceedUserInfoResp = SucceedRespOf>; -export type SucceedUserInfoRespNullable = SucceedRespOf>; export type UserInfo = SucceedUserInfoResp['data']; +export const loginRespSchema = userInfoRespSchema; +export const registerRespSchema = userInfoRespSchema; export const verifyRespSchema = createRespSchema( z .object({ diff --git a/src/stores/user.ts b/src/stores/user.ts index 3f7f191..c0d1d88 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -4,6 +4,7 @@ import type { UserInfo } from '@/schemas/response'; import { type idAndNameSchema } from '@/schemas/response'; import type { MaybePromise } from '@/utils/types'; import { StorageSerializers, useLocalStorage } from '@vueuse/core'; +import { ElMessage } from 'element-plus'; import { defineStore } from 'pinia'; import { computed, ref, watch } from 'vue'; import { z } from 'zod'; @@ -59,6 +60,7 @@ export const useUserStore = defineStore('user', () => { if (!res.every((r) => r === undefined || r)) return false; token.value = null; await updateSelfUserInfo(); + ElMessage.info('退出成功'); return true; } return { diff --git a/src/utils/game-socket.ts b/src/utils/game-socket.ts index 9c70de5..8f42364 100644 --- a/src/utils/game-socket.ts +++ b/src/utils/game-socket.ts @@ -37,6 +37,7 @@ export interface UseGameSocketOptions< // 只有拥有依赖关系的请求才可以有finally [P in keyof TRelations]?: (error: boolean) => void; }; + disconnected?(): void; } export function useGameSocket, TResp extends BaseResp>() { return >( @@ -102,7 +103,6 @@ export function useGameSocket, TResp extends } }, onDisconnected(_, ev) { - console.log('disconnected'); // 正常断开 if (ev.code === 1000) return; ElMessage.error(`连接已断开:${ev.reason}`); diff --git a/src/views/GobangPlayPage.vue b/src/views/GobangPlayPage.vue index cca66c5..90ca526 100644 --- a/src/views/GobangPlayPage.vue +++ b/src/views/GobangPlayPage.vue @@ -247,13 +247,9 @@ const userStore = useUserStore(); const { smLess, mdLess } = storeToRefs(useMediaStore()); let canExit = false; let confirming = false; -useLogoutInterceptor(() => { - if (confirming) { - return; - } - if (canExit || matchState.value !== MatchState.GAMING) return true; +function confirm(description: string) { confirming = true; - ElMessageBox.confirm('你正在游戏中, 是否退出登录?', '警告', { + return ElMessageBox.confirm(description, '警告', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', @@ -261,15 +257,21 @@ useLogoutInterceptor(() => { .then((action: Action) => { if (action !== 'confirm') return; canExit = true; - confirming = false; - return userStore.logout(); }) - .catch(() => { + .catch(() => {}) + .finally(() => { confirming = false; }); - return false; +} +useLogoutInterceptor(async () => { + if (confirming) { + return; + } + if (canExit || matchState.value !== MatchState.GAMING) return true; + await confirm('你正在游戏中, 是否退出登录?'); + return canExit; }); -onBeforeRouteLeave((to, _, next) => { +onBeforeRouteLeave(async (_, __, next) => { if (confirming) { next(false); return; @@ -279,21 +281,8 @@ onBeforeRouteLeave((to, _, next) => { return; } confirming = true; - ElMessageBox.confirm('你正在游戏中, 是否退出房间?', '警告', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning', - }) - .then((action: Action) => { - if (action !== 'confirm') return; - canExit = true; - confirming = false; - router.push(to); - }) - .catch(() => { - confirming = false; - }); - next(false); + await confirm('你正在游戏中, 是否退出房间?'); + next(canExit); }); const roomId = useRoute().params.id as RoomId | undefined; const canvas = ref(); @@ -421,9 +410,7 @@ const otherUser = computed(() => { }); watch( () => otherUser.value?.id, - () => { - updateMatchState(); - }, + () => updateMatchState(), ); const white = ref(false); const grid = computed(() => diff --git a/src/views/MainPage.vue b/src/views/MainPage.vue index 5f618ce..a10698c 100644 --- a/src/views/MainPage.vue +++ b/src/views/MainPage.vue @@ -1,12 +1,19 @@ - +