相关推荐recommended
云上办公系统项目
作者:mmseoamin日期:2023-11-30

云上办公系统项目

  • 1、云上办公系统
    • 1.1、介绍
    • 1.2、核心技术
    • 1.3、开发环境说明
    • 1.4、产品展示
      • 后台
      • 前台
      • 1.5、 个人总结
      • 2、后端环境搭建
        • 2.1、建库建表
        • 2.2、创建Maven项目
          • pom文件
            • guigu-oa-parent
            • common
            • common-util
            • service-util
            • model
            • service-oa
            • 配置数据源、服务器端口号
              • application.yml
              • application-dev.yml
              • 导入实体类
              • 2.3、编写代码
                • 启动类
                • 3、后端角色管理
                  • 3.1、查询所有角色
                    • SysRoleMapper
                    • SysRoleService
                    • SysRoleServiceImpl
                    • 编写测试类
                    • 编写统一结果返回类
                      • ResultCodeEnum
                      • Result
                      • SysRoleController
                      • 测试
                      • 3.2、集成knife4j
                          • Swagger介绍
                          • 目的
                          • 使用步骤
                            • 添加依赖
                            • 添加knife4j配置类
                            • Controller层添加注解
                            • 测试
                            • 3.3、分页查询所有角色
                                • MybatisPlusConfig
                                • 主启动类上添加包扫描
                                • SysRoleController
                                • 测试
                                • 3.4、添加/修改/删除角色
                                  • 测试
                                  • 4、统一异常处理
                                    • 4.1、全局异常处理
                                    • 4.2、特定异常处理
                                    • 4.3、自定义异常处理
                                      • GlobalExceptionHandler
                                      • GuiguException
                                      • 5、前端环境搭建
                                        • 安装脚手架工程
                                        • 前后联调的流程
                                          • 修改前端的IP地址
                                          • 编写后台登录/登出的请求
                                          • 修改前端的跳转地址
                                          • 修改响应状态码
                                          • 测试
                                          • 6、前端角色管理
                                            • 6.1、角色列表
                                              • 修改路由
                                              • 创建角色页面
                                              • 定义角色管理相关的API请求函数
                                              • 测试
                                              • 6.2、角色删除
                                                • sysRole.js
                                                • list.vue
                                                • 6.3、角色添加
                                                • 6.4、角色修改与数据回显
                                                • 6.5、批量删除
                                                  • sysRole.js
                                                  • list.vue
                                                  • 页面展示
                                                  • 7、用户管理
                                                    • 7.1、用户管理CRUD
                                                      • 需求分析
                                                      • 代码生成器
                                                      • 编写代码
                                                      • 测试
                                                      • 整合前端
                                                        • 前端页面 list.vue
                                                        • 添加路由
                                                        • 定义API接口
                                                        • 页面展示
                                                        • 7.2、用户管理分配角色
                                                          • 需求分析
                                                          • 接口分析
                                                          • 编写代码
                                                          • 前端展示
                                                          • 7.3、修改用户状态
                                                            • 需求分析
                                                            • 编写代码
                                                            • 整合前端
                                                              • 定义前端路由
                                                              • 修改前端页面
                                                              • 页面展示
                                                              • 8、菜单管理
                                                                • 8.1、菜单管理CRUD
                                                                  • 需求分析
                                                                  • 编写代码
                                                                  • 接口测试
                                                                  • 整合前端
                                                                    • sysMenu.js
                                                                    • list.vue
                                                                    • 页面展示
                                                                    • 8.2、角色分配菜单功能
                                                                      • 需求分析
                                                                      • 编写代码
                                                                      • 整合前端
                                                                        • router/index.js
                                                                        • sysRole/list.vue
                                                                        • sysMenu.js
                                                                        • assignAuth.vue
                                                                        • 页面展示
                                                                        • 9、权限管理(重难点)
                                                                          • 9.1、用户登录权限管理
                                                                            • 需求分析
                                                                            • 引入JWT
                                                                            • 修改用户登录
                                                                              • 先引入MD5工具类
                                                                              • 修改SysUserControler保存用户的方法
                                                                              • 修改IndexController的登录方法
                                                                              • SysMenuService
                                                                              • SysMenuServiceImpl
                                                                              • 接口测试
                                                                                • 登录接口测试
                                                                                • info接口测试
                                                                                • 整合前端
                                                                                • 页面展示
                                                                                • 9.2、用户认证
                                                                                  • 整合SpringSecurity
                                                                                    • 引入依赖
                                                                                    • 添加配置类
                                                                                    • 测试
                                                                                    • 用户认证
                                                                                      • 流程分析
                                                                                      • 自定义组件的编写
                                                                                        • 自定义加密器PasswordEncoder
                                                                                        • 自定义用户对象UserDetails
                                                                                        • UserDetailsService
                                                                                        • UserDetailsServiceImpl
                                                                                        • 自定义用户认证接口
                                                                                        • 认证解析token
                                                                                        • 配置用户认证
                                                                                        • 测试
                                                                                        • 9.3、用户权限控制
                                                                                          • 流程分析
                                                                                          • 修改代码
                                                                                            • spring-security模块配置redis
                                                                                            • 修改TokenLoginFilter
                                                                                            • 修改TokenAuthenticationFilter
                                                                                            • 修改WebSecurityConfig类
                                                                                            • service-oa模块添加redis配置
                                                                                            • 控制controller层接口权限
                                                                                            • 异常处理
                                                                                            • 测试
                                                                                            • 10、Activiti
                                                                                              • 10.1、Activiti流程操作
                                                                                                • 配置Activiti
                                                                                                  • 引入Activiti依赖
                                                                                                  • 添加配置
                                                                                                  • 重启项目
                                                                                                  • 使用activiti插件
                                                                                                    • 下载activiti-explorer
                                                                                                    • 解压部署
                                                                                                    • 访问activiti-explorer
                                                                                                    • 10.2、流程控制
                                                                                                      • 绘制流程
                                                                                                        • 新建
                                                                                                        • 绘制
                                                                                                        • 导出
                                                                                                        • 下载文件
                                                                                                        • 部署流程
                                                                                                        • 流程实例
                                                                                                        • 任务分配
                                                                                                        • 任务组
                                                                                                        • 10.3、网关
                                                                                                            • 排他网关
                                                                                                            • 并行网关
                                                                                                            • 包含网关
                                                                                                            • 11、审批管理
                                                                                                              • 11.1、审批设置--CRUD
                                                                                                              • 11.2、模板审批--CRUD
                                                                                                              • 11.3、添加审批模板
                                                                                                              • 11.4、查看审批模板
                                                                                                              • 11.5、审批列表
                                                                                                                • 分页查询
                                                                                                                • 页面展示
                                                                                                                • 部署流程定义
                                                                                                                • 12、前端审批
                                                                                                                  • 12.1、OA审批
                                                                                                                  • 13、代码托管
                                                                                                                    • Git
                                                                                                                    • Gitee
                                                                                                                    • GitHub
                                                                                                                    • 网盘资料

                                                                                                                      申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计13077字,阅读大概需要30分钟

                                                                                                                      更多学习内容, 欢迎关注我

                                                                                                                      个人公众号:不懂开发的程序猿

                                                                                                                      个人网站:https://jerry-jy.co/

                                                                                                                      【警告】本篇博客较长,若引起阅读不适,建议收藏,稍后再读

                                                                                                                      1、云上办公系统

                                                                                                                      1.1、介绍

                                                                                                                      云上办公系统是一套自动办公系统,系统主要包含:管理端和员工端

                                                                                                                      管理端包含:权限管理、审批管理、公众号菜单管理

                                                                                                                      员工端采用微信公众号操作,包含:办公审批、微信授权登录、消息推送等功能

                                                                                                                      项目服务器端架构:SpringBoot + MyBatisPlus + SpringSecurity + Redis + Activiti+ MySQL

                                                                                                                      前端架构:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios

                                                                                                                      1.2、核心技术

                                                                                                                      基础框架:SpringBoot
                                                                                                                      数据缓存:Redis
                                                                                                                      数据库:MySQL
                                                                                                                      权限控制:SpringSecurity
                                                                                                                      工作流引擎:Activiti
                                                                                                                      前端技术:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios
                                                                                                                      微信公众号:公众号菜单 + 微信授权登录 + 消息推送

                                                                                                                      1.3、开发环境说明

                                                                                                                      工具版本
                                                                                                                      后台SpringBoot 2.3.6 + MyBatisPlus 3.4.1
                                                                                                                      服务器Tomcat 8.5.73
                                                                                                                      数据库MySQL 8.0.27
                                                                                                                      Build ToolsMaven 3.8.5
                                                                                                                      前端Vue + ElementUI + Node.js 14.15.0
                                                                                                                      开发工具IDEA 2022.3
                                                                                                                      版本管理工具Git

                                                                                                                      1.4、产品展示

                                                                                                                      后台

                                                                                                                      登录页

                                                                                                                      云上办公系统项目,在这里插入图片描述,第1张

                                                                                                                      【系统管理】–【用户管理】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第2张

                                                                                                                      【系统管理】–【角色管理】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第3张

                                                                                                                      【系统管理】–【菜单管理】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第4张

                                                                                                                      【审批设置】–【审批类型】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第5张

                                                                                                                      【审批设置】–【审批模板】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第6张

                                                                                                                      【审批管理】–【审批列表】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第7张

                                                                                                                      【公众号菜单】–【菜单列表】

                                                                                                                      云上办公系统项目,在这里插入图片描述,第8张

                                                                                                                      前台

                                                                                                                      正常的前台页面是在微信公众号上,我这里没有整合

                                                                                                                      http://localhost:9090/#/

                                                                                                                      云上办公系统项目,在这里插入图片描述,第9张

                                                                                                                      审批页面

                                                                                                                      云上办公系统项目,在这里插入图片描述,第10张

                                                                                                                      测试号的页面展示

                                                                                                                      云上办公系统项目,在这里插入图片描述,第11张

                                                                                                                      1.5、 个人总结

                                                                                                                      我认为该项目对我来说主要的帮助有:

                                                                                                                      1、项目是前后端分离的,符合目前主流业务开发逻辑,作为后端程序员,复习前端Vue + ElementUI框架, 巩固练习使用前端的脚手架工程,学习使用前后端联调开发过程

                                                                                                                      2、项目中引入JWT加密token,用作用户登录身份校验,用 SpringSecurity 来做权限控制,涉及多表查询,是项目的重难点学习对象,也是对前面学习SpringSecurity的一个巩固

                                                                                                                      3、前端使用微信公众号来作为前端接入口,以前没有开发过,也是亮点。

                                                                                                                      4、引入 工作流引擎:Activiti 作为组件,第一次用,学习下

                                                                                                                      5、集成Swagger,方便进行接口API的统一测试

                                                                                                                      2、后端环境搭建

                                                                                                                      2.1、建库建表

                                                                                                                      db.sql

                                                                                                                      sql语句太多了,见文末的资料
                                                                                                                      

                                                                                                                      2.2、创建Maven项目

                                                                                                                      本项目采用Maven聚合模块来管理工程

                                                                                                                      云上办公系统项目,在这里插入图片描述,第12张

                                                                                                                      pom文件

                                                                                                                      guigu-oa-parent
                                                                                                                      
                                                                                                                        4.0.0
                                                                                                                        
                                                                                                                          org.springframework.boot
                                                                                                                          spring-boot-starter-parent
                                                                                                                          2.3.6.RELEASE
                                                                                                                        
                                                                                                                        com.jerry
                                                                                                                        guigu-oa-parent
                                                                                                                        1.0
                                                                                                                        pom
                                                                                                                        
                                                                                                                          common
                                                                                                                          model
                                                                                                                          service-oa
                                                                                                                        
                                                                                                                        
                                                                                                                          1.8
                                                                                                                          3.4.1
                                                                                                                          8.0.27
                                                                                                                          3.0.3
                                                                                                                          0.9.1
                                                                                                                          2.0.21
                                                                                                                        
                                                                                                                        
                                                                                                                        
                                                                                                                          
                                                                                                                            
                                                                                                                            
                                                                                                                              com.baomidou
                                                                                                                              mybatis-plus-boot-starter
                                                                                                                              ${mybatis-plus.version}
                                                                                                                            
                                                                                                                            
                                                                                                                            
                                                                                                                              mysql
                                                                                                                              mysql-connector-java
                                                                                                                              ${mysql.version}
                                                                                                                            
                                                                                                                            
                                                                                                                            
                                                                                                                              com.github.xiaoymin
                                                                                                                              knife4j-spring-boot-starter
                                                                                                                              ${knife4j.version}
                                                                                                                            
                                                                                                                            
                                                                                                                            
                                                                                                                              io.jsonwebtoken
                                                                                                                              jjwt
                                                                                                                              ${jwt.version}
                                                                                                                            
                                                                                                                            
                                                                                                                            
                                                                                                                              com.alibaba
                                                                                                                              fastjson
                                                                                                                              ${fastjson.version}
                                                                                                                            
                                                                                                                          
                                                                                                                        
                                                                                                                        
                                                                                                                          
                                                                                                                            
                                                                                                                              org.apache.maven.plugins
                                                                                                                              maven-compiler-plugin
                                                                                                                              3.1
                                                                                                                              
                                                                                                                                1.8
                                                                                                                                1.8
                                                                                                                              
                                                                                                                            
                                                                                                                          
                                                                                                                        
                                                                                                                      
                                                                                                                      
                                                                                                                      common
                                                                                                                      
                                                                                                                          4.0.0
                                                                                                                          
                                                                                                                              com.jerry
                                                                                                                              guigu-oa-parent
                                                                                                                              1.0
                                                                                                                          
                                                                                                                          common
                                                                                                                          pom
                                                                                                                          
                                                                                                                              common-util
                                                                                                                              service-util
                                                                                                                          
                                                                                                                      
                                                                                                                      
                                                                                                                      common-util
                                                                                                                      
                                                                                                                          4.0.0
                                                                                                                          
                                                                                                                              com.jerry
                                                                                                                              common
                                                                                                                              1.0
                                                                                                                          
                                                                                                                          common-util
                                                                                                                          jar
                                                                                                                          
                                                                                                                              
                                                                                                                                  org.springframework.boot
                                                                                                                                  spring-boot-starter-web
                                                                                                                                  provided 
                                                                                                                              
                                                                                                                              
                                                                                                                                  io.jsonwebtoken
                                                                                                                                  jjwt
                                                                                                                              
                                                                                                                              
                                                                                                                                  org.projectlombok
                                                                                                                                  lombok
                                                                                                                              
                                                                                                                              
                                                                                                                                  com.alibaba
                                                                                                                                  fastjson
                                                                                                                              
                                                                                                                          
                                                                                                                      
                                                                                                                      
                                                                                                                      service-util
                                                                                                                      
                                                                                                                          4.0.0
                                                                                                                          
                                                                                                                              com.jerry
                                                                                                                              common
                                                                                                                              1.0
                                                                                                                          
                                                                                                                          service-util
                                                                                                                          
                                                                                                                              
                                                                                                                                  com.jerry
                                                                                                                                  common-util
                                                                                                                                  1.0
                                                                                                                              
                                                                                                                              
                                                                                                                                  org.springframework.boot
                                                                                                                                  spring-boot-starter-web
                                                                                                                              
                                                                                                                              
                                                                                                                                  com.baomidou
                                                                                                                                  mybatis-plus-boot-starter
                                                                                                                              
                                                                                                                              
                                                                                                                              
                                                                                                                                  mysql
                                                                                                                                  mysql-connector-java
                                                                                                                              
                                                                                                                          
                                                                                                                      
                                                                                                                      
                                                                                                                      model
                                                                                                                      
                                                                                                                          4.0.0
                                                                                                                          
                                                                                                                              com.jerry
                                                                                                                              guigu-oa-parent
                                                                                                                              1.0
                                                                                                                          
                                                                                                                          model
                                                                                                                          
                                                                                                                              
                                                                                                                              
                                                                                                                                  org.projectlombok
                                                                                                                                  lombok
                                                                                                                              
                                                                                                                              
                                                                                                                                  com.github.xiaoymin
                                                                                                                                  knife4j-spring-boot-starter
                                                                                                                                  provided 
                                                                                                                              
                                                                                                                              
                                                                                                                                  com.baomidou
                                                                                                                                  mybatis-plus-boot-starter
                                                                                                                                  provided 
                                                                                                                              
                                                                                                                          
                                                                                                                      
                                                                                                                      
                                                                                                                      service-oa
                                                                                                                      
                                                                                                                          4.0.0
                                                                                                                          
                                                                                                                              com.jerry
                                                                                                                              guigu-oa-parent
                                                                                                                              1.0
                                                                                                                          
                                                                                                                          service-oa
                                                                                                                          jar
                                                                                                                          
                                                                                                                              
                                                                                                                                  com.jerry
                                                                                                                                  model
                                                                                                                                  1.0
                                                                                                                              
                                                                                                                              
                                                                                                                                  com.jerry
                                                                                                                                  service-util
                                                                                                                                  1.0
                                                                                                                              
                                                                                                                              
                                                                                                                                  org.springframework.boot
                                                                                                                                  spring-boot-starter-test
                                                                                                                                  test
                                                                                                                              
                                                                                                                          
                                                                                                                          
                                                                                                                              ${project.artifactId}
                                                                                                                              
                                                                                                                                  
                                                                                                                                      org.springframework.boot
                                                                                                                                      spring-boot-maven-plugin
                                                                                                                                  
                                                                                                                              
                                                                                                                          
                                                                                                                      
                                                                                                                      

                                                                                                                      配置数据源、服务器端口号

                                                                                                                      application.yml

                                                                                                                      云上办公系统项目,在这里插入图片描述,第13张

                                                                                                                      spring:
                                                                                                                        application:
                                                                                                                          name: service-oa
                                                                                                                        profiles:
                                                                                                                          active: dev
                                                                                                                      
                                                                                                                      application-dev.yml
                                                                                                                      server:
                                                                                                                        port: 8800
                                                                                                                      mybatis-plus:
                                                                                                                        configuration:
                                                                                                                          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
                                                                                                                      spring:
                                                                                                                        datasource:
                                                                                                                          type: com.zaxxer.hikari.HikariDataSource
                                                                                                                          driver-class-name: com.mysql.cj.jdbc.Driver
                                                                                                                          url: jdbc:mysql://localhost:3306/guigu-oa?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
                                                                                                                          username: root
                                                                                                                          password: root
                                                                                                                      

                                                                                                                      导入实体类

                                                                                                                      云上办公系统项目,在这里插入图片描述,第14张

                                                                                                                      2.3、编写代码

                                                                                                                      云上办公系统项目,在这里插入图片描述,第15张

                                                                                                                      启动类

                                                                                                                      package com.jerry.auth;
                                                                                                                      import org.springframework.boot.SpringApplication;
                                                                                                                      import org.springframework.boot.autoconfigure.SpringBootApplication;
                                                                                                                      /**
                                                                                                                       * ClassName: ServiceAuthApplication
                                                                                                                       * Package: com.jerry.auth
                                                                                                                       * Description:
                                                                                                                       *
                                                                                                                       * @Author jerry_jy
                                                                                                                       * @Create 2023-02-28 22:03
                                                                                                                       * @Version 1.0
                                                                                                                       */
                                                                                                                      @SpringBootApplication
                                                                                                                      public class ServiceAuthApplication {
                                                                                                                          public static void main(String[] args) {
                                                                                                                              SpringApplication.run(ServiceAuthApplication.class, args);
                                                                                                                          }
                                                                                                                      }
                                                                                                                      

                                                                                                                      3、后端角色管理

                                                                                                                      3.1、查询所有角色

                                                                                                                      SysRoleMapper

                                                                                                                      package com.jerry.auth.mapper;
                                                                                                                      import com.baomidou.mybatisplus.core.mapper.BaseMapper;
                                                                                                                      import com.jerry.model.system.SysRole;
                                                                                                                      import org.apache.ibatis.annotations.Mapper;
                                                                                                                      /**
                                                                                                                       * ClassName: SysRoleMapper
                                                                                                                       * Package: com.jerry.auth.mapper
                                                                                                                       * Description:
                                                                                                                       *
                                                                                                                       * @Author jerry_jy
                                                                                                                       * @Create 2023-02-28 22:05
                                                                                                                       * @Version 1.0
                                                                                                                       */
                                                                                                                      @Mapper
                                                                                                                      public interface SysRoleMapper extends BaseMapper {
                                                                                                                      }
                                                                                                                      

                                                                                                                      SysRoleService

                                                                                                                      package com.jerry.auth.service;
                                                                                                                      import com.baomidou.mybatisplus.extension.service.IService;
                                                                                                                      import com.jerry.model.system.SysRole;
                                                                                                                      /**
                                                                                                                       * ClassName: SysRoleService
                                                                                                                       * Package: com.jerry.auth.service
                                                                                                                       * Description:
                                                                                                                       *
                                                                                                                       * @Author jerry_jy
                                                                                                                       * @Create 2023-03-01 9:12
                                                                                                                       * @Version 1.0
                                                                                                                       */
                                                                                                                      public interface SysRoleService extends IService {
                                                                                                                      }
                                                                                                                      

                                                                                                                      SysRoleServiceImpl

                                                                                                                      package com.jerry.auth.service.impl;
                                                                                                                      import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
                                                                                                                      import com.jerry.auth.mapper.SysRoleMapper;
                                                                                                                      import com.jerry.auth.service.SysRoleService;
                                                                                                                      import com.jerry.model.system.SysRole;
                                                                                                                      import org.springframework.stereotype.Service;
                                                                                                                      /**
                                                                                                                       * ClassName: SysRoleServiceImpl
                                                                                                                       * Package: com.jerry.auth.service.impl
                                                                                                                       * Description:
                                                                                                                       *
                                                                                                                       * @Author jerry_jy
                                                                                                                       * @Create 2023-03-01 9:13
                                                                                                                       * @Version 1.0
                                                                                                                       */
                                                                                                                      @Service
                                                                                                                      public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService {
                                                                                                                      }
                                                                                                                      

                                                                                                                      编写测试类

                                                                                                                      目的是:

                                                                                                                      • 测试数据源连接
                                                                                                                      • 复习下MyBatisPlus对数据库的CRUD
                                                                                                                        package com.jerry.auth;
                                                                                                                        import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
                                                                                                                        import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
                                                                                                                        import com.jerry.auth.mapper.SysRoleMapper;
                                                                                                                        import com.jerry.auth.service.SysRoleService;
                                                                                                                        import com.jerry.model.system.SysRole;
                                                                                                                        import org.junit.jupiter.api.Test;
                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                        import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                        import java.util.Arrays;
                                                                                                                        import java.util.List;
                                                                                                                        /**
                                                                                                                         * ClassName: TestMpDemo1
                                                                                                                         * Package: com.jerry.auth
                                                                                                                         * Description:
                                                                                                                         *
                                                                                                                         * @Author jerry_jy
                                                                                                                         * @Create 2023-02-28 22:07
                                                                                                                         * @Version 1.0
                                                                                                                         */
                                                                                                                        @SpringBootTest
                                                                                                                        public class TestMpDemo1 {
                                                                                                                            // MyBatisPlus 对 service 层和 dao 层都做了很好的封装,直接调对应的CRUD方法就行
                                                                                                                            @Autowired
                                                                                                                            private SysRoleMapper sysRoleMapper;
                                                                                                                            @Autowired
                                                                                                                            private SysRoleService sysRoleService;
                                                                                                                            // 使用MP 封装的 service 来操作数据库,查询所有记录
                                                                                                                            @Test
                                                                                                                            public void getAllByService(){
                                                                                                                                List list = sysRoleService.list();
                                                                                                                                list.forEach(System.out::println);
                                                                                                                            }
                                                                                                                            // 使用MP 封装的 mapper查询所有记录
                                                                                                                            @Test
                                                                                                                            public void getAllByMapper(){
                                                                                                                                List sysRoles = sysRoleMapper.selectList(null);
                                                                                                                                sysRoles.forEach(System.out::println);
                                                                                                                            }
                                                                                                                            // 添加操作
                                                                                                                            @Test
                                                                                                                            public void insert(){
                                                                                                                                SysRole sysRole = new SysRole();
                                                                                                                                sysRole.setRoleName("角色管理员");
                                                                                                                                sysRole.setRoleCode("role");
                                                                                                                                sysRole.setDescription("角色管理员");
                                                                                                                                int result = sysRoleMapper.insert(sysRole);
                                                                                                                                System.out.println(result); //影响的行数
                                                                                                                                System.out.println(sysRole.getId()); //id自动回填
                                                                                                                            }
                                                                                                                            // 修改操作
                                                                                                                            @Test
                                                                                                                            public void updateById(){
                                                                                                                                // 根据id查询
                                                                                                                                SysRole sysRole = sysRoleMapper.selectById(9);
                                                                                                                                // 设置修改值
                                                                                                                                sysRole.setRoleName("角色管理员1");
                                                                                                                                // 调用方法实现最终修改
                                                                                                                                int update = sysRoleMapper.updateById(sysRole);
                                                                                                                                System.out.println("update = " + update); // 受影响的行数
                                                                                                                            }
                                                                                                                            // 根据id删除
                                                                                                                            @Test
                                                                                                                            public void deleteById(){
                                                                                                                                int delete = sysRoleMapper.deleteById(9);
                                                                                                                                System.out.println("delete = " + delete); // 受影响的行数
                                                                                                                            }
                                                                                                                            // 批量删除
                                                                                                                            @Test
                                                                                                                            public void deleteBatchByIds(){
                                                                                                                        //        int delete = sysRoleMapper.delete(null);
                                                                                                                                // 或者下面这种写法
                                                                                                                                int delete = sysRoleMapper.deleteBatchIds(Arrays.asList(1, 2));
                                                                                                                                System.out.println("ids = " + delete); // 受影响的行数
                                                                                                                            }
                                                                                                                            // 条件查询
                                                                                                                            @Test
                                                                                                                            public void testQueryWrapper(){
                                                                                                                        //        QueryWrapper queryWrapper = new QueryWrapper<>();
                                                                                                                        //        queryWrapper.eq("role_name", "系统管理员");
                                                                                                                                // 或者下面这种写法
                                                                                                                                LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                queryWrapper.eq(SysRole::getRoleName,"系统管理员");
                                                                                                                                List list = sysRoleMapper.selectList(queryWrapper);
                                                                                                                                list.forEach(System.out::println);
                                                                                                                            }
                                                                                                                        }
                                                                                                                        

                                                                                                                        编写统一结果返回类

                                                                                                                        目的:定义好统一的返回状态码和返回结果信息

                                                                                                                        ResultCodeEnum
                                                                                                                        package com.jerry.common.result;
                                                                                                                        import lombok.Getter;
                                                                                                                        /**
                                                                                                                         * ClassName: ResultCodeEnum
                                                                                                                         * Package: com.jerry.common.result
                                                                                                                         * Description:
                                                                                                                         *
                                                                                                                         * @Author jerry_jy
                                                                                                                         * @Create 2023-03-01 9:50
                                                                                                                         * @Version 1.0
                                                                                                                         */
                                                                                                                        @Getter
                                                                                                                        public enum ResultCodeEnum {
                                                                                                                            SUCCESS(200, "成功"),
                                                                                                                            FAIL(201, "失败"),
                                                                                                                            SERVICE_ERROR(2012, "服务异常"),
                                                                                                                            DATA_ERROR(204, "数据异常"),
                                                                                                                            LOGIN_AUTH(208, "未登陆"),
                                                                                                                            PERMISSION(209, "没有权限");
                                                                                                                            private Integer code;
                                                                                                                            private String message;
                                                                                                                            private ResultCodeEnum(Integer code, String message) {
                                                                                                                                this.code = code;
                                                                                                                                this.message = message;
                                                                                                                            }
                                                                                                                        }
                                                                                                                        
                                                                                                                        Result
                                                                                                                        package com.jerry.common.result;
                                                                                                                        import lombok.Data;
                                                                                                                        /**
                                                                                                                         * ClassName: Result
                                                                                                                         * Package: com.jerry.common.result
                                                                                                                         * Description:
                                                                                                                         *
                                                                                                                         * @Author jerry_jy
                                                                                                                         * @Create 2023-03-01 9:52
                                                                                                                         * @Version 1.0
                                                                                                                         */
                                                                                                                        @Data
                                                                                                                        public class Result {
                                                                                                                            private Integer code; // 状态码
                                                                                                                            private String message; // 返回信息
                                                                                                                            private T data; // 统一返回的结果数据
                                                                                                                            /**
                                                                                                                             * 封装返回数据
                                                                                                                             * @param body
                                                                                                                             * @param resultCodeEnum
                                                                                                                             * @return
                                                                                                                             * @param 
                                                                                                                             */
                                                                                                                            public static  Result build(T body, ResultCodeEnum resultCodeEnum) {
                                                                                                                                Result result = new Result<>();
                                                                                                                                // 封装数据
                                                                                                                                if (body!=null){
                                                                                                                                    result.setData(body);
                                                                                                                                }
                                                                                                                                // 状态码
                                                                                                                                result.setCode(resultCodeEnum.getCode());
                                                                                                                                //返回信息
                                                                                                                                result.setMessage(resultCodeEnum.getMessage());
                                                                                                                                return result;
                                                                                                                            }
                                                                                                                            // 构造私有化 外部不能new
                                                                                                                            private Result(){}
                                                                                                                            // 成功 空结果
                                                                                                                            public static Result ok(){
                                                                                                                                return build(null,ResultCodeEnum.SUCCESS);
                                                                                                                            }
                                                                                                                            /**
                                                                                                                             * 成功 返回有数据的结果
                                                                                                                             * @param data
                                                                                                                             * @return
                                                                                                                             * @param 
                                                                                                                             */
                                                                                                                            public static Result ok(T data){
                                                                                                                                return build(data,ResultCodeEnum.SUCCESS);
                                                                                                                            }
                                                                                                                            // 失败
                                                                                                                            public static Result fail(){
                                                                                                                                return build(null,ResultCodeEnum.FAIL);
                                                                                                                            }
                                                                                                                            /**
                                                                                                                             * 失败  返回有数据的结果
                                                                                                                             * @param data
                                                                                                                             * @return
                                                                                                                             * @param 
                                                                                                                             */
                                                                                                                            public static Result fail(T data){
                                                                                                                                return build(data,ResultCodeEnum.FAIL);
                                                                                                                            }
                                                                                                                            public Result message(String msg){
                                                                                                                                this.setMessage(msg);
                                                                                                                                return this;
                                                                                                                            }
                                                                                                                            public Result code(Integer code){
                                                                                                                                this.setCode(code);
                                                                                                                                return this;
                                                                                                                            }
                                                                                                                        }
                                                                                                                        

                                                                                                                        SysRoleController

                                                                                                                        package com.jerry.auth.controller;
                                                                                                                        import com.jerry.auth.service.SysRoleService;
                                                                                                                        import com.jerry.common.result.Result;
                                                                                                                        import com.jerry.model.system.SysRole;
                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                        import org.springframework.web.bind.annotation.GetMapping;
                                                                                                                        import org.springframework.web.bind.annotation.RequestMapping;
                                                                                                                        import org.springframework.web.bind.annotation.RestController;
                                                                                                                        import java.util.List;
                                                                                                                        /**
                                                                                                                         * ClassName: SysRoleController
                                                                                                                         * Package: com.jerry.auth.controller
                                                                                                                         * Description:
                                                                                                                         *
                                                                                                                         * @Author jerry_jy
                                                                                                                         * @Create 2023-03-01 9:38
                                                                                                                         * @Version 1.0
                                                                                                                         */
                                                                                                                        @RestController
                                                                                                                        @RequestMapping("/admin/system/sysRole")
                                                                                                                        public class SysRoleController {
                                                                                                                            @Autowired
                                                                                                                            private SysRoleService sysRoleService;
                                                                                                                            // http://localhost:8800/admin/system/sysRole/getAll
                                                                                                                            // 测试查询所有的角色
                                                                                                                        //    @GetMapping("/getAll")
                                                                                                                        //    private List getAll(){
                                                                                                                        //        List list = sysRoleService.list();
                                                                                                                        //        return list;
                                                                                                                        //    }
                                                                                                                            /**
                                                                                                                             * 统一返回数据结果
                                                                                                                             * @return
                                                                                                                             */
                                                                                                                            @GetMapping("/getAll")
                                                                                                                            private Result getAll(){
                                                                                                                                List list = sysRoleService.list();
                                                                                                                                return Result.ok(list);
                                                                                                                            }
                                                                                                                        }
                                                                                                                        

                                                                                                                        测试

                                                                                                                        http://localhost:8800/admin/system/sysRole/getAll

                                                                                                                        云上办公系统项目,在这里插入图片描述,第16张

                                                                                                                        3.2、集成knife4j

                                                                                                                        文档地址:https://doc.xiaominfo.com/

                                                                                                                        knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案。

                                                                                                                        Swagger介绍

                                                                                                                        前后端分离开发模式中,api文档是最好的沟通方式。

                                                                                                                        Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

                                                                                                                        1、及时性 (接口变更后,能够及时准确地通知相关前后端开发人员)

                                                                                                                        2、规范性 (并且保证接口的规范性,如接口的地址,请求方式,参数及响应格式和错误信息)

                                                                                                                        3、一致性 (接口信息一致,不会出现因开发人员拿到的文档版本不一致,而出现分歧)

                                                                                                                        4、可测性 (直接在接口文档上进行测试,以方便理解业务)

                                                                                                                        目的
                                                                                                                        • 用来生成接口的API文档

                                                                                                                        • 方便后端Java程序员进行接口测试

                                                                                                                          使用步骤
                                                                                                                          添加依赖

                                                                                                                          service-uitl.pom

                                                                                                                          
                                                                                                                              com.github.xiaoymin
                                                                                                                              knife4j-spring-boot-starter
                                                                                                                          
                                                                                                                          
                                                                                                                          添加knife4j配置类
                                                                                                                          package com.jerry.common.config.knife4j;
                                                                                                                          import org.springframework.context.annotation.Bean;
                                                                                                                          import org.springframework.context.annotation.Configuration;
                                                                                                                          import springfox.documentation.builders.ApiInfoBuilder;
                                                                                                                          import springfox.documentation.builders.ParameterBuilder;
                                                                                                                          import springfox.documentation.builders.PathSelectors;
                                                                                                                          import springfox.documentation.builders.RequestHandlerSelectors;
                                                                                                                          import springfox.documentation.schema.ModelRef;
                                                                                                                          import springfox.documentation.service.ApiInfo;
                                                                                                                          import springfox.documentation.service.Contact;
                                                                                                                          import springfox.documentation.service.Parameter;
                                                                                                                          import springfox.documentation.spi.DocumentationType;
                                                                                                                          import springfox.documentation.spring.web.plugins.Docket;
                                                                                                                          import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
                                                                                                                          import java.util.ArrayList;
                                                                                                                          import java.util.List;
                                                                                                                          /**
                                                                                                                           * ClassName: knife4j
                                                                                                                           * Package: com.jerry.common.config
                                                                                                                           * Description:
                                                                                                                           *
                                                                                                                           * @Author jerry_jy
                                                                                                                           * @Create 2023-03-01 10:53
                                                                                                                           * @Version 1.0
                                                                                                                           */
                                                                                                                          /**
                                                                                                                           * knife4j配置信息
                                                                                                                           */
                                                                                                                          @Configuration
                                                                                                                          @EnableSwagger2WebMvc
                                                                                                                          public class Knife4jConfig {
                                                                                                                              @Bean
                                                                                                                              public Docket adminApiConfig(){
                                                                                                                                  List pars = new ArrayList<>();
                                                                                                                                  ParameterBuilder tokenPar = new ParameterBuilder();
                                                                                                                                  tokenPar.name("token")
                                                                                                                                          .description("用户token")
                                                                                                                                          .defaultValue("")
                                                                                                                                          .modelRef(new ModelRef("string"))
                                                                                                                                          .parameterType("header")
                                                                                                                                          .required(false)
                                                                                                                                          .build();
                                                                                                                                  pars.add(tokenPar.build());
                                                                                                                                  //添加head参数end
                                                                                                                                  Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
                                                                                                                                          .groupName("adminApi")
                                                                                                                                          .apiInfo(adminApiInfo())
                                                                                                                                          .select()
                                                                                                                                          //只显示admin路径下的页面
                                                                                                                                          .apis(RequestHandlerSelectors.basePackage("com.jerry"))
                                                                                                                                          .paths(PathSelectors.regex("/admin/.*"))
                                                                                                                                          .build()
                                                                                                                                          .globalOperationParameters(pars);
                                                                                                                                  return adminApi;
                                                                                                                              }
                                                                                                                              private ApiInfo adminApiInfo(){
                                                                                                                                  return new ApiInfoBuilder()
                                                                                                                                          .title("后台管理系统-API文档")
                                                                                                                                          .description("本文档描述了后台管理系统微服务接口定义")
                                                                                                                                          .version("1.0")
                                                                                                                                          .contact(new Contact("jerry", "https://jerry-jy.co", "jinyang9248@163.com"))
                                                                                                                                          .build();
                                                                                                                              }
                                                                                                                          }
                                                                                                                          
                                                                                                                          Controller层添加注解
                                                                                                                          • 类上加@Api(tags = "角色管理接口")
                                                                                                                          • 方法上加@ApiOperation("查询所有角色")

                                                                                                                            云上办公系统项目,在这里插入图片描述,第17张

                                                                                                                            测试

                                                                                                                            http://localhost:8800/doc.html

                                                                                                                            云上办公系统项目,在这里插入图片描述,第18张

                                                                                                                            3.3、分页查询所有角色

                                                                                                                            service-util模块下创建 MybatisPlusConfig

                                                                                                                            MybatisPlusConfig
                                                                                                                            package com.jerry.common.config.mp;
                                                                                                                            import com.baomidou.mybatisplus.annotation.DbType;
                                                                                                                            import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
                                                                                                                            import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
                                                                                                                            import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
                                                                                                                            import org.mybatis.spring.annotation.MapperScan;
                                                                                                                            import org.springframework.context.annotation.Bean;
                                                                                                                            import org.springframework.context.annotation.Configuration;
                                                                                                                            /**
                                                                                                                             * ClassName: MybatisPlusConfig
                                                                                                                             * Package: com.jerry.common.config.mp
                                                                                                                             * Description:
                                                                                                                             *
                                                                                                                             * @Author jerry_jy
                                                                                                                             * @Create 2023-03-01 11:17
                                                                                                                             * @Version 1.0
                                                                                                                             */
                                                                                                                            @Configuration
                                                                                                                            @MapperScan("com.jerry.auth.mapper")
                                                                                                                            public class MybatisPlusConfig {
                                                                                                                                /**
                                                                                                                                 * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
                                                                                                                                 */
                                                                                                                                @Bean
                                                                                                                                public MybatisPlusInterceptor mybatisPlusInterceptor() {
                                                                                                                                    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
                                                                                                                                    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
                                                                                                                                    return interceptor;
                                                                                                                                }
                                                                                                                                @Bean
                                                                                                                                public ConfigurationCustomizer configurationCustomizer() {
                                                                                                                                    return configuration -> configuration.setUseDeprecatedExecutor(false);
                                                                                                                                }
                                                                                                                            }
                                                                                                                            
                                                                                                                            主启动类上添加包扫描

                                                                                                                            云上办公系统项目,在这里插入图片描述,第19张

                                                                                                                            SysRoleController
                                                                                                                                /**
                                                                                                                                 * 条件分页查询
                                                                                                                                 *
                                                                                                                                 * @param page           当前页
                                                                                                                                 * @param pageSize       分页大小
                                                                                                                                 * @param sysRoleQueryVo 条件查询对象
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("条件分页查询")
                                                                                                                                @GetMapping("{page}/{pageSize}")
                                                                                                                                private Result page(@PathVariable int page, @PathVariable int pageSize, SysRoleQueryVo sysRoleQueryVo) {
                                                                                                                                    // 1、创建 page 对象, 传递分页查询的参数
                                                                                                                                    Page sysRolePage = new Page<>(page, pageSize);
                                                                                                                                    // 2、构造分页查询条件, 判断条件是否为空,不为空进行封装
                                                                                                                                    LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                    String roleName = sysRoleQueryVo.getRoleName();
                                                                                                                                    if (!StringUtils.isEmpty(roleName)) {
                                                                                                                                        // 封装
                                                                                                                                        lambdaQueryWrapper.like(SysRole::getRoleName,roleName);
                                                                                                                                    }
                                                                                                                                    // 3、调用方法实现分页查询
                                                                                                                                   sysRoleService.page(sysRolePage, lambdaQueryWrapper);
                                                                                                                                    return Result.ok(sysRolePage);
                                                                                                                                }
                                                                                                                            
                                                                                                                            测试

                                                                                                                            云上办公系统项目,在这里插入图片描述,第20张

                                                                                                                            3.4、添加/修改/删除角色

                                                                                                                                /**
                                                                                                                                 * 添加角色
                                                                                                                                 * @param sysRole
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("添加角色")
                                                                                                                                @PostMapping("/save")
                                                                                                                                public Result save(@RequestBody SysRole sysRole) {
                                                                                                                                    // 调用 service 方法
                                                                                                                                    boolean is_success = sysRoleService.save(sysRole);
                                                                                                                                    if (is_success) {
                                                                                                                                        return Result.ok();
                                                                                                                                    } else {
                                                                                                                                        return Result.fail();
                                                                                                                                    }
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 根据 id 修改角色
                                                                                                                                 * @param id
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("根据 id 查询角色")
                                                                                                                                @GetMapping("/get/{id}")
                                                                                                                                public Result get(@PathVariable long id){
                                                                                                                                    SysRole sysRole = sysRoleService.getById(id);
                                                                                                                                    return Result.ok(sysRole);
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 修改角色
                                                                                                                                 * @param sysRole
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("修改角色")
                                                                                                                                @PutMapping("/update")
                                                                                                                                public Result update(@RequestBody SysRole sysRole) {
                                                                                                                                    // 调用 service 方法
                                                                                                                                    boolean is_success = sysRoleService.updateById(sysRole);
                                                                                                                                    if (is_success) {
                                                                                                                                        return Result.ok();
                                                                                                                                    } else {
                                                                                                                                        return Result.fail();
                                                                                                                                    }
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 根据 id 删除
                                                                                                                                 * @param id
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("根据 id 删除")
                                                                                                                                @DeleteMapping("delete/{id}")
                                                                                                                                public Result deleteById(@PathVariable long id){
                                                                                                                                    boolean is_success = sysRoleService.removeById(id);
                                                                                                                                    if (is_success) {
                                                                                                                                        return Result.ok();
                                                                                                                                    } else {
                                                                                                                                        return Result.fail();
                                                                                                                                    }
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 批量删除
                                                                                                                                 * 说明:
                                                                                                                                 *      Java 中的对象会转化为Json对象
                                                                                                                                 *      Java 中的List集合会转化为数组
                                                                                                                                 * @param ids
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("批量删除")
                                                                                                                                @DeleteMapping("/ids")
                                                                                                                                public Result deleteByIds(@RequestBody List ids){
                                                                                                                                    boolean is_success = sysRoleService.removeByIds(ids);
                                                                                                                                    if (is_success) {
                                                                                                                                        return Result.ok();
                                                                                                                                    } else {
                                                                                                                                        return Result.fail();
                                                                                                                                    }
                                                                                                                                }
                                                                                                                            

                                                                                                                            测试

                                                                                                                            云上办公系统项目,在这里插入图片描述,第21张

                                                                                                                            配置日期时间格式

                                                                                                                            application-dev.yml添加以下内容

                                                                                                                              jackson:
                                                                                                                                date-format: yyyy-MM-dd HH:mm:ss
                                                                                                                                time-zone: GMT+8
                                                                                                                            

                                                                                                                            4、统一异常处理

                                                                                                                            异常处理的思路流程

                                                                                                                            云上办公系统项目,在这里插入图片描述,第22张

                                                                                                                            4.1、全局异常处理

                                                                                                                            4.2、特定异常处理

                                                                                                                            4.3、自定义异常处理

                                                                                                                            service-util 模块下

                                                                                                                            GlobalExceptionHandler

                                                                                                                            package com.jerry.common.config.exception;
                                                                                                                            import com.jerry.common.result.Result;
                                                                                                                            import org.springframework.web.bind.annotation.ControllerAdvice;
                                                                                                                            import org.springframework.web.bind.annotation.ExceptionHandler;
                                                                                                                            import org.springframework.web.bind.annotation.ResponseBody;
                                                                                                                            /**
                                                                                                                             * ClassName: GlobalExceptionHandler
                                                                                                                             * Package: com.jerry.common.config.exception
                                                                                                                             * Description:
                                                                                                                             *
                                                                                                                             * @Author jerry_jy
                                                                                                                             * @Create 2023-03-01 15:48
                                                                                                                             * @Version 1.0
                                                                                                                             */
                                                                                                                            @ControllerAdvice
                                                                                                                            public class GlobalExceptionHandler {
                                                                                                                                /**
                                                                                                                                 * 全局异常处理 执行的方法
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ExceptionHandler(Exception.class)
                                                                                                                                @ResponseBody
                                                                                                                                public Result error(Exception e){
                                                                                                                                    e.printStackTrace();
                                                                                                                                    return Result.fail().message("执行全局处理异常...");
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 特定异常处理
                                                                                                                                 * @param e
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ExceptionHandler(ArithmeticException.class)
                                                                                                                                @ResponseBody
                                                                                                                                public Result error(ArithmeticException e){
                                                                                                                                    e.printStackTrace();
                                                                                                                                    return Result.fail().message("执行特定处理异常...");
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 自定义异常处理
                                                                                                                                 * @param e
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ExceptionHandler(GuiguException.class)
                                                                                                                                @ResponseBody
                                                                                                                                public Result error(GuiguException e){
                                                                                                                                    e.printStackTrace();
                                                                                                                                    return Result.fail().code(e.getCode()).message(e.getMsg());
                                                                                                                                }
                                                                                                                            }
                                                                                                                            

                                                                                                                            GuiguException

                                                                                                                            package com.jerry.common.config.exception;
                                                                                                                            import com.jerry.common.result.ResultCodeEnum;
                                                                                                                            import lombok.Data;
                                                                                                                            /**
                                                                                                                             * ClassName: GuiguException
                                                                                                                             * Package: com.jerry.common.config.exception
                                                                                                                             * Description:
                                                                                                                             *
                                                                                                                             * @Author jerry_jy
                                                                                                                             * @Create 2023-03-01 15:59
                                                                                                                             * @Version 1.0
                                                                                                                             */
                                                                                                                            @Data
                                                                                                                            public class GuiguException extends RuntimeException {
                                                                                                                                private Integer code;
                                                                                                                                private String msg;
                                                                                                                                /**
                                                                                                                                 * 通过状态码和错误消息创建异常对象
                                                                                                                                 * @param code
                                                                                                                                 * @param msg
                                                                                                                                 */
                                                                                                                                public GuiguException(Integer code, String msg) {
                                                                                                                                    super(msg);
                                                                                                                                    this.code = code;
                                                                                                                                    this.msg = msg;
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * 接收枚举类型对象
                                                                                                                                 * @param resultCodeEnum
                                                                                                                                 */
                                                                                                                                public GuiguException(ResultCodeEnum resultCodeEnum) {
                                                                                                                                    super(resultCodeEnum.getMessage());
                                                                                                                                    this.code = resultCodeEnum.getCode();
                                                                                                                                    this.msg = resultCodeEnum.getMessage();
                                                                                                                                }
                                                                                                                                @Override
                                                                                                                                public String toString() {
                                                                                                                                    return "GuiguException{" +
                                                                                                                                            "code=" + code +
                                                                                                                                            ", msg='" + msg + '\'' +
                                                                                                                                            '}';
                                                                                                                                }
                                                                                                                            }
                                                                                                                            

                                                                                                                            5、前端环境搭建

                                                                                                                            安装脚手架工程

                                                                                                                            前端用的脚手架工程是:vue-element-admin

                                                                                                                            https://panjiachen.github.io/vue-element-admin-site/#/

                                                                                                                            # clone the project
                                                                                                                            git clone https://github.com/PanJiaChen/vue-element-admin.git
                                                                                                                            # install dependency
                                                                                                                            npm install
                                                                                                                            # develop
                                                                                                                            npm run dev
                                                                                                                            

                                                                                                                            http://localhost:9528/#/dashboard

                                                                                                                            云上办公系统项目,在这里插入图片描述,第23张

                                                                                                                            前后联调的流程

                                                                                                                            云上办公系统项目,在这里插入图片描述,第24张

                                                                                                                            云上办公系统项目,在这里插入图片描述,第25张

                                                                                                                            修改前端的IP地址

                                                                                                                                // before: require('./mock/mock-server.js')
                                                                                                                                proxy: {
                                                                                                                                  '/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
                                                                                                                                    target: 'http://localhost:8800',
                                                                                                                                    changeOrigin: true, // 支持跨域
                                                                                                                                    pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
                                                                                                                                      '^/dev-api': ''
                                                                                                                                    }
                                                                                                                                  }
                                                                                                                                }
                                                                                                                            

                                                                                                                            云上办公系统项目,在这里插入图片描述,第26张

                                                                                                                            编写后台登录/登出的请求

                                                                                                                            IndexController

                                                                                                                            package com.jerry.auth.controller;
                                                                                                                            import com.jerry.common.result.Result;
                                                                                                                            import io.swagger.annotations.Api;
                                                                                                                            import io.swagger.annotations.ApiOperation;
                                                                                                                            import org.springframework.web.bind.annotation.GetMapping;
                                                                                                                            import org.springframework.web.bind.annotation.PostMapping;
                                                                                                                            import org.springframework.web.bind.annotation.RequestMapping;
                                                                                                                            import org.springframework.web.bind.annotation.RestController;
                                                                                                                            import java.util.HashMap;
                                                                                                                            import java.util.Map;
                                                                                                                            import java.util.Objects;
                                                                                                                            /**
                                                                                                                             * ClassName: IndexController
                                                                                                                             * Package: com.jerry.auth.controller
                                                                                                                             * Description:
                                                                                                                             *
                                                                                                                             * @Author jerry_jy
                                                                                                                             * @Create 2023-03-01 18:15
                                                                                                                             * @Version 1.0
                                                                                                                             */
                                                                                                                            @Api(tags = "后台登录管理")
                                                                                                                            @RestController
                                                                                                                            @RequestMapping("/admin/system/index")
                                                                                                                            public class IndexController {
                                                                                                                                /**
                                                                                                                                 * login
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("登录")
                                                                                                                                @PostMapping("/login")
                                                                                                                                public Result login(){
                                                                                                                                    // {"code":200,"data":{"token":"admin-token"}}
                                                                                                                                    HashMap map = new HashMap<>();
                                                                                                                                    map.put("token","admin-token");
                                                                                                                                    return Result.ok(map);
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * info
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @GetMapping("/info")
                                                                                                                                public Result info(){
                                                                                                                                    Map map = new HashMap<>();
                                                                                                                                    map.put("roles","[admin]");
                                                                                                                                    map.put("name","admin");
                                                                                                                                    map.put("avatar","https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                                                                                                                                    return Result.ok(map);
                                                                                                                                }
                                                                                                                                /**
                                                                                                                                 * logout
                                                                                                                                 * @return
                                                                                                                                 */
                                                                                                                                @ApiOperation("登出")
                                                                                                                                @PostMapping("/logout")
                                                                                                                                public Result logout(){
                                                                                                                                    return Result.ok();
                                                                                                                                }
                                                                                                                            }
                                                                                                                            

                                                                                                                            修改前端的跳转地址

                                                                                                                            云上办公系统项目,在这里插入图片描述,第27张

                                                                                                                            修改响应状态码

                                                                                                                            云上办公系统项目,在这里插入图片描述,第28张

                                                                                                                            测试

                                                                                                                            重启前端、后端项目,可以发现请求头信息已经做了跳转、转发

                                                                                                                            云上办公系统项目,在这里插入图片描述,第29张

                                                                                                                            6、前端角色管理

                                                                                                                            6.1、角色列表

                                                                                                                            修改路由

                                                                                                                            重新定义constantRoutes

                                                                                                                            云上办公系统项目,在这里插入图片描述,第30张

                                                                                                                              {
                                                                                                                                path: '/system',
                                                                                                                                component: Layout,
                                                                                                                                meta: {
                                                                                                                                  title: '系统管理',
                                                                                                                                  icon: 'el-icon-s-tools'
                                                                                                                                },
                                                                                                                                alwaysShow: true,
                                                                                                                                children: [
                                                                                                                                  {
                                                                                                                                    path: 'sysRole',
                                                                                                                                    component: () => import('@/views/system/sysRole/list'),
                                                                                                                                    meta: {
                                                                                                                                      title: '角色管理',
                                                                                                                                      icon: 'el-icon-s-help'
                                                                                                                                    },
                                                                                                                                  }
                                                                                                                                ]
                                                                                                                              },
                                                                                                                            

                                                                                                                            创建角色页面

                                                                                                                            云上办公系统项目,在这里插入图片描述,第31张

                                                                                                                            
                                                                                                                            
                                                                                                                            

                                                                                                                            定义角色管理相关的API请求函数

                                                                                                                            云上办公系统项目,在这里插入图片描述,第32张

                                                                                                                            /*
                                                                                                                            角色管理相关的API请求函数
                                                                                                                            */
                                                                                                                            import request from '@/utils/request'
                                                                                                                            const api_name = '/admin/system/sysRole'
                                                                                                                            export default {
                                                                                                                              /*
                                                                                                                              获取角色分页列表(带搜索)
                                                                                                                              */
                                                                                                                              getPageList(page, limit, searchObj) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/${page}/${limit}`,
                                                                                                                                  method: 'get',
                                                                                                                                  // 如果是普通对象参数写法,params:对象参数名
                                                                                                                                  // 如果是使用json格式传递,data:对象参数名
                                                                                                                                  params: searchObj
                                                                                                                                })
                                                                                                                              }
                                                                                                                            }
                                                                                                                            

                                                                                                                            测试

                                                                                                                            重新启动前端工程

                                                                                                                            http://localhost:9528/?#/system/sysRole

                                                                                                                            云上办公系统项目,在这里插入图片描述,第33张

                                                                                                                            6.2、角色删除

                                                                                                                            sysRole.js

                                                                                                                              /**
                                                                                                                               * 角色删除
                                                                                                                               * @param {*} id 
                                                                                                                               * @returns 
                                                                                                                               */
                                                                                                                              removeById(id) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/delete/${id}`,
                                                                                                                                  method: 'delete'
                                                                                                                                })
                                                                                                                              }
                                                                                                                            

                                                                                                                            list.vue

                                                                                                                                // 根据id删除数据
                                                                                                                                removeDataById(id) {
                                                                                                                                    // debugger
                                                                                                                                    this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
                                                                                                                                        confirmButtonText: '确定',
                                                                                                                                        cancelButtonText: '取消',
                                                                                                                                        type: 'warning'
                                                                                                                                    }).then(() => { // promise
                                                                                                                                        // 点击确定,远程调用ajax
                                                                                                                                        return api.removeById(id)
                                                                                                                                    }).then((response) => {
                                                                                                                                        // 刷新页面
                                                                                                                                        this.fetchData(this.page)
                                                                                                                                        // 提示信息
                                                                                                                                        this.$message.success(response.message || '删除成功')
                                                                                                                                    })
                                                                                                                                }
                                                                                                                            

                                                                                                                            6.3、角色添加

                                                                                                                            6.4、角色修改与数据回显

                                                                                                                            6.5、批量删除

                                                                                                                            前端CRUD完整代码

                                                                                                                            注意点:

                                                                                                                            前端中的url请求路径要和后端的@DeleteMapping,@PutMapping,@PostMapping,@GetMapping路径一致

                                                                                                                            云上办公系统项目,在这里插入图片描述,第34张

                                                                                                                            sysRole.js

                                                                                                                            /*
                                                                                                                            角色管理相关的API请求函数
                                                                                                                            */
                                                                                                                            import request from '@/utils/request'
                                                                                                                            const api_name = '/admin/system/sysRole'
                                                                                                                            export default {
                                                                                                                             /**
                                                                                                                              * 获取角色分页列表(带搜索)
                                                                                                                              * @param {*} page 
                                                                                                                              * @param {*} limit 
                                                                                                                              * @param {*} searchObj 
                                                                                                                              * @returns 
                                                                                                                              */
                                                                                                                              getPageList(page, limit, searchObj) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/${page}/${limit}`,
                                                                                                                                  method: 'get',
                                                                                                                                  // 如果是普通对象参数写法,params:对象参数名
                                                                                                                                  // 如果是使用json格式传递,data:对象参数名
                                                                                                                                  params: searchObj
                                                                                                                                })
                                                                                                                              },
                                                                                                                              /**
                                                                                                                               * 角色删除
                                                                                                                               * @param {*} id 
                                                                                                                               * @returns 
                                                                                                                               */
                                                                                                                              removeById(id) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/delete/${id}`,
                                                                                                                                  method: 'delete'
                                                                                                                                })
                                                                                                                              },
                                                                                                                              /**
                                                                                                                               * 角色添加
                                                                                                                               * @param {*} role 
                                                                                                                               * @returns 
                                                                                                                               */
                                                                                                                              save(role) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/save`,
                                                                                                                                  method: 'post',
                                                                                                                                  data: role
                                                                                                                                })
                                                                                                                              },
                                                                                                                              // 回显要修改的id信息
                                                                                                                              getById(id) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/get/${id}`,
                                                                                                                                  method: 'get'
                                                                                                                                })
                                                                                                                              },
                                                                                                                              
                                                                                                                              // 修改
                                                                                                                              updateById(role) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/update`,
                                                                                                                                  method: 'put',
                                                                                                                                  data: role
                                                                                                                                })
                                                                                                                              },
                                                                                                                              // 批量删除
                                                                                                                              batchRemove(idList) {
                                                                                                                                return request({
                                                                                                                                  url: `${api_name}/ids`,
                                                                                                                                  method: `delete`,
                                                                                                                                  data: idList
                                                                                                                                })
                                                                                                                              }
                                                                                                                            }
                                                                                                                            

                                                                                                                            list.vue

                                                                                                                            
                                                                                                                            
                                                                                                                            

                                                                                                                            页面展示

                                                                                                                            云上办公系统项目,在这里插入图片描述,第35张

                                                                                                                            7、用户管理

                                                                                                                            7.1、用户管理CRUD

                                                                                                                            需求分析

                                                                                                                            云上办公系统项目,在这里插入图片描述,第36张

                                                                                                                            代码生成器

                                                                                                                            • 可以采用MyBatisPlus提供的代码生成器直接生成 mapper,service,impl,controller,
                                                                                                                            • 手动创建的话,也行

                                                                                                                              service-oa

                                                                                                                                      
                                                                                                                                          com.baomidou
                                                                                                                                          mybatis-plus-generator
                                                                                                                                          3.4.1
                                                                                                                                      
                                                                                                                                      
                                                                                                                                          org.apache.velocity
                                                                                                                                          velocity-engine-core
                                                                                                                                          2.0
                                                                                                                                      
                                                                                                                              

                                                                                                                              CodeGet.java

                                                                                                                              云上办公系统项目,在这里插入图片描述,第37张

                                                                                                                              package com.jerry.code;
                                                                                                                              import com.baomidou.mybatisplus.annotation.DbType;
                                                                                                                              import com.baomidou.mybatisplus.generator.AutoGenerator;
                                                                                                                              import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
                                                                                                                              import com.baomidou.mybatisplus.generator.config.GlobalConfig;
                                                                                                                              import com.baomidou.mybatisplus.generator.config.PackageConfig;
                                                                                                                              import com.baomidou.mybatisplus.generator.config.StrategyConfig;
                                                                                                                              import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
                                                                                                                              public class CodeGet {
                                                                                                                                  public static void main(String[] args) {
                                                                                                                                      // 1、创建代码生成器
                                                                                                                                      AutoGenerator mpg = new AutoGenerator();
                                                                                                                                      // 2、全局配置
                                                                                                                                      // 全局配置
                                                                                                                                      GlobalConfig gc = new GlobalConfig();
                                                                                                                                      gc.setOutputDir("E:\\CodeLife\\IdeaProject\\guigu-oa\\guigu-oa-parent\\service-oa"+"/src/main/java");
                                                                                                                                      gc.setServiceName("%sService");	//去掉Service接口的首字母I
                                                                                                                                      gc.setAuthor("jerry");
                                                                                                                                      gc.setOpen(false);
                                                                                                                                      mpg.setGlobalConfig(gc);
                                                                                                                                      // 3、数据源配置
                                                                                                                                      DataSourceConfig dsc = new DataSourceConfig();
                                                                                                                                      dsc.setUrl("jdbc:mysql://localhost:3306/guigu-oa?serverTimezone=GMT%2B8&useSSL=false");
                                                                                                                                      dsc.setDriverName("com.mysql.cj.jdbc.Driver");
                                                                                                                                      dsc.setUsername("root");
                                                                                                                                      dsc.setPassword("root");
                                                                                                                                      dsc.setDbType(DbType.MYSQL);
                                                                                                                                      mpg.setDataSource(dsc);
                                                                                                                                      // 4、包配置
                                                                                                                                      PackageConfig pc = new PackageConfig();
                                                                                                                                      pc.setParent("com.jerry");
                                                                                                                                      pc.setModuleName("auth"); //模块名
                                                                                                                                      pc.setController("controller");
                                                                                                                                      pc.setService("service");
                                                                                                                                      pc.setMapper("mapper");
                                                                                                                                      mpg.setPackageInfo(pc);
                                                                                                                                      // 5、策略配置
                                                                                                                                      StrategyConfig strategy = new StrategyConfig();
                                                                                                                                      strategy.setInclude("sys_user");
                                                                                                                                      strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
                                                                                                                                      strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
                                                                                                                                      strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作
                                                                                                                                      strategy.setRestControllerStyle(true); //restful api风格控制器
                                                                                                                                      strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
                                                                                                                                      mpg.setStrategy(strategy);
                                                                                                                                      // 6、执行
                                                                                                                                      mpg.execute();
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              

                                                                                                                              编写代码

                                                                                                                              代码是写在service-oa类中的

                                                                                                                              SysUserMapper

                                                                                                                              public interface SysUserMapper extends BaseMapper {
                                                                                                                              }
                                                                                                                              

                                                                                                                              SysUserService

                                                                                                                              public interface SysUserService extends IService {
                                                                                                                              }
                                                                                                                              

                                                                                                                              SysUserServiceImpl

                                                                                                                              @Service
                                                                                                                              public class SysUserServiceImpl extends ServiceImpl implements SysUserService {
                                                                                                                              }
                                                                                                                              

                                                                                                                              SysUserController

                                                                                                                              package com.jerry.auth.controller;
                                                                                                                              import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
                                                                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                                                                              import com.jerry.auth.service.SysUserService;
                                                                                                                              import com.jerry.common.result.Result;
                                                                                                                              import com.jerry.model.system.SysUser;
                                                                                                                              import com.jerry.vo.system.SysUserQueryVo;
                                                                                                                              import io.swagger.annotations.Api;
                                                                                                                              import io.swagger.annotations.ApiOperation;
                                                                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                              import org.springframework.util.StringUtils;
                                                                                                                              import org.springframework.web.bind.annotation.*;
                                                                                                                              /**
                                                                                                                               * 

                                                                                                                              * 用户表 前端控制器 *

                                                                                                                              * * @author jerry * @since 2023-03-01 */ @Api(tags = "用户管理接口") @RestController @RequestMapping("/admin/system/sysUser") public class SysUserController { @Autowired private SysUserService sysUserService; /** * 用户条件分页查询 * * @param page * @param pageSize * @param sysUserQueryVo * @return */ @ApiOperation("用户条件分页查询") @GetMapping("/{page}/{pageSize}") public Result page(@PathVariable int page, @PathVariable int pageSize, SysUserQueryVo sysUserQueryVo) { Page sysUserPage = new Page<>(page, pageSize); LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 获取条件 String userName = sysUserQueryVo.getKeyword(); String createTimeBegin = sysUserQueryVo.getCreateTimeBegin(); String createTimeEnd = sysUserQueryVo.getCreateTimeEnd(); // 判断条件值不为空 if (!StringUtils.isEmpty(userName)){ lambdaQueryWrapper.like(SysUser::getUsername,userName); } if (!StringUtils.isEmpty(createTimeBegin)){ lambdaQueryWrapper.ge(SysUser::getCreateTime,createTimeBegin); } if (!StringUtils.isEmpty(createTimeEnd)){ lambdaQueryWrapper.le(SysUser::getCreateTime,createTimeEnd); } sysUserService.page(sysUserPage,lambdaQueryWrapper); return Result.ok(sysUserPage); } /** * 获取用户 * @param id * @return */ @ApiOperation("获取用户") @GetMapping("/get/{id}") public Result get(@PathVariable long id){ SysUser user = sysUserService.getById(id); return Result.ok(user); } /** * 更新用户 * @param sysUser * @return */ @ApiOperation("更新用户") @PutMapping("/update") public Result update(@RequestBody SysUser sysUser){ boolean is_success = sysUserService.updateById(sysUser); if (is_success) { return Result.ok(); } else { return Result.fail(); } } /** * 保存用户 * @param sysUser * @return */ @ApiOperation("保存用户") @PostMapping("/save") public Result save(@RequestBody SysUser sysUser){ boolean is_success = sysUserService.save(sysUser); if (is_success) { return Result.ok(); } else { return Result.fail(); } } /** * 删除用户 * @param id * @return */ @ApiOperation("删除用户") @DeleteMapping("/remove/{id}") public Result remove(@PathVariable long id){ boolean is_success = sysUserService.removeById(id); if (is_success) { return Result.ok(); } else { return Result.fail(); } } }

                                                                                                                              测试

                                                                                                                              全部测试通过

                                                                                                                              云上办公系统项目,在这里插入图片描述,第38张

                                                                                                                              整合前端

                                                                                                                              前端页面 list.vue

                                                                                                                              云上办公系统项目,在这里插入图片描述,第39张

                                                                                                                              
                                                                                                                                
                                                                                                                                
                                                                                                                              
                                                                                                                              添加路由

                                                                                                                              云上办公系统项目,在这里插入图片描述,第40张

                                                                                                                                    {
                                                                                                                                      name: 'sysUser',
                                                                                                                                      path: 'sysUser',
                                                                                                                                      component: () => import('@/views/system/sysUser/list'),
                                                                                                                                      meta: {
                                                                                                                                        title: '用户管理',
                                                                                                                                        icon: 'el-icon-s-custom'
                                                                                                                                      },
                                                                                                                                    },
                                                                                                                              
                                                                                                                              定义API接口

                                                                                                                              云上办公系统项目,在这里插入图片描述,第41张

                                                                                                                              import request from '@/utils/request'
                                                                                                                              const api_name = '/admin/system/sysUser'
                                                                                                                              export default {
                                                                                                                                getPageList(page, limit, searchObj) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/${page}/${limit}`,
                                                                                                                                    method: 'get',
                                                                                                                                    params: searchObj // url查询字符串或表单键值对
                                                                                                                                  })
                                                                                                                                },
                                                                                                                                getById(id) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/get/${id}`,
                                                                                                                                    method: 'get'
                                                                                                                                  })
                                                                                                                                },
                                                                                                                                save(role) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/save`,
                                                                                                                                    method: 'post',
                                                                                                                                    data: role
                                                                                                                                  })
                                                                                                                                },
                                                                                                                                updateById(role) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/update`,
                                                                                                                                    method: 'put',
                                                                                                                                    data: role
                                                                                                                                  })
                                                                                                                                },
                                                                                                                                removeById(id) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/remove/${id}`,
                                                                                                                                    method: 'delete'
                                                                                                                                  })
                                                                                                                                },
                                                                                                                                updateStatus(id, status) {
                                                                                                                                  return request({
                                                                                                                                    url: `${api_name}/updateStatus/${id}/${status}`,
                                                                                                                                    method: 'get'
                                                                                                                                  })
                                                                                                                                }
                                                                                                                              }
                                                                                                                              

                                                                                                                              页面展示

                                                                                                                              [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oiKS5qR9-1678180003061)(E:/typora/image-20230302122542413.png)]

                                                                                                                              7.2、用户管理分配角色

                                                                                                                              需求分析

                                                                                                                              • 一个用户对应多个角色

                                                                                                                              • 一个角色可以有多个用户

                                                                                                                                多对多的关系

                                                                                                                                云上办公系统项目,在这里插入图片描述,第42张

                                                                                                                                接口分析

                                                                                                                                • 1、进入分配页面:获取已分配角色与全部角色,进行页面展示

                                                                                                                                • 2、保存分配角色:删除之前分配的角色和保存现在分配的角色

                                                                                                                                  编写代码

                                                                                                                                  代码是写在service-oa类中的

                                                                                                                                  SysUserRoleMapper

                                                                                                                                  public interface SysUserRoleMapper extends BaseMapper {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysUserRoleService

                                                                                                                                  public interface SysUserRoleService extends IService {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysUserRoleServiceImpl

                                                                                                                                  @Service
                                                                                                                                  public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysRoleController

                                                                                                                                      // 1、查询所有角色 和 当前用户所属角色
                                                                                                                                      @ApiOperation("根据用户获取角色数据")
                                                                                                                                      @GetMapping("/toAssign/{userId}")
                                                                                                                                      public Result toAssign(@PathVariable Long userId) {
                                                                                                                                          Map map = sysRoleService.findRoleDataByUserId(userId);
                                                                                                                                          return Result.ok(map);
                                                                                                                                      }
                                                                                                                                      // 2、为用户分配角色
                                                                                                                                      @ApiOperation("为用户分配角色")
                                                                                                                                      @PostMapping("/doAssign")
                                                                                                                                      public Result doAssign(@RequestBody AssginRoleVo assginRoleVo) {
                                                                                                                                          sysRoleService.doAssign(assginRoleVo);
                                                                                                                                          return Result.ok();
                                                                                                                                      }
                                                                                                                                  

                                                                                                                                  SysRoleServiceImpl

                                                                                                                                  /**
                                                                                                                                   * ClassName: SysRoleServiceImpl
                                                                                                                                   * Package: com.jerry.auth.service.impl
                                                                                                                                   * Description:
                                                                                                                                   *
                                                                                                                                   * @Author jerry_jy
                                                                                                                                   * @Create 2023-03-01 9:13
                                                                                                                                   * @Version 1.0
                                                                                                                                   */
                                                                                                                                  @Service
                                                                                                                                  public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService {
                                                                                                                                      @Autowired
                                                                                                                                      private SysUserRoleService sysUserRoleService;
                                                                                                                                      //1 查询所有角色 和 当前用户所属角色
                                                                                                                                      @Override
                                                                                                                                      public Map findRoleDataByUserId(Long userId) {
                                                                                                                                          //1 查询所有角色,返回list集合,返回
                                                                                                                                          List allRoleList =
                                                                                                                                                  baseMapper.selectList(null);
                                                                                                                                          //2 根据userid查询 角色用户关系表,查询userid对应所有角色id
                                                                                                                                          LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
                                                                                                                                          wrapper.eq(SysUserRole::getUserId,userId);
                                                                                                                                          List existUserRoleList = sysUserRoleService.list(wrapper);
                                                                                                                                          //从查询出来的用户id对应角色list集合,获取所有角色id
                                                                                                                                  //        List list = new ArrayList<>();
                                                                                                                                  //        for (SysUserRole sysUserRole:existUserRoleList) {
                                                                                                                                  //            Long roleId = sysUserRole.getRoleId();
                                                                                                                                  //            list.add(roleId);
                                                                                                                                  //        }
                                                                                                                                          List existRoleIdList =
                                                                                                                                                  existUserRoleList.stream().map(c -> c.getRoleId()).collect(Collectors.toList());
                                                                                                                                          //3 根据查询所有角色id,找到对应角色信息
                                                                                                                                          //根据角色id到所有的角色的list集合进行比较
                                                                                                                                          List assignRoleList = new ArrayList<>();
                                                                                                                                          for(SysRole sysRole : allRoleList) {
                                                                                                                                              //比较
                                                                                                                                              if(existRoleIdList.contains(sysRole.getId())) {
                                                                                                                                                  assignRoleList.add(sysRole);
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                                          //4 把得到两部分数据封装map集合,返回
                                                                                                                                          Map roleMap = new HashMap<>();
                                                                                                                                          roleMap.put("assginRoleList", assignRoleList);
                                                                                                                                          roleMap.put("allRolesList", allRoleList);
                                                                                                                                          return roleMap;
                                                                                                                                      }
                                                                                                                                      //2 为用户分配角色
                                                                                                                                      @Override
                                                                                                                                      public void doAssign(AssginRoleVo assginRoleVo) {
                                                                                                                                          //把用户之前分配角色数据删除,用户角色关系表里面,根据userid删除
                                                                                                                                          LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
                                                                                                                                          wrapper.eq(SysUserRole::getUserId,assginRoleVo.getUserId());
                                                                                                                                          sysUserRoleService.remove(wrapper);
                                                                                                                                          //重新进行分配
                                                                                                                                          List roleIdList = assginRoleVo.getRoleIdList();
                                                                                                                                          for(Long roleId:roleIdList) {
                                                                                                                                              if(StringUtils.isEmpty(roleId)) {
                                                                                                                                                  continue;
                                                                                                                                              }
                                                                                                                                              SysUserRole sysUserRole = new SysUserRole();
                                                                                                                                              sysUserRole.setUserId(assginRoleVo.getUserId());
                                                                                                                                              sysUserRole.setRoleId(roleId);
                                                                                                                                              sysUserRoleService.save(sysUserRole);
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  前端展示

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第43张

                                                                                                                                  7.3、修改用户状态

                                                                                                                                  需求分析

                                                                                                                                  用户状态:状态(1:正常 0:停用),当用户状态为正常时,可以访问后台系统,当用户状态停用后,不可以登录后台系统

                                                                                                                                  编写代码

                                                                                                                                  SysRoleController

                                                                                                                                      @ApiOperation(value = "更新状态")
                                                                                                                                      @GetMapping("/updateStatus/{id}/{status}")
                                                                                                                                      public Result updateStatus(@PathVariable Long id, @PathVariable Integer status){
                                                                                                                                          sysUserService.updateStatus(id, status);
                                                                                                                                          return Result.ok();
                                                                                                                                      }
                                                                                                                                  

                                                                                                                                  SysUserService

                                                                                                                                  public interface SysUserService extends IService {
                                                                                                                                      // 更新状态
                                                                                                                                      void updateStatus(Long id, Integer status);
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysUserServiceImpl

                                                                                                                                  @Service
                                                                                                                                  @Slf4j
                                                                                                                                  public class SysUserServiceImpl extends ServiceImpl implements SysUserService {
                                                                                                                                      // 更新状态
                                                                                                                                      @Override
                                                                                                                                      @Transactional
                                                                                                                                      public void updateStatus(Long id, Integer status) {
                                                                                                                                          // 根据用户 userid 查询用户对象
                                                                                                                                          SysUser sysUser = baseMapper.selectById(id);
                                                                                                                                          // 设置修改状态
                                                                                                                                          if (status == 0 || status == 1) {
                                                                                                                                              sysUser.setStatus(status);
                                                                                                                                          } else {
                                                                                                                                              log.info("数值不合法");
                                                                                                                                          }
                                                                                                                                          // 调用方法进行修改
                                                                                                                                          baseMapper.updateById(sysUser);
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  整合前端

                                                                                                                                  定义前端路由

                                                                                                                                  src/api/system/sysUser.js

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第44张

                                                                                                                                  updateStatus(id, status) {
                                                                                                                                    return request({
                                                                                                                                      url: `${api_name}/updateStatus/${id}/${status}`,
                                                                                                                                      method: 'get'
                                                                                                                                    })
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  src/api/system/sysRole.js

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第45张

                                                                                                                                  getRoles(adminId) {
                                                                                                                                    return request({
                                                                                                                                      url: `${api_name}/toAssign/${adminId}`,
                                                                                                                                      method: 'get'
                                                                                                                                    })
                                                                                                                                  },
                                                                                                                                  assignRoles(assginRoleVo) {
                                                                                                                                    return request({
                                                                                                                                      url: `${api_name}/doAssign`,
                                                                                                                                      method: 'post',
                                                                                                                                      data: assginRoleVo
                                                                                                                                    })
                                                                                                                                  }
                                                                                                                                  
                                                                                                                                  修改前端页面

                                                                                                                                  list.vue

                                                                                                                                  
                                                                                                                                    
                                                                                                                                    
                                                                                                                                  

                                                                                                                                  页面展示

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第46张

                                                                                                                                  8、菜单管理

                                                                                                                                  8.1、菜单管理CRUD

                                                                                                                                  需求分析

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第47张

                                                                                                                                  编写代码

                                                                                                                                  SysMenuMapper

                                                                                                                                  public interface SysMenuMapper extends BaseMapper {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysRoleMenuMapper

                                                                                                                                  public interface SysRoleMenuMapper extends BaseMapper {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysMenuService

                                                                                                                                  public interface SysMenuService extends IService {
                                                                                                                                      List findNodes();
                                                                                                                                      // 删除菜单
                                                                                                                                      void removeMenuById(Long id);
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysRoleMenuService

                                                                                                                                  public interface SysRoleMenuService extends IService {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysMenuServiceImpl

                                                                                                                                  @Service
                                                                                                                                  public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService {
                                                                                                                                      @Override
                                                                                                                                      public List findNodes() {
                                                                                                                                          // 1、查询所有 的数据
                                                                                                                                          List sysMenuList = baseMapper.selectList(null);
                                                                                                                                          // 2、构建树形结构
                                                                                                                                          List list = MenuHelper.buildTree(sysMenuList);
                                                                                                                                          return list;
                                                                                                                                      }
                                                                                                                                      // 删除菜单
                                                                                                                                      @Override
                                                                                                                                      public void removeMenuById(Long id) {
                                                                                                                                          // 判断当前菜单是否有下一层菜单
                                                                                                                                          LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                          lambdaQueryWrapper.eq(SysMenu::getParentId,id);
                                                                                                                                          Integer count = baseMapper.selectCount(lambdaQueryWrapper);
                                                                                                                                          if (count>0){
                                                                                                                                              throw new GuiguException(201,"菜单不能删除");
                                                                                                                                          }
                                                                                                                                          baseMapper.deleteById(id);
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  MenuHelper

                                                                                                                                  package com.jerry.auth.util;
                                                                                                                                  import com.jerry.model.system.SysMenu;
                                                                                                                                  import java.util.ArrayList;
                                                                                                                                  import java.util.List;
                                                                                                                                  /**
                                                                                                                                   * ClassName: MenuHelper
                                                                                                                                   * Package: com.jerry.auth.util
                                                                                                                                   * Description:
                                                                                                                                   *
                                                                                                                                   * @Author jerry_jy
                                                                                                                                   * @Create 2023-03-02 17:14
                                                                                                                                   * @Version 1.0
                                                                                                                                   */
                                                                                                                                  public class MenuHelper {
                                                                                                                                      /**
                                                                                                                                       * 使用递归方法建菜单
                                                                                                                                       * @param sysMenuList
                                                                                                                                       * @return
                                                                                                                                       */
                                                                                                                                      public static List buildTree(List sysMenuList) {
                                                                                                                                          // 存放最终数据
                                                                                                                                          List trees = new ArrayList<>();
                                                                                                                                          // 把所有的菜单数据进行遍历
                                                                                                                                          for (SysMenu sysMenu : sysMenuList) {
                                                                                                                                              // 递归入口 parentId = 0
                                                                                                                                              if (sysMenu.getParentId().longValue()==0){
                                                                                                                                                  trees.add(getChildren(sysMenu,sysMenuList));
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                                          return trees;
                                                                                                                                      }
                                                                                                                                      /**
                                                                                                                                       * 递归查找子节点
                                                                                                                                       * @param sysMenu
                                                                                                                                       * @param sysMenuList
                                                                                                                                       * @return
                                                                                                                                       */
                                                                                                                                      public static SysMenu getChildren(SysMenu sysMenu,List sysMenuList){
                                                                                                                                          sysMenu.setChildren(new ArrayList());
                                                                                                                                          // 遍历所有的菜单数据,判断id和parent_id的对应关系
                                                                                                                                          for (SysMenu menu : sysMenuList) {
                                                                                                                                              if (sysMenu.getId().longValue() == menu.getParentId().longValue()){
                                                                                                                                                  if (sysMenu.getChildren() == null) {
                                                                                                                                                      sysMenu.setChildren(new ArrayList<>());
                                                                                                                                                  }
                                                                                                                                                  sysMenu.getChildren().add(getChildren(menu,sysMenuList));
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                                          return sysMenu;
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysRoleMenuServiceImpl

                                                                                                                                  @Service
                                                                                                                                  public class SysRoleMenuServiceImpl extends ServiceImpl implements SysRoleMenuService {
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  SysMenuController

                                                                                                                                  package com.jerry.auth.controller;
                                                                                                                                  import com.jerry.auth.service.SysMenuService;
                                                                                                                                  import com.jerry.common.result.Result;
                                                                                                                                  import com.jerry.model.system.SysMenu;
                                                                                                                                  import io.swagger.annotations.Api;
                                                                                                                                  import io.swagger.annotations.ApiOperation;
                                                                                                                                  import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                  import org.springframework.web.bind.annotation.*;
                                                                                                                                  import java.util.List;
                                                                                                                                  /**
                                                                                                                                   * 

                                                                                                                                  * 菜单表 前端控制器 *

                                                                                                                                  * * @author jerry * @since 2023-03-02 */ @Api(tags = "菜单管理接口") @RestController @RequestMapping("/admin/system/sysMenu") public class SysMenuController { @Autowired private SysMenuService sysMenuService; @ApiOperation(value = "菜单列表") @GetMapping("/findNodes") public Result findNodes() { List list = sysMenuService.findNodes(); return Result.ok(list); } @ApiOperation(value = "新增菜单") @PostMapping("save") public Result save(@RequestBody SysMenu sysMenu) { sysMenuService.save(sysMenu); return Result.ok(); } @ApiOperation(value = "修改菜单") @PutMapping("update") public Result updateById(@RequestBody SysMenu sysMenu) { sysMenuService.updateById(sysMenu); return Result.ok(); } @ApiOperation(value = "删除菜单") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { sysMenuService.removeMenuById(id); return Result.ok(); } }

                                                                                                                                  接口测试

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第48张

                                                                                                                                  整合前端

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第49张

                                                                                                                                        {
                                                                                                                                          name: 'sysMenu',
                                                                                                                                          path: 'sysMenu',
                                                                                                                                          component: () => import('@/views/system/sysMenu/list'),
                                                                                                                                          meta: {
                                                                                                                                            title: '菜单管理',
                                                                                                                                            icon: 'el-icon-s-unfold'
                                                                                                                                          },
                                                                                                                                        }
                                                                                                                                  
                                                                                                                                  sysMenu.js

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第50张

                                                                                                                                  import request from '@/utils/request'
                                                                                                                                  /*
                                                                                                                                  菜单管理相关的API请求函数
                                                                                                                                  */
                                                                                                                                  const api_name = '/admin/system/sysMenu'
                                                                                                                                  export default {
                                                                                                                                    /*
                                                                                                                                    获取权限(菜单/功能)列表
                                                                                                                                    */
                                                                                                                                    findNodes() {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/findNodes`,
                                                                                                                                        method: 'get'
                                                                                                                                      })
                                                                                                                                    },
                                                                                                                                    /*
                                                                                                                                    删除一个权限项
                                                                                                                                    */
                                                                                                                                    removeById(id) {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/remove/${id}`,
                                                                                                                                        method: "delete"
                                                                                                                                      })
                                                                                                                                    },
                                                                                                                                    /*
                                                                                                                                    保存一个权限项
                                                                                                                                    */
                                                                                                                                    save(sysMenu) {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/save`,
                                                                                                                                        method: "post",
                                                                                                                                        data: sysMenu
                                                                                                                                      })
                                                                                                                                    },
                                                                                                                                    /*
                                                                                                                                    更新一个权限项
                                                                                                                                    */
                                                                                                                                    updateById(sysMenu) {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/update`,
                                                                                                                                        method: "put",
                                                                                                                                        data: sysMenu
                                                                                                                                      })
                                                                                                                                    }
                                                                                                                                  }
                                                                                                                                  
                                                                                                                                  list.vue

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第51张

                                                                                                                                  
                                                                                                                                    
                                                                                                                                    
                                                                                                                                    
                                                                                                                                  

                                                                                                                                  页面展示

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第52张

                                                                                                                                  8.2、角色分配菜单功能

                                                                                                                                  需求分析

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第53张

                                                                                                                                  编写代码

                                                                                                                                  整合前端

                                                                                                                                  router/index.js

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第54张

                                                                                                                                        {
                                                                                                                                          path: 'assignAuth',
                                                                                                                                          component: () => import('@/views/system/sysRole/assignAuth'),
                                                                                                                                          meta: {
                                                                                                                                            activeMenu: '/system/sysRole',
                                                                                                                                            title: '角色授权'
                                                                                                                                          },
                                                                                                                                          hidden: true,
                                                                                                                                        }
                                                                                                                                  
                                                                                                                                  sysRole/list.vue

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第55张

                                                                                                                                  添加一个分配权限的button按钮

                                                                                                                                            
                                                                                                                                  
                                                                                                                                      // 跳转到分配菜单的页面
                                                                                                                                      showAssignAuth(row) {
                                                                                                                                      this.$router.push('/system/assignAuth?id='+row.id+'&roleName='+row.roleName);
                                                                                                                                      },
                                                                                                                                  
                                                                                                                                  sysMenu.js

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第56张

                                                                                                                                    /*
                                                                                                                                  查看某个角色的权限列表
                                                                                                                                  */
                                                                                                                                  toAssign(roleId) {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/toAssign/${roleId}`,
                                                                                                                                        method: 'get'
                                                                                                                                      })
                                                                                                                                    },
                                                                                                                                    
                                                                                                                                    /*
                                                                                                                                    给某个角色授权
                                                                                                                                    */
                                                                                                                                    doAssign(assginMenuVo) {
                                                                                                                                      return request({
                                                                                                                                        url: `${api_name}/doAssign`,
                                                                                                                                        method: "post",
                                                                                                                                        data: assginMenuVo
                                                                                                                                      })
                                                                                                                                    }
                                                                                                                                  
                                                                                                                                  assignAuth.vue

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第57张

                                                                                                                                  
                                                                                                                                    
                                                                                                                                  

                                                                                                                                  关闭Vue语法校验,避免报错

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第58张

                                                                                                                                  页面展示

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第59张

                                                                                                                                  9、权限管理(重难点)

                                                                                                                                  9.1、用户登录权限管理

                                                                                                                                  需求分析

                                                                                                                                  云上办公系统项目,在这里插入图片描述,第60张

                                                                                                                                  引入JWT

                                                                                                                                  • JWT是JSON Web Token的缩写

                                                                                                                                  • 一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上

                                                                                                                                  • 官网:https://jwt.io/

                                                                                                                                  • 最重要的作用就是对 token信息的防伪作用。

                                                                                                                                  • 由三个部分组成:JWT头、有效载荷、签名哈希

                                                                                                                                  • base64url算法编码得到JWT

                                                                                                                                    common-util

                                                                                                                                            
                                                                                                                                                io.jsonwebtoken
                                                                                                                                                jjwt
                                                                                                                                            
                                                                                                                                    

                                                                                                                                    JwtHwlper

                                                                                                                                    package com.jerry.common.jwt;
                                                                                                                                    import io.jsonwebtoken.*;
                                                                                                                                    import org.springframework.util.StringUtils;
                                                                                                                                    import java.util.Date;
                                                                                                                                    /**
                                                                                                                                     * ClassName: JwtHwlper
                                                                                                                                     * Package: com.jerry.common
                                                                                                                                     * Description:
                                                                                                                                     *
                                                                                                                                     * @Author jerry_jy
                                                                                                                                     * @Create 2023-03-02 20:39
                                                                                                                                     * @Version 1.0
                                                                                                                                     */
                                                                                                                                    public class JwtHelper {
                                                                                                                                        private static long tokenExpiration = 365 * 24 * 60 * 60 * 1000;
                                                                                                                                        private static String tokenSignKey = "123456";
                                                                                                                                        // 根据用户 id 和用户名称, 生成token的字符串
                                                                                                                                        public static String createToken(Long userId, String username) {
                                                                                                                                            String token = Jwts.builder()
                                                                                                                                                    .setSubject("AUTH-USER")
                                                                                                                                                    .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                                                                                                                                                    .claim("userId", userId)
                                                                                                                                                    .claim("username", username)
                                                                                                                                                    .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                                                                                                                                                    .compressWith(CompressionCodecs.GZIP)
                                                                                                                                                    .compact();
                                                                                                                                            return token;
                                                                                                                                        }
                                                                                                                                        public static Long getUserId(String token) {
                                                                                                                                            try {
                                                                                                                                                if (StringUtils.isEmpty(token)) return null;
                                                                                                                                                Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
                                                                                                                                                Claims claims = claimsJws.getBody();
                                                                                                                                                Integer userId = (Integer) claims.get("userId");
                                                                                                                                                return userId.longValue();
                                                                                                                                            } catch (Exception e) {
                                                                                                                                                e.printStackTrace();
                                                                                                                                                return null;
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                        public static String getUsername(String token) {
                                                                                                                                            try {
                                                                                                                                                if (StringUtils.isEmpty(token)) return "";
                                                                                                                                                Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
                                                                                                                                                Claims claims = claimsJws.getBody();
                                                                                                                                                return (String) claims.get("username");
                                                                                                                                            } catch (Exception e) {
                                                                                                                                                e.printStackTrace();
                                                                                                                                                return null;
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                        public static void main(String[] args) {
                                                                                                                                            String token = JwtHelper.createToken(1L, "admin");
                                                                                                                                            System.out.println(token);
                                                                                                                                            String username = JwtHelper.getUsername(token);
                                                                                                                                            Long userId = JwtHelper.getUserId(token);
                                                                                                                                            System.out.println("username = " + username);
                                                                                                                                            System.out.println("userId = " + userId);
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    

                                                                                                                                    修改用户登录

                                                                                                                                    先引入MD5工具类
                                                                                                                                    package com.jerry.common.utils;
                                                                                                                                    import java.security.MessageDigest;
                                                                                                                                    import java.security.NoSuchAlgorithmException;
                                                                                                                                    public final class MD5 {
                                                                                                                                        public static String encrypt(String strSrc) {
                                                                                                                                            try {
                                                                                                                                                char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                                                                                                                                                        '9', 'a', 'b', 'c', 'd', 'e', 'f' };
                                                                                                                                                byte[] bytes = strSrc.getBytes();
                                                                                                                                                MessageDigest md = MessageDigest.getInstance("MD5");
                                                                                                                                                md.update(bytes);
                                                                                                                                                bytes = md.digest();
                                                                                                                                                int j = bytes.length;
                                                                                                                                                char[] chars = new char[j * 2];
                                                                                                                                                int k = 0;
                                                                                                                                                for (int i = 0; i < bytes.length; i++) {
                                                                                                                                                    byte b = bytes[i];
                                                                                                                                                    chars[k++] = hexChars[b >>> 4 & 0xf];
                                                                                                                                                    chars[k++] = hexChars[b & 0xf];
                                                                                                                                                }
                                                                                                                                                return new String(chars);
                                                                                                                                            } catch (NoSuchAlgorithmException e) {
                                                                                                                                                e.printStackTrace();
                                                                                                                                                throw new RuntimeException("MD5加密出错!!+" + e);
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                        public static void main(String[] args) {
                                                                                                                                            System.out.println(MD5.encrypt("111111"));
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    
                                                                                                                                    修改SysUserControler保存用户的方法

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第61张

                                                                                                                                    修改IndexController的登录方法
                                                                                                                                    package com.jerry.auth.controller;
                                                                                                                                    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
                                                                                                                                    import com.jerry.auth.service.SysMenuService;
                                                                                                                                    import com.jerry.auth.service.SysUserService;
                                                                                                                                    import com.jerry.common.config.exception.GuiguException;
                                                                                                                                    import com.jerry.common.jwt.JwtHelper;
                                                                                                                                    import com.jerry.common.result.Result;
                                                                                                                                    import com.jerry.common.utils.MD5;
                                                                                                                                    import com.jerry.model.system.SysUser;
                                                                                                                                    import com.jerry.vo.system.LoginVo;
                                                                                                                                    import com.jerry.vo.system.RouterVo;
                                                                                                                                    import io.swagger.annotations.Api;
                                                                                                                                    import io.swagger.annotations.ApiOperation;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.web.bind.annotation.*;
                                                                                                                                    import javax.servlet.http.HttpServletRequest;
                                                                                                                                    import java.util.HashMap;
                                                                                                                                    import java.util.List;
                                                                                                                                    import java.util.Map;
                                                                                                                                    import java.util.Objects;
                                                                                                                                    /**
                                                                                                                                     * ClassName: IndexController
                                                                                                                                     * Package: com.jerry.auth.controller
                                                                                                                                     * Description:
                                                                                                                                     *
                                                                                                                                     * @Author jerry_jy
                                                                                                                                     * @Create 2023-03-01 18:15
                                                                                                                                     * @Version 1.0
                                                                                                                                     */
                                                                                                                                    @Api(tags = "后台登录管理")
                                                                                                                                    @RestController
                                                                                                                                    @RequestMapping("/admin/system/index")
                                                                                                                                    public class IndexController {
                                                                                                                                        @Autowired
                                                                                                                                        private SysUserService sysUserService;
                                                                                                                                        @Autowired
                                                                                                                                        private SysMenuService sysMenuService;
                                                                                                                                        /**
                                                                                                                                         * login
                                                                                                                                         *
                                                                                                                                         * @return
                                                                                                                                         */
                                                                                                                                        @ApiOperation("登录")
                                                                                                                                        @PostMapping("/login")
                                                                                                                                        public Result login(@RequestBody LoginVo loginVo) {
                                                                                                                                            // {"code":200,"data":{"token":"admin-token"}}
                                                                                                                                    //        HashMap map = new HashMap<>();
                                                                                                                                    //        map.put("token","admin-token");
                                                                                                                                    //        return Result.ok(map);
                                                                                                                                            // 1、获取用户名和密码
                                                                                                                                            // 2、根据用户名查询数据库
                                                                                                                                            String username = loginVo.getUsername();
                                                                                                                                            LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                            queryWrapper.eq(SysUser::getUsername, username);
                                                                                                                                            SysUser sysUser = sysUserService.getOne(queryWrapper);
                                                                                                                                            // 3、用户信息是否存在
                                                                                                                                            if (sysUser == null) {
                                                                                                                                                throw new GuiguException(201, "用户不存在...");
                                                                                                                                            }
                                                                                                                                            // 4、判断密码
                                                                                                                                            // 取出数据库中的密文密码(MD5)
                                                                                                                                            String password_dB = sysUser.getPassword();
                                                                                                                                            String password_input = MD5.encrypt(loginVo.getPassword());
                                                                                                                                            if (!password_dB.equals(password_input)) {
                                                                                                                                                throw new GuiguException(201, "密码错误...");
                                                                                                                                            }
                                                                                                                                            // 5、判断用户是否被禁用  1  可用    0   禁用
                                                                                                                                            if (sysUser.getStatus().intValue() == 0) {
                                                                                                                                                throw new GuiguException(201, "用户被禁用...");
                                                                                                                                            }
                                                                                                                                            // 6、使用jwt根据用户id和用户名称生成token的字符串
                                                                                                                                            String token = JwtHelper.createToken(sysUser.getId(), sysUser.getUsername());
                                                                                                                                            // 7、返回
                                                                                                                                            Map map = new HashMap<>();
                                                                                                                                            map.put("token", token);
                                                                                                                                            return Result.ok(map);
                                                                                                                                        }
                                                                                                                                        /**
                                                                                                                                         * info
                                                                                                                                         *
                                                                                                                                         * @return
                                                                                                                                         */
                                                                                                                                        @GetMapping("/info")
                                                                                                                                        public Result info(HttpServletRequest request) {
                                                                                                                                            // 1、从请求头获取用户信息(获取请求头的 token 字符串)
                                                                                                                                            String token = request.getHeader("token");
                                                                                                                                            // 2、从 token 字符串中获取 用户id 或者 用户名称
                                                                                                                                            Long userId = JwtHelper.getUserId(token); //1L;
                                                                                                                                            // 3、根据 用户id 查询数据库, 获取用户信息
                                                                                                                                            SysUser sysUser = sysUserService.getById(userId);
                                                                                                                                            // 4、根据 用户id 获取用户可以操作的菜单列表
                                                                                                                                            // 查询数据库动态构建路由结构,进行显示
                                                                                                                                            List routerList = sysMenuService.findUserMenuListByUserId(userId);
                                                                                                                                            // 5、根据 用户id 获取用户可以操作的按钮列表
                                                                                                                                            List permsList = sysMenuService.findUserPermsByUserId(userId);
                                                                                                                                            // 6、返回相应的数据
                                                                                                                                            Map map = new HashMap<>();
                                                                                                                                            map.put("roles", "[admin]");
                                                                                                                                            map.put("name", sysUser.getName());
                                                                                                                                            map.put("avatar", "https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                                                                                                                                            // 返回用户可以操作的菜单
                                                                                                                                            map.put("routers", routerList);
                                                                                                                                            // 返回用户可以操作的按钮
                                                                                                                                            map.put("buttons", permsList);
                                                                                                                                            return Result.ok(map);
                                                                                                                                        }
                                                                                                                                        /**
                                                                                                                                         * logout
                                                                                                                                         *
                                                                                                                                         * @return
                                                                                                                                         */
                                                                                                                                        @ApiOperation("登出")
                                                                                                                                        @PostMapping("/logout")
                                                                                                                                        public Result logout() {
                                                                                                                                            return Result.ok();
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    
                                                                                                                                    SysMenuService
                                                                                                                                        // 根据 用户id 获取用户可以操作的菜单列表
                                                                                                                                        List findUserMenuListByUserId(Long userId);
                                                                                                                                        // 根据 用户id 获取用户可以操作的按钮列表
                                                                                                                                        List findUserPermsByUserId(Long userId);
                                                                                                                                    
                                                                                                                                    SysMenuServiceImpl
                                                                                                                                        // 根据 用户id 获取用户可以操作的菜单列表
                                                                                                                                        @Override
                                                                                                                                        public List findUserMenuListByUserId(Long userId) {
                                                                                                                                            List sysMenusList = null;
                                                                                                                                            // 1、判断当前用户是否是管理员       userId=1 是管理员
                                                                                                                                            // 1.1、 如果是管理员,查询所有菜单列表
                                                                                                                                            if (userId.longValue() == 1) {
                                                                                                                                                // 查询所有菜单列表
                                                                                                                                                LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                                queryWrapper.eq(SysMenu::getStatus, 1);
                                                                                                                                                queryWrapper.orderByAsc(SysMenu::getSortValue);
                                                                                                                                                sysMenusList = baseMapper.selectList(queryWrapper);
                                                                                                                                            } else {
                                                                                                                                                // 1.2、如果不是管理员,根据 userId 查询可以操作菜单列表
                                                                                                                                                // 多表关联查询:sys_role、sys_role_mexnu、sys_menu
                                                                                                                                                sysMenusList = baseMapper.findMenuListByUserId(userId);
                                                                                                                                            }
                                                                                                                                            // 2、把查询出来的数据列表, 构建成框架要求的路由结构
                                                                                                                                            // 先构建树形结构
                                                                                                                                            List sysMenuTreeList = MenuHelper.buildTree(sysMenusList);
                                                                                                                                            // 构建框架要求的路由结构
                                                                                                                                            List routerList = this.buildRouter(sysMenuTreeList);
                                                                                                                                            return routerList;
                                                                                                                                        }
                                                                                                                                        // 构建框架要求的路由结构
                                                                                                                                        private List buildRouter(List menus) {
                                                                                                                                            // 创建 list 集合,存值最终数据
                                                                                                                                            List routers = new ArrayList<>();
                                                                                                                                            // menus 遍历
                                                                                                                                            for (SysMenu menu : menus) {
                                                                                                                                                RouterVo router = new RouterVo();
                                                                                                                                                router.setHidden(false);
                                                                                                                                                router.setAlwaysShow(false);
                                                                                                                                                router.setPath(getRouterPath(menu));
                                                                                                                                                router.setComponent(menu.getComponent());
                                                                                                                                                router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
                                                                                                                                                // 下一层数据
                                                                                                                                                List children = menu.getChildren();
                                                                                                                                                if (menu.getType().intValue() == 1) {
                                                                                                                                                    // 加载隐藏路由
                                                                                                                                                    List hiddenMenuList = children.stream().filter(item -> !StringUtils.isEmpty(item.getComponent())).collect(Collectors.toList());
                                                                                                                                                    for (SysMenu hiddenMenu : hiddenMenuList) {
                                                                                                                                                        RouterVo hiddenRouter = new RouterVo();
                                                                                                                                                        hiddenRouter.setHidden(true);
                                                                                                                                                        hiddenRouter.setAlwaysShow(false);
                                                                                                                                                        hiddenRouter.setPath(getRouterPath(hiddenMenu));
                                                                                                                                                        hiddenRouter.setComponent(hiddenMenu.getComponent());
                                                                                                                                                        hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                                                                                                                                                        routers.add(hiddenRouter);
                                                                                                                                                    }
                                                                                                                                                }else {
                                                                                                                                                    if (!CollectionUtils.isEmpty(children)) {
                                                                                                                                                        if(children.size() > 0) {
                                                                                                                                                            router.setAlwaysShow(true);
                                                                                                                                                        }
                                                                                                                                                        // 递归
                                                                                                                                                        router.setChildren(buildRouter(children));
                                                                                                                                                    }
                                                                                                                                                }
                                                                                                                                                routers.add(router);
                                                                                                                                            }
                                                                                                                                            return routers;
                                                                                                                                        }
                                                                                                                                        /**
                                                                                                                                         * 获取路由地址
                                                                                                                                         *
                                                                                                                                         * @param menu 菜单信息
                                                                                                                                         * @return 路由地址
                                                                                                                                         */
                                                                                                                                        public String getRouterPath(SysMenu menu) {
                                                                                                                                            String routerPath = "/" + menu.getPath();
                                                                                                                                            if (menu.getParentId().intValue() != 0) {
                                                                                                                                                routerPath = menu.getPath();
                                                                                                                                            }
                                                                                                                                            return routerPath;
                                                                                                                                        }
                                                                                                                                        // 根据 用户id 获取用户可以操作的按钮列表
                                                                                                                                        @Override
                                                                                                                                        public List findUserPermsByUserId(Long userId) {
                                                                                                                                            // 1、判断是否是管理员,如果是管理员,查询所有按钮列表
                                                                                                                                            List sysMenusList = null;
                                                                                                                                            if (userId.longValue() == 1) {
                                                                                                                                                // 查询所有菜单列表
                                                                                                                                                LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                                queryWrapper.eq(SysMenu::getStatus, 1);
                                                                                                                                                sysMenusList = baseMapper.selectList(queryWrapper);
                                                                                                                                            }else {
                                                                                                                                                // 2、如果不是管理员,根据userId查询可以操作按钮列表
                                                                                                                                                // 多表关联查询:sys_role、sys_role_menu、sys_menu
                                                                                                                                                sysMenusList = baseMapper.findMenuListByUserId(userId);
                                                                                                                                            }
                                                                                                                                            // 3、从查询出来的数据里面,获取可以操作按钮值的List集合,返回
                                                                                                                                            List permsList = sysMenusList.stream()
                                                                                                                                                    .filter(item -> item.getType() == 2)
                                                                                                                                                    .map(item -> item.getPerms())
                                                                                                                                                    .collect(Collectors.toList());
                                                                                                                                            return permsList;
                                                                                                                                        }
                                                                                                                                    

                                                                                                                                    接口测试

                                                                                                                                    登录接口测试

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第62张

                                                                                                                                    info接口测试

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第63张

                                                                                                                                    我这里没有报错,如果出现以下的报错信息

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第64张

                                                                                                                                    解决思路是:

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第65张

                                                                                                                                    1、在pom.xml添加

                                                                                                                                        
                                                                                                                                            
                                                                                                                                                
                                                                                                                                                    org.springframework.boot
                                                                                                                                                    spring-boot-maven-plugin
                                                                                                                                                
                                                                                                                                            
                                                                                                                                            
                                                                                                                                                
                                                                                                                                                    src/main/java
                                                                                                                                                    
                                                                                                                                                        **/*.yml
                                                                                                                                                        **/*.properties
                                                                                                                                                        **/*.xml
                                                                                                                                                    
                                                                                                                                                    false
                                                                                                                                                
                                                                                                                                                
                                                                                                                                                    src/main/resources
                                                                                                                                                     **/*.yml
                                                                                                                                                        **/*.properties
                                                                                                                                                        **/*.xml
                                                                                                                                                    
                                                                                                                                                    false
                                                                                                                                                
                                                                                                                                            
                                                                                                                                        
                                                                                                                                    

                                                                                                                                    2、application-dev.yml添加

                                                                                                                                    mybatis-plus:
                                                                                                                                      mapper-locations: classpath:com/atguigu/auth/mapper/xml/*.xml
                                                                                                                                    

                                                                                                                                    整合前端

                                                                                                                                    从这部分开始,整合前端不在写了,比较麻烦,直接复用现有的

                                                                                                                                    页面展示

                                                                                                                                    给李四分配没有添加的权限

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第66张

                                                                                                                                    9.2、用户认证

                                                                                                                                    整合SpringSecurity

                                                                                                                                    本项目采用 Spring-Security 来做用户认证和权限控制,也可以采用 Shiro

                                                                                                                                    新建一个spring-security的module

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第67张

                                                                                                                                    引入依赖
                                                                                                                                    
                                                                                                                                        4.0.0
                                                                                                                                        
                                                                                                                                            com.jerry
                                                                                                                                            common
                                                                                                                                            1.0
                                                                                                                                        
                                                                                                                                        spring-security
                                                                                                                                        
                                                                                                                                            
                                                                                                                                                com.jerry
                                                                                                                                                common-util
                                                                                                                                                1.0
                                                                                                                                            
                                                                                                                                            
                                                                                                                                            
                                                                                                                                                org.springframework.boot
                                                                                                                                                spring-boot-starter-security
                                                                                                                                            
                                                                                                                                            
                                                                                                                                                org.springframework.boot
                                                                                                                                                spring-boot-starter-web
                                                                                                                                                provided 
                                                                                                                                            
                                                                                                                                        
                                                                                                                                    
                                                                                                                                    
                                                                                                                                    添加配置类
                                                                                                                                    package com.jerry.security.config;
                                                                                                                                    import org.springframework.context.annotation.Configuration;
                                                                                                                                    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
                                                                                                                                    /**
                                                                                                                                     * ClassName: WebSecurityConfig
                                                                                                                                     * Package: com.jerry.security.config
                                                                                                                                     * Description:
                                                                                                                                     *
                                                                                                                                     * @Author jerry_jy
                                                                                                                                     * @Create 2023-03-03 13:44
                                                                                                                                     * @Version 1.0
                                                                                                                                     */
                                                                                                                                    @Configuration
                                                                                                                                    @EnableWebSecurity  //@EnableWebSecurity是开启SpringSecurity的默认行为
                                                                                                                                    public class WebSecurityConfig {
                                                                                                                                    }
                                                                                                                                    

                                                                                                                                    在 service-oa 中引入spring-security的module

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第68张

                                                                                                                                    测试

                                                                                                                                    在浏览器访问:http://localhost:8800/admin/system/sysRole/getAll

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第69张

                                                                                                                                    这时候想绕过登录页是不能的,后台服务经过会spring-security做了用户认证,提示用户需要先登录

                                                                                                                                    默认的登录名是:user

                                                                                                                                    密码是IDEA中生成的一串随机字符,每次都不一样

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第70张

                                                                                                                                    用户认证

                                                                                                                                    流程分析

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第71张

                                                                                                                                    自定义组件的编写

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第72张

                                                                                                                                    操作spring-securitymodule

                                                                                                                                    自定义加密器PasswordEncoder
                                                                                                                                    @Component
                                                                                                                                    public class CustomMd5PasswordEncoder implements PasswordEncoder {
                                                                                                                                        public String encode(CharSequence rawPassword) {
                                                                                                                                            return MD5.encrypt(rawPassword.toString());
                                                                                                                                        }
                                                                                                                                        public boolean matches(CharSequence rawPassword, String encodedPassword) {
                                                                                                                                            return encodedPassword.equals(MD5.encrypt(rawPassword.toString()));
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    
                                                                                                                                    自定义用户对象UserDetails
                                                                                                                                    public class CustomUser extends User {
                                                                                                                                        /**
                                                                                                                                         * 我们自己的用户实体对象,要调取用户信息时直接获取这个实体对象。(这里我就不写get/set方法了)
                                                                                                                                         */
                                                                                                                                        private SysUser sysUser;
                                                                                                                                        public CustomUser(SysUser sysUser, Collection authorities) {
                                                                                                                                            super(sysUser.getUsername(), sysUser.getPassword(), authorities);
                                                                                                                                            this.sysUser = sysUser;
                                                                                                                                        }
                                                                                                                                        public SysUser getSysUser() {
                                                                                                                                            return sysUser;
                                                                                                                                        }
                                                                                                                                        public void setSysUser(SysUser sysUser) {
                                                                                                                                            this.sysUser = sysUser;
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    
                                                                                                                                    UserDetailsService
                                                                                                                                    public interface UserDetailsService {
                                                                                                                                        /**
                                                                                                                                         * 根据用户名获取用户对象(获取不到直接抛异常)
                                                                                                                                         */
                                                                                                                                        UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
                                                                                                                                    }
                                                                                                                                    

                                                                                                                                    操作service-oamodule

                                                                                                                                    UserDetailsServiceImpl
                                                                                                                                    @Service
                                                                                                                                    public class UserDetailsServiceImpl implements UserDetailsService {
                                                                                                                                        @Autowired
                                                                                                                                        private SysUserService sysUserService;
                                                                                                                                        @Override
                                                                                                                                        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                                                                                                                                            // 根据用户名查询
                                                                                                                                            SysUser sysUser = sysUserService.getUserByUserName(username);
                                                                                                                                            if(null == sysUser) {
                                                                                                                                                throw new UsernameNotFoundException("用户名不存在!");
                                                                                                                                            }
                                                                                                                                            if(sysUser.getStatus().intValue() == 0) {
                                                                                                                                                throw new RuntimeException("账号已停用");
                                                                                                                                            }
                                                                                                                                            return new CustomUser(sysUser, Collections.emptyList());
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    

                                                                                                                                    SysUserService

                                                                                                                                        SysUser getUserByUserName(String username);
                                                                                                                                    

                                                                                                                                    SysUserServiceImpl

                                                                                                                                        // 根据用户名查询
                                                                                                                                        @Override
                                                                                                                                        public SysUser getUserByUserName(String username) {
                                                                                                                                            LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
                                                                                                                                            queryWrapper.eq(SysUser::getUsername,username);
                                                                                                                                            SysUser sysUser = baseMapper.selectOne(queryWrapper);
                                                                                                                                            return sysUser;
                                                                                                                                        }
                                                                                                                                    
                                                                                                                                    自定义用户认证接口

                                                                                                                                    TokenLoginFilter

                                                                                                                                    package com.jerry.security.filter;
                                                                                                                                    import com.fasterxml.jackson.databind.ObjectMapper;
                                                                                                                                    import com.jerry.common.jwt.JwtHelper;
                                                                                                                                    import com.jerry.common.result.ResponseUtil;
                                                                                                                                    import com.jerry.common.result.Result;
                                                                                                                                    import com.jerry.common.result.ResultCodeEnum;
                                                                                                                                    import com.jerry.security.custom.CustomUser;
                                                                                                                                    import com.jerry.vo.system.LoginVo;
                                                                                                                                    import org.springframework.security.authentication.AuthenticationManager;
                                                                                                                                    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
                                                                                                                                    import org.springframework.security.core.Authentication;
                                                                                                                                    import org.springframework.security.core.AuthenticationException;
                                                                                                                                    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
                                                                                                                                    import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
                                                                                                                                    import javax.servlet.FilterChain;
                                                                                                                                    import javax.servlet.ServletException;
                                                                                                                                    import javax.servlet.http.HttpServletRequest;
                                                                                                                                    import javax.servlet.http.HttpServletResponse;
                                                                                                                                    import java.io.IOException;
                                                                                                                                    import java.util.HashMap;
                                                                                                                                    import java.util.Map;
                                                                                                                                    /**
                                                                                                                                     * ClassName: TokenLoginFilter 
                                                                                                                                    * Package: com.jerry.security.filter
                                                                                                                                    * Description: 登录过滤器,继承UsernamePasswordAuthenticationFilter,对用户名密码进行登录校验 * * @Author: jerry_jy * @Create: 2023-03-03 15:29 * @Version: 1.0 */ public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter { // 构造方法 public TokenLoginFilter(AuthenticationManager authenticationManager){ this.setAuthenticationManager(authenticationManager); this.setPostOnly(false); //指定登录接口及提交方式,可以指定任意路径 this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/index/login","POST")); } // 登录认证过程 // 获取输入的用户名和密码,调用方法认证 @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException { try { // 获取用户信息 LoginVo loginVo = new ObjectMapper().readValue(req.getInputStream(), LoginVo.class); //封装对象 Authentication authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword()); //调用方法 return this.getAuthenticationManager().authenticate(authenticationToken); } catch (IOException e) { throw new RuntimeException(e); } } // 认证成功调用的方法 @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) throws IOException, ServletException { // 获取当前用户 CustomUser customUser = (CustomUser) auth.getPrincipal(); // 生成token String token = JwtHelper.createToken(customUser.getSysUser().getId(), customUser.getSysUser().getUsername()); // 返回 Map map = new HashMap<>(); map.put("token", token); ResponseUtil.out(response, Result.ok(map)); } // 认证失败调用的方法 @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { if(e.getCause() instanceof RuntimeException) { ResponseUtil.out(response, Result.build(null, ResultCodeEnum.DATA_ERROR)); } else { ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_AUTH)); } } }

                                                                                                                                    common-util下的ResponseUtil

                                                                                                                                    package com.jerry.common.result;
                                                                                                                                    import com.fasterxml.jackson.databind.ObjectMapper;
                                                                                                                                    import org.springframework.http.HttpStatus;
                                                                                                                                    import org.springframework.http.MediaType;
                                                                                                                                    import javax.servlet.http.HttpServletResponse;
                                                                                                                                    import java.io.IOException;
                                                                                                                                    /**
                                                                                                                                     * ClassName: ResponseUtil 
                                                                                                                                    * Package: com.jerry.common.result
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-03 15:55 * @Version: 1.0 */ public class ResponseUtil { public static void out(HttpServletResponse response, Result r) { ObjectMapper mapper = new ObjectMapper(); response.setStatus(HttpStatus.OK.value()); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); try { mapper.writeValue(response.getWriter(), r); } catch (IOException e) { e.printStackTrace(); } } }
                                                                                                                                    认证解析token

                                                                                                                                    因为用户登录状态在token中存储在客户端,所以每次请求接口请求头携带token, 后台通过自定义token过滤器拦截解析token完成认证并填充用户信息实体

                                                                                                                                    package com.jerry.security.filter;
                                                                                                                                    import com.jerry.common.jwt.JwtHelper;
                                                                                                                                    import com.jerry.common.result.ResponseUtil;
                                                                                                                                    import com.jerry.common.result.Result;
                                                                                                                                    import com.jerry.common.result.ResultCodeEnum;
                                                                                                                                    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
                                                                                                                                    import org.springframework.security.core.context.SecurityContextHolder;
                                                                                                                                    import org.springframework.util.StringUtils;
                                                                                                                                    import org.springframework.web.filter.OncePerRequestFilter;
                                                                                                                                    import javax.servlet.FilterChain;
                                                                                                                                    import javax.servlet.ServletException;
                                                                                                                                    import javax.servlet.http.HttpServletRequest;
                                                                                                                                    import javax.servlet.http.HttpServletResponse;
                                                                                                                                    import java.io.IOException;
                                                                                                                                    import java.util.Collections;
                                                                                                                                    /**
                                                                                                                                     * ClassName: TokenAuthenticationFilter 
                                                                                                                                    * Package: com.jerry.security.filter
                                                                                                                                    * Description: 认证解析token过滤器 * * @Author: jerry_jy * @Create: 2023-03-03 16:01 * @Version: 1.0 */ public class TokenAuthenticationFilter extends OncePerRequestFilter { public TokenAuthenticationFilter() { } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { logger.info("uri:"+request.getRequestURI()); //如果是登录接口,直接放行 if("/admin/system/index/login".equals(request.getRequestURI())) { chain.doFilter(request, response); return; } UsernamePasswordAuthenticationToken authentication = getAuthentication(request); if(null != authentication) { SecurityContextHolder.getContext().setAuthentication(authentication); chain.doFilter(request, response); } else { ResponseUtil.out(response, Result.build(null, ResultCodeEnum.PERMISSION)); } } private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { // token置于header里 String token = request.getHeader("token"); logger.info("token:"+token); if (!StringUtils.isEmpty(token)) { String username = JwtHelper.getUsername(token); logger.info("username:"+username); if (!StringUtils.isEmpty(username)) { return new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()); } } return null; } }
                                                                                                                                    配置用户认证
                                                                                                                                    package com.jerry.security.config;
                                                                                                                                    import com.jerry.security.custom.CustomMd5PasswordEncoder;
                                                                                                                                    import com.jerry.security.filter.TokenAuthenticationFilter;
                                                                                                                                    import com.jerry.security.filter.TokenLoginFilter;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.context.annotation.Bean;
                                                                                                                                    import org.springframework.context.annotation.Configuration;
                                                                                                                                    import org.springframework.security.authentication.AuthenticationManager;
                                                                                                                                    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
                                                                                                                                    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
                                                                                                                                    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
                                                                                                                                    import org.springframework.security.config.annotation.web.builders.WebSecurity;
                                                                                                                                    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
                                                                                                                                    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
                                                                                                                                    import org.springframework.security.config.http.SessionCreationPolicy;
                                                                                                                                    import org.springframework.security.core.userdetails.UserDetailsService;
                                                                                                                                    import org.springframework.security.crypto.password.PasswordEncoder;
                                                                                                                                    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
                                                                                                                                    import org.springframework.web.cors.CorsUtils;
                                                                                                                                    /**
                                                                                                                                     * ClassName: WebSecurityConfig
                                                                                                                                     * Package: com.jerry.security.config
                                                                                                                                     * Description:
                                                                                                                                     *
                                                                                                                                     * @Author jerry_jy
                                                                                                                                     * @Create 2023-03-03 13:44
                                                                                                                                     * @Version 1.0
                                                                                                                                     */
                                                                                                                                    @Configuration
                                                                                                                                    @EnableWebSecurity  //@EnableWebSecurity是开启SpringSecurity的默认行为
                                                                                                                                    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                                                                                                                                        @Autowired
                                                                                                                                        private UserDetailsService userDetailsService; // 装载的是 org.springframework.security.core.userdetails.UserDetailsService;
                                                                                                                                        @Autowired
                                                                                                                                        private CustomMd5PasswordEncoder customMd5PasswordEncoder;
                                                                                                                                        @Bean
                                                                                                                                        @Override
                                                                                                                                        protected AuthenticationManager authenticationManager() throws Exception {
                                                                                                                                            return super.authenticationManager();
                                                                                                                                        }
                                                                                                                                        @Override
                                                                                                                                        protected void configure(HttpSecurity http) throws Exception {
                                                                                                                                            // 这是配置的关键,决定哪些接口开启防护,哪些接口绕过防护
                                                                                                                                            http
                                                                                                                                                    //关闭csrf跨站请求伪造
                                                                                                                                                    .csrf().disable()
                                                                                                                                                    // 开启跨域以便前端调用接口
                                                                                                                                                    .cors().and()
                                                                                                                                                    .authorizeRequests()
                                                                                                                                                    // 指定某些接口不需要通过验证即可访问。登陆接口肯定是不需要认证的
                                                                                                                                                    .antMatchers("/admin/system/index/login").permitAll()
                                                                                                                                                    // 这里意思是其它所有接口需要认证才能访问
                                                                                                                                                    .anyRequest().authenticated()
                                                                                                                                                    .and()
                                                                                                                                                    //TokenAuthenticationFilter放到UsernamePasswordAuthenticationFilter的前面,这样做就是为了除了登录的时候去查询数据库外,其他时候都用token进行认证。
                                                                                                                                                    .addFilterBefore(new TokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                                                                                                                                                    .addFilter(new TokenLoginFilter(authenticationManager()));
                                                                                                                                            //禁用session
                                                                                                                                            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
                                                                                                                                        }
                                                                                                                                        @Override
                                                                                                                                        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                                                                                                                                            // 指定UserDetailService和加密器
                                                                                                                                            auth.userDetailsService(userDetailsService)
                                                                                                                                                    .passwordEncoder(customMd5PasswordEncoder);
                                                                                                                                        }
                                                                                                                                        /**
                                                                                                                                         * 配置哪些请求不拦截
                                                                                                                                         * 排除swagger相关请求
                                                                                                                                         *
                                                                                                                                         * @param web
                                                                                                                                         * @throws Exception
                                                                                                                                         */
                                                                                                                                        @Override
                                                                                                                                        public void configure(WebSecurity web) throws Exception {
                                                                                                                                            web.ignoring().antMatchers("/favicon.ico", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html");
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                    

                                                                                                                                    测试

                                                                                                                                    说明:

                                                                                                                                    1、我们是前后端分离项目,使用jwt生成token ,即用户状态保存在客户端中,前后端交互通过api接口 无session生成,所以我们不需要配置formLogin,session禁用

                                                                                                                                    2、在浏览器访问:http://localhost:8800/admin/system/sysRole/getAll

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第73张

                                                                                                                                    9.3、用户权限控制

                                                                                                                                    流程分析

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第74张

                                                                                                                                    修改代码

                                                                                                                                    修改UserDetailsServiceImpl中的loadUserByUsername

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第75张

                                                                                                                                            // 根据 user_id 查询用户操作权限数据
                                                                                                                                            List userPermsList = sysMenuService.findUserPermsByUserId(sysUser.getId());
                                                                                                                                            // 创建list集合,封装最终权限数据
                                                                                                                                            List authList =  new ArrayList<>();
                                                                                                                                            // 遍历 authList
                                                                                                                                            for (String perms : userPermsList) {
                                                                                                                                                authList.add(new SimpleGrantedAuthority(perms.trim()));
                                                                                                                                            }
                                                                                                                                            return new CustomUser(sysUser, authList);
                                                                                                                                    
                                                                                                                                    spring-security模块配置redis

                                                                                                                                    添加依赖

                                                                                                                                            
                                                                                                                                                org.springframework.boot
                                                                                                                                                spring-boot-starter-data-redis
                                                                                                                                            
                                                                                                                                    
                                                                                                                                    修改TokenLoginFilter

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第76张

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第77张

                                                                                                                                    修改TokenAuthenticationFilter

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第78张

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第79张

                                                                                                                                    修改WebSecurityConfig类

                                                                                                                                    配置类添加注解:

                                                                                                                                    开启基于方法的安全认证机制,也就是说在web层的controller启用注解机制的安全确认

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第80张

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第81张

                                                                                                                                    service-oa模块添加redis配置

                                                                                                                                    application-dev.yml配文件

                                                                                                                                    spring:
                                                                                                                                      redis:
                                                                                                                                        host: localhost
                                                                                                                                        port: 6379
                                                                                                                                        database: 0
                                                                                                                                        timeout: 1800000
                                                                                                                                        password:
                                                                                                                                        jedis:
                                                                                                                                          pool:
                                                                                                                                            max-active: 20 #最大连接数
                                                                                                                                            max-wait: -1    #最大阻塞等待时间(负数表示没限制)
                                                                                                                                            max-idle: 5    #最大空闲
                                                                                                                                            min-idle: 0     #最小空闲
                                                                                                                                    
                                                                                                                                    控制controller层接口权限

                                                                                                                                    Spring Security默认是禁用注解的,要想开启注解,需要在继承WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解,来判断用户对某个控制层的方法是否具有访问权限

                                                                                                                                        @PreAuthorize("hasAuthority('bnt.sysRole.list')")
                                                                                                                                    

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第82张

                                                                                                                                        @PreAuthorize("hasAuthority('bnt.sysRole.add')")
                                                                                                                                    

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第83张

                                                                                                                                        @PreAuthorize("hasAuthority('bnt.sysRole.list')")
                                                                                                                                    

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第84张

                                                                                                                                        @PreAuthorize("hasAuthority('bnt.sysRole.update')")
                                                                                                                                    

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第85张

                                                                                                                                        @PreAuthorize("hasAuthority('bnt.sysRole.remove')")
                                                                                                                                    

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第86张

                                                                                                                                    异常处理

                                                                                                                                    在service-util模块引入依赖

                                                                                                                                            
                                                                                                                                                org.springframework.boot
                                                                                                                                                spring-boot-starter-security
                                                                                                                                                provided
                                                                                                                                            
                                                                                                                                    

                                                                                                                                    AccessDeniedException需要引入依赖,Spring Security对应的异常

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第87张

                                                                                                                                        /**
                                                                                                                                         * spring security异常
                                                                                                                                         * @param e
                                                                                                                                         * @return
                                                                                                                                         */
                                                                                                                                        @ExceptionHandler(AccessDeniedException.class)
                                                                                                                                        @ResponseBody
                                                                                                                                        public Result error(AccessDeniedException e) throws AccessDeniedException {
                                                                                                                                            return Result.build(null, ResultCodeEnum.PERMISSION);
                                                                                                                                        }
                                                                                                                                    

                                                                                                                                    测试

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第88张

                                                                                                                                    10、Activiti

                                                                                                                                    10.1、Activiti流程操作

                                                                                                                                    配置Activiti

                                                                                                                                    引入Activiti依赖

                                                                                                                                    在service-oa中

                                                                                                                                    
                                                                                                                                    
                                                                                                                                        org.activiti
                                                                                                                                        activiti-spring-boot-starter
                                                                                                                                        7.1.0.M6
                                                                                                                                        
                                                                                                                                            
                                                                                                                                                mybatis
                                                                                                                                                org.mybatis
                                                                                                                                            
                                                                                                                                        
                                                                                                                                    
                                                                                                                                    
                                                                                                                                    添加配置

                                                                                                                                    在application-dev.yml中添加如下配置

                                                                                                                                    spring:    
                                                                                                                                    	activiti:
                                                                                                                                          #    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)
                                                                                                                                          #    true:表不存在,自动创建(开发使用)
                                                                                                                                          #    create_drop: 启动时创建,关闭时删除表(测试使用)
                                                                                                                                          #    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)
                                                                                                                                          database-schema-update: true
                                                                                                                                          #监测历史表是否存在,activities7默认不开启历史表
                                                                                                                                          db-history-used: true
                                                                                                                                          #none:不保存任何历史数据,流程中这是最高效的
                                                                                                                                          #activity:只保存流程实例和流程行为
                                                                                                                                          #audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值
                                                                                                                                          #full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数
                                                                                                                                          history-level: full
                                                                                                                                          #校验流程文件,默认校验resources下的process 文件夹的流程文件
                                                                                                                                          check-process-definitions: true
                                                                                                                                    
                                                                                                                                    重启项目

                                                                                                                                    会自己创建数据表

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第89张

                                                                                                                                    使用activiti插件

                                                                                                                                    下载activiti-explorer

                                                                                                                                    官网下载:https://www.activiti.org/get-started

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第90张

                                                                                                                                    解压部署

                                                                                                                                    把解压出来的activiti-explorer.war放在Tomcat的webapps下

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第91张

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第92张

                                                                                                                                    启动Tomcat服务器

                                                                                                                                    访问activiti-explorer

                                                                                                                                    http://localhost:8080/activiti-explorer

                                                                                                                                    默认登录账号: kermit kermit

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第93张

                                                                                                                                    10.2、流程控制

                                                                                                                                    绘制流程

                                                                                                                                    请假流程审批绘制

                                                                                                                                    新建

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第94张

                                                                                                                                    绘制

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第95张

                                                                                                                                    导出

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第96张

                                                                                                                                    下载文件

                                                                                                                                    qingjia.bpmn20.xml

                                                                                                                                    
                                                                                                                                    
                                                                                                                                      
                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                      
                                                                                                                                      
                                                                                                                                        
                                                                                                                                          
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                            
                                                                                                                                          
                                                                                                                                          
                                                                                                                                            
                                                                                                                                            
                                                                                                                                          
                                                                                                                                        
                                                                                                                                      
                                                                                                                                    
                                                                                                                                    

                                                                                                                                    下载流程定义图片

                                                                                                                                    单击右键上图图片,图片另存为:qingjia.png

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第97张

                                                                                                                                    将资源文件放入项目

                                                                                                                                    在service-oa模块resources下新建process资源文件夹

                                                                                                                                    将qingjia.bpmn20.xml与qingjia.png放入process目录

                                                                                                                                    部署流程

                                                                                                                                    package com.jerry.auth.activiti;
                                                                                                                                    import org.activiti.engine.RepositoryService;
                                                                                                                                    import org.activiti.engine.repository.Deployment;
                                                                                                                                    import org.junit.jupiter.api.Test;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                                    /**
                                                                                                                                     * ClassName: ProcessTest 
                                                                                                                                    * Package: com.jerry.activiti
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-05 10:51 * @Version: 1.0 */ @SpringBootTest public class ProcessTest { @Autowired private RepositoryService repositoryService; // 单个文件的部署 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment() .addClasspathResource("process/qingjia.bpmn20.xml") .addClasspathResource("process/qingjia.png") .name("请假申请流程") .deploy(); System.out.println("deploy.getId() = " + deploy.getId()); System.out.println("deploy.getName() = " + deploy.getName()); } }

                                                                                                                                    云上办公系统项目,在这里插入图片描述,第98张

                                                                                                                                    流程实例

                                                                                                                                    package com.jerry.auth.activiti;
                                                                                                                                    import org.activiti.engine.HistoryService;
                                                                                                                                    import org.activiti.engine.RepositoryService;
                                                                                                                                    import org.activiti.engine.RuntimeService;
                                                                                                                                    import org.activiti.engine.TaskService;
                                                                                                                                    import org.activiti.engine.history.HistoricTaskInstance;
                                                                                                                                    import org.activiti.engine.repository.Deployment;
                                                                                                                                    import org.activiti.engine.repository.ProcessDefinition;
                                                                                                                                    import org.activiti.engine.runtime.ProcessInstance;
                                                                                                                                    import org.activiti.engine.task.Task;
                                                                                                                                    import org.junit.jupiter.api.Test;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                                    import java.util.List;
                                                                                                                                    /**
                                                                                                                                     * ClassName: ProcessTest 
                                                                                                                                    * Package: com.jerry.activiti
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-05 10:51 * @Version: 1.0 */ @SpringBootTest public class ProcessTest1 { @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; // 单个流程实例挂起 @Test public void SingleSuspendProcessInstance() { String processInstanceId = "71f6803b-bb19-11ed-a845-005056c00001"; ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); //获取到当前流程定义是否为暂停状态 suspended方法为true代表为暂停 false就是运行的 boolean suspended = processInstance.isSuspended(); if (suspended) { runtimeService.activateProcessInstanceById(processInstanceId); System.out.println("流程实例:" + processInstanceId + "激活"); } else { runtimeService.suspendProcessInstanceById(processInstanceId); System.out.println("流程实例:" + processInstanceId + "挂起"); } } // 全部流程实例挂起 @Test public void suspendProcessInstance() { // 1、获取流程定义对象 ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult(); // 2、调用流程定义对象的方法判断当前状态:挂起 激活 boolean suspended = qingjia.isSuspended(); if (suspended) { // 暂定,那就可以激活 // 参数1:流程定义的id 参数2:是否激活 参数3:时间点 repositoryService.activateProcessDefinitionById(qingjia.getId(), true, null); System.out.println("流程定义:" + qingjia.getId() + "激活"); } else { repositoryService.suspendProcessDefinitionById(qingjia.getId(), true, null); System.out.println("流程定义:" + qingjia.getId() + "挂起"); } } /** * 启动流程实例,添加businessKey */ @Test public void startUpProcessAddBusinessKey(){ // 启动流程实例,指定业务标识businessKey,也就是请假申请单id ProcessInstance processInstance = runtimeService. startProcessInstanceByKey("qingjia","1001"); // 输出 System.out.println("业务id:"+processInstance.getBusinessKey()); //1001 System.out.println("processInstance.getId() = " + processInstance.getId()); // 71f6803b-bb19-11ed-a845-005056c00001 } /** * 查询流程定义 */ @Test public void findProcessDefinitionList(){ List definitionList = repositoryService.createProcessDefinitionQuery() .orderByProcessDefinitionVersion() .desc() .list(); //输出流程定义信息 for (ProcessDefinition processDefinition : definitionList) { System.out.println("流程定义 id="+processDefinition.getId()); System.out.println("流程定义 name="+processDefinition.getName()); System.out.println("流程定义 key="+processDefinition.getKey()); System.out.println("流程定义 Version="+processDefinition.getVersion()); System.out.println("流程部署ID ="+processDefinition.getDeploymentId()); } } /** * 删除流程定义 */ @Test public void deleteDeployment() { //部署id String deploymentId = "qingjia:1:c493c327-bb02-11ed-8360-005056c00001"; // //删除流程定义,如果该流程定义已有流程实例启动则删除时出错 // repositoryService.deleteDeployment(deploymentId); //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式 repositoryService.deleteDeployment(deploymentId, true); } // 查询已经处理的任务 @Test public void findCompleteTaskList(){ List list = historyService.createHistoricTaskInstanceQuery() .taskAssignee("zhangsan") .finished().list(); for (HistoricTaskInstance historicTaskInstance : list) { System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId()); System.out.println("任务id:" + historicTaskInstance.getId()); System.out.println("任务负责人:" + historicTaskInstance.getAssignee()); System.out.println("任务名称:" + historicTaskInstance.getName()); } } // 处理当前任务 @Test public void completeTask(){ // 查询负责人需要处理的任务,返回一条 Task task = taskService.createTaskQuery().taskAssignee("zhangsan").singleResult(); // 完成任务 taskService.complete(task.getId()); } // 查询个人的代办任务--zhangsan @Test public void findTaskList(){ String assign = "zhangsan"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); } } // 启动流程实例 @Test public void startProcess(){ ProcessInstance processInstance = runtimeService.startProcessInstanceById("qingjia"); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); System.out.println("processInstance.getId() = " + processInstance.getId()); System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId()); } // 单个文件的部署 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment() .addClasspathResource("process/qingjia.bpmn20.xml") .addClasspathResource("process/qingjia.png") .name("请假申请流程") .deploy(); System.out.println("deploy.getId() = " + deploy.getId()); System.out.println("deploy.getName() = " + deploy.getName()); } }

                                                                                                                                    任务分配

                                                                                                                                    package com.jerry.auth.activiti;
                                                                                                                                    import org.activiti.engine.HistoryService;
                                                                                                                                    import org.activiti.engine.RepositoryService;
                                                                                                                                    import org.activiti.engine.RuntimeService;
                                                                                                                                    import org.activiti.engine.TaskService;
                                                                                                                                    import org.activiti.engine.repository.Deployment;
                                                                                                                                    import org.activiti.engine.runtime.ProcessInstance;
                                                                                                                                    import org.activiti.engine.task.Task;
                                                                                                                                    import org.junit.jupiter.api.Test;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                                    import java.util.HashMap;
                                                                                                                                    import java.util.List;
                                                                                                                                    import java.util.Map;
                                                                                                                                    /**
                                                                                                                                     * ClassName: ProcessTest2 
                                                                                                                                    * Package: com.jerry.auth.activiti
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-05 14:05 * @Version: 1.0 */ @SpringBootTest public class ProcessTest2 { @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; /// // 监听器分配任务 // 部署流程定义 @Test public void deployProcess02() { Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban02.bpmn20.xml").name("加班申请流程02").deploy(); System.out.println("deploy.getId() = " + deploy.getId()); // ed080f00-bb41-11ed-a6f2-005056c00001 System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程02 } @Test public void startProcessInstance02(){ ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban02"); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban02:1:ed150752-bb41-11ed-a6f2-005056c00001 System.out.println("processInstance.getId() = " + processInstance.getId()); // 06eca124-bb42-11ed-9bbc-005056c00001 } // 查询个人的代办任务--Tim @Test public void findTaskList02(){ String assign = "Tim"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); // 06eca124-bb42-11ed-9bbc-005056c00001 System.out.println("任务id:" + task.getId()); // 06f071b8-bb42-11ed-9bbc-005056c00001 System.out.println("任务负责人:" + task.getAssignee()); // Tim System.out.println("任务名称:" + task.getName()); // 经理审批 } } /// // uel-method // 部署流程定义 @Test public void deployProcess01() { Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban01.bpmn20.xml").name("加班申请流程01").deploy(); System.out.println("deploy.getId() = " + deploy.getId()); // 8c4ac05e-bb20-11ed-8d65-005056c00001 System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程01 } @Test public void startProcessInstance01(){ ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban01"); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban01:1:8c56a740-bb20-11ed-8d65-005056c00001 System.out.println("processInstance.getId() = " + processInstance.getId()); // abb9c7c4-bb20-11ed-b608-005056c00001 } // 查询个人的代办任务--LiLei @Test public void findTaskList01(){ String assign = "LiLei"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); // abb9c7c4-bb20-11ed-b608-005056c00001 System.out.println("任务id:" + task.getId()); // abbd4a38-bb20-11ed-b608-005056c00001 System.out.println("任务负责人:" + task.getAssignee()); // LiLei System.out.println("任务名称:" + task.getName()); // 经理审批 } } /// // uel-value // 部署流程定义 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban.bpmn20.xml").name("加班申请流程").deploy(); System.out.println("deploy.getId() = " + deploy.getId()); // 5c5519ad-bb1d-11ed-b5c8-005056c00001 System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程 } // 启动流程实例 @Test public void startProcessInstance() { Map map = new HashMap<>(); // 设置任务人 map.put("assignee1","tom"); map.put("assignee2","jerry"); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban", map); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban:1:5c60d97f-bb1d-11ed-b5c8-005056c00001 System.out.println("processInstance.getId() = " + processInstance.getId()); // 7f720dd9-bb1d-11ed-b6e9-005056c00001 } // 查询个人的代办任务--tom @Test public void findTaskList(){ String assign = "tom"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); //7f720dd9-bb1d-11ed-b6e9-005056c00001 System.out.println("任务id:" + task.getId()); // 7f759051-bb1d-11ed-b6e9-005056c00001 System.out.println("任务负责人:" + task.getAssignee()); // tom System.out.println("任务名称:" + task.getName()); // 经理审批 } } }

                                                                                                                                    配置监听器

                                                                                                                                    package com.jerry.auth.activiti;
                                                                                                                                    import org.springframework.stereotype.Component;
                                                                                                                                    /**
                                                                                                                                     * ClassName: UserBean 
                                                                                                                                    * Package: com.jerry.auth.activiti
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-05 14:25 * @Version: 1.0 */ @Component public class UserBean { public String getUsername(int id) { if (id == 1) { return "LiLei"; } if (id == 2) { return "HanMeiMei"; } return "admin"; } }

                                                                                                                                    任务组

                                                                                                                                    package com.jerry.auth.activiti;
                                                                                                                                    import org.activiti.engine.RepositoryService;
                                                                                                                                    import org.activiti.engine.RuntimeService;
                                                                                                                                    import org.activiti.engine.TaskService;
                                                                                                                                    import org.activiti.engine.repository.Deployment;
                                                                                                                                    import org.activiti.engine.runtime.ProcessInstance;
                                                                                                                                    import org.activiti.engine.task.Task;
                                                                                                                                    import org.junit.jupiter.api.Test;
                                                                                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                    import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                                    import java.util.HashMap;
                                                                                                                                    import java.util.List;
                                                                                                                                    import java.util.Map;
                                                                                                                                    /**
                                                                                                                                     * ClassName: ProcessTest3 
                                                                                                                                    * Package: com.jerry.auth.activiti
                                                                                                                                    * Description: * * @Author: jerry_jy * @Create: 2023-03-05 19:18 * @Version: 1.0 */ @SpringBootTest public class ProcessTest3 { @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; // 1、部署流程定义 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban04.bpmn20.xml").name("加班申请流程04").deploy(); System.out.println("deploy.getId() = " + deploy.getId()); // f204be8a-bb48-11ed-950e-005056c00001 System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程04 } // 1.5、启动流程实例 @Test public void startProcessInstance() { // Map map = new HashMap<>(); // 设置任务人 // map.put("assignee1","tom"); // map.put("assignee2","jerry"); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban04"); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban04:1:f210f38c-bb48-11ed-950e-005056c00001 System.out.println("processInstance.getId() = " + processInstance.getId()); // 428d0c0f-bb49-11ed-83a5-005056c00001 } // 2、查询组任务 @Test public void findGroupTaskList(){ List list = taskService.createTaskQuery() .taskCandidateUser("tom") .list(); for (Task task : list) { System.out.println("----------------------------"); System.out.println("流程实例id:" + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); } } // 3、分配组任务 @Test public void claimTask(){ Task task = taskService.createTaskQuery() .taskCandidateUser("tom") .singleResult(); if (task!=null){ taskService.claim(task.getId(),"tom"); System.out.println("分配任务完成"); } } // 4、查询个人的代办任务--tom @Test public void findTaskList(){ String assign = "tom"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); //7f720dd9-bb1d-11ed-b6e9-005056c00001 System.out.println("任务id:" + task.getId()); // 7f759051-bb1d-11ed-b6e9-005056c00001 System.out.println("任务负责人:" + task.getAssignee()); // tom System.out.println("任务名称:" + task.getName()); // 经理审批 } } // 5、办理个人任务 @Test public void completeGroupTask() { Task task = taskService.createTaskQuery() .taskAssignee("tom") //要查询的负责人 .singleResult();//返回一条 taskService.complete(task.getId()); } }

                                                                                                                                    10.3、网关

                                                                                                                                    网关用来控制流程的流向,通常会和流程变量一起使用。

                                                                                                                                    排他网关
                                                                                                                                    • 排他网关:只有一条路径会被选择

                                                                                                                                      当你的流程出现这样的场景:请假申请,两天以内,部门经理审批流程就结束了,两天以上需要总经理直接审批,这个时候就需要排他网关

                                                                                                                                      云上办公系统项目,在这里插入图片描述,第99张

                                                                                                                                      并行网关
                                                                                                                                      • 并(平)行网关:所有路径会被同时选择

                                                                                                                                        当出现这样的场景:请假申请开始,需要部门经理和总经理都审批,两者没有前后需要两个人全部审批才能进入下个节点人事审批。这个时候就需要并行网关

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第100张

                                                                                                                                        与排他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

                                                                                                                                        包含网关

                                                                                                                                        包容网关:可以同时执行多条线路,也可以在网关上设置条件,可以看做是排他网关和并行网关的结合体。

                                                                                                                                        当出现这样的场景:请假申请大于等于2天需要由部门总经理审批,小于2天由部门经理审批,请假申请必须经过人事经理审批。这个时候就需要包含网关

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第101张

                                                                                                                                        package com.jerry.auth.activiti;
                                                                                                                                        import org.activiti.engine.HistoryService;
                                                                                                                                        import org.activiti.engine.RepositoryService;
                                                                                                                                        import org.activiti.engine.RuntimeService;
                                                                                                                                        import org.activiti.engine.TaskService;
                                                                                                                                        import org.activiti.engine.repository.Deployment;
                                                                                                                                        import org.activiti.engine.runtime.ProcessInstance;
                                                                                                                                        import org.activiti.engine.task.Task;
                                                                                                                                        import org.junit.jupiter.api.Test;
                                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                        import org.springframework.boot.test.context.SpringBootTest;
                                                                                                                                        import java.util.HashMap;
                                                                                                                                        import java.util.List;
                                                                                                                                        import java.util.Map;
                                                                                                                                        /**
                                                                                                                                         * ClassName: ProcessTestGateway 
                                                                                                                                        * Package: com.jerry.auth.activiti
                                                                                                                                        * Description: * * @Author: jerry_jy * @Create: 2023-03-05 19:52 * @Version: 1.0 */ @SpringBootTest public class ProcessTestGateway { @Autowired private RepositoryService repositoryService; //注入RuntimeService @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; //1 部署流程定义 @Test public void deployProcess() { Deployment deployment = repositoryService.createDeployment() .addClasspathResource("process/qingjia003.bpmn20.xml") .name("请假申请流程003") .deploy(); System.out.println(deployment.getId()); // af9242f0-bb4c-11ed-85bf-005056c00001 System.out.println(deployment.getName()); // 请假申请流程002 } //2 启动流程实例 @Test public void startProcessInstance() { Map map = new HashMap<>(); //设置请假天数 map.put("day", "3"); ProcessInstance processInstance = // runtimeService.startProcessInstanceByKey("qingjia002", map); runtimeService.startProcessInstanceByKey("qingjia003"); System.out.println(processInstance.getProcessDefinitionId()); // qingjia002:1:afac0c82-bb4c-11ed-85bf-005056c00001 System.out.println(processInstance.getId()); // 90d46e2c-bb4d-11ed-9b92-005056c00001 } //3 查询个人的代办任务--zhao6 @Test public void findTaskList() { // String assign = "zhao6"; // String assign = "gousheng"; // String assign = "xiaocui"; // String assign = "wang5"; // String assign = "gouwa"; String assign = "xiaoli"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("流程实例id:" + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); } } //完成任务 @Test public void completeTask() { Task task = taskService.createTaskQuery() // .taskAssignee("zhao6") //要查询的负责人 // .taskAssignee("xiaocui") //要查询的负责人 // .taskAssignee("gousheng") // .taskAssignee("wang5") .taskAssignee("gouwa") .singleResult();//返回一条 //完成任务,参数:任务id taskService.complete(task.getId()); } }

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第102张

                                                                                                                                        11、审批管理

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第103张

                                                                                                                                        11.1、审批设置–CRUD

                                                                                                                                        package com.jerry.process.controller;
                                                                                                                                        import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
                                                                                                                                        import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                                                                                        import com.jerry.common.result.Result;
                                                                                                                                        import com.jerry.model.process.ProcessType;
                                                                                                                                        import com.jerry.process.service.OaProcessTypeService;
                                                                                                                                        import io.swagger.annotations.Api;
                                                                                                                                        import io.swagger.annotations.ApiOperation;
                                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                        import org.springframework.security.access.prepost.PreAuthorize;
                                                                                                                                        import org.springframework.web.bind.annotation.*;
                                                                                                                                        /**
                                                                                                                                         * 

                                                                                                                                        * 审批类型 前端控制器 *

                                                                                                                                        * * @author jerry * @since 2023-03-05 */ @Api(value = "审批类型", tags = "审批类型") @RestController @RequestMapping(value = "/admin/process/processType") public class OaProcessTypeController { @Autowired private OaProcessTypeService processTypeService; @ApiOperation(value = "获取分页列表") @GetMapping("{page}/{pageSize}") public Result index(@PathVariable Long page, @PathVariable Long pageSize) { Page pageInfo = new Page<>(page, pageSize); Page pageModel = processTypeService.page(pageInfo); return Result.ok(pageModel); } @PreAuthorize("hasAuthority('bnt.processType.list')") @ApiOperation(value = "获取") @GetMapping("get/{id}") public Result get(@PathVariable Long id) { ProcessType processType = processTypeService.getById(id); return Result.ok(processType); } @PreAuthorize("hasAuthority('bnt.processType.add')") @ApiOperation(value = "新增") @PostMapping("save") public Result save(@RequestBody ProcessType processType) { processTypeService.save(processType); return Result.ok(); } @PreAuthorize("hasAuthority('bnt.processType.update')") @ApiOperation(value = "修改") @PutMapping("update") public Result updateById(@RequestBody ProcessType processType) { processTypeService.updateById(processType); return Result.ok(); } @ApiOperation(value = "删除") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { processTypeService.removeById(id); return Result.ok(); } }

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第104张

                                                                                                                                        11.2、模板审批–CRUD

                                                                                                                                        package com.jerry.process.controller;
                                                                                                                                        import com.baomidou.mybatisplus.core.metadata.IPage;
                                                                                                                                        import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                                                                                        import com.jerry.common.result.Result;
                                                                                                                                        import com.jerry.model.process.ProcessTemplate;
                                                                                                                                        import com.jerry.process.service.OaProcessTemplateService;
                                                                                                                                        import io.swagger.annotations.Api;
                                                                                                                                        import io.swagger.annotations.ApiOperation;
                                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                        import org.springframework.web.bind.annotation.*;
                                                                                                                                        /**
                                                                                                                                         * 

                                                                                                                                        * 审批模板 前端控制器 *

                                                                                                                                        * * @author jerry * @since 2023-03-05 */ @Api(value = "审批模板管理", tags = "审批模板管理") @RestController @RequestMapping(value = "/admin/process/processTemplate") public class OaProcessTemplateController { @Autowired private OaProcessTemplateService processTemplateService; // 分页查询审批模板 @ApiOperation("获取分页查询审批模板数据") @GetMapping("{page}/{pageSize}") public Result index(@PathVariable Long page, @PathVariable Long pageSize){ Page pageInfo = new Page<>(page, pageSize); //分页查询审批模板,把审批类型对应名称查询 IPage pageModel = processTemplateService.selectPageProcessTemplate(pageInfo); return Result.ok(pageModel); } //@PreAuthorize("hasAuthority('bnt.processTemplate.list')") @ApiOperation(value = "获取") @GetMapping("get/{id}") public Result get(@PathVariable Long id) { ProcessTemplate processTemplate = processTemplateService.getById(id); return Result.ok(processTemplate); } //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')") @ApiOperation(value = "新增") @PostMapping("save") public Result save(@RequestBody ProcessTemplate processTemplate) { processTemplateService.save(processTemplate); return Result.ok(); } //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')") @ApiOperation(value = "修改") @PutMapping("update") public Result updateById(@RequestBody ProcessTemplate processTemplate) { processTemplateService.updateById(processTemplate); return Result.ok(); } //@PreAuthorize("hasAuthority('bnt.processTemplate.remove')") @ApiOperation(value = "删除") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { processTemplateService.removeById(id); return Result.ok(); } }

                                                                                                                                        11.3、添加审批模板

                                                                                                                                        OaProcessTypeController

                                                                                                                                            @ApiOperation(value = "获取全部审批分类")
                                                                                                                                            @GetMapping("findAll")
                                                                                                                                            public Result findAll() {
                                                                                                                                                return Result.ok(processTypeService.list());
                                                                                                                                            }
                                                                                                                                        

                                                                                                                                        OaProcessTemplateController

                                                                                                                                            @ApiOperation(value = "上传流程定义")
                                                                                                                                            @PostMapping("/uploadProcessDefinition")
                                                                                                                                            public Result uploadProcessDefinition(MultipartFile file) throws FileNotFoundException {
                                                                                                                                                // 获取classes目录位置
                                                                                                                                                String path = new File(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
                                                                                                                                                // 设置上传文件夹
                                                                                                                                                File tempFile = new File(path + "/processes/");
                                                                                                                                                if (!tempFile.exists()) {
                                                                                                                                                    tempFile.mkdirs();
                                                                                                                                                }
                                                                                                                                                // 创建空文件,实现文件写入
                                                                                                                                                String filename = file.getOriginalFilename();
                                                                                                                                                File zipFile = new File(path + "/processes/" + filename);
                                                                                                                                                // 保存文件
                                                                                                                                                try {
                                                                                                                                                    file.transferTo(zipFile);
                                                                                                                                                } catch (IOException e) {
                                                                                                                                                   return Result.fail();
                                                                                                                                                }
                                                                                                                                                Map map = new HashMap<>();
                                                                                                                                                //根据上传地址后续部署流程定义,文件名称为流程定义的默认key
                                                                                                                                                map.put("processDefinitionPath", "processes/" + filename);
                                                                                                                                                map.put("processDefinitionKey", filename.substring(0, filename.lastIndexOf(".")));
                                                                                                                                                return Result.ok(map);
                                                                                                                                            }
                                                                                                                                            public static void main(String[] args) {
                                                                                                                                                try {
                                                                                                                                                    String path = new File(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
                                                                                                                                                    System.out.println("path = " + path); //E:\CodeLife\IdeaProject\guigu-oa\guigu-oa-parent\service-oa\target\classes
                                                                                                                                                } catch (FileNotFoundException e) {
                                                                                                                                                    throw new RuntimeException(e);
                                                                                                                                                }
                                                                                                                                            }
                                                                                                                                        

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第105张

                                                                                                                                        11.4、查看审批模板

                                                                                                                                        整合前端,无后台接口

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第106张

                                                                                                                                        11.5、审批列表

                                                                                                                                        分页查询

                                                                                                                                        OaProcessController

                                                                                                                                        package com.jerry.process.controller;
                                                                                                                                        import com.baomidou.mybatisplus.core.mapper.BaseMapper;
                                                                                                                                        import com.baomidou.mybatisplus.core.metadata.IPage;
                                                                                                                                        import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                                                                                        import com.jerry.common.result.Result;
                                                                                                                                        import com.jerry.model.process.Process;
                                                                                                                                        import com.jerry.process.service.OaProcessService;
                                                                                                                                        import com.jerry.vo.process.ProcessQueryVo;
                                                                                                                                        import com.jerry.vo.process.ProcessVo;
                                                                                                                                        import io.swagger.annotations.ApiOperation;
                                                                                                                                        import org.springframework.beans.factory.annotation.Autowired;
                                                                                                                                        import org.springframework.web.bind.annotation.GetMapping;
                                                                                                                                        import org.springframework.web.bind.annotation.PathVariable;
                                                                                                                                        import org.springframework.web.bind.annotation.RequestMapping;
                                                                                                                                        import org.springframework.web.bind.annotation.RestController;
                                                                                                                                        /**
                                                                                                                                         * 

                                                                                                                                        * 审批类型 前端控制器 *

                                                                                                                                        * * @author jerry * @since 2023-03-06 */ @RestController @RequestMapping(value = "/admin/process") public class OaProcessController { @Autowired private OaProcessService processService; //审批管理列表 @ApiOperation(value = "获取分页列表") @GetMapping("{page}/{limit}") public Result index(@PathVariable Long page, @PathVariable Long limit, ProcessQueryVo processQueryVo) { Page pageInfo = new Page<>(page, limit); IPage pageModel = processService.selectPage(pageInfo,processQueryVo); return Result.ok(); } }

                                                                                                                                        OaProcessService

                                                                                                                                        public interface OaProcessService extends IService {
                                                                                                                                            //审批管理列表
                                                                                                                                            IPage selectPage(Page pageInfo, ProcessQueryVo processQueryVo);
                                                                                                                                        }
                                                                                                                                        

                                                                                                                                        OaProcessServiceImpl

                                                                                                                                            //审批管理列表
                                                                                                                                            @Override
                                                                                                                                            public IPage selectPage(Page pageInfo, ProcessQueryVo processQueryVo) {
                                                                                                                                                IPage pageModel =  baseMapper.selectPage(pageInfo,processQueryVo);
                                                                                                                                                return pageModel;
                                                                                                                                            }
                                                                                                                                        

                                                                                                                                        OaProcessMapper

                                                                                                                                            //审批管理列表
                                                                                                                                            IPage selectPage(Page pageInfo, @Param("vo") ProcessQueryVo processQueryVo);
                                                                                                                                        

                                                                                                                                        涉及到4张表的多表查询,自己编写SQL语句

                                                                                                                                        OaProcessMapper.xml

                                                                                                                                        
                                                                                                                                        
                                                                                                                                        
                                                                                                                                            
                                                                                                                                        
                                                                                                                                        

                                                                                                                                        修改mapper的映射路径

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第107张

                                                                                                                                        页面展示

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第108张

                                                                                                                                        部署流程定义

                                                                                                                                        OaProcessTemplateServiceImpl

                                                                                                                                            // 修改模板的发布状态 status==1 代表已发布
                                                                                                                                            // 流程定义部署
                                                                                                                                            @Override
                                                                                                                                            public void publish(Long id) {
                                                                                                                                                // 修改模板的发布状态 status==1 代表已发布
                                                                                                                                                ProcessTemplate processTemplate = baseMapper.selectById(id);
                                                                                                                                                processTemplate.setStatus(1);
                                                                                                                                                baseMapper.updateById(processTemplate);
                                                                                                                                                // 流程定义部署
                                                                                                                                                if (StringUtils.isEmpty(processTemplate.getProcessDefinitionPath())){
                                                                                                                                                    processService.deployByZip(processTemplate.getProcessDefinitionPath());
                                                                                                                                                }
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                        

                                                                                                                                        OaProcessService

                                                                                                                                            // 流程定义部署
                                                                                                                                            void deployByZip(String deployPath);
                                                                                                                                        

                                                                                                                                        OaProcessServiceImpl

                                                                                                                                            // 流程定义部署
                                                                                                                                            @Override
                                                                                                                                            public void deployByZip(String deployPath) {
                                                                                                                                                InputStream inputStream= this.getClass().getClassLoader().getResourceAsStream(deployPath);
                                                                                                                                                ZipInputStream zipInputStream = new ZipInputStream(inputStream);
                                                                                                                                                // 部署
                                                                                                                                                Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();
                                                                                                                                                System.out.println("deployment.getId() = " + deployment.getId());
                                                                                                                                                System.out.println("deployment.getName() = " + deployment.getName());
                                                                                                                                            }
                                                                                                                                        

                                                                                                                                        12、前端审批

                                                                                                                                        12.1、OA审批

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第109张

                                                                                                                                        node -v
                                                                                                                                        v 16.16.0
                                                                                                                                        

                                                                                                                                        报错

                                                                                                                                        npm ERR! path F:\guigu-oa\guigu-oa-web\node_modules\node-sass
                                                                                                                                        npm ERR! command failed
                                                                                                                                        npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node scripts/build.js
                                                                                                                                        npm ERR! Building: E:\nodejs\node.exe F:\guigu-oa\guigu-oa-web\node_modules\node-gyp\bin\node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
                                                                                                                                        npm ERR! gyp info it worked if it ends with ok
                                                                                                                                        npm ERR! gyp verb cli [
                                                                                                                                        npm ERR! gyp verb cli   'E:\nodejs\node.exe',
                                                                                                                                        npm ERR! gyp verb cli   'F:\guigu-oa\guigu-oa-web\node_modules\node-gyp\bin\node-gyp.js',
                                                                                                                                        npm ERR! gyp verb cli   'rebuild',
                                                                                                                                        npm ERR! gyp verb cli   '--verbose',
                                                                                                                                        npm ERR! gyp verb cli   '--libsass_ext=',
                                                                                                                                        npm ERR! gyp verb cli   '--libsass_cflags=',
                                                                                                                                        npm ERR! gyp verb cli   '--libsass_ldflags=',
                                                                                                                                        npm ERR! gyp verb cli   '--libsass_library='
                                                                                                                                        npm ERR! gyp verb cli ]
                                                                                                                                        npm ERR! gyp info using node-gyp@3.8.0
                                                                                                                                        npm ERR! gyp info using node@16.16.0 | win32 | x64
                                                                                                                                        npm ERR! gyp verb command rebuild []
                                                                                                                                        npm ERR! gyp verb command clean []
                                                                                                                                        npm ERR! gyp verb clean removing "build" directory
                                                                                                                                        

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第110张

                                                                                                                                        nodejs版本过高,与node-sass不兼容,降级版本

                                                                                                                                        v14.15.0
                                                                                                                                        

                                                                                                                                        npm install没问题

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第111张

                                                                                                                                        13、代码托管

                                                                                                                                        Git

                                                                                                                                        云上办公系统项目,在这里插入图片描述,第112张

                                                                                                                                        Gitee

                                                                                                                                        https://gitee.com/jinyang-jy/OnlineOfficeSystem.git

                                                                                                                                        GitHub

                                                                                                                                        网盘资料

                                                                                                                                        链接:https://pan.baidu.com/s/1ZVNqzPlcfMH89NgUYNYZtQ?pwd=2022

                                                                                                                                        提取码:2022