kindergarten_java/docs/dev-logs/2026-03-24.md
En 6f47a07401 docs(开发日志): 补充 RSA 加密功能文档和细节调整
- 追加 RSA 密码加密传输的完整实现文档
- 操作日志相关细节调整

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:08:29 +08:00

8.0 KiB
Raw Blame History

开发日志 - 2026-03-24

工作内容

租户管理详情页字段补充

背景

超管端租户管理查看详情时,前端页面期望展示以下数据:

  1. 使用统计:教师数、学生数、班级数授课数
  2. 最近教师列表(姓名、手机号、状态)
  3. 最近学生列表(姓名、性别、阅读数)
  4. 最近班级列表(名称、年级、学生数)

修改内容

1. 后端 DTO 扩展 (TenantResponse.java)

  • 新增 classCount 字段 - 班级数量
  • 新增 lessonCount 字段 - 授课数量
  • 新增 teachers 字段 - 最近教师列表(TeacherItem 内部类)
  • 新增 students 字段 - 最近学生列表(StudentItem 内部类)
  • 新增 classes 字段 - 最近班级列表(ClassItem 内部类)

2. 后端 Service 层修改 (TenantServiceImpl.java)

  • 新增 getTenantDetail() 方法 - 返回完整的租户详情响应
  • 新增 buildTenantResponse() 方法 - 构建包含统计信息和列表的响应数据
  • 新增 Mapper 依赖注入:
    • ClazzMapper - 班级数据访问
    • StudentRecordMapper - 学生阅读记录访问
    • StudentClassHistoryMapper - 学生班级关联访问

3. 后端 Controller 层修改 (AdminTenantController.java)

  • 修改 getTenant() 方法调用 tenantService.getTenantDetail(id) 返回完整详情

4. 前端类型定义更新 (admin.ts)

  • 扩展 TenantDetail 接口:
    • 添加 classCountlessonCount 字段
    • students[].classId 改为可选字段(因为学生班级关联是可选的)

5. 前端详情组件更新 (TenantListView.vue)

  • 修改统计数据显示使用 detailData.classCountdetailData.lessonCount

技术细节

  1. 学生班级 ID 获取:由于学生实体没有直接的 classId 字段,通过 student_class_history 关联表查询学生当前所在的班级 ID。

  2. 班级学生数统计:通过 student_class_history 表查询每个班级的 ACTIVE 状态学生数量。

  3. 学生阅读次数统计:通过 student_record 表统计每个学生的记录数。

  4. 教师授课次数统计:通过 schedule_plan 表统计每个教师的排课数量。

验证步骤

  1. 后端编译成功
  2. 启动服务测试(待用户验证)

文件清单

文件 修改内容
TenantResponse.java 新增字段和内部类
TenantServiceImpl.java 新增方法和 Mapper 依赖
AdminTenantController.java 修改详情查询方法
admin.ts 扩展类型定义
TenantListView.vue 更新详情展示

工作内容 - 学校端操作日志请求参数与接口展示

背景

