feat: add school organization capability switches

main
chenyuan 1 month ago
parent 01e68b255b
commit f4f354b367

@ -0,0 +1,9 @@
ALTER TABLE school_product_config
ADD COLUMN faculty_management_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'whether faculty management is enabled' AFTER student_roster_owner,
ADD COLUMN major_management_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'whether major management is enabled' AFTER faculty_management_enabled,
ADD COLUMN admin_class_management_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'whether administrative class management is enabled' AFTER major_management_enabled;
UPDATE school_product_config
SET faculty_management_enabled = CASE WHEN organization_mode = 'TEACHING_CLASS_ONLY' THEN 0 ELSE 1 END,
major_management_enabled = CASE WHEN organization_mode = 'TEACHING_CLASS_ONLY' THEN 0 ELSE 1 END,
admin_class_management_enabled = CASE WHEN organization_mode = 'TEACHING_CLASS_ONLY' THEN 0 ELSE 1 END;

@ -84,7 +84,7 @@ public class SchoolAdminController {
@RequestParam(required = false) String schoolFacultyName, @RequestParam(required = false) String schoolFacultyName,
HttpServletRequest request) { HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireFacultyManagement(schoolId);
PageInfo<SchoolFacultyDto> pageInfo = schoolService.seleteSchoolFaculty(index, size, schoolId, schoolFacultyName); PageInfo<SchoolFacultyDto> pageInfo = schoolService.seleteSchoolFaculty(index, size, schoolId, schoolFacultyName);
return new ResultEntity<>(HttpStatus.OK, "查询成功", pageInfo); return new ResultEntity<>(HttpStatus.OK, "查询成功", pageInfo);
} }
@ -93,7 +93,7 @@ public class SchoolAdminController {
@ApiOperation("学校管理员-新增院系") @ApiOperation("学校管理员-新增院系")
public ResultEntity addFaculty(@RequestBody SchoolFaculty faculty, HttpServletRequest request) { public ResultEntity addFaculty(@RequestBody SchoolFaculty faculty, HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireFacultyManagement(schoolId);
if (StringUtils.isBlank(faculty.getSchoolFacultyName())) { if (StringUtils.isBlank(faculty.getSchoolFacultyName())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系名称不能为空"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系名称不能为空");
} }
@ -110,7 +110,7 @@ public class SchoolAdminController {
@RequestBody SchoolFaculty faculty, @RequestBody SchoolFaculty faculty,
HttpServletRequest request) { HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireFacultyManagement(schoolId);
SchoolFaculty existing = requireFaculty(id, schoolId); SchoolFaculty existing = requireFaculty(id, schoolId);
faculty.setSchoolFacultyId(existing.getSchoolFacultyId()); faculty.setSchoolFacultyId(existing.getSchoolFacultyId());
faculty.setSchoolId(schoolId); faculty.setSchoolId(schoolId);
@ -122,7 +122,7 @@ public class SchoolAdminController {
@ApiOperation("学校管理员-删除院系") @ApiOperation("学校管理员-删除院系")
public ResultEntity deleteFaculty(@PathVariable String id, HttpServletRequest request) { public ResultEntity deleteFaculty(@PathVariable String id, HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireFacultyManagement(schoolId);
requireFaculty(id, schoolId); requireFaculty(id, schoolId);
if (hasMajorInFaculty(id) || hasUserByFaculty(id)) { if (hasMajorInFaculty(id) || hasUserByFaculty(id)) {
return new ResultEntity<>(HttpStatus.ACCEPTED, "院系下存在专业或用户,不能删除"); return new ResultEntity<>(HttpStatus.ACCEPTED, "院系下存在专业或用户,不能删除");
@ -139,7 +139,7 @@ public class SchoolAdminController {
@RequestParam(required = false) String schoolFacultyId, @RequestParam(required = false) String schoolFacultyId,
HttpServletRequest request) { HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireMajorManagement(schoolId);
if (StringUtils.isNotBlank(schoolFacultyId)) { if (StringUtils.isNotBlank(schoolFacultyId)) {
requireFaculty(schoolFacultyId, schoolId); requireFaculty(schoolFacultyId, schoolId);
} }
@ -151,7 +151,7 @@ public class SchoolAdminController {
@ApiOperation("学校管理员-新增专业") @ApiOperation("学校管理员-新增专业")
public ResultEntity addMajor(@RequestBody SchoolMajor major, HttpServletRequest request) { public ResultEntity addMajor(@RequestBody SchoolMajor major, HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireMajorManagement(schoolId);
if (StringUtils.isBlank(major.getSchoolMajorName())) { if (StringUtils.isBlank(major.getSchoolMajorName())) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "专业名称不能为空"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "专业名称不能为空");
} }
@ -168,7 +168,7 @@ public class SchoolAdminController {
@RequestBody SchoolMajor major, @RequestBody SchoolMajor major,
HttpServletRequest request) { HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireMajorManagement(schoolId);
requireMajor(id, schoolId); requireMajor(id, schoolId);
if (StringUtils.isNotBlank(major.getSchoolFacultyId())) { if (StringUtils.isNotBlank(major.getSchoolFacultyId())) {
requireFaculty(major.getSchoolFacultyId(), schoolId); requireFaculty(major.getSchoolFacultyId(), schoolId);
@ -182,7 +182,7 @@ public class SchoolAdminController {
@ApiOperation("学校管理员-删除专业") @ApiOperation("学校管理员-删除专业")
public ResultEntity deleteMajor(@PathVariable String id, HttpServletRequest request) { public ResultEntity deleteMajor(@PathVariable String id, HttpServletRequest request) {
String schoolId = currentSchoolId(request); String schoolId = currentSchoolId(request);
requireAdministrativeOrganization(schoolId); requireMajorManagement(schoolId);
requireMajor(id, schoolId); requireMajor(id, schoolId);
if (hasClassInMajor(id) || hasUserByMajor(id)) { if (hasClassInMajor(id) || hasUserByMajor(id)) {
return new ResultEntity<>(HttpStatus.ACCEPTED, "专业下存在班级或用户,不能删除"); return new ResultEntity<>(HttpStatus.ACCEPTED, "专业下存在班级或用户,不能删除");
@ -425,6 +425,14 @@ public class SchoolAdminController {
schoolProductConfigService.requireAdminClassEnabled(schoolId); schoolProductConfigService.requireAdminClassEnabled(schoolId);
} }
private void requireFacultyManagement(String schoolId) {
schoolProductConfigService.requireFacultyManagementEnabled(schoolId);
}
private void requireMajorManagement(String schoolId) {
schoolProductConfigService.requireMajorManagementEnabled(schoolId);
}
private ResultEntity writeResult(int count, String success, String fail) { private ResultEntity writeResult(int count, String success, String fail) {
if (count > 0) { if (count > 0) {
return new ResultEntity<>(HttpStatus.OK, success); return new ResultEntity<>(HttpStatus.OK, success);

@ -164,7 +164,7 @@ public class UserController {
if (school == null) { if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
} }
if (!canManageSchoolStructure(userId, schoolId)) { if (!canManageFaculty(userId, schoolId)) {
return noManagePermission(); return noManagePermission();
} }
//查询该学校下院系下 专业名称是否重复 //查询该学校下院系下 专业名称是否重复
@ -220,7 +220,7 @@ public class UserController {
if (schoolFaculty == null) { if (schoolFaculty == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在");
} }
if (!canManageSchoolStructure(userId, schoolFaculty.getSchoolId())) { if (!canManageFaculty(userId, schoolFaculty.getSchoolId())) {
return noManagePermission(); return noManagePermission();
} }
if (hasMajorUnderFaculty(schoolFacultyId)) { if (hasMajorUnderFaculty(schoolFacultyId)) {
@ -244,7 +244,7 @@ public class UserController {
if (existing == null) { if (existing == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "院系不存在");
} }
if (!canManageSchoolStructure(userId, existing.getSchoolId())) { if (!canManageFaculty(userId, existing.getSchoolId())) {
return noManagePermission(); return noManagePermission();
} }
int i = schoolFacultyMapper.updateByPrimaryKey(schoolFaculty); int i = schoolFacultyMapper.updateByPrimaryKey(schoolFaculty);
@ -272,7 +272,7 @@ public class UserController {
if (school == null) { if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
} }
if (!canManageSchoolStructure(userId, schoolId)) { if (!canManageMajorStructure(userId, schoolId)) {
return noManagePermission(); return noManagePermission();
} }
//再根据schoolFacultyId查询 如果不存在则返回 //再根据schoolFacultyId查询 如果不存在则返回
@ -374,8 +374,8 @@ public class UserController {
@ApiOperation("班级管理-添加班级") @ApiOperation("班级管理-添加班级")
@AnonymousAccess @AnonymousAccess
public ResultEntity addSchoolClass(@ApiParam("学校ID") @RequestParam String schoolId, public ResultEntity addSchoolClass(@ApiParam("学校ID") @RequestParam String schoolId,
@ApiParam("院系ID") @RequestParam String schoolFacultyId, @ApiParam("院系ID") @RequestParam(required = false) String schoolFacultyId,
@ApiParam("专业ID") @RequestParam String schoolMajorId, @ApiParam("专业ID") @RequestParam(required = false) String schoolMajorId,
@ApiParam("班级名称") @RequestParam String className, @ApiParam("班级名称") @RequestParam String className,
@RequestParam(required = false) String userId, @RequestParam(required = false) String userId,
@RequestParam(required = false) String classType, @RequestParam(required = false) String classType,
@ -386,18 +386,22 @@ public class UserController {
if (school == null) { if (school == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该学校不存在");
} }
//再根据schoolFacultyId查询 如果不存在则返回 String requestedClassType = StringUtils.defaultIfBlank(classType, StringUtils.isBlank(userId) ? "ADMIN" : "TEACHING");
SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId); boolean majorManagementEnabled = isMajorManagementEnabled(schoolId);
if (schoolFaculty == null) { if (!isAdminClassManagementEnabled(schoolId) && !"TEACHING".equals(requestedClassType)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该院系不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "当前学校只支持教学班");
} }
//再根据schoolMajorId查询 如果不存在则返回 if (majorManagementEnabled) {
SchoolMajor schoolMajor = schoolMajorMapper.selectByPrimaryKey(schoolMajorId); SchoolFaculty schoolFaculty = schoolFacultyMapper.selectByPrimaryKey(schoolFacultyId);
if (schoolMajor == null) { if (schoolFaculty == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该专业不存在"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该院系不存在");
}
SchoolMajor schoolMajor = schoolMajorMapper.selectByPrimaryKey(schoolMajorId);
if (schoolMajor == null) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该专业不存在");
}
} }
//查询班级名称是否存在 //查询班级名称是否存在
String requestedClassType = StringUtils.defaultIfBlank(classType, StringUtils.isBlank(userId) ? "ADMIN" : "TEACHING");
if (!canCreateSchoolClass(userId, schoolId, requestedClassType)) { if (!canCreateSchoolClass(userId, schoolId, requestedClassType)) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "No permission to add this class type"); return new ResultEntity<>(HttpStatus.BAD_REQUEST, "No permission to add this class type");
} }
@ -2016,7 +2020,7 @@ public class UserController {
} }
Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId); Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId);
if (isPlatformAdmin(operator)) { if (isPlatformAdmin(operator)) {
return true; return !"ADMIN".equals(classType) || isAdminClassManagementEnabled(schoolId);
} }
if (!Integer.valueOf(3).equals(operator == null ? null : operator.getRole()) if (!Integer.valueOf(3).equals(operator == null ? null : operator.getRole())
|| !StringUtils.equals(operator.getSchoolId(), schoolId)) { || !StringUtils.equals(operator.getSchoolId(), schoolId)) {
@ -2026,7 +2030,7 @@ public class UserController {
return true; return true;
} }
if ("ADMIN".equals(classType)) { if ("ADMIN".equals(classType)) {
return true; return isAdminClassManagementEnabled(schoolId);
} }
return false; return false;
} }
@ -2048,10 +2052,11 @@ public class UserController {
return false; return false;
} }
if (isPlatformAdmin(operator)) { if (isPlatformAdmin(operator)) {
return true; return isAdminClassManagementEnabled(schoolClass.getSchoolId());
} }
return isSchoolTeacher(operator) return isSchoolTeacher(operator)
&& StringUtils.equals(operator.getSchoolId(), schoolClass.getSchoolId()); && StringUtils.equals(operator.getSchoolId(), schoolClass.getSchoolId())
&& isAdminClassManagementEnabled(schoolClass.getSchoolId());
} }
private boolean canManageSchoolStructure(String operatorId, String schoolId) { private boolean canManageSchoolStructure(String operatorId, String schoolId) {
@ -2062,7 +2067,43 @@ public class UserController {
if (isPlatformAdmin(operator)) { if (isPlatformAdmin(operator)) {
return true; return true;
} }
return isTeacherAdmin(operator) && StringUtils.equals(operator.getSchoolId(), schoolId); return isTeacherAdmin(operator)
&& StringUtils.equals(operator.getSchoolId(), schoolId)
&& !isTeacherRosterMode(schoolId);
}
private boolean canManageFaculty(String operatorId, String schoolId) {
return hasSchoolStructureAuthority(operatorId, schoolId) && isFacultyManagementEnabled(schoolId);
}
private boolean canManageMajorStructure(String operatorId, String schoolId) {
return hasSchoolStructureAuthority(operatorId, schoolId) && isMajorManagementEnabled(schoolId);
}
private boolean hasSchoolStructureAuthority(String operatorId, String schoolId) {
if (StringUtils.isAnyBlank(operatorId, schoolId)) {
return false;
}
Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId);
return isPlatformAdmin(operator)
|| (isTeacherAdmin(operator) && StringUtils.equals(operator.getSchoolId(), schoolId));
}
private boolean isFacultyManagementEnabled(String schoolId) {
return schoolProductConfigService != null && schoolProductConfigService.isFacultyManagementEnabled(schoolId);
}
private boolean isMajorManagementEnabled(String schoolId) {
return schoolProductConfigService != null && schoolProductConfigService.isMajorManagementEnabled(schoolId);
}
private boolean isAdminClassManagementEnabled(String schoolId) {
return schoolProductConfigService != null && schoolProductConfigService.isAdminClassManagementEnabled(schoolId);
}
private boolean isTeacherRosterMode(String schoolId) {
return schoolProductConfigService != null
&& schoolProductConfigService.isTeacherRosterManaged(schoolId);
} }
private boolean canManageMajor(String operatorId, String schoolMajorId) { private boolean canManageMajor(String operatorId, String schoolMajorId) {
@ -2074,7 +2115,7 @@ public class UserController {
return false; return false;
} }
SchoolFaculty faculty = schoolFacultyMapper.selectByPrimaryKey(major.getSchoolFacultyId()); SchoolFaculty faculty = schoolFacultyMapper.selectByPrimaryKey(major.getSchoolFacultyId());
return faculty != null && canManageSchoolStructure(operatorId, faculty.getSchoolId()); return faculty != null && canManageMajorStructure(operatorId, faculty.getSchoolId());
} }
private boolean teacherHasCreatedClass(String teacherId) { private boolean teacherHasCreatedClass(String teacherId) {

@ -6,6 +6,9 @@ public class SchoolProductConfig {
private String schoolId; private String schoolId;
private String organizationMode; private String organizationMode;
private String studentRosterOwner; private String studentRosterOwner;
private Boolean facultyManagementEnabled;
private Boolean majorManagementEnabled;
private Boolean adminClassManagementEnabled;
private Date createTime; private Date createTime;
private Date updateTime; private Date updateTime;
@ -15,6 +18,12 @@ public class SchoolProductConfig {
public void setOrganizationMode(String organizationMode) { this.organizationMode = organizationMode == null ? null : organizationMode.trim(); } public void setOrganizationMode(String organizationMode) { this.organizationMode = organizationMode == null ? null : organizationMode.trim(); }
public String getStudentRosterOwner() { return studentRosterOwner; } public String getStudentRosterOwner() { return studentRosterOwner; }
public void setStudentRosterOwner(String studentRosterOwner) { this.studentRosterOwner = studentRosterOwner == null ? null : studentRosterOwner.trim(); } public void setStudentRosterOwner(String studentRosterOwner) { this.studentRosterOwner = studentRosterOwner == null ? null : studentRosterOwner.trim(); }
public Boolean getFacultyManagementEnabled() { return facultyManagementEnabled; }
public void setFacultyManagementEnabled(Boolean facultyManagementEnabled) { this.facultyManagementEnabled = facultyManagementEnabled; }
public Boolean getMajorManagementEnabled() { return majorManagementEnabled; }
public void setMajorManagementEnabled(Boolean majorManagementEnabled) { this.majorManagementEnabled = majorManagementEnabled; }
public Boolean getAdminClassManagementEnabled() { return adminClassManagementEnabled; }
public void setAdminClassManagementEnabled(Boolean adminClassManagementEnabled) { this.adminClassManagementEnabled = adminClassManagementEnabled; }
public Date getCreateTime() { return createTime; } public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; }
public Date getUpdateTime() { return updateTime; } public Date getUpdateTime() { return updateTime; }

@ -11,6 +11,16 @@ public interface SchoolProductConfigService {
boolean requiresAdminClass(String schoolId); boolean requiresAdminClass(String schoolId);
boolean isFacultyManagementEnabled(String schoolId);
boolean isMajorManagementEnabled(String schoolId);
boolean isAdminClassManagementEnabled(String schoolId);
void requireFacultyManagementEnabled(String schoolId);
void requireMajorManagementEnabled(String schoolId);
boolean isTeacherRosterManaged(String schoolId); boolean isTeacherRosterManaged(String schoolId);
void requireAdminClassEnabled(String schoolId); void requireAdminClassEnabled(String schoolId);

@ -1,12 +1,8 @@
package com.sztzjy.linkCommerce.service.impl; package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException; import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.entity.SchoolClassExample;
import com.sztzjy.linkCommerce.entity.SchoolProductConfig; import com.sztzjy.linkCommerce.entity.SchoolProductConfig;
import com.sztzjy.linkCommerce.entity.UserinfoExample;
import com.sztzjy.linkCommerce.mapper.SchoolClassMapper;
import com.sztzjy.linkCommerce.mapper.SchoolProductConfigMapper; import com.sztzjy.linkCommerce.mapper.SchoolProductConfigMapper;
import com.sztzjy.linkCommerce.mapper.UserinfoMapper;
import com.sztzjy.linkCommerce.service.SchoolProductConfigService; import com.sztzjy.linkCommerce.service.SchoolProductConfigService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,18 +15,13 @@ import java.util.Date;
public class SchoolProductConfigServiceImpl implements SchoolProductConfigService { public class SchoolProductConfigServiceImpl implements SchoolProductConfigService {
public static final String ADMIN_CLASS_ENABLED = "ADMIN_CLASS_ENABLED"; public static final String ADMIN_CLASS_ENABLED = "ADMIN_CLASS_ENABLED";
public static final String TEACHING_CLASS_ONLY = "TEACHING_CLASS_ONLY"; public static final String TEACHING_CLASS_ONLY = "TEACHING_CLASS_ONLY";
public static final String CUSTOM = "CUSTOM";
public static final String SCHOOL_ADMIN = "SCHOOL_ADMIN"; public static final String SCHOOL_ADMIN = "SCHOOL_ADMIN";
public static final String TEACHER = "TEACHER"; public static final String TEACHER = "TEACHER";
@Autowired @Autowired
public SchoolProductConfigMapper schoolProductConfigMapper; public SchoolProductConfigMapper schoolProductConfigMapper;
@Autowired
public SchoolClassMapper schoolClassMapper;
@Autowired
public UserinfoMapper userinfoMapper;
@Override @Override
public void createDefaultConfig(String schoolId) { public void createDefaultConfig(String schoolId) {
if (StringUtils.isBlank(schoolId)) { if (StringUtils.isBlank(schoolId)) {
@ -40,6 +31,9 @@ public class SchoolProductConfigServiceImpl implements SchoolProductConfigServic
config.setSchoolId(schoolId); config.setSchoolId(schoolId);
config.setOrganizationMode(ADMIN_CLASS_ENABLED); config.setOrganizationMode(ADMIN_CLASS_ENABLED);
config.setStudentRosterOwner(SCHOOL_ADMIN); config.setStudentRosterOwner(SCHOOL_ADMIN);
config.setFacultyManagementEnabled(true);
config.setMajorManagementEnabled(true);
config.setAdminClassManagementEnabled(true);
config.setCreateTime(new Date()); config.setCreateTime(new Date());
config.setUpdateTime(new Date()); config.setUpdateTime(new Date());
schoolProductConfigMapper.insert(config); schoolProductConfigMapper.insert(config);
@ -50,16 +44,8 @@ public class SchoolProductConfigServiceImpl implements SchoolProductConfigServic
if (config == null || StringUtils.isBlank(config.getSchoolId())) { if (config == null || StringUtils.isBlank(config.getSchoolId())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "学校组织配置不存在"); throw new ServiceException(HttpStatus.BAD_REQUEST, "学校组织配置不存在");
} }
boolean standard = ADMIN_CLASS_ENABLED.equals(config.getOrganizationMode()) && SCHOOL_ADMIN.equals(config.getStudentRosterOwner());
boolean teacherManaged = TEACHING_CLASS_ONLY.equals(config.getOrganizationMode()) && TEACHER.equals(config.getStudentRosterOwner());
if (!standard && !teacherManaged) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "学校组织模式与名单维护方不匹配");
}
SchoolProductConfig current = getRequiredConfig(config.getSchoolId()); SchoolProductConfig current = getRequiredConfig(config.getSchoolId());
if (!StringUtils.equals(current.getOrganizationMode(), config.getOrganizationMode()) normalizeManagementCapabilities(config);
&& hasAdministrativeOrganizationData(config.getSchoolId())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "学校已有组织数据,不能直接切换组织模式");
}
config.setCreateTime(current.getCreateTime()); config.setCreateTime(current.getCreateTime());
config.setUpdateTime(new Date()); config.setUpdateTime(new Date());
schoolProductConfigMapper.updateByPrimaryKey(config); schoolProductConfigMapper.updateByPrimaryKey(config);
@ -80,7 +66,36 @@ public class SchoolProductConfigServiceImpl implements SchoolProductConfigServic
@Override @Override
public boolean requiresAdminClass(String schoolId) { public boolean requiresAdminClass(String schoolId) {
return ADMIN_CLASS_ENABLED.equals(getRequiredConfig(schoolId).getOrganizationMode()); return isAdminClassManagementEnabled(schoolId);
}
@Override
public boolean isFacultyManagementEnabled(String schoolId) {
return Boolean.TRUE.equals(getRequiredConfig(schoolId).getFacultyManagementEnabled());
}
@Override
public boolean isMajorManagementEnabled(String schoolId) {
return Boolean.TRUE.equals(getRequiredConfig(schoolId).getMajorManagementEnabled());
}
@Override
public boolean isAdminClassManagementEnabled(String schoolId) {
return Boolean.TRUE.equals(getRequiredConfig(schoolId).getAdminClassManagementEnabled());
}
@Override
public void requireFacultyManagementEnabled(String schoolId) {
if (!isFacultyManagementEnabled(schoolId)) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "当前学校未启用院系管理");
}
}
@Override
public void requireMajorManagementEnabled(String schoolId) {
if (!isMajorManagementEnabled(schoolId)) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "当前学校未启用专业管理");
}
} }
@Override @Override
@ -95,18 +110,23 @@ public class SchoolProductConfigServiceImpl implements SchoolProductConfigServic
} }
} }
private boolean hasAdministrativeOrganizationData(String schoolId) { private void normalizeManagementCapabilities(SchoolProductConfig config) {
SchoolClassExample classExample = new SchoolClassExample(); boolean defaultEnabled = ADMIN_CLASS_ENABLED.equals(config.getOrganizationMode());
classExample.createCriteria() boolean facultyEnabled = config.getFacultyManagementEnabled() == null ? defaultEnabled : config.getFacultyManagementEnabled();
.andSchoolIdEqualTo(schoolId) boolean majorEnabled = facultyEnabled && (config.getMajorManagementEnabled() == null ? defaultEnabled : config.getMajorManagementEnabled());
.andClassTypeEqualTo("ADMIN"); boolean adminClassEnabled = majorEnabled && (config.getAdminClassManagementEnabled() == null ? defaultEnabled : config.getAdminClassManagementEnabled());
if (schoolClassMapper.countByExample(classExample) > 0) { config.setFacultyManagementEnabled(facultyEnabled);
return true; config.setMajorManagementEnabled(majorEnabled);
config.setAdminClassManagementEnabled(adminClassEnabled);
if (facultyEnabled && majorEnabled && adminClassEnabled) {
config.setOrganizationMode(ADMIN_CLASS_ENABLED);
config.setStudentRosterOwner(SCHOOL_ADMIN);
} else if (!facultyEnabled && !majorEnabled && !adminClassEnabled) {
config.setOrganizationMode(TEACHING_CLASS_ONLY);
config.setStudentRosterOwner(TEACHER);
} else {
config.setOrganizationMode(CUSTOM);
config.setStudentRosterOwner(TEACHER);
} }
UserinfoExample userExample = new UserinfoExample();
userExample.createCriteria()
.andSchoolIdEqualTo(schoolId)
.andSchoolClassIdIsNotNull();
return userinfoMapper.countByExample(userExample) > 0;
} }
} }

@ -54,7 +54,14 @@ public class UserInfoServiceImpl implements UserInfoService {
Userinfo userinfo = userInfoMapper.selectByPrimaryKey(userId); Userinfo userinfo = userInfoMapper.selectByPrimaryKey(userId);
String schoolMajorId = userinfo.getSchoolMajorId(); String schoolMajorId = userinfo.getSchoolMajorId();
SchoolClassExample schoolClassExample = new SchoolClassExample(); SchoolClassExample schoolClassExample = new SchoolClassExample();
schoolClassExample.createCriteria().andSchoolMajorIdEqualTo(schoolMajorId); SchoolClassExample.Criteria criteria = schoolClassExample.createCriteria();
if (StringUtils.hasText(schoolMajorId)) {
criteria.andSchoolMajorIdEqualTo(schoolMajorId);
} else {
criteria.andSchoolIdEqualTo(userinfo.getSchoolId())
.andClassTypeEqualTo("TEACHING")
.andCreatedByEqualTo(userId);
}
List<SchoolClass> schoolClasses = schoolClassMapper.selectByExample(schoolClassExample); List<SchoolClass> schoolClasses = schoolClassMapper.selectByExample(schoolClassExample);
List<String> list=new ArrayList<>(); List<String> list=new ArrayList<>();
for (int i = 0; i < schoolClasses.size(); i++) { for (int i = 0; i < schoolClasses.size(); i++) {

@ -5,18 +5,21 @@
<id column="school_id" property="schoolId" jdbcType="VARCHAR"/> <id column="school_id" property="schoolId" jdbcType="VARCHAR"/>
<result column="organization_mode" property="organizationMode" jdbcType="VARCHAR"/> <result column="organization_mode" property="organizationMode" jdbcType="VARCHAR"/>
<result column="student_roster_owner" property="studentRosterOwner" jdbcType="VARCHAR"/> <result column="student_roster_owner" property="studentRosterOwner" jdbcType="VARCHAR"/>
<result column="faculty_management_enabled" property="facultyManagementEnabled" jdbcType="BIT"/>
<result column="major_management_enabled" property="majorManagementEnabled" jdbcType="BIT"/>
<result column="admin_class_management_enabled" property="adminClassManagementEnabled" jdbcType="BIT"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/> <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/> <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
</resultMap> </resultMap>
<sql id="Columns">school_id, organization_mode, student_roster_owner, create_time, update_time</sql> <sql id="Columns">school_id, organization_mode, student_roster_owner, faculty_management_enabled, major_management_enabled, admin_class_management_enabled, create_time, update_time</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap"> <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select <include refid="Columns"/> from school_product_config where school_id = #{schoolId,jdbcType=VARCHAR} select <include refid="Columns"/> from school_product_config where school_id = #{schoolId,jdbcType=VARCHAR}
</select> </select>
<insert id="insert" parameterType="com.sztzjy.linkCommerce.entity.SchoolProductConfig"> <insert id="insert" parameterType="com.sztzjy.linkCommerce.entity.SchoolProductConfig">
insert into school_product_config (school_id, organization_mode, student_roster_owner, create_time, update_time) insert into school_product_config (school_id, organization_mode, student_roster_owner, faculty_management_enabled, major_management_enabled, admin_class_management_enabled, create_time, update_time)
values (#{schoolId,jdbcType=VARCHAR}, #{organizationMode,jdbcType=VARCHAR}, #{studentRosterOwner,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}) values (#{schoolId,jdbcType=VARCHAR}, #{organizationMode,jdbcType=VARCHAR}, #{studentRosterOwner,jdbcType=VARCHAR}, #{facultyManagementEnabled,jdbcType=BIT}, #{majorManagementEnabled,jdbcType=BIT}, #{adminClassManagementEnabled,jdbcType=BIT}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
</insert> </insert>
<update id="updateByPrimaryKey" parameterType="com.sztzjy.linkCommerce.entity.SchoolProductConfig"> <update id="updateByPrimaryKey" parameterType="com.sztzjy.linkCommerce.entity.SchoolProductConfig">
update school_product_config set organization_mode = #{organizationMode,jdbcType=VARCHAR}, student_roster_owner = #{studentRosterOwner,jdbcType=VARCHAR}, update_time = #{updateTime,jdbcType=TIMESTAMP} where school_id = #{schoolId,jdbcType=VARCHAR} update school_product_config set organization_mode = #{organizationMode,jdbcType=VARCHAR}, student_roster_owner = #{studentRosterOwner,jdbcType=VARCHAR}, faculty_management_enabled = #{facultyManagementEnabled,jdbcType=BIT}, major_management_enabled = #{majorManagementEnabled,jdbcType=BIT}, admin_class_management_enabled = #{adminClassManagementEnabled,jdbcType=BIT}, update_time = #{updateTime,jdbcType=TIMESTAMP} where school_id = #{schoolId,jdbcType=VARCHAR}
</update> </update>
</mapper> </mapper>

@ -33,4 +33,17 @@ class SchoolAdminControllerTest {
verify(configService).requireAdminClassEnabled("school-zj"); verify(configService).requireAdminClassEnabled("school-zj");
} }
@Test
void facultyAndMajorGuardsDelegateToTheirOwnConfigurationSwitches() {
SchoolAdminController controller = new SchoolAdminController();
SchoolProductConfigService configService = mock(SchoolProductConfigService.class);
ReflectionTestUtils.setField(controller, "schoolProductConfigService", configService);
ReflectionTestUtils.invokeMethod(controller, "requireFacultyManagement", "school-zj");
ReflectionTestUtils.invokeMethod(controller, "requireMajorManagement", "school-zj");
verify(configService).requireFacultyManagementEnabled("school-zj");
verify(configService).requireMajorManagementEnabled("school-zj");
}
} }

@ -14,6 +14,7 @@ import com.sztzjy.linkCommerce.mapper.SchoolMajorMapper;
import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper;
import com.sztzjy.linkCommerce.mapper.UserinfoMapper; import com.sztzjy.linkCommerce.mapper.UserinfoMapper;
import com.sztzjy.linkCommerce.service.UserInfoService; import com.sztzjy.linkCommerce.service.UserInfoService;
import com.sztzjy.linkCommerce.service.SchoolProductConfigService;
import com.sztzjy.linkCommerce.entity.importDto.SchoolAdminStudentImportDTO; import com.sztzjy.linkCommerce.entity.importDto.SchoolAdminStudentImportDTO;
import com.sztzjy.linkCommerce.entity.importDto.TeachingClassStudentImportDTO; import com.sztzjy.linkCommerce.entity.importDto.TeachingClassStudentImportDTO;
import com.sztzjy.linkCommerce.util.Pinyin4jUtil; import com.sztzjy.linkCommerce.util.Pinyin4jUtil;
@ -80,6 +81,18 @@ class UserControllerTeacherAdminTest {
verify(controller.schoolFacultyMapper).insert(any(SchoolFaculty.class)); verify(controller.schoolFacultyMapper).insert(any(SchoolFaculty.class));
} }
@Test
void teacherAdminCannotAddFacultyWhenFacultyManagementSwitchIsOff() {
UserController controller = controllerWithCommonMocks();
when(controller.userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(teacher("teacher-admin", true));
when(controller.schoolProductConfigService.isFacultyManagementEnabled("school-1")).thenReturn(false);
ResultEntity result = controller.addSchoolFaculty("school-1", "faculty", null, null, null, "teacher-admin");
assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
verify(controller.schoolFacultyMapper, never()).insert(any(SchoolFaculty.class));
}
@Test @Test
void ordinaryTeacherCannotAddMajor() { void ordinaryTeacherCannotAddMajor() {
UserController controller = controllerWithCommonMocks(); UserController controller = controllerWithCommonMocks();
@ -123,6 +136,24 @@ class UserControllerTeacherAdminTest {
assertEquals("LOCAL", captor.getValue().getDataSource()); assertEquals("LOCAL", captor.getValue().getDataSource());
} }
@Test
void teacherRosterSchoolCreatesTeachingClassWithoutFacultyOrMajor() {
UserController controller = controllerWithCommonMocks();
controller.schoolProductConfigService = mock(SchoolProductConfigService.class);
when(controller.schoolProductConfigService.isTeacherRosterManaged("school-1")).thenReturn(true);
when(controller.schoolClassMapper.selectByExample(any())).thenReturn(Collections.emptyList());
when(controller.schoolClassMapper.insert(any(SchoolClass.class))).thenReturn(1);
when(controller.pinyin4jUtil.convertToPinyin(any())).thenReturn("py");
ResultEntity result = controller.addSchoolClass("school-1", null, null, "teaching-class",
"teacher-1", "TEACHING", null);
assertEquals(HttpStatus.OK, result.getStatusCode());
verify(controller.schoolClassMapper).insert(argThat(schoolClass ->
"TEACHING".equals(schoolClass.getClassType())
&& schoolClass.getSchoolMajorId() == null));
}
@Test @Test
void ordinaryTeacherCanAddAdminClassWithinOwnSchool() { void ordinaryTeacherCanAddAdminClassWithinOwnSchool() {
UserController controller = controllerWithCommonMocks(); UserController controller = controllerWithCommonMocks();
@ -943,6 +974,7 @@ class UserControllerTeacherAdminTest {
controller.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class); controller.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class);
controller.userinfoMapper = mock(UserinfoMapper.class); controller.userinfoMapper = mock(UserinfoMapper.class);
controller.userInfoService = mock(UserInfoService.class); controller.userInfoService = mock(UserInfoService.class);
controller.schoolProductConfigService = mock(SchoolProductConfigService.class);
controller.pinyin4jUtil = mock(Pinyin4jUtil.class); controller.pinyin4jUtil = mock(Pinyin4jUtil.class);
controller.cptfController = mock(CptfController.class); controller.cptfController = mock(CptfController.class);
@ -961,6 +993,9 @@ class UserControllerTeacherAdminTest {
when(controller.schoolMajorMapper.selectByPrimaryKey("major-1")).thenReturn(major); when(controller.schoolMajorMapper.selectByPrimaryKey("major-1")).thenReturn(major);
when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1")); when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1"));
when(controller.userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(teacher("teacher-admin", true)); when(controller.userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(teacher("teacher-admin", true));
when(controller.schoolProductConfigService.isFacultyManagementEnabled("school-1")).thenReturn(true);
when(controller.schoolProductConfigService.isMajorManagementEnabled("school-1")).thenReturn(true);
when(controller.schoolProductConfigService.isAdminClassManagementEnabled("school-1")).thenReturn(true);
return controller; return controller;
} }

@ -68,29 +68,37 @@ class SchoolProductConfigServiceImplTest {
verify(service.schoolProductConfigMapper).insert(org.mockito.ArgumentMatchers.argThat(config -> verify(service.schoolProductConfigMapper).insert(org.mockito.ArgumentMatchers.argThat(config ->
"school-new".equals(config.getSchoolId()) "school-new".equals(config.getSchoolId())
&& "ADMIN_CLASS_ENABLED".equals(config.getOrganizationMode()) && "ADMIN_CLASS_ENABLED".equals(config.getOrganizationMode())
&& "SCHOOL_ADMIN".equals(config.getStudentRosterOwner()))); && "SCHOOL_ADMIN".equals(config.getStudentRosterOwner())
&& config.getFacultyManagementEnabled()
&& config.getMajorManagementEnabled()
&& config.getAdminClassManagementEnabled()));
} }
@Test @Test
void updateRejectsOrganizationModeChangeWhenAdministrativeDataExists() { void disablingFacultyManagementCascadesToMajorAndAdministrativeClassWithoutDeletingData() {
SchoolProductConfigServiceImpl service = new SchoolProductConfigServiceImpl(); SchoolProductConfigServiceImpl service = new SchoolProductConfigServiceImpl();
service.schoolProductConfigMapper = mock(SchoolProductConfigMapper.class); service.schoolProductConfigMapper = mock(SchoolProductConfigMapper.class);
service.schoolClassMapper = mock(SchoolClassMapper.class);
service.userinfoMapper = mock(UserinfoMapper.class);
SchoolProductConfig current = config("school-standard", "ADMIN_CLASS_ENABLED", "SCHOOL_ADMIN"); SchoolProductConfig current = config("school-standard", "ADMIN_CLASS_ENABLED", "SCHOOL_ADMIN");
when(service.schoolProductConfigMapper.selectByPrimaryKey("school-standard")).thenReturn(current); when(service.schoolProductConfigMapper.selectByPrimaryKey("school-standard")).thenReturn(current);
when(service.schoolClassMapper.countByExample(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
assertThrows(ServiceException.class, () -> service.updateConfig( SchoolProductConfig requested = config("school-standard", "CUSTOM", "TEACHER");
config("school-standard", "TEACHING_CLASS_ONLY", "TEACHER"))); requested.setFacultyManagementEnabled(false);
requested.setMajorManagementEnabled(true);
requested.setAdminClassManagementEnabled(true);
service.updateConfig(requested);
verify(service.schoolProductConfigMapper).updateByPrimaryKey(org.mockito.ArgumentMatchers.argThat(updated ->
!updated.getFacultyManagementEnabled()
&& !updated.getMajorManagementEnabled()
&& !updated.getAdminClassManagementEnabled()
&& "TEACHING_CLASS_ONLY".equals(updated.getOrganizationMode())));
} }
@Test @Test
void updateKeepsTheOriginalCreationTime() { void updateKeepsTheOriginalCreationTime() {
SchoolProductConfigServiceImpl service = new SchoolProductConfigServiceImpl(); SchoolProductConfigServiceImpl service = new SchoolProductConfigServiceImpl();
service.schoolProductConfigMapper = mock(SchoolProductConfigMapper.class); service.schoolProductConfigMapper = mock(SchoolProductConfigMapper.class);
service.schoolClassMapper = mock(SchoolClassMapper.class);
service.userinfoMapper = mock(UserinfoMapper.class);
SchoolProductConfig current = config("school-standard", "ADMIN_CLASS_ENABLED", "SCHOOL_ADMIN"); SchoolProductConfig current = config("school-standard", "ADMIN_CLASS_ENABLED", "SCHOOL_ADMIN");
Date createdAt = new Date(1000L); Date createdAt = new Date(1000L);
current.setCreateTime(createdAt); current.setCreateTime(createdAt);
@ -107,6 +115,9 @@ class SchoolProductConfigServiceImplTest {
config.setSchoolId(schoolId); config.setSchoolId(schoolId);
config.setOrganizationMode(organizationMode); config.setOrganizationMode(organizationMode);
config.setStudentRosterOwner(rosterOwner); config.setStudentRosterOwner(rosterOwner);
config.setFacultyManagementEnabled("ADMIN_CLASS_ENABLED".equals(organizationMode));
config.setMajorManagementEnabled("ADMIN_CLASS_ENABLED".equals(organizationMode));
config.setAdminClassManagementEnabled("ADMIN_CLASS_ENABLED".equals(organizationMode));
return config; return config;
} }
} }

@ -0,0 +1,40 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.entity.SchoolClass;
import com.sztzjy.linkCommerce.entity.Userinfo;
import com.sztzjy.linkCommerce.mapper.SchoolClassMapper;
import com.sztzjy.linkCommerce.mapper.UserinfoMapper;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class UserInfoServiceImplOrganizationModeTest {
@Test
void teacherWithoutMajorSeesOnlyTeachingClassesTheyCreated() {
UserInfoServiceImpl service = new UserInfoServiceImpl();
service.userInfoMapper = mock(UserinfoMapper.class);
service.schoolClassMapper = mock(SchoolClassMapper.class);
Userinfo teacher = new Userinfo();
teacher.setUserId("teacher-zj");
teacher.setSchoolId("school-zj");
teacher.setSchoolMajorId(null);
SchoolClass teachingClass = new SchoolClass();
teachingClass.setClassName("电商实训一班");
when(service.userInfoMapper.selectByPrimaryKey("teacher-zj")).thenReturn(teacher);
when(service.schoolClassMapper.selectByExample(org.mockito.ArgumentMatchers.any()))
.thenReturn(Collections.singletonList(teachingClass));
assertEquals(Collections.singletonList("电商实训一班"), service.getClassNameList("teacher-zj"));
ArgumentCaptor<com.sztzjy.linkCommerce.entity.SchoolClassExample> example = ArgumentCaptor.forClass(com.sztzjy.linkCommerce.entity.SchoolClassExample.class);
verify(service.schoolClassMapper).selectByExample(example.capture());
assertEquals(3, example.getValue().getOredCriteria().get(0).getAllCriteria().size());
}
}
Loading…
Cancel
Save