diff --git a/components.d.ts b/components.d.ts index e9e012a..dcb45b9 100644 --- a/components.d.ts +++ b/components.d.ts @@ -19,14 +19,19 @@ declare module 'vue' { ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] + ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] + ElPopover: typeof import('element-plus/es')['ElPopover'] ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] Game2048: typeof import('./src/components/Game2048.vue')['default'] IconCsLock: typeof import('~icons/cs/lock')['default'] + IconCsValidate: typeof import('~icons/cs/validate')['default'] IconEpLoading: typeof import('~icons/ep/loading')['default'] IconEpUserFilled: typeof import('~icons/ep/user-filled')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + VerifyInput: typeof import('./src/components/VerifyInput.vue')['default'] + VerifyInputImage: typeof import('./src/components/VerifyInputImage.vue')['default'] } } diff --git a/src/App.vue b/src/App.vue index 314a4ad..f979ce3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -60,16 +60,7 @@ - - - 登录 - - + @@ -136,6 +127,7 @@ display: flex; align-items: center; } + .title-container { font-size: 1.2em; } @@ -145,15 +137,22 @@ diff --git a/src/api/index.ts b/src/api/index.ts index 0045460..632ba5d 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import { useUserStore } from '@/stores'; const axiosInstance = axios.create({ - baseURL: 'http://wzpmc.cn:18080/' + baseURL: 'http://pc.wzpmc.cn:18080/' }); // 自动添加token到请求中. axiosInstance.interceptors.request.use((config) => { diff --git a/src/assets/avatar1.jpg b/src/assets/avatar1.jpg new file mode 100644 index 0000000..8c00888 Binary files /dev/null and b/src/assets/avatar1.jpg differ diff --git a/src/assets/icons/Validate.svg b/src/assets/icons/Validate.svg new file mode 100644 index 0000000..8c2ad2b --- /dev/null +++ b/src/assets/icons/Validate.svg @@ -0,0 +1,5 @@ + + + diff --git a/src/components/VerifyInput.vue b/src/components/VerifyInput.vue new file mode 100644 index 0000000..1c0c9c3 --- /dev/null +++ b/src/components/VerifyInput.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/router/index.ts b/src/router/index.ts index 38827fc..ad868e6 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,10 +1,6 @@ -import axiosInstance from '@/api'; -import { userInfoResponseSchema, type Route } from '@/schemas'; +import { type Route } from '@/schemas'; import { useUserStore } from '@/stores'; -import { errorMessage, timeout } from '@/utils'; -import { AxiosError } from 'axios'; -import { ElMessage } from 'element-plus'; -import { type Component } from 'vue'; +import { watch, type Component } from 'vue'; import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'; const routes: RouteRecordRaw[] = [ { @@ -39,7 +35,7 @@ function _getAvailableRoutes(routeResponses: Route[], root: boolean, pathList: s } return res; } -function getAvailableRoutes(routeResponse: Route[]) { +export function getAvailableRoutes(routeResponse: Route[]) { _getAvailableRoutes(routeResponse, true, []); } router.beforeEach(async (to) => { @@ -48,29 +44,7 @@ router.beforeEach(async (to) => { // await timeout(1000); console.log(userStore.initialized); if (!userStore.initialized) { - try { - const userInfoResponse = userInfoResponseSchema.parse( - (await axiosInstance.get('/api/user/info')).data - ); - console.log(userInfoResponse); - if (userInfoResponse.type === 'error') { - ElMessage.error( - errorMessage('获取用户信息失败', userInfoResponse.code, userInfoResponse.msg) - ); - return false; - } - // 判断是否已登录. - if (userStore.token !== null) { - userStore.updateUserInfo(userInfoResponse); - } - getAvailableRoutes(userInfoResponse.data.auth.permissions[0].routers); - } catch (e) { - if (e instanceof AxiosError) { - ElMessage.error(errorMessage('获取用户信息失败', e.code, e.message)); - } - } finally { - userStore.initialized = true; - } + await new Promise((resolve) => watch(() => userStore.initialized, resolve)); } if (userStore.addedRouteSet.has(to.fullPath) || to.fullPath === '/404') { return true; diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 9a5df64..6b2fe6b 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -44,9 +44,20 @@ const routeResponsesSchema: z.ZodSchema = z.lazy(() => ); export const userInfoResponseSchema = createResponseSchema( idAndNameSchema.extend({ - avatar: z.string(), + avatar: z.nullable(z.string()), auth: idAndNameSchema.extend({ permissions: idAndNameSchema.extend({ routers: routeResponsesSchema }).array() }) }) ); +export const verifyResponseSchema = createResponseSchema( + z + .object({ + img: z.string(), + key: z.string() + }) + .transform((raw) => { + raw.img = `data:image/png;base64,${raw.img}`; + return raw; + }) +);