30 分钟生成学生成绩管理系统!飞算 JavaAI 从需求到落地实战

30 分钟生成学生成绩管理系统!飞算 JavaAI 从需求到落地实战

前言

在高校教学管理工作中,学生成绩是教学质量评估、学生学业监测的核心数据,但传统Excel表格管理或单机版系统常面临数据同步滞后、权限管控缺失、成绩分析低效等问题。为解决这一痛点,以“学生成绩管理系统”为开发目标,借助飞算JavaAI工具实现全流程开发,本文将从需求分析到系统落地的关键环节进行梳理,分享AI辅助开发的高效实践经验。

在这里插入图片描述

一、需求分析与规划

1. 功能需求

系统需满足三类核心用户(教学管理员、教师、学生)的差异化需求,功能拆解如下:

  • 教学管理员端:用户管理(新增教师/学生账号、分配班级与课程权限)、课程管理(创建课程、关联授课教师)、成绩模板配置(设置成绩构成比例,如平时成绩占30%、期末成绩占70%)、成绩数据导出(按班级/课程/学期生成Excel报表)、系统日志查看(跟踪成绩修改、账号操作记录);
  • 教师端:成绩录入(按学生名单批量或单个录入平时、期中、期末成绩,系统自动计算总成绩)、成绩审核(提交总成绩前预览核对,提交后锁定不可修改)、成绩分析(查看所授课程的平均分、及格率、分数段分布图表)、学生成绩反馈(回复学生的成绩疑问,标注异常成绩说明);
  • 学生端:成绩查询(按学期/课程查看个人各项成绩及总成绩)、成绩趋势分析(查看同一课程历年成绩对比或个人多学期成绩变化)、成绩异议申请(对疑问成绩提交申诉,跟踪处理进度)、成绩单下载(下载经管理员审核后的官方成绩证明)。

2. 核心模块

基于需求拆解,系统划分为5个联动模块,模块职责与关联关系如下表所示:

模块名称核心功能关联模块
用户权限模块账号注册登录、角色权限分配(管理员/教师/学生)、密码重置、账号状态管理所有模块(权限校验)
课程管理模块课程信息维护(新增/编辑/删除课程)、班级-课程-教师关联、课程学期管理用户权限模块(教师课程权限)、成绩管理模块(课程成绩归属)
成绩管理模块成绩录入与计算、成绩审核与锁定、成绩修改申请与审批、异常成绩标注课程管理模块(课程数据)、用户权限模块(成绩操作权限)
数据统计模块成绩分析(平均分、及格率、分数段)、成绩趋势图表生成、数据报表导出成绩管理模块(成绩数据源)、课程管理模块(课程筛选条件)
消息通知模块成绩录入提醒、成绩审核结果推送、学生成绩异议反馈、系统公告发布成绩管理模块(成绩状态变更)、用户权限模块(接收人匹配)

二、飞算JavaAI开发实录

1. 步骤1:输入提示词(明确开发需求)

打开IntelliJ IDEA并启动飞算JavaAI插件,在“需求输入”界面输入提示词:“开发学生成绩管理系统后端代码,基于Spring Boot 3.0和MySQL 8.0,需包含用户权限(管理员/教师/学生三类角色)、课程管理(课程CRUD与师生关联)、成绩管理(成绩录入/计算/审核)三大核心模块,生成实体类、Mapper接口、Service层、Controller层代码,符合RESTful API规范,需支持成绩自动计算(按比例汇总)与权限细粒度控制(如教师仅能操作所授课程成绩)。”

2. 步骤2:AI理解需求(需求拆解与确认)

提交提示词后,飞算JavaAI约8秒生成需求拆解报告,核心内容包括:

  • 需求匹配度分析:明确系统为教学场景下的成绩管理类系统,核心诉求是“数据安全+效率提升”,需重点解决权限隔离与成绩自动化处理,与教育领域常见管理系统需求高度适配;
  • 模块拆解确认:将需求细化为用户权限模块(含角色权限矩阵设计,如管理员全权限、教师仅课程内权限)、课程管理模块(含班级-课程-教师关联逻辑)、成绩管理模块(含成绩计算规则配置、审核流程设计)。

3. 步骤3:设计接口(RESTful API规划)

