├── .gitignore ├── README.md ├── pom.xml ├── src ├── main │ ├── java │ │ └── com │ │ │ └── ironmanjay │ │ │ └── springboot │ │ │ ├── SpringbootApplication.java │ │ │ ├── common │ │ │ ├── Constants.java │ │ │ ├── Result.java │ │ │ └── RoleEnum.java │ │ │ ├── config │ │ │ ├── AuthAccess.java │ │ │ ├── CorsConfig.java │ │ │ ├── Interceptor │ │ │ │ └── JwtInterceptor.java │ │ │ ├── InterceptorConfig.java │ │ │ ├── MybatisPlusConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ ├── ArticleController.java │ │ │ ├── CommentController.java │ │ │ ├── CourseController.java │ │ │ ├── EchartsController.java │ │ │ ├── FileController.java │ │ │ ├── MenuController.java │ │ │ ├── RoleController.java │ │ │ ├── UserController.java │ │ │ └── dto │ │ │ │ ├── UserDTO.java │ │ │ │ └── UserPasswordDTO.java │ │ │ ├── entity │ │ │ ├── Article.java │ │ │ ├── Comment.java │ │ │ ├── Course.java │ │ │ ├── Dict.java │ │ │ ├── Files.java │ │ │ ├── Menu.java │ │ │ ├── Role.java │ │ │ ├── RoleMenu.java │ │ │ └── User.java │ │ │ ├── exception │ │ │ ├── GlobalExceptionHandler.java │ │ │ └── ServiceException.java │ │ │ ├── mapper │ │ │ ├── ArticleMapper.java │ │ │ ├── CommentMapper.java │ │ │ ├── CourseMapper.java │ │ │ ├── DictMapper.java │ │ │ ├── FileMapper.java │ │ │ ├── MenuMapper.java │ │ │ ├── RoleMapper.java │ │ │ ├── RoleMenuMapper.java │ │ │ └── UserMapper.java │ │ │ ├── service │ │ │ ├── IArticleService.java │ │ │ ├── ICommentService.java │ │ │ ├── ICourseService.java │ │ │ ├── IMenuService.java │ │ │ ├── IRoleService.java │ │ │ ├── IUserService.java │ │ │ └── impl │ │ │ │ ├── ArticleServiceImpl.java │ │ │ │ ├── CommentServiceImpl.java │ │ │ │ ├── CourseServiceImpl.java │ │ │ │ ├── MenuServiceImpl.java │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils │ │ │ ├── CodeGenerator.java │ │ │ └── TokenUtils.java │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── files │ │ ├── 062e1e4d241e4abfa6f3d320f4c09a9d.png │ │ ├── 132317f9756d4807a30df821c2ce3a83.mp4 │ │ ├── 2007e9c9bdfe447c825056a139bec221.png │ │ ├── 2a827fa7d68640b1b21494327daa1e56.png │ │ ├── bfd885550582475f9fe33d92ff70a070.png │ │ ├── c349b95aec2b464dbd826b94648ba1a4.png │ │ └── fcc27fb1e8864a77ad83d4dccefc55b2.png │ │ ├── mapper │ │ ├── ArticleMapper.xml │ │ ├── CommentMapper.xml │ │ ├── CourseMapper.xml │ │ ├── MenuMapper.xml │ │ ├── RoleMapper.xml │ │ └── UserMapper.xml │ │ └── templates │ │ └── controller.java.vm └── test │ └── java │ └── com │ └── ironmanjay │ └── springboot │ └── SpringbootApplicationTests.java └── vue ├── .gitignore ├── README.md ├── babel.config.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── 404.png │ ├── gloable.css │ ├── logo.png │ └── logoSub.png ├── components │ ├── Aside.vue │ ├── Header.vue │ └── HelloWorld.vue ├── main.js ├── router │ └── index.js ├── store │ └── store.js ├── utils │ └── request.js └── views │ ├── 404.vue │ ├── About.vue │ ├── Article.vue │ ├── Course.vue │ ├── File.vue │ ├── Home.vue │ ├── Login.vue │ ├── Manage.vue │ ├── Map.vue │ ├── Menu.vue │ ├── Password.vue │ ├── Person.vue │ ├── Register.vue │ ├── Role.vue │ ├── User.vue │ └── front │ ├── Article.vue │ ├── ArticleDetail.vue │ ├── Front.vue │ ├── Home.vue │ ├── Video.vue │ └── VideoDetail.vue └── vue.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目简介 2 |   本项目基于SpringBoot搭建后台,使用Vue搭建前端服务。完成了Vue2安装并集成ElementUI、Vue2前端主体框架搭建、SpringBoot后端初始框架搭建、SpringBoot集成Mybatis、SpringBoot实现增删改查、SpringBoot实现分页查询、SpringBoot实现集成Mybatis-Plus和SwaggerUI、Vue实现增删改查、SpringBoot实现代码生成器、Vue使用路由、SpringBoot和Vue实现导入导出、SpringBoot和Vue实现用户登录注册与异常处理、SpringBoot和Vue实现用户个人信息展示与保存与集成JWT、SpringBoot和Vue实现文件上传与下载、SpringBoot和Vue整合ECharts、权限菜单讲解、SpringBoot实现1对1、1对多、多对多关联查询、用户前台页面设计与实现、SpringBoot集成Redis实现缓存、高德地图集成演示、Vue集成视频播放组件、Vue集成Markdown和多级评论等功能。从功能的实现难度以及可应用性出发,此项目完全可以作为本科毕业设计以及简历项目使用。 3 |
4 | 5 | # 项目开发软件环境 6 | - Windows 11 7 | - Idea 2019.3 8 | - Maven 3.3.9 9 | - Postman 10 | - jdk 1.8 11 | - springboot 2.7.1 12 | - mybatis-plus 3.5.1 13 | - mybatis 2.2.2 14 | - mysql 5.7 15 | - element-ui 2.15.9 16 | - vue 2.6.14 17 | - vue-router 3.5.1 18 | - vuex 3.6.2 19 | - echarts 5.3.3 20 | - axios 0.27.2 21 |
22 | 23 | # 项目开发硬件环境 24 | - CPU:Intel® Core™ i7-8750H CPU @ 2.20GHz 2.20 GHz 25 | - RAM:24GB 26 | - GPU:NVIDIA GeForce GTX 1060 27 |
28 | 29 | # 一、功能图片演示 30 | ## 1.1 基本功能 31 | ### 1.1.1 用户登录 32 | ![请添加图片描述](https://img-blog.csdnimg.cn/37ef90abc9ef4ba38a8bef8497fce8a8.png#pic_center) 33 | ### 1.1.2 用户注册 34 | ![请添加图片描述](https://img-blog.csdnimg.cn/62233b3f809542d2a9f8377ca158e25b.png#pic_center) 35 | ## 1.2 系统后台功能 36 | ### 1.2.1 系统后台主页 37 | ![请添加图片描述](https://img-blog.csdnimg.cn/47dedd87cf3c44fa816f8347ee67f838.png#pic_center) 38 | ### 1.2.2 用户管理 39 | ![请添加图片描述](https://img-blog.csdnimg.cn/4109dfa1961e41a796a959e126a59cf6.png#pic_center) 40 | ### 1.2.3 选课信息 41 | ![请添加图片描述](https://img-blog.csdnimg.cn/73da1230a5db4c1a85a86cc338f022d7.png#pic_center) 42 | ### 1.2.4 修改密码 43 | ![请添加图片描述](https://img-blog.csdnimg.cn/ab64a70ce4c04d0b87b99876dea03b7b.png#pic_center) 44 | ### 1.2.5 文章管理 45 | ![请添加图片描述](https://img-blog.csdnimg.cn/a380d3ecc7674e3c8aac8bc4f17426f1.png#pic_center) 46 | ### 1.2.6 查看文章内容 47 | ![请添加图片描述](https://img-blog.csdnimg.cn/830dd7eb91a64abf9b0eb436d193447f.png#pic_center) 48 | 49 | ### 1.2.7 编写MarkDown文章 50 | ![请添加图片描述](https://img-blog.csdnimg.cn/f6043208d4fa424996cec8b74f05ff9b.png#pic_center) 51 | ### 1.2.8 文件管理 52 | ![请添加图片描述](https://img-blog.csdnimg.cn/c4610021914c42f3b0f3f7fc8014adad.png) 53 | ### 1.2.9 授课信息 54 | ![请添加图片描述](https://img-blog.csdnimg.cn/7d4fc0206df2483fb53e56ff3aa02b96.png) 55 | ### 1.2.10 课程管理 56 | ![请添加图片描述](https://img-blog.csdnimg.cn/d18eec63507d48c3884874802d56d7e3.png) 57 | ### 1.2.11 角色管理 58 | ![请添加图片描述](https://img-blog.csdnimg.cn/01bfc5914223468eb8e27c6b4c034512.png) 59 | ### 2.12 个人信息 60 | ![请添加图片描述](https://img-blog.csdnimg.cn/6125838d83d6468c9a609d485224d872.png) 61 | ### 1.2.13 高德地图 62 | ![请添加图片描述](https://img-blog.csdnimg.cn/984f429551f9417a9a343ddeeb864ea1.png) 63 | ### 1.2.14 菜单管理 64 | ![请添加图片描述](https://img-blog.csdnimg.cn/e0a7a3353edb439385b6a9018a62bacc.png) 65 | ### 1.2.15 菜单分配 66 | ![请添加图片描述](https://img-blog.csdnimg.cn/0fbc32c16ca3424a9d96c63e088a7d09.png) 67 | ## 1.3 系统前台功能 68 | ### 1.3.1 系统前台主页 69 | ![请添加图片描述](https://img-blog.csdnimg.cn/0b44c856e5bb49049997852cf6fb4ef7.png) 70 | ### 1.3.2 视频播放列表 71 | ![请添加图片描述](https://img-blog.csdnimg.cn/c7e8268bf87c4e759e0d67b778e13d35.png) 72 | ### 1.3.3 视频播放内容展示 73 | ![请添加图片描述](https://img-blog.csdnimg.cn/9ed11c9dcdfc4a6f83a09598e6972402.png) 74 | ### 1.3.4 文章列表 75 | ![请添加图片描述](https://img-blog.csdnimg.cn/93374e5e9a08488280e1d76fb9d9a6ba.png) 76 | ### 1.3.5 文章内容展示 77 | ![请添加图片描述](https://img-blog.csdnimg.cn/35064232ad194dda8962fe4ab8914192.png) 78 | ### 1.3.6 用户多级评论 79 | ![请添加图片描述](https://img-blog.csdnimg.cn/6efd630eb2394b8bbe5bef7648635469.png) 80 | # 二、功能视频演示 81 | 82 | 功能视频演示见如下链接:[基于SpringBoot和Vue的后台管理系统项目视频演示](https://live.csdn.net/v/247792) 83 | 84 | # 三、项目启动 85 | ## 3.1 SpringBoot项目启动配置 86 | ![请添加图片描述](https://img-blog.csdnimg.cn/f6c0eeef11ea409b8d12aea7e542d4c1.png) 87 | 88 | ## 3.2 进入Vue项目目录 89 | ![请添加图片描述](https://img-blog.csdnimg.cn/1cc2d8b3cdae49daadfc8c9243896132.png) 90 | 91 | ## 3.3 启动SpringBoot 92 | ![请添加图片描述](https://img-blog.csdnimg.cn/6ab63242d8f548a38bb6907908c672d6.png) 93 | 94 | ## 3.4 启动Vue项目 95 | ![请添加图片描述](https://img-blog.csdnimg.cn/30dc0f881eb34681965a079ca0bd4616.png) 96 | 97 | ## 3.5 进入系统 98 | ![请添加图片描述](https://img-blog.csdnimg.cn/bd3e7d139d2b487b8ef26311ac5b74f3.png) 99 | 100 |
101 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.1 9 | 10 | 11 | com.IronmanJay 12 | springboot 13 | 0.0.1-SNAPSHOT 14 | springboot 15 | IronmanJay 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | org.mybatis.spring.boot 26 | mybatis-spring-boot-starter 27 | 2.2.2 28 | 29 | 30 | 31 | 32 | com.baomidou 33 | mybatis-plus-boot-starter 34 | 3.5.1 35 | 36 | 37 | 38 | 39 | io.springfox 40 | springfox-boot-starter 41 | 3.0.0 42 | 43 | 44 | 45 | 46 | mysql 47 | mysql-connector-java 48 | runtime 49 | 50 | 51 | org.projectlombok 52 | lombok 53 | true 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-test 58 | test 59 | 60 | 61 | 62 | 63 | com.baomidou 64 | mybatis-plus-generator 65 | 3.5.1 66 | 67 | 68 | org.apache.velocity 69 | velocity 70 | 1.7 71 | 72 | 73 | 74 | 75 | cn.hutool 76 | hutool-all 77 | 5.7.20 78 | 79 | 80 | org.apache.poi 81 | poi-ooxml 82 | 4.1.2 83 | 84 | 85 | 86 | 87 | com.auth0 88 | java-jwt 89 | 3.10.3 90 | 91 | 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-starter-data-redis 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-maven-plugin 105 | 106 | 107 | 108 | org.projectlombok 109 | lombok 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/SpringbootApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * IronmanJay 3 | * 2022/07/13 16:47 4 | */ 5 | 6 | package com.ironmanjay.springboot; 7 | 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | // 代表应用启动主体代码 12 | @SpringBootApplication 13 | public class SpringbootApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(SpringbootApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/common/Constants.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.common; 2 | 3 | public interface Constants { 4 | 5 | String CODE_200 = "200"; // 成功 6 | String CODE_500 = "500"; // 系统错误 7 | String CODE_401 = "401"; // 权限不足 8 | String CODE_400 = "400"; // 参数错误 9 | String CODE_600 = "600"; // 其他业务异常 10 | String DICT_TYPE_ICON = "icon"; // 图标类型 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/common/Result.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * 接口统一返回包装类 9 | */ 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Result { 14 | 15 | // 返回成功还是失败 16 | private String code; 17 | // 失败的原因 18 | private String msg; 19 | // 后台所需要携带的数据 20 | private Object data; 21 | 22 | /** 23 | * 无数据的成功请求 24 | * 25 | * @return 返回封装的结果 26 | */ 27 | public static Result success() { 28 | return new Result(Constants.CODE_200, "", null); 29 | } 30 | 31 | /** 32 | * 有数据的成功请求 33 | * 34 | * @param data 请求得到的数据 35 | * @return 返回封装的结果 36 | */ 37 | public static Result success(Object data) { 38 | return new Result(Constants.CODE_200, "", data); 39 | } 40 | 41 | /** 42 | * 请求错误 43 | * 44 | * @param code 错误标志码 45 | * @param msg 错误信息 46 | * @return 返回封装的结果 47 | */ 48 | public static Result error(String code, String msg) { 49 | return new Result(code, msg, null); 50 | } 51 | 52 | /** 53 | * 默认的请求错误 54 | * 55 | * @return 返回封装的结果 56 | */ 57 | public static Result error() { 58 | return new Result(Constants.CODE_500, "系统错误", null); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/common/RoleEnum.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.common; 2 | 3 | public enum RoleEnum { 4 | 5 | ROLE_ADMIN, ROLE_USER; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/AuthAccess.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Target({ElementType.METHOD}) 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Documented 8 | public @interface AuthAccess { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 | import org.springframework.web.filter.CorsFilter; 8 | 9 | /** 10 | * 解决前端跨域问题 11 | */ 12 | @Configuration 13 | public class CorsConfig { 14 | 15 | // 当前跨域请求最大有效时长。这里默认1天 16 | private static final long MAX_AGE = 24 * 60 * 60; 17 | 18 | @Bean 19 | public CorsFilter corsFilter() { 20 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 21 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 22 | corsConfiguration.addAllowedOrigin("http://localhost:8080"); // 1 设置访问源地址 23 | corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 24 | corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 25 | corsConfiguration.setMaxAge(MAX_AGE); 26 | source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置 27 | return new CorsFilter(source); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/Interceptor/JwtInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config.Interceptor; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.auth0.jwt.JWT; 5 | import com.auth0.jwt.JWTVerifier; 6 | import com.auth0.jwt.algorithms.Algorithm; 7 | import com.auth0.jwt.exceptions.JWTDecodeException; 8 | import com.auth0.jwt.exceptions.JWTVerificationException; 9 | import com.ironmanjay.springboot.common.Constants; 10 | import com.ironmanjay.springboot.config.AuthAccess; 11 | import com.ironmanjay.springboot.entity.User; 12 | import com.ironmanjay.springboot.exception.ServiceException; 13 | import com.ironmanjay.springboot.service.IUserService; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.web.method.HandlerMethod; 16 | import org.springframework.web.servlet.HandlerInterceptor; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpServletResponse; 20 | 21 | public class JwtInterceptor implements HandlerInterceptor { 22 | 23 | @Autowired 24 | private IUserService userService; 25 | 26 | @Override 27 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 28 | String token = request.getHeader("token"); 29 | // 如果不是映射到方法直接通过 30 | if (!(handler instanceof HandlerMethod)) { 31 | return true; 32 | } else { 33 | HandlerMethod h = (HandlerMethod) handler; 34 | AuthAccess authAccess = h.getMethodAnnotation(AuthAccess.class); 35 | if (authAccess != null) { 36 | return true; 37 | } 38 | } 39 | // 执行认证 40 | if (StrUtil.isBlank(token)) { 41 | throw new ServiceException(Constants.CODE_401, "无token,请重新登录"); 42 | } 43 | // 获取 token 中的 userId 44 | String userId; 45 | try { 46 | userId = JWT.decode(token).getAudience().get(0); 47 | } catch (JWTDecodeException j) { 48 | throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录"); 49 | } 50 | // 根据token中的userId查询数据库 51 | User user = userService.getById(userId); 52 | if (user == null) { 53 | throw new ServiceException(Constants.CODE_401, "用户不存在,请重新登录"); 54 | } 55 | // 用户密码加签验证token 56 | JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); 57 | try { 58 | jwtVerifier.verify(token); // 验证token 59 | } catch (JWTVerificationException e) { 60 | throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录"); 61 | } 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/InterceptorConfig.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config; 2 | 3 | import com.ironmanjay.springboot.config.Interceptor.JwtInterceptor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | @Configuration 10 | public class InterceptorConfig implements WebMvcConfigurer { 11 | 12 | @Override 13 | public void addInterceptors(InterceptorRegistry registry) { 14 | // 拦截所有请求,通过判断token是否合法来决定是否需要登录 15 | registry.addInterceptor(jwtInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login", "/user/register", "/**/export", "/**/import", "/file/**"); 16 | } 17 | 18 | @Bean 19 | public JwtInterceptor jwtInterceptor() { 20 | return new JwtInterceptor(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | // 配置注解 11 | @Configuration 12 | /** 13 | * 引入Mybatis-Plus分页插件 14 | */ 15 | @MapperScan("com.ironmanjay.springboot.mapper") 16 | public class MybatisPlusConfig { 17 | 18 | // 最新版 19 | @Bean 20 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 21 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 22 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 23 | return interceptor; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.oas.annotations.EnableOpenApi; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | 14 | @Configuration 15 | @EnableOpenApi 16 | public class SwaggerConfig { 17 | 18 | /** 19 | * 创建API应用 20 | * apiInfo() 增加API相关信息 21 | * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现, 22 | * 本例采用指定扫描的包路径来定义指定要建立API的目录。 23 | * 24 | * @return 25 | */ 26 | @Bean 27 | public Docket restApi() { 28 | return new Docket(DocumentationType.SWAGGER_2) 29 | .groupName("标准接口") 30 | .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0")) 31 | .useDefaultResponseMessages(true) 32 | .forCodeGeneration(false) 33 | .select() 34 | .apis(RequestHandlerSelectors.basePackage("com.ironmanjay.springboot.controller")) 35 | .paths(PathSelectors.any()) 36 | .build(); 37 | } 38 | 39 | /** 40 | * 创建该API的基本信息(这些基本信息会展现在文档页面中) 41 | * 访问地址:http://ip:port/swagger-ui.html 42 | * 43 | * @return 44 | */ 45 | private ApiInfo apiInfo(String title, String version) { 46 | return new ApiInfoBuilder() 47 | .title(title) 48 | .description("更多请关注: https://blog.csdn.net/IronmanJay?spm=1003.2020.3001.5343") 49 | .termsOfServiceUrl("https://blog.csdn.net/IronmanJay?spm=1003.2020.3001.5343") 50 | .contact(new Contact("IronmanJay", "https://blog.csdn.net/IronmanJay?spm=1003.2020.3001.5343", "1975686676@qq.com")) 51 | .version(version) 52 | .build(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/ArticleController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import cn.hutool.core.date.DateUtil; 5 | import cn.hutool.core.util.StrUtil; 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.ironmanjay.springboot.common.Result; 9 | import com.ironmanjay.springboot.entity.Article; 10 | import com.ironmanjay.springboot.service.IArticleService; 11 | import com.ironmanjay.springboot.utils.TokenUtils; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.List; 16 | 17 | /** 18 | *

