1. 项目概述:疫情居家办公系统管理平台
去年帮学弟调试毕业设计时,接触到一个典型的SpringBoot+Vue前后端分离项目。这个疫情居家办公系统管理平台,本质上是通过信息化手段解决远程协作中的流程管理问题。系统采用Java+MySQL技术栈,包含员工健康上报、在线审批、任务派发等核心模块,特别适合作为计算机专业学生的综合实践项目。
从技术实现角度看,这种管理平台类项目能覆盖企业级应用开发的完整链路:前端用Vue处理交互逻辑,后端用SpringBoot构建RESTful API,MySQL负责数据持久化。我在实际部署过程中发现,项目虽然基础但五脏俱全,涉及权限控制、数据可视化、文件上传等实用功能点,对理解现代Web开发架构非常有帮助。
2. 技术架构解析
2.1 前后端分离设计
系统采用典型的前后端分离架构,这种模式在2015年后逐渐成为企业级开发的标准方案。前端Vue.js通过axios与后端通信,后端SpringBoot提供JSON格式的API响应。实测在本地开发时,需要分别启动前端服务(默认8080端口)和后端服务(默认8888端口),这种设计带来的最大优势是前后端可以并行开发。
注意:跨域问题必须通过配置CorsFilter解决,建议在后端添加@CrossOrigin注解,而不是在前端使用代理模式。我在调试时发现,某些浏览器安全策略会导致预检请求失败。
2.2 核心组件选型
后端技术栈:
- SpringBoot 2.3.4.RELEASE(稳定版)
- MyBatis-Plus 3.4.0(简化CRUD操作)
- Hutool 5.7.0(工具类库)
- JWT 3.11.0(认证方案)
前端技术栈:
- Vue 2.6.11(兼容性好)
- Element UI 2.15.1(管理后台经典方案)
- ECharts 4.9.0(数据可视化)
- Axios 0.21.1(HTTP客户端)
数据库:
- MySQL 5.7(必须版本一致)
- 包含12张核心表(用户/部门/公告/审批等)
3. 关键功能实现细节
3.1 健康打卡模块
这是最具疫情特色的功能,采用每日定时提交设计。后端主要代码逻辑:
java复制@PostMapping("/health/report")
public Result reportHealth(@RequestBody HealthReport report) {
// 验证当日是否已提交
LambdaQueryWrapper<HealthReport> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(HealthReport::getUserId, getCurrentUserId())
.eq(HealthReport::getReportDate, LocalDate.now());
if (service.count(wrapper) > 0) {
return Result.error("今日已提交健康报告");
}
report.setUserId(getCurrentUserId());
return service.save(report) ? Result.success() : Result.error();
}
前端对应使用Element UI的表单验证:
vue复制<el-form :model="form" :rules="rules" ref="formRef">
<el-form-item label="体温" prop="temperature">
<el-input-number v-model="form.temperature" :min="35" :max="42" :step="0.1"/>
</el-form-item>
<el-form-item label="是否接触确诊" prop="isContact">
<el-radio-group v-model="form.isContact">
<el-radio :label="false">否</el-radio>
<el-radio :label="true">是</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
3.2 审批流程设计
采用状态机模式实现请假审批:
mermaid复制stateDiagram
[*] --> PENDING
PENDING --> APPROVED: 主管审批
PENDING --> REJECTED: 主管驳回
APPROVED --> FINISHED: 销假完成
实际开发中需要特别注意:
- 审批链路由部门层级决定
- 超过3天的请假需二级审批
- 审批通过后自动同步日历
4. 开发环境搭建指南
4.1 后端配置要点
- 修改application.yml中的数据库连接:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/remote_office?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
- 初始化数据库:
sql复制CREATE DATABASE IF NOT EXISTS remote_office DEFAULT CHARSET utf8mb4;
- 使用Flyway进行数据库版本控制(建议):
xml复制<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
4.2 前端启动注意事项
- 解决Node版本兼容问题:
bash复制# 推荐使用nvm管理版本
nvm install 12.18.3
nvm use 12.18.3
- 安装依赖时常见问题:
bash复制# 如果出现sass-loader报错
npm rebuild node-sass
- 开发环境代理配置(vue.config.js):
javascript复制devServer: {
proxy: {
'/api': {
target: 'http://localhost:8888',
changeOrigin: true
}
}
}
5. 典型问题排查实录
5.1 跨域问题深度解决
虽然@CrossOrigin注解能解决简单请求,但遇到以下情况会失效:
- 自定义请求头
- Content-Type非标准值
- PUT/DELETE等特殊方法
完整解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
5.2 JWT失效异常处理
常见错误场景:
- 令牌过期(需前端跳转登录页)
- 签名不匹配(检查secretKey一致性)
- 非标准令牌(检查Authorization头格式)
建议的全局异常处理:
java复制@RestControllerAdvice
public class JwtExceptionHandler {
@ExceptionHandler(value = ExpiredJwtException.class)
public Result handleExpiredJwt() {
return Result.error(401, "登录已过期");
}
}
6. 项目扩展建议
6.1 功能增强方向
- 集成WebSocket实现实时通知
- 添加OAuth2.0第三方登录
- 开发移动端适配(Vant组件库)
- 接入钉钉/企业微信API
6.2 性能优化方案
- 二级缓存策略:
java复制@Cacheable(value = "dept", key = "#id")
public Dept getById(Long id) {
return getBaseMapper().selectById(id);
}
- 接口响应优化:
java复制@GetMapping("/list")
public Result<List<User>> listUsers() {
long start = System.currentTimeMillis();
List<User> list = service.list();
log.info("查询耗时:{}ms", System.currentTimeMillis()-start);
return Result.success(list);
}
- 前端懒加载方案:
vue复制<template>
<el-table :data="tableData" v-loading="loading">
<!-- 列定义 -->
</el-table>
</template>
<script>
export default {
data() {
return {
loading: false,
tableData: []
}
},
created() {
this.loadData();
},
methods: {
async loadData() {
this.loading = true;
try {
const res = await axios.get('/api/users');
this.tableData = res.data;
} finally {
this.loading = false;
}
}
}
}
</script>
7. 毕设答辩技巧
7.1 演示重点把握
- 核心业务流程演示(健康上报->审批->统计)
- 技术亮点展示(如JWT认证流程)
- 系统安全措施(XSS防护、SQL注入防范)
7.2 常见问题准备
-
为什么选择SpringBoot+Vue组合?
- 标准答案:SpringBoot简化了传统SSM的配置,Vue的组件化开发适合管理后台这类交互复杂的场景
-
如何保证系统安全性?
- 从输入验证、权限控制、数据加密三个维度回答
-
数据库设计遵循哪些范式?
- 至少要说明达到第三范式(3NF)
8. 开发心得记录
在实际调试这个项目时,有几个容易忽略的细节值得注意:
-
MySQL时区问题:必须显式设置serverTimezone=Asia/Shanghai,否则日期字段会出现8小时时差
-
MyBatis-Plus的LambdaQueryWrapper在构建复杂查询时,建议先打印生成的SQL语句:
java复制System.out.println(wrapper.getSqlSegment());
- Element UI表单验证的trigger配置要根据场景选择:
- blur:适合输入框失焦验证
- change:适合下拉框即时反馈
- 前端axios拦截器的正确使用姿势:
javascript复制// 请求拦截器
axios.interceptors.request.use(config => {
config.headers['Authorization'] = localStorage.getItem('token')
return config
})
// 响应拦截器
axios.interceptors.response.use(response => {
return response.data
}, error => {
if (error.response.status === 401) {
router.push('/login')
}
return Promise.reject(error)
})
这个项目虽然基础,但完整实现了企业级应用的核心功能链。建议学习时重点关注三个技术难点:前后端数据交互规范、权限系统的RBAC实现、以及数据库事务管理。我在本地测试时特意模拟了高并发场景下的考勤打卡,发现需要额外添加乐观锁机制防止数据冲突。
