stu01:权限控制
This commit is contained in:
parent
9f388da5c7
commit
22c47b9eb5
@ -1,32 +1 @@
|
|||||||
# Read Me First
|
|
||||||
The following was discovered as part of building this project:
|
|
||||||
|
|
||||||
* The JVM level was changed from '25' to '24', review the [JDK Version Range](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions#jdk-version-range) on the wiki for more details.
|
|
||||||
|
|
||||||
# Getting Started
|
|
||||||
|
|
||||||
### Reference Documentation
|
|
||||||
For further reference, please consider the following sections:
|
|
||||||
|
|
||||||
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
|
|
||||||
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/3.4.12/maven-plugin)
|
|
||||||
* [Create an OCI image](https://docs.spring.io/spring-boot/3.4.12/maven-plugin/build-image.html)
|
|
||||||
* [Spring Web](https://docs.spring.io/spring-boot/3.4.12/reference/web/servlet.html)
|
|
||||||
* [MyBatis Framework](https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/)
|
|
||||||
|
|
||||||
### Guides
|
|
||||||
The following guides illustrate how to use some features concretely:
|
|
||||||
|
|
||||||
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
|
|
||||||
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
|
|
||||||
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
|
|
||||||
* [MyBatis Quick Start](https://github.com/mybatis/spring-boot-starter/wiki/Quick-Start)
|
|
||||||
* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/)
|
|
||||||
|
|
||||||
### Maven Parent overrides
|
|
||||||
|
|
||||||
Due to Maven's design, elements are inherited from the parent POM to the project POM.
|
|
||||||
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the parent.
|
|
||||||
To prevent this, the project POM contains empty overrides for these elements.
|
|
||||||
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.
|
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
提示词模板:
|
||||||
|
|
||||||
一、核心协作规则重申
|
一、核心协作规则重申
|
||||||
|
|
||||||
|
|
||||||
@ -23,10 +25,10 @@
|
|||||||
3. 学生信息模块开发 3.3 学生查询参数校验 校验 ID 合法性、防 SQL 注入 合法 ID、非法 ID、SQL 注入拦截 已完成 1. 跳过分组校验设计(留作软件测试工程实践报告素材,后续忽略);2. 仅保留基础校验:ID 非负整数 + 存在性、MyBatis-Plus 参数预编译防 SQL 注入;3. 简化代码,无分组相关逻辑
|
3. 学生信息模块开发 3.3 学生查询参数校验 校验 ID 合法性、防 SQL 注入 合法 ID、非法 ID、SQL 注入拦截 已完成 1. 跳过分组校验设计(留作软件测试工程实践报告素材,后续忽略);2. 仅保留基础校验:ID 非负整数 + 存在性、MyBatis-Plus 参数预编译防 SQL 注入;3. 简化代码,无分组相关逻辑
|
||||||
3. 学生信息模块开发 3.5 学生并发测试基础支持 支持添加 / 查询接口并发请求 学生查询 / 添加并发测试 未完成 依赖 3.x 默认配置
|
3. 学生信息模块开发 3.5 学生并发测试基础支持 支持添加 / 查询接口并发请求 学生查询 / 添加并发测试 未完成 依赖 3.x 默认配置
|
||||||
4. 教师信息模块开发 4.1 后端教师基础 CRUD 实现教师添加 / 更新 / 删除接口 教师添加、更新、删除 已完成 1. 适配新数据库结构:teacher 表移除 major/title,仅保留 tea_no/name/user_id,外键关联 sys_user.id;2. 校验逻辑:教师编号 8 位纯数字 + 唯一、姓名非空、关联 userId 存在且为教师类型(user_type=2);3. 仅支持更新教师姓名;4. 接口路径:POST /api/teacher/add、PUT /api/teacher/update、DELETE /api/teacher/delete/{id};5. 依赖 JWT 拦截器,需携带合法 token
|
4. 教师信息模块开发 4.1 后端教师基础 CRUD 实现教师添加 / 更新 / 删除接口 教师添加、更新、删除 已完成 1. 适配新数据库结构:teacher 表移除 major/title,仅保留 tea_no/name/user_id,外键关联 sys_user.id;2. 校验逻辑:教师编号 8 位纯数字 + 唯一、姓名非空、关联 userId 存在且为教师类型(user_type=2);3. 仅支持更新教师姓名;4. 接口路径:POST /api/teacher/add、PUT /api/teacher/update、DELETE /api/teacher/delete/{id};5. 依赖 JWT 拦截器,需携带合法 token
|
||||||
4. 教师信息模块开发 4.2 教师删除关联拦截 教师关联课程 / 学分时拦截删除 删除关联拦截 未完成 校验逻辑:查询 course 表关联关系,存在则拦截;可选 @Transactional 事务处理
|
4. 教师信息模块开发 4.2 教师删除关联拦截 教师关联课程 / 学分时拦截删除 删除关联拦截 已完成 1. 核心逻辑:删除前查询 course 表中关联的 tea_id,存在记录则抛业务异常(code=400),提示 “教师 IDxx 关联了 xx 门课程,禁止删除”;2. 无关联时执行物理删除;3. 无需修改控制器,仅扩展 Service 层逻辑;4. 兼容全局异常处理,返回统一 Result 格式
|
||||||
4. 教师信息模块开发 4.3 教师查询防 SQL 注入 校验查询参数、防 SQL 注入 教师查询、SQL 注入拦截 未完成 接口:/api/teacher/query;防注入:MyBatis-Plus 参数绑定
|
4. 教师信息模块开发 4.3 教师查询防 SQL 注入 校验查询参数、防 SQL 注入 教师查询、SQL 注入拦截 未完成 接口:/api/teacher/query;防注入:MyBatis-Plus 参数绑定
|
||||||
4. 教师信息模块开发 4.5 教师查询并发基础支持 确保教师查询接口支持并发请求 老师查询接口并发测试 未完成 依赖 3.x 默认配置
|
4. 教师信息模块开发 4.5 教师查询并发基础支持 确保教师查询接口支持并发请求 老师查询接口并发测试 未完成 依赖 3.x 默认配置
|
||||||
5. 课程与学分模块开发 5.1 后端课程 / 学分基础 CRUD 编写课程 / 学分实体 / DAO/Service/Controller 课程添加、学分添加 未完成 接口路径:POST /api/course/add、POST /api/score/add
|
5. 课程与学分模块开发 5.1 后端课程 / 学分基础 CRUD 编写课程 / 学分实体 / DAO/Service/Controller 课程添加、学分添加 已完成 1. 课程添加:校验课程名称(2-20 字符,仅中文 / 数字 / 字母)、关联教师 ID 存在性;接口路径:POST /api/course/add;2. 学分添加:校验关联学生 ID / 课程 ID 存在性、分数 0-100;接口路径:POST /api/score/add;3. 依赖 JWT 拦截器,返回统一 Result 格式;4. 代码简洁,仅满足测试基础需求
|
||||||
5. 课程与学分模块开发 5.2 课程参数校验 校验课程名称合法性、实现课程查询 课程查询、不合法名称 未完成 课程名规则:2-20 字符(中文 / 数字 / 字母);接口路径:/api/course/query
|
5. 课程与学分模块开发 5.2 课程参数校验 校验课程名称合法性、实现课程查询 课程查询、不合法名称 未完成 课程名规则:2-20 字符(中文 / 数字 / 字母);接口路径:/api/course/query
|
||||||
5. 课程与学分模块开发 5.3 学分参数校验 校验分数合法性、实现学分更新 学分更新、错误分数 未完成 分数规则:0-100,超范围返回校验失败;接口路径:PUT /api/score/update
|
5. 课程与学分模块开发 5.3 学分参数校验 校验分数合法性、实现学分更新 学分更新、错误分数 未完成 分数规则:0-100,超范围返回校验失败;接口路径:PUT /api/score/update
|
||||||
5. 课程与学分模块开发 5.5 课程查询并发基础支持 确保课程查询接口支持并发请求 课程查询并发测试 未完成 依赖 3.x 默认配置
|
5. 课程与学分模块开发 5.5 课程查询并发基础支持 确保课程查询接口支持并发请求 课程查询并发测试 未完成 依赖 3.x 默认配置
|
||||||
@ -34,3 +36,7 @@
|
|||||||
6. 权限控制模块开发 6.2 后端接口权限拦截 拦截未登录请求、越权访问请求 越权访问 - 学生 - 老师、学生 - 管理员、老师 - 管理员 未完成 基于 JWT 的 user_type 判断权限;拦截器扩展:学生禁访 /api/teacher/、/api/admin/,教师禁访 /api/admin/**
|
6. 权限控制模块开发 6.2 后端接口权限拦截 拦截未登录请求、越权访问请求 越权访问 - 学生 - 老师、学生 - 管理员、老师 - 管理员 未完成 基于 JWT 的 user_type 判断权限;拦截器扩展:学生禁访 /api/teacher/、/api/admin/,教师禁访 /api/admin/**
|
||||||
|
|
||||||
三、执行反馈模块(每次会话必填)
|
三、执行反馈模块(每次会话必填)
|
||||||
|
确认完成5.1
|
||||||
|
测试通过
|
||||||
|
部分实体在之前的步骤中已经编写,内容一致,无需修改。部分Mapper已经存在,无需修改。
|
||||||
|
现在开始任务5.2
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
package top.awinx.stu01.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import top.awinx.stu01.common.Result;
|
||||||
|
import top.awinx.stu01.dto.CourseAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Course;
|
||||||
|
import top.awinx.stu01.service.CourseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程CRUD控制器(仅实现添加接口)
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/course")
|
||||||
|
public class CourseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CourseService courseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加课程
|
||||||
|
* POST /api/course/add
|
||||||
|
*/
|
||||||
|
@PostMapping("/add")
|
||||||
|
public Result<Course> addCourse(@RequestBody CourseAddDTO addDTO) {
|
||||||
|
Course course = courseService.addCourse(addDTO);
|
||||||
|
return Result.success("添加课程成功", course);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package top.awinx.stu01.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import top.awinx.stu01.common.Result;
|
||||||
|
import top.awinx.stu01.dto.ScoreAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Score;
|
||||||
|
import top.awinx.stu01.service.ScoreService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分CRUD控制器(仅实现添加接口)
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/score")
|
||||||
|
public class ScoreController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ScoreService scoreService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加学分
|
||||||
|
* POST /api/score/add
|
||||||
|
*/
|
||||||
|
@PostMapping("/add")
|
||||||
|
public Result<Score> addScore(@RequestBody ScoreAddDTO addDTO) {
|
||||||
|
Score score = scoreService.addScore(addDTO);
|
||||||
|
return Result.success("添加学分成功", score);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
stu01/src/main/java/top/awinx/stu01/dto/CourseAddDTO.java
Normal file
19
stu01/src/main/java/top/awinx/stu01/dto/CourseAddDTO.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package top.awinx.stu01.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程添加请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CourseAddDTO {
|
||||||
|
/**
|
||||||
|
* 课程名称(2-20字符,仅中文/数字/字母)
|
||||||
|
*/
|
||||||
|
private String courseName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联教师ID(非空且存在)
|
||||||
|
*/
|
||||||
|
private Long teaId;
|
||||||
|
}
|
||||||
24
stu01/src/main/java/top/awinx/stu01/dto/ScoreAddDTO.java
Normal file
24
stu01/src/main/java/top/awinx/stu01/dto/ScoreAddDTO.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package top.awinx.stu01.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分添加请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ScoreAddDTO {
|
||||||
|
/**
|
||||||
|
* 关联学生ID(非空且存在)
|
||||||
|
*/
|
||||||
|
private Long stuId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联课程ID(非空且存在)
|
||||||
|
*/
|
||||||
|
private Long courseId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分数(0-100)
|
||||||
|
*/
|
||||||
|
private Integer score;
|
||||||
|
}
|
||||||
41
stu01/src/main/java/top/awinx/stu01/entity/Score.java
Normal file
41
stu01/src/main/java/top/awinx/stu01/entity/Score.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package top.awinx.stu01.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分实体类(匹配stu01_db.score表)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("score")
|
||||||
|
public class Score {
|
||||||
|
/**
|
||||||
|
* 学分ID(主键自增)
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联学生ID(外键关联student.id)
|
||||||
|
*/
|
||||||
|
private Long stuId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联课程ID(外键关联course.id)
|
||||||
|
*/
|
||||||
|
private Long courseId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分数(0-100)
|
||||||
|
*/
|
||||||
|
private Integer score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间(数据库默认CURRENT_TIMESTAMP)
|
||||||
|
*/
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
@ -8,12 +8,13 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import top.awinx.stu01.common.Result;
|
import top.awinx.stu01.common.Result;
|
||||||
import top.awinx.stu01.config.JwtConfig;
|
import top.awinx.stu01.config.JwtConfig;
|
||||||
|
import top.awinx.stu01.entity.SysUser;
|
||||||
import top.awinx.stu01.utils.JwtUtil;
|
import top.awinx.stu01.utils.JwtUtil;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JWT拦截器:校验请求头中的token合法性
|
* JWT拦截器:校验请求头中的token合法性并基于user_type控制访问权限
|
||||||
*/
|
*/
|
||||||
public class JwtInterceptor implements HandlerInterceptor {
|
public class JwtInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|||||||
private JwtConfig jwtConfig;
|
private JwtConfig jwtConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预处理:请求到达Controller前校验token
|
* 预处理:请求到达Controller前校验token并进行权限控制
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
@ -48,7 +49,55 @@ public class JwtInterceptor implements HandlerInterceptor {
|
|||||||
return false; // 拦截请求
|
return false; // 拦截请求
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. token合法,放行请求
|
// 4. 解析token获取用户信息进行权限控制
|
||||||
|
SysUser sysUser = jwtUtil.getUserFromToken(token);
|
||||||
|
Integer userType = sysUser.getUserType(); // 1-学生 2-教师 3-管理员
|
||||||
|
String requestPath = request.getRequestURI(); // 获取当前请求路径
|
||||||
|
|
||||||
|
// 5. 权限匹配逻辑(核心)
|
||||||
|
// 5.1 管理员(3):放行所有接口
|
||||||
|
if (userType == 3) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5.2 教师(2):禁止访问/admin/**接口
|
||||||
|
if (userType == 2) {
|
||||||
|
if (requestPath.startsWith("/api/admin/")) {
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
Result<Object> result = Result.error("权限不足:教师禁止访问管理员接口");
|
||||||
|
PrintWriter writer = response.getWriter();
|
||||||
|
writer.write(new ObjectMapper().writeValueAsString(result));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.3 学生(1):禁止访问/teacher/**、/admin/**接口
|
||||||
|
if (userType == 1) {
|
||||||
|
if (requestPath.startsWith("/api/teacher/") || requestPath.startsWith("/api/admin/")) {
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
Result<Object> result = Result.error("权限不足:学生禁止访问教师/管理员接口");
|
||||||
|
PrintWriter writer = response.getWriter();
|
||||||
|
writer.write(new ObjectMapper().writeValueAsString(result));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 未知用户类型(兜底)
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
Result<Object> result = Result.error("未知的用户类型,权限校验失败");
|
||||||
|
PrintWriter writer = response.getWriter();
|
||||||
|
writer.write(new ObjectMapper().writeValueAsString(result));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
stu01/src/main/java/top/awinx/stu01/mapper/ScoreMapper.java
Normal file
12
stu01/src/main/java/top/awinx/stu01/mapper/ScoreMapper.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package top.awinx.stu01.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import top.awinx.stu01.entity.Score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分Mapper(MyBatis-Plus基础CRUD)
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ScoreMapper extends BaseMapper<Score> {
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package top.awinx.stu01.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import top.awinx.stu01.dto.CourseAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Course;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程Service接口
|
||||||
|
*/
|
||||||
|
public interface CourseService extends IService<Course> {
|
||||||
|
/**
|
||||||
|
* 添加课程
|
||||||
|
*/
|
||||||
|
Course addCourse(CourseAddDTO addDTO);
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package top.awinx.stu01.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import top.awinx.stu01.dto.ScoreAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分Service接口
|
||||||
|
*/
|
||||||
|
public interface ScoreService extends IService<Score> {
|
||||||
|
/**
|
||||||
|
* 添加学分
|
||||||
|
*/
|
||||||
|
Score addScore(ScoreAddDTO addDTO);
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package top.awinx.stu01.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import top.awinx.stu01.dto.CourseAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Course;
|
||||||
|
import top.awinx.stu01.entity.Teacher;
|
||||||
|
import top.awinx.stu01.exception.BusinessException;
|
||||||
|
import top.awinx.stu01.mapper.CourseMapper;
|
||||||
|
import top.awinx.stu01.mapper.TeacherMapper;
|
||||||
|
import top.awinx.stu01.service.CourseService;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 课程Service实现类(添加核心逻辑)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TeacherMapper teacherMapper;
|
||||||
|
|
||||||
|
// 课程名称校验正则:2-20字符,仅中文、数字、字母
|
||||||
|
private static final Pattern COURSE_NAME_PATTERN = Pattern.compile("^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Course addCourse(CourseAddDTO addDTO) {
|
||||||
|
// 1. 课程名称校验
|
||||||
|
if (addDTO.getCourseName() == null || !COURSE_NAME_PATTERN.matcher(addDTO.getCourseName()).matches()) {
|
||||||
|
throw new BusinessException("课程名称必须为2-20字符,仅包含中文、数字、字母");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 关联教师ID存在性校验
|
||||||
|
if (addDTO.getTeaId() == null) {
|
||||||
|
throw new BusinessException("关联教师ID不能为空");
|
||||||
|
}
|
||||||
|
Teacher teacher = teacherMapper.selectById(addDTO.getTeaId());
|
||||||
|
if (teacher == null) {
|
||||||
|
throw new BusinessException("关联的教师ID" + addDTO.getTeaId() + "不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. DTO转实体
|
||||||
|
Course course = new Course();
|
||||||
|
course.setCourseName(addDTO.getCourseName());
|
||||||
|
course.setTeaId(addDTO.getTeaId());
|
||||||
|
course.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
this.save(course);
|
||||||
|
return course;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package top.awinx.stu01.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import top.awinx.stu01.dto.ScoreAddDTO;
|
||||||
|
import top.awinx.stu01.entity.Course;
|
||||||
|
import top.awinx.stu01.entity.Score;
|
||||||
|
import top.awinx.stu01.entity.Student;
|
||||||
|
import top.awinx.stu01.exception.BusinessException;
|
||||||
|
import top.awinx.stu01.mapper.CourseMapper;
|
||||||
|
import top.awinx.stu01.mapper.ScoreMapper;
|
||||||
|
import top.awinx.stu01.mapper.StudentMapper;
|
||||||
|
import top.awinx.stu01.service.ScoreService;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学分Service实现类(添加核心逻辑)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ScoreServiceImpl extends ServiceImpl<ScoreMapper, Score> implements ScoreService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StudentMapper studentMapper;
|
||||||
|
@Resource
|
||||||
|
private CourseMapper courseMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Score addScore(ScoreAddDTO addDTO) {
|
||||||
|
// 1. 关联学生ID存在性校验
|
||||||
|
if (addDTO.getStuId() == null) {
|
||||||
|
throw new BusinessException("关联学生ID不能为空");
|
||||||
|
}
|
||||||
|
Student student = studentMapper.selectById(addDTO.getStuId());
|
||||||
|
if (student == null) {
|
||||||
|
throw new BusinessException("关联的学生ID" + addDTO.getStuId() + "不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 关联课程ID存在性校验
|
||||||
|
if (addDTO.getCourseId() == null) {
|
||||||
|
throw new BusinessException("关联课程ID不能为空");
|
||||||
|
}
|
||||||
|
Course course = courseMapper.selectById(addDTO.getCourseId());
|
||||||
|
if (course == null) {
|
||||||
|
throw new BusinessException("关联的课程ID" + addDTO.getCourseId() + "不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 分数范围校验
|
||||||
|
if (addDTO.getScore() == null || addDTO.getScore() < 0 || addDTO.getScore() > 100) {
|
||||||
|
throw new BusinessException("分数必须为0-100之间的整数");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. DTO转实体
|
||||||
|
Score score = new Score();
|
||||||
|
score.setStuId(addDTO.getStuId());
|
||||||
|
score.setCourseId(addDTO.getCourseId());
|
||||||
|
score.setScore(addDTO.getScore());
|
||||||
|
score.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
this.save(score);
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,27 +3,39 @@
|
|||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/CorsConfig.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/CorsConfig.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/JwtConfig.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/JwtConfig.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/WebMvcConfig.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/config/WebMvcConfig.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/CourseController.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/LoginController.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/LoginController.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/ScoreController.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/StudentController.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/StudentController.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/TeacherController.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/TeacherController.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/TestController.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/controller/TestController.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/CourseAddDTO.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/LoginRequest.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/LoginRequest.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/ScoreAddDTO.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/StudentAddDTO.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/StudentAddDTO.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/StudentQueryDTO.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/StudentQueryDTO.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/TeacherAddDTO.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/TeacherAddDTO.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/TeacherUpdateDTO.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/dto/TeacherUpdateDTO.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Course.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Score.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Student.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Student.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/SysUser.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/SysUser.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Teacher.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/entity/Teacher.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/exception/BusinessException.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/exception/BusinessException.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/exception/GlobalExceptionHandler.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/exception/GlobalExceptionHandler.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/interceptor/JwtInterceptor.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/interceptor/JwtInterceptor.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/CourseMapper.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/ScoreMapper.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/StudentMapper.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/StudentMapper.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/SysUserMapper.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/SysUserMapper.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/TeacherMapper.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/mapper/TeacherMapper.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/CourseService.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/ScoreService.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/StudentService.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/StudentService.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/SysUserService.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/SysUserService.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/TeacherService.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/TeacherService.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/CourseServiceImpl.java
|
||||||
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/ScoreServiceImpl.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/StudentServiceImpl.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/StudentServiceImpl.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/SysUserServiceImpl.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/SysUserServiceImpl.java
|
||||||
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/TeacherServiceImpl.java
|
/home/awinx/code/java/lerning/java_web/stu01/src/main/java/top/awinx/stu01/service/impl/TeacherServiceImpl.java
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user