ShenHailiang_branch
shl 9 months ago
parent 1b60ce86be
commit 22d20a181a

@ -1,14 +1,15 @@
package com.yf.exam.modules; package com.yf.exam.modules; // 包名:表示该类属于 modules 包
/** /**
* *
* @author bool * 使
* @ bool
*/ */
public class Constant { public class Constant {
/** /**
* *
* Token
*/ */
public static final String TOKEN = "token"; public static final String TOKEN = "token"; // 定义一个常量 TOKEN表示会话中的 Token 名称
} }

@ -1,117 +1,113 @@
package com.yf.exam.modules.repo.controller; package com.yf.exam.modules.repo.controller; // 包名:表示该类属于 repo.controller 包
import com.baomidou.mybatisplus.core.metadata.IPage; // 导入所需的类和包
import com.yf.exam.core.api.ApiRest; import com.baomidou.mybatisplus.core.metadata.IPage; // 分页元数据接口
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.ApiRest; // 统一 API 响应类
import com.yf.exam.core.api.dto.BaseIdReqDTO; import com.yf.exam.core.api.controller.BaseController; // 控制器基类,提供通用控制功能
import com.yf.exam.core.api.dto.BaseIdsReqDTO; import com.yf.exam.core.api.dto.BaseIdReqDTO; // 数据传输对象,用于封装单个 ID 请求
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.BaseIdsReqDTO; // 数据传输对象,用于封装多个 ID 请求
import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 数据传输对象,用于分页请求
import com.yf.exam.modules.qu.service.QuRepoService; import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO; // 数据传输对象,用于题库批量操作请求
import com.yf.exam.modules.repo.dto.RepoDTO; import com.yf.exam.modules.qu.service.QuRepoService; // 服务接口,用于题库的批量操作
import com.yf.exam.modules.repo.dto.request.RepoReqDTO; import com.yf.exam.modules.repo.dto.RepoDTO; // 数据传输对象,封装题库信息
import com.yf.exam.modules.repo.dto.response.RepoRespDTO; import com.yf.exam.modules.repo.dto.request.RepoReqDTO; // 数据传输对象,用于题库分页查询请求
import com.yf.exam.modules.repo.entity.Repo; import com.yf.exam.modules.repo.dto.response.RepoRespDTO; // 数据传输对象,用于题库分页查询响应
import com.yf.exam.modules.repo.service.RepoService; import com.yf.exam.modules.repo.entity.Repo; // 题库实体类
import io.swagger.annotations.Api; import com.yf.exam.modules.repo.service.RepoService; // 服务接口,用于题库操作
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Api; // Swagger 注解,用于 API 文档生成
import org.apache.shiro.authz.annotation.RequiresRoles; import io.swagger.annotations.ApiOperation; // Swagger 注解,用于定义接口操作说明
import org.springframework.beans.BeanUtils; import org.apache.shiro.authz.annotation.RequiresRoles; // Shiro 注解,用于权限控制
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.BeanUtils; // 工具类,用于对象属性拷贝
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.beans.factory.annotation.Autowired; // Spring 注解,用于依赖注入
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody; // 注解,用于绑定请求体
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMapping; // 注解,用于定义请求路径
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMethod; // 注解,用于指定 HTTP 请求方法
import org.springframework.web.bind.annotation.RestController; // 注解,标识为 REST 控制器
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-25 13:25 * @
*/ * @ 2020-05-25 13:25
@Api(tags={"题库"}) */
@RestController @Api(tags = {"题库"}) // Swagger 注解:定义 API 文档中该控制器的标签为“题库”
@RequestMapping("/exam/api/repo") @RestController // Spring 注解:标识该类为 REST 控制器
public class RepoController extends BaseController { @RequestMapping("/exam/api/repo") // 定义请求路径前缀为 /exam/api/repo
public class RepoController extends BaseController { // 题库控制器类,继承基础控制器
@Autowired @Autowired // 自动注入题库服务
private RepoService baseService; private RepoService baseService;
@Autowired @Autowired // 自动注入题库批量操作服务
private QuRepoService quRepoService; private QuRepoService quRepoService;
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "添加或修改") @ApiOperation(value = "添加或修改") // Swagger 注解:定义接口操作说明为“添加或修改”
@RequestMapping(value = "/save", method = { RequestMethod.POST}) @RequestMapping(value = "/save", method = {RequestMethod.POST}) // 定义请求路径为 /save请求方法为 POST
public ApiRest save(@RequestBody RepoDTO reqDTO) { public ApiRest save(@RequestBody RepoDTO reqDTO) { // 添加或修改题库的方法
baseService.save(reqDTO); baseService.save(reqDTO); // 调用服务保存题库信息
return super.success(); return super.success(); // 返回成功结果
} }
/** /**
* *
* @param reqDTO * @param reqDTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "批量删除") @ApiOperation(value = "批量删除") // Swagger 注解:定义接口操作说明为“批量删除”
@RequestMapping(value = "/delete", method = { RequestMethod.POST}) @RequestMapping(value = "/delete", method = {RequestMethod.POST}) // 定义请求路径为 /delete请求方法为 POST
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { // 批量删除题库的方法
//根据ID删除 baseService.removeByIds(reqDTO.getIds()); // 根据 ID 列表删除题库
baseService.removeByIds(reqDTO.getIds()); return super.success(); // 返回成功结果
return super.success();
} }
/** /**
* *
* @param reqDTO * @param reqDTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "查找详情") @ApiOperation(value = "查找详情") // Swagger 注解:定义接口操作说明为“查找详情”
@RequestMapping(value = "/detail", method = { RequestMethod.POST}) @RequestMapping(value = "/detail", method = {RequestMethod.POST}) // 定义请求路径为 /detail请求方法为 POST
public ApiRest<RepoDTO> find(@RequestBody BaseIdReqDTO reqDTO) { public ApiRest<RepoDTO> find(@RequestBody BaseIdReqDTO reqDTO) { // 查找题库详情的方法
Repo entity = baseService.getById(reqDTO.getId()); Repo entity = baseService.getById(reqDTO.getId()); // 根据 ID 查找题库实体
RepoDTO dto = new RepoDTO(); RepoDTO dto = new RepoDTO(); // 创建题库数据传输对象
BeanUtils.copyProperties(entity, dto); BeanUtils.copyProperties(entity, dto); // 将实体属性拷贝到 DTO 中
return super.success(dto); return super.success(dto); // 返回成功结果,包含题库详情
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解:定义接口操作说明为“分页查找”
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = {RequestMethod.POST}) // 定义请求路径为 /paging请求方法为 POST
public ApiRest<IPage<RepoRespDTO>> paging(@RequestBody PagingReqDTO<RepoReqDTO> reqDTO) { public ApiRest<IPage<RepoRespDTO>> paging(@RequestBody PagingReqDTO<RepoReqDTO> reqDTO) { // 分页查找题库的方法
IPage<RepoRespDTO> page = baseService.paging(reqDTO); // 调用服务进行分页查询
//分页查询并转换 return super.success(page); // 返回成功结果,包含分页数据
IPage<RepoRespDTO> page = baseService.paging(reqDTO);
return super.success(page);
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "批量操作", notes = "批量加入或从题库移除") @ApiOperation(value = "批量操作", notes = "批量加入或从题库移除") // Swagger 注解:定义接口操作说明为“批量操作”,并提供备注
@RequestMapping(value = "/batch-action", method = { RequestMethod.POST}) @RequestMapping(value = "/batch-action", method = {RequestMethod.POST}) // 定义请求路径为 /batch-action请求方法为 POST
public ApiRest batchAction(@RequestBody QuRepoBatchReqDTO reqDTO) { public ApiRest batchAction(@RequestBody QuRepoBatchReqDTO reqDTO) { // 批量操作题库的方法
quRepoService.batchAction(reqDTO); // 调用服务执行批量操作
//分页查询并转换 return super.success(); // 返回成功结果
quRepoService.batchAction(reqDTO);
return super.success();
} }
} }

@ -1,43 +1,42 @@
package com.yf.exam.modules.repo.dto; package com.yf.exam.modules.repo.dto; // 包名:表示该类属于 repo.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持序列化
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理日期和时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
@Data */
@ApiModel(value="题库", description="题库") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class RepoDTO implements Serializable { @ApiModel(value = "题库", description = "题库") // Swagger 注解,定义该类的 API 模型名称及描述
public class RepoDTO implements Serializable { // 定义类 RepoDTO实现 Serializable 接口以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "题库ID", required = true) // Swagger 注解,描述该属性为“题库 ID”
private String id; // 定义属性:题库的唯一标识符
@ApiModelProperty(value = "题库ID", required=true) @ApiModelProperty(value = "题库编号", required = true) // Swagger 注解,描述该属性为“题库编号”
private String id; private String code; // 定义属性:题库编号
@ApiModelProperty(value = "题库编号", required=true) @ApiModelProperty(value = "题库名称", required = true) // Swagger 注解,描述该属性为“题库名称”
private String code; private String title; // 定义属性:题库名称
@ApiModelProperty(value = "题库名称", required=true) @ApiModelProperty(value = "题库备注", required = true) // Swagger 注解,描述该属性为“题库备注”
private String title; private String remark; // 定义属性:题库备注信息
@ApiModelProperty(value = "题库备注", required=true) @ApiModelProperty(value = "创建时间", required = true) // Swagger 注解,描述该属性为“创建时间”
private String remark; private Date createTime; // 定义属性:题库的创建时间
@ApiModelProperty(value = "创建时间", required=true) @ApiModelProperty(value = "更新时间", required = true) // Swagger 注解,描述该属性为“更新时间”
private Date createTime; private Date updateTime; // 定义属性:题库的最后更新时间
@ApiModelProperty(value = "更新时间", required=true)
private Date updateTime;
} }

@ -1,30 +1,30 @@
package com.yf.exam.modules.repo.dto.request; package com.yf.exam.modules.repo.dto.request; // 包名:表示该类属于 repo.dto.request 包
import com.yf.exam.modules.repo.dto.RepoDTO; import com.yf.exam.modules.repo.dto.RepoDTO; // 导入 RepoDTO 类,题库数据传输对象
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.util.List; import java.util.List; // 导入 Java 的 List 接口,用于存储排除的题库 ID 列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
@Data */
@ApiModel(value="题库分页请求类", description="题库分页请求类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class RepoReqDTO extends RepoDTO { @ApiModel(value = "题库分页请求类", description = "题库分页请求类") // Swagger 注解,定义该类的 API 模型名称及描述
public class RepoReqDTO extends RepoDTO { // 定义类 RepoReqDTO继承自 RepoDTO
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "排除题库ID", required=true) @ApiModelProperty(value = "排除题库ID", required = true) // Swagger 注解,描述该属性为“需要排除的题库 ID 列表”
private List<String> excludes; private List<String> excludes; // 定义属性:排除的题库 ID 列表
@ApiModelProperty(value = "单选题数量", required=true)
private String title;
@ApiModelProperty(value = "单选题数量", required = true) // Swagger 注解,描述该属性为“单选题数量”
private String title; // 定义属性:单选题数量(注意:变量名可能存在歧义,建议确认或重命名)
} }

@ -1,31 +1,31 @@
package com.yf.exam.modules.repo.dto.response; package com.yf.exam.modules.repo.dto.response; // 包名:表示该类属于 repo.dto.response 包
import com.yf.exam.modules.repo.dto.RepoDTO; import com.yf.exam.modules.repo.dto.RepoDTO; // 导入 RepoDTO 类,题库通用数据传输对象
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
@Data */
@ApiModel(value="题库分页响应类", description="题库分页响应类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class RepoRespDTO extends RepoDTO { @ApiModel(value = "题库分页响应类", description = "题库分页响应类") // Swagger 注解,定义该类的 API 模型名称及描述
public class RepoRespDTO extends RepoDTO { // 定义类 RepoRespDTO继承自 RepoDTO
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "多选题数量", required=true) @ApiModelProperty(value = "多选题数量", required = true) // Swagger 注解,描述该属性为“多选题数量”
private Integer multiCount; private Integer multiCount; // 定义属性:多选题的数量
@ApiModelProperty(value = "单选题数量", required=true) @ApiModelProperty(value = "单选题数量", required = true) // Swagger 注解,描述该属性为“单选题数量”
private Integer radioCount; private Integer radioCount; // 定义属性:单选题的数量
@ApiModelProperty(value = "判断题数量", required=true)
private Integer judgeCount;
@ApiModelProperty(value = "判断题数量", required = true) // Swagger 注解,描述该属性为“判断题数量”
private Integer judgeCount; // 定义属性:判断题的数量
} }

@ -1,59 +1,59 @@
package com.yf.exam.modules.repo.entity; package com.yf.exam.modules.repo.entity; // 包名:表示该类属于 repo.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于定义主键类型
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于映射数据库字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于标识主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于映射数据库表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus ActiveRecord 模式基类
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.util.Date; import java.util.Date; // 导入 Java 的 Date 类,用于表示日期和时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
@Data */
@TableName("el_repo") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class Repo extends Model<Repo> { @TableName("el_repo") // MyBatis-Plus 注解,指定该实体类映射的数据库表名为 "el_repo"
public class Repo extends Model<Repo> { // 定义类 Repo继承 MyBatis-Plus 的 Model 类以支持 ActiveRecord 模式
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
/** /**
* ID * ID
*/ */
@TableId(value = "id", type = IdType.ASSIGN_ID) @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,标识主键字段,并指定主键生成策略为分配 ID
private String id; private String id; // 定义字段:题库的唯一标识符
/** /**
* *
*/ */
private String code; private String code; // 定义字段:题库编号
/** /**
* *
*/ */
private String title; private String title; // 定义字段:题库名称
/** /**
* *
*/ */
private String remark; private String remark; // 定义字段:题库备注信息
/** /**
* *
*/ */
@TableField("create_time") @TableField("create_time") // MyBatis-Plus 注解,指定该字段映射数据库中的 "create_time" 列
private Date createTime; private Date createTime; // 定义字段:题库的创建时间
/** /**
* *
*/ */
@TableField("update_time") @TableField("update_time") // MyBatis-Plus 注解,指定该字段映射数据库中的 "update_time" 列
private Date updateTime; private Date updateTime; // 定义字段:题库的最后更新时间
} }

@ -1,29 +1,29 @@
package com.yf.exam.modules.repo.mapper; package com.yf.exam.modules.repo.mapper; // 包名:表示该类属于 repo.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,用于基本的数据库操作
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 分页插件中的 Page 类
import com.yf.exam.modules.repo.dto.request.RepoReqDTO; import com.yf.exam.modules.repo.dto.request.RepoReqDTO; // 导入用于分页查询的请求数据传输对象 RepoReqDTO
import com.yf.exam.modules.repo.dto.response.RepoRespDTO; import com.yf.exam.modules.repo.dto.response.RepoRespDTO; // 导入用于分页查询的响应数据传输对象 RepoRespDTO
import com.yf.exam.modules.repo.entity.Repo; import com.yf.exam.modules.repo.entity.Repo; // 导入题库实体类 Repo
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param; // 导入 MyBatis 注解,用于标注参数
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * Mapper
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
public interface RepoMapper extends BaseMapper<Repo> { */
public interface RepoMapper extends BaseMapper<Repo> { // RepoMapper 接口,继承自 MyBatis-Plus 的 BaseMapper提供常见的数据库操作
/** /**
* *
* @param page * @param page
* @param query * @param query
* @return * @return
*/ */
IPage<RepoRespDTO> paging(Page page, @Param("query") RepoReqDTO query); IPage<RepoRespDTO> paging(Page page, @Param("query") RepoReqDTO query); // 自定义分页查询方法,返回题库分页响应数据
} }

@ -1,34 +1,34 @@
package com.yf.exam.modules.repo.service; package com.yf.exam.modules.repo.service; // 包名:表示该类属于 repo.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 服务接口,提供通用的数据库操作
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.modules.repo.dto.RepoDTO; import com.yf.exam.modules.repo.dto.RepoDTO; // 导入 RepoDTO 类,题库数据传输对象
import com.yf.exam.modules.repo.dto.request.RepoReqDTO; import com.yf.exam.modules.repo.dto.request.RepoReqDTO; // 导入 RepoReqDTO 类,用于封装分页查询条件
import com.yf.exam.modules.repo.dto.response.RepoRespDTO; import com.yf.exam.modules.repo.dto.response.RepoRespDTO; // 导入 RepoRespDTO 类,题库分页响应数据传输对象
import com.yf.exam.modules.repo.entity.Repo; import com.yf.exam.modules.repo.entity.Repo; // 导入 Repo 实体类,表示题库
/** /**
* <p> * <p>
* *
* </p> * </p>
* * MyBatis-Plus IService
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
public interface RepoService extends IService<Repo> { */
public interface RepoService extends IService<Repo> { // RepoService 接口,继承 MyBatis-Plus 的 IService提供常见数据库操作
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<RepoRespDTO> paging(PagingReqDTO<RepoReqDTO> reqDTO); IPage<RepoRespDTO> paging(PagingReqDTO<RepoReqDTO> reqDTO); // 分页查询方法,接收分页请求数据对象,并返回分页结果
/** /**
* *
* @param reqDTO * @param reqDTO
*/ */
void save(RepoDTO reqDTO); void save(RepoDTO reqDTO); // 保存题库方法,用于保存或更新题库信息
} }

@ -1,39 +1,49 @@
package com.yf.exam.modules.repo.service.impl; package com.yf.exam.modules.repo.service.impl; // 包名:表示该类属于 repo.service.impl 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 服务实现类,用于提供通用的数据库操作
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.repo.dto.RepoDTO; import com.yf.exam.modules.repo.dto.RepoDTO; // 导入 RepoDTO题库数据传输对象
import com.yf.exam.modules.repo.dto.request.RepoReqDTO; import com.yf.exam.modules.repo.dto.request.RepoReqDTO; // 导入 RepoReqDTO封装分页查询条件的请求数据传输对象
import com.yf.exam.modules.repo.dto.response.RepoRespDTO; import com.yf.exam.modules.repo.dto.response.RepoRespDTO; // 导入 RepoRespDTO题库分页响应数据传输对象
import com.yf.exam.modules.repo.entity.Repo; import com.yf.exam.modules.repo.entity.Repo; // 导入 Repo 实体类,表示题库实体
import com.yf.exam.modules.repo.mapper.RepoMapper; import com.yf.exam.modules.repo.mapper.RepoMapper; // 导入 RepoMapper数据访问层接口
import com.yf.exam.modules.repo.service.RepoService; import com.yf.exam.modules.repo.service.RepoService; // 导入 RepoService题库服务接口
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 的 Service 注解,标识该类为服务层组件
/** /**
* <p> * <p>
* *
* </p> * </p>
* * RepoService
* @author *
* @since 2020-05-25 13:23 * @
*/ * @ 2020-05-25 13:23
@Service */
public class RepoServiceImpl extends ServiceImpl<RepoMapper, Repo> implements RepoService { @Service // Spring 注解,标识该类为服务层组件
public class RepoServiceImpl extends ServiceImpl<RepoMapper, Repo> implements RepoService { // 继承 MyBatis-Plus 提供的 ServiceImpl简化数据库操作
/**
*
* @param reqDTO
* @return
*/
@Override @Override
public IPage<RepoRespDTO> paging(PagingReqDTO<RepoReqDTO> reqDTO) { public IPage<RepoRespDTO> paging(PagingReqDTO<RepoReqDTO> reqDTO) {
return baseMapper.paging(reqDTO.toPage(), reqDTO.getParams()); return baseMapper.paging(reqDTO.toPage(), reqDTO.getParams()); // 调用 Mapper 的分页查询方法,传入分页信息和查询条件
} }
/**
*
* @param reqDTO
*/
@Override @Override
public void save(RepoDTO reqDTO) { public void save(RepoDTO reqDTO) {
//复制参数 // 复制参数,将请求数据传输对象的属性复制到实体类中
Repo entity = new Repo(); Repo entity = new Repo(); // 创建 Repo 实体对象
BeanMapper.copy(reqDTO, entity); BeanMapper.copy(reqDTO, entity); // 使用 BeanMapper 工具类复制属性
this.saveOrUpdate(entity); this.saveOrUpdate(entity); // 调用 MyBatis-Plus 提供的 saveOrUpdate 方法,保存或更新实体
} }
} }

