简介面向电梯运维与监管场景的微信小程序三端源码包适合具备小程序基础或Java后端经验的开发者学习完整项目落地。总体压缩包共2436个文件、182.14MB前端为小程序页面wxml/wxss/js与后台管理界面html/css/js后端为Java工程java/class/war另有大量json/xml配置、png/gif素材及mp4演示视频。包含956个js脚本和507个html页面覆盖界面渲染、交互逻辑与后台展示104个java与103个class对应后端业务处理。包内按管理界面代码、后端代码、微信小程序代码、演示视频四个目录清晰组织并含数据库相关文件与3个war运行包部署门槛低录屏覆盖后台与手机端核心操作。已有136人学习浏览可借助ElevatorController、MaintainenceController、TestingController、InspectionController等类快速定位电梯档案、维保、检验、检测与消息管理等业务模块也适合课程设计使用、毕业选题或监管平台二次开发借鉴。1. 电梯智慧监管系统为什么说它的核心价值不在“监控”而在“闭环”做电梯监管的老问题从来不是看不到电梯而是电梯从故障发生到维保恢复的整条链路处于黑匣子状态值班员接到电话记一张纸条维保工到了现场拍一张照片台账和真实情况对不上。这个基于微信小程序开发的电梯智慧监管系统解决的正是“电梯档案、运行状态、故障工单、维保计划”四件事的数据闭环源码、数据库初始化脚本和演示视频都已打包能直接跑起来。它适合两类人一类是手里有真实电梯台账、想用轻量工具替代纸质记录的物业或维保从业者另一类是拿它做课程设计或毕设的学生可以把业务建模、状态流转、小程序与后端的交互链路完整过一遍。2. 架构拆解小程序、后端与数据库之间到底怎么分工2.1 三端职责与一次完整的电梯故障上报数据流整套系统最常见的做法是拆成三端微信小程序负责展示和录入后端服务负责业务规则与接口MySQL负责持久化。我一般不把业务逻辑写进小程序原因很直接——小程序发布要过审核每次改规则都要重新提审太痛苦而把状态判断、工单流转这类逻辑放在后端改完重启服务就生效。一次完整的故障上报数据流大致是这样小程序端用户点击“故障上报”按钮把电梯编号和故障描述通过wx.request发送到后端接口后端先校验参数、再更新电梯状态为“故障”同时生成一条故障工单并写入数据库小程序端通过轮询接口拿到最新状态页面上的电梯卡片从绿色变成红色。这个链路里后端是唯一写数据库的角色小程序只做“读展示、写提交”避免多端并发写导致数据错乱。2.2 小程序端的技术选型与页面结构安排小程序端我通常用原生框架不引入第三方UI库。原因不是不能用而是这类监管系统的页面数量少总共就首页状态看板、电梯台账、故障工单、维保计划和我的五个Tab页面原生写法完全够用而且更容易让新人看懂代码结构。每个页面拆成三件套wxml负责结构、wxss负责样式、js负责数据和事件。页面之间的跳转和传参我习惯用URL参数而不是全局变量。比如从首页点进某部电梯的详情页跳转路径带上电梯编号详情页通过onLoad里接收的options参数请求详情接口。这样页面刷新后数据不会丢也方便后面做分享和打印工单。2.3 后端接口风格与数据库部署的落地形态接口风格我一般设计成RESTful返回统一JSON结构。前端统一处理code、message、data三个字段成功时code是0失败时返回错误码和提示文案。这样小程序端只需要封装一个request工具函数统一处理token失效、网络超时、错误弹窗不用每个页面各写一套错误处理。数据库部署上低成本方案是后端和MySQL都跑在同一台服务器或本地开发机上小程序用开发者工具的“不校验合法域名”选项联调。线上部署时再把接口换成HTTPS域名并在小程序后台配置request合法域名。常见部署形态有三种按项目阶段选部署场景后端与数据库位置适合阶段纯本地开发本地电脑跑后端和MySQL小程序工具关闭域名校验开发和自测内网演示一台Windows/Linux机器装MySQL和Node.js后端手机连同一WiFi项目验收和演示公网部署云服务器上跑后端MySQL走内网或公网地址域名配置HTTPS正式上线我遇到过很多人卡在“代码明明对真机预览却请求失败”基本都是域名校验问题在作怪。这一步配置好再往后推进度才顺利。3. 数据库设计电梯监管系统的表结构、字段参数与状态机3.1 四张核心业务表的建表语句与关系电梯监管系统的数据模型不需要设计得太花哨核心就是四张表电梯档案表、运行状态表、故障工单表、维保计划表。档案表存静态信息状态表存实时状态工单表和维保表存业务流程记录这四张表通过电梯编号关联起来。下面给出初始化脚本的骨架字段注释直接写在DDL里-- 电梯档案表每部电梯一条记录 CREATE TABLE elevator ( id INT PRIMARY KEY AUTO_INCREMENT, elevator_no VARCHAR(32) NOT NULL UNIQUE COMMENT 电梯编号全局唯一, building_name VARCHAR(64) COMMENT 所在楼栋, address VARCHAR(128) COMMENT 详细地址, brand VARCHAR(32) COMMENT 电梯品牌, install_date DATE COMMENT 安装日期, next_inspect_date DATE COMMENT 下次年检日期, status TINYINT DEFAULT 1 COMMENT 1正常 2故障 3维保中, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 运行状态表记录电梯最近一次状态快照 CREATE TABLE elevator_status ( id INT PRIMARY KEY AUTO_INCREMENT, elevator_no VARCHAR(32) NOT NULL, status TINYINT DEFAULT 1, current_floor INT DEFAULT 1, direction TINYINT DEFAULT 0 COMMENT 0停止 1上行 2下行, update_time DATETIME, KEY idx_elevator_no (elevator_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 故障工单表每次故障上报生成一条工单 CREATE TABLE fault_order ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE, elevator_no VARCHAR(32) NOT NULL, fault_type VARCHAR(32) COMMENT 故障类型困人/异响/停电/门故障等, reporter VARCHAR(32) COMMENT 上报人姓名, reporter_phone VARCHAR(20), description VARCHAR(255), status TINYINT DEFAULT 1 COMMENT 1待处理 2处理中 3已完成 4已关闭, handler VARCHAR(32) COMMENT 处理人, handle_time DATETIME, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这段建表脚本有四个细节值得注意。电梯编号字段必须加UNIQUE约束因为后面三张表都依赖它做关联重复编号会直接导致数据错乱。状态字段用TINYINT而不是VARCHAR既节省存储又方便后端代码里用switch做状态映射避免到处写魔法字符串。update_time字段是给状态轮询用的小程序端轮询时只捞“距离上次更新超过N秒”的记录这样可以区分“电梯真的停了”和“数据根本没更新”。字符集统一用utf8mb4因为工单描述里会出现电梯品牌、地址等中文和特殊符号utf8mb4才能完整存下来。3.2 字段类型选择、长度设计与索引经验字段类型我踩过不少坑印象最深的是手机号用VARCHAR(20)而不是INT。很多人图省事用INT存手机号结果手机号前导0被吞掉后端的长度校验也跟着翻车。手机号、电梯编号这类“看起来像数字但不是数字”的字段一律用VARCHAR。描述类字段像故障描述、处理意见用VARCHAR(255)是最低标准如果业务上要存更长的维保记录直接改成TEXT不要卡在255上反复截断。索引设计遵循一个简单原则WHERE里经常出现的字段才建索引。故障工单表里elevator_no和status是高频查询条件建联合索引比建两个单列索引更有用。我常遇到的一个误区是给所有字段都加索引实际上写入性能会明显下降监管系统每天要刷入大量状态快照索引过多反而拖慢入库速度。运行状态表只保留最近一条快照即可历史数据按天归档到另一张统计表避免一张表无限膨胀。3.3 电梯三态流转正常、故障、维保中的边界条件电梯状态是整个系统的业务核心我设计成一个三态流转模型正常、故障、维保中。规则是正常可以转故障故障可以转维保中维保完成后回到正常。这个流转用后端一个统一接口处理而不是让小程序前端随意改状态。前端展示只是结果后端逻辑才是约束。-- 状态变更记录表每次状态切换写一条方便追溯 CREATE TABLE status_change_log ( id INT PRIMARY KEY AUTO_INCREMENT, elevator_no VARCHAR(32) NOT NULL, from_status TINYINT, to_status TINYINT, change_reason VARCHAR(255), operator VARCHAR(32), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;状态变更记录表是后期排查问题的关键。比如某部电梯状态莫名其妙变成故障又没人上报过工单翻这张表就能定位是哪个操作、什么原因触发的变更。我把它称为监管系统的后悔药有它在数据出问题不用靠猜。状态机里还有一个边界条件要处理故障恢复时系统不能直接把状态改成正常而应该通过维保工单的“完成”操作来触发恢复保证每一次恢复都有维保记录支撑。否则就会出现“状态正常了但没有任何人做维护”的假数据。4. 小程序端核心实现状态看板、故障上报与工单闭环4.1 首页状态看板轮询渲染电梯卡片的完整代码首页是整个系统最直观的门面。进入小程序后首页先请求后端接口拿到所有电梯的最新状态然后用wx:for循环渲染成卡片列表。每张卡片显示电梯编号、所在楼栋、当前状态、当前楼层和方向。状态用不同颜色标识绿色正常、红色故障、黄色维保中扫一眼就知道哪个片区有问题。轮询我用setInterval实现每10秒拉一次接口。间隔不是越大越好也不是越小越好。10秒适合监管场景刷新太快对后端造成没必要的压力太慢又做不到“实时”。页面切到后台时要在onHide里清除定时器否则一直轮询不仅耗电还会因为请求堆积导致页面卡顿。// pages/index/index.js 核心轮询逻辑 const API_BASE https://your-domain.com/api; Page({ data: { elevatorList: [], loading: true }, onShow() { this.fetchElevatorStatus(); this.startPolling(); }, onHide() { this.stopPolling(); }, fetchElevatorStatus() { wx.request({ url: ${API_BASE}/elevator/status/list, method: GET, success: (res) { if (res.data.code 0) { this.setData({ elevatorList: res.data.data, loading: false }); } }, fail: () { wx.showToast({ title: 网络异常, icon: none }); } }); }, startPolling() { this.pollingTimer setInterval(() { this.fetchElevatorStatus(); }, 10000); }, stopPolling() { if (this.pollingTimer) { clearInterval(this.pollingTimer); this.pollingTimer null; } } });这段代码里setData是整个小程序性能的关键。每次轮询都全量更新elevatorList如果电梯数量超过100部会造成不必要的渲染开销。优化思路是后端接口支持按更新时间增量返回前端只更新变动的卡片但多数场景下几十部电梯全量刷新已经足够流畅。轮询失败时我选择静默处理而不是反复弹Toast避免每10秒打扰一次用户。4.2 故障上报与工单闭环的页面逻辑和参数校验故障上报页面是事件起点。用户进入页面后先选择电梯编号再选择故障类型最后填写描述。提交时前端做一层基础校验后端再做一层校验。前端的校验是为了用户体验后端的校验才是数据安全防线两层的职责必须分开。// pages/report/report.js 故障上报逻辑 Page({ data: { elevatorNo: , faultType: , description: }, submitReport() { const { elevatorNo, faultType, description } this.data; if (!elevatorNo) { wx.showToast({ title: 请选择电梯, icon: none }); return; } if (!faultType) { wx.showToast({ title: 请选择故障类型, icon: none }); return; } if (description.trim().length 5) { wx.showToast({ title: 描述至少5个字, icon: none }); return; } wx.request({ url: ${API_BASE}/fault/order/create, method: POST, data: { elevatorNo, faultType, description }, success: (res) { if (res.data.code 0) { wx.showToast({ title: 上报成功, icon: success }); setTimeout(() wx.navigateBack(), 1500); } else { wx.showToast({ title: res.data.message, icon: none }); } } }); } });这里的校验逻辑里description.trim().length 5是关键。用户经常输入空格或几个字就点提交后端如果用空字符串判断会放过纯空格。先用trim去掉首尾空格再判断长度才能有效拦住无效提交。故障类型我设计成固定下拉项而不是自由输入原因是自由输入会造成同一故障多种叫法后面做统计分析时数据一塌糊涂。困人、异响、停电、门故障、其他故障这五个枚举值足够覆盖绝大多数情况。后端收到上报请求后处理顺序是校验电梯编号是否存在插入故障工单更新电梯状态为故障写入状态变更日志。四个步骤必须放在同一个事务里任何一个失败都要回滚。如果只插工单不更新电梯状态首页看板永远显示绿色用户会以为系统没收到上报。4.3 维保计划与台账展示列表页的加载与筛选参数维保计划页面展示每部电梯的维保安排包括下次维保日期、维保类型和执行人。这个页面的核心需求不是录入而是提醒哪些电梯即将到期哪些已经超期。我在接口里直接支持status参数前端用一个分段器切“全部/即将到期/已超期”三个Tab每次切换都重新请求而不是前端本地过滤。列表页的翻页设计我推荐用“下拉触底加载更多”而不是传统的页码跳转。移动端用户习惯往下滑触底后自动请求下一页page和pageSize参数通过data传给请求函数。加载完成后把新数据concat到旧数据后面同时更新loading状态。要注意的是分页接口返回数据时要多返回一个hasMore字段前端拿它判断是否还有下一页避免滑到底部后反复发起无效请求。5. 避坑指南从部署到演示最容易翻车的基础设施问题5.1 真机预览时接口请求直接失败开发者工具里却一切正常现象项目在微信开发者工具里跑得好好的数据能加载页面能跳转。一换到真机预览就全部白屏控制台一堆“request:fail”报错。原因绝大多数情况下是域名校验问题。开发者工具默认开启了“不校验合法域名”选项所以本地HTTP接口能通过真机上这个选项不生效微信强制要求request请求的域名必须在小程序后台配置过而且必须是HTTPS。用IP加端口直接访问是被禁止的。解决本地调试阶段不改代码只做两步。第一步在开发者工具详情里勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”第二步真机预览时在手机微信里打开调试模式这样真机也会跳过域名校验。正式环境再去申请域名和HTTPS证书在小程序后台配置request合法域名。5.2 状态卡片不刷新下拉刷新才有新数据现象首页电梯状态看板的数据一直是旧值轮询看起来在跑setInterval也设置了但页面上就是不变。手动下拉刷新后数据又变成最新了。原因多半是把this指向搞丢了。setInterval的回调函数里如果用普通function而不是箭头函数this指向的是定时器对象而不是Page实例调用this.setData时会报错但报错被吞掉后表现为界面不更新。另一个常见原因是把setInterval放进了onLoad而onLoad只在页面创建时执行一次从后台切回前台时定时器失效。解决统一用箭头函数写定时器回调定时器启动放在onShow里销毁放在onHide里。onShow每次页面显示都会执行保证从后台切回来时定时器重新启动。这样既保住了this绑定也解决了生命周期导致的轮询失效。5.3 导入数据库后中文乱码或建表失败现象用Navicat或命令行导入SQL脚本后表结构里的中文字段注释变成问号工单描述里的中文全部乱码。更严重的情况是脚本跑到一半报错表建了一半就停了。原因两件事。第一SQL脚本文件的编码不是UTF-8或者数据库连接字符集不是utf8mb4中文进去就乱码。第二脚本里有重复的CREATE TABLE语句之前导过一次又导一次MySQL直接报“Table already exists”导入中断。解决导入前先用记事本或编辑器确认SQL文件另存为UTF-8编码连接数据库时在连接参数里显式指定charsetutf8mb4导入操作前先执行DROP TABLE IF EXISTS保证可重复执行。建表脚本开头加一句SET NAMES utf8mb4这样不管连接工具用什么默认字符集脚本里的中文注释都能正常写入。5.4 视频演示的流程跑得通自己操作时电梯状态永远卡在“故障”现象照着演示视频里的操作登录系统、上报故障、查看工单、标记完成前几步都正常但故障状态标记完成后电梯卡片还是红色怎么点都不变绿。原因状态恢复的逻辑设计有问题。视频里演示的可能是直接改数据库把状态改回去或者后端有个手动复位接口但自己操作时只点了“工单完成”而后端代码里工单完成并没有联动更新电梯状态。这两个操作是断开的等于工单流程走完了状态机还停在故障态。解决在工单完成的接口处理逻辑里加上电梯状态恢复的联动。工单状态更新为完成后同时更新elevator表的状态为正常并写入状态变更日志。我习惯把这一步放在后端同一个事务里保证工单完成和状态恢复要么同时成功、要么同时失败。加一个兜底如果工单完成超过24小时状态仍异常系统每日定时任务自动比对一次把不一致的数据捞出来告警。6. 用一场故障演练验证系统的闭环能力系统做完不能只看代码有没有报错要用真实业务流程去验证。我每次做这类监管系统都会设计一场完整的故障演练拿一部电梯模拟从正常到故障再到维保恢复的全流程。验证时不再点开每个页面人肉确认而是借助后端接口返回的JSON数据和数据库查询结果来判断系统是否按预期工作。演练步骤操作动作预期结果1进入故障上报页选择某部电梯提交困人故障工单表新增记录电梯状态变为故障变更日志写入一条“正常→故障”2工单列表查看新工单工单状态为待处理首页该电梯卡片为红色3维保人员接单工单状态变为处理中工单表处理人字段有值状态自动更新4现场处理完成工单标记已完成电梯状态恢复为正常首页卡片变绿变更日志写入“故障→正常”演练结束后我会核验三个点状态变更日志是不是完整记录了每一次切换、工单状态和电梯状态是不是始终联动、从上报到恢复的整体耗时有没有超过设定的阈值。这三项都通过系统才算真正闭环。这套系统跑顺之后值得做的第一个进阶功能是误报治理。实际运营中会发现电梯故障上报里有不少误报比如住户按错按钮或者维修时误触。我现在的做法是给工单增加一个“故障来源”参数区分乘客上报和维保人员上报同时设置一个宽限期定时器故障上报后5分钟内没有二次确认自动发一条微信订阅消息给值班人员确认。这个机制能把误报率明显压下来也让监管系统的数据更可信。我做这类系统最大的教训是功能可以砍但状态流转和日志记录绝对不能省。没有日志的状态系统出问题只能靠猜猜来猜去最后还是得加日志重来一遍。希望帮到你。本文还有配套的精品资源点击获取