招聘求职系统|基于Springboot+Vue+Nodejs实现求职招聘系统

541 阅读7分钟

收藏点赞不迷路  关注作者有好处

文末获取源码 

项目编号:BS-PT-080

前言:

由CNNIC最新数据表明,截止2022年7月,互联网普及率达78.6%[数据来源于中国互联网络信息中心、中国互联网络发展状况统计报告]。相较于传统的招聘方式,越来越多的人选择网络招聘的渠道进行求职和招聘,这将进一步促进网络招聘行业的进步。开发求职招聘平台更加具有意义,网络招聘有着诸多的优势,主要体现在覆盖面广、信息传递快,资源丰富,招聘职位多样化,下面从以下五个点具体介绍网络招聘的优势:

1、覆盖面广。互联网的覆盖是以往任何媒介都无法比拟的,它的触角可以轻易地延伸到世界的每一个角落。网络招聘依托于互联网的这个特点,达到了传统招聘方式无法获得的效果。

2、时效性强。网络招聘的双方通过交互式的网上登陆和查询完成信息的交流。这种方式与传统招聘方式不同,它不强求时间和空间上的绝对一致,方便了双方时间的选择。互联网本身不受时间、地域限制,也不受服务周期和发行渠道限制。它不仅可以迅速、快捷地传递信息,而且还可以瞬问更新信息。这种基于招聘双方主动性的网上交流,于无声无息之间,完成了及时、迅捷的互动。

3、成本更低。网络招聘在节约费用上有很大的优势。对于毕业生来说,通过轻点鼠标即可完成个人简历的传递,原本一个月才能完成的信息整理、发布工作,现在可能只要半天就能够完成。这既节约了复印、打印费用,还省却了一番鞍马劳顿。对用人单位来讲,网络招聘的成本更低。

4、针对性强。网络招聘是一个跨时空的互动过程,对供求双方而言都是主动行为,无论是用人单位还是个人都能根据自己的条件在网上进行选择。这种积极的互动,减少了招聘和应聘过程中的盲目行为。一些大型的人才招聘网站都提供了个性化服务,如快捷搜索方式,条件搜索引擎等,这进一步加强了网络招聘的针对性。

5、筛选功能。构成“网民”主体的是一个年轻、高学历、向往未来的群体。通过上网,招聘者就已经对应聘者的基本素质有了初步的了解,相当于已经对他们进行了一次小型的计算机和英文的测试,对应聘者作了一次初步筛选。

一,项目简介

(1)EKKO招聘平台系统的用户共分为三类类:个人用户、企业用户、管理员。

  1. 求职用户可以管理自己的信息,管理自己的简历,也可以实时浏览企业发布的招聘信息,按自己的要求筛选出合适的企业从而决定报名,并可以在企业应答之后收到相应的回复。求职用户的用例图如图3-2所示。

​编辑

图3-2  求职用户用例图

  1. 企业用户可以管理本公司的登记信息,管理企业用户信息,进行企业认证,发布招聘岗位,也可以实时浏览求职者投递的简历进行筛选,简历通过的就可以发送面试通知。企业用户的用例图如图3-3所示。

​编辑

图3-3  企业用户用例图

  1. 管理员可以进行用户管理、增删改查二级管理员、为后台系统的用户分配权限、对后台的公告进行增删改查、手动操作企业认证审核的流程、可以对求职用户和企业用户信息和公司信息进行导入导出,方便统计数据。管理员的用例图如图3-4所示。

​编辑

图3-4  管理员用例图

本系统的功能主要有求职用户管理功能,企业用户管理功能、管理员管理功能,简历管理功能,求职申请管理功能,招聘管理功能,权限管理,企业入驻管理,用户信息统计管理,公告管理。

10 大核心功能描述如下:

求职用户管理功能:用户信息注册、修改信息、求职用户登录、查看个人信息、上传简历附件。

企业用户管理功能:企业信息注册、修改信息、企业认证、企业用户登录、查看个人信息。

简历管理功能:求职用户生成简历、修改简历、查看简历、上传简历附件。

求职管理功能:求职用户查看已投递岗位,选择投递岗位。

