• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

CloudOffice: 中小型企业在线办公系统-云E办(后端)

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

CloudOffice

开源软件地址:

https://gitee.com/hmfdev/CloudOffice

开源软件介绍:

CloudOffice

介绍

  本项目目的是实现中小型企业的在线办公系统,云E办在线办公系统是一个用来管理日常的办公事务的一个系统,他能够管的内容有:日常的各种流程审批,新闻,通知,公告,文件信息,财务,人事,费用,资产,行政,项目,移动办公等等。
  它的作用就是通过软件的方式,方便管理,更加简单,更加扁平,更加高效,更加规范,能够提高整体的管理运营水平。

软件架构

软件架构说明

展示后台接口图片

输入图片说明

安装教程

  1. xxxx
  2. xxxx
  3. xxxx

使用说明

  1. 获取菜单时使用了缓存技术,所以这里需要配置redis,然后开启redis
  2. 添加员工时,使用了 rabbitmq 做员工添加完成后邮件的发送,需要配置服务的ip地址,还需要在配置文件中写你的发送邮件授权码,然后开启 rabbitmq
  3. 更新头像时使用了fastdfs轻量级的分布式文件系统上传图片,需要配置服务的ip地址,还需要开启fastdfs的 tracker(跟踪器)、storage(存储节点) 服务 和 nginx 服务器

