淘先锋技术网

首页 1 2 3 4 5 6 7

文章目录

1.构建后台项目

- 1.创建项目

在这里插入图片描述

- 2.编辑pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jt</groupId>
    <artifactId>jt</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/>
    </parent>

    <properties>
        <!--指定JDK版本-->
        <java.version>1.8</java.version>
        <!--跳过测试类打包-->
        <skipTests>true</skipTests>
    </properties>

    <!--按需导入
        历史说明: 2010 原来SSM 需要手动的编辑大量的的配置文件
        思想: SpringBoot使用体现了"开箱即用"的思想
    -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <!--Springboot的启动器 在内部已经将整合的配置写好,实现拿来就用-->
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--支持热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <!--引入插件lombok 自动的set/get/构造方法插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--引入数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--springBoot数据库连接  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--spring整合mybatis-plus 删除mybatis的包 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>

    </dependencies>

    <!--build标签
        springboot项目在打包部署发布时,需要依赖maven工具API
        如果不添加该插件,则直接影响项目发布
    -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.3</version>
            </plugin>
        </plugins>
    </build>

</project>

- 3.项目结构

说明: 从码云中下载jt的完整代码,之后粘贴到本地项目中,如图所示:
在这里插入图片描述

- 4.修改YML文件

server:
  port: 8091
  servlet:
    context-path: /

#配置数据源
spring:
  datasource:
    #如果使用高版本驱动 则添加cj
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root


#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    com.jt.mapper: debug

- 5.编辑启动项

1.点击修改
在这里插入图片描述
2.为启动项修改文件.方便以后使用
在这里插入图片描述

2.前端项目搭建

- 1.关于前端路径说明

为了让全国同学们了解前端的编码规则,所以全国最好统一项目路径.
要求: 将前端项目放到IDEA维护的工作目录中.
如图所示:
在这里插入图片描述

- 2.操作步骤

1.码云下载前端资料
在这里插入图片描述
2.项目解压之后复制到IDEA维护的目录中
注意事项: 不要出现目录的嵌套,要求目录的根 就是项目. 如图
在这里插入图片描述
3.导入项目
在这里插入图片描述
4.运行前端项目
在这里插入图片描述
3.命令启动
在这里插入图片描述

3.代码调试

- 1.前端代码调试

目的: 经常性的出现本来编辑的是李逵的代码,但是由于代码不熟练,编辑的李鬼. 所以有如下的测试.
编辑App.vue文件
在这里插入图片描述
代码测试
在这里插入图片描述

4.用户登录业务实现

- 1.项目划分

前端项目网址: http://localhost:8080/
后端项目网址: http://localhost:8091/
用户操作项目请求的流程: 用户----前端服务器------后端服务器

- 2.用户模块分析

- - 1.表设计分析

注意事项:
1.密码 加密处理
2.created/updated 每张表中都有该字段
在这里插入图片描述

- - 2.POJO分析(User.java)

package com.jt.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
// Linux系统,严格区分大小写
// 注意:类中必须写表名,防止大小写问题导致异常
@TableName("user")
@Data
@Accessors(chain = true)
public class User extends BasePojo{
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String username;
    private String password;
    private String phone;
    private String email;
    private Boolean status;
    @TableField(exist = false)  //该属性不存在
    private Role role;  //定义role角色数据
}

- 3.用户登录业务实现

- - 1.项目开发流程

人员配置:
1.项目经理(统筹规划协调资源,控制项目进度)
2.职能经理: 凭技术吃饭的 项目组长.
3.产品经理: 根据甲方要求,绘制项目原型. 出原型图
4.UI设计: 根据产品的图,用美学的眼光 绘制图片/按钮/logo
5.前端开发: 绘制页面(html/css/js)
6.后端开发: 根据业务接口文档.实现项目
7.测试工程师: 工具测试(黑白盒测试) 测试机型!!!
8.实施/运维工程师 事情杂/工资低

- - 2.接口文档说明

  • 请求路径: /user/login
  • 请求方式: POST
  • 请求参数
参数名称参数说明备注
username用户名不能为空
password密码不能为空
  • 响应数据 SysResult对象
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据返回密钥token信息

返回值格式如下:


{"status":200,"msg":"服务器调用成功!","data":"1e893a97634847b3a8b499b173bea620"}