@ -1,70 +1,71 @@
package com.yf.exam.modules.sys.config.controller; package com.yf.exam.modules.sys.config.controller; // 包名:表示该类属于 sys.config.controller 包
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入统一的 API 响应类
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入控制器基类,提供通用的控制器功能
import com.yf.exam.core.api.dto.BaseIdRespDTO; import com.yf.exam.core.api.dto.BaseIdRespDTO; // 导入基础响应 DTO用于返回 ID 响应
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.qu.utils.ImageCheckUtils; import com.yf.exam.modules.qu.utils.ImageCheckUtils; // 导入图片检查工具类,用于校验图片地址
import com.yf.exam.modules.sys.config.dto.SysConfigDTO; import com.yf.exam.modules.sys.config.dto.SysConfigDTO; // 导入 SysConfigDTO 类,用于封装系统配置的数据传输对象
import com.yf.exam.modules.sys.config.entity.SysConfig; import com.yf.exam.modules.sys.config.entity.SysConfig; // 导入 SysConfig 实体类,表示系统配置
import com.yf.exam.modules.sys.config.service.SysConfigService; import com.yf.exam.modules.sys.config.service.SysConfigService; // 导入 SysConfigService 服务接口
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 注解,用于 API 文档生成
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 注解,用于定义接口操作说明
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles; // 导入 Shiro 权限控制注解,限制角色访问
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 注解,用于依赖注入
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入注解,用于绑定请求体
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入注解,用于定义请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入注解,用于指定请求方法
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入注解,标识该类为 REST 控制器
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
@Api(tags={"通用配置"}) */
@RestController @Api(tags = {"通用配置"}) // Swagger 注解:定义该类的 API 文档标签为“通用配置”
@RequestMapping("/exam/api/sys/config") @RestController // Spring 注解:标识该类为 REST 控制器
public class SysConfigController extends BaseController { @RequestMapping("/exam/api/sys/config") // 定义请求路径前缀为 /exam/api/sys/config
public class SysConfigController extends BaseController { // SysConfigController 类,继承自 BaseController提供通用功能
@Autowired @Autowired // 自动注入 SysConfigService 服务
private SysConfigService baseService; private SysConfigService baseService;
@Autowired @Autowired // 自动注入 ImageCheckUtils 工具类
private ImageCheckUtils imageCheckUtils; private ImageCheckUtils imageCheckUtils;
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return ID
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "添加或修改") @ApiOperation(value = "添加或修改") // Swagger 注解:定义接口操作说明为“添加或修改”
@RequestMapping(value = "/save", method = { RequestMethod.POST}) @RequestMapping(value = "/save", method = { RequestMethod.POST}) // 定义请求路径为 /save方法为 POST
public ApiRest<BaseIdRespDTO> save(@RequestBody SysConfigDTO reqDTO) { public ApiRest<BaseIdRespDTO> save(@RequestBody SysConfigDTO reqDTO) { // 定义保存或修改系统配置的方法
//复制参数 // 复制请求参数到实体对象
SysConfig entity = new SysConfig(); SysConfig entity = new SysConfig(); // 创建 SysConfig 实体对象
BeanMapper.copy(reqDTO, entity); BeanMapper.copy(reqDTO, entity); // 使用 BeanMapper 工具类将 DTO 的属性拷贝到实体对象
// 校验图片地址 // 校验图片地址是否有效
imageCheckUtils.checkImage(entity.getBackLogo(), "系统LOGO地址错误"); imageCheckUtils.checkImage(entity.getBackLogo(), "系统LOGO地址错误"); // 检查系统LOGO地址是否有效
baseService.saveOrUpdate(entity); baseService.saveOrUpdate(entity); // 调用服务的保存或更新方法
return super.success(new BaseIdRespDTO(entity.getId())); return super.success(new BaseIdRespDTO(entity.getId())); // 返回成功响应,并包含系统配置 ID
} }
/** /**
* *
* @return * @return
*/ */
@ApiOperation(value = "查找详情") @ApiOperation(value = "查找详情") // Swagger 注解:定义接口操作说明为“查找详情”
@RequestMapping(value = "/detail", method = { RequestMethod.POST}) @RequestMapping(value = "/detail", method = { RequestMethod.POST}) // 定义请求路径为 /detail方法为 POST
public ApiRest<SysConfigDTO> find() { public ApiRest<SysConfigDTO> find() { // 定义查找系统配置详情的方法
SysConfigDTO dto = baseService.find(); SysConfigDTO dto = baseService.find(); // 调用服务查找系统配置详情
return super.success(dto); return super.success(dto); // 返回成功响应,包含系统配置详情
} }
} }

@ -1,39 +1,38 @@
package com.yf.exam.modules.sys.config.dto; package com.yf.exam.modules.sys.config.dto; // 包名:表示该类属于 sys.config.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于对象序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* * API
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
@Data */
@ApiModel(value="通用配置", description="通用配置") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysConfigDTO implements Serializable { @ApiModel(value = "通用配置", description = "通用配置") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysConfigDTO implements Serializable { // 定义 SysConfigDTO 类,实现 Serializable 接口以支持序列化
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "ID", required=true) @ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
private String id; private String id; // 定义字段:系统配置的唯一标识符
@ApiModelProperty(value = "系统名称") @ApiModelProperty(value = "系统名称") // Swagger 注解:描述该属性为“系统名称”
private String siteName; private String siteName; // 定义字段:系统名称
@ApiModelProperty(value = "前端LOGO") @ApiModelProperty(value = "前端LOGO") // Swagger 注解描述该属性为“前端LOGO”
private String frontLogo; private String frontLogo; // 定义字段:前端展示用的 LOGO 图片地址
@ApiModelProperty(value = "后台LOGO") @ApiModelProperty(value = "后台LOGO") // Swagger 注解描述该属性为“后台LOGO”
private String backLogo; private String backLogo; // 定义字段:后台管理用的 LOGO 图片地址
@ApiModelProperty(value = "版权信息") @ApiModelProperty(value = "版权信息") // Swagger 注解:描述该属性为“版权信息”
private String copyRight; private String copyRight; // 定义字段:版权信息
} }

@ -1,53 +1,54 @@
package com.yf.exam.modules.sys.config.entity; package com.yf.exam.modules.sys.config.entity; // 包名:表示该类属于 sys.config.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于定义主键类型
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于映射数据库字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于标识主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于映射数据库表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus ActiveRecord 模式基类
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* * `sys_config`
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
@Data */
@TableName("sys_config") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysConfig extends Model<SysConfig> { @TableName("sys_config") // MyBatis-Plus 注解,指定该实体类映射数据库表名为 `sys_config`
public class SysConfig extends Model<SysConfig> { // SysConfig 类继承自 MyBatis-Plus 的 Model 类,启用 ActiveRecord 模式
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
/** /**
* ID * ID
*/ */
@TableId(value = "id", type = IdType.ASSIGN_ID) @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,标识主键字段,并指定主键生成策略为分配 ID
private String id; private String id; // 定义字段:系统配置的唯一标识符
/** /**
* *
*/ */
@TableField("site_name") @TableField("site_name") // MyBatis-Plus 注解,指定该字段映射数据库中的 "site_name" 列
private String siteName; private String siteName; // 定义字段:系统名称
/** /**
* LOGO * LOGO
*/ */
@TableField("front_logo") @TableField("front_logo") // MyBatis-Plus 注解,指定该字段映射数据库中的 "front_logo" 列
private String frontLogo; private String frontLogo; // 定义字段:前端展示的 LOGO 图片地址
/** /**
* LOGO * LOGO
*/ */
@TableField("back_logo") @TableField("back_logo") // MyBatis-Plus 注解,指定该字段映射数据库中的 "back_logo" 列
private String backLogo; private String backLogo; // 定义字段:后台管理系统的 LOGO 图片地址
/** /**
* *
*/ */
@TableField("copy_right") @TableField("copy_right") // MyBatis-Plus 注解,指定该字段映射数据库中的 "copy_right" 列
private String copyRight; private String copyRight; // 定义字段:版权信息
} }

@ -1,16 +1,18 @@
package com.yf.exam.modules.sys.config.mapper; package com.yf.exam.modules.sys.config.mapper; // 包名:表示该类属于 sys.config.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,用于基本的数据库操作
import com.yf.exam.modules.sys.config.entity.SysConfig; import com.yf.exam.modules.sys.config.entity.SysConfig; // 导入 SysConfig 实体类,表示系统配置
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * MyBatis-Plus BaseMapper
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
public interface SysConfigMapper extends BaseMapper<SysConfig> { */
public interface SysConfigMapper extends BaseMapper<SysConfig> { // SysConfigMapper 接口,继承自 MyBatis-Plus 的 BaseMapper
// 该接口继承了 BaseMapper<SysConfig>,因此自动具备了 CRUD 方法,无需手动实现
} }

@ -1,22 +1,23 @@
package com.yf.exam.modules.sys.config.service; package com.yf.exam.modules.sys.config.service; // 包名:表示该类属于 sys.config.service 包
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 提供的 IService 接口,提供通用的数据库操作
import com.yf.exam.modules.sys.config.dto.SysConfigDTO; import com.yf.exam.modules.sys.config.dto.SysConfigDTO; // 导入 SysConfigDTO 类,封装系统配置的数据传输对象
import com.yf.exam.modules.sys.config.entity.SysConfig; import com.yf.exam.modules.sys.config.entity.SysConfig; // 导入 SysConfig 实体类,表示系统配置
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
public interface SysConfigService extends IService<SysConfig> { */
public interface SysConfigService extends IService<SysConfig> { // SysConfigService 接口继承 MyBatis-Plus 的 IService 接口,提供 CRUD 操作
/** /**
* *
* @return * @return DTO
*/ */
SysConfigDTO find(); SysConfigDTO find(); // 定义查找系统配置信息的方法,返回一个 SysConfigDTO 对象
} }

@ -1,34 +1,44 @@
package com.yf.exam.modules.sys.config.service.impl; package com.yf.exam.modules.sys.config.service.impl; // 包名:表示该类属于 sys.config.service.impl 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 类,用于提供常见的数据库操作
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.sys.config.dto.SysConfigDTO; import com.yf.exam.modules.sys.config.dto.SysConfigDTO; // 导入 SysConfigDTO 类,封装系统配置的数据传输对象
import com.yf.exam.modules.sys.config.entity.SysConfig; import com.yf.exam.modules.sys.config.entity.SysConfig; // 导入 SysConfig 实体类,表示系统配置
import com.yf.exam.modules.sys.config.mapper.SysConfigMapper; import com.yf.exam.modules.sys.config.mapper.SysConfigMapper; // 导入 SysConfigMapper数据访问层接口
import com.yf.exam.modules.sys.config.service.SysConfigService; import com.yf.exam.modules.sys.config.service.SysConfigService; // 导入 SysConfigService系统配置服务接口
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 注解,用于标识该类为服务层组件
/** /**
* <p> * <p>
* *
* </p> * </p>
* * SysConfigService
* @author *
* @since 2020-04-17 09:12 * @
*/ * @ 2020-04-17 09:12
@Service */
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService { @Service // Spring 注解,标识该类为服务层组件
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService { // 继承 MyBatis-Plus 的 ServiceImpl 类,简化数据库操作
/**
*
* @return DTO
*/
@Override @Override
public SysConfigDTO find() { public SysConfigDTO find() {
// 创建 QueryWrapper 对象,用于构建查询条件
QueryWrapper<SysConfig> wrapper = new QueryWrapper<>(); QueryWrapper<SysConfig> wrapper = new QueryWrapper<>();
wrapper.last(" LIMIT 1"); wrapper.last(" LIMIT 1"); // 限制查询结果为一条记录
SysConfig entity = this.getOne(wrapper, false); // 使用 getOne 方法查询系统配置的第一条记录
SysConfigDTO dto = new SysConfigDTO(); SysConfig entity = this.getOne(wrapper, false); // false 表示不抛出异常,如果没有结果会返回 null
BeanMapper.copy(entity, dto);
return dto; // 将查询到的实体对象复制到 DTO 对象
SysConfigDTO dto = new SysConfigDTO(); // 创建 SysConfigDTO 对象
BeanMapper.copy(entity, dto); // 使用 BeanMapper 工具类将 SysConfig 实体对象的属性复制到 DTO 中
return dto; // 返回系统配置 DTO
} }
} }

@ -1,150 +1,136 @@
package com.yf.exam.modules.sys.depart.controller; package com.yf.exam.modules.sys.depart.controller; // 包名:表示该类属于 sys.depart.controller 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入统一的 API 响应类
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入控制器基类,提供通用的控制器功能
import com.yf.exam.core.api.dto.BaseIdReqDTO; import com.yf.exam.core.api.dto.BaseIdReqDTO; // 导入基本请求 DTO用于单个 ID 请求
import com.yf.exam.core.api.dto.BaseIdsReqDTO; import com.yf.exam.core.api.dto.BaseIdsReqDTO; // 导入基本请求 DTO用于多个 ID 请求
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; // 导入 SysDepartDTO 数据传输对象
import com.yf.exam.modules.sys.depart.dto.request.DepartSortReqDTO; import com.yf.exam.modules.sys.depart.dto.request.DepartSortReqDTO; // 导入部门排序请求 DTO
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; // 导入部门树状结构响应 DTO
import com.yf.exam.modules.sys.depart.entity.SysDepart; import com.yf.exam.modules.sys.depart.entity.SysDepart; // 导入 SysDepart 实体类,表示部门
import com.yf.exam.modules.sys.depart.service.SysDepartService; import com.yf.exam.modules.sys.depart.service.SysDepartService; // 导入部门服务接口
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 注解,用于 API 文档生成
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 注解,用于定义接口操作说明
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles; // 导入 Shiro 权限控制注解,限制角色访问
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils; // 导入 Spring 的 BeanUtils用于对象属性拷贝
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 注解,用于依赖注入
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入注解,用于绑定请求体
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入注解,用于定义请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入注解,用于指定请求方法
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入注解,标识该类为 REST 控制器
import java.util.List;
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
@Api(tags={"部门信息"}) */
@RestController @Api(tags = {"部门信息"}) // Swagger 注解:定义该类的 API 文档标签为“部门信息”
@RequestMapping("/exam/api/sys/depart") @RestController // Spring 注解:标识该类为 REST 控制器
public class SysDepartController extends BaseController { @RequestMapping("/exam/api/sys/depart") // 定义请求路径前缀为 /exam/api/sys/depart
public class SysDepartController extends BaseController { // SysDepartController 类,继承自 BaseController提供通用功能
@Autowired
@Autowired // 自动注入 SysDepartService 服务
private SysDepartService baseService; private SysDepartService baseService;
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "添加或修改") @ApiOperation(value = "添加或修改") // Swagger 注解:定义接口操作说明为“添加或修改”
@RequestMapping(value = "/save", method = { RequestMethod.POST}) @RequestMapping(value = "/save", method = {RequestMethod.POST}) // 定义请求路径为 /save方法为 POST
public ApiRest save(@RequestBody SysDepartDTO reqDTO) { public ApiRest save(@RequestBody SysDepartDTO reqDTO) { // 添加或修改部门的方法
baseService.save(reqDTO); baseService.save(reqDTO); // 调用服务保存或更新部门信息
return super.success(); return super.success(); // 返回成功响应
} }
/** /**
* *
* @param reqDTO * @param reqDTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "批量删除") @ApiOperation(value = "批量删除") // Swagger 注解:定义接口操作说明为“批量删除”
@RequestMapping(value = "/delete", method = { RequestMethod.POST}) @RequestMapping(value = "/delete", method = {RequestMethod.POST}) // 定义请求路径为 /delete方法为 POST
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { // 批量删除部门的方法
//根据ID删除 baseService.removeByIds(reqDTO.getIds()); // 根据 ID 列表删除部门
baseService.removeByIds(reqDTO.getIds()); return super.success(); // 返回成功响应
return super.success();
} }
/** /**
* *
* @param reqDTO * @param reqDTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "查找详情") @ApiOperation(value = "查找详情") // Swagger 注解:定义接口操作说明为“查找详情”
@RequestMapping(value = "/detail", method = { RequestMethod.POST}) @RequestMapping(value = "/detail", method = {RequestMethod.POST}) // 定义请求路径为 /detail方法为 POST
public ApiRest<SysDepartDTO> find(@RequestBody BaseIdReqDTO reqDTO) { public ApiRest<SysDepartDTO> find(@RequestBody BaseIdReqDTO reqDTO) { // 查找部门详情的方法
SysDepart entity = baseService.getById(reqDTO.getId()); SysDepart entity = baseService.getById(reqDTO.getId()); // 根据 ID 查找部门实体
SysDepartDTO dto = new SysDepartDTO(); SysDepartDTO dto = new SysDepartDTO(); // 创建部门数据传输对象
BeanUtils.copyProperties(entity, dto); BeanUtils.copyProperties(entity, dto); // 将实体对象属性拷贝到 DTO 对象
return super.success(dto); return super.success(dto); // 返回成功响应,包含部门详情
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解:定义接口操作说明为“分页查找”
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = {RequestMethod.POST}) // 定义请求路径为 /paging方法为 POST
public ApiRest<IPage<SysDepartTreeDTO>> paging(@RequestBody PagingReqDTO<SysDepartDTO> reqDTO) { public ApiRest<IPage<SysDepartTreeDTO>> paging(@RequestBody PagingReqDTO<SysDepartDTO> reqDTO) { // 分页查找部门的方法
IPage<SysDepartTreeDTO> page = baseService.paging(reqDTO); // 调用服务进行分页查询
//分页查询并转换 return super.success(page); // 返回成功响应,包含分页数据
IPage<SysDepartTreeDTO> page = baseService.paging(reqDTO);
return super.success(page);
} }
/** /**
* 200 * 200
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "查找列表") @ApiOperation(value = "查找列表") // Swagger 注解:定义接口操作说明为“查找列表”
@RequestMapping(value = "/list", method = { RequestMethod.POST}) @RequestMapping(value = "/list", method = {RequestMethod.POST}) // 定义请求路径为 /list方法为 POST
public ApiRest<List<SysDepartDTO>> list(@RequestBody SysDepartDTO reqDTO) { public ApiRest<List<SysDepartDTO>> list(@RequestBody SysDepartDTO reqDTO) { // 查找部门列表的方法
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); // 创建查询条件
//分页查询并转换 List<SysDepart> list = baseService.list(wrapper); // 获取部门列表
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); List<SysDepartDTO> dtoList = BeanMapper.mapList(list, SysDepartDTO.class); // 将部门实体列表转换为 DTO 列表
return super.success(dtoList); // 返回成功响应,包含部门列表
//转换并返回
List<SysDepart> list = baseService.list(wrapper);
//转换数据
List<SysDepartDTO> dtoList = BeanMapper.mapList(list, SysDepartDTO.class);
return super.success(dtoList);
} }
/** /**
* *
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "树列表") @ApiOperation(value = "树列表") // Swagger 注解:定义接口操作说明为“树列表”
@RequestMapping(value = "/tree", method = { RequestMethod.POST}) @RequestMapping(value = "/tree", method = {RequestMethod.POST}) // 定义请求路径为 /tree方法为 POST
public ApiRest<List<SysDepartTreeDTO>> tree() { public ApiRest<List<SysDepartTreeDTO>> tree() { // 查找部门树状结构的方法
List<SysDepartTreeDTO> dtoList = baseService.findTree(); List<SysDepartTreeDTO> dtoList = baseService.findTree(); // 获取部门树状结构
return super.success(dtoList); return super.success(dtoList); // 返回成功响应,包含部门树状结构
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "分类排序") @ApiOperation(value = "分类排序") // Swagger 注解:定义接口操作说明为“分类排序”
@RequestMapping(value = "/sort", method = { RequestMethod.POST}) @RequestMapping(value = "/sort", method = {RequestMethod.POST}) // 定义请求路径为 /sort方法为 POST
public ApiRest sort(@RequestBody DepartSortReqDTO reqDTO) { public ApiRest sort(@RequestBody DepartSortReqDTO reqDTO) { // 部门排序的方法
baseService.sort(reqDTO.getId(), reqDTO.getSort()); baseService.sort(reqDTO.getId(), reqDTO.getSort()); // 调用服务进行排序
return super.success(); return super.success(); // 返回成功响应
} }
} }

@ -1,42 +1,41 @@
package com.yf.exam.modules.sys.depart.dto; package com.yf.exam.modules.sys.depart.dto; // 包名:表示该类属于 sys.depart.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
@Data */
@ApiModel(value="部门信息", description="部门信息") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysDepartDTO implements Serializable { @ApiModel(value = "部门信息", description = "部门信息") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysDepartDTO implements Serializable { // 实现 Serializable 接口以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
private String id; // 定义字段:部门的唯一标识符
@ApiModelProperty(value = "ID", required=true) @ApiModelProperty(value = "1公司2部门", required = true) // Swagger 注解描述该属性为“1公司2部门”并标记为必填
private String id; private Integer deptType; // 定义字段部门类型1 表示公司2 表示部门
@ApiModelProperty(value = "1公司2部门", required=true) @ApiModelProperty(value = "所属上级", required = true) // Swagger 注解:描述该属性为“所属上级”,并标记为必填
private Integer deptType; private String parentId; // 定义字段:上级部门的 ID
@ApiModelProperty(value = "所属上级", required=true) @ApiModelProperty(value = "部门名称", required = true) // Swagger 注解:描述该属性为“部门名称”,并标记为必填
private String parentId; private String deptName; // 定义字段:部门名称
@ApiModelProperty(value = "部门名称", required=true) @ApiModelProperty(value = "部门编码", required = true) // Swagger 注解:描述该属性为“部门编码”,并标记为必填
private String deptName; private String deptCode; // 定义字段:部门的唯一编码,用于标识部门
@ApiModelProperty(value = "部门编码", required=true)
private String deptCode;
@ApiModelProperty(value = "排序", required=true)
private Integer sort;
@ApiModelProperty(value = "排序", required = true) // Swagger 注解:描述该属性为“排序”,并标记为必填
private Integer sort; // 定义字段:部门排序序号,用于定义显示顺序
} }

@ -1,28 +1,29 @@
package com.yf.exam.modules.sys.depart.dto.request; package com.yf.exam.modules.sys.depart.dto.request; // 包名:表示该类属于 sys.depart.dto.request 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于对象序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-03-14 10:37 * @
*/ * @ 2020-03-14 10:37
@Data */
@ApiModel(value="部门排序请求类", description="部门排序请求类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class DepartSortReqDTO implements Serializable { @ApiModel(value = "部门排序请求类", description = "部门排序请求类") // Swagger 注解:定义该类的 API 模型名称和描述
public class DepartSortReqDTO implements Serializable { // 实现 Serializable 接口以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "分类ID") @ApiModelProperty(value = "分类ID") // Swagger 注解描述该属性为“分类ID”
private String id; private String id; // 定义字段:分类的唯一标识符
@ApiModelProperty(value = "排序0下降1上升") @ApiModelProperty(value = "排序0下降1上升") // Swagger 注解描述该属性为“排序”0 表示下降1 表示上升
private Integer sort; private Integer sort; // 定义字段排序方式0 为下降排序1 为上升排序
} }

@ -1,28 +1,27 @@
package com.yf.exam.modules.sys.depart.dto.response; package com.yf.exam.modules.sys.depart.dto.response; // 包名:表示该类属于 sys.depart.dto.response 包
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; // 导入 SysDepartDTO 类,表示部门的基本信息
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.util.List; import java.util.List; // 导入 List 接口,用于存储子部门列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
@Data */
@ApiModel(value="部门树结构响应类", description="部门树结构响应类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysDepartTreeDTO extends SysDepartDTO { @ApiModel(value = "部门树结构响应类", description = "部门树结构响应类") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysDepartTreeDTO extends SysDepartDTO { // 继承 SysDepartDTO扩展支持树形结构
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "子列表", required=true) @ApiModelProperty(value = "子列表", required = true) // Swagger 注解:描述该属性为“子列表”,标记为必填
private List<SysDepartTreeDTO> children; private List<SysDepartTreeDTO> children; // 定义字段:子部门列表,支持递归嵌套表示树形结构
} }