插件自动跳转至“接口设计”界面,围绕三大核心模块生成接口说明,明确各接口功能定位:

  • 用户权限接口:负责账号认证(登录生成JWT令牌)、权限校验(接口访问时验证角色权限)、用户信息维护,例如/api/user/login(登录接口)、/api/user/role/assign(权限分配接口);
  • 课程管理接口:实现课程信息CRUD与关联管理,例如/api/course/add(新增课程)、/api/course/teacher/bind(课程-教师绑定接口);
  • 成绩管理接口:覆盖成绩录入、计算、审核全流程,例如/api/score/batch/save(批量录入成绩)、/api/score/calculate(自动计算总成绩接口)、/api/score/audit(成绩审核接口)。

4. 步骤4:表结构设计(数据库表生成)

接口设计完成后,插件自动推导数据库表结构(支持手动编辑),核心表结构如下:

CREATE TABLE user_info ( user_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '用户唯一标识', username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名', password VARCHAR(255) NOT NULL COMMENT '密码(加密存储)', user_role ENUM('admin', 'teacher', 'student') NOT NULL COMMENT '用户角色:admin-管理员,teacher-教师,student-学生', status TINYINT DEFAULT 1 COMMENT '用户状态:1-正常,0-禁用', create_by VARCHAR(50) COMMENT '创建人', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_by VARCHAR(50) COMMENT '修改人', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间')COMMENT='用户信息表'; CREATE TABLE course_info ( course_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '课程唯一标识', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', course_code VARCHAR(50) NOT NULL UNIQUE COMMENT '课程编号', teacher_id BIGINT COMMENT '授课教师ID', description TEXT COMMENT '课程描述', credits INT DEFAULT 0 COMMENT '学分', status TINYINT DEFAULT 1 COMMENT '课程状态:1-启用,0-停用', create_by VARCHAR(50) COMMENT '创建人', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_by VARCHAR(50) COMMENT '修改人', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间')COMMENT='课程信息表'; CREATE TABLE student_course ( relation_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '师生关联关系唯一标识', student_id BIGINT NOT NULL COMMENT '学生用户ID', course_id BIGINT NOT NULL COMMENT '课程ID', select_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '选课时间', create_by VARCHAR(50) COMMENT '创建人', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间')COMMENT='学生选课关系表'; CREATE TABLE score_record ( score_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '成绩记录唯一标识', student_id BIGINT NOT NULL COMMENT '学生用户ID', course_id BIGINT NOT NULL COMMENT '课程ID', score_type ENUM('exam', 'homework', 'project', 'quiz') NOT NULL COMMENT '成绩类型:exam-考试,homework-作业,project-项目,quiz-小测', score_value DECIMAL(5,1) NOT NULL COMMENT '成绩数值', score_weight DECIMAL(3,2) DEFAULT 1.00 COMMENT '该成绩在总评中的权重比例', is_reviewed TINYINT DEFAULT 0 COMMENT '是否已审核:0-未审核,1-已审核', review_time DATETIME COMMENT '审核时间', reviewer VARCHAR(50) COMMENT '审核人', create_by VARCHAR(50) COMMENT '创建人', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_by VARCHAR(50) COMMENT '修改人', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间')COMMENT='成绩记录表';

5. 步骤5:处理逻辑(接口实现思路生成)

进入“处理逻辑”界面,插件针对核心接口生成详细业务流程,以“成绩管理”模块为例,关键接口逻辑如下:

接口名称: 录入成绩

入参对象属性:studentId(学生ID,必填)、courseId(课程ID,必填)、score(成绩分数,必填)、type(成绩类型,必填)

处理逻辑:检查学生是否选课且课程是否存在

返回RestResult结果:{“code”:“000001”,“msg”:“学生未选该课程或课程不存在”,“data”:…}

处理逻辑:将成绩信息保存到数据库

返回RestResult结果:{“code”:“000000”,“msg”:“调用成功”,“data”:…}

接口名称:计算并汇总成绩

入参对象属性:studentId(学生ID,必填)、courseId(课程ID,必填)

处理逻辑:获取该学生在指定课程下的所有成绩项

返回RestResult结果:{“code”:“000001”,“msg”:“无相关成绩记录”,“data”:…}

处理逻辑:根据预设比例规则进行加权计算

返回RestResult结果:{“code”:“000000”,“msg”:“调用成功”,“data”:…}

接口名称:审核成绩

入参对象属性:studentId(学生ID,必填)、courseId(课程ID,必填)、status(审核状态,必填)

处理逻辑:确认成绩是否存在且处于待审核状态

返回RestResult结果:{“code”:“000001”,“msg”:“成绩不存在或已审核”,“data”:…}

处理逻辑:更新成绩的审核状态为通过或拒绝

返回RestResult结果:{“code”:“000000”,“msg”:“调用成功”,“data”:…}

接口名称:修改成绩

入参对象属性:studentId(学生ID,必填)、courseId(课程ID,必填)、newScore(新成绩分数,必填)

处理逻辑:验证成绩是否允许修改(如:是否已审核)

返回RestResult结果:{“code”:“000001”,“msg”:“成绩不可修改”,“data”:…}

处理逻辑:更新对应的成绩数据

返回RestResult结果:{“code”:“000000”,“msg”:“调用成功”,“data”:…}

接口名称:查看成绩历史记录

入参对象属性:studentId(学生ID,必填)、courseId(课程ID,必填)

处理逻辑:查询该学生在指定课程下所有的成绩变更记录

返回RestResult结果:{“code”:“000000”,“msg”:“调用成功”,“data”:…}

6. 步骤6:生成源码(完整工程代码输出)

确认处理逻辑后,点击“生成源码”,飞算JavaAI约3分钟生成完整工程代码(遵循MVC架构),核心代码结构如下:

  • 配置类:src/main/java/score/system/config/CorsConfig(跨域配置)、RedisConfig(Redis缓存配置)、SecurityConfig(权限安全配置);
  • Controller层:src/main/java/score/system/controller/UserController.java、CourseController.java、ScoreController.java(接口映射与参数接收);
  • DTO类:src/main/java/score/system/dto/request/ScoreBatchSaveRequest.java(批量成绩录入请求类)、ScoreAuditRequest.java(成绩审核请求类),src/main/java/score/system/dto/response/ScoreStatisticResponse.java(成绩统计响应类);
  • 实体类:src/main/java/score/system/entity/UserInfo.java、CourseInfo.java、ScoreInfo.java、ScoreRule.java(映射数据库表);
  • Service层:src/main/java/score/system/service/UserService.java、CourseService.java、ScoreService.java(接口定义)及对应的impl实现类(业务逻辑实现);
  • 启动类:src/main/java/score/system/ScoreManagementApplication.java(项目入口)。

生成的代码无语法错误,导入IDEA后可直接启动测试。

三、优化与调试心得

1. 遇到的问题及解决方案

(1)问题1:成绩计算精度丢失

生成的ScoreService中,总成绩计算使用普通浮点数运算,存在精度丢失问题(如30%平时成绩+70%期末成绩,结果出现多位小数)。
解决方案:通过飞算JavaAI“智能会话”查询“Java BigDecimal精确计算成绩比例”,获取优化代码,在ScoreServiceImpl中使用BigDecimal类进行比例计算,示例如下:

BigDecimal usualRatio =newBigDecimal(scoreRule.getUsualRatio()).divide(newBigDecimal(100));BigDecimal midtermRatio =newBigDecimal(scoreRule.getMidtermRatio()).divide(newBigDecimal(100));BigDecimal finalRatio =newBigDecimal(scoreRule.getFinalRatio()).divide(newBigDecimal(100));BigDecimal totalScore = usualScore.multiply(usualRatio).add(midtermScore.multiply(midtermRatio)).add(finalScore.multiply(finalRatio)).setScale(2,BigDecimal.ROUND_HALF_UP);
(2)问题2:高频成绩查询性能低

学生集中查询成绩时,频繁访问MySQL数据库,导致接口响应延迟(平均响应时间超1.5秒)。
解决方案:借助飞算JavaAI“智能会话”获取“Spring Boot Redis缓存成绩数据”方案,在ScoreService的成绩查询方法上添加@Cacheable注解,缓存课程成绩统计结果与学生个人成绩,示例:

@Cacheable(value ="score:student", key ="#studentId + ':' + #courseId")publicScoreInfogetStudentCourseScore(Long studentId,Long courseId){return scoreMapper.selectByStudentAndCourse(studentId, courseId);}

优化后接口响应时间降至0.3秒以内。

(3)问题3:成绩修改无痕迹

教师提交成绩后,若管理员驳回需修改,但生成的代码未记录成绩修改历史,无法追溯变更内容。
解决方案:手动新增score_history(成绩修改历史表),并通过飞算JavaAI生成ScoreHistory实体与对应的Mapper、Service代码,在ScoreServiceImpl的update方法中添加历史记录逻辑,每次修改成绩时自动保存旧数据至score_history表,实现“每改必留痕”。

