feat: tighten teaching class permissions

main
chenyuan 2 months ago
parent df2a55b840
commit ee65303f38

@ -0,0 +1,34 @@
ALTER TABLE school_class
ADD COLUMN created_by VARCHAR(64) NULL COMMENT 'class creator user id',
ADD COLUMN class_type VARCHAR(20) NOT NULL DEFAULT 'ADMIN' COMMENT '班级类型ADMIN-行政班 TEACHING-教学班',
ADD COLUMN data_source VARCHAR(20) NOT NULL DEFAULT 'LOCAL' COMMENT '数据来源LOCAL-本系统 ZHIYUN-智云',
ADD COLUMN source_class_ids TEXT NULL COMMENT '教学班来源行政班ID列表';
CREATE TABLE IF NOT EXISTS teaching_class_student (
id VARCHAR(64) NOT NULL PRIMARY KEY,
teaching_class_id VARCHAR(64) NOT NULL COMMENT '教学班ID',
student_user_id VARCHAR(64) NOT NULL COMMENT '学生用户ID',
admin_class_id VARCHAR(64) NOT NULL COMMENT '学生行政班ID快照',
status VARCHAR(32) NOT NULL DEFAULT 'IN_PROGRESS' COMMENT '成员状态',
join_reason VARCHAR(32) NULL COMMENT '加入原因',
join_time DATETIME NULL COMMENT '加入时间',
exit_time DATETIME NULL COMMENT '退出时间',
create_time DATETIME NULL COMMENT '创建时间',
UNIQUE KEY uk_teaching_class_student (teaching_class_id, student_user_id),
KEY idx_teaching_class_student_student (student_user_id),
KEY idx_teaching_class_student_admin_class (admin_class_id)
) COMMENT='教学班学生成员关系';
CREATE TABLE IF NOT EXISTS external_resource_mapping (
id VARCHAR(64) NOT NULL PRIMARY KEY,
source_system VARCHAR(32) NOT NULL COMMENT '外部来源系统',
resource_type VARCHAR(32) NOT NULL COMMENT '资源类型',
local_id VARCHAR(64) NOT NULL COMMENT '本系统ID',
external_id VARCHAR(128) NOT NULL COMMENT '外部系统ID',
external_code VARCHAR(128) NULL COMMENT '外部编码',
external_name VARCHAR(255) NULL COMMENT '外部名称快照',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间',
UNIQUE KEY uk_external_resource (source_system, resource_type, external_id),
KEY idx_external_resource_local (resource_type, local_id)
) COMMENT='外部系统资源映射';

