新增教师名册只读接口

教师名册来自开放平台全量同步,只用于检索与选人(教师不建登录账号,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,可重复执行
This commit is contained in:
2026-09-15 17:21:32 +08:00
parent 582d7dfbcb
commit 853f3c3f5b
3 changed files with 252 additions and 0 deletions
@@ -0,0 +1,84 @@
package com.gxwebsoft.gxmu.openplat.controller;
import com.gxwebsoft.gxmu.openplat.entity.GxmuTeacher;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* 教师名册的敏感字段守卫测试(spec §5.2)。
*
* <p>教师手机号是落盘但「不进任何列表接口」的字段。名册页是本项目里第一个把
* {@link GxmuTeacher} 直接序列化出去的地方,一旦漏掉清空,1.7 万条手机号就会随
* 分页接口泄露——这类事故从代码评审里看不出来,所以直接钉在测试里。
*
* @author Codex
* @since 2026-09-15
*/
class GxmuTeacherControllerTest {
private static GxmuTeacher sample(String jgh, String sjh) {
GxmuTeacher teacher = new GxmuTeacher();
teacher.setJgh(jgh);
teacher.setXm("张三");
teacher.setXbm("1");
teacher.setSex("男");
teacher.setDwh("010318");
teacher.setCollegeId(60);
teacher.setKsjybh("01031801");
teacher.setSjh(sjh);
teacher.setStatus(1);
return teacher;
}
@Test
void phoneNumberNeverSurvives() {
List<GxmuTeacher> records = new ArrayList<>(Arrays.asList(
sample("10001", "13800000000"),
sample("10002", "13900000000")));
GxmuTeacherController.hideSensitive(records);
for (GxmuTeacher teacher : records) {
assertNull(teacher.getSjh(), "手机号必须清空后再返回");
}
}
/**
* 清空的是手机号这一列,不是整行——列表页要靠其余字段渲染。
*/
@Test
void otherFieldsAreUntouched() {
List<GxmuTeacher> records = new ArrayList<>(Arrays.asList(sample("10001", "13800000000")));
GxmuTeacherController.hideSensitive(records);
GxmuTeacher teacher = records.get(0);
assertEquals("10001", teacher.getJgh());
assertEquals("张三", teacher.getXm());
assertEquals("男", teacher.getSex());
assertEquals(Integer.valueOf(60), teacher.getCollegeId());
assertEquals("01031801", teacher.getKsjybh());
assertEquals(Integer.valueOf(1), teacher.getStatus());
}
@Test
void emptyListIsFine() {
GxmuTeacherController.hideSensitive(new ArrayList<>());
}
@Test
void nullPhoneStaysNull() {
List<GxmuTeacher> records = new ArrayList<>(Arrays.asList(sample("10001", null)));
GxmuTeacherController.hideSensitive(records);
assertNull(records.get(0).getSjh());
}
}