简介:面向高校毕业设计与Java学习者,这套基于SpringBoot的大学生心理健康管理系统项目涵盖个人信息、学生管理、心理老师管理、试卷管理、试题管理和通知管理等核心模块,可实现心理健康测试、档案记录、咨询预约等功能。压缩包共846个文件,23.78MB,核心包括Java后端源码149个、Vue前端页面69个、JavaScript脚本157个、HTML/CSS页面以及SVG、GIF图标图片等静态资源,并带有SQL数据库脚本与安装、构建、启动批处理文件,便于快速部署运行。目前已有508人学习/下载。系统采用SpringBoot框架降低业务开发复杂度,前端与后端分离明确,目录结构清晰,配套批处理脚本和数据库文件可直接在本地复现项目;对毕业论文选题、功能模块设计、SpringBoot项目搭建方法以及前后端联调思路均具有较强的参考价值,适合作为课程设计或毕设项目的完整蓝本。
1. 这套 Spring Boot 大学生心理健康管理系统,毕设选它到底值不值
如果你的毕业设计选中了 Spring Boot 大学生心理健康管理系统,你大概率已经在搜索引擎里翻过一圈:要么是只给几张截图的“半成品源码”,要么是需求文档写得天花乱坠但代码一跑就报错的“开源项目”。作为拿它完成过答辩的人,我的判断是:这套题目的技术栈非常经典,Spring Boot 做后端、Vue 做前端、MySQL 存数据,功能边界清晰,既有业务深度又不会难到失控,很适合作为本科毕业设计。难点从来不在“写代码”本身,而在量表设计、角色权限、数据关联这几处容易翻车的地方。这篇笔记会把系统的表结构、测评算法、登录授权、部署排错讲透,并指出哪些坑是我当时踩了整整一周才爬出来的。适合打算基于 Spring Boot 做心理测评类的毕设、课程设计,或者正在选型做心理健康平台的开发者。
2. 先看清系统的骨架:角色模型与数据表设计
毕设答辩时老师最喜欢问的一个问题是:“你这个系统有几类用户?每类用户能干什么?”这个问题的答案,直接决定了数据库表怎么建、接口怎么划分、权限怎么控制。所以拿到源码后不要急着启动,先把角色模型和数据表结构理清楚,后面所有功能都是在这些表上做增删改查。
2.1 三种核心角色与权限边界
大学生心理健康管理系统通常不是简单的“学生登录后填问卷”,它需要支撑一套完整的工作流程:学生做测评 → 系统生成报告 → 心理咨询师查看并干预 → 管理员管理全部数据。最常见的角色划分是三类:
第一类是学生,他们能维护个人信息、参与心理测评、查看自己的测评报告和预约记录。第二类是咨询师,除了能看到分配给自己的学生列表,还要能查看学生的测评报告、填写咨询记录、处理预约申请。第三类是管理员,负责账号管理、量表配置、问卷发布、数据统计。
这里有一个很容易被忽略的设计点:学生和咨询师是两类有业务关联的角色,咨询师可以查看学生的测评结果。如果系统里“学生表”和“咨询师表”没有任何关联字段,那咨询师在页面里就见不到任何学生,功能就断链了。我当时的设计是在学生表里加了一个counselor_id字段,表示该学生归属哪位咨询师。这样咨询师登录后,用一条SELECT * FROM student WHERE counselor_id = 当前咨询师id就能拉出自己的学生列表。
提示:如果需求里还有“心理委员”或“辅导员”这类角色,可以把角色表设计成通用模型,用户的角色用
role_id关联,而不是在用户表里硬塞多个布尔字段。
2.2 核心表结构:测评结果不能只存一个总分
心理测评模块是整个系统的核心,也是最容易暴露设计短板的地方。很多毕设源码把测评结果设计成一张assessment_result表,字段是student_id、total_score、level,完事了。这种设计应付演示可以,但在论文的“数据库设计”章节根本站不住脚——开题时导师如果追问“你的量表有多少个维度?每个维度的得分怎么算?”就答不上来了。
实际的量表计算远不是一个总分能表达的。以最常用的 SCL-90 症状自评量表为例,它有 90 道题,每道题 5 个选项(1-5 分),结果要按 10 个因子(躯体化、强迫症状、人际关系敏感、抑郁、焦虑、敌对、恐怖、偏执、精神病性、其他)分别计算因子分,再和常模比较。总分只是其中一个参考指标。所以表结构至少需要四张表配合:
量表配置表定义“这个量表叫什么、有几题、每题多少分”,题目表存放每一道题的文本内容和所属量表,维度表定义量表拆成哪些因子、每个因子包含哪些题号,测评记录表存学生每次作答的原始结果。
下面是我建议的最小建表方案,兼容后续扩展:
-- 量表配置表 CREATE TABLE scale_config ( id BIGINT PRIMARY KEY AUTO_INCREMENT, scale_name VARCHAR(100) NOT NULL COMMENT '量表名称', scale_type VARCHAR(20) NOT NULL COMMENT '量表类型编码,如 SCL90', question_count INT NOT NULL COMMENT '题目总数', status TINYINT DEFAULT 1 COMMENT '1-启用 0-停用', create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 题目表 CREATE TABLE scale_question ( id BIGINT PRIMARY KEY AUTO_INCREMENT, scale_id BIGINT NOT NULL COMMENT '所属量表id', question_no INT NOT NULL COMMENT '题号,从1开始', question_content VARCHAR(500) NOT NULL COMMENT '题干内容' ); -- 维度/因子表 CREATE TABLE scale_dimension ( id BIGINT PRIMARY KEY AUTO_INCREMENT, scale_id BIGINT NOT NULL, dimension_name VARCHAR(50) NOT NULL COMMENT '因子名称', question_range VARCHAR(100) NOT NULL COMMENT '包含题号,如 1-12,35-40' ); -- 测评记录表 CREATE TABLE assessment_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, student_id BIGINT NOT NULL COMMENT '学生id', scale_id BIGINT NOT NULL, answers TEXT NOT NULL COMMENT '原始答案,JSON数组,如 [1,2,3,...]', create_time DATETIME DEFAULT CURRENT_TIMESTAMP );注意测评记录表里那个answers字段,我用的是 TEXT 类型,存 JSON 数组,保留每道题的原始选择值。这样做的好处是:无论量表规则怎么调整(比如因子重新划分、计算逻辑改变),都能用原始数据重新计算,不用改表结构。如果你把每道题的答案拆成 90 个字段,那才是真的灾难。
2.3 项目目录结构与分层规范
拿到源码包后,建议先看后端目录结构。一个规范的 Spring Boot 项目应该是这样分层的:
src/main/java/com/example/mentalhealth/ ├── config/ # 配置类:CORS、Security、WebMvc ├── controller/ # 控制层:暴露REST接口 ├── service/ # 业务层:测评计算、预约流程、登录认证 ├── mapper/ # MyBatis的Mapper接口 ├── entity/ # 实体类 ├── dto/ # 前端交互用的数据对象 ├── common/ # 统一返回结果、异常处理 └── utils/ # JWT工具、日期工具等很多初写毕设的同学喜欢把代码全堆在 controller 里,一个方法几百行。但答辩时老师如果看代码,第一眼就看分层。用 Spring Boot 做系统,controller 应该薄,只负责参数接收和结果返回;核心计算逻辑放 service;数据库访问放 mapper。这样既符合 Spring Boot 的开发习惯,也方便论文里画“系统架构图”和“软件层次图”。
表结构搞清楚了,下一步就是动真格的业务实现——测评计算和报告生成。
3. 测评模块的实现:SCL-90 量表计算与报告生成
心理测评模块绝不能做成“学生答完题,系统显示个总分”的玩具。我见过太多毕设源码,测评完只输出一个“正常/轻度/中度/重度”的结论,没有任何中间数据。真正的做法是:按量表维度分别计算因子分,再结合常模数据进行分层判定,最后生成一份包含各维度得分和文字建议的测评报告。
3.1 因子分计算:90 道题的原始数据怎么变成一个可解释的结果
先说计算逻辑。SCL-90 的 90 道题被划分为 10 个因子,每个因子包含若干题。以“抑郁”因子为例,它包含 5、14、15、20、22、26、29、30、31、32、54、71、79 这几题。因子分的计算方法是:该因子所有题目得分之和除以题目数量。
但这里有个考试重点:总分和总均分的计算方式不同。总分是 90 题得分直接相加,总均分是总分除以 90。而阳性项目数是指单项得分大于等于 2 的题目数,阳性症状均分是阳性项目得分之和除以阳性项目数。这四个指标在论文结果分析里都要展示。
下面是我在 service 层写的计算逻辑,现在拿出来当模板参考:
public AssessmentReport calculateSCL90Report(AssessmentRecord record, List<ScaleQuestion> questions, List<ScaleDimension> dimensions) { // 将 JSON 格式的答案字符串解析为整数数组 JSONArray answersJson = JSON.parseArray(record.getAnswers()); int[] answers = new int[answersJson.size()]; for (int i = 0; i < answersJson.size(); i++) { answers[i] = answersJson.getInteger(i); } // 1. 计算总分 int totalScore = Arrays.stream(answers).sum(); // 2. 计算总均分 double averageScore = Math.round((totalScore / (double) answers.length) * 100.0) / 100.0; // 3. 计算阳性项目数(单项分 >= 2 的题目数) long positiveCount = Arrays.stream(answers).filter(score -> score >= 2).count(); // 4. 按因子遍历,分别计算因子分 Map<String, Double> dimensionScores = new LinkedHashMap<>(); for (ScaleDimension dimension : dimensions) { List<Integer> indexList = parseQuestionRange(dimension.getQuestionRange()); int dimensionTotal = 0; for (int index : indexList) { dimensionTotal += answers[index - 1]; // 题号从1开始,数组下标从0开始 } double factorScore = Math.round((dimensionTotal / (double) indexList.size()) * 100.0) / 100.0; dimensionScores.put(dimension.getDimensionName(), factorScore); } // 5. 组装报告对象 AssessmentReport report = new AssessmentReport(); report.setTotalScore(totalScore); report.setAverageScore(averageScore); report.setPositiveCount(positiveCount); report.setDimensionScores(dimensionScores); report.setResultLevel(judgeLevel(totalScore, positiveCount)); return report; }这里有两个细节必须说明。第一个是parseQuestionRange方法的实现,维度表里的question_range字段我设计成了“1-12,35-40”这种字符串格式,解析时先按逗号拆分成段,每段再按横线拆出起止位置,然后生成连续的题号列表。第二种思路是把维度映射关系做成一张独立的关联表,每行写一个题号,冗余但查询直观。两种方案我都用过,毕设论文里建议用字符串范围设计,理由是可以写进数据字典说明里,节省表数量。
第二个细节是judgeLevel方法,它需要结合常模数据判断结果等级。SCL-90 的常见判定标准是:总分超过 160 分提示阳性,超过 200 分为中度,超过 250 分为重度;或者阳性项目数超过 43 项提示问题。这个标准在论文里引用时最好标注来源,答辩时老师问起来你能说出依据。
3.2 测评报告生成:把冰冷的分数组装成学生看得懂的建议
报告不仅仅是把因子分罗列出来,还要做文字解读。我当时的设计是写了一个静态模板类,每个维度配置了一段默认解读文本和一条建议,根据因子得分区间选择文本拼接。核心逻辑其实就是一个字符串模板替换。
这里的坑在于“高分段”与“低分段”的解读不能颠三倒四。比如“人际关系敏感”因子,得分高说明可能存在人际交往的困扰;得分低反而是正常表现。我当时直接把十个因子的分数段建议写成了一个配置数组,硬编码在代码里,虽然不够优雅,但答辩时讲起来很清楚。你也可以把它做成一个suggestion_config表,让管理员在后台可以改文字,这属于加分项,但不是必选。
3.3 前端作答页与后端接口的交互约定
测评功能的接口通常需要两组:一组是给学生用的“获取量表 + 提交答案”,一组是给管理端用的“配置量表”。学生端接口的设计要注意一个体验问题:一次测评 90 道题,万一中途刷新或断网,答案就丢了。解决思路是前端在每一题作答后就把答案缓存在localStorage,提交时一次性传给后端。后端收到后先校验题目数量是否一致,不一致就报错提示。
下面是我当时设计的接口返回结构,提交答案时前端往/api/assessment/submit发 POST 请求:
{ "studentId": 1001, "scaleId": 1, "answers": [1, 2, 1, 3, 5, ...] }后端校验通过后,业务层执行两件事:先存原始答案到assessment_record,再执行计算逻辑生成报告,同时把报告摘要写入assessment_report表。这两件事放在同一个事务里,任何一步失败都一起回滚,避免出现“答案存了但报告没生成”的脏数据。
提示:报告表里建议冗余一个
submit_time字段用于后续按时间筛选,比如查看某学生最近一次测评结果。很多接口业务都会用到这个字段,临时 join 测评记录表虽然也能查,但 SQL 写起来更复杂,一层冗余能省不少事。
测评和报告模块搞定后,系统的另一个容易翻车的地方是登录认证。很多毕设源码用的是简单的 session 缓存,存一个 userId 就完事,完全没有权限控制。但大学生心理健康管理系统涉及学生隐私数据,登录授权这块如果做得太敷衍,答辩时老师很可能直接问:“你怎么防止一个学生请求别人的测评报告?”下面展开讲认证授权。
4. 登录与权限:用 Spring Security + JWT 守住隐私数据边界
大学生心理健康管理系统的数据是敏感数据,整个系统的“安全设计”章节在论文里是必有模块。最稳妥的组合是 Spring Security 负责请求拦截与角色鉴权,JWT 承担无状态登录凭证。这套方案在 Spring Boot 生态里非常主流,面试和答辩都能讲出东西。
4.1 为什么选 JWT + Spring Security 而不是 Session
Session 方案的逻辑简单:用户登录成功后,服务器把 userId 存在 session 里,后续请求带上 Cookie 就行。问题有两个:一是前后端分离时跨域携带 Cookie 需要额外配置,容易踩坑;二是系统重启后 session 丢失,所有用户都要重新登录。JWT 的优点是 token 里直接携带用户信息和角色信息,服务器不需要存储会话状态,接口只需验签就能拿到当前用户是谁。
用 JWT 时有两个字段是必须携带的:userId和roleId。登录成功后,后端生成 token 并返回给前端,前端把它存在localStorage,每次请求在请求头带Authorization: Bearer <token>。
下面是 JWT 工具类的核心代码,用的jjwt库:
public class JwtUtils { // 密钥建议放在 application.yml 中,用 @Value 注入 private static final String SECRET = "your-256-bit-secret-key"; private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; // 24小时 // 生成token,payload中放入userId和roleId public static String generateToken(Long userId, Integer roleId, String username) { Date now = new Date(); return Jwts.builder() .setSubject(username) .claim("userId", userId) .claim("roleId", roleId) .setIssuedAt(now) .setExpiration(new Date(now.getTime() + EXPIRE_TIME)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } // 解析token,获取userId public static Long getUserId(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); return claims.get("userId", Long.class); } // 判断token是否过期 public static boolean isTokenExpired(String token) { try { Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody(); return claims.getExpiration().before(new Date()); } catch (ExpiredJwtException e) { return true; } } }这段代码里的claim是 JWT 的自定义字段,相当于往 token 里塞业务数据。我这里塞了userId和roleId,后续所有接口都能从 token 里直接取,不用查数据库。过期时间设置成 24 小时,如果你担心学生挂机时间太长,改成 12 小时,也就是12 * 60 * 60 * 1000,都可以。
4.2 Spring Security 拦截规则:哪些接口必须登录,哪些需要角色
Spring Security 的配置是整个认证模块的核心。配置不当会出现两种典型问题:一是所有接口全被拦截,导致前端请求 401,连登录页都进不去;二是只放行了登录接口,但静态资源(比如图片、Swagger 文档)也被拦截,拖慢开发调试。
下面是我在config/SecurityConfig里放行的规则,注意看注释:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable() .cors().and() .authorizeRequests() // 登录注册接口放行,不需要token .antMatchers("/api/auth/login", "/api/auth/register").permitAll() // Swagger接口放行,方便接口调试 .antMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() // 静态资源放行 .antMatchers("/img/**", "/css/**", "/js/**").permitAll() // 其他所有请求都需要认证 .anyRequest().authenticated() .and() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler()) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } }这里重点说明一下addFilterBefore的含义。Spring Security 本身有一套过滤器链,其中UsernamePasswordAuthenticationFilter负责处理表单登录。我们插入自己的JwtAuthenticationFilter在这个过滤器之前,意味着每次请求进来先走 JWT 解析,解析成功就设置认证信息,后续的权限判断直接以 JWT 携带的角色为准。
但角色权限控制不能只看 token,服务端必须在接口上做二次校验。比如管理员查看学生列表的接口,只允许roleId = 1的角色访问,光靠前端按钮隐藏没有意义,因为接口可以被直接调用。我用的是在 controller 上加自定义注解的方式,类似 Spring Security 的@PreAuthorize,核心作用是在业务方法执行前检查当前用户角色。
4.3 权限设计中的身份校验陷阱
容易踩的坑是“学生只能查看自己的报告”这个需求。如果后端接口写成/api/report/get?id=123,学生把 id 改成 124 就能看别人的报告了,这是典型的越权漏洞。正确做法是接口参数不带 id,从 token 里取 userId,然后查该学生的报告列表。如果确实需要按 id 查询,也必须先判断当前用户权限。
我当时在实现“我的测评报告”接口时,直接忽略了前端传来的studentId,用 JwtUtils 从 token 里取:
@GetMapping("/myReport") public Result<ReportVO> getMyReport() { Long userId = JwtUtils.getUserId(getTokenFromRequest()); ReportVO report = assessmentService.getLatestReportByStudent(userId); return Result.success(report); }为什么这么写?因为页面按钮本来就是按当前登录人渲染的,后端如果还相信前端传的学生 id,权限控制就形同虚设。这个思路在论文的“系统安全设计”章节写一笔,答辩时是加分项。
提示:管理员查看所有学生的报告,可以走另一个带鉴权的接口。两个接口分别对应不同角色的页面,避免用一个接口通过不同入参切换身份。
5. 首次启动到答辩演示:部署配置、初始化数据与五个高频报错
很多同学拿到源码后第一个动作是打开 IDEA 直接 run,结果控制台飘红一片。这里的坑多半不是代码问题,而是环境配置问题。下面把这套系统从本地跑起来再到打包部署的完整过程捋一遍,顺带给出我实际遇过的五个高频报错和解决办法。
5.1 application.yml 配置项逐项说明
打开src/main/resources/application.yml,核心配置集中在数据源、端口和 JWT 密钥:
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/mentalhealth?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true jwt: secret: your-256-bit-secret-key-here expire: 86400注意数据库连接串里的serverTimezone=Asia/Shanghai和characterEncoding=utf8,这俩参数缺一个就够你折腾半天。map-underscore-to-camel-case开启后,数据库的create_time就能自动映射到实体的createTime字段,不用写一堆 resultMap。
如果你的源码包用的是 MySQL 5.7,驱动类名可以写com.mysql.jdbc.Driver;MySQL 8 以上必须写com.mysql.cj.jdbc.Driver,这是驱动包变更后的结果,写错启动直接报ClassNotFoundException。
5.2 初始化数据:没有量表数据,测评功能就是空的
源码包里如果带了sql脚本,正常会包含建库建表语句和初始数据。但有一部分开源项目的初始数据是空表,管理员账号、量表配置全都要自己造。我当时是把 SCL-90 的 90 道题全部录进scale_question表的,写了条循环插入的脚本,现在直接讲这个脚本怎么生成。
-- 用存储过程批量插入SCL-90的90道题,这里只贴前3行作为示例 INSERT INTO scale_question (scale_id, question_no, question_content) VALUES (1, 1, '头痛'), (1, 2, '神经过敏,心中不踏实'), (1, 3, '头脑中有不必要的想法或字句盘旋');实际答题过程中,每条题目都对应一个分值选项,这个选项比较固定:没有、很轻、中等、偏重、严重,对应 1-5 分。前端渲染时直接用单选按钮组,后端只收数组。
如果你拿到的源码里没有 SQL 初始化脚本,那就要手工创建数据库。这也是毕设准备阶段必做的事,千万别等答辩当天才建库。
5.3 把项目打包成可部署的 jar
演示和部署环节,不建议在 IDEA 里点绿三角给老师看,显得太学生气。更稳妥的做法是打成 jar 包,用命令行启动:
mvn clean package -DskipTests # 启动 java -jar target/mentalhealth-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod打包前要做两件事:检查pom.xml是否引入了spring-boot-maven-plugin,否则打出来的 jar 运行不了;检查application-prod.yml里的数据库地址是不是服务器 IP,而不是localhost。
5.4 高频报错与排查清单(血泪经验)
下面是实际运行中我遇到过的五个最高频问题,按“现象 → 原因 → 解决”格式整理:
现象一:启动报Access denied for user 'root'@'localhost'
原因:application.yml里的数据库密码和本地 MySQL 不一致。解决:先把application.yml改成本机能连的账户密码,服务器部署时再改回正式库的账户。
现象二:前端请求接口返回 401,登录接口也返回 401
原因:Spring Security 把登录接口也拦截了,说明.permitAll()的路径没写对。我犯过的一个低级错误是对/api/auth/login有印象,但实际 controller 的@RequestMapping写的是/auth/login,前缀不一致。解决:先打开 controller 确认接口路径,再回头对齐 Security 配置。
现象三:前端跨域请求报 CORS 错误
原因:后端默认不允许跨域访问,Vue 项目的接口地址是localhost:8080,页面运行在localhost:3000,所以必须在后端配置跨域。解决:在config包下新建CorsConfig,或者直接在 Security 配置里.cors().and()并配合@CrossOrigin注解。
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }这里有个细节:前端如果用了axios并且开启了withCredentials,后端的allowedOriginPatterns不能写*,否则浏览器会拒绝响应。要么前端去掉withCredentials,要么后端明确写允许的源地址。
现象四:MyBatis 的 Mapper 接口找不到,启动报Invalid bound statement (not found)
原因:要么mapper-locations配置的 XML 路径不对,要么 Mapper 接口没有加@Mapper注解,或者没有在启动类上加@MapperScan("com.example.mentalhealth.mapper")。解决:在启动类里显式加@MapperScan,并确认 XML 文件路径和mapper-locations一致。
现象五:JWT token 解析报JWT signature does not match
原因:不同节点生成 token 时用了不同的密钥,最常见的是配置文件里的密钥和过滤器里硬编码的密钥不一致。解决:统一从application.yml读取密钥,尽量少在代码里硬编码。
排查以上问题时,最高效的路径是先看日志的第一行异常类型,再定位具体的模块,不建议从头到尾翻一遍代码。你再怎么猜也不如一行报错堆栈信息来得准确。
6. 从系统到論文:SCL-90 常模表与演示数据怎么变成答辩素材
系统能跑起来只是第一步,答辩时你要能解释“测评结果为什么可信”。这里有个技巧:把 SCL-90 的常模数据做成一张表放进论文里,就能把业务逻辑和心理学理论衔接起来,这能明显提升论文的深度。
SCL-90 常模的常见参考值如下(各维度均值约 1.23-1.65,标准差约 0.4-0.6),不同来源版本的数字略有差异。我当时用的是这样的简化版:
| 因子名称 | 均值(M) | 标准差(SD) | 判断参考 |
|---|---|---|---|
| 躯体化 | 1.37 | 0.48 | 因子分 > M + 2*SD 提示异常 |
| 强迫症状 | 1.62 | 0.58 | 同上 |
| 人际敏感 | 1.65 | 0.51 | 同上 |
| 抑郁 | 1.50 | 0.59 | 同上 |
| 焦虑 | 1.39 | 0.43 | 同上 |
论文里你可以这样写:系统将学生各因子得分与常模均值比较,超过均值加两个标准差的因子判定为异常,并在报告中给出文字提示。这就是把“系统设计与实现”和“心理测量学”结合的方法,比单纯写“系统可以计算总分”高级得多。
演示环节还有一个实战技巧:答辩前在系统里造好三组演示数据,分别对应心理健康、轻度异常、中重度异常三个等级。展示时先演示正常学生的报告,再演示异常学生的报告,配合页面上的“系统预警”功能展示系统确实能区分不同状态。这个操作能让评委直观理解系统的业务价值和算法有效性。
最后讲一个我在答辩前一周踩过的教训:我当时用的数据库是本地 MySQL,答辩前一天把项目拷到笔记本上,因为没有导出数据,演示时测评记录全是空的。从那以后我每次做项目演示准备工作,都强制走一遍“SQL 脚本导出 → 新环境导入 → 登录测试 → 测评流程跑通”四步流程,确保演示所用的环境是干净且可再生的。希望这份踩坑经验帮你少走一些弯路。
本文还有配套的精品资源,点击获取