当前位置:首页 > 技术 > 正文内容

SpringBoot校园招聘平台:前后端分离架构设计与核心模块实现

访客 技术 2026年6月1日 1

本文介绍一套采用SpringBoot作为后端服务框架、Vue3配合ElementPlus构建前端界面、MySQL8.0持久化数据的高校人才招聘系统。系统支持学生求职端、企业招聘端与平台管理后台三大业务场景,实现简历投递、职位发布、面试邀约等核心招聘流程的数字化管理。

技术架构选型

后端服务层选用SpringBoot 2.7.x快速搭建RESTful API,整合MyBatis-Plus简化数据访问层编码;前端采用Vue3组合式API配合ElementPlus组件库,通过Axios实现与服务端的异步通信;数据库使用MySQL8.0,利用InnoDB引擎保障事务一致性。

核心实体关系设计

系统围绕用户中心展开,区分求职者(ROLE_SEEKER)与招聘方(ROLE_RECRUITER)两种身份。关键关联包括:用户与简历的一对一映射、企业与职位的一对多关联、简历与职位的多对多投递关系。删除用户时需级联清理其附属数据,包括工作经历、项目经验、教育背景、作品集及期望职位等扩展信息。

企业资质审核模块

企业入驻平台需经过人工审核流程,管理员可对企业认证状态进行变更操作:

@RestController
@RequestMapping("/api/v1/enterprise")
public class EnterpriseAuditController {

    @Autowired
    private EnterpriseService enterpriseService;

    @PostMapping("/audit")
    public ResponseEntity<Result<Boolean>> auditEnterprise(
            @RequestBody @Valid AuditDTO auditDTO) {
        
        if (auditDTO.getEnterpriseId() == null) {
            return ResponseEntity.badRequest()
                .body(Result.fail(ErrorCode.PARAM_INVALID));
        }
        
        Enterprise entity = enterpriseService.getById(auditDTO.getEnterpriseId());
        if (entity == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(Result.fail(ErrorCode.ENTERPRISE_NOT_FOUND));
        }
        
        entity.setAuditStatus(auditDTO.getStatus());
        entity.setAuditRemark(auditDTO.getRemark());
        entity.setAuditTime(LocalDateTime.now());
        
        boolean updated = enterpriseService.updateById(entity);
        return updated ? ResponseEntity.ok(Result.success(true))
                      : ResponseEntity.internalServerError()
                          .body(Result.fail(ErrorCode.OPERATION_FAILED));
    }
}

用户数据级联清理

由于用户关联多张扩展信息表,删除操作需保证事务原子性,避免脏数据残留:

@Service
@Transactional(rollbackFor = Exception.class)
public class UserLifecycleService {

    @Autowired private UserMapper userMapper;
    @Autowired private ResumeMapper resumeMapper;
    @Autowired private ExperienceMapper experienceMapper;
    @Autowired private EducationMapper educationMapper;
    @Autowired private PortfolioMapper portfolioMapper;
    @Autowired private ExpectationMapper expectationMapper;
    @Autowired private EnterpriseMapper enterpriseMapper;
    @Autowired private PositionMapper positionMapper;

    public void terminateUserAccount(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) return;
        
        // 清理求职者附属数据
        resumeMapper.deleteByUserId(userId);
        experienceMapper.deleteByUserId(userId);
        educationMapper.deleteByUserId(userId);
        portfolioMapper.deleteByUserId(userId);
        expectationMapper.deleteByUserId(userId);
        
        // 若为企业账号,需清理企业相关数据
        if (UserType.RECRUITER.equals(user.getUserType())) {
            Enterprise enterprise = enterpriseMapper.selectByUserId(userId);
            if (enterprise != null) {
                // 删除企业下所有职位
                positionMapper.deleteByEnterpriseId(enterprise.getId());
                // 删除收到的所有简历投递
                resumeMapper.deleteByEnterpriseId(enterprise.getId());
                enterpriseMapper.deleteById(enterprise.getId());
            }
        }
        
        userMapper.deleteById(userId);
    }
}

管理员信息维护

后台管理员信息更新采用属性拷贝策略,保护敏感字段不被覆盖:

@PatchMapping("/{adminId}")
public ResponseEntity<Result<Void>> modifyAdmin(
        @PathVariable Long adminId,
        @RequestBody @Valid AdminUpdateDTO dto) {
    
    if (adminId == null || adminId <= 0) {
        return ResponseEntity.badRequest()
            .body(Result.fail(ErrorCode.ID_EMPTY));
    }
    
    Admin existAdmin = adminService.getById(adminId);
    if (existAdmin == null) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body(Result.fail(ErrorCode.ADMIN_NOT_EXIST));
    }
    
    // 仅拷贝允许修改的字段,忽略id、创建时间、密码等敏感属性
    BeanUtils.copyProperties(dto, existAdmin, 
        "id", "createTime", "updateTime", "password", "salt");
    
    existAdmin.setUpdateTime(LocalDateTime.now());
    
    boolean success = adminService.updateById(existAdmin);
    return success ? ResponseEntity.ok(Result.success())
                  : ResponseEntity.internalServerError()
                      .body(Result.fail(ErrorCode.UPDATE_FAILURE));
}

分页数据查询优化

后台列表查询采用MyBatis-Plus分页插件,统一封装响应结构:

@GetMapping("/list")
public ResponseEntity<Map<String, Object>> queryUserPage(
        @RequestParam(defaultValue = "1") Integer current,
        @RequestParam(defaultValue = "10") Integer size) {
    
    Page<User> pageParam = new Page<>(current, size);
    Page<User> resultPage = userService.page(pageParam);
    
    Map<String, Object> response = new HashMap<>(2);
    response.put("records", resultPage.getRecords());
    response.put("total", resultPage.getTotal());
    
    return ResponseEntity.ok(response);
}

环境配置与启动

项目采用Maven多模块结构,启动前需完成以下配置:

  1. 创建MySQL数据库并导入初始化脚本
  2. 修改application-dev.yml中的数据源配置
  3. 安装Node依赖并启动前端服务:npm install && npm run dev
  4. 启动SpringBoot应用,默认服务端口8080

访问入口:前台http://localhost:8080,管理后台http://localhost:8080/admin

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。