写这篇文章前,先交代一下背景。我带过的毕业生里,每届都有几个选“xx管理系统”做毕设,结果答辩现场被评委一句“你这就是增删改查”问得下不来台。而“家校互联”这类题目恰恰相反,它表面是管理系统,内核却包含了多角色权限、消息触达、数据统计、文件上传、第三方登录,甚至还能塞进定时任务和扫码签到,撑得起一个本科毕设该有的工作量,又不会难到做不完。这篇文章就围绕“springboot家校互联小程序”这个题目,从选题逻辑、系统设计、后端实现、小程序端开发、填坑记录到论文答辩,完整过一遍我做这类毕设的实操思路,给正在选题或者已经开工的你一个能直接照做的参考。
1. 选题判断:家校互联为什么是毕设的“性价比之王”
1.1 功能需求拆解:你要做的不只是通讯录
很多人一听“家校互联”,第一反应是“做个通讯录,把老师和家长的电话放一起”。如果你也这么想,那恭喜你,这个选题已经被你浪费了一半的价值。
真实的家校互联系统,服务对象至少有四类人:学生、家长、教师、系统管理员。他们各自的操作场景完全不同。学生要查课表、看作业、交考勤;家长要接收通知、请假审批、查成绩、和班主任沟通;教师要发布作业、录入成绩、管理考勤、发起通知;管理员则要维护班级、教师账号、数据统计。这一拆,功能模块就出来了:用户管理、班级管理、通知公告、作业管理、成绩管理、考勤签到、请假审批、留言沟通、数据看板。
我一般建议毕设至少覆盖六个核心模块,再加上一个亮点模块。亮点模块可以是教师端的小程序扫码点名、家长端的孩子成绩趋势分析、或者通知公告的已读未读统计。这样评委问“你的创新点是什么”的时候,你不需要编,指着功能说就行。
1.2 为什么pick springboot + 微信小程序
技术选型上,十个题里有八个会用Spring Boot,这不是随大流,是因为这套组合对毕设极其友好。
Spring Boot的好处在于内置Tomcat、自动配置、生态成熟,网上资料多到爆炸。遇到问题排查时,随便搜一下就有解决方案。而且Spring Boot在面试里的出现频率极高,做了毕设等于顺带复习了面试题。
前端为什么选微信小程序而不是Vue网页或者安卓App?我是从三个维度权衡的:
| 对比维度 | 微信小程序 | Vue网页 | 安卓原生App |
|---|---|---|---|
| 使用门槛 | 扫码即用,无需下载 | 浏览器访问,需要输入网址 | 需要下载安装APK |
| 开发成本 | 中,语法接近Vue | 低 | 高,环境配置费时 |
| 演示效果 | 贴近真实产品 | 一般 | 较强但受设备限制 |
| 答辩加分 | 多端适配、移动端场景真实 | 一般 | 中等 |
家校互联的使用场景本来就是家长手机上,用小程序最贴近真实业务。而且小程序现在的开发工具很完善,真机调试、云开发都方便,对新手来说,界面调试比原生安卓舒服太多。
1.3 工作量评估与创新点设计
工作量上,我按经验给一个粗略估算:数据库和表结构设计约1周,后端核心接口约3周,小程序端页面与联调约3周,论文撰写约2周,答辩准备缓冲1周。满打满算10周,适合大四下学期开始动手,时间上不紧张。
创新点的设计,我强烈建议围绕“家长真实需求”来做,而不是炫技术。比如“考勤异常提醒”,学生迟到早退,系统自动给家长推送通知,这个功能在真实家校产品里是刚需,但毕设里很少人做,做了就是差异化。再比如“成绩报告单生成”,把学生历次成绩汇总成一个可视化报告,家长一眼能看到趋势,这也是很有说服力的加分项。
2. 系统架构与数据库设计:先画好图纸再动手
2.1 前后端分离的整体结构
整体架构上,我采用的是标准的前后端分离:微信小程序做用户端(家长、学生、教师共用,根据登录角色动态渲染菜单),Spring Boot提供RESTful API,MySQL存数据,可选引入Redis做会话缓存,MinIO或本地磁盘做文件存储,管理后台如果时间紧张,直接用Spring Boot自带的Thymeleaf写几个简单页面,或者干脆做一个Web端管理界面。
这里要提醒一句:毕设评分里,架构图占的分值不低。你不需要画得多漂亮,但一定要能把请求链路讲清楚。我的建议是准备一张包含“小程序端 - Nginx(可选) - Spring Boot服务 - MySQL/Redis/文件存储”的架构图,每个组件写一句职责说明,答辩时照着讲三分钟,评委立刻觉得你心里有底。
2.2 核心表结构:这几张表直接决定功能上限
数据库设计是毕设的重头戏,我见过太多人栽在这上面。要么是一张表恨不得装下整个系统,要么是表之间外键乱飞。我把自己反复调优后的核心表结构分享出来,字段不追求全,只求够用且可扩展:
第一张表是用户表,我习惯命名为sys_user:
CREATE TABLE sys_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, open_id VARCHAR(64) UNIQUE COMMENT '微信小程序openid', username VARCHAR(32) COMMENT '账号,教师/管理员登录用', password VARCHAR(64) COMMENT '密码,BCrypt加密', real_name VARCHAR(32) NOT NULL COMMENT '真实姓名', role TINYINT NOT NULL COMMENT '1-学生 2-家长 3-教师 4-管理员', student_id BIGINT COMMENT '学生ID,家长绑定学生', class_id BIGINT COMMENT '班级ID,学生和教师所属班级', phone VARCHAR(20), avatar VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, ... )第二张核心表是班级表class_info,字段包括班级名称、年级、班主任ID。注意,班主任ID关联的是教师用户,这里我用逻辑关联而不是物理外键,目的就是避免后面调整数据时被外键约束卡死。
第三张是通知公告表notice,字段包括标题、内容、发布教师ID、班级ID、是否全体可见、已读统计用的read_count。这里有个细节:真实场景中通知可能需要精确统计谁读了谁没读,所以最好再加一张notice_read_record中间表,记录每个用户是否已读。别觉得麻烦,这个表是你做“已读率统计”创新点的基础。
作业表homework、成绩表grade、请假表leave_request、考勤表attendance这些我就不一一列SQL了,说几个容易踩坑的点:作业表要加deadline字段用于定时提醒,成绩表要加exam_name字段用于区分月考期中期末,请假表要有status状态机(待审批/通过/驳回),考勤表要区分type是迟到早退还是请假缺勤。
2.3 用户身份与权限模型:怎么区分老师、家长、学生
权限模型我用的是最简单也最稳妥的RBAC——角色带菜单和接口权限。不要一上来就搞Spring Security加OAuth2,毕设阶段用拦截器加注解就足够清晰。
具体做法是:登录成功后后端返回一个token,前端每次请求把token放在Header里,后端用一个拦截器统一解析token,从Redis里取出用户信息,判断当前用户角色,再决定这个接口是否放行。比如发布通知的接口,只有角色为3(教师)或4(管理员)才能调用,查看成绩的接口,学生只能查自己的,家长只能查绑定孩子的。
这里有一个非常容易被忽略的场景:一个家长可能同时绑定两个孩子,一个孩子在不同班级。如果只给家长表放一个student_id,就漏了。我的做法是单独建一张parent_student_rel关系表,字段就三个:id, parent_user_id, student_user_id。这种多对多关系在真实业务里非常常见,写进论文里也是一个体现你考虑周全的点。
3. Spring Boot后端开发:从搭项目到跑通核心接口
3.1 项目初始化:版本选型和工程结构
Spring Boot的版本选择,我有话要说。很多教程一上来让你用最新版,结果Spring Boot 3.x要求JDK 17,很多学生电脑上装的还是JDK 8,光环境就折腾一个星期。我个人的建议是:如果只是为了稳,选Spring Boot 2.7.x + JDK 8,这个组合是过去几年最成熟的搭配,资料最多,遇到报错搜一下就有答案。如果你本身熟悉JDK 17,可以上3.x,但注意3.x里很多旧版写法(比如javax改jakarta)需要适配。
工程结构上,我推荐按模块分包,而不是按技术层次分包:
com.example.jiaxiaohulian ├── config // 配置类:拦截器、跨域、MyBatisPlus分页 ├── controller // 接口层 ├── service // 业务层,接口+实现 ├── mapper // 数据访问层 ├── entity // 实体类 ├── common // 通用返回结果、异常处理、工具类 └── task // 定时任务这样的分包方式,做毕设最大的好处是:当你写论文第三章“系统设计”时,可以直接对照包结构画模块图,评委看起来也直观。
application.yml的配置,把关键项都写上,避免每次都要问:
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/jiaxiaohulian?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 03.2 微信登录与Token鉴权:家长端的第一道门
小程序端用户首次登录,流程是:小程序调用wx.login拿到临时code,传到后端,后端拿code去微信服务器换openid,然后查库,如果用户存在就直接发token,不存在则跳转到绑定信息页(选择身份、填写姓名、绑定学生)。
核心代码其实不长,我拆开来讲:
@GetMapping("/login") public Result login(@RequestParam String code) { // 1. 用code换openid String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code"; String result = restTemplate.getForObject(url, String.class); JSONObject obj = JSON.parseObject(result); String openid = obj.getString("openid"); // 2. 查库,看用户是否已注册 User user = userMapper.selectOne(new LambdaQueryWrapper<User>() .eq(User::getOpenId, openid)); // 3. 已注册:生成token返回;未注册:返回特殊标记,引导绑定信息 if (user != null) { String token = JwtUtil.generateToken(user.getId(), user.getRole()); return Result.success(token); } else { return Result.build(2001, "未绑定", openid); // openid前端的临时凭证 } }这里我踩过的坑是:小程序登录的appid和secret一定要填对,而且如果要用真机调试,必须在微信公众平台把开发者加进体验成员,否则真机上登录时jscode2session会报invalid code错误。如果你是个人开发者没有AppID,测试阶段可以用测试号,上线前再换成正式的。
JWT的生成,网上工具类一堆,我只强调一点:token过期时间设置为7天,过期后小程序端要能通过刷新token续期。毕设里不需要做太复杂的双token机制,但“session失效后用户要重新登录”这个逻辑一定要处理好,否则演示时中途掉线会很尴尬。
3.3 通知公告与作业的定时推送逻辑
“消息推送”是家校互联最核心的功能,但也是最容易被做成“假功能”的模块。很多毕设里所谓的推送,其实就是用户刷新页面时拉取最新列表,没有真正主动触达。想做出真实感,可以引入定时任务:每天晚上八点,系统扫描当天作业表和通知表,把“未读”的用户统计出来,通过小程序订阅消息或模拟站内信的方式提醒。
Spring Boot里用@Scheduled注解就能实现,不需要引入Quartz:
@Component public class HomeworkRemindTask { @Scheduled(cron = "0 0 20 * * ?") // 每天晚上8点 public void remindUnfinishedHomework() { // 1. 查今天的作业 List<Homework> homeworkList = homeworkMapper.selectToday(); // 2. 遍历每项作业,查这个班级下哪些学生还没提交 // 3. 给对应的家长用户生成站内消息 } }这里必须提醒你:@Scheduled默认是单线程串行执行,如果你有好几个定时任务,一定要设置线程池配置,或者把@EnableScheduling和@EnableAsync搭配使用,否则多个任务会互相阻塞。我接手过一个学生的项目,他放了三个定时任务,结果发现每天只有凌晨三点那个任务跑了,其他两个全被堵住了,就是在配置上吃了亏。
再强调一点:很多教程会暗示你用“微信订阅消息”做真正的推送提醒。我的建议是毕设阶段优先做站内信和横幅提醒,原因是订阅消息的模板需要微信官方审核,申请流程比较繁琐,而且用户点击授权后单次订阅只能推送一条。你可以把“小程序订阅消息集成”作为扩展点写在论文的展望里,不需要真的做通。这不是偷懒,而是把时间花在更稳的功能上。
3.4 文件上传与存储:MinIO还是本地磁盘
家校互联里会涉及图片上传,比如作业附件、头像、请假证明。这块我建议不要在毕设里单独搭建复杂的文件服务,除非你想在答辩时秀一把。
最省事的方案是存本地磁盘。在application.yml里配置一个上传路径,用MultipartFile接收文件,写入磁盘,返回一个URL前缀加文件名。这个方案的好处是零依赖、演示的时候不会因为MinIO没启动导致上传失败。
如果你想让项目好看一点,可以集成MinIO。从热搜词里也能看到MinIO是目前比较热门的对象存储方案。集成后的核心操作就是三件事:创建bucket、上传文件、获取访问链接。要注意两个坑:一是bucket的权限要设置为public,否则前端图片加载不出来;二是MinIO默认端口9000,控制台端口是9001,很多人会混淆导致访问MinIO管理页面、或者API访问失败。
MyBatis-Plus 分页插件配置也别漏掉,不然写分页查询时会遇到total为0的问题:
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }4. 微信小程序端实现:页面怎么排、交互怎么做
4.1 页面结构设计:tabBar怎么安排、权限入口怎么控制
小程序端我采用的是“一个程序、三套入口”的设计:登录时根据角色不同,渲染不同的底部菜单和首页功能列表。
- 家长端:首页(孩子动态概览)、消息(通知与作业提醒)、我的(孩子信息与账户)
- 教师端:工作台(发布通知、布置作业、扫码点名)、班级(学生名单与考勤)、我的
- 学生端:首页(课表与待办)、学习(作业与成绩)、我的
这个设计的好处是代码复用率高,同一个homework列表页面,家长看到的是提交状态,老师看到的是批改入口,学生看到的是上传附件按钮。权限控制在前端通过wx.getStorageSync('userInfo')里的role字段判断,在后端通过拦截器二次校验,双重保险。
具体的页面清单大概是:pages/login/index、pages/index/index、pages/notice/list、pages/notice/detail、pages/homework/list、pages/homework/detail、pages/grade/list、pages/attendance/list、pages/leave/apply、pages/mine/index、pages/class/studentList等。这样一列出来就是十来个页面,论文里画页面功能结构图时很占篇幅,工作量看起来也饱满。
4.2 列表加载更多的正确写法:分页参数和触底逻辑
热搜词里有一条“微信小程序页面列表加载更多”,这说明很多人都卡在这个看似简单的功能上。我做这个项目时的标准写法,直接从homework列表的案例入手:
小程序的onReachBottom触底事件回调,配合后端分页接口,核心逻辑是这段代码:
Page({ data: { pageNum: 1, pageSize: 10, list: [], hasMore: true, loading: false }, async loadList(reset = false) { if (this.data.loading || (!reset && !this.data.hasMore)) return; if (reset) { this.setData({ pageNum: 1, hasMore: true, list: [] }); } this.setData({ loading: true }); const res = await request.get('/homework/list', { pageNum: this.data.pageNum, pageSize: this.data.pageSize }); const records = res.data.records || []; const newList = reset ? records : this.data.list.concat(records); this.setData({ pageNum: this.data.pageNum + 1, list: newList, hasMore: records.length >= this.data.pageSize, loading: false }); }, onReachBottom() { this.loadList(); } })有几个细节必须咬死:第一,concat拼接而不是覆盖,否则下一页会把上一页顶掉;第二,hasMore的判断用records.length >= pageSize,而不是后端返回total里的全部数量,因为踩过一页请求重复触发的坑;第三,loading防抖一定要加,触底事件会在iOS上频繁触发,不加防抖你的列表会被重复请求打爆。这套逻辑我从大项目里搬过来,在小程序里一样很稳。
4.3 与后端联调最容易翻车的三个地方
开发小程序和做网页不同,很多之前没遇到的问题会在联调阶段集中爆发。我挑三个最常见的说。
第一个是请求域名配置。开发时你在调试工具里勾选“不校验合法域名”,一切正常。但只要换真机预览,如果请求地址是http://localhost:8080,必然失败。正确做法是:后端在本机跑的时候,小程序请求地址填你电脑的局域网IP,比如http://192.168.1.100:8080,手机和电脑连同一个WiFi。这里注意Windows防火墙可能会拦截,需要在入站规则里放行8080端口。我见过有同学在真机上调试了一下午,最后发现是电脑防火墙把端口掐了。
第二个是数据格式的统一。前端用wx.request请求后,拿到的响应是一个字符串,需要JSON.parse。为了避免每次手动解析,我一般封装一个request.js,在基类封装里统一处理状态码。更关键的是,后端返回的结构必须统一成{ code: 200, message: "success", data: ... },如果每个接口返回格式不同,前端没法写通用拦截器,联调时各个页面都会出奇奇怪怪的问题。
第三个是token失效的自动跳转。前端拦截器要统一检查code字段,如果后端返回的是401或用户未认证,就清空本地缓存并跳转登录页。这个逻辑在演示时尤为重要——你切换到另一个页面时,token在使用过程中过期,如果不处理,后续所有请求都会失败且无提示,评委看起来就像系统崩了。
5. 开发过程中的坑与排查思路
5.1 接口调试:别等页面写完才联调
很多人的开发习惯是后端点全部写完再让前端对接,这是毕设进度的头号杀手。我的建议是:后端写完一个模块的接口,立刻用接口调试工具尝试请求一遍,确认返回结构后再继续写小程序页面。这样做的好处是,接口的问题在设计阶段就会被暴露,而不是堆到联调时一起爆发。
调试工具有三种用法值得掌握:一是Postman或Apifox手动发送请求,验证接口逻辑;二是微信开发者工具自带的Network面板,查看小程序发出的真实请求参数和返回值;三是后端控制台打印SQL日志(MyBatis-Plus的StdOutImpl),确保Mapper拼接的SQL和预期一致。我排查一个“列表查不出数据”的问题时,就是靠日志发现SQL里多了一个软删除条件,数据其实没写错,是查询条件的锅。
5.2 时间字段与跨天问题的排查记录
我这里记录一个比较典型的坑,如果你做考勤模块,很可能也会遇到。我的考勤表用DATETIME存签到时间,前端传的是"2025-05-20T08:30:00"这种格式。有一次学生早上8点打卡,系统却显示他在昨天的考勤记录里,怎么查都查不对。
排查过程是:先看后端接收到的参数,用日志打印发现异常;再检查application.yml里数据库连接的serverTimezone=Asia/Shanghai配置;最后定位到是前端在new Date()之后用toISOString()转格式,把时间转成了UTC,导致和后端差了8小时。
解决方法是前端直接把时间字符串原样传过来,不做任何时区转换,后端用LocalDateTime.parse接收。类似的坑还包括:日期范围查询时,结束时间如果没有包含23:59:59,会漏掉当天最后一秒的数据。我给每个时间参数都加了默认值和格式校验,才彻底消灭这类问题。
5.3 真机调试与模拟器的差异:字体、安全区、相册权限
小程序开发工具里的模拟器基本只能验证布局和交互逻辑,真机上会出现很多“看起来莫名其妙”的问题。比如你写了一个底部固定的按钮,模拟器上好好贴着底部,真机上被iPhone的Home指示条遮住一半。这个问题的解法是用safe-area-inset-bottom这个环境变量,给按钮加一个安全区padding:
.safe-btn { padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); }还有图片上传时,如果在模拟器上能弹出相册,真机却弹不出来,大概率是权限说明没配,或者用户没有在系统设置里打开相册权限。这个在演示前一定要提前在真机测一遍。
再有一个是字体大小和预览问题,小程序的rpx单位在真机上是会自动缩放的,但你如果写了固定px的尺寸,部分安卓机型上会显示偏小。统一用rpx写布局,文字可以用px或rpx,但保持一致性,别混用。
5.4 并发与数据一致性:两个家长同时提交请假怎么办
请假审批模块有一个并发场景很容易被忽略:家长提交请假申请后,还有撤销操作;教师审批通过后,统计里要实时扣减出勤数。如果多个家长同时操作,数据可能不一致。毕设阶段不要求你做分布式锁那么重的东西,但至少要做到:用乐观锁的版本号机制控制“审批”这个核心操作。
UPDATE leave_request SET status = 2, approver_id = ?, audit_time = NOW() WHERE id = ? AND status = 1这条SQL执行后如果返回0行,说明状态已经变了,业务上要给出“该申请已被处理”的提示。这种“用更新结果判断是否冲突”的方式非常简单,但在答辩里能体现你懂并发控制基础,属于投入产出比很高的加分细节。
6. 论文与答辩准备:让毕设变成加分项
6.1 论文核心结构:不要按代码顺序写
很多毕业设计的论文写的像代码注释,全部围绕“我写了哪些请求接口”,这是大忌。我建议按“发现问题—分析需求—设计方案—实现系统—验证效果”的项目逻辑来组织,重点讲清楚“为什么这么设计”,而不是“怎么敲代码”。
具体章节上,绪论写清楚家庭教育信息化、家校沟通效率这个背景;需求分析用用例图和角色权限矩阵,把业务边界画明白;系统设计是重头戏,写架构图、功能模块图、数据库ER图、类图;系统实现部分每个核心模块配两三张截图加核心代码片段,代码不要大段粘贴,评委和你论文查重系统都烦这个;系统测试部分要有功能测试用例表,以及测试结果汇总。
6.2 答辩演示脚本:三分钟讲出重点
答辩演示最忌讳从头到尾点一遍菜单。我给你的建议是准备一条“问题驱动”的演示主线:比如从“家长想知道孩子今天作业提交了没有”这个场景切入,演示教师登录发布作业,家长端收到通知查看,学生上传作业附件,教师批改,家长查看结果。这个链路能把通知、作业、文件上传、权限管理全部串起来,评委不用思考就能看懂你的系统价值。
演示脚本固定下来之后,提前练习三遍,每次都把要点的功能和截图准备好。还要预演两个故障场景:一是网络断开时页面的表现,二是后端服务重启后小程序token失效的处理。我见过不少人在答辩现场因为这两个场面手忙脚乱。
6.3 评委爱问的几个问题及准备思路
高频问题基本是这几类:
- “你这个系统最大的难点是什么?”答案是:多角色权限控制下的数据隔离,以及通知消息的已读统计。
- “一个家长绑定了两个孩子,数据怎么隔离?”答案是:家长–学生关系表设计,和查询时通过孩子ID过滤数据。
- “用什么方法保证考勤数据不重复提交?”答案是:一张考勤表加唯一约束(学生ID、日期、节次),或者通过乐观锁控制。
- “为什么选小程序不用App?”答案是:用户获取成本低,免安装,微信生态内分享方便,适合家校轻量场景。
回答的时候不管问题多偏,都尽量往你真实做过的功能上引,不要硬编。评委最反感的就是答非所问和盲目背概念。
6.4 Spring Boot版本和依赖管理上的三个自查项
最后一个实操向的建议,交稿之前检查三样东西:
- 检查
pom.xml里有没有多余的依赖。很多项目前期试验引入了一堆包,后面没用上,论文里一贴依赖清单,评委一眼看到无用依赖,印象分会受影响。 - 检查Spring Boot版本与项目实际用到的JDK是否匹配。调试时无所谓,答辩要在评委机器上演示,如果对方环境是JDK 8而你代码跑在JDK 17上,环境不一致会直接死机。
- 检查数据库里的测试数据是否足够丰富。至少要准备两三个班级、三五个教师、二三十个学生和家长的模拟数据,成绩和考勤数据最好覆盖连续三个月,这样统计图表和趋势分析才展示得起来。
我个人带毕设这几年,最大的体会是:题目本身不决定成绩,决定成绩的是你在每一个环节有没有“多想一步”。家校互联这个题目最大的优势,就是你有很多机会做这种“多想一步”——别人做增删改查,你做了已读统计;别人做一个公告栏,你做了定时提醒。把这些差异点做实、写进论文、演示到位,这个毕设就成功了一大半。最后再分享一个实用技巧:正式答辩前,找一个完全不懂技术的人(比如你室友或家里人)用你的小程序走一遍“家长查看孩子考勤”的流程,他卡住的地方,就是你要在答辩前修好的地方。