1. 项目概述与背景
公寓报修管理系统是现代化物业管理中不可或缺的数字化工具。在传统物业管理模式下,住户通过电话或纸质表单提交报修请求,物业人员手工记录并分配任务,这种方式存在信息传递效率低、进度不透明、历史记录难以追溯等问题。我去年参与开发的这套系统,正是为了解决这些痛点而生。
系统采用前后端分离架构,前端使用Vue.js+ElementUI构建响应式界面,后端基于SpringBoot框架开发RESTful API,数据存储选用MySQL关系型数据库。这种技术组合既保证了系统性能,又便于后期功能扩展。在实际部署中,系统显著提升了某小区物业的工单处理效率,平均响应时间从原来的48小时缩短至12小时以内。
2. 核心功能设计
2.1 多角色权限管理
系统设计了三种核心角色:住户、维修工和物业管理员。权限控制采用RBAC(基于角色的访问控制)模型,通过Spring Security实现:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resident/**").hasRole("RESIDENT")
.antMatchers("/worker/**").hasRole("WORKER")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
关键点:住户只能查看和提交自己的工单,维修工可见分配的任务,管理员拥有全部权限。密码存储采用BCrypt加密算法,避免明文存储风险。
2.2 报修工单全流程管理
工单生命周期包含五个状态:待提交→已提交→已分配→维修中→已完成。状态转换通过状态模式实现,确保业务流程合规:
mermaid复制stateDiagram
[*] --> 待提交
待提交 --> 已提交: 用户提交
已提交 --> 已分配: 管理员分配
已分配 --> 维修中: 维修工接单
维修中 --> 已完成: 维修完成
实际开发中我们遇到状态流转的并发问题,最终通过数据库乐观锁(version字段)解决:
sql复制UPDATE repair_order
SET status = 'ASSIGNED', version = version + 1
WHERE repair_id = ? AND version = ?
3. 数据库详细设计
3.1 核心表结构优化
初始设计的工单表缺少维修类型分类,后期补充了type字段并建立字典表:
sql复制CREATE TABLE repair_type (
type_id INT PRIMARY KEY,
type_name VARCHAR(20) NOT NULL,
estimated_time INT COMMENT '预估维修时长(分钟)'
);
ALTER TABLE repair_order ADD COLUMN type_id INT AFTER resident_id;
经验:字段注释要完整,VARCHAR长度根据实际需求设置(如手机号20字符考虑国际号码)
3.2 索引设计策略
针对高频查询场景建立了复合索引:
- 住户查工单:(resident_id, submit_time)
- 管理员查未分配工单:(status, submit_time)
- 维修工查任务:(worker_id, status)
避免过度索引导致写入性能下降,我们通过EXPLAIN分析执行计划,最终只保留了5个必要索引。
4. 前后端关键技术实现
4.1 文件上传与预览
住户上传报修图片采用分块上传策略,前端使用el-upload组件:
vue复制<el-upload
action="/api/upload"
:multiple="false"
:on-success="handleSuccess"
:before-upload="checkFile">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
后端使用阿里云OSS存储,关键配置:
properties复制# application.properties
aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
aliyun.oss.bucket-name=repair-system
aliyun.oss.expire-time=3600
4.2 实时通知功能
采用WebSocket实现状态变更实时推送,前端建立长连接:
javascript复制const socket = new WebSocket(`wss://${location.host}/ws/notify`);
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if(data.type === 'STATUS_UPDATE') {
this.$notify({
title: '工单状态更新',
message: `工单${data.repairId}已变更为${data.status}`
});
}
};
后端使用Spring的WebSocketHandler处理消息,注意要解决跨域问题和心跳检测。
5. 部署与性能优化
5.1 生产环境部署方案
推荐使用Docker Compose部署,docker-compose.yml示例:
yaml复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root123
volumes:
- ./mysql-data:/var/lib/mysql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
frontend:
build: ./frontend
ports:
- "80:80"
5.2 性能调优经验
- 接口响应慢:启用Spring Boot Actuator监控发现N+1查询问题,通过@EntityGraph优化
- 列表页加载慢:添加Redis缓存,设置合理的过期策略
- 高并发提交:使用Guava RateLimiter做接口限流,防止恶意请求
经过优化,系统在2核4G服务器上可支持500+并发用户正常使用。
6. 常见问题解决方案
6.1 跨域问题处理
开发阶段遇到跨域访问限制,最终方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST")
.allowCredentials(true)
.maxAge(3600);
}
}
生产环境建议配置Nginx反向代理,更安全高效。
6.2 日期时间处理
前后端时间格式统一方案:
- 后端全局配置Jackson
java复制@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder
.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME));
}
- 前端使用day.js处理日期显示
7. 项目扩展方向
现有系统可进一步扩展:
- 微信小程序接入:使用uni-app开发跨端应用
- 智能派单:根据维修工位置、技能自动分配工单
- 物料管理:跟踪维修耗材使用情况
- 数据分析:使用ECharts展示工单处理效率等指标
我在实际开发中发现,增加维修评价功能能显著提升服务质量,建议在二期加入。