@ -1,59 +1,59 @@
package com.yf.exam.modules.sys.depart.entity; package com.yf.exam.modules.sys.depart.entity; // 包名:表示该类属于 sys.depart.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于定义主键类型
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于映射数据库字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于标识主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于映射数据库表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus 的 Model 基类,用于支持 ActiveRecord 模式
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* * `sys_depart`
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
@Data */
@TableName("sys_depart") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysDepart extends Model<SysDepart> { @TableName("sys_depart") // MyBatis-Plus 注解,指定该类映射的数据库表名为 `sys_depart`
public class SysDepart extends Model<SysDepart> { // 继承 MyBatis-Plus 的 Model 类,支持 ActiveRecord 模式
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
/** /**
* ID * ID
*/ */
@TableId(value = "id", type = IdType.ASSIGN_ID) @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,指定主键字段及其生成策略为 ASSIGN_ID
private String id; private String id; // 部门的唯一标识符
/** /**
* 12 * 12
*/ */
@TableField("dept_type") @TableField("dept_type") // MyBatis-Plus 注解,指定该字段映射数据库中的 `dept_type` 列
private Integer deptType; private Integer deptType; // 部门类型1 表示公司2 表示部门
/** /**
* *
*/ */
@TableField("parent_id") @TableField("parent_id") // MyBatis-Plus 注解,指定该字段映射数据库中的 `parent_id` 列
private String parentId; private String parentId; // 上级部门的 ID用于定义层级关系
/** /**
* *
*/ */
@TableField("dept_name") @TableField("dept_name") // MyBatis-Plus 注解,指定该字段映射数据库中的 `dept_name` 列
private String deptName; private String deptName; // 部门的名称,用于显示和标识部门
/** /**
* *
*/ */
@TableField("dept_code") @TableField("dept_code") // MyBatis-Plus 注解,指定该字段映射数据库中的 `dept_code` 列
private String deptCode; private String deptCode; // 部门的唯一编码,用于标识部门
/** /**
* *
*/ */
private Integer sort; private Integer sort; // 排序字段,用于定义部门显示的顺序
} }

@ -1,28 +1,29 @@
package com.yf.exam.modules.sys.depart.mapper; package com.yf.exam.modules.sys.depart.mapper; // 包名:表示该类属于 sys.depart.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,用于提供基础的数据库操作
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 的分页插件中的 Page 类
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; // 导入部门数据传输对象,用于封装查询条件
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; // 导入部门树形结构响应对象
import com.yf.exam.modules.sys.depart.entity.SysDepart; import com.yf.exam.modules.sys.depart.entity.SysDepart; // 导入部门实体类
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param; // 导入 MyBatis 注解,用于标注参数
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* *
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
public interface SysDepartMapper extends BaseMapper<SysDepart> { */
public interface SysDepartMapper extends BaseMapper<SysDepart> { // SysDepartMapper 接口,继承 MyBatis-Plus 的 BaseMapper
/** /**
* *
* @param page * @param page
* @param query * @param query
* @return * @return
*/ */
IPage<SysDepartTreeDTO> paging(Page page, @Param("query") SysDepartDTO query); IPage<SysDepartTreeDTO> paging(Page page, @Param("query") SysDepartDTO query); // 自定义分页查询方法,返回部门树形结构的分页数据
} }

@ -1,62 +1,62 @@
package com.yf.exam.modules.sys.depart.service; package com.yf.exam.modules.sys.depart.service; // 包名:表示该接口属于 sys.depart.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的分页接口,用于返回分页查询结果
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,用于提供通用的数据库操作
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; // 导入 SysDepartDTO 数据传输对象,用于封装部门数据
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; // 导入 SysDepartTreeDTO 类,用于表示部门树形结构
import com.yf.exam.modules.sys.depart.entity.SysDepart; import com.yf.exam.modules.sys.depart.entity.SysDepart; // 导入 SysDepart 实体类,表示部门
import java.util.List; import java.util.List; // 导入 List 接口,用于存储部门 ID 或部门列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
public interface SysDepartService extends IService<SysDepart> { */
public interface SysDepartService extends IService<SysDepart> { // SysDepartService 接口继承 MyBatis-Plus 的 IService 接口,提供 CRUD 操作
/** /**
* *
* @param reqDTO * @param reqDTO
*/ */
void save(SysDepartDTO reqDTO); void save(SysDepartDTO reqDTO); // 保存部门信息方法,接收部门数据传输对象
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO); IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO); // 分页查询部门树的方法
/** /**
* *
* @return * @return
*/ */
List<SysDepartTreeDTO> findTree(); List<SysDepartTreeDTO> findTree(); // 查找所有部门树的方法,返回树形结构数据
/** /**
* * ID
* @param ids * @param ids ID
* @return * @return
*/ */
List<SysDepartTreeDTO> findTree(List<String> ids); List<SysDepartTreeDTO> findTree(List<String> ids); // 查找指定部门ID列表下的部门树的方法
/** /**
* *
* @param id * @param id ID
* @param sort * @param sort 01
*/ */
void sort(String id, Integer sort); void sort(String id, Integer sort); // 排序部门的方法,支持上升和下降排序
/** /**
* IDID * IDID
* @param id * @param id ID
* @return * @return ID
*/ */
List<String> listAllSubIds( String id); List<String> listAllSubIds(String id); // 获取某个部门下所有子部门ID的方法
} }

@ -1,227 +1,233 @@
package com.yf.exam.modules.sys.depart.service.impl; package com.yf.exam.modules.sys.depart.service.impl; // 包名:表示该类属于 sys.depart.service.impl 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 分页插件中的 Page 类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 类,用于提供通用的数据库操作
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; import com.yf.exam.modules.sys.depart.dto.SysDepartDTO; // 导入 SysDepartDTO 类,封装部门数据传输对象
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO; // 导入 SysDepartTreeDTO 类,用于部门树形结构
import com.yf.exam.modules.sys.depart.entity.SysDepart; import com.yf.exam.modules.sys.depart.entity.SysDepart; // 导入 SysDepart 实体类,表示部门
import com.yf.exam.modules.sys.depart.mapper.SysDepartMapper; import com.yf.exam.modules.sys.depart.mapper.SysDepartMapper; // 导入部门的 Mapper 接口,用于数据库交互
import com.yf.exam.modules.sys.depart.service.SysDepartService; import com.yf.exam.modules.sys.depart.service.SysDepartService; // 导入部门服务接口
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils; // 导入 Apache Commons Lang3 库中的 StringUtils用于字符串操作
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 注解,用于标识该类为服务层组件
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils; // 导入 Spring 的 CollectionUtils 工具类,用于集合操作
import java.util.ArrayList; import java.util.ArrayList; // 导入 ArrayList 类,用于列表数据存储
import java.util.HashMap; import java.util.HashMap; // 导入 HashMap 类,用于映射键值对
import java.util.List; import java.util.List; // 导入 List 接口,用于存储列表数据
import java.util.Map; import java.util.Map; // 导入 Map 接口,用于映射键值对
/** /**
* <p> * <p>
* *
* </p> * </p>
* * SysDepartService
* @author *
* @since 2020-09-02 17:25 * @
*/ * @ 2020-09-02 17:25
@Service */
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements SysDepartService { @Service // Spring 注解,标识该类为服务层组件
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements SysDepartService { // 继承 MyBatis-Plus 的 ServiceImpl 类,简化数据库操作
/** /**
* 0 * 0
*/ */
private static final String ROOT_TAG = "0"; private static final String ROOT_TAG = "0"; // 顶级部门标识符
/**
*
* @param reqDTO
*/
@Override @Override
public void save(SysDepartDTO reqDTO) { public void save(SysDepartDTO reqDTO) {
// 如果部门ID为空生成部门编码
if(StringUtils.isBlank(reqDTO.getId())) { if(StringUtils.isBlank(reqDTO.getId())) {
this.fillCode(reqDTO); this.fillCode(reqDTO); // 填充部门编码
}else{ } else {
reqDTO.setSort(null); reqDTO.setSort(null); // 如果有ID则清空排序字段
reqDTO.setDeptCode(null); reqDTO.setDeptCode(null); // 清空部门编码
} }
SysDepart entity = new SysDepart(); SysDepart entity = new SysDepart(); // 创建部门实体对象
BeanMapper.copy(reqDTO, entity); BeanMapper.copy(reqDTO, entity); // 将 DTO 数据拷贝到实体对象
this.saveOrUpdate(entity); this.saveOrUpdate(entity); // 保存或更新部门信息
} }
/**
*
* @param reqDTO
* @return
*/
@Override @Override
public IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO) { public IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO) {
// 创建分页对象 // 创建分页对象
Page query = new Page(reqDTO.getCurrent(), reqDTO.getSize()); Page query = new Page(reqDTO.getCurrent(), reqDTO.getSize());
// 请求参数 // 获取查询条件
SysDepartDTO params = reqDTO.getParams(); SysDepartDTO params = reqDTO.getParams();
//转换结果 // 执行分页查询
IPage<SysDepartTreeDTO> pageData = baseMapper.paging(query, params); IPage<SysDepartTreeDTO> pageData = baseMapper.paging(query, params);
return pageData; return pageData; // 返回分页结果
} }
/**
*
* @return
*/
@Override @Override
public List<SysDepartTreeDTO> findTree() { public List<SysDepartTreeDTO> findTree() {
return this.findTree(null); return this.findTree(null); // 默认查找所有部门
} }
/**
* ID
* @param ids ID
* @return
*/
@Override @Override
public List<SysDepartTreeDTO> findTree(List<String> ids) { public List<SysDepartTreeDTO> findTree(List<String> ids) {
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); // 创建查询条件
wrapper.lambda().orderByAsc(SysDepart::getSort); // 按照排序字段升序排列
QueryWrapper<SysDepart> wrapper = new QueryWrapper(); // 如果传入了部门ID列表递归获取所有父级部门
wrapper.lambda().orderByAsc(SysDepart::getSort);
if(!CollectionUtils.isEmpty(ids)){ if(!CollectionUtils.isEmpty(ids)){
List<String> fullIds = new ArrayList<>(); List<String> fullIds = new ArrayList<>(); // 用于存储所有父部门ID
for(String id: ids){ for(String id: ids){
this.cycleAllParent(fullIds, id); this.cycleAllParent(fullIds, id); // 递归获取所有父部门ID
} }
if(!CollectionUtils.isEmpty(fullIds)){ if(!CollectionUtils.isEmpty(fullIds)){
wrapper.lambda().in(SysDepart::getId, fullIds); wrapper.lambda().in(SysDepart::getId, fullIds); // 根据部门ID列表查询
} }
} }
//全部列表 // 获取所有部门数据
List<SysDepart> list = this.list(wrapper); List<SysDepart> list = this.list(wrapper);
List<SysDepartTreeDTO> dtoList = BeanMapper.mapList(list, SysDepartTreeDTO.class); List<SysDepartTreeDTO> dtoList = BeanMapper.mapList(list, SysDepartTreeDTO.class); // 将部门实体列表转换为部门树形结构DTO列表
//子结构的列表
Map<String,List<SysDepartTreeDTO>> map = new HashMap<>(16);
// 构建子部门的映射关系
Map<String, List<SysDepartTreeDTO>> map = new HashMap<>(16);
for(SysDepartTreeDTO item: dtoList){ for(SysDepartTreeDTO item: dtoList){
// 如果当前部门已经有子部门,直接添加
//如果存在
if(map.containsKey(item.getParentId())){ if(map.containsKey(item.getParentId())){
map.get(item.getParentId()).add(item); map.get(item.getParentId()).add(item);
continue; continue;
} }
//增加新的结构 // 如果没有子部门,则新建一个子部门列表
List<SysDepartTreeDTO> a = new ArrayList<>(); List<SysDepartTreeDTO> a = new ArrayList<>();
a.add(item); a.add(item);
map.put(item.getParentId(), a); map.put(item.getParentId(), a);
} }
//注意第0级为顶级的 // 获取顶级部门parentId 为 ROOT_TAG
List<SysDepartTreeDTO> topList = map.get(ROOT_TAG); List<SysDepartTreeDTO> topList = map.get(ROOT_TAG);
if(!CollectionUtils.isEmpty(topList)){ if(!CollectionUtils.isEmpty(topList)){
for(SysDepartTreeDTO item: topList){ for(SysDepartTreeDTO item: topList){
this.fillChildren(map, item); this.fillChildren(map, item); // 填充子部门
} }
} }
return topList; return topList; // 返回顶级部门及其子部门树
} }
/**
*
* @param id ID
* @param sort 01
*/
@Override @Override
public void sort(String id, Integer sort) { public void sort(String id, Integer sort) {
SysDepart depart = this.getById(id); SysDepart depart = this.getById(id); // 获取部门实体
SysDepart exchange = null; SysDepart exchange = null;
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); // 创建查询条件
// 同级排序 // 根据部门的父ID查询同级别的部门
wrapper.lambda() wrapper.lambda().eq(SysDepart::getParentId, depart.getParentId());
.eq(SysDepart::getParentId, depart.getParentId());
wrapper.last("LIMIT 1"); wrapper.last("LIMIT 1");
// 上升 // 上升排序
if(sort == 0){ if(sort == 0){
// 同级排序 wrapper.lambda().lt(SysDepart::getSort, depart.getSort()).orderByDesc(SysDepart::getSort); // 查找排序小于当前部门的部门
wrapper.lambda() exchange = this.getOne(wrapper, false); // 获取交换部门
.lt(SysDepart::getSort, depart.getSort())
.orderByDesc(SysDepart::getSort);
exchange = this.getOne(wrapper, false);
} }
// 下降 // 下降排序
if(sort == 1){ if(sort == 1){
// 同级排序 wrapper.lambda().gt(SysDepart::getSort, depart.getSort()).orderByAsc(SysDepart::getSort); // 查找排序大于当前部门的部门
wrapper.lambda() exchange = this.getOne(wrapper, false); // 获取交换部门
.gt(SysDepart::getSort, depart.getSort())
.orderByAsc(SysDepart::getSort);
exchange = this.getOne(wrapper, false);
} }
// 如果找到了交换的部门,进行交换排序
if(exchange!=null) { if(exchange != null) {
SysDepart a = new SysDepart(); SysDepart a = new SysDepart();
a.setId(id); a.setId(id);
a.setSort(exchange.getSort()); a.setSort(exchange.getSort());
SysDepart b = new SysDepart(); SysDepart b = new SysDepart();
b.setId(exchange.getId()); b.setId(exchange.getId());
b.setSort(depart.getSort()); b.setSort(depart.getSort());
this.updateById(a); this.updateById(a); // 更新部门a的排序
this.updateById(b); this.updateById(b); // 更新部门b的排序
} }
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return
*/ */
private void fillCode(SysDepartDTO reqDTO){ private void fillCode(SysDepartDTO reqDTO){
// 前缀
String code = ""; String code = "";
if(StringUtils.isNotBlank(reqDTO.getParentId()) // 获取上级部门编码
&& !ROOT_TAG.equals(reqDTO.getParentId())){ if(StringUtils.isNotBlank(reqDTO.getParentId()) && !ROOT_TAG.equals(reqDTO.getParentId())){
SysDepart parent = this.getById(reqDTO.getParentId()); SysDepart parent = this.getById(reqDTO.getParentId());
code = parent.getDeptCode(); code = parent.getDeptCode(); // 获取上级部门的编码
} }
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysDepart::getParentId, reqDTO.getParentId()).orderByDesc(SysDepart::getSort); // 查询同级部门
// 同级排序
wrapper.lambda()
.eq(SysDepart::getParentId, reqDTO.getParentId())
.orderByDesc(SysDepart::getSort);
wrapper.last("LIMIT 1");
SysDepart depart = this.getOne(wrapper, false); SysDepart depart = this.getOne(wrapper, false);
if(depart != null){
if(depart !=null){ code += this.formatCode(depart.getSort() + 1); // 根据排序生成部门编码
code += this.formatCode(depart.getSort()+1); reqDTO.setSort(depart.getSort() + 1); // 设置部门的排序
reqDTO.setSort(depart.getSort()+1); } else {
}else{ code += this.formatCode(1); // 如果没有同级部门则从1开始
code += this.formatCode(1); reqDTO.setSort(1); // 设置部门的排序为1
reqDTO.setSort(1);
} }
reqDTO.setDeptCode(code); reqDTO.setDeptCode(code); // 设置部门编码
} }
/** /**
* 0 *
* @param sort * @param sort
* @return * @return
*/ */
private String formatCode(Integer sort){ private String formatCode(Integer sort){
if(sort < 10){ if(sort < 10){
return "A0"+sort; return "A0" + sort; // 排序小于10时返回带前导零的编码
} }
return "A"+sort; return "A" + sort; // 排序大于或等于10时返回正常编码
} }
/** /**
* *
* @param map * @param map
* @param item * @param item
*/ */
private void fillChildren(Map<String,List<SysDepartTreeDTO>> map, SysDepartTreeDTO item){ private void fillChildren(Map<String, List<SysDepartTreeDTO>> map, SysDepartTreeDTO item){
//设置子类 //设置子类
if(map.containsKey(item.getId())){ if(map.containsKey(item.getId())){
@ -229,60 +235,61 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
List<SysDepartTreeDTO> children = map.get(item.getId()); List<SysDepartTreeDTO> children = map.get(item.getId());
if(!CollectionUtils.isEmpty(children)){ if(!CollectionUtils.isEmpty(children)){
for(SysDepartTreeDTO sub: children){ for(SysDepartTreeDTO sub: children){
this.fillChildren(map, sub); this.fillChildren(map, sub); // 递归填充子部门
} }
} }
item.setChildren(children); item.setChildren(children); // 设置子部门列表
} }
} }
/**
* ID
* @param id ID
* @return ID
*/
@Override @Override
public List<String> listAllSubIds( String id){ public List<String> listAllSubIds(String id){
List<String> ids = new ArrayList<>(); List<String> ids = new ArrayList<>();
this.cycleAllSubs(ids, id); this.cycleAllSubs(ids, id); // 递归获取所有子部门的ID
return ids; return ids;
} }
/** /**
* ID * ID
* @param list * @param list ID
* @param id * @param id ID
*/ */
private void cycleAllSubs(List<String> list, String id){ private void cycleAllSubs(List<String> list, String id){
// 添加ID // 添加当前部门ID
list.add(id); list.add(id);
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>(); QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(SysDepart::getParentId, id) .eq(SysDepart::getParentId, id)
.orderByDesc(SysDepart::getSort); .orderByDesc(SysDepart::getSort); // 查询当前部门的所有子部门
List<SysDepart> subList = this.list(wrapper); List<SysDepart> subList = this.list(wrapper);
if(!CollectionUtils.isEmpty(subList)){ if(!CollectionUtils.isEmpty(subList)){
for(SysDepart item: subList){ for(SysDepart item: subList){
this.cycleAllSubs(list, item.getId()); this.cycleAllSubs(list, item.getId()); // 递归查询子部门
} }
} }
} }
/** /**
* ID * ID
* @param list * @param list ID
* @param id * @param id ID
*/ */
private void cycleAllParent(List<String> list, String id){ private void cycleAllParent(List<String> list, String id){
// 往上递归获得父类 // 往上递归获取父部门
list.add(id); list.add(id);
SysDepart depart = this.getById(id); SysDepart depart = this.getById(id);
if(StringUtils.isNotBlank(depart.getParentId()) if(StringUtils.isNotBlank(depart.getParentId()) && !ROOT_TAG.equals(depart.getParentId())){
&& !ROOT_TAG.equals(depart.getParentId())){ this.cycleAllParent(list, depart.getParentId()); // 递归查询父部门
this.cycleAllParent(list, depart.getParentId());
} }
} }
} }