- - 3.编辑SysResult对象

说明: 该对象主要负责前端项目与后端项目的数据交互. 几乎所有的后台服务器的返回值都是SysResult对象.

package com.jt.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult implements Serializable {
    private Integer status; //200业务执行成功 201业务执行失败
    private String msg; //服务器的提示信息
    private Object data; //封装后台返回值

    public static SysResult fail(){
        return new SysResult(201,"业务执行失败",null);
    }

    public static SysResult success(){
        return new SysResult(200,"业务执行成功",null);
    }

    //服务器返回业务数据
    public static SysResult success(Object data){
        return new SysResult(200,"业务执行成功",data);
    }

    public static SysResult success(String msg,Object data){
        return new SysResult(200,msg,data);
    }
}

- - 4.页面JS分析

1.路由跳转规则
在这里插入图片描述
2. axios 全局定义
在这里插入图片描述
3. axios的使用
在这里插入图片描述

- 4.用户登陆操作

- - 1.关于token的说明

1.由于服务器需要标识已经登录的用户,所以服务器动态生成一个独一无二的token,返回给用户.
2.用户将token保存到本地,方便下次访问时携带.

- - 2.生成UUID

编辑controller层

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.web.bind.annotation.*;

import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/hello")
    public List<User> hello(){

        return userService.findAll();
    }

    /**
     * 业务说明:实现用户登录
     * 思想:根据参数,查询数据库
     *       有值:用户名和密码正确
     *       没有值:用户名和密码错误
     *
     * url:/user/login
     * 参数:username/password
     * 类型:post
     * 返回值:SysResult对象(token)
     */
    @PostMapping("/login")
    public SysResult login(@RequestBody User user){

        //需求:要求登陆成功之后,返回标识符信息
        String token = userService.login(user);

        //如果token为null,说明登录失败
        if(token == null || token.length()==0){
            return SysResult.fail();
        }
        //否则 正确返回
        return SysResult.success(token);
    }
}

编辑server层 UserServiceImpl

package com.jt.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.selectList(null);
    }

    /**
     * 思路:
     *      1.将密码进行加密处理
     *      2.根据username/password查询数据库
     *      3.有值:
     *          登录成功,返回密钥
     *        没有值:
     *          登录失败,返回null
     */
    @Override
    public String login(User user) {
        //1.获取密码明文
        String password = user.getPassword();

        //2.加密处理
        String md5 = DigestUtils.md5DigestAsHex(password.getBytes());
        user.setPassword(md5);
        System.out.println(md5);

        //3.查询数据库
        //根据对象中不为空的属性当作where条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);

        //4.获取数据库对象
        User userDB = userMapper.selectOne(queryWrapper);

        //5.判断登录是否成功
        if(userDB == null){
            return null;
        }

        //6.使用UUID动态生成TOKEN,根据当前毫秒数+随机数利用hash算法生成
        //几乎可以保证不重复
        String token = UUID.randomUUID().toString().replace("-", "");
        return token;
    }
}

- - 3.Session与Cookie机制

- - - 1.Session机制介绍

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。注意会话状态仅在支持cookie的浏览器中保留。

小结:
1.Session称之为 “会话机制”
2.在浏览器中打开网页 就是一个会话.
3.用户的数据可以保存到会话中,但是有生命周期. 当会话关闭,则数据消失.

- - - 2.Cookie机制

Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息 [1] 。
说明:
1.cookie是一个小型的文本文件
2.cookie中存储的数据一般都是密文.
3.cookie中的数据的生命周期可控. 几天.几年!!!

- - - 3.Session与Cookie的区别

1.session的数据是临时存储.cookie的数据可以永久保存. (生命周期不同)
2.sesion是浏览器中的一个内存对象!而cookie是一个实际的本地文件. (形式不同).
3.session一般存储是一些涉密数据.cookie一般存储相对公开的数据(免密登录). (安全性)

- - - 4.项目使用[前端保存用户信息(Login.vue)]
//登录按钮函数
login(){
      //获取表单对象之后进行数据校验
      //valid 表示校验的结果 true表示通过  false表示失败
      this.$refs.loginFormRef.validate(async valid => {
         //如果没有完成校验则直接返回
         if(!valid) return

        //如果校验成功,则发起ajax请求
        const {data: result} = await this.$http.post('/user/login',this.loginForm)
        if(result.status !== 200) return this.$message.error("用户登录失败")
        this.$message.success("用户登录成功")

        //获取用户token信息,将其保存到Session中
        let token = result.data
        //调用浏览器中Session机制,存储信息
        window.sessionStorage.setItem("token",token)

        //用户登录成功之后,跳转到home页面
        this.$router.push("/home")
      })
    }

