人力资源系统简单流程介绍

人力资源系统简单流程介绍

  • HRM人力资源管理系统
    • 项目简介
    • 项目结构
    • (1)整体功能
    • 在这里插入图片描述(2)模块划分
    • (3)整体架构分析
    • (4)技术使用
    • (5)团队成员
    • 负责模块及任务
    • (1)系统管理中心:
    • (2)课程中心
    • (3)用户中心
    • 问题及解决
    • (1)前后联调登录时:跨域问题
    • (3)Redis的缓存穿透、缓存击穿、缓存雪崩
    • (4)比较棘手的业务:页面静态化
    • (5)使用feign的接口实现文件上传
    • (6)单点登录如何进行登录拦截

HRM人力资源管理系统

XXX人力资源管理平台

项目简介

XXX公司推出的专业在线教育平台,聚合大量优质教育机构和名师,下设职业培训、公务员考试、托福雅思、考证考级、英语口语、中小学教育等众多在线学习精品课程,打造老师在线上课教学、学生及时互动学习的课堂。对于培训机构而言,可以入驻平台,发布相应的课程信息,也可以和企业定向合作进行定点培训。该项目分为6大模块:课程中心,岗位中心,用户中心,鉴权中心,机构管理中心,系统管理中心;

项目结构

(1)整体功能

人力资源系统简单流程介绍_第1张图片(2)模块划分

该项目整体分为6大模板:
课程中心 :管理发布课程,课程的搜索服务
岗位中心 :管理发布岗位信息,岗位的搜索服务
用户中心 :用户注册,用户信息,用户的课程申请和订单管理
鉴权中心 :用户登录以及权限控制
机构管理中心 :机构入驻与管理
系统管理中心 :数据字典,员工角色权限信息的维护

(3)整体架构分析

项目是前后端分离架构,前端使用vue,后端采用springboot+springcloud微服务架构,springboot搭建单个服务,springcloud治理服务。

(4)技术使用

SpringBoot、SpringCloud、Mybatis-Plus、Redis、FastDFS、Elasticsearch、Vue、ElementUI、 Velocity、RabbitMQ 、Gitlab
人力资源系统简单流程介绍_第2张图片

(5)团队成员

项目经理:1、架构师:1、UI:1、前端:2、后端:4、测试:2、运维:1。

负责模块及任务

(1)系统管理中心:

需求:hrm人力资源系统是一个出租型服务,需要有需求的公司入驻,购买套餐,获得相应的服务。

搭建:基于SSM框架,配置注册Eureka,使用配置中心,配置网关路由

负责任务:基于代码生成器实现租户表的CRUD,租户入驻:使用FastDFS分布式文件系统实现租户LOGO文件的管理,使用百度地图接口,收集租户的地址。

(2)课程中心

​需求:通过主站首页的链接跳转到课程中心门户,在课程中心门户首页有课程类型列表 - 后台:维护课程类型,选中某个类型后跳转到课程的列表页,列表课程信息 - 后台:维护课程信息,选中某个课程跳转到课程详情页,展示课程的详细信息,在课程的详情页可进行课程的购买,线上购买,线下学习,门户网站是高并发,需要进行页面静态化

搭建:基于SSM框架,配置注册Eureka,使用配置中心,配置网关路由

负责任务:使用循环+map的方式完成无线级别课程类型树数据的查询,使用redis对课程类型树的数据进行缓存,在前台页面展示,课程信息维护:基本信息,课程详情,市场信息,图片信息,课程管理表需要反三范式设计,创建人名称和机构名称冗余到了课程基本信息表,完成课程上下线:课程上线时,将上线课程的数据保存到ElasticSearch中,前台只能检索已经上线的课程。课程下线时:将上线课程的数据从ElasticSearch中删除。增删改时同步操作。使用velocity模板引擎技术,实现课程首页页面静态化,将静态化页面上传到FastDFS中,使用RabbitMQ消息队列接收fileId,下载页面完成静态化。课程中心首页:课程类型选择跳转,面包屑加载,课程的分页高级排序搜索。

(3)用户中心

需求:用户注册和登陆,各种用户的信息维护

搭建:基于SSM框架,配置注册Eureka,使用配置中心,配置网关路由

负责任务:用户注册:使用redis技术实现图形验证码注册,使用阿里云短信服务接口+redis实现短信验证码注册,同时进行用户注册其余信息的维护。用户登录:使用redis+cookie完成用户单点登录。

问题及解决

(1)前后联调登录时:跨域问题

​ 首先对于跨域的概念是:请求从一个域发出,访问另一个域的资源 ip:端口号 -> 另一个或者端口的资源, 只要ip或者端口不同,都认定为不同的域,如果之间有资源访问,这种行为叫做跨域访问

​ 但不是所有的跨域都会出现跨域问题,跨域问题出现在:出现在ajax请求中,因为同源策源的限制,浏览器出于安全起见,会对ajax跨域请求做限制,限制ajax请求访问其他域的资源

​ 对于跨域问题的解决方法有很多,但是我比较常用CORS
​ 在springboot+springcloud+前后端分离的微服务程序中,解决跨域问题需要,在网关中配置跨域过滤器,因为所有前端的请求都是通过zuul网关进行服务调用的,也就是说所有的前端请求都先访问网关,我们就把跨域配置到zuul网关中。

/**
 * 解决跨域问题
 */
@Configuration
public class GlobalCorsConfig {
   
    @Bean
    public CorsFilter corsFilter() {
   
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了
        //浏览器认为127.0.0.1和localhost不是同一个域
        config.addAllowedOrigin("http://127.0.0.1:6001");
        config.addAllowedOrigin("http://localhost:6001");
        config.addAllowedOrigin("http://127.0.0.1:6002");
        config.addAllowedOrigin("http://localhost:6002");
        config.addAllowedOrigin("http://127.0.0.1:6003");
        config.addAllowedOrigin("http://localhost:6003");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");
        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new
                UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

(2)无限级别课程类型树获取
​ 在课程中心业务模块,课程类型无限级别的树形菜单数据的获取

​ 最开始是通过递归的方式进行获取,这种方式每次都要去查询数据库,导致效率低, 当数据量变大,递归深度增加,容易导致栈内存溢出

​ 后面,我使用了嵌套循环的方式,查询出所有的课程类型,放入到一个list中,遍历查出来的所有类型,先判断是不是一级类型,一级类型就存储在一个专门的list容器中,不是一级类型,继续遍历,找出他的父类型,设置子类型到这个父类型中;但是这种方式,查询次数增加,导致效率低下;

​ 所以,在项目中,我最终使用的是循环+Map的方式。

​ 首先查询所有的类型放入List中,再将List中的所有类型放入Map中,Map的key为类型的ID,Map的value为当前类型对象。对List中所有类型进行遍历,如果是一级类型,则放入结果的List集合中,如果不是一级类型,则到Map中根据类型ID找到对应的父类型,将当前类型添加到父类型的children集合中,最终就能实现无线级别属性菜单数据的获取

/**
     * 嵌套循环+map
     * @return
     */
    private List<CourseType> getTreeData() {
   
        //准备一个list集合 存放所有的一级类型
        List<CourseType> firstLevelType = new ArrayList<>();

        //查询出所有的课程类型
        List<CourseType> allCourseTypes = baseMapper.selectList<

你可能感兴趣的:(java)