Files
2026-01-04 10:00:08 +08:00

19 KiB
Raw Permalink Blame History

学生操行分管理 - API 接口设计

📋 文档说明

版本: v1.0 制定时间: 2025-01-13 适用范围: 学生操行分管理模块 API 接口设计 重要性: ⚠️ 强制性规范 - API 设计必须遵循项目统一接口规范


🎯 设计原则

1. RESTful 设计

  • 使用标准的 HTTP 方法(GET、POST、PUT、DELETE)
  • 资源路径清晰,层次分明
  • 状态码规范,返回信息明确

2. 统一响应格式

  • 所有接口返回统一的 JSON 格式
  • 包含状态码、消息、数据三个部分
  • 分页查询使用统一的 TableDataInfo 格式

3. 权限控制

  • 每个接口必须有 @SaCheckPermission 注解
  • 班主任只能操作自己班级的学生
  • 学生处管理员可查看全校数据

🔌 接口概览

接口分类

基础 CRUD 接口

接口名称 请求方式 路径 权限字符 功能描述
查询操行分列表 GET /api/conduct-score/list conduct:score:list 分页查询操行分记录
查询操行分详情 GET /api/conduct-score/{id} conduct:score:query 根据 ID 查询操行分详情
新增操行分 POST /api/conduct-score conduct:score:add 创建新的操行分记录
更新操行分 PUT /api/conduct-score/{id} conduct:score:edit 更新指定操行分记录
删除操行分 DELETE /api/conduct-score/{id} conduct:score:remove 删除指定操行分记录

业务逻辑接口

接口名称 请求方式 路径 权限字符 功能描述
批量录入操行分 POST /api/conduct-score/batch conduct:score:batchAdd 批量保存操行分
班主任班级学生 GET /api/conduct-score/class-students conduct:score:classStudents 获取班主任班级学生列表
学期平均分统计 GET /api/statistics/semester-average conduct:statistics:semester 查询学期平均分
导出学期统计 GET /api/statistics/export conduct:statistics:export 导出学期统计数据
验证录入权限 GET /api/conduct-score/check-permission conduct:score:checkPermission 检查班主任录入权限

📝 接口详细设计

1. 查询操行分列表

接口信息

  • 请求方式: GET
  • 接口路径: /api/conduct-score/list
  • 权限字符: conduct:score:list
  • 接口描述: 分页查询操行分记录列表

请求参数

参数名 类型 必填 说明
academicYear Integer 否 学年(如:2024)
semester Integer 否 学期(1-第一学期,2-第二学期)
month Integer 否 月份(1-12)
studentName String 否 学生姓名
className String 否 班级名称
scoreMin BigDecimal 否 最低分数
scoreMax BigDecimal 否 最高分数
pageNum Integer 否 当前页码(默认1)
pageSize Integer 否 每页显示数量(默认10)

响应格式

{
  "code": 200,
  "msg": "查询成功",
  "data": {
    "total": 100,
    "rows": [
      {
        "id": 1234567890123456789,
        "academicYear": 2024,
        "semester": 1,
        "month": 9,
        "studentId": 987654321098765432,
        "studentName": "张三",
        "studentNo": "2024001",
        "classId": 876543210987654321,
        "className": "计算机应用1班",
        "classTeacherId": 765432109876543210,
        "classTeacherName": "李老师",
        "score": 95.50,
        "remark": "表现优秀,积极参加班级活动",
        "createTime": "2024-09-01 10:00:00",
        "createBy": "李老师"
      }
    ],
    "code": 200,
    "msg": "查询成功"
  }
}

2. 批量录入操行分

接口信息

  • 请求方式: POST
  • 接口路径: /api/conduct-score/batch
  • 权限字符: conduct:score:batchAdd
  • 接口描述: 批量保存操行分记录

请求参数

{
  "academicYear": 2024,
  "semester": 1,
  "month": 9,
  "classId": 876543210987654321,
  "scores": [
    {
      "studentId": 987654321098765432,
      "score": 95.50,
      "remark": "表现优秀,积极参加班级活动"
    },
    {
      "studentId": 987654321098765433,
      "score": 88.00,
      "remark": "表现良好,需要继续努力"
    }
  ]
}

