☰
微信小程序+SSM社区养老服务系统开发毕设实战指南
2026/10/4 1:06:12 网站建设 项目流程

简介:这套毕业设计项目基于微信小程序与SSM框架,构建社区养老服务管理系统,面向计算机相关专业学生,适用于毕业设计、课程设计或工程实训。前端包含微信小程序页面与Vue管理端,后端采用Spring、SpringMVC、MyBatis技术栈,覆盖老人档案管理、服务预约、健康数据、工单处理等核心模块,并配套论文、答辩PPT、开题报告与任务书,可完整支持从立项到答辩的流程。压缩包共1709个文件,以js、java、vue、wxml、wxss、json等源码和配置为主,含png、jpg图片素材、sql数据库脚本及演示视频,整包约88.43MB,目录按源码、文档、答辩材料分类,便于快速定位。源码均经过测试可运行,已有63人学习下载,适合在此基础上二次开发,也可直接作为毕设参考。

1. 为什么“微信小程序社区养老服务系统+SSM”是毕业设计里的稳妥牌

如果你的毕设题目写着“基于微信小程序社区养老服务系统+SSM”,那么这套组合在本科课题里已经算非常稳的选择:前端用微信小程序解决家属和护理员操作门槛低的问题,后端用 SSM 处理管理员对工单和老人档案的维护,业务链条清晰,论文好写,答辩也容易让老师听明白。这类课题包通常会把源码、论文、答辩PPT、开题报告和任务书一起打包成 zip 交付,但拿到手最常见的困境不是功能不够,而是跑不起来、讲不清、答不上追问。这篇笔记会顺着业务建模、数据表、代码闭环和排错清单一条线展开,目标是让你拿到任何同类课题包后,能在一周内把它真正跑通并讲圆。

2. 先把业务边界定下来:角色、核心流程与数据表设计

这一章不写代码,先做一件很多人跳过但最后返工最多的事:定业务边界。社区养老服务系统最容易犯的错是功能越加越多,最后论文里业务图画不圆,答辩被“这个功能谁用、流程怎么闭环”问住。先把角色、流程和数据表定清楚,后面所有代码都是往这张骨架上填肉。

2.1 用户角色怎么分:管理员、护理员、家属的三方视角

社区养老系统的使用者不是只有“管理员”和“老人”两方。常见的合理设计是三到四个角色,其中老人本人通常不直接操作小程序,而是由家属代下单,护理员接单执行,管理员在后台做审核和统计。

管理员负责维护服务项目、录入并更新老人档案、审核订单、指派护理员、查看服务数据统计。护理员在小程序端看到分配给自己的工单,执行后标记完成。家属的角色是替老人预约服务、查看服务进度、对已完成的工单做评价。有的系统还会把“老人”单独做成一个受监护档案对象,挂在家属账号下,而不是一个可登录角色,这样更贴近社区养老的真实场景。

这个角色划分直接决定后续的表结构和接口设计:账号表里放一个 role 字段区分管理员、护理员和家属;老人档案表通过家属账号的 user_id 关联;工单表再关联到护理员账号。不要把所有功能塞进一个登录用户里,否则后面写权限拦截和页面显示时会非常痛苦。我在带这类课题时,一般会在开题阶段就把这三类角色的主流程走一遍,顺着角色画用例图,越早画越省事。

2.2 核心业务流程:从服务预约到回访完成的闭环

社区养老和普通外卖点单系统最大的区别在于:服务不是“下单即完成”,它中间有审核、指派和执行环节。典型主流程是这样的:

家属登录后选择服务项目,比如助餐、保洁、陪诊、康复护理,提交预约时间与地址;管理员审核这条预约,通过后生成服务工单并指派给某位护理员;护理员在小程序端看到待接单的工单,确认接单,服务完成后点击完成;家属可以对完成的服务进行评价,管理员再根据评价做回访记录。

工单状态在这个流程里逐步流转,我建议定义成 0 待审核、1 待服务、2 服务中、3 已完成、4 已取消、5 已回访。很多课题包源码里只写“状态”字段,没有状态机说明,结果就是代码里各种数字散落,自己想改都不知道从哪里改。把状态机画成论文里的一张图,再对应到工单表的一个 int 字段,既好写代码也好答辩。