招聘管理功能:企业用户发布招聘岗位、撤销招聘岗位、筛选用户已投递的简历、发送面试通知。

权限管理功能:管理员给用户分配角色、给角色分配权限。

企业入驻管理功能:管理员审核企业提交的认证材料(企业Logo、营业执照)企,审核通过则认证成功,反之认证失败。

用户统计管理功能: 管理员导入用户信息、导出用户信息、下载导入用户信息模板。

公告管理功能: 管理员发布公告、修改公告、删除公告。

管理员管理功能:创建二级管理员、删除二级管理员、修改二级管理员、查询二级管理员、管理员登录。

功能具体信息分析如下:

​编辑

二,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

后台开发技术:Springboot+Mybatis

前台开发技术:Vue+Nodejs+EelementUI

三,系统展示

6.1 登录界面原型

​编辑

6.2 注册界面原型

​编辑​编辑

6.3 首页界面原型

​编辑

6.4 岗位展示页面原型

​编辑

6.5 岗位详情页面原型

​编辑

6.6 个人中心页面原型

​编辑

6.7 简历信息页面原型

​编辑

6.8 后台管理登录原型

​编辑

6.9 后台管理首页原型

​编辑

6.10 公司管理页面原型

​编辑

6.11 岗位分类页面原型

​编辑

6.12 招聘信息原型

​编辑

6.13 简历投递信息原型

​编辑

四,核心代码展示

package com.zeus.web.controller.system;

import com.zeus.common.annotation.Log;
import com.zeus.common.constant.UserConstants;
import com.zeus.common.core.controller.BaseController;
import com.zeus.common.core.domain.AjaxResult;
import com.zeus.common.core.domain.entity.SysMenu;
import com.zeus.common.enums.BusinessType;
import com.zeus.common.utils.StringUtils;
import com.zeus.system.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 菜单信息
 * 
 * @author
 */
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
    @Autowired
    private ISysMenuService menuService;

    /**
     * 获取菜单列表
     */
    @PreAuthorize("@ss.hasPermi('system:menu:list')")
    @GetMapping("/list")
    public AjaxResult list(SysMenu menu)
    {
        List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
        return AjaxResult.success(menus);
    }

    /**
     * 根据菜单编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:menu:query')")
    @GetMapping(value = "/{menuId}")
    public AjaxResult getInfo(@PathVariable Long menuId)
    {
        return AjaxResult.success(menuService.selectMenuById(menuId));
    }

    /**
     * 获取菜单下拉树列表
     */
    @GetMapping("/treeselect")
    public AjaxResult treeselect(SysMenu menu)
    {
        List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
        return AjaxResult.success(menuService.buildMenuTreeSelect(menus));
    }

    /**
     * 加载对应角色菜单列表树
     */
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        List<SysMenu> menus = menuService.selectMenuList(getUserId());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
        return ajax;
    }

    /**
     * 新增菜单
     */
    @PreAuthorize("@ss.hasPermi('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
        {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
        }
        menu.setCreateBy(getUsername());
        return toAjax(menuService.insertMenu(menu));
    }

    /**
     * 修改菜单
     */
    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
        {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
        {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
        }
        else if (menu.getMenuId().equals(menu.getParentId()))
        {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
        }
        menu.setUpdateBy(getUsername());
        return toAjax(menuService.updateMenu(menu));
    }

    /**
     * 删除菜单
     */
    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{menuId}")
    public AjaxResult remove(@PathVariable("menuId") Long menuId)
    {
        if (menuService.hasChildByMenuId(menuId))
        {
            return AjaxResult.error("存在子菜单,不允许删除");
        }
        if (menuService.checkMenuExistRole(menuId))
        {
            return AjaxResult.error("菜单已分配,不允许删除");
        }
        return toAjax(menuService.deleteMenuById(menuId));
    }
}

package com.zeus.web.controller.system;