@ -1,29 +1,30 @@
package com.yf.exam.modules.sys.system.mapper; package com.yf.exam.modules.sys.system.mapper; // 包名:表示该接口属于 sys.system.mapper 包
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper; // 导入 MyBatis 的 @Mapper 注解,表示这是一个 Mapper 接口
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param; // 导入 MyBatis 的 @Param 注解,用于指定参数名称
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* *
* @author *
* @since 2020-08-22 13:46 * @
*/ * @ 2020-08-22 13:46
@Mapper */
@Mapper // MyBatis 注解,表示该接口为 Mapper 接口MyBatis 会自动生成相应的实现
public interface SysDictMapper { public interface SysDictMapper {
/** /**
* *
* @param table * @param table
* @param text * @param text
* @param key * @param key
* @param value * @param value
* @return * @return
*/ */
String findDict(@Param("table") String table, String findDict(@Param("table") String table, // 使用 @Param 注解绑定 SQL 参数名
@Param("text") String text, @Param("text") String text, // 绑定 SQL 参数 text
@Param("key") String key, @Param("key") String key, // 绑定 SQL 参数 key
@Param("value") String value); @Param("value") String value); // 绑定 SQL 参数 value
} }

@ -1,21 +1,25 @@
package com.yf.exam.modules.sys.system.service; package com.yf.exam.modules.sys.system.service; // 包名:表示该接口属于 sys.system.service 包
/** /**
* *
* @author bool *
*
* @ bool
*/ */
public interface SysDictService { public interface SysDictService { // 定义 SysDictService 接口,提供数据字典的服务
/** /**
* *
* @param table *
* @param text *
* @param key * @param table
* @param value * @param text
* @return * @param key
* @param value
* @return
*/ */
String findDict(String table, String findDict(String table, // 表示字典数据的表名
String text, String text, // 字段文本,用于描述字段
String key, String key, // 字段的键
String value); String value); // 字段的值,查询条件之一
} }

@ -1,21 +1,30 @@
package com.yf.exam.modules.sys.system.service.impl; package com.yf.exam.modules.sys.system.service.impl; // 包名:表示该类属于 sys.system.service.impl 包
import com.yf.exam.modules.sys.system.mapper.SysDictMapper; import com.yf.exam.modules.sys.system.mapper.SysDictMapper; // 导入 SysDictMapper 接口,用于操作数据字典
import com.yf.exam.modules.sys.system.service.SysDictService; import com.yf.exam.modules.sys.system.service.SysDictService; // 导入 SysDictService 接口,定义数据字典的业务逻辑
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 的 @Autowired 注解,用于自动注入依赖
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 的 @Service 注解,用于标识该类为服务层组件
/** /**
* SysDictServiceImpl
* @author bool * @author bool
*/ */
@Service @Service // Spring 注解,标识该类为服务层组件
public class SysDictServiceImpl implements SysDictService { public class SysDictServiceImpl implements SysDictService { // 实现 SysDictService 接口
@Autowired @Autowired // 自动注入 SysDictMapper
private SysDictMapper sysDictMapper; private SysDictMapper sysDictMapper;
/**
*
* @param table
* @param text
* @param key
* @param value
* @return
*/
@Override @Override
public String findDict(String table, String text, String key, String value) { public String findDict(String table, String text, String key, String value) {
return sysDictMapper.findDict(table, text, key, value); return sysDictMapper.findDict(table, text, key, value); // 调用 Mapper 层的方法查找字典数据
} }
} }

@ -1,77 +1,75 @@
package com.yf.exam.modules.sys.user.controller; package com.yf.exam.modules.sys.user.controller; // 包名:表示该类属于 sys.user.controller 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入统一的 API 响应类
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入基类控制器,提供通用功能
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象属性拷贝
import com.yf.exam.modules.sys.user.dto.SysRoleDTO; import com.yf.exam.modules.sys.user.dto.SysRoleDTO; // 导入 SysRoleDTO 数据传输对象
import com.yf.exam.modules.sys.user.entity.SysRole; import com.yf.exam.modules.sys.user.entity.SysRole; // 导入 SysRole 实体类,表示角色
import com.yf.exam.modules.sys.user.service.SysRoleService; import com.yf.exam.modules.sys.user.service.SysRoleService; // 导入 SysRoleService 服务接口
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 注解,用于定义 API 文档
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 注解,用于描述接口操作
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles; // 导入 Shiro 注解,用于权限控制,限制访问角色
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 注解,用于自动注入依赖
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入注解,用于绑定请求体
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入注解,用于定义请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入注解,用于指定请求方法
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入注解,标识该类为 REST 控制器
import java.util.List; import java.util.List; // 导入 List 接口,用于存储角色列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
* @ 2020-04-13 16:57
*/ */
@Api(tags = {"管理用户"}) @Api(tags = {"管理用户"}) // Swagger 注解:定义该类的 API 文档标签为“管理用户”
@RestController @RestController // Spring 注解:标识该类为 REST 控制器,处理 HTTP 请求
@RequestMapping("/exam/api/sys/role") @RequestMapping("/exam/api/sys/role") // 定义请求路径前缀为 /exam/api/sys/role
public class SysRoleController extends BaseController { public class SysRoleController extends BaseController { // SysRoleController 继承自 BaseController提供通用功能
@Autowired @Autowired // 自动注入 SysRoleService 服务
private SysRoleService baseService; private SysRoleService baseService;
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解:描述接口操作为“分页查找”
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = { RequestMethod.POST}) // 请求路径为 /paging方法为 POST
public ApiRest<IPage<SysRoleDTO>> paging(@RequestBody PagingReqDTO<SysRoleDTO> reqDTO) { public ApiRest<IPage<SysRoleDTO>> paging(@RequestBody PagingReqDTO<SysRoleDTO> reqDTO) {
//分页查询并转换 // 调用服务层进行分页查询,并返回角色数据
IPage<SysRoleDTO> page = baseService.paging(reqDTO); IPage<SysRoleDTO> page = baseService.paging(reqDTO);
return super.success(page); return super.success(page); // 返回成功响应,包含分页数据
} }
/** /**
* 200 * 200
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "查找列表") @ApiOperation(value = "查找列表") // Swagger 注解:描述接口操作为“查找列表”
@RequestMapping(value = "/list", method = { RequestMethod.POST}) @RequestMapping(value = "/list", method = { RequestMethod.POST}) // 请求路径为 /list方法为 POST
public ApiRest<List<SysRoleDTO>> list() { public ApiRest<List<SysRoleDTO>> list() {
//分页查询并转换 // 创建查询条件
QueryWrapper<SysRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
//转换并返回 // 获取所有角色数据
List<SysRole> list = baseService.list(wrapper); List<SysRole> list = baseService.list(wrapper);
//转换数据 // 将角色实体数据转换为角色数据传输对象
List<SysRoleDTO> dtoList = BeanMapper.mapList(list, SysRoleDTO.class); List<SysRoleDTO> dtoList = BeanMapper.mapList(list, SysRoleDTO.class);
return super.success(dtoList); return super.success(dtoList); // 返回成功响应,包含角色列表
} }
} }

@ -1,182 +1,185 @@
package com.yf.exam.modules.sys.user.controller; package com.yf.exam.modules.sys.user.controller; // 包名:表示该类属于 sys.user.controller 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入统一的 API 响应类
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入基类控制器,提供通用功能
import com.yf.exam.core.api.dto.BaseIdsReqDTO; import com.yf.exam.core.api.dto.BaseIdsReqDTO; // 导入基本请求 DTO用于处理多个 ID 请求
import com.yf.exam.core.api.dto.BaseStateReqDTO; import com.yf.exam.core.api.dto.BaseStateReqDTO; // 导入基本状态请求 DTO用于更新状态
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO
import com.yf.exam.modules.sys.user.dto.SysUserDTO; import com.yf.exam.modules.sys.user.dto.SysUserDTO; // 导入 SysUserDTO 数据传输对象
import com.yf.exam.modules.sys.user.dto.request.SysUserLoginReqDTO; import com.yf.exam.modules.sys.user.dto.request.SysUserLoginReqDTO; // 导入 SysUserLoginReqDTO 登录请求 DTO
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; // 导入 SysUserSaveReqDTO 保存请求 DTO
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; // 导入 SysUserLoginDTO 登录响应 DTO
import com.yf.exam.modules.sys.user.entity.SysUser; import com.yf.exam.modules.sys.user.entity.SysUser; // 导入 SysUser 实体类,表示系统用户
import com.yf.exam.modules.sys.user.service.SysUserService; import com.yf.exam.modules.sys.user.service.SysUserService; // 导入 SysUserService 服务接口
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 注解,用于定义 API 文档
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 注解,用于描述接口操作
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles; // 导入 Shiro 注解,用于角色权限控制
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 注解,用于自动注入依赖
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin; // 导入 Spring 注解,用于启用跨域请求
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入 Spring 注解,用于请求体绑定
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入 Spring 注解,用于指定请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入 Spring 注解,用于指定请求方法
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam; // 导入 Spring 注解,用于请求参数绑定
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入 Spring 注解,标识该类为 REST 控制器
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类,用于获取 HTTP 请求
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
* @ 2020-04-13 16:57
*/ */
@Api(tags = {"管理用户"}) @Api(tags = {"管理用户"}) // Swagger 注解:定义该类的 API 文档标签为“管理用户”
@RestController @RestController // Spring 注解:标识该类为 REST 控制器,处理 HTTP 请求
@RequestMapping("/exam/api/sys/user") @RequestMapping("/exam/api/sys/user") // 定义请求路径前缀为 /exam/api/sys/user
public class SysUserController extends BaseController { public class SysUserController extends BaseController { // SysUserController 类继承 BaseController提供通用功能
@Autowired @Autowired // 自动注入 SysUserService 服务
private SysUserService baseService; private SysUserService baseService;
/** /**
* *
* @return * @param reqDTO DTO
* @return
*/ */
@CrossOrigin @CrossOrigin // 允许跨域请求
@ApiOperation(value = "用户登录") @ApiOperation(value = "用户登录") // Swagger 注解:描述接口操作为“用户登录”
@RequestMapping(value = "/login", method = {RequestMethod.POST}) @RequestMapping(value = "/login", method = {RequestMethod.POST}) // 请求路径为 /login方法为 POST
public ApiRest<SysUserLoginDTO> login(@RequestBody SysUserLoginReqDTO reqDTO) { public ApiRest<SysUserLoginDTO> login(@RequestBody SysUserLoginReqDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.login(reqDTO.getUsername(), reqDTO.getPassword()); SysUserLoginDTO respDTO = baseService.login(reqDTO.getUsername(), reqDTO.getPassword()); // 调用服务层的登录方法
return super.success(respDTO); return super.success(respDTO); // 返回成功响应,包含用户登录信息
} }
/** /**
* *
* @return * @param request HTTP token
* @return
*/ */
@CrossOrigin @CrossOrigin // 允许跨域请求
@ApiOperation(value = "用户登录") @ApiOperation(value = "用户登出") // Swagger 注解:描述接口操作为“用户登出”
@RequestMapping(value = "/logout", method = {RequestMethod.POST}) @RequestMapping(value = "/logout", method = {RequestMethod.POST}) // 请求路径为 /logout方法为 POST
public ApiRest logout(HttpServletRequest request) { public ApiRest logout(HttpServletRequest request) {
String token = request.getHeader("token"); String token = request.getHeader("token"); // 获取请求头中的 token
System.out.println("+++++当前会话为:"+token); System.out.println("+++++当前会话为:" + token); // 打印当前会话的 token
baseService.logout(token); baseService.logout(token); // 调用服务层的登出方法
return super.success(); return super.success(); // 返回成功响应
} }
/** /**
* *
* @return * @param token token
* @return
*/ */
@ApiOperation(value = "获取会话") @ApiOperation(value = "获取会话") // Swagger 注解:描述接口操作为“获取会话”
@RequestMapping(value = "/info", method = {RequestMethod.POST}) @RequestMapping(value = "/info", method = {RequestMethod.POST}) // 请求路径为 /info方法为 POST
public ApiRest info(@RequestParam("token") String token) { public ApiRest info(@RequestParam("token") String token) {
SysUserLoginDTO respDTO = baseService.token(token); SysUserLoginDTO respDTO = baseService.token(token); // 根据 token 获取当前会话信息
return success(respDTO); return success(respDTO); // 返回会话信息
} }
/** /**
* *
* @return * @param reqDTO DTO
* @return
*/ */
@ApiOperation(value = "修改用户资料") @ApiOperation(value = "修改用户资料") // Swagger 注解:描述接口操作为“修改用户资料”
@RequestMapping(value = "/update", method = {RequestMethod.POST}) @RequestMapping(value = "/update", method = {RequestMethod.POST}) // 请求路径为 /update方法为 POST
public ApiRest update(@RequestBody SysUserDTO reqDTO) { public ApiRest update(@RequestBody SysUserDTO reqDTO) {
baseService.update(reqDTO); baseService.update(reqDTO); // 调用服务层的更新方法
return success(); return success(); // 返回成功响应
} }
/** /**
* *
* @return * @param reqDTO DTO
* @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "保存或修改") @ApiOperation(value = "保存或修改") // Swagger 注解:描述接口操作为“保存或修改”
@RequestMapping(value = "/save", method = {RequestMethod.POST}) @RequestMapping(value = "/save", method = {RequestMethod.POST}) // 请求路径为 /save方法为 POST
public ApiRest save(@RequestBody SysUserSaveReqDTO reqDTO) { public ApiRest save(@RequestBody SysUserSaveReqDTO reqDTO) {
baseService.save(reqDTO); baseService.save(reqDTO); // 调用服务层的保存方法
return success(); return success(); // 返回成功响应
} }
/** /**
* *
* @param reqDTO * @param reqDTO DTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "批量删除") @ApiOperation(value = "批量删除") // Swagger 注解:描述接口操作为“批量删除”
@RequestMapping(value = "/delete", method = { RequestMethod.POST}) @RequestMapping(value = "/delete", method = {RequestMethod.POST}) // 请求路径为 /delete方法为 POST
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) {
//根据ID删除 baseService.removeByIds(reqDTO.getIds()); // 根据 ID 列表删除用户
baseService.removeByIds(reqDTO.getIds()); return super.success(); // 返回成功响应
return super.success();
} }
/** /**
* *
* @param reqDTO * @param reqDTO DTO
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解:描述接口操作为“分页查找”
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = {RequestMethod.POST}) // 请求路径为 /paging方法为 POST
public ApiRest<IPage<SysUserDTO>> paging(@RequestBody PagingReqDTO<SysUserDTO> reqDTO) { public ApiRest<IPage<SysUserDTO>> paging(@RequestBody PagingReqDTO<SysUserDTO> reqDTO) {
//分页查询并转换 // 调用服务层的分页查询方法
IPage<SysUserDTO> page = baseService.paging(reqDTO); IPage<SysUserDTO> page = baseService.paging(reqDTO);
return super.success(page); return super.success(page); // 返回成功响应,包含分页数据
} }
/** /**
* *
* @param reqDTO * @param reqDTO DTO ID
* @return * @return
*/ */
@RequiresRoles("sa") @RequiresRoles("sa") // 权限控制:要求用户具有 "sa" 角色
@ApiOperation(value = "修改状态") @ApiOperation(value = "修改状态") // Swagger 注解:描述接口操作为“修改状态”
@RequestMapping(value = "/state", method = { RequestMethod.POST}) @RequestMapping(value = "/state", method = {RequestMethod.POST}) // 请求路径为 /state方法为 POST
public ApiRest state(@RequestBody BaseStateReqDTO reqDTO) { public ApiRest state(@RequestBody BaseStateReqDTO reqDTO) {
// 条件 // 构建查询条件:排除 admin 用户
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.in(SysUser::getId, reqDTO.getIds()) .in(SysUser::getId, reqDTO.getIds()) // 根据 ID 列表查询
.ne(SysUser::getUserName, "admin"); .ne(SysUser::getUserName, "admin"); // 排除用户名为 admin 的用户
SysUser record = new SysUser(); SysUser record = new SysUser();
record.setState(reqDTO.getState()); record.setState(reqDTO.getState()); // 设置用户状态
baseService.update(record, wrapper); baseService.update(record, wrapper); // 更新状态
return super.success(); return super.success(); // 返回成功响应
} }
/** /**
* *
* @return * @param reqDTO DTO
* @return
*/ */
@ApiOperation(value = "学员注册") @ApiOperation(value = "学员注册") // Swagger 注解:描述接口操作为“学员注册”
@RequestMapping(value = "/reg", method = {RequestMethod.POST}) @RequestMapping(value = "/reg", method = {RequestMethod.POST}) // 请求路径为 /reg方法为 POST
public ApiRest<SysUserLoginDTO> reg(@RequestBody SysUserDTO reqDTO) { public ApiRest<SysUserLoginDTO> reg(@RequestBody SysUserDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.reg(reqDTO); SysUserLoginDTO respDTO = baseService.reg(reqDTO); // 调用服务层的注册方法
return success(respDTO); return success(respDTO); // 返回注册后的用户登录信息
} }
/** /**
* *
* @return * @param reqDTO DTO
* @return
*/ */
@ApiOperation(value = "快速注册") @ApiOperation(value = "快速注册") // Swagger 注解:描述接口操作为“快速注册”
@RequestMapping(value = "/quick-reg", method = {RequestMethod.POST}) @RequestMapping(value = "/quick-reg", method = {RequestMethod.POST}) // 请求路径为 /quick-reg方法为 POST
public ApiRest<SysUserLoginDTO> quick(@RequestBody SysUserDTO reqDTO) { public ApiRest<SysUserLoginDTO> quick(@RequestBody SysUserDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.quickReg(reqDTO); SysUserLoginDTO respDTO = baseService.quickReg(reqDTO); // 调用服务层的快速注册方法
return success(respDTO); return success(respDTO); // 返回快速注册后的用户登录信息
} }
} }

@ -1,30 +1,29 @@
package com.yf.exam.modules.sys.user.dto; package com.yf.exam.modules.sys.user.dto; // 包名:表示该类属于 sys.user.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* * ID
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="角色", description="角色") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysRoleDTO implements Serializable { @ApiModel(value = "角色", description = "角色") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysRoleDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "角色ID", required = true) // Swagger 注解描述该属性为“角色ID”并标记为必填
@ApiModelProperty(value = "角色ID", required=true) private String id; // 定义字段:角色的唯一标识符
private String id;
@ApiModelProperty(value = "角色名称", required = true) // Swagger 注解:描述该属性为“角色名称”,并标记为必填
@ApiModelProperty(value = "角色名称", required=true) private String roleName; // 定义字段:角色的名称
private String roleName;
} }

@ -1,55 +1,54 @@
package com.yf.exam.modules.sys.user.dto; package com.yf.exam.modules.sys.user.dto; // 包名:表示该类属于 sys.user.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
import java.util.Date; import java.util.Date; // 导入 Date 类,用于表示日期和时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="管理用户", description="管理用户") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserDTO implements Serializable { @ApiModel(value = "管理用户", description = "管理用户") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
private String id; // 定义字段:用户的唯一标识符
@ApiModelProperty(value = "ID", required=true) @ApiModelProperty(value = "用户名", required = true) // Swagger 注解:描述该属性为“用户名”,并标记为必填
private String id; private String userName; // 定义字段:管理员的用户名,用于登录和身份验证
@ApiModelProperty(value = "用户名", required=true) @ApiModelProperty(value = "真实姓名", required = true) // Swagger 注解:描述该属性为“真实姓名”,并标记为必填
private String userName; private String realName; // 定义字段:管理员的真实姓名
@ApiModelProperty(value = "真实姓名", required=true) @ApiModelProperty(value = "密码", required = true) // Swagger 注解:描述该属性为“密码”,并标记为必填
private String realName; private String password; // 定义字段:管理员的密码
@ApiModelProperty(value = "密码", required=true) @ApiModelProperty(value = "密码", required = true) // Swagger 注解:描述该属性为“密码盐”,并标记为必填
private String password; private String salt; // 定义字段:用于加密密码的盐值
@ApiModelProperty(value = "密码盐", required=true) @ApiModelProperty(value = "角色列表", required = true) // Swagger 注解:描述该属性为“角色列表”,并标记为必填
private String salt; private String roleIds; // 定义字段用户的角色ID列表用于权限控制
@ApiModelProperty(value = "角色列表", required=true) @ApiModelProperty(value = "部门ID", required = true) // Swagger 注解描述该属性为“部门ID”并标记为必填
private String roleIds; private String departId; // 定义字段用户所属的部门ID
@ApiModelProperty(value = "部门ID", required=true) @ApiModelProperty(value = "创建时间", required = true) // Swagger 注解:描述该属性为“创建时间”,并标记为必填
private String departId; private Date createTime; // 定义字段:管理员账号的创建时间
@ApiModelProperty(value = "创建时间", required=true) @ApiModelProperty(value = "更新时间", required = true) // Swagger 注解:描述该属性为“更新时间”,并标记为必填
private Date createTime; private Date updateTime; // 定义字段:管理员账号的最后更新时间
@ApiModelProperty(value = "更新时间", required=true) @ApiModelProperty(value = "状态", required = true) // Swagger 注解:描述该属性为“状态”,并标记为必填
private Date updateTime; private Integer state; // 定义字段:管理员账号的状态,如启用或禁用
@ApiModelProperty(value = "状态", required=true)
private Integer state;
} }

