Spring-jt-Day12-登录退出页面布局

版权声明:本文为闪耀太阳原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_16804847/article/details/116780342

1. 用户登录

1.1 用户登录操作

1.1.1 编辑UserController

package com.jt.controller;

import com.jt.pojo.User;
import com.jt.service.UserService;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author 刘昱江
 * 时间 2021/5/11
 */
@RestController
@CrossOrigin
@RequestMapping("/user")    //抽取公共的请求
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 1.url地址: /user/login
     * 2.请求参数: 用户表单对象的JSON串   post类型
     * 3.返回值结果 SysResult  token?有值 正确        null 错误
     */
    @PostMapping("/login")
    public SysResult login(@RequestBody User user){

        String token = userService.findUserByUP(user);
        if(StringUtils.hasLength(token)){
            return SysResult.success(token);
        }else{
            return SysResult.fail();
        }
    }
}

1.1.2 编辑UserService

/**
     * user对象: username/password 明文
     * 业务思路:
     *  1.将密码进行加密处理  md5加密方式
     *  2.根据新的用户名和密码查询数据
     *  3. 结果:null 没查到  u/p错误
     *          不为null u/p正确  返回令牌 token  UUID算法
     *
     *  * @param user
     * @return
     *
     * 数据库信息:   用户名 :admin    密码:admin123456
     */
    @Override
    public String findUserByUP(User user) {
        //1.将密码加密 一般可能添加  盐值: 由公司域名构成
        // hash(md5(www.baidu.com12345))
        String md5Pass =DigestUtils
                        .md5DigestAsHex(user.getPassword().getBytes());
        //2.根据用户名/密码查询数据库.
        user.setPassword(md5Pass);
        //根据对象中不为null的属性当做where条件
        QueryWrapper queryWrapper = new QueryWrapper(user);
        User userDB = userMapper.selectOne(queryWrapper);

        //3.返回密钥token
        String token = UUID.randomUUID().toString()
                       .replace("-", "");
        return userDB==null?null:token;
    }

1.2 全局异常的处理

1.2.1 业务说明

在后端服务器中会有很多的地方需要添加,如果都写到业务代码中,会造成代码可读性差 如图:
在这里插入图片描述

1.2.2 编辑全局异常处理

@RestControllerAdvice   //定义全局异常处理 拦截controller层 返回JSON
public class AOPException {

    //实现原理 异常通知
    //1.拦截什么类型的异常!!
    //2.拦截之后如何处理!!
    @ExceptionHandler({RuntimeException.class})
    public Object exception(Exception e){
        //将异常 控制台输出
        e.printStackTrace();
        return SysResult.fail();
    }
}

1.3 保存用户登录信息

1.3.1 下载vue文件

说明: 去码云中的资源文件中查找组件Home/Welcome.导入项目中
在这里插入图片描述

1.3.2 实现路由跳转

说明: 实现Home组件路由的跳转 代码如下
在这里插入图片描述
页面效果:
在这里插入图片描述

1.3.3 业务需求

当用户登录成功之后,需要重定向到home页面.这时用户token将会丢失.用户后端的操作要求用户必须登录之后才可以执行,因此必须保存用户的登录凭证 token!!!

问题: 浏览器如果保存服务器记录?
补充知识:
1.cookie 可以将用户信息永久的保存到cookie中. 有安全性问题 如果需要使用则需要特殊处理 IP绑定/手机的认证 30天免密登录 视频会员
2.Session 表示服务器的会话机制 可以将数据保存到Session中.当会话关闭时Session失效了.

1.3.4 用户登录凭证保存

当用户登录成功之后,需要通过session保存用户的token信息.代码如下:
在这里插入图片描述

1.4 路由导航守卫

1.4.1 业务介绍

要求: 如果用户没有登录(token),则不允许访问其他页面.
判断依据: 根据session中的token进行判断. token有数据 则放行请求 没有数据 跳转到登录页面.
难点: 如果实现请求的拦截?
实现策略: 使用路由导航守卫.

1.4.2 路由导航守卫API

编辑router中的index.js 实现功能

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'

Vue.use(VueRouter)
const routes = [
  {path: '/', redirect: '/login'},
  {path: '/login', component: Login},
  {path: '/home', component: Home}
]

//1.定义路由对象
const router = new VueRouter({
  routes
})

 //  2.定义导航守卫(注意位置)
 //   beforeEach: 循环遍历用户的所有的请求.(拦截)
 //               在其中需要定义一个回调函数(3个参数)
 //  参数介绍:  to :要访问的请求路径
 //            from: 从哪个页面跳转而来
 //            next: 表示请求放行
 //业务需求: 1.如果用户请求/login
 //         2.如果不是login则判断是否登录 token
router.beforeEach((to,from,next) => {
    if(to.path === '/login') return next()

    //2.获取token信息
    let token = window.sessionStorage.getItem('token')
    //3.判断token是否有数据??  if(token) 如果token不为null
    //如果token为null 则跳转到登录页面
    if(!token) return next('/login')

    //表示放行
    next()

})

export default router

1.5 实现用户退出操作

1.5.1 需求说明

当用户点击退出按钮时,应该删除session中的数据. 之后跳转到登录页面.

