飞算Java在线学生成绩综合统计分析系统的设计与实现

飞算Java在线学生成绩综合统计分析系统的设计与实现
在这里插入图片描述


目录

引言

在教育信息化深度推进的背景下,学校对成绩数据的管理需求已从 “简单存储” 转向 “智能分析”—— 传统手工统计不仅耗时耗力,更无法快速挖掘成绩背后的教学问题(如班级薄弱学科、学生成绩波动趋势)。本次设计与实现的在线学生成绩综合统计分析系统,基于飞算 JavaAI 平台搭建,旨在解决成绩管理效率低、分析维度单一的痛点,为管理员、教师、学生三类角色提供差异化的数据服务,既保障成绩数据的安全管理,又能通过可视化看板输出教学决策依据,贴合现代化教学的实际业务场景。

技术栈

  • 后端:采用Spring Boot 3.x框架,简化项目配置与依赖管理,快速实现RESTful接口;结合MyBatis-Plus增强工具,减少数据库操作代码冗余,支持复杂查询与批量处理。
  • 数据库:使用MySQL 8.0,存储学生信息、成绩数据、课程信息等核心数据,其支持的复合索引与事务特性,能满足10万+条成绩记录的高效存储与安全读写。
  • 前端可视化:集成ECharts图表库与Vue.js框架,实现班级成绩分布直方图、个人成绩趋势折线图等可视化看板,提升数据可读性;采用Element UI组件库构建页面,保证交互体验一致性。
  • 开发工具:依赖IntelliJ IDEA 2024.3.2作为开发环境,搭配飞算JavaAI插件实现“自然语言转代码”,大幅缩短开发周期。
在这里插入图片描述

一.需求分析与规划

功能需求

系统需覆盖三类角色的核心业务场景,具体功能如下:

  • 管理员:成绩Excel批量导入(支持5000条/次)、课程信息增删改查、用户角色权限配置、全校成绩统计报表导出(PDF/Excel格式)。
  • 教师:单条成绩录入与修改、所带班级成绩分布分析(按分数段统计)、学生成绩波动预警(分数下降超20分自动提示)、学科平均分排名查询。
  • 学生:个人成绩明细查询、单科年级排名查看、学期成绩趋势图展示、薄弱学科(低于班级平均分10分)标注。

核心模块

按“高内聚、低耦合”原则,将系统划分为三大核心模块,模块间通过接口交互,便于后续扩展:

  1. 用户权限模块:管理用户注册、登录、角色分配,基于RBAC模型控制数据访问权限。
  2. 成绩管理模块:负责成绩的录入、导入、修改与存储,核心是保证成绩数据的准确性与安全性。
  3. 统计分析模块:实现成绩的多维度分析(班级、个人、分数段),输出可视化结果与统计报表。

技术选型

综合考虑开发效率、系统性能与教育场景适配性,技术栈选择逻辑如下:

  • 后端框架:Spring Boot 3.x(轻量化、社区支持丰富)+ MyBatis-Plus(简化SQL操作,支持批量插入)。
  • 数据库:MySQL 8.0(开源免费、支持大规模数据存储,兼容教育行业预算需求)。
  • 可视化:ECharts(开源图表库,支持多类型图表,适配成绩分析场景)。
  • 开发工具:飞算JavaAI(通过自然语言生成代码,降低重复编码工作量)。

从该图可清晰看到系统四大模块的功能拆解与技术支撑关系,为后续开发明确了执行路径。

在这里插入图片描述

二.环境准备

1. 下载IntelliJ IDEA

选择IntelliJ IDEA作为开发环境,其对Java项目的兼容性与插件生态更适配飞算JavaAI工具:

  1. 点击“Download”下载安装包,等待约5-10分钟(视网络速度而定)。

进入IntelliJ IDEA官网,根据操作系统选择“Windows 64-bit”版本(本文以Windows为例)。

在这里插入图片描述

2. 安装IntelliJ IDEA