@ -1,33 +1,32 @@
package com.yf.exam.modules.sys.user.dto; package com.yf.exam.modules.sys.user.dto; // 包名:表示该类属于 sys.user.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="用户角色", description="用户角色") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserRoleDTO implements Serializable { @ApiModel(value = "用户角色", description = "用户角色") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserRoleDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
@ApiModelProperty(value = "ID", required=true) private String id; // 定义字段:用户角色关系的唯一标识符
private String id;
@ApiModelProperty(value = "用户ID", required = true) // Swagger 注解描述该属性为“用户ID”并标记为必填
@ApiModelProperty(value = "用户ID", required=true) private String userId; // 定义字段:用户的唯一标识符,关联到特定的用户
private String userId;
@ApiModelProperty(value = "角色ID", required = true) // Swagger 注解描述该属性为“角色ID”并标记为必填
@ApiModelProperty(value = "角色ID", required=true) private String roleId; // 定义字段:角色的唯一标识符,关联到特定的角色
private String roleId;
} }

@ -1,29 +1,29 @@
package com.yf.exam.modules.sys.user.dto.request; package com.yf.exam.modules.sys.user.dto.request; // 包名:表示该类属于 sys.user.dto.request 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="管理员登录请求类", description="管理员登录请求类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserLoginReqDTO implements Serializable { @ApiModel(value = "管理员登录请求类", description = "管理员登录请求类") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserLoginReqDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "用户名", required=true) @ApiModelProperty(value = "用户名", required = true) // Swagger 注解:描述该属性为“用户名”,并标记为必填
private String username; private String username; // 定义字段:用户名,登录时使用
@ApiModelProperty(value = "密码", required=true) @ApiModelProperty(value = "密码", required = true) // Swagger 注解:描述该属性为“密码”,并标记为必填
private String password; private String password; // 定义字段:密码,登录时使用
} }

@ -1,43 +1,43 @@
package com.yf.exam.modules.sys.user.dto.request; package com.yf.exam.modules.sys.user.dto.request; // 包名:表示该类属于 sys.user.dto.request 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
import java.util.List; import java.util.List; // 导入 List 接口,用于存储角色列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="管理员保存请求类", description="管理员保存请求类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserSaveReqDTO implements Serializable { @ApiModel(value = "管理员保存请求类", description = "管理员保存请求类") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserSaveReqDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
@ApiModelProperty(value = "ID", required=true)
private String id; @ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
private String id; // 定义字段:管理员的唯一标识符,通常用于更新操作
@ApiModelProperty(value = "用户名", required=true)
private String userName; @ApiModelProperty(value = "用户名", required = true) // Swagger 注解:描述该属性为“用户名”,并标记为必填
private String userName; // 定义字段:管理员的用户名,用于登录
@ApiModelProperty(value = "头像", required=true)
private String avatar; @ApiModelProperty(value = "头像", required = true) // Swagger 注解:描述该属性为“头像”,并标记为必填
private String avatar; // 定义字段:管理员的头像 URL
@ApiModelProperty(value = "真实姓名", required=true)
private String realName; @ApiModelProperty(value = "真实姓名", required = true) // Swagger 注解:描述该属性为“真实姓名”,并标记为必填
private String realName; // 定义字段:管理员的真实姓名
@ApiModelProperty(value = "密码", required=true)
private String password; @ApiModelProperty(value = "密码", required = true) // Swagger 注解:描述该属性为“密码”,并标记为必填
private String password; // 定义字段:管理员的登录密码
@ApiModelProperty(value = "部门", required=true)
private String departId; @ApiModelProperty(value = "部门", required = true) // Swagger 注解:描述该属性为“部门”,并标记为必填
private String departId; // 定义字段管理员所属的部门ID
@ApiModelProperty(value = "角色列表", required=true)
private List<String> roles; @ApiModelProperty(value = "角色列表", required = true) // Swagger 注解:描述该属性为“角色列表”,并标记为必填
private List<String> roles; // 定义字段:管理员的角色列表,每个角色的 ID 组成的列表
} }

@ -1,26 +1,26 @@
package com.yf.exam.modules.sys.user.dto.request; package com.yf.exam.modules.sys.user.dto.request; // 包名:表示该类属于 sys.user.dto.request 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
/** /**
* <p> * <p>
* *
* </p> * </p>
* * token
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="会话检查请求类", description="会话检查请求类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserTokenReqDTO implements Serializable { @ApiModel(value = "会话检查请求类", description = "会话检查请求类") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserTokenReqDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "用户名", required=true) @ApiModelProperty(value = "用户名", required = true) // Swagger 注解:描述该属性为“用户名”,并标记为必填
private String token; private String token; // 定义字段:会话的 token用于标识当前会话
} }

@ -1,55 +1,55 @@
package com.yf.exam.modules.sys.user.dto.response; package com.yf.exam.modules.sys.user.dto.response; // 包名:表示该类属于 sys.user.dto.response 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于定义 API 模型
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述 API 模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于支持对象的序列化
import java.util.Date; import java.util.Date; // 导入 Date 类,用于表示日期和时间
import java.util.List; import java.util.List; // 导入 List 接口,用于存储角色列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@ApiModel(value="管理用户登录响应类", description="管理用户登录响应类") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserLoginDTO implements Serializable { @ApiModel(value = "管理用户登录响应类", description = "管理用户登录响应类") // Swagger 注解:定义该类的 API 模型名称和描述
public class SysUserLoginDTO implements Serializable { // 实现 Serializable 接口,以支持序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
@ApiModelProperty(value = "ID", required=true) @ApiModelProperty(value = "ID", required = true) // Swagger 注解描述该属性为“ID”并标记为必填
private String id; private String id; // 定义字段:管理员的唯一标识符
@ApiModelProperty(value = "用户名", required=true) @ApiModelProperty(value = "用户名", required = true) // Swagger 注解:描述该属性为“用户名”,并标记为必填
private String userName; private String userName; // 定义字段:管理员的用户名
@ApiModelProperty(value = "真实姓名", required=true) @ApiModelProperty(value = "真实姓名", required = true) // Swagger 注解:描述该属性为“真实姓名”,并标记为必填
private String realName; private String realName; // 定义字段:管理员的真实姓名
@ApiModelProperty(value = "角色列表", required=true) @ApiModelProperty(value = "角色列表", required = true) // Swagger 注解:描述该属性为“角色列表”,并标记为必填
private String roleIds; private String roleIds; // 定义字段管理员的角色ID列表用于权限控制
@ApiModelProperty(value = "部门ID", required=true) @ApiModelProperty(value = "部门ID", required = true) // Swagger 注解描述该属性为“部门ID”并标记为必填
private String departId; private String departId; // 定义字段管理员所属部门的ID
@ApiModelProperty(value = "创建时间", required=true) @ApiModelProperty(value = "创建时间", required = true) // Swagger 注解:描述该属性为“创建时间”,并标记为必填
private Date createTime; private Date createTime; // 定义字段:管理员账号的创建时间
@ApiModelProperty(value = "更新时间", required=true) @ApiModelProperty(value = "更新时间", required = true) // Swagger 注解:描述该属性为“更新时间”,并标记为必填
private Date updateTime; private Date updateTime; // 定义字段:管理员账号的最后更新时间
@ApiModelProperty(value = "状态", required=true) @ApiModelProperty(value = "状态", required = true) // Swagger 注解:描述该属性为“状态”,并标记为必填
private Integer state; private Integer state; // 定义字段:管理员账号的状态,如启用或禁用
@ApiModelProperty(value = "角色列表", required=true) @ApiModelProperty(value = "角色列表", required = true) // Swagger 注解:描述该属性为“角色列表”,并标记为必填
private List<String> roles; private List<String> roles; // 定义字段管理员角色的列表每个角色的名称或ID
@ApiModelProperty(value = "登录令牌", required=true) @ApiModelProperty(value = "登录令牌", required = true) // Swagger 注解:描述该属性为“登录令牌”,并标记为必填
private String token; private String token; // 定义字段:管理员登录后的令牌,用于身份验证
} }

@ -1,36 +1,38 @@
package com.yf.exam.modules.sys.user.entity; package com.yf.exam.modules.sys.user.entity; // 包名:表示该类属于 sys.user.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于指定主键生成策略
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于指定表字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于指定表主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于指定表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus 扩展的 Model 类,支持 ActiveRecord 模式
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* * `sys_role`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@TableName("sys_role") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysRole extends Model<SysRole> { @TableName("sys_role") // MyBatis-Plus 注解,指定该实体类对应数据库表名为 "sys_role"
public class SysRole extends Model<SysRole> { // SysRole 类继承自 Model 类,支持 ActiveRecord 模式
private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
private static final long serialVersionUID = 1L;
/** /**
* ID * ID
*/ * 使 MyBatis-Plus
@TableId(value = "id", type = IdType.ASSIGN_ID) */
private String id; @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,指定主键字段及生成策略
private String id; // 定义字段:角色的唯一标识符
/** /**
* *
*/ * "role_name"
@TableField("role_name") */
private String roleName; @TableField("role_name") // MyBatis-Plus 注解,指定该字段对应数据库中的 "role_name" 字段
private String roleName; // 定义字段:角色的名称
} }

@ -1,83 +1,93 @@
package com.yf.exam.modules.sys.user.entity; package com.yf.exam.modules.sys.user.entity; // 包名:表示该类属于 sys.user.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于指定主键生成策略
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于指定表字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于指定表主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于指定表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus 扩展的 Model 类,支持 ActiveRecord 模式
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
import java.util.Date; import java.util.Date; // 导入 Date 类,用于表示日期和时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* * `sys_user`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@TableName("sys_user") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUser extends Model<SysUser> { @TableName("sys_user") // MyBatis-Plus 注解,指定该实体类对应数据库表名为 "sys_user"
public class SysUser extends Model<SysUser> { // SysUser 类继承自 Model 类,支持 ActiveRecord 模式
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
/** /**
* ID * ID
* 使 MyBatis-Plus
*/ */
@TableId(value = "id", type = IdType.ASSIGN_ID) @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,指定主键字段及生成策略
private String id; private String id; // 定义字段:用户的唯一标识符
/** /**
* *
* "user_name"
*/ */
@TableField("user_name") @TableField("user_name") // MyBatis-Plus 注解,指定该字段对应数据库中的 "user_name" 字段
private String userName; private String userName; // 定义字段:管理员的用户名,用于登录和身份验证
/** /**
* *
* "real_name"
*/ */
@TableField("real_name") @TableField("real_name") // MyBatis-Plus 注解,指定该字段对应数据库中的 "real_name" 字段
private String realName; private String realName; // 定义字段:管理员的真实姓名
/** /**
* *
*
*/ */
private String password; private String password; // 定义字段:管理员的登录密码
/** /**
* *
*
*/ */
private String salt; private String salt; // 定义字段:用于加密密码的盐值
/** /**
* *
* "role_ids" ID
*/ */
@TableField("role_ids") @TableField("role_ids") // MyBatis-Plus 注解,指定该字段对应数据库中的 "role_ids" 字段
private String roleIds; private String roleIds; // 定义字段用户的角色ID列表用于权限控制
/** /**
* ID * ID
* "depart_id"
*/ */
@TableField("depart_id") @TableField("depart_id") // MyBatis-Plus 注解,指定该字段对应数据库中的 "depart_id" 字段
private String departId; private String departId; // 定义字段管理员所属的部门ID
/** /**
* *
* "create_time"
*/ */
@TableField("create_time") @TableField("create_time") // MyBatis-Plus 注解,指定该字段对应数据库中的 "create_time" 字段
private Date createTime; private Date createTime; // 定义字段:管理员账号的创建时间
/** /**
* *
* "update_time"
*/ */
@TableField("update_time") @TableField("update_time") // MyBatis-Plus 注解,指定该字段对应数据库中的 "update_time" 字段
private Date updateTime; private Date updateTime; // 定义字段:管理员账号的最后更新时间
/** /**
* *
*
*/ */
private Integer state; private Integer state; // 定义字段:管理员账号的状态(如启用或禁用)
} }

@ -1,42 +1,45 @@
package com.yf.exam.modules.sys.user.entity; package com.yf.exam.modules.sys.user.entity; // 包名:表示该类属于 sys.user.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于指定主键生成策略
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于指定表字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于指定表主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于指定表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus 扩展的 Model 类,支持 ActiveRecord 模式
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 Getter、Setter、toString 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* * `sys_user_role`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Data */
@TableName("sys_user_role") @Data // Lombok 注解,自动生成 Getter、Setter 和其他方法
public class SysUserRole extends Model<SysUserRole> { @TableName("sys_user_role") // MyBatis-Plus 注解,指定该实体类对应数据库表名为 "sys_user_role"
public class SysUserRole extends Model<SysUserRole> { // SysUserRole 类继承自 Model 类,支持 ActiveRecord 模式
private static final long serialVersionUID = 1L; // 序列化版本号,用于序列化和反序列化的一致性检查
private static final long serialVersionUID = 1L;
/** /**
* ID * ID
*/ * 使 MyBatis-Plus
@TableId(value = "id", type = IdType.ASSIGN_ID) */
private String id; @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,指定主键字段及生成策略
private String id; // 定义字段:用户角色关系的唯一标识符
/** /**
* ID * ID
*/ * "user_id"
@TableField("user_id") */
private String userId; @TableField("user_id") // MyBatis-Plus 注解,指定该字段对应数据库中的 "user_id" 字段
private String userId; // 定义字段:用户的唯一标识符,关联到特定的用户
/** /**
* ID * ID
*/ * "role_id"
@TableField("role_id") */
private String roleId; @TableField("role_id") // MyBatis-Plus 注解,指定该字段对应数据库中的 "role_id" 字段
private String roleId; // 定义字段:角色的唯一标识符,关联到特定的角色
} }

@ -1,15 +1,17 @@
package com.yf.exam.modules.sys.user.mapper; package com.yf.exam.modules.sys.user.mapper; // 包名:表示该类属于 sys.user.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.sys.user.entity.SysRole; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,提供基本的数据库操作方法
import com.yf.exam.modules.sys.user.entity.SysRole; // 导入 SysRole 实体类,表示角色实体
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * MyBatis-Plus BaseMapper `SysRole`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysRoleMapper extends BaseMapper<SysRole> { */
public interface SysRoleMapper extends BaseMapper<SysRole> { // 继承 MyBatis-Plus 的 BaseMapper自动提供对 SysRole 实体的 CRUD 操作
} }

@ -1,16 +1,17 @@
package com.yf.exam.modules.sys.user.mapper; package com.yf.exam.modules.sys.user.mapper; // 包名:表示该类属于 sys.user.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,提供基本的数据库操作方法
import com.yf.exam.modules.sys.user.entity.SysUser; import com.yf.exam.modules.sys.user.entity.SysUser; // 导入 SysUser 实体类,表示管理员用户实体
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * MyBatis-Plus BaseMapper `SysUser`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysUserMapper extends BaseMapper<SysUser> { */
public interface SysUserMapper extends BaseMapper<SysUser> { // 继承 MyBatis-Plus 的 BaseMapper自动提供对 SysUser 实体的 CRUD 操作
} }

@ -1,16 +1,17 @@
package com.yf.exam.modules.sys.user.mapper; package com.yf.exam.modules.sys.user.mapper; // 包名:表示该类属于 sys.user.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,提供基本的数据库操作方法
import com.yf.exam.modules.sys.user.entity.SysUserRole; import com.yf.exam.modules.sys.user.entity.SysUserRole; // 导入 SysUserRole 实体类,表示用户角色实体
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * MyBatis-Plus BaseMapper `SysUserRole`
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> { */
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> { // 继承 MyBatis-Plus 的 BaseMapper自动提供对 SysUserRole 实体的 CRUD 操作
} }

@ -1,25 +1,26 @@
package com.yf.exam.modules.sys.user.service; package com.yf.exam.modules.sys.user.service; // 包名:表示该类属于 sys.user.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,提供基本的服务方法
import com.yf.exam.modules.sys.user.dto.SysRoleDTO; import com.yf.exam.modules.sys.user.dto.SysRoleDTO; // 导入 SysRoleDTO 数据传输对象,用于封装角色数据
import com.yf.exam.modules.sys.user.entity.SysRole; import com.yf.exam.modules.sys.user.entity.SysRole; // 导入 SysRole 实体类,表示角色
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO用于封装分页请求参数
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysRoleService extends IService<SysRole> { */
public interface SysRoleService extends IService<SysRole> { // 继承 MyBatis-Plus 的 IService 接口,提供基本的 CRUD 操作
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO); IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO); // 定义分页查询方法,返回角色的分页数据
} }

@ -1,61 +1,64 @@
package com.yf.exam.modules.sys.user.service; package com.yf.exam.modules.sys.user.service; // 包名:表示该类属于 sys.user.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,提供基本的服务方法
import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO; import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO; // 导入 SysUserRoleDTO 数据传输对象,用于封装用户角色数据
import com.yf.exam.modules.sys.user.entity.SysUserRole; import com.yf.exam.modules.sys.user.entity.SysUserRole; // 导入 SysUserRole 实体类,表示用户角色
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO用于封装分页请求参数
import java.util.List; import java.util.List; // 导入 List 接口用于存储多个角色ID
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysUserRoleService extends IService<SysUserRole> { */
public interface SysUserRoleService extends IService<SysUserRole> { // 继承 MyBatis-Plus 的 IService 接口,提供基本的 CRUD 操作
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO); IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO); // 定义分页查询用户角色数据的方法,返回角色的分页数据
/** /**
* *
* @param userId * @param userId ID
* @return * @return ID
*/ */
List<String> listRoles(String userId); List<String> listRoles(String userId); // 根据用户ID查找该用户的角色ID列表
/** /**
* *
* @param userId * @param userId ID
* @param ids * @param ids ID
* @return * @return ID
*/ */
String saveRoles(String userId, List<String> ids); String saveRoles(String userId, List<String> ids); // 保存指定用户的角色
/** /**
* *
* @param userId * @param userId ID
* @return * @return truefalse
*/ */
boolean isStudent(String userId); boolean isStudent(String userId); // 判断指定用户是否为学生
/** /**
* *
* @param userId ID
* @return truefalse
*/ */
boolean isTeacher(String userId); boolean isTeacher(String userId); // 判断指定用户是否为老师
/** /**
* *
* @param userId * @param userId ID
* @return * @return truefalse
*/ */
boolean isAdmin(String userId); boolean isAdmin(String userId); // 判断指定用户是否为管理员
} }

@ -1,72 +1,75 @@
package com.yf.exam.modules.sys.user.service; package com.yf.exam.modules.sys.user.service; // 包名:表示该类属于 sys.user.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,提供基本的服务方法
import com.yf.exam.modules.sys.user.dto.SysUserDTO; import com.yf.exam.modules.sys.user.dto.SysUserDTO; // 导入 SysUserDTO 数据传输对象,用于封装用户数据
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; // 导入 SysUserSaveReqDTO 请求 DTO用于保存用户信息
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; // 导入 SysUserLoginDTO 响应 DTO用于返回登录信息
import com.yf.exam.modules.sys.user.entity.SysUser; import com.yf.exam.modules.sys.user.entity.SysUser; // 导入 SysUser 实体类,表示管理员用户
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO用于封装分页请求参数
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
public interface SysUserService extends IService<SysUser> { */
public interface SysUserService extends IService<SysUser> { // 继承 MyBatis-Plus 的 IService 接口,提供基本的 CRUD 操作
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO); IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO); // 定义分页查询用户数据的方法,返回用户的分页数据
/** /**
* *
* @param userName * @param userName
* @param password * @param password
* @return * @return token
*/ */
SysUserLoginDTO login(String userName, String password); SysUserLoginDTO login(String userName, String password); // 实现用户登录,验证用户名和密码
/** /**
* *
* @param token * @param token JWT token
* @return * @return
*/ */
SysUserLoginDTO token(String token); SysUserLoginDTO token(String token); // 根据 token 获取用户的会话信息并验证
/** /**
* 退 * 退
* @param token * @param token JWT token
*/ */
void logout(String token); void logout(String token); // 退出登录,销毁当前会话
/** /**
* *
* @param reqDTO * @param reqDTO
*/ */
void update(SysUserDTO reqDTO); void update(SysUserDTO reqDTO); // 修改用户资料,包括密码等信息
/** /**
* *
* @param reqDTO * @param reqDTO
*/ */
void save(SysUserSaveReqDTO reqDTO); void save(SysUserSaveReqDTO reqDTO); // 保存或更新系统用户
/** /**
* *
* @param reqDTO * @param reqDTO
* @return token
*/ */
SysUserLoginDTO reg(SysUserDTO reqDTO); SysUserLoginDTO reg(SysUserDTO reqDTO); // 用户注册,保存用户信息并返回登录数据
/** /**
* *
* @param reqDTO * @param reqDTO
* @return token
*/ */
SysUserLoginDTO quickReg(SysUserDTO reqDTO); SysUserLoginDTO quickReg(SysUserDTO reqDTO); // 快速注册,如果用户已存在则直接登录,否则进行注册
} }