在学校端操作日志页面,需要记录并返回以下三个信息:

  1. 操作人 - 谁执行的操作(已有 userIduserRole
  2. 请求参数 - 操作时传入的参数(requestParams
  3. 请求接口 - 执行的具体 API 接口路径(requestUri

当前后端已通过 LogAspect 自动记录这些信息到数据库,但未返回给前端展示。

修改内容

1. 数据库迁移

文件: V50__add_request_uri_to_operation_log.sql

  • 添加 request_uri 字段 - VARCHAR(500),记录请求接口路径

2. 后端实体修改

文件: OperationLog.java

  • 新增 requestUri 字段

3. 后端切面修改

文件: LogAspect.java

  • before() 方法中记录 requestURI

4. 后端 Response DTO 修改

文件: OperationLogResponse.java

  • 新增 requestParams 字段 - 请求参数 JSON
  • 新增 requestUri 字段 - 请求接口路径

5. 后端 Controller 修改

文件: SchoolOperationLogController.java

  • convertToResponse() 方法中添加字段映射

6. 前端类型定义更新

文件: school.ts

  • OperationLog 接口添加 requestParamsrequestUri 字段

7. 前端页面修改

文件: OperationLogView.vue

  • 详情弹窗新增"请求接口"展示项
  • 详情弹窗新增"请求参数"展示项JSON 格式化)

验证步骤

  1. 后端编译成功
  2. 数据库迁移待执行
  3. 启动服务测试

文件清单

文件 修改内容
V50__add_request_uri_to_operation_log.sql 新增数据库迁移
OperationLog.java 新增 requestUri 字段
LogAspect.java 记录 requestURI
OperationLogResponse.java 新增返回字段
SchoolOperationLogController.java 字段映射
school.ts 类型定义更新
OperationLogView.vue 详情展示新增字段

工作内容 - RSA 密码加密传输实现

背景

当前登录系统密码明文传输,存在安全风险。需要实现 RSA 非对称加密,确保密码在传输过程中加密。

实现方案

使用简化 RSA 方案:

  1. 后端生成 RSA 密钥对,提供公钥获取接口
  2. 前端登录前获取公钥,用 RSA 加密密码
  3. 后端用私钥解密密码,继续原有登录流程

修改内容

后端部分

1. 新建 RSA 加密工具类 (RsaEncryptionUtil.java)

  • 生成 RSA 2048 位密钥对
  • 提供公钥获取方法
  • 提供私钥解密方法
  • 支持密钥版本管理
  • 密钥仅保存在内存中,不持久化

2. 新建密钥轮换任务 (RsaKeyRotationTask.java)

  • 每月 1 日凌晨 2 点自动更换 RSA 密钥
  • 使用 @Scheduled(cron = "0 0 2 1 * ?") 定时执行
  • 支持日志记录密钥版本变更

3. 新建加密登录请求 DTO (EncryptedLoginRequest.java)

  • username - 登录账号(明文)
  • encryptedPassword - RSA 加密后的密码Base64
  • role - 登录角色
  • keyVersion - 密钥版本号(可选)

4. 新建公钥响应 DTO (PublicKeyResponse.java)

  • publicKey - RSA 公钥Base64
  • keyVersion - 当前密钥版本号

5. 修改认证控制器 (AuthController.java)

  • 新增 GET /api/v1/auth/public-key - 获取 RSA 公钥
  • 新增 POST /api/v1/auth/login/encrypted - 加密登录接口
  • 注入 RsaEncryptionUtil 进行加解密操作

前端部分

6. 添加依赖 (package.json)

  • 添加 jsencrypt@^3.3.2 - RSA 加密库

7. 新建加密工具 (encryption.ts)

  • rsaEncrypt(data, publicKey) - RSA 加密函数
  • 导出 PublicKeyResponseEncryptedLoginParams 类型

8. 修改认证 API (auth.ts)

  • 新增 getPublicKey() - 获取公钥
  • 新增 loginEncrypted(params) - 加密登录

9. 修改用户 Store (user.ts)

  • 修改 login() 函数,改为 RSA 加密流程:
    1. 获取 RSA 公钥
    2. 加密密码
    3. 调用加密登录接口

登录流程变更

原流程

明文密码 → POST /api/v1/auth/login → 后端验证

新流程

1. GET /api/v1/auth/public-key → 获取 RSA 公钥
2. 前端用公钥加密密码
3. POST /api/v1/auth/login/encrypted → 后端私钥解密 → 验证登录

安全特性

  • RSA 2048 位加密,安全性足够
  • 密钥每月自动更换 - 每月 1 日凌晨 2 点自动更换
  • 密钥版本管理 - 便于排查问题
  • 私钥仅保存在后端内存中,不持久化
  • 必须配合 HTTPS 使用

验证步骤

  1. 安装前端依赖:cd reading-platform-frontend && npm install
  2. 启动后端服务,测试 GET /api/v1/auth/public-key 返回公钥
  3. 启动前端,打开浏览器开发者工具
  4. 登录时检查 Network 面板:
    • /v1/auth/public-key 返回公钥
    • /v1/auth/login/encrypted 请求的 encryptedPassword 为密文
  5. 验证登录功能正常

文件清单

文件 操作 说明
RsaEncryptionUtil.java 新建 RSA 加密工具类
RsaKeyRotationTask.java 新建 密钥轮换定时任务
EncryptedLoginRequest.java 新建 加密登录请求 DTO
PublicKeyResponse.java 新建 公钥响应 DTO
AuthController.java 修改 添加公钥和加密登录接口
package.json 修改 添加 jsencrypt 依赖
encryption.ts 新建 前端 RSA 加密工具
auth.ts 修改 添加加密登录 API
user.ts 修改 使用 RSA 加密登录