2026/10/13 13:45:54

微信小程序+SSM框架的小区管理系统设计与实现

微信小程序+SSM框架的小区管理系统设计与实现 说实话各种小区管理系统的源码我之前看过不下几十套但大多数要么只给了一个管理后台要么前端就是一堆写死的静态页面。weixin191基于微信小程序的小区管理系统的设计ssm(源码)这套毕业设计题目的含金量在于它是真正的前后端分离业主不用额外装APP打开微信就能用后端用的是Java三件套里最经典的SSM框架组合Spring SpringMVC MyBatis。你要是正在找毕业设计题目或者刚入行想完完整整走一遍真实项目流程这套系统值得好好拆一拆。这套系统能干什么简单说就是三件事业主在微信小程序上查小区公告、交物业费、发报修和投诉物业在后台管业主档案、管房屋信息、处理报修投诉、发缴费账单。如果让你从头写你会怎么设计整体结构这篇就把整个设计思路、数据库表结构、后端接口、小程序端联调以及我实际踩过的坑一次性讲清楚直接照着做基本不会走偏。1. 项目定位与整体设计思路1.1 用户角色与核心业务流先理清楚人再理清楚事。这套系统一共有三类角色业主、物业管理员、系统超级管理员通常由业主管理员兼任。千万不要一上来就建一张用户表把所有角色塞进去那是单人博客的做法。小区管理这种业务角色权限边界很清晰分开建表反而好维护。从业务流程来看核心链路有四条缴费链路管理员在后台生成账单 - 业主在小程序看到待缴账单 - 缴费 - 管理员确认到账 - 账单状态变为已缴。报修链路业主提交报修单文字图片 - 管理员受理 - 派发给维修人员/物业人员 - 处理完成回填结果 - 业主确认并评价。投诉建议链路业主提交投诉 - 管理员回复 - 业主查看回复结论。公告链路管理员发布公告 - 小程序首页轮播或列表展示 - 业主查看详情。这四条链路几乎覆盖了所有页面设计需求。换句话说项目里每一个页面都能在业务链路上找到它的位置不存在为了凑功能而加的页面。1.2 功能清单与页面划分把上面的链路落到具体功能上就是一张很标准的模块清单。功能模块业主端微信小程序管理端后台登录与用户微信授权登录、账号绑定管理员登录、业主账号管理房屋信息查看房屋信息、绑定房屋楼栋楼层房间信息维护小区公告公告列表、公告详情发布公告、置顶、下线缴费管理账单列表、账单详情、缴费账单生成、缴费确认、统计查询报修管理提交报修、查看进度、评价受理派单、处理回填投诉建议提交投诉、查看回复回复处理访客登记提交访客申请、申请记录审批、登记查询车位管理查看车位状态、绑定车位车位分配、变更登记这个功能规模放在毕业设计中刚好合适既有完整的业务闭环又不至于多到写不完。如果你是想加亮点建议在统计查询上下工夫比如月度收费额趋势、各楼栋报修数量排行这两块图表一加答辩时观感提升非常明显。1.3 为什么选SSM而不是Spring Boot每次写这类项目都会被人问现在都2024年了为什么还抱着SSM不放我的看法是分场景。如果是在真实企业里做新项目那我确实会用Spring Boot毕竟自动装配、内嵌容器、配置简化这些优势太香了。但在毕业设计/课程设计这个场景下SSM反而更合适SSM三个框架各司其职Spring管IoC和AOP、SpringMVC管请求路由、MyBatis管SQL持久化导师想看的技术点一目了然。Spring Boot大量依赖自动配置很多报错直接给出堆栈你都不知道底层发生了什么SSM的配置虽然啰嗦但每一步都是显式声明出现问题反而好排查。很多学校的教学大纲和答辩评分标准还停留在SSM时期用SSM答辩不容易被追问超出认知范围的框架细节。另外SSM的项目结构天然就是分层开发的模板拆解出来的Controller、Service、Mapper三层模式将来让你转Spring Boot也毫无障碍因为这些底层思想完全是同一套东西。2. 数据库设计与核心表结构2.1 表关系设计思路数据库设计是整个系统的地基这块我不建议偷懒。我的习惯是先画E-R图再建表用纸笔画一遍关系比直接写SQL清晰得多。这套系统的核心实体有业主、房屋、管理员、公告、账单、报修单、投诉单、访客记录、车位一共九张表。关键关系如下房屋表与业主表一套房通常绑定一个主要业主但实际居住人可能有多个。设计时把房屋表独立出来业主表里存room_id外键这样一套房可以挂多个业主账号同时保留一个主业主字段做缴费的默认归属人。业主表与账单表一对多。一个业主账户名下有多条缴费记录。业主表与报修/投诉表一对多。每次报修或投诉都挂着发起人的id。管理员表与业主表互不干扰分表存储避免权限耦合。这里有个容易犯的错误把业主管理员的账号也放进业主表然后加一个role字段区分。短期看省了一张表后期写权限拦截的时候会非常别扭因为所有接口都要先判断role再决定放行不放行代码会越写越乱。老老实实分表一个sso_user和admin_user分开就完事了。2.2 关键表结构示例先看业主表这是整个系统里被引用最多的表。CREATE TABLE t_owner ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, openid VARCHAR(64) DEFAULT NULL COMMENT 微信openid, username VARCHAR(32) DEFAULT NULL COMMENT 账号(可用于非微信端登录), password VARCHAR(64) DEFAULT NULL COMMENT 密码(加密存储), real_name VARCHAR(32) NOT NULL COMMENT 业主姓名, phone VARCHAR(20) NOT NULL COMMENT 手机号, id_card VARCHAR(20) DEFAULT NULL COMMENT 身份证号, room_id INT DEFAULT NULL COMMENT 房屋外键, is_main_owner TINYINT DEFAULT 0 COMMENT 是否主业主, status TINYINT DEFAULT 1 COMMENT 1正常 0禁用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT业主表;几个字段设计我特别说明一下openid设计成可空是为了兼容两种登录方式微信授权登录靠openid识别和账密登录靠username/password。如果你确定只做微信登录也可以去掉username/password但保留的话演示时更灵活万一小程序审核出问题了还能用网页版后台顶一下。status字段不是摆设。业主搬走了你不能直接删他的记录否则这个人的历史缴费记录、历史报修记录全部失去关联数据就乱了。用状态禁用是正道删除只应该出现在测试数据清理阶段。密码字段一律加密存储MD5加盐或BCrypt都行明文存储是很低级的失误答辩时被问到直接扣印象分。再看缴费账单表这是业务核心中的核心。CREATE TABLE t_bill ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, owner_id INT NOT NULL COMMENT 业主id, room_id INT NOT NULL COMMENT 房屋id, bill_type TINYINT NOT NULL COMMENT 账单类型: 1物业费 2水费 3电费 4停车费, amount DECIMAL(10,2) NOT NULL COMMENT 金额, period VARCHAR(20) COMMENT 账单周期,如2024-06, status TINYINT DEFAULT 0 COMMENT 0待缴 1已缴 2已撤销, remark VARCHAR(255) DEFAULT NULL COMMENT 备注, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 生成时间, pay_time DATETIME DEFAULT NULL COMMENT 缴费确认时间, confirm_admin_id INT DEFAULT NULL COMMENT 确认管理员id ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT缴费账单表;金额字段用DECIMAL(10,2)是常识了但还是要啰嗦一句绝不要用FLOAT或DOUBLE存金额浮点数精度问题在金额计算上会要命。period这个字段也别忽略它记录了账单属于哪个月份到时候做月度统计全靠它分组。报修单表的核心在于状态流转字段CREATE TABLE t_repair ( id INT PRIMARY KEY AUTO_INCREMENT, owner_id INT NOT NULL, room_id INT NOT NULL, content TEXT NOT NULL COMMENT 报修描述, images VARCHAR(500) DEFAULT NULL COMMENT 图片路径,多张用逗号分隔, status TINYINT DEFAULT 0 COMMENT 0待受理 1已受理/处理中 2已处理待确认 3已确认完成, handler VARCHAR(32) DEFAULT NULL COMMENT 处理人, handle_content TEXT COMMENT 处理结果说明, handle_time DATETIME DEFAULT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT报修单表;注意images字段它是用逗号分隔的图片路径字符串。你也可以建一张子表专门存图片列表但毕业设计这个体量下逗号分隔已经够用处理时做一个split就行不给自己加工作量。2.3 索引设计外键字段必须建索引这是入门规则。具体到这套系统重点加上这几个t_owner.room_id按房屋查业主、按业主查房屋都很高频。t_bill.owner_idt_bill.status联合索引因为业主查账单时大概率带状态筛选只看待缴。t_repair.owner_id业主查自己的报修记录。t_bill.period月度账单统计时的大范围查询条件。create_time这种字段一般不用单独建索引除非你做时间范围查询特别频繁。我用一个小米加步枪的方法先不建索引跑一版用慢查询日志看哪些SQL超时了再针对性地加索引省下来的时间比什么都值。3. SSM后端架构与核心接口实现3.1 标准分层项目结构后端我用的是经典Maven多包结构目录如下com.hometown.controller // 控制层接收HTTP请求 com.hometown.service // 业务接口 com.hometown.service.impl // 业务实现 com.hometown.mapper // MyBatis数据访问接口 com.hometown.entity // 实体类 com.hometown.common // 通用返回、常量、工具类 com.hometown.config // 配置类如拦截器、定时任务每层职责用一句话说清楚Controller层只做参数接收和结果包装不写任何业务逻辑业务逻辑写在Controller里是后续维护的灾难源头。Service层处理业务规则比如缴费时先判断账单状态是不是待缴再判断金额是否匹配最后才改状态。Mapper层只写数据库操作每一条SQL都要清晰可控复杂的多表联查就写XML里的自定义SQL。这套分层是SSM的通用套路配合IDE自动生成也不难。最忌讳的是图省事在Controller里直接调Mapper——当时写得很爽后面改需求的时候你想死的心都有。3.2 统一返回格式前后端联调的时候最怕的就是各写各的返回格式。我的习惯是在项目最早期就定一个统一返回类public class Result { private Integer code; // 0成功1业务失败500系统异常 private String msg; // 提示信息 private Object data; // 业务数据 public static Result success() { ... } public static Result success(Object data) { ... } public static Result error(String msg) { ... } }这样小程序端的请求封装写起来非常轻松看到code 0就认为成功直接取data渲染页面如果code ! 0就弹出msg提示。联调阶段80%的扯皮问题都能被这套统一格式提前消灭掉。3.3 核心接口拆解微信登录微信小程序的登录流程很多新手搞不清楚我拆细一点。小程序端调用wx.login()拿到一个临时code这个code的有效期只有五分钟而且只能用一次。小程序端把这个code通过自有接口传到后端后端再拿code去微信官方接口换openid和session_keyPostMapping(/api/login) public Result login(RequestBody MapString, String params) { String code params.get(code); String url https://api.weixin.qq.com/sns/jscode2session?appidAPP_IDsecretAPP_SECRETjs_code code grant_typeauthorization_code; // 用HttpClient发起GET请求解析返回的openid String openid parseOpenid(weChatService.getSession(url)); // 查数据库如果openid不存在则自动注册 Owner owner ownerMapper.findByOpenid(openid); if (owner null) { owner new Owner(); owner.setOpenid(openid); ownerMapper.insert(owner); } // 生成token返回前端可以是UUID也可以简化处理 String token UUID.randomUUID().toString(); return Result.success(token); }注意几个细节appid和secret千万不能写在小程序端一旦打包出去前端代码谁都能看直接泄露认证和支付功能会被盗用。正确的做法是放在后端配置文件里通过接口代理转发。另外用openid自动注册的账号虽然能登录但业主姓名、手机号这些信息还没有所以登录后要引导绑定手机号或填写房屋信息。3.4 核心接口拆解缴费查询与状态流转缴费列表接口其实就是一个分页查询但要注意加上权限过滤不能让业主A看到业主B的账单。我习惯在SQL条件里强制带owner_id而不是靠代码里去判断双重保险才有意义。select idselectBillPage resultTypecom.hometown.entity.Bill SELECT * FROM t_bill WHERE owner_id #{ownerId} if teststatus ! null AND status #{status} /if if testbillType ! null AND bill_type #{billType} /if ORDER BY create_time DESC /select状态流转的逻辑写在Service层。比如确认缴费这个操作代码逻辑是public Result confirmPay(Integer billId, Integer adminId) { Bill bill billMapper.selectById(billId); if (bill null) { return Result.error(账单不存在); } if (bill.getStatus() ! 0) { return Result.error(账单不是待缴状态无法确认); } bill.setStatus(1); bill.setPayTime(new Date()); bill.setConfirmAdminId(adminId); billMapper.updateById(bill); return Result.success(); }先查状态再更新这一步叫乐观锁防止并发情况下重复确认。虽然毕业设计场景下并发量不高但这份严谨在答辩时是加分项。3.5 定时生成账单每个月都要手动生成物业费账单太痛苦了肯定要用定时任务。SSM框架里可以用Spring自带的Scheduled注解配置起来非常轻量Component public class BillGenerateTask { Scheduled(cron 0 0 2 1 * ?) // 每月1日凌晨2点执行 public void generateMonthlyBill() { // 查询所有正常状态的房屋 ListRoom rooms roomMapper.selectActiveRooms(); for (Room room : rooms) { // 判断该房屋本月账单是否已存在避免重复 if (billMapper.existsByRoomIdAndPeriod(room.getId(), lastMonthPeriod())) { continue; } // 按房屋面积 * 单价 物业费 BigDecimal amount room.getArea().multiply(MONTHLY_PRICE_PER_METER); // 归属到主业主 Owner mainOwner ownerMapper.findMainOwnerByRoomId(room.getId()); Bill bill new Bill(); bill.setOwnerId(mainOwner.getId()); bill.setRoomId(room.getId()); bill.setPeriod(lastMonthPeriod()); bill.setAmount(amount); billMapper.insert(bill); } } }这里有一个细节坑任务执行前一定要先查本月账单是否已存在否则任务重跑一次就会出现重复账单用户端直接炸锅。另外定时任务的cron表达式建议写成在线工具校验一遍我第一次写就把秒和月份的位置搞反了。3.6 图片上传问题报修图片上传是很多新手卡壳的地方。小程序的wx.chooseMedia拿到临时文件路径之后通过wx.uploadFile上传到后端wx.uploadFile({ url: BASE_URL /api/upload, filePath: tempFilePath, name: file, success: (res) { // 后端返回文件访问URL } })后端用MultipartFile接收并保存到指定目录。这里我要提醒一个Tomcat部署的大坑在本地IDE运行Tomcat时把文件写到项目根目录没问题但打成war包部署到服务器后上传的文件一旦重启Tomcat可能会丢或者写到一个临时目录导致图片访问404。稳妥的做法是配置一个独立的上传目录比如服务器上的/data/upload然后通过SpringMVC的静态资源映射把它映射成URL路径对外访问。4. 微信小程序前端实现要点4.1 页面结构设计小程序端不需要复杂的架构按业务模块建目录就好pages/ ├── index/ // 首页轮胎公告快捷入口 ├── notice/ // 公告列表与详情 ├── pay/ // 缴费账单列表 ├── repair/ // 报修列表、提交、详情 ├── complaint/ // 投诉建议 ├── visitor/ // 访客登记 ├── owner/ // 我的房屋信息、绑定、设置app.json里注册页面时注意顺序第一个页面就是小程序启动后展示的首页。我建议把首页放在pages里第一行顺手把navigationBarTitleText改掉系统默认的小程序三个字显得太不上心了。4.2 登录状态管理小程序端登录后的用户身份我用token作为登录凭证存到wx.setStorageSync里。每次请求由统一封装的request方法自动带上const BASE_URL https://your-domain.com; // 实际部署时为HTTPS域名 const request (url, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, method, data, header: { Content-Type: application/json, token: wx.getStorageSync(token) || }, success: (res) { if (res.data.code 0) { resolve(res.data.data); } else if (res.data.code 401) { // 登录过期重新走登录流程 handleLogin(); } else { wx.showToast({ title: res.data.msg, icon: none }); reject(res.data); } }, fail: (err) { wx.showToast({ title: 网络异常, icon: none }); reject(err); } }); }); } module.exports request;这里code 401的场景是专门给登录过期用的。后端拦截器发现token无效或者过期就返回401前端收到这个状态码就重新调用wx.login()换code再登录整个过程对用户基本无感。4.3 列表页的下拉刷新和触底加载业务列表页面几乎都逃不过分页加载小程序提供了一套很好用的原生接口Page({ data: { list: [], pageNum: 1, pageSize: 10, total: 0, loading: false }, onPullDownRefresh() { this.setData({ pageNum: 1, list: [] }); this.fetchList(() wx.stopPullDownRefresh()); }, onReachBottom() { if (this.data.list.length this.data.total) { return; // 没有更多数据了 } this.setData({ pageNum: this.data.pageNum 1 }); this.fetchList(); }, fetchList(done) { this.setData({ loading: true }); request(/api/repair/list, POST, { pageNum: this.data.pageNum, pageSize: this.data.pageSize }).then(res { this.setData({ list: this.data.list.concat(res.list), total: res.total }); }).finally(() { this.setData({ loading: false }); if (done) done(); }); } })onReachBottom防重复请求是很容易漏的。建议加一个loading标志位请求没结束之前直接return避免用户快速滑动触发N次请求。4.4 房屋状态的下拉选择优化有些选项类数据比如账单类型、报修状态直接用前端写死的字典值就够了不用每打开一次页面就调一次接口。我把这些字典集中在一个常量文件里const BILL_TYPE { 1: 物业费, 2: 水费, 3: 电费, 4: 停车费 }但有些数据是要实时从后端拿的比如我的房屋列表当前绑定车位这些数据必须动态获取不能写死不然业主换了房子数据就对不上了。经验法则一句话枚举类状态写前端业务类数据走后端接口。5. 关键业务闭环与难点攻克5.1 线上缴费不申请微信支付也能做闭环很多毕业设计卡在微信支付上。小程序要接入微信支付需要企业主体、商户号、资质审核个人开发者根本搞不定。我的建议是别硬怼支付接口做线下确认模式的缴费闭环也完全够用。具体做法是账单显示待缴状态同时给出支付说明比如请转账到对公账户并备注小区楼栋号。业主在线下完成转账后管理员在后台根据转账凭证把账单状态改成已缴。这个方案避开了微信支付申请流程的重重门槛但业务逻辑一点都没缩水账单状态流转、金额核对、支付时间记录全都保留了。如果你想画面更好看一点还可以在账单详情加一个上传转账凭证的入口业主把转账截图传上去管理员在后台查看截图后确认。这个功能也不难就是复用报修的图片上传而已但答辩时能多讲一个业务场景。5.2 报修闭环的处理心得报修是整个系统里我最推荐认真做的模块因为它的生命周期最完整能讲的业务点最多。状态流转业主提交 -status 0待受理管理员查看 - 受理并备注处理人 -status 1处理中处理人回填结果 -status 2已处理待确认业主查看结果 - 确认或追问 -status 3已完成这里面有个小坑报修单一旦变成已确认完成很多同学就认为流程结束了其实还可以留一个业主评价字段。加个评价文案和评分一来业主有参与感二来管理后台可以按评分筛选维修质量差的分包商等于把管理系统延伸成了一个小型工单系统。代码量增加很少业务故事多了不少。5.3 权限控制与数据隔离SSM项目我用拦截器做登录校验比AOP简单直接。写一个LoginInterceptor在不同请求路径上配置拦截规则mvc:interceptors mvc:interceptor mvc:mapping path/api/owner/**/ !-- 业主端接口必须登录 -- bean classcom.hometown.interceptor.OwnerInterceptor/ /mvc:interceptor mvc:interceptor mvc:mapping path/api/admin/**/ !-- 管理端接口必须管理员登录 -- bean classcom.hometown.interceptor.AdminInterceptor/ /mvc:interceptor /mvc:interceptors这样业主端接口和管理员端接口在物理路径上就分开了配合拦截器可以做到登录接口放行、上传接口放行、其他接口统统校验token。我见过很多项目把/api/login和/api/owner/bill/list放在同一个Controller里这样拦截器就没法用路径区分只能在方法上加鉴权注解复杂度立刻上去了。数据隔离要做到Service层。业主查询自己房屋信息时我直接在SQL里把owner_id作为必要条件后端再额外校验一遍token对应用户和参数里的ownerId是否一致。双保险不是过度设计而是把误操作和越权请求挡在数据访问之外。5.4 公告发布与富文本内容的处理公告详情如果只是纯文字演示效果会很单薄。如果你打算支持富文本展示前端可以用小程序的rich-text组件后端在公告表加一个content_html字段存富文本内容。要注意的是富文本里的图片通常是网络URL如果图片来自其他网站有防盗链的话就会显示失败要么把图片上传到自己服务器要么在发布公告时做好图片的处理。这个功能我建议作为答辩加分点做但不要放太多时间富文本编辑器集成和维护的成本不高但烦人点到为止即可。6. 常见问题与排坑实战6.1 我在调试中踩过的典型问题不管你是照着这篇文章一步步做还是直接跑这套源码下面这些坑大概率会碰到。问题现象根本原因解决方案小程序请求后端接口报不在以下request合法域名列表中开发者工具默认校验HTTPS域名开发阶段在工具详情里勾选不校验合法域名上线前必须配置HTTPS域名后端返回的时间显示为一串数字JSON序列化默认把Date转成了时间戳在日期字段上加JsonFormat(patternyyyy-MM-dd HH:mm:ss)表单提交中文乱码缺少编码过滤器web.xml里配置CharacterEncodingFilterforceEncoding设为true跨域CORS报错小程序端一般不走浏览器跨域但管理后台网页版会SpringMVC配置CorsFilter允许指定来源和请求头上传图片后访问404上传目录和静态资源映射没对上配置文件里新增/upload/**映射到物理路径下拉刷新出现页面闪跳setData传了冗余大数据只更新变化的数据片段避免整页数据重刷重复点击缴费按钮生成多条记录并发未处理前端按钮loading后端对账单状态做前置校验重启Tomcat后上传图片丢失文件写在了临时目录配置独立磁盘目录保存上传文件6.2 排查技巧实录第一个技巧看后端日志要有系统日志框架而不是System.out。把log4j或logback配上记录每次请求的接口名、参数、耗时、错误栈遇到问题翻日志比瞎猜高效一百倍。我在Controller层加了一个简单的AOP日志切面把所有请求和响应都打出来联调的时候对方说我这边报错了我直接看日志就能定位是他参数传错了还是我代码写错了。第二个技巧小程序端调试时善用Network面板。很多人一遇到问题就在代码里疯狂console.log其实先看Network面板里的请求列表状态码、耗时、返回数据一目了然。90%的前后端联调问题在Network面板里都能看出端倪。第三个技巧MySQL开启慢查询日志。虽然项目数据量不大但多表联查没写对的时候慢查询日志能直接帮你定位是哪条SQL最耗时。把my.ini里的slow_query_log和long_query_time2改一下重启MySQL就生效成本极低收益很高。6.3 部署时需要留心的细节本地跑通只是第一步实际部署又是另一层世界。如果有一台云服务器我建议后端用Tomcat MySQL的常规部署方式环境和工具链都成熟资料也好找。前端小程序在开发者工具里上传代码后去微信公众平台提交审核审核期间做一个体验版给导师演示够用了。部署有几个细节容易踩数据库连接串记得加上useUnicodetruecharacterEncodingutf8useSSLfalse不然中文乱码和SSL握手问题够你喝一壶。服务器放行端口时除了Tomcat默认的8080还要放行MySQL的3306注意3306不要对所有IP开放用防火墙白名单限制来源安全上稳妥一点。数据库每天做一次定时备份用mysqldump加crontab脚本里保留最近7天的备份文件清理旧备份的逻辑也要写不然磁盘会不知不觉被填满。HTts证书能用云服务商免费证书搞定的就别自己折腾证书签发省下来的时间拿去调业务。项目跑通之后我还推荐你做三件收尾的事。第一把README写清楚包括技术栈、运行环境、账号信息、部署步骤这份文档既是答辩材料也是给后来者的指南。第二数据初始化脚本里除了必要的表结构补几条演示数据比如三个业主、两套房、几条不同状态的报修单这样截图和演示效果比空表好太多。第三录一个五分钟的演示视频把业主端和管理员的完整操作流走一遍万一现场演示出状况视频就是你的救场备胎。最后说点实在的。我自己做过不少类似的管理系统这套小区的项目从零开始到跑通大概用了两周其中一半时间花在前后端联调和上传图片这种边角问题上。我的建议是不要熬夜赶进度每天固定推进两个小时先搞定登录和业主绑房这条主线再往上面加功能。主线通了其他模块就是套模板的问题。做项目这事儿最怕的不是代码写不出来而是对着空屏幕迟迟不肯动手。你照着这篇文章把表和接口设计先落地后面的事情自然水到渠成。