按照安装向导逐步操作,重点配置如下:

  1. 选择安装路径(建议非C盘,如D:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2)。
  2. 勾选“Create Desktop Shortcut”(创建桌面快捷方式)与“Add launchers dir to PATH”(添加环境变量)。

点击“Install”开始安装,完成后勾选“Run IntelliJ IDEA”启动软件。
启动后界面如下,选择“New Project”进入项目创建流程:

在这里插入图片描述

3. 安装飞算JavaAI插件

飞算JavaAI插件是实现“自然语言转代码”的核心工具,安装步骤如下:

下载完成后,点击“Restart IDE”重启IDEA,插件生效。重启后左侧工具栏会出现“飞算JavaAI”图标,即为安装成功:

在这里插入图片描述

在搜索框输入“飞算”,找到“Feisuan JavaAI”插件,点击“Install”下载(需等待1-2分钟)。

在这里插入图片描述

打开IDEA,点击顶部菜单栏“File → Settings → Plugins”,进入插件市场。

在这里插入图片描述

4. 登录飞算JavaAI

需登录飞算账号绑定项目,才能使用代码生成功能:

  1. 在弹出的登录窗口中,输入飞算开发者中心账号(无账号需先到飞算官网注册),点击“登录”。

登录成功后,插件面板会显示“已绑定项目”,选择本次开发的项目(项目ID:EDU-2025-09),完成环境对接:

在这里插入图片描述

点击左侧“飞算JavaAI”图标,打开插件面板,点击“登录”按钮。

在这里插入图片描述

三.模块设计与编码

1. 飞算JavaAI生成基础模块

通过飞算插件输入自然语言需求,自动生成项目骨架与核心代码,步骤如下:

  1. 在飞算插件面板的“需求编辑器”中,输入以下指令:
    “生成在线学生成绩综合统计分析系统基础模块,包含:学生实体(学号、姓名、班级、入学年份)、成绩实体(成绩ID、关联学号、课程编码、分数、考试时间、考试类型)、课程实体(课程编码、课程名称、学分);实现用户登录/注册、成绩录入/导入、班级平均分统计、个人排名查询功能;技术栈:Spring Boot 3.x + MyBatis-Plus + MySQL 8.0。”
  2. 点击“提交需求”,按照指引一步步进行;

最后生成的项目结构如下,核心包与类已自动创建:

在这里插入图片描述

2. 核心代码展示

entity包下实体类示例

Student.java(学生实体)
packagecom.feisuan.edu.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.time.LocalDate;/** * <p> * 学生实体类:映射student表 * </p> * @author feisuan-javaai */@Data@NoArgsConstructor@AllArgsConstructor@TableName("student")// 关联数据库表名publicclassStudent{/** * 学号:主键,自增 */@TableId(type =IdType.AUTO)privateLong studentNo;/** * 学生姓名:非空 */privateString studentName;/** * 班级ID:格式如2024-01(2024级1班) */privateString classId;/** * 入学年份:如2024 */privateInteger enrollmentYear;/** * 创建时间:自动填充 */privateLocalDate createTime;}
Score.java(成绩实体)
packagecom.feisuan.edu.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.math.BigDecimal;importjava.time.LocalDate;/** * <p> * 成绩实体类:映射score表 * </p> * @author feisuan-javaai */@Data@NoArgsConstructor@AllArgsConstructor@TableName("score")publicclassScore{/** * 成绩ID:主键,自增 */@TableId(type =IdType.AUTO)privateLong id;/** * 关联学号:外键,关联student表的studentNo */privateLong studentNo;/** * 课程编码:关联course表的courseCode */privateString courseCode;/** * 分数:保留2位小数,范围0-100 */privateBigDecimal score;/** * 考试时间:如2024-06-20 */privateLocalDate examDate;/** * 考试类型:期中/期末/月考 */privateString examType;}

dto包下数据传输对象示例

