接入医科大开放平台数据同步

新增 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)。
This commit is contained in:
2026-09-15 15:54:49 +08:00
parent f379291e4f
commit cd54039f28
51 changed files with 4586 additions and 3 deletions
@@ -58,6 +58,8 @@ public class WxLoginController extends BaseController {
private RoleService roleService;
@Resource
private WxMaProperties wxMaProperties;
@Resource
private com.gxwebsoft.gxmu.openplat.claim.StudentClaimService studentClaimService;
@Autowired
private StringRedisTemplate redisTemplate;
@@ -90,6 +92,7 @@ public class WxLoginController extends BaseController {
userOauthService.save(uo);
}
// 4.签发token
autoClaimQuietly(user);
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
@@ -124,6 +127,7 @@ public class WxLoginController extends BaseController {
userOauthService.save(uo);
}
// 签发token
autoClaimQuietly(user);
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
@@ -146,6 +150,19 @@ public class WxLoginController extends BaseController {
return fail("更新失败");
}
/**
* 尝试按手机号自动认领学生名册(docs/adr/0001)。
*
* <p>认领失败不影响登录:命中不到、命中多条、姓名不符等都只是返回 false。
*/
private void autoClaimQuietly(User user) {
try {
studentClaimService.autoClaimByPhone(user);
} catch (Exception e) {
System.out.println("学生认领失败:" + e.getMessage());
}
}
/**
* 新用户注册
*/