前端代码
This commit is contained in:
+203
@@ -0,0 +1,203 @@
|
||||
package com.roomroot.jwgl.interceptor;
|
||||
|
||||
import com.roomroot.jwgl.unit.Result;
|
||||
import com.roomroot.jwgl.utils.JwglRoleHelper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import tools.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 按角色限制教务接口访问范围。管理员放行全部。
|
||||
*/
|
||||
@Component
|
||||
public class JwglApiAccessInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final JwglRoleHelper roleHelper;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public JwglApiAccessInterceptor(JwglRoleHelper roleHelper, ObjectMapper objectMapper) {
|
||||
this.roleHelper = roleHelper;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication == null || !authentication.isAuthenticated()
|
||||
|| "anonymousUser".equals(String.valueOf(authentication.getPrincipal()))) {
|
||||
return true;
|
||||
}
|
||||
if (roleHelper.isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
String path = request.getRequestURI();
|
||||
String context = request.getContextPath();
|
||||
if (context != null && !context.isEmpty() && path.startsWith(context)) {
|
||||
path = path.substring(context.length());
|
||||
}
|
||||
if (path.isEmpty()) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
if (roleHelper.isStudent()) {
|
||||
if (isStudentAllowed(path, request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
return deny(response, "学员无权访问该功能");
|
||||
}
|
||||
if (roleHelper.isTeacher()) {
|
||||
if (isTeacherDenied(path)) {
|
||||
return deny(response, "教员无权访问该功能");
|
||||
}
|
||||
if (isTeacherAdjustDenied(path, request.getMethod())) {
|
||||
return deny(response, "教员只能提交、查看和撤销本人的调课申请");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (roleHelper.isResearchOffice()) {
|
||||
if (isOfficeDenied(path)) {
|
||||
return deny(response, "教研室无权访问系统管理功能");
|
||||
}
|
||||
if (isResearchOfficeAdjustDenied(path)) {
|
||||
return deny(response, "教研室仅可查看和审批本室调课申请");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (roleHelper.isDepartmentPersonnel()) {
|
||||
if (isOfficeDenied(path)) {
|
||||
return deny(response, "机关人员无权访问系统管理功能");
|
||||
}
|
||||
if (isOfficeAdjustDenied(path, request.getMethod())) {
|
||||
return deny(response, "机关人员仅可查看和审批调课申请");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isStudentAllowed(String path, String method) {
|
||||
if (startsWithAny(path, "/getInfo", "/getRouters", "/logout", "/system/user/profile")) {
|
||||
return true;
|
||||
}
|
||||
if (!HttpMethod.GET.matches(method)) {
|
||||
return false;
|
||||
}
|
||||
return startsWithAny(path,
|
||||
"/xqxlb",
|
||||
"/kcb",
|
||||
"/studentTeamOutputSchedule",
|
||||
"/classCalendar",
|
||||
"/course-running/plan/list",
|
||||
"/course-running/plan/detail",
|
||||
"/course-running/plan/export",
|
||||
"/student-records/warning-result",
|
||||
"/student-records/get",
|
||||
"/student-records/list",
|
||||
"/student-records/grades",
|
||||
"/student-records/process-grades");
|
||||
}
|
||||
|
||||
private boolean isTeacherAdjustDenied(String path, String method) {
|
||||
if (!path.startsWith("/course-running/adjust")) {
|
||||
return false;
|
||||
}
|
||||
if (path.startsWith("/course-running/adjust/audit")
|
||||
|| path.startsWith("/course-running/adjust/receive")) {
|
||||
return true;
|
||||
}
|
||||
if (path.equals("/course-running/adjust/submit")) {
|
||||
return !HttpMethod.POST.matches(method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isResearchOfficeAdjustDenied(String path) {
|
||||
if (!path.startsWith("/course-running/adjust")) {
|
||||
return false;
|
||||
}
|
||||
if (path.equals("/course-running/adjust/submit")
|
||||
|| path.equals("/course-running/adjust/cancel")
|
||||
|| path.startsWith("/course-running/adjust/lessons")
|
||||
|| path.startsWith("/course-running/adjust/audit/jg")
|
||||
|| path.startsWith("/course-running/adjust/audit/jxx")
|
||||
|| path.startsWith("/course-running/adjust/receive/jg")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isOfficeAdjustDenied(String path, String method) {
|
||||
if (!path.startsWith("/course-running/adjust")) {
|
||||
return false;
|
||||
}
|
||||
if (HttpMethod.GET.matches(method)) {
|
||||
return path.startsWith("/course-running/adjust/lessons")
|
||||
|| path.startsWith("/course-running/adjust/strategy");
|
||||
}
|
||||
return !(path.startsWith("/course-running/adjust/audit/jg")
|
||||
|| path.startsWith("/course-running/adjust/receive/jg"));
|
||||
}
|
||||
|
||||
private boolean isTeacherDenied(String path) {
|
||||
return startsWithAny(path,
|
||||
"/faculty",
|
||||
"/jys",
|
||||
"/elective",
|
||||
"/department",
|
||||
"/department-personnel",
|
||||
"/account-management",
|
||||
"/system-initialization",
|
||||
"/system/user",
|
||||
"/system/role",
|
||||
"/system/menu",
|
||||
"/system/dept",
|
||||
"/system/post",
|
||||
"/monitor",
|
||||
"/tool")
|
||||
&& !path.startsWith("/system/user/profile");
|
||||
}
|
||||
|
||||
private boolean isOfficeDenied(String path) {
|
||||
return startsWithAny(path,
|
||||
"/account-management",
|
||||
"/system-initialization",
|
||||
"/system/user",
|
||||
"/system/role",
|
||||
"/system/menu",
|
||||
"/system/dept",
|
||||
"/system/post",
|
||||
"/monitor",
|
||||
"/tool")
|
||||
&& !path.startsWith("/system/user/profile");
|
||||
}
|
||||
|
||||
private boolean startsWithAny(String path, String... prefixes) {
|
||||
for (String prefix : prefixes) {
|
||||
if (path.equals(prefix) || path.startsWith(prefix + "/") || path.startsWith(prefix + "?")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean deny(HttpServletResponse response, String message) throws IOException {
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.getWriter().write(objectMapper.writeValueAsString(Result.forbidden(message)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.roomroot.jwgl.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.JYSDLB;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
/**
|
||||
* 教研室登录表 Mapper。
|
||||
*/
|
||||
@Mapper
|
||||
public interface JYSDLBMapper extends BaseMapper<JYSDLB> {
|
||||
|
||||
@Select("SELECT TRIM(b.\"教研室代号\") FROM \"教研室登录表\" b "
|
||||
+ "JOIN \"登录信息表\" a ON TRIM(a.\"编号\") = TRIM(b.\"登录信息编号\") "
|
||||
+ "WHERE TRIM(a.\"账号\") = #{username}")
|
||||
String selectResearchOfficeIdByAccount(@Param("username") String username);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.roomroot.jwgl.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.roomroot.common.constant.Constants;
|
||||
import com.roomroot.common.core.domain.entity.SysRole;
|
||||
import com.roomroot.common.core.domain.entity.SysUser;
|
||||
import com.roomroot.common.core.domain.model.LoginUser;
|
||||
import com.roomroot.common.exception.ServiceException;
|
||||
import com.roomroot.common.utils.SecurityUtils;
|
||||
import com.roomroot.common.utils.StringUtils;
|
||||
import com.roomroot.jwgl.entity.JYB;
|
||||
import com.roomroot.jwgl.entity.XYXX;
|
||||
import com.roomroot.jwgl.mapper.JYBMapper;
|
||||
import com.roomroot.jwgl.mapper.JYSDLBMapper;
|
||||
import com.roomroot.jwgl.mapper.XYXXMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.roomroot.jwgl.utils.AccountManagementConstants.ROLE_DEPARTMENT_PERSONNEL;
|
||||
import static com.roomroot.jwgl.utils.AccountManagementConstants.ROLE_RESEARCH_OFFICE;
|
||||
import static com.roomroot.jwgl.utils.AccountManagementConstants.ROLE_STUDENT;
|
||||
import static com.roomroot.jwgl.utils.AccountManagementConstants.ROLE_TEACHER;
|
||||
import static com.roomroot.jwgl.utils.BasicManagementConstants.FORBIDDEN;
|
||||
|
||||
/**
|
||||
* 教务角色识别与本人数据范围。
|
||||
* <p>管理员、机关人员(教务部)看全部;教员看本人;学员看本人。</p>
|
||||
*/
|
||||
@Component
|
||||
public class JwglRoleHelper {
|
||||
|
||||
@Resource
|
||||
private JYBMapper jybMapper;
|
||||
|
||||
@Resource
|
||||
private XYXXMapper xyxxMapper;
|
||||
|
||||
@Resource
|
||||
private JYSDLBMapper jysdlbMapper;
|
||||
|
||||
public boolean isAdmin() {
|
||||
try {
|
||||
if (SecurityUtils.isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return hasRoleKey(Constants.SUPER_ADMIN);
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDepartmentPersonnel() {
|
||||
return isAdmin() || hasRoleKey(ROLE_DEPARTMENT_PERSONNEL);
|
||||
}
|
||||
|
||||
public boolean isResearchOffice() {
|
||||
if (isDepartmentPersonnel()) {
|
||||
return false;
|
||||
}
|
||||
if (hasRoleKey(ROLE_RESEARCH_OFFICE)) {
|
||||
return true;
|
||||
}
|
||||
if (hasRoleKey(ROLE_TEACHER)) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.isNotEmpty(findResearchOfficeId());
|
||||
}
|
||||
|
||||
public boolean isTeacher() {
|
||||
return !isDepartmentPersonnel() && !isResearchOffice() && hasRoleKey(ROLE_TEACHER);
|
||||
}
|
||||
|
||||
public boolean isStudent() {
|
||||
return !isDepartmentPersonnel() && !hasRoleKey(ROLE_TEACHER) && hasRoleKey(ROLE_STUDENT);
|
||||
}
|
||||
|
||||
public String requireTeacherId() {
|
||||
String teacherId = findTeacherId();
|
||||
if (StringUtils.isEmpty(teacherId)) {
|
||||
throw new ServiceException("当前登录用户不是教员,无法查看教员数据", FORBIDDEN);
|
||||
}
|
||||
return teacherId;
|
||||
}
|
||||
|
||||
public String requireResearchOfficeId() {
|
||||
String officeId = findResearchOfficeId();
|
||||
if (StringUtils.isEmpty(officeId)) {
|
||||
throw new ServiceException("当前登录用户不是教研室账号,无法审批本室申请", FORBIDDEN);
|
||||
}
|
||||
return officeId;
|
||||
}
|
||||
|
||||
public String findResearchOfficeId() {
|
||||
try {
|
||||
String username = SecurityUtils.getUsername();
|
||||
if (StringUtils.isEmpty(username) || jysdlbMapper == null) {
|
||||
return null;
|
||||
}
|
||||
return jysdlbMapper.selectResearchOfficeIdByAccount(username);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String requireStudentId() {
|
||||
String studentId = findStudentId();
|
||||
if (StringUtils.isEmpty(studentId)) {
|
||||
throw new ServiceException("当前登录用户不是学员,无法查看学员数据", FORBIDDEN);
|
||||
}
|
||||
return studentId;
|
||||
}
|
||||
|
||||
public String findTeacherId() {
|
||||
try {
|
||||
String username = SecurityUtils.getUsername();
|
||||
if (StringUtils.isNotEmpty(username)) {
|
||||
String fromLogin = jybMapper.selectTeacherIdByAccount(username);
|
||||
if (StringUtils.isNotEmpty(fromLogin)) {
|
||||
return fromLogin.trim();
|
||||
}
|
||||
JYB byId = jybMapper.selectById(username);
|
||||
if (byId != null) {
|
||||
return byId.getJybh();
|
||||
}
|
||||
}
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
SysUser user = loginUser.getUser();
|
||||
String nickName = user == null ? null : user.getNickName();
|
||||
if (StringUtils.isNotEmpty(nickName)) {
|
||||
List<JYB> matched = jybMapper.selectList(
|
||||
new LambdaQueryWrapper<JYB>().eq(JYB::getJyxm, nickName));
|
||||
if (matched != null && matched.size() == 1) {
|
||||
return matched.get(0).getJybh();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String findStudentId() {
|
||||
try {
|
||||
String username = SecurityUtils.getUsername();
|
||||
if (StringUtils.isNotEmpty(username)) {
|
||||
XYXX byXh = xyxxMapper.selectOne(
|
||||
new LambdaQueryWrapper<XYXX>().eq(XYXX::getXh, username));
|
||||
if (byXh != null) {
|
||||
return byXh.getBh();
|
||||
}
|
||||
XYXX byBh = xyxxMapper.selectById(username);
|
||||
if (byBh != null) {
|
||||
return byBh.getBh();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasRoleKey(String roleKey) {
|
||||
try {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
SysUser user = loginUser.getUser();
|
||||
if (user == null || user.getRoles() == null || StringUtils.isEmpty(roleKey)) {
|
||||
return false;
|
||||
}
|
||||
for (SysRole role : user.getRoles()) {
|
||||
if (role != null && roleKey.equalsIgnoreCase(role.getRoleKey())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.roomroot.jwgl.vo.courserunning;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 可供调课的课次,来自学员队任务表,并关联课表、课程表。
|
||||
*/
|
||||
@Data
|
||||
public class AdjustableLessonVO {
|
||||
|
||||
/** 实施_课程表编号(实施_调课申请主关联) */
|
||||
private String sskcbbh;
|
||||
|
||||
/** 原上课日期 */
|
||||
private java.time.LocalDateTime rq;
|
||||
|
||||
/** 原节次 */
|
||||
private Integer jc;
|
||||
|
||||
/** 学员队任务表编号 */
|
||||
private String xydrwbh;
|
||||
|
||||
/** 课表.课编号 */
|
||||
private String kbh;
|
||||
|
||||
/** 课程名称 */
|
||||
private String kcmc;
|
||||
|
||||
/** 学员队编号 */
|
||||
private String xydbh;
|
||||
|
||||
/** 学员队名称 */
|
||||
private String xydmc;
|
||||
|
||||
/** 教员编号 */
|
||||
private String jybh;
|
||||
|
||||
/** 课次序号 */
|
||||
private Integer kcxh;
|
||||
|
||||
/** 教室编号 */
|
||||
private String jsbh;
|
||||
|
||||
/** 年度 */
|
||||
private Integer nd;
|
||||
|
||||
/** 教研室代号 */
|
||||
private String jysdh;
|
||||
|
||||
/** 课程表编号 */
|
||||
private String kcbbh;
|
||||
}
|
||||
Reference in New Issue
Block a user