1. 项目背景与核心价值
宿舍卫生管理一直是高校后勤工作的痛点。传统纸质记录方式存在数据易丢失、评分标准不透明、奖惩执行滞后等问题。我在参与某高校智慧校园建设时,发现宿管员平均每天要花费2小时处理卫生评分表格,而学生经常因不清楚扣分原因产生投诉。这套基于SpringBoot+Vue的系统正是为解决这些痛点而设计。
系统通过数字化流程实现三大核心价值:
- 管理效率提升:宿管员检查评分时间缩短60%,自动生成奖惩记录
- 过程透明化:学生可实时查看评分明细及扣分原因照片
- 数据驱动决策:管理员通过可视化报表识别卫生问题高发区域
关键设计原则:采用RESTful API实现前后端解耦,便于后续扩展移动端应用。JWT令牌确保接口安全,同时避免频繁的会话状态维护。
2. 系统架构设计
2.1 技术栈选型分析
后端技术组合:
- SpringBoot 2.7.x:快速构建微服务架构,内置Tomcat简化部署
- MyBatis-Plus 3.5.x:增强的ORM框架,减少90%的常规SQL编写
- Redis 6.x:缓存高频访问的宿舍评分规则和近期检查记录
- JWT:无状态认证方案,适应多终端访问场景
前端技术组合:
- Vue 3.x:组合式API提升代码复用率
- Element Plus:表单和表格组件加速管理后台开发
- ECharts 5.x:直观展示宿舍评分趋势对比
- Axios:封装请求拦截器自动处理JWT刷新
java复制// 典型Controller示例
@RestController
@RequestMapping("/api/score")
public class ScoreController {
@Autowired
private ScoreService scoreService;
@PostMapping
public Result addScore(@RequestBody ScoreDTO dto) {
return scoreService.saveScore(dto);
}
@GetMapping("/statistics")
public Result getDormStats(@RequestParam String building) {
return scoreService.getBuildingStats(building);
}
}
2.2 数据库设计要点
核心表结构设计遵循三大范式,同时针对高频查询做优化:
-
用户体系表:
sys_user:基础用户信息sys_role:三种角色定义sys_user_role:用户角色关联
-
业务核心表:
dorm_info:宿舍楼/房间基础数据task_assign:卫生任务分配记录check_record:检查评分明细(含照片URL字段)reward_punish:自动生成的奖惩流水
特别注意:在
check_record表中设置appeal_status字段记录申诉状态,包含枚举值(0-未申诉 1-申诉中 2-已处理)
3. 核心功能实现细节
3.1 权限控制系统
采用RBAC模型实现三级权限控制:
- 接口级别:通过Spring Security的
@PreAuthorize注解控制
java复制@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/user")
public Result addUser(@Valid @RequestBody UserDTO dto) {
// 管理员专属接口
}
- 数据权限:通过AOP实现宿舍楼数据过滤
java复制@Around("execution(* com..service.*.*(..))")
public Object dataPermissionCheck(ProceedingJoinPoint pjp) {
// 自动注入当前用户可管理的宿舍楼条件
}
- 前端路由:根据用户角色动态生成Vue路由表
javascript复制// 路由守卫示例
router.beforeEach((to, from, next) => {
if (to.meta.roles && !store.getters.roles.some(role => to.meta.roles.includes(role))) {
return next('/403')
}
next()
})
3.2 卫生检查业务流程
完整业务流程包含六个关键环节:
- 任务分配:宿管员通过拖拽日历界面分配任务
- 移动端检查:支持手机拍照上传现场情况
- 智能评分:根据预设规则自动计算基础分
- 人工调整:宿管员可对自动评分进行±10分微调
- 结果通知:通过WebSocket实时推送评分结果
- 申诉处理:学生提交申诉后触发工作流审批
mermaid复制graph TD
A[任务分配] --> B[移动检查]
B --> C[自动评分]
C --> D[人工调整]
D --> E[结果通知]
E --> F{是否有申诉}
F -->|是| G[申诉处理]
F -->|否| H[归档记录]
4. 关键技术难题解决方案
4.1 评分规则引擎设计
采用策略模式实现可配置的评分规则:
java复制public interface ScoreRule {
int calculate(CheckRecord record);
}
@Service
public class BasicCleanRule implements ScoreRule {
@Override
public int calculate(CheckRecord record) {
// 基础清洁度评分逻辑
}
}
@Service
public class DeductionRule implements ScoreRule {
@Override
public int calculate(CheckRecord record) {
// 扣分项处理逻辑
}
}
通过RuleEngine上下文类组合多个规则:
java复制public class RuleEngine {
private List<ScoreRule> rules;
public int execute(CheckRecord record) {
return rules.stream()
.mapToInt(rule -> rule.calculate(record))
.sum();
}
}
4.2 实时通知系统
基于Spring Boot的事件机制实现解耦的通知系统:
- 定义领域事件
java复制public class ScorePublishedEvent {
private Long recordId;
private Long studentId;
// 其他必要字段
}
- 事件发布处理器
java复制@TransactionalEventListener
public void handleScoreEvent(ScorePublishedEvent event) {
// 1. 站内信通知
messageService.send(event.getStudentId(), "您有新评分");
// 2. WebSocket推送
wsTemplate.convertAndSend(
"/topic/score/" + event.getStudentId(),
new ScoreNoticeDTO(...)
);
// 3. 触发奖惩规则检查
rewardService.checkRules(event.getRecordId());
}
5. 部署与性能优化
5.1 生产环境部署方案
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:6-alpine
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
5.2 性能优化实践
-
缓存策略:
- 使用Redis缓存高频访问的宿舍基本信息
- 对历史评分数据采用多级缓存策略
-
SQL优化:
sql复制/* 反例 - 全表扫描 */ SELECT * FROM check_record WHERE student_id = 1001; /* 正例 - 联合索引优化 */ CREATE INDEX idx_student_date ON check_record(student_id, check_date); SELECT id, score FROM check_record WHERE student_id = 1001 ORDER BY check_date DESC LIMIT 10; -
前端懒加载:
javascript复制// 按需加载评分记录 const loadRecords = async (page) => { return await axios.get(`/api/records?page=${page}&size=10`); }
6. 典型问题排查实录
6.1 照片上传失败问题
现象:移动端上传检查照片时报413错误
排查过程:
- 检查Nginx配置发现默认限制1MB
- 前端未做图片压缩处理
- 后端未校验文件类型
解决方案:
- Nginx配置调整:
nginx复制client_max_body_size 10M; - 前端添加图片压缩:
javascript复制const compressImage = async (file) => { return await imageCompression(file, { maxSizeMB: 1, maxWidthOrHeight: 1024 }); } - 后端添加文件校验:
java复制if (!Arrays.asList("image/jpeg", "image/png").contains(file.getContentType())) { throw new BusinessException("仅支持JPEG/PNG格式"); }
6.2 并发评分冲突问题
现象:多人同时给同一宿舍评分时数据覆盖
解决方案:
- 数据库添加乐观锁:
java复制@Version private Integer version; - 业务层加分布式锁:
java复制public Result saveScore(ScoreDTO dto) { String lockKey = "score:" + dto.getDormId(); try { if (redisLock.tryLock(lockKey, 10, TimeUnit.SECONDS)) { // 核心业务逻辑 } } finally { redisLock.unlock(lockKey); } }
7. 扩展与演进方向
-
智能分析扩展:
- 使用Python构建卫生预测模型
- 通过gRPC与Java服务通信
-
物联网集成:
plantuml复制@startuml participant "传感器设备" as device participant "IoT网关" as gateway participant "本系统" as system device -> gateway : 温湿度数据 gateway -> system : HTTP推送 system -> system : 触发异常警报 @enduml -
微服务改造:
- 将奖惩规则引擎拆分为独立服务
- 采用Spring Cloud Alibaba实现服务治理
在实际部署某高校版本时,我们通过添加"卫生红旗排行榜"功能,使优秀宿舍参与率提升了45%。建议根据具体需求灵活调整奖惩机制,比如将卫生评分与热水供应时长挂钩,这种正向激励效果往往比单纯惩罚更好。