# CloudOffice **Repository Path**: hmfdev/CloudOffice ## Basic Information - **Project Name**: CloudOffice - **Description**: 中小型企业在线办公系统-云E办(后端) - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 34 - **Forks**: 23 - **Created**: 2021-07-22 - **Last Updated**: 2025-06-18 ## Categories & Tags **Categories**: erp **Tags**: SpringBoot ## README # CloudOffice #### 介绍   本项目目的是实现中小型企业的在线办公系统,云E办在线办公系统是一个用来管理日常的办公事务的一个系统,他能够管的内容有:日常的各种流程审批,新闻,通知,公告,文件信息,财务,人事,费用,资产,行政,项目,移动办公等等。   它的作用就是通过软件的方式,方便管理,更加简单,更加扁平,更加高效,更加规范,能够提高整体的管理运营水平。 #### 软件架构 软件架构说明 #### 展示后台接口图片 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0817/071452_f787f0aa_5474516.png "云E办后端接口展示图片.png") #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 1. 获取菜单时使用了缓存技术,所以这里需要配置redis,然后开启redis 2. 添加员工时,使用了 rabbitmq 做员工添加完成后邮件的发送,需要配置服务的ip地址,还需要在配置文件中写你的发送邮件授权码,然后开启 rabbitmq 3. 更新头像时使用了fastdfs轻量级的分布式文件系统上传图片,需要配置服务的ip地址,还需要开启fastdfs的 tracker(跟踪器)、storage(存储节点) 服务 和 nginx 服务器 4. 访问 http://localhost:8081/doc.html 打开后台接口API #### 提交日志细节记录 1. 【1.本地初始化】 1)IDEA中使用 Spring Initializr 创建一个SpringBoot项目 2)使用git clone gitee版本库中新建的repository项目到本地,加入clone下来的内容到新建的SpringBoot项目中,整合后,做本地初始化提交 3)我把IDEA生成的.gitignore和gitee中clone下来的.gitignore合并到一起了 2. 【2.项目准备】 1)数据库准备,新建yeb数据库,数据库字符集选utf8mb4,导入放在database文件夹下的yeb.sql数据库脚本 2)使用lombok,需要先在IDEA中安装lombok插件 3. 【3.项目搭建】 1)刚刚新建的SpringBoot项目,就作为我们的父工程,该父工程*只是用来做我们所有项目的pom依赖管理*,所以可以删掉大部分的文件及文件夹 2)修改pom.xml文件,删掉依赖dependencies标签和构建build标签及其内容,加入packaging标签里面写pom 3)创建一个Module项目,使用Maven创建一个quickstart的Module子项目 yeb-server 负责我们整个的业务逻辑 4)对新建的Module项目 yeb-server 进行修改,删掉生成的App类和AppTest类,然后添加一个server包名 5)在yeb-server子项目的pom.xml中引入父工程坐标,关联父工程(主工程) 6)删除构建bulid标签,删除依赖(因为我们直接copy需要的依赖进来) 7)把子项目工程的目录补充完整,如 resources、各层目录等,并添加application.yml配置文件,注意copy配置文件里的内容很容易出现问题 8)添加启动类 YebApplication,并添加mapper扫描注解 9)把配置文件application.yml放到config目录下 4. 【4.逆向工程(逆向工程生成所有数据库表前的备份提交)】 1)使用MyBatisPlus自带的逆向工程代码生成器AutoGenerator可以快速生成Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。 2)使用maven的quickstart新建逆向工程代码生成器子项目Module,专门用于各模块代码的生成 3)删除新建的yeb-generator子项目pom.xml中用不到的内容,指定父工程坐标,copy依赖过来,还有新建包名generator 4)该代码生成器子项目用不到测试,所以把生成的test文件夹删掉了 5. 【5.逆向工程(逆向工程生成所有数据库表对应的各模块类)】 1)在yeb-generator子项目中,生成好各模块的类后,copy到yeb-server子项目中 2)copy到yeb-server子项目中后,删除掉在yeb-generator子项目中生成好的各模块的类,因为它们会报红 3)添加所需的依赖,解决报红的问题,如添加swagger2的依赖 4)逆向工程文件CodeGenerator,你需要在这个文件里配置你要生成对应模块类的包,里面有具体的注释说明 6. 【6.Jwt Token工具类编写】 1)登录功能采用SpringSecurity+JWT令牌实现登录功能,引入对应的依赖 2)在application.yml中配置JWT,并新建config专门用来存放我们项目要使用到的一些配置 3)新建并编写JwtTokenUtil工具类 7. 【7.公共返回对象】 1)调用接口时返回的json数据对象封装到 RespBean 中 8. 【8.登录之后返回token】 1)登录使用Spring Security + JWT 2)前端传用户名和密码,判断如果正确就生成JWT令牌,并把token和请求头返回给前端 9. 【9.获取当前登录用户信息以及退出功能】 1)退出流程是前端请求接口,成功后,前端把请求头删掉就行了 10. 【10.配置Security登录授权过滤器】 11. 【11.Security自定义返回结果】 1)Spring Security配置基本完成 12. 【12.Swagger2配置】 1)还需要配置放行Swagger2的资源 2)修改了代码漏写的错误 13. 【13.Swagger2添加Authorize】 1)修复了一些代码错误内容 14. 【14.生成验证码】 1)使用谷歌的图形验证码,并给一个谷歌验证码的配置类CaptchaConfig,并加上@Configuration 2)然后写接口,CaptchaController 3)在SecurityConfig把图形验证码给放行,就是放行访问的地址 4)改造一下接口文档,让在接口文档中也能显示图形验证码,加上 @GetMapping(value = "/captcha", **produces = "image/jpeg"**) 5)如果token过期会提示:io.jsonwebtoken.ExpirdidExcetiom:JWT expired at 202-7-23723:18.2 Current time:2001-47-2412208.34, a difference of 82207652 milliseconds. Allowed clock skew:0 mill 15. 【15.校验验证码】 1)在AdminLoginParam类中添加验证码参数,相应层的方法也加上code参数 2)然后在AdminServiceImpl类的login()方法中,判断用户输入的code验证码是否和生成存在session中的一致 16. 【16.根据用户id查询菜单列表】 1)我们使用了SpringSecurity,登录之后设置了全局保存的用户对象,我们可以通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取 17. 【17.根据用户id查询菜单列表Sql语句编写】 1)这里的sql语句较多较长,而且还有点复杂 2)因为之前代码写在了错误的层上面,本来是要写在MenuController这一流程下的,所以在这里也修复了 18. 【18.Redis集成菜单功能】 1)加入Redis的依赖,然后在application.yml配置redis的连接等 2)再配置Redis的序列化,没有配置序列化,在redis会出现乱码,在这别忘了@Configuration注解,否则配置不成功 3)如果菜单有修改,那么就要清空redis,让他重新从数据库中获取,再存到redis中,这样才能保证数据是最新的 19. 【19.根据请求url判断角色】 1)根据角色获取菜单的列表,需要放到过滤器中 2)新建component包,改变一些.java文件的存放路径 20. 【20.判断用户角色】 1)动态权限等的配置,菜单和权限配置完成 21. 【21.职位管理功能实现-实现职位的增删改查】 1)url的前缀需要按照t_menu表系统管理的前缀去写,否则会出现没有权限的情况 2)通过在实体类中给属性加注解@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")来格式化时间,有两个参数格式化和时区 3)单表的增删改查,MyBatisPlus是非常快的,甚至可以使用MyBatisPlus定义好的方法查询数据 4)可以使用 LocalDateTime.now() 获取系统当前的时间 5)把数据转为List的方法:Arrays.asList(ids) 6)使用MyBatisPlus提供的增删改查方法,我们只需在controller层操作就行了,而无需在修改service层和mapper层 22. 【22.全局异常处理】 1)注解 @RestControllerAdvice // 表示控制器的增强类,符合我们的异常就会被拦截 23. 【23.职称管理功能实现】 1)对于时间,我们都需要在实体类相应的字段上加上注解@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")来格式化时间 2)通过Arrays.asList(ids),把数组转为集合List 3)t_joblevel表中的titleLevel字段是固定了值,这个需要注意一下 4)像上面数据库中已经固定了值,最好就使用枚举Enum类型 24. 【24.权限组角色功能实现】 1)修改了MenuController的RequestMapping为"system/config" 2)这里通过MyBatisPlus提供的list()方法,roleService.list()来获取表的所有数据 3)通过MyBatisPlus提供的save()方法,roleService.save()来添加数据 4)通过MyBatisPlus提供的removeById()方法,roleService.removeById()来通过Id删除一条数据 25. 【25.权限组菜单查询功能实现】 1)这里注意MenuMapper.xml里resultMap的写法 2)这里注意(根据角色id查询菜单id)方法中的内容,menuRoleService.list(new QueryWrapper().eq("rid", rid)).stream().map(MenuRole::getMid).collect(Collectors.toList()); 26. 【26.权限组菜单更新功能实现】 1)更新删除操作时,在Service层加个事务的注解 @Transactional 2)注意这里的dao层参数加了注解@Param,在org.apache.ibatis.annotations.Param;包下 27. 【27.存储过程介绍】 28. 【28.存储过程创建及调用】 29. 【29.项目存储过程讲解】 30. 【30.获取所有部门】 1)这里的sql语句要注意理解,采用sql的递归查询 31. 【31.添加部门】 1)因为使用了存储过程,所以在添加部门时在xxxMapper.xml文件中没有使用标签,而改用了