参数说明

参数名 类型 必填 说明
academicYear Integer 是 学年(如:2024)
semester Integer 是 学期(1-第一学期,2-第二学期)
month Integer 是 月份(1-12)
classId Long 是 班级ID
scores Array 是 操行分记录数组
└─studentId Long 是 学生ID
└─score BigDecimal 是 操行分数(0.00-100.00)
└─remark String 否 备注信息

响应格式

{
  "code": 200,
  "msg": "批量录入成功",
  "data": {
    "successCount": 45,
    "failCount": 0,
    "failList": []
  }
}

3. 班主任班级学生列表

接口信息

  • 请求方式: GET
  • 接口路径: /api/conduct-score/class-students
  • 权限字符: conduct:score:classStudents
  • 接口描述: 获取班主任负责的所有班级及学生列表,用于多Tab页展示

请求参数

参数名 类型 必填 说明
academicYear Integer 否 学年(如:2024)
semester Integer 否 学期(1-第一学期,2-第二学期)
month Integer 否 月份(1-12)

响应格式

{
  "code": 200,
  "msg": "查询成功",
  "data": {
    "classes": [
      {
        "classId": 876543210987654321,
        "className": "计算机1班",
        "classCode": "JSJ202401",
        "studentCount": 45,
        "enrollmentYear": 2024,
        "majorName": "计算机应用技术",
        "students": [
          {
            "studentId": 987654321098765432,
            "studentNo": "2024001",
            "studentName": "张三",
            "gender": "0",
            "existingScore": null,
            "lastScore": 95.50,
            "lastMonth": 8
          },
          {
            "studentId": 987654321098765433,
            "studentNo": "2024002",
            "studentName": "李四",
            "gender": "1",
            "existingScore": {
              "id": 1234567890123456789,
              "score": 88.00,
              "remark": "表现良好",
              "createTime": "2024-09-01 09:00:00"
            },
            "lastScore": 90.00,
            "lastMonth": 8
          }
        ]
      },
      {
        "classId": 876543210987654322,
        "className": "计算机2班",
        "classCode": "JSJ202402",
        "studentCount": 42,
        "enrollmentYear": 2024,
        "majorName": "计算机应用技术",
        "students": [
          {
            "studentId": 987654321098765434,
            "studentNo": "2024046",
            "studentName": "王五",
            "gender": "0",
            "existingScore": {
              "id": 1234567890123456790,
              "score": 92.00,
              "remark": "学习认真",
              "createTime": "2024-09-01 09:15:00"
            },
            "lastScore": 90.00,
            "lastMonth": 8
          }
        ]
      },
      {
        "classId": 876543210987654323,
        "className": "电子1班",
        "classCode": "DZ202401",
        "studentCount": 38,
        "enrollmentYear": 2024,
        "majorName": "电子信息工程",
        "students": [
          {
            "studentId": 987654321098765435,
            "studentNo": "2024088",
            "studentName": "赵六",
            "gender": "0",
            "existingScore": null,
            "lastScore": 87.50,
            "lastMonth": 8
          }
        ]
      }
    ],
    "summary": {
      "totalClasses": 3,
      "totalStudents": 125,
      "recordedStudents": 87,
      "pendingStudents": 38,
      "completionRate": 69.6
    }
  }
}

4. 学期平均分统计

接口信息

  • 请求方式: GET
  • 接口路径: /api/statistics/semester-average
  • 权限字符: conduct:statistics:semester
  • 接口描述: 查询学生的学期操行平均分

请求参数

参数名 类型 必填 说明
academicYear Integer 是 学年(如:2024)
semester Integer 是 学期(1-第一学期,2-第二学期)
className String 否 班级名称筛选
studentName String 否 学生姓名筛选
pageNum Integer 否 当前页码(默认1)
pageSize Integer 否 每页显示数量(默认10)

响应格式