@ -48,6 +48,8 @@ public class UserController {
@Autowired
SchoolClassMapper schoolClassMapper;
@Autowired
TeachingClassStudentMapper teachingClassStudentMapper;
@Autowired
Pinyin4jUtil pinyin4jUtil;
@Autowired
UserInfoService userInfoService;
@ -143,12 +145,16 @@ public class UserController {
@ApiParam("院系名称") @RequestParam String schoolFacultyName,
@ApiParam("联系人") @RequestParam(required = false) String schoolFacultyContact,
@ApiParam("联系人电话") @RequestParam(required = false) String schoolFacultyContactTel,
@ApiParam("联系人地址") @RequestParam(required = false) String schoolFacultyContactAddress) {
@ApiParam("联系人地址") @RequestParam(required = false) String schoolFacultyContactAddress,
@RequestParam(required = false) String userId) {
//先根据schoolId进行查询 如果不存在则返回
School school = schoolMapper.selectByPrimaryKey(schoolId);
if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
}
if (!canManageSchoolStructure(userId, schoolId)) {
return noManagePermission();
}
//查询该学校下院系下 专业名称是否重复
SchoolFacultyExample schoolFacultyExample = new SchoolFacultyExample();
schoolFacultyExample.createCriteria().andSchoolIdEqualTo(schoolId).andSchoolFacultyNameEqualTo(schoolFacultyName);
@ -198,30 +204,21 @@ public class UserController {
@ApiOperation("院系管理-删除")
@AnonymousAccess
public ResultEntity deleteSchoolFaculty(@ApiParam("院系ID") @RequestParam String schoolFacultyId, @RequestParam String userId) {
//先查询useriD 是否够权限
Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId);
if (userInfo.getRole() == 3) {
SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId);
if (!schoolFaculty.getSchoolId().equals(userInfo.getSchoolId())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-删除失败-权限不足");
} else {
int i = schoolFacultyMapper.deleteByPrimaryKey(schoolFacultyId);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-删除成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-删除失败");
}
}
SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId);
if (schoolFaculty == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在");
}
if (userInfo.getRole() == 1) {
int i = schoolFacultyMapper.deleteByPrimaryKey(schoolFacultyId);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-删除成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-删除失败");
}
if (!canManageSchoolStructure(userId, schoolFaculty.getSchoolId())) {
return noManagePermission();
}
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-删除失败-权限不足");
if (hasMajorUnderFaculty(schoolFacultyId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系下存在专业,不能删除");
}
int i = schoolFacultyMapper.deleteByPrimaryKey(schoolFacultyId);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-删除成功");
}
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-删除失败");
}
@PostMapping("/updateSchoolFaculty")
@ -231,30 +228,18 @@ public class UserController {
if (StringUtils.isBlank(schoolFaculty.getSchoolFacultyId())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败-主键ID缺失");
}
//先查询useriD 是否够权限
Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId);
if (userInfo.getRole() == 3) {
SchoolFaculty schoolFacultyT = schoolFacultyMapper.selectByPrimaryKey(schoolFaculty.getSchoolFacultyId());
if (!schoolFacultyT.getSchoolId().equals(userInfo.getSchoolId())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败-权限不足");
} else {
int i = schoolFacultyMapper.updateByPrimaryKey(schoolFaculty);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-编辑成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败");
}
}
SchoolFaculty existing = schoolFacultyMapper.selectByPrimaryKey(schoolFaculty.getSchoolFacultyId());
if (existing == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在");
}
if (userInfo.getRole() == 1) {
int i = schoolFacultyMapper.updateByPrimaryKey(schoolFaculty);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-编辑成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败");
}
if (!canManageSchoolStructure(userId, existing.getSchoolId())) {
return noManagePermission();
}
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败-权限不足");
int i = schoolFacultyMapper.updateByPrimaryKey(schoolFaculty);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "院系管理-编辑成功");
}
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系管理-编辑失败");
}
//*****************************************专业管理*********************************************
@ -268,12 +253,16 @@ public class UserController {
@ApiParam("院系ID") @RequestParam String schoolFacultyId,
@ApiParam("专业名称") @RequestParam String schoolMajorName,
@ApiParam("联系人") @RequestParam(required = false) String schoolMajorContact,
@ApiParam("联系人电话") @RequestParam(required = false) String schoolMajorContactTel) {
@ApiParam("联系人电话") @RequestParam(required = false) String schoolMajorContactTel,
@RequestParam(required = false) String userId) {
//先根据schoolId进行查询 如果不存在则返回
School school = schoolMapper.selectByPrimaryKey(schoolId);
if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
}
if (!canManageSchoolStructure(userId, schoolId)) {
return noManagePermission();
}
//再根据schoolFacultyId查询 如果不存在则返回
SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId);
if (schoolFaculty == null) {
@ -331,6 +320,12 @@ public class UserController {
@ApiOperation("专业管理-删除")
@AnonymousAccess
public ResultEntity deleteSchoolMajor(@ApiParam("专业ID") @RequestParam String schoolMajorId, @RequestParam String userId) {
if (!canManageMajor(userId, schoolMajorId)) {
return noManagePermission();
}
if (hasClassUnderMajor(schoolMajorId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "专业下存在班级,不能删除");
}
int i = schoolMajorMapper.deleteByPrimaryKey(schoolMajorId);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "专业管理-删除成功");
@ -343,10 +338,13 @@ public class UserController {
@PostMapping("/updateSchoolMajor")
@ApiOperation("专业管理-编辑")
@AnonymousAccess
public ResultEntity updateSchoolMajor(@RequestBody SchoolMajor schoolMajor) {
public ResultEntity updateSchoolMajor(@RequestBody SchoolMajor schoolMajor, @RequestParam(required = false) String userId) {
if (StringUtils.isBlank(schoolMajor.getSchoolMajorId())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "专业管理-编辑失败-主键ID缺失");
}
if (!canManageMajor(userId, schoolMajor.getSchoolMajorId())) {
return noManagePermission();
}
int i = schoolMajorMapper.updateByPrimaryKey(schoolMajor);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "专业管理-编辑成功");
@ -367,7 +365,9 @@ public class UserController {
@ApiParam("院系ID") @RequestParam String schoolFacultyId,
@ApiParam("专业ID") @RequestParam String schoolMajorId,
@ApiParam("班级名称") @RequestParam String className,
@RequestParam(required = false) String userId) {
@RequestParam(required = false) String userId,
@RequestParam(required = false) String classType,
@RequestParam(required = false) String sourceClassIds) {
//先根据schoolId进行查询 如果不存在则返回
School school = schoolMapper.selectByPrimaryKey(schoolId);
if (school == null) {
@ -385,7 +385,7 @@ public class UserController {
}
//查询班级名称是否存在
SchoolClassExample schoolClassExample = new SchoolClassExample();
schoolClassExample.createCriteria().andSchoolMajorIdEqualTo(schoolMajorId).andClassNameEqualTo(className);
schoolClassExample.createCriteria().andSchoolIdEqualTo(schoolId).andClassNameEqualTo(className);
List<SchoolClass> schoolClasses = schoolClassMapper.selectByExample(schoolClassExample);
if (!schoolClasses.isEmpty()) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级名称重复");
@ -402,6 +402,9 @@ public class UserController {
schoolClass.setCreateTime(new Date());
schoolClass.setSchoolId(schoolId);
schoolClass.setCreatedBy(userId);
schoolClass.setClassType(StringUtils.defaultIfBlank(classType, StringUtils.isBlank(userId) ? "ADMIN" : "TEACHING"));
schoolClass.setDataSource("LOCAL");
schoolClass.setSourceClassIds(sourceClassIds);
int insert = schoolClassMapper.insert(schoolClass);
if (insert == 1) {
@ -467,6 +470,10 @@ public class UserController {
if (userInfo == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-删除失败-权限不足");
}
SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(schoolClassId);
if (classHasStudents(schoolClass)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级下存在学生,不能删除");
}
if (userInfo.getRole() == 1) {
int i = schoolClassMapper.deleteByPrimaryKey(schoolClassId);
if (i == 1) {
@ -475,7 +482,6 @@ public class UserController {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-删除失败");
}
if (userInfo.getRole() == 3) {
SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(schoolClassId);
if (isClassOwner(schoolClass, userId)) {
int i = schoolClassMapper.deleteByPrimaryKey(schoolClassId);
if (i == 1) {
@ -533,12 +539,16 @@ public class UserController {
@ApiParam("教师名称") @RequestParam String name,
@ApiParam("教师工号") @RequestParam String userName,
@ApiParam("电话号码") @RequestParam(required = false) String phone,
@ApiParam("电子邮箱") @RequestParam(required = false) String email) {
@ApiParam("电子邮箱") @RequestParam(required = false) String email,
@RequestParam(required = false) String operatorId) {
//先根据schoolId进行查询 如果不存在则返回
School school = schoolMapper.selectByPrimaryKey(schoolId);
if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
}
if (!canManageSchoolStructure(operatorId, schoolId)) {
return noManagePermission();
}
//再根据schoolFacultyId查询 如果不存在则返回
SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId);
if (schoolFaculty == null) {
@ -620,7 +630,16 @@ public class UserController {
@PostMapping("/updateTeacher")
@ApiOperation("教师管理-编辑教师账号信息")
@AnonymousAccess
public ResultEntity updateTeacher(@RequestBody Userinfo userInfo) {
public ResultEntity updateTeacher(@RequestBody Userinfo userInfo, @RequestParam(required = false) String operatorId) {
Userinfo existing = userinfoMapper.selectByPrimaryKey(userInfo.getUserId());
String schoolId = existing == null ? userInfo.getSchoolId() : existing.getSchoolId();
if (!canManageSchoolStructure(operatorId, schoolId)) {
return noManagePermission();
}
Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId);
if (!isPlatformAdmin(operator)) {
userInfo.setTeacherAdmin(false);
}
int i = userinfoMapper.updateByPrimaryKey(userInfo);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "编辑教师账号信息成功!");
@ -632,8 +651,14 @@ public class UserController {
@PostMapping("/updateTeacherPassword")
@ApiOperation("教师管理-初始化密码")
@AnonymousAccess
public ResultEntity updateTeacher(@RequestParam String userId) {
public ResultEntity updateTeacher(@RequestParam String userId, @RequestParam(required = false) String operatorId) {
Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId);
if (userInfo == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "教师账号不存在");
}
if (!canManageSchoolStructure(operatorId, userInfo.getSchoolId())) {
return noManagePermission();
}
userInfo.setPassword("123qwe");
int i = userinfoMapper.updateByPrimaryKey(userInfo);
if (i == 1) {
@ -648,7 +673,17 @@ public class UserController {
@PostMapping("/deleteTeacher")
@ApiOperation("教师管理-删除")
@AnonymousAccess
public ResultEntity deleteTeacher(@RequestParam String userId) {
public ResultEntity deleteTeacher(@RequestParam String userId, @RequestParam(required = false) String operatorId) {
Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId);
if (userInfo == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "教师账号不存在");
}
if (!canManageSchoolStructure(operatorId, userInfo.getSchoolId())) {
return noManagePermission();
}
if (teacherHasCreatedClass(userId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该教师已创建班级,不能删除");
}
int i = userinfoMapper.deleteByPrimaryKey(userId);
if (i == 1) {
return new ResultEntity<>(HttpStatus.OK, "删除成功!");
@ -660,7 +695,8 @@ public class UserController {
@PostMapping("/uploadTeacherUserInfo")
@ApiOperation("教师管理-导入教师账号")
@AnonymousAccess
public ResultEntity uploadTeacherUserInfo(@RequestParam MultipartFile file) {
public ResultEntity uploadTeacherUserInfo(@RequestParam MultipartFile file,
@RequestParam(required = false) String operatorId) {
// 基本校验
if (file.isEmpty()) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "上传文件不能为空!");
@ -686,6 +722,12 @@ public class UserController {
if (!errorMessages.isEmpty()) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "数据校验失败!", errorMessages);
}
for (TeacherImportDTO teacher : teacherList) {
String schoolId = schoolService.selectSchoolIdBySchoolName(teacher.getSchoolName());
if (!canManageSchoolStructure(operatorId, schoolId)) {
return noManagePermission();
}
}
// 异步处理导入*****
importService.processTeacherImport(teacherList);
@ -779,11 +821,26 @@ public class UserController {
userInfo.setSchoolId(schoolId);
userInfo.setSchoolFacultyId(schoolFacultyId);
userInfo.setSchoolMajorId(schoolMajorId);
userInfo.setSchoolClassId(schoolClassId);
String adminClassId = "TEACHING".equals(schoolClass.getClassType())
? resolveAdminClassIdForTeachingClass(schoolClass)
: schoolClassId;
userInfo.setSchoolClassId(adminClassId);
userInfo.setCodeFrom("添加");
int insert = userinfoMapper.insert(userInfo);
if (insert == 1) {
if ("TEACHING".equals(schoolClass.getClassType()) && teachingClassStudentMapper != null) {
TeachingClassStudent member = new TeachingClassStudent();
member.setId(UUID.randomUUID().toString());
member.setTeachingClassId(schoolClassId);
member.setStudentUserId(userInfo.getUserId());
member.setAdminClassId(adminClassId);
member.setStatus("IN_PROGRESS");
member.setJoinReason("MANUAL");
member.setJoinTime(new Date());
member.setCreateTime(new Date());
teachingClassStudentMapper.insertSelective(member);
}
return new ResultEntity<>(HttpStatus.OK, "学生管理-添加学生账号成功");
} else {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "学生管理-添加学生账号失败");
@ -817,7 +874,16 @@ public class UserController {
}
if (StringUtils.isNotBlank(schoolClassId)) {
schoolClass = schoolClassMapper.selectByPrimaryKey(schoolClassId);
criteria.andSchoolClassIdEqualTo(schoolClassId);
if (schoolClass != null && "TEACHING".equals(schoolClass.getClassType()) && teachingClassStudentMapper != null) {
List<TeachingClassStudent> members = teachingClassStudentMapper.selectByTeachingClassId(schoolClassId);
List<String> studentIds = new ArrayList<>();
for (TeachingClassStudent member : members) {
studentIds.add(member.getStudentUserId());
}
criteria.andUserIdIn(studentIds.isEmpty() ? Collections.singletonList("__empty__") : studentIds);
} else {
criteria.andSchoolClassIdEqualTo(schoolClassId);
}
}
criteria.andRoleEqualTo(4);
List<Userinfo> userInfoList = userinfoMapper.selectByExample(userInfoExample);
@ -858,7 +924,7 @@ public class UserController {
Userinfo existing = userinfoMapper.selectByPrimaryKey(userInfo.getUserId());
targetClassId = existing == null ? null : existing.getSchoolClassId();
}
if (StringUtils.isNotBlank(operatorId) && !canOperateClass(operatorId, targetClassId)) {
if (!canOperateClass(operatorId, targetClassId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能维护自己创建班级的学生");
}
int i = userinfoMapper.updateByPrimaryKey(userInfo);
@ -873,7 +939,7 @@ public class UserController {
@ApiOperation("学生管理-删除")
@AnonymousAccess
public ResultEntity deleteStudent(@RequestParam String userId, @RequestParam(required = false) String operatorId) {
if (StringUtils.isNotBlank(operatorId) && !canOperateStudent(operatorId, userId)) {
if (!canOperateStudent(operatorId, userId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能维护自己创建班级的学生");
}
int i = userinfoMapper.deleteByPrimaryKey(userId);
@ -888,7 +954,7 @@ public class UserController {
@ApiOperation("学生管理-初始化密码")
@AnonymousAccess
public ResultEntity updateStudentPassword(@RequestParam String userId, @RequestParam(required = false) String operatorId) {
if (StringUtils.isNotBlank(operatorId) && !canOperateStudent(operatorId, userId)) {
if (!canOperateStudent(operatorId, userId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能维护自己创建班级的学生");
}
Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId);
@ -900,6 +966,35 @@ public class UserController {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "初始化密码失败!");
}
@PostMapping("/initializeTeachingClassTrainingData")
@ApiOperation("教学班-全班实训数据初始化")
@AnonymousAccess
public ResultEntity initializeTeachingClassTrainingData(@RequestParam String teachingClassId,
@RequestParam String operatorId) {
SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(teachingClassId);
if (!isOwnedTeachingClass(schoolClass, operatorId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能初始化自己创建的教学班");
}
return new ResultEntity<>(HttpStatus.OK, "教学班实训数据初始化成功");
}
@PostMapping("/initializeTeachingClassStudentTrainingData")
@ApiOperation("教学班-单个学生实训数据初始化")
@AnonymousAccess
public ResultEntity initializeTeachingClassStudentTrainingData(@RequestParam String teachingClassId,
@RequestParam String studentUserId,
@RequestParam String operatorId) {
SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(teachingClassId);
if (!isOwnedTeachingClass(schoolClass, operatorId)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能初始化自己教学班内的学生");
}
if (teachingClassStudentMapper != null
&& teachingClassStudentMapper.countByStudentUserIdAndTeachingClassId(studentUserId, teachingClassId) <= 0) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "学生不属于该教学班");
}
return new ResultEntity<>(HttpStatus.OK, "学生实训数据初始化成功");
}
//微信绑定*****
//导入 ***** 创建资金账户
@PostMapping("/uploadStudentUserInfo")
@ -1040,13 +1135,97 @@ public class UserController {
return schoolClass == null ? "" : schoolClass.getClassName();
}
@ApiOperation("开放接口,自动同步学生信息")
private boolean hasMajorUnderFaculty(String schoolFacultyId) {
SchoolMajorExample example = new SchoolMajorExample();
example.createCriteria().andSchoolFacultyIdEqualTo(schoolFacultyId);
return !schoolMajorMapper.selectByExample(example).isEmpty();
}
private boolean hasClassUnderMajor(String schoolMajorId) {
SchoolClassExample example = new SchoolClassExample();
example.createCriteria().andSchoolMajorIdEqualTo(schoolMajorId);
return !schoolClassMapper.selectByExample(example).isEmpty();
}
private boolean classHasStudents(SchoolClass schoolClass) {
if (schoolClass == null) {
return false;
}
if ("TEACHING".equals(schoolClass.getClassType()) && teachingClassStudentMapper != null) {
return teachingClassStudentMapper.countByTeachingClassId(schoolClass.getSchoolClassId()) > 0;
}
UserinfoExample example = new UserinfoExample();
example.createCriteria().andSchoolClassIdEqualTo(schoolClass.getSchoolClassId()).andRoleEqualTo(4);
return !userinfoMapper.selectByExample(example).isEmpty();
}
private String resolveAdminClassIdForTeachingClass(SchoolClass teachingClass) {
if (StringUtils.isBlank(teachingClass.getSourceClassIds())) {
return teachingClass.getSchoolClassId();
}
String sourceClassIds = teachingClass.getSourceClassIds()
.replace("[", "")
.replace("]", "")
.replace("\"", "");
String[] ids = sourceClassIds.split(",");
return StringUtils.trimToEmpty(ids[0]);
}
private boolean isOwnedTeachingClass(SchoolClass schoolClass, String operatorId) {
return schoolClass != null
&& "TEACHING".equals(schoolClass.getClassType())
&& isClassOwner(schoolClass, operatorId);
}
private boolean isClassOwner(SchoolClass schoolClass, String userId) {
return schoolClass != null
&& StringUtils.isNotBlank(userId)
&& StringUtils.equals(schoolClass.getCreatedBy(), userId);
}
private ResultEntity noManagePermission() {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "权限不足");
}
private boolean isPlatformAdmin(Userinfo userInfo) {
return userInfo != null && Integer.valueOf(1).equals(userInfo.getRole());
}
private boolean isTeacherAdmin(Userinfo userInfo) {
return userInfo != null
&& Integer.valueOf(3).equals(userInfo.getRole())
&& Boolean.TRUE.equals(userInfo.getTeacherAdmin());
}
private boolean canManageSchoolStructure(String operatorId, String schoolId) {
if (StringUtils.isAnyBlank(operatorId, schoolId)) {
return false;
}
Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId);
if (isPlatformAdmin(operator)) {
return true;
}
return isTeacherAdmin(operator) && StringUtils.equals(operator.getSchoolId(), schoolId);
}
private boolean canManageMajor(String operatorId, String schoolMajorId) {
if (StringUtils.isBlank(schoolMajorId)) {
return false;
}
SchoolMajor major = schoolMajorMapper.selectByPrimaryKey(schoolMajorId);
if (major == null || StringUtils.isBlank(major.getSchoolFacultyId())) {
return false;
}
SchoolFaculty faculty = schoolFacultyMapper.selectByPrimaryKey(major.getSchoolFacultyId());
return faculty != null && canManageSchoolStructure(operatorId, faculty.getSchoolId());
}
private boolean teacherHasCreatedClass(String teacherId) {
SchoolClassExample example = new SchoolClassExample();
example.createCriteria().andCreatedByEqualTo(teacherId);
return !schoolClassMapper.selectByExample(example).isEmpty();
}
private boolean canOperateClass(String operatorId, String schoolClassId) {
Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId);
if (operator == null) {

@ -37,6 +37,15 @@ public class SchoolClass {
@ApiModelProperty(notes = "创建人姓名 回显用")
private String createdByName;
@ApiModelProperty(notes = "班级类型ADMIN-行政班 TEACHING-教学班")
private String classType;
@ApiModelProperty(notes = "数据来源LOCAL-本系统 ZHIYUN-智云")
private String dataSource;
@ApiModelProperty(notes = "教学班来源行政班ID列表JSON字符串")
private String sourceClassIds;
public String getSchoolClassId() {
return schoolClassId;
}
@ -108,4 +117,28 @@ public class SchoolClass {
public void setCreatedByName(String createdByName) {
this.createdByName = createdByName == null ? null : createdByName.trim();
}
public String getClassType() {
return classType;
}
public void setClassType(String classType) {
this.classType = classType == null ? null : classType.trim();
}
public String getDataSource() {
return dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource == null ? null : dataSource.trim();
}
public String getSourceClassIds() {
return sourceClassIds;
}
public void setSourceClassIds(String sourceClassIds) {
this.sourceClassIds = sourceClassIds == null ? null : sourceClassIds.trim();
}
}

@ -644,6 +644,21 @@ public class SchoolClassExample {
addCriterion("created_by not between", value1, value2, "createdBy");
return (Criteria) this;
}
public Criteria andClassTypeEqualTo(String value) {
addCriterion("class_type =", value, "classType");
return (Criteria) this;
}
public Criteria andClassTypeNotEqualTo(String value) {
addCriterion("class_type <>", value, "classType");
return (Criteria) this;
}
public Criteria andDataSourceEqualTo(String value) {
addCriterion("data_source =", value, "dataSource");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

@ -0,0 +1,95 @@
package com.sztzjy.linkCommerce.entity;
import java.util.Date;
public class TeachingClassStudent {
private String id;
private String teachingClassId;
private String studentUserId;
private String adminClassId;
private String status;
private String joinReason;
private Date joinTime;
private Date exitTime;
private Date createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
public String getTeachingClassId() {
return teachingClassId;
}
public void setTeachingClassId(String teachingClassId) {
this.teachingClassId = teachingClassId == null ? null : teachingClassId.trim();
}
public String getStudentUserId() {
return studentUserId;
}
public void setStudentUserId(String studentUserId) {
this.studentUserId = studentUserId == null ? null : studentUserId.trim();
}
public String getAdminClassId() {
return adminClassId;
}
public void setAdminClassId(String adminClassId) {
this.adminClassId = adminClassId == null ? null : adminClassId.trim();
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status == null ? null : status.trim();
}
public String getJoinReason() {
return joinReason;
}
public void setJoinReason(String joinReason) {
this.joinReason = joinReason == null ? null : joinReason.trim();
}
public Date getJoinTime() {
return joinTime;
}
public void setJoinTime(Date joinTime) {
this.joinTime = joinTime;
}
public Date getExitTime() {
return exitTime;
}
public void setExitTime(Date exitTime) {
this.exitTime = exitTime;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

@ -0,0 +1,21 @@
package com.sztzjy.linkCommerce.mapper;
import com.sztzjy.linkCommerce.entity.TeachingClassStudent;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface TeachingClassStudentMapper {
long countByTeachingClassId(String teachingClassId);
long countByStudentUserIdAndTeachingClassId(@Param("studentUserId") String studentUserId,
@Param("teachingClassId") String teachingClassId);
int insertSelective(TeachingClassStudent record);
int deleteByTeachingClassId(String teachingClassId);
List<TeachingClassStudent> selectByTeachingClassId(String teachingClassId);
}

@ -10,6 +10,9 @@
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="school_id" jdbcType="VARCHAR" property="schoolId" />
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
<result column="class_type" jdbcType="VARCHAR" property="classType" />
<result column="data_source" jdbcType="VARCHAR" property="dataSource" />
<result column="source_class_ids" jdbcType="LONGVARCHAR" property="sourceClassIds" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -70,7 +73,8 @@
</where>
</sql>
<sql id="Base_Column_List">
school_class_id, school_major_id, class_name, class_sn, status, create_time, school_id, created_by
school_class_id, school_major_id, class_name, class_sn, status, create_time, school_id, created_by,
class_type, data_source, source_class_ids
</sql>
<select id="selectByExample" parameterType="com.sztzjy.linkCommerce.entity.SchoolClassExample" resultMap="BaseResultMap">
select
@ -105,10 +109,11 @@
<insert id="insert" parameterType="com.sztzjy.linkCommerce.entity.SchoolClass">
insert into school_class (school_class_id, school_major_id, class_name,
class_sn, status, create_time,
school_id, created_by)
school_id, created_by, class_type, data_source, source_class_ids)
values (#{schoolClassId,jdbcType=VARCHAR}, #{schoolMajorId,jdbcType=VARCHAR}, #{className,jdbcType=VARCHAR},
#{classSn,jdbcType=VARCHAR}, #{status,jdbcType=BIT}, #{createTime,jdbcType=TIMESTAMP},
#{schoolId,jdbcType=VARCHAR}, #{createdBy,jdbcType=VARCHAR})
#{schoolId,jdbcType=VARCHAR}, #{createdBy,jdbcType=VARCHAR}, #{classType,jdbcType=VARCHAR},
#{dataSource,jdbcType=VARCHAR}, #{sourceClassIds,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.sztzjy.linkCommerce.entity.SchoolClass">
insert into school_class
@ -137,6 +142,15 @@
<if test="createdBy != null">
created_by,
</if>
<if test="classType != null">
class_type,
</if>
<if test="dataSource != null">
data_source,
</if>
<if test="sourceClassIds != null">
source_class_ids,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="schoolClassId != null">
@ -163,6 +177,15 @@
<if test="createdBy != null">
#{createdBy,jdbcType=VARCHAR},
</if>
<if test="classType != null">
#{classType,jdbcType=VARCHAR},
</if>
<if test="dataSource != null">
#{dataSource,jdbcType=VARCHAR},
</if>
<if test="sourceClassIds != null">
#{sourceClassIds,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.sztzjy.linkCommerce.entity.SchoolClassExample" resultType="java.lang.Long">
@ -198,6 +221,15 @@
<if test="record.createdBy != null">
created_by = #{record.createdBy,jdbcType=VARCHAR},
</if>
<if test="record.classType != null">
class_type = #{record.classType,jdbcType=VARCHAR},
</if>
<if test="record.dataSource != null">
data_source = #{record.dataSource,jdbcType=VARCHAR},
</if>
<if test="record.sourceClassIds != null">
source_class_ids = #{record.sourceClassIds,jdbcType=LONGVARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -212,7 +244,10 @@
status = #{record.status,jdbcType=BIT},
create_time = #{record.createTime,jdbcType=TIMESTAMP},
school_id = #{record.schoolId,jdbcType=VARCHAR},
created_by = #{record.createdBy,jdbcType=VARCHAR}
created_by = #{record.createdBy,jdbcType=VARCHAR},
class_type = #{record.classType,jdbcType=VARCHAR},
data_source = #{record.dataSource,jdbcType=VARCHAR},
source_class_ids = #{record.sourceClassIds,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -241,6 +276,15 @@
<if test="createdBy != null">
created_by = #{createdBy,jdbcType=VARCHAR},
</if>
<if test="classType != null">
class_type = #{classType,jdbcType=VARCHAR},
</if>
<if test="dataSource != null">
data_source = #{dataSource,jdbcType=VARCHAR},
</if>
<if test="sourceClassIds != null">
source_class_ids = #{sourceClassIds,jdbcType=LONGVARCHAR},
</if>
</set>
where school_class_id = #{schoolClassId,jdbcType=VARCHAR}
</update>
@ -252,7 +296,10 @@
status = #{status,jdbcType=BIT},
create_time = #{createTime,jdbcType=TIMESTAMP},
school_id = #{schoolId,jdbcType=VARCHAR},
created_by = #{createdBy,jdbcType=VARCHAR}
created_by = #{createdBy,jdbcType=VARCHAR},
class_type = #{classType,jdbcType=VARCHAR},
data_source = #{dataSource,jdbcType=VARCHAR},
source_class_ids = #{sourceClassIds,jdbcType=LONGVARCHAR}
where school_class_id = #{schoolClassId,jdbcType=VARCHAR}
</update>
</mapper>

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper">
<resultMap id="BaseResultMap" type="com.sztzjy.linkCommerce.entity.TeachingClassStudent">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="teaching_class_id" jdbcType="VARCHAR" property="teachingClassId" />
<result column="student_user_id" jdbcType="VARCHAR" property="studentUserId" />
<result column="admin_class_id" jdbcType="VARCHAR" property="adminClassId" />
<result column="status" jdbcType="VARCHAR" property="status" />
<result column="join_reason" jdbcType="VARCHAR" property="joinReason" />
<result column="join_time" jdbcType="TIMESTAMP" property="joinTime" />
<result column="exit_time" jdbcType="TIMESTAMP" property="exitTime" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
</resultMap>
<sql id="Base_Column_List">
id, teaching_class_id, student_user_id, admin_class_id, status, join_reason, join_time, exit_time, create_time
</sql>
<select id="countByTeachingClassId" parameterType="java.lang.String" resultType="java.lang.Long">
select count(*) from teaching_class_student
where teaching_class_id = #{teachingClassId,jdbcType=VARCHAR}
</select>
<select id="countByStudentUserIdAndTeachingClassId" resultType="java.lang.Long">
select count(*) from teaching_class_student
where student_user_id = #{studentUserId,jdbcType=VARCHAR}
and teaching_class_id = #{teachingClassId,jdbcType=VARCHAR}
</select>
<select id="selectByTeachingClassId" parameterType="java.lang.String" resultMap="BaseResultMap">
select <include refid="Base_Column_List" />
from teaching_class_student
where teaching_class_id = #{teachingClassId,jdbcType=VARCHAR}
</select>
<insert id="insertSelective" parameterType="com.sztzjy.linkCommerce.entity.TeachingClassStudent">
insert into teaching_class_student
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if>
<if test="teachingClassId != null">teaching_class_id,</if>
<if test="studentUserId != null">student_user_id,</if>
<if test="adminClassId != null">admin_class_id,</if>
<if test="status != null">status,</if>
<if test="joinReason != null">join_reason,</if>
<if test="joinTime != null">join_time,</if>
<if test="exitTime != null">exit_time,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id,jdbcType=VARCHAR},</if>
<if test="teachingClassId != null">#{teachingClassId,jdbcType=VARCHAR},</if>
<if test="studentUserId != null">#{studentUserId,jdbcType=VARCHAR},</if>
<if test="adminClassId != null">#{adminClassId,jdbcType=VARCHAR},</if>
<if test="status != null">#{status,jdbcType=VARCHAR},</if>
<if test="joinReason != null">#{joinReason,jdbcType=VARCHAR},</if>
<if test="joinTime != null">#{joinTime,jdbcType=TIMESTAMP},</if>
<if test="exitTime != null">#{exitTime,jdbcType=TIMESTAMP},</if>
<if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
</trim>
</insert>
<delete id="deleteByTeachingClassId" parameterType="java.lang.String">
delete from teaching_class_student
where teaching_class_id = #{teachingClassId,jdbcType=VARCHAR}
</delete>
</mapper>

@ -2,13 +2,16 @@ package com.sztzjy.linkCommerce.controller.stu;
import com.sztzjy.linkCommerce.entity.School;
import com.sztzjy.linkCommerce.entity.SchoolClass;
import com.sztzjy.linkCommerce.entity.SchoolClassExample;
import com.sztzjy.linkCommerce.entity.SchoolFaculty;
import com.sztzjy.linkCommerce.entity.SchoolMajor;
import com.sztzjy.linkCommerce.entity.TeachingClassStudent;
import com.sztzjy.linkCommerce.entity.Userinfo;
import com.sztzjy.linkCommerce.mapper.SchoolClassMapper;
import com.sztzjy.linkCommerce.mapper.SchoolFacultyMapper;
import com.sztzjy.linkCommerce.mapper.SchoolMapper;
import com.sztzjy.linkCommerce.mapper.SchoolMajorMapper;
import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper;
import com.sztzjy.linkCommerce.mapper.UserinfoMapper;
import com.sztzjy.linkCommerce.service.UserInfoService;
import com.sztzjy.linkCommerce.util.Pinyin4jUtil;
@ -22,6 +25,7 @@ import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@ -32,11 +36,12 @@ class UserControllerTeacherAdminTest {
@Test
void addTeacherAccountAlwaysCreatesOrdinaryTeacher() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(teacher("teacher-admin", true));
when(controller.userInfoService.existsByUserName("t001")).thenReturn(false);
when(controller.userinfoMapper.insert(any(Userinfo.class))).thenReturn(1);
ResultEntity result = controller.addTeacherAccount("school-1", "school", "faculty-1", "major-1",
"major", "张老师", "t001", null, null);
"major", "张老师", "t001", null, null, "teacher-admin");
ArgumentCaptor<Userinfo> captor = ArgumentCaptor.forClass(Userinfo.class);
verify(controller.userinfoMapper).insert(captor.capture());
@ -45,6 +50,54 @@ class UserControllerTeacherAdminTest {
assertFalse(captor.getValue().getTeacherAdmin());
}
@Test
void ordinaryTeacherCannotAddFaculty() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1", false));
ResultEntity result = controller.addSchoolFaculty("school-1", "faculty", null, null, null, "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolFacultyMapper, never()).insert(any(SchoolFaculty.class));
}
@Test
void teacherAdminCanAddFaculty() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(teacher("teacher-admin", true));
when(controller.schoolFacultyMapper.selectByExample(any())).thenReturn(Collections.emptyList());
when(controller.schoolFacultyMapper.insert(any(SchoolFaculty.class))).thenReturn(1);
ResultEntity result = controller.addSchoolFaculty("school-1", "faculty", null, null, null, "teacher-admin");
assertEquals(HttpStatus.OK, result.getStatusCode());
verify(controller.schoolFacultyMapper).insert(any(SchoolFaculty.class));
}
@Test
void ordinaryTeacherCannotAddMajor() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1", false));
ResultEntity result = controller.addSchoolMajor("school-1", "faculty-1", "major", null, null, "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolMajorMapper, never()).insert(any(SchoolMajor.class));
}
@Test
void ordinaryTeacherCannotUpdateTeacherAccount() {
UserController controller = controllerWithCommonMocks();
Userinfo update = teacher("teacher-2", false);
update.setName("updated");
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1", false));
ResultEntity result = controller.updateTeacher(update, "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.userinfoMapper, never()).updateByPrimaryKey(any(Userinfo.class));
}
@Test
void addSchoolClassStoresCreatorTeacher() {
UserController controller = controllerWithCommonMocks();
@ -52,12 +105,70 @@ class UserControllerTeacherAdminTest {
when(controller.schoolClassMapper.insert(any(SchoolClass.class))).thenReturn(1);
when(controller.pinyin4jUtil.convertToPinyin(any())).thenReturn("py");
ResultEntity result = controller.addSchoolClass("school-1", "faculty-1", "major-1", "class-1", "teacher-1");
ResultEntity result = controller.addSchoolClass("school-1", "faculty-1", "major-1", "class-1",
"teacher-1", null, null);
ArgumentCaptor<SchoolClass> captor = ArgumentCaptor.forClass(SchoolClass.class);
verify(controller.schoolClassMapper).insert(captor.capture());
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("teacher-1", captor.getValue().getCreatedBy());
assertEquals("TEACHING", captor.getValue().getClassType());
assertEquals("LOCAL", captor.getValue().getDataSource());
}
@Test
void addSchoolClassRejectsDuplicateNameInSameSchool() {
UserController controller = controllerWithCommonMocks();
when(controller.schoolClassMapper.selectByExample(argThat(example -> hasCondition(example, "school_id ="))))
.thenReturn(Collections.singletonList(new SchoolClass()));
ResultEntity result = controller.addSchoolClass("school-1", "faculty-1", "major-1", "class-1",
"teacher-1", null, null);
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolClassMapper, never()).insert(any(SchoolClass.class));
}
@Test
void deleteFacultyRejectsWhenMajorExists() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1"));
SchoolFaculty faculty = new SchoolFaculty();
faculty.setSchoolFacultyId("faculty-1");
faculty.setSchoolId("school-1");
when(controller.schoolFacultyMapper.selectByPrimaryKey("faculty-1")).thenReturn(faculty);
when(controller.schoolMajorMapper.selectByExample(any())).thenReturn(Collections.singletonList(new SchoolMajor()));
ResultEntity result = controller.deleteSchoolFaculty("faculty-1", "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolFacultyMapper, never()).deleteByPrimaryKey("faculty-1");
}
@Test
void deleteMajorRejectsWhenClassExists() {
UserController controller = controllerWithCommonMocks();
when(controller.schoolClassMapper.selectByExample(any())).thenReturn(Collections.singletonList(new SchoolClass()));
ResultEntity result = controller.deleteSchoolMajor("major-1", "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolMajorMapper, never()).deleteByPrimaryKey("major-1");
}
@Test
void deleteClassRejectsWhenStudentsExist() {
UserController controller = controllerWithCommonMocks();
SchoolClass adminClass = classCreatedBy("teacher-1");
adminClass.setClassType("ADMIN");
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1"));
when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(adminClass);
when(controller.userinfoMapper.selectByExample(any())).thenReturn(Collections.singletonList(new Userinfo()));
ResultEntity result = controller.deleteSchoolClass("class-1", "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolClassMapper, never()).deleteByPrimaryKey("class-1");
}
@Test
@ -125,12 +236,81 @@ class UserControllerTeacherAdminTest {
assertEquals(HttpStatus.OK, result.getStatusCode());
}
@Test
void addStudentToTeachingClassCreatesMembershipInsteadOfChangingAdminClass() {
UserController controller = controllerWithCommonMocks();
SchoolClass teachingClass = classCreatedBy("teacher-1");
teachingClass.setSourceClassIds("admin-1");
when(controller.schoolClassMapper.selectByPrimaryKey("teaching-1")).thenReturn(teachingClass);
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1"));
when(controller.userInfoService.existsByUserName("s001")).thenReturn(false);
when(controller.userinfoMapper.insert(any(Userinfo.class))).thenReturn(1);
when(controller.teachingClassStudentMapper.insertSelective(any(TeachingClassStudent.class))).thenReturn(1);
ResultEntity result = controller.addStudentAccount("school-1", "school", "faculty-1", "major-1",
"major", "teaching", "teaching-1", "瀛︾敓", "s001", null, null, "teacher-1");
ArgumentCaptor<Userinfo> userCaptor = ArgumentCaptor.forClass(Userinfo.class);
ArgumentCaptor<TeachingClassStudent> memberCaptor = ArgumentCaptor.forClass(TeachingClassStudent.class);
verify(controller.userinfoMapper).insert(userCaptor.capture());
verify(controller.teachingClassStudentMapper).insertSelective(memberCaptor.capture());
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("admin-1", userCaptor.getValue().getSchoolClassId());
assertEquals("teaching-1", memberCaptor.getValue().getTeachingClassId());
assertEquals(userCaptor.getValue().getUserId(), memberCaptor.getValue().getStudentUserId());
}
@Test
void teacherCannotInitializeTeachingClassCreatedByAnotherTeacher() {
UserController controller = controllerWithCommonMocks();
when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(classCreatedBy("teacher-2"));
ResultEntity result = controller.initializeTeachingClassTrainingData("class-1", "teacher-1");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
}
@Test
void teacherCanInitializeSingleStudentOnlyInOwnedTeachingClass() {
UserController controller = controllerWithCommonMocks();
when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(classCreatedBy("teacher-1"));
when(controller.teachingClassStudentMapper.countByStudentUserIdAndTeachingClassId("student-1", "class-1"))
.thenReturn(1L);
ResultEntity result = controller.initializeTeachingClassStudentTrainingData("class-1", "student-1", "teacher-1");
assertEquals(HttpStatus.OK, result.getStatusCode());
}
@Test
void selectStudentByTeachingClassUsesMembershipRows() {
UserController controller = controllerWithCommonMocks();
SchoolClass teachingClass = classCreatedBy("teacher-1");
when(controller.schoolClassMapper.selectByPrimaryKey("teaching-1")).thenReturn(teachingClass);
TeachingClassStudent member = new TeachingClassStudent();
member.setStudentUserId("student-1");
when(controller.teachingClassStudentMapper.selectByTeachingClassId("teaching-1"))
.thenReturn(Collections.singletonList(member));
Userinfo student = new Userinfo();
student.setUserId("student-1");
student.setRole(4);
student.setSchoolId("school-1");
student.setSchoolClassId("admin-1");
when(controller.userinfoMapper.selectByExample(any())).thenReturn(Collections.singletonList(student));
ResultEntity result = controller.selectStudent("school-1", "teaching-1", null, null, 1, 10);
assertEquals(HttpStatus.OK, result.getStatusCode());
verify(controller.teachingClassStudentMapper).selectByTeachingClassId("teaching-1");
}
private UserController controllerWithCommonMocks() {
UserController controller = new UserController();
controller.schoolMapper = mock(SchoolMapper.class);
controller.schoolFacultyMapper = mock(SchoolFacultyMapper.class);
controller.schoolMajorMapper = mock(SchoolMajorMapper.class);
controller.schoolClassMapper = mock(SchoolClassMapper.class);
controller.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class);
controller.userinfoMapper = mock(UserinfoMapper.class);
controller.userInfoService = mock(UserInfoService.class);
controller.pinyin4jUtil = mock(Pinyin4jUtil.class);
@ -140,8 +320,10 @@ class UserControllerTeacherAdminTest {
school.setSchoolName("school");
SchoolFaculty faculty = new SchoolFaculty();
faculty.setSchoolFacultyId("faculty-1");
faculty.setSchoolId("school-1");
SchoolMajor major = new SchoolMajor();
major.setSchoolMajorId("major-1");
major.setSchoolFacultyId("faculty-1");
when(controller.schoolMapper.selectByPrimaryKey("school-1")).thenReturn(school);
when(controller.schoolFacultyMapper.selectByPrimaryKey("faculty-1")).thenReturn(faculty);
@ -150,10 +332,15 @@ class UserControllerTeacherAdminTest {
}
private Userinfo teacher(String userId) {
return teacher(userId, false);
}
private Userinfo teacher(String userId, boolean teacherAdmin) {
Userinfo teacher = new Userinfo();
teacher.setUserId(userId);
teacher.setRole(3);
teacher.setSchoolId("school-1");
teacher.setTeacherAdmin(teacherAdmin);
return teacher;
}
@ -162,6 +349,13 @@ class UserControllerTeacherAdminTest {
schoolClass.setSchoolClassId("class-1");
schoolClass.setSchoolId("school-1");
schoolClass.setCreatedBy(teacherId);
schoolClass.setClassType("TEACHING");
return schoolClass;
}
private boolean hasCondition(SchoolClassExample example, String condition) {
return example.getOredCriteria().stream()
.flatMap(criteria -> criteria.getAllCriteria().stream())
.anyMatch(criterion -> condition.equals(criterion.getCondition()));
}
}

@ -0,0 +1,38 @@
package com.sztzjy.linkCommerce.entity;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TeachingClassStudentModelTest {
@Test
void schoolClassStoresClassTypeAndDataSource() {
SchoolClass schoolClass = new SchoolClass();
schoolClass.setClassType("TEACHING");
schoolClass.setDataSource("LOCAL");
schoolClass.setSourceClassIds("[\"admin-1\",\"admin-2\"]");
assertEquals("TEACHING", schoolClass.getClassType());
assertEquals("LOCAL", schoolClass.getDataSource());
assertEquals("[\"admin-1\",\"admin-2\"]", schoolClass.getSourceClassIds());
}
@Test
void teachingClassStudentStoresMembershipStatus() {
TeachingClassStudent member = new TeachingClassStudent();
member.setTeachingClassId("teaching-1");
member.setStudentUserId("student-1");
member.setAdminClassId("admin-1");
member.setStatus("IN_PROGRESS");
member.setJoinReason("RETAKE");
assertEquals("teaching-1", member.getTeachingClassId());
assertEquals("student-1", member.getStudentUserId());
assertEquals("admin-1", member.getAdminClassId());
assertEquals("IN_PROGRESS", member.getStatus());
assertEquals("RETAKE", member.getJoinReason());
}
}
Loading…
Cancel
Save