提交日志细节记录

  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文件中没有使用标签,而改用了标签
    2)注意有些单词不要写错了

  32. 【32.删除部门】
    1)这里针对的是存储过程的操作
    2)到这里部门操作的后台接口就全都实现了

  33. 【33.获取所有操作员】
    1)封装AdminUtils工具类,获取登陆用户的信息,如id,是从SpringSecurity中获取的
    2)dao/mapper层中方法参数需要加上@Param注解
    3)sql语句中使用数据库提供的concat()函数连接字符串
    4)这里注意AdminMapper.xml文件中,标签的写法

  34. 【34.操作员更新及删除操作】
    1)通过MyBatisPlus提供的方法updateById()来更新数据
    2)这里注意@Data的问题,加注解@Getter(AccessLevel.NONE)表示不是从该字段不生成Getter方法
    3)这里的更新和删除接口没有测试

  35. 【35.操作员角色功能实现】
    1)这里注意批量更新操作员数据的AdminRolMapper.xml中sql语句的循环
    2)这里的接口也没有测试

  36. 【36.员工管理准备工作】
    1)配置分页插件,添加分页的公共返回对象RespPageBean
    2)分页公共返回对象RespPageBean的注释使用阿里巴巴规范,即使用文档注释
    3)做一个全局的日期格式转换工具类DateConverter,别忘了加上@Component
    4)在Employee类中加上@JsonFormat注解格式化时间,主要是为了返回给前端方便
    5)需要操作的外键字段也需要加到pojo类中,还需要加上@TableField注解,因为对应的表字段没有

  37. 【37.获取所有员工分页查询】
    1)通过controller的方法中设置注解@RequestParam(defaultValue = "1")来设置默认值
    2)在dao/mapper层中接口方法有多个参数时,需要加上@Param注解
    3)EmployeeMapper.xml中sql语句的连接依旧使用功concat()函数,可用可的字段需要在sql语句中使用if做判断是
    4)MyBatisPlus的分页插件IPage是国人开发的一个插件,用来做分页
    5)分页查询的基本配置就都在这里啦
    6)做了一个全局的日期格式化转换

  38. 【38.获取所有员工分页查询测试】
    1)所以每次写完一个接口就都要去测试,有问题就解决问题,没问题就是最好的

  39. 【39.添加员工前期准备】
    1)在EmployeeServiceImpl类中,使用String.format格式化防止出现乱码的情况

  40. 【40.修复获取工号出现500错误问题】
    1)错误原因是max(workID) 写成了 max(workId),单词写错了

  41. 【41.添加员工功能实现】
    1)这里涉及到一个合同期限的计算
    2)通过Java自带的LocalDate类来处理合同期限时间的计算

  42. 【42.员工更新及删除】
    1)使用MyBatisPlus提供的更新和删除方法,就可以很快实现了
    2)更新和删除接口都完成了测试
    3)员工模块的数据操作到这里就基本完成了
    4)接下来就是实现员工数据的导入和导出操作

  43. 【43.EasyPoi注解使用】
    1)使用EasyPoi工具实现Excel数据的导入导出
    2)在pom.xml中引入easy poi依赖,它最大的特点是可以使用注解去定义你要导出的哪些字段
    3)在pojo对应类的字段中加上EasyPoi的注解@Excel,这里注意@ExcelEntity注解的使用
    4)对象使用@ExcelEntity注解,然后再到对象里的字段使用@Excel注解

  44. 【44.导出员工数据】
    1)注意注解@GetMapping(value = "/export", produces = "application/octet-stream")中,produces属性的使用,不然会出现乱码,就像验证码那里使用的一样
    2)返回导出的数据是使用流的方式导出去
    3)查询员工复用了之前【37.获取所有员工分页查询】的sql语句
    4)我测试导出了一下,感觉好牛逼呀
    5)离职日期和工龄数据库中没有数据,这里就不做导出显示了

  45. 【45.导入员工数据】
    1)需要注意民族、政治面貌、部门、职称、职位字段的导入,因为这几个字段涉及到对象,而且数据库保存的是他们对应的id值
    2)重写@EqualsAndHashCode方法
    3)有参构造的注解出现了,最好也把无参构造的注解也加上
    4)这里需要注意导入时民族、政治面貌、部门、职称、职位字段需要转换成Id值保存在数据库中

  46. 【46.员工数据导入导出测试】
    1)直接删除Excel中的行数据,可能会导致导入时,会读取到该行为空的情况,这个需要注意
    2)导入成功但数据库查询却没有,这个可能要检查一下你是否查询到了所有的数据,或者数据可能在下一页,这是经验之谈了
    3)参数 ExcelType.HSSF,表示使用03版的Excel,因为兼容性好

  47. 【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. 【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. 【49.添加注释理解邮件发送功能】
    1)添加部分注释理解,邮件发送的流程

  50. 【50.生产端可靠性投递方案介绍】

  51. 【51.开启消息回调机制】
    1)主要是确保邮件能够正常的发送
    2)需要有个RabbitMQ配置类RabbitMQConfig,使用路由模式 DirectExchange
    3)然后在application.yml中配置,消息确认回调和消息失败回调
    4)确认回调、失败回调,做一个相应的处理

  52. 【52.生产端消息投递可靠性实现】
    1)创建邮件发送定时任务
    2)在启动类中加注解@EnableScheduling开启定时任务
    3)到这里发送消息就会入数据库了

  53. 【53.消费端幂等性操作】
    1)RabbitMQ开启手动确认
    2)在yeb-mail的application.yml中添加redis配置
    3)修改发送邮件服务的地方,改的还挺多的
    4)存在redis中,在发送邮件的时候存
    5)这里还需要重点的理解,理解

  54. 【54.员工薪资模块--工资账套功能实现】
    1)在pojo类的字段上加入注解 @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")用来格式化时间
    2)因为请求地址都在数据库中定义好了,所以每次写controller时都要在类上写上对应的@@RequestMapping()路径
    3)获取当前时间使用LocalDateTime.now()
    4)这里的增删该查可以学习他的过程,全厂完全使用MyBatisPlus提供的方法

  55. 【55.获取所有员工账套】
    1)工资账套其实可以理解为工资的模板
    2)分页查询要返回 RespPageBean,这里的分页操作需要看懂怎么个流程
    3)使用注解@RequestParam在Controller层的方法参数中指定默认值

  56. 【56.员工账套功能实现】
    1)这里的更新语句要注意学习一下 employeeService.update(new UpdateWrapper().set("salaryId", sid).eq("id", eid))
    2)Controller层类上,需要的注解是@RestController 和 @RequestMapping("/salary/sobcfg")

  57. 【57.在线聊天模块--webSocket普通配置】
    1)添加websocket所需的依赖
    2)新建WebSocket配置类WebSocketConfig并在类上添加注解@Configuratioin和@EnableWebSocketMessageBroker,其中注解@Configuration是配置类必须要加上的
    3)WebSocket配置类还需要实现 WebSocketMessageBrokerConfigurer 接口
    4)前端一般都会使用 sockJs 去连接 WebSocket,原生的现在很少使用了

  58. 【58.webSocket有关JWT的配置】
    1)使用了JWT令牌登录,在这里还需要额外的配置,即输入通道的配置
    2)通过在字段变量上添加注解@Value("${jwt.tokenHead}"),就可以获取application.yml文件中配置的值,并绑定到字段变量上
    3)新建一个消息类 ChatMsg,存放发送的消息内容
    4)注意controller层中方法行的注解 @MessageMapping
    5)还需要配置放行websocket

  59. 【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. 【60.个人中心模块--个人中心功能实现】
    1)实现的功能主要是个人中心的常规操作、更新头像(使用FastDFS)
    2)个人中心的常规操作:更新用户信息、更新密码
    3)更改密码后,强制下线重新登录,这个流程由前端进行处理

  61. 【61.自定义反序列化】
    1)到这里更新登录用户信息有个json转换的问题,authorities 入参字段有问题, GrantedAuthority的默认不能反序列化问题
    2)我们就需要自定义一个反序列化类 CustomAuthorityDeserializer
    3)在需要使用到反序列化的地方使用注解 @JsonDeserialize(using = CustomAuthorityDeserializer.class)
    4)更新当前用户信息、更新用户密码接口测试完成

  62. 【62.FastDFS工具类编写】
    1)主要是更新头像功能实现,要确保FastDFS的服务已经启动,即需要先安装好FastDFS
    2)FastDFS是一个开源的轻量级分布式文件系统
    3)首先是fdfs配置文件 fdfs_client.conf,注意是.conf后缀
    4)fdfs_client.conf配置文件中主要是要配置你的 tracker ip地址 和 端口号
    5)然后是编写fdfs的工具类,里面有各种的操作方法,如上传、下载文件等

  63. 【63.更新头像功能实现】
    1)更新头像功能接口测试完成

  64. 【64.后端基本完成】
    1)到这里云E办项目后端的基础功能已经完成,后续根据需要再添加相应的功能。
    2)添加使用说明,如,需要开启的一些服务器,redis、rabbitmq、fastdfs、nginx等
    3)此致,敬礼 -- peace

  65. 【65.swaggerUI界面切换】
    1)需要对比原生swaggerUI界面和第三方swaggerUI界面的小伙伴,这里只需三步就可以轻松切换
    2)全局搜索“swaggerUI界面切换”,根据后面显示的(swaggerUI界面切换第一/二/三步),根据步骤放开注释即可
    3)如果前两步放开注释后可以访问成功,第三步就不需要操作了

  66. 【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. 【67.加入在swagger文档中的登录流程说明】
    1)调用 CaptchaController 中的 /captcha 接口获取到验证码
    2)调用 LoginController 中的 /login 接口,并传入刚刚获取到的验证码,并传入用户名 admin、密码 123,获取到返回的 token
    3)找到 Authorize ,在参数值中加入刚刚返回的 token 值,并在 token 值前面加上 Bearer ,并用空格分开,点击保存即可

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request

特技

  1. 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
  2. Gitee 官方博客 blog.gitee.com
  3. 你可以 https://gitee.com/explore 这个地址来了解 Gitee 上的优秀开源项目
  4. GVP 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
  5. Gitee 官方提供的使用手册 https://gitee.com/help
  6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 https://gitee.com/gitee-stars/

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap