feat(auth): 实现退出登录功能并优化登录状态验证

- 在 DefaultLayout 组件中添加退出登录按钮
- 实现 logout 函数,用于清除 token 并重定向到登录页
- 修改路由配置,增加 requiresAuth 元数据用于权限控制
- 优化 auth.js 中的 TokenKey 名称
- 移除 CustomCard、AboutView 和 TestApi 组件中的冗余样式
This commit is contained in:
LingandRX 2025-01-01 17:33:57 +08:00
parent 68bcdb309e
commit d9f814ccfb
8 changed files with 44 additions and 51 deletions

View File

@ -28,39 +28,4 @@ defineProps({
</a-card>
</template>
<style scoped>
.card {
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
box-sizing: border-box;
.avatar {
width: 50%;
img {
border-radius: 50%;
}
}
.name {
width: 50%;
}
.content {
width: 100%;
}
}
@media screen and (max-width: 800px) {
.card {
width: 160px;
}
}
@media screen and (min-width: 800px) {
.card {
width: 200px;
}
}
</style>
<style scoped></style>

View File

@ -2,6 +2,7 @@
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
import { computed, reactive } from 'vue'
import router from '@/router/index.js'
import { setToken } from '@/utils/auth.js'
const formState = reactive({
account: '',
@ -22,8 +23,8 @@ const onfinish = async () => {
})
if (response.ok) {
const data = await response.json()
console.log(data)
console.log(`formState.account:${formState.account}`)
setToken(formState.account)
await router.push('/')
} else {
console.error('Login failed', response.statusText)

View File

@ -22,7 +22,7 @@ export default defineComponent({
<template>
<button @click="testapi">测试接口调用</button>
<p v-if="this.test != ''">
<p v-if="this.test !== ''">
{{ this.test[0].name }}<br />
{{ this.test[0].birth }}<br />
{{ this.test[0].gender }}<br />

View File

@ -3,6 +3,7 @@ import CustomCard from '@/components/CustomCard.vue'
import { RouterView } from 'vue-router'
import { h, ref } from 'vue'
import { AppstoreOutlined, MailOutlined } from '@ant-design/icons-vue'
import router from '@/router/index.js'
const current = ref(['mail'])
const items = ref([
@ -25,6 +26,23 @@ const items = ref([
title: '工具'
}
])
const logout = async () => {
const response = await fetch('http://localhost:3000/logout', {
method: 'POST',
cache: 'default',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
credentials: 'include'
})
if (response.ok) {
await router.push('/login')
} else {
console.error('Logout failed', response.statusText)
}
}
</script>
<template>
@ -52,6 +70,7 @@ const items = ref([
:defaultCollapsed="true"
>
<CustomCard :name="'rsgl'" :style="{ margin: 'auto', padding: '10px' }" />
<a-button @click="logout">退出登录</a-button>
</a-layout-sider>
</a-layout>
<a-layout-footer>footer</a-layout-footer>

View File

@ -6,6 +6,7 @@ import DefaultLayout from '../layouts/DefaultLayout.vue'
import LoginLayout from '@/layouts/LoginLayout.vue'
import LoginView from '@/views/LoginView.vue'
import HomeView from '@/views/HomeView.vue'
import { getToken } from '@/utils/auth.js'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -43,11 +44,25 @@ const router = createRouter({
{
path: '',
name: 'Login',
component: LoginView
component: LoginView,
meta: {
requiresAuth: true
}
}
]
}
]
})
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some((record) => record.meta.requiresAuth)
if (!requiresAuth && !getToken()) {
next({ path: '/login' })
} else {
console.log('next')
next()
}
})
export default router

View File

@ -1,6 +1,6 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
const TokenKey = 'account'
export function getToken() {
return Cookies.get(TokenKey)

View File

@ -21,7 +21,7 @@ function dateTimeToTimestamp(pattern, datetime) {
}
Date.prototype.Format = function (fmt) {
var o = {
const o = {
'M+': this.getMonth() + 1, //月份
'd+': this.getDate(), //日
'h+': this.getHours(), //小时
@ -32,7 +32,7 @@ Date.prototype.Format = function (fmt) {
}
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
for (var k in o)
for (const k in o)
if (new RegExp('(' + k + ')').test(fmt))
fmt = fmt.replace(
RegExp.$1,

View File

@ -5,11 +5,4 @@ import CustomNews from '@/components/CustomNews.vue'
<CustomNews />
</template>
<style>
@media (min-width: 1024px) {
.about {
display: flex;
align-items: center;
}
}
</style>
<style></style>