浏览器中的Session 控制:
当会话关闭时,Session数据将会被清空
在这里插入图片描述

- - - 5.实现系统首页跳转说明

1.实现页面跳转
在这里插入图片描述
2.编辑路由规则
编辑router/index.js 添加组件信息,实现首页跳转
在这里插入图片描述
3.实现效果
在这里插入图片描述

- 5.MD5介绍

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

理论: MD5不可以被破解的. 只能由明文加密为密文. 不可以反向编译

- - 1.编辑UserController

用户名: admin123
密码: admin123456

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.web.bind.annotation.*;

import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/hello")
    public List<User> hello(){

        return userService.findAll();
    }

	/**
     * 业务说明: 实现用户登录
     * 思想: 根据参数,查询数据库
     *      有值: 用户名和密码正确
     *      没有值: 用户名和密码错误
     *
     *  URL:/user/login
     *  参数: username/password json
     *  类型: post
     *  返回值: SysResult对象(token)
     */
    @PostMapping("/login")
    public SysResult login(@RequestBody User user){
        //需求:要求登录成功之后,返回值标识符信息
        String token = userService.login(user);
        //如果token为null,说明登录失败
        if(token == null || token.length()==0){
            return SysResult.fail();
        }
        //否则 正确返回
        return SysResult.success(token);
    }

- - 2.编辑UserService

package com.jt.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.selectList(null);
    }
	
	/**
     * 思路:
     *      1.将密码进行加密处理
     *      2.根据username/password查询数据库
     *      3.有值:
     *          登录成功,返回秘钥
     *        没有值:
     *          登录失败,返回null
     * @param user
     * @return
     */
    @Override
    public String login(User user) {
        //1.获取明文
        String password = user.getPassword();
        //2.加密处理
        String md5 = DigestUtils.md5DigestAsHex(password.getBytes());
        user.setPassword(md5);
        System.out.println(md5);
        //3.查询数据库
        QueryWrapper<User> queryWrapper= new QueryWrapper<>(user);
        //4.获取数据库对象
        User userDB = userMapper.selectOne(queryWrapper);
        //5.判断登录是否正确
        if(userDB == null){
            return null;
        }
        String token = "我是秘钥";
        return token;
    }

- 6.同源策略

规定: 浏览器要求在解析Ajax请求时,要求浏览器的路径与Ajax的请求的路径必须满足三个要求.则满足同源策略.可以访问服务器.
三个要求:
请求协议://域名:端口号都必须相同!!!

要素:
1.浏览器的请求路径.
2.Ajax请求的网址

- - 1.同源策略案例

案例1:
1.浏览器地址 http://localhost:8090/findAll
2.Ajax请求地址 http://localhost:8090/aaaa
满足同源策略.服务器可以正常访问.

案例2:
1.浏览器地址 http://localhost:8091/findAll
2.Ajax请求地址 http://localhost:8090/aaaa
不满足同源策略. 端口号不同. 属于跨域请求.

案例3:
1.浏览器地址 http://localhost:8090/findAll
2.Ajax请求地址 https://localhost:8090/aaaa
不满足同源策略. 协议不同. 属于跨域请求.

案例4:
前提: IP与域名映射
1.浏览器地址 http://www.baidu.com/findAll
2.Ajax请求地址 http://10.0.1.1/aaaa
不满足同源策略. 域名不同.

案例5:
1.浏览器地址 http://10.0.1.1:80/findAll
2.Ajax请求地址 http://10.0.1.1/aaaa
满足同源策略. 默认端口号就是80

案例6:
1.浏览器地址 https://10.0.1.1:443/findAll
2.Ajax请求地址 https://10.0.1.1:443/aaaa
满足同源策略

- - 2.什么是跨域

违反了同源策略的请求,就是跨域的请求.

- - 3.跨域解决方法

1.JSONP(了解)

**JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。**由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的

核心用法: 利用
返回值语法固定的: callback(JSON数据)