ScoreAddDTO.java(成绩录入请求DTO)
packagecom.feisuan.edu.dto;importjakarta.validation.constraints.DecimalMax;importjakarta.validation.constraints.DecimalMin;importjakarta.validation.constraints.NotBlank;importjakarta.validation.constraints.NotNull;importlombok.Data;importjava.math.BigDecimal;importjava.time.LocalDate;/** * <p> * 成绩录入请求DTO:接收前端传入的成绩数据,含参数校验 * </p> * @author feisuan-javaai */@DatapublicclassScoreAddDTO{/** * 关联学号:必填 */@NotNull(message ="学号不能为空")privateLong studentNo;/** * 课程编码:必填 */@NotBlank(message ="课程编码不能为空")privateString courseCode;/** * 分数:必填,0-100分 */@NotNull(message ="分数不能为空")@DecimalMin(value ="0.00", message ="分数不能低于0分")@DecimalMax(value ="100.00", message ="分数不能高于100分")privateBigDecimal score;/** * 考试时间:必填 */@NotNull(message ="考试时间不能为空")privateLocalDate examDate;/** * 考试类型:必填,只能是期中/期末/月考 */@NotBlank(message ="考试类型不能为空")privateString examType;}
StudentRankQueryDTO.java(个人排名查询DTO)
packagecom.feisuan.edu.dto;importjakarta.validation.constraints.NotBlank;importjakarta.validation.constraints.NotNull;importlombok.Data;/** * <p> * 个人排名查询DTO:接收前端查询参数 * </p> * @author feisuan-javaai */@DatapublicclassStudentRankQueryDTO{/** * 学号:必填 */@NotNull(message ="学号不能为空")privateLong studentNo;/** * 课程编码:必填 */@NotBlank(message ="课程编码不能为空")privateString courseCode;/** * 学期:必填,格式如2024-2025-1 */@NotBlank(message ="学期不能为空")privateString term;}

vo包下视图对象示例

StudentRankVO.java(个人排名返回VO)
packagecom.feisuan.edu.vo;importlombok.Data;importjava.math.BigDecimal;/** * <p> * 个人排名返回VO:封装前端需要的排名数据,隐藏数据库字段细节 * </p> * @author feisuan-javaai */@DatapublicclassStudentRankVO{/** * 学号 */privateLong studentNo;/** * 学生姓名 */privateString studentName;/** * 课程名称 */privateString courseName;/** * 分数 */privateBigDecimal score;/** * 年级排名 */privateInteger rank;/** * 年级总人数 */privateInteger gradeTotal;/** * 排名百分比:如30.50% */privateString rankPercentage;}

mapper包下数据访问接口示例

ScoreMapper.java
packagecom.feisuan.edu.mapper;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.feisuan.edu.entity.Score;importorg.apache.ibatis.annotations.Mapper;importorg.apache.ibatis.annotations.Select;importjava.util.List;/** * <p> * 成绩Mapper接口:继承MyBatis-Plus的BaseMapper,自带CRUD方法 * </p> * @author feisuan-javaai */@MapperpublicinterfaceScoreMapperextendsBaseMapper<Score>{/** * 自定义查询:按班级、课程、学期查询成绩列表 */@Select("SELECT * FROM score s JOIN student st ON s.student_no = st.student_no "+"WHERE st.class_id = #{classId} AND s.course_code = #{courseCode} AND s.term = #{term}")List<Score>selectByClassAndCourse(String classId,String courseCode,String term);/** * 自定义查询:统计年级内某课程分数高于目标分数的人数 */@Select("SELECT COUNT(*) FROM score WHERE course_code = #{courseCode} AND term = #{term} AND score > #{targetScore}")LongcountHigherScore(String courseCode,String term,BigDecimal targetScore);}

service包下接口及实现类示例

