Skip to content

feat: course teacher scores#411

Merged
renbaoshuo merged 3 commits intomainfrom
feat/course-teacher-scores-improvements
Mar 6, 2026
Merged

feat: course teacher scores#411
renbaoshuo merged 3 commits intomainfrom
feat/course-teacher-scores-improvements

Conversation

@renbaoshuo
Copy link
Member

@renbaoshuo renbaoshuo commented Mar 6, 2026

Closes #285.

Resolves #284.

自查 PR 结构

  • PR 标题符合这个格式: <type>(optional scope): <description>

  • 此 PR 标题的描述以用户为导向,足够清晰,其他人可以理解。

  • 我已经对所有 commit 提供了签名(GPG 密钥签名、SSH 密钥签名)

  • 这个 PR 属于强制变更/破坏性更改

如果是,请在 PR 标题中添加 BREAKING CHANGE 前缀,并在 PR 描述中详细说明。

这个 PR 的类型是什么?

feat

这个 PR 做了什么 / 我们为什么需要这个 PR?

(可选)这个 PR 解决了哪个/些 issue?

对 Reviewer 预留的一些提醒

新表结构如下:

CREATE TABLE `course_teacher_scores` (
  `id` BIGINT NOT NULL COMMENT '雪花ID,由应用层生成',
  `stu_id_sha256` VARCHAR(64) NOT NULL COMMENT 'SHA-256 哈希后的学生ID',
  `course_name` VARCHAR(50) NOT NULL COMMENT '课程名称',
  `elective_type` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '选修类型,从electiveType提取',
  `teacher_name` VARCHAR(30) NOT NULL COMMENT '教师姓名',
  `semester` CHAR(6) NOT NULL COMMENT '学期',
  `score` DECIMAL(5,2) NOT NULL DEFAULT -10.00 COMMENT '数值化成绩,-10 表示未知或其他',
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
  `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录最后更新时间',
  `deleted_at` TIMESTAMP NULL DEFAULT NULL COMMENT '逻辑删除时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_record` (`course_name`, `teacher_name`, `semester`, `stu_id_sha256`),
  KEY `idx_course` (`course_name`),
  KEY `idx_teacher` (`teacher_name`),
  KEY `idx_score` (`score`),
  KEY `idx_course_teacher_sem_score` (`course_name`, `teacher_name`, `semester`, `score`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_0900_ai_ci
  COMMENT='展开自 scores.scores_info 的课程-教师-学期-成绩记录,主键由雪花生成';

已经更新到生产服务器上,部署时不需要再次更新表结构!!!

测试生成数据时使用的 SQL 过程:

DELIMITER //

DROP PROCEDURE IF EXISTS BatchProcessScoresByStuId //
CREATE PROCEDURE BatchProcessScoresByStuId()
BEGIN
  DECLARE v_last_stu_id VARCHAR(16) DEFAULT '';
  DECLARE v_current_max_stu_id VARCHAR(16) DEFAULT '';
  DECLARE v_batch_size INT DEFAULT 200;

  read_loop: LOOP
    SELECT MAX(stu_id) INTO v_current_max_stu_id 
    FROM (
      SELECT stu_id 
      FROM `scores` 
      WHERE stu_id > v_last_stu_id 
      ORDER BY stu_id ASC 
      LIMIT v_batch_size
    ) AS tmp;

    IF v_current_max_stu_id IS NULL THEN
      SELECT 'All records have been processed.' AS message;
      LEAVE read_loop;
    END IF;

    SELECT CONCAT('Processing batch: stu_id > ', v_last_stu_id, ' AND stu_id <= ', v_current_max_stu_id) AS message;

    START TRANSACTION;

    INSERT INTO `course_teacher_scores` (
      id, stu_id_sha256, course_name, teacher_name, semester, score, elective_type
    )
    SELECT 
      id, stu_id_sha256, course_name, teacher_name, semester, score, elective_type
    FROM (
      SELECT
        UUID_SHORT()         AS id,
        SHA2(s.stu_id, 256)  AS stu_id_sha256,
        jt.name              AS course_name,
        TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(IFNULL(jt.teacher_list, ''), ',', n.n), ',', -1)) AS teacher_name,
        jt.semester,
        CASE
          WHEN jt.score REGEXP '^[0-9]+(\\.[0-9]+)?$' THEN CAST(jt.score AS DECIMAL(5,2))
          WHEN jt.score IN ('优秀','')               THEN 90.00
          WHEN jt.score IN ('良好','')               THEN 80.00
          WHEN jt.score IN ('中等')                    THEN 68.00
          WHEN jt.score IN ('及格','合格')             THEN 60.00
          WHEN jt.score IN ('不及格','不合格')         THEN 0.00
          WHEN jt.score IN ('缺考')                    THEN -1.00
          WHEN jt.score IN ('作弊')                    THEN -2.00
          ELSE -10.00
        END AS score,
        jt.elective_type
      FROM `scores` AS s

      JOIN JSON_TABLE(
        s.scores_info, '$[*]'
        COLUMNS (
          name          VARCHAR(255) PATH '$.name',
          teacher_list  TEXT         PATH '$.teacher',
          semester      VARCHAR(64)  PATH '$.semester',
          score         VARCHAR(16)  PATH '$.score',
          elective_type VARCHAR(64)  PATH '$.electivetype' 
        )
      ) AS jt ON TRUE

      JOIN (
        SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 
        UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10
      ) AS n 
      ON CHAR_LENGTH(IFNULL(jt.teacher_list, '')) - CHAR_LENGTH(REPLACE(IFNULL(jt.teacher_list, ''), ',', '')) >= n.n - 1

      WHERE s.stu_id > v_last_stu_id AND s.stu_id <= v_current_max_stu_id
      
    ) AS new_data
    
    ON DUPLICATE KEY UPDATE
      course_teacher_scores.score = new_data.score,
      course_teacher_scores.elective_type = new_data.elective_type;

    COMMIT;

    SET v_last_stu_id = v_current_max_stu_id;

  END LOOP;

END //

DELIMITER ;

call BatchProcessScoresByStuId();

@renbaoshuo renbaoshuo requested review from a team, jiuxia211, mutezebra and ozline as code owners March 6, 2026 12:06
@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 1.00000% with 99 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...l/academic/service/update_course_teacher_scores.go 0.00% 69 Missing ⚠️
pkg/db/academic/upsert_course_teacher_scores.go 0.00% 20 Missing ⚠️
pkg/db/academic/get_scores_batch.go 0.00% 10 Missing ⚠️
@@            Coverage Diff             @@
##             main     #411      +/-   ##
==========================================
- Coverage   62.65%   61.50%   -1.15%     
==========================================
  Files         209      212       +3     
  Lines        5278     5378     +100     
==========================================
+ Hits         3307     3308       +1     
- Misses       1869     1968      +99     
  Partials      102      102              
Flag Coverage Δ
unittest 61.50% <1.00%> (-1.15%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
internal/academic/service/service.go 100.00% <100.00%> (ø)
pkg/db/academic/get_scores_batch.go 0.00% <0.00%> (ø)
pkg/db/academic/upsert_course_teacher_scores.go 0.00% <0.00%> (ø)
...l/academic/service/update_course_teacher_scores.go 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renbaoshuo renbaoshuo merged commit 0857733 into main Mar 6, 2026
9 of 10 checks passed
@renbaoshuo renbaoshuo deleted the feat/course-teacher-scores-improvements branch March 6, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Course Teacher Scores CronJob Support

1 participant