{
  "code": 200,
  "msg": "查询成功",
  "data": {
    "total": 500,
    "rows": [
      {
        "studentId": 987654321098765432,
        "studentNo": "2024001",
        "studentName": "张三",
        "gender": "0",
        "classId": 876543210987654321,
        "className": "计算机应用1班",
        "academicYear": 2024,
        "semester": 1,
        "avgScore": 92.83,
        "recordCount": 6,
        "maxScore": 98.00,
        "minScore": 88.00,
        "scoreRange": "88.00-98.00",
        "lastUpdateTime": "2024-09-30 16:00:00"
      }
    ],
    "summary": {
      "totalStudents": 500,
      "avgScore": 85.67,
      "excellentCount": 120,
      "goodCount": 280,
      "averageCount": 85,
      "needImprovementCount": 15
    },
    "code": 200,
    "msg": "查询成功"
  }
}

5. 导出学期统计

接口信息

  • 请求方式: GET
  • 接口路径: /api/statistics/export
  • 权限字符: conduct:statistics:export
  • 接口描述: 导出学期操行分统计数据

请求参数

参数名 类型 必填 说明
academicYear Integer 是 学年(如:2024)
semester Integer 是 学期(1-第一学期,2-第二学期)
className String 否 班级名称筛选
exportType String 否 导出类型(excel/pdf,默认excel)

响应格式

返回 Excel 或 PDF 文件流


🔒 权限控制设计

权限字符定义

// 操行分管理权限
conduct:score:list          // 查看操行分列表
conduct:score:query         // 查看操行分详情
conduct:score:add           // 新增操行分
conduct:score:edit          // 编辑操行分
conduct:score:remove        // 删除操行分
conduct:score:batchAdd      // 批量录入操行分
conduct:score:classStudents // 查看班主任班级学生

// 统计分析权限
conduct:statistics:semester // 学期统计查看
conduct:statistics:export   // 数据导出

权限控制逻辑

班主任权限控制

@SaCheckPermission("conduct:score:classStudents")
@GetMapping("/class-students")
public AjaxResult getClassStudents(@RequestParam Integer academicYear,
                                  @RequestParam Integer semester,
                                  @RequestParam Integer month) {
    // 获取当前登录用户ID
    Long userId = SecurityUtils.getUserId();

    // 从 xg_class_msg 表查询该用户作为班主任的所有班级
    // WHERE class_teacher_id = #{userId} AND deleted = 0
    List<Long> classIds = conductScoreService.getTeacherClassIds(userId);

    // 返回按班级分组的学生信息,用于前端生成Tab页
    return AjaxResult.success(conductScoreService.getClassStudentsGrouped(classIds, academicYear, semester, month));
}

管理员权限控制

@SaCheckPermission("conduct:statistics:semester")
@GetMapping("/semester-average")
public TableDataInfo getSemesterAverage(@RequestParam Integer academicYear,
                                       @RequestParam Integer semester,
                                       ConductScoreQueryBo queryBo) {
    // 管理员可以查看全校数据,无班级限制
    startPage();
    List<SemesterAverageVo> list = statisticsService.getSemesterAverage(academicYear, semester, queryBo);
    return getDataTable(list);
}

📊 数据验证规则

请求参数验证

public class ConductScoreBatchBo {
    @NotNull(message = "学年不能为空")
    @Min(value = 2020, message = "学年不能小于2020")
    @Max(value = 2030, message = "学年不能大于2030")
    private Integer academicYear;

    @NotNull(message = "学期不能为空")
    @Min(value = 1, message = "学期只能是1或2")
    @Max(value = 2, message = "学期只能是1或2")
    private Integer semester;

    @NotNull(message = "月份不能为空")
    @Min(value = 1, message = "月份范围为1-12")
    @Max(value = 12, message = "月份范围为1-12")
    private Integer month;

    @NotNull(message = "班级ID不能为空")
    private Long classId;

    @NotEmpty(message = "操行分记录不能为空")
    @Size(min = 1, max = 100, message = "一次最多录入100条记录")
    private List<ConductScoreItemBo> scores;
}

public class ConductScoreItemBo {
    @NotNull(message = "学生ID不能为空")
    private Long studentId;