ScoreService.java(成绩服务接口)
packagecom.feisuan.edu.service;importcom.baomidou.mybatisplus.extension.service.IService;importcom.feisuan.edu.dto.ScoreAddDTO;importcom.feisuan.edu.dto.StudentRankQueryDTO;importcom.feisuan.edu.entity.Score;importcom.feisuan.edu.vo.ScoreDistributionVO;importcom.feisuan.edu.vo.StudentRankVO;/** * <p> * 成绩服务接口:定义成绩相关业务逻辑 * </p> * @author feisuan-javaai */publicinterfaceScoreServiceextendsIService<Score>{/** * 录入成绩 * @param scoreAddDTO 成绩录入参数 * @return 录入成功的成绩实体 */ScoreaddScore(ScoreAddDTO scoreAddDTO);/** * 查询个人年级排名 * @param queryDTO 排名查询参数 * @return 个人排名信息VO */StudentRankVOgetStudentGradeRank(StudentRankQueryDTO queryDTO);/** * 统计班级成绩分布(按分数段) * @param classId 班级ID * @param courseCode 课程编码 * @param term 学期 * @return 成绩分布VO */ScoreDistributionVOgetClassScoreDistribution(String classId,String courseCode,String term);}
ScoreServiceImpl.java(成绩服务实现类)
packagecom.feisuan.edu.service.impl;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.feisuan.edu.dto.ScoreAddDTO;importcom.feisuan.edu.dto.StudentRankQueryDTO;importcom.feisuan.edu.entity.Course;importcom.feisuan.edu.entity.Score;importcom.feisuan.edu.entity.Student;importcom.feisuan.edu.mapper.CourseMapper;importcom.feisuan.edu.mapper.ScoreMapper;importcom.feisuan.edu.mapper.StudentMapper;importcom.feisuan.edu.service.ScoreService;importcom.feisuan.edu.vo.ScoreDistributionVO;importcom.feisuan.edu.vo.StudentRankVO;importlombok.RequiredArgsConstructor;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.BeanUtils;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.List;importjava.util.Map;importjava.util.stream.Collectors;/** * <p> * 成绩服务实现类:实现成绩相关业务逻辑 * </p> * @author feisuan-javaai */@Slf4j@Service@RequiredArgsConstructor// 构造器注入,替代@AutowiredpublicclassScoreServiceImplextendsServiceImpl<ScoreMapper,Score>implementsScoreService{privatefinalScoreMapper scoreMapper;privatefinalStudentMapper studentMapper;privatefinalCourseMapper courseMapper;@Override@Transactional// 事务控制:确保成绩录入失败时回滚publicScoreaddScore(ScoreAddDTO scoreAddDTO){ log.info("开始录入成绩:学号={}, 课程编码={}", scoreAddDTO.getStudentNo(), scoreAddDTO.getCourseCode());// 1. 校验学生与课程是否存在Student student = studentMapper.selectById(scoreAddDTO.getStudentNo());Course course = courseMapper.selectById(scoreAddDTO.getCourseCode());if(student ==null){thrownewRuntimeException("学号不存在:"+ scoreAddDTO.getStudentNo());}if(course ==null){thrownewRuntimeException("课程编码不存在:"+ scoreAddDTO.getCourseCode());}// 2. 转换DTO为实体Score score =newScore();BeanUtils.copyProperties(scoreAddDTO, score);// 补充学期(从考试时间推导,如2024-06属于2023-2024-2学期)String term =getTermByExamDate(scoreAddDTO.getExamDate()); score.setTerm(term);// 3. 保存成绩save(score); log.info("成绩录入成功:成绩ID={}", score.getId());return score;}@OverridepublicStudentRankVOgetStudentGradeRank(StudentRankQueryDTO queryDTO){ log.info("查询个人排名:学号={}, 课程编码={}, 学期={}", queryDTO.getStudentNo(), queryDTO.getCourseCode(), queryDTO.getTerm());// 1. 查询学生、课程与成绩信息Student student = studentMapper.selectById(queryDTO.getStudentNo());Course course = courseMapper.selectById(queryDTO.getCourseCode());Score score =lambdaQuery().eq(Score::getStudentNo, queryDTO.getStudentNo()).eq(Score::getCourseCode, queryDTO.getCourseCode()).eq(Score::getTerm, queryDTO.getTerm()).one();if(score ==null){thrownewRuntimeException("未查询到该学生的成绩记录");}// 2. 统计排名(高于当前分数的人数+1)Long higherCount = scoreMapper.countHigherScore( queryDTO.getCourseCode(), queryDTO.getTerm(), score.getScore());Integer rank = higherCount.intValue()+1;// 3. 统计年级总人数Integer gradeTotal =lambdaQuery().eq(Score::getCourseCode, queryDTO.getCourseCode()).eq(Score::getTerm, queryDTO.getTerm()).list().size();// 4. 封装VO返回StudentRankVO rankVO =newStudentRankVO(); rankVO.setStudentNo(student.getStudentNo()); rankVO.setStudentName(student.getStudentName()); rankVO.setCourseName(course.getCourseName()); rankVO.setScore(score.getScore()); rankVO.setRank(rank); rankVO.setGradeTotal(gradeTotal);// 计算排名百分比(保留2位小数)String rankPercentage =String.format("%.2f%%",(double) rank / gradeTotal *100); rankVO.setRankPercentage(rankPercentage);return rankVO;}@OverridepublicScoreDistributionVOgetClassScoreDistribution(String classId,String courseCode,String term){// 1. 查询班级成绩列表List<Score> scoreList = scoreMapper.selectByClassAndCourse(classId, courseCode, term);// 2. 按分数段分组统计Map<String,Long> distributionMap = scoreList.stream().collect(Collectors.groupingBy( s ->{double scoreValue = s.getScore().doubleValue();if(scoreValue <60)return"0-59";elseif(scoreValue <70)return"60-69";elseif(scoreValue <80)return"70-79";elseif(scoreValue <90)return"80-89";elsereturn"90-100";},Collectors.counting()));// 3. 封装VOScoreDistributionVO distributionVO =newScoreDistributionVO(); distributionVO.setClassId(classId); distributionVO.setCourseCode(courseCode); distributionVO.setTerm(term); distributionVO.setSegment0_59(distributionMap.getOrDefault("0-59",0L)); distributionVO.setSegment60_69(distributionMap.getOrDefault("60-69",0L)); distributionVO.setSegment70_79(distributionMap.getOrDefault("70-79",0L)); distributionVO.setSegment80_89(distributionMap.getOrDefault("80-89",0L)); distributionVO.setSegment90_100(distributionMap.getOrDefault("90-100",0L));return distributionVO;}/** * 辅助方法:根据考试时间推导学期 */privateStringgetTermByExamDate(java.time.LocalDate examDate){int year = examDate.getYear();int month = examDate.getMonthValue();if(month >=9&& month <=12){return year +"-"+(year +1)+"-1";// 9-12月属于下学年第一学期}else{return(year -1)+"-"+ year +"-2";// 1-8月属于本学年第二学期}}}