这里还有一个容易被忽略的点:服务时间冲突。同一个老人在同一时间段只能有一个未完结的工单,这个校验放到 Service 层做,不能只靠前端禁选时间。类似的业务规则在下一章的代码里会体现出来。

2.3 数据表设计与关键字段参考

社区养老系统的表不用设计太多,核心五张表就够了。下面这张表是我常用的一套基础设计,既覆盖主流程,又不会让开题报告显得臃肿。

表名作用关键字段
sys_user账号表id, username, password, role, real_name, phone, status, create_time
elder_info老人档案id, user_id(家属账号), name, gender, birthday, id_card, address, health_status, contact_phone
service_item服务项目表id, name, category, price, duration, description, cover_url, status
service_order服务工单表id, order_no, elder_id, item_id, appoint_time, address, worker_id, status, remark, evaluation, create_time
visit_record回访记录表id, order_id, visit_time, content, operator_id

账号表里的 password 字段,建议论文里写“使用 MD5 加盐存储”,哪怕课题包源码里是明文,你也要在论文的改进点里提一句,答辩会显得你懂安全。老人档案表挂在家属账号下,也就是 elder_info.user_id 指向 sys_user.id,这样家属可以管理多个老人,比如同时给父母和岳父岳母下单。工单表里的 order_no 用时间戳加随机数生成,作为展示给用户看的单号,不要直接用自增 id 当单号。

数据库统一用 utf8mb4,别用 utf8,否则老人姓名里生僻字或表情符号会插入失败。这个坑我在第一次做同类系统时踩过,现象是前端提交后接口报错,但看日志完全看不出来是编码问题。后续所有表的 create_time 都建议用 datetime,不要用 varchar 存时间,否则按时间筛选工单时会非常别扭。

3. 先把最小闭环跑起来:小程序登录、token 与第一个查询接口

很多人在这一步翻车:后端工程建好了,小程序也建好了,但两边对不上。问题往往不是某个技术不会,而是没有一个“最小闭环”的概念。所谓最小闭环,就是不碰任何业务功能,先让小程序通过 wx.request 调通后端一个登录接口,拿到 token,再带着 token 查询当前用户信息。这个闭环通了,后续所有功能都是套路。

3.1 后端工程骨架:Maven 依赖与 Spring/MyBatis 配置

后端我建议直接用单模块 Maven 工程,结构按 controller、service、mapper、entity、util 分包,不要拆多模块,毕业设计没必要。pom.xml 里核心依赖如下:

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.16</version> </dependency> </dependencies>

版本号只作参考,以你本机 JDK 版本和项目实际情况为准。Spring 5.x 配 JDK 8 或 11 都没问题,MySQL 驱动 8.x 可以同时兼容 MySQL 5.7 和 8.0。这里没列 Spring AOP 和 Jackson,因为 spring-webmvc 已经传递依赖了 Jackson,AOP 用到的 spring-aspects 有需要再补。

数据库连接配置写在 jdbc.properties 里,然后被 Spring 的 XML 读取。常见的坑是 MySQL 8.x 的驱动类和时区参数:驱动类是 com.mysql.cj.jdbc.Driver,URL 必须带 serverTimezone,否则会报 CST 时区错误。

jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/community_care?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false jdbc.username=root jdbc.password=123456