四、系统成果展示与应用价值

1. 功能成果展示

系统开发完成后,通过本地部署与多角色实测,实现了 “需求全覆盖、操作零门槛、数据高可靠” 的开发目标,核心功能代码成果如下:

package com.example.service.impl; import com.example.demo1.dto.request.*; import com.example.dto.request.BoundTeacherToCourseRequest; import com.example.dto.request.CreateCourseRequest; import com.example.dto.request.DeleteCourseRequest; import com.example.dto.request.SelectCourseRequest; import com.example.dto.request.UpdateCourseRequest; import com.example.dto.response.RestResult; import com.example.entity.CourseInfo; import com.example.entity.StudentCourse; import com.example.entity.UserInfo; import com.example.repository.CourseRepository; import com.example.repository.StudentCourseRepository; import com.example.repository.UserRepository; import com.example.service.CourseService; import java.time.LocalDateTime; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * 课程服务实现类 * */ @Slf4j @Service @Transactional public class CourseServiceImpl implements CourseService { @Autowired private CourseRepository courseRepository; @Autowired private UserRepository userRepository; @Autowired private StudentCourseRepository studentCourseRepository; @Override public RestResult<Object> createCourse(CreateCourseRequest request) { // 校验课程名称是否已存在 if (courseRepository.findByCourseName(request.getCourseName()) != null) { return RestResult.error("000001", "课程名称已存在"); } // 构造新的课程信息对象 CourseInfo courseInfo = new CourseInfo(); BeanUtils.copyProperties(request, courseInfo); courseInfo.setCreateTime(LocalDateTime.now()); courseInfo.setUpdateTime(LocalDateTime.now()); courseInfo.setStatus((byte) 1); // 默认启用 try { courseRepository.save(courseInfo); return RestResult.success(courseInfo); } catch (Exception e) { log.error("创建课程失败", e); return RestResult.error("999999", "系统错误"); } } @Override public RestResult<Object> queryCourseList(Integer pageNo, Integer pageSize, String keyword) { // 设置默认值 if (pageNo == null || pageNo <= 0) { pageNo = 1; } if (pageSize == null || pageSize <= 0) { pageSize = 10; } Pageable pageable = PageRequest.of(pageNo - 1, pageSize); List<CourseInfo> courses = courseRepository.findAll(pageable).getContent(); Page<CourseInfo> coursePage = new PageImpl<>(courses, pageable, courseRepository.count()); return RestResult.success(coursePage); } @Override public RestResult<Object> updateCourse(UpdateCourseRequest request) { // 判断课程是否存在 CourseInfo existingCourse = courseRepository.findById(request.getCourseId()).orElse(null); if (existingCourse == null) { return RestResult.error("000001", "课程不存在"); } // 如果传了课程名称,则检查是否与其他课程冲突 if (request.getCourseName() != null && !request.getCourseName().equals(existingCourse.getCourseName())) { if (courseRepository.findByCourseName(request.getCourseName()) != null) { return RestResult.error("000001", "课程名称已存在"); } } // 更新课程信息 BeanUtils.copyProperties(request, existingCourse, "courseId", "createTime"); // 忽略这些字段 existingCourse.setUpdateTime(LocalDateTime.now()); try { courseRepository.save(existingCourse); return RestResult.success(existingCourse); } catch (Exception e) { log.error("更新课程失败", e); return RestResult.error("999999", "系统错误"); } } @Override public RestResult<Object> deleteCourse(DeleteCourseRequest request) { // 判断课程是否存在 CourseInfo existingCourse = courseRepository.findById(request.getCourseId()).orElse(null); if (existingCourse == null) { return RestResult.error("000001", "课程不存在"); } try { // 删除相关的学生选课记录 studentCourseRepository.deleteByCourseId(request.getCourseId()); // 删除课程本身 courseRepository.deleteById(request.getCourseId()); return RestResult.success(null); } catch (Exception e) { log.error("删除课程失败", e); return RestResult.error("999999", "系统错误"); } } @Override public RestResult<Object> boundTeacherToCourse(BoundTeacherToCourseRequest request) { // 判断教师与课程是否存在 UserInfo teacher = userRepository.findById(request.getTeacherId()).orElse(null); CourseInfo course = courseRepository.findById(request.getCourseId()).orElse(null); if (teacher == null || course == null) { return RestResult.error("000001", "教师或课程不存在"); } // 更新课程中的教师ID course.setTeacherId(request.getTeacherId()); course.setUpdateTime(LocalDateTime.now()); try { courseRepository.save(course); return RestResult.success(null); } catch (Exception e) { log.error("绑定教师到课程失败", e); return RestResult.error("999999", "系统错误"); } } @Override public RestResult<Object> selectCourse(SelectCourseRequest request) { // 判断学生和课程是否存在 UserInfo student = userRepository.findById(request.getStudentId()).orElse(null); CourseInfo course = courseRepository.findById(request.getCourseId()).orElse(null); if (student == null || course == null) { return RestResult.error("000001", "学生或课程不存在"); } // 检查该学生是否已经选过此课程 StudentCourse existingRecord = studentCourseRepository.findByStudentIdAndCourseId(request.getStudentId(), request.getCourseId()); if (existingRecord != null) { return RestResult.error("000001", "该学生已选过此课程"); } // 添加学生的选课记录 StudentCourse record = new StudentCourse(); record.setStudentId(request.getStudentId()); record.setCourseId(request.getCourseId()); record.setCreateTime(LocalDateTime.now()); try { studentCourseRepository.save(record); return RestResult.success(null); } catch (Exception e) { log.error("学生选课失败", e); return RestResult.error("999999", "系统错误"); } } } 
package com.example.service.impl; import com.example.dto.request.ScoreModifyRequest; import com.example.dto.request.ScoreRecordRequest; import com.example.dto.request.ScoreReviewRequest; import com.example.entity.CourseInfo; import com.example.entity.ScoreRecord; import com.example.entity.StudentCourse; import com.example.repository.CourseRepository; import com.example.repository.ScoreRepository; import com.example.repository.StudentCourseRepository; import com.example.service.ScoreService; import com.example.util.RestResult; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * 成绩服务实现类 */ @Slf4j @Service @Transactional public class ScoreServiceImpl implements ScoreService { @Autowired private ScoreRepository scoreRepository; @Autowired private CourseRepository courseRepository; @Autowired private StudentCourseRepository studentCourseRepository; /** * 录入成绩 * * @param request 入参对象 * @return RestResult 结果 */ @Override public RestResult recordScore(ScoreRecordRequest request) { // 检查学生是否选课且课程是否存在 if (!checkStudentSelectCourse(request.getStudentId(), request.getCourseId())) { return RestResult.error("学生未选该课程或课程不存在"); } try { ScoreRecord scoreRecord = new ScoreRecord(); scoreRecord.setStudentId(request.getStudentId()); scoreRecord.setCourseId(request.getCourseId()); scoreRecord.setScoreType(request.getType()); scoreRecord.setScoreValue(BigDecimal.valueOf(request.getScore())); scoreRecord.setIsReviewed(0); // 默认未审核 scoreRecord.setCreateTime(LocalDateTime.now()); scoreRecord.setUpdateTime(LocalDateTime.now()); scoreRepository.save(scoreRecord); return RestResult.success("录入成功"); } catch (Exception e) { log.error("录入成绩失败: ", e); return RestResult.error("系统异常,请稍后再试"); } } /** * 计算并汇总成绩 * * @param studentId 学生ID * @param courseId 课程ID * @return RestResult 结果 */ @Override public RestResult calculateScore(Long studentId, Long courseId) { List<ScoreRecord> records = scoreRepository.findByStudentIdAndCourseIdOrderByCreateTimeAsc(studentId, courseId); if (records.isEmpty()) { return RestResult.error("无相关成绩记录"); } double totalScore = 0.0; for (ScoreRecord record : records) { if (record.getIsReviewed() == 1) { // 只计算已审核的成绩 totalScore += record.getScoreValue().doubleValue() * record.getScoreWeight().doubleValue(); } } return RestResult.success(totalScore); } /** * 审核成绩 * * @param request 入参对象 * @return RestResult 结果 */ @Override public RestResult reviewScore(ScoreReviewRequest request) { ScoreRecord latestRecord = scoreRepository.findLatestByStudentIdAndCourseId(request.getStudentId(), request.getCourseId()); if (latestRecord == null || latestRecord.getIsReviewed() == 1) { return RestResult.error("成绩不存在或已审核"); } try { latestRecord.setIsReviewed(request.getStatus() ? 1 : 0); latestRecord.setReviewer("system"); // 这里可以替换为当前登录用户的用户名 latestRecord.setReviewTime(LocalDateTime.now()); latestRecord.setUpdateTime(LocalDateTime.now()); scoreRepository.save(latestRecord); return RestResult.success("审核完成"); } catch (Exception e) { log.error("审核成绩失败: ", e); return RestResult.error("系统异常,请稍后再试"); } } /** * 修改成绩 * * @param request 入参对象 * @return RestResult 结果 */ @Override public RestResult modifyScore(ScoreModifyRequest request) { ScoreRecord latestRecord = scoreRepository.findLatestByStudentIdAndCourseId(request.getStudentId(), request.getCourseId()); if (latestRecord == null) { return RestResult.error("成绩不存在"); } // 判断是否已经审核过 if (latestRecord.getIsReviewed() == 1) { return RestResult.error("成绩不可修改"); } try { latestRecord.setScoreValue(BigDecimal.valueOf(request.getNewScore())); latestRecord.setUpdateTime(LocalDateTime.now()); scoreRepository.save(latestRecord); return RestResult.success("修改成功"); } catch (Exception e) { log.error("修改成绩失败: ", e); return RestResult.error("系统异常,请稍后再试"); } } /** * 查看成绩历史记录 * * @param studentId 学生ID * @param courseId 课程ID * @return RestResult 结果 */ @Override public RestResult getScoreHistory(Long studentId, Long courseId) { List<ScoreRecord> records = scoreRepository.findByStudentIdAndCourseIdOrderByCreateTimeAsc(studentId, courseId); return RestResult.success(records); } /** * 检查学生是否选课且课程是否存在 * * @param studentId 学生ID * @param courseId 课程ID * @return boolean 是否满足条件 */ private boolean checkStudentSelectCourse(Long studentId, Long courseId) { // 检查课程是否存在且启用 CourseInfo course = courseRepository.findById(courseId).orElse(null); if (course == null || course.getStatus() != 1) { return false; } // 检查学生是否选了这门课 StudentCourse studentCourse = studentCourseRepository.findOneByStudentIdAndCourseId(studentId, courseId); return studentCourse != null; } } 
package com.example.service.impl; import com.example.demo1.entity.UserRole; import com.example.dto.request.LoginRequest; import com.example.dto.request.RegisterRequest; import com.example.dto.request.RoleAssignRequest; import com.example.dto.response.RestResult; import com.example.entity.UserInfo; import com.example.repository.UserRepository; import com.example.service.UserService; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.security.Key; import java.time.LocalDateTime; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.crypto.spec.SecretKeySpec; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; /** * 用户业务逻辑实现类 */ @Slf4j @Service public class UserServiceImpl implements UserService { private final UserRepository userRepository; // JWT密钥,实际应用中应从配置文件读取 @Value("${jwt.secret}") private String secretKey; public UserServiceImpl(UserRepository userRepository) { this.userRepository = userRepository; } @Override public RestResult<?> register(RegisterRequest request) { log.info("开始进行用户注册: {}", request.getUsername()); if (StringUtils.hasText(request.getUsername()) && StringUtils.hasText(request.getPassword())) { // 检查用户是否已存在 if (userRepository.findByUsername(request.getUsername()).isPresent()) { return RestResult.fail("000001", "用户名已存在"); } // 将新用户信息保存到数据库 try { UserInfo userInfo = new UserInfo(); userInfo.setUsername(request.getUsername()); userInfo.setPassword(encryptPassword(request.getPassword())); // 假设有一个密码加密方法 userInfo.setUserRole(request.getRole()); userInfo.setCreateTime(java.time.LocalDateTime.now()); userInfo.setUpdateTime(java.time.LocalDateTime.now()); userRepository.save(userInfo); log.info("用户注册成功: {}", request.getUsername()); Map<String, Object> data = new HashMap<>(); data.put("userId", userInfo.getUserId()); data.put("username", userInfo.getUsername()); data.put("role", userInfo.getUserRole()); return RestResult.success(data); } catch (Exception e) { log.error("用户注册失败", e); return RestResult.fail("999999", "服务器内部错误"); } } else { return RestResult.fail("000002", "用户名或密码不能为空"); } } @Override public RestResult<?> login(LoginRequest request) { log.info("开始用户登录验证: {}", request.getUsername()); if (!StringUtils.hasText(request.getUsername()) || !StringUtils.hasText(request.getPassword())) { return RestResult.fail("000002", "用户名或密码不能为空"); } try { UserInfo user = userRepository.findByUsername(request.getUsername()) .orElse(null); if (user == null || !validatePassword(request.getPassword(), user.getPassword())) { return RestResult.fail("000001", "用户名或密码错误"); } // 生成JWT Token String token = generateToken(user); Map<String, Object> data = new HashMap<>(); data.put("token", token); data.put("username", user.getUsername()); data.put("role", user.getUserRole()); return RestResult.success(data); } catch (Exception e) { log.error("用户登录异常", e); return RestResult.fail("999999", "服务器内部错误"); } } @Override public RestResult<?> validateToken(String token) { log.info("开始校验Token有效性"); try { Claims claims = Jwts.parserBuilder() .setSigningKey(secretKey.getBytes()) .build() .parseClaimsJws(token) .getBody(); String username = claims.getSubject(); String roleStr = (String) claims.get("role"); UserRole role = UserRole.valueOf(roleStr.toUpperCase()); Map<String, Object> data = new HashMap<>(); data.put("username", username); data.put("role", role); return RestResult.success(data); } catch (Exception e) { log.warn("Token无效或已过期", e); return RestResult.fail("000001", "Token无效或已过期"); } } @Override public RestResult<?> assignRole(RoleAssignRequest request) { log.info("开始为用户分配角色: userId={}, role={}", request.getUserId(), request.getRole()); UserInfo user = userRepository.findById(request.getUserId()).orElse(null); if (user == null) { return RestResult.fail("000001", "用户不存在"); } try { user.setUserRole(request.getRole()); user.setUpdateTime(java.time.LocalDateTime.now()); userRepository.save(user); Map<String, Object> data = new HashMap<>(); data.put("userId", user.getUserId()); data.put("username", user.getUsername()); data.put("role", user.getUserRole()); return RestResult.success(data); } catch (Exception e) { log.error("更新用户角色失败", e); return RestResult.fail("999999", "服务器内部错误"); } } /** * 密码加密模拟方法 * * @param rawPassword 明文密码 * @return 加密后的密码 */ private String encryptPassword(String rawPassword) { // 实际项目中应该使用BCrypt等强哈希算法进行加密 return rawPassword; // 此处仅为示例,真实场景需加强加密处理 } /** * 密码验证模拟方法 * * @param rawPassword 明文密码 * @param encodedPassword 已加密密码 * @return 是否匹配 */ private boolean validatePassword(String rawPassword, String encodedPassword) { // 实际项目中应该使用BCrypt等算法进行比对 return rawPassword.equals(encodedPassword); // 此处仅为示例,真实场景需加强加密处理 } /** * 生成JWT Token * * @param user 用户信息 * @return Token字符串 */ private String generateToken(UserInfo user) { Date now = new Date(); Date expiryDate = new Date(now.getTime() + 86400000); // 设置一天有效期 Key key = new SecretKeySpec(secretKey.getBytes(), SignatureAlgorithm.HS512.getJcaName()); return Jwts.builder() .setSubject(user.getUsername()) .claim("role", user.getUserRole().toString()) .setIssuedAt(new Date()) .setExpiration(expiryDate) .signWith(key, SignatureAlgorithm.HS512) .compact(); } } 

2. 应用价值与延伸

该学生成绩管理系统的落地,不仅解决了传统管理模式的痛点,更具备三大核心价值:

  • 效率提升:将教师成绩录入、管理员数据汇总的时间成本降低 70%,释放教学管理人力投入核心教学工作;
  • 数据安全:基于 RBAC 权限模型与操作日志追溯,实现 “谁操作、谁负责”,成绩修改记录永久留存,杜绝信息泄露与数据篡改风险;
  • 可扩展性:系统预留 “对接教务系统”“接入人脸识别签到数据” 等接口,未来可扩展 “成绩与考勤关联分析”“个性化学习推荐” 等功能,适配高校教学管理的长期发展需求。

此外,借助飞算 JavaAI 的开发模式,相比传统手动编码,整体开发周期从原本的 30 天缩短至 7 天,且生成的代码符合行业规范,后期维护成本降低 50%,为高校毕业设计、中小型教学管理系统开发提供了高效、低成本的实现路径。

Read more

迈向AI4S 2.0,上海AI实验室开源书生万亿科学大模型Intern-S1-Pro

迈向AI4S 2.0,上海AI实验室开源书生万亿科学大模型Intern-S1-Pro

2月4日,上海人工智能实验室开源基于“通专融合”技术架构SAGE打造的万亿参数科学多模态大模型 Intern-S1-Pro,为AI4S从“工具革命”的1.0阶段迈向以“革命的工具”驱动科学发现的2.0时代,提供创新的系统性开源基座。 作为当前全球开源社区中参数规模最大的科学多模态模型,Intern-S1-Pro的核心科学能力实现了质的跃升,高难度综合学科评测稳居AI4S领域国际领先水平,复杂数理逻辑推理能力达奥赛金牌水平,面向真实科研流程的智能体能力位居开源模型第一梯队。 此次发布的Intern-S1-Pro是通过SAGE实现 “可深度专业化通用模型” 的关键实践。该模型基于混合专家架构(MoE),共拥有512个专家,总参数达1T,每次调用仅激活8个专家、22B参数。其通用能力和科学能力协同演进,并在底层架构实现了两大核心突破:在SAGE的基础模型层,通过引入傅里叶位置编码①并重构时序编码器,赋予模型统一理解从微观生命信号到宏观宇宙波动的“物理直觉”;通过高效路由机制,系统攻克了训练万亿参数MoE模型在稳定性与算力效率上的瓶颈,为超大规模模型的训练提供了关键的工程基础。 与此同时

By Ne0inhk

《HelloGitHub》第 119 期

兴趣是最好的老师,HelloGitHub 让你对开源感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、Java、Go、C/C++、Swift...让你在短时间内感受到开源的魅力,爱上开源! 以下为本期内容|每月 28 号更新 C 项目 1、voidImageViewer:比图片还小的免费看图工具。这是一款用 C 语言编写的 Windows 轻量级图片查看工具,让你几乎感受不到等待。它体积小、启动快,拥有极快的图片加载和切换速度,支持 JPG、PNG、WEBP、BMP、

By Ne0inhk
开源AI编程工具对决:Superpowers技能库与OpenSpec规范驱动,谁更胜一筹?

开源AI编程工具对决:Superpowers技能库与OpenSpec规范驱动,谁更胜一筹?

文章概要 在AI辅助编程领域,Obra/superpowers库与Fission-AI/OpenSpec库代表了两种截然不同的技术路径。前者致力于构建可复用的AI编程技能库,后者则倡导以规范(Spec)为核心的驱动开发模式。本文将深入对比两者在核心理念、工作流程及适用场景上的核心差异,探讨它们如何分别解决AI开发中的效率与一致性难题,并分析在项目演进中应如何取舍。 前几天在咖啡店,我无意中听到邻桌两位程序员在激烈争论。一位坚持说:“AI编程助手最大的价值就是帮我快速写出新代码,我需要的是更多‘技能’。”另一位则反驳:“不对,AI最该解决的是代码一致性,我们团队现在最缺的是‘规范’。”这让我立刻想到了最近在GitHub上观察到的两个项目:Obra的superpowers技能库和Fission-AI的OpenSpec规范驱动框架。它们恰好代表了这两种截然不同的思路。 我打开superpowers的仓库,第一印象是它像一个为AI助手精心打造的“瑞士军刀”工具箱。它的核心理念非常直接:将常见的、复杂的编程任务封装成一个个可复用的“技能”(Skill)。这就像给AI安装了一个插件商店,当需要

By Ne0inhk
OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目

OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目

OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目 💡 导读 GitHub上这些OpenClaw开源项目,Star数为什么能破千?我们扒了13个宝藏仓库后发现… 有人用OpenClaw给钉钉搭了智能助手,有人在飞书里养了个AI女友Clawra,还有人把记忆层memU玩成了第二大脑——而这些全部免费开源! 2026年OpenClaw热度飙升,但官方文档晦涩、部署门槛高劝退无数人?别慌!本文汇总了OpenClawInstaller、OneClaw、Moltworker等13个硬核开源项目,覆盖:✅ 一键部署工具(零代码上手)✅ 钉钉/企微/飞书/微信全平台接入方案✅ 云端托管+本地Sandbox双模式✅ 记忆层memU、技能库Skills、甚至AI女友Clawra… 收藏这一篇,省掉你100个小时的踩坑时间! 文章目录 * OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目 * 💡 导读 * 一、OpenClawInstall

By Ne0inhk