@ -1,42 +1,46 @@
package com.yf.exam.modules.sys.user.service.impl; package com.yf.exam.modules.sys.user.service.impl; // 包名:表示该类属于 sys.user.service.impl 包
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON; // 导入 Fastjson 库,用于 JSON 处理
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference; // 导入 Fastjson 的 TypeReference用于泛型类型的转换
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 分页类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl实现基本的服务层操作
import com.yf.exam.modules.sys.user.dto.SysRoleDTO; import com.yf.exam.modules.sys.user.dto.SysRoleDTO; // 导入 SysRoleDTO 数据传输对象,用于封装角色数据
import com.yf.exam.modules.sys.user.entity.SysRole; import com.yf.exam.modules.sys.user.entity.SysRole; // 导入 SysRole 实体类,表示角色
import com.yf.exam.modules.sys.user.mapper.SysRoleMapper; import com.yf.exam.modules.sys.user.mapper.SysRoleMapper; // 导入 SysRoleMapper用于数据库操作
import com.yf.exam.modules.sys.user.service.SysRoleService; import com.yf.exam.modules.sys.user.service.SysRoleService; // 导入 SysRoleService 服务接口
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 的 Service 注解,标识该类为服务层组件
/** /**
* <p> * <p>
* *
* </p> * </p>
* * SysRoleService
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Service */
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService { @Service // 标识该类为服务层组件
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService { // 继承 MyBatis-Plus 的 ServiceImpl自动提供基础的 CRUD 操作
@Override @Override
public IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO) { public IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO) { // 重写分页查询方法
//创建分页对象 // 创建分页对象,设置当前页和每页显示的条数
IPage<SysRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); IPage<SysRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件 // 创建查询条件对象(此处没有具体条件,查询所有数据)
QueryWrapper<SysRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
//获得数据 // 查询数据,获取分页结果
IPage<SysRole> page = this.page(query, wrapper); IPage<SysRole> page = this.page(query, wrapper);
//转换结果
IPage<SysRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysRoleDTO>>(){}); // 将查询结果转换为 SysRoleDTO 类型的分页结果
IPage<SysRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysRoleDTO>>() {});
// 返回分页数据
return pageData; return pageData;
} }
} }

@ -1,128 +1,144 @@
package com.yf.exam.modules.sys.user.service.impl; package com.yf.exam.modules.sys.user.service.impl; // 包名:表示该类属于 sys.user.service.impl 包
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON; // 导入 Fastjson 库,用于 JSON 处理
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference; // 导入 Fastjson 的 TypeReference用于泛型类型的转换
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 分页类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 类,提供基础的数据库操作
import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO; import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO; // 导入 SysUserRoleDTO 数据传输对象,用于封装用户角色数据
import com.yf.exam.modules.sys.user.entity.SysUserRole; import com.yf.exam.modules.sys.user.entity.SysUserRole; // 导入 SysUserRole 实体类,表示用户角色
import com.yf.exam.modules.sys.user.mapper.SysUserRoleMapper; import com.yf.exam.modules.sys.user.mapper.SysUserRoleMapper; // 导入 SysUserRoleMapper用于数据库操作
import com.yf.exam.modules.sys.user.service.SysUserRoleService; import com.yf.exam.modules.sys.user.service.SysUserRoleService; // 导入 SysUserRoleService 服务接口
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 的 Service 注解,标识该类为服务层组件
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils; // 导入 Spring 的 CollectionUtils 工具类,用于判断集合是否为空
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils; // 导入 Spring 的 StringUtils 工具类,用于判断字符串是否为空
import java.util.ArrayList; import java.util.ArrayList; // 导入 ArrayList 类,用于创建列表
import java.util.List; import java.util.List; // 导入 List 接口,用于存储角色列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* * SysUserRoleService
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Service */
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService { @Service // 标识该类为服务层组件
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService { // 继承 MyBatis-Plus 的 ServiceImpl自动提供基础的 CRUD 操作
@Override @Override
public IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO) { public IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO) { // 实现分页查询方法
//创建分页对象 // 创建分页对象,设置当前页和每页显示的条数
IPage<SysUserRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); IPage<SysUserRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件 // 创建查询条件对象
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
//获得数据 // 查询数据,获取分页结果
IPage<SysUserRole> page = this.page(query, wrapper); IPage<SysUserRole> page = this.page(query, wrapper);
//转换结果
IPage<SysUserRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserRoleDTO>>(){}); // 将查询结果转换为 SysUserRoleDTO 类型的分页结果
IPage<SysUserRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserRoleDTO>>() {});
// 返回分页数据
return pageData; return pageData;
} }
@Override @Override
public List<String> listRoles(String userId) { public List<String> listRoles(String userId) { // 根据用户ID获取该用户的角色列表
// 创建查询条件对象,筛选出指定用户的角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId); wrapper.lambda().eq(SysUserRole::getUserId, userId);
// 查询角色列表
List<SysUserRole> list = this.list(wrapper); List<SysUserRole> list = this.list(wrapper);
List<String> roles = new ArrayList<>(); List<String> roles = new ArrayList<>();
if(!CollectionUtils.isEmpty(list)){
for(SysUserRole item: list){ // 如果查询结果不为空将角色ID添加到列表中
if (!CollectionUtils.isEmpty(list)) {
for (SysUserRole item : list) {
roles.add(item.getRoleId()); roles.add(item.getRoleId());
} }
} }
// 返回角色ID列表
return roles; return roles;
} }
@Override @Override
public String saveRoles(String userId, List<String> ids) { public String saveRoles(String userId, List<String> ids) { // 保存用户角色方法
// 删除全部角色 // 删除该用户所有角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId); wrapper.lambda().eq(SysUserRole::getUserId, userId);
this.remove(wrapper); this.remove(wrapper);
// 如果角色列表不为空,保存新的角色
if(!CollectionUtils.isEmpty(ids)){ if (!CollectionUtils.isEmpty(ids)) {
List<SysUserRole> list = new ArrayList<>(); List<SysUserRole> list = new ArrayList<>();
String roleIds = null; String roleIds = null;
for(String item: ids){ // 将角色ID列表转为 SysUserRole 实体对象列表
for (String item : ids) {
SysUserRole role = new SysUserRole(); SysUserRole role = new SysUserRole();
role.setRoleId(item); role.setRoleId(item);
role.setUserId(userId); role.setUserId(userId);
list.add(role); list.add(role);
if(StringUtils.isEmpty(roleIds)){ if (StringUtils.isEmpty(roleIds)) {
roleIds = item; roleIds = item;
}else{ } else {
roleIds+=","+item; roleIds += "," + item; // 将角色ID拼接成字符串
} }
} }
// 批量保存角色数据
this.saveBatch(list); this.saveBatch(list);
return roleIds; return roleIds; // 返回拼接后的角色ID字符串
} }
return ""; return ""; // 如果角色列表为空,返回空字符串
} }
@Override @Override
public boolean isStudent(String userId) { public boolean isStudent(String userId) { // 检查用户是否为学生
// 学生角色 // 查询用户是否拥有学生角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId) wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "student"); .eq(SysUserRole::getRoleId, "student");
// 如果查询结果数量大于0则表示该用户是学生
return this.count(wrapper) > 0; return this.count(wrapper) > 0;
} }
@Override @Override
public boolean isTeacher(String userId) { public boolean isTeacher(String userId) { // 检查用户是否为教师
// 学生角色
// 查询用户是否拥有教师角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId) wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "teacher"); .eq(SysUserRole::getRoleId, "teacher");
// 如果查询结果数量大于0则表示该用户是教师
return this.count(wrapper) > 0; return this.count(wrapper) > 0;
} }
@Override @Override
public boolean isAdmin(String userId) { public boolean isAdmin(String userId) { // 检查用户是否为管理员
// 学生角色
// 查询用户是否拥有管理员角色角色ID为 "sa"
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId) wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "sa"); .eq(SysUserRole::getRoleId, "sa");
// 如果查询结果数量大于0则表示该用户是管理员
return this.count(wrapper) > 0; return this.count(wrapper) > 0;
} }
} }

@ -1,176 +1,185 @@
package com.yf.exam.modules.sys.user.service.impl; package com.yf.exam.modules.sys.user.service.impl; // 包名:表示该类属于 sys.user.service.impl 包
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON; // 导入 Fastjson 库,用于 JSON 处理
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference; // 导入 Fastjson 的 TypeReference用于泛型类型的转换
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker; // 导入 MyBatis-Plus 的 IdWorker用于生成唯一ID
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 分页类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 类,提供基础的数据库操作
import com.yf.exam.core.api.ApiError; import com.yf.exam.core.api.ApiError; // 导入 ApiError 用于错误码定义
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO
import com.yf.exam.core.enums.CommonState; import com.yf.exam.core.enums.CommonState; // 导入公共状态枚举,定义正常与异常状态
import com.yf.exam.core.exception.ServiceException; import com.yf.exam.core.exception.ServiceException; // 导入 ServiceException用于抛出自定义异常
import com.yf.exam.core.utils.BeanMapper; import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象之间的属性拷贝
import com.yf.exam.core.utils.passwd.PassHandler; import com.yf.exam.core.utils.passwd.PassHandler; // 导入 PassHandler 用于密码处理
import com.yf.exam.core.utils.passwd.PassInfo; import com.yf.exam.core.utils.passwd.PassInfo; // 导入 PassInfo 用于存储密码和盐
import com.yf.exam.ability.shiro.jwt.JwtUtils; import com.yf.exam.ability.shiro.jwt.JwtUtils; // 导入 JwtUtils 用于生成和验证 JWT
import com.yf.exam.modules.sys.user.dto.SysUserDTO; import com.yf.exam.modules.sys.user.dto.SysUserDTO; // 导入 SysUserDTO 数据传输对象,用于封装用户数据
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO; // 导入 SysUserSaveReqDTO 请求 DTO用于保存用户信息
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; // 导入 SysUserLoginDTO 响应 DTO用于返回登录信息
import com.yf.exam.modules.sys.user.entity.SysUser; import com.yf.exam.modules.sys.user.entity.SysUser; // 导入 SysUser 实体类,表示管理员用户
import com.yf.exam.modules.sys.user.mapper.SysUserMapper; import com.yf.exam.modules.sys.user.mapper.SysUserMapper; // 导入 SysUserMapper用于数据库操作
import com.yf.exam.modules.sys.user.service.SysUserRoleService; import com.yf.exam.modules.sys.user.service.SysUserRoleService; // 导入 SysUserRoleService 服务接口,用于角色操作
import com.yf.exam.modules.sys.user.service.SysUserService; import com.yf.exam.modules.sys.user.service.SysUserService; // 导入 SysUserService 服务接口,用于用户操作
import com.yf.exam.modules.user.UserUtils; import com.yf.exam.modules.user.UserUtils; // 导入 UserUtils 工具类,用于获取当前用户信息
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils; // 导入 StringUtils 工具类,用于判断字符串是否为空
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils; // 导入 Shiro 的 SecurityUtils用于获取和处理用户会话
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 注解,用于自动注入依赖
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Spring 的 Service 注解,标识该类为服务层组件
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional; // 导入 Spring 的事务注解,支持事务管理
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils; // 导入 Spring 的 CollectionUtils 工具类,用于判断集合是否为空
import java.util.ArrayList; import java.util.ArrayList; // 导入 ArrayList 类,用于创建列表
import java.util.List; import java.util.List; // 导入 List 接口,用于存储角色列表
/** /**
* <p> * <p>
* *
* </p> * </p>
* * SysUserService
* @author *
* @since 2020-04-13 16:57 * @
*/ * @ 2020-04-13 16:57
@Service */
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService { @Service // 标识该类为服务层组件
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService { // 继承 MyBatis-Plus 的 ServiceImpl自动提供基础的 CRUD 操作
@Autowired @Autowired
private SysUserRoleService sysUserRoleService; private SysUserRoleService sysUserRoleService; // 注入 SysUserRoleService用于用户角色管理
@Override @Override
public IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO) { public IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO) { // 实现分页查询方法
//创建分页对象 // 创建分页对象,设置当前页和每页显示的条数
IPage<SysUser> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); IPage<SysUser> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件 // 创建查询条件对象
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
SysUserDTO params = reqDTO.getParams(); SysUserDTO params = reqDTO.getParams();
if(params!=null){ // 根据传入的参数设置查询条件
if(!StringUtils.isBlank(params.getUserName())){ if (params != null) {
if (!StringUtils.isBlank(params.getUserName())) {
wrapper.lambda().like(SysUser::getUserName, params.getUserName()); wrapper.lambda().like(SysUser::getUserName, params.getUserName());
} }
if(!StringUtils.isBlank(params.getRealName())){ if (!StringUtils.isBlank(params.getRealName())) {
wrapper.lambda().like(SysUser::getRealName, params.getRealName()); wrapper.lambda().like(SysUser::getRealName, params.getRealName());
} }
} }
//获得数据 // 查询数据,获取分页结果
IPage<SysUser> page = this.page(query, wrapper); IPage<SysUser> page = this.page(query, wrapper);
//转换结果
IPage<SysUserDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserDTO>>(){}); // 将查询结果转换为 SysUserDTO 类型的分页结果
IPage<SysUserDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserDTO>>() {});
// 返回分页数据
return pageData; return pageData;
} }
@Override @Override
public SysUserLoginDTO login(String userName, String password) { public SysUserLoginDTO login(String userName, String password) { // 用户登录方法
// 查询用户是否存在
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, userName); wrapper.lambda().eq(SysUser::getUserName, userName);
SysUser user = this.getOne(wrapper, false); SysUser user = this.getOne(wrapper, false);
if(user == null){ if (user == null) {
throw new ServiceException(ApiError.ERROR_90010002); throw new ServiceException(ApiError.ERROR_90010002); // 用户不存在,抛出异常
} }
// 被禁用 // 检查用户是否被禁用
if(user.getState().equals(CommonState.ABNORMAL)){ if (user.getState().equals(CommonState.ABNORMAL)) {
throw new ServiceException(ApiError.ERROR_90010005); throw new ServiceException(ApiError.ERROR_90010005); // 用户被禁用,抛出异常
} }
boolean check = PassHandler.checkPass(password,user.getSalt(), user.getPassword()); // 校验密码
if(!check){ boolean check = PassHandler.checkPass(password, user.getSalt(), user.getPassword());
throw new ServiceException(ApiError.ERROR_90010002); if (!check) {
throw new ServiceException(ApiError.ERROR_90010002); // 密码不正确,抛出异常
} }
// 设置 JWT token 并返回登录信息
return this.setToken(user); return this.setToken(user);
} }
@Override @Override
public SysUserLoginDTO token(String token) { public SysUserLoginDTO token(String token) { // 根据 token 获取用户会话信息
// 获得会话 // 获取 token 中的用户名
String username = JwtUtils.getUsername(token); String username = JwtUtils.getUsername(token);
// 校验结果 // 校验 token 是否有效
boolean check = JwtUtils.verify(token, username); boolean check = JwtUtils.verify(token, username);
if(!check){ if (!check) {
throw new ServiceException(ApiError.ERROR_90010002); throw new ServiceException(ApiError.ERROR_90010002); // token 无效,抛出异常
} }
// 查询用户信息
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, username); wrapper.lambda().eq(SysUser::getUserName, username);
SysUser user = this.getOne(wrapper, false); SysUser user = this.getOne(wrapper, false);
if(user == null){ if (user == null) {
throw new ServiceException(ApiError.ERROR_10010002); throw new ServiceException(ApiError.ERROR_10010002); // 用户不存在,抛出异常
} }
// 被禁用 // 检查用户是否被禁用
if(user.getState().equals(CommonState.ABNORMAL)){ if (user.getState().equals(CommonState.ABNORMAL)) {
throw new ServiceException(ApiError.ERROR_90010005); throw new ServiceException(ApiError.ERROR_90010005); // 用户被禁用,抛出异常
} }
// 设置 JWT token 并返回登录信息
return this.setToken(user); return this.setToken(user);
} }
@Override @Override
public void logout(String token) { public void logout(String token) { // 用户登出方法
// 退出当前会话 // 退出当前会话
SecurityUtils.getSubject().logout(); SecurityUtils.getSubject().logout();
} }
@Override @Override
public void update(SysUserDTO reqDTO) { public void update(SysUserDTO reqDTO) { // 更新用户信息
String pass = reqDTO.getPassword();
String pass = reqDTO.getPassword(); if (!StringUtils.isBlank(pass)) {
if(!StringUtils.isBlank(pass)){ // 如果提供了新密码,则更新密码
PassInfo passInfo = PassHandler.buildPassword(pass); PassInfo passInfo = PassHandler.buildPassword(pass);
SysUser user = this.getById(UserUtils.getUserId()); SysUser user = this.getById(UserUtils.getUserId());
user.setPassword(passInfo.getPassword()); user.setPassword(passInfo.getPassword());
user.setSalt(passInfo.getSalt()); user.setSalt(passInfo.getSalt());
this.updateById(user); this.updateById(user); // 更新用户数据
} }
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class) // 启用事务管理,保证数据一致性
@Override @Override
public void save(SysUserSaveReqDTO reqDTO) { public void save(SysUserSaveReqDTO reqDTO) { // 保存或修改用户信息
List<String> roles = reqDTO.getRoles(); List<String> roles = reqDTO.getRoles();
if(CollectionUtils.isEmpty(roles)){ if (CollectionUtils.isEmpty(roles)) {
throw new ServiceException(ApiError.ERROR_90010003); throw new ServiceException(ApiError.ERROR_90010003); // 角色列表不能为空,抛出异常
} }
// 保存基本信息 // 保存基本信息
SysUser user = new SysUser(); SysUser user = new SysUser();
BeanMapper.copy(reqDTO, user); BeanMapper.copy(reqDTO, user);
// 添加模式 // 添加模式,生成新的 ID
if(StringUtils.isBlank(user.getId())){ if (StringUtils.isBlank(user.getId())) {
user.setId(IdWorker.getIdStr()); user.setId(IdWorker.getIdStr());
} }
// 修改密码 // 如果提供了密码,则加密并保存
if(!StringUtils.isBlank(reqDTO.getPassword())){ if (!StringUtils.isBlank(reqDTO.getPassword())) {
PassInfo pass = PassHandler.buildPassword(reqDTO.getPassword()); PassInfo pass = PassHandler.buildPassword(reqDTO.getPassword());
user.setPassword(pass.getPassword()); user.setPassword(pass.getPassword());
user.setSalt(pass.getSalt()); user.setSalt(pass.getSalt());
@ -179,23 +188,23 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 保存角色信息 // 保存角色信息
String roleIds = sysUserRoleService.saveRoles(user.getId(), roles); String roleIds = sysUserRoleService.saveRoles(user.getId(), roles);
user.setRoleIds(roleIds); user.setRoleIds(roleIds);
this.saveOrUpdate(user);
this.saveOrUpdate(user); // 保存或更新用户信息
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class) // 启用事务管理
@Override @Override
public SysUserLoginDTO reg(SysUserDTO reqDTO) { public SysUserLoginDTO reg(SysUserDTO reqDTO) { // 用户注册方法
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName()); wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName());
int count = this.count(wrapper); int count = this.count(wrapper);
if(count > 0){ if (count > 0) {
throw new ServiceException(1, "用户名已存在,换一个吧!"); throw new ServiceException(1, "用户名已存在,换一个吧!"); // 用户名已存在,抛出异常
} }
// 保存用户 // 保存用户
SysUser user = new SysUser(); SysUser user = new SysUser();
user.setId(IdWorker.getIdStr()); user.setId(IdWorker.getIdStr());
@ -212,21 +221,22 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
user.setRoleIds(roleIds); user.setRoleIds(roleIds);
this.save(user); this.save(user);
// 返回生成的 token
return this.setToken(user); return this.setToken(user);
} }
@Override @Override
public SysUserLoginDTO quickReg(SysUserDTO reqDTO) { public SysUserLoginDTO quickReg(SysUserDTO reqDTO) { // 快速注册方法
QueryWrapper<SysUser> wrapper = new QueryWrapper<>(); QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName()); wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName());
wrapper.last(" LIMIT 1 "); wrapper.last(" LIMIT 1 ");
SysUser user = this.getOne(wrapper); SysUser user = this.getOne(wrapper);
if(user!=null){ if (user != null) {
return this.setToken(user); return this.setToken(user); // 如果用户已存在,直接返回登录信息
} }
return this.reg(reqDTO); return this.reg(reqDTO); // 如果用户不存在,进行注册
} }
@ -235,16 +245,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* @param user * @param user
* @return * @return
*/ */
private SysUserLoginDTO setToken(SysUser user){ private SysUserLoginDTO setToken(SysUser user) { // 生成并设置用户的 JWT token
SysUserLoginDTO respDTO = new SysUserLoginDTO(); SysUserLoginDTO respDTO = new SysUserLoginDTO();
BeanMapper.copy(user, respDTO); BeanMapper.copy(user, respDTO);
// 生成Token // 生成 JWT token
String token = JwtUtils.sign(user.getUserName()); String token = JwtUtils.sign(user.getUserName());
respDTO.setToken(token); respDTO.setToken(token);
// 填充角色 // 填充角色信息
List<String> roles = sysUserRoleService.listRoles(user.getId()); List<String> roles = sysUserRoleService.listRoles(user.getId());
respDTO.setRoles(roles); respDTO.setRoles(roles);

@ -1,56 +1,56 @@
package com.yf.exam.modules.user; package com.yf.exam.modules.user; // 包名:表示该类属于 user 包
import com.yf.exam.core.api.ApiError; import com.yf.exam.core.api.ApiError; // 导入 ApiError 类,定义 API 错误码
import com.yf.exam.core.exception.ServiceException; import com.yf.exam.core.exception.ServiceException; // 导入 ServiceException 类,定义自定义服务异常
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO; // 导入用户登录响应 DTO 类
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils; // 导入 Shiro 的 SecurityUtils 类,用于获取当前登录用户的信息
/** /**
* *
* @author bool *
* @ bool
*/ */
public class UserUtils { public class UserUtils {
/** /**
* ID * ID
* @param throwable * @param throwable
* @return * @return ID
*/ */
public static String getUserId(boolean throwable){ public static String getUserId(boolean throwable) { // 获取当前登录用户 ID 的方法
try { try {
// 使用 Shiro 获取当前用户的主体对象,然后从中提取用户 ID
return ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()).getId(); return ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()).getId();
}catch (Exception e){ } catch (Exception e) { // 捕获异常
if(throwable){ if (throwable) { // 如果 throwable 为 true则抛出自定义服务异常
throw new ServiceException(ApiError.ERROR_10010002); throw new ServiceException(ApiError.ERROR_10010002); // 异常码10010002
} }
return null; return null; // 如果发生异常且 throwable 为 false则返回 null
} }
} }
/** /**
* ID * ID
* @param throwable * @param throwable
* @return * @return ID
*/ */
public static boolean isAdmin(boolean throwable){ public static boolean isAdmin(boolean throwable) { // 判断当前用户是否为管理员的方法
try { try {
SysUserLoginDTO dto = ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()); SysUserLoginDTO dto = ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()); // 获取当前用户的登录信息
return dto.getRoles().contains("sa"); return dto.getRoles().contains("sa"); // 判断用户角色中是否包含管理员角色 "sa"
}catch (Exception e){ } catch (Exception e) { // 捕获异常
if(throwable){ if (throwable) { // 如果 throwable 为 true则抛出自定义服务异常
throw new ServiceException(ApiError.ERROR_10010002); throw new ServiceException(ApiError.ERROR_10010002); // 异常码10010002
} }
} }
return false; // 如果发生异常且 throwable 为 false则返回 false
return false;
} }
/** /**
* ID * ID
* @return * @return ID
*/ */
public static String getUserId(){ public static String getUserId() { // 默认抛出异常的获取用户 ID 方法
return getUserId(true); return getUserId(true); // 调用带有 throwable 参数的方法,默认抛出异常
} }
} }

