ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SpringBoot+Vue员工信息管理系统开发实践

2026/9/14 1:59:43 拓冰建站 浏览量
SpringBoot+Vue员工信息管理系统开发实践 1. 项目背景与核心价值去年接手公司HR系统升级项目时我深刻体会到传统Excel管理员工信息的痛点数据分散在多个文件中版本混乱难以追溯部门间信息孤岛严重每月统计报表需要人工汇总数小时。这正是我们开发这套SpringBootVue员工信息管理系统的初衷。现代企业员工管理至少需要解决三个核心问题基础信息的高效录入与实时更新多维度的快速检索与组合查询敏感数据的权限隔离与操作审计我们采用的技术栈组合恰好能完美应对这些需求SpringBoot 2.7 MyBatis Plus构建稳健后端Vue 3 Element Plus实现动态前端MySQL 8.0作为主数据库Redis缓存高频访问数据2. 系统架构设计解析2.1 技术选型决策树选择SpringBoot而非传统SSM框架主要基于内嵌Tomcat避免部署环境差异Starter依赖自动配置省去70%的XML配置Actuator端点提供完善的健康监控前端选用Vue 3而非React的考虑更平滑的学习曲线适合企业内部开发Composition API比Options API更适合复杂业务逻辑与Element Plus的深度集成减少UI开发成本2.2 分层架构示意图[Vue前端] │ └─Axios→[SpringBoot REST API] │ ├─[Service层]←Redis缓存 │ └─[MyBatis Plus]→MySQL关键设计要点前后端完全分离部署通过JWT进行认证API网关统一处理跨域和权限校验采用DTO模式隔离实体与视图模型3. 核心功能实现细节3.1 员工信息CRUD实现数据库表设计示例CREATE TABLE employee ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, employee_no VARCHAR(20) UNIQUE COMMENT 工号, name VARCHAR(50) NOT NULL COMMENT 姓名, dept_id INT COMMENT 部门ID, position VARCHAR(50) COMMENT 职位, entry_date DATE COMMENT 入职日期, id_card VARCHAR(18) COMMENT 身份证号, contact VARCHAR(20) COMMENT 联系方式, status TINYINT DEFAULT 1 COMMENT 状态(1在职 0离职), PRIMARY KEY (id), INDEX idx_dept (dept_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;SpringBoot服务层关键代码RestController RequestMapping(/api/employee) public class EmployeeController { Autowired private EmployeeService employeeService; PostMapping public Result addEmployee(Valid RequestBody EmployeeDTO dto) { return employeeService.addEmployee(dto); } GetMapping(/{id}) public Result getEmployee(PathVariable Long id) { return Result.success(employeeService.getById(id)); } GetMapping(/page) public Result pageList(EmployeeQuery query, RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { PageEmployeeVO pageInfo new Page(page, size); return employeeService.queryPage(pageInfo, query); } }3.2 高级查询功能实现Vue前端组合查询组件template el-form :modelqueryForm inline el-form-item label姓名 el-input v-modelqueryForm.name clearable / /el-form-item el-form-item label部门 el-select v-modelqueryForm.deptId clearable el-option v-fordept in deptList :keydept.id :labeldept.name :valuedept.id / /el-select /el-form-item el-form-item label入职日期 el-date-picker v-modelqueryForm.entryDateRange typedaterange value-formatyyyy-MM-dd / /el-form-item el-button typeprimary clickhandleSearch查询/el-button /el-form /template script setup const queryForm reactive({ name: , deptId: null, entryDateRange: [] }) const handleSearch () { emit(search, { ...queryForm, startDate: queryForm.entryDateRange?.[0], endDate: queryForm.entryDateRange?.[1] }) } /script后端动态SQL构建MyBatis Pluspublic PageEmployeeVO queryPage(PageEmployeeVO page, EmployeeQuery query) { return employeeMapper.selectPage(page, new LambdaQueryWrapperEmployee() .like(StringUtils.isNotBlank(query.getName()), Employee::getName, query.getName()) .eq(query.getDeptId() ! null, Employee::getDeptId, query.getDeptId()) .ge(query.getStartDate() ! null, Employee::getEntryDate, query.getStartDate()) .le(query.getEndDate() ! null, Employee::getEntryDate, query.getEndDate()) .orderByDesc(Employee::getId)); }4. 权限控制方案4.1 基于RBAC的权限模型数据库关系设计user - user_role - role - role_menu - menuSpring Security配置要点Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .antMatchers(/api/employee/export).hasRole(HR) .antMatchers(/api/employee/**).hasAnyRole(HR, MANAGER) .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager())); } }4.2 前端权限控制实现Vue路由守卫示例router.beforeEach((to, from, next) { const hasToken store.getters.token const hasRoles store.getters.roles store.getters.roles.length 0 if (hasToken) { if (to.path /login) { next(/) } else { if (hasRoles) { next() } else { try { const { roles } await store.dispatch(user/getInfo) const accessRoutes await store.dispatch(permission/generateRoutes, roles) router.addRoutes(accessRoutes) next({ ...to, replace: true }) } catch (error) { await store.dispatch(user/resetToken) next(/login?redirect${to.path}) } } } } else { if (whiteList.includes(to.path)) { next() } else { next(/login?redirect${to.path}) } } })5. 典型问题排查实录5.1 跨域问题解决方案开发环境配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }生产环境推荐方案使用Nginx反向代理统一域名配置精确的allowedOrigins而非通配符启用CORS预检请求缓存5.2 大数据量导出优化常规导出方案的问题一次性查询全量数据导致OOM同步导出阻塞主线程Excel工具内存溢出我们的优化方案RestController RequestMapping(/api/employee) public class EmployeeController { GetMapping(/export) public void exportExcel(EmployeeQuery query, HttpServletResponse response) { response.setContentType(application/vnd.ms-excel); response.setHeader(Content-Disposition, attachment;filenameemployees.xlsx); try (ExcelWriter writer ExcelUtil.getWriter()) { // 分批查询写入 int pageSize 1000; int current 1; while (true) { PageEmployee page new Page(current, pageSize); IPageEmployee pageData employeeService.page(page, buildQueryWrapper(query)); if (pageData.getRecords().isEmpty()) { break; } writer.write(pageData.getRecords(), true); current; } writer.flush(response.getOutputStream(), true); } catch (IOException e) { log.error(导出失败, e); } } }6. 部署与监控方案6.1 生产环境部署推荐Docker Compose方案version: 3 services: backend: image: employee-system-api:1.0 ports: - 8080:8080 environment: - SPRING_PROFILES_ACTIVEprod - DB_URLjdbc:mysql://mysql:3306/employee - REDIS_HOSTredis depends_on: - mysql - redis frontend: image: employee-system-web:1.0 ports: - 80:80 depends_on: - backend mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD123456 - MYSQL_DATABASEemployee volumes: - mysql_data:/var/lib/mysql redis: image: redis:6 volumes: - redis_data:/data volumes: mysql_data: redis_data:6.2 系统监控配置SpringBoot Actuator关键端点# application-prod.properties management.endpoints.web.exposure.includehealth,info,metrics,prometheus management.metrics.export.prometheus.enabledtrue management.endpoint.health.show-detailsalwaysGrafana监控看板配置要点JVM内存使用率接口QPS/RT监控数据库连接池状态缓存命中率统计7. 项目演进方向在实际使用过程中我们持续收集到以下改进需求员工自助服务门户请假/报销申请组织架构可视化编辑器与钉钉/企业微信的组织同步基于ELK的日志分析系统技术债解决方案引入Spring Cloud组件实现微服务化用WebSocket实现实时通知采用Apache POI-TL实现复杂Word报表使用EasyExcel替代Hutool Excel工具这套系统经过三个月的迭代开发目前已在公司稳定运行半年管理着800员工信息。最大的收获是认识到好的管理系统应该是透明的——员工感受不到它的存在却能随时获取需要的信息。