SpringBoot社区智慧养老系统开发实战:从数据库设计到权限与告警实现 这两年我前前后后做过几个基于 SpringBoot 的管理系统但真正让我觉得这系统做出来是给人用的还是这个社区智慧养老系统。起因很朴素有次我陪家里长辈去社区服务站办高龄津贴看到工作人员还在用 Excel 翻老人的健康档案几万个格子眼睛都快看瞎了。旁边一台血压计测完数据全靠手抄家属打电话问老人今天血压怎么样对方得翻五分钟纸质记录才能答上来。回来后我就想能不能用 SpringBoot 把这事串起来老人档案、健康数据、服务工单、告警通知全部数字化。于是就有了这套基于 SpringBoot 的社区智慧养老系统。它会解决社区养老服务站最头疼的三件事老人底数不清、服务过程无记录、健康异常靠人盯。适合刚学完 SpringBoot 想拿真实项目练手的人也适合正在构思毕业设计的同学以及想了解这类系统怎么从需求落到代码的开发者。这篇就把完整的技术选型、数据库设计、核心模块实现和上线前踩过的坑一条条讲清楚。1. 社区养老的业务盘子究竟有多大需求剖析与模块边界想写代码之前先把业务看清楚。很多做管理系统的人犯的第一个错就是上来就建表结果表建了二三十张业务逻辑却是乱的。智慧养老系统看起来是管理老人信息实际上它是一个典型的社区级综合业务平台涉及的人员、事项、流程相当繁杂。1.1 系统到底要管哪些事我先后走访了几个社区服务站跟一线社工聊完把业务归纳为四条主线第一老人全生命周期档案。这个不只是姓名、电话、住址还包含健康等级评估自理、半失能、失能、是否独居、紧急联系人、补贴类型、既往病史、用药情况等。这些字段不建好后面服务派单、告警判断都无从谈起。第二健康数据采集与风险预警。社区里有一部分老人配备了智能手环、血压计、血糖仪设备会定时把数据传到平台。平台要做的不只是存下来而是根据阈值判断是否异常异常了通知谁、以什么方式通知、多长时间没响应要升级处理。第三服务工单流转。助餐、助浴、保洁、陪诊、代买药这些服务的预约、派单、执行、回访、评价要形成一个完整闭环。这个环节最考验数据库状态设计因为工单状态一旦设计乱了统计报表全是错的。第四补贴与费用管理。高龄津贴、护理补贴、服务费用减免牵扯到审批流程。这部分业务规则因地区而异所以系统设计上要留扩展位不能写死。四条主线理完之后核心用户角色也浮现出来了系统管理员管账号和配置、社区工作人员社工/网格员日常操作主体、服务人员承接工单的人、老人家属查看老人情况、接收告警、老人本人通过终端/小程序简易交互。家属这个角色最容易漏掉但恰恰是养老系统最有价值的服务对象之一。1.2 一期功能边界哪些必须做哪些放二期需求调研出来能列的功能两三页纸都写不完。如果全做工期会失控所以我做了一期和二期切割。一期必须做的是闭环核心老人档案管理、健康档案管理、服务工单管理、告警管理、账号权限管理、数据统计看板。这六个模块能支撑社区服务站跑通建档—监测—服务—回访的完整链路。二期再考虑家属/老人移动端小程序、App用来查档案、接收消息、IoT 设备自动接入与心电图等多维数据、政务对接与第三方支付对账。这些东西不是不重要而是可以等业务跑起来之后用实际数据反推需求再设计比一次性做一堆没人用的功能强得多。这里我总结了一张角色功能矩阵设计菜单和权限时直接照着分功能模块系统管理员社区工作人员服务人员老人家属老人档案查看/导出新增/编辑/查看仅查看被服务对象仅查看本人亲属健康档案与告警查看全部查看/处理告警不涉及接收通知/查看服务工单查看/统计创建/派单/回访接单/提交完成查看进度账号权限完整管理查看本人不涉及不涉及统计看板全部数据本网格数据不涉及不涉及模块边界清晰之后建表和写接口才有了依据。接下来就是技术选型的问题。2. 技术选型不是越新越好基于 SpringBoot 的这套组合为什么够用技术选型这件事我的态度一直很务实先看项目规模和运行环境再决定用什么。社区智慧养老系统的典型部署环境是街道/社区的一台普通服务器预算不高网络环境一般并发量不大一个街道几百个并发就到顶了但业务逻辑复杂、角色权限多、后续可能有移动端和 IoT 设备接入。这种场景下SpringBoot 单体应用就是最合适的形态。2.1 框架选型的取舍逻辑我用的版本组合是SpringBoot 2.7.18 JDK 1.8 Maven 3.8。有人会问都什么年代了还用 JDK 8原因很实在很多社区机房里还有老系统运维方的 JDK 环境不一定是新的JDK 8 的兼容性最稳。而且 SpringBoot 2.7 是 2.x 生命周期里最后一个支持 JDK 8 的稳定版本社区资料多遇到问题一搜全有答案。如果你是用 JDK 17 起步那可以直接上 SpringBoot 3.x但注意 MyBatis-Plus、某些短信 SDK 的兼容版本要对应升级不然启动直接报错。我个人建议除非你明确知道要在新环境下部署否则SpringBoot 2.7.x 是最保守稳妥的选择。持久层我选了 MyBatis-Plus不是 JPA。理由有三点社区养老系统有大量多表联查和部分字段更新的操作MyBatis-Plus 的 LambdaQueryWrapper 写起来直观复杂 SQL 又可以手写灵活度高。团队里新人上手快MyBatis 系是国内 Java 开发者的基本功底。分页插件非常成熟列表页几乎都要分页用它省很多事。JPA 在简单的 CRUD 上确实优雅但在复杂查询和多人协作时Hibernate 的实体映射和懒加载问题容易变成坑。这个项目业务规则复杂、报表查询多选 MyBatis-Plus 更合适。2.2 权限框架、缓存与其他组件权限这块我用的是Spring Security JWT。系统里有五类角色菜单权限、按钮权限、数据权限都要控制Spring Security 的过滤器链机制能很好地承担这个职责。JWT 做无状态登录接口返回一个 token前端统一携带不需要在服务端维护 session比较省事。Redis 在这个系统里不是必需品但用了之后体验提升明显。我主要拿它做两件事一是缓存菜单权限和老人档案热点数据减少数据库压力二是做接口防重提交的分布式锁后面详细讲。如果服务器实在紧张2G 内存的机器也能跑Redis 和数据都在一台机器上配置好 JVM 参数即可。MySQL 用的 5.7原因是老服务器上现成的版本就是 5.7够用。字段全部用 utf8mb4不然手机端家属名字带个生僻字就存不进去这种事我踩过。文件存储方面一期我没有搞对象存储先做成本地磁盘存储配置一个 upload 目录映射为静态资源。如果以后部署到云上再切换到 OSS接口层预留了 FileService 接口切换成本很低。最终选型清单如下技术点选型选型理由开发框架SpringBoot 2.7.18稳定成熟、兼容 JDK8、资料丰富JDKJDK 1.8兼容老环境部署风险最低持久层MyBatis-Plus 3.5.x灵活、易上手、分页插件好用权限Spring Security JWT多角色菜单按钮数据权限都够用缓存Redis 5.x热点缓存 防重锁数据库MySQL 5.7现有环境、稳定够用接口文档knife4j前后端联调方便、生成的文档可以给社区方留档部署方式单机 JAR systemd运维简单升级只需要换包重启这里多说一句有些团队一上来就想上 Spring Cloud Alibaba、Nacos 注册中心、网关网关的一个社区项目完全没必要。微服务解决的是协作和扩容问题不是业务复杂度问题。单体应用把模块边界划清楚后面真要拆也是水到渠成的事。3. 数据库模型设计老人档案、服务工单与健康数据的关联玩法数据库是整个系统的地基。我在设计表结构时核心思路是档案表做全、业务表做净、关联表做稳。档案表把该有的信息都放进去业务表只管业务字段关联关系用外键逻辑管理实际建表不一定要物理外键但逻辑关系必须明确。3.1 核心表结构拆解先看老人档案表。这个表我命名为elderly_info字段设计是踩过几轮坑之后定下来的CREATE TABLE elderly_info ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, elderly_no VARCHAR(32) NOT NULL COMMENT 老人编号业务唯一, name VARCHAR(64) NOT NULL COMMENT 姓名, id_card VARCHAR(18) NOT NULL COMMENT 身份证号加密存储, gender TINYINT NOT NULL COMMENT 性别 1男 2女, birthday DATE NOT NULL COMMENT 出生日期, phone VARCHAR(20) DEFAULT NULL COMMENT 本人电话, address VARCHAR(255) DEFAULT NULL COMMENT 居住地址, emergency_contact_name VARCHAR(64) DEFAULT NULL COMMENT 紧急联系人姓名, emergency_contact_phone VARCHAR(20) DEFAULT NULL COMMENT 紧急联系人电话, relation VARCHAR(20) DEFAULT NULL COMMENT 与老人关系, health_level TINYINT DEFAULT 1 COMMENT 健康等级 1自理 2半失能 3失能, live_status TINYINT DEFAULT 1 COMMENT 居住情况 1独居 2与家人同住 3其他, subsidy_type VARCHAR(100) DEFAULT NULL COMMENT 补贴类型逗号分隔, medical_history TEXT COMMENT 既往病史, medication_info TEXT COMMENT 用药情况, area_code VARCHAR(20) DEFAULT NULL COMMENT 所属网格/片区编码, status TINYINT DEFAULT 1 COMMENT 状态 1正常 0注销, remark VARCHAR(500) DEFAULT NULL COMMENT 备注, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_elderly_no (elderly_no), KEY idx_area_code (area_code), KEY idx_health_level (health_level) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT老人档案表;身份证号是敏感信息生产环境我做了AES 加密后再入库查询时按需解密展示而不是明文存储。手机号同样处理。这个细节如果漏掉等安全审查的时候会被打回来重做。健康档案表health_record是这样设计的CREATE TABLE health_record ( id BIGINT NOT NULL AUTO_INCREMENT, elderly_id BIGINT NOT NULL COMMENT 老人ID, record_type VARCHAR(20) NOT NULL COMMENT 指标类型blood_pressure/blood_sugar/heart_rate, systolic_pressure INT DEFAULT NULL COMMENT 收缩压(血压), diastolic_pressure INT DEFAULT NULL COMMENT 舒张压(血压), blood_sugar_value DECIMAL(5,1) DEFAULT NULL COMMENT 血糖值, heart_rate_value INT DEFAULT NULL COMMENT 心率, measure_time DATETIME NOT NULL COMMENT 测量时间, source TINYINT DEFAULT 1 COMMENT 来源 1设备 2手动录入, device_no VARCHAR(50) DEFAULT NULL COMMENT 设备编号, is_abnormal TINYINT DEFAULT 0 COMMENT 是否异常 1是 0否, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_elderly_time (elderly_id, measure_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT健康指标记录表;这里的is_abnormal字段是后端计算后落库的不是查询时即时判断。原因有两个一是告警逻辑随时间会调整落库保留当时判断结果后续统计口径一致二是列表页按异常筛选走索引不用每次联表算。3.2 服务工单的状态流转设计服务工单表service_order是这个系统里业务最复杂的表。我设计的字段大致是老人ID、服务类型ID、服务人员ID、预约时间、完成时间、费用、状态、评价内容、创建人、派单时间、回访时间、回访结果。关键是状态字段。我定的状态枚举为0待派单 → 1待服务 → 2服务中 → 3已完成另有4已取消和5已驳回两个终态。流转规则如下创建工单后状态为待派单工作人员指派服务人员时变为待服务服务人员接单可选如果强制派单则跳过后进入待服务服务人员点击开始服务变为服务中完成服务变为已完成创建人可取消未开始的单待派单/待服务状态服务人员也可申请驳回要有驳回原因字段已完成之后由工作人员回访回访结果放在单独的visit_record表不改工单主状态。状态流转必须由代码控制不允许直接 UPDATE 状态。我封装了一个状态校验方法每次更新前检查当前状态是否在合法流转路径上。这里有一个很容易犯的错允许从任意状态改成已完成。这样最后统计服务完成率的时候数据会莫名其妙地好但实际上是脏数据。另外一个容易忽略的点是工单号。工单号要具有可读性比如FW20240512001前缀 FW 日期 当天自增序号。千万别用自增主键直接展示给用户否则社区的工作人员在微信里对工单号的时候根本记不住也看不出是哪天的单子。4. 后端关键模块的实现细节从登录鉴权到健康告警骨架搭好了接下来是血肉。这一节我挑三个最有代表性的模块讲实现多角色登录与权限控制、健康数据异常判定与告警推送、服务工单闭环流转。这三个模块几乎覆盖了系统一半的逻辑复杂度。4.1 多角色统一登录与权限控制的落地系统有五类角色登录入口是统一的。登录成功之后后端返回 JWT tokentoken 里只放用户ID、用户名、角色编码三个核心信息不放大对象。JWT 工具类这样写Component public class JwtUtil { Value(${jwt.secret}) private String secret; Value(${jwt.expire}) private Long expire; public String generateToken(Long userId, String username, String roleCode) { return Jwts.builder() .setSubject(String.valueOf(userId)) .claim(username, username) .claim(role, roleCode) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() expire)) .signWith(SignatureAlgorithm.HS256, secret.getBytes(StandardCharsets.UTF_8)) .compact(); } public Claims parseToken(String token) { return Jwts.parser() .setSigningKey(secret.getBytes(StandardCharsets.UTF_8)) .parseClaimsJws(token) .getBody(); } }注意secret不能写在代码里放在 application.yml 中通过配置项读取生产环境用环境变量注入。这个细节被安全工具扫描出来过所以专门提醒。权限控制我采用的是 Spring Security 过滤器链里加一个 JWT 认证过滤器然后把动态菜单和按钮权限存到 Redis。每次请求进来过滤器解析 token、加载用户权限再通过 Spring Security 的PreAuthorize注解做接口级权限校验。实际项目中很多开发者只做了接口级权限谁能调这个接口而忘了数据级权限同一个接口社工只能看到自己网格的老人。这个坑我在下一节专门讲这里先埋个伏笔。4.2 健康数据异常判定与告警推送的实现健康数据接入有两种方式一是智能设备通过 HTTP 接口直接上报二是社工手动录入。我设计了一个统一的HealthRecordService来做数据接收和异常判定Service public class HealthRecordService { private static final MapString, HealthRule RULE_MAP new HashMap(); static { RULE_MAP.put(blood_pressure, new HealthRule(90, 140, 60, 90)); RULE_MAP.put(blood_sugar, new HealthRule(3.9, 6.1, null, null)); RULE_MAP.put(heart_rate, new HealthRule(60, 100, null, null)); } Transactional(rollbackFor Exception.class) public void handleHealthData(HealthRecord record) { // 1. 查老人档案确认老人存在且状态正常 ElderlyInfo elderly elderlyInfoMapper.selectById(record.getElderlyId()); if (elderly null) { throw new ServiceException(老人档案不存在); } // 2. 根据指标类型做异常判定 HealthRule rule RULE_MAP.get(record.getRecordType()); boolean abnormal judgeAbnormal(record, rule); record.setIsAbnormal(abnormal ? 1 : 0); // 3. 保存健康记录 healthRecordMapper.insert(record); // 4. 如果异常生成告警记录并触发通知 if (abnormal) { generateAlarm(record, elderly); } } private boolean judgeAbnormal(HealthRecord record, HealthRule rule) { switch (record.getRecordType()) { case blood_pressure: return record.getSystolicPressure() rule.getMaxHigh() || record.getSystolicPressure() rule.getMinHigh() || record.getDiastolicPressure() rule.getMaxLow() || record.getDiastolicPressure() rule.getMinLow(); case blood_sugar: return record.getBloodSugarValue() rule.getMaxHigh() || record.getBloodSugarValue() rule.getMinHigh(); case heart_rate: return record.getHeartRateValue() rule.getMaxHigh() || record.getHeartRateValue() rule.getMinHigh(); default: return false; } } }告警生成之后要处理两件事一是写告警记录表设置处理状态为待确认二是通过短信/公众号模板消息通知家属。这块我在做的时候学到的一个经验是告警不是越快越好。如果老人血压 141 就立刻给家属发血压偏高家属一天能收到七八条最后直接免疫了真正严重的告警也被无视。更要命的是半夜给家属发心率65正常之类消息就是骚扰。所以我把告警分等级数值偏离阈值但在安全区间内的判为观察提醒只在系统内生成一条待回访记录超过危险阈值的才触发短信通知家属并转给社工处理。比如高压超过 170 才发短信120~170 之间只是系统提醒。这个阈值规则我放在了数据库配置表里方便业务人员调整而不是写死在代码中。4.3 服务工单闭环的完整实现工单状态流转前面已经说清楚了这里给一个核心代码片段。关键在于封装一个状态校验方法让所有状态变更走同一入口。Service public class ServiceOrderService { Autowired private ServiceOrderMapper serviceOrderMapper; private static final MapInteger, SetInteger TRANSITION_MAP new HashMap(); static { TRANSITION_MAP.put(0, Set.of(1, 4)); // 待派单 - 待服务/取消 TRANSITION_MAP.put(1, Set.of(2, 4, 5)); // 待服务 - 服务中/取消/驳回 TRANSITION_MAP.put(2, Set.of(3)); // 服务中 - 已完成 } Transactional(rollbackFor Exception.class) public void changeStatus(Long orderId, Integer targetStatus, Long operatorId) { ServiceOrder order serviceOrderMapper.selectById(orderId); if (order null) { throw new ServiceException(工单不存在); } SetInteger allowed TRANSITION_MAP.get(order.getStatus()); if (allowed null || !allowed.contains(targetStatus)) { throw new ServiceException(非法状态流转: order.getStatus() - targetStatus); } // 业务校验取消要填原因完成要校验预约时间、服务人等 order.setStatus(targetStatus); order.setUpdateTime(new Date()); serviceOrderMapper.updateById(order); } }这段代码看着简单但它解决了最头大的问题并发状态下重复提交导致的脏数据。比如服务员手速快点两下完成服务如果没有状态校验数据可能被更新两次虽然结果一样但操作日志会多出一条审计的时候说不清。另外我在创建工单的接口上做了防重处理。思路是前端生成一个requestIdUUID后端在 Redis 里以这个 requestId 为 key 设置过期时间 10 秒的锁如果 key 已存在直接拒绝请求返回请勿重复提交。这个方案比数据库唯一索引更灵活因为工单本身没有业务唯一键用 requestId 做防重最干净。5. 真正上线前容易踩的坑数据权限、接口幂等与部署细节这段内容全部来自真实上线过程中踩过的坑。很多系统在 Demo 阶段一切正常一上生产就各种问题根源往往不在功能逻辑而在这几类非功能性设计上。5.1 数据权限为什么光有角色认证还不够社区场景下每个社工只管自己网格的老人。如果账号权限只做到社工可以访问老人档案接口那么任何一个社工登录后都能通过循环遍历 ID 查看全街道的老人数据。这在功能上没错在数据安全和业务规则上是严重缺陷。我的解决思路在用户表加一个area_code网格编码老人档案表也加area_code。查询列表时在 MyBatis-Plus 查询构造器里强制追加数据权限条件public void appendDataScope(LambdaQueryWrapperElderlyInfo wrapper, LoginUser loginUser) { if (loginUser.isAdmin()) { return; // 管理员不过滤 } if (community_worker.equals(loginUser.getRoleCode())) { wrapper.eq(ElderlyInfo::getAreaCode, loginUser.getAreaCode()); } // 服务人员只看到自己被服务对象 if (service_person.equals(loginUser.getRoleCode())) { wrapper.in(ElderlyInfo::getId, getServedElderlyIds(loginUser.getUserId())); } }这里有一个细节差点坑死人服务人员权限有个特殊情况工单创建人可以看全街道老人列表因为要选服务对象但只能看当前是待派单状态的工单。如果一刀切按 area_code 过滤社工根本没法正常建单。所以数据权限要区分三个维度菜单权限能不能进、接口权限能不能调用、数据范围能看哪些行。三者独立控制才能灵活应对真实业务。5.2 接口设计里的几个坑第一个坑是时间字段的时区问题。服务器如果是 UTC 时区数据库连接串没指定serverTimezoneAsia/Shanghai查询出来的时间就会差 8 小时。健康数据差 8 小时意味着凌晨的告警记录被显示成上午家属会误以为老人白天出事直接打电话过来质问。解决方案JDBC 连接串必须带上时区参数应用层统一用LocalDateTime前端展示时再格式化。第二个坑是身份证号校验切忌只验长度。社区录入人员有时候会把 15 位老身份证号、身份证带 X 的都录进来如果只按 18 位校验一批老人都建档失败。我的做法是参照现行身份证编码规则写一个校验工具兼容 15 位和 18 位生日字段直接从身份证里提取避免手工填错。18 位身份证最后一位是校验码算法固定网上有现成实现别自己在纸上推费时间还容易错。第三个坑是导出功能导致服务器内存溢出。列表页导出是标配但直接用 POI 把几万条记录一次性查出来写入 Excel老服务器的内存直接被打爆。我给导出功能加了一个限制单次导出最多 5000 条超过之后提示用户按条件筛选导出。同时用SXSSFWorkbook流式处理一边查一边写内存占用从几百兆降到几十兆。这个优化做完导出功能才算真正能用了。5.3 打包部署与老社区网络环境的适配部署环境通常是一台 2C4G 的云服务器或机房实体机操作系统是 CentOS 7 这种老家伙。打包部署采用最直接的方案Maven 打成可执行 JAR配合 systemd 服务管理。JVM 参数我用的是一组保守配置java -Xms512m -Xmx1024m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m \ -jar smart-elderly-care.jar --spring.profiles.activeprod 这里要特别注意MySQL 连接池、Redis 连接池的最大连接数不要按默认配。默认的 HikariCP 连接池最大连接数是 10看起来够用但社区场景会有集中录入的高峰比如上午社工统一上传数据连接会排队甚至超时。我把连接池最大设到 20最小空闲 5 个性能立刻改善。在 4G 内存的服务器上这个值要配合 JVM 内存一起调不能只追求大。网络环境的适配也是坑。有的社区网络出口会有白名单策略短信服务商的接口域名不一定开放导致告警短信发不出去。我的建议是提前与居委会 IT 确认好服务器出网策略和短信/公众号服务商的支持情况并且做好公告集群发消息失败后的重试与记录谁能看到错误信息谁负责重试都要在系统里留痕。6. 从测试到上线我在实际项目中沉淀的几个额外经验系统开发完成只是第一步真正让它跑起来、跑得好靠的是上线前后的打磨。这部分我写几个不属于代码、但同样影响项目成败的经验。第一上线前一定要找真实社工试用而不是自己拿测试数据自嗨。我当时的做法是找一个关系不错的社区把系统部署到测试环境让两位社工拿真实老人数据试了一周。结果是她们一眼就发现了订单列表缺少按时间倒序排序健康档案录入时缺少最近一次测量时间的快捷筛选这些都是我坐在电脑前想象不出来的真实使用习惯。业务系统的交互细节只有实际使用者能告诉你答案。第二迁移存量数据比开发系统更费时间。社区里有大量存量老人档案纸质表格、Excel、政务系统导出的格式各不相同身份证格式不统一、电话缺位、地址写法混乱。我当时安排了两周左右专门做数据清洗写脚本批量校验、人工核对、按网格分批导入。数据质量决定系统初期体验如果导入 5000 个老人有 300 个身份证格式不对社工一搜名字搜不到信任感瞬间崩塌。第三预留一个扩展字段位。养老政策和社区服务方向变化很快今天补贴类型有三种明天就可能加一个新的。我在老人档案表里预留了ext_infoJSON 字段系统级配置表留了config_key/config_value这样政策调整时不用动表结构改配置就能跟上。第四一定要有除草机制。智慧养老系统的核心数据是老人档案。老人去世、搬离辖区之后status要由社工及时置为注销状态而不是一直占用活动档案。我加了每月提醒功能系统自动筛出一年没有健康记录、没有服务工单的老人生成活跃度预警列表让社工主动核实。这个功能对数据保鲜的帮助极大也是这类系统区别于普通 CRUD 系统的价值所在。最后再说一个理念层面的体会社区智慧养老系统的难点从来不是技术而是对业务细节的捕捉和尊重。你要理解社工的一天是怎么度过的她们早上要批量录入数据中午要给老人打电话约服务下午要上门回访晚上可能还要处理一条健康告警。系统如果能把她们从反复抄写、到处翻数据里解放出来这个 SpringBoot 项目就算真正做成了。技术再炫最终都是为了一句话让老人能得到更及时、更安心的照护。