19 | * 前端控制器 20 | *

21 | * 22 | * @author IronmanJay 23 | * @since 2022-10-18 24 | */ 25 | @RestController 26 | @RequestMapping("/article") 27 | public class ArticleController { 28 | 29 | @Resource 30 | private IArticleService articleService; 31 | 32 | // 新增或者更新 33 | @PostMapping 34 | public Result save(@RequestBody Article article) { 35 | // 新增 36 | if (article.getId() == null) { 37 | article.setTime(DateUtil.now()); // new Date() 38 | article.setUser(TokenUtils.getCurrentUser().getNickname()); 39 | } 40 | articleService.saveOrUpdate(article); 41 | return Result.success(); 42 | } 43 | 44 | @DeleteMapping("/{id}") 45 | public Result delete(@PathVariable Integer id) { 46 | articleService.removeById(id); 47 | return Result.success(); 48 | } 49 | 50 | @PostMapping("/del/batch") 51 | public Result deleteBatch(@RequestBody List ids) { 52 | articleService.removeByIds(ids); 53 | return Result.success(); 54 | } 55 | 56 | @GetMapping 57 | public Result findAll() { 58 | return Result.success(articleService.list()); 59 | } 60 | 61 | @GetMapping("/{id}") 62 | public Result findOne(@PathVariable Integer id) { 63 | return Result.success(articleService.getById(id)); 64 | } 65 | 66 | @GetMapping("/page") 67 | public Result findPage(@RequestParam String name, 68 | @RequestParam Integer pageNum, 69 | @RequestParam Integer pageSize) { 70 | QueryWrapper
queryWrapper = new QueryWrapper<>(); 71 | queryWrapper.orderByDesc("id"); 72 | if (StrUtil.isNotBlank(name)) { 73 | queryWrapper.like("name", name); 74 | } 75 | return Result.success(articleService.page(new Page<>(pageNum, pageSize), queryWrapper)); 76 | } 77 | 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/CommentController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import cn.hutool.core.date.DateUtil; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.ironmanjay.springboot.common.Result; 8 | import com.ironmanjay.springboot.entity.Comment; 9 | import com.ironmanjay.springboot.service.ICommentService; 10 | import com.ironmanjay.springboot.utils.TokenUtils; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import javax.annotation.Resource; 14 | import java.util.List; 15 | import java.util.Optional; 16 | import java.util.stream.Collectors; 17 | 18 | /** 19 | *

20 | * 前端控制器 21 | *

22 | * 23 | * @author IronmanJay 24 | * @since 2022-10-21 25 | */ 26 | @RestController 27 | @RequestMapping("/comment") 28 | public class CommentController { 29 | 30 | @Resource 31 | private ICommentService commentService; 32 | 33 | // 新增或者更新 34 | @PostMapping 35 | public Result save(@RequestBody Comment comment) { 36 | if (comment.getId() == null) { // 新增评论 37 | comment.setUserId(TokenUtils.getCurrentUser().getId()); 38 | comment.setTime(DateUtil.now()); 39 | if (comment.getPid() != null) { // 判断如果是回复,进行处理 40 | Integer pid = comment.getPid(); 41 | Comment pComment = commentService.getById(pid); 42 | if (pComment.getOriginId() != null) { // 如果当前回复的父级有祖宗,那么就设置相同的祖宗 43 | comment.setOriginId(pComment.getOriginId()); 44 | } else { // 否则就设置父级为当前回复的祖宗 45 | comment.setOriginId(comment.getPid()); 46 | } 47 | } 48 | } 49 | commentService.saveOrUpdate(comment); 50 | return Result.success(); 51 | 52 | } 53 | 54 | @DeleteMapping("/{id}") 55 | public Result delete(@PathVariable Integer id) { 56 | commentService.removeById(id); 57 | return Result.success(); 58 | } 59 | 60 | @PostMapping("/del/batch") 61 | public Result deleteBatch(@RequestBody List ids) { 62 | commentService.removeByIds(ids); 63 | return Result.success(); 64 | } 65 | 66 | @GetMapping 67 | public Result findAll() { 68 | return Result.success(commentService.list()); 69 | } 70 | 71 | @GetMapping("/tree/{articleId}") 72 | public Result findTree(@PathVariable Integer articleId) { 73 | List articleComments = commentService.findCommentDetail(articleId); // 查询所有的评论和回复数据 74 | // 查询评论数据(不包括回复) 75 | List originList = articleComments.stream().filter(comment -> comment.getOriginId() == null).collect(Collectors.toList()); 76 | // 设置评论数据的子节点,也就是回复内容 77 | for (Comment origin : originList) { 78 | List comments = articleComments.stream().filter(comment -> origin.getId().equals(comment.getOriginId())).collect(Collectors.toList()); // 表示回复对象集合 79 | comments.forEach(comment -> { 80 | Optional pComment = articleComments.stream().filter(c1 -> c1.getId().equals(comment.getPid())).findFirst(); // 找到当前评论的父级 81 | pComment.ifPresent((v -> { // 找到父级评论的用户id和用户昵称,并设置给当前的回复对象 82 | comment.setPUserId(v.getUserId()); 83 | comment.setPNickname(v.getNickname()); 84 | })); 85 | }); 86 | origin.setChildren(comments); 87 | } 88 | return Result.success(originList); 89 | } 90 | 91 | @GetMapping("/{id}") 92 | public Result findOne(@PathVariable Integer id) { 93 | return Result.success(commentService.getById(id)); 94 | } 95 | 96 | @GetMapping("/page") 97 | public Result findPage(@RequestParam Integer pageNum, 98 | @RequestParam Integer pageSize) { 99 | QueryWrapper queryWrapper = new QueryWrapper<>(); 100 | queryWrapper.orderByDesc("id"); 101 | return Result.success(commentService.page(new Page<>(pageNum, pageSize), queryWrapper)); 102 | } 103 | 104 | } 105 | 106 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/CourseController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.ironmanjay.springboot.common.Result; 6 | import com.ironmanjay.springboot.entity.Course; 7 | import com.ironmanjay.springboot.service.ICourseService; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.List; 12 | 13 | /** 14 | *

15 | * 前端控制器 16 | *

17 | * 18 | * @author IronmanJay 19 | * @since 2022-10-04 20 | */ 21 | @RestController 22 | @RequestMapping("/course") 23 | public class CourseController { 24 | 25 | @Resource 26 | private ICourseService courseService; 27 | 28 | // 新增或者更新 29 | @PostMapping 30 | public Result save(@RequestBody Course course) { 31 | courseService.saveOrUpdate(course); 32 | return Result.success(); 33 | } 34 | 35 | @PostMapping("/studentCourse/{courseId}/{studentId}") 36 | public Result studentCourse(@PathVariable Integer courseId, @PathVariable Integer studentId) { 37 | courseService.setStudentCourse(courseId, studentId); 38 | return Result.success(); 39 | } 40 | 41 | @DeleteMapping("/{id}") 42 | public Result delete(@PathVariable Integer id) { 43 | courseService.removeById(id); 44 | return Result.success(); 45 | } 46 | 47 | @PostMapping("/del/batch") 48 | public Result deleteBatch(@RequestBody List ids) { 49 | courseService.removeByIds(ids); 50 | return Result.success(); 51 | } 52 | 53 | @GetMapping 54 | public Result findAll() { 55 | return Result.success(courseService.list()); 56 | } 57 | 58 | @GetMapping("/{id}") 59 | public Result findOne(@PathVariable Integer id) { 60 | return Result.success(courseService.getById(id)); 61 | } 62 | 63 | @GetMapping("/page") 64 | public Result findPage(@RequestParam String name, @RequestParam Integer pageNum, @RequestParam Integer pageSize) { 65 | Page page = courseService.findPage(new Page<>(pageNum, pageSize), name); 66 | return Result.success(page); 67 | } 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/EchartsController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import cn.hutool.core.date.DateUtil; 5 | import cn.hutool.core.date.Quarter; 6 | import cn.hutool.core.lang.TypeReference; 7 | import cn.hutool.core.util.StrUtil; 8 | import cn.hutool.json.JSONUtil; 9 | import com.ironmanjay.springboot.common.Result; 10 | import com.ironmanjay.springboot.config.AuthAccess; 11 | import com.ironmanjay.springboot.entity.Files; 12 | import com.ironmanjay.springboot.entity.User; 13 | import com.ironmanjay.springboot.mapper.FileMapper; 14 | import com.ironmanjay.springboot.service.IUserService; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.data.redis.core.StringRedisTemplate; 17 | import org.springframework.web.bind.annotation.GetMapping; 18 | import org.springframework.web.bind.annotation.RequestMapping; 19 | import org.springframework.web.bind.annotation.RestController; 20 | 21 | import javax.annotation.Resource; 22 | import java.util.Date; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | @RestController 28 | @RequestMapping("/echarts") 29 | public class EchartsController { 30 | 31 | @Autowired 32 | private IUserService userService; 33 | 34 | @Resource 35 | private FileMapper fileMapper; 36 | 37 | @Resource 38 | private StringRedisTemplate stringRedisTemplate; 39 | 40 | public static final String FILES_KEY = "FILES_FRONT_ALL"; 41 | 42 | /** 43 | * 生成前端图形数据 44 | * 45 | * @return 返回生成的数据 46 | */ 47 | @GetMapping("/example") 48 | public Result get() { 49 | Map map = new HashMap<>(); 50 | map.put("x", CollUtil.newArrayList("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")); 51 | map.put("y", CollUtil.newArrayList(150, 230, 224, 218, 135, 147, 260)); 52 | return Result.success(map); 53 | } 54 | 55 | /** 56 | * 按季度获取数据 57 | * 58 | * @return 返回季度数据 59 | */ 60 | @GetMapping("/members") 61 | public Result members() { 62 | List list = userService.list(); 63 | int q1 = 0; // 第一季度 64 | int q2 = 0; // 第二季度 65 | int q3 = 0; // 第三季度 66 | int q4 = 0; // 第四季度 67 | for (User user : list) { 68 | Date createTime = user.getCreateTime(); 69 | Quarter quarter = DateUtil.quarterEnum(createTime); 70 | switch (quarter) { 71 | case Q1: 72 | q1 += 1; 73 | break; 74 | case Q2: 75 | q2 += 1; 76 | break; 77 | case Q3: 78 | q3 += 1; 79 | break; 80 | case Q4: 81 | q4 += 1; 82 | break; 83 | default: 84 | break; 85 | } 86 | } 87 | return Result.success(CollUtil.newArrayList(q1, q2, q3, q4)); 88 | } 89 | 90 | /** 91 | * 查询数据 92 | * 93 | * @return 返回查询到的数据 94 | */ 95 | @AuthAccess 96 | @GetMapping("/file/front/all") 97 | public Result frontAll() { 98 | // 1. 从缓存获取数据 99 | String jsonStr = stringRedisTemplate.opsForValue().get(FILES_KEY); 100 | List files; 101 | // 2. 取出来的json是空的 102 | if (StrUtil.isBlank(jsonStr)) { 103 | files = fileMapper.selectList(null); 104 | // 3. 从数据库取出数据,再去缓存到redis 105 | stringRedisTemplate.opsForValue().set(FILES_KEY, JSONUtil.toJsonStr(files)); 106 | } 107 | // 4. 取出来的json不是空的 108 | else { 109 | // 5. 如果有,从redis缓存中获取数据,减轻了数据库的压力 110 | files = JSONUtil.toBean(jsonStr, new TypeReference>() { 111 | }, true); 112 | } 113 | return Result.success(files); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/FileController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | import cn.hutool.core.io.FileUtil; 4 | import cn.hutool.core.util.IdUtil; 5 | import cn.hutool.core.util.StrUtil; 6 | import cn.hutool.crypto.SecureUtil; 7 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 8 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 9 | import com.ironmanjay.springboot.common.Result; 10 | import com.ironmanjay.springboot.entity.Files; 11 | import com.ironmanjay.springboot.mapper.FileMapper; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.data.redis.core.StringRedisTemplate; 14 | import org.springframework.web.bind.annotation.*; 15 | import org.springframework.web.multipart.MultipartFile; 16 | 17 | import javax.annotation.Resource; 18 | import javax.servlet.ServletOutputStream; 19 | import javax.servlet.http.HttpServletResponse; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.net.URLEncoder; 23 | import java.util.List; 24 | 25 | /** 26 | * 文件上传与下载相关接口 27 | */ 28 | @RestController 29 | @RequestMapping("/file") 30 | public class FileController { 31 | 32 | @Value("${files.upload.path}") 33 | private String fileUploadPath; 34 | 35 | @Resource 36 | private FileMapper fileMapper; 37 | 38 | @Resource 39 | private StringRedisTemplate stringRedisTemplate; 40 | 41 | public static final String FILES_KEY = "FILES_FRONT_ALL"; 42 | 43 | /** 44 | * 文件上传接口 45 | * 46 | * @param file 前端传递过来的文件 47 | * @return 返回文件url 48 | * @throws IOException 异常处理 49 | */ 50 | @PostMapping("/upload") 51 | public String upload(@RequestParam MultipartFile file) throws IOException { 52 | String originalFilename = file.getOriginalFilename(); 53 | String type = FileUtil.extName(originalFilename); 54 | long size = file.getSize(); 55 | // 定义一个文件唯一的标识码 56 | String uuid = IdUtil.fastSimpleUUID(); 57 | String fileUUID = uuid + StrUtil.DOT + type; 58 | File uploadFile = new File(fileUploadPath + fileUUID); 59 | // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录 60 | File parentFile = uploadFile.getParentFile(); 61 | if (!parentFile.exists()) { 62 | parentFile.mkdirs(); 63 | } 64 | String url; 65 | // 获取文件的md5,通过对比md5避免重复上传相同内容的文件 66 | String md5 = SecureUtil.md5(file.getInputStream()); 67 | // 从数据库查询是否存在相同的记录 68 | Files dbFiles = getFileByMd5(md5); 69 | if (dbFiles != null) { // 文件已存在 70 | url = dbFiles.getUrl(); 71 | } else { 72 | // 上传文件到磁盘 73 | file.transferTo(uploadFile); 74 | // 数据库若不存在重复文件,则不删除刚才上传的文件 75 | url = "http://localhost:9090/file/" + fileUUID; 76 | } 77 | // 存储数据库 78 | Files saveFile = new Files(); 79 | saveFile.setName(originalFilename); 80 | saveFile.setType(type); 81 | saveFile.setSize(size / 1024); 82 | saveFile.setUrl(url); 83 | saveFile.setMd5(md5); 84 | fileMapper.insert(saveFile); 85 | flushRedis(FILES_KEY); 86 | return url; 87 | } 88 | 89 | /** 90 | * 文件下载接口 91 | * 92 | * @param fileUUID 文件唯一标识符 93 | * @param response 请求响应 94 | * @throws IOException 异常处理 95 | */ 96 | @GetMapping("/{fileUUID}") 97 | public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException { 98 | // 根据文件的唯一标识码获取文件 99 | File uploadFile = new File(fileUploadPath + fileUUID); 100 | // 设置输出流的格式 101 | ServletOutputStream os = response.getOutputStream(); 102 | response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8")); 103 | response.setContentType("application/octetcd ream"); 104 | // 读取文件的字节流 105 | os.write(FileUtil.readBytes(uploadFile)); 106 | os.flush(); 107 | os.close(); 108 | } 109 | 110 | /** 111 | * 通过文件的md5查询文件 112 | * 113 | * @param md5 114 | * @return 返回文件的md5 115 | */ 116 | private Files getFileByMd5(String md5) { 117 | // 查询文件的md5是否存在 118 | QueryWrapper queryWrapper = new QueryWrapper<>(); 119 | queryWrapper.eq("md5", md5); 120 | List filesList = fileMapper.selectList(queryWrapper); 121 | return filesList.size() == 0 ? null : filesList.get(0); 122 | } 123 | 124 | /** 125 | * 分页查询接口 126 | * 127 | * @param pageNum 分多少页 128 | * @param pageSize 每页多少个数据 129 | * @param name 根据文件名查询记录 130 | * @return 返回分页查询结果 131 | */ 132 | @GetMapping("/page") 133 | public Result findPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize, @RequestParam(defaultValue = "") String name) { 134 | QueryWrapper queryWrapper = new QueryWrapper<>(); 135 | // 查询未删除的记录 136 | queryWrapper.eq("is_delete", false); 137 | queryWrapper.orderByDesc("id"); 138 | if (!"".equals(name)) { 139 | queryWrapper.like("name", name); 140 | } 141 | return Result.success(fileMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper)); 142 | } 143 | 144 | /** 145 | * 更新文件信息 146 | * 147 | * @param files 待更新的文件 148 | * @return 返回更新结果 149 | */ 150 | @PostMapping("/update") 151 | public Result update(@RequestBody Files files) { 152 | fileMapper.updateById(files); 153 | flushRedis(FILES_KEY); 154 | return Result.success(); 155 | } 156 | 157 | /** 158 | * 按照文件id删除 159 | * 160 | * @param id 待删除的文件id 161 | * @return 返回删除结果 162 | */ 163 | @DeleteMapping("/{id}") 164 | public Result delete(@PathVariable Integer id) { 165 | Files files = fileMapper.selectById(id); 166 | files.setIsDelete(true); 167 | fileMapper.updateById(files); 168 | flushRedis(FILES_KEY); 169 | return Result.success(); 170 | } 171 | 172 | /** 173 | * 按照文件id查询 174 | * 175 | * @param id 待查询的文件id 176 | * @return 返回查询结果 177 | */ 178 | @GetMapping("/detail/{id}") 179 | public Result getById(@PathVariable Integer id) { 180 | return Result.success(fileMapper.selectById(id)); 181 | } 182 | 183 | /** 184 | * 按照id批量删除文件 185 | * 186 | * @param ids 待删除的文件id即可 187 | * @return 返回删除结果 188 | */ 189 | @PostMapping("/del/batch") 190 | public Result deleteBatch(@RequestBody List ids) { 191 | QueryWrapper queryWrapper = new QueryWrapper<>(); 192 | queryWrapper.in("id", ids); 193 | List files = fileMapper.selectList(queryWrapper); 194 | for (Files file : files) { 195 | file.setIsDelete(true); 196 | fileMapper.updateById(file); 197 | } 198 | return Result.success(); 199 | } 200 | 201 | /** 202 | * 删除缓存 203 | * 204 | * @param key 要删除的缓存key 205 | */ 206 | private void flushRedis(String key) { 207 | stringRedisTemplate.delete(key); 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/MenuController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.ironmanjay.springboot.common.Constants; 7 | import com.ironmanjay.springboot.common.Result; 8 | import com.ironmanjay.springboot.entity.Dict; 9 | import com.ironmanjay.springboot.entity.Menu; 10 | import com.ironmanjay.springboot.mapper.DictMapper; 11 | import com.ironmanjay.springboot.service.IMenuService; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.List; 16 | 17 | /** 18 | *

19 | * 前端控制器 20 | *

21 | * 22 | * @author IronmanJay 23 | * @since 2022-09-14 24 | */ 25 | @RestController 26 | @RequestMapping("/menu") 27 | public class MenuController { 28 | 29 | @Resource 30 | private IMenuService menuService; 31 | 32 | @Resource 33 | private DictMapper dictMapper; 34 | 35 | // 新增或者更新 36 | @PostMapping 37 | public boolean save(@RequestBody Menu menu) { 38 | return menuService.saveOrUpdate(menu); 39 | } 40 | 41 | @DeleteMapping("/{id}") 42 | public Boolean delete(@PathVariable Integer id) { 43 | return menuService.removeById(id); 44 | } 45 | 46 | @PostMapping("/del/batch") 47 | public boolean deleteBatch(@RequestBody List ids) { 48 | return menuService.removeByIds(ids); 49 | } 50 | 51 | @GetMapping("/ids") 52 | public Result findAllIds() { 53 | return Result.success(menuService.list().stream().map(Menu::getId)); 54 | } 55 | 56 | @GetMapping 57 | public Result findAll(@RequestParam(defaultValue = "") String name) { 58 | return Result.success(menuService.findMenus(name)); 59 | } 60 | 61 | @GetMapping("/{id}") 62 | public Menu findOne(@PathVariable Integer id) { 63 | return menuService.getById(id); 64 | } 65 | 66 | @GetMapping("/page") 67 | public Page findPage(@RequestParam String name, @RequestParam Integer pageNum, @RequestParam Integer pageSize) { 68 | QueryWrapper queryWrapper = new QueryWrapper<>(); 69 | queryWrapper.like("name", name); 70 | queryWrapper.orderByDesc("id"); 71 | return menuService.page(new Page<>(pageNum, pageSize), queryWrapper); 72 | } 73 | 74 | @GetMapping("/icons") 75 | public Result getIcons() { 76 | QueryWrapper queryWrapper = new QueryWrapper<>(); 77 | queryWrapper.eq("type", Constants.DICT_TYPE_ICON); 78 | return Result.success(dictMapper.selectList(null)); 79 | } 80 | 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/RoleController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.ironmanjay.springboot.common.Result; 7 | import com.ironmanjay.springboot.entity.Role; 8 | import com.ironmanjay.springboot.service.IRoleService; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | 14 | /** 15 | *

16 | * 前端控制器 17 | *

18 | * 19 | * @author IronmanJay 20 | * @since 2022-09-14 21 | */ 22 | @RestController 23 | @RequestMapping("/role") 24 | public class RoleController { 25 | 26 | @Resource 27 | private IRoleService roleService; 28 | 29 | // 新增或者更新 30 | @PostMapping 31 | public boolean save(@RequestBody Role role) { 32 | return roleService.saveOrUpdate(role); 33 | } 34 | 35 | @DeleteMapping("/{id}") 36 | public Boolean delete(@PathVariable Integer id) { 37 | return roleService.removeById(id); 38 | } 39 | 40 | @PostMapping("/del/batch") 41 | public boolean deleteBatch(@RequestBody List ids) { 42 | return roleService.removeByIds(ids); 43 | } 44 | 45 | @GetMapping 46 | public List findAll() { 47 | return roleService.list(); 48 | } 49 | 50 | @GetMapping("/{id}") 51 | public Role findOne(@PathVariable Integer id) { 52 | return roleService.getById(id); 53 | } 54 | 55 | @GetMapping("/page") 56 | public Page findPage(@RequestParam String name, @RequestParam Integer pageNum, @RequestParam Integer pageSize) { 57 | QueryWrapper queryWrapper = new QueryWrapper<>(); 58 | queryWrapper.like("name", name); 59 | queryWrapper.orderByDesc("id"); 60 | return roleService.page(new Page<>(pageNum, pageSize), queryWrapper); 61 | } 62 | 63 | /** 64 | * 绑定角色和菜单的关系 65 | * 66 | * @param roleId 角色id 67 | * @param menuIds 菜单id数组 68 | * @return 绑定结果 69 | */ 70 | @PostMapping("/roleMenu/{roleId}") 71 | public Result roleMenu(@PathVariable Integer roleId, @RequestBody List menuIds) { 72 | roleService.setRoleMenu(roleId, menuIds); 73 | return Result.success(); 74 | } 75 | 76 | @GetMapping("/roleMenu/{roleId}") 77 | public Result getRoleMenu(@PathVariable Integer roleId) { 78 | return Result.success(roleService.getRoleMenu(roleId)); 79 | } 80 | 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller; 2 | 3 | 4 | import cn.hutool.core.collection.CollUtil; 5 | import cn.hutool.core.util.StrUtil; 6 | import cn.hutool.poi.excel.ExcelReader; 7 | import cn.hutool.poi.excel.ExcelUtil; 8 | import cn.hutool.poi.excel.ExcelWriter; 9 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 10 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 11 | import com.ironmanjay.springboot.common.Constants; 12 | import com.ironmanjay.springboot.common.Result; 13 | import com.ironmanjay.springboot.controller.dto.UserDTO; 14 | import com.ironmanjay.springboot.controller.dto.UserPasswordDTO; 15 | import com.ironmanjay.springboot.entity.User; 16 | import com.ironmanjay.springboot.service.IUserService; 17 | import org.springframework.web.bind.annotation.*; 18 | import org.springframework.web.multipart.MultipartFile; 19 | 20 | import javax.annotation.Resource; 21 | import javax.servlet.ServletOutputStream; 22 | import javax.servlet.http.HttpServletResponse; 23 | import java.io.InputStream; 24 | import java.net.URLEncoder; 25 | import java.util.List; 26 | 27 | /** 28 | * @author IronmanJay 29 | * @since 2022-07-25 30 | */ 31 | @RestController 32 | @RequestMapping("/user") 33 | public class UserController { 34 | 35 | /** 36 | * 引入user相关功能 37 | */ 38 | @Resource 39 | private IUserService userService; 40 | 41 | /** 42 | * 数据插入或数据更新,@RequestBody将前台的json对象转换为java对象 43 | * 44 | * @param user 用户实体类 45 | * @return 返回插入或者更新结果 46 | */ 47 | @PostMapping 48 | public boolean save(@RequestBody User user) { 49 | return userService.saveOrUpdate(user); 50 | } 51 | 52 | /** 53 | * 删除数据 54 | * 55 | * @param id 要删除的用户id 56 | * @return 返回删除结果 57 | */ 58 | @DeleteMapping("/{id}") 59 | public Boolean delete(@PathVariable Integer id) { 60 | return userService.removeById(id); 61 | } 62 | 63 | /** 64 | * 批量删除数据 65 | * 66 | * @param ids 要删除的批量用户id 67 | * @return 返回删除结果 68 | */ 69 | @PostMapping("/del/batch") 70 | public boolean deleteBatch(@RequestBody List ids) { 71 | return userService.removeByIds(ids); 72 | } 73 | 74 | /** 75 | * 测试查询所有信息 76 | * 77 | * @return 返回所有用户信息 78 | */ 79 | @GetMapping 80 | public List findAll() { 81 | return userService.list(); 82 | } 83 | 84 | /** 85 | * 查询当前角色的所有用户 86 | * 87 | * @param role 角色 88 | * @return 返回当前角色的所有用户 89 | */ 90 | @GetMapping("/role/{role}") 91 | public Result findUsersByRole(@PathVariable String role) { 92 | QueryWrapper queryWrapper = new QueryWrapper<>(); 93 | queryWrapper.eq("role", role); 94 | List list = userService.list(queryWrapper); 95 | return Result.success(list); 96 | } 97 | 98 | /** 99 | * 查找数据 100 | * 101 | * @param id 要查找的用户id 102 | * @return 返回查找结果 103 | */ 104 | @GetMapping("/{id}") 105 | public User findOne(@PathVariable Integer id) { 106 | return userService.getById(id); 107 | } 108 | 109 | /** 110 | * 分页查询接口 111 | * 接口路径:/user/page 112 | * 113 | * @param pageNum = (pageNum - 1) * pageSize 114 | * @param pageSize = pageSize 115 | * @param username 用户名 116 | * @param email 邮箱 117 | * @param address 地址 118 | * @return 返回分页用户信息 119 | * @RequestParam 接收?pageNum=1&pageSize=10 120 | */ 121 | @GetMapping("/page") 122 | public Result findPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize, @RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "") String email, @RequestParam(defaultValue = "") String address) { 123 | return Result.success(userService.findPage(new Page<>(pageNum, pageSize), username, email, address)); 124 | } 125 | 126 | /** 127 | * 导出接口 128 | * 129 | * @param response 导出请求 130 | * @throws Exception 131 | */ 132 | @GetMapping("/export") 133 | public void export(HttpServletResponse response) throws Exception { 134 | // 从数据库查询出所有的数据 135 | List list = userService.list(); 136 | // 在内存操作,写出到浏览器 137 | ExcelWriter writer = ExcelUtil.getWriter(true); 138 | // 自定义标题别名 139 | writer.addHeaderAlias("username", "用户名"); 140 | writer.addHeaderAlias("password", "密码"); 141 | writer.addHeaderAlias("nickname", "昵称"); 142 | writer.addHeaderAlias("email", "邮箱"); 143 | writer.addHeaderAlias("phone", "电话"); 144 | writer.addHeaderAlias("address", "地址"); 145 | writer.addHeaderAlias("createTime", "创建时间"); 146 | writer.addHeaderAlias("avatarUrl", "头像"); 147 | 148 | // 一次性写出list内的对象到excel,使用默认样式,强制输出标题 149 | writer.write(list, true); 150 | 151 | // 设置浏览器响应的格式 152 | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); 153 | String fileName = URLEncoder.encode("用户信息", "UTF-8"); 154 | response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx"); 155 | 156 | ServletOutputStream out = response.getOutputStream(); 157 | writer.flush(out, true); 158 | out.close(); 159 | writer.close(); 160 | } 161 | 162 | /** 163 | * 导入接口 164 | * 165 | * @param file 导入文件 166 | * @throws Exception 167 | */ 168 | @PostMapping("/import") 169 | public Boolean imp(MultipartFile file) throws Exception { 170 | InputStream inputStream = file.getInputStream(); 171 | ExcelReader reader = ExcelUtil.getReader(inputStream); 172 | List> list = reader.read(1); 173 | List users = CollUtil.newArrayList(); 174 | for (List row : list) { 175 | User user = new User(); 176 | user.setUsername(row.get(0).toString()); 177 | user.setPassword(row.get(1).toString()); 178 | user.setNickname(row.get(2).toString()); 179 | user.setEmail(row.get(3).toString()); 180 | user.setPhone(row.get(4).toString()); 181 | user.setAddress(row.get(5).toString()); 182 | users.add(user); 183 | } 184 | userService.saveBatch(users); 185 | return true; 186 | } 187 | 188 | /** 189 | * 用户登录接口 190 | * 191 | * @param userDTO 登录的用户信息 192 | * @return 返回登录结果 193 | */ 194 | @PostMapping("/login") 195 | public Result login(@RequestBody UserDTO userDTO) { 196 | String username = userDTO.getUsername(); 197 | String password = userDTO.getPassword(); 198 | if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) { 199 | return Result.error(Constants.CODE_400, "参数错误"); 200 | } 201 | UserDTO dto = userService.login(userDTO); 202 | return Result.success(dto); 203 | } 204 | 205 | /** 206 | * 用户注册接口 207 | * 208 | * @param userDTO 登录的用户信息 209 | * @return 返回登录结果 210 | */ 211 | @PostMapping("/register") 212 | public Result register(@RequestBody UserDTO userDTO) { 213 | String username = userDTO.getUsername(); 214 | String password = userDTO.getPassword(); 215 | if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) { 216 | return Result.error(Constants.CODE_400, "参数错误"); 217 | } 218 | return Result.success(userService.register(userDTO)); 219 | } 220 | 221 | /** 222 | * 用户个人信息接口 223 | * 224 | * @param username 用户名 225 | * @return 返回用户个人信息 226 | */ 227 | @GetMapping("/username/{username}") 228 | public Result findOne(@PathVariable String username) { 229 | QueryWrapper queryWrapper = new QueryWrapper<>(); 230 | queryWrapper.eq("username", username); 231 | return Result.success(userService.getOne(queryWrapper)); 232 | } 233 | 234 | /** 235 | * 修改密码 236 | * 237 | * @param userPasswordDTO 修改密码的结构体 238 | * @return 返回修改密码的结果 239 | */ 240 | @PostMapping("/password") 241 | public Result password(@RequestBody UserPasswordDTO userPasswordDTO) { 242 | userService.updatePassword(userPasswordDTO); 243 | return Result.success(); 244 | } 245 | 246 | } 247 | 248 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/dto/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller.dto; 2 | 3 | import com.ironmanjay.springboot.entity.Menu; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 接收前端登录请求的参数 10 | */ 11 | @Data 12 | public class UserDTO { 13 | 14 | private Integer id; 15 | private String username; 16 | private String password; 17 | private String nickname; 18 | private String avatar; 19 | private String token; 20 | private String role; 21 | private List menus; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/controller/dto/UserPasswordDTO.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.controller.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class UserPasswordDTO { 7 | private String username; 8 | private String password; 9 | private String newPassword; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Article.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import io.swagger.annotations.ApiModel; 6 | import io.swagger.annotations.ApiModelProperty; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

14 | * 15 | *

16 | * 17 | * @author IronmanJay 18 | * @since 2022-10-18 19 | */ 20 | @Getter 21 | @Setter 22 | @ApiModel(value = "Article对象", description = "") 23 | public class Article implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | @ApiModelProperty("ID") 28 | @TableId(value = "id", type = IdType.AUTO) 29 | private Integer id; 30 | 31 | @ApiModelProperty("标题") 32 | private String name; 33 | 34 | @ApiModelProperty("内容") 35 | private String content; 36 | 37 | @ApiModelProperty("发布人") 38 | private String user; 39 | 40 | private String time; 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Comment.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import io.swagger.annotations.ApiModel; 8 | import io.swagger.annotations.ApiModelProperty; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | import java.io.Serializable; 13 | import java.util.List; 14 | 15 | /** 16 | *

17 | * 18 | *

19 | * 20 | * @author IronmanJay 21 | * @since 2022-10-21 22 | */ 23 | @Getter 24 | @Setter 25 | @TableName("t_comment") 26 | @ApiModel(value = "Comment对象", description = "") 27 | public class Comment implements Serializable { 28 | 29 | private static final long serialVersionUID = 1L; 30 | 31 | @ApiModelProperty("ID") 32 | @TableId(value = "id", type = IdType.AUTO) 33 | private Integer id; 34 | 35 | @ApiModelProperty("评论内容") 36 | private String content; 37 | 38 | @ApiModelProperty("评论人Id") 39 | private Integer userId; 40 | 41 | @ApiModelProperty("评论时间") 42 | private String time; 43 | 44 | @ApiModelProperty("父Id") 45 | private Integer pid; 46 | 47 | @ApiModelProperty("最上级评论Id") 48 | private Integer originId; 49 | 50 | @ApiModelProperty("关联文章Id") 51 | private Integer articleId; 52 | 53 | @TableField(exist = false) 54 | private String nickname; 55 | @TableField(exist = false) 56 | private String avatar; 57 | 58 | @TableField(exist = false) 59 | private List children; 60 | 61 | @TableField(exist = false) 62 | private String pNickname; // 父节点的用户昵称 63 | @TableField(exist = false) 64 | private Integer pUserId; // 父节点的用户id 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Course.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import io.swagger.annotations.ApiModel; 5 | import io.swagger.annotations.ApiModelProperty; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | *

13 | * 14 | *

15 | * 16 | * @author IronmanJay 17 | * @since 2022-10-04 18 | */ 19 | @Getter 20 | @Setter 21 | @ApiModel(value = "Course对象", description = "") 22 | public class Course implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | @ApiModelProperty("id") 27 | private Integer id; 28 | 29 | @ApiModelProperty("课程名称") 30 | private String name; 31 | 32 | @ApiModelProperty("学分") 33 | private Integer score; 34 | 35 | @ApiModelProperty("上课时间") 36 | private String times; 37 | 38 | @ApiModelProperty("授课老师id") 39 | private Integer teacherId; 40 | 41 | @TableField(exist = false) 42 | private String teacher; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Dict.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | 6 | @TableName("sys_dict") 7 | @Data 8 | public class Dict { 9 | 10 | private String name; 11 | private String value; 12 | private String type; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Files.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import lombok.Data; 7 | 8 | @Data 9 | @TableName("sys_file") 10 | public class Files { 11 | 12 | @TableId(type = IdType.AUTO) 13 | private Integer id; 14 | private String name; 15 | private String type; 16 | private long size; 17 | private String url; 18 | private Boolean isDelete; 19 | private Boolean enable; 20 | private String md5; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Menu.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import io.swagger.annotations.ApiModel; 8 | import io.swagger.annotations.ApiModelProperty; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | import java.io.Serializable; 13 | import java.util.List; 14 | 15 | /** 16 | *

17 | * 18 | *

19 | * 20 | * @author IronmanJay 21 | * @since 2022-09-14 22 | */ 23 | @Getter 24 | @Setter 25 | @TableName("sys_menu") 26 | @ApiModel(value = "Menu对象", description = "") 27 | public class Menu implements Serializable { 28 | 29 | private static final long serialVersionUID = 1L; 30 | 31 | @ApiModelProperty("id") 32 | @TableId(value = "id", type = IdType.AUTO) 33 | private Integer id; 34 | 35 | @ApiModelProperty("名称") 36 | private String name; 37 | 38 | @ApiModelProperty("路径") 39 | private String path; 40 | 41 | @ApiModelProperty("图标") 42 | private String icon; 43 | 44 | @ApiModelProperty("描述") 45 | private String description; 46 | 47 | @TableField(exist = false) 48 | private List children; 49 | 50 | private Integer pid; 51 | 52 | private String pagePath; 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/Role.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import io.swagger.annotations.ApiModel; 5 | import io.swagger.annotations.ApiModelProperty; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | *

13 | * 14 | *

15 | * 16 | * @author IronmanJay 17 | * @since 2022-09-14 18 | */ 19 | @Getter 20 | @Setter 21 | @TableName("sys_role") 22 | @ApiModel(value = "Role对象", description = "") 23 | public class Role implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | @ApiModelProperty("id") 28 | private Integer id; 29 | 30 | @ApiModelProperty("名称") 31 | private String name; 32 | 33 | @ApiModelProperty("描述") 34 | private String description; 35 | 36 | @ApiModelProperty("唯一标识") 37 | private String flag; 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/RoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | 6 | @TableName("sys_role_menu") 7 | @Data 8 | public class RoleMenu { 9 | 10 | private Integer roleId; 11 | private Integer menuId; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import io.swagger.annotations.ApiModel; 8 | import io.swagger.annotations.ApiModelProperty; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | import lombok.ToString; 12 | 13 | import java.io.Serializable; 14 | import java.util.Date; 15 | import java.util.List; 16 | 17 | /** 18 | * @author IronmanJayF 19 | * @since 2022-07-25 20 | */ 21 | @Getter 22 | @Setter 23 | @TableName("sys_user") 24 | @ApiModel(value = "User对象", description = "") 25 | @ToString 26 | public class User implements Serializable { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | @ApiModelProperty("id") 31 | @TableId(value = "id", type = IdType.AUTO) 32 | private Integer id; 33 | 34 | @ApiModelProperty("用户名") 35 | private String username; 36 | 37 | @ApiModelProperty("密码") 38 | private String password; 39 | 40 | @ApiModelProperty("昵称") 41 | private String nickname; 42 | 43 | @ApiModelProperty("邮箱") 44 | private String email; 45 | 46 | @ApiModelProperty("电话") 47 | private String phone; 48 | 49 | @ApiModelProperty("地址") 50 | private String address; 51 | 52 | @ApiModelProperty("创建时间") 53 | private Date createTime; 54 | 55 | @ApiModelProperty("头像") 56 | private String avatar; 57 | 58 | @ApiModelProperty("角色") 59 | private String role; 60 | 61 | @TableField(exist = false) 62 | private List courses; 63 | 64 | @TableField(exist = false) 65 | private List stuCourses; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/exception/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.exception; 2 | 3 | import com.ironmanjay.springboot.common.Result; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | @ControllerAdvice 9 | public class GlobalExceptionHandler { 10 | 11 | /** 12 | * 如果抛出的的是ServiceException,则调用该方法 13 | * @param se 业务异常 14 | * @return Result 15 | */ 16 | @ExceptionHandler(ServiceException.class) 17 | @ResponseBody 18 | public Result handle(ServiceException se){ 19 | return Result.error(se.getCode(), se.getMessage()); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/exception/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.exception; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * 自定义异常 7 | */ 8 | @Getter 9 | public class ServiceException extends RuntimeException { 10 | 11 | private String code; 12 | 13 | public ServiceException(String code, String msg) { 14 | super(msg); 15 | this.code = code; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/ArticleMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.ironmanjay.springboot.entity.Article; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | *

8 | * Mapper 接口 9 | *

10 | * 11 | * @author IronmanJay 12 | * @since 2022-10-18 13 | */ 14 | public interface ArticleMapper extends BaseMapper
{ 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/CommentMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ironmanjay.springboot.entity.Comment; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * Mapper 接口 13 | *

14 | * 15 | * @author IronmanJay 16 | * @since 2022-10-21 17 | */ 18 | public interface CommentMapper extends BaseMapper { 19 | 20 | @Select("select c.*,u.nickname,u.avatar from t_comment c left join sys_user u on c.user_id = u.id where c.article_id = #{articleId} order by id desc") 21 | List findCommentDetail(@Param("articleId") Integer articleId); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/CourseMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.ironmanjay.springboot.entity.Course; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | /** 9 | *

10 | * Mapper 接口 11 | *

12 | * 13 | * @author IronmanJay 14 | * @since 2022-10-04 15 | */ 16 | public interface CourseMapper extends BaseMapper { 17 | 18 | Page findPage(Page page, @Param("name") String name); 19 | 20 | void deleteStudentCourse(@Param("courseId") Integer courseId, @Param("studentId") Integer studentId); 21 | 22 | void setStudentCourse(@Param("courseId") Integer courseId, @Param("studentId") Integer studentId); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/DictMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ironmanjay.springboot.entity.Dict; 5 | 6 | public interface DictMapper extends BaseMapper { 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/FileMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ironmanjay.springboot.entity.Files; 5 | 6 | public interface FileMapper extends BaseMapper { 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/MenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.ironmanjay.springboot.entity.Menu; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | *

8 | * Mapper 接口 9 | *

10 | * 11 | * @author IronmanJay 12 | * @since 2022-09-14 13 | */ 14 | public interface MenuMapper extends BaseMapper { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/RoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ironmanjay.springboot.entity.Role; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | /** 9 | *

10 | * Mapper 接口 11 | *

12 | * 13 | * @author IronmanJay 14 | * @since 2022-09-14 15 | */ 16 | public interface RoleMapper extends BaseMapper { 17 | 18 | @Select("select id from sys_role where flag = #{flag}") 19 | Integer selectByFlag(@Param("flag") String flag); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/RoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ironmanjay.springboot.entity.RoleMenu; 5 | import org.apache.ibatis.annotations.Delete; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | import java.util.List; 10 | 11 | public interface RoleMenuMapper extends BaseMapper { 12 | 13 | @Select("select menu_id from sys_role_menu where role_id = #{roleId}") 14 | List selectByRoleId(@Param("roleId") Integer roleId); 15 | 16 | @Delete("delete from sys_role_menu where role_id = #{roleId}") 17 | int deleteByRoleId(@Param("roleId") Integer roleId); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.ironmanjay.springboot.controller.dto.UserPasswordDTO; 6 | import com.ironmanjay.springboot.entity.User; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | /** 10 | * @author IronmanJay 11 | * @since 2022-07-25 12 | */ 13 | public interface UserMapper extends BaseMapper { 14 | 15 | int updatePassword(@Param("userPasswordDTO") UserPasswordDTO userPasswordDTO); 16 | 17 | Page findPage(Page page, @Param("username") String username, @Param("email") String email, @Param("address") String address); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/IArticleService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.ironmanjay.springboot.entity.Article; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 服务类 9 | *

10 | * 11 | * @author IronmanJay 12 | * @since 2022-10-18 13 | */ 14 | public interface IArticleService extends IService
{ 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/ICommentService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.ironmanjay.springboot.entity.Comment; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author IronmanJay 14 | * @since 2022-10-21 15 | */ 16 | public interface ICommentService extends IService { 17 | 18 | List findCommentDetail(Integer articleId); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/ICourseService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.ironmanjay.springboot.entity.Course; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | *

9 | * 服务类 10 | *

11 | * 12 | * @author IronmanJay 13 | * @since 2022-10-04 14 | */ 15 | public interface ICourseService extends IService { 16 | 17 | Page findPage(Page page, String name); 18 | 19 | void setStudentCourse(Integer courseId, Integer studentId); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/IMenuService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.ironmanjay.springboot.entity.Menu; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author IronmanJay 14 | * @since 2022-09-14 15 | */ 16 | public interface IMenuService extends IService { 17 | 18 | List findMenus(String name); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/IRoleService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.ironmanjay.springboot.entity.Role; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 服务类 11 | *

12 | * 13 | * @author IronmanJay 14 | * @since 2022-09-14 15 | */ 16 | public interface IRoleService extends IService { 17 | 18 | void setRoleMenu(Integer roleId, List menuIds); 19 | 20 | List getRoleMenu(Integer roleId); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.ironmanjay.springboot.controller.dto.UserDTO; 6 | import com.ironmanjay.springboot.controller.dto.UserPasswordDTO; 7 | import com.ironmanjay.springboot.entity.User; 8 | 9 | /** 10 | * @author IronmanJay 11 | * @since 2022-07-25 12 | */ 13 | public interface IUserService extends IService { 14 | 15 | UserDTO login(UserDTO userDTO); 16 | 17 | User register(UserDTO userDTO); 18 | 19 | void updatePassword(UserPasswordDTO userPasswordDTO); 20 | 21 | Page findPage(Page page, String username, String email, String address); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/ArticleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import com.ironmanjay.springboot.entity.Article; 4 | import com.ironmanjay.springboot.mapper.ArticleMapper; 5 | import com.ironmanjay.springboot.service.IArticleService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 服务实现类 12 | *

13 | * 14 | * @author IronmanJay 15 | * @since 2022-10-18 16 | */ 17 | @Service 18 | public class ArticleServiceImpl extends ServiceImpl implements IArticleService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/CommentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.ironmanjay.springboot.entity.Comment; 5 | import com.ironmanjay.springboot.mapper.CommentMapper; 6 | import com.ironmanjay.springboot.service.ICommentService; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.annotation.Resource; 10 | import java.util.List; 11 | 12 | /** 13 | *

14 | * 服务实现类 15 | *

16 | * 17 | * @author IronmanJay 18 | * @since 2022-10-21 19 | */ 20 | @Service 21 | public class CommentServiceImpl extends ServiceImpl implements ICommentService { 22 | 23 | @Resource 24 | private CommentMapper commentMapper; 25 | 26 | @Override 27 | public List findCommentDetail(Integer articleId) { 28 | 29 | return commentMapper.findCommentDetail(articleId); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/CourseServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.ironmanjay.springboot.entity.Course; 6 | import com.ironmanjay.springboot.mapper.CourseMapper; 7 | import com.ironmanjay.springboot.service.ICourseService; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import javax.annotation.Resource; 12 | 13 | /** 14 | *

15 | * 服务实现类 16 | *

17 | * 18 | * @author IronmanJay 19 | * @since 2022-10-04 20 | */ 21 | @Service 22 | public class CourseServiceImpl extends ServiceImpl implements ICourseService { 23 | 24 | @Resource 25 | private CourseMapper courseMapper; 26 | 27 | @Override 28 | public Page findPage(Page page, String name) { 29 | return courseMapper.findPage(page, name); 30 | } 31 | 32 | @Transactional 33 | @Override 34 | public void setStudentCourse(Integer courseId, Integer studentId) { 35 | courseMapper.deleteStudentCourse(courseId, studentId); 36 | courseMapper.setStudentCourse(courseId, studentId); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/MenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.ironmanjay.springboot.entity.Menu; 7 | import com.ironmanjay.springboot.mapper.MenuMapper; 8 | import com.ironmanjay.springboot.service.IMenuService; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | /** 15 | *

16 | * 服务实现类 17 | *

18 | * 19 | * @author IronmanJay 20 | * @since 2022-09-14 21 | */ 22 | @Service 23 | public class MenuServiceImpl extends ServiceImpl implements IMenuService { 24 | 25 | @Override 26 | public List findMenus(String name) { 27 | QueryWrapper queryWrapper = new QueryWrapper<>(); 28 | if (StrUtil.isNotBlank(name)) { 29 | queryWrapper.like("name", name); 30 | } 31 | // 查询所有数据 32 | List list = list(queryWrapper); 33 | // 找出pid为null的一级菜单 34 | List parentNodes = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList()); 35 | // 找出一级菜单的子菜单 36 | for (Menu menu : parentNodes) { 37 | // 筛选所有数据中pid=父级id的数据就是二级菜单 38 | menu.setChildren(list.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList())); 39 | } 40 | return parentNodes; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/RoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.ironmanjay.springboot.entity.Menu; 6 | import com.ironmanjay.springboot.entity.Role; 7 | import com.ironmanjay.springboot.entity.RoleMenu; 8 | import com.ironmanjay.springboot.mapper.RoleMapper; 9 | import com.ironmanjay.springboot.mapper.RoleMenuMapper; 10 | import com.ironmanjay.springboot.service.IMenuService; 11 | import com.ironmanjay.springboot.service.IRoleService; 12 | import org.springframework.stereotype.Service; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.List; 16 | 17 | /** 18 | *

19 | * 服务实现类 20 | *

21 | * 22 | * @author IronmanJay 23 | * @since 2022-09-14 24 | */ 25 | @Service 26 | public class RoleServiceImpl extends ServiceImpl implements IRoleService { 27 | 28 | @Resource 29 | private RoleMenuMapper roleMenuMapper; 30 | 31 | @Resource 32 | private IMenuService menuService; 33 | 34 | @Override 35 | public void setRoleMenu(Integer roleId, List menuIds) { 36 | // 先删除当前角色id所有的绑定关系 37 | roleMenuMapper.deleteByRoleId(roleId); 38 | // 再把前端传过来的菜单id数组绑定到当前的这个角色id上去 39 | List menuIdsCopy = CollUtil.newArrayList(menuIds); 40 | for (Integer menuId : menuIds) { 41 | Menu menu = menuService.getById(menuId); 42 | if (menu.getPid() != null && !menuIdsCopy.contains(menu.getPid())) { // 二级菜单 并且传过来的menuId数组里面没有它的父级id 43 | // 那么我们就得补上这个父级id 44 | RoleMenu roleMenu = new RoleMenu(); 45 | roleMenu.setRoleId(roleId); 46 | roleMenu.setMenuId(menu.getPid()); 47 | roleMenuMapper.insert(roleMenu); 48 | menuIdsCopy.add(menu.getPid()); 49 | } 50 | RoleMenu roleMenu = new RoleMenu(); 51 | roleMenu.setRoleId(roleId); 52 | roleMenu.setMenuId(menuId); 53 | roleMenuMapper.insert(roleMenu); 54 | } 55 | } 56 | 57 | @Override 58 | public List getRoleMenu(Integer roleId) { 59 | return roleMenuMapper.selectByRoleId(roleId); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.service.impl; 2 | 3 | import cn.hutool.core.bean.BeanUtil; 4 | import cn.hutool.log.Log; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 8 | import com.ironmanjay.springboot.common.Constants; 9 | import com.ironmanjay.springboot.controller.dto.UserDTO; 10 | import com.ironmanjay.springboot.controller.dto.UserPasswordDTO; 11 | import com.ironmanjay.springboot.entity.Menu; 12 | import com.ironmanjay.springboot.entity.User; 13 | import com.ironmanjay.springboot.exception.ServiceException; 14 | import com.ironmanjay.springboot.mapper.RoleMapper; 15 | import com.ironmanjay.springboot.mapper.RoleMenuMapper; 16 | import com.ironmanjay.springboot.mapper.UserMapper; 17 | import com.ironmanjay.springboot.service.IMenuService; 18 | import com.ironmanjay.springboot.service.IUserService; 19 | import com.ironmanjay.springboot.utils.TokenUtils; 20 | import org.springframework.stereotype.Service; 21 | 22 | import javax.annotation.Resource; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * @author IronmanJay 28 | * @since 2022-07-25 29 | */ 30 | @Service 31 | public class UserServiceImpl extends ServiceImpl implements IUserService { 32 | 33 | // 用于打印错误日志 34 | private static final Log LOG = Log.get(); 35 | 36 | @Resource 37 | private RoleMapper roleMapper; 38 | 39 | @Resource 40 | private RoleMenuMapper roleMenuMapper; 41 | 42 | @Resource 43 | private IMenuService menuService; 44 | 45 | @Resource 46 | private UserMapper userMapper; 47 | 48 | /** 49 | * 用户登录 50 | * 51 | * @param userDTO 用户类 52 | * @return 返回登录结果 53 | */ 54 | @Override 55 | public UserDTO login(UserDTO userDTO) { 56 | User one = getUserInfo(userDTO); 57 | if (one != null) { 58 | BeanUtil.copyProperties(one, userDTO, true); 59 | // 设置token 60 | String token = TokenUtils.genToken(one.getId().toString(), one.getPassword()); 61 | userDTO.setToken(token); 62 | String role = one.getRole(); // ROLE_ADMIN 63 | // 设置用户的菜单列表 64 | List roleMenus = getRoleMenus(role); 65 | userDTO.setMenus(roleMenus); 66 | return userDTO; 67 | } else { 68 | throw new ServiceException(Constants.CODE_600, "用户名或密码错误"); 69 | } 70 | } 71 | 72 | /** 73 | * 获取当前角色的菜单列表 74 | * 75 | * @param roleFlag 当前角色唯一标识 76 | * @return 返回当前角色的菜单列表 77 | */ 78 | private List getRoleMenus(String roleFlag) { 79 | Integer roleId = roleMapper.selectByFlag(roleFlag); 80 | // 当前角色所有菜单id集合 81 | List menuIds = roleMenuMapper.selectByRoleId(roleId); 82 | // 查出系统所有的菜单 83 | List menus = menuService.findMenus(""); 84 | // new一个最后筛选完成之后的list 85 | List roleMenus = new ArrayList<>(); 86 | // 筛选当前用户角色的菜单 87 | for (Menu menu : menus) { 88 | if (menuIds.contains(menu.getId())) { 89 | roleMenus.add(menu); 90 | } 91 | List children = menu.getChildren(); 92 | // removeIf 移除 children 里面不在 menuIds集合中的元素 93 | children.removeIf(child -> !menuIds.contains(child.getId())); 94 | } 95 | return roleMenus; 96 | } 97 | 98 | /** 99 | * 用户注册 100 | * 101 | * @param userDTO 用户类 102 | * @return 返回注册结果 103 | */ 104 | @Override 105 | public User register(UserDTO userDTO) { 106 | User one = getUserInfo(userDTO); 107 | if (one == null) { 108 | one = new User(); 109 | BeanUtil.copyProperties(userDTO, one, true); 110 | save(one); // 把copy完的用户对象存储到数据库 111 | } else { 112 | throw new ServiceException(Constants.CODE_600, "用户已存在"); 113 | } 114 | return null; 115 | } 116 | 117 | /** 118 | * 判断当前用户是否存在 119 | * 120 | * @param userDTO 待判断用户 121 | * @return 判断结果 122 | */ 123 | private User getUserInfo(UserDTO userDTO) { 124 | QueryWrapper queryWrapper = new QueryWrapper<>(); 125 | queryWrapper.eq("username", userDTO.getUsername()); 126 | queryWrapper.eq("password", userDTO.getPassword()); 127 | User one; 128 | try { 129 | one = getOne(queryWrapper); 130 | } catch (Exception e) { 131 | // 在控制台打印错误日志 132 | LOG.error(e); 133 | throw new ServiceException(Constants.CODE_600, "系统错误"); 134 | } 135 | return one; 136 | } 137 | 138 | @Override 139 | public void updatePassword(UserPasswordDTO userPasswordDTO) { 140 | int update = userMapper.updatePassword(userPasswordDTO); 141 | if (update < 1) { 142 | throw new ServiceException(Constants.CODE_600, "密码错误"); 143 | } 144 | } 145 | 146 | @Override 147 | public Page findPage(Page page, String username, String email, String address) { 148 | return userMapper.findPage(page, username, email, address); 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/utils/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.utils; 2 | 3 | import com.baomidou.mybatisplus.generator.FastAutoGenerator; 4 | import com.baomidou.mybatisplus.generator.config.OutputFile; 5 | 6 | import java.util.Collections; 7 | 8 | /** 9 | * mp代码生成器 10 | * by IronmanJay 11 | * @since 2022-07-25 12 | */ 13 | public class CodeGenerator { 14 | 15 | public static void main(String[] args) { 16 | generate(); 17 | } 18 | 19 | private static void generate() { 20 | FastAutoGenerator.create("jdbc:mysql://localhost:3306/bms?serverTimezone=GMT%2b8", "root", "990929") 21 | .globalConfig(builder -> { 22 | builder.author("IronmanJay") // 设置作者 23 | .enableSwagger() // 开启 swagger 模式 24 | .fileOverride() // 覆盖已生成文件 25 | .outputDir("D:\\Software\\Java_Code\\BackgroundManagementSystemBasedOnSpringBootAndVue\\src\\main\\java\\"); // 指定输出目录 26 | }) 27 | .packageConfig(builder -> { 28 | builder.parent("com.ironmanjay.springboot") // 设置父包名 29 | .moduleName(null) // 设置父包模块名 30 | .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D:\\Software\\Java_Code\\BackgroundManagementSystemBasedOnSpringBootAndVue\\src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径 31 | }) 32 | .strategyConfig(builder -> { 33 | builder.entityBuilder().enableLombok(); 34 | builder.controllerBuilder().enableHyphenStyle() // 开启驼峰转连字符 35 | .enableRestStyle(); // 开启生成@RestController 控制器 36 | builder.addInclude("t_comment") // 设置需要生成的表名 37 | .addTablePrefix("t_", "sys_"); // 设置过滤表前缀 38 | }) 39 | .execute(); 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/ironmanjay/springboot/utils/TokenUtils.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot.utils; 2 | 3 | import cn.hutool.core.date.DateUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.auth0.jwt.JWT; 6 | import com.auth0.jwt.algorithms.Algorithm; 7 | import com.ironmanjay.springboot.entity.User; 8 | import com.ironmanjay.springboot.service.IUserService; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.context.request.RequestContextHolder; 11 | import org.springframework.web.context.request.ServletRequestAttributes; 12 | 13 | import javax.annotation.PostConstruct; 14 | import javax.annotation.Resource; 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.util.Date; 17 | 18 | @Component 19 | public class TokenUtils { 20 | 21 | private static IUserService staticUserService; 22 | 23 | @Resource 24 | private IUserService userService; 25 | 26 | @PostConstruct 27 | public void setUserService() { 28 | staticUserService = userService; 29 | } 30 | 31 | /** 32 | * 生成Token 33 | * 34 | * @param userId 用户的id 35 | * @param sign 用户的信息 36 | * @return 返回生产的Token 37 | */ 38 | public static String genToken(String userId, String sign) { 39 | // 将 userId 保存到 token 里面,作为载荷 40 | // 2小时后token过期 41 | // 以 password 作为 token 的密钥 42 | return JWT.create().withAudience(userId).withExpiresAt(DateUtil.offsetHour(new Date(), 2)).sign(Algorithm.HMAC256(sign)); 43 | } 44 | 45 | public static User getCurrentUser() { 46 | try { 47 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 48 | String token = request.getHeader("token"); 49 | if (StrUtil.isNotBlank(token)) { 50 | String userId = JWT.decode(token).getAudience().get(0); 51 | return staticUserService.getById(Integer.valueOf(userId)); 52 | } 53 | } catch (Exception e) { 54 | return null; 55 | } 56 | return null; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": [ 3 | { 4 | "name": "files.upload.path", 5 | "type": "java.lang.String", 6 | "description": "Description for files.upload.path." 7 | } 8 | ] } -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 修改后端服务的端口号,以免和前端服务端口号冲突 2 | server: 3 | port: 9090 4 | 5 | spring: 6 | datasource: 7 | driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySql数据库驱动 8 | url: jdbc:mysql://localhost:3306/bms?serverTimezone=GMT%2b8 # 配置MySql的url 9 | username: root # 配置数据库的用户名 10 | password: 990929 # 配置数据库的密码 11 | redis: 12 | host: 127.0.0.1 13 | port: 6379 14 | servlet: 15 | multipart: 16 | max-file-size: 100MB 17 | max-request-size: 100MB 18 | mvc: 19 | pathmatch: 20 | matching-strategy: ant_path_matcher # 解决Springboot与Swagger-Ui版本不兼容的问题 21 | 22 | # 扫描所有mybatis的xml文件 23 | mybatis: 24 | mapper-locations: classpath:mapper/*.xml 25 | 26 | # Mybatis-Plus的日志 27 | mybatis-plus: 28 | configuration: 29 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 30 | 31 | # 文件的保存地址 32 | files: 33 | upload: 34 | path: D:/Software/Java_Code/BackgroundManagementSystemBasedOnSpringBootAndVue/src/main/resources/files/ 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/files/062e1e4d241e4abfa6f3d320f4c09a9d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/062e1e4d241e4abfa6f3d320f4c09a9d.png -------------------------------------------------------------------------------- /src/main/resources/files/132317f9756d4807a30df821c2ce3a83.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/132317f9756d4807a30df821c2ce3a83.mp4 -------------------------------------------------------------------------------- /src/main/resources/files/2007e9c9bdfe447c825056a139bec221.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/2007e9c9bdfe447c825056a139bec221.png -------------------------------------------------------------------------------- /src/main/resources/files/2a827fa7d68640b1b21494327daa1e56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/2a827fa7d68640b1b21494327daa1e56.png -------------------------------------------------------------------------------- /src/main/resources/files/bfd885550582475f9fe33d92ff70a070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/bfd885550582475f9fe33d92ff70a070.png -------------------------------------------------------------------------------- /src/main/resources/files/c349b95aec2b464dbd826b94648ba1a4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/c349b95aec2b464dbd826b94648ba1a4.png -------------------------------------------------------------------------------- /src/main/resources/files/fcc27fb1e8864a77ad83d4dccefc55b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/src/main/resources/files/fcc27fb1e8864a77ad83d4dccefc55b2.png -------------------------------------------------------------------------------- /src/main/resources/mapper/ArticleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/mapper/CommentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/mapper/CourseMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | delete from student_course where student_id = #{studentId} and course_id = #{courseId} 7 | 8 | 9 | 10 | insert into student_course(student_id,course_id) values(#{studentId},#{courseId}) 11 | 12 | 13 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/mapper/MenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/mapper/RoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | update sys_user set `password` = #{userPasswordDTO.newPassword} where `username` = #{userPasswordDTO.username}; 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/resources/templates/controller.java.vm: -------------------------------------------------------------------------------- 1 | package ${package.Controller}; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import org.springframework.web.bind.annotation.*; 6 | import javax.annotation.Resource; 7 | import java.util.List; 8 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 9 | import com.ironmanjay.springboot.common.Result; 10 | 11 | import ${package.Service}.${table.serviceName}; 12 | import ${package.Entity}.${entity}; 13 | 14 | #if(${restControllerStyle}) 15 | import org.springframework.web.bind.annotation.RestController; 16 | #else 17 | import org.springframework.stereotype.Controller; 18 | #end 19 | #if(${superControllerClassPackage}) 20 | import ${superControllerClassPackage}; 21 | #end 22 | 23 | /** 24 | *

25 | * $!{table.comment} 前端控制器 26 | *

27 | * 28 | * @author ${author} 29 | * @since ${date} 30 | */ 31 | #if(${restControllerStyle}) 32 | @RestController 33 | #else 34 | @Controller 35 | #end 36 | @RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end") 37 | #if(${kotlin}) 38 | class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end 39 | 40 | #else 41 | #if(${superControllerClass}) 42 | public class ${table.controllerName} extends ${superControllerClass} { 43 | #else 44 | public class ${table.controllerName} { 45 | #end 46 | 47 | @Resource 48 | private ${table.serviceName} ${table.entityPath}Service; 49 | 50 | // 新增或者更新 51 | @PostMapping 52 | public Result save(@RequestBody ${entity} ${table.entityPath}) { 53 | ${table.entityPath}Service.saveOrUpdate(${table.entityPath}); 54 | return Result.success(); 55 | } 56 | 57 | @DeleteMapping("/{id}") 58 | public Result delete(@PathVariable Integer id) { 59 | ${table.entityPath}Service.removeById(id); 60 | return Result.success(); 61 | } 62 | 63 | @PostMapping("/del/batch") 64 | public Result deleteBatch(@RequestBody List ids) { 65 | ${table.entityPath}Service.removeByIds(ids); 66 | return Result.success(); 67 | } 68 | 69 | @GetMapping 70 | public Result findAll() { 71 | return Result.success(${table.entityPath}Service.list()); 72 | } 73 | 74 | @GetMapping("/{id}") 75 | public Result findOne(@PathVariable Integer id) { 76 | return Result.success(${table.entityPath}Service.getById(id)); 77 | } 78 | 79 | @GetMapping("/page") 80 | public Result findPage(@RequestParam Integer pageNum, 81 | @RequestParam Integer pageSize) { 82 | QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>(); 83 | queryWrapper.orderByDesc("id"); 84 | return Result.success(${table.entityPath}Service.page(new Page<>(pageNum, pageSize), queryWrapper)); 85 | } 86 | 87 | } 88 | 89 | #end 90 | -------------------------------------------------------------------------------- /src/test/java/com/ironmanjay/springboot/SpringbootApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.ironmanjay.springboot; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /vue/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /vue/README.md: -------------------------------------------------------------------------------- 1 | # vue 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Customize configuration 19 | See [Configuration Reference](https://cli.vuejs.org/config/). 20 | -------------------------------------------------------------------------------- /vue/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vue/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.27.2", 11 | "core-js": "^3.8.3", 12 | "echarts": "^5.3.3", 13 | "element-ui": "^2.15.9", 14 | "mavon-editor": "^2.10.4", 15 | "video.js": "^7.20.3", 16 | "vue": "^2.6.14", 17 | "vue-router": "^3.5.1", 18 | "vue-video-player": "^5.0.2", 19 | "vuex": "^3.6.2" 20 | }, 21 | "devDependencies": { 22 | "@vue/cli-plugin-babel": "~5.0.0", 23 | "@vue/cli-plugin-router": "~5.0.0", 24 | "@vue/cli-service": "~5.0.0", 25 | "vue-template-compiler": "^2.6.14" 26 | }, 27 | "browserslist": [ 28 | "> 1%", 29 | "last 2 versions", 30 | "not dead" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/vue/public/favicon.ico -------------------------------------------------------------------------------- /vue/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /vue/src/assets/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/vue/src/assets/404.png -------------------------------------------------------------------------------- /vue/src/assets/gloable.css: -------------------------------------------------------------------------------- 1 | /** 2 | 本css作为全局css样式使用 3 | */ 4 | 5 | /*消除页面下方白边,统一格式*/ 6 | *{ 7 | margin: 0; 8 | padding: 0; 9 | box-sizing: border-box; 10 | } 11 | 12 | /*以下三项为全局的自定义样式,方便调用*/ 13 | .ml-5 { 14 | margin-left: 5px; 15 | } 16 | .mr-5 { 17 | margin-right: 5px; 18 | } 19 | .pd-10 { 20 | padding: 10px 0; 21 | } -------------------------------------------------------------------------------- /vue/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/vue/src/assets/logo.png -------------------------------------------------------------------------------- /vue/src/assets/logoSub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IronmanJay/BackgroundManagementSystemBasedOnSpringBootAndVue/848438e0e12459b2b7bd3c2c05ea618625e48213/vue/src/assets/logoSub.png -------------------------------------------------------------------------------- /vue/src/components/Aside.vue: -------------------------------------------------------------------------------- 1 | 2 | 39 | 40 | 55 | 56 | 57 | 73 | -------------------------------------------------------------------------------- /vue/src/components/Header.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 58 | 59 | 61 | -------------------------------------------------------------------------------- /vue/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /vue/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import ElementUI from 'element-ui'; 5 | import 'element-ui/lib/theme-chalk/index.css'; 6 | // 引入全局css样式 7 | import './assets/gloable.css' 8 | // 引入request.js 9 | import request from "@/utils/request"; 10 | import store from './store/store' 11 | 12 | // main.js全局注册 13 | import mavonEditor from 'mavon-editor' 14 | import 'mavon-editor/dist/css/index.css' 15 | // use 16 | Vue.use(mavonEditor) 17 | 18 | Vue.config.productionTip = false; 19 | 20 | // 设置大小,适配屏幕 21 | Vue.use(ElementUI, {size: "mini"}); 22 | 23 | // 引入request.js 24 | Vue.prototype.request = request 25 | 26 | new Vue({ 27 | router, 28 | store, 29 | render: h => h(App) 30 | }).$mount('#app') 31 | -------------------------------------------------------------------------------- /vue/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import store from "@/store/store"; 4 | 5 | Vue.use(VueRouter) 6 | 7 | const routes = [ 8 | // 用户登陆页面 9 | { 10 | path: '/login', 11 | name: 'Login', 12 | component: () => import('../views/Login.vue') 13 | }, 14 | // 用户注册页面 15 | { 16 | path: '/register', 17 | name: 'Register', 18 | component: () => import('../views/Register.vue') 19 | }, 20 | { 21 | path: '/404', 22 | name: '404', 23 | component: () => import('../views/404.vue') 24 | }, 25 | { 26 | path: '/front', 27 | name: 'Front', 28 | component: () => import('../views/front/Front.vue'), 29 | children: [ 30 | { 31 | path: 'home', 32 | name: 'FrontHome', 33 | component: () => import('../views/front/Home.vue') 34 | }, 35 | { 36 | path: 'video', 37 | name: 'FrontVideo', 38 | component: () => import('../views/front/Video.vue') 39 | }, 40 | { 41 | path: 'videoDetail', 42 | name: 'FrontVideoDetail', 43 | component: () => import('../views/front/VideoDetail.vue') 44 | }, 45 | { 46 | path: 'article', 47 | name: 'FrontArticle', 48 | component: () => import('../views/front/Article.vue') 49 | }, 50 | { 51 | path: 'articleDetail', 52 | name: 'FrontArticleDetail', 53 | component: () => import('../views/front/ArticleDetail.vue') 54 | }, 55 | ] 56 | }, 57 | ] 58 | 59 | const router = new VueRouter({ 60 | mode: 'history', 61 | base: process.env.BASE_URL, 62 | routes 63 | }) 64 | 65 | // 提供一个重置路由的方法 66 | export const resetRouter = () => { 67 | router.matcher = new VueRouter({ 68 | mode: 'history', 69 | base: process.env.BASE_URL, 70 | routes 71 | }) 72 | } 73 | 74 | // 注意:刷新页面会导致页面路由重置 75 | export const setRoutes = () => { 76 | const storeMenus = localStorage.getItem("menus"); 77 | if (storeMenus) { 78 | // 拼装动态路由 79 | const manageRoute = { 80 | path: '/', 81 | name: 'Manage', 82 | component: () => import('../views/Manage.vue'), 83 | redirect: "/home", 84 | children: [ 85 | {path: 'person', name: '个人信息', component: () => import('../views/Person.vue')}, 86 | {path: 'password', name: '修改密码', component: () => import('../views/Password.vue')} 87 | ] 88 | } 89 | const menus = JSON.parse(storeMenus) 90 | menus.forEach(item => { 91 | if (item.path) { // 当且仅当path不为空的时候才去设置路由 92 | let itemMenu = { 93 | path: item.path.replace("/", ""), 94 | name: item.name, 95 | component: () => import('../views/' + item.pagePath + '.vue') 96 | } 97 | manageRoute.children.push(itemMenu) 98 | } else if (item.children.length) { 99 | item.children.forEach(item => { 100 | if (item.path) { 101 | let itemMenu = { 102 | path: item.path.replace("/", ""), 103 | name: item.name, 104 | component: () => import('../views/' + item.pagePath + '.vue') 105 | } 106 | manageRoute.children.push(itemMenu) 107 | } 108 | }) 109 | } 110 | }) 111 | // 获取当前的路由对象名称数组 112 | const currentRouteNames = router.getRoutes().map(v => v.name) 113 | if (!currentRouteNames.includes("Manage")) { 114 | // 动态添加到现在的路由对象中去 115 | router.addRoute(manageRoute) 116 | } 117 | } 118 | } 119 | 120 | // 重置我就再set一次路由 121 | setRoutes() 122 | 123 | // 路由守卫 124 | router.beforeEach((to, from, next) => { 125 | localStorage.setItem("currentPathName", to.name) // 设置当前的路由名称,为了在Header组件中去使用 126 | store.commit("setPath") // 触发store的数据更新 127 | // 未找到路由的情况 128 | if (!to.matched.length) { 129 | const storeMenus = localStorage.getItem("menus") 130 | if (storeMenus) { 131 | next("/404") 132 | } else { 133 | // 跳回登录页面 134 | next("/login") 135 | } 136 | } 137 | next() // 放行路由 138 | }) 139 | 140 | export default router -------------------------------------------------------------------------------- /vue/src/store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import router, {resetRouter} from "@/router"; 4 | 5 | Vue.use(Vuex) 6 | 7 | const store = new Vuex.Store({ 8 | state: { 9 | currentPathName: '' 10 | }, 11 | mutations: { 12 | setPath(state) { 13 | state.currentPathName = localStorage.getItem("currentPathName") 14 | }, 15 | logout() { 16 | // 清空缓存 17 | localStorage.removeItem("user") 18 | localStorage.removeItem("menus") 19 | router.push("/login") 20 | // 重置路由 21 | resetRouter() 22 | } 23 | } 24 | }) 25 | 26 | export default store -------------------------------------------------------------------------------- /vue/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import ElementUI from 'element-ui' 3 | 4 | const request = axios.create({ 5 | baseURL: 'http://localhost:9090', 6 | timeout: 30000 7 | }) 8 | 9 | // request 拦截器 10 | // 可以自请求发送前对请求做一些处理 11 | // 比如统一加token,对请求参数统一加密 12 | request.interceptors.request.use(config => { 13 | config.headers['Content-Type'] = 'application/json;charset=utf-8'; 14 | let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {} 15 | if (user) { 16 | config.headers['token'] = user.token; // 设置请求头 17 | } 18 | return config 19 | }, error => { 20 | return Promise.reject(error) 21 | }); 22 | 23 | // response 拦截器 24 | // 可以在接口响应后统一处理结果 25 | request.interceptors.response.use( 26 | response => { 27 | let res = response.data; 28 | // 如果是返回的文件 29 | if (response.config.responseType === 'blob') { 30 | return res 31 | } 32 | // 兼容服务端返回的字符串数据 33 | if (typeof res === 'string') { 34 | res = res ? JSON.parse(res) : res 35 | } 36 | // 当权限验证不通过的时候给出提示 37 | if (res.code == '401') { 38 | ElementUI.Message({ 39 | message: res.msg, 40 | type: 'error' 41 | }); 42 | } 43 | return res; 44 | }, 45 | error => { 46 | console.log('err' + error) // for debug 47 | return Promise.reject(error) 48 | } 49 | ) 50 | 51 | 52 | export default request -------------------------------------------------------------------------------- /vue/src/views/404.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /vue/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 42 | 43 | -------------------------------------------------------------------------------- /vue/src/views/Article.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 230 | 231 | -------------------------------------------------------------------------------- /vue/src/views/Course.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 213 | 214 | -------------------------------------------------------------------------------- /vue/src/views/File.vue: -------------------------------------------------------------------------------- 1 | 71 | 72 | 157 | 158 | -------------------------------------------------------------------------------- /vue/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 187 | 188 | -------------------------------------------------------------------------------- /vue/src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 72 | 73 | -------------------------------------------------------------------------------- /vue/src/views/Manage.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 72 | -------------------------------------------------------------------------------- /vue/src/views/Map.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 101 | 102 | -------------------------------------------------------------------------------- /vue/src/views/Menu.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 94 | 201 | 202 | -------------------------------------------------------------------------------- /vue/src/views/Password.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 68 | 69 | 98 | -------------------------------------------------------------------------------- /vue/src/views/Person.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 79 | 80 | 113 | -------------------------------------------------------------------------------- /vue/src/views/Register.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 72 | 73 | -------------------------------------------------------------------------------- /vue/src/views/front/Article.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 165 | 166 | -------------------------------------------------------------------------------- /vue/src/views/front/ArticleDetail.vue: -------------------------------------------------------------------------------- 1 | 113 | 114 | 181 | 182 | -------------------------------------------------------------------------------- /vue/src/views/front/Front.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 84 | 85 | 102 | -------------------------------------------------------------------------------- /vue/src/views/front/Home.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 48 | 49 | 52 | -------------------------------------------------------------------------------- /vue/src/views/front/Video.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 33 | 34 | 40 | -------------------------------------------------------------------------------- /vue/src/views/front/VideoDetail.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 58 | 59 | 62 | -------------------------------------------------------------------------------- /vue/vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | module.exports = defineConfig({ 3 | transpileDependencies: true 4 | }) 5 | --------------------------------------------------------------------------------