恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SpringBoot与微信小程序实现的社区疫情报备系统全解析
首页
资讯中心
/
SpringBoot与微信小程序实现的社区疫情报备系统全解析
SpringBoot与微信小程序实现的社区疫情报备系统全解析
发布时间:2026/10/13 22:37:31
又是一个被毕业设计题目困住的朋友。我太熟悉这种题了——springboot社区疫情报备微信小程序的设计与实现听上去像个又大又空的标准命题但拆开看其实非常落地。这类题目本质上是让你实现一个完整的信息采集、上报、审核、统计的业务闭环后端用SpringBoot前端用微信小程序业务场景清晰技术栈经典非常适合用来做毕设。我帮不少人看过类似的项目整体感觉是题目不难但需要你想清楚社区管理端要什么、居民端要什么、数据库怎么设计、权限怎么控制。这篇文章我就以这个题目为例把整个实现过程踩过的坑、总结的经验、能直接照做的代码结构全部摊开来讲适合正在准备开题、已经写完一半不知道怎么继续、或者想给项目加分的同学参考。1. 先想清楚业务闭环再动手写代码1.1 这个项目到底在解决什么问题这种题目拿到手第一反应是慌因为疫情报备四个字看着既像业务又像政策其实你只需要把它理解成一个垂直场景的信息管理系统就够了。核心解决的是社区工作人员需要掌握辖区居民的健康相关信息但靠微信群接龙或者纸质表格效率低、容易漏、不好统计所以需要一个小程序让居民自助填报后台自动汇总。简化之后的业务模型就两个端居民端微信小程序登录、绑定楼栋房间、提交健康报备信息、查看自己的报备记录和审核状态、接收社区通知。管理端Web后台或者小程序内的管理页面查看辖区报备数据、审核异常报备、按楼栋/日期统计、导出报表、管理居民和楼栋信息。大多数毕设要求不高管理端可以直接做成小程序里的管理员页面省去单独做Web前端的工程量。如果想给项目加分再单独拆一个Vue后台管理页面这个后面章节我会展开说。想清楚这个闭环之后你会发现后面的所有设计都围绕一条主线在走居民填数据 - 数据落库 - 管理员查询与审核 - 结果回显给居民。只要这条主线通了项目就成功了八成。1.2 技术选型为什么是SpringBoot 微信小程序先说结论这个组合是当前毕业设计里最稳妥、最不容易翻车的组合之一。SpringBoot负责后端接口理由很充分生态成熟和MyBatis-Plus、Redis、Spring Security等配套方案极度成熟出了问题搜索引擎上一搜一大把解决方案。上手门槛适中一个普通的Java基础水平照着官方文档就能跑通增删改查接口不需要像学Spring老版本那样配置一堆XML。部署方便打包成Jar包直接扔服务器上就能跑对于没接触过运维的同学来说最省心。微信小程序做前端理由更直接——用户不需要下载App扫码或搜索就能用非常贴合社区居民快速使用这个场景。小程序开发用的WXML和WXSS语法跟HTML/CSS很接近如果你有Web基础基本半天就能上手。而且微信官方提供了完善的前后端交互方案登录体系直接复用微信授权不用自己搞短信验证码那一套。如果你的导师偏爱新技术你可以在这个基础上把Redis加进来做热点缓存把RabbitMQ加进来做消息异步处理。但基本功还是这套SpringBoot 小程序先把主链路跑通比什么都重要。1.3 角色划分与用例设计我建议一开始就把三种角色分清楚不要偷懒合并因为后面数据库设计和接口设计都依赖这个划分。角色使用端核心用例普通居民微信小程序登录、绑定楼栋房间、每日报备、查询自己的报备记录、查看审核状态社区管理员小程序管理端或Web后台查看居民列表、审核异常报备、按楼栋/日期统计、导出数据、管理公告超级管理员Web后台管理管理员账号、管理系统配置、查看全局数据这个设计看着简单但很多人会漏掉绑定楼栋房间这一步。我见过有同学把楼栋信息直接硬编码在用户表里居民想改地址只能找管理员改数据库。正确做法是把用户—楼栋—房间号设计成可修改的绑定关系让居民在个人中心自己维护管理员也能在后台手动修正。这是数据模型设计的重点下一章细说。2. 数据库与表结构设计抱着能上线部署的标准来设计2.1 核心表设计数据库设计这块我强烈建议你站在这套代码未来真的要部署给一个社区用的角度去做而不是站在只要能跑通答辩演示的角度。原因很简单评审老师见过太多只有三张表的毕设了你拿出一个设计合理、能自圆其说的库表印象分会直接拉开差距。这个项目至少需要这几张表用户表user字段类型说明idbigint主键自增openidvarchar(64)微信唯一标识建唯一索引nicknamevarchar(64)微信昵称avatarvarchar(255)头像地址phonevarchar(20)手机号可后期绑定building_idbigint所属楼栋IDunit_novarchar(20)单元号room_novarchar(20)房间号roletinyint角色1-居民 2-管理员 3-超级管理员statustinyint状态1-正常 0-禁用create_timedatetime创建时间update_timedatetime更新时间楼栋表building字段类型说明idbigint主键namevarchar(64)楼栋名称如1号楼addressvarchar(255)楼栋地址manager_idbigint负责该楼栋的管理员IDcreate_timedatetime创建时间报备记录表health_report字段类型说明idbigint主键user_idbigint提交人IDreport_datedate报备所属日期建联合索引health_statustinyint健康状态1-正常 2-异常body_temperaturedecimal(4,1)体温symptomvarchar(255)症状描述travel_historyvarchar(255)近期行程简述contact_statustinyint是否接触风险人员0-否 1-是address_infovarchar(255)当前所在地remarkvarchar(255)备注statustinyint审核状态0-待审核 1-通过 2-驳回reject_reasonvarchar(255)驳回原因auditor_idbigint审核人IDaudit_timedatetime审核时间create_timedatetime提交时间update_timedatetime更新时间公告表notice字段类型说明idbigint主键titlevarchar(128)标题contenttext内容create_bybigint发布人IDcreate_timedatetime发布时间top_flagtinyint是否置顶这四张表足够覆盖项目主流程。如果想加分可以再加一张系统日志表记录管理员的审核操作这对答辩时说系统可追溯非常有用。2.2 字段类型与常见细节很多同学在这块会犯低级错误我总结几个最常见的。第一日期字段一定要区分报备日期和提交时间。report_date是居民为哪一天报备create_time是这条记录什么时候提交到系统。有的人图省事只用了一个create_time结果管理员想查今天有多少人报备时发现日期口径混乱很难查出正确数据。第二体温字段用decimal(4,1)而不用float。浮点类型在比较和精度上容易出问题而且报备体温一般就36到37度左右4位有效数字加1位小数完全够用。第三openid必须建唯一索引。微信登录的返回数据中openid是每个用户在小程序下的唯一标识。不建唯一索引可能出现用户重复注册后面查数据时非常痛苦。第四状态字段用tinyint并用常量类定义不要直接散落在各处写魔法数字。我习惯在项目里建一个ReportStatusEnum定义类似PENDING(0, 待审核)、APPROVED(1, 通过)、REJECTED(2, 驳回)代码里到处是1和0的后果就是两周后你自己都看不懂这段逻辑。2.3 表之间的关系理一下关系你答辩画ER图的时候直接用一个楼栋building对应多个用户user一对多一个用户user对应多条报备记录health_report一对多一个管理员可以审核多条报备记录报备记录与用户、管理员都存在关联一个管理员可以发布多条公告一对多注意用户与楼栋虽然是所属关系但同样也要走外键关联逻辑。user表的building_id指向building表的id不要只是存个名字字符串就完事。存ID而不是存名称是为了后面改楼栋名称时不至于连带改一堆用户数据这也是基本范式思维的体现。3. 后端SpringBoot开发中真正值得花时间的四个点3.1 统一返回结构和全局异常处理起步阶段最容易被忽略但后期收益最大的环节就是统一返回结构。我见过太多半途崩掉的项目前后端联调时最大的问题就是——接口有时候返回数据有时候返回null有时候直接抛出一堆英文异常小程序端收到后完全不知道怎么处理。我的推荐做法是定义一个ResultT类Data public class ResultT { private Integer code; private String msg; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMsg(操作成功); result.setData(data); return result; } public static T ResultT error(Integer code, String msg) { ResultT result new Result(); result.setCode(code); result.setMsg(msg); return result; } }再加一个RestControllerAdvice做全局异常捕获把业务异常、参数校验异常、兜底异常分开返回。这样前端只需要判断code 200就能决定是正常渲染还是弹出错误提示。小程序端的代码也能写得很干净。这一步价值在于它把接口的意外失败变成了预料的失败联调时至少省一半时间。3.2 登录鉴权小程序登录为什么不能用简单的账号密码很多同学第一次做小程序项目会习惯性地设计一个账号密码登录页然后在数据库里存明文密码。这是个大坑。小程序登录的正规路径是小程序端调用wx.login()拿到临时凭证code后端拿着code请求微信接口交换得到openid和session_key后端用openid查用户表不存在则自动注册存在则加载用户信息后端生成一个token返回给小程序后续请求都带上这个token这里不展开细说微信授权的全部细节但有两个关键点你必须搞清楚第一code是一次性的有效期只有几分钟不能反复使用第二openid就是用户在这个小程序下的唯一身份标识你不需要也拿不到用户的微信号、手机号手机号需要另外的授权。后端生成token我建议直接用JWT简单、无状态、适合毕设。核心逻辑大致是这样Component public class JwtUtils { Value(${jwt.secret}) private String secret; public String generateToken(Long userId, Integer role) { return Jwts.builder() .setSubject(String.valueOf(userId)) .claim(role, role) .setExpiration(new Date(System.currentTimeMillis() 7 * 24 * 3600 * 1000)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public Long getUserId(String token) { return Long.parseLong(Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody() .getSubject()); } }然后写一个拦截器把所有需要登录的接口拦一下从Header里取token解析出用户信息放到ThreadLocal里备用。这里有个常见的坑拦截器放行路径要配置正确。/api/auth/**放行其余全部拦截管理员接口要额外校验role字段。对了还有一个很容易踩的坑别忘了处理token过期。JWT过期后拦截器会抛出异常如果你没有统一捕获小程序端会收到一个莫名其妙的500。建议在全局异常处理里捕获过期异常返回一个特定错误码小程序端收到后引导用户重新登录。3.3 报备记录的分页与状态流转报备记录是这个项目最核心的业务数据接口设计要分成两条线居民端查询我的报备记录用user_id create_time倒序分页。管理端查询全部报备记录需要支持按report_date、building_id、status筛选也是分页。前后端分页我建议直接用MyBatis-Plus的Page封装public PageHealthReport queryReportPage(ReportQueryDTO dto) { LambdaQueryWrapperHealthReport wrapper new LambdaQueryWrapper(); wrapper.eq(dto.getUserId() ! null, HealthReport::getUserId, dto.getUserId()) .eq(dto.getStatus() ! null, HealthReport::getStatus, dto.getStatus()) .eq(dto.getReportDate() ! null, HealthReport::getReportDate, dto.getReportDate()) .eq(dto.getBuildingId() ! null, HealthReport::getBuildingId, dto.getBuildingId()) .orderByDesc(HealthReport::getReportDate) .orderByDesc(HealthReport::getCreateTime); return this.page(new Page(dto.getPageNum(), dto.getPageSize()), wrapper); }关于状态流转一定要把逻辑写清楚不要无限制地让用户在已审核的记录上反复修改。我的建议是居民提交报备后状态为待审核。待审核状态下居民当天可以修改或撤销审核之后不能再改。管理员审核时如果判为通过记录定稿如果驳回必须填写原因居民可以修改后重新提交。这套流程看起来简单但牵涉到几个后端接口的联动提交接口要判断当前日期是否已存在同人记录审核接口要权限校验修改接口要状态校验。这些都是评审老师喜欢追问的细节提前想好会从容很多。3.4 数据统计接口的设计统计接口是给管理端首页用的但不建议做大而全的报表答辩时也讲不清楚。我觉得做三个基础统计就够了今日报备总人数按report_date等于今天统计count(*)。今日异常报备人数上面基础上加health_status 2条件。近7天报备趋势按report_date分组统计每天的总数和异常数返回折线图数据。关键在于性能。有的是直接select *拿回程序内存里count数据量小还行数据多了就慢。正确姿势是用SQL的group bycountpublic ListMapString, Object getTrend(int days) { String startDate LocalDate.now().minusDays(days - 1).toString(); return jdbcTemplate.queryForList( SELECT report_date, COUNT(*) total, SUM(CASE WHEN health_status 2 THEN 1 ELSE 0 END) abnormal FROM health_report WHERE report_date ? GROUP BY report_date ORDER BY report_date, startDate ); }这类SQL统计逻辑在答辩时非常好讲因为它直接体现了你对业务的理解——管理员真正关心的是有没有异常、每天上报量波动大不大。4. 微信小程序端从零到一实现报备主流程4.1 小程序初始化与登录流程小程序的搭建建议直接用微信开发者工具新建一个原生小程序项目别一上来就工程化毕设项目用原生框架已经足够。先把页面的骨架搭好我习惯做一个底部TabBar四个入口首页、报备、记录、我的。登录逻辑要放在App.onLaunch里做一次静默登录不要在用户点按钮时才登录。大概流程是// app.js onLaunch() { wx.login({ success: (res) { wx.request({ url: https://你的接口域名/api/auth/login, method: POST, data: { code: res.code }, success: (res) { wx.setStorageSync(token, res.data.data.token); wx.setStorageSync(userInfo, res.data.data.userInfo); } }); } }); }注意wx.login拿到的code必须传给后端由后端去微信服务器换openid前端拿不到也永远不应该拿到openid。这是安全底线。token存储到wx.setStorageSync后后续所有需要登录的请求都在Header里带上Authorization: Bearer xxx。建议封装一个request工具函数统一加header、统一处理错误码避免每个页面都写一遍。4.2 报备表单页面的实现报备页是小程序的核心用户每天打开小程序第一件事就是填这个表单。表单字段对应后端health_report表的字段包含健康状态正常/异常单选、体温数字输入、症状多选发热、咳嗽、乏力等、近期行程输入、是否接触风险人员、备注。这里给一个WXML片段示例view classform-item text classlabel健康状态/text radio-group bindchangeonHealthChange label classradio-item radio value1 checked{{form.healthStatus 1}} / 正常 /label label classradio-item radio value2 checked{{form.healthStatus 2}} / 异常 /label /radio-group /view view classform-item text classlabel体温/text input typedigit value{{form.bodyTemperature}} bindinputonTempInput placeholder请输入体温 / /view button classsubmit-btn bindtapsubmitReport提交报备/button在JS里submitReport要做两件事本地校验网络提交。本地校验至少覆盖体温不能为空、体温范围要在35到42之间健康状态为异常时症状必须填写。网络提交代码submitReport() { const token wx.getStorageSync(token); wx.request({ url: https://你的接口域名/api/report/submit, method: POST, header: { Authorization: Bearer token }, data: this.data.form, success: (res) { if (res.data.code 200) { wx.showToast({ title: 提交成功, icon: success }); wx.switchTab({ url: /pages/record/record }); } else { wx.showToast({ title: res.data.msg, icon: none }); } } }); }这里有一个很容易踩的坑提交按钮要加防重复点击。我在真机上遇到过用户双击提交结果生成两条报备记录。简单做法是点击后立即置灰按钮或者加一个isSubmitting标志位。4.3 我的报备与状态查询记录页面展示当前用户的所有报备记录按日期倒序排列。每一项显示报备日期、健康状态、审核状态、驳回原因如果有。界面结构建议用wx.request拉取分页数据配合onReachBottom上拉加载下一页。核心逻辑是维护一个pageNum每次滚动到底部就加一页再查一次然后concat到列表后面。这里要特别注意状态展示的颜色区分。待审核用黄色通过用绿色驳回用红色。信息状态一眼能看清这对答辩演示时非常加分——评审老师会认为你考虑了用户体验。如果居民提交了异常报备列表项最好有特殊标识比如显示异常标签。这也是业务理解深度的体现。5. 前后端联调、测试与部署避坑5.1 联调前必须统一的三件事联调是每个写毕设的人最头疼的环节但如果你在动手写接口之前就做好三件事能省掉一大半的痛苦。第一统一时间格式。后端默认返回的是LocalDateTime序列化后的格式小程序端解析起来容易出问题。建议在配置里统一为yyyy-MM-dd HH:mm:ss或者统一返回时间戳让前端自己格式化。两种都要前后端约定好千万不要一天靠后端格式化另一天又靠前端解析时间戳。第二统一返回结构。就是第3章提到的ResultT前端所有请求都判断res.data.code不直接操作res.data。这个约定要在写代码之前就定好不然后面每个接口都要返工。第三统一接口路径前缀。后端Controller统一加/api前缀后面部署到服务器nginx做反向代理时可以直接把/api转发到后端服务不需要再改前端代码里的路径。5.2 常见的坑与排查思路我给你列几个我实际带学生改进项目时反复出现的问题跨域问题。小程序端wx.request是不受浏览器跨域限制的所以本地开发时你会觉得怎么没跨域问题。但如果你做了Web管理后台用Vue开发时就会遇到跨域。建议后端配置一个全局CORS过滤器别等到联调Web端时才慌。index.php 之类的服务器伪静态问题。这个不常见但如果你用某些集成环境部署可能是伪静态规则没配置好导致接口404。排查时先在浏览器直接访问接口地址看返回是不是JSON如果是页面文件内容那基本就是转发规则问题。小程序域名校验。真机调试时如果请求的接口域名不是HTTPS且在微信后台配置过会直接报request:fail url not in domain list。解决办法分两种开发测试时在微信开发者工具里勾选不校验合法域名上线前把后端域名加到小程序后台的request合法域名列表。时间差问题。居民填表时前端传了今天但后端是用服务器时间生成report_date的。如果你的服务器时区没配好会出现今天17点以后提交的记录被记到明天这种诡异问题。解决方法是统一用后端服务器时间并在application.yml里配置好时区。空指针。用户首次登录时还没绑定楼栋buildingId是null。如果接口里直接user.getBuilding().getId()就会NPE。建议用Optional或者提前判空并且把未绑定楼栋与绑定成功返回给前端不同的提示引导用户去个人中心绑定。5.3 部署上线的基本姿势毕设阶段不要求你真的上线运营但至少要在服务器上跑起来给导师演示一遍这比本地演示有说服力得多。部署流程不复杂购买一台云服务器装好JDK8或JDK11和MySQL。本地打包后端项目执行mvn clean package -DskipTests生成jar包。上传jar包到服务器用java -jar xxx.jar --spring.profiles.activeprod启动。安装nginx配置反向代理把/api转发到localhost:8080。在小程序后台配置request合法域名改成你的HTTPS域名。有几点要注意HTTPS证书要提前申请现在云厂商一般都有免费版数据库导入用mysqldump或Navicat都可以记得关掉服务器的调试端口只暴露80和443日志要查看用tail -f nohup.out能实时看到启动日志和报错信息。如果你是第一次接触服务器部署建议先在本地虚拟机里完整走一遍流程再到云服务器操作。别直接拿线上服务器练手容易让自己慌。6. 让毕业设计从能跑到能答辩的加分点6.1 做一个简单的数据可视化面板很多同类项目的管理端首页就是一张表格列表看起来真的很单薄。我强烈建议你在管理端加一个数据可视化面板用ECharts或者小程序端的ec-canvas组件画两个图近7天报备趋势折线图、各楼栋报备异常率柱状图。这两个图表直接使用第3.4节设计的统计接口数据代码量不大但呈现出来的效果完全不一样。答辩时你指着图说我的系统支持管理员实时掌握各楼栋的异常情况这个说服力比任何PPT都强。如果管理端用Web做ECharts集成非常简单如果是小程序端用ec-canvas组件也可以实现。注意图表加载要有loading状态数据为空时要有空态展示别让图表区域出现一大片空白。6.2 小程序端体验优化三个小优化就能让体验感明显提升第一首页放一个今日报备状态卡。居民登录后第一眼就能看到自己今天是否已经报备、报备后是否已审核。这个需求其实很自然——用户打开小程序就是为了完成今天的报备不是为了看一堆导航菜单。第二表单默认值。体温输入框默认填36.5健康状态默认选正常减少用户的点击次数。别小看这个细节它体现了你是真的站在用户角度考虑。第三提交结果反馈。报备提交成功后不要在Stay on当前页而是跳转到我的记录页让用户明确看到今天的记录已经生成。我在实际使用中发现跳转过去的用户体验比弹个toast好很多因为用户能看到结果落地的过程。6.3 文档和演示的准备最后说一下答辩准备这是毕设的临门一脚。首先数据库设计文档要画ER图不用特别复杂关键是讲清楚每张表的职责和表间关系。我曾经见过有同学答辩时被老师问你的报备记录表里为什么会有冗余的楼栋信息没能答上来。提前想好该冗余还是不该冗余的问题会让你从容很多。其次准备一个真实的演示数据包。在系统里预置一些模拟数据若干居民、若干楼栋、近一周的报备记录、几条待审核记录、一条驳回记录。演示流程按居民提交报备 - 管理员审核 - 居民查看结果的顺序走让老师完整看到业务闭环。最后准备几个自查问题的答案比如如果某天居民忘记报备怎么办一个用户能不能提交多条同日报备管理员误操作怎么处理。这些问题不算难度大但答不上来会在印象分上吃亏。提前把这些边界场景在代码里想清楚并加上处理逻辑比临时背答案要真实得多。这个题目做完之后你会发现SpringBoot后端、小程序前端、关系型数据库设计、权限控制这些核心技能都过了一遍后续想扩展成其他管理类系统比如社区报修、物业缴费登记也只是换层皮的事。我实际带过的项目里凡是认真把报备闭环做完整的人答辩基本都顺利通过原因很简单——老师能看出你是真理解了业务和技术怎么结合而不是拿一个Demo糊弄事。希望这篇文章能帮你把思路理清动手写起来的时候少走弯路。