新增教师名册只读接口
教师名册来自开放平台全量同步,只用于检索与选人(教师不建登录账号,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:
@@ -0,0 +1,118 @@
|
||||
package com.gxwebsoft.gxmu.openplat.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.gxmu.openplat.SyncSupport;
|
||||
import com.gxwebsoft.gxmu.openplat.entity.GxmuTeacher;
|
||||
import com.gxwebsoft.gxmu.openplat.mapper.GxmuTeacherMapper;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 教师名册控制器(只读)。
|
||||
*
|
||||
* <p>教师名册来自开放平台全量同步,只用于检索与选人,教师本身不建登录账号(见 ADR-0001)。
|
||||
* 因此这里没有认领类接口,也没有可写字段。
|
||||
*
|
||||
* <p>手机号按 spec §5.2「落盘但不进任何列表接口」处理:{@link #hideSensitive} 在返回前一律清空,
|
||||
* 明文不出本控制器。
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-09-15
|
||||
*/
|
||||
@Api(tags = "教师名册")
|
||||
@RestController
|
||||
@RequestMapping("/api/gxmu/teacher")
|
||||
public class GxmuTeacherController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private GxmuTeacherMapper teacherMapper;
|
||||
|
||||
@Resource
|
||||
private SyncSupport syncSupport;
|
||||
|
||||
@PreAuthorize("hasAuthority('gxmu:teacher:list')")
|
||||
@ApiOperation("教师名册分页查询")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<GxmuTeacher>> page(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "20") Integer limit,
|
||||
@RequestParam(value = "collegeId", required = false) Integer collegeId,
|
||||
@RequestParam(value = "jgh", required = false) String jgh,
|
||||
@RequestParam(value = "xm", required = false) String xm,
|
||||
@RequestParam(value = "status", required = false) Integer status) {
|
||||
LambdaQueryWrapper<GxmuTeacher> wrapper = buildWrapper(collegeId, jgh, xm, status);
|
||||
Page<GxmuTeacher> pageParam = new Page<>(page, limit);
|
||||
IPage<GxmuTeacher> result = teacherMapper.selectPage(pageParam, wrapper);
|
||||
List<GxmuTeacher> records = result.getRecords();
|
||||
hideSensitive(records);
|
||||
enrich(records);
|
||||
return success(new PageResult<>(records, result.getTotal()));
|
||||
}
|
||||
|
||||
@ApiOperation("导出教师名册(不含手机号)")
|
||||
@PreAuthorize("hasAuthority('gxmu:teacher:export')")
|
||||
@OperationLog
|
||||
@PostMapping("/export")
|
||||
public ApiResult<List<GxmuTeacher>> export(
|
||||
@RequestParam(value = "collegeId", required = false) Integer collegeId,
|
||||
@RequestParam(value = "status", required = false) Integer status) {
|
||||
List<GxmuTeacher> records = teacherMapper.selectList(buildWrapper(collegeId, null, null, status));
|
||||
hideSensitive(records);
|
||||
enrich(records);
|
||||
return success(records);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<GxmuTeacher> buildWrapper(Integer collegeId, String jgh, String xm, Integer status) {
|
||||
LambdaQueryWrapper<GxmuTeacher> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(GxmuTeacher::getTenantId, getTenantId());
|
||||
wrapper.eq(collegeId != null, GxmuTeacher::getCollegeId, collegeId);
|
||||
wrapper.eq(StrUtil.isNotBlank(jgh), GxmuTeacher::getJgh, StrUtil.trim(jgh));
|
||||
wrapper.like(StrUtil.isNotBlank(xm), GxmuTeacher::getXm, StrUtil.trim(xm));
|
||||
// 默认只看启用(停用=上游已消失,见 ADR-0004,需要时显式查 status=0)
|
||||
wrapper.eq(status != null, GxmuTeacher::getStatus, status);
|
||||
wrapper.eq(status == null, GxmuTeacher::getStatus, 1);
|
||||
wrapper.orderByAsc(GxmuTeacher::getCollegeId).orderByAsc(GxmuTeacher::getJgh);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号绝不随响应返回:置空而不是脱敏,教师名册页也不需要这个字段(spec §5.2)。
|
||||
*
|
||||
* <p>包级可见是为了让单元测试能直接钉住这条规则。
|
||||
*/
|
||||
static void hideSensitive(List<GxmuTeacher> records) {
|
||||
for (GxmuTeacher teacher : records) {
|
||||
teacher.setSjh(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void enrich(List<GxmuTeacher> records) {
|
||||
if (records.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Integer, String> orgNames = syncSupport.orgNameById();
|
||||
for (GxmuTeacher teacher : records) {
|
||||
if (teacher.getCollegeId() != null) {
|
||||
teacher.setCollegeName(orgNames.get(teacher.getCollegeId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user