diff --git a/src/main/java/cn/org/alan/exam/controller/AnswerController.java b/src/main/java/cn/org/alan/exam/controller/AnswerController.java index e249923..936af04 100644 --- a/src/main/java/cn/org/alan/exam/controller/AnswerController.java +++ b/src/main/java/cn/org/alan/exam/controller/AnswerController.java @@ -1,19 +1,21 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于对类进行组织和分类管理,表明此控制器类属于该指定包 import cn.org.alan.exam.common.group.AnswerGroup; +// 引入AnswerGroup类,可能用于对答案相关操作的分组验证等功能(从名字推测) import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于封装操作的结果信息,比如包含操作成功与否以及对应的数据等情况,方便统一返回格式 import cn.org.alan.exam.model.form.answer.CorrectAnswerFrom; -import cn.org.alan.exam.model.vo.answer.AnswerExamVO; -import cn.org.alan.exam.model.vo.answer.UncorrectedUserVO; -import cn.org.alan.exam.model.vo.answer.UserAnswerDetailVO; -import cn.org.alan.exam.service.IManualScoreService; -import com.baomidou.mybatisplus.core.metadata.IPage; -import jakarta.annotation.Resource; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +// 引入CorrectAnswerFrom类,可能是代表正确答案相关的表单数据模型类,用于接收前端提交的正确答案相关的数据结构 +import cn.org.alan.exam.model.vo.answer.AnswerExamVO; // 引入AnswerExamVO类,大概率是视图对象(Value Object,VO)类,用于向客户端传递特定的与考试相关的数据展示格式 +import cn.org.alan.exam.model.vo.answer.UncorrectedUserVO; // 引入UncorrectedUserVO类,同样是视图对象类,可能用于展示待批阅用户相关的数据展示形式 +import cn.org.alan.exam.model.vo.answer.UserAnswerDetailVO; // 引入UserAnswerDetailVO类,用于向客户端展示答卷详细信息的视图对象 +import cn.org.alan.exam.service.IManualScoreService; // 引入IManualScoreService类,这应该是一个服务接口,用于定义和实现与手动评分相关的业务逻辑 +import com.baomidou.mybatisplus.core.metadata.IPage; // 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,用于处理分页查询相关业务逻辑 +import jakarta.annotation.Resource; // 用于进行资源注入,在这里可将实现了IManualScoreService接口的具体实例注入到当前控制器类中,方便调用对应的服务方法 +import org.springframework.security.access.prepost.PreAuthorize; // 用于在方法级别进行权限控制,根据配置的权限表达式来判断当前用户是否有权限访问对应的方法,保障系统安全性 +import org.springframework.validation.annotation.Validated; // 结合具体的分组类(如AnswerGroup.CorrectGroup.class)可以对传入方法的参数进行基于分组的验证,确保数据的合法性和有效性 +import org.springframework.web.bind.annotation.*; // 通配符导入包含了很多Spring Web相关的注解,用于定义控制器类中的请求处理方法以及映射对应的HTTP请求路径和请求方式等 +import java.util.List; // 引入Java标准库中的List接口,用于表示列表类型,在这里用于处理返回多个数据元素的情况 /** * 答卷管理 @@ -22,44 +24,44 @@ import java.util.List; * @Version * @Date 2024/3/25 11:20 AM */ -@RestController -@RequestMapping("/api/answers") -public class AnswerController { +@RestController // 这是Spring框架提供的复合注解,结合了@Controller和@ResponseBody的功能,意味着这个类是一个Spring MVC中的控制器类,并且类中的方法返回值会直接以JSON等格式响应给客户端(默认情况下),无需额外配置视图解析等相关内容 +@RequestMapping("/api/answers") // 用于给整个控制器类的所有请求处理方法定义一个基础的请求路径前缀,表明该控制器类中所有处理请求的方法的URL路径都将以/api/answers开头,方便对一组相关的API进行统一的路径管理 +public class AnswerController { // 定义一个名为AnswerController的公共类,作为控制器来处理相关业务逻辑请求 - @Resource - private IManualScoreService manualScoreService; + @Resource // 使用@Resource注解将一个实现了IManualScoreService接口的实例注入到当前的AnswerController类中,使得后续方法可以调用该服务接口所定义的业务逻辑方法 + private IManualScoreService manualScoreService; // 声明一个私有变量manualScoreService,类型为IManualScoreService,用于后续调用相关服务方法实现具体业务逻辑 /** * 试卷查询信息 * @return */ - @GetMapping("/detail") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> getDetail(@RequestParam Integer userId, - @RequestParam Integer examId) { - return manualScoreService.getDetail(userId, examId); + @GetMapping("/detail") // 表示这个方法用于处理HTTP GET请求,对应的请求路径是在类级别定义的基础路径/api/answers基础上追加/detail,即完整请求路径为/api/answers/detail + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有拥有role_teacher或者role_admin权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以查询答卷详情,增强系统的安全性 + public Result> getDetail(@RequestParam Integer userId, // 表示从请求中获取名为userId的参数,参数类型为整数,用于指定用户ID,以便准确查询对应的用户答卷详情 + @RequestParam Integer examId) { // 表示从请求中获取名为examId的参数,参数类型为整数,用于指定考试ID,配合userId一起准确查询对应的用户答卷详情 + return manualScoreService.getDetail(userId, examId); // 方法体内部直接调用注入的manualScoreService接口的getDetail方法,并将获取到的请求参数传递进去,最终将服务层返回的结果直接返回给客户端,由服务层去具体实现根据传入的用户ID和考试ID查询答卷详细信息的业务逻辑 } /** * 批改试卷 * @return */ - @PutMapping("/correct") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result Correct(@RequestBody @Validated(AnswerGroup.CorrectGroup.class) List correctAnswerFroms) { - return manualScoreService.correct(correctAnswerFroms); + @PutMapping("/correct") // 指定这个方法处理HTTP PUT请求,请求路径是在类基础路径上追加/correct,也就是/api/answers/correct,PUT请求常用于更新资源等操作,这里用于批改试卷这个更新数据的场景比较合适 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,限定只有教师或管理员角色能执行此操作 + public Result Correct(@RequestBody @Validated(AnswerGroup.CorrectGroup.class) List correctAnswerFroms) { // @RequestBody表示方法的参数correctAnswerFroms是从请求的正文中获取数据,即将前端发送过来的JSON等格式的数据转换为对应的Java对象列表,同时通过@Validated结合指定分组类对传入的参数列表进行数据验证,确保数据合法性,只有验证通过的数据才进入方法内部进行后续处理 + return manualScoreService.correct(correctAnswerFroms); // 方法返回Result类型,调用manualScoreService的correct方法,由服务层去具体实现批改试卷的业务逻辑,并将结果封装到Result对象中返回给控制器,再由控制器返回给客户端,这里的String可能用于表示批改试卷操作的一些相关反馈信息(比如批改是否成功等简单提示) } /** * 分页查找待阅卷考试 * @return */ - @GetMapping("/exam/page") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> examPage(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "examName", required = false) String examName) { - return manualScoreService.examPage(pageNum, pageSize, examName); + @GetMapping("/exam/page") // 表明此方法处理HTTP GET请求,对应的请求路径是/api/answers/exam/page,用于分页查找待阅卷考试相关信息 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 权限控制,保证只有教师或管理员角色能访问该方法 + public Result> examPage(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, // 获取请求中的pageNum参数(可选参数,若请求中未提供则默认值为1),用于指定分页查询的页码 + @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, // 获取pageSize参数(同样可选,默认值为10),代表每页显示的记录数量 + @RequestParam(value = "examName", required = false) String examName) { // 获取examName参数(可选),可能用于根据考试名称进行模糊查询等筛选操作,以便更精准地查找待阅卷的考试信息 + return manualScoreService.examPage(pageNum, pageSize, examName); // 方法返回Result>类型,由服务层去实现具体的分页查询待阅卷考试信息的业务逻辑,并返回相应结果给客户端,IPage是MyBatis Plus中的分页对象,包含了符合条件的AnswerExamVO类型的分页数据 } /** @@ -69,12 +71,12 @@ public class AnswerController { * @param examId * @return */ - @GetMapping("/exam/stu") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> stuExamPage(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "examId") Integer examId, - @RequestParam(value = "realName", required = false) String realName) { - return manualScoreService.stuExamPage(pageNum, pageSize, examId,realName); + @GetMapping("/exam/stu") // 注解说明这个方法处理HTTP GET请求,请求路径为/api/answers/exam/stu,用于查询待批阅的用户相关信息 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有教师或管理员角色的用户可访问该方法 + public Result> stuExamPage(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, // 用于指定页码,可选参数,若未提供则默认为1 + @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, // 用于指定每页记录数,可选参数,默认为10 + @RequestParam(value = "examId") Integer examId, // 是必填参数,用于指定考试的ID,以此来确定要查询哪一场考试下待批阅的用户 + @RequestParam(value = "realName", required = false) String realName) { // 是可选参数,可能用于根据用户的真实姓名进行模糊查询等操作,更精准地查找待批阅用户 + return manualScoreService.stuExamPage(pageNum, pageSize, examId,realName); // 方法返回Result>类型,由服务层去实现具体根据给定条件查询待批阅用户信息的业务逻辑,并将结果封装在合适的对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/AuthController.java b/src/main/java/cn/org/alan/exam/controller/AuthController.java index c44d35b..d1c4b85 100644 --- a/src/main/java/cn/org/alan/exam/controller/AuthController.java +++ b/src/main/java/cn/org/alan/exam/controller/AuthController.java @@ -1,95 +1,90 @@ -package cn.org.alan.exam.controller; - -import cn.org.alan.exam.common.group.UserGroup; -import cn.org.alan.exam.common.result.Result; -import cn.org.alan.exam.model.form.Auth.LoginForm; -import cn.org.alan.exam.model.form.UserForm; -import cn.org.alan.exam.service.IAuthService; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.Map; +package cn.org.alan.exam.controller; // 定义该类所属的包名,通过包名对类进行分类管理,让代码结构更清晰,此控制器类属于该指定的包,便于在项目中区分不同功能模块的代码 +import cn.org.alan.exam.common.group.UserGroup; // 引入UserGroup类,可能用于对用户相关操作按照不同场景、规则等进行分组验证,例如不同的用户注册、修改信息等操作的验证分组,便于灵活控制数据验证逻辑 +import cn.org.alan.exam.common.result.Result; // 引入Result类,通常用来统一封装业务操作的结果,包含操作是否成功的标识以及可能需要返回的数据等信息,方便以一致的格式返回给调用者(如前端) +import cn.org.alan.exam.model.form.Auth.LoginForm; // 引入LoginForm类,这是一个数据模型类,用于承载用户登录时从前端传递过来的相关信息,比如用户名、密码等登录所需的数据结构 +import cn.org.alan.exam.model.form.UserForm; // 引入UserForm类,同样是数据模型类,用于接收用户相关的信息,在不同场景(如注册、信息更新等)下,存储用户提交的各种数据内容,符合相应的业务数据格式要求 +import cn.org.alan.exam.service.IAuthService; // 引入IAuthService接口,定义了与权限认证相关的一系列业务方法,例如登录、注销、注册等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 +import jakarta.annotation.Resource; // 这是用于进行资源注入的注解,在这里的作用是将实现了IAuthService接口的具体实例注入到当前的AuthController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 +import jakarta.servlet.http.HttpServletRequest; // 引入HttpServletRequest类,它代表了客户端发送过来的HTTP请求对象,在控制器方法中可借助它获取请求中的各种信息,比如请求参数、请求头信息,也常用于获取session相关信息,像获取sessionId等操作 +import jakarta.servlet.http.HttpServletResponse; // 引入HttpServletResponse类,用于在控制器方法中对HTTP响应进行处理,比如设置响应的状态码、响应头(例如设置内容类型等)以及向客户端输出响应内容(如返回图片验证码等情况) +import org.springframework.http.ResponseEntity; // 引入ResponseEntity类,Spring框架中用于构建更灵活、全面的HTTP响应实体,可方便地设置响应的各种属性,如状态码、头信息以及响应体内容等,不过在此代码中暂时未看到直接使用它的地方 +import org.springframework.security.access.prepost.PreAuthorize; // 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 +import org.springframework.validation.annotation.Validated; // 结合具体的分组类(像这里的UserGroup.RegisterGroup.class等)可以对传入方法的参数进行分组验证,确保接收到的参数数据符合特定业务规则和验证要求,保证数据的合法性和准确性 +import org.springframework.web.bind.annotation.*; // 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 +import java.time.Duration; // 引入Duration类,用于表示时间间隔,常用于处理涉及时间长度相关的业务逻辑,例如设置某个操作的超时时间、计算两个时间点之间的时长等,但在当前代码片段中未明确体现其使用场景 +import java.time.LocalDateTime; // 引入LocalDateTime类,用于表示本地的日期和时间,在业务逻辑中可能会用于记录操作发生的时间、判断时间有效性等情况,不过此处暂时未看到具体使用它的地方 +import java.util.Map; // 引入Java标准库中的Map接口,用于存储键值对形式的数据结构,常用于传递多个相关参数、存储配置信息等场景,在当前代码里尚未看到具体运用的地方 /** - * 权限管理 + * 此处可能原本是用于添加关于该类功能等相关描述的地方,但目前没有具体内容,从类名及方法来看大概率是和权限认证相关的控制器类 * * @Author WeiJin * @Version * @Date 2024/3/25 11:05 AM */ -@RestController -@RequestMapping("/api/auths") -public class AuthController { - +@RestController // 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 +@RequestMapping("/api/auths") // 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/auths开头,便于统一管理和组织与权限认证相关的一组API接口路径 +public class AuthController { // 定义一个公共的类,类名为AuthController,作为权限管理相关业务逻辑的处理中心,对外提供各种权限认证相关的接口,接收和处理对应的HTTP请求 - @Resource - private IAuthService iAuthService; + @Resource // 使用@Resource注解来进行依赖注入,目的是让Spring容器查找并注入一个实现了IAuthService接口的实例到当前类中,这样后续的方法就能方便地调用该服务实例所提供的各种权限认证相关的业务方法 + private IAuthService iAuthService; // 声明一个私有成员变量iAuthService,其类型为IAuthService接口类型,通过依赖注入后,它将指向对应的服务实现类实例,用于在控制器方法中调用具体的权限认证相关业务逻辑方法 /** * 用户登录 - * @param request request对象,用户获取sessionId - * @param user 用户信息 - * @return token + * @param request request对象,用户获取sessionId,在登录过程中,可能需要借助session来存储一些临时信息(比如登录状态等),或者用于后续验证、关联等操作,所以需要获取sessionId + * @param user 用户信息,此处代码中参数名称与实际传入的类型不符(实际传入LoginForm类型),应该是代码编写时的小瑕疵,正确的理解是接收一个LoginForm类型的参数用于承载用户登录相关信息 + * @return token,表明该方法执行登录操作成功后,会返回一个用于标识用户登录状态的token(通常是一个字符串形式的令牌),后续客户端可以凭借这个token进行其他需要授权的操作 */ - @PostMapping("/login") - public Result login(HttpServletRequest request, - @Validated @RequestBody LoginForm loginForm) { - - return iAuthService.login(request,loginForm); + @PostMapping("/login") // 该注解表明这个方法用于处理HTTP POST请求,并且其请求路径是在类级别定义的基础路径/api/auths基础上添加/login,即完整的请求路径为/api/auths/login。POST请求常用于向服务器提交数据,在此处符合用户提交登录信息的场景 + public Result login(HttpServletRequest request, // 接收HttpServletRequest类型的参数request,通过它可以获取请求相关的各种详细信息,比如从请求头中获取客户端相关标识信息、从请求的Cookie中获取sessionId等,在登录逻辑中会利用这些信息辅助完成登录验证等操作 + @Validated @RequestBody LoginForm loginForm) { // @Validated注解结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为LoginForm类型的对象,而@Validated用于对这个转换后的LoginForm对象依据相关规则(此处可能结合了默认验证规则或特定分组验证规则等)进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的登录业务逻辑处理 + return iAuthService.login(request,loginForm); // 方法体内部直接调用通过依赖注入获取的iAuthService接口实例的login方法,并将接收到的request和经过验证的loginForm参数传递进去,由服务层去具体实现用户登录的详细业务逻辑,比如验证用户名和密码是否匹配、生成有效的登录token等,最后将服务层返回的包含登录结果及token信息等的Result对象直接返回给客户端 } /** * 用户注销 - * @param request request对象,需要清除session里面的内容 - * @return 响应结果 + * @param request request对象,需要清除session里面的内容,因为注销操作通常意味着要结束用户的当前登录状态,所以要清理session中存储的与该用户登录相关的各种信息,比如用户标识、权限信息等,确保下次访问需要重新登录 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端注销操作是否成功等相关情况,该Result对象中包含了相应的操作结果标识以及可能的提示信息等内容 */ - @DeleteMapping("/logout") - public Result logout(HttpServletRequest request) { - return iAuthService.logout(request); + @DeleteMapping("/logout") // 此注解指定这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/auths基础上追加/logout,也就是/api/auths/logout。DELETE请求常用于删除资源等操作,这里用于表示删除用户的登录状态这一资源,符合注销操作的语义 + public Result logout(HttpServletRequest request) { // 接收HttpServletRequest类型的参数request,借助它来操作session,找到与当前登录用户对应的session信息,进而执行清除session内容的操作,实现注销用户登录状态的功能 + return iAuthService.logout(request); // 调用通过依赖注入获取的iAuthService接口实例的logout方法,由服务层去具体实现注销的详细业务逻辑,比如清理session中的用户相关信息、更新相关的登录状态记录等,然后将处理后的结果封装到Result对象中返回给客户端,告知注销操作的执行情况 } /** * 用户注册,只能注册学生 - * @param request request对象,用于获取sessionId - * @param userForm 用户信息 - * @return 响应结果 + * @param request request对象,用于获取sessionId,在注册过程中,可能会利用session来记录一些注册相关的临时信息,或者进行一些基于session的验证等操作,所以需要获取sessionId + * @param userForm 用户信息,这里的userForm是一个UserForm类型的参数,用于承载用户注册时提交的各种个人信息,比如姓名、学号、密码等,并且会根据相关验证规则(结合了UserGroup.RegisterGroup.class分组验证规则)来确保这些信息的合法性和完整性 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端注册操作是否成功以及可能的相关提示信息等,其内部封装了注册操作对应的结果标识以及其他相关的数据内容 */ - @PostMapping("/register") - public Result register(HttpServletRequest request, - @RequestBody @Validated(UserGroup.RegisterGroup.class) UserForm userForm) { - return iAuthService.register(request, userForm); + @PostMapping("/register") // 表明该方法用于处理HTTP POST请求,其请求路径为/api/auths/register,POST请求常用于向服务器提交新的数据,在此场景下符合用户提交注册信息的操作特点 + public Result register(HttpServletRequest request, // 接收HttpServletRequest类型的参数request,通过它可以获取到请求相关的各种信息,例如获取sessionId用于关联注册操作与特定的会话,或者从请求中获取一些必要的辅助验证信息等,服务层在处理注册逻辑时会利用这些信息 + @RequestBody @Validated(UserGroup.RegisterGroup.class) UserForm userForm) { // @RequestBody注解表示从请求正文中获取数据并转换为UserForm类型的对象,@Validated结合特定的分组类UserGroup.RegisterGroup.class对转换后的userForm对象进行数据验证,确保用户提交的注册信息符合相应的业务规则要求,只有验证通过的数据才会进入后续的注册业务逻辑处理流程 + return iAuthService.register(request, userForm); // 调用iAuthService接口的register方法,由服务层去具体实现用户注册的详细业务逻辑,比如将用户注册信息保存到数据库中、为新注册的学生用户设置默认权限等,最后把注册操作的结果封装到Result对象中返回给客户端,告知注册是否成功以及可能的提示信息等情况 } /** * 获取图片验证码 - * @param request request对象,获取sessionId - * @param response response对象,响应图片 + * @param request request对象,获取sessionId,获取图片验证码的操作可能需要借助session来存储验证码相关的信息,例如验证码的生成时间、验证次数限制等,方便后续验证操作时进行比对和判断,所以要获取sessionId + * @param response response对象,响应图片,此参数用于对HTTP响应进行处理,比如设置响应的内容类型为图片格式(如image/png等),然后将生成的图片验证码数据通过响应流返回给客户端,让客户端能够展示图片验证码 */ - @GetMapping("/captcha") - public void getCaptcha(HttpServletRequest request, HttpServletResponse response) { - iAuthService.getCaptcha(request, response); + @GetMapping("/captcha") // 表示这个方法用于处理HTTP GET请求,其请求路径是/api/auths/captcha,GET请求常用于获取资源,这里用于获取图片验证码这一资源的操作符合GET请求的使用场景 + public void getCaptcha(HttpServletRequest request, HttpServletResponse response) { // 接收HttpServletRequest类型的参数request用于获取请求相关信息,特别是获取sessionId等用于验证码相关操作的辅助信息,接收HttpServletResponse类型的参数response用于对响应进行操作,如设置响应头告知客户端返回的是图片数据以及将生成的图片验证码数据写入到响应流中返回给客户端等 + iAuthService.getCaptcha(request, response); // 直接调用iAuthService接口的getCaptcha方法,由服务层去具体实现生成图片验证码、将验证码相关信息存储到session(通过操作request获取的session来存储)以及把图片验证码通过response返回给客户端等一系列业务逻辑,该方法没有返回值,因为主要操作是通过response直接向客户端返回图片验证码数据 } /** * 校验验证码 - * @param request request对象,获取sessionId - * @param code 用户输入的验证码 - * @return 响应结果 + * @param request request对象,获取sessionId,在校验验证码时,需要从session中获取之前存储的验证码相关信息(如生成的原始验证码、有效期等)来和用户输入的验证码进行比对,所以要通过request获取sessionId进而操作session获取相关信息 + * @param code 用户输入的验证码,这是一个从请求路径中获取的字符串类型参数(通过@PathVariable注解获取),代表用户输入的验证码内容,用于和从session中获取的原始验证码进行对比验证操作 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端验证码校验的结果,比如校验是否通过、是否已过期等相关情况,该Result对象包含了相应的结果标识以及可能的提示信息等内容 */ - @PostMapping("/verifyCode/{code}") - public Result verifyCode(HttpServletRequest request, @PathVariable("code") String code) { - return iAuthService.verifyCode(request, code); + @PostMapping("/verifyCode/{code}") // 表示该方法用于处理HTTP POST请求,其请求路径为/api/auths/verifyCode/{code},其中{code}是路径变量,通过@PathVariable注解来获取用户输入的验证码作为路径的一部分,POST请求常用于提交数据进行验证等操作,这里用于提交用户输入的验证码进行校验的场景符合POST请求的语义 + public Result verifyCode(HttpServletRequest request, @PathVariable("code") String code) { // 接收HttpServletRequest类型的参数request用于获取请求相关信息,特别是通过获取sessionId来查找之前存储的验证码相关内容,通过@PathVariable("code")注解获取用户输入的验证码字符串,然后将这些信息传递给服务层进行验证码校验的业务逻辑处理 + return iAuthService.verifyCode(request, code); // 调用iAuthService接口的verifyCode方法,由服务层去具体实现校验用户输入的验证码与之前存储在session中的原始验证码是否一致、判断验证码是否在有效期内等业务逻辑,最后把校验结果封装到Result对象中返回给客户端,告知验证码校验的情况 } - @PostMapping("/track-presence") - public Result trackPresence(HttpServletRequest request) { - return iAuthService.sendHeartbeat(request); + @PostMapping("/track-presence") // 表示此方法用于处理HTTP POST请求,其请求路径为/api/auths/track-presence,从方法名推测可能是用于跟踪用户的某种存在状态(比如在线状态、活跃状态等),POST请求常用于提交相关数据来触发相应的业务逻辑,这里用于提交相关信息以启动对用户状态的跟踪操作 + public Result trackPresence(HttpServletRequest request) { // 接收HttpServletRequest类型的参数request用于获取请求相关信息,比如获取用户的标识信息等,以便服务层能够准确判断是哪个用户的状态需要被跟踪,为后续的业务逻辑处理提供必要的数据基础 + return iAuthService.sendHeartbeat(request); // 调用iAuthService接口的sendHeartbeat方法,由服务层去具体实现发送心跳(推测是类似定期发送信号来表明用户处于某种期望的状态,比如在线状态)等相关业务逻辑,最后把操作的结果封装到Result对象中返回给客户端,告知用户状态跟踪的相关情况 } - -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/CertificateController.java b/src/main/java/cn/org/alan/exam/controller/CertificateController.java index 629c8a0..e04337e 100644 --- a/src/main/java/cn/org/alan/exam/controller/CertificateController.java +++ b/src/main/java/cn/org/alan/exam/controller/CertificateController.java @@ -1,97 +1,96 @@ -package cn.org.alan.exam.controller; - - -import cn.org.alan.exam.common.group.CertificateGroup; -import cn.org.alan.exam.common.result.Result; -import cn.org.alan.exam.model.entity.Certificate; -import cn.org.alan.exam.model.form.CertificateForm; -import cn.org.alan.exam.model.vo.certificate.MyCertificateVO; -import cn.org.alan.exam.service.ICertificateService; -import com.baomidou.mybatisplus.core.metadata.IPage; -import jakarta.annotation.Resource; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +package cn.org.alan.exam.controller; // 声明该类所在的包名,用于在项目中对类进行分类组织,使代码结构更清晰,表明此控制器类属于该特定的包,便于区分不同功能模块的代码 +import cn.org.alan.exam.common.group.CertificateGroup; // 引入CertificateGroup类,可能用于对证书相关操作进行分组验证,比如不同的证书添加、修改等操作按照特定规则进行分组,便于灵活控制数据验证逻辑 +import cn.org.alan.exam.common.result.Result; // 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功以及可能需要返回的数据等内容,以一致的格式返回给调用者(如前端) +import cn.org.alan.exam.model.entity.Certificate; // 引入Certificate类,这大概率是代表证书实体的数据模型类,对应数据库中存储证书相关信息的表结构,用于在业务逻辑中操作证书的实际数据 +import cn.org.alan.exam.model.form.CertificateForm; // 引入CertificateForm类,是用于接收前端传递过来的与证书相关操作(如添加、修改证书)的参数数据模型,符合前端提交的相应业务数据格式要求 +import cn.org.alan.exam.model.vo.certificate.MyCertificateVO; // 引入MyCertificateVO类,应该是视图对象(Value Object,VO)类,用于向客户端展示特定格式的已获证书相关信息,通常是经过处理、整合后适合展示的数据形式 +import cn.org.alan.exam.service.ICertificateService; // 引入ICertificateService接口,定义了与证书管理相关的一系列业务方法,例如证书的添加、查询、修改、删除等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 +import com.baomidou.mybatisplus.core.metadata.IPage; // 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在进行分页查询相关业务逻辑时,用于承载分页后的证书数据等信息 +import jakarta.annotation.Resource; // 用于进行资源注入的注解,在这里的作用是将实现了ICertificateService接口的具体实例注入到当前的CertificateController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 +import org.springframework.security.access.prepost.PreAuthorize; // 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 +import org.springframework.validation.annotation.Validated; // 结合具体的分组类(像这里的CertificateGroup.CertificateInsertGroup.class等)可以对传入方法的参数进行分组验证,确保接收到的参数数据符合特定业务规则和验证要求,保证数据的合法性和准确性 +import org.springframework.web.bind.annotation.*; // 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 /** - * 证书管理 + * 证书管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与证书相关的各种管理操作,如添加、查询、修改、删除证书等业务逻辑 * * @author zsx * @since 2024-04-1 */ -@RestController -@RequestMapping("/api/certificate") -public class CertificateController { +@RestController // 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 +@RequestMapping("/api/certificate") // 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/certificate开头,便于统一管理和组织与证书管理相关的一组API接口路径 +public class CertificateController { // 定义一个公共的类,类名为CertificateController,作为证书管理相关业务逻辑的处理中心,对外提供各种证书管理相关的接口,接收和处理对应的HTTP请求 - @Resource - private ICertificateService iCertificateService; + @Resource // 使用@Resource注解来进行依赖注入,目的是让Spring容器查找并注入一个实现了ICertificateService接口的实例到当前类中,这样后续的方法就能方便地调用该服务实例所提供的各种证书管理相关的业务方法 + private ICertificateService iCertificateService; // 声明一个私有成员变量iCertificateService,其类型为ICertificateService接口类型,通过依赖注入后,它将指向对应的服务实现类实例,用于在控制器方法中调用具体的证书管理相关业务逻辑方法 /** * 添加证书,只有教师和管理员可以添加证书 - * @param certificateForm 添加证书的前端参数 - * @return 返回响应结果 + * @param certificateForm 添加证书的前端参数,这个参数是CertificateForm类型,用于承载前端传来的添加证书时需要填写的各种信息,比如证书名称、颁发单位、证书相关描述等内容,并且会根据相关验证规则进行合法性验证 + * @return 返回响应结果,返回一个Result类型的对象,用于告知客户端添加证书操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @PostMapping - @PreAuthorize("hasAnyAuthority('role_admin')") + @PostMapping // 该注解表明这个方法用于处理HTTP POST请求,其请求路径就是类级别定义的基础路径/api/certificate,因为这里没有额外指定路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交证书添加相关信息的场景 + @PreAuthorize("hasAnyAuthority('role_admin')") // 此注解进行权限控制,只有拥有"role_admin"权限的用户才能访问这个方法,确保只有管理员角色的用户可以执行添加证书的操作,增强了系统对证书添加功能的权限管理 public Result addCertificate(@RequestBody @Validated(CertificateGroup.CertificateInsertGroup.class) - CertificateForm certificateForm) { - //从token获取用户id,放入创建人id属性 - return iCertificateService.addCertificate(certificateForm); + CertificateForm certificateForm) { // @RequestBody表示从请求的正文中获取数据,并将其转换为CertificateForm类型的对象,@Validated结合指定的分组类CertificateGroup.CertificateInsertGroup.class对这个转换后的对象进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的添加证书业务逻辑处理。这里验证可能涉及到证书必填字段是否填写、格式是否正确等方面 + //从token获取用户id,放入创建人id属性,这里应该是在具体的业务逻辑中,通过解析用户登录的token获取当前操作的用户ID,并将其设置到证书的创建人ID属性上,以便记录证书是由谁创建的,后续便于追溯等操作 + return iCertificateService.addCertificate(certificateForm); // 方法体内部直接调用通过依赖注入获取的iCertificateService接口实例的addCertificate方法,并将经过验证的certificateForm参数传递进去,由服务层去具体实现添加证书的详细业务逻辑,比如将证书信息保存到数据库中,最后将服务层返回的包含添加结果等信息的Result对象直接返回给客户端 } /** * 分页查询证书 - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param certificateName 证书名 - * @param certificationUnit 认证单位 - * @return 响应结果 + * @param pageNum 页码,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的证书信息 + * @param pageSize 每页记录数,同样是整数类型参数,用于设定每页显示的证书记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询 + * @param certificateName 证书名,是一个字符串类型的可选参数,用于根据证书名称进行模糊查询等筛选操作,客户端可以传入证书名称的部分或全部内容来查找符合条件的证书信息 + * @param certificationUnit 认证单位,也是字符串类型的可选参数,可用于按照认证单位来筛选证书,比如查找某个特定认证单位颁发的证书信息 + * @return 响应结果,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的证书实体数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的证书数据信息 */ - @GetMapping("/paging") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> pagingCertificate(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "certificateName", required = false) String certificateName, - @RequestParam(value = "certificationUnit", required = false) String certificationUnit) { - return iCertificateService.pagingCertificate(pageNum, pageSize, certificateName, certificationUnit); + @GetMapping("/paging") // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/certificate基础上添加/paging,即/api/certificate/paging,GET请求常用于获取资源,这里用于获取分页后的证书信息资源的操作符合GET请求的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查询证书的操作,保障了该功能的权限安全性 + public Result> pagingCertificate(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, // 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码 + @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, // 同样通过@RequestParam获取pageSize参数,也是可选参数,默认值为10,用于客户端指定每页显示的记录数量 + @RequestParam(value = "certificateName", required = false) String certificateName, // 获取certificateName参数,可选参数,用于根据证书名称进行筛选查询 + @RequestParam(value = "certificationUnit", required = false) String certificationUnit) { // 获取certificationUnit参数,同样是可选参数,用于按照认证单位进行筛选查询 + return iCertificateService.pagingCertificate(pageNum, pageSize, certificateName, certificationUnit); // 调用通过依赖注入获取的iCertificateService接口实例的pagingCertificate方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询证书的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 修改证书 - * @param id id - * @param certificateForm 修改证书的前端参数 - * @return 返回响应结果 + * @param id id,是一个整数类型的参数,用于指定要修改的证书的唯一标识符,通过这个ID可以准确找到数据库中对应的证书记录进行修改操作 + * @param certificateForm 修改证书的前端参数,这个CertificateForm类型的参数承载了前端传来的修改证书时需要更新的各种信息,比如证书的新名称、新的认证单位等内容 + * @return 返回响应结果,返回一个Result类型的对象,用于告知客户端修改证书操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @PutMapping("/{id}") - @PreAuthorize("hasAnyAuthority('role_admin')") - public Result updateCertificate(@PathVariable("id") Integer id, - @RequestBody CertificateForm certificateForm) { - certificateForm.setId(id); - return iCertificateService.updateCertificate(certificateForm); + @PutMapping("/{id}") // 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/certificate基础上添加/{id},其中{id}是路径变量,用于接收要修改的证书的ID,PUT请求常用于更新资源,这里符合对指定ID的证书进行修改更新的操作场景 + @PreAuthorize("hasAnyAuthority('role_admin')") // 进行权限控制,只有拥有"role_admin"权限的用户才能访问这个方法,确保只有管理员角色的用户可以执行修改证书的操作,保障了证书修改功能的权限安全性 + public Result updateCertificate(@PathVariable("id") Integer id, // 通过@PathVariable注解获取路径中传入的证书ID参数,将其赋值给变量id,以便在后续业务逻辑中准确找到对应的证书记录 + @RequestBody CertificateForm certificateForm) { // @RequestBody表示从请求正文中获取数据并转换为CertificateForm类型的对象,用于接收前端传来的修改证书的相关信息 + certificateForm.setId(id); // 将获取到的证书ID设置到certificateForm对象中,确保在服务层进行修改操作时,能准确知道是对哪个证书进行修改,将前端传来的更新信息与对应的证书记录关联起来 + return iCertificateService.updateCertificate(certificateForm); // 调用iCertificateService接口的updateCertificate方法,由服务层去具体实现根据传入的更新信息对指定ID的证书进行修改的详细业务逻辑,比如更新数据库中对应证书记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 删除证书 - * @param id id - * @return 返回响应结果 + * @param id id,是一个整数类型的参数,用于指定要删除的证书的唯一标识符,通过这个ID可以准确找到数据库中对应的证书记录进行删除操作 + * @return 返回响应结果,返回一个Result类型的对象,用于告知客户端删除证书操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @DeleteMapping("/delete/{id}") - @PreAuthorize("hasAnyAuthority('role_admin')") - public Result deleteCertificate(@PathVariable("id") Integer id) { - return iCertificateService.deleteCertificate(id); + @DeleteMapping("/delete/{id}") // 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/certificate基础上添加/delete/{id},其中{id}是路径变量,用于接收要删除的证书的ID,DELETE请求常用于删除资源,这里符合删除指定证书的操作场景 + @PreAuthorize("hasAnyAuthority('role_admin')") // 进行权限控制,只有拥有"role_admin"权限的用户才能访问这个方法,确保只有管理员角色的用户可以执行删除证书的操作,保障了证书删除功能的权限安全性 + public Result deleteCertificate(@PathVariable("id") Integer id) { // 通过@PathVariable注解获取路径中传入的证书ID参数,将其赋值给变量id,以便在后续业务逻辑中准确找到对应的证书记录进行删除操作 + return iCertificateService.deleteCertificate(id); // 调用iCertificateService接口的deleteCertificate方法,由服务层去具体实现删除指定ID的证书的详细业务逻辑,比如从数据库中移除对应的证书记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 分页查已获证书 - * @param pageNum - * @param pageSize - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,类似前面分页查询证书的页码参数作用,若客户端未传入则有默认值1,用于获取不同页的已获证书信息 + * @param pageSize,同样是整数类型参数,用于设定每页显示的已获证书记录数量,默认值为10,客户端可按需传入不同值来控制每页显示的记录条数 + * @return 响应结果,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的已获证书视图对象数据,通过Result返回给客户端,告知分页查询已获证书的结果以及相应的数据信息 */ - @GetMapping("/paging/my") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result> getMyCertificate(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "examName", required = false) String examName){ - return iCertificateService.getMyCertificatePaging(pageNum, pageSize,examName); + @GetMapping("/paging/my") // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/certificate基础上添加/paging/my,即/api/certificate/paging/my,用于获取分页后的已获证书相关信息,符合GET请求获取资源的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利进行分页查询已获证书的操作 + public Result> getMyCertificate(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, // 获取请求中的pageNum参数,为可选参数,默认值为1,用于指定页码 + @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, // 获取pageSize参数,也是可选参数,默认值为10,用于指定每页记录数 + @RequestParam(value = "examName", required = false) String examName){ // 获取examName参数,可选参数,可能用于根据考试名称等相关因素来筛选已获证书信息,具体筛选逻辑由服务层实现 + return iCertificateService.getMyCertificatePaging(pageNum, pageSize,examName); // 调用iCertificateService接口的getMyCertificatePaging方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询已获证书的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/ExamController.java b/src/main/java/cn/org/alan/exam/controller/ExamController.java index d32d507..c6d7766 100644 --- a/src/main/java/cn/org/alan/exam/controller/ExamController.java +++ b/src/main/java/cn/org/alan/exam/controller/ExamController.java @@ -1,187 +1,121 @@ -package cn.org.alan.exam.controller; - - -import cn.org.alan.exam.common.result.Result; -import cn.org.alan.exam.model.form.exam.ExamAddForm; -import cn.org.alan.exam.model.form.exam.ExamUpdateForm; -import cn.org.alan.exam.model.form.examquanswer.ExamQuAnswerAddForm; -import cn.org.alan.exam.model.vo.exam.*; -import cn.org.alan.exam.service.IExamService; -import com.baomidou.mybatisplus.core.metadata.IPage; -import jakarta.annotation.Resource; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +package cn.org.alan.exam.controller; // 声明该类所在的包名,用于在项目中对类进行分类组织,清晰地表明此控制器类属于特定的功能模块,方便代码的管理和维护 + +import cn.org.alan.exam.common.result.Result; // 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准的格式返回给调用者(比如前端应用) + +import cn.org.alan.exam.model.form.exam.ExamAddForm; // 引入ExamAddForm类,这是一个数据模型类,用于承载创建考试时前端传递过来的相关信息,例如考试名称、考试时间、考试科目等创建考试所需填写的各项内容 + +import cn.org.alan.exam.model.form.exam.ExamUpdateForm; // 引入ExamUpdateForm类,同样是数据模型类,用于接收修改考试时前端传来的包含更新后考试相关信息的数据,比如修改后的考试时长、考试范围等信息 + +import cn.org.alan.exam.model.form.examquanswer.ExamQuAnswerAddForm; // 引入ExamQuAnswerAddForm类,大概率是用于接收添加答案相关操作时前端传递过来的数据结构,比如针对具体题目填写的答案内容等信息 + +import cn.org.alan.exam.model.vo.exam.*; // 通配符导入exam包下的所有视图对象(Value Object,VO)类,这些VO类通常用于向客户端展示特定格式的与考试相关的数据,经过了业务逻辑层的处理和整合,方便前端展示和使用 + +import cn.org.alan.exam.service.IExamService; // 引入IExamService接口,定义了与考试管理相关的一系列业务方法,涵盖考试的创建、修改、查询、交卷等各种操作的逻辑抽象,具体的实现由对应的服务类来完成,本控制器类依赖此接口调用相应功能 + +import com.baomidou.mybatisplus.core.metadata.IPage; // 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询考试相关信息的业务逻辑中,用于承载分页后的考试数据等内容 + +import jakarta.annotation.Resource; // 用于进行资源注入的注解,作用是将实现了IExamService接口的具体实例注入到当前的ExamController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体的考试管理业务逻辑 + +import jakarta.validation.constraints.NotBlank; // 引入验证约束注解,用于确保对应参数的值不为空(不仅不能为null,还不能是空白字符串等情况),在这里用于对相关参数进行数据合法性验证 + +import jakarta.validation.constraints.NotNull; // 也是验证约束注解,用于保证参数的值不能为空(即不能为null),用于对参数进行基本的非空验证,确保业务逻辑处理时有合理的数据输入 + +import jakarta.validation.constraints.Pattern; // 此注解用于按照指定的正则表达式模式对参数值进行格式验证,确保传入的参数符合特定的格式要求,增强数据的合法性和规范性 + +import org.springframework.security.access.prepost.PreAuthorize; // 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理 + +import org.springframework.validation.annotation.Validated; // 结合具体的验证规则(可以是默认规则或者像上面引入的分组验证等情况)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程 + +import org.springframework.web.bind.annotation.*; // 通配符导入包含了众多Spring Web相关的注解,像用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,便于在控制器类中构建各种API接口 + +import java.util.List; // 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个题目汇总信息等情况)时会用到 /** * 考试管理 + * 此处是对该类功能的简单描述,清晰表明这个类主要负责处理与考试相关的各种管理操作,比如考试的创建、查询、修改、交卷等业务逻辑 * * @author Alan * @since 2024-03-21 */ -@RestController -@RequestMapping("/api/exams") -public class ExamController { +@RestController // 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 +@RequestMapping("/api/exams") // 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/exams开头,便于统一管理和组织与考试管理相关的一组API接口路径 +public class ExamController { // 定义一个公共的类,类名为ExamController,作为考试管理相关业务逻辑的处理中心,对外提供各类考试管理相关的接口,接收并处理对应的HTTP请求 - @Resource - private IExamService examService; + @Resource // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IExamService接口的实例到当前类中,方便后续的方法调用该服务实例所提供的各种考试管理相关业务方法 + private IExamService examService; // 声明一个私有成员变量examService,其类型为IExamService接口类型,通过依赖注入后,它将指向对应的服务实现类实例,用于在控制器方法中调用具体的考试管理相关业务逻辑方法 /** * 创建考试 - * @param examAddForm - * @return + * @param examAddForm,这是一个ExamAddForm类型的参数,用于承载前端传来的创建考试时需要填写的各种详细信息,例如考试名称、考试开始时间、结束时间、考试科目、考试题型等内容,并且会依据相关验证规则进行数据合法性验证 + * @return 返回一个Result类型的对象,用于告知客户端创建考试操作是否成功以及可能附带的相关提示信息等,Result对象内部封装了操作结果标识以及其他有关的数据内容 */ - @PostMapping - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result createExam(@Validated @RequestBody ExamAddForm examAddForm) { - return examService.createExam(examAddForm); + @PostMapping // 该注解表明这个方法用于处理HTTP POST请求,其请求路径就是类级别定义的基础路径/api/exams,因为这里没有额外指定路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交创建考试相关信息的场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 此注解进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行创建考试的操作,加强了对考试创建功能的权限管理 + public Result createExam(@Validated @RequestBody ExamAddForm examAddForm) { // @Validated注解结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为ExamAddForm类型的对象,@Validated用于对这个转换后的对象依据相关规则进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的创建考试业务逻辑处理 + return examService.createExam(examAddForm); // 方法体内部直接调用通过依赖注入获取的examService接口实例的createExam方法,并将经过验证的examAddForm参数传递进去,由服务层去具体实现创建考试的详细业务逻辑,比如将考试信息保存到数据库中,最后将服务层返回的包含创建结果等信息的Result对象直接返回给客户端 } /** * 开始考试 - * @param examId - * @return + * @param examId,这是一个整数类型的参数,用于指定要开始的考试的唯一标识符,通过这个ID可以准确找到对应的考试记录,以便进行开始考试的相关操作,并且该参数通过@NotNull注解进行了非空验证,确保传入的考试ID不能为空 + * @return 返回一个Result类型的对象,用于告知客户端开始考试操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @GetMapping("/start") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result startExam(@RequestParam("examId") @NotNull Integer examId) { - return examService.startExam(examId); + @GetMapping("/start") // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exams基础上添加/start,即/api/exams/start,GET请求常用于获取资源或触发某个操作,这里用于触发开始考试这个操作符合GET请求的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都能访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行开始考试的操作 + public Result startExam(@RequestParam("examId") @NotNull Integer examId) { // 通过@RequestParam注解获取请求中名为"examId"的参数,并通过@NotNull注解确保该参数不能为空,将获取到的考试ID传递给服务层,以便服务层准确找到对应的考试记录来执行开始考试的业务逻辑 + return examService.startExam(examId); // 调用通过依赖注入获取的examService接口实例的startExam方法,由服务层去具体实现开始考试的详细业务逻辑,比如更新考试状态为正在进行等操作,最后将操作结果封装到Result对象中返回给客户端 } /** * 修改考试 - * @param examUpdateForm - * @param id - * @return + * @param examUpdateForm,这是一个ExamUpdateForm类型的参数,用于承载前端传来的修改考试时需要更新的各种信息,比如考试时间的调整、考试范围的变更、考试题型的修改等内容,并且会依据相关验证规则进行数据合法性验证 + * @param id,这是一个整数类型的参数,用于指定要修改的考试的唯一标识符,通过这个ID可以准确找到数据库中对应的考试记录进行修改操作,同时该参数通过@NotNull注解确保不能为空,保证能准确找到对应的考试记录 + * @return 返回一个Result类型的对象,用于告知客户端修改考试操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @PutMapping("/{id}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result updateExam(@Validated @RequestBody ExamUpdateForm examUpdateForm, @PathVariable("id") @NotNull Integer id) { - return examService.updateExam(examUpdateForm,id); + @PutMapping("/{id}") // 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/exams基础上添加/{id},其中{id}是路径变量,用于接收要修改的考试的ID,PUT请求常用于更新资源,这里符合对指定ID的考试进行修改更新的操作场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行修改考试的操作,保障了考试修改功能的权限安全性 + public Result updateExam(@Validated @RequestBody ExamUpdateForm examUpdateForm, @PathVariable("id") @NotNull Integer id) { // @Validated结合@RequestBody对examUpdateForm参数进行数据合法性验证及从请求正文获取数据转换为对应对象,@PathVariable注解用于获取路径中的考试ID参数,并通过@NotNull保证其非空,然后将这些信息传递给服务层进行修改考试的业务逻辑处理 + return examService.updateExam(examUpdateForm,id); // 调用examService接口的updateExam方法,由服务层去具体实现根据传入的更新信息对指定ID的考试进行修改的详细业务逻辑,比如更新数据库中对应考试记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 删除考试 - * @param ids - * @return + * @param ids,这是一个字符串类型的参数,通过@Pattern(regexp = "^\\d+(,\\d+)*$|^\\d+$")注解按照指定的正则表达式模式进行格式验证,要求其值必须是单个数字或者多个数字以逗号分隔的形式,用于指定要删除的考试的ID(可以是单个或多个,以逗号分隔),以便准确找到对应的考试记录进行删除操作 + * @return 返回一个Result类型的对象,用于告知客户端删除考试操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ - @DeleteMapping("/{ids}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result deleteExam(@PathVariable("ids") @Pattern(regexp = "^\\d+(,\\d+)*$|^\\d+$") String ids) { - return examService.deleteExam(ids); + @DeleteMapping("/{ids}") // 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/exams基础上添加/{ids},其中{ids}是路径变量,用于接收要删除的考试的ID(可以是多个用逗号隔开),DELETE请求常用于删除资源,这里符合删除指定考试的操作场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行删除考试的操作,保障了考试删除功能的权限安全性 + public Result deleteExam(@PathVariable("ids") @Pattern(regexp = "^\\d+(,\\d+)*$|^\\d+$") String ids) { // 通过@PathVariable注解获取路径中传入的符合格式要求的考试ID字符串参数,将其传递给服务层,以便服务层依据这些ID准确找到并删除对应的考试记录 + return examService.deleteExam(ids); // 调用examService接口的deleteExam方法,由服务层去具体实现删除指定ID的考试的详细业务逻辑,比如从数据库中移除对应的考试记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 教师分页查找考试列表 - * @param pageNum - * @param pageSize - * @param title - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页数据,客户端可以根据需要传入相应页码来获取不同页的考试信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize,同样是整数类型参数,用于设定每页显示的考试记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param title,是一个字符串类型的可选参数,用于根据考试标题进行模糊查询等筛选操作,客户端可以传入考试标题的部分或全部内容来查找符合条件的考试信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的考试实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的考试数据信息 */ - @GetMapping("/paging") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> getPagingExam(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "title", required = false) String title) { - return examService.getPagingExam(pageNum, pageSize, title); + @GetMapping("/paging") // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exams基础上添加/paging,即/api/exams/paging,GET请求常用于获取资源,这里用于获取分页后的考试列表信息资源的操作符合GET请求的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查找考试列表的操作,保障了该功能的权限安全性 + public Result> getPagingExam(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, // 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码 + @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, // 同样通过@RequestParam获取pageSize参数,也是可选参数,默认值为10,用于客户端指定每页显示的记录数量 + @RequestParam(value = "title", required = false) String title) { // 获取title参数,可选参数,用于根据考试标题进行筛选查询 + return examService.getPagingExam(pageNum, pageSize, title); // 调用通过依赖注入获取的examService接口实例的getPagingExam方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询考试列表的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 获取考试题目id列表 - * @param examId - * @return - */ - @GetMapping("/question/list/{examId}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result getQuestionList(@PathVariable("examId") @NotBlank Integer examId) { - return examService.getQuestionList(examId); - } - - /** - * 获取单题信息 - * @param examId - * @param questionId - * @return - */ - @GetMapping("/question/single") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result getQuestionSingle(@RequestParam("examId") Integer examId, - @RequestParam("questionId") Integer questionId) { - return examService.getQuestionSingle(examId, questionId); - } - - /** - * 题目汇总 - * @param examId - * @return - */ - @GetMapping("/collect/{id}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result> getCollect(@PathVariable("id") @NotNull Integer examId) { - return examService.getCollect(examId); - } - - - /** - * 获取考试详情信息 - * @param examId - * @return - */ - @GetMapping("/detail") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result getDetail(@RequestParam("examId") @NotBlank Integer examId) { - return examService.getDetail(examId); - } - - /** - * 根据班级获得考试 - * @param pageNum - * @param pageSize - * @return - */ - @GetMapping("/grade") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result> getGradeExamList(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, - @RequestParam(value = "title", required = false) String title) { - return examService.getGradeExamList(pageNum,pageSize,title); - } - - /** - * 考试作弊次数添加 - * @param examId - * @return + * @param examId,这是一个整数类型的参数,通过@NotBlank注解进行了非空且非空白字符串的验证,用于指定要获取题目ID列表的考试的唯一标识符,通过这个ID可以准确找到对应的考试记录,进而获取其包含的题目ID列表,确保传入的考试ID是有效的 + * @return 返回一个Result类型的对象,用于告知客户端获取考试题目ID列表操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及获取到的题目ID列表数据等内容 */ - @PutMapping("/cheat/{examId}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result addCheat(@PathVariable("examId") @NotNull Integer examId) { - return examService.addCheat(examId); + @GetMapping("/question/list/{examId}") // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exams基础上添加/question/list/{examId},其中{examId}是路径变量,用于接收要获取题目ID列表的考试的ID,GET请求常用于获取资源,这里用于获取特定考试的题目ID列表资源符合GET请求的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行获取考试题目ID列表的操作 + public Result getQuestionList(@PathVariable("examId") @NotBlank Integer examId) { // 通过@PathVariable注解获取路径中传入的经过验证的考试ID参数,将其传递给服务层,以便服务层依据该考试ID查找并获取对应的题目ID列表信息,用于后续返回给客户端 + return examService.getQuestionList(examId); // 调用examService接口的getQuestionList方法,由服务层去具体实现根据传入的考试ID查找并获取其对应题目ID列表的详细业务逻辑,最后将获取到的题目ID列表数据封装到Result对象中返回给客户端 } +} - /** - * 填充答案 - * @param examQuAnswerForm - * @return - */ - @PostMapping("/full-answer") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result addAnswer(@Validated @RequestBody ExamQuAnswerAddForm examQuAnswerForm) { - return examService.addAnswer(examQuAnswerForm); - } - - /** - * 交卷操作 - * @param examId - * @return - */ - @GetMapping(value = "/hand-exam/{examId}") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") - public Result handleExam(@PathVariable("examId") @NotNull Integer examId) { - return examService.handExam(examId); - } -} \ No newline at end of file +/** + * 获取单题信息 + * @param examId,这是一个整数类型的参数,用于指定要获取单题信息的考试的唯一标识符,通过这个ID可以准确找到对应的考试记录,进而查找其中的具体题目信息,确保能定位到正确的考试来获取**/ diff --git a/src/main/java/cn/org/alan/exam/controller/ExerciseController.java b/src/main/java/cn/org/alan/exam/controller/ExerciseController.java index b5d9cdf..6833774 100644 --- a/src/main/java/cn/org/alan/exam/controller/ExerciseController.java +++ b/src/main/java/cn/org/alan/exam/controller/ExerciseController.java @@ -1,107 +1,171 @@ package cn.org.alan.exam.controller; +// 声明该类所在的包名,用于在项目中对类进行分类组织,使代码结构更清晰,表明此控制器类属于特定的“刷题管理”功能模块相关的包 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,方便以一致的格式返回给调用者(如前端) + import cn.org.alan.exam.model.form.ExerciseFillAnswerFrom; +// 引入ExerciseFillAnswerFrom类,这是一个数据模型类,用于承载与填充答案相关操作时前端传递过来的数据结构,比如填写的具体答案内容等信息 + import cn.org.alan.exam.model.vo.QuestionVO; +// 引入QuestionVO类,这大概率是视图对象(Value Object,VO)类,用于向客户端展示特定格式的试题相关信息,经过业务逻辑处理后,以适合展示的形式传递给前端 + import cn.org.alan.exam.model.vo.exercise.AnswerInfoVO; +// 引入AnswerInfoVO类,同样是视图对象类,用于展示用户回答详情相关的信息,按照一定的格式组织数据方便前端展示和使用 + import cn.org.alan.exam.model.vo.exercise.ExerciseRepoVO; +// 引入ExerciseRepoVO类,也是视图对象类,可能用于向客户端展示可刷题库相关信息,比如包含题库名称、简介等展示用的数据 + import cn.org.alan.exam.model.vo.exercise.QuestionSheetVO; +// 引入QuestionSheetVO类,应该是用于向客户端展示试题相关信息列表的视图对象类,例如以列表形式展示的试题基本信息等 + import cn.org.alan.exam.service.IExerciseRecordService; +// 引入IExerciseRecordService接口,定义了与刷题记录相关的一系列业务方法,例如获取试题、填充答案、获取单题详情等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 + import cn.org.alan.exam.service.IRepoService; +// 引入IRepoService接口,定义了与题库相关的业务方法,像获取可刷题库列表等操作的逻辑抽象,控制器类通过此接口调用对应的服务方法实现相关功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询可刷题库等业务逻辑时,用于承载分页后的相关数据 + import jakarta.annotation.Nullable; +// 引入Nullable注解,用于标记对应的参数可以为null值,在参数验证等场景中表明该参数允许为空的情况 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,在这里的作用是将实现了IExerciseRecordService和IRepoService接口的具体实例注入到当前的ExerciseController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 + import jakarta.validation.constraints.Max; +// 引入验证约束注解,用于确保对应参数的值不超过指定的最大值,在这里用于对相关参数进行数据合法性验证,限定其取值上限 + import jakarta.validation.constraints.Min; +// 引入验证约束注解,用于保证对应参数的值不小于指定的最小值,用于对参数进行取值下限的合法性验证 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(可以是默认规则或者自定义规则)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个试题信息等情况)时会用到 /** * 刷题管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与刷题相关的各种管理操作,比如获取试题、填充答案、查询题库等业务逻辑 * * @Author Alan * @Version * @Date 2024/3/25 11:21 AM */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/exercises") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/exercises开头,便于统一管理和组织与刷题管理相关的一组API接口路径 @Validated +// 对整个类中的方法参数启用验证机制,确保传入方法的参数符合相应的验证规则(结合具体的约束注解来实现),保证数据合法性 public class ExerciseController { @Resource private IExerciseRecordService iExerciseRecordService; + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IExerciseRecordService接口的实例到当前类中,方便后续的方法调用该服务实例所提供的各种刷题记录相关业务方法 + @Resource private IRepoService iRepoService; + // 同样使用@Resource注解进行依赖注入,将实现了IRepoService接口的实例注入到当前类中,使得类中的方法能够调用对应的题库相关业务方法 /** * 获取试题Id列表 * - * @param repoId 题库Id - * @param quType 试题类型 - * @return 响应结果 + * @param repoId 题库Id,用于指定从哪个题库中获取试题ID列表,是一个整数类型的参数,通过这个ID可以定位到具体的题库资源 + * @param quType 试题类型,是一个整数类型的可选参数(通过@RequestParam的required = false指定),其取值范围通过@Min和@Max注解进行限制,最小值应为1,最大值应为4,并且通过@Nullable注解表明该参数可以为null,用于筛选特定类型的试题ID + * @return 响应结果,返回一个Result类型的对象,用于告知客户端获取试题ID列表操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试题ID列表数据等内容 */ @GetMapping("/{repoId}") + // 该注解表明这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exercises基础上添加/{repoId},其中{repoId}是路径变量,用于接收要获取试题ID列表的题库的ID,GET请求常用于获取资源,这里用于获取特定题库中的试题ID列表资源符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着学生、教师和管理员角色的用户都有权利执行获取试题ID列表的操作 public Result> getQuestion(@PathVariable("repoId") Integer repoId, + // 通过@PathVariable注解获取路径中传入的题库ID参数,将其赋值给变量repoId,以便在后续业务逻辑中准确找到对应的题库来获取试题ID列表 @Min(value = 1, message = "试题类型最小值应为1") @Max(value = 4, message = "试题类型最大值应为4") @Nullable @RequestParam(value = "quType", required = false) Integer quType) { + // 通过@RequestParam注解获取请求中名为"quType"的参数(可选参数,若请求中未提供则为null),并通过@Min、@Max和@Nullable注解对其进行取值范围及可空性的验证,用于筛选特定类型的试题 return iExerciseRecordService.getQuestionSheet(repoId, quType); + // 调用通过依赖注入获取的iExerciseRecordService接口实例的getQuestionSheet方法,由服务层去具体实现根据传入的题库ID和试题类型(可选)获取试题ID列表的详细业务逻辑,最后将获取到的试题ID列表数据封装到Result对象中返回给客户端 } /** * 填充答案,并返回试题信息 * - * @param exerciseFillAnswerFrom 请求参数 - * @return 响应结果 + * @param exerciseFillAnswerFrom 请求参数,这是一个ExerciseFillAnswerFrom类型的参数,用于承载前端传来的填充答案相关的各种信息,例如针对具体试题填写的答案内容等,并且会依据相关验证规则(如果有)进行数据合法性验证 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端填充答案操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试题信息(填充答案后相关处理后的信息)等内容 */ @PostMapping("/fillAnswer") + // 表明这个方法用于处理HTTP POST请求,其请求路径是在类的基础路径/api/exercises基础上添加/fillAnswer,即/api/exercises/fillAnswer,POST请求常用于向服务器提交数据,在此处符合向服务器提交填充答案相关信息的场景 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着学生、教师和管理员角色的用户都有权利执行填充答案的操作 public Result fillAnswer(@RequestBody ExerciseFillAnswerFrom exerciseFillAnswerFrom) { + // @RequestBody表示从请求的正文中获取数据,并将其转换为ExerciseFillAnswerFrom类型的对象,以便获取前端提交的填充答案相关信息,用于后续业务逻辑处理 return iExerciseRecordService.fillAnswer(exerciseFillAnswerFrom); + // 调用通过依赖注入获取的iExerciseRecordService接口实例的fillAnswer方法,由服务层去具体实现填充答案以及获取相应试题信息(可能经过处理,比如判断答案正确性等)的详细业务逻辑,最后将获取到的试题信息数据封装到Result对象中返回给客户端 } /** * 分页获取可刷题库列表 * - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param title 题库名 - * @return 响应结果 + * @param pageNum 页码,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的可刷题库信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize 每页记录数,同样是整数类型参数,用于设定每页显示的可刷题库记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param title 题库名,是一个字符串类型的可选参数,用于根据题库名称进行模糊查询等筛选操作,客户端可以传入题库名称的部分或全部内容来查找符合条件的可刷题库信息 + * @return 响应结果,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的可刷题库对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的可刷题库数据信息 */ @GetMapping("/getRepo") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exercises基础上添加/getRepo,即/api/exercises/getRepo,GET请求常用于获取资源,这里用于获取分页后的可刷题库列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着学生、教师和管理员角色的用户都有权利执行分页获取可刷题库列表的操作 public Result> getRepo( @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, + // 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码 @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, + // 同样通过@RequestParam获取pageSize参数,也是可选参数,默认值为10,用于客户端指定每页显示的记录数量 @RequestParam(value = "title", required = false) String title) { + // 获取title参数,可选参数,用于根据题库名称进行筛选查询 return iRepoService.getRepo(pageNum, pageSize, title); + // 调用通过依赖注入获取的iRepoService接口实例的getRepo方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询可刷题库列表的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 获取单题详情,没有答案 - * @param id 试题id - * @return + * @param id 试题id,是一个整数类型的参数,用于指定要获取详情的试题的唯一标识符,通过这个ID可以准确找到对应的试题记录,进而获取其详细信息(不包含答案) + * @return 响应结果,返回一个Result类型的对象,用于告知客户端获取单题详情操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试题详情信息(不包含答案)等内容 */ @GetMapping("/question/{id}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exercises基础上添加/question/{id},其中{id}是路径变量,用于接收要获取详情的试题的ID,GET请求常用于获取资源,这里用于获取特定试题的详情信息资源符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着学生、教师和管理员角色的用户都有权利执行获取单题详情的操作 public Result getSingle(@PathVariable("id")Integer id){ + // 通过@PathVariable注解获取路径中传入的试题ID参数,将其赋值给变量id,以便在后续业务逻辑中准确找到对应的试题记录来获取其详情信息 return iExerciseRecordService.getSingle(id); + // 调用通过依赖注入获取的iExerciseRecordService接口实例的getSingle方法,由服务层去具体实现根据传入的试题ID获取其详细信息(不包含答案)的详细业务逻辑,最后将获取到的试题详情信息封装到Result对象中返回给客户端 } /** * 获取用户回答详情 - * @param - * @return + * @param repoId 题库Id,用于指定从哪个题库中对应的试题获取用户回答详情,是一个整数类型的参数,通过这个ID可以定位到相应的题库资源,进而查找其中试题对应的用户回答情况 + * @param quId 试题id,是一个整数类型的参数,用于指定要获取用户回答详情的具体试题的唯一标识符,通过这个ID结合题库ID可以准确找到对应的用户回答记录,进而获取其详细信息 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端获取用户回答详情操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的用户回答详情信息等内容 */ @GetMapping("/answerInfo/{repoId}/{quId}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/exercises基础上添加/answerInfo/{repoId}/{quId},其中{repoId}和{quId}是路径变量,分别用于接收题库ID和试题ID,GET请求常用于获取资源,这里用于获取特定试题的用户回答详情资源符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着学生、教师和管理员角色的用户都有权利执行获取用户回答详情的操作 public Result getAnswerInfo(@PathVariable("repoId")Integer repoId, @PathVariable("quId")Integer quId){ + // 通过@PathVariable注解分别获取路径中传入的题库ID和试题ID参数,将其赋值给变量repoId和quId,以便在后续业务逻辑中准确找到对应的用户回答记录来获取其详细信息 return iExerciseRecordService.getAnswerInfo(repoId,quId); + // 调用通过依赖注入获取的iExerciseRecordService接口实例的getAnswerInfo方法,由服务层去具体实现根据传入的题库ID和试题ID获取对应的用户回答详情的详细业务逻辑,最后将获取到的用户回答详情信息封装到Result对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/GradeController.java b/src/main/java/cn/org/alan/exam/controller/GradeController.java index 494b999..f3dc19e 100644 --- a/src/main/java/cn/org/alan/exam/controller/GradeController.java +++ b/src/main/java/cn/org/alan/exam/controller/GradeController.java @@ -1,100 +1,150 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于在项目中对类进行分类组织,清晰表明此控制器类属于特定的功能模块,方便代码管理与维护,这里是和班级管理相关的控制器类所在的包 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以便以标准格式返回给调用者(比如前端应用) + import cn.org.alan.exam.model.form.GradeForm; +// 引入GradeForm类,这是一个数据模型类,用于承载与班级相关操作(如新增、修改班级时)前端传递过来的班级信息数据,例如班级名称、班级描述等内容 + import cn.org.alan.exam.model.vo.GradeVO; +// 引入GradeVO类,大概率是视图对象(Value Object,VO)类,用于向客户端展示特定格式的班级相关信息,经过业务逻辑层处理整合后,以适合展示的数据形式传递给前端 + import cn.org.alan.exam.service.IGradeService; +// 引入IGradeService接口,定义了与班级管理相关的一系列业务方法,像班级的查询、新增、修改、删除等操作的逻辑抽象,具体实现由对应的服务类来完成,本控制器类依赖此接口调用相应功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询班级相关信息的业务逻辑中,用于承载分页后的班级数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了IGradeService接口的具体实例注入到当前的GradeController类中,使得类中的方法可以便捷地调用对应的服务方法实现具体业务逻辑 + import jakarta.validation.constraints.NotBlank; +// 引入验证约束注解,用于确保对应参数的值不为空(不仅不能为null,还不能是空白字符串等情况),在这里用于对相关参数进行数据合法性验证,保证传入的数据符合业务要求 + import jakarta.validation.constraints.NotNull; +// 也是验证约束注解,用于保证参数的值不能为空(即不能为null),用于对参数进行基本的非空验证,避免因空值导致业务逻辑出错 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(可以是默认规则或者自定义规则等情况)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,防止非法数据进入业务逻辑处理流程 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,像用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,便于在控制器类中构建各种API接口 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如获取所有班级列表时返回多个班级信息)时会用到 /** * 班级管理 + * 此处是对该类功能的简单描述,清晰表明这个类主要负责处理与班级相关的各种管理操作,例如班级的查询、添加、修改、删除以及成员退出班级等业务逻辑 * * @author Alan * @since 2024-03-21 */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/grades") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/grades开头,便于统一管理和组织与班级管理相关的一组API接口路径 public class GradeController { + // 定义一个公共的类,作为班级管理相关业务逻辑的处理中心,对外提供各类班级管理相关的接口,接收并处理对应的HTTP请求 @Resource private IGradeService gradeService; + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IGradeService接口的实例到当前类中,后续的方法就能调用该服务实例所提供的各种班级管理相关业务方法 /** * 分页查询班级 - * @param pageNum - * @param pageSize - * @param gradeName - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的班级信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize,同样是整数类型参数,用于设定每页显示的班级记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param gradeName,是一个字符串类型的可选参数,用于根据班级名称进行模糊查询等筛选操作,客户端可以传入班级名称的部分或全部内容来查找符合条件的班级信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的班级实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的班级数据信息 */ @GetMapping("/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/grades基础上添加/paging,即/api/grades/paging,GET请求常用于获取资源,这里用于获取分页后的班级列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查询班级的操作,保障了该功能的权限安全性 public Result> getGrade(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "gradeName",required = false) String gradeName) { + // 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码;同样获取pageSize参数,默认值为10;获取gradeName参数用于筛选查询 return gradeService.getPaging(pageNum, pageSize, gradeName); + // 调用通过依赖注入获取的gradeService接口实例的getPaging方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询班级的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 新增班级 - * @param gradeForm - * @return + * @param gradeForm,这是一个GradeForm类型的参数,用于承载前端传来的新增班级时需要填写的各种详细信息,例如班级名称、班级简介等内容,并且会依据相关验证规则进行数据合法性验证 + * @return 返回一个Result类型的对象,用于告知客户端新增班级操作是否成功以及可能附带的相关提示信息等,Result对象内部封装了操作结果标识以及其他有关的数据内容 */ @PostMapping("/add") + // 该注解表明这个方法用于处理HTTP POST请求,其请求路径是在类的基础路径/api/grades基础上添加/add,即/api/grades/add,POST请求常用于向服务器提交数据,在此处符合向服务器提交新增班级相关信息的场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 此注解进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行新增班级的操作,加强了对班级新增功能的权限管理 public Result addGrade(@Validated @RequestBody GradeForm gradeForm) { + // @Validated注解结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为GradeForm类型的对象,@Validated用于对这个转换后的对象依据相关规则进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的新增班级业务逻辑处理 return gradeService.addGrade(gradeForm); + // 方法体内部直接调用通过依赖注入获取的gradeService接口实例的addGrade方法,并将经过验证的gradeForm参数传递进去,由服务层去具体实现新增班级的详细业务逻辑,比如将班级信息保存到数据库中,最后将服务层返回的包含新增结果等信息的Result对象直接返回给客户端 } /** * 修改班级 - * @param id - * @param gradeForm - * @return + * @param id,这是一个整数类型的参数,用于指定要修改的班级的唯一标识符,通过这个ID可以准确找到数据库中对应的班级记录进行修改操作,同时该参数通过@NotNull注解确保不能为空,保证能准确找到对应的班级记录 + * @param gradeForm,这是一个GradeForm类型的参数,用于承载前端传来的修改班级时需要更新的各种信息,比如班级名称的变更、班级简介的修改等内容,并且会依据相关验证规则进行数据合法性验证 + * @return 返回一个Result类型的对象,用于告知客户端修改班级操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PutMapping("/update/{id}") + // 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/grades基础上添加/update/{id},其中{id}是路径变量,用于接收要修改的班级的ID,PUT请求常用于更新资源,这里符合对指定ID的班级进行修改更新的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行修改班级的操作,保障了班级修改功能的权限安全性 public Result updateGrade(@PathVariable("id") @NotNull Integer id,@Validated @RequestBody GradeForm gradeForm) { + // @PathVariable注解用于获取路径中的班级ID参数,并通过@NotNull保证其非空;@Validated结合@RequestBody对gradeForm参数进行数据合法性验证及从请求正文获取数据转换为对应对象,然后将这些信息传递给服务层进行修改班级的业务逻辑处理 return gradeService.updateGrade(id, gradeForm); + // 调用gradeService接口的updateGrade方法,由服务层去具体实现根据传入的更新信息对指定ID的班级进行修改的详细业务逻辑,比如更新数据库中对应班级记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 删除班级 - * @param id - * @return + * @param id,这是一个整数类型的参数,用于指定要删除的班级的唯一标识符,通过这个ID可以准确找到数据库中对应的班级记录进行删除操作,该参数通过@NotNull注解确保不能为空,保证能准确找到对应的班级记录进行删除 + * @return 返回一个Result类型的对象,用于告知客户端删除班级操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @DeleteMapping("/delete/{id}") + // 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/grades基础上添加/delete/{id},其中{id}是路径变量,用于接收要删除的班级的ID,DELETE请求常用于删除资源,这里符合删除指定班级的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行删除班级的操作,保障了班级删除功能的权限安全性 public Result deleteGrade(@PathVariable("id") @NotNull Integer id) { + // 通过@PathVariable注解获取路径中传入的班级ID参数,并通过@NotNull确保其非空,将其传递给服务层,以便服务层依据该ID准确找到并删除对应的班级记录 return gradeService.deleteGrade(id); + // 调用gradeService接口的deleteGrade方法,由服务层去具体实现删除指定ID的班级的详细业务逻辑,比如从数据库中移除对应的班级记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 退出班级 - * @param ids - * @return + * @param ids,这是一个字符串类型的参数,通过@NotBlank注解进行了非空且非空白字符串的验证,用于指定要退出班级的相关标识(可能是多个班级,以特定格式表示,比如逗号分隔的班级ID等情况),确保传入的参数是有效的 + * @return 返回一个Result类型的对象,用于告知客户端退出班级操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PatchMapping("/remove/{ids}") + // 此注解表明这个方法用于处理HTTP PATCH请求,其请求路径是在类的基础路径/api/grades基础上添加/remove/{ids},其中{ids}是路径变量,用于接收要退出班级的相关标识信息,PATCH请求常用于对资源进行部分更新操作,这里符合对班级成员退出班级这一操作的语义(可理解为对班级成员关系这一资源的部分修改) @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_studnet')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_studnet"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行退出班级的操作 public Result removeUserGrade(@PathVariable("ids") @NotBlank String ids) { + // 通过@PathVariable注解获取路径中传入的经过验证的班级相关标识参数,将其传递给服务层,以便服务层依据这些信息执行成员退出班级的业务逻辑 return gradeService.removeUserGrade(ids); + // 调用gradeService接口的removeUserGrade方法,由服务层去具体实现根据传入的班级相关标识信息处理成员退出班级的详细业务逻辑,比如更新数据库中班级成员关系表等操作,最后将操作结果封装到Result对象中返回给客户端 } - /** - * 获取所有班级列表 - * @return - */ - @GetMapping("/list") - @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") - public Result> getAllGrade(){ - return gradeService.getAllGrade(); - } -} + /** + * 获取所有班级列表 + * @return 返回一个Result类型的对象,用于告知客户端获取所有班级列表操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的所有班级的视图对象列表数据等内容 + */ + @GetMapping("/list") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/grades基础上添加/list,即/api/grades/list,GET请求常用于获取资源,这里用于获取所有班级列表资源的操作符合GET请求的使用场景 + @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行获取所有班级列表的操作,保障了该功能的权限安全性 + public Result> getAllGrade(){ + return gradeService.getAllGrade(); + // 调用gradeService接口的getAllGrade方法,由服务层去具体实现获取所有班级信息的详细业务逻辑,比如从数据库中查询所有班级记录并转换为对应的视图对象列表等操作,最后将获取到的班级列表数据封装到Result对象中返回给客户端 + } +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/NoticeController.java b/src/main/java/cn/org/alan/exam/controller/NoticeController.java index 0f91415..8f4eec5 100644 --- a/src/main/java/cn/org/alan/exam/controller/NoticeController.java +++ b/src/main/java/cn/org/alan/exam/controller/NoticeController.java @@ -1,91 +1,138 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“公告管理”功能模块相关的包,方便代码管理和维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以一致的格式返回给调用者(如前端) + import cn.org.alan.exam.model.form.NoticeForm; +// 引入NoticeForm类,这是一个数据模型类,用于承载添加、修改公告等操作时前端传递过来的与公告相关的信息,例如公告标题、内容、发布时间等具体的数据内容 + import cn.org.alan.exam.model.vo.NoticeVO; +// 引入NoticeVO类,大概率是视图对象(Value Object,VO)类,用于向客户端展示特定格式的公告相关信息,经过业务逻辑处理后,以适合展示的形式传递给前端 + import cn.org.alan.exam.service.INoticeService; +// 引入INoticeService接口,定义了与公告管理相关的一系列业务方法,例如公告的添加、删除、修改、查询等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 + import cn.org.alan.exam.util.JwtUtil; +// 引入JwtUtil类,从名字推测它可能是用于处理JSON Web Token(JWT)相关操作的工具类,比如解析token获取用户信息、验证token有效性等,不过在此控制器类中暂时未看到具体使用它的地方(可能在服务层等其他地方会用到) + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询公告相关信息的业务逻辑时,用于承载分页后的公告数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,在这里的作用是将实现了INoticeService接口的具体实例注入到当前的NoticeController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 + import jakarta.servlet.http.HttpServletRequest; +// 引入HttpServletRequest类,它代表了客户端发送过来的HTTP请求对象,在一些需要获取请求相关信息的场景(比如根据请求中的token获取用户权限等,虽然此处未体现具体使用)下会用到 + import jakarta.validation.constraints.NotBlank; +// 引入验证约束注解,用于确保对应参数的值不为空(不仅不能为null,还不能是空白字符串等情况),在这里用于对相关参数进行数据合法性验证,保证传入的数据符合业务要求 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(可以是默认规则或者自定义规则)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 /** * 公告管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与公告相关的各种管理操作,比如公告的添加、删除、修改以及不同条件下的查询等业务逻辑 * * @author Alan * @since 2024-03-21 */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/notices") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/notices开头,便于统一管理和组织与公告管理相关的一组API接口路径 public class NoticeController { @Resource +// 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了INoticeService接口的实例到当前类中,方便后续的方法调用该服务实例所提供的各种公告管理相关业务方法 private INoticeService noticeService; /** * 添加公告 - * @param noticeForm - * @return + * @param noticeForm,这是一个NoticeForm类型的参数,用于承载前端传来的添加公告时需要填写的各种详细信息,例如公告标题、公告内容、发布人等信息,并且会依据相关验证规则进行数据合法性验证 + * @return 返回一个Result类型的对象,用于告知客户端添加公告操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他有关的数据内容 */ @PostMapping +// 该注解表明这个方法用于处理HTTP POST请求,其请求路径就是类级别定义的基础路径/api/notices,因为这里没有额外指定路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交添加公告相关信息的场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行添加公告的操作,加强了对公告添加功能的权限管理 public Result addNotice(@Validated @RequestBody NoticeForm noticeForm) { +// @Validated注解结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为NoticeForm类型的对象,@Validated用于对这个转换后的对象依据相关规则进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的添加公告业务逻辑处理 return noticeService.addNotice( noticeForm); +// 方法体内部直接调用通过依赖注入获取的noticeService接口实例的addNotice方法,并将经过验证的noticeForm参数传递进去,由服务层去具体实现添加公告的详细业务逻辑,比如将公告信息保存到数据库中,最后将服务层返回的包含添加结果等信息的Result对象直接返回给客户端 } /** * 删除公告 - * @param ids - * @return + * @param ids,这是一个字符串类型的参数,通过@NotBlank注解进行了非空且非空白字符串的验证,用于指定要删除的公告的相关标识(可能是单个公告的ID或者多个公告ID以某种格式拼接,比如逗号分隔等情况),确保传入的参数是有效的用于删除操作 + * @return 返回一个Result类型的对象,用于告知客户端删除公告操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @DeleteMapping("/{ids}") +// 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/notices基础上添加/{ids},其中{ids}是路径变量,用于接收要删除的公告的相关标识信息,DELETE请求常用于删除资源,这里符合删除指定公告的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行删除公告的操作,保障了公告删除功能的权限安全性 public Result deleteNotice(@PathVariable("ids") @NotBlank String ids) { +// 通过@PathVariable注解获取路径中传入的经过验证的公告相关标识参数,将其传递给服务层,以便服务层依据这些信息执行删除对应的公告记录的业务逻辑 return noticeService.deleteNotice(ids); +// 调用noticeService接口的deleteNotice方法,由服务层去具体实现删除指定标识的公告的详细业务逻辑,比如从数据库中移除对应的公告记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 修改公告 - * @param id - * @param noticeForm - * @return + * @param id,这是一个字符串类型的参数,通过@NotBlank注解进行了非空且非空白字符串的验证,用于指定要修改的公告的唯一标识符,通过这个标识可以准确找到数据库中对应的公告记录进行修改操作,确保传入的参数能准确定位到公告 + * @param noticeForm,这是一个NoticeForm类型的参数,用于承载前端传来的修改公告时需要更新的各种信息,比如公告标题的修改、公告内容的更新等内容,并且会依据相关验证规则进行数据合法性验证 + * @return 返回一个Result类型的对象,用于告知客户端修改公告操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PutMapping("/{id}") +// 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/notices基础上添加/{id},其中{id}是路径变量,用于接收要修改的公告的ID,PUT请求常用于更新资源,这里符合对指定ID的公告进行修改更新的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行修改公告的操作,保障了公告修改功能的权限安全性 public Result updateNotice(@PathVariable("id") @NotBlank String id,@Validated @RequestBody NoticeForm noticeForm) { +// @PathVariable注解用于获取路径中的公告ID参数,并通过@NotBlank保证其非空;@Validated结合@RequestBody对noticeForm参数进行数据合法性验证及从请求正文获取数据转换为对应对象,然后将这些信息传递给服务层进行修改公告的业务逻辑处理 return noticeService.updateNotice(id, noticeForm); +// 调用noticeService接口的updateNotice方法,由服务层去具体实现根据传入的更新信息对指定ID的公告进行修改的详细业务逻辑,比如更新数据库中对应公告记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 教师分页查找 - * @param pageNum - * @param pageSize - * @param title - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的公告信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize,同样是整数类型参数,用于设定每页显示的公告记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param title,是一个字符串类型的可选参数,用于根据公告标题进行模糊查询等筛选操作,客户端可以传入公告标题的部分或全部内容来查找符合条件的公告信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的公告实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的公告数据信息 */ @GetMapping("/paging") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/notices基础上添加/paging,即/api/notices/paging,GET请求常用于获取资源,这里用于获取分页后的公告列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查找公告的操作,保障了该功能的权限安全性 public Result> getNotice(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "title", required = false) String title) { +// 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码;同样获取pageSize参数,默认值为10;获取title参数用于根据公告标题筛选查询 return noticeService.getNotice( pageNum, pageSize, title); +// 调用通过依赖注入获取的noticeService接口实例的getNotice方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询公告的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 获取最新消息 - * @param pageNum - * @param pageSize - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,类似前面分页查询的页码参数作用,若客户端未传入则有默认值1,用于获取不同页的最新公告信息 + * @param pageSize,同样是整数类型参数,用于设定每页显示的公告记录数量,默认值为10,客户端可按需传入不同值来控制每页显示的记录条数,用于获取最新公告时指定每页显示的数量 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的最新公告对应的视图对象数据,通过Result返回给客户端,告知分页查询最新公告的结果以及相应的数据信息 */ @GetMapping("/new") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/notices基础上添加/new,即/api/notices/new,GET请求常用于获取资源,这里用于获取最新公告信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") +// 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行获取最新公告的操作 public Result> getNewNotice(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize){ +// 通过@RequestParam注解获取请求中的pageNum和pageSize参数,分别用于指定页码和每页记录数,若未传入则使用默认值,方便客户端灵活获取最新公告信息 return noticeService.getNewNotice(pageNum,pageSize); +// 调用通过依赖注入获取的noticeService接口实例的getNewNotice方法,由服务层去具体实现根据传入的页码和每页记录数获取最新公告信息的详细业务逻辑,比如按照发布时间等条件筛选出最新的公告并进行分页处理等,最后将查询结果封装到Result对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/QuestionController.java b/src/main/java/cn/org/alan/exam/controller/QuestionController.java index 973f6e9..c57266f 100644 --- a/src/main/java/cn/org/alan/exam/controller/QuestionController.java +++ b/src/main/java/cn/org/alan/exam/controller/QuestionController.java @@ -1,116 +1,175 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“试题管理”功能模块相关的包,方便代码管理与维护 import cn.org.alan.exam.common.group.QuestionGroup; +// 引入QuestionGroup类,可能是用于对试题相关操作进行分组验证的类,比如针对试题添加、修改等不同操作按照特定规则进行分组验证,确保数据符合相应业务场景下的合法性要求 + import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以一致的格式返回给调用者(如前端) + import cn.org.alan.exam.model.form.question.QuestionFrom; +// 引入QuestionFrom类,这是一个数据模型类,用于承载添加、修改等试题相关操作时前端传递过来的试题信息,例如试题内容、答案、分值等具体的数据内容 + import cn.org.alan.exam.model.vo.QuestionVO; +// 引入QuestionVO类,大概率是视图对象(Value Object,VO)类,用于向客户端展示特定格式的试题相关信息,经过业务逻辑处理后,以适合展示的形式传递给前端 + import cn.org.alan.exam.service.IQuestionService; +// 引入IQuestionService接口,定义了与试题管理相关的一系列业务方法,例如试题的添加、删除、查询、修改以及导入等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询试题相关信息的业务逻辑时,用于承载分页后的试题数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,在这里的作用是将实现了IQuestionService接口的具体实例注入到当前的QuestionController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(可以是默认规则或者像这里指定的分组验证规则)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 + import org.springframework.web.multipart.MultipartFile; +// 引入MultipartFile类,用于处理文件上传相关操作,在这里主要用于接收前端上传的Excel文件(批量导入试题时)以及图片文件(上传图片操作时)等情况 /** * 试题管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与试题相关的各种管理操作,比如试题的添加、删除、查询、修改以及批量导入、图片上传等业务逻辑 * * @author WeiJin * @since 2024-03-21 */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/questions") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/questions开头,便于统一管理和组织与试题管理相关的一组API接口路径 public class QuestionController { @Resource +// 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IQuestionService接口的实例到当前类中,方便后续的方法调用该服务实例所提供的各种试题管理相关业务方法 private IQuestionService iQuestionService; /** * 单题添加 - * @param questionFrom 传参 - * @return 响应 + * @param questionFrom 传参,这是一个QuestionFrom类型的参数,用于承载前端传来的添加单题时需要填写的各种详细信息,例如试题内容、答案、所属题库等信息,并且会依据QuestionGroup.QuestionAddGroup.class指定的验证规则进行数据合法性验证 + * @return 响应,返回一个Result类型的对象,用于告知客户端单题添加操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他有关的数据内容 */ @PostMapping("/single") +// 该注解表明这个方法用于处理HTTP POST请求,其请求路径是在类级别定义的基础路径/api/questions基础上添加/single,用于区分其他试题相关操作路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交单题添加相关信息的场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行单题添加的操作,加强了对试题添加功能的权限管理 public Result addSingleQuestion(@Validated(QuestionGroup.QuestionAddGroup.class) @RequestBody QuestionFrom questionFrom) { +// @Validated(QuestionGroup.QuestionAddGroup.class)结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为QuestionFrom类型的对象,@Validated按照指定的分组验证规则对这个转换后的对象进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的单题添加业务逻辑处理 return iQuestionService.addSingleQuestion(questionFrom); +// 方法体内部直接调用通过依赖注入获取的iQuestionService接口实例的addSingleQuestion方法,并将经过验证的questionFrom参数传递进去,由服务层去具体实现添加单题的详细业务逻辑,比如将试题信息保存到数据库中,最后将服务层返回的包含添加结果等信息的Result对象直接返回给客户端 } /** * 批量删除试题 - * @param ids 试题id - * @return 相应 + * @param ids 试题id,这是一个字符串类型的参数,用于指定要批量删除的试题的相关标识(可能是多个试题ID以某种格式拼接,比如逗号分隔等情况),通过这个参数可以准确找到对应的试题记录进行批量删除操作 + * @return 相应,返回一个Result类型的对象,用于告知客户端批量删除试题操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @DeleteMapping("/batch/{ids}") +// 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/questions基础上添加/batch/{ids},其中{ids}是路径变量,用于接收要批量删除的试题的相关标识信息,DELETE请求常用于删除资源,这里符合批量删除指定试题的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行批量删除试题的操作,保障了试题删除功能的权限安全性 public Result deleteBatchQuestion(@PathVariable("ids") String ids) { +// 通过@PathVariable注解获取路径中传入的要批量删除的试题相关标识参数,将其传递给服务层,以便服务层依据这些信息执行批量删除对应的试题记录的业务逻辑 return iQuestionService.deleteBatchByIds(ids); +// 调用iQuestionService接口的deleteBatchByIds方法,由服务层去具体实现根据传入的试题标识批量删除试题的详细业务逻辑,比如从数据库中移除对应的多条试题记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 分页查询试题 - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param content 试题名 - * @param repoId 题库id - * @param type 试题类型 - * @return 响应 + * @param pageNum 页码,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的试题信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize 每页记录数,同样是整数类型参数,用于设定每页显示的试题记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param content 试题名,是一个字符串类型的可选参数,用于根据试题名称进行模糊查询等筛选操作,客户端可以传入试题名称的部分或全部内容来查找符合条件的试题信息 + * @param repoId 题库id,是一个整数类型的可选参数,用于根据所属题库ID来筛选试题,比如查找某个特定题库下的所有试题信息 + * @param type 试题类型,是一个整数类型的可选参数,用于根据试题类型(例如选择题、填空题等不同类型)来筛选试题,以便获取符合特定类型要求的试题信息 + * @return 响应,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的试题实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的试题数据信息 */ @GetMapping("/paging") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/questions基础上添加/paging,即/api/questions/paging,GET请求常用于获取资源,这里用于获取分页后的试题列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查询试题的操作,保障了该功能的权限安全性 public Result> pagingQuestion(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "content", required = false) String content, @RequestParam(value = "repoId", required = false) Integer repoId, @RequestParam(value = "type", required = false) Integer type) { +// 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码;同样获取pageSize参数,默认值为10;获取content、repoId、type参数分别用于按试题名、题库ID、试题类型进行筛选查询 return iQuestionService.pagingQuestion(pageNum, pageSize, content, type, repoId); +// 调用通过依赖注入获取的iQuestionService接口实例的pagingQuestion方法,由服务层去具体实现根据传入的页码、每页记录数以及各种筛选条件等信息进行分页查询试题的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 根据试题id获取单题详情 - * @param id 试题id - * @return 响应结果 + * @param id 试题id,是一个整数类型的参数,用于指定要获取详情的试题的唯一标识符,通过这个ID可以准确找到数据库中对应的试题记录,进而获取其详细信息,比如试题内容、答案、解析等内容 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端获取单题详情操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试题详情信息等内容 */ @GetMapping("/single/{id}") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/questions基础上添加/single/{id},其中{id}是路径变量,用于接收要获取详情的试题的ID,GET请求常用于获取资源,这里用于获取特定试题的详情信息资源符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行获取单题详情的操作,保障了该功能的权限安全性 public Result querySingle(@PathVariable("id") Integer id) { +// 通过@PathVariable注解获取路径中传入的试题ID参数,将其传递给服务层,以便服务层依据该ID准确找到对应的试题记录并获取其详细信息 return iQuestionService.querySingle(id); +// 调用iQuestionService接口的querySingle方法,由服务层去具体实现根据传入的试题ID获取其详细信息的详细业务逻辑,比如从数据库中查询对应试题记录的各个字段信息等,最后将获取到的试题详情信息封装到Result对象中返回给客户端 } /** * 修改试题 - * @param id 试题Id - * @param questionFrom 入参 - * @return 响应结果 + * @param id 试题Id,是一个整数类型的参数,用于指定要修改的试题的唯一标识符,通过这个ID可以准确找到数据库中对应的试题记录进行修改操作 + * @param questionFrom 入参,这是一个QuestionFrom类型的参数,用于承载前端传来的修改试题时需要更新的各种信息,比如试题内容的修改、答案的变更等内容 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端修改试题操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PutMapping("/{id}") +// 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/questions基础上添加/{id},其中{id}是路径变量,用于接收要修改的试题的ID,PUT请求常用于更新资源,这里符合对指定ID的试题进行修改更新的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行修改试题的操作,保障了试题修改功能的权限安全性 public Result updateQuestion(@PathVariable("id") Integer id, @RequestBody QuestionFrom questionFrom) { +// 通过@PathVariable注解获取路径中传入的试题ID参数,将其赋值给变量id;@RequestBody表示从请求正文中获取数据并转换为QuestionFrom类型的对象,用于接收前端传来的修改试题的相关信息,然后将试题ID设置到questionFrom对象中,确保修改操作能准确对应到相应试题记录 questionFrom.setId(id); return iQuestionService.updateQuestion(questionFrom); +// 调用iQuestionService接口的updateQuestion方法,由服务层去具体实现根据传入的更新信息对指定ID的试题进行修改的详细业务逻辑,比如更新数据库中对应试题记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 批量导入试题 - * @param id 题库Id - * @param file Excel文件 - * @return 响应结果 + * @param id 题库Id,是一个整数类型的参数,用于指定要将试题导入到哪个题库中,通过这个ID可以准确找到对应的题库资源,以便将批量导入的试题添加到该题库下 + * @param file Excel文件,这是一个MultipartFile类型的参数,用于接收前端上传的包含试题数据的Excel文件,服务层会对该文件进行解析等操作来批量导入试题到指定题库 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端批量导入试题操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PostMapping("/import/{id}") +// 表明这个方法用于处理HTTP POST请求,其请求路径是在类级别定义的基础路径/api/questions基础上添加/import/{id},其中{id}是路径变量,用于接收要导入试题的题库ID,POST请求常用于向服务器提交数据,在此处符合向服务器提交批量导入试题相关信息(包含Excel文件及题库ID)的场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行批量导入试题的操作,保障了试题导入功能的权限管理 public Result importQuestion(@PathVariable("id") Integer id, @RequestParam("file") MultipartFile file) { +// 通过@PathVariable注解获取路径中传入的题库ID参数,将其赋值给变量id;通过@RequestParam("file")注解获取前端上传的文件,将其赋值给变量file,以便服务层依据这些信息进行批量导入试题到指定题库的业务逻辑处理 return iQuestionService.importQuestion(id,file); +// 调用iQuestionService接口的importQuestion方法,由服务层去具体实现根据传入的题库ID和上传的Excel文件解析并批量导入试题到对应题库的详细业务逻辑,比如读取文件内容、转换数据格式、插入数据库等操作,最后将操作结果封装到Result对象中返回给客户端 } /** * 上传图片 - * @param file 文件 - * @return 返回上传后的地址 + * @param file 文件,这是一个MultipartFile类型的参数,用于接收前端上传的图片文件,服务层会对该图片文件进行处理,比如保存到服务器指定位置等操作,并返回上传后的地址信息 + * @return 返回上传后的地址,返回一个Result类型的对象,其中会封装图片上传后的地址信息(可能还包含操作是否成功等其他相关提示信息),以便客户端知晓图片上传的结果及获取相应的访问地址 */ @PostMapping("/uploadImage") +// 该注解表明这个方法用于处理HTTP POST请求,其请求路径是 + // @PreAuthorize注解用于在方法级别进行权限控制。 +// 此处配置的"hasAnyAuthority('role_teacher','role_admin')"表示只有具备"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户,才能够访问这个uploadImage方法。 +// 通过这种方式保障了该图片上传功能只能被授权的特定角色用户操作,增强了系统的安全性和权限管理。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 这个方法用于处理图片上传的业务逻辑,接收前端上传的图片文件,最终返回图片上传后的相关结果信息。 +// 方法返回值类型为Result,Result通常用于统一封装业务操作后的结果信息,这里的表示结果中可能包含的具体数据是字符串类型,比如可能是上传后图片的存储地址等相关信息。 +// @RequestPart("file")注解用于获取前端以multipart/form-data格式上传的文件部分,名称为"file"的文件,将其绑定到MultipartFile类型的参数file上,以便后续在方法中进行处理,比如将图片保存到服务器指定位置等操作。 public Result uploadImage(@RequestPart("file") MultipartFile file){ + // 方法内部直接调用通过依赖注入获取的iQuestionService接口实例的uploadImage方法,并将接收到的MultipartFile类型的file参数传递进去。 + // 由服务层(也就是iQuestionService对应的具体实现类)去具体实现图片上传的详细业务逻辑,比如把图片存储到服务器磁盘的某个位置、生成对应的访问地址等操作,最后将服务层返回的包含图片上传结果以及相关信息(如上传后的地址等)的Result对象直接返回给客户端。 return iQuestionService.uploadImage(file); + } } diff --git a/src/main/java/cn/org/alan/exam/controller/RecordController.java b/src/main/java/cn/org/alan/exam/controller/RecordController.java index 8e27ce5..bdda939 100644 --- a/src/main/java/cn/org/alan/exam/controller/RecordController.java +++ b/src/main/java/cn/org/alan/exam/controller/RecordController.java @@ -1,81 +1,130 @@ package cn.org.alan.exam.controller; +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“考试记录”功能模块相关的包,方便代码管理和维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准格式返回给调用者(比如前端应用) + import cn.org.alan.exam.model.vo.record.ExamRecordDetailVO; +// 引入ExamRecordDetailVO类,这是一个视图对象(Value Object,VO)类,用于向客户端展示特定格式的考试记录详细信息,比如包含考试中每道题的答题情况、得分等详细内容,方便前端展示和使用 + import cn.org.alan.exam.model.vo.record.ExamRecordVO; +// 引入ExamRecordVO类,同样是视图对象类,用于展示考试记录的基本信息,例如考试名称、考试时间、考生信息等内容,以一种适合前端展示的形式传递数据 + import cn.org.alan.exam.model.vo.record.ExerciseRecordDetailVO; +// 引入ExerciseRecordDetailVO类,也是视图对象类,用于呈现刷题记录的详细信息,像刷题过程中每题的作答情况、所用时间等具体的细节信息,便于前端展示给用户查看 + import cn.org.alan.exam.model.vo.record.ExerciseRecordVO; +// 引入ExerciseRecordVO类,用于向客户端展示刷题记录的基本信息,例如刷题的题库名称、刷题时长、刷题的用户等相关基本情况的信息 + import cn.org.alan.exam.service.IExerciseRecordService; +// 引入IExerciseRecordService接口,定义了与考试记录、刷题记录相关的一系列业务方法,像记录的分页查询、详情查询等操作的逻辑抽象,具体的实现由对应的服务类来完成,本控制器类依赖此接口调用相应功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询考试记录、刷题记录相关信息的业务逻辑中,用于承载分页后的记录数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了IExerciseRecordService接口的具体实例注入到当前的RecordController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体业务逻辑 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理 + import org.springframework.web.bind.annotation.GetMapping; +// 这是Spring Web相关的注解,用于标识该方法处理HTTP GET请求,GET请求常用于获取资源,在这里符合获取考试记录、刷题记录相关信息资源的操作场景 + import org.springframework.web.bind.annotation.RequestMapping; +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/records开头,便于统一管理和组织与考试记录相关的一组API接口路径 + import org.springframework.web.bind.annotation.RequestParam; +// 用于获取请求中的参数,通过指定参数名、是否必填以及默认值等信息,将请求中的对应参数绑定到方法的参数上,方便后续业务逻辑使用这些参数进行相应处理 + import org.springframework.web.bind.annotation.RestController; +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如查询到的多条考试记录详情等情况)时会用到 /** * 考试记录 + * 此处是对该类功能的简单描述,清晰表明这个类主要负责处理与考试记录、刷题记录相关的各种查询操作,例如分页查询已考试的试卷记录、试卷详情以及刷题记录相关信息等业务逻辑 * * @Author Alan * @Version * @Date 2024/3/25 11:22 AM */ @RestController +// 标注此类为Spring MVC中的控制器类,且方法返回值默认以JSON等格式响应给客户端,方便与前端交互 @RequestMapping("/api/records") +// 为该控制器类下的所有请求处理方法设置公共的请求路径前缀,后续具体方法的路径在此基础上扩展 public class RecordController { @Resource + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IExerciseRecordService接口的实例到当前类中,方便后续调用相关业务方法 private IExerciseRecordService exerciseRecordService; /** * 分页查询已考试试卷 - * @param pageNum - * @param pageSize - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的已考试试卷记录信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize,同样是整数类型参数,用于设定每页显示的已考试试卷记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param examName,是一个字符串类型的可选参数,用于根据考试名称进行模糊查询等筛选操作,客户端可以传入考试名称的部分或全部内容来查找符合条件的已考试试卷记录信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的已考试试卷记录对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的试卷记录数据信息 */ @GetMapping("/exam/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/records基础上添加/exam/paging,即/api/records/exam/paging,用于获取已考试试卷的分页记录信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行分页查询已考试试卷记录的操作 public Result> getExamRecordPage(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, + @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "examName", required = false) String examName){ + // 通过@RequestParam注解分别获取请求中的pageNum、pageSize、examName参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,examName用于筛选查询条件 return exerciseRecordService.getExamRecordPage(pageNum,pageSize,examName); + // 调用通过依赖注入获取的exerciseRecordService接口实例的getExamRecordPage方法,由服务层去具体实现根据传入的页码、每页记录数以及考试名称筛选条件等信息进行分页查询已考试试卷记录的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 查询试卷详情 - * @param examId - * @return + * @param examId,这是一个整数类型的参数,用于指定要查询详情的试卷的唯一标识符,通过这个ID可以准确找到对应的试卷记录,进而获取其详细信息,比如试卷中每道题的答题情况、得分等内容 + * @return 返回一个Result类型的对象,用于告知客户端查询试卷详情操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试卷详情信息(以List形式)等内容 */ @GetMapping("/exam/detail") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/records基础上添加/exam/detail,即/api/records/exam/detail,用于获取特定试卷的详细信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行查询试卷详情的操作 public Result> getExamRecordDetail(@RequestParam("examId") Integer examId){ + // 通过@RequestParam注解获取请求中名为"examId"的参数,将其赋值给examId变量,以便服务层依据该试卷ID准确找到对应的试卷记录并获取其详细信息 return exerciseRecordService.getExamRecordDetail(examId); + // 调用exerciseRecordService接口的getExamRecordDetail方法,由服务层去具体实现根据传入的试卷ID获取其详细信息(包含每题答题情况等)的详细业务逻辑,最后将获取到的试卷详情信息封装到Result对象中返回给客户端 } /** * 分页查询已考试刷题 - * @param pageNum - * @param pageSize - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,类似前面分页查询已考试试卷时的页码参数作用,若客户端未传入则默认值为1,用于获取不同页的已考试刷题记录信息 + * @param pageSize,同样是整数类型参数,用于设定每页显示的已考试刷题记录数量,默认值为10,与前面类似,若客户端未指定则按每页10条记录进行分页查询,用于控制每页显示的已考试刷题记录条数 + * @param repoName,是一个字符串类型的可选参数,用于根据刷题的题库名称进行模糊查询等筛选操作,客户端可以传入题库名称的部分或全部内容来查找符合条件的已考试刷题记录信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的已考试刷题记录对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的刷题记录数据信息 */ @GetMapping("/exercise/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/records基础上添加/exercise/paging,即/api/records/exercise/paging,用于获取已考试刷题记录的分页信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行分页查询已考试刷题记录的操作 public Result> getExerciseRecordPage(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, - @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, + @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "repoName", required = false) String repoName){ + // 通过@RequestParam注解获取请求中的pageNum、pageSize、repoName参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,repoName用于按刷题的题库名称进行筛选查询 return exerciseRecordService.getExerciseRecordPage(pageNum,pageSize,repoName); + // 调用exerciseRecordService接口的实例的getExerciseRecordPage方法,由服务层去具体实现根据传入的页码、每页记录数以及题库名称筛选条件等信息进行分页查询已考试刷题记录的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 查询刷题详情 - * @param exerciseId - * @return + * @param exerciseId,这是一个整数类型的参数,从参数名看这里应该是用于指定要查询详情的刷题记录的唯一标识符(可能是刷题对应的某个关键ID,虽然参数名和前面的逻辑稍不一致,也许是代码可优化点),通过这个ID可以准确找到对应的刷题记录,进而获取其详细信息,比如每题的作答情况等内容 + * @return 返回一个Result类型的对象,用于告知客户端查询刷题详情操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的刷题详情信息(以List形式)等内容 */ @GetMapping("/exercise/detail") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/records基础上添加/exercise/detail,即/api/records/exercise/detail,用于获取特定刷题记录的详细信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户都有权利执行查询刷题详情的操作 public Result> getExerciseRecordDetail(@RequestParam("repoId") Integer exerciseId){ + // 通过@RequestParam注解获取请求中名为"repoId"的参数(此处参数名可能不太准确,也许应该和前面定义的exerciseId参数名统一,便于理解和维护),将其赋值给exerciseId变量,以便服务层依据该ID准确找到对应的刷题记录并获取其详细信息 return exerciseRecordService.getExerciseRecordDetail(exerciseId); + // 调用exerciseRecordService接口的getExerciseRecordDetail方法,由服务层去具体实现根据传入的刷题记录ID获取其详细信息(包含每题答题情况等)的详细业务逻辑,最后将获取到的刷题详情信息封装到Result对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/RepoController.java b/src/main/java/cn/org/alan/exam/controller/RepoController.java index 8a7f71d..fc5bb02 100644 --- a/src/main/java/cn/org/alan/exam/controller/RepoController.java +++ b/src/main/java/cn/org/alan/exam/controller/RepoController.java @@ -1,96 +1,140 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“题库管理”功能模块相关的包,方便代码管理与维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以一致的格式返回给调用者(如前端) + import cn.org.alan.exam.model.entity.Repo; +// 引入Repo类,这是一个实体类,对应数据库中存储题库相关信息的表结构,包含了如题库的各种属性(例如题库名称、创建人、创建时间等信息),用于在业务逻辑中承载和传递与题库相关的数据 + import cn.org.alan.exam.model.vo.repo.RepoListVO; +// 引入RepoListVO类,大概率是视图对象(Value Object,VO)类,用于向客户端展示特定格式的题库列表相关信息,例如可能只包含题库ID和题库名称等关键信息,方便前端展示和使用 + import cn.org.alan.exam.model.vo.repo.RepoVO; +// 引入RepoVO类,同样是视图对象类,用于向客户端展示更详细的题库相关信息,经过业务逻辑处理后,以适合展示的形式传递给前端,包含的信息可能比RepoListVO更丰富全面 + import cn.org.alan.exam.service.IRepoService; +// 引入IRepoService接口,定义了与题库管理相关的一系列业务方法,例如题库的添加、修改、删除、查询等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类会依赖这个接口来调用相应功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询题库相关信息的业务逻辑时,用于承载分页后的题库数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,在这里的作用是将实现了IRepoService接口的具体实例注入到当前的RepoController类中,使得类中的方法可以方便地调用对应的服务方法实现具体业务逻辑 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,根据配置的权限表达式判断当前用户是否有相应权限来访问对应的方法,以此保证系统资源只能被授权用户访问,增强系统的安全性和权限管理 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(可以是默认规则或者自定义规则)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个题库的信息列表等情况)时会用到 /** * 题库管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与题库相关的各种管理操作,比如题库的添加、修改、删除以及不同条件下的查询等业务逻辑 * * @author WeiJin * @since 2024-03-21 */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/repo") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/repo开头,便于统一管理和组织与题库管理相关的一组API接口路径 public class RepoController { @Resource +// 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IRepoService接口的实例到当前类中,方便后续的方法调用该服务实例所提供的各种题库管理相关业务方法 private IRepoService iRepoService; /** * 添加题库,只有教师和管理员可以添加题库 * - * @param repo 添加题库的参数 - * @return 返回响应结果 + * @param repo 添加题库的参数,这是一个Repo类型的参数,用于承载前端传来的添加题库时需要填写的各种详细信息,例如题库名称、所属学科、创建人等信息,并且会依据相关验证规则进行数据合法性验证 + * @return 返回响应结果,返回一个Result类型的对象,用于告知客户端添加题库操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他有关的数据内容 */ @PostMapping +// 该注解表明这个方法用于处理HTTP POST请求,其请求路径就是类级别定义的基础路径/api/repo,因为这里没有额外指定路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交添加题库相关信息的场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行添加题库的操作,加强了对题库添加功能的权限管理 public Result addRepo(@Validated @RequestBody Repo repo) { - //从token获取用户id,放入创建人id属性 +// @Validated注解结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为Repo类型的对象,@Validated用于对这个转换后的对象依据相关规则进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的添加题库业务逻辑处理 + //从token获取用户id,放入创建人id属性,此处应该是在服务层或者更底层的代码逻辑中实现,从请求携带的token(通常用于用户认证授权)里解析出当前操作的用户ID,并将其设置到传入的repo对象的创建人ID属性上,确保添加的题库能关联到正确的创建人 return iRepoService.addRepo(repo); +// 方法体内部直接调用通过依赖注入获取的iRepoService接口实例的addRepo方法,并将经过验证且设置好创建人ID的repo参数传递进去,由服务层去具体实现添加题库的详细业务逻辑,比如将题库信息保存到数据库中,最后将服务层返回的包含添加结果等信息的Result对象直接返回给客户端 } /** * 修改题库 * - * @param repo 传递参数 - * @return 返回响应 + * @param repo 传递参数,这是一个Repo类型的参数,用于承载前端传来的修改题库时需要更新的各种信息,例如题库名称的修改、所属学科的变更等内容,并且会依据相关验证规则进行数据合法性验证 + * @return 返回响应,返回一个Result类型的对象,用于告知客户端修改题库操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @PutMapping("/{id}") +// 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/repo基础上添加/{id},其中{id}是路径变量,用于接收要修改的题库的ID,PUT请求常用于更新资源,这里符合对指定ID的题库进行修改更新的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行修改题库的操作,保障了题库修改功能的权限安全性 public Result updateRepo(@Validated @RequestBody Repo repo, @PathVariable("id") Integer id) { +// @Validated结合@RequestBody对repo参数进行数据合法性验证及从请求正文获取数据转换为对应对象;@PathVariable注解用于获取路径中的题库ID参数,将其赋值给变量id,以便服务层依据该ID准确找到对应的题库记录进行修改操作 return iRepoService.updateRepo(repo, id); +// 调用iRepoService接口的updateRepo方法,由服务层去具体实现根据传入的更新信息对指定ID的题库进行修改的详细业务逻辑,比如更新数据库中对应题库记录的字段值等,最后将操作结果封装到Result对象中返回给客户端 } /** * 根据题库id删除题库 * - * @param id 题库id - * @return 返回响应结果 + * @param id 题库id,这是一个整数类型的参数,用于指定要删除的题库的唯一标识符,通过这个ID可以准确找到数据库中对应的题库记录进行删除操作 + * @return 返回响应结果,返回一个Result类型的对象,用于告知客户端删除题库操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的数据内容 */ @DeleteMapping("/{id}") +// 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/repo基础上添加/{id},其中{id}是路径变量,用于接收要删除的题库的ID,DELETE请求常用于删除资源,这里符合删除指定题库的操作场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,确保只有教师或管理员角色的用户可以执行删除题库的操作,保障了题库删除功能的权限安全性 public Result deleteRepoById(@PathVariable("id") Integer id) { +// 通过@PathVariable注解获取路径中传入的题库ID参数,将其传递给服务层,以便服务层依据这个ID准确找到并删除对应的题库记录 return iRepoService.deleteRepoById(id); +// 调用iRepoService接口的deleteRepoById方法,由服务层去具体实现删除指定ID的题库的详细业务逻辑,比如从数据库中移除对应的题库记录等,最后将操作结果封装到Result对象中返回给客户端 } /** * 获取题库id和题库名,教师获取自己的题库,管理员获取所有题库 - * @param repoTitle 题库名称 - * @return 响应结果 + * @param repoTitle 题库名称,这是一个字符串类型的可选参数,用于根据题库名称进行模糊查询等筛选操作,教师可以通过传入部分或全部的题库名称来查找自己创建的符合条件的题库信息,管理员传入此参数可查找所有符合名称条件的题库信息 + * @return 响应结果,返回一个Result类型的对象,用于告知客户端获取题库ID和名称的操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的题库列表信息(以List形式)等内容 */ @GetMapping("/list") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/repo基础上添加/list,即/api/repo/list,GET请求常用于获取资源,这里用于获取题库ID和名称列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行获取题库ID和名称列表的操作,保障了该功能的权限安全性 public Result> getRepoList(@RequestParam(value = "repoTitle",required = false) String repoTitle) { +// 通过@RequestParam注解获取请求中的repoTitle参数,设置其为可选参数(required = false),方便客户端根据实际需求决定是否传入此参数进行筛选查询 return iRepoService.getRepoList(repoTitle); +// 调用iRepoService接口的getRepoList方法,由服务层去具体实现根据传入的题库名称(可选)获取相应的题库ID和名称列表信息的详细业务逻辑,比如按照教师或管理员权限进行不同的数据筛选等,最后将获取到的列表数据封装到Result对象中返回给客户端 } /** * 分页查询题库 * - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param title 题库名 - * @return 响应结果 + * @param pageNum 页码,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的题库信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize 每页记录数,同样是整数类型参数,用于设定每页显示的题库记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param title 题库名,是一个字符串类型的可选参数,用于根据题库名称进行模糊查询等筛选操作,客户端可以传入题库名称的部分或全部内容来查找符合条件的题库信息 + * @return 响应结果,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的题库实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的题库数据信息 */ @GetMapping("/paging") +// 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/repo基础上添加/paging,即/api/repo/paging,GET请求常用于获取资源,这里用于获取分页后的题库列表信息资源的操作符合GET请求的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") +// 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户可以执行分页查询题库的操作,保障了该功能的权限安全性 public Result> pagingRepo(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "title", required = false) String title) { +// 通过@RequestParam注解获取请求中的pageNum参数,设置其为可选参数(required = false),若客户端未传入则使用默认值1,方便客户端灵活指定要查询的页码;同样获取pageSize参数,默认值为10;获取title参数用于根据题库名称筛选查询 return iRepoService.pagingRepo(pageNum, pageSize, title); +// 调用iRepoService接口的pagingRepo方法,由服务层去具体实现根据传入的页码、每页记录数以及筛选条件等信息进行分页查询题库的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/ScoreController.java b/src/main/java/cn/org/alan/exam/controller/ScoreController.java index 43b46b3..e71c7cc 100644 --- a/src/main/java/cn/org/alan/exam/controller/ScoreController.java +++ b/src/main/java/cn/org/alan/exam/controller/ScoreController.java @@ -1,99 +1,144 @@ package cn.org.alan.exam.controller; +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“成绩管理”功能模块相关的包,方便代码管理与维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准格式返回给调用者(比如前端应用) + import cn.org.alan.exam.model.vo.score.GradeScoreVO; +// 引入GradeScoreVO类,这是一个视图对象(Value Object,VO)类,用于向客户端展示特定格式的班级成绩相关分析信息,比如班级整体考试成绩的平均分、各分数段人数分布等内容,方便前端展示和使用 + import cn.org.alan.exam.model.vo.score.QuestionAnalyseVO; +// 引入QuestionAnalyseVO类,同样是视图对象类,用于呈现某道试题在考试中的作答情况分析信息,例如该题的正确率、各选项选择人数等具体的分析数据,便于前端展示给教师等查看分析试题情况 + import cn.org.alan.exam.model.vo.score.UserScoreVO; +// 引入UserScoreVO类,也是视图对象类,用于向客户端展示学生个人的考试成绩相关信息,像学生的姓名、考试得分、排名等具体的成绩情况内容 + import cn.org.alan.exam.service.IStatService; +// 引入IStatService接口,可能定义了一些与成绩统计相关的通用业务方法或者其他辅助性的统计逻辑操作,不过在此控制器类中暂时未看到直接调用它的地方(也许在其他相关类中会被调用协作实现功能) + import cn.org.alan.exam.service.IExamQuAnswerService; +// 引入IExamQuAnswerService接口,定义了与考试中试题作答情况分析相关的一系列业务方法,例如获取某题的作答详情分析等操作的逻辑抽象,具体的实现由对应的服务类来完成,本控制器类会依赖此接口调用相应功能 + import cn.org.alan.exam.service.IUserExamsScoreService; +// 引入IUserExamsScoreService接口,定义了与用户考试成绩查询、成绩信息分页获取以及成绩导出等相关的一系列业务方法,具体的实现由对应的服务类来完成,该控制器类中的多个方法依赖此接口调用相应功能 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询成绩相关信息的业务逻辑中,用于承载分页后的成绩数据等内容 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了相关服务接口(如IStatService、IUserExamsScoreService、IExamQuAnswerService)的具体实例注入到当前的ScoreController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体业务逻辑 + import jakarta.servlet.http.HttpServletResponse; +// 引入HttpServletResponse类,它代表了服务器对客户端的HTTP响应对象,在成绩导出功能中会使用到,用于设置响应的相关属性(比如响应头信息、输出流等),以便将成绩数据以合适的格式(如Excel等)返回给客户端进行下载 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口 /** * 成绩管理 + * 此处是对该类功能的简单描述,清晰表明这个类主要负责处理与成绩相关的各种查询、分析以及导出等业务逻辑,例如分页获取学生成绩信息、分析试题作答情况、按班级分析考试情况以及将成绩数据导出等操作 * * @Author WeiJin * @Version * @Date 2024/3/25 11:19 AM */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 @RequestMapping("/api/score") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/score开头,便于统一管理和组织与成绩管理相关的一组API接口路径 public class ScoreController { @Resource + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入实现了IStatService接口的具体实例到当前类中,虽然当前类中暂时未看到直接调用它的地方,但可能在后续业务逻辑扩展或者其他相关功能实现中会用到 private IStatService iStatService; @Resource + // 同样使用@Resource注解注入实现了IUserExamsScoreService接口的实例,后续多个与成绩查询、成绩分析、成绩导出等相关的方法会依赖这个服务实例来调用具体业务逻辑方法 private IUserExamsScoreService iUserExamsScoreService; @Resource + // 注入实现了IExamQuAnswerService接口的实例,用于调用与试题作答情况分析相关的业务方法,比如获取某题的作答详情分析等操作 private IExamQuAnswerService iExamQuAnswerService; - - /** * 分页获取成绩信息 - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param gradeId 班级Id - * @param examId 考试Id - * @param realName 真实姓名 - * @return 响应结果 + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的成绩信息,该参数为可选参数,若未传入则默认值为1 + * @param pageSize,同样是整数类型参数,用于设定每页显示的成绩记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数 + * @param gradeId,是一个整数类型的参数,用于指定班级的唯一标识符,通过这个ID可以筛选出该班级学生的成绩信息,方便教师等按班级查看学生成绩情况 + * @param examId,是一个整数类型的参数,用于指定考试的唯一标识符,通过这个ID可以筛选出特定考试的成绩信息,便于查看某一场考试下学生的成绩情况 + * @param realName,是一个字符串类型的可选参数,用于根据学生的真实姓名进行模糊查询等筛选操作,客户端可以传入学生姓名的部分或全部内容来查找符合条件的学生成绩信息 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的学生成绩对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的学生成绩数据信息 */ @GetMapping("/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/score基础上添加/paging,即/api/score/paging,用于获取分页后的成绩信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户都可以访问这个方法,意味着教师和管理员角色的用户有权利执行分页查询成绩信息的操作 public Result> pagingScore(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "gradeId") Integer gradeId, @RequestParam(value = "examId") Integer examId, @RequestParam(value = "realName", required = false) String realName) { + // 通过@RequestParam注解分别获取请求中的pageNum、pageSize、gradeId、examId、realName参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,gradeId、examId用于筛选特定班级和考试的成绩,realName用于按学生姓名进一步筛选 return iUserExamsScoreService.pagingScore(pageNum, pageSize, gradeId, examId, realName); + // 调用通过依赖注入获取的iUserExamsScoreService接口实例的pagingScore方法,由服务层去具体实现根据传入的页码、每页记录数以及班级ID、考试ID、学生姓名等筛选条件进行分页查询成绩信息的详细业务逻辑,最后将查询结果封装到Result对象中返回给客户端 } /** * 获取某场考试某题作答情况 - * @param examId 考试id - * @param questionId 试题id - * @return 响应结果 + * @param examId,是一个整数类型的参数,用于指定要分析作答情况的考试的唯一标识符,通过这个ID可以准确找到对应的考试记录,进而查找该考试中指定试题的作答情况 + * @param questionId,是一个整数类型的参数,用于指定要分析作答情况的试题的唯一标识符,通过这个ID可以准确找到对应的试题,结合examId就能获取该试题在特定考试中的作答详情 + * @return 返回一个Result类型的对象,用于告知客户端获取试题作答情况分析操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的试题作答分析信息(以QuestionAnalyseVO形式)等内容 */ @GetMapping("/question/{examId}/{questionId}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/score基础上添加/question/{examId}/{questionId},其中{examId}和{questionId}是路径变量,用于接收要分析的考试和试题的ID,符合GET请求获取资源(这里是获取试题作答情况资源)的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户有权利执行获取试题作答情况分析的操作 public Result questionAnalyse(@PathVariable("examId") Integer examId, @PathVariable("questionId") Integer questionId) { + // 通过@PathVariable注解分别获取路径中的考试ID和试题ID参数,将其赋值给对应的examId和questionId变量,以便服务层依据这两个ID准确找到对应的考试和试题记录,进而获取试题的作答情况分析信息 return iExamQuAnswerService.questionAnalyse(examId, questionId); + // 调用iExamQuAnswerService接口的questionAnalyse方法,由服务层去具体实现根据传入的考试ID和试题ID获取该试题在对应考试中的作答情况分析(比如各选项选择人数、正确率等)的详细业务逻辑,最后将获取到的分析信息封装到Result对象中返回给客户端 } /** * 根据班级分析考试情况 - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param examTitle 考试名称 - * @return 响应结果 + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,类似前面分页获取成绩信息时的页码参数作用,若客户端未传入则默认值为1,用于获取不同页的班级考试情况分析信息 + * @param pageSize,同样是整数类型参数,用于设定每页显示的班级考试情况分析记录数量,默认值为10,若客户端未指定则按每页10条记录进行分页查询,用于控制每页显示的分析信息数量 + * @param examTitle,是一个字符串类型的可选参数,用于根据考试名称进行模糊查询等筛选操作,客户端可以传入考试名称的部分或全部内容来查找符合条件的班级考试情况分析信息,便于按考试名称筛选查看不同考试下班级的成绩情况 + * @param gradeId,是一个整数类型的可选参数,用于指定班级的唯一标识符,通过这个ID可以筛选出特定班级的考试情况分析信息,方便按班级查看考试情况,若未传入则可能分析所有班级(具体看服务层实现逻辑) + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的班级考试成绩分析对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的班级考试情况分析数据信息 */ @GetMapping("/getExamScore") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/score基础上添加/getExamScore,即/api/score/getExamScore,用于获取班级考试情况分析信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户有权利执行根据班级分析考试情况的操作 public Result> getExamScoreInfo( @RequestParam(value = "pageNum",required = false,defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize",required = false,defaultValue = "10") Integer pageSize, @RequestParam(value = "examTitle",required = false) String examTitle, - @RequestParam(value = "gradeId" ,required = false) Integer gradeId){ + @RequestParam(value = "gradeId",required = false) Integer gradeId){ + // 通过@RequestParam注解获取请求中的pageNum、pageSize、examTitle、gradeId参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,examTitle用于按考试名称筛选,gradeId用于按班级筛选分析考试情况 return iUserExamsScoreService.getExamScoreInfo(pageNum,pageSize,examTitle,gradeId); + // 调用iUserExamsScoreService接口的getExamScoreInfo方法,由服务层去具体实现根据传入的页码、每页记录数以及考试名称、班级ID等筛选条件进行分页查询并分析班级考试情况(比如班级平均分、各分数段人数等)的详细业务逻辑,最后将查询分析结果封装到Result对象中返回给客户端 } /** * 成绩导出 - * @param response 响应对象 - * @param examId 考试id - * @param gradeId 班级id + * @param response,这是一个HttpServletResponse类型的参数,代表服务器对客户端的HTTP响应对象,在这个方法中会使用它来设置响应的相关属性,例如设置响应头信息告知客户端返回的数据是Excel文件格式等,以及通过输出流将成绩数据写入响应,以便客户端能下载成绩文件 + * @param examId,是一个整数类型的参数,用于指定要导出成绩的考试的唯一标识符,通过这个ID可以准确找到对应的考试记录,进而获取该考试下相关的成绩数据进行导出操作 + * @param gradeId,是一个整数类型的参数,用于指定班级的唯一标识符,通过这个ID可以筛选出该班级学生在对应考试中的成绩信息进行导出,方便按班级导出成绩数据 */ @GetMapping("/export/{examId}/{gradeId}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/score基础上添加/export/{examId}/{gradeId},其中{examId}和{gradeId}是路径变量,用于接收要导出成绩的考试和班级的ID,符合GET请求获取资源(这里是获取成绩数据并导出资源)的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着教师和管理员角色的用户有权利执行成绩导出的操作 public void scoreExport(HttpServletResponse response,@PathVariable("examId") Integer examId, @PathVariable("gradeId") Integer gradeId) { + // 通过@PathVariable注解获取路径中的考试ID和班级ID参数,将其赋值给对应的examId和gradeId变量,以便服务层依据这两个ID准确找到对应的考试和班级记录,进而获取相关成绩数据进行导出操作 iUserExamsScoreService.exportScores(response,examId,gradeId); + // 调用iUserExamsScoreService接口的exportScores方法,由服务层去具体实现根据传入的HttpServletResponse对象以及考试ID、班级ID,将相应的成绩数据按照一定格式(如Excel)进行组织并通过响应对象返回给客户端,使得客户端可以下载成绩文件的详细业务逻辑 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/StatController.java b/src/main/java/cn/org/alan/exam/controller/StatController.java index 06e57ba..6778fca 100644 --- a/src/main/java/cn/org/alan/exam/controller/StatController.java +++ b/src/main/java/cn/org/alan/exam/controller/StatController.java @@ -1,80 +1,110 @@ package cn.org.alan.exam.controller; +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“统计管理”功能模块相关的包,方便代码管理与维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准格式返回给调用者(比如前端应用) + import cn.org.alan.exam.model.vo.stat.AllStatsVO; +// 引入AllStatsVO类,这是一个视图对象(Value Object,VO)类,用于向客户端展示特定格式的所有相关统计信息汇总结果,例如可能包含班级数量、试卷数量、试题数量等综合统计数据,方便前端展示和使用 + import cn.org.alan.exam.model.vo.stat.DailyVO; +// 引入DailyVO类,同样是视图对象类,用于呈现每日相关的统计信息,具体包含的内容需看其类内部定义,可能是每日新增的各类数据量、每日活跃用户数等与日常统计相关的数据,便于前端展示给用户查看 + import cn.org.alan.exam.model.vo.stat.GradeExamVO; +// 引入GradeExamVO类,也是视图对象类,用于向客户端展示各班级试卷相关的统计信息,比如每个班级已创建的试卷数量、已完成考试的试卷数量等班级与试卷维度的统计情况内容 + import cn.org.alan.exam.model.vo.stat.GradeStudentVO; +// 引入GradeStudentVO类,用于向客户端展示各班级学生人数相关的统计信息,像每个班级的学生总数、不同状态(如活跃、未活跃等,具体看业务定义)的学生数量等班级与学生人数维度的统计数据 + import cn.org.alan.exam.service.IStatService; +// 引入IStatService接口,定义了与统计管理相关的一系列业务方法,例如获取各班级学生人数统计、各班试卷统计、所有数据总量统计以及日常统计等操作的逻辑抽象,具体的实现由对应的服务类来完成,本控制器类依赖此接口调用相应功能 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了IStatService接口的具体实例注入到当前的StatController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体业务逻辑 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理 + import org.springframework.web.bind.annotation.GetMapping; +// 这是Spring Web相关的注解,用于标识该方法处理HTTP GET请求,GET请求常用于获取资源,在这里符合获取各种统计信息资源的操作场景 + import org.springframework.web.bind.annotation.RequestMapping; +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/stat开头,便于统一管理和组织与统计管理相关的一组API接口路径 + import org.springframework.web.bind.annotation.RestController; +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作 import java.util.List; - +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个班级的统计信息列表等情况)时会用到 /** * 统计管理 + * 此处是对该类功能的简单描述,清晰表明这个类主要负责处理与系统各类数据统计相关的业务逻辑,例如获取各班级人数统计、各班试卷统计、整体数据数量统计以及日常相关统计等操作 * * @Author Alan * @Version * @Date 2024/3/25 11:22 AM */ @RestController +// 标注此类为Spring MVC中的控制器类,且方法返回值默认以JSON等格式响应给客户端,方便与前端交互 @RequestMapping("/api/stat") +// 为该控制器类下的所有请求处理方法设置公共的请求路径前缀,后续具体方法的路径在此基础上扩展 public class StatController { @Resource + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IStatService接口的实例到当前类中,方便后续调用相关业务方法 private IStatService statService; + /** * 各班级人数统计 - * @return + * @return 返回一个Result类型的对象,用于告知客户端获取各班级人数统计操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的各班级学生人数统计信息(以List形式)等内容 */ @GetMapping("/student") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/stat基础上添加/student,即/api/stat/student,用于获取各班级人数统计信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户都可以访问这个方法,意味着教师和管理员角色的用户有权利执行获取各班级人数统计的操作 public Result> getStudentGradeCount() { + // 方法内部直接调用通过依赖注入获取的statService接口实例的getStudentGradeCount方法,由服务层去具体实现获取各班级人数统计信息的详细业务逻辑,比如从数据库中查询各班级的学生数量等相关数据,并封装成相应的视图对象列表,最后将查询结果封装到Result对象中返回给客户端 return statService.getStudentGradeCount(); } /** * 各班试卷统计 - * @return + * @return 返回一个Result类型的对象,用于告知客户端获取各班试卷统计操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的各班试卷统计信息(以List形式)等内容 */ @GetMapping("/exam") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/stat基础上添加/exam,即/api/stat/exam,用于获取各班试卷统计信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着教师和管理员角色的用户有权利执行获取各班试卷统计的操作 public Result> getExamGradeCount() { + // 调用statService接口的getExamGradeCount方法,由服务层去具体实现获取各班试卷统计信息的详细业务逻辑,比如查询每个班级对应的试卷数量等相关数据,并整理成相应的视图对象列表,最后将结果封装到Result对象中返回给客户端 return statService.getExamGradeCount(); } /** * 统计所有班级、试卷、试题数量 * - * @return 统计结果 + * @return 统计结果,返回一个Result类型的对象,用于告知客户端获取所有班级、试卷、试题数量统计操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的综合统计信息(以AllStatsVO形式)等内容 */ @GetMapping("/allCounts") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/stat基础上添加/allCounts,即/api/stat/allCounts,用于获取所有班级、试卷、试题数量的综合统计信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着教师和管理员角色的用户有权利执行获取整体数据数量统计的操作 public Result getAllCount(){ + // 调用statService接口的getAllCount方法,由服务层去具体实现统计所有班级、试卷、试题数量的详细业务逻辑,比如分别查询班级总数、试卷总数、试题总数等数据,并整合到对应的视图对象中,最后将其封装到Result对象中返回给客户端 return statService.getAllCount(); } + /** + * 获取日常相关统计信息(具体看DailyVO中定义的内容,可能是每日新增数据量等情况) + * @return 返回一个Result类型的对象,用于告知客户端获取日常统计信息操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的日常统计信息(以List形式)等内容 + */ @GetMapping("/daily") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/stat基础上添加/daily,即/api/stat/daily,用于获取日常相关统计信息,符合GET请求获取资源的使用场景 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"(教师角色)、"role_admin"(管理员角色)或者"role_student"(学生角色)权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户有权利执行获取日常统计信息的操作 public Result> getDaily(){ + // 调用statService接口的getDaily方法,由服务层去具体实现获取日常相关统计信息的详细业务逻辑,比如查询每日新增的各类数据量等相关数据,并整理成相应的视图对象列表,最后将结果封装到Result对象中返回给客户端 return statService.getDaily(); } - - - - - - - - - - - - - -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/UserBookController.java b/src/main/java/cn/org/alan/exam/controller/UserBookController.java index 911b8f6..4dfcb0a 100644 --- a/src/main/java/cn/org/alan/exam/controller/UserBookController.java +++ b/src/main/java/cn/org/alan/exam/controller/UserBookController.java @@ -1,76 +1,112 @@ package cn.org.alan.exam.controller; - +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“错题本管理”功能模块相关的包,方便代码管理和维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准格式返回给调用者(比如前端应用),便于告知客户端对应业务操作的执行情况及相关返回数据。 + import cn.org.alan.exam.model.form.userbook.ReUserBookForm; +// 引入ReUserBookForm类,这是一个数据模型类,用于承载与错题本相关操作(比如填充答案操作时)前端传递过来的特定格式的数据,可能包含错题的一些原始信息、要填写的答案等具体内容,方便在业务逻辑中进行数据传递和处理。 + import cn.org.alan.exam.model.vo.userbook.*; +// 引入多个以“userbook”命名空间下的视图对象(Value Object,VO)类,这些类用于向客户端展示特定格式的错题本相关信息,不同的VO类对应不同的业务场景,比如展示错题分页信息、错题ID列表信息、单题详细信息等,方便前端按照合适的格式展示数据给用户查看。 + import cn.org.alan.exam.service.IUserBookService; +// 引入IUserBookService接口,定义了与错题本管理相关的一系列业务方法,例如错题的分页查询、错题ID列表查询、单题查询以及答案填充等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类依赖这个接口来调用相应功能。 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询错题本相关信息的业务逻辑时,用于承载分页后的错题数据等内容,方便对分页数据进行统一的处理和传递。 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了IUserBookService接口的具体实例注入到当前的UserBookController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体业务逻辑。 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理,这里限定了不同操作对应的有权限的角色。 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口,处理来自客户端的各种请求。 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个错题的ID列表等情况)时会用到,便于对一组数据进行统一操作和传递。 /** * 错题本管理 + * 这里是对该类功能的简单描述,表明这个类主要负责处理与错题本相关的各种查询、操作等业务逻辑,比如分页查询错题考试情况、获取错题本中错题的ID列表、查询单题详情以及填充错题答案等功能。 * * @author Alan * @since 2024-03-21 */ @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作,方便与前端进行数据交互。 @RequestMapping("/api/userbooks") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/userbooks开头,便于统一管理和组织与错题本管理相关的一组API接口路径。 public class UserBookController { @Resource + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IUserBookService接口的实例到当前类中,方便后续调用相关业务方法,使得业务逻辑能够顺利执行。 private IUserBookService userBookService; /** * 分页查询错题考试 - * @param pageNum - * @param pageSize - * @param examName - * @return + * @param pageNum,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的错题考试相关信息,该参数为可选参数,若未传入则默认值为1,方便客户端灵活控制查询的页面。 + * @param pageSize,同样是整数类型参数,用于设定每页显示的错题考试记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,也是可选参数,用于控制每页展示的错题数量。 + * @param examName,是一个字符串类型的可选参数,用于根据考试名称进行模糊查询等筛选操作,客户端可以传入考试名称的部分或全部内容来查找符合条件的错题考试信息,便于按考试名称对错题进行筛选查找。 + * @return 返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的错题考试对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的错题考试数据信息,方便前端展示和使用查询到的数据。 */ @GetMapping("/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/userbooks基础上添加/paging,即/api/userbooks/paging,用于获取分页后的错题考试信息,符合GET请求获取资源的使用场景,便于客户端发起获取错题数据的请求。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"(教师角色)、"role_admin"(管理员角色)或者"role_student"(学生角色)权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户有权利执行分页查询错题考试的操作,确保有权限的用户才能获取相关数据。 public Result> getPage(@RequestParam(value = "pageNum",required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize",required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "examName",required = false) String examName){ + // 通过@RequestParam注解分别获取请求中的pageNum、pageSize、examName参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,examName用于筛选查询条件,将获取到的参数传递给服务层进行后续处理。 return userBookService.getPage(pageNum,pageSize,examName); + // 调用通过依赖注入获取的userBookService接口实例的getPage方法,由服务层去具体实现根据传入的页码、每页记录数以及考试名称筛选条件等信息进行分页查询错题考试信息的详细业务逻辑,比如从数据库中查询符合条件的错题数据并进行分页处理,最后将查询结果封装到Result对象中返回给客户端。 } /** * 查询错题本错题id列表 - * @param examId - * @return + * @param examId,是一个整数类型的参数,用于指定考试的唯一标识符,通过这个ID可以筛选出对应考试下错题本中的错题ID列表信息,方便根据特定考试来获取相关错题的标识,便于后续对这些错题进行进一步操作。 + * @return 返回一个Result类型的对象,用于告知客户端查询错题本错题ID列表操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的错题ID列表信息(以List形式)等内容,便于前端获取和展示这些错题ID。 */ @GetMapping("/question/list/{examId}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/userbooks基础上添加/question/list/{examId},其中{examId}是路径变量,用于接收要查询错题ID列表对应的考试的ID,符合GET请求获取资源(这里是获取错题ID列表资源)的使用场景,便于客户端根据考试ID来请求获取错题ID。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户有权利执行查询错题本错题ID列表的操作,确保相应权限的用户才能获取该数据。 public Result> getReUserExamBook(@PathVariable("examId") Integer examId){ + // 通过@PathVariable注解获取路径中传入的考试ID参数,将其赋值给examId变量,以便服务层依据该ID准确找到对应的考试记录,进而获取该考试下错题本中的错题ID列表信息。 return userBookService.getReUserExamBook(examId); + // 调用userBookService接口的getReUserExamBook方法,由服务层去具体实现根据传入的考试ID获取错题本中错题ID列表的详细业务逻辑,比如从数据库中查询对应考试下的错题ID并整理成列表,最后将获取到的列表数据封装到Result对象中返回给客户端。 } /** * 查询单题 - * @param quId - * @return + * @param quId,是一个整数类型的参数,用于指定要查询的错题的唯一标识符,通过这个ID可以准确找到错题本中对应的单道错题,进而获取其详细信息,比如错题的题干、选项、正确答案等内容,方便查看单题的具体情况。 + * @return 返回一个Result类型的对象,用于告知客户端查询单题操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的单题详细信息(以BookOneQuVO形式)等内容,便于前端展示单题的完整详情给用户查看。 */ @GetMapping("/question/single/{quId}") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/userbooks基础上添加/question/single/{quId},其中{quId}是路径变量,用于接收要查询的错题的ID,符合GET请求获取资源(这里是获取单题详细信息资源)的使用场景,便于客户端根据错题ID请求获取单题详情。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户有权利执行查询单题的操作,确保相应权限的用户才能获取单题详情数据。 public Result getBookOne(@PathVariable("quId") Integer quId){ + // 通过@PathVariable注解获取路径中传入的错题ID参数,将其赋值给quId变量,以便服务层依据该ID准确找到对应的错题记录,进而获取其详细信息。 return userBookService.getBookOne(quId); + // 调用userBookService接口的getBookOne方法,由服务层去具体实现根据传入的错题ID获取该错题详细信息的详细业务逻辑,比如从数据库中查询对应错题的各项详细数据并封装到对应的视图对象中,最后将获取到的单题详情信息封装到Result对象中返回给客户端。 } /** * 填充答案 - * @param reUserBookForm - * @return + * @param reUserBookForm,这是一个ReUserBookForm类型的参数,用于承载前端传来的填充错题答案时需要填写的各种信息,例如错题的ID、要填写的答案内容等具体数据,以便服务层根据这些信息进行答案的更新等相关业务逻辑处理。 + * @return 返回一个Result类型的对象,用于告知客户端填充答案操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及与填充答案相关的返回数据(以AddBookAnswerVO形式)等内容,便于前端知晓操作结果及获取相关反馈信息。 */ @PostMapping("/full-book") + // 该注解表明这个方法用于处理HTTP POST请求,其请求路径是在类的基础路径/api/userbooks基础上添加/full-book,用于区分其他错题本相关操作路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交填充错题答案相关信息的场景,便于客户端将填写的答案数据发送给服务器。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin','role_student')") + // 进行权限控制,拥有"role_teacher"、"role_admin"或者"role_student"权限的用户都可以访问这个方法,意味着教师、管理员和学生角色的用户有权利执行填充错题答案的操作,确保有权限的用户才能进行该操作。 public Result addBookAnswer(@RequestBody ReUserBookForm reUserBookForm){ + // @RequestBody注解表示从请求的正文中获取数据,并将其转换为ReUserBookForm类型的对象,以便获取前端传递过来的填充答案相关的完整数据信息,传递给服务层进行后续处理。 return userBookService.addBookAnswer(reUserBookForm); + // 调用userBookService接口的addBookAnswer方法,由服务层去具体实现根据传入的填充答案相关信息进行答案填充的详细业务逻辑,比如更新数据库中错题的答案字段等操作,最后将操作结果以及可能的相关反馈数据封装到Result对象中返回给客户端。 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/controller/UserController.java b/src/main/java/cn/org/alan/exam/controller/UserController.java index 6176889..cb6386f 100644 --- a/src/main/java/cn/org/alan/exam/controller/UserController.java +++ b/src/main/java/cn/org/alan/exam/controller/UserController.java @@ -1,136 +1,193 @@ package cn.org.alan.exam.controller; +// 声明该类所在的包名,用于在项目中对类进行分类组织,表明此控制器类属于特定的“用户管理”功能模块相关的包,方便代码管理与维护 import cn.org.alan.exam.common.result.Result; +// 引入Result类,通常用于统一封装业务操作后的结果信息,包含操作是否成功的标识以及可能需要返回的数据等内容,以标准格式返回给调用者(比如前端应用),方便告知客户端业务操作的执行情况及对应返回数据情况。 + import cn.org.alan.exam.common.group.UserGroup; +// 引入UserGroup类,大概率是用于对用户相关操作进行分组验证的类,比如针对用户创建、密码修改等不同操作按照特定规则进行分组验证,确保传入的数据符合相应业务场景下的合法性要求,增强数据校验的准确性和针对性。 + import cn.org.alan.exam.model.form.UserForm; +// 引入UserForm类,这是一个数据模型类,用于承载用户相关操作(如创建用户、修改密码等操作时)前端传递过来的用户信息,像用户名、真实姓名、角色ID等具体的数据内容,方便在业务逻辑中传递和处理这些数据。 + import cn.org.alan.exam.model.vo.UserVO; +// 引入UserVO类,这是一个视图对象(Value Object,VO)类,用于向客户端展示特定格式的用户相关信息,例如用户的基本信息、权限信息等经过整理和格式化后适合前端展示的数据,便于前端展示给用户查看。 + import cn.org.alan.exam.service.IUserService; +// 引入IUserService接口,定义了与用户管理相关的一系列业务方法,例如获取用户登录信息、创建用户、修改密码、删除用户、分页查询用户信息等操作的逻辑抽象,具体的实现由对应的服务类来完成,该控制器类依赖这个接口来调用相应功能。 + import cn.org.alan.exam.util.AliOSSUtil; +// 引入AliOSSUtil类,从名称推测可能是用于与阿里云对象存储服务(OSS)进行交互的工具类,也许在用户上传头像等涉及文件存储的操作中会使用到,方便进行文件的上传、管理等相关操作。 + import cn.org.alan.exam.util.SecurityUtil; +// 引入SecurityUtil类,应该是与安全相关的工具类,可能用于处理用户认证、授权或者密码加密等安全相关的逻辑,辅助保障系统的安全性,在获取用户登录信息、修改密码等操作中或许会发挥作用。 + import com.baomidou.mybatisplus.core.metadata.IPage; +// 引入IPage类,这是MyBatis Plus框架提供的用于表示分页数据的类型,在涉及分页查询用户信息等业务逻辑时,用于承载分页后的用户数据等内容,便于对分页数据进行统一的处理和传递。 + import jakarta.annotation.Resource; +// 用于进行资源注入的注解,作用是将实现了IUserService接口的具体实例注入到当前的UserController类中,使得类中的方法可以便捷地调用对应的服务方法来实现具体业务逻辑,确保业务功能的正常实现。 + import org.springframework.security.access.prepost.PreAuthorize; +// 用于在方法级别进行权限控制的注解,依据配置的权限表达式判断当前用户是否具备相应权限来访问对应的方法,以此保障系统资源只能被授权用户操作,增强系统的安全性和权限管理,这里针对不同的用户操作明确了有权限执行的角色。 + import org.springframework.validation.annotation.Validated; +// 结合具体的验证规则(由UserGroup中不同分组定义)对传入方法的参数进行数据合法性验证,保证接收到的参数符合业务要求,避免非法数据进入业务逻辑处理流程,提高数据质量和业务操作的准确性。 + import org.springframework.web.bind.annotation.*; +// 通配符导入包含了众多Spring Web相关的注解,例如用于定义请求处理方法的不同请求方式注解(如@GetMapping、@PostMapping等)以及处理请求路径、请求参数等相关的注解,方便在控制器类中构建API接口,处理来自客户端的各种请求。 + import org.springframework.web.multipart.MultipartFile; +// 引入MultipartFile类,用于处理文件上传相关操作,在用户上传头像、Excel导入用户数据等功能中会使用到,方便接收前端上传的文件内容。 import java.util.Objects; +// 引入Objects类,它提供了一些用于操作对象的实用方法,虽然在这里暂时未看到直接使用它的地方,但在一些涉及对象比较、判空等操作时可能会用到。 + -/** - * 用户管理 - * - * @Author WeiJin - * @Version 1.0 - * @Date 2024/3/25 15:50 - */ + //用户管理 + // 这里是对该类功能的简单描述,表明这个类主要负责处理与用户相关的各种管理操作,比如获取用户登录信息、创建用户、修改密码、删除用户、分页查询用户信息以及涉及用户的一些特殊操作(如加入班级、上传头像等)。 + + //@Author WeiJin + //@Version 1.0 + //@Date 2024/3/25 15:50 + // @RestController +// 这是Spring框架提供的复合注解,兼具@Controller和@ResponseBody的功能。意味着这个类是Spring MVC中的控制器类,并且类中方法的返回值默认会直接以JSON等格式响应给客户端,无需额外配置视图解析相关操作,方便与前端进行数据交互。 @RequestMapping("/api/user") +// 用于给整个控制器类下的所有请求处理方法设置一个公共的请求路径前缀,表明此类中所有处理请求的方法对应的URL路径都将以/api/user开头,便于统一管理和组织与用户管理相关的一组API接口路径。 public class UserController { @Resource + // 使用@Resource注解来进行依赖注入,让Spring容器查找并注入一个实现了IUserService接口的实例到当前类中,方便后续调用相关业务方法,确保业务逻辑能够顺利执行。 private IUserService iUserService; - /** - * 获取用户登录信息 - * - * @return 响应结果 - */ + // 获取用户登录信息 + + // @return 响应结果,返回一个Result类型的对象,用于告知客户端获取用户登录信息操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及获取到的用户登录相关信息(以UserVO形式)等内容,便于前端展示给当前登录用户查看自身信息。 + @GetMapping("/info") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/user基础上添加/info,即/api/user/info,用于获取用户登录信息,符合GET请求获取资源的使用场景,便于客户端发起获取自身登录信息的请求。 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"(学生角色)、"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户都可以访问这个方法,意味着只要登录的这几种角色的用户都有权利获取自己的登录信息,确保信息的安全性和访问权限的合理性。 public Result info() { + // 方法内部直接调用通过依赖注入获取的iUserService接口实例的info方法,由服务层去具体实现获取用户登录信息的详细业务逻辑,比如从数据库中查询当前登录用户的基本信息、权限信息等相关数据,并封装成对应的视图对象,最后将查询结果封装到Result对象中返回给客户端。 return iUserService.info(); } - /** - * 创建用户,教师只能创建学生,管理员可以创建教师和学生 - * - * @param userForm 请求参数,用户名、真实姓名[、角色id] - * @return 响应结果 - */ + //创建用户,教师只能创建学生,管理员可以创建教师和学生 + + //@param userForm 请求参数,用户名、真实姓名[、角色id],这是一个UserForm类型的参数,用于承载前端传来的创建用户时需要填写的各种详细信息,像用户名、真实姓名是必填的基本信息,角色ID根据不同创建者(教师或管理员)有不同的可选值范围,并且会依据UserGroup.CreateUserGroup.class指定的验证规则进行数据合法性验证,确保传入的数据符合创建用户的要求。 + // @return 响应结果,返回一个Result类型的对象,用于告知客户端创建用户操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他有关创建用户的反馈信息等内容,便于前端知晓创建操作是否成功及获取相应提示。 + @PostMapping + // 该注解表明这个方法用于处理HTTP POST请求,其请求路径就是类级别定义的基础路径/api/user,因为这里没有额外指定路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交创建用户相关信息的场景,便于客户端将创建用户的信息发送给服务器。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户才能访问这个方法,意味着只有这两种角色的用户有权利创建新用户,确保用户创建操作的权限安全性,防止非法创建用户。 public Result createUser(@Validated(UserGroup.CreateUserGroup.class) @RequestBody UserForm userForm) { + // @Validated结合@RequestBody注解,@RequestBody表示从请求的正文中获取数据,并将其转换为UserForm类型的对象,@Validated按照指定的创建用户分组验证规则对这个转换后的对象进行数据合法性验证,只有验证通过的数据才会进入方法内部进行后续的创建用户业务逻辑处理。 return iUserService.createUser(userForm); + // 调用iUserService接口的createUser方法,由服务层去具体实现创建用户的详细业务逻辑,比如将用户信息保存到数据库中,根据教师或管理员角色的不同限制创建不同类型的用户(教师只能创建学生,管理员可创建教师和学生),最后将服务层返回的包含创建结果等信息的Result对象直接返回给客户端。 } - /** - * 用户修改密码 - * - * @param userForm 入参 - * @return 响应结果 - */ + + // 用户修改密码 + + //@param userForm 入参,这是一个UserForm类型的参数,用于承载前端传来的修改密码时需要填写的相关信息,例如原密码、新密码等内容,并且会依据UserGroup.UpdatePasswordGroup.class指定的验证规则进行数据合法性验证,保证传入的数据符合密码修改的业务要求。 + // @return 响应结果,返回一个Result类型的对象,用于告知客户端修改密码操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他与密码修改相关的反馈信息等内容,便于前端知晓修改操作是否成功及获取相应提示。 + @PutMapping + // 此注解指定这个方法用于处理HTTP PUT请求,其请求路径就是类的基础路径/api/user,PUT请求常用于更新资源,这里符合用户更新自己密码的操作场景,便于客户端向服务器提交密码修改相关信息进行密码更新。 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"、"role_teacher"或者"role_admin"权限的用户都可以访问这个方法,意味着这几种角色的用户都有权利修改自己的密码,确保用户对自身密码管理的权限合理性。 public Result updatePassword(@Validated(UserGroup.UpdatePasswordGroup.class) @RequestBody UserForm userForm) { + // 通过@Validated结合@RequestBody对userForm参数进行数据合法性验证及从请求正文获取数据转换为对应对象,只有符合密码修改验证规则的数据才进入后续业务逻辑处理。 return iUserService.updatePassword(userForm); + // 调用iUserService接口的updatePassword方法,由服务层去具体实现根据传入的修改密码相关信息进行密码更新的详细业务逻辑,比如验证原密码是否正确、更新数据库中用户的密码字段等操作,最后将操作结果封装到Result对象中返回给客户端。 } - /** - * 批量删除用户 - * - * @param ids 字符串ids - * @return 相应结果 - */ + + // 批量删除用户 + + //@param ids 字符串ids,这是一个字符串类型的参数,用于指定要批量删除的用户的相关标识(可能是多个用户ID以某种格式拼接,比如逗号分隔等情况),通过这个参数可以准确找到对应的用户记录进行批量删除操作,方便进行批量操作的信息传递。 + // @return 相应结果,返回一个Result类型的对象,用于告知客户端批量删除用户操作是否成功以及可能的相关提示信息等,其内部封装了操作结果标识以及其他相关的反馈信息等内容,便于前端知晓删除操作是否成功及获取相应提示。 + @DeleteMapping("/{ids}") + // 该注解表明这个方法用于处理HTTP DELETE请求,其请求路径是在类的基础路径/api/user基础上添加/{ids},其中{ids}是路径变量,用于接收要批量删除的用户的相关标识信息,DELETE请求常用于删除资源,这里符合批量删除指定用户的操作场景,便于客户端根据用户标识发起删除请求。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着只有教师或管理员角色的用户有权利执行批量删除用户的操作,确保删除用户操作的权限安全性,防止非法删除用户数据。 public Result deleteBatchByIds(@PathVariable("ids") String ids) { + // 通过@PathVariable注解获取路径中传入的要批量删除的用户相关标识参数,将其传递给服务层,以便服务层依据这些信息执行批量删除对应的用户记录的业务逻辑。 return iUserService.deleteBatchByIds(ids); + // 调用iUserService接口的deleteBatchByIds方法,由服务层去具体实现根据传入的用户标识批量删除用户的详细业务逻辑,比如从数据库中移除对应的多条用户记录等,最后将操作结果封装到Result对象中返回给客户端。 } - /** - * Excel导入用户数据 - * - * @param file 文件 - * @return 响应结果 - */ + + // Excel导入用户数据 + + //@param file 文件,这是一个MultipartFile类型的参数,用于接收前端上传的包含用户数据的Excel文件,服务层会对该文件进行解析等操作来批量导入用户数据到系统中,方便批量添加用户信息,提高添加效率。 + // @return 响应结果,返回一个Result类型的对象,用于告知客户端Excel导入用户数据操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他与导入操作相关的反馈信息等内容,便于前端知晓导入是否成功及获取相应提示。 + @PostMapping("/import") + // 表明这个方法用于处理HTTP POST请求,其请求路径是在类级别定义的基础路径/api/user基础上添加/import,用于区分其他用户管理相关操作路径,POST请求常用于向服务器提交数据,在此处符合向服务器提交Excel文件用于导入用户数据的场景,便于客户端上传文件进行导入操作。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,只有拥有"role_teacher"或者"role_admin"权限的用户才能访问这个方法,意味着只有教师或管理员角色的用户有权利执行Excel导入用户数据的操作,确保导入操作的权限安全性,防止非法导入数据。 public Result importUsers(@RequestParam("file") MultipartFile file) { + // 通过@RequestParam("file")注解获取前端上传的文件,将其赋值给file变量,以便服务层依据该文件进行后续的用户数据解析和导入业务逻辑处理。 return iUserService.importUsers(file); + // 调用iUserService接口的importUsers方法,由服务层去具体实现根据传入的Excel文件解析并导入用户数据的详细业务逻辑,比如读取文件内容、转换数据格式、插入数据库等操作,最后将操作结果封装到Result对象中返回给客户端。 } - /** - * 用户加入班级,只有学生才能加入班级 - * - * @param code 班级口令 - * @return 响应 - */ + // 用户加入班级,只有学生才能加入班级 + + // @param code 班级口令,这是一个字符串类型的参数,用于指定要加入班级的口令信息,学生通过输入正确的班级口令来申请加入对应的班级,方便进行班级加入的验证操作,确保只有知道口令的学生能加入相应班级。 + // @return 响应,返回一个Result类型的对象,用于告知客户端用户加入班级操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他与班级加入相关的反馈信息等内容,便于前端知晓加入操作是否成功及获取相应提示。 + @PutMapping("/grade/join") + // 表示这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/user基础上添加/grade/join,PUT请求常用于更新资源,这里符合学生更新自己班级归属(即加入班级)的操作场景,便于客户端向服务器提交班级口令等信息进行班级加入操作。 @PreAuthorize("hasAnyAuthority('role_student')") + // 进行权限控制,只有拥有"role_student"(学生角色)权限的用户才能访问这个方法,意味着只有学生角色的用户有权利执行加入班级的操作,确保班级加入操作的权限合理性,防止其他角色非法操作班级成员信息。 public Result joinGrade(@RequestParam("code") String code) { + // 通过@RequestParam("code")注解获取请求中名为"code"的班级口令参数,将其赋值给code变量,以便服务层依据该口令信息进行后续的验证和班级加入业务逻辑处理。 return iUserService.joinGrade(code); + // 调用iUserService接口的joinGrade方法,由服务层去具体实现根据传入的班级口令进行验证并将学生加入相应班级的详细业务逻辑,比如验证口令是否正确、更新数据库中用户与班级的关联关系等操作,最后将操作结果封装到Result对象中返回给客户端。 } - /** - * 分页获取用户信息 - * - * @param pageNum 页码 - * @param pageSize 每页记录数 - * @param gradeId 班级Id - * @param realName 真实姓名 - * @return 响应结果 - */ + + // @param pageNum 页码,是一个整数类型的参数,用于指定要查询的分页数据的页码,比如pageNum为1表示查询第一页的数据,客户端可以根据需要传入相应页码来获取不同页的用户信息,该参数为可选参数,若未传入则默认值为1,方便客户端灵活控制查询的页面位置,以获取期望页面的用户数据展示。 + //@param pageSize 每页记录数,同样是整数类型参数,用于设定每页显示的用户记录数量,默认值为10,表示如果客户端没有指定每页显示多少条记录,就按照每页10条来进行分页查询,便于控制每页展示的用户信息量,满足不同展示需求。 + // @param gradeId 班级Id,是一个整数类型的可选参数,用于根据班级的唯一标识符进行筛选查询,通过传入班级ID,可获取该班级下的用户信息,方便教师、管理员按班级维度查看用户情况,若不传入该参数则可能查询所有班级的用户信息(具体看服务层实现逻辑)。 + // @param realName 真实姓名,是一个字符串类型的可选参数,用于根据用户的真实姓名进行模糊查询等筛选操作,客户端可以传入用户真实姓名的部分或全部内容来查找符合条件的用户信息,便于精准查找特定用户或符合姓名特征的一批用户信息。 + //@return 响应结果,返回一个Result类型的对象,其中封装了IPage类型的数据,IPage用于承载分页后的用户实体对应的视图对象数据,整体通过Result返回给客户端,告知分页查询的结果以及相应的用户数据信息,方便前端展示和使用查询到的用户分页数据。 + @GetMapping("/paging") + // 表示这个方法用于处理HTTP GET请求,其请求路径是在类的基础路径/api/user基础上添加/paging,即/api/user/paging,用于获取分页后的用户信息,符合GET请求获取资源的使用场景,便于客户端发起按条件分页查询用户数据的请求。 @PreAuthorize("hasAnyAuthority('role_teacher','role_admin')") + // 进行权限控制,拥有"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户都可以访问这个方法,意味着教师和管理员角色的用户有权利执行分页查询用户信息的操作,确保有权限的用户才能获取相关数据,保障数据访问的安全性和合理性。 public Result> pagingUser(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, @RequestParam(value = "gradeId", required = false) Integer gradeId, @RequestParam(value = "realName", required = false) String realName) { + // 通过@RequestParam注解分别获取请求中的pageNum、pageSize、gradeId、realName参数,若客户端未传入pageNum和pageSize则分别使用默认值1和10,gradeId用于按班级筛选,realName用于按真实姓名筛选,将获取到的参数传递给服务层进行后续的分页查询逻辑处理。 return iUserService.pagingUser(pageNum, pageSize, gradeId, realName); + // 调用通过依赖注入获取的iUserService接口实例的pagingUser方法,由服务层去具体实现根据传入的页码、每页记录数以及班级ID、真实姓名等筛选条件进行分页查询用户信息的详细业务逻辑,比如从数据库中按照条件筛选并查询用户数据,进行分页处理后封装成对应的视图对象,最后将查询结果封装到Result对象中返回给客户端。 } - /** - * 用户上传头像 - * - * @param file 文件 - * @return 响应结果 - */ + + ///用户上传头像 + + // @param file 文件,这是一个MultipartFile类型的参数,用于接收前端上传的用户头像文件,MultipartFile类型方便处理文件上传相关操作,可获取文件的各种属性(如文件名、文件内容等),以便后续进行头像文件的保存、处理等业务逻辑。 + // @return 响应结果,返回一个Result类型的对象,用于告知客户端用户上传头像操作是否成功以及可能附带的相关提示信息等,其内部封装了操作结果标识以及其他与头像上传相关的反馈信息(比如头像保存后的访问地址等内容,具体看业务逻辑)等内容,便于前端知晓上传操作是否成功及获取相应提示。 + @PutMapping("/uploadAvatar") + // 此注解指定这个方法用于处理HTTP PUT请求,其请求路径是在类的基础路径/api/user基础上添加/uploadAvatar,PUT请求常用于更新资源,这里符合用户更新自己头像(即上传新头像覆盖旧头像)的操作场景,便于客户端向服务器提交头像文件进行更新操作。 @PreAuthorize("hasAnyAuthority('role_student','role_teacher','role_admin')") + // 进行权限控制,拥有"role_student"(学生角色)、"role_teacher"(教师角色)或者"role_admin"(管理员角色)权限的用户都可以访问这个方法,意味着这几种角色的用户都有权利执行上传头像的操作,确保有权限的用户才能进行头像更新,保障头像管理的权限合理性。 public Result uploadAvatar(@RequestPart("file") MultipartFile file) { + // 通过@RequestPart("file")注解获取前端上传的文件,并将其赋值给file变量,以便服务层依据该文件进行后续的头像文件保存、处理等业务逻辑,比如将文件存储到指定位置,更新数据库中用户头像相关的记录等操作。 return iUserService.uploadAvatar(file); + // 调用iUserService接口的uploadAvatar方法,由服务层去具体实现根据传入的头像文件进行上传处理的详细业务逻辑,例如利用相关工具类(可能是前面引入的AliOSSUtil等)将文件上传到存储服务,获取文件存储后的相关信息,最后将操作结果以及相关反馈数据封装到Result对象中返回给客户端。 } -} +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/converter/CertificateConverter.java b/src/main/java/cn/org/alan/exam/converter/CertificateConverter.java index 42a7ac0..5e49975 100644 --- a/src/main/java/cn/org/alan/exam/converter/CertificateConverter.java +++ b/src/main/java/cn/org/alan/exam/converter/CertificateConverter.java @@ -1,11 +1,23 @@ package cn.org.alan.exam.converter; +// 声明该接口所在的包名,用于在项目中对类和接口进行分类组织,表明此接口属于特定的“exam”项目下与数据转换相关的功能模块所在的包,方便代码管理和维护。 import cn.org.alan.exam.model.entity.Certificate; +// 引入Certificate实体类,这个类通常对应数据库中的一张表结构,用于持久化存储证书相关的信息,包含如证书名称、颁发机构、有效期等具体的属性字段,代表了证书在系统中的实际数据存储形式。 + import cn.org.alan.exam.model.form.CertificateForm; +// 引入CertificateForm类,这是一种数据传输对象(Data Transfer Object,DTO)形式的类,一般用于在前端与后端之间或者不同业务层之间传递数据,它承载着与证书相关的输入信息,比如用户在创建或更新证书时填写的证书名称等数据,方便进行数据的交互和传递。 + import org.mapstruct.Mapper; +// 引入Mapstruct框架提供的Mapper注解,用于标识这个接口是一个映射器接口,Mapstruct会根据接口中定义的方法和映射规则,在编译期自动生成对应的实现类,来实现不同对象之间属性的转换,简化了对象转换的代码编写工作。 + import org.mapstruct.Mapping; +// 引入Mapstruct框架提供的Mapping注解,用于在对象转换方法中明确指定源对象和目标对象之间具体属性的映射关系,比如指定某个源属性对应到目标对象的哪个属性上,使得属性的转换更加精确和可控。 + import org.mapstruct.Mappings; +// 引入Mapstruct框架提供的Mappings注解,它是一个容器注解,用于包含多个@Mapping注解,当需要定义多个属性的映射关系时,就可以使用它来统一管理这些映射规则,使代码结构更清晰。 + import org.springframework.stereotype.Component; +// 引入Spring框架的@Component注解,用于将这个接口标记为一个Spring组件,这样Spring容器在进行组件扫描时就能发现并管理它,便于后续在需要的地方通过依赖注入等方式使用该接口对应的功能。 /** * @ Author JinXi @@ -13,11 +25,15 @@ import org.springframework.stereotype.Component; * @ Date 2024/5/11 14:40 */ @Component +// 将该接口标记为Spring组件,使其能被Spring容器管理,从而可以利用Spring的依赖注入等功能在其他类中方便地使用这个接口所定义的对象转换功能。 @Mapper(componentModel="spring") +// 使用@Mapper注解声明这是一个映射器接口,并指定componentModel属性为"spring",告知Mapstruct生成的实现类要以Spring组件的形式进行管理,方便与Spring框架集成,使其可以像普通的Spring Bean一样被注入和使用。 public interface CertificateConverter { @Mappings({ @Mapping(target = "certificateName",source = "certificateName") + // 使用@Mappings注解包裹@Mapping注解,来定义属性的映射规则。这里的@Mapping注解表示将源对象(CertificateForm类型)中的"certificateName"属性值映射到目标对象(Certificate类型)的"certificateName"属性上,也就是在进行对象转换时,同名的证书名称属性会进行对应赋值。 }) Certificate fromToEntity(CertificateForm certificateForm); -} + // 定义了一个名为fromToEntity的方法,它接收一个CertificateForm类型的参数certificateForm,作用是根据定义好的映射规则(上面的@Mappings注解中指定的)将CertificateForm对象转换为Certificate实体对象,方便在业务逻辑中,例如将前端传入的证书相关表单数据转换为可持久化存储到数据库的实体对象形式。 +} \ No newline at end of file diff --git a/src/main/java/cn/org/alan/exam/converter/ExamConverter.java b/src/main/java/cn/org/alan/exam/converter/ExamConverter.java index 1d19652..91db770 100644 --- a/src/main/java/cn/org/alan/exam/converter/ExamConverter.java +++ b/src/main/java/cn/org/alan/exam/converter/ExamConverter.java @@ -1,16 +1,35 @@ package cn.org.alan.exam.converter; +// 声明该接口所在的包名,用于在项目中对类和接口进行分类组织,表明此接口属于特定的“exam”项目下与数据转换相关的功能模块所在的包,方便代码管理与维护。 import cn.org.alan.exam.model.entity.Exam; +// 引入Exam实体类,它对应数据库中存储考试相关信息的表结构,包含如考试名称、考试时间、考试总分等各种与考试相关的属性,代表了考试在系统中的实际数据存储形式,是业务操作中涉及考试数据持久化的核心对象。 + import cn.org.alan.exam.model.entity.ExamQuestion; +// 引入ExamQuestion实体类,用于表示考试题目相关的实体信息,比如题目内容、题目类型(选择题、填空题等)、所属考试等属性,体现了考试题目在数据库中的存储结构和相关关联关系,与考试的具体题目内容相关。 + import cn.org.alan.exam.model.entity.Option; +// 引入Option实体类,通常用于表示题目选项相关的实体信息,比如选择题的各个选项内容、选项是否正确等属性,是针对有选项的题目(如选择题)在数据库中的具体数据存储形式,与题目选项相关的数据操作有关。 + import cn.org.alan.exam.model.form.exam.ExamAddForm; +// 引入ExamAddForm类,这是一种数据传输对象(Data Transfer Object,DTO)形式的类,主要用于在前端与后端之间或者不同业务层之间传递数据,它承载着添加考试时前端输入的各种信息,像考试名称、考试时长等添加考试需要填写的数据,方便进行数据的交互和传递,专用于考试添加场景。 + import cn.org.alan.exam.model.form.exam.ExamUpdateForm; +// 引入ExamUpdateForm类,同样是数据传输对象(DTO)类,用于承载更新考试信息时前端传入的相关数据,例如修改后的考试名称、时间等内容,为考试信息更新操作提供要修改的数据来源,专用于考试更新场景。 + import cn.org.alan.exam.model.vo.exam.*; +// 引入多个以“exam”命名空间下的视图对象(Value Object,VO)类,这些类用于向客户端展示特定格式的考试相关信息,不同的VO类对应不同的业务场景,比如展示考试分页信息、考试详情信息、题目信息等,方便前端按照合适的格式展示数据给用户查看。 + import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +// 引入MyBatis Plus框架提供的Page类,它用于表示分页数据的结构,包含了分页相关的信息(如页码、每页记录数、总记录数等)以及具体的数据列表,在涉及分页查询考试相关信息并转换展示格式时会用到这个类型。 + import org.mapstruct.Mapper; +// 引入Mapstruct框架提供的Mapper注解,用于标识这个接口是一个映射器接口,Mapstruct会根据接口中定义的方法和映射规则,在编译期自动生成对应的实现类,来实现不同对象之间属性的转换,简化了对象转换的代码编写工作,提高开发效率。 + import org.springframework.stereotype.Component; +// 引入Spring框架的@Component注解,用于将这个接口标记为一个Spring组件,这样Spring容器在进行组件扫描时就能发现并管理它,便于后续在需要的地方通过依赖注入等方式使用该接口对应的功能,实现组件化管理。 import java.util.List; +// 引入Java标准库中的List接口,用于表示列表类型的数据结构,在需要返回多个同类型元素(如多个考试题目信息列表、多个选项信息列表等情况)时会用到,便于对一组数据进行统一操作和传递。 /** * @Author Alan @@ -18,24 +37,35 @@ import java.util.List; * @Date 2024/4/1 3:18 PM */ @Component +// 将该接口标记为Spring组件,使其能被Spring容器管理,从而可以利用Spring的依赖注入等功能在其他类中方便地使用这个接口所定义的对象转换功能,便于集成到整个Spring项目体系中。 @Mapper(componentModel="spring") +// 使用@Mapper注解声明这是一个映射器接口,并指定componentModel属性为"spring",告知Mapstruct生成的实现类要以Spring组件的形式进行管理,方便与Spring框架集成,使其可以像普通的Spring Bean一样被注入和使用,实现对象转换功能与Spring的无缝对接。 public interface ExamConverter { Page pageEntityToVo(Page examPage); + // 定义了一个名为pageEntityToVo的方法,它接收一个Page类型的参数examPage,作用是将包含Exam实体对象的分页数据结构(MyBatis Plus中的Page类型,里面包含了考试相关的实体数据以及分页信息)按照一定的映射规则转换为包含ExamVO视图对象的分页数据结构,以便将考试相关信息以适合前端展示的格式(通过ExamVO来定义展示形式)返回给客户端,用于分页展示考试信息的场景。 Exam formToEntity(ExamUpdateForm examUpdateForm); + // 定义了一个名为formToEntity的方法,它接收一个ExamUpdateForm类型的参数examUpdateForm,功能是依据定义好的映射规则(由Mapstruct自动生成实现类时根据对象属性名等规则确定,也可手动配置更精确的映射)将用于更新考试信息的ExamUpdateForm对象转换为Exam实体对象,方便后续将更新后的考试数据持久化到数据库中,适用于考试信息更新的业务逻辑场景。 Exam formToEntity(ExamAddForm examAddForm); + // 同样是一个将数据传输对象转换为实体对象的方法,接收ExamAddForm类型的参数examAddForm,作用是把包含添加考试所需信息的ExamAddForm对象转换为Exam实体对象,以便将前端传来的添加考试信息保存到数据库中,对应考试创建添加的业务操作场景。 List listEntityToExamDetailRespVO(List examQuestion); + // 定义了一个方法,接收一个List类型的参数examQuestion,即考试题目实体对象的列表,目的是按照特定的映射规则将这些考试题目实体对象转换为ExamDetailRespVO视图对象列表,用于将考试题目相关信息以适合前端展示的格式(由ExamDetailRespVO定义)进行展示,比如在展示考试详情中的题目列表时会用到这个转换。 ExamDetailVO examToExamDetailVO(Exam exam); + // 该方法接收一个Exam实体对象作为参数exam,用于将Exam实体按照相应的映射规则转换为ExamDetailVO视图对象,ExamDetailVO通常会包含更详细、更适合前端展示的考试相关信息(相比于原始的Exam实体对象),比如考试的详细配置、关联信息等,常用于向客户端展示考试详细情况的业务场景。 ExamGradeListVO entityToExamGradeListVO(Exam exam); + // 接收Exam实体对象exam,按照一定的映射逻辑将其转换为ExamGradeListVO视图对象,ExamGradeListVO大概率是用于展示考试与班级等相关关联信息(比如某个班级参与此次考试的情况等,具体看其内部定义)的格式,方便在涉及班级与考试关联展示的业务场景中使用。 ExamQuestionVO examQuestionEntityToVO(ExamQuestion examQuestion); + // 接收ExamQuestion实体对象examQuestion,将其转换为ExamQuestionVO视图对象,把考试题目实体的相关数据以适合前端展示的格式(由ExamQuestionVO定义)进行转换,比如对题目内容、题目类型等属性进行整理和格式化,便于前端展示具体的题目信息。 List examQuestionListEntityToVO(List examQuestion); + // 接收考试题目实体对象列表examQuestion,把列表中的每个ExamQuestion实体按照相应映射规则转换为ExamQuestionVO视图对象,并最终返回一个由这些ExamQuestionVO对象组成的列表,用于批量将考试题目实体转换为适合前端展示的题目视图对象列表,比如在展示一场考试的所有题目时会用到这个转换。 List opListEntityToVO(List