@ -1,76 +1,79 @@
package com.yf.exam.modules.user.book.controller; package com.yf.exam.modules.user.book.controller; // 包名:表示该类属于 user.book.controller 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 分页接口
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入 ApiRest 类,定义接口返回的统一格式
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入 BaseController 基础控制器类,提供一些基础功能
import com.yf.exam.core.api.dto.BaseIdRespDTO; import com.yf.exam.core.api.dto.BaseIdRespDTO; // 导入 BaseIdRespDTO 数据传输对象,用于返回 ID 响应
import com.yf.exam.core.api.dto.BaseIdsReqDTO; import com.yf.exam.core.api.dto.BaseIdsReqDTO; // 导入 BaseIdsReqDTO 数据传输对象,用于接收 ID 列表请求
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入 PagingReqDTO 数据传输对象,用于分页请求
import com.yf.exam.modules.user.book.dto.UserBookDTO; import com.yf.exam.modules.user.book.dto.UserBookDTO; // 导入 UserBookDTO 数据传输对象,用于封装错题本数据
import com.yf.exam.modules.user.book.service.UserBookService; import com.yf.exam.modules.user.book.service.UserBookService; // 导入 UserBookService 服务接口,用于处理业务逻辑
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 的 Api 注解,用于生成 API 文档
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 的 ApiOperation 注解,用于描述 API 操作
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 注解,用于自动注入依赖
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入 RequestBody 注解,用于接收请求体数据
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 注解,用于映射请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入 RequestMethod 枚举,表示请求方法类型
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入 RestController 注解,表示这是一个控制器类
/** /**
* <p> * <p>
* *
* </p> * </p>
* * API
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
@Api(tags={"错题本"}) */
@RestController @Api(tags={"错题本"}) // 为这个控制器定义一个标签,用于生成 API 文档
@RequestMapping("/exam/api/user/wrong-book") @RestController // 标识该类为 Spring 的控制器类,自动注入到 Spring 上下文
public class UserBookController extends BaseController { @RequestMapping("/exam/api/user/wrong-book") // 设置该类的请求路径前缀
public class UserBookController extends BaseController { // 继承自 BaseController享受基础功能
@Autowired @Autowired
private UserBookService baseService; private UserBookService baseService; // 注入 UserBookService用于处理错题本的相关逻辑
/** /**
* *
* @param reqDTO * @param reqDTO ID
* @return * @return
*/ */
@ApiOperation(value = "批量删除") @ApiOperation(value = "批量删除") // 为该方法生成 Swagger 的文档描述
@RequestMapping(value = "/delete", method = { RequestMethod.POST}) @RequestMapping(value = "/delete", method = { RequestMethod.POST }) // 映射 POST 请求路径 "/delete"
public ApiRest delete(@RequestBody BaseIdsReqDTO reqDTO) { public ApiRest delete(@RequestBody BaseIdsReqDTO reqDTO) { // 接收请求体中的 ID 列表
//根据ID删除
// 根据 ID 删除错题本数据
baseService.removeByIds(reqDTO.getIds()); baseService.removeByIds(reqDTO.getIds());
return super.success(); return super.success(); // 返回成功的响应
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // 为该方法生成 Swagger 的文档描述
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = { RequestMethod.POST }) // 映射 POST 请求路径 "/paging"
public ApiRest<IPage<UserBookDTO>> paging(@RequestBody PagingReqDTO<UserBookDTO> reqDTO) { public ApiRest<IPage<UserBookDTO>> paging(@RequestBody PagingReqDTO<UserBookDTO> reqDTO) { // 接收分页请求数据
//分页查询并转换 // 调用服务层的分页查询方法
IPage<UserBookDTO> page = baseService.paging(reqDTO); IPage<UserBookDTO> page = baseService.paging(reqDTO);
return super.success(page); return super.success(page); // 返回分页查询的结果
} }
/** /**
* 200 * 200
* @param reqDTO * @param reqDTO ID ID
* @return * @return ID
*/ */
@ApiOperation(value = "查找列表") @ApiOperation(value = "查找列表") // 为该方法生成 Swagger 的文档描述
@RequestMapping(value = "/next", method = { RequestMethod.POST}) @RequestMapping(value = "/next", method = { RequestMethod.POST }) // 映射 POST 请求路径 "/next"
public ApiRest<BaseIdRespDTO> nextQu(@RequestBody UserBookDTO reqDTO) { public ApiRest<BaseIdRespDTO> nextQu(@RequestBody UserBookDTO reqDTO) { // 接收包含考试 ID 和题目 ID 的请求数据
//转换并返回
// 调用服务层的 findNext 方法查找下一题
String quId = baseService.findNext(reqDTO.getExamId(), reqDTO.getQuId()); String quId = baseService.findNext(reqDTO.getExamId(), reqDTO.getQuId());
return super.success(new BaseIdRespDTO(quId)); return super.success(new BaseIdRespDTO(quId)); // 返回下一题的 ID
} }
} }

@ -1,52 +1,51 @@
package com.yf.exam.modules.user.book.dto; package com.yf.exam.modules.user.book.dto; // 包名:表示该类属于 user.book.dto 包
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 的 ApiModel 注解,用于生成 API 文档中的模型描述
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 的 ApiModelProperty 注解,用于描述模型的属性
import lombok.Data; import lombok.Data; // 导入 Lombok 的 Data 注解,自动生成 getters、setters、toString 等方法
import java.io.Serializable; import java.io.Serializable; // 导入 Serializable 接口,用于对象序列化
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理日期数据
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
@Data */
@ApiModel(value="错题本", description="错题本") @Data // Lombok 注解,自动生成常用的 getter、setter、toString、equals 和 hashCode 方法
public class UserBookDTO implements Serializable { @ApiModel(value="错题本", description="错题本") // Swagger 注解,定义该类用于描述错题本
public class UserBookDTO implements Serializable { // 实现 Serializable 接口,支持对象序列化
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 定义序列化版本 UID
@ApiModelProperty(value = "ID", required=true) // Swagger 注解,描述属性的含义和是否必填
private String id; // 错题本 ID
@ApiModelProperty(value = "ID", required=true) @ApiModelProperty(value = "考试ID", required=true) // Swagger 注解,描述考试 ID
private String id; private String examId; // 关联的考试 ID
@ApiModelProperty(value = "考试ID", required=true) @ApiModelProperty(value = "用户ID", required=true) // Swagger 注解,描述用户 ID
private String examId; private String userId; // 关联的用户 ID
@ApiModelProperty(value = "用户ID", required=true) @ApiModelProperty(value = "题目ID", required=true) // Swagger 注解,描述题目 ID
private String userId; private String quId; // 关联的题目 ID
@ApiModelProperty(value = "题目ID", required=true) @ApiModelProperty(value = "加入时间", required=true) // Swagger 注解,描述错题本的加入时间
private String quId; private Date createTime; // 错题本加入时间
@ApiModelProperty(value = "加入时间", required=true) @ApiModelProperty(value = "最近错误时间", required=true) // Swagger 注解,描述最近一次错误的时间
private Date createTime; private Date updateTime; // 最近一次错题的时间
@ApiModelProperty(value = "最近错误时间", required=true) @ApiModelProperty(value = "错误次数", required=true) // Swagger 注解,描述错题的错误次数
private Date updateTime; private Integer wrongCount; // 错题的错误次数
@ApiModelProperty(value = "错误时间", required=true) @ApiModelProperty(value = "题目标题", required=true) // Swagger 注解,描述题目标题
private Integer wrongCount; private String title; // 题目的标题
@ApiModelProperty(value = "题目标题", required=true) @ApiModelProperty(value = "错题序号", required=true) // Swagger 注解,描述错题的序号
private String title; private Integer sort; // 错题的序号,用于排序
}
@ApiModelProperty(value = "错题序号", required=true)
private Integer sort;
}

@ -1,78 +1,78 @@
package com.yf.exam.modules.user.book.entity; package com.yf.exam.modules.user.book.entity; // 包名:表示该类属于 user.book.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 的 IdType用于设置 ID 类型
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 TableField 注解,用于标识表字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 TableId 注解,用于标识表的主键
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 注解,用于标识表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 Model 类,用于支持 Active Record 模式
import lombok.Data; import lombok.Data; // 导入 Lombok 的 Data 注解,自动生成 getter、setter、toString 等方法
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理日期类型数据
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
@Data */
@TableName("el_user_book") @Data // Lombok 注解,自动为类生成 getter、setter、toString、equals 和 hashCode 方法
public class UserBook extends Model<UserBook> { @TableName("el_user_book") // 表示该类对应数据库中的 el_user_book 表
public class UserBook extends Model<UserBook> { // 继承自 MyBatis-Plus 的 Model 类,支持 Active Record 模式
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本 UID
/** /**
* ID * ID
*/ */
@TableId(value = "id", type = IdType.ASSIGN_ID) @TableId(value = "id", type = IdType.ASSIGN_ID) // 设置表的主键 ID 类型为 ASSIGN_ID表示数据库自增长
private String id; private String id; // 错题本记录的 ID
/** /**
* ID * ID
*/ */
@TableField("exam_id") @TableField("exam_id") // 映射数据库表的 exam_id 字段
private String examId; private String examId; // 关联的考试 ID
/** /**
* ID * ID
*/ */
@TableField("user_id") @TableField("user_id") // 映射数据库表的 user_id 字段
private String userId; private String userId; // 关联的用户 ID
/** /**
* ID * ID
*/ */
@TableField("qu_id") @TableField("qu_id") // 映射数据库表的 qu_id 字段
private String quId; private String quId; // 关联的题目 ID
/** /**
* *
*/ */
@TableField("create_time") @TableField("create_time") // 映射数据库表的 create_time 字段
private Date createTime; private Date createTime; // 错题加入时间
/** /**
* *
*/ */
@TableField("update_time") @TableField("update_time") // 映射数据库表的 update_time 字段
private Date updateTime; private Date updateTime; // 最近一次错误的时间
/** /**
* *
*/ */
@TableField("wrong_count") @TableField("wrong_count") // 映射数据库表的 wrong_count 字段
private Integer wrongCount; private Integer wrongCount; // 错误的次数
/** /**
* *
*/ */
private String title; private String title; // 题目的标题
/** /**
* *
*/ */
private Integer sort; private Integer sort; // 错题的序号,用于排序
} }

@ -1,16 +1,17 @@
package com.yf.exam.modules.user.book.mapper; package com.yf.exam.modules.user.book.mapper; // 包名:表示该接口属于 user.book.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,提供基本的 CRUD 操作
import com.yf.exam.modules.user.book.entity.UserBook; import com.yf.exam.modules.user.book.entity.UserBook; // 导入 UserBook 实体类,表示错题本数据
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * MyBatis-Plus BaseMapper
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
public interface UserBookMapper extends BaseMapper<UserBook> { */
public interface UserBookMapper extends BaseMapper<UserBook> { // 继承 MyBatis-Plus 的 BaseMapper 接口,自动具备对 UserBook 实体的基本 CRUD 操作
} }

@ -1,40 +1,41 @@
package com.yf.exam.modules.user.book.service; package com.yf.exam.modules.user.book.service; // 包名:表示该接口属于 user.book.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,提供常用的 CRUD 操作
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象
import com.yf.exam.modules.user.book.dto.UserBookDTO; import com.yf.exam.modules.user.book.dto.UserBookDTO; // 导入错题本 DTO 类,用于封装错题本的数据
import com.yf.exam.modules.user.book.entity.UserBook; import com.yf.exam.modules.user.book.entity.UserBook; // 导入错题本实体类,映射数据库中的错题本表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
public interface UserBookService extends IService<UserBook> { */
public interface UserBookService extends IService<UserBook> { // 继承 MyBatis-Plus 的 IService 接口,提供基本的 CRUD 操作
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO); IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO); // 分页查询错题本数据
/** /**
* *
* @param quId * @param examId ID
* @param examId * @param quId ID
*/ */
void addBook(String examId, String quId); void addBook(String examId, String quId); // 将指定的错题添加到错题本
/** /**
* *
* @param quId * @param quId ID
* @param examId * @param examId ID
* @return * @return ID
*/ */
String findNext(String examId, String quId); String findNext(String examId, String quId); // 查找下一个错题 ID
} }

@ -1,155 +1,153 @@
package com.yf.exam.modules.user.book.service.impl; package com.yf.exam.modules.user.book.service.impl; // 包名:表示该类属于 user.book.service.impl 包
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON; // 导入 fastjson用于将对象转换为 JSON 字符串
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference; // 导入 TypeReference 用于反序列化复杂类型
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper 类,用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 的分页插件
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 基类
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求的 DTO 类
import com.yf.exam.modules.qu.entity.Qu; import com.yf.exam.modules.qu.entity.Qu; // 导入题目实体类
import com.yf.exam.modules.qu.service.QuService; import com.yf.exam.modules.qu.service.QuService; // 导入题目服务接口
import com.yf.exam.modules.user.UserUtils; import com.yf.exam.modules.user.UserUtils; // 导入用户工具类,用于获取当前用户信息
import com.yf.exam.modules.user.book.dto.UserBookDTO; import com.yf.exam.modules.user.book.dto.UserBookDTO; // 导入错题本 DTO
import com.yf.exam.modules.user.book.entity.UserBook; import com.yf.exam.modules.user.book.entity.UserBook; // 导入错题本实体类
import com.yf.exam.modules.user.book.mapper.UserBookMapper; import com.yf.exam.modules.user.book.mapper.UserBookMapper; // 导入错题本 Mapper 类
import com.yf.exam.modules.user.book.service.UserBookService; import com.yf.exam.modules.user.book.service.UserBookService; // 导入错题本服务接口
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 注解,用于自动注入依赖
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Service 注解,标识该类为 Spring 服务层组件
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils; // 导入 StringUtils 工具类,用于字符串操作
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-05-27 17:56 * @
*/ * @ 2020-05-27 17:56
@Service */
public class UserBookServiceImpl extends ServiceImpl<UserBookMapper, UserBook> implements UserBookService { @Service // 标识该类为 Spring 的服务类
public class UserBookServiceImpl extends ServiceImpl<UserBookMapper, UserBook> implements UserBookService { // 继承 MyBatis-Plus 的 ServiceImpl实现 UserBookService 接口
@Autowired @Autowired
private QuService quService; private QuService quService; // 注入题目服务,用于获取题目内容
@Override @Override
public IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO) { public IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO) { // 分页查询错题本数据
//创建分页对象 // 创建分页对象
Page query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); Page query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件 // 查询条件
QueryWrapper<UserBook> wrapper = new QueryWrapper<>(); QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
// 查找用户的错题 // 查找用户的错题
wrapper.lambda().eq(UserBook::getUserId, UserUtils.getUserId(true)); wrapper.lambda().eq(UserBook::getUserId, UserUtils.getUserId(true));
UserBookDTO params = reqDTO.getParams(); UserBookDTO params = reqDTO.getParams();
if(params!=null){ if(params != null) {
if(!StringUtils.isEmpty(params.getTitle())){ // 根据题目标题查询
if(!StringUtils.isEmpty(params.getTitle())) {
wrapper.lambda().like(UserBook::getTitle, params.getTitle()); wrapper.lambda().like(UserBook::getTitle, params.getTitle());
} }
if(!StringUtils.isEmpty(params.getExamId())){ // 根据考试 ID 查询
if(!StringUtils.isEmpty(params.getExamId())) {
wrapper.lambda().eq(UserBook::getExamId, params.getExamId()); wrapper.lambda().eq(UserBook::getExamId, params.getExamId());
} }
} }
//获得数据 // 执行分页查询
IPage<UserBook> page = this.page(query, wrapper); IPage<UserBook> page = this.page(query, wrapper);
//转换结果 // 转换结果为 DTO
IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>(){}); IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>() {});
return pageData; return pageData;
} }
@Override @Override
public void addBook(String examId, String quId) { public void addBook(String examId, String quId) { // 添加错题到错题本
QueryWrapper<UserBook> wrapper = new QueryWrapper<>(); QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(UserBook::getUserId, UserUtils.getUserId()) .eq(UserBook::getUserId, UserUtils.getUserId()) // 查找当前用户的错题
.eq(UserBook::getExamId, examId) .eq(UserBook::getExamId, examId) // 查找特定考试的错题
.eq(UserBook::getQuId, quId); .eq(UserBook::getQuId, quId); // 查找特定题目的错题
//查找已有的错题信息 // 查找已有的错题信息
UserBook book = this.getOne(wrapper, false); UserBook book = this.getOne(wrapper, false);
// 获取题目信息
// 问题
Qu qu = quService.getById(quId); Qu qu = quService.getById(quId);
if (book == null) { if (book == null) { // 如果错题本中没有该题目,则添加
book = new UserBook(); book = new UserBook();
book.setExamId(examId); book.setExamId(examId);
book.setUserId(UserUtils.getUserId()); book.setUserId(UserUtils.getUserId()); // 设置当前用户的 ID
book.setTitle(qu.getContent()); book.setTitle(qu.getContent()); // 设置题目内容
book.setQuId(quId); book.setQuId(quId);
book.setWrongCount(1); book.setWrongCount(1); // 错误次数初始化为 1
Integer maxSort = this.findMaxSort(examId, UserUtils.getUserId()); Integer maxSort = this.findMaxSort(examId, UserUtils.getUserId()); // 查找当前用户的最大排序号
book.setSort(maxSort+1); book.setSort(maxSort + 1); // 设置错题的排序号
this.save(book); this.save(book); // 保存错题记录
} else { } else { // 如果错题本中已有该题目,则更新错误次数
book.setWrongCount(book.getWrongCount()+1); book.setWrongCount(book.getWrongCount() + 1); // 错误次数加 1
this.updateById(book); this.updateById(book); // 更新错题记录
} }
} }
@Override @Override
public String findNext(String examId, String quId) { public String findNext(String examId, String quId) { // 查找下一个错题
Integer sort = 999999; Integer sort = 999999;
if(!StringUtils.isEmpty(quId)){ if(!StringUtils.isEmpty(quId)) {
QueryWrapper<UserBook> wrapper = new QueryWrapper<>(); QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(UserBook::getUserId, UserUtils.getUserId()) .eq(UserBook::getUserId, UserUtils.getUserId()) // 查找当前用户的错题
.eq(UserBook::getExamId, examId) .eq(UserBook::getExamId, examId) // 查找特定考试的错题
.eq(UserBook::getQuId, quId); .eq(UserBook::getQuId, quId); // 查找特定题目的错题
wrapper.last(" ORDER BY `sort` DESC"); wrapper.last(" ORDER BY `sort` DESC"); // 按照排序降序排列
UserBook last = this.getOne(wrapper, false); UserBook last = this.getOne(wrapper, false);
if(last!=null){ if(last != null) {
sort = last.getSort(); sort = last.getSort(); // 获取当前错题的排序号
} }
} }
QueryWrapper<UserBook> wrapper = new QueryWrapper<>(); QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(UserBook::getUserId, UserUtils.getUserId()) .eq(UserBook::getUserId, UserUtils.getUserId()) // 查找当前用户的错题
.eq(UserBook::getExamId, examId) .eq(UserBook::getExamId, examId) // 查找特定考试的错题
.lt(UserBook::getSort, sort); .lt(UserBook::getSort, sort); // 查找排序号小于当前错题的错题
wrapper.last(" ORDER BY `sort` DESC"); wrapper.last(" ORDER BY `sort` DESC"); // 按照排序降序排列
UserBook next = this.getOne(wrapper, false); UserBook next = this.getOne(wrapper, false); // 查找下一个错题
if(next != null){ if(next != null) {
return next.getQuId(); return next.getQuId(); // 返回下一个错题的 ID
} }
return null; return null; // 如果没有下一个错题,返回 null
} }
/** /**
* *
* @param userId * @param examId ID
* @return * @param userId ID
* @return
*/ */
private Integer findMaxSort(String examId, String userId){ private Integer findMaxSort(String examId, String userId) { // 查找当前用户在某个考试中的最大排序号
QueryWrapper<UserBook> wrapper = new QueryWrapper<>(); QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(UserBook::getExamId, examId) .eq(UserBook::getExamId, examId) // 查找特定考试的错题
.eq(UserBook::getUserId, userId); .eq(UserBook::getUserId, userId); // 查找当前用户的错题
wrapper.last(" ORDER BY `sort` DESC"); wrapper.last(" ORDER BY `sort` DESC"); // 按照排序号降序排列
UserBook book = this.getOne(wrapper, false); UserBook book = this.getOne(wrapper, false); // 获取最大排序号的错题
if(book == null){ if(book == null) {
return 0; return 0; // 如果没有错题,返回 0
} }
return book.getSort(); return book.getSort(); // 返回最大排序号
} }
} }