2.CORS方式
说明: CORS(Cross-origin resource sharing) “跨域资源共享”,现在的主流的浏览器都支持cors的方式. 如果需要跨域,则需要配置响应头信息.标识是否允许.

服务器端标识:
在这里插入图片描述
检查响应头信息:
在这里插入图片描述
CORS调用原理图:
在这里插入图片描述

- 7.权限校验-路由导航守卫

- - 1.业务需求

前端页面跳转是通过路由进行控制. 规定: 如果用户没有登录,则只允许访问登录页面.只有登录之后才能访问其它页面.
难点: 如何实现用户请求的拦截.
拦截器作用: 拦截用户的请求.
结果1: 请求放行
结果2: 请求拦截,一般配合重定向使用!!

- - 2.路由导航守卫的实现

- - - 1.参数说明

在这里插入图片描述

- - - 2.配置前端路由导航守卫(index.js)
const router = new VueRouter({
  routes
})

/**
 * 定义路由导航守卫!!!
 * 参数1: to    路由跳转的网址
 * 参数2: from  路由从哪里来
 * 参数3: next  是一个函数,表示放行或者重定向
 *              next()          放行
 *              next("/login")  重定向
 * 业务实现:
 *    核心逻辑: 检查是否有token
 *          若有token,表示用户已经登录,放行请求
 *          若没有token,表示用户没有登陆,重定向到登录页面
 *          若访问login页面,则直接放行
 */
router.beforeEach(
  (to,from,next) => {
    //若访问页面是login,则放行
    if(to.path === "/login"){// === 表示数值和类型相等
      return next()
    }
    //说明用户访问的请求不是login,请求需要校验
    //获取token数据
    let token = window.sessionStorage.getItem("token")
    // if(token !== null && token.length > 0) 与 if(token) 相同
    //用于子字符串的判断,判断解释为: 如果token不为null
    if(token){
      return next()
    }
     next("/login")
  }
)

5.左侧菜单获取

- 1.项目介绍

- - 1.表设计分析

说明: 如果查询所有的一级菜单 则parent_id = 0
如果查询二级菜单信息 则parent_id = 1级菜单的ID
如果查询三级菜单信息 则parent_id= 2级菜单的ID
在这里插入图片描述

- - 2.编辑POJO(Rights .java)

说明:
1.当前对象中children属性不属于字段,所以使用@TableField(exist = false)进行标识.
2.权限列表中有父子级关系,所以通过children封装子级

package com.jt.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

@TableName("rights")
@Data
@Accessors(chain = true)
public class Rights extends BasePojo{
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String name;
    @TableField("parent_id")
    private Integer parentId;
    private String path;
    private Integer level;
    //用来封装父子关系
    @TableField(exist = false)
    private List<Rights> children; //不是表格固有属性
}

- - 3.搭建Rights层级代码

1.编辑Mapper----Service-----Controller 层级代码 方便后续业务调用
在这里插入图片描述
2.完成查询
在这里插入图片描述
3.页面展示
在这里插入图片描述
关于端口号说明
8000端口: VUE UI vue客户端管理器所有占用的端口.
8080端口: jtadmin 脚手架项目启动时占用的端口号
8091端口: 后台SpringBoot业务系统的端口号

- 2.实现左侧菜单

- - 1.编辑页面JS

说明:当页面访问时,根据生命周期函数,调用getMenuList()方法.从后台的服务器获取菜单列表信息. JS如下.
在这里插入图片描述

- - 2.业务接口说明

只查询一级和二级的信息

  • 请求路径 /rights/getRightsList
  • 请求类型 GET
  • 请求参数 无
  • 响应数据 SysResult对象
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据返回权限List集合
  • 响应数据如图所示

在这里插入图片描述

- - 3. 编辑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;

    @GetMapping("/findAll")
    public List<Rights> findAll(Rights rights){
        return rightsService.findAll(rights);
    }

    /**
     * 查询左侧菜单列表,一级套二级的结构
     * url:/rights/getRightsList
     * 参数:没有参数
     * 返回值:SysResult(list)
     */
    @GetMapping("/getRightsList")
    public SysResult getRightsList(){
        List<Rights> rightsList = rightsService.getRightsList();
        return SysResult.success(rightsList);
    }
}

- - 4.编辑RightsServiceImpl

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;

    @Override
    public List<Rights> findAll(Rights rights) {
//        QueryWrapper<Rights> queryWrapper = new QueryWrapper<>(rights);
        return rightsMapper.selectList(new QueryWrapper<>(rights));
    }

    /**
     * 实现思路:
     *  1.先查询一级菜单信息 parent_id = 0
     *  2.将以及菜单循环遍历 一级菜单对象
     *  3.根据一级菜单信息,查询当前菜单下的二级
     *  4.将查询得到的二级菜单,封装到一级对象中
     * 实现思路二(扩展):
     *      利用左连接 实现关联查询 封装数据
     */
    @Override
    public List<Rights> getRightsList() {
        //1.查询一级列表信息
        QueryWrapper<Rights> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", 0);
        List<Rights> oneList = rightsMapper.selectList(queryWrapper);
        //2.遍历一级列表
        for(Rights oneRights : oneList){
            //根据一级查询二级
            queryWrapper.clear(); //清除之前的条件
            queryWrapper.eq("parent_id", oneRights.getId());
            List<Rights> twoList = rightsMapper.selectList(queryWrapper);

            //将查询的结果封装到一级对象中
            oneRights.setChildren(twoList);
        }
        return oneList;
    }
}

- - 5.页面效果展现

在这里插入图片描述

- - 6.关于层级表设计的说明

案例: 有一个业务逻辑 父子关系有3级 问:表如何设计?
业务关系: 爷爷—父亲—儿子-----孙子------重孙子
想法1: 定义三张表 爷爷表(id)—父亲表(parent_id–爷爷)—儿子表(parent_id—父亲)
数据结构复杂!!! 不便于扩展!!!

想法2: 定义一张表(id-----parent_id)
要求: 每个ID都应该有自己的parent_id

总结: 如果有父子关系,则一遍采用parent_id的方式进行封装. 自关联的方式

- 3.左侧菜单的跳转说明

- - 1.关于左侧菜单路径说明

说明: 用户点击2级菜单时,跳转的路径 是由数据表中的path字段进行控制.
在这里插入图片描述

- - 2.左侧菜单路由机制

1.定义路由占位符 在Home组件中 在中间定义了路由占位符.
在这里插入图片描述
2.编辑路由机制
根据路由嵌套的规则,通过children属性 实现组件嵌套.最终实现课堂页面效果.
在这里插入图片描述

- - 3.左侧菜单路由全部实现

需求: 当用户默认跳转到home时,应该默认展现 Welcome的组件 关键语法:重定向机制
效果:
在这里插入图片描述

- 4.ElementUI 基本用法

ElementUI官网

<template>
  <div>
      <!-- 标签使用原则:
          规则: 先定义,后使用
          语法: el-breadcrumb 找到名称为Breadcrumb组件进行展现
          定义elementUI的组件: 按需导入组件
             从elementUI中导入特定的组件
             1.import Vue from 'vue'
             2.import {Breadcrumb} from 'element-ui'
             3.Vue.use(Breadcrumb)  声明为全局组件.子组件可以直接调用
      -->
      <!-- 1.添加面包屑导航 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>活动管理</el-breadcrumb-item>
        <el-breadcrumb-item>活动列表</el-breadcrumb-item>
        <el-breadcrumb-item>活动详情</el-breadcrumb-item>
      </el-breadcrumb>

      <!-- 2.定义卡片视图  -->
      <el-card class="box-card">
        <div class="text item">
          <!-- 4.栅格: 每行24格,可以动态的缩放 -->
          <el-row :gutter="20">
            <el-col :span="8">
              <!-- 3.定义文本输入框-->
              <el-input placeholder="请输入内容" v-model="input3" class="input-with-select">
                 <el-button slot="append" icon="el-icon-search"></el-button>
              </el-input>
            </el-col>
            <el-col :span="3">
                <el-button type="primary">主要按钮</el-button>
            </el-col>
          </el-row>

        </div>
      </el-card>
  </div>
</template>

<script>
    //对外声明组件属性/方法等参数.要被根组件调用
    export default {
      data(){
        return {

        }
      }
    }
</script>

<style lang="less" scoped>
</style>

- 5.debug说明

说明: debug是编程中常用的代码的调试工具. 可以让代码一行一行执行.
在这里插入图片描述

6.用户模块实现

- 1.实现用户页面跳转