毕业设计实战:基于Spring Boot的公寓报修管理系统毕设全流程指南✨

96 阅读11分钟

毕业设计实战:基于Spring Boot的公寓报修管理系统毕设全流程指南✨

去年做公寓报修管理系统毕设时,我在维修工单状态流转和分配逻辑上卡了整整3天——一开始没处理"维修工重复分配"问题,同一维修单能被分配给多个维修工,导师演示时直接发现了这个重大业务漏洞😫 经过反复修改优化,终于总结出了这套公寓报修管理系统毕设实战经验!

一、需求分析:抓住报修管理核心业务

刚开始我想做一个"万能物业系统",包含了收费管理、安防监控、投诉建议等模块,结果导师说"重点不突出,核心报修流程不清晰"。后来明白,公寓报修系统要围绕报修-分配-维修-评价这个核心业务链展开。

1. 核心用户角色与功能

系统主要面向三类用户,功能定位要精准:

  • 管理员端(物业管理核心):

    • 住户管理:审核住户信息、分配房间、管理住户档案
    • 维修工管理:管理维修工信息、设置维修分类、审核维修工资质
    • 报修审核:审核住户提交的报修申请、分配维修任务
    • 数据统计:维修数据统计、工单处理分析、绩效考核
  • 维修工端(维修执行核心):

    • 工单接收:查看分配的维修任务、接收或拒绝工单
    • 维修执行:记录维修过程、上传维修结果、填写维修费用
    • 请假管理:提交请假申请、查看请假状态
    • 改派申请:申请工单改派、说明改派原因
  • 住户端(服务使用核心):

    • 在线报修:提交报修申请、上传故障图片、描述详细问题
    • 进度查询:查看报修处理状态、了解维修进度
    • 服务评价:对完成的维修服务进行评价反馈
    • 个人中心:管理个人信息、查看报修历史

2. 需求分析实战技巧

  • 实地调研很重要:我走访了几个小区物业,发现他们最需要"维修工状态管理"功能,于是重点设计了维修工状态跟踪
  • 绘制业务流程图:用DrawIO画出"住户报修→管理员审核→分配维修工→维修完成→住户评价"的完整流程,答辩时清晰展示业务逻辑
  • 明确业务规则:如"紧急报修优先处理""维修工请假期间不分配新工单""已完成工单才能评价"等约束条件

3. 可行性分析要点

  • 技术可行性:Spring Boot+MySQL技术成熟,开发效率高
  • 经济可行性:全部使用开源工具,零开发成本
  • 操作可行性:界面设计参考主流报修平台,用户上手快

二、技术选型:现代化开发方案

曾经尝试用传统的SSH框架,结果配置太复杂,最终选择Spring Boot,开发效率大大提升!

1. 技术栈选择理由

技术组件选择理由避坑提醒
Spring Boot 2.7自动配置,快速启动不要用3.x,兼容性问题多
MySQL 8.0事务支持完善,适合工单系统记得配置事务隔离级别
MyBatis Plus简化CRUD操作,提高效率注意代码生成器的配置
Redis缓存热点数据,提升性能合理设置缓存过期时间
JWT无状态登录,适合分布式注意token过期时间设置

2. 开发环境搭建

# application.yml 配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/repair_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  redis:
    host: localhost
    port: 6379
    database: 0
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

三、数据库设计:报修业务数据建模

最初设计时把报修单和维修记录放在同一张表,导致数据冗余严重。重新设计后按业务状态分表,系统性能大幅提升。

1. 核心数据表设计

维修申请表(weixiushenqing)

CREATE TABLE `weixiushenqing` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `weixiubianhao` varchar(100) NOT NULL COMMENT '维修编号',
  `wupinmingcheng` varchar(200) NOT NULL COMMENT '物品名称',
  `weixiufenlei` varchar(100) NOT NULL COMMENT '维修分类',
  `shangchuantupian` varchar(500) DEFAULT NULL COMMENT '上传图片',
  `weixiuneirong` text NOT NULL COMMENT '维修内容',
  `shifouyouxian` varchar(10) DEFAULT '否' COMMENT '是否优先',
  `yaoqiubeizhu` text COMMENT '要求备注',
  `fangjianhao` varchar(50) NOT NULL COMMENT '房间号',
  `fangjianleixing` varchar(50) DEFAULT NULL COMMENT '房间类型',
  `fangjianmingcheng` varchar(100) DEFAULT NULL COMMENT '房间名称',
  `fangjianweizhi` varchar(200) DEFAULT NULL COMMENT '房间位置',
  `zhuhuzhanghao` varchar(100) NOT NULL COMMENT '住户账号',
  `zhuhuxingming` varchar(100) NOT NULL COMMENT '住户姓名',
  `shoujihaoma` varchar(20) NOT NULL COMMENT '手机号码',
  `shenqing_status` int(11) DEFAULT '1' COMMENT '申请状态:1待审核/2已分配/3维修中/4已完成/5已关闭',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_weixiubianhao` (`weixiubianhao`),
  KEY `idx_zhuhu` (`zhuhuzhanghao`),
  KEY `idx_status` (`shenqing_status`),
  KEY `idx_youxian` (`shifouyouxian`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修申请表';

维修分配表(weixiufenpei)

CREATE TABLE `weixiufenpei` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `weixiubianhao` varchar(100) NOT NULL COMMENT '维修编号',
  `weixiuzhanghao` varchar(100) NOT NULL COMMENT '维修账号',
  `weixiuxingming` varchar(100) NOT NULL COMMENT '维修姓名',
  `fenpei_status` int(11) DEFAULT '1' COMMENT '分配状态:1待接收/2已接收/3已拒绝/4已完成',
  `jieshou_time` datetime DEFAULT NULL COMMENT '接收时间',
  `jujue_reason` text COMMENT '拒绝原因',
  `fenpei_time` datetime DEFAULT NULL COMMENT '分配时间',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_weixiubianhao` (`weixiubianhao`),
  KEY `idx_weixiuzhanghao` (`weixiuzhanghao`),
  KEY `idx_fenpei_status` (`fenpei_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修分配表';

维修记录表(weixiujilu)

CREATE TABLE `weixiujilu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `weixiubianhao` varchar(100) NOT NULL COMMENT '维修编号',
  `weixiuzhanghao` varchar(100) NOT NULL COMMENT '维修账号',
  `weixiuxingming` varchar(100) NOT NULL COMMENT '维修姓名',
  `weixiushijian` datetime NOT NULL COMMENT '维修时间',
  `weixiufeiyong` decimal(10,2) DEFAULT '0.00' COMMENT '维修费用',
  `weixiujieguo` text NOT NULL COMMENT '维修结果',
  `xiulitupian` varchar(500) DEFAULT NULL COMMENT '修理图片',
  `wancheng_status` int(11) DEFAULT '1' COMMENT '完成状态:1待确认/2已完成/3需返修',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_weixiubianhao` (`weixiubianhao`),
  KEY `idx_weixiushijian` (`weixiushijian`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='维修记录表';

2. 表关系设计要点

  • 状态字段设计:申请状态(待审核/已分配/维修中/已完成)、分配状态(待接收/已接收/已拒绝)、完成状态(待确认/已完成/需返修)
  • 唯一约束:维修编号唯一,防止重复
  • 级联更新:维修分配时自动更新申请状态

四、核心功能实现与代码详解

1. 报修申请模块(住户端核心功能)

Service层实现:

@Service
public class WeixiushenqingServiceImpl implements WeixiushenqingService {
    
    @Autowired
    private WeixiushenqingMapper weixiushenqingMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional
    public String submitWeixiu(WeixiushenqingEntity weixiu) {
        // 1. 生成唯一维修编号
        String weixiubianhao = "WX" + System.currentTimeMillis() + RandomUtil.randomNumbers(4);
        weixiu.setWeixiubianhao(weixiubianhao);
        
        // 2. 设置初始状态
        weixiu.setShenqingStatus(1); // 待审核
        weixiu.setShifouyouxian("否"); // 默认非优先
        
        // 3. 检查紧急程度
        if (isEmergencyRepair(weixiu.getWeixiuneirong())) {
            weixiu.setShifouyouxian("是");
        }
        
        weixiushenqingMapper.insert(weixiu);
        
        // 4. 发送通知(可以集成短信、邮件等)
        sendNewRepairNotification(weixiu);
        
        return weixiubianhao;
    }
    
    private boolean isEmergencyRepair(String content) {
        // 判断是否为紧急报修的简单逻辑
        String[] emergencyKeywords = {"漏水", "漏电", "火灾", "燃气", "电梯故障"};
        for (String keyword : emergencyKeywords) {
            if (content.contains(keyword)) {
                return true;
            }
        }
        return false;
    }
    
    private void sendNewRepairNotification(WeixiushenqingEntity weixiu) {
        // 实现通知发送逻辑
        // 可以是系统消息、短信、邮件等
        System.out.println("新报修通知:住户" + weixiu.getZhuhuxingming() + 
                          "提交了" + weixiu.getWeixiufenlei() + "报修");
    }
}

Controller层:

@RestController
@RequestMapping("/api/weixiu")
public class WeixiushenqingController {
    
    @Autowired
    private WeixiushenqingService weixiushenqingService;

    @PostMapping("/submit")
    public Result submitWeixiu(@RequestBody WeixiushenqingEntity weixiu, 
                              HttpServletRequest request) {
        try {
            // 获取当前登录住户
            ZhuhuEntity zhuhu = (ZhuhuEntity) request.getSession().getAttribute("zhuhu");
            weixiu.setZhuhuzhanghao(zhuhu.getZhuhuzhanghao());
            weixiu.setZhuhuxingming(zhuhu.getZhuhuxingming());
            weixiu.setShoujihaoma(zhuhu.getShoujihaoma());
            
            String weixiubianhao = weixiushenqingService.submitWeixiu(weixiu);
            return Result.ok("报修提交成功").put("weixiubianhao", weixiubianhao);
        } catch (Exception e) {
            return Result.error("报修提交失败:" + e.getMessage());
        }
    }

    @GetMapping("/list")
    public Result getWeixiuList(@RequestParam Map<String, Object> params,
                               HttpServletRequest request) {
        try {
            ZhuhuEntity zhuhu = (ZhuhuEntity) request.getSession().getAttribute("zhuhu");
            params.put("zhuhuzhanghao", zhuhu.getZhuhuzhanghao());
            
            PageUtils page = weixiushenqingService.queryPage(params);
            return Result.ok().put("data", page);
        } catch (Exception e) {
            return Result.error("查询失败:" + e.getMessage());
        }
    }
}

2. 维修分配模块(管理员端核心功能)

Service层实现:

@Service
public class WeixiufenpeiServiceImpl implements WeixiufenpeiService {
    
    @Autowired
    private WeixiufenpeiMapper weixiufenpeiMapper;
    
    @Autowired
    private WeixiushenqingMapper weixiushenqingMapper;
    
    @Autowired
    private WeixiurenyuanMapper weixiurenyuanMapper;

    @Override
    @Transactional
    public void fenpeiWeixiu(WeixiufenpeiEntity fenpei) {
        // 1. 检查维修工状态
        WeixiurenyuanEntity weixiuyuan = weixiurenyuanMapper.selectById(fenpei.getWeixiuzhanghao());
        if (!"正常".equals(weixiuyuan.getZhuangtai())) {
            throw new RuntimeException("该维修工当前状态不可用");
        }
        
        // 2. 检查维修工当前工单数量
        Integer currentOrders = weixiufenpeiMapper.selectCount(
            new LambdaQueryWrapper<WeixiufenpeiEntity>()
                .eq(WeixiufenpeiEntity::getWeixiuzhanghao, fenpei.getWeixiuzhanghao())
                .in(WeixiufenpeiEntity::getFenpeiStatus, Arrays.asList(1, 2)) // 待接收和已接收
        );
        if (currentOrders >= 5) {
            throw new RuntimeException("该维修工当前工单已满");
        }
        
        // 3. 创建分配记录
        fenpei.setFenpeiStatus(1); // 待接收
        fenpei.setFenpeiTime(new Date());
        weixiufenpeiMapper.insert(fenpei);
        
        // 4. 更新报修申请状态
        WeixiushenqingEntity weixiu = weixiushenqingMapper.selectOne(
            new LambdaQueryWrapper<WeixiushenqingEntity>()
                .eq(WeixiushenqingEntity::getWeixiubianhao, fenpei.getWeixiubianhao())
        );
        weixiu.setShenqingStatus(2); // 已分配
        weixiushenqingMapper.updateById(weixiu);
        
        // 5. 发送通知给维修工
        sendFenpeiNotification(fenpei, weixiuyuan);
    }

    @Override
    @Transactional
    public void jieshouWeixiu(String weixiubianhao, String weixiuzhanghao) {
        WeixiufenpeiEntity fenpei = weixiufenpeiMapper.selectOne(
            new LambdaQueryWrapper<WeixiufenpeiEntity>()
                .eq(WeixiufenpeiEntity::getWeixiubianhao, weixiubianhao)
                .eq(WeixiufenpeiEntity::getWeixiuzhanghao, weixiuzhanghao)
        );
        
        if (fenpei == null) {
            throw new RuntimeException("分配记录不存在");
        }
        
        fenpei.setFenpeiStatus(2); // 已接收
        fenpei.setJieshouTime(new Date());
        weixiufenpeiMapper.updateById(fenpei);
        
        // 更新报修申请状态
        WeixiushenqingEntity weixiu = weixiushenqingMapper.selectOne(
            new LambdaQueryWrapper<WeixiushenqingEntity>()
                .eq(WeixiushenqingEntity::getWeixiubianhao, weixiubianhao)
        );
        weixiu.setShenqingStatus(3); // 维修中
        weixiushenqingMapper.updateById(weixiu);
    }
}

3. 维修评价模块(住户端功能)

Service层实现:

@Service
public class WeixiupingjiaServiceImpl implements WeixiupingjiaService {
    
    @Autowired
    private WeixiupingjiaMapper weixiupingjiaMapper;
    
    @Autowired
    private WeixiushenqingMapper weixiushenqingMapper;

    @Override
    @Transactional
    public void submitPingjia(WeixiupingjiaEntity pingjia) {
        // 1. 检查维修是否已完成
        WeixiushenqingEntity weixiu = weixiushenqingMapper.selectOne(
            new LambdaQueryWrapper<WeixiushenqingEntity>()
                .eq(WeixiushenqingEntity::getWeixiubianhao, pingjia.getWeixiubianhao())
        );
        
        if (weixiu.getShenqingStatus() != 4) {
            throw new RuntimeException("只有已完成的维修才能评价");
        }
        
        // 2. 检查是否已评价
        Integer existCount = weixiupingjiaMapper.selectCount(
            new LambdaQueryWrapper<WeixiupingjiaEntity>()
                .eq(WeixiupingjiaEntity::getWeixiubianhao, pingjia.getWeixiubianhao())
        );
        if (existCount > 0) {
            throw new RuntimeException("该维修已评价,不可重复评价");
        }
        
        // 3. 保存评价
        pingjia.setPingjiashijian(new Date());
        weixiupingjiaMapper.insert(pingjia);
        
        // 4. 更新维修申请状态为已关闭
        weixiu.setShenqingStatus(5); // 已关闭
        weixiushenqingMapper.updateById(weixiu);
    }
}

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

五、系统测试:确保报修业务流程可靠

曾经以为功能实现就完成了,结果测试时发现维修工可以重复接收同一工单,紧急加了状态校验。

1. 功能测试用例

报修流程测试:

测试场景操作步骤预期结果
紧急报修住户提交包含紧急关键词的报修自动标记为优先处理
正常报修住户提交普通报修申请状态为待审核,非优先
重复报修住户重复提交相同问题报修提示"相似问题已提交"

维修分配测试:

测试场景操作步骤预期结果
维修工状态异常分配工单给状态异常的维修工提示"该维修工当前状态不可用"
工单已满分配工单给工单已满的维修工提示"该维修工当前工单已满"
正常分配分配工单给可用维修工分配成功,状态更新

2. 业务规则测试

  • 状态一致性:维修分配、接收、完成时同步更新相关状态
  • 权限控制:维修工只能操作分配给自己的工单
  • 防重复操作:防止重复评价、重复接收等操作
  • 紧急处理:紧急报修自动优先处理

六、部署与演示准备

1. 数据库初始化脚本

-- 插入测试数据
INSERT INTO `zhuhu` VALUES 
(1, 'zhuhu001', '123456', '张三', '/images/user1.jpg', '男', '13800138000', '110101199001011234', 'zhangsan@qq.com', NOW());

INSERT INTO `weixiurenyuan` VALUES 
(1, 'wx001', '123456', '李维修', '/images/repair1.jpg', '男', '13800138001', '110101199001011235', '水电维修', '正常', NOW());

INSERT INTO `fangjian` VALUES 
(1, 'A101', '101房间', '公寓', 'A栋1楼101室', 'zhuhu001', '张三', '13800138000', '110101199001011234', NOW());

2. 演示流程设计

按照真实业务流程演示:

  1. 住户登录→提交报修申请→上传故障图片
  2. 管理员登录→审核报修→分配维修工
  3. 维修工登录→接收工单→完成维修→填写记录
  4. 住户登录→确认维修→评价服务

3. 答辩重点准备

  • 业务逻辑亮点:状态流转管理、紧急报修处理、防重复分配
  • 技术实现亮点:事务管理、状态同步、权限控制
  • 系统特色:完整的报修处理闭环、多角色协同工作

结语

基于Spring Boot的公寓报修管理系统毕设成功的关键在于:抓住报修处理核心业务,处理好状态流转,保证数据一致性。这套系统虽然业务逻辑相对复杂,但一旦掌握,无论是完成度还是实用性都能得到导师认可。

记住:状态流转管理、权限控制、紧急处理是三大得分点!需要完整源码、数据库脚本、部署文档的同学可以在评论区留言。

点赞收藏这篇,下次找流程不迷路~祝宝子们毕设顺利,轻松毕业!😘