3.网页展示

在这里插入图片描述


登录进去之后,我们可以看到很详细的页面:

在这里插入图片描述

四.自我感想

在开发在线学生成绩综合统计分析系统的过程中,我对“教育信息化”的理解从“技术落地”转向了“业务适配”。比如最初仅关注成绩的增删改查,后来发现教师更需要“成绩波动预警”来定位待辅导学生,学生需要“薄弱学科标注”来明确学习方向——这让我意识到,技术开发必须围绕用户实际需求展开。

技术层面,飞算JavaAI平台的“自然语言转代码”功能大幅降低了重复编码工作量,原本需要2天编写的Entity、Mapper层代码,现在20分钟即可生成,让我有更多精力投入到业务逻辑优化(如排名算法、缓存策略)。同时,通过解决“数据重复导入”“可视化加载慢”等问题,我对数据库索引优化、Redis缓存使用的理解也更加深入,不再是单纯“会用”,而是“能用好”。

这次开发也让我明白,一个合格的系统不仅要“功能能用”,更要“体验好用”——比如为成绩录入添加参数校验,避免教师输入错误分数;为统计报表提供多格式导出,方便管理员汇报使用。这些细节虽小,却直接影响用户对系统的认可程度。

总结

本次在线学生成绩综合统计分析系统的设计与实现,完整覆盖了“需求分析→环境搭建→模块开发→问题优化”的全流程,成功构建了支持多角色、多维度分析的成绩管理系统。系统的核心价值在于:通过飞算JavaAI提升开发效率,通过可视化分析挖掘成绩数据价值,通过权限控制保障数据安全,切实解决了传统成绩管理的痛点。