    @NotNull(message = "分数不能为空")
    @DecimalMin(value = "0.00", message = "分数不能小于0")
    @DecimalMax(value = "100.00", message = "分数不能大于100")
    private BigDecimal score;

    @Size(max = 500, message = "备注不能超过500字符")
    private String remark;
}

业务逻辑验证

班主任权限验证

private void validateTeacherPermission(Long classId, Long teacherId) {
    // 验证班主任是否负责该班级
    boolean isResponsible = conductScoreService.checkTeacherClass(teacherId, classId);
    if (!isResponsible) {
        throw new ServiceException("您不是该班级的班主任,无权录入操行分");
    }
}

重复录入验证

private void validateNoDuplicate(Long studentId, Integer academicYear,
                                Integer semester, Integer month) {
    // 检查是否已存在该学生的当月记录
    boolean exists = conductScoreService.existsByStudentAndMonth(
        studentId, academicYear, semester, month);

    if (exists) {
        throw new ServiceException("该学生当月操行分已录入,不可重复录入");
    }
}

🔄 错误码设计

系统级错误码

错误码 说明
200 成功
400 请求参数错误
401 未授权
403 权限不足
500 系统错误

业务级错误码

错误码 说明
1001 班主任权限不足
1002 学生不存在
1003 班级不存在
1004 操行分已存在,不可重复录入
1005 分数范围错误
1006 时间参数错误

错误响应格式

{
  "code": 1001,
  "msg": "您不是该班级的班主任,无权录入操行分",
  "data": null
}

📈 性能优化

接口性能指标

  • 响应时间: 平均 < 200ms,95% < 500ms
  • 并发处理: 支持 100+ 并发请求
  • 数据量: 支持万人规模数据查询

缓存策略

Redis 缓存配置

// 学期统计缓存
@Cacheable(value = "conductScoreStats", key = "#academicYear + '_' + #semester")
public List<SemesterAverageVo> getSemesterAverage(Integer academicYear, Integer semester) {
    // 查询逻辑
}

// 班主任班级缓存
@Cacheable(value = "teacherClasses", key = "#teacherId")
public List<Long> getTeacherClassIds(Long teacherId) {
    // 查询逻辑
}

分页查询优化

// 大数据量分页查询
PageHelper.startPage(pageNum, pageSize);
List<ConductScoreVo> list = conductScoreMapper.selectConductScoreList(queryBo);
// 自动添加 LIMIT 和 OFFSET

🧪 接口测试

测试用例设计

正常流程测试

# 批量录入操行分
curl -X POST "http://localhost:8080/api/conduct-score/batch" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "academicYear": 2024,
    "semester": 1,
    "month": 9,
    "classId": 876543210987654321,
    "scores": [
      {"studentId": 987654321098765432, "score": 95.5, "remark": "优秀"}
    ]
  }'

异常流程测试

# 权限不足测试
curl -X GET "http://localhost:8080/api/conduct-score/class-students" \
  -H "Authorization: Bearer {invalid_token}"

# 响应: {"code": 403, "msg": "权限不足", "data": null}

性能测试

# 并发测试脚本
ab -n 1000 -c 50 "http://localhost:8080/api/statistics/semester-average?academicYear=2024&semester=1"

📚 接口文档

Swagger 文档

@Api(tags = "操行分管理")
@RestController
@RequestMapping("/api/conduct-score")
public class ConductScoreController {

    @ApiOperation("批量录入操行分")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "academicYear", value = "学年", required = true),
        @ApiImplicitParam(name = "semester", value = "学期", required = true),
        @ApiImplicitParam(name = "month", value = "月份", required = true)
    })
    @PostMapping("/batch")
    public AjaxResult batchAddConductScore(@RequestBody ConductScoreBatchBo bo) {
        // 接口实现
    }
}

接口变更记录

版本 变更时间 变更内容 变更人
v1.0 2025-01-13 初始版本 开发团队

📞 技术支持

如有疑问或需要技术支持,请联系:

  • 接口负责人: 后端开发负责人
  • 测试负责人: 测试团队
  • 业务负责人: 学生处管理员

最后更新: 2025-01-13 接口版本: v1.0 兼容性: 向后兼容