1.5.2 编辑页面JS

在这里插入图片描述

1.6 elementUI 页面布局说明

1.6.1 布局API

<el-container>
  <el-header>Header</el-header>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-main>Main</el-main>
  </el-container>
</el-container>

1.6.2 页面布局

在这里插入图片描述

2. 左侧菜单实现

2.1 业务分析

说明: 当用户跳转到home页面中,之后发起Ajax请求获取模块信息.之后通过导航菜单的形式进行展现.

2.2 业务接口说明

在这里插入图片描述

2.3 实现权限获取后端业务

2.3.1 表结构说明

说明: 权限有父子级关系,通过parent_id实现父子关联
在这里插入图片描述

2.3.2 构建权限代码结构

在这里插入图片描述

2.3.3 权限POJO对象

在这里插入图片描述

2.3.4 编辑RightsController

package com.jt.controller;

import com.jt.pojo.Rights;
import com.jt.service.RightsService;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/rights")
public class RightsController {

    @Autowired
    private RightsService rightsService;

    /**
     * URL: /rights/getRightsList
     * 参数: null
     * 类型: get
     * 返回值: SysResult对象 List
     * 业务: 只查询前 2级权限
     */
    @GetMapping("/getRightsList")
    public SysResult getRightsList(){
        List<Rights> rightsList =
                rightsService.findRightsList();
        return SysResult.success(rightsList);
    }
}

2.3.5 编辑RightsService

package com.jt.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.RightsMapper;
import com.jt.pojo.Rights;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class RightsServiceImpl implements RightsService{

    @Autowired
    private RightsMapper rightsMapper;

    /**
     * 查询一级/二级菜单
     *  查询条件:    一级菜单  parent_id = 0
     *              二级菜单  parent_id = 一级的Id
     *  作业: 利用左连接的方式 实现数据的封装 restMap
     * @return
     */
    @Override
    public List<Rights> findRightsList() {
        //1.查询一级菜单数据
        QueryWrapper<Rights> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",0);
        List<Rights> oneList =
                        rightsMapper.selectList(queryWrapper);
        //2.如何查询二级菜单  父子关系的封装!!!
        for (Rights oneRights : oneList){
            //查询该元素的二级菜单
            //QueryWrapper<Rights> queryWrapper2 = new QueryWrapper<>();
            queryWrapper.clear();
            queryWrapper.eq("parent_id",oneRights.getId());
            List<Rights> twoList = rightsMapper.selectList(queryWrapper);
            oneRights.setChildren(twoList);
        }
        return oneList;
    }
}

2.4 实现前端左侧菜单展现

在这里插入图片描述
在这里插入图片描述

2.5 左侧菜单ElementUI学习

<el-container>
      <!-- 当打开左侧菜单时 宽度为200, 当不打开时为默认值-->
      <el-aside :width="isCollapse ? '64px' : '200px' ">
        <!-- 这是左侧菜单-->

        <!--定义折叠项-->
        <div class="leftCollapse" @click="collspseClick">|||</div>

        <!--
            1.background-color="#2C3E50"
            2.text-color="#fff" 文本颜色
            3.active-text-color="#4094ff"
            4.unique-opened=true 是否只打开一个菜单
            5.collapse  是否折叠
            6.collapse-transition 折叠时是否展现动画效果
            7.default-active  默认选中的菜单
         -->

        <el-menu background-color="#2C3E50"  text-color="#fff"
                 active-text-color="#4094ff"
                 unique-opened
        :collapse="isCollapse" :collapse-transition="isCollapseTransition" router  :default-active="defaultActive">

          <!-- 定义一级菜单 -->
          <el-submenu :index="menu.id+''" v-for="menu in menuList" :key="menu.id">
            <!-- 定义一级菜单模版 -->
            <template slot="title">
              <!-- 定义左侧图标-->
              <i :class="menuIcon[menu.id]"></i>
              <!-- 定义菜单名称-->
              <span>{{menu.name}}</span>
            </template>
            <!-- 定义二级菜单 -->
            <el-menu-item :index="childrenMenu.path" v-for="childrenMenu in menu.children" :key="childrenMenu.id"
            @click="defaultActiveMenu(childrenMenu.path)">
              <template slot="title">
                <i class="el-icon-menu"></i>
                <span>{{childrenMenu.name}}</span>
              </template>
            </el-menu-item>
          </el-submenu>

        </el-menu>
      </el-aside>

      <!-- 定义主页面结构-->
      <el-main>
        <!-- 定义路由展现页面-->
        <router-view></router-view>
      </el-main>
    </el-container>

2.6 脚手架项目执行过程

2.6.1 目录结构的说明

在这里插入图片描述

2.6.2 梳理程序加载流程

在这里插入图片描述

2.7 Home页面路由说明

2.7.1 中间菜单的结构

将来在view的位置,展现其他的页面组件
当前组件是谁: Home组件
如果需要在该位置展现组件,则必然是Home组件的子级
在这里插入图片描述

2.7.2 访问主页面

用户跳转到home组件之后,在中间展现欢迎页面.配置如下
在这里插入图片描述
页面效果展现:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值