applicationContext.xml 里配置数据源、SqlSessionFactory 和 Mapper 扫描,spring-mvc.xml 配置注解驱动和 Controller 扫描。有两个细节值得注意:第一,jdbc.url 里的 & 符号在 XML 中必须转义成 &,否则 Tomcat 启动时配置解析直接报错;第二,MyBatis 的 XML Mapper 文件如果放在 resources 目录下,要保证 mapper-locations 路径写对,我一般写成 classpath:mapper/*.xml。

3.2 初始化数据库:建表与插入一个管理员账号

在 MySQL 里新建数据库,然后执行建表语句。为了最小闭环,先只建 sys_user 这一张表就够。

CREATE DATABASE IF NOT EXISTS community_care DEFAULT CHARACTER SET utf8mb4; USE community_care; CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, role VARCHAR(20) NOT NULL, real_name VARCHAR(50), phone VARCHAR(20), status TINYINT DEFAULT 1, create_time DATETIME ); INSERT INTO sys_user (username, password, role, real_name, phone, status, create_time) VALUES ('admin', 'e10adc3949ba59abbe56e057f20f883e', 'ADMIN', '系统管理员', '13800000000', 1, NOW());

这里 password 存的是“123456”的 MD5 值。为什么要提前做这一步:后端登录校验直接比对加密后的字符串,比明文存库更容易在论文里解释安全设计。如果课题包源码里是明文登录,你也建议改成这种形式,改动成本很低。

3.3 小程序端工程初始化:测试号、导航栏与全局配置

微信开发者工具里新建项目时,AppID 可以选择“测试号”,不需要注册小程序账号,真机预览时同样能用。项目创建后先确认 app.json 的基础配置,导航栏标题和样式在 window 里统一控制。

{ "pages": [ "pages/login/login", "pages/index/index" ], "window": { "navigationBarTitleText": "社区养老服务", "navigationBarBackgroundColor": "#4A90D9", "navigationBarTextStyle": "white" } }

如果你要做自定义导航栏,也就是把 navigationStyle 设为 custom,那就不要写死顶部高度。不同机型胶囊按钮位置不一样,iPhone 和 Android 的刘海屏差异很大。常见的做法是拿胶囊按钮的 boundingClientRect 动态计算导航栏高度,存到 globalData 里再让每个页面读取。这个点经常出现在微信小程序顶部导航栏高度的搜索话题里,实际开发中很多同学在这里反复调样式。

app.js 里可以放全局变量,比如后端接口的 baseURL。本地联调时建议用局域网 IP,而不是 localhost,因为真机预览时 localhost 指向的是手机自己,不是你的电脑。

App({ globalData: { baseURL: 'http://192.168.1.100:8080', token: '' } })

这里 baseURL 换成你自己电脑的局域网 IP,端口要和 Tomcat 的端口一致。注意后面不要带斜杠,小程序端封装 request 时再拼接路径。

3.4 登录接口与 token 传递的最小闭环代码

后端先写一个简单的登录 Controller,接收用户名和密码,校验通过后生成一个 UUID 作为 token,存到一个静态的内存 Map 里。

@RestController @RequestMapping("/api/user") public class UserController { @Autowired private UserService userService; @PostMapping("/login") public Result<UserVO> login(@RequestBody LoginDTO dto) { User user = userService.login(dto.getUsername(), dto.getPassword()); String token = UUID.randomUUID().toString().replace("-", ""); TokenStore.put(token, user.getId()); UserVO vo = new UserVO(); vo.setToken(token); vo.setUsername(user.getUsername()); vo.setRole(user.getRole()); vo.setRealName(user.getRealName()); return Result.success(vo); } }

LoginDTO 用 @RequestBody 接收 JSON,所以前端 wx.request 里要设置 header 的 content-type 为 application/json。TokenStore 是一个静态 ConcurrentHashMap,key 是 token,value 是用户 id,这样后续拦截器从 token 反查用户时不需要查库,速度也快。这个方案不是生产级方案,但作为毕业设计足够讲清楚,论文里也能顺带提一句 Redis 的替代方案。

小程序端的请求封装是保证后续开发效率的关键。我一般会封装一个 request.js,统一处理 baseURL、token 注入和错误提示。

const request = (url, method, data) => { const app = getApp(); return new Promise((resolve, reject) => { wx.request({ url: app.globalData.baseURL + url, method: method, data: data, header: { 'Content-Type': 'application/json', 'token': app.globalData.token }, success: (res) => { if (res.data.code === 0) { resolve(res.data.data); } else { wx.showToast({ title: res.data.message, icon: 'none' }); reject(res.data); } }, fail: (err) => { wx.showToast({ title: '网络请求失败', icon: 'none' }); reject(err); } }); }); };

这段封装的逻辑是:所有后端返回结构统一为 Result 对象,code 为 0 表示成功,非 0 直接弹 toast。前端页面只需要关心 data 部分,不用每个页面都写一遍失败处理。token 从 header 里传递,后端拦截器从 header 读取,这也是目前最通用的小程序与 SSM 后端交互方式。我在做这类课题时,通常还会在登录成功后把 token 写入 wx.setStorageSync,这样重新打开小程序不用重新登录,只需要在 app.js 的 onLaunch 里读取并恢复。

4. 把服务预约做成能交付的功能:Controller、Service、Mapper 三层调用链

最小闭环通了之后,接下来就是填充一个完整业务功能,我会选择“服务预约”来做范例。因为它贯穿三层架构,包含事务、校验、动态 SQL 和状态更新,是论文里最能体现技术含量的部分。

4.1 统一返回体与 Controller 层设计

SSM 项目里每个接口都返回同一种结构,前端封装才好写。Result 类我通常放在 common 包里,包含 code、message、data 三个字段。

public class Result<T> { private int code; private String message; private T data; public static <T> Result<T> success(T data) { Result<T> r = new Result<>(); r.code = 0; r.message = "success"; r.data = data; return r; } public static <T> Result<T> error(String message) { Result<T> r = new Result<>(); r.code = 500; r.message = message; return r; } }

这里看到 Result 的静态方法直接生成返回对象,避免每个 Controller 都 new 一次。code 用 0 表示成功,500 表示业务失败,和 HTTP 状态码区分开,因为 HTTP 可能 200 但业务失败。前端封装里已经约定 code 非 0 就提示 message,所以后端所有业务异常都必须通过 Result.error 返回,而不是直接抛异常给前端。

OrderController 的写法要注意路径设计和参数校验。创建预约的接口用 POST,路径用 /api/order/create,接收的字段包括 elderId、itemId、appointTime、address 和 remark。

@RestController @RequestMapping("/api/order") public class OrderController { @Autowired private OrderService orderService; @PostMapping("/create") public Result<OrderVO> create(@RequestBody @Valid OrderCreateDTO dto) { return orderService.createOrder(dto); } }

这里把业务逻辑全部放到 Service 层,Controller 只做参数接收和返回值转发。假如需要权限控制,可以在这里加注解或者依赖拦截器校验角色。不要把 SQL 拼接写进 Controller,这是分层架构最基本的要求,也是论文里可以展开说设计思想的地方。

4.2 Service 层事务与业务校验:排期冲突怎么拦

Service 层是业务规则的集中地。创建订单时至少做三件事:校验老人档案存在、校验服务项目处于上架状态、校验同一老人同一时段没有未完结工单。

@Service public class OrderService { @Autowired private ElderInfoMapper elderInfoMapper; @Autowired private ServiceItemMapper serviceItemMapper; @Autowired private OrderMapper orderMapper; @Transactional(rollbackFor = Exception.class) public Result<OrderVO> createOrder(OrderCreateDTO dto) { ElderInfo elder = elderInfoMapper.selectById(dto.getElderId()); if (elder == null) { return Result.error("老人档案不存在"); } ServiceItem item = serviceItemMapper.selectById(dto.getItemId()); if (item == null || item.getStatus() != 1) { return Result.error("服务项目不可预约"); } int count = orderMapper.countBusyOrder(dto.getElderId(), dto.getAppointTime(), dto.getAppointTime()); if (count > 0) { return Result.error("该时段已有预约"); } Order order = new Order(); // 拼接订单号并插入 order.setOrderNo(generateOrderNo()); order.setElderId(dto.getElderId()); order.setItemId(dto.getItemId()); order.setStatus(0); orderMapper.insert(order); return Result.success(OrderVO.from(order)); } }

@Transactional 的作用是整个方法要么全部成功,要么全部回滚。这里 createOrder 插入订单时依赖前面的校验结果,如果插入时报错,前面所有已经执行的操作都不留痕。rollbackFor 指定异常触发回滚。

时间冲突校验是这类业务里最容易漏掉的地方。countBusyOrder 的 SQL 在 Mapper XML 中实现,核心是查同一位老人、同一个预约时间、并且状态不是已取消的订单数量。注意这里只用了等值判断。如果系统要支持更灵活的时间段重叠判断,就得把预约时间设计成开始时间和结束时间两个字段。我在做这类毕业设计时通常建议用等值时间即可,论文里提一句“支持时间冲突检测”就够了,不要过度设计。

4.3 Mapper 层动态 SQL 与分页:按状态筛选工单

Mapper 层要写动态 SQL 的场景特别多,比如后台工单列表需要按状态和时间筛选。用 MyBatis 的 和 标签是最常见的做法。

<select id="selectOrderList" resultType="com.demo.entity.Order"> SELECT * FROM service_order <where> <if test="status != null"> AND status = #{status} </if> <if test="startTime != null"> AND appoint_time &gt;= #{startTime} </if> <if test="endTime != null"> AND appoint_time &lt;= #{endTime} </if> </where> ORDER BY create_time DESC </select>

这里有两个细节。第一,> 和 < 是 XML 转义,不能直接写大于号小于号,否则 XML 解析报错。第二, 标签会自动去掉第一个 AND,所以每个条件都写 AND 是安全的。如果不动态拼 SQL,用注解方式写死 SQL 会需要写多个方法,动态 SQL 一条语句就解决。

分页可以引入 PageHelper,配置十分简单。先加 Maven 依赖,再在 applicationContext.xml 里配置拦截器插件:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:mapper/*.xml"/> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <value> helperDialect=mysql reasonable=true </value> </property> </bean> </array> </property> </bean>

使用 PageHelper 的时候,只要在 Service 层查询前调用 PageHelper.startPage(pageNum, pageSize),紧接着的第一条 SQL 就会自动带上 limit 分页。这个机制有一个坑:startPage 必须紧挨着查询语句,中间不能穿插其他查询,否则分页会作用到错误的 SQL 上。很多同学遇到“分页不生效”的问题,八成是这个原因。

4.4 状态机跑起来:接单、完成、回访的防重复操作

工单从待审核到已完成,每一步都是状态更新。最容易出问题的是“重复点击”导致状态被覆盖。比如护理员连续点了两次“接单”,第二次操作应该被拦截。后端解决这个问题不需要复杂的锁,用一条带条件的 update 就能实现。

@Update("UPDATE service_order SET status = #{targetStatus} WHERE id = #{id} AND status = #{expectStatus}") int updateStatus(@Param("id") Integer id, @Param("targetStatus") Integer targetStatus, @Param("expectStatus") Integer expectStatus);

这条 SQL 的含义是:只有当当前状态等于期望状态时,才把状态改为目标状态。护理员接单时,expectStatus 传 0(待审核),targetStatus 传 1(待服务),如果 update 返回的行数是 0,说明工单已经被别人接走或状态早就变了,Service 层就返回“操作失败,请刷新后重试”。

这个写法本质上是一种乐观锁,不用给数据库加悲观锁,也避免并发下状态错乱。论文里甚至可以把这个设计单独拿出来讲,名字就叫“基于状态条件的防重复更新机制”。所有状态变更接口都遵循这个模式,你会发现系统的逻辑混乱问题少很多。

5. 常见问题排查:真机预览、日期格式、图片上传与答辩追问

这章写的是我在调试这类项目时反复遇到的真实问题。每一条都有现象、原因、解决三个环节,你可以直接当成排查手册来用。

5.1 开发者工具正常,真机预览却请求失败

现象:微信开发者工具里接口请求都通,点击真机预览后,页面能打开但所有数据加载不出来,控制台提示 request 请求失败。原因分两种:一是开发者工具默认勾选了“不校验合法域名”,真机环境不会跳过这个校验;二是你用的是 localhost 或 127.0.0.1,手机根本访问不到你电脑的地址。解决:本地联调用局域网 IP,并在开发者工具中勾选“不校验合法域名”只对开发版和体验版生效,发布前必须在小程序管理后台配置 request 合法域名,域名需要是 HTTPS 且备案过的。如果你把系统同时做成了一个 H5 版本,还要注意普通链接和业务域名也要在后台配置,否则微信里打开 H5 同样受限。

5.2 小程序传时间,后端收到后变 null 或者报 400

现象:前端表单里选了 2024-05-01 10:00:00,后端 @RequestBody 接收时报 HTTP 400,或者字段为 null。原因:Spring 默认的 JSON 反序列化不认这个时间格式。解决:在实体类的日期字段上加 @JsonFormat 注解,同时把时区指定为 GMT+8,否则在服务器上会出现 8 小时偏移。

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date appointTime;

另一个容易翻车的位置是 MySQL 驱动对时间类型的处理,如果 entity 里用 String 接收时间,随后拼到 SQL 里比较,那是隐患。建议统一用 Date 类型 + @JsonFormat 转换。

5.3 图片上传成功,前端 image 标签却加载不出来

现象:wx.uploadFile 返回了路径和文件名,数据库也存了,但小程序端 显示空白。原因通常是后端返回的是一个像 /upload/xxx.jpg 的相对路径,而小程序端 src 写成了直接拼这个相对路径,没有拼接域名。解决:后端把上传文件的保存路径映射成静态资源路径,前端统一用 String.format('%s%s', baseURL, url) 拼接完整地址。可以顺手做一个上传目录统一管理工具,在 applicationContext.xml 里配置 resource handler 把磁盘目录映射到 /upload/** 路径,这样前端拿到的就只是一个相对路径,拼接规则全部收敛到一处。

5.4 论文查重改稿后,图表编号和交叉引用全乱了

现象:论文里写了“如图 3-2 所示”,查重后在 Word 里删改段落,图号引文对不上了,手动改了几次仍然有漏。原因:图表编号是纯手打文本,没有使用 Word 的题注和交叉引用功能。解决:所有图、表、公式的编号一律用“插入题注”,正文引用用“交叉引用”,标题用多级列表关联样式。这样只要按 Ctrl+A 后 F9 更新域,所有编号自动纠正。这个习惯在写开题报告时就要建立,不要等到查重结束后再改。

5.5 答辩被问“为什么用 SSM 不用 Spring Boot”怎么答

现象:答辩老师看完项目后问了这句,支支吾吾答不上来。原因:没有提前预设技术选型问题。这不是代码问题,而是思路问题。解决:回答从三个方面组织。第一,课题要求是基于 SSM 框架,教学体系和考核目标围绕手写配置和三层架构理解;第二,SSM 能清晰看到 Spring IoC、SpringMVC 和 MyBatis 三者如何协作,避免 Spring Boot 自动配置把关键细节隐藏掉;第三,承认技术选型可以升级,并主动说如果重新做,会基于 Spring Boot 重构,但业务模型和数据库设计完全复用。这个回答既守住课题要求,又展示了你对技术演进有认知。

6. 让作品更有说服力的最后一步:定时回访提醒、列表加载更多与自检清单

如果你的开题报告和任务书里写了“服务回访”和“数据统计”,但代码里只是简单的一个表单,那工作量看起来明显不足。这一章写三个能快速补进项目、又容易在答辩时展示的增强点。

6.1 用 @Scheduled 做一个回访提醒任务

服务完成后,系统应该提醒管理员做回访。Spring 支持在 SSM 项目里开启定时任务。

@Component public class VisitRemindTask { @Autowired private OrderMapper orderMapper; @Scheduled(cron = "0 0 9 * * ?") public void remind() { List<Order> list = orderMapper.selectNeedVisitOrder(); for (Order order : list) { // 生成回访提醒记录,可用日志输出便于演示 System.out.println("需要回访的工单:" + order.getOrderNo()); } } }

spring-mvc.xml 里需加上<task:annotation-driven/>。cron 表达式里固定每天 9 点执行,注意服务器时区问题,如果部署在境外云主机,早上 9 点可能跑到北京时间下午。

6.2 小程序端列表加载更多:触底刷新与下拉刷新

后台工单列表如果一次性返回几十条,小程序端体验会差。实现触底加载的标准方法是页面 json 里开启 onReachBottom,代码里记录当前页码。

onReachBottom() { const nextPage = this.data.page + 1; this.loadOrderList(nextPage); }

同时开启下拉刷新后要调用 wx.stopPullDownRefresh。之前见过一个课题包里用的是“加载更多”按钮而不是触底加载,答辩老师问了一句为什么不用触底,学生答不上来。如果你准备用 uniapp 重写或打包,还要注意小程序包体积限制是 2MB,超出后需要通过分包或者压缩图片源码方式处理。这些都是加分项。

6.3 数据流自检清单

编号检查项
1家属能登录并看到老人列表
2提交预约后,管理员后台看到待审核工单
3审核通过后,护理员账号能看到工单
4护理员接单、完成,家属端状态同步变化
5完成后生成回访提醒记录

这套系统的价值恰恰在角色流转上。以前帮朋友过一遍类似的课题包,印象最深的是他工单表的时间字段是 varchar,服务顺序靠字符串比较,答辩时被问得接不上来。很多坑不是代码写不出来,而是配置和约定没对齐。你动手时先把最小闭环跑通,再按这张清单走一遍数据流,最后把状态机、事务和权限这几个点讲透,整套工作量和答辩准备工作就都到位了。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询