4 Commits

Author SHA1 Message Date
weicw1996 853f3c3f5b 新增教师名册只读接口
教师名册来自开放平台全量同步,只用于检索与选人(教师不建登录账号,ADR-0001),
因此不提供认领类接口,也没有可写字段。

- GET /api/gxmu/teacher/page:学院/教工号/姓名/状态筛选,默认只返回启用
- POST /api/gxmu/teacher/export:导出用列表,带操作日志
- 权限拆成 gxmu:teacher:list 与 gxmu:teacher:export
- 手机号按 spec §5.2 落盘但不进任何列表接口,返回前一律清空(hideSensitive)
- 菜单与按钮权限见 sql/20260915_add_teacher_roster_menu.sql,可重复执行
2026-09-15 17:21:32 +08:00
weicw1996 582d7dfbcb 学生同步稳态只写变更行
实测写入才是大头,不是平台拉取:9.8 万行的表上 800 行/批 upsert 要 716ms,
123 批共 88 秒;而窄读全部 (xh, row_hash) 只要 2.1 秒。

做法:
- gxmu_student 增列 row_hash,存放「平台权威字段」的 MD5 指纹
  (迁移 sql/20260915_add_student_row_hash.sql,可重复执行)
- 同步时先窄读现有指纹,只 upsert 指纹变化的行
- 窄读同时服务于停用差集,省掉原先单独的一次 selectAllXh
- deactivateByXh 顺带把 row_hash 置空,保证停用行以后重新出现时一定被重新写入

指纹规则单独成类 StudentFingerprint:它必须与 mapper 的
ON DUPLICATE KEY UPDATE 子句严格对应——往 UPDATE 里加字段却忘了加进指纹,
那一列就会静默地不再更新,这类 bug 不报错、只产生过期数据。
因此附有逐字段的测试,并由 MapperFieldWhitelistTest 守住 UPDATE 子句本身。

附带收益:未变更的行不再刷新 update_time,该字段恢复「最后变更时间」的含义;
码表修正后 nation/politics 变化会触发自动重算,正是 ADR-0006 承诺的行为。

预期学生同步 170 秒 -> 约 85 秒,其中写库 88 秒 -> 约 2 秒。
现有 98187 行 row_hash 为空,部署后第一次仍会全量写一次。
离线单测 50 个。
2026-09-15 16:14:05 +08:00
weicw1996 cd54039f28 接入医科大开放平台数据同步
新增 com.gxwebsoft.gxmu.openplat:开放平台客户端(oauth 鉴权、token 缓存与失效
重取、分页拉取)、部门/教师/班级/学生四段同步、异步编排与手动同步接口、学生认领、
学生名册查询与导出、每天 03:30 的定时任务、同步记录。

关键设计:
- 名册与登录账号分离,学生通过「认领」(手机号自动 / 学号姓名自助)关联 sys_user
- 组织数据以 sys_organization 为唯一载体,gxmu_college 废弃
- 平台无可用增量字段,只做全量拉取 + 幂等 upsert
- 上游消失只停用不删除,且只作用于同步来源的记录(避免误停用人工维护的研究生班)
- 平台权威字段按白名单覆盖,人工字段不触碰
- 码表可配置并保留原始码,码值实测存在两套编码混用,不做硬编码
- 手动同步为异步:提交返回批次号,前端轮询 /status 看分段进度

性能:
- 班级/部门由逐条 update 改为多行 upsert,班级 1584 条 41s -> 0.19s
- 码表解析加进程内缓存,学生同步由 >17 分钟不完成 -> 170 秒完成 98187 行

迁移脚本需手动执行(可重复执行):
  sql/20260912_create_openplat_sync_tables.sql
  sql/20260912_add_openplat_menu.sql

离线单测 43 个;另有联网集成测试 OpenPlatformClientIT(需 -Dopenplat.it=true)。
2026-09-15 15:54:49 +08:00
b2894lxlx f379291e4f 260720 2026-07-20 11:48:06 +08:00