import com.zeus.common.annotation.Log;
import com.zeus.common.constant.UserConstants;
import com.zeus.common.core.controller.BaseController;
import com.zeus.common.core.domain.AjaxResult;
import com.zeus.common.core.domain.entity.SysDept;
import com.zeus.common.core.domain.entity.SysRole;
import com.zeus.common.core.domain.entity.SysUser;
import com.zeus.common.core.domain.model.LoginUser;
import com.zeus.common.core.page.TableDataInfo;
import com.zeus.common.enums.BusinessType;
import com.zeus.common.utils.StringUtils;
import com.zeus.common.utils.poi.ExcelUtil;
import com.zeus.framework.web.service.SysPermissionService;
import com.zeus.framework.web.service.TokenService;
import com.zeus.system.domain.SysUserRole;
import com.zeus.system.service.ISysDeptService;
import com.zeus.system.service.ISysRoleService;
import com.zeus.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 角色信息
 * 
 * @author 
 */
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysDeptService deptService;

    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysRole role)
    {
        startPage();
        List<SysRole> list = roleService.selectRoleList(role);
        return getDataTable(list);
    }

    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:role:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysRole role)
    {
        List<SysRole> list = roleService.selectRoleList(role);
        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
        util.exportExcel(response, list, "角色数据");
    }

    /**
     * 根据角色编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId)
    {
        roleService.checkRoleDataScope(roleId);
        return AjaxResult.success(roleService.selectRoleById(roleId));
    }

    /**
     * 新增角色
     */
    @PreAuthorize("@ss.hasPermi('system:role:add')")
    @Log(title = "角色管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysRole role)
    {
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
        {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
        {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
        }
        role.setCreateBy(getUsername());
        return toAjax(roleService.insertRole(role));

    }

    /**
     * 修改保存角色
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
        {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
        }
        else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
        {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
        }
        role.setUpdateBy(getUsername());
        
        if (roleService.updateRole(role) > 0)
        {
            // 更新缓存用户权限
            LoginUser loginUser = getLoginUser();
            if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
            {
                loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
                loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
                tokenService.setLoginUser(loginUser);
            }
            return AjaxResult.success();
        }
        return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
    }

    /**
     * 修改保存数据权限
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/dataScope")
    public AjaxResult dataScope(@RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        return toAjax(roleService.authDataScope(role));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        role.setUpdateBy(getUsername());
        return toAjax(roleService.updateRoleStatus(role));
    }

    /**
     * 删除角色
     */
    @PreAuthorize("@ss.hasPermi('system:role:remove')")
    @Log(title = "角色管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{roleIds}")
    public AjaxResult remove(@PathVariable Long[] roleIds)
    {
        return toAjax(roleService.deleteRoleByIds(roleIds));
    }

    /**
     * 获取角色选择框列表
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping("/optionselect")
    public AjaxResult optionselect()
    {
        return AjaxResult.success(roleService.selectRoleAll());
    }

    /**
     * 查询已分配用户角色列表
     */
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/allocatedList")
    public TableDataInfo allocatedList(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectAllocatedList(user);
        return getDataTable(list);
    }

    /**
     * 查询未分配用户角色列表
     */
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/unallocatedList")
    public TableDataInfo unallocatedList(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUnallocatedList(user);
        return getDataTable(list);
    }

    /**
     * 取消授权用户
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/cancel")
    public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
    {
        return toAjax(roleService.deleteAuthUser(userRole));
    }

    /**
     * 批量取消授权用户
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/cancelAll")
    public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
    {
        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
    }

    /**
     * 批量选择用户授权
     */
    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/selectAll")
    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
    {
        roleService.checkRoleDataScope(roleId);
        return toAjax(roleService.insertAuthUsers(roleId, userIds));
    }

    /**
     * 获取对应角色部门树列表
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/deptTree/{roleId}")
    public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
    {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
        ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
        return ajax;
    }
}

五,项目总结

EKKO招聘平台系统采用MVVM对其整体进行划分,这样做的好处是:一方面,可以使整个系统结构清晰,功能明确,从而使开发人员对特定功能模块的针对性得到提高,开发效率大大增加。另一方面,也可以大大增强系统后期的可维护性,可扩展性。该系统架构如图4-1所示。

​编辑

图4-1 系统部署图