后续,我计划进一步扩展系统功能:一是添加AI成绩预测模块,基于历史数据预测学生期末成绩;二是对接区域教育大数据平台,实现跨学校成绩对比分析。

Read more

【数据结构副本篇】顺序表 链表OJ

【数据结构副本篇】顺序表 链表OJ

🏝️专栏:【数据结构实战篇】 🌅主页:f狐o狸x 目录         一、移除元素         1.1 题目分析         1.2 解题代码 二、删除有序数组中的重复项         2.1 题目分析         2.2 解题代码 三、合并两个有序数组         3.1 题目分析                 3.2 解题代码 四、移除链表元素         4.1 题目分析         4.2 解题代码 五、反转一个链表         5.1 题目分析         5.2 解题代码         六、链表的中间节点         6.1 题目分析

By Ne0inhk

Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx‘):从报错根源到根治方案(前端/后端通用)

Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’):从报错根源到根治方案(前端/后端通用) 引言:被“undefined”支配的恐惧 如果你是开发者,大概率在控制台见过这句红色报错——“Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx’)”(或后端类似“Cannot read field ‘xxx’ of null”)。据2024年《开发者调试痛点调研》显示,这类“空值访问错误”占前端日常报错的32%,后端接口处理报错的28%,平均每次调试耗时15-30分钟,尤其在复杂业务场景(如嵌套数据渲染、异步接口依赖)中,往往需要逐层排查才能定位根因。 但多数开发者解决这类报错时,只停留在“加个if判断”

By Ne0inhk
Flutter for OpenHarmony: Flutter 三方库 fixnum 解决鸿蒙 Web 与原生端 64 位大整数精度失真难题(精准计算护卫)

Flutter for OpenHarmony: Flutter 三方库 fixnum 解决鸿蒙 Web 与原生端 64 位大整数精度失真难题(精准计算护卫)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在进行 OpenHarmony 的跨平台开发时,你可能会遇到一个诡异的 Bug:同样的 64 位长整数(如 Int64),在鸿蒙原生(Native)模式下运行正常,但编译为 Flutter Web 模式在浏览器运行时,数值却发生了精度漂移或溢出。 1. 产生原因:JavaScript 原生的数字类型实质上是 64 位浮点数,它能安全表示的最大整数只有 53 位( 2 53 − 1 2^{53}-1 253−1)。 2. 后果:大额订单 ID、高精度的金融分位值、或是底层硬件的 64 位地址位,在

By Ne0inhk
平衡车:核心算法与工程实现

平衡车:核心算法与工程实现

目录 一、核心算法架构 二、完整工程代码实现 1. 头文件定义(balance_car_full.h) 2. 核心算法实现(balance_car_full.c) 3. 主函数(main.c) 4. 无刷电机驱动(bldc_driver.c 核心片段) 三、关键模块工程化解释 1. 无刷电机控制(工业级适配) 2. 方向控制 3. 通信接口 4. 工程化优化 四、工程落地适配要点 1. 硬件适配 2. PID 参数调试步骤 3. 编译与烧录 五、总结 本次提供的算法是工业级可落地版本,

By Ne0inhk