@ -1,65 +1,64 @@
package com.yf.exam.modules.user.exam.controller; package com.yf.exam.modules.user.exam.controller; // 包名:表示该类属于 user.exam.controller 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.yf.exam.core.api.ApiRest; import com.yf.exam.core.api.ApiRest; // 导入 API 响应封装类,用于统一返回格式
import com.yf.exam.core.api.controller.BaseController; import com.yf.exam.core.api.controller.BaseController; // 导入基础控制器类,提供通用的接口方法
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO 类,用于封装分页参数
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; // 导入用户考试请求 DTO 类,用于封装考试查询参数
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; // 导入用户考试响应 DTO 类,用于封装查询结果
import com.yf.exam.modules.user.exam.service.UserExamService; import com.yf.exam.modules.user.exam.service.UserExamService; // 导入用户考试服务接口,用于处理考试相关的业务逻辑
import io.swagger.annotations.Api; import io.swagger.annotations.Api; // 导入 Swagger 注解,用于生成 API 文档中的标签
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation; // 导入 Swagger 注解,用于描述接口方法
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 注解,用于自动注入依赖
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody; // 导入 RequestBody 注解,用于绑定请求体参数
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 注解,用于映射请求路径
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod; // 导入 RequestMethod 枚举,用于指定请求方法类型
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; // 导入 RestController 注解,标识该类为 RESTful 风格的控制器
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Api(tags={"考试记录"}) */
@RestController @Api(tags={"考试记录"}) // Swagger 注解,定义该类在 API 文档中的标签
@RequestMapping("/exam/api/user/exam") @RestController // 标识该类为 RESTful 风格的控制器
public class UserExamController extends BaseController { @RequestMapping("/exam/api/user/exam") // 映射请求路径,所有接口都以 "/exam/api/user/exam" 开头
public class UserExamController extends BaseController { // 继承 BaseController提供基础的响应方法
@Autowired @Autowired
private UserExamService baseService; private UserExamService baseService; // 自动注入 UserExamService 服务,处理考试记录相关业务
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解,描述接口方法的作用
@RequestMapping(value = "/paging", method = { RequestMethod.POST}) @RequestMapping(value = "/paging", method = { RequestMethod.POST}) // 映射 POST 请求路径 "/exam/api/user/exam/paging"
public ApiRest<IPage<UserExamRespDTO>> paging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) { public ApiRest<IPage<UserExamRespDTO>> paging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) { // 接收分页请求,返回分页结果
//分页查询并转换 // 调用服务层方法进行分页查询将结果转换为响应 DTO
IPage<UserExamRespDTO> page = baseService.paging(reqDTO); IPage<UserExamRespDTO> page = baseService.paging(reqDTO);
return super.success(page); return super.success(page); // 调用父类的 success 方法返回查询结果
} }
/** /**
* *
* @param reqDTO * @param reqDTO
* @return * @return
*/ */
@ApiOperation(value = "分页查找") @ApiOperation(value = "分页查找") // Swagger 注解,描述接口方法的作用
@RequestMapping(value = "/my-paging", method = { RequestMethod.POST}) @RequestMapping(value = "/my-paging", method = { RequestMethod.POST}) // 映射 POST 请求路径 "/exam/api/user/exam/my-paging"
public ApiRest<IPage<UserExamRespDTO>> myPaging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) { public ApiRest<IPage<UserExamRespDTO>> myPaging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) { // 接收分页请求,返回用户的分页考试记录
//分页查询并转换 // 调用服务层方法进行分页查询将结果转换为响应 DTO
IPage<UserExamRespDTO> page = baseService.myPaging(reqDTO); IPage<UserExamRespDTO> page = baseService.myPaging(reqDTO);
return super.success(page); return super.success(page); // 调用父类的 success 方法返回查询结果
} }
} }

@ -1,50 +1,72 @@
package com.yf.exam.modules.user.exam.dto; package com.yf.exam.modules.user.exam.dto; // 包名:表示该类属于 user.exam.dto 包
import com.yf.exam.core.annon.Dict; import com.yf.exam.core.annon.Dict; // 导入 Dict 注解,用于字段的字典数据转换
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于生成 API 文档中的描述
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述类字段
import lombok.Data; import lombok.Data; // 导入 Lombok 的 Data 注解,用于自动生成 getter、setter 等方法
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理时间
import java.io.Serializable; // 导入 Serializable 接口,确保该类可以序列化
import java.io.Serializable;
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Data */
@ApiModel(value="考试记录", description="考试记录") @Data // Lombok 注解,自动为类生成 getter、setter、toString 等方法
public class UserExamDTO implements Serializable { @ApiModel(value="考试记录", description="考试记录") // Swagger 注解,描述该类的作用,生成 API 文档时使用
public class UserExamDTO implements Serializable { // 实现 Serializable 接口,使该类可以序列化
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L; // 序列化版本 UID
private String id; /**
* ID
@ApiModelProperty(value = "用户ID", required=true) */
private String userId; private String id; // 用户ID字段
@Dict(dictTable = "el_exam", dicText = "title", dicCode = "id") /**
@ApiModelProperty(value = "考试ID", required=true) * ID
private String examId; */
@ApiModelProperty(value = "用户ID", required=true) // Swagger 注解,描述字段的作用,设置为必填项
@ApiModelProperty(value = "考试次数", required=true) private String userId; // 用户ID字段
private Integer tryCount;
/**
@ApiModelProperty(value = "最高分数", required=true) * ID
private Integer maxScore; */
@Dict(dictTable = "el_exam", dicText = "title", dicCode = "id") // 使用 Dict 注解,指定字典表及映射字段
@ApiModelProperty(value = "是否通过", required=true) @ApiModelProperty(value = "考试ID", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private Boolean passed; private String examId; // 考试ID字段
@ApiModelProperty(value = "创建时间") /**
private Date createTime; *
*/
@ApiModelProperty(value = "更新时间") @ApiModelProperty(value = "考试次数", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private Date updateTime; private Integer tryCount; // 考试次数字段
/**
*
*/
@ApiModelProperty(value = "最高分数", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private Integer maxScore; // 最高分数字段
/**
*
*/
@ApiModelProperty(value = "是否通过", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private Boolean passed; // 是否通过字段
/**
*
*/
@ApiModelProperty(value = "创建时间") // Swagger 注解,描述字段的作用
private Date createTime; // 创建时间字段
/**
*
*/
@ApiModelProperty(value = "更新时间") // Swagger 注解,描述字段的作用
private Date updateTime; // 更新时间字段
} }

@ -1,30 +1,34 @@
package com.yf.exam.modules.user.exam.dto.request; package com.yf.exam.modules.user.exam.dto.request; // 包名:表示该类属于 user.exam.dto.request 包
import com.yf.exam.modules.user.exam.dto.UserExamDTO; import com.yf.exam.modules.user.exam.dto.UserExamDTO; // 导入 UserExamDTO 类,作为父类,包含通用的考试记录信息
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于生成 API 文档中的描述
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述类字段
import lombok.Data; import lombok.Data; // 导入 Lombok 的 Data 注解,用于自动生成 getter、setter 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Data */
@ApiModel(value="考试记录", description="考试记录") @Data // Lombok 注解,自动为类生成 getter、setter、toString 等方法
public class UserExamReqDTO extends UserExamDTO { @ApiModel(value="考试记录", description="考试记录") // Swagger 注解,描述该类的作用,生成 API 文档时使用
public class UserExamReqDTO extends UserExamDTO { // 继承 UserExamDTO 类,扩展额外的请求字段
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L; // 序列化版本 UID
@ApiModelProperty(value = "考试名称", required=true) /**
private String title; *
*/
@ApiModelProperty(value = "人员名称", required=true) @ApiModelProperty(value = "考试名称", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private String realName; private String title; // 考试名称字段
/**
*
*/
@ApiModelProperty(value = "人员名称", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private String realName; // 人员名称字段
} }

@ -1,29 +1,34 @@
package com.yf.exam.modules.user.exam.dto.response; package com.yf.exam.modules.user.exam.dto.response; // 包名:表示该类属于 user.exam.dto.response 包
import com.yf.exam.modules.user.exam.dto.UserExamDTO; import com.yf.exam.modules.user.exam.dto.UserExamDTO; // 导入 UserExamDTO 类,作为父类,包含通用的考试记录信息
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel; // 导入 Swagger 注解,用于生成 API 文档中的描述
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty; // 导入 Swagger 注解,用于描述类字段
import lombok.Data; import lombok.Data; // 导入 Lombok 的 Data 注解,用于自动生成 getter、setter 等方法
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Data */
@ApiModel(value="考试记录", description="考试记录") @Data // Lombok 注解,自动为类生成 getter、setter、toString 等方法
public class UserExamRespDTO extends UserExamDTO { @ApiModel(value="考试记录", description="考试记录") // Swagger 注解,描述该类的作用,生成 API 文档时使用
public class UserExamRespDTO extends UserExamDTO { // 继承 UserExamDTO 类,扩展额外的响应字段
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L; // 序列化版本 UID
/**
*
*/
@ApiModelProperty(value = "考试名称", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private String title; // 考试名称字段
@ApiModelProperty(value = "考试名称", required=true) /**
private String title; *
*/
@ApiModelProperty(value = "人员名称", required=true) @ApiModelProperty(value = "人员名称", required=true) // Swagger 注解,描述字段的作用,设置为必填项
private String realName; private String realName; // 人员名称字段
} }

@ -1,69 +1,72 @@
package com.yf.exam.modules.user.exam.entity; package com.yf.exam.modules.user.exam.entity; // 包名:表示该类属于 user.exam.entity 包
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType; // 导入 MyBatis-Plus 注解,用于指定主键策略
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField; // 导入 MyBatis-Plus 注解,用于指定数据库表字段
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId; // 导入 MyBatis-Plus 注解,用于指定主键字段
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName; // 导入 MyBatis-Plus 注解,用于指定数据库表名
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model; // 导入 MyBatis-Plus 提供的 Model 类,用于增强实体类
import lombok.Data; import lombok.Data; // 导入 Lombok 注解,用于自动生成 getter、setter 等方法
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Data */
@TableName("el_user_exam") @Data // Lombok 注解,自动为类生成 getter、setter、toString 等方法
public class UserExam extends Model<UserExam> { @TableName("el_user_exam") // MyBatis-Plus 注解,指定该实体类对应的数据库表名为 "el_user_exam"
public class UserExam extends Model<UserExam> { // 继承 Model 类,提供额外的 MyBatis-Plus 功能
private static final long serialVersionUID = 1L; // 序列化版本 UID
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/** /**
* ID * ID
*/ */
@TableField("user_id") @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis-Plus 注解,指定主键字段为 "id",主键类型为 "ASSIGN_ID"
private String userId; private String id; // ID字段
/** /**
* ID * ID
*/ */
@TableField("exam_id") @TableField("user_id") // MyBatis-Plus 注解,指定数据库字段 "user_id" 对应实体类的 "userId" 字段
private String examId; private String userId; // 用户ID字段
/** /**
* * ID
*/ */
@TableField("try_count") @TableField("exam_id") // MyBatis-Plus 注解,指定数据库字段 "exam_id" 对应实体类的 "examId" 字段
private Integer tryCount; private String examId; // 考试ID字段
/** /**
* *
*/ */
@TableField("max_score") @TableField("try_count") // MyBatis-Plus 注解,指定数据库字段 "try_count" 对应实体类的 "tryCount" 字段
private Integer maxScore; private Integer tryCount; // 考试次数字段
/** /**
* *
*/ */
private Boolean passed; @TableField("max_score") // MyBatis-Plus 注解,指定数据库字段 "max_score" 对应实体类的 "maxScore" 字段
private Integer maxScore; // 最高分数字段
/**
*
*/
private Boolean passed; // 是否通过字段
/** /**
* *
*/ */
@TableField("create_time") @TableField("create_time") // MyBatis-Plus 注解,指定数据库字段 "create_time" 对应实体类的 "createTime" 字段
private Date createTime; private Date createTime; // 创建时间字段
/** /**
* *
*/ */
@TableField("update_time") @TableField("update_time") // MyBatis-Plus 注解,指定数据库字段 "update_time" 对应实体类的 "updateTime" 字段
private Date updateTime; private Date updateTime; // 更新时间字段
} }

@ -1,29 +1,29 @@
package com.yf.exam.modules.user.exam.mapper; package com.yf.exam.modules.user.exam.mapper; // 包名:表示该类属于 user.exam.mapper 包
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper 接口,提供基本的数据库操作
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 的 Page 类,用于分页查询
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; // 导入用户考试请求 DTO 类,用于封装分页查询请求
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; // 导入用户考试响应 DTO 类,用于封装分页查询结果
import com.yf.exam.modules.user.exam.entity.UserExam; import com.yf.exam.modules.user.exam.entity.UserExam; // 导入用户考试实体类,用于映射数据库表
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param; // 导入 MyBatis 的 Param 注解,用于标注方法参数
/** /**
* <p> * <p>
* Mapper * Mapper
* </p> * </p>
* * 访
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
public interface UserExamMapper extends BaseMapper<UserExam> { */
public interface UserExamMapper extends BaseMapper<UserExam> { // 继承 BaseMapper 提供基础的增删改查功能
/** /**
* *
* @param page * @param page
* @param query * @param query
* @return * @return
*/ */
IPage<UserExamRespDTO> paging(Page page, @Param("query") UserExamReqDTO query); IPage<UserExamRespDTO> paging(Page page, @Param("query") UserExamReqDTO query); // 自定义分页查询方法,返回分页结果
} }

@ -1,43 +1,43 @@
package com.yf.exam.modules.user.exam.service; package com.yf.exam.modules.user.exam.service; // 包名:表示该类属于 user.exam.service 包
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 的 IService 接口,提供基础服务接口
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO 类,用于封装分页查询请求
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; // 导入用户考试请求 DTO 类
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; // 导入用户考试响应 DTO 类
import com.yf.exam.modules.user.exam.entity.UserExam; import com.yf.exam.modules.user.exam.entity.UserExam; // 导入用户考试实体类,用于映射数据库表
/** /**
* <p> * <p>
* *
* </p> * </p>
* *
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
public interface UserExamService extends IService<UserExam> { */
public interface UserExamService extends IService<UserExam> { // 继承 IService 接口,提供对 UserExam 实体的增删改查功能
/**
*
* @param reqDTO
* @return
*/
IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO);
/** /**
* *
* @param reqDTO * @param reqDTO DTO
* @return * @return
*/ */
IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO); IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO); // 用于分页查询考试记录
/**
*
* @param reqDTO DTO
* @return
*/
IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO); // 用于分页查询当前用户的考试记录
/** /**
* *
* @param userId * @param userId ID
* @param examId * @param examId ID
* @param score * @param score
* @param passed * @param passed
*/ */
void joinResult(String userId, String examId, Integer score, boolean passed); void joinResult(String userId, String examId, Integer score, boolean passed); // 记录用户考试结果
} }

@ -1,88 +1,87 @@
package com.yf.exam.modules.user.exam.service.impl; package com.yf.exam.modules.user.exam.service.impl; // 包名:表示该类属于 user.exam.service.impl 包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper用于构建查询条件
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 提供的 ServiceImpl 类,提供基础的服务层实现
import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求 DTO 类,用于封装分页查询请求
import com.yf.exam.modules.user.UserUtils; import com.yf.exam.modules.user.UserUtils; // 导入 UserUtils 工具类,用于获取当前用户的 ID
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO; // 导入用户考试请求 DTO 类
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO; // 导入用户考试响应 DTO 类
import com.yf.exam.modules.user.exam.entity.UserExam; import com.yf.exam.modules.user.exam.entity.UserExam; // 导入用户考试实体类,用于映射数据库表
import com.yf.exam.modules.user.exam.mapper.UserExamMapper; import com.yf.exam.modules.user.exam.mapper.UserExamMapper; // 导入用户考试 Mapper 类,提供数据库操作
import com.yf.exam.modules.user.exam.service.UserExamService; import com.yf.exam.modules.user.exam.service.UserExamService; // 导入用户考试服务接口
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service; // 导入 Service 注解,标识该类为服务层组件
import java.util.Date; import java.util.Date; // 导入 Date 类,用于处理时间
/** /**
* <p> * <p>
* *
* </p> * </p>
* * UserExamService
* @author *
* @since 2020-09-21 15:13 * @
*/ * @ 2020-09-21 15:13
@Service */
public class UserExamServiceImpl extends ServiceImpl<UserExamMapper, UserExam> implements UserExamService { @Service // 标识该类为 Spring 服务层组件
public class UserExamServiceImpl extends ServiceImpl<UserExamMapper, UserExam> implements UserExamService { // 继承 ServiceImpl 类,提供基础的增删改查功能,并实现 UserExamService 接口
@Override @Override
public IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO) { public IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO) { // 分页查询方法
//转换结果 // 使用 MyBatis-Plus 提供的 paging 方法进行分页查询,并转换为响应 DTO 类型
IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), reqDTO.getParams()); IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), reqDTO.getParams());
return pageData; return pageData; // 返回分页查询结果
} }
@Override @Override
public IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO) { public IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO) { // 我的考试分页查询方法
UserExamReqDTO params = reqDTO.getParams(); UserExamReqDTO params = reqDTO.getParams(); // 获取请求参数
// 如果没有传入参数,则初始化为空的 UserExamReqDTO 对象
if(params==null){ if(params == null) {
params = new UserExamReqDTO(); params = new UserExamReqDTO();
} }
params.setUserId(UserUtils.getUserId()); params.setUserId(UserUtils.getUserId()); // 设置当前用户的 ID
//转换结果 // 使用 MyBatis-Plus 提供的 paging 方法进行分页查询,并转换为响应 DTO 类型
IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), params); IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), params);
return pageData; return pageData; // 返回分页查询结果
} }
@Override @Override
public void joinResult(String userId, String examId, Integer score, boolean passed) { public void joinResult(String userId, String examId, Integer score, boolean passed) { // 记录考试结果的方法
//查询条件 // 构建查询条件,查找用户的考试记录
QueryWrapper<UserExam> wrapper = new QueryWrapper<>(); QueryWrapper<UserExam> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(UserExam::getUserId, userId) wrapper.lambda().eq(UserExam::getUserId, userId) // 查询条件:用户 ID
.eq(UserExam::getExamId, examId); .eq(UserExam::getExamId, examId); // 查询条件:考试 ID
UserExam record = this.getOne(wrapper, false); UserExam record = this.getOne(wrapper, false); // 查找匹配的记录
if(record == null){ if(record == null) { // 如果记录不存在,则创建新记录
record = new UserExam(); record = new UserExam();
record.setCreateTime(new Date()); record.setCreateTime(new Date()); // 设置创建时间
record.setUpdateTime(new Date()); record.setUpdateTime(new Date()); // 设置更新时间
record.setUserId(userId); record.setUserId(userId); // 设置用户 ID
record.setExamId(examId); record.setExamId(examId); // 设置考试 ID
record.setMaxScore(score); record.setMaxScore(score); // 设置最大分数
record.setPassed(passed); record.setPassed(passed); // 设置是否通过
this.save(record); this.save(record); // 保存新记录
return; return;
} }
// 修复低分数不加入统计问题 // 如果记录存在,则更新该记录
record.setTryCount(record.getTryCount()+1); record.setTryCount(record.getTryCount() + 1); // 增加考试次数
record.setUpdateTime(new Date()); record.setUpdateTime(new Date()); // 更新更新时间
if(record.getMaxScore() < score){ // 如果当前分数高于记录中的最大分数,则更新最大分数
record.setMaxScore(score); if(record.getMaxScore() < score) {
record.setPassed(passed); record.setMaxScore(score); // 更新最大分数
record.setPassed(passed); // 更新是否通过
} }
this.updateById(record); this.updateById(record); // 更新记录
} }
} }

Loading…
Cancel
Save