本项目目的是实现中小型企业的在线办公系统,云E办在线办公系统是一个用来管理日常的办公事务的一个系统,他能够管的内容有:日常的各种流程审批,新闻,通知,公告,文件信息,财务,人事,费用,资产,行政,项目,移动办公等等。
它的作用就是通过软件的方式,方便管理,更加简单,更加扁平,更加高效,更加规范,能够提高整体的管理运营水平。
【1.本地初始化】
1)IDEA中使用 Spring Initializr 创建一个SpringBoot项目
2)使用git clone gitee版本库中新建的repository项目到本地,加入clone下来的内容到新建的SpringBoot项目中,整合后,做本地初始化提交
3)我把IDEA生成的.gitignore和gitee中clone下来的.gitignore合并到一起了
【2.项目准备】
1)数据库准备,新建yeb数据库,数据库字符集选utf8mb4,导入放在database文件夹下的yeb.sql数据库脚本
2)使用lombok,需要先在IDEA中安装lombok插件
【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.逆向工程(逆向工程生成所有数据库表前的备份提交)】
1)使用MyBatisPlus自带的逆向工程代码生成器AutoGenerator可以快速生成Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
2)使用maven的quickstart新建逆向工程代码生成器子项目Module,专门用于各模块代码的生成
3)删除新建的yeb-generator子项目pom.xml中用不到的内容,指定父工程坐标,copy依赖过来,还有新建包名generator
4)该代码生成器子项目用不到测试,所以把生成的test文件夹删掉了
【5.逆向工程(逆向工程生成所有数据库表对应的各模块类)】
1)在yeb-generator子项目中,生成好各模块的类后,copy到yeb-server子项目中
2)copy到yeb-server子项目中后,删除掉在yeb-generator子项目中生成好的各模块的类,因为它们会报红
3)添加所需的依赖,解决报红的问题,如添加swagger2的依赖
4)逆向工程文件CodeGenerator,你需要在这个文件里配置你要生成对应模块类的包,里面有具体的注释说明
【6.Jwt Token工具类编写】
1)登录功能采用SpringSecurity+JWT令牌实现登录功能,引入对应的依赖
2)在application.yml中配置JWT,并新建config专门用来存放我们项目要使用到的一些配置
3)新建并编写JwtTokenUtil工具类
【7.公共返回对象】
1)调用接口时返回的json数据对象封装到 RespBean 中
【8.登录之后返回token】
1)登录使用Spring Security + JWT
2)前端传用户名和密码,判断如果正确就生成JWT令牌,并把token和请求头返回给前端
【9.获取当前登录用户信息以及退出功能】
1)退出流程是前端请求接口,成功后,前端把请求头删掉就行了
【10.配置Security登录授权过滤器】
【11.Security自定义返回结果】
1)Spring Security配置基本完成
【12.Swagger2配置】
1)还需要配置放行Swagger2的资源
2)修改了代码漏写的错误
【13.Swagger2添加Authorize】
1)修复了一些代码错误内容
【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.校验验证码】
1)在AdminLoginParam类中添加验证码参数,相应层的方法也加上code参数
2)然后在AdminServiceImpl类的login()方法中,判断用户输入的code验证码是否和生成存在session中的一致
【16.根据用户id查询菜单列表】
1)我们使用了SpringSecurity,登录之后设置了全局保存的用户对象,我们可以通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取
【17.根据用户id查询菜单列表Sql语句编写】
1)这里的sql语句较多较长,而且还有点复杂
2)因为之前代码写在了错误的层上面,本来是要写在MenuController这一流程下的,所以在这里也修复了
【18.Redis集成菜单功能】
1)加入Redis的依赖,然后在application.yml配置redis的连接等
2)再配置Redis的序列化,没有配置序列化,在redis会出现乱码,在这别忘了@Configuration注解,否则配置不成功
3)如果菜单有修改,那么就要清空redis,让他重新从数据库中获取,再存到redis中,这样才能保证数据是最新的
【19.根据请求url判断角色】
1)根据角色获取菜单的列表,需要放到过滤器中
2)新建component包,改变一些.java文件的存放路径
【20.判断用户角色】
1)动态权限等的配置,菜单和权限配置完成
【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.全局异常处理】
1)注解 @RestControllerAdvice // 表示控制器的增强类,符合我们的异常就会被拦截
【23.职称管理功能实现】
1)对于时间,我们都需要在实体类相应的字段上加上注解@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")来格式化时间
2)通过Arrays.asList(ids),把数组转为集合List
3)t_joblevel表中的titleLevel字段是固定了值,这个需要注意一下4)像上面数据库中已经固定了值,最好就使用枚举Enum类型
【24.权限组角色功能实现】
1)修改了MenuController的RequestMapping为"system/config"
2)这里通过MyBatisPlus提供的list()方法,roleService.list()来获取表的所有数据
3)通过MyBatisPlus提供的save()方法,roleService.save()来添加数据
4)通过MyBatisPlus提供的removeById()方法,roleService.removeById()来通过Id删除一条数据
【25.权限组菜单查询功能实现】
1)这里注意MenuMapper.xml里resultMap的写法
2)这里注意(根据角色id查询菜单id)方法中的内容,menuRoleService.list(new QueryWrapper().eq("rid", rid)).stream().map(MenuRole::getMid).collect(Collectors.toList());
【26.权限组菜单更新功能实现】
1)更新删除操作时,在Service层加个事务的注解 @Transactional
2)注意这里的dao层参数加了注解@Param,在org.apache.ibatis.annotations.Param;包下
【27.存储过程介绍】
【28.存储过程创建及调用】
【29.项目存储过程讲解】
【30.获取所有部门】
1)这里的sql语句要注意理解,采用sql的递归查询
【31.添加部门】
1)因为使用了存储过程,所以在添加部门时在xxxMapper.xml文件中没有使用标签,而改用了标签
2)注意有些单词不要写错了
【32.删除部门】
1)这里针对的是存储过程的操作
2)到这里部门操作的后台接口就全都实现了
【33.获取所有操作员】
1)封装AdminUtils工具类,获取登陆用户的信息,如id,是从SpringSecurity中获取的
2)dao/mapper层中方法参数需要加上@Param注解
3)sql语句中使用数据库提供的concat()函数连接字符串
4)这里注意AdminMapper.xml文件中,标签的写法
【34.操作员更新及删除操作】
1)通过MyBatisPlus提供的方法updateById()来更新数据
2)这里注意@Data的问题,加注解@Getter(AccessLevel.NONE)表示不是从该字段不生成Getter方法
3)这里的更新和删除接口没有测试
【35.操作员角色功能实现】
1)这里注意批量更新操作员数据的AdminRolMapper.xml中sql语句的循环
2)这里的接口也没有测试
【36.员工管理准备工作】
1)配置分页插件,添加分页的公共返回对象RespPageBean
2)分页公共返回对象RespPageBean的注释使用阿里巴巴规范,即使用文档注释
3)做一个全局的日期格式转换工具类DateConverter,别忘了加上@Component
4)在Employee类中加上@JsonFormat注解格式化时间,主要是为了返回给前端方便
5)需要操作的外键字段也需要加到pojo类中,还需要加上@TableField注解,因为对应的表字段没有
【37.获取所有员工分页查询】
1)通过controller的方法中设置注解@RequestParam(defaultValue = "1")来设置默认值
2)在dao/mapper层中接口方法有多个参数时,需要加上@Param注解
3)EmployeeMapper.xml中sql语句的连接依旧使用功concat()函数,可用可的字段需要在sql语句中使用if做判断是
4)MyBatisPlus的分页插件IPage是国人开发的一个插件,用来做分页
5)分页查询的基本配置就都在这里啦
6)做了一个全局的日期格式化转换
【38.获取所有员工分页查询测试】
1)所以每次写完一个接口就都要去测试,有问题就解决问题,没问题就是最好的
【39.添加员工前期准备】
1)在EmployeeServiceImpl类中,使用String.format格式化防止出现乱码的情况
【40.修复获取工号出现500错误问题】
1)错误原因是max(workID) 写成了 max(workId),单词写错了
【41.添加员工功能实现】
1)这里涉及到一个合同期限的计算
2)通过Java自带的LocalDate类来处理合同期限时间的计算
【42.员工更新及删除】
1)使用MyBatisPlus提供的更新和删除方法,就可以很快实现了
2)更新和删除接口都完成了测试
3)员工模块的数据操作到这里就基本完成了
4)接下来就是实现员工数据的导入和导出操作
【43.EasyPoi注解使用】
1)使用EasyPoi工具实现Excel数据的导入导出
2)在pom.xml中引入easy poi依赖,它最大的特点是可以使用注解去定义你要导出的哪些字段
3)在pojo对应类的字段中加上EasyPoi的注解@Excel,这里注意@ExcelEntity注解的使用
4)对象使用@ExcelEntity注解,然后再到对象里的字段使用@Excel注解
【44.导出员工数据】
1)注意注解@GetMapping(value = "/export", produces = "application/octet-stream")中,produces属性的使用,不然会出现乱码,就像验证码那里使用的一样
2)返回导出的数据是使用流的方式导出去
3)查询员工复用了之前【37.获取所有员工分页查询】的sql语句
4)我测试导出了一下,感觉好牛逼呀
5)离职日期和工龄数据库中没有数据,这里就不做导出显示了
【45.导入员工数据】
1)需要注意民族、政治面貌、部门、职称、职位字段的导入,因为这几个字段涉及到对象,而且数据库保存的是他们对应的id值
2)重写@EqualsAndHashCode方法
3)有参构造的注解出现了,最好也把无参构造的注解也加上
4)这里需要注意导入时民族、政治面貌、部门、职称、职位字段需要转换成Id值保存在数据库中
【46.员工数据导入导出测试】
1)直接删除Excel中的行数据,可能会导致导入时,会读取到该行为空的情况,这个需要注意
2)导入成功但数据库查询却没有,这个可能要检查一下你是否查询到了所有的数据,或者数据可能在下一页,这是经验之谈了
3)参数 ExcelType.HSSF,表示使用03版的Excel,因为兼容性好
【47.创建邮件发送服务项目】
1)邮件的发送需要开启邮件的SMTP服务
2)新建yeb-mail子项目,处理pom.xml文件,添加所需依赖,添加启动类3)准备邮箱模板,使用的是thymeleaf,所以要在resources资源目录下新建templates目录存放邮件模板文件mail.html等
4)使用thymeleaf还需要在html文件中引入头文件,<html lang="en" xmlns:th="http://www.thymeleaf.org">
5)为了安全起见我的邮件发送授权我就没有上传了,使用时需要修改mail服务的application.yml文件,加上你的邮件授权码
【48.邮件发送功能实现】
1)还需要在yeb-server子项目的pom.xml中加上rabbitmq的依赖,因为需要使用就要添加依赖
2)除了依赖也还需要在yeb-server子项目的application.yml文件中配置rabbitmq
3)rabbitmq的配置,需要配置你自己的用户名、密码和服务器地址
4)这里只实现添加员工是发送邮件,使用Excel导入时就不实现了
5)在yeb-server子项目中发送消息,在yeb-mail子项目中接收消息并发送邮件
6)在yeb-mail的启动类中,配置rabbitmq的绑定,如队列、交换机
7)我们在yeb-mail中引入了yeb-server的依赖,需要连接数据库,所以就提示我们要配置数据源,在MailApplication启动类的注解中去掉数据库@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
8)注意这一定要配置你的邮箱授权码
【49.添加注释理解邮件发送功能】
1)添加部分注释理解,邮件发送的流程
【50.生产端可靠性投递方案介绍】
【51.开启消息回调机制】
1)主要是确保邮件能够正常的发送
2)需要有个RabbitMQ配置类RabbitMQConfig,使用路由模式 DirectExchange
3)然后在application.yml中配置,消息确认回调和消息失败回调
4)确认回调、失败回调,做一个相应的处理
【52.生产端消息投递可靠性实现】
1)创建邮件发送定时任务
2)在启动类中加注解@EnableScheduling开启定时任务
3)到这里发送消息就会入数据库了
【53.消费端幂等性操作】
1)RabbitMQ开启手动确认
2)在yeb-mail的application.yml中添加redis配置
3)修改发送邮件服务的地方,改的还挺多的
4)存在redis中,在发送邮件的时候存
5)这里还需要重点的理解,理解
【54.员工薪资模块--工资账套功能实现】
1)在pojo类的字段上加入注解 @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")用来格式化时间
2)因为请求地址都在数据库中定义好了,所以每次写controller时都要在类上写上对应的@@RequestMapping()路径
3)获取当前时间使用LocalDateTime.now()
4)这里的增删该查可以学习他的过程,全厂完全使用MyBatisPlus提供的方法
【55.获取所有员工账套】
1)工资账套其实可以理解为工资的模板
2)分页查询要返回 RespPageBean,这里的分页操作需要看懂怎么个流程
3)使用注解@RequestParam在Controller层的方法参数中指定默认值
【56.员工账套功能实现】
1)这里的更新语句要注意学习一下 employeeService.update(new UpdateWrapper().set("salaryId", sid).eq("id", eid))
2)Controller层类上,需要的注解是@RestController 和 @RequestMapping("/salary/sobcfg")
【57.在线聊天模块--webSocket普通配置】
1)添加websocket所需的依赖
2)新建WebSocket配置类WebSocketConfig并在类上添加注解@Configuratioin和@EnableWebSocketMessageBroker,其中注解@Configuration是配置类必须要加上的
3)WebSocket配置类还需要实现 WebSocketMessageBrokerConfigurer 接口
4)前端一般都会使用 sockJs 去连接 WebSocket,原生的现在很少使用了
【58.webSocket有关JWT的配置】
1)使用了JWT令牌登录,在这里还需要额外的配置,即输入通道的配置
2)通过在字段变量上添加注解@Value("${jwt.tokenHead}"),就可以获取application.yml文件中配置的值,并绑定到字段变量上
3)新建一个消息类 ChatMsg,存放发送的消息内容
4)注意controller层中方法行的注解 @MessageMapping
5)还需要配置放行websocket
【59.webSocket流程讲解】
1)添加一些注释帮助理解websocket流程
2)配置端点 /ws/ep
3)设置token Auth-Token
4)设置Security全局用户对象 和 accessor.setUser(),不然连不上
5)设置代理域 registry.enableSimpleBroker("/queue"); 可以根据业务的需求设置多个
6)最后别忘了在 SecurityConfig 类中,放行发消息的请求路径,就使用注解 @MessageMapping("/ws/chat") 的路径
【60.个人中心模块--个人中心功能实现】
1)实现的功能主要是个人中心的常规操作、更新头像(使用FastDFS)
2)个人中心的常规操作:更新用户信息、更新密码
3)更改密码后,强制下线重新登录,这个流程由前端进行处理
【61.自定义反序列化】
1)到这里更新登录用户信息有个json转换的问题,authorities 入参字段有问题, GrantedAuthority的默认不能反序列化问题
2)我们就需要自定义一个反序列化类 CustomAuthorityDeserializer
3)在需要使用到反序列化的地方使用注解 @JsonDeserialize(using = CustomAuthorityDeserializer.class)
4)更新当前用户信息、更新用户密码接口测试完成
【62.FastDFS工具类编写】
1)主要是更新头像功能实现,要确保FastDFS的服务已经启动,即需要先安装好FastDFS
2)FastDFS是一个开源的轻量级分布式文件系统
3)首先是fdfs配置文件 fdfs_client.conf,注意是.conf后缀
4)fdfs_client.conf配置文件中主要是要配置你的 tracker ip地址 和 端口号
5)然后是编写fdfs的工具类,里面有各种的操作方法,如上传、下载文件等
【63.更新头像功能实现】
1)更新头像功能接口测试完成
【64.后端基本完成】
1)到这里云E办项目后端的基础功能已经完成,后续根据需要再添加相应的功能。
2)添加使用说明,如,需要开启的一些服务器,redis、rabbitmq、fastdfs、nginx等
3)此致,敬礼 -- peace
【65.swaggerUI界面切换】
1)需要对比原生swaggerUI界面和第三方swaggerUI界面的小伙伴,这里只需三步就可以轻松切换
2)全局搜索“swaggerUI界面切换”,根据后面显示的(swaggerUI界面切换第一/二/三步),根据步骤放开注释即可
3)如果前两步放开注释后可以访问成功,第三步就不需要操作了
【66.添加 redis、rabbitmq、fastdfs(tracker/storage)、nginx 项目服务启动命令说明】
0)在操作下面的启动命令时,需要首先在application.yml配置文件中配置服务的ip地址,和你用来发送给新入职员工的邮件授权码,例如163邮箱的
1)redis启动命令:./redis-server redis.conf
1)查看redis启动状态:ps -ef | grep redis
2)rabbitmq启动命令:systemctl start rabbitmq-server.service
2)查看rabbitmq启动状态:systemctl status rabbitmq-server.service
3)FastDFS的跟踪器tracker启动命令:/etc/init.d/fdfs_trackerd start(如果tracker开启了开机启动,这里就无需执行该命令)
3)FastDFS的存储节点storage启动命令:/etc/init.d/fdfs_storaged start(因启动前提为tracker服务必须已启动,因此不推荐开启自启)
3)查看tracker、storage服务启动状态:ps aux | grep fdfs
4)nginx启动命令:/usr/local/nginx/sbin/nginx
5)如果redis没有配置并启动,那么在登录时,将登录不成功,因为登录后就需要获取菜单列表数据,但是redis服务没有开启导致登录成功,但页面跳转到空白页
6)给需要修改的地方加了注释的ip地址
【67.加入在swagger文档中的登录流程说明】
1)调用 CaptchaController 中的 /captcha 接口获取到验证码
2)调用 LoginController 中的 /login 接口,并传入刚刚获取到的验证码,并传入用户名 admin、密码 123,获取到返回的 token
3)找到 Authorize ,在参数值中加入刚刚返回的 token 值,并在 token 值前面加上 Bearer ,并用空格分开,点击保存即可
请发表评论