微服务项目->在线oj系统(Java-Spring)-后台管理(1)
创建后台管理前端代码
Layout.vue
<template><el-container class="layout-container"><el-container><el-header class="el-header"><el-dropdown placement="bottom-end"><span class="el-dropdown__box"><div><strong>当前⽤⼾:</strong>管理员</div><el-icon><ArrowDownBold /></el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item :icon="SwitchButton">退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></el-header><el-main class="layout-bottom-box"><div class="left"><el-aside width="200px" class="el-aside"><el-menu class="el-menu" router><el-menu-item index="/oj/layout/cuser"><el-icon><Management /></el-icon><span>⽤⼾管理</span></el-menu-item><el-menu-item index="/oj/layout/question"><el-icon><Management /></el-icon><span>题⽬管理</span ></el-menu-item><el-menu-item index="/oj/layout/exam"><el-icon><Management /></el-icon><span>竞赛管理</span></el-menu-item></el-menu></el-aside></div><div class="right"><RouterView /></div></el-main></el-container></el-container></template><script setup>
import {Management,ArrowDownBold,SwitchButton
} from '@element-plus/icons-vue'</script><style lang="scss" scoped>
.layout-container {height: 100vh;background: #f7f7f7;.layout-bottom-box{display: flex;justify-content: space-between;height: calc(100vh - 100px);overflow: hidden;.left{margin-right: 20px;background: #fff;display: flex;:deep(.el-menu){flex: 1;.el-menu-item.is-active{color: #32c5ff;}.el-menu-item:hover{background:#fff ;color: #32c5ff;}}}.right{flex: 1;overflow-y: auto;background: #fff;padding: 20px;}}.el-aside {background-color: #fff;&__logo {height: 120px;// background: url('@/assets/logo.png') no-repeat center / 120px auto;}.el-menu {border-right: none;}}.el-header {background-color: #fff;display: flex;align-items: center;justify-content: flex-end;height: 40px;.el-dropdown__box {display: flex;align-items: center;.el-icon {color: #4c4141;margin-left: 20px;}&:active,&:focus {outline: none;}}}.el-footer {display: flex;align-items: center;justify-content: center;font-size: 14px;color: #666;}
}
</style>
下拉栏
菜单栏 后面加一个router的目的是增加路由功能
创建下列文件
配置路由:
{path: '/oj/layout',name: 'layout',component: () => import('../views/Layout.vue'),children:[{path: 'cuser',name: 'cuser',component: () => import('../views/Cuser.vue'),},{path: 'question',name: 'question',component: () => import('../views/Question.vue'),},{path: 'exam',name: 'exam',component: () => import('../views/Exam.vue'),},]},
对二级路由进行路由时候需要额外写
修改菜单栏
当前页面展示:
点击左边菜单栏会路由到不同的页面 ,点击右上角会有下拉栏退出
但是我们这里还不能得到具体的昵称
所以我们进行修改
这里由于我们之前定义的失误,所以我们需要对表进行修改
首先,由于我们的昵称是可能包含中文的,那么我们就需要去修改数据库配置
其次,由于我们修改了数据库配置,那么我们就需要对我们的数据库进行删除重建
匿称功能
修改表结构
修改第26和27行
然后进行创建表和插入元素
这样可以帮我们把数据导出为插入语句,方便我们重新插入数据
修改后端代码
创建token的时候把昵称也存入
@Overridepublic R<LoginVO> info(String token) {if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);}LoginUser loginUser= tokenService.getLoginUser(token,secret);if (loginUser==null){return R.fail();}LoginVO loginVO=new LoginVO();loginVO.setNickName(loginUser.getNickName());return R.ok(loginVO);}
总体思路:从前端标头里面取出AUTHENTICATION,然后对它进行处理得到token,我们通过token又可以得到redis的key,通过key又可以取出redis里面存的用户信息
AUTHENTICATION-----》token------》》claim-----》》userkey-----》》key------》》value
修改前端代码
定义前端的交互的函数
定义响应式数据(使数据动态变化),然后创建一个函数,等待后端处理完之后对响应式数据进行
赋值,最后调用函数
但是,这个时候,我们如果前端去访问后端,我们的token现在存储于cookie中,其他接口去访问后端数据时候也需要携带token,所以我们增加一个请求拦截器,对所有的请求增加处理
再修改原来固定的昵称
最终效果
退出登录
后端代码
整体逻辑:
从token中去除userkey,然后处理得到key,再去调用redis,删除redis中存的value,这样这个key就失效了,下次访问的时候就需要进行重新登录
前端代码
定义前端的交互的函数
去Element-plus 上去寻找叫确认消息的弹框代码,然后进行修改,得出大体结构
如果我们点击确认则调用下面代码,如果我们点击取消,则不走下面代码
我们等待后端执行完代码后,再删除我们前端中的token,否则如果前端先删除了token,我们后端无法获得到token,更无法去删除token,这样后端的token还在,执行结束后,我们页面转到登录页面
路由优化处理
当我们访问的时候,我们会出现一个空白页面,这对用户不友好,我们可以修改路由,让用户访问的时候,重定向到登录页面
如果我们已经登录,然后用户因为有事关闭了浏览器,他之后继续访问登录页面的时候,我们可以直接让他跳转到后端管理页面,如果用户还没有访问过的话,我们让他直接重定向到登录页面(如果不是登录页面)
这个时候看起来好像没什么问题了,但是如果我们的token过期了,我们前端的token没有删除,这个时候如果过期了,我们去访问页面,它会弹出提示,令牌已经过期,但是:它并不会返回到登录页面所以对响应结果进行修改
当我们后端给我们返回结果为3001(令牌到期)时候,我们返回到登录页面,并弹出提示框
xxx'x