尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于Android和Spring Boot的自闭症康复训练全流程管理系统设计

发布时间:2026/9/26 0:10:42

资讯中心
01
ARTICLE

基于Android和Spring Boot的自闭症康复训练全流程管理系统设计

基于Android和Spring Boot的自闭症康复训练全流程管理系统设计
1. 选题拆解一个毕业生题目背后的“三层需求”每年的毕业设计选题季“基于 Android 的 XX 管理系统”这类题目都会以不同面貌出现。今年轮到你手里的是“基于 Android 的自闭症康复训练 APP Spring Boot 框架 全流程管理系统”——标题很长关键词很多乍看起来就是个常规的增删改查项目。但真做起来你会发现这个题目的难点不在 CRUD而在“全流程”三个字。自闭症康复训练不是用户打开 APP 做几个题那么简单它牵扯到儿童建档、能力评估、训练计划制定、日常执行、数据记录、效果反馈、计划调整是一条完整业务链路。把这条链路用软件系统支撑起来才是这个毕设的真正价值。1.1 业务层康复训练“全流程”到底指什么我先把这个项目的核心业务拆给你看。自闭症康复训练比较主流的流程大概是这样的儿童建档记录孩子的基本信息、诊断情况、初始能力水平能力评估康复师对孩子在认知、语言、社交、精细动作等维度做评估形成评估报告制定训练计划根据评估结果为每个孩子生成阶段性训练计划计划里有具体的训练任务执行训练任务孩子在家里或机构通过 APP 完成配对、分类、点选、语音跟读等任务或者在线下完成训练后由家长/康复师记录结果数据留痕每次训练的时间、完成度、正确率、情绪表现都要记录下来评估反馈周期结束后再次评估对比前后数据判断训练是否有效再调整下一步计划。这个闭环听起来不复杂但落到系统上就有很多文章可做。“康复训练服务平台”解决的核心问题就是把过去靠纸质表格和口头沟通完成的流程变成数据驱动、多方协同的信息流。你把这个闭环讲清楚毕设的业务层面就立住了。这也是为什么我建议你做系统之前先画业务流程图别急着写代码。哪怕只是在一张白纸上把“谁在什么时间对谁做了什么操作、产生了什么数据”画出来后面建表、写接口、设计界面都会顺很多。很多同学做这个题目做到一半发现要改表结构、改接口根因就是没在第一步理清业务闭环。1.2 用户层谁在用这个系统他们分别在乎什么这个 APP 表面上是给“使用者”用的但“使用者”其实分三类角色而且三类角色的诉求差异非常大康复师治疗师他们要给孩子做评估、制定计划、查看训练结果最关心的是“数据准不准、计划好不好下发、能不能快速看到孩子的进步曲线”家长在家里带孩子做训练最关心的是“任务怎么开始、孩子完成得怎么样、今天练了什么、下次该练什么”而且家长不一定懂专业术语界面必须足够简单系统管理员负责账号管理、基础数据维护、数据统计关心的是系统稳不稳定、角色权限分得清不清楚。很多同学做管理系统只有一个“用户”概念所有功能堆在一起这样答辩时很容易被问倒。我的建议是从一开始就按三种角色设计权限模型和界面哪怕实际只做了两种角色的完整流程也要把角色边界想清楚。这不仅是业务需要也是毕业设计评分表里“系统设计合理性”这一项的得分点。角色权限在 Spring Boot 端用一张角色字段加接口拦截就能解决不必上太重的权限框架。Android 端则根据登录后返回的角色字段动态决定底部导航栏显示哪些页面。这样实现成本低演示效果却非常直观。1.3 技术层标题里的技术栈如何分工再来看题目里这串技术名词Java、Android、Spring Boot、APP、框架。其实分工很清晰Android 端Java 编写面向家长和孩子承担训练任务呈现、交互操作、数据采集展示是“前台”Spring Boot 端Java 编写提供 RESTful API负责任务管理、数据存储、权限校验、报表统计是“后台”MySQL 数据库存放用户、儿童档案、训练计划、训练记录、评估报告等数据两者通过 HTTP JSON 通信。这个组合是 Java 技术栈毕设里最稳的组合之一。原因在于Android 原生开发 Spring Boot 都是 Java 生态你只需要掌握一门语言就能同时驾驭客户端和服务端学习曲线比“Android Node.js”或“iOS Spring Boot”平滑得多。对于毕业设计来说技术栈的一致性直接决定你开发效率的上限。接下来的章节我按照实际开发顺序分别讲服务端设计、Android 端实现、全流程管理闭环和联调踩坑最后说答辩准备。每一部分都会给出可以直接抄作业的表结构、接口定义和实现思路。2. 技术选型与架构决策为什么这个组合能撑起整个毕设选技术栈这件事很多同学是“题目里写了什么就用什么”但如果你能说出“为什么这么选”毕业设计答辩时的底气会完全不一样。这个项目我着重考虑了几个点。2.1 客户端为什么用 Android 原生而不是跨平台方案现在 uni-app、Flutter、React Native 确实很火但毕业设计我依然推荐 Android 原生理由很务实第一跑通一个原生项目的环境成本最低。Android Studio 装好、SDK 配好就能跑网上资料一搜一大把遇到问题排查路径也清晰。跨平台框架虽然一套代码多端复用但环境配置、依赖版本、原生插件这些问题对新手来说反而更容易卡住。第二自闭症康复训练的场景非常依赖触屏交互和系统能力。比如配对训练需要拖动卡片、点击反馈要有震动和音效、语音跟读需要调用系统 TTSTextToSpeech、精细动作训练可能要检测触摸轨迹这些用原生控件和系统 API 实现最直接。跨平台框架遇到这种高频交互场景往往还要写原生插件反而绕远路。第三这个 APP 的核心使用者是家长和孩子Android 设备在家庭中的普及率也足够高选题本身就是 Android 方向用原生实现最契合需求。你不用担心“原生开发没亮点”只要把训练交互做出质感——比如卡片匹配成功时的放大动画、连续完成时的星星奖励、情绪状态选择的大表情按钮——这些体验上的细节就是答辩时的加分项。做原生反而更容易做出细节。2.2 Spring Boot 在项目中扮演什么角色Spring Boot 在这个项目里承担的是典型的服务端职责但有几个点值得展开。首先是接口服务这是最基础的。Android 端所有数据的读写都通过 RESTful API 完成我把接口按业务模块划分认证模块、儿童档案模块、训练计划模块、训练记录模块、评估报告模块。每个模块一组接口路径清晰联调时前端后端都省心。其次是权限控制。Spring Boot 拦截器加 JWTJSON Web Token就可以实现角色校验不用引入 Spring Security 全家桶。你只需要在登录成功后把用户 ID 和角色写进 Token后续请求带着 Token 访问拦截器里解析出来放行或拒绝即可。这个方案代码量少、逻辑直观、答辩也好解释。第三是数据聚合与报表。评估报告、训练统计这类功能需要把多张表的数据按孩子维度聚合。Spring Boot 的 Service 层做业务计算把结果封装成 DTO 返回给 Android 端比在客户端做聚合严谨得多。报表数据尽量服务端算好客户端只负责展示这也是前后端职责分离的体现。表驱动设计也是一个被很多毕设忽略的点。什么算“表驱动”就是数据库表结构是你的系统骨架先定义好表再围绕表写代码。后面我会给出完整的核心表设计这是整个项目最关键的部分比代码更值得你花时间。2.3 整体架构与一次训练的完整数据链路先宏观构建一下系统的整体结构方便你后面理解模块划分。系统分为两层。服务端是 Spring Boot 单体应用连接 MySQL提供 RESTful API内置 JWT 权限拦截器Android 端是原生应用网络层用 Retrofit 封装页面按角色动态展示。两端之间只通过接口通信不共享任何代码和状态。架构上不需要微服务不要分布式单机部署就够毕业设计用了。把这套结构降级理解一个 Tomcat 端口、一个数据库实例、一个 Android APK全链路可以在一台电脑上跑通这对演示和答辩反而是好事。一次典型的训练执行数据是怎么流动的我以“家长带孩子完成一个水果配对任务”为例家长打开 APP登录后进入今日训练列表Android 端调用GET /api/trainings/today?childIdxx服务端从数据库查出今天该执行的训练任务服务端返回任务内容、训练类型、所需素材、目标数量Android 端渲染训练界面孩子开始操作训练结束后家长点击完成Android 端调用POST /api/training/record上报本次训练记录包括完成状态、正确率、用时、孩子的情绪状态服务端写入训练记录表同时更新该计划的累计完成数家长在“成长档案”里可以看到最新一次训练记录和本周训练汇总数据来自GET /api/children/{id}/progress。这个链路把“执行—记录—反馈”串起来了而这个闭环的每个节点都需要对应的表和接口支撑。下面进入服务端核心设计。3. 服务端设计表结构、接口约定与关键实现服务端是整项目的底座。很多同学代码写到一半发现“这个数据没地方存”“那个字段查不出来”绝大多数问题出在表结构设计阶段。我先把核心表给你这些表已经过实际项目的检验直接拿来用不会有大坑。3.1 核心数据模型六张表撑起全流程管理先明确一点不需要设计几十张表六张核心表加两张辅助表足够覆盖这个题目。用户表sys_user字段类型说明idbigint主键自增usernamevarchar(50)登录账号passwordvarchar(100)BCrypt 加密后的密码rolevarchar(20)角色ADMIN / THERAPIST / PARENTreal_namevarchar(50)姓名phonevarchar(20)联系电话create_timedatetime创建时间儿童档案表child_profile字段类型说明idbigint主键namevarchar(50)儿童姓名birth_datedate出生日期gendertinyint性别1男 2女diagnosis_infovarchar(500)诊断情况概述parent_idbigint关联家长用户 IDavatarvarchar(200)头像地址create_timedatetime建档时间一个家长可以绑定多个孩子一个孩子也可以同时有多个康复师跟进所以儿童表和用户表是多对多关联的。这里我加了一张中间表child_therapist_rel字段就三个id、child_id、therapist_id不做冗余设计。训练计划表training_plan字段类型说明idbigint主键child_idbigint关联儿童plan_namevarchar(100)计划名称例如“8月认知提升计划”start_datedate开始日期end_datedate结束日期statustinyint0未开始 1进行中 2已完成 3已暂停creator_idbigint创建人康复师create_timedatetime创建时间训练任务表training_task字段类型说明idbigint主键plan_idbigint所属计划task_typevarchar(20)任务类型MATCH配对/ CLASSIFY分类/ SPEECH语音/ FINE_MOTOR精细动作titlevarchar(100)任务标题content_jsontext任务内容JSON格式存放素材和答案difficultytinyint难度1-3级target_durationint目标时长单位分钟rewardvarchar(100)完成后奖励描述如“奖励一颗星星”order_noint同计划内排序frequencyvarchar(20)执行频率DAILY / WEEKLY / CUSTOMcontent_json 是任务内容的核心字段不同任务类型存不同结构。比如配对任务存素材图片 URL 列表和正确答案语音任务存示范音频和评分提示。用 JSON 字段而不是建一堆任务子表能大幅降低系统复杂度也方便 Android 端解析。训练记录表training_record字段类型说明idbigint主键task_idbigint关联任务child_idbigint关联儿童operator_idbigint操作人家长或康复师completion_statustinyint1完成 2未完成 3超时accuracydecimal(5,2)正确率百分比durationint实际用时单位秒emotion_leveltinyint训练情绪1抗拒 2一般 3配合 4积极remarkvarchar(500)备注record_timedatetime记录时间评估记录表assessment_record字段类型说明idbigint主键child_idbigint关联儿童assessor_idbigint评估人康复师assessment_typevarchar(20)评估类型INITIAL初始/ PERIODIC阶段dimension_scorestext各维度得分 JSON如语言、认知、社交、精细动作summaryvarchar(500)综合评估结论suggestionvarchar(500)下一阶段训练建议create_timedatetime评估时间这套表结构最核心的设计思想是计划是模板记录是事实评估是反馈。计划表达“应该练什么”记录表达“实际练了什么、效果如何”评估表达“数据说明了什么”。三者通过 child_id 关联起来构成完整的业务闭环。3.2 接口约定前后端怎么对齐接口设计遵循一个原则按资源划分按角色控制。我把主要接口列出来你可以直接作为接口文档的骨架。POST /api/auth/login 登录返回 Token 和用户信息 GET /api/children 家长/康复师获取自己关联的儿童列表 POST /api/children 新建儿童档案家长/康复师 GET /api/children/{id} 获取儿童详情 GET /api/children/{id}/progress 获取儿童训练进度汇总 POST /api/plans 新建训练计划康复师 GET /api/plans/{childId} 获取某儿童所有训练计划 GET /api/plans/{planId}/tasks 获取计划内所有任务 GET /api/trainings/today 获取今日训练任务列表 POST /api/training/record 提交训练记录 GET /api/assessments/{childId} 获取儿童评估报告列表 POST /api/assessments 提交评估报告康复师这组接口的路径设计遵循了 RESTful 风格资源名用复数名词操作通过 HTTP 方法区分。你不需要追求严格的 REST 规范但路径一定要直观让答辩老师一眼看出是哪个模块的功能。统一返回结构也很重要。我建议定义一个 Result 类所有接口返回格式一致public class ResultT { private Integer code; // 200 成功500 失败401 未登录 private String message; private T data; public static T ResultT ok(T data) { ResultT result new Result(); result.code 200; result.message 操作成功; result.data data; return result; } public static T ResultT error(Integer code, String message) { ResultT result new Result(); result.code code; result.message message; return result; } }Android 端接这种格式非常省事统一判断 code 是否为 200再解析 data 即可。如果每个接口返回结构都不一样客户端解析逻辑会变得很啰嗦这是很多前后端联调痛苦的根本原因。3.3 关键代码训练记录上报接口实现我挑两个最有代表性的接口展开训练记录上报和今日任务查询这两个是业务闭环的核心也最容易在答辩时被追问。先看训练记录上报。这是一个写接口核心逻辑是校验任务和儿童是否存在、写入记录、更新计划进度。注意我说“核心逻辑是校验”不是“核心逻辑是插入”。很多同学写接口只做 insert完全不校验被答辩老师一追问就答不上来“万一重复提交怎么办”“找不到任务怎么办”。RestController RequestMapping(/api/training) public class TrainingRecordController { Resource private TrainingRecordService recordService; PostMapping(/record) public Result? submitRecord(RequestBody TrainingRecordDTO dto) { // 1. 校验任务和儿童是否存在 TrainingTask task recordService.getTaskById(dto.getTaskId()); if (task null) { return Result.error(500, 训练任务不存在); } ChildProfile child recordService.getChildById(dto.getChildId()); if (child null) { return Result.error(500, 儿童档案不存在); } // 2. 基本参数校验 if (dto.getCompletionStatus() null || dto.getAccuracy() null || dto.getDuration() null) { return Result.error(500, 关键参数缺失); } // 3. 写入训练记录 TrainingRecord record new TrainingRecord(); BeanUtils.copyProperties(dto, record); record.setOperatorId(CurrentUserHolder.getUserId()); record.setRecordTime(new Date()); recordService.save(record); return Result.ok(null); } }这里有三个细节值得注意。第一CurrentUserHolder是我写的一个 ThreadLocal 工具类在 JWT 拦截器里把当前登录用户 ID 放进去Controller 里直接取避免在每个接口都手动传 userId既方便又安全。第二BeanUtils.copyProperties可以少写一堆 setter但这个工具类同名属性才会拷贝DTO 字段名一定要和实体类对齐否则拷不过去。第三服务端时间以服务器时间为准客户端不上传 record_time避免两端时钟不一致这一点很实用。再看今日任务查询。这是一个读接口逻辑上要组合“计划状态 任务列表 完成情况”。我的实现思路是先查当前处于“进行中”状态的计划然后查计划下的所有任务再查出今天的训练记录最后在内存中组装标记每个任务是否已完成。public ListTrainingTaskVO getTodayTasks(Long childId, Date today) { // 1. 查询进行中的计划 LambdaQueryWrapperTrainingPlan planQuery new LambdaQueryWrapper(); planQuery.eq(TrainingPlan::getChildId, childId) .eq(TrainingPlan::getStatus, 1) .le(TrainingPlan::getStartDate, today) .ge(TrainingPlan::getEndDate, today); ListTrainingPlan plans planMapper.selectList(planQuery); if (plans.isEmpty()) { return Collections.emptyList(); } // 2. 获取所有计划下的任务 ListLong planIds plans.stream().map(TrainingPlan::getId).collect(Collectors.toList()); LambdaQueryWrapperTrainingTask taskQuery new LambdaQueryWrapper(); taskQuery.in(TrainingTask::getPlanId, planIds) .orderByAsc(TrainingTask::getOrderNo); ListTrainingTask allTasks taskMapper.selectList(taskQuery); // 3. 查询今天的已完成记录 LambdaQueryWrapperTrainingRecord recordQuery new LambdaQueryWrapper(); recordQuery.eq(TrainingRecord::getChildId, childId) .eq(TrainingRecord::getRecordTime, today); ListTrainingRecord todayRecords recordMapper.selectList(recordQuery); SetLong doneTaskIds todayRecords.stream() .map(TrainingRecord::getTaskId) .collect(Collectors.toSet()); // 4. 组装VO标记完成状态 ListTrainingTaskVO result new ArrayList(); for (TrainingTask task : allTasks) { TrainingTaskVO vo new TrainingTaskVO(); BeanUtils.copyProperties(task, vo); vo.setCompleted(doneTaskIds.contains(task.getId())); result.add(vo); } return result; }注意这里我把“查询计划”“查询任务”“查询记录”分三步做没有写一条大 SQL 去 join原因是表之间的关联复杂度不高分开查询逻辑清晰代码可读性好并且数据量很小性能完全够用。毕业设计阶段代码可读性远比微优化重要。这也是我经常和学生强调的一点不要为了秀技术写出谁都看不懂的代码。3.4 数据库初始化与演示数据一个很实用的小建议在项目里放一个data.sql或启动初始化类预置一组演示数据。包括一个管理员账号、一个康复师账号、一个家长账号、两个孩子的档案、一个进行中的计划、若干训练任务和几条训练记录。这看起来是个细节但对毕设演示至关重要。答辩现场不可能现场注册账号、现场做训练、现场生成报表预置数据能让你 30 秒内进入演示状态避免现场等待。同时也让代码审查时看到系统不是空架子有真实数据支撑。4. Android 端落地康复训练功能的交互实现与细节处理服务端是整个系统的底座但用户真正接触的是 Android 端。康复训练 APP 和普通管理系统最大的区别在于它不只是信息展示工具还要承载孩子实际的操作行为。所以这一端的工作量和难点都比想象中大。4.1 客户端分层与网络层封装Android 端我采用了标准的 MVC Repository 思路没有用比较重的 MVVM 框架因为毕业设计代码的可读性比架构先进性更重要。分层结构如下model数据实体类和服务端 DTO 字段一一对应networkRetrofit 接口定义和网络工具类repository数据仓库负责调接口并处理结果activity/fragment页面层负责绑定数据和渲染界面adapter列表适配器。网络层用 Retrofit OkHttp这是目前 Android 最主流的方案。先说一个容易踩的坑Android 9API 28之后默认禁止明文 HTTP 请求。如果你服务端没有配置 HTTPS 证书直接访问http://192.168.x.x:8080会报错“Cleartext HTTP traffic not permitted”。解决方式是在AndroidManifest.xml的 application 节点加一行application android:usesCleartextTraffictrue ...这样本地联调时才能正常访问测试环境接口。正式商用当然要用 HTTPS但毕设阶段加这一行就够。Retrofit 接口定义示例public interface ApiService { POST(api/auth/login) CallResultLoginVO login(Body LoginDTO dto); GET(api/children) CallResultListChildVO getChildren(); GET(api/plans/{childId}) CallResultListPlanVO getPlans(Path(childId) long childId); GET(api/trainings/today) CallResultListTrainingTaskVO getTodayTasks(Query(childId) long childId); POST(api/training/record) CallResultVoid submitRecord(Body TrainingRecordDTO dto); }登录功能建议做成全局会话管理。登录成功后把 Token 和用户信息保存到 SharedPreferences网络层通过拦截器自动附加 Token 到请求头。这样后续所有接口都不用手动传 Token体验和真实项目一致。public class AuthInterceptor implements Interceptor { Override public Response intercept(Chain chain) throws IOException { Request original chain.request(); String token SessionManager.getToken(); if (token ! null) { Request request original.newBuilder() .header(Authorization, Bearer token) .build(); return chain.proceed(request); } return chain.proceed(original); } }提示在实际开发中我发现一个很好用的调试姿势——OkHttp 的日志拦截器在 debug 环境打印所有请求和响应体联调时打开遇到接口报错一眼就能定位是参数传错还是返回格式不对。上线前记得关掉这个建议对任何 Android 项目都适用。4.2 训练任务的交互设计配对、分类、语音训练任务是整个 APP 的核心功能。我按类型分别实现了几个训练组件这里挑最有代表性的三个讲。配对训练界面是一个 GridView卡片分成上下两行上排是目标图片下排是候选图片。孩子点击下排卡片如果和目标匹配则播放成功音效并弹出星星动画卡片变成灰色如果不匹配卡片抖动一下提示错误。核心逻辑其实不复杂一个列表存所有卡片点击时对比两张卡片的 itemId 即可。我建议把目标卡片和候选卡片混合在同一列表中避免维护两个列表的状态。匹配成功后用ValueAnimator做缩放动画视觉反馈很直观孩子也容易理解“做对了”和“做错了”。分类训练界面上显示多个类别按钮比如“动物”和“水果”屏幕中央出现一张图片孩子需要把图片拖到正确的类别区域。这里用 RecyclerView ItemTouchHelper 实现简单拖拽拖到区域后判断类别是否正确。分类训练的难点是拖拽的命中判断。我的方案是在拖拽过程中实时获取目标区域的中心坐标当拖拽位置距离目标中心小于阈值时判定为“放入该区域”。这个阈值根据屏幕宽度动态计算避免大屏和小屏体验差异过大。语音跟读训练调用 Android 系统的 TextToSpeech 播放示范读音孩子跟读后如果家长在场辅助家长选择“发音清楚”“发音模糊”“不配合”三个选项并记录得分。这个功能用系统 API 就能完成但注意释放资源。TextToSpeech 实例在页面销毁时必须调用shutdown()否则会有内存泄漏提醒。此外语音训练的结果判定不要做成自动识别语音识别准确率对儿童发音不友好容易误判而是做成家长/康复师主观选项既简单又符合机构里“教师辅助评估”的真实流程。这个设计思路很重要毕设功能的第一优先级不是“看起来厉害”而是“符合业务真实逻辑且技术可行”。自动语音识别在真实康复场景中既不可靠又增加复杂度简化的主观选项反而更贴合实际。4.3 训练记录上报与离线容错Android 端另外一个关键点是训练记录上报。孩子在训练过程中可能多次暂停、中断所以上报时机和上报内容需要仔细设计。我的方案是页面记录训练开始时间戳孩子完成任务后展示结果页显示用时、正确率、获得奖励家长确认后点击“完成训练”此时客户端才组装记录并上报服务端如果在训练过程中退出 APP再次进入时提示“存在未完成的训练是否继续”从本地缓存的进度恢复。这里有个体验细节训练中途退出时要把当前训练状态保存到本地数据库或 SharedPreferences。我选择用 Room 数据库保存训练中间状态因为任务可能在服务端下发多个本地持久化需要结构化存储。如果只是临时状态用 SharedPreferences 也可以但存储体验会差一些。上报失败的情况也必须处理。网络不稳定时把记录存入本地待上传队列等网络恢复后自动补传。这个“待上传队列”是加分项答辩时可以当做“系统容错设计”来讲。实现上可以用一个表存待上传记录再在 Application 里监听网络状态变化恢复网络时遍历队列上传。5. 全流程管理闭环评估、报告与多方协同把 Android 端的单个训练功能做完系统已经能用了但“全流程管理”的深度还不够。这一章讲的是如何把训练、评估、报告串成真正有价值的闭环。5.1 训练计划如何生成康复师怎么介入训练计划不是家长自己随便定的而是康复师基于评估结果生成的。在系统里康复师的操作路径是这样设计的登录 APP 后进入“儿童管理”选择需要安排计划的孩子查看该孩子最近一次评估报告了解能力短板点击“新建计划”选择计划周期通常 2 到 4 周填写计划名称和目标在计划中添加任务选择任务类型、标题、难度、频率、每日目标时长保存并发布计划孩子今天起就能在“今日训练”里看到任务。为了让这个流程能落地服务端需要两个关键接口查看评估报告和新建计划。尤其是新建计划接口要支持一次提交整个计划的全部任务列表而不是一个个任务地创建。我在设计这个接口时用了嵌套 DTOpublic class PlanCreateDTO { private Long childId; private String planName; private LocalDate startDate; private LocalDate endDate; private ListTaskItemDTO tasks; public static class TaskItemDTO { private String taskType; private String title; private String contentJson; private Integer difficulty; private Integer targetDuration; private String frequency; } }Service 层逻辑是先插入计划主记录再循环插入任务列表用一个事务包住两个操作。Transactional(rollbackFor Exception.class) public void createPlanWithTasks(PlanCreateDTO dto) { TrainingPlan plan new TrainingPlan(); plan.setChildId(dto.getChildId()); plan.setPlanName(dto.getPlanName()); plan.setStartDate(dto.getStartDate()); plan.setEndDate(dto.getEndDate()); plan.setStatus(0); plan.setCreatorId(CurrentUserHolder.getUserId()); planMapper.insert(plan); for (int i 0; i dto.getTasks().size(); i) { PlanCreateDTO.TaskItemDTO item dto.getTasks().get(i); TrainingTask task new TrainingTask(); task.setPlanId(plan.getId()); task.setTaskType(item.getTaskType()); task.setTitle(item.getTitle()); task.setContentJson(item.getContentJson()); task.setDifficulty(item.getDifficulty()); task.setTargetDuration(item.getTargetDuration()); task.setFrequency(item.getFrequency()); task.setOrderNo(i 1); taskMapper.insert(task); } }Transactional一定要加。如果不加事务任务列表插入到一半失败就会出现“有计划没任务”的脏数据。我在联调阶段就吃过这个亏前 4 个任务插入成功、第 5 个失败页面显示计划存在但任务列表是空的排查了大半天才发现是事务没加。你不踩上这一个坑可能都不知道事务注解在真实开发里有多重要。5.2 家长端家庭训练与打卡模式家长端是这个系统里使用频率最高的入口设计上必须足够简单。我的推荐方案家长登录后只看到四个核心页面——首页、今日训练、训练记录、我的。首页展示当前绑定儿童的今日训练完成进度用进度环展示今天完成了几个任务、还需完成几个直接告诉家长“今天还有两个任务没完成”。今日训练页面按顺序列出任务卡片点进去就是任务执行界面。训练记录页面按时间倒序展示历史训练结果。我的页面展示当前账号信息和绑定儿童列表支持切换孩子。有一个功能建议必做训练提醒。每天设定一个提醒时间到点推送通知“该带孩子训练啦”。用 Android 的 AlarmManager 通知栏实现代码量不大但能极大提升系统完整度也是答辩演示时很有画面感的一个功能。家长端的数据统计要克制。展示本周训练天数、累计训练分钟数、任务完成率、情绪状态分布即可不要堆砌一堆看不懂的图表。统计图我推荐用 MPAndroidChart 库曲线图和柱状图足够用而且库很成熟接入成本低。但要注意这个库的体积较大不影响使用但演示时首屏加载稍慢别在图表页面停留太久。5.3 数据报表怎么设计才算有用评估报告是系统里最有专业含量的部分。康复师做完一次评估后系统要生成一份结构化的报告包含基本信息儿童姓名、年龄、评估类型、评估时间、评估人各维度得分语言、认知、社交、精细动作、生活自理各维度百分制分数综合结论一段评估总结文字训练建议结合得分给出的下一阶段建议历史对比和上一次评估相比每个维度分数变化情况。这个报告在 Android 端的展示页是一个长列表顶部是基本信息和综合结论中部是各维度得分条形图底部是建议和历史对比。条形图用 MPAndroidChart 的 HorizontalBarChart 实现一个数据集五根柱子非常简单。历史对比的数据要服务端算好再返回。服务端查询该儿童最近两次评估记录按维度计算差值组装成对比数据结构public class AssessmentReportVO { private Long childId; private String childName; private String assessmentType; private ListDimensionScoreVO dimensions; private String summary; private String suggestion; private MapString, Integer scoreChange; // 维度名 - 变化值 }这里的关键思维是客户端越“笨”系统越稳。所有计算、聚合、对比逻辑都在服务端完成客户端只负责把拿到的数据渲染出来。这样不用管 Android 端数据不一致的问题也好测试。5.4 评估与训练的整体协同逻辑把评估和训练串起来看系统闭环就完整了初始评估建档 → 根据评估结果制定训练计划 → 家长带孩子按计划执行训练 → 系统记录每次训练数据 → 周期结束后再次评估 → 根据前后两次评估对比判断训练是否有效 → 调整下一阶段训练计划。这个闭环在答辩时一定要流畅地讲出来。我的建议是准备一个标准演示脚本按顺序走一遍康复师登录 → 查看儿童评估报告 → 创建新计划 → 退出登录 → 家长登录 → 查看今日任务 → 完成一个训练并上报记录 → 查看本周训练统计 → 回到康复师端查看训练记录汇总。整个演示最好控制在 10 分钟以内突出业务完整性和交互流畅度。答辩老师最喜欢问的问题之一就是“如果训练效果不好系统能做什么”回答思路是系统不直接判断训练是否有效而是通过记录的数据和再次评估的结果把变化趋势呈现给康复师康复师根据趋势人工调整计划。系统的角色是“数据辅助决策”不是“自动决策”。这个定位既符合真实业务逻辑又避开了“系统是否有医学价值”这种难以回答的质疑。6. 联调阶段的坑、性能优化与答辩准备系统功能做完不是终点真正让人头疼的是联调阶段。这一章把我在这个项目中遇到过的问题和解决办法集中整理出来你大概率也会碰到其中几个。6.1 前后端联调最常见的四个坑第一时间格式不一致。服务端返回的日期时间默认是 ISO 格式例如2025-06-28T15:30:00Android 端如果用SimpleDateFormat直接解析会报错。解决办法是统一约定服务端在application.yml配置全局时间格式。spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8Android 端用Gson或Fastjson解析时也统一按这个格式处理。时间问题不解决你在训练记录列表页、评估报告页会看到一串排不整齐的时间字符串非常影响观感。第二图片上传的路径问题。儿童头像、训练素材图片都需要上传我在 Spring Boot 里做了静态资源映射把本地上传目录和外部访问路径对应起来Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(file: uploadDir /); } }但这里有一个联调常见的坑上传时返回的图片地址如果是相对路径/upload/xxx.jpgAndroid 端加载时必须拼接服务端 IP 和端口变成http://192.168.1.100:8080/upload/xxx.jpg。如果拼接逻辑写错图片就加载不出来。我的做法是上传成功后服务端直接返回完整的可访问地址客户端拿到什么就用什么不自行拼接省去很多麻烦。第三Android 端模拟器访问宿主机。如果你用 Android Studio 模拟器调试访问本机服务端时不能用localhost或127.0.0.1因为模拟器里这指向模拟器自身。要用10.0.2.2才能访问宿主机。这个坑几乎所有初次做前后端联调的人都会遇到我在这个项目里也花了不少时间排查最后才反应过来是地址写错了。第四请求参数序列化。如果你在 Android 端用 Fastjson 序列化对象命名风格不一致会导致字段解析不出来。比如服务端字段是childIdAndroid 端写成了child_id解析结果就是 null。建议两端都用驼峰命名并配合 Lombok 的Data注解字段名保持完全一致。提示联调开始前先花 10 分钟确认双端的字段命名规范、时间格式、返回结构三项约定后面能省下几十倍的排查时间。6.2 训练环节的流畅度优化训练界面是孩子直接操作的地方流畅度直接决定使用体验。我在项目中做了一次性能优化核心是减少卡顿图片加载用 Glide 做缓存。配对训练中的素材图片如果每次都从网络拉取加载时间不可控。Glide 会自动做内存缓存和磁盘缓存第一次加载后后续进入训练页面几乎瞬间呈现。Glide.with(context) .load(imageUrl) .placeholder(R.drawable.ic_loading) .error(R.drawable.ic_error) .into(imageView);动画用硬件加速。配对成功时的缩放动画、卡片翻转动画可能在低端设备上出现掉帧。在 Activity 的onCreate里开启硬件加速默认就是开启的但不要在自定义 View 的draw里频繁创建对象导致 GC 频繁触发。我的做法是动画的 ValueAnimator 只创建一次通过反复 start 复用。数据列表用 RecyclerView。训练记录列表页和计划列表页都用 RecyclerView配合setHasFixedSize(true)提升性能。如果列表数据量不大几十条以内不需要分页加载如果评估报告按时间累积多了可以加一个简单的滑动加载更多。本地缓存减少接口请求。家长端的首页进度环在进入时调用一次接口训练记录页面在数据不变时不清空缓存。我用Lifecycle的onResume才刷新数据避免页面切换时重复拉取接口导致白屏和等待。6.3 答辩的核心梳理与常见提问最后说答辩。毕业设计做得再好讲不清楚也拿不到高分。我建议你按这条线准备答辩材料第一讲清楚“这是一个什么问题”。用 30 秒说明背景自闭症儿童康复训练周期长、过程复杂需要多角色协作现有管理方式效率低所以做一个平台把评估、计划、执行、反馈串起来。第二讲清楚“系统怎么解决问题的”。展示系统架构服务端 客户端 数据库三层展示核心业务流程评估 → 计划 → 训练 → 记录 → 评估展示核心页面计划管理、训练执行、记录上报、评估报告。第三讲清楚“你自己做的最有价值的部分”。每个人都应该有自己最熟悉的亮点。如果你的亮点在 Android 端就重点讲训练交互设计和离线容错如果在服务端就重点讲接口设计和事务一致性。重点不在于功能多而在于你能把某一个部分讲透。第四准备好被追问的技术点。我根据自己的答辩经验把高频问题整理如下Q1你的系统如何保证同一计划不会被重复创建答创建计划接口在 Service 层校验该儿童当前是否存在进行中的计划如果存在则提示先结束旧计划。同时用一个唯一索引 业务校验双重保障。Q2训练记录数据量很大怎么处理答数据量增大后可以按月分区或只在服务端做统计聚合客户端按页加载历史记录。统计报表查询时按 child_id 时间范围走索引。Q3为什么用 JWT 而不用 Session答JWT 适合前后端分离场景服务端不需要维护会话状态Android 端只需保存 Token 并在请求头携带轻量且易扩展。缺点是 Token 无法主动失效但毕设场景下完全够用。Q4Android 端如何保证离线也能使用部分功能答我把今日任务列表和训练中间状态缓存在本地数据库网络不可用时可以查看已缓存的任务训练完成后的记录先保存到本地待上传队列网络恢复后自动补传。这些问答你自己要先过一遍哪怕只是嘴上说说也比现场临场发挥强很多。6.4 还有哪些可扩展的方向如果一个学期的时间比较充裕或者你想把项目做得更好看有几个方向可以在现有基础上扩展不必伤筋动骨视频训练指导在任务中嵌入示范视频孩子先看示范再练习需要服务端支持视频上传和流媒体播放数据大屏管理员端增加一个 Web 或 Android 大屏页面展示所有儿童训练完成率、情绪状态分布、康复师工作量等统计指标消息推送用极光推送或 Firebase Cloud Messaging把任务提醒、计划调整通知主动推送到家长手机语音识别辅助评估引入成熟语音识别 SDK对儿童跟读进行初步打分再结合教师人工确认形成半自动评估家庭报告邮件定期把孩子的训练报告生成为 PDF 发送给家长Spring Boot 端用 iText 或 POI 生成 PDF 即可。这些方向任意选一个做出来“系统亮点”就非常突出了。但记住一个原则扩展功能是锦上添花先把主流程跑通、跑稳定再谈扩展。很多同学一开始就想做视频、做推送结果主流程都没做完最后被迫删功能非常可惜。写在最后的一点体会这个项目从头到尾做下来我最大的感受是毕业设计选题看起来是“技术题”实际上更多是“业务题”。技术栈都是现成的框架、库、网上教程一大把真正拉开差距的是你对业务的理解深度和设计能力。自闭症康复训练全流程管理系统这个题目是有温度的方向——它不是做一个普通的后台管理而是试图用技术去支持一个特殊群体的日常康复过程。把评估、计划、训练、记录、反馈这条链路想清楚并落地学到的东西会比单纯做一百个增删改查接口多得多。如果你正在做这个题目或者选了类似的“XX平台 XX管理系统”方向我希望这篇内容能帮你少走弯路。先理业务再建表再写接口最后做界面这个顺序不要乱。反而仗着一身技术冲动从界面开始写大概率会在后期返工。祝你的项目顺利通过验收也祝你能在答辩台上把这个系统讲得漂漂亮亮。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。