ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java+SSM+MySQL+微信小程序设备报修系统实战:工单状态机与避坑指南

Java+SSM+MySQL+微信小程序设备报修系统实战:工单状态机与避坑指南 简介本资源为基于JavaSSMMySQL微信小程序的设备故障报修管理系统完整毕业设计包面向高校计算机相关专业学生及需要设备报修管理方案的开发者可作为高分毕设、课程设计或期末大作业直接使用。包内共1287个文件涵盖Java后端源码、微信小程序前端页面、MySQL数据库脚本、论文文档及配套工具主要类型包括png图片、js脚本、vue组件、java类文件、wxss与wxml小程序样式结构、sql建库脚本等压缩包约22.55MB目录结构清晰前后端代码与数据库文件齐全。系统采用SpringSpringMVCMyBatis架构前端以微信小程序实现移动端报修交互后端负责业务逻辑与数据持久化功能覆盖设备报修、故障处理与数据管理界面美观且操作便捷。项目经过严格调试确保可运行已有253人学习下载。读者可获得完整源码、数据库脚本、论文参考及部署所需工具便于快速理解系统设计思路并完成二次开发或答辩准备。1. 从一份 SSM 小程序报修系统说起设备坏了流程怎么跑通工厂车间里一台空压机突然停机操作工在微信里发条语音给班组长班组长再打电话给设备科设备科翻纸质台账找上次维修记录——这套流程走下来半小时过去了故障原因还没定位。设备故障报修管理系统要解决的就是这个链路让报修人扫码或在小程序里提交工单系统自动带出设备档案、历史维修记录派单给对应维修工维修完成后回填结果并归档。标题里的 Java SSM MySQL 微信小程序就是这套系统最常见的技术组合SSMSpring SpringMVC MyBatis做后端接口和业务逻辑MySQL 存设备、工单、用户、维修记录微信小程序做移动端入口让一线工人不用装 App 就能报修。这套方案适合谁一是做毕业设计的学生SSM 是 Java Web 教学里最经典的框架组合资料多、坑相对可控二是中小制造企业或物业后勤的信息化负责人预算有限、不想上重型 EAM 系统用小程序 自建后端能快速落地三是想练手 Java 全栈的开发者这个项目覆盖了权限、工单状态机、文件上传、消息通知等典型场景。下面按「先跑通环境 → 再拆后端 → 再拆小程序 → 再避坑 → 最后讲进阶」的顺序展开每一步都给可复现的命令和参数。2. 环境先跑通JDK、MySQL 8 与 SSM 依赖的版本咬合2.1 JDK 与 Tomcat 的版本选择SSM 项目对 JDK 版本敏感。常见做法是用 JDK 81.8.0_xxx因为 Spring 4.x/5.x 与 MyBatis 3.4/3.5 在 JDK 8 上最稳JDK 11 以上会遇到javax.xml.bind缺失、CGLIB 代理报错等问题。安装后验证java -version # 期望输出java version 1.8.0_381 或类似 1.8 系列 javac -version如果机器上已有多个 JDK用JAVA_HOME显式指定Windows 下在系统环境变量里把JAVA_HOME指向 JDK 8 目录Path里加%JAVA_HOME%\bin。Tomcat 选 8.5 或 9.0不要用 Tomcat 10因为 Tomcat 10 把javax.servlet换成了jakarta.servletSSM 老项目的 web.xml 和依赖会全线报ClassNotFoundException。2.2 MySQL 8 安装与建库建表MySQL 用 8.0 系列即可安装时记住 root 密码。安装完成后建库CREATE DATABASE repair_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE repair_system; CREATE TABLE device ( id BIGINT PRIMARY KEY AUTO_INCREMENT, device_code VARCHAR(64) NOT NULL UNIQUE COMMENT 设备编号, device_name VARCHAR(128) NOT NULL COMMENT 设备名称, location VARCHAR(255) COMMENT 安装位置, status TINYINT DEFAULT 1 COMMENT 1正常 2故障 3维修中 4报废, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE repair_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE COMMENT 工单号, device_id BIGINT NOT NULL, reporter_id BIGINT NOT NULL COMMENT 报修人, repairer_id BIGINT COMMENT 维修人, fault_desc VARCHAR(500) COMMENT 故障描述, status TINYINT DEFAULT 1 COMMENT 1待派单 2已派单 3维修中 4已完成 5已关闭, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, finish_time DATETIME, INDEX idx_device (device_id), INDEX idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;字符集必须用utf8mb4否则小程序端提交的 emoji 或生僻字会插入失败。repair_order.status是工单状态机的核心字段后面所有业务逻辑都围绕它流转。2.3 SSM 依赖与数据源配置Maven 的pom.xml里锁定版本避免依赖冲突properties spring.version5.3.30/spring.version mybatis.version3.5.13/mybatis.version mysql.connector.version8.0.33/mysql.connector.version /properties数据源用 Druid 或 HikariCP连接串注意 MySQL 8 的时区和 SSL 参数jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/repair_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.password你的密码serverTimezoneAsia/Shanghai不加会报The server time zone value ?D1ú±ê×?ê±?? is unrecognizedallowPublicKeyRetrievaltrue是 MySQL 8 默认caching_sha2_password认证插件下必须的否则连接被拒。MyBatis 的mapper-locations指向classpath:mapper/*.xml实体类包用type-aliases-package扫描减少 XML 里写全限定名。3. 后端接口怎么拆工单状态机与 MyBatis 映射3.1 工单状态流转的 Service 设计工单不是简单的增删改查它有状态机待派单 → 已派单 → 维修中 → 已完成 → 已关闭。每次流转都要校验当前状态是否允许该操作并记录操作日志。Service 层核心方法Service public class RepairOrderServiceImpl implements RepairOrderService { Autowired private RepairOrderMapper orderMapper; // 派单只有待派单状态才能派 Override Transactional(rollbackFor Exception.class) public void assign(Long orderId, Long repairerId) { RepairOrder order orderMapper.selectById(orderId); if (order null) { throw new BizException(工单不存在); } if (order.getStatus() ! 1) { throw new BizException(当前状态不允许派单); } order.setRepairerId(repairerId); order.setStatus(2); orderMapper.updateById(order); } // 完成维修只有维修中状态才能完成 Override Transactional(rollbackFor Exception.class) public void finish(Long orderId, String result) { RepairOrder order orderMapper.selectById(orderId); if (order.getStatus() ! 3) { throw new BizException(工单未在维修中); } order.setStatus(4); order.setFinishTime(new Date()); orderMapper.updateById(order); // 同步更新设备状态为正常 deviceMapper.updateStatus(order.getDeviceId(), 1); } }Transactional保证工单状态和设备状态同时更新避免工单完成了设备还显示故障。状态判断用!而不是equals是因为 status 是TINYINT映射的Integer小数值在缓存范围内可用但为保险起见建议统一用!order.getStatus().equals(1)。3.2 MyBatis 映射与分页查询工单列表要支持按状态、设备、时间筛选用 MyBatis 动态 SQLselect idselectPage resultMapBaseResultMap SELECT o.*, d.device_name, u.real_name AS reporter_name FROM repair_order o LEFT JOIN device d ON o.device_id d.id LEFT JOIN sys_user u ON o.reporter_id u.id where if teststatus ! nullAND o.status #{status}/if if testdeviceId ! nullAND o.device_id #{deviceId}/if if teststartTime ! nullAND o.create_time gt; #{startTime}/if if testendTime ! nullAND o.create_time lt; #{endTime}/if /where ORDER BY o.create_time DESC LIMIT #{offset}, #{limit} /select分页用 PageHelper 插件最省事在 Service 里PageHelper.startPage(pageNum, pageSize)后紧跟查询即可。注意LIMIT的offset要自己算(pageNum - 1) * pageSize。如果不用 PageHelper手写 count 查询时要把where条件复制一份容易漏条件导致总数对不上。3.3 文件上传与小程序图片回传报修时工人会拍故障照片后端要接收 multipart 文件。SpringMVC 配置bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver property namemaxUploadSize value10485760/ property namedefaultEncoding valueUTF-8/ /beanController 里用MultipartFile接收存到本地磁盘或对象存储返回可访问的 URL。小程序端用wx.uploadFile上传注意name参数要和后端RequestParam(file)一致否则报Required MultipartFile parameter file is not present。文件大小限制 10MB 够用超过要提示用户压缩。4. 微信小程序端登录、报修表单与列表渲染4.1 登录与获取手机号小程序登录流程是wx.login拿 code后端用 code 换 openid再查用户表。如果要获取手机号用button open-typegetPhoneNumber回调里拿到encryptedData和iv后端用 session_key 解密。常见做法是后端存 openid 和手机号前端存 token// 小程序端登录 wx.login({ success(res) { if (res.code) { wx.request({ url: https://你的域名/api/login, method: POST, data: { code: res.code }, success(r) { wx.setStorageSync(token, r.data.token); } }); } } });后端换 openid 需要调用微信接口注意appid和secret不要写在前端。token 用 JWT 或简单 UUID 存 Redis 都行SSM 项目里用拦截器校验 token放行登录和静态资源路径。4.2 报修表单与设备选择报修页面要有设备选择、故障描述、图片上传。设备列表从后端拉用picker组件Page({ data: { devices: [], deviceIndex: 0, faultDesc: , images: [] }, onLoad() { wx.request({ url: https://你的域名/api/device/list, header: { token: wx.getStorageSync(token) }, success: (res) { this.setData({ devices: res.data.data }); } }); }, onDeviceChange(e) { this.setData({ deviceIndex: e.detail.value }); }, submit() { const { devices, deviceIndex, faultDesc, images } this.data; wx.request({ url: https://你的域名/api/order/create, method: POST, header: { token: wx.getStorageSync(token) }, data: { deviceId: devices[deviceIndex].id, faultDesc: faultDesc, images: images.join(,) }, success: () wx.showToast({ title: 提交成功 }) }); } });deviceIndex是 picker 的索引提交时要转成devices[deviceIndex].id。图片先wx.chooseImage选再wx.uploadFile逐个上传拿到 URL 后拼成逗号分隔字符串存库。注意小程序请求域名要在微信公众平台配置合法域名本地调试可以勾选「不校验合法域名」。4.3 工单列表与状态标签列表页用wx:for渲染状态用不同颜色标签区分view wx:for{{orders}} wx:keyid classorder-item view classorder-no{{item.orderNo}}/view view classdevice-name{{item.deviceName}}/view view classstatus status-{{item.status}} {{item.status 1 ? 待派单 : item.status 2 ? 已派单 : item.status 3 ? 维修中 : item.status 4 ? 已完成 : 已关闭}} /view /view状态映射建议在后端就转成文字返回前端只负责展示避免逻辑分散。列表分页用onReachBottom加载下一页传pageNum和pageSize给后端。5. 避坑与排查那些让工单卡住的细节5.1 中文乱码从数据库到小程序全线排查现象报修描述里的中文在数据库里显示正常但小程序端显示成????。原因通常是 MySQL 连接串没加characterEncodingutf8或者 Tomcat 的server.xml里 Connector 没配URIEncodingUTF-8。解决连接串加useUnicodetruecharacterEncodingutf8Tomcat Connector 加URIEncodingUTF-8数据库和表都用utf8mb4。三处都对齐后重启。5.2 工单状态更新后列表不刷新现象维修工点了「完成维修」返回列表页还是显示「维修中」。原因是小程序页面onShow里没重新拉数据或者后端更新了但前端缓存了旧数据。解决在onShow里调用列表查询接口不要只在onLoad里拉一次。如果用了全局状态管理更新后要手动触发刷新。5.3 MySQL 8 连接报 Public Key Retrieval 错误现象启动 Tomcat 时报Public Key Retrieval is not allowed。原因是 MySQL 8 默认认证插件是caching_sha2_passwordJDBC 连接需要允许公钥检索。解决连接串加allowPublicKeyRetrievaltrueuseSSLfalse。如果还不行把用户认证插件改成mysql_native_passwordALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 密码;。5.4 小程序请求 403 但浏览器能访问现象浏览器直接访问接口正常小程序里报 403。原因是小程序请求头没带 token或者拦截器把 OPTIONS 预检请求拦了。解决拦截器里放行OPTIONS请求前端wx.request的 header 里带上token。另外检查微信公众平台的合法域名配置开发阶段可以关闭校验。5.5 图片上传后路径 404现象上传成功返回了 URL但小程序里image src显示不出来。原因是后端存的是相对路径或者静态资源映射没配。解决存绝对 URL 或配置 SpringMVC 的mvc:resources映射上传目录确保 URL 能直接访问。本地开发时注意 Tomcat 的docBase配置。6. 进阶用状态机 消息通知把报修闭环做扎实工单系统跑通后真正拉开差距的是「闭环」——报修人提交后知道谁在处理、维修工接单后知道去哪、管理员能看到超时工单。我一般会加两个东西状态机日志表和订阅消息。状态机日志表记录每次流转CREATE TABLE order_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT NOT NULL, from_status TINYINT, to_status TINYINT, operator_id BIGINT, remark VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_order (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;每次assign、finish时插一条日志排查「工单为什么卡住」时直接查这张表比翻应用日志快得多。这是血泪经验没有日志表线上问题只能靠猜。订阅消息用小程序的wx.requestSubscribeMessage在用户提交报修时请求订阅「工单状态变更」模板。后端在状态流转时调用微信的订阅消息接口推送。注意模板 ID 要在公众平台申请推送有频率限制不要每条日志都推只在「派单」和「完成」两个节点推。验证方法造一条工单从提交到完成走一遍查order_log看状态是否连续查小程序是否收到两条订阅消息。如果消息没到先查 access_token 是否过期再查用户是否授权了订阅。最后说个习惯我做完这类系统一定会写一个reset.sql把测试数据清掉、状态重置方便反复演示。毕业设计答辩前跑一遍比手动改数据库靠谱。希望帮到你。本文还有配套的精品资源点击获取
返回列表