SSM单体项目:拉勾教育后台管理系统(上)
任务一:课程模块
1.项目架构
1.1 项目介绍
拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、广告信息、用户信息、 权限信息等数据进行维护.
在 web阶段,我们已经完成了拉勾教育后台管理系统中课程模块, 接下来将对拉勾教育后台管理系统进行升级改造,基于SSM框架来完成课程信息模块,广告信息模块,用户信息模块,权限信息模块
1.2 页面原型展示
访问 http://eduboss.lagou.com
用户名:18201288771 密码:111111
1.3 技术选型
1.3.1 前端技术选型
1.3.2 后端技术选型
1.4 项目开发环境
- 开发工具
- 后端: IDEA 2019
- 前端: VS code
- 数据库客户端工具: SQLYog
- 开发环境
- JDK 11
- Maven 3.6.3
- MySQL 5.7
2.Maven进阶使用(Maven聚合工程)
2.1 maven基础知识回顾
2.1.1 maven介绍
maven 是一个项目管理工具,主要作用是在项目开发阶段对Java项目进行依赖管理和项目构建。
依赖管理:就是对jar包的管理。通过导入maven坐标,就相当于将仓库中的jar包导入了当前项目中。
项目构建:通过maven的一个命令就可以完成项目从清理、编译、测试、报告、打包,部署整个过程。
2.1.2 maven的仓库类型
1.本地仓库
2.远程仓库
①maven中央仓库(地址:http://repo2.maven.org/maven2/)
②maven私服(公司局域网内的仓库,需要自己搭建)
③其他公共远程仓库(例如apache提供的远程仓库,地址:http://repo.maven.apache.org/maven2/)
本地仓库---》maven私服---》maven中央仓库
2.1.3 maven常用命令
clean: 清理
compile:编译
test: 测试
package:打包
install: 安装
2.1.4 maven坐标书写规范
2.2 maven的依赖传递
2.2.1 什么是依赖传递
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
通过上面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。
依赖冲突
由于依赖传递现象的存在, spring-webmvc 依赖 spirng-beans-5.1.5,spring-aop 依赖 spring-beans-5.1.6,但是发现 spirng-beans-5.1.5 加入到了工程中,而我们希望 spring-beans-5.1.6 加入工程。这就造成了依赖冲突。
2.2.2 如何解决依赖冲突
1.使用maven提供的依赖调解原则
第一声明者优先原则
路径近者优先原则
2.排除依赖
3.锁定版本
2.2.3 依赖调节原则——第一声明者优先原则
在 pom 文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。
结论:通过上图可以看到,spring-aop和spring-webmvc都传递过来了spring-beans,但是因为spring-aop在前面,所以最终使用的spring-beans是由spring-aop传递过来的,而spring-webmvc传递过来的spring-beans则被忽略了。
2.2.4 依赖调节原则——路径近者优先原则
总结:直接依赖大于依赖传递
2.2.5 排除依赖
可以使用exclusions标签将传递过来的依赖排除出去。
2.2.6 版本锁定
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二步:在dependencies标签中声明需要导入的maven坐标
①在dependencyManagement标签中锁定依赖的版本
②在dependencies标签中声明需要导入的maven坐标
2.2.7 properties标签的使用
5.1.5.RELEASE
5.1.5.RELEASE
3.5.1
org.mybatis
mybatis
${mybatis.version}
org.springframework
spring-webmvc
${springmvc.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-aop
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-expression
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-tx
${spring.version}
2.3 maven聚合工程(分模块)
概念:
在现实生活中,汽车厂家进行汽车生产时,由于整个生产过程非常复杂和繁琐,工作量非常大,所以厂家都会将整个汽车的部件分开生产,最终再将生产好的部件进行组装,形成一台完整的汽车。
2.3.1 分模块构建maven工程分析
在企业项目开发中,由于项目规模大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用
常见的拆分方式有两种:
第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块,订单模块,购物车模块等,每个模块对应就是一个maven工程
第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程
不管上面那种拆分方式,通常都会提供一个父工程,将一些公共的代码和配置提取到父工程中进行统一管理和配置。
2.3.2 maven工程的继承
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
2.3.3 maven工程的聚合
在maven工程的pom.xml文件中可以使用标签< modules>将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到maven父工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
2.3.4 maven聚合工程_搭建拉勾教育后台管理系统
工程整体结构如下:
1)lagou_edu_home_parent为父工程,其余工程为子工程,都继承父工程lagou_edu_home_parent
2)lagou_edu_home_parent工程将其子工程都进行了聚合
3)子工程之间存在依赖关系:
? ssm_domain依赖ssm_utils
? ssm_dao依赖ssm_domain
? ssm_service依赖ssm_dao
? ssm_web依赖ssm_service
① 父工程lagou_edu_home_parent构建
修改pom.xml,添加依赖
5.1.5.RELEASE
5.1.5.RELEASE
3.5.1
org.mybatis
mybatis
${mybatis.version}
org.springframework
spring-webmvc
${springmvc.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-aop
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-expression
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-tx
${spring.version}
mysql
mysql-connector-java
5.1.47
com.alibaba
druid
1.1.15
org.mybatis
mybatis
junit
junit
4.12
org.springframework
spring-context
org.aspectj
aspectjweaver
1.8.13
org.springframework
spring-jdbc
org.springframework
spring-tx
org.springframework
spring-test
org.mybatis
mybatis-spring
1.3.1
org.springframework
spring-webmvc
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet.jsp
jsp-api
2.2
provided
jstl
jstl
1.2
com.fasterxml.jackson.core
jackson-databind
2.9.8
com.fasterxml.jackson.core
jackson-core
2.9.8
com.fasterxml.jackson.core
jackson-annotations
2.9.0
com.github.pagehelper
pagehelper
4.1.6
commons-beanutils
commons-beanutils
1.8.3
commons-fileupload
commons-fileupload
1.3.1
com.thetransactioncompany
cors-filter
2.5
org.apache.maven.plugins
maven-compiler-plugin
3.1
1.8
1.8
UTF-8
② 子工程ssm_utils构建
③ 子工程ssm_domain构建
com.lagou
ssm_utils
1.0-SNAPSHOT
④ 子工程ssm_dao构建
? 配置ssm_domain工程的pom.xml文件
com.lagou
ssm_domain
1.0-SNAPSHOT
创建DAO接口和Mapper映射文件
package com.lagou.dao;
import com.lagou.domain.Test;
import java.util.List;
public interface TestMapper {
public List findAllTest();
}
<?xml version="1.0" encoding="UTF-8" ?>
在resources目录下创建spring配置文件applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
⑤子工程ssm_service构建
? 第一步:创建ssm_service工程
? 第二步:配置ssm_service工程的pom.xml文件
com.lagou
ssm_dao
1.0-SNAPSHOT
第三步:创建TestService接口和实现类
public interface TestService {
public List findAllTest();
}
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Override
public List findAllTest() {
List allTest = testMapper.findAllTest();
return allTest;
}
}
第四步:创建spring配置文件applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
⑥子工程ssm_web构建
? 第一步:创建maven_web工程,注意打包方式为war
? 第二步:配置maven_web工程的pom.xml文件
com.lagou
ssm_service
1.0-SNAPSHOT
第三步:创建Controller
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping("/findAllTest")
public List findAllTest(){
List allTest = testService.findAllTest();
return allTest;
}
}
第四步: 创建springmvc配置文件springmvc.xml
第五步:编写applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
第六步:配置web.xml
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
2
DispatcherServlet
/
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext.xml
corsFilter
com.thetransactioncompany.cors.CORSFilter
corsFilter
/*
3.拉勾教育后台管理系统研发
3.1 课程管理模块功能分析
在本次的项目中,首先先来完成拉勾教育后台管理系统的 课程管理模块, 课程管理模块包含了多条件查询、 图片上传、 新建&修改课程、课程状态管理、课程内容展示、回显章节对应的课程信息、新建&修改章节信息、修改章节状态、 新建&修改课时信息等接口的编写
3.1.1 课程管理
- 实现以下功能:
- 多条件查询
- 图片上传
- 新建课程信息
- 回显课程信息
- 修改课程信息
- 课程状态管理
- 课程内容展示
- 回显章节对应的课程信息
- 新建&修改章节信息
- 修改章节状态
- 新建课时信息
3.2 课程管理模块表设计
3.2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
3.2.2 表关系介绍
1.ER图
2.数据实体描述
2.1 课程表
3.3 课程管理模块接口实现
多条件课程列表查询
需求分析
根据课程名称及课程状态进行多条件查询
查看接口文档,进行编码
查看接口文档
实体类:Course
//主键
private int id;
//课程名称
private String courseName;
//课程一句话简介
private String brief;
//原价
private double price;
//原价标签
private String priceTag;
//优惠价
private double discounts;
//优惠价标签
private String discountsTag;
//课程内容markdown
private String courseDescriptionMarkDown;
//课程描述
private String courseDescription;
//课程分享图片url
private String courseImgUrl;
//是否新品
private int isNew;
//广告语
private String isNewDes;
//最后操作者
private int lastOperatorId;
//自动上架时间
private Date autoOnlineTime;
//创建时间
private Date createTime;
//更新时间
private Date updateTime;
//是否删除
private int isDel;
//总时长
private int totalDuration;
//课程列表展示图片
private String courseListImg;
//课程状态,0-草稿,1-上架
private int status;
//课程排序
private int sortNum;
//课程预览第一个字段
private String previewFirstField;
//课程预览第二个字段
private String previewSecondField;
// getter/setter....
ResponseResult
public class ResponseResult {
private Boolean success;
private Integer state;
private String message;
private Object content;
public ResponseResult() {
}
public ResponseResult(Boolean success, Integer state, String message, Object
content) {
this.success = success;
this.state = state;
this.message = message;
this.content = content;
}
//getter/setter..
}
实体类:CourseVo(View Object表现层对象:主要用于表现层来接收参数的)
public class CourseVO {
/**
* 课程名称
* */
private String courseName;
/**
* 课程状态
* */
private Integer status;
// getter/setter....
}
Dao层:CourseMapper
public interface CourseMapper {
/**
* 多条件课程列表查询
*/
public List findCourseByConditioin(CourseVo courseVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:CourseService
public interface CourseService {
/**
* 多条件查询课程列表
* */
public List findCourseByConditioin(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public List findCourseByConditioin(CourseVO courseVO) {
List courseList = courseMapper.findCourseByConditioin(courseVO);
return courseList;
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 查询课程信息&条件查询 接口
* */
@RequestMapping("/findCourseByConditioin")
public ResponseResult findCourseByConditioin(@RequestBody CourseVO courseVO)
{
List courseList = courseService.findCourseByConditioin(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成功",courseList);
return result;
}
Postman测试接口
课程图片上传
需求分析:
需求:在新增课程页面需要进行图片上传,并回显图片信息
查看接口文档,进行编码
查看接口文档
springmvc.xml
Web层:CourseController
/**
* 图片上传接口
* */
@RequestMapping("/courseUpload")
public ResponseResult fileUpload(@RequestParam("file")MultipartFile file,
HttpServletRequest request){
try {
//1.判断文件是否为空
if(file.isEmpty()){
throw new RuntimeException();
}
//2.获取项目部署路径
// D:\apache-tomcat-8.5.56\webapps\ssm_web\
String realPath = request.getServletContext().getRealPath("/");
// D:\apache-tomcat-8.5.56\webapps\
String webappsPath =
realPath.substring(0,realPath.indexOf("ssm_web"));
//3.获取原文件名
String fileName = file.getOriginalFilename();
//4.新文件名
String newFileName = System.currentTimeMillis() +
fileName.substring(fileName.lastIndexOf("."));
//5.上传文件
String uploadPath = webappsPath+"upload\\";
File filePath = new File(uploadPath,newFileName);
//如果目录不存在就创建目录
if(!filePath.getParentFile().exists()){
filePath.getParentFile().mkdirs();
System.out.println("创建目录: " + filePath);
}
file.transferTo(filePath);
//6.将文件名和文件路径返回
Map map = new HashMap<>();
map.put("fileName",newFileName);
map.put("filePath",LOCAL_URL+"/upload/"+newFileName);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建课程信息
需求分析:
填写好新增课程信息后,点击保存,将表单信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 保存课程信息
*/
public int saveCourse(Course course);
/**
* 保存讲师信息
* */
public void saveTeacher(Teacher teacher);
}
CourseMapper.xml
INSERT INTO course(
course_name,
brief,
preview_first_field,
preview_second_field,
course_img_url,
course_list_img,
sort_num,
price,
discounts,
sales,
discounts_tag,
course_description_mark_down,
create_time,
update_time
) VALUES(#{courseName},#{brief},#{previewFirstField},#{previewSecondField},#{courseImgUrl},
#{courseListImg},#{sortNum},#{price},#{discounts},#{sales},#{discountsTag},#{courseDescriptionMarkDown},
#{createTime},#{updateTime});
SELECT LAST_INSERT_ID();
INSERT INTO teacher(
course_id,
teacher_name,
POSITION,
description,
create_time,
update_time
) VALUES(#{courseId},#{teacherName},#{position},#{description},#
{createTime},#{updateTime});
Service层:CourseService
public interface CourseService {
/**
* 保存课程信息
* */
public void saveCourseOrTeacher(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public void saveCourseOrTeacher(CourseVO courseVO) {
try {
//封装课程信息
Course course = new Course();
BeanUtils.copyProperties(course,courseVO);
//补全信息
Date date = new Date();
course.setCreateTime(date);
course.setUpdateTime(date);
//保存课程
courseMapper.saveCourse(course);
//获取新插入数据的id
int id = course.getId();
//封装讲师信息
Teacher teacher = new Teacher();
BeanUtils.copyProperties(teacher,courseVO);
//补全信息
teacher.setCourseId(id);
teacher.setCreateTime(date);
teacher.setUpdateTime(date);
//保存讲师信息
courseMapper.saveTeacher(teacher);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 保存&修改课程信息接口
* */
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO){
try {
if(courseVO.getId() == null){
courseService.saveCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}else{
courseService.updateCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
回显课程信息
需求分析:
点击编辑按钮,回显课程信息
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 根据id 获取课程信息
* */
public CourseVO findCourseById(int id);
}
CourseMapper.xml
Service层:CourseService
public interface CourseService {
/**
* 根据id获取课程信息
* */
public CourseVO findCourseById(int id);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public CourseVO findCourseById(int id) {
return courseMapper.findCourseById(id);
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 根据id获取课程信息
* */
@RequestMapping("/findCourseById")
public ResponseResult findCourseById(@RequestParam int id) {
try {
CourseVO courseVO = courseService.findCourseById(id);
ResponseResult result = new ResponseResult(true,200,"响应成功",courseVO);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
修改课程信息
需求分析:
点击保存按钮,将修改后的课程信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 修改课程信息
* */
public void updateCourse(Course course);
/**
* 修改讲师信息
* */
public void updateTeacher(Teacher teacher);
}
CourseMapper.xml
UPDATE course
course_name = #{courseName},
brief=#{brief},
preview_first_field=#{previewFirstField},
preview_second_field=#{previewSecondField},
course_img_url=#{courseImgUrl},
course_list_img=#{courseListImg},
sort_num=#{sortNum},
price=#{price},
discounts=#{discounts},
sales=#{sales},
discounts_tag=#{discountsTag},
course_description_mark_down=#{courseDescriptionMarkDown},
update_time=#{updateTime},
id=#{id}
UPDATE teacher
teacher_name = #{teacherName},
position = #{position},
description = #{description},
update_time=#{updateTime}
course_id = #{courseId}
Service层:CourseService
public interface CourseService {
/**
* 修改课程信息
* */
public void updateCourseOrTeacher(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public void updateCourseOrTeacher(CourseVO courseVO) {
try {
//封装课程信息
Course course = new Course();
BeanUtils.copyProperties(course,courseVO);
//补全信息
Date date = new Date();
course.setUpdateTime(date);
//更新课程
courseMapper.updateCourse(course);
//封装讲师信息
Teacher teacher = new Teacher();
BeanUtils.copyProperties(teacher,courseVO);
//补全信息
teacher.setCourseId(course.getId());
teacher.setUpdateTime(date);
//更新讲师信息
courseMapper.updateTeacher(teacher);
} catch (Exception e) {
e.printStackTrace();
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 保存&修改课程信息接口
* */
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO){
try {
if(courseVO.getId() == null){
courseService.saveCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}else{
courseService.updateCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
课程状态管理
需求分析:
在课程列表展示页面中,可以通过点击 上架/下架按钮,修改课程状态
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 修改课程状态
* */
public void updateCourseStatus(Course course);
}
CourseMapper.xml
UPDATE course SET STATUS = #{status} ,update_time = #{updateTime} WHERE
id = #{id}
Service层:CourseService
/**
* 修改课程状态
* */
public void updateCourseStatus(int id,int status);
@Override
public void updateCourseStatus(int id,int status) {
try {
//封装数据
Course course = new Course();
course.setStatus(status);
course.setId(id);
course.setUpdateTime(new Date());
//调用Dao
courseMapper.updateCourseStatus(course);
} catch (Exception e) {
e.printStackTrace();
}
}
Web层:CourseController
/**
* 修改课程状态
* */
@RequestMapping("/updateCourseStatus")
public ResponseResult updateCourseStatus(@RequestParam int id,@RequestParam
int status){
try {
//执行修改操作
courseService.updateCourseStatus(id, status);
//保存修改后的状态,并返回
Map map = new HashMap<>();
map.put("status",status);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Postman测试接口
课程内容展示
需求分析:
需求:点击内容管理,展示课程对应的课程内容(课程内容包含了章节和课时)
查看接口文档,进行编码:
查看接口文档:
CourseSection
/**
* 章节类
* */
public class CourseSection {
//id
private Integer id;
//课程id
private int courseId;
//章节名
private String sectionName;
//章节描述
private String description;
//创建时间
private Date createTime;
//更新时间
private Date updateTime;
//是否删除
private int isDe;
//排序
private int orderNum;
//状态
private int status;
//课时集合
private List lessonList;
public List getLessonList() {
return lessonList;
}
public void setLessonList(List lessonList) {
this.lessonList = lessonList;
}
Dao层:CourseContentMapper
public interface CourseContentMapper {
/**
* 查询课程下的章节与课时信息
* */
public List findSectionAndLessonByCourseId(int courseId);
}
cl.id as lessonId,
cl.course_id,
cl.section_id,
cl.theme,
cl.duration,
cl.is_free,
cl.order_num,
cl.status
Service层:CourseContentService
public interface CourseContentService {
public List findSectionAndLessonByCourseId(int courseId);
}
@Service
public class CourseContentServiceImpl implements CourseContentService {
@Autowired
private CourseContentMapper contentMapper;
@Override
public List findSectionAndLessonByCourseId(int courseId) {
List sectionList =
contentMapper.findSectionAndLessonByCourseId(courseId);
return sectionList;
}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {
@Autowired
private CourseContentService contentService;
/**
* 查询课程内容
* */
@RequestMapping("/findSectionAndLesson")
public ResponseResult findSectionAndLessonByCourseId(@RequestParam int
courseId){
try {
//调用service
List sectionList =
contentService.findSectionAndLessonByCourseId(courseId);
//封装数据并返回
ResponseResult result = new ResponseResult(true,200,"响应成
功",sectionList);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
回显章节对应的课程信息
需求分析:
需求:在课程内容界面回显课程信息
查看接口文档,进行编码:
查看接口文档:
Dao层:CourseContentMapper
public interface CourseContentMapper {
/**
* 回显章节对应的课程信息
* */
public Course findCourseByCourseId(int courseId);
}
Service层:CourseContentService
public interface CourseContentService {
public Course findCourseByCourseId(int courseId);
}
@Service
public class CourseContentServiceImpl implements CourseContentService {
@Autowired
private CourseContentMapper contentMapper;
@Override
public Course findCourseByCourseId(int courseId) {
Course course = contentMapper.findCourseByCourseId(courseId);
return course;
}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {
@Autowired
private CourseContentService contentService;
/**
* 回显章节对应的课程信息
* */
@RequestMapping("/findCourseByCourseId")
public ResponseResult findCourseByCourseId(@RequestParam int courseId){
try {
//调用service
Course course = contentService.findCourseByCourseId(courseId);
ResponseResult result = new ResponseResult(true,200,"响应成
功",course);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建章节信息
需求分析:
在课程内容展示页面中,可以通过点击添加阶段按钮,添加章节信息
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 保存章节
* */
public void saveSection(CourseSection section);
INSERT INTO course_section(
course_id,
section_name,
description,
order_num,
STATUS,
create_time,
update_time
)VALUES(#{courseId},#{sectionName},#{description},#{orderNum},
#{status},#{createTime},#{updateTime});
Service层:CourseContentService
public void saveSection(CourseSection section);
@Override
public void saveSection(CourseSection section) {
//补全信息
Date date = new Date();
section.setCreateTime(date);
section.setUpdateTime(date);
contentMapper.saveSection(section);
}
Web层:CourseContentController
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection
section) {
try {
contentService.saveSection(section);
return new ResponseResult(true,200,"响应成功",null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
修改章节信息
需求分析:
点击确定按钮,将修改后的章节信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 修改章节
* */
public void updateSection(CourseSection section);
UPDATE course_section
section_name = #{sectionName},
description = #{description},
order_num = #{orderNum},
update_time=#{updateTime}
id = #{id}
Service层:CourseContentService
public void updateSection(CourseSection section);
@Override
public void updateSection(CourseSection section) {
//补全信息
Date date = new Date();
section.setUpdateTime(date);
contentMapper.updateSection(section);
}
Web层:CourseContentController
/**
* 保存&修改章节信息
*/
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection
section) {
try {
//判断携带id是修改操作否则是插入操作
if(section.getId() == null){
contentService.saveSection(section);
return new ResponseResult(true,200,"响应成功",null);
}else{
contentService.updateSection(section);
return new ResponseResult(true,200,"响应成功",null);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
修改章节状态
需求分析:
需求:点击修改章节状态按钮,将当前章节信息的状态进行修改
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 修改章节状态
* */
public void updateSectionStatus(CourseSection section);
CourseContentMapper.xml
UPDATE course_section set
status = #{status},
update_time = #{updateTime}
WHERE id = #{id}
Service层:CourseContentService
public void updateSectionStatus(int id,int status);
@Override
public void updateSectionStatus(int id,int status) {
//封装数据
CourseSection section = new CourseSection();
section.setId(id);
section.setStatus(status);
section.setUpdateTime(new Date());
contentMapper.updateSectionStatus(section);
}
Web层:CourseContentController
/**
* 修改章节状态
* 状态,0:隐藏;1:待更新;2:已发布
* */
@RequestMapping("/updateSectionStatus")
public ResponseResult updateSectionStatus(@RequestParam int id,@RequestParam
int status){
try {
contentService.updateSectionStatus(id,status);
//封装最新的状态信息
Map map = new HashMap<>();
map.put("status",status);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建课时信息(自行完成)
需求分析:
需求:点击添加阶段按钮,将弹出页面填写的章节信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 保存课时
* */
public void saveLesson(CourseLesson lesson);
INSERT INTO course_lesson (
id,course_id,
section_id,
theme,
duration,
is_free,
order_num,
create_time,
update_time
)VALUES(#{id},#{courseId},#{sectionId},#{theme},#{duration},#{isFree},
#{orderNum},#{createTime},#{updateTime});
Service层:CourseContentService
public void saveLesson(CourseLesson lesson);
@Override
public void saveLesson(CourseLesson lesson) {
//补全信息
Date date = new Date();
lesson.setCreateTime(date);
lesson.setUpdateTime(date);
contentMapper.saveLesson(lesson);
}
Web层:CourseContentController
/**
* 保存&修改课时
* */
@RequestMapping("/saveOrUpdateLesson")
public ResponseResult saveOrUpdateLesson(@RequestBody CourseLesson lesson){
try {
if(lesson.getId() == null){
contentService.saveLesson(lesson);
return new ResponseResult(true,200,"响应成功",null);
}else{
contentService.updateLesson(lesson);
return new ResponseResult(true,200,"响应成功",null);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
任务二:广告模块
一 广告模块功能分析
在任务二中,首先先来完成拉勾教育后台管理系统的 广告管理模块, 广告模块包含了广告位列表查询、添加&修改广告位、回显广告位名称、广告分页查询、图片上传接口、新建&修改广告、回显广告信息、广告状态上下线等接口的编写
1.1 课程管理
- 实现以下功能:
- 广告位列表查询
- 添加&修改广告位
- 回显广告位名称
- 广告分页查询
- 图片上传接口
- 新建&修改广告接口
- 回显广告信息
- 广告状态上下线
二 广告管理模块表设计
2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
2.2 表关系介绍
1.ER图
2.数据实体描述
2.1 广告位表
2.2 广告表
三 广告管理模块接口实现
1.广告位列表查询
1.1 需求分析
需求:点击广告列表按钮进行广告列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:PromotionSpace
public class PromotionSpace {
private Integer id;
private String name;
private String spaceKey;
private Date createTime;
private Date updateTime;
private Integer isDel;
@Override
public String toString() {
return "PromotionSpace{" +
"id=" + id +
", name='" + name + '\'' +
", spaceKey='" + spaceKey + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", isDel=" + isDel +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSpaceKey() {
return spaceKey;
}
public void setSpaceKey(String spaceKey) {
this.spaceKey = spaceKey;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getIsDel() {
return isDel;
}
public void setIsDel(Integer isDel) {
this.isDel = isDel;
}
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/*
获取所有的广告位
*/
public List findAllPromotionSpace();
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:PromotionSpaceService
public interface PromotionSpaceService {
/*
获取所有的广告位
*/
public List findAllPromotionSpace();
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public List findAllPromotionSpace() {
List allPromotionSpace =
promotionSpaceMapper.findAllPromotionSpace();
return allPromotionSpace;
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
查询所有广告位列表
*/
@RequestMapping("/findAllPromotionSpace")
public ResponseResult findAllPromotionSpace(){
List allPromotionSpace =
promotionSpaceService.findAllPromotionSpace();
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allPromotionSpace);
return responseResult;
}
}
Postman测试接口
2.添加&修改广告位
1.1 需求分析
添加:点击广告列表按钮进行广告列表展示
修改:页面回显基础上,点击提交按钮 真正进行数据修改
2.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/*
添加广告位
*/
public void savePromotionSpace(PromotionSpace promotionSpace);
/**
* 修改广告位
* */
public void updatePromotionSpace(PromotionSpace promotionSpace);
}
<?xml version="1.0" encoding="UTF-8" ?>
insert into promotion_space values(null,#{name},#{spaceKey},#
{createTime},#{updateTime},#{isDel})
UPDATE promotion_space SET NAME = #{name},updateTime = #{updateTime}
where id = #{id}
Service层:PromotionSpaceService
public interface PromotionSpaceService {
void savePromotionSpace(PromotionSpace promotionSpace);
void updatePromotionSpace(PromotionSpace promotionSpace);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public void savePromotionSpace(PromotionSpace promotionSpace) {
// 封装PromotionSpace
UUID uuid = UUID.randomUUID();
promotionSpace.setSpaceKey(uuid.toString());
promotionSpace.setCreateTime(new Date());
promotionSpace.setUpdateTime(new Date());
promotionSpace.setIsDel(0);
promotionSpaceMapper.savePromotionSpace(promotionSpace);
}
@Override
public void updatePromotionSpace(PromotionSpace promotionSpace) {
promotionSpace.setUpdateTime(new Date());
promotionSpaceMapper.updatePromotionSpace(promotionSpace);
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
添加&修改广告位
*/
@RequestMapping("/saveOrUpdatePromotionSpace")
public ResponseResult savePromotionSpace(@RequestBody PromotionSpace
promotionSpace){
try {
if(promotionSpace.getId() == null){
//新增
promotionSpaceService.savePromotionSpace(promotionSpace);
ResponseResult responseResult = new ResponseResult(true,200,"响应
成功","");
return responseResult;
}else{
//修改
promotionSpaceService.updatePromotionSpace(promotionSpace);
ResponseResult responseResult = new ResponseResult(true,200,"响应
成功","");
return responseResult;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
3.回显广告位名称
3.1 需求分析
需求:点击编辑按钮,进行广告位信息回显
3.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/**
* 根据id 查询广告位信息
* */
PromotionSpace findPromotionSpaceById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:PromotionSpaceService
public interface PromotionSpaceService {
PromotionSpace findPromotionSpaceById(int id);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public PromotionSpace findPromotionSpaceById(int id) {
PromotionSpace promotionSpace =
promotionSpaceMapper.findPromotionSpaceById(id);
return promotionSpace;
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/**
* 根据id查询 广告位信息
* */
@RequestMapping("/findPromotionSpaceById")
public ResponseResult findPromotionSpaceById(@RequestParam int id){
PromotionSpace promotionSpace =
promotionSpaceService.findPromotionSpaceById(id);
ResponseResult result = new ResponseResult(true,200,"响应成
功",promotionSpace);
return result;
}
}
4.广告分页查询
4.1 需求分析
需求:点击广告列表,对广告信息进行分页列表展示
4.2 查看接口文档,进行编码
查看接口文档
实体类:PromotionAd
public class PromotionAd {
// 标识
private Integer id;
// 广告名
private String name;
// 广告位id
private Integer spaceId;
// 精确搜索关键词
private String keyword;
// 静态广告的内容
private String htmlContent;
// 文字一
private String text;
// 链接一
private String link;
// 开始时间
private Date startTime;
// 结束时间
private Date endTime;
private Integer status;
private Date createTime;
private Date updateTime;
// 优先级
private Integer priority;
private String img;
getter/setter..
}
PromotionAdVo
public class PromotionAdVo {
private Integer currentPage = 1;
private Integer pageSize = 10;
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
/*
分页获取所有的广告列表
*/
public List findAllAdByPage();
}
Service层:PromotionAdService
applicationContext.xml
helperDialect=mysql
public interface PromotionAdService {
/*
分页获取所有的广告列表
*/
public PageInfo findAllAdByPage(PromotionAdVo adVo);
}
@Service
public class PromotionAdServiceImpl implements PromotionAdService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public PageInfo findAllAdByPage(PromotionAdVo adVo) {
PageHelper.startPage(adVo.getCurrentPage(),adVo.getPageSize());
List allAd = adMapper.findAllAdByPage();
PageInfo adPageInfo = new PageInfo<>(allAd);
return adPageInfo;
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
分页查询所有广告信息
*/
@RequestMapping("/findAllPromotionAd")
public ResponseResult findAllAdByPage(PromotionAdVo adVo) {
PageInfo allAdByPage = adService.findAllAdByPage(adVo);
ResponseResult responseResult = new ResponseResult(true, 200, "响应成功",
allAdByPage);
return responseResult;
}
}
Postman测试接口
5.图片上传接口
5.1 需求分析
需求:添加广告页面,点击上传按钮,需完成图片上传
5.2 查看接口文档,进行编码
查看接口文档
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
文件上传
*/
@RequestMapping("/PromotionAdUpload")
public ResponseResult fileupload(@RequestParam("file") MultipartFile file,
HttpServletRequest request) throws IOException {
try {
//1.判断文件是否为空
if (file.isEmpty()) {
throw new RuntimeException();
}
//2.获取项目部署路径
String realPath = request.getServletContext().getRealPath("/");
String webappsPath = realPath.substring(0,
realPath.indexOf("ssm_web"));
//3.获取原文件名
String fileName = file.getOriginalFilename();
//4.新文件名
String newFileName = System.currentTimeMillis() +
fileName.substring(fileName.lastIndexOf("."));
//5.上传文件
String uploadPath = webappsPath + "upload\\";
File filePath = new File(uploadPath, newFileName);
//如果目录不存在就创建目录
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
System.out.println("创建目录: " + filePath);
}
file.transferTo(filePath);
//6.将文件名和文件路径返回
Map map = new HashMap<>();
map.put("fileName", newFileName);
map.put("filePath", LOCAL_URL + "/upload/" + newFileName);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
6.新建&修改广告(自行完成)
6.1 需求分析
新建需求:点击提交按钮,将页面内容保存到数据库
修改需求:点击编辑按钮,由前端实现数据回显,在回显页面进行数据修改,将修改后值更新到数据库中
6.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
void savePromotionAd(PromotionAd promotionAd);
void updatePromotionAd(PromotionAd promotionAd);
}
<?xml version="1.0" encoding="UTF-8" ?>
INSERT INTO promotion_ad VALUES(NULL,#{name},#{spaceId},#{keyword},#{htmlContent},#{text},#{link},
#{startTime},#{endTime},#{createTime},#{updateTime},#{status},#{priority},#{img});
update promotion_ad
name = #{name},
spaceId = #{spaceId},
link=#{link},
status=#{status},
img=#{img},
text=#{text},
startTime=#{startTime},
endTime=#{endTime},
updateTime=#{updateTime},
id = #{id}
Service层:PromotionAdService
public interface PromotionAdService {
void savePromotionAd(PromotionAd promotionAd);
void updatePromotionAd(PromotionAd promotionAd);
}
@Service
public class PromotionAdServiceImpl implements PromotionAdService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public void savePromotionAd(PromotionAd promotionAd) {
adMapper.savePromotionAd(promotionAd);
}
@Override
public void updatePromotionAd(PromotionAd promotionAd) {
adMapper.updatePromotionAd(promotionAd);
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
新增或更新广告位置
*/
@RequestMapping("/saveOrUpdatePromotionAd")
public ResponseResult saveOrUpdatePromotionAd(@RequestBody PromotionAd
promotionAd) {
try {
if (promotionAd.getId() == null) {
Date date = new Date();
promotionAd.setCreateTime(date);
promotionAd.setUpdateTime(date);
adService.savePromotionAd(promotionAd);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
null);
return result;
} else {
Date date = new Date();
promotionAd.setUpdateTime(date);
adService.updatePromotionAd(promotionAd);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
7.回显广告信息(自行完成)
7.1 需求分析
需求:点击编辑按钮,进行广告位名称回显
7.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
/**
* 根据id查询广告信息
* */
PromotionAd findPromotionAdById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:PromotionAdService
public interface PromotionAdService {
/*
回显广告信息
*/
PromotionAd findPromotionAdById(int id);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public PromotionAd findPromotionAdById(int id) {
PromotionAd promotionAd = adMapper.findPromotionAdById(id);
return promotionAd;
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/**
* 根据id回显 广告数据
* */
@RequestMapping("/findPromotionAdById")
public ResponseResult findPromotionAdById(@RequestParam int id){
try {
PromotionAd promotionAd = adService.findPromotionAdById(id);
ResponseResult result = new ResponseResult(true,200,"响应成
功",promotionAd);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
8.广告状态上下线
8.1 需求分析
需求:点击按钮,实现状态的动态上下线
8.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionAdMapper {
void updatePromotionAdStatus(PromotionAd promotionAd);
}
<?xml version="1.0" encoding="UTF-8" ?>
UPDATE promotion_ad SET STATUS = #{status} ,updatetime = #{updateTime} WHERE id = #{id}
Service层:PromotionAdService
public interface PromotionSpaceService {
void updatePromotionAdStatus(int id, int status);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public void updatePromotionAdStatus(int id, int status) {
PromotionAd promotionAd = new PromotionAd();
promotionAd.setId(id);
promotionAd.setStatus(status);
promotionAd.setUpdateTime(new Date());
adMapper.updatePromotionAdStatus(promotionAd);
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
广告位置上下线
*/
@RequestMapping("/updatePromotionAdStatus")
public ResponseResult updateCourseStatus(@RequestParam int id, @RequestParam
int status) {
try {
//执行修改操作
if (status == 1) {
adService.updatePromotionAdStatus(id, status);
} else {
adService.updatePromotionAdStatus(id, 0);
}
//保存修改后的状态,并返回
Map map = new HashMap<>();
map.put("status", status);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
任务三:用户模块
一 用户模块功能分析
在任务二中,再来完成拉勾教育后台管理系统的用户管理模块, 广告管理模块包含了用户分页&条件查询、用户状态设置,(登陆、权限控制)等接口的编写
1.1 用户模块
- 实现以下功能:
- 登陆(权限模块)
- 权限控制(权限模块)
- 用户分页&条件查询
- 用户状态设置
- 分配角色(权限模块)
二 用户管理模块表设计
2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
2.2 表关系介绍
1.ER图
三 用户管理模块接口实现
1.用户分页&条件查询
1.1 需求分析
需求:实现多条件分页组合查询
2.2 查看接口文档,进行编码
查看接口文档
UserVo
public class UserVo {
private Integer currentPage;
private Integer pageSize;
private String username;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startCreateTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endCreateTime;
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getStartCreateTime() {
return startCreateTime;
}
public void setStartCreateTime(Date startCreateTime) {
this.startCreateTime = startCreateTime;
}
public Date getEndCreateTime() {
return endCreateTime;
}
public void setEndCreateTime(Date endCreateTime) {
this.endCreateTime = endCreateTime;
}
}
Dao层:UserMapper
public interface UserMapper {
/*
查询所有用户
*/
public List findAllUserByPage(UserVo userVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:UserService
public interface UserService {
/*
查询所有用户
*/
public PageInfo findAllUserByPage(UserVo userVo);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public PageInfo findAllUserByPage(UserVo userVo) {
// 使用pageHelper
PageHelper.startPage(userVo.getCurrentPage(),userVo.getPageSize());
List allUser = userMapper.findAllUser(userVo);
PageInfo pageInfo = new PageInfo(allUser);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
return pageInfo;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findAllUserByPage")
public ResponseResult findAllUserByPage(@RequestBody UserVo userVo){
PageInfo pageInfo = userService.findAllUserByPage(userVo);
ResponseResult responseResult = new ResponseResult(true,200,"响应成功",pageInfo);
List list = pageInfo.getList();
System.out.println(list);
return responseResult;
}
}
Postman测试接口
2.用户状态设置(自行完成)
2.1 需求分析
点击禁用,实现用户的状态变更
用户状态:ENABLE能登录,DISABLE不能登录
2.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 修改用户状态
* */
public void updateUserStatus(@Param("id") int id,@Param("status") String
status);
}
<?xml version="1.0" encoding="UTF-8" ?>
UPDATE USER SET STATUS = #{status} where id = #{id};
Service层:UserService
public interface UserService {
/*
* 修改用户状态
* */
public void updateUserStatus(int id, String status);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void updateUserStatus(int id, String status) {
userMapper.updateUserStatus(id,status);
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 修改用户状态
* ENABLE能登录,DISABLE不能登录
* */
@RequestMapping("/updateUserStatus")
public ResponseResult updateUserStatus(@RequestParam int id ,@RequestParam
String status){
if("ENABLE".equalsIgnoreCase(status)){
status = "DISABLE";
}else{
status = "ENABLE";
}
userService.updateUserStatus(id,status);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",status);
return responseResult;
}
}
Postman测试接口
任务四:权限模块
一 权限概念介绍
权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做
? 认证: 验证用户名密码是否正确的过程
? 授权: 对用户所能访问的资源进行控制(动态显示菜单、url级别的权限控制)
为什么要实现权限系统
首先系统需要进行登陆才能访问
其次不同登陆用户要有不同的权利,而且要有不同的菜单(例如财务经理针对系统中财务相关模块进行操作,人事经理针对系统中人事模块进行操作)
权限控制基本原理
1.ACL(Access Control Lists,缩写ACL)
ACL是最早也是最基本的一种访问控制机制,它的原理非常简单:每一项资源,都配有一个列表,这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图访问这项资源时,会首先检查这个列表中是否有关于当前用户的访问权限,从而确定当前用户可否执行相应的操作。总得来说,ACL是一种面向资源的访问控制模型,它的机制是围绕“资源”展开的。
2.基于角色的访问控制RBAC(Role-Based Access Control)
RBAC是把用户按角色进行归类,通过用户的角色来确定用户能否针对某项资源进行某项操作。
RBAC相对于ACL最大的优势就是它简化了用户与权限的管理,通过对用户进行分类,使得角色与权限关联起来,而用户与权限变成了间接关联。RBAC模型使得访问控制,特别是对用户的授权管理变得非常简单和易于维护,因此有广泛的应用
规则一:每个登陆的用户,可以有多个角色;
规则二:每个角色又可以拥有多个权限(包含菜单和资源);
二 权限模块功能分析
权限模块主要细分为角色模块、菜单模块、资源模块,将针对细分的三个模块进行具体功能实现,同时会完成用户登陆、用户关联角色及动态菜单显示
2.1 权限模块管理
- 实现以下功能:
- 角色列表&条件查询(角色模块)
- 分配菜单(角色模块)
- 删除角色(角色模块)
- 菜单列表查询(菜单模块)
- 查询菜单信息回显(菜单模块)
- 资源分页&多条件查询(资源模块)
- 用户登陆(用户模块)
- 动态菜单展示(权限模块)
- 用户关联角色(用户模块)
三 权限管理模块表设计
3.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
3.2 表关系介绍
1.ER图
2.数据实体描述
2.1 菜单表(menu)
2.2 资源类表(resource_category)
2.3 资源表(resource)
2.4 角色表(roles)
2.5 用户-角色关系表(user_role_relation)
2.6 角色-菜单关系表(role_menu_relation)
2.7 角色-资源关系表(role_resource_relation)
四 权限管理(角色模块)接口实现
1.角色列表查询&条件查询
1.1 需求分析
需求:点击角色列表按钮进行角色列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:Role
public class Role {
private Integer id;
private String code;
private String name;
private String description;
private Date createdTime;
private Date updatedTime;
private String createdBy;
private String updatedBy;
//getter/setter...
}
Dao层:RoleMapper
public interface RoleMapper {
/*
查询角色列表(条件)
*/
public List findAllRole(Role role);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:RoleService
public interface RoleService {
public List findAllRole(Role role);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public List findAllRole(Role role) {
List allRole = roleMapper.findAllRole(role);
return allRole;
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
@RequestMapping("/findAllRole")
public ResponseResult findAllUserByPage(@RequestBody Role role){
List allRole = roleService.findAllRole(role);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allRole);
return responseResult;
}
}
Postman测试接口
2.分配菜单
2.1 需求分析
需求:点击分配菜单,回显可选择菜单信息,并回显选中状态
2.2 接口1 查询所有菜单列表
查看接口文档
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询全部的父子菜单信息
* */
public List
Service层:MenuService
public interface MenuService {
public List
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private MenuService menuService;
/*
查询所有菜单信息
*/
@RequestMapping("/findAllMenu")
public ResponseResult findAllMenu(){
//-1 表示查询所有菜单数据
List menuList = menuService.findSubMenuListByPid(-1);
Map map = new HashMap<>();
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
Postman测试接口
2.3 接口2 根据角色ID查询关联菜单ID
Dao层:RoleMapperr
public interface RoleMapper {
/*
根据角色ID查询菜单信息
*/
List findMenuByRoleId(Integer roleId);
}
Service层:RoleService
public interface RoleService {
/**
* 根据ID查询角色关联菜单
* */
List findMenuByRoleId(Integer roleId);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public List findMenuByRoleId(Integer roleId) {
List list = roleMapper.findMenuByRoleId(roleId);
return list;
}
}
Web层:RoleController
/**
* 查询角色关联菜单列表ID
* */
@RequestMapping("/findMenuByRoleId")
public ResponseResult findMenuByRoleId(Integer roleId){
List menuList = roleService.findMenuByRoleId(roleId);
ResponseResult result = new ResponseResult(true,200,"响应成功",menuList);
return result;
}
Postman测试接口
2.4 接口3 为角色分配菜单列表
Dao层:RoleMapper
public interface RoleMapper {
/*
角色菜单关联
*/
void RoleContextMenu(Role_menu_relation role_menu_relation);
}
<?xml version="1.0" encoding="UTF-8" ?>
delete from role_menu_relation where role_id = #{id}
insert into role_menu_relation values(null,#{menuId},#{roleId},#
{createdTime},#{updatedTime},#{createdBy},#{updatedby})
Service层:RoleService
public interface RoleService {
void RoleContextMenu(RoleMenuVo roleMenuVo);
}
@Service
public class RoleServiceImpl implements RoleService {
@Override
public void RoleContextMenu(RoleMenuVo roleMenuVo) {
// 清空中间表
roleMapper.deleteRoleContextMenu(roleMenuVo.getRoleId());
for (Integer mid : roleMenuVo.getMenuIdList()) {
Role_menu_relation role_menu_relation = new Role_menu_relation();
role_menu_relation.setRoleId(roleMenuVo.getRoleId());
role_menu_relation.setMenuId(mid);
role_menu_relation.setCreatedTime(new Date());
role_menu_relation.setUpdatedTime(new Date());
role_menu_relation.setCreatedBy("system");
role_menu_relation.setUpdatedby("system");
roleMapper.RoleContextMenu(role_menu_relation);
}
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
/*
用户关联菜单 {roleId: 4, menuIdList: [19, 20, 7, 8, 9, 15, 16, 17, 18]}
*/
@RequestMapping("/RoleContextMenu")
public ResponseResult RoleContextMenu(@RequestBody RoleMenuVo roleMenuVo){
roleService.RoleContextMenu(roleMenuVo);
ResponseResult result = new ResponseResult(true,200,"响应成功","");
return result;
}
}
Postman测试接口
3.删除角色
3.1 需求分析
需求:点击删除按钮,将选中的角色信息删除
3.2 查看接口文档,进行编码
查看接口文档
Dao层:RoleMapper
public interface RoleMapper {
/*
删除角色
*/
void deleteRole(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
delete from roles where id = #{id}
Service层:RoleService
public interface RoleService {
void deleteRole(Integer id);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public void deleteRole(Integer id) {
// 清空中间表
roleMapper.deleteRoleContextMenu(id);
roleMapper.deleteRole(id);
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
/**
* 删除角色
* */
@RequestMapping("/deleteRole")
public ResponseResult deleteRole(Integer id){
roleService.deleteRole(id);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功","");
return responseResult;
}
}
Postman测试接口
五 权限管理(菜单模块)接口实现
1.菜单列表查询
1.1 需求分析
需求:点击菜单列表,对菜单信息进行列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:Menu
public class Menu {
//主键id
private Integer id;
//父菜单id
private int parentId;
//菜单路径
private String href;
//菜单图标
private String icon;
//菜单名称
private String name;
//描述
private String description;
//排序号
private int orderNum;
//是否展示
private int shown;
//菜单层级,从0开始
private int level;
//创建时间
private Date createdTime;
//更新时间
private Date updatedTime;
//创建人
private String createdBy;
//更新人
private String updatedBy;
// getter/setter..
}
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询菜单列表
* */
public List findAllMenu();
}
Service层:MenuService
public interface MenuService {
public List findAllMenu();
}
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List findAllMenu() {
List list = menuMapper.findAllMenu();
return list;
}
Web层:MenuController
@RestController
@RequestMapping("/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
* 查询菜单列表信息
* */
@RequestMapping("/findAllMenu")
public ResponseResult findAllMenu(){
List list = menuService.findAllMenu();
ResponseResult result = new ResponseResult(true,200,"响应成功",list);
return result;
}
}
Postman测试接口
2.查询菜单信息(回显)
2.1 需求分析
需求:点击添加菜单按钮,跳转到添加菜单页面,回显当前添加菜单可以选择的上级菜单信息
2.2 查看接口文档,进行编码
查看接口文档
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询全部的父子菜单信息
* */
public List findSubMenuListByPid(int pid);
}
Service层:MenuService
public interface MenuService {
public List findSubMenuListByPid(int pid);
}
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List findSubMenuListByPid(int pid) {
List menuList = menuMapper.findSubMenuListByPid(pid);
return menuList;
}
}
Web层:MenuController
@RestController
@RequestMapping("/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
* 回显菜单信息(包括父子菜单的全部信息)
* */
@RequestMapping("/findMenuInfoById")
public ResponseResult findMenuInfoById(@RequestParam int id){
if(id == -1){
//添加操作 回显不需要查询 menu信息
List menuList = menuService.findSubMenuListByPid(-1);
//封装数据
Map map = new HashMap<>();
map.put("menuInfo",null);
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}else{
//修改操作 回显
Menu menu = menuService.findMenuById(id);
List menuList = menuService.findSubMenuListByPid(-1);
Map map = new HashMap<>();
map.put("menuInfo",menu);
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
}
Postman测试接口
六 权限管理(资源模块)接口实现
1.资源分页&多条件查询
1.1 需求分析
需求:资源列表及多条件组合查询
1.2 查看接口文档,进行编码
查看接口文档
Dao层:ResourceMapper
public interface ResourceMapper {
public List findAllResource(ResourceVo resourceVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:ResourceService
public interface ResourceService {
public PageInfo findAllResource(ResourceVo resourceVo);
}
@Service
public class ResourceServiceImpl implements ResourceService {
@Autowired
private ResourceMapper resourceMapper;
@Override
public PageInfo findAllResource(ResourceVo resourceVo) {
PageHelper.startPage(resourceVo.getCurrentPage(),resourceVo.getPageSize());
List allResource = resourceMapper.findAllResource(resourceVo);
PageInfo adPageInfo = new PageInfo(allResource);
return adPageInfo;
}
Web层:ResourceController
@RestController
@RequestMapping("/resource")
public class ResourceController {
@Autowired
private ResourceService resourceService;
/**
* 分页与条件查询
* */
@RequestMapping("/findAllResource")
public ResponseResult findAllResource(@RequestBody ResourceVo resourceVo){
PageInfo allResource =
resourceService.findAllResource(resourceVo);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allResource);
return responseResult;
}
}
Postman测试接口
七 登陆及动态菜单展示
1.登陆
1.1 需求分析
需求:输入用户名密码,点击登陆按钮,进行用户登陆
加密算法MD5介绍
1、什么是MD5
MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。
2、MD5有哪些特点
MD5加密的特点主要有以下几点:
1、针对不同长度待加密的数据、字符串等等,其都可以返回一个固定长度的MD5加密字符串。(通常32位的16进制字符串)
2、其加密过程几乎不可逆,除非维护一个庞大的Key-Value数据库来进行碰撞破解,否则几乎无法解开。
3、运算简便,且可实现方式多样,通过一定的处理方式也可以避免碰撞算法的破解。(加盐:随机字符串)
4、对于一个固定的字符串。数字等等,MD5加密后的字符串是固定的,也就是说不管MD5加密多少次,都是同样的结果。
3、Java代码中如何使用MD5
(1)添加依赖
org.apache.commons
commons-lang3
3.3.2
commons-codec
commons-codec
1.3
(2)添加工具类
public class Md5 {
public final static String md5key = "Ms2";
/**
* MD5方法
* @param text 明文
* @param key 密钥
* @return 密文
* @throws Exception
*/
public static String md5(String text, String key) throws Exception {
//加密后的字符串
String encodeStr= DigestUtils.md5Hex(text+key);
System.out.println("MD5加密后的字符串为:encodeStr="+encodeStr);
return encodeStr;
}
/**
* MD5验证方法
* @param text 明文
* @param key 密钥
* @param md5 密文
* @return true/false
* @throws Exception
*/
public static boolean verify(String text, String key, String md5) throws
Exception {
//根据传入的密钥进行验证
String md5Text = md5(text, key);
if(md5Text.equalsIgnoreCase(md5))
{
System.out.println("MD5验证通过");
return true;
}
return false;
}
public static void main(String[] args) throws Exception {
// 注册 用户名:tom 密码 123456
// 添加用户的时候,要进行加密
String lagou = Md5.md5("123456", "lagou");
System.out.println(lagou);
// 登陆 用户名 tom 123456 select * from user where username = tom and
password = 123456
// 1.根据用户名进行查询 f00485441dfb815c75a13f3c3389c0b9
boolean verify = Md5.verify("123456", "lagou",
"f00485441dfb815c75a13f3c3389c0b9");
System.out.println(verify);
}
}
1.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/*
用户登陆
*/
public User login(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:UserService
public interface UserService {
/*
用户登录
*/
public User login(User user);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 用户登录
* */
@Override
public User login(User user) throws Exception {
User user2 = userMapper.login(user);
if(user2 != null &&
Md5.verify(user.getPassword(),"lagou",user2.getPassword())){
return user2;
}else {
return null;
}
}
}
Web层:UserControlle
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 用户登录
* */
@RequestMapping("/login")
public ResponseResult login(User user, HttpServletRequest request) throws
Exception {
User login = userService.login(user);
ResponseResult result = null;
if(login !=null ){
//保存access_token
Map map = new HashMap<>();
String access_token = UUID.randomUUID().toString();
map.put("access_token", access_token);
map.put("user_id",login.getId());
HttpSession session = request.getSession();
session.setAttribute("user_id",login.getId());
session.setAttribute("access_token",access_token);
result = new ResponseResult(true,1,"响应成功",map);
}else{
result = new ResponseResult(true,1,"用户名密码错误",null);
}
return result;
}
}
Postman测试接口
2.分配角色(回显)
2.1 需求分析
需求:点击分配角色,将该用户所具有的角色信息进行回显
2.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 根据ID查询用户当前角色
* */
public List findUserRelationRoleById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:UserService
public interface UserService {
/**
* 获取用户拥有的角色
* */
public List findUserRelationRoleById(int id) ;
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 获取用户拥有的角色
* */
@Override
public List findUserRelationRoleById(int id) {
List roleList = userMapper.findUserRelationRoleById(id);
return roleList;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
获取用户拥有的角色
*/
@RequestMapping("/findUserRoleById")
public ResponseResult findUserRoleById(int id){
List roleList = userService.findUserRelationRoleById(id);
return new ResponseResult(true,200,"分配角色回显成功",roleList);
}
}
Postman测试接口
3分配角色
3.1 需求分析
需求:点击确定按钮,真正实现用户角色关联
3.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/*
根据用户ID清空中间表
*/
void deleteUserContextRole(Integer userId);
/*
分配角色
*/
void userContextRole(User_Role_relation user_role_relation);
}
<?xml version="1.0" encoding="UTF-8" ?>
delete from user_role_relation where user_id = #{userid}
insert into user_role_relation values(null,#{userId},#{roleId},#{createdTime},#{updatedTime},
#{createdBy},#{updatedby})
Service层:UserService
public interface UserService {
/*
用户关联角色
*/
void userContextRole(UserVo userVo);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/*
用户关联角色
*/
@Override
public void userContextRole(UserVo userVo) {
// 根据用户ID清空中间表的关联关系
userMapper.deleteUserContextRole(userVo.getUserId());
// 向中间表添加记录
for (Integer roleid : userVo.getRoleIdList()) {
User_Role_relation user_role_relation = new User_Role_relation();
user_role_relation.setUserId(userVo.getUserId());
user_role_relation.setRoleId(roleid);
Date date = new Date();
user_role_relation.setCreatedTime(date);
user_role_relation.setUpdatedTime(date);
user_role_relation.setCreatedBy("system");
user_role_relation.setUpdatedby("system");
userMapper.userContextRole(user_role_relation);
}
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
分配角色
*/
@RequestMapping("/userContextRole")
public ResponseResult userContextRole(@RequestBody UserVo userVo){
userService.userContextRole(userVo);
return new ResponseResult(true,200,"分配角色成功",null);
}
}
Postman测试接口
4.动态菜单显示
4.1 需求分析
需求:登陆成功后,根据用户所拥有的权限信息,进行菜单列表动态展示
4.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 根据ID查询用户当前角色
* */
public List findUserRelationRoleById(int id);
/**
* 根据角色id,查询角色拥有的顶级菜单信息
* */
public List findParentMenuByRoleId(List ids);
/**
* 根据PID 查询子菜单信息
* */
public List findSubMenuByPid(int pid);
/**
* 获取用户拥有的资源权限信息
* */
public List findResourceByRoleId(List ids);
}
<?xml version="1.0" encoding="UTF-8" ?>
Service层:UserService
public interface UserService {
/*
* 获取用户权限
* */
ResponseResult getUserPermissions(Integer id);
}
@Service
public class UserServiceImpl implements PromotionSpaceService {
@Autowired
private UserMapper userMapper;
@Override
public ResponseResult getUserPermissions(Integer id) {
//1.获取当前用户拥有的角色
List roleList = userMapper.findUserRelationRoleById(id);
//2.获取角色ID,保存到 list
List list = new ArrayList<>();
for (Role role : roleList) {
list.add(role.getId());
}
//3.根据角色id查询 父菜单
List parentMenu = userMapper.findParentMenuByRoleId(list);
//4.封装父菜单下的子菜单
for (Menu menu : parentMenu) {
List subMenu = userMapper.findSubMenuByPid(menu.getId());
menu.setSubMenuList(subMenu);
}
//5.获取资源权限
List resourceList = userMapper.findResourceByRoleId(list);
//6.封装数据
Map map = new HashMap<>();
map.put("menuList",parentMenu); //menuList: 菜单权限数据
map.put("resourceList",resourceList);//resourceList: 资源权限数据
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 获取用户权限
* */
@RequestMapping("/getUserPermissions")
public ResponseResult getUserPermissions(HttpServletRequest request){
//获取请求头中的 token
String token = request.getHeader("Authorization");
//获取session中的access_token
HttpSession session = request.getSession();
String access_token = (String)session.getAttribute("access_token");
//判断
if(token.equals(access_token)){
int user_id = (Integer)session.getAttribute("user_id");
ResponseResult result = userService.getUserPermissions(user_id);
return result;
}else{
ResponseResult result = new ResponseResult(false,400,"获取失败","");
return result;
}
}
}
Postman测试接口