From be4ff0967febd638fe767b82889b29cc99e9eada Mon Sep 17 00:00:00 2001 From: kwc <3316977819@qq.com> Date: Thu, 28 Nov 2024 08:22:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=A1=E6=96=87=E8=B6=85=E5=88=86=E6=94=AF?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yf/exam/core/annon/Dict.java | 25 +- .../java/com/yf/exam/core/api/ApiError.java | 80 ++- .../java/com/yf/exam/core/api/ApiRest.java | 54 +- .../core/api/controller/BaseController.java | 136 +++-- .../com/yf/exam/core/api/dto/BaseDTO.java | 7 + .../yf/exam/core/api/dto/BaseIdReqDTO.java | 34 +- .../yf/exam/core/api/dto/BaseIdRespDTO.java | 30 +- .../yf/exam/core/api/dto/BaseIdsReqDTO.java | 30 +- .../yf/exam/core/api/dto/BaseStateReqDTO.java | 42 +- .../yf/exam/core/api/dto/PagingReqDTO.java | 59 +-- .../yf/exam/core/api/dto/PagingRespDTO.java | 28 +- .../yf/exam/core/api/utils/JsonConverter.java | 58 +-- .../com/yf/exam/core/enums/CommonState.java | 16 +- .../java/com/yf/exam/core/enums/OpenType.java | 11 +- .../exam/core/exception/ServiceException.java | 45 +- .../exception/ServiceExceptionHandler.java | 44 +- .../com/yf/exam/core/utils/BeanMapper.java | 45 +- .../com/yf/exam/core/utils/CronUtils.java | 33 +- .../com/yf/exam/core/utils/DateUtils.java | 90 ++-- .../java/com/yf/exam/core/utils/IpUtils.java | 48 +- .../com/yf/exam/core/utils/Reflections.java | 301 ++++++----- .../com/yf/exam/core/utils/SpringUtils.java | 37 +- .../com/yf/exam/core/utils/StringUtils.java | 39 +- .../yf/exam/core/utils/excel/ExportExcel.java | 481 +++++++++--------- .../yf/exam/core/utils/excel/ImportExcel.java | 326 ++++++------ .../utils/excel/annotation/ExcelField.java | 28 + .../core/utils/excel/fieldtype/ListType.java | 51 +- .../com/yf/exam/core/utils/file/Md5Util.java | 34 +- .../exam/core/utils/passwd/PassHandler.java | 33 +- .../yf/exam/core/utils/passwd/PassInfo.java | 51 +- 30 files changed, 1161 insertions(+), 1135 deletions(-) diff --git a/src-源文件/main/java/com/yf/exam/core/annon/Dict.java b/src-源文件/main/java/com/yf/exam/core/annon/Dict.java index 4aa3f07..17f8813 100644 --- a/src-源文件/main/java/com/yf/exam/core/annon/Dict.java +++ b/src-源文件/main/java/com/yf/exam/core/annon/Dict.java @@ -1,21 +1,22 @@ -package com.yf.exam.core.annon; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/annon/Dict.java +package com.yf.exam.core.annon; // 定义包名,表示该类属于 com.yf.exam.core.annon 包 -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.ElementType; // 导入 ElementType 类,用于指定注解可以应用于的元素类型 +import java.lang.annotation.Retention; // 导入 Retention 类,用于指定注解的保留策略 +import java.lang.annotation.RetentionPolicy; // 导入 RetentionPolicy 类,定义注解的保留策略 +import java.lang.annotation.Target; // 导入 Target 类,用于指定注解的适用范围 /** * 数据字典注解 * @author bool */ -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Dict { +@Target(ElementType.FIELD) // 指定该注解可以应用于字段(类的属性) +@Retention(RetentionPolicy.RUNTIME) // 指定该注解在运行时仍然可用 +public @interface Dict { // 定义一个名为 Dict 的注解 - String dicCode(); + String dicCode(); // 定义一个抽象方法 dicCode,返回数据字典的代码 - String dicText() default ""; + String dicText() default ""; // 定义一个抽象方法 dicText,返回数据字典的文本,默认为空字符串 - String dictTable() default ""; -} + String dictTable() default ""; // 定义一个抽象方法 dictTable,返回数据字典的表名,默认为空字符串 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/ApiError.java b/src-源文件/main/java/com/yf/exam/core/api/ApiError.java index f299fac..d9584a9 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/ApiError.java +++ b/src-源文件/main/java/com/yf/exam/core/api/ApiError.java @@ -1,67 +1,63 @@ -package com.yf.exam.core.api; +package com.yf.exam.core.api; // 定义包名 +import lombok.AllArgsConstructor; // 导入Lombok的全参构造器注解 +import lombok.NoArgsConstructor; // 导入Lombok的无参构造器注解 -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; - -import java.io.Serializable; +import java.io.Serializable; // 导入Serializable接口 /** - * 全局错误码定义,用于定义接口的响应数据, - * 枚举名称全部使用代码命名,在系统中调用,免去取名难的问题。 - * @author bool - * @date 2019-06-14 21:15 + * 全局错误码定义,用于定义接口的响应数据, // 类注释,说明该类的用途 + * 枚举名称全部使用代码命名,在系统中调用,免去取名难的问题。 // 说明枚举命名规则 + * @author bool // 作者信息 + * @date 2019-06-14 21:15 // 日期信息 */ -@NoArgsConstructor -@AllArgsConstructor -public enum ApiError implements Serializable { - +@NoArgsConstructor // 生成无参构造器 +@AllArgsConstructor // 生成全参构造器 +public enum ApiError implements Serializable { // 定义ApiError枚举,实现Serializable接口 /** * 通用错误,接口参数不全 */ - ERROR_10010001("参数不全或类型错误!"), - ERROR_10010002("您还未登录,请先登录!"), - ERROR_10010003("数据不存在!"), - ERROR_10010012("图形验证码错误!"), - ERROR_10010013("短信验证码错误!"), - ERROR_10010014("不允许重复评论!"), + ERROR_10010001("参数不全或类型错误!"), // 错误码10010001及其对应的消息 + ERROR_10010002("您还未登录,请先登录!"), // 错误码10010002及其对应的消息 + ERROR_10010003("数据不存在!"), // 错误码10010003及其对应的消息 + ERROR_10010012("图形验证码错误!"), // 错误码10010012及其对应的消息 + ERROR_10010013("短信验证码错误!"), // 错误码10010013及其对应的消息 + ERROR_10010014("不允许重复评论!"), // 错误码10010014及其对应的消息 /** * 考试相关错误 */ - ERROR_20010001("试题被删除,无法继续考试!"), - ERROR_20010002("您有正在进行的考试!"), - - - ERROR_90010001("账号不存在,请确认!"), - ERROR_90010002("账号或密码错误!"), - ERROR_90010003("至少要包含一个角色!"), - ERROR_90010004("管理员账号无法修改!"), - ERROR_90010005("账号被禁用,请联系管理员!"), - ERROR_90010006("活动用户不足,无法开启竞拍!"), - ERROR_90010007("旧密码不正确,请确认!"), + ERROR_20010001("试题被删除,无法继续考试!"), // 错误码20010001及其对应的消息 + ERROR_20010002("您有正在进行的考试!"), // 错误码20010002及其对应的消息 + ERROR_90010001("账号不存在,请确认!"), // 错误码90010001及其对应的消息 + ERROR_90010002("账号或密码错误!"), // 错误码90010002及其对应的消息 + ERROR_90010003("至少要包含一个角色!"), // 错误码90010003及其对应的消息 + ERROR_90010004("管理员账号无法修改!"), // 错误码90010004及其对应的消息 + ERROR_90010005("账号被禁用,请联系管理员!"), // 错误码90010005及其对应的消息 + ERROR_90010006("活动用户不足,无法开启竞拍!"), // 错误码90010006及其对应的消息 + ERROR_90010007("旧密码不正确,请确认!"), // 错误码90010007及其对应的消息 - ERROR_60000001("数据不存在!"); + ERROR_60000001("数据不存在!"); // 错误码60000001及其对应的消息 - public String msg; + public String msg; // 定义错误消息字段 /** - * 生成Markdown格式文档,用于更新文档用的 - * @param args + * 生成Markdown格式文档,用于更新文档用的 // 方法注释,说明该方法的用途 + * @param args // 参数说明 */ - public static void main(String[] args) { - for (ApiError e : ApiError.values()) { - System.out.println("'"+e.name().replace("ERROR_", "")+"':'"+e.msg+"',"); + public static void main(String[] args) { // 主方法 + for (ApiError e : ApiError.values()) { // 遍历所有ApiError枚举值 + System.out.println("'"+e.name().replace("ERROR_", "")+"':'"+e.msg+"',"); // 输出错误码和消息 } } /** - * 获取错误码 - * @return + * 获取错误码 // 方法注释,说明该方法的用途 + * @return // 返回值说明 */ - public Integer getCode(){ - return Integer.parseInt(this.name().replace("ERROR_", "")); + public Integer getCode(){ // 获取错误码的方法 + return Integer.parseInt(this.name().replace("ERROR_", "")); // 返回去掉"ERROR_"前缀的整数值 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/ApiRest.java b/src-源文件/main/java/com/yf/exam/core/api/ApiRest.java index 4785bfb..c10b277 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/ApiRest.java +++ b/src-源文件/main/java/com/yf/exam/core/api/ApiRest.java @@ -1,64 +1,64 @@ -package com.yf.exam.core.api; +package com.yf.exam.core.api; // 定义包名 -import com.yf.exam.core.api.ApiError; -import com.yf.exam.core.exception.ServiceException; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.NoArgsConstructor; +import com.yf.exam.core.api.ApiError; // 导入ApiError类 +import com.yf.exam.core.exception.ServiceException; // 导入ServiceException类 +import io.swagger.annotations.ApiModel; // 导入ApiModel注解 +import io.swagger.annotations.ApiModelProperty; // 导入ApiModelProperty注解 +import lombok.Data; // 导入Data注解 +import lombok.NoArgsConstructor; // 导入NoArgsConstructor注解 /** * 数据结果返回的封装 * @author bool * @date 2018/11/20 09:48 */ -@Data -@NoArgsConstructor -@ApiModel(value="接口响应", description="接口响应") -public class ApiRest{ +@Data // 自动生成getter、setter、toString等方法 +@NoArgsConstructor // 自动生成无参构造函数 +@ApiModel(value="接口响应", description="接口响应") // Swagger注解,描述API模型 +public class ApiRest{ // 定义泛型类ApiRest /** * 响应消息 */ - @ApiModelProperty(value = "响应消息") - private String msg; + @ApiModelProperty(value = "响应消息") // Swagger注解,描述响应消息属性 + private String msg; // 响应消息 + /** * 响应代码 */ - @ApiModelProperty(value = "响应代码,0为成功,1为失败", required = true) - private Integer code; + @ApiModelProperty(value = "响应代码,0为成功,1为失败", required = true) // Swagger注解,描述响应代码属性 + private Integer code; // 响应代码 /** * 请求或响应body */ - @ApiModelProperty(value = "响应内容") - protected T data; - + @ApiModelProperty(value = "响应内容") // Swagger注解,描述响应内容属性 + protected T data; // 响应内容 /** * 是否成功 * @return */ - public boolean isSuccess(){ - return code.equals(0); + public boolean isSuccess(){ // 判断请求是否成功 + return code.equals(0); // 如果响应代码为0,返回true } /** * 构造函数 * @param error */ - public ApiRest(ServiceException error){ - this.code = error.getCode(); - this.msg = error.getMsg(); + public ApiRest(ServiceException error){ // 构造函数,接收ServiceException对象 + this.code = error.getCode(); // 设置响应代码 + this.msg = error.getMsg(); // 设置响应消息 } /** * 构造函数 * @param error */ - public ApiRest(ApiError error){ - this.code = error.getCode(); - this.msg = error.msg; + public ApiRest(ApiError error){ // 构造函数,接收ApiError对象 + this.code = error.getCode(); // 设置响应代码 + this.msg = error.msg; // 设置响应消息 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/controller/BaseController.java b/src-源文件/main/java/com/yf/exam/core/api/controller/BaseController.java index 22fcf09..66e9fb7 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/controller/BaseController.java +++ b/src-源文件/main/java/com/yf/exam/core/api/controller/BaseController.java @@ -1,154 +1,150 @@ package com.yf.exam.core.api.controller; - -import com.yf.exam.core.api.ApiError; -import com.yf.exam.core.api.ApiRest; -import com.yf.exam.core.exception.ServiceException; +// 导入所需的类 +import com.yf.exam.core.api.ApiError; // 导入ApiError类,用于处理API错误 +import com.yf.exam.core.api.ApiRest; // 导入ApiRest类,用于构建API响应 +import com.yf.exam.core.exception.ServiceException; // 导入ServiceException类,用于处理服务异常 /** * 基础控制器 + * 该类提供了一些通用的方法,用于构建API的成功和失败响应 * @author Dav */ public class BaseController { /** * 成功默认消息 + * CODE_SUCCESS用于表示成功的状态码 */ - private static final Integer CODE_SUCCESS = 0; - private static final String MSG_SUCCESS = "操作成功!"; + private static final Integer CODE_SUCCESS = 0; // 定义成功状态码 + private static final String MSG_SUCCESS = "操作成功!"; // 定义成功消息 /** * 失败默认消息 + * CODE_FAILURE用于表示失败的状态码 */ - private static final Integer CODE_FAILURE = 1; - private static final String MSG_FAILURE = "请求失败!"; + private static final Integer CODE_FAILURE = 1; // 定义失败状态码 + private static final String MSG_FAILURE = "请求失败!"; // 定义失败消息 /** * 完成消息构造 - * @param code - * @param message - * @param data - * @param - * @return + * @param code 状态码 + * @param message 消息内容 + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回构造好的API响应 */ protected ApiRest message(Integer code, String message, T data){ - ApiRest response = new ApiRest<>(); - response.setCode(code); - response.setMsg(message); - if(data!=null) { - response.setData(data); + ApiRest response = new ApiRest<>(); // 创建ApiRest对象 + response.setCode(code); // 设置状态码 + response.setMsg(message); // 设置消息内容 + if(data!=null) { // 如果数据不为空 + response.setData(data); // 设置响应数据 } - return response; + return response; // 返回构造好的响应 } /** * 请求成功空数据 - * @param - * @return + * @param 数据类型 + * @return ApiRest 返回成功的API响应,数据为空 */ protected ApiRest success(){ - return message(0, "请求成功!", null); + return message(0, "请求成功!", null); // 调用message方法构造成功响应 } - - /** * 请求成功,通用代码 - * @param message - * @param data - * @param - * @return + * @param message 消息内容 + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回成功的API响应 */ protected ApiRest success(String message, T data){ - return message(CODE_SUCCESS, message, data); + return message(CODE_SUCCESS, message, data); // 调用message方法构造成功响应 } - /** * 请求成功,仅内容 - * @param data - * @param - * @return + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回成功的API响应 */ protected ApiRest success(T data){ - return message(CODE_SUCCESS, MSG_SUCCESS, data); + return message(CODE_SUCCESS, MSG_SUCCESS, data); // 调用message方法构造成功响应 } - /** * 请求失败,完整构造 - * @param code - * @param message - * @param data - * @param - * @return + * @param code 状态码 + * @param message 消息内容 + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回失败的API响应 */ protected ApiRest failure(Integer code, String message, T data){ - return message(code, message, data); + return message(code, message, data); // 调用message方法构造失败响应 } /** * 请求失败,消息和内容 - * @param message - * @param data - * @param - * @return + * @param message 消息内容 + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回失败的API响应 */ protected ApiRest failure(String message, T data){ - return message(CODE_FAILURE, message, data); + return message(CODE_FAILURE, message, data); // 调用message方法构造失败响应 } /** * 请求失败,消息 - * @param message - * @return + * @param message 消息内容 + * @return ApiRest 返回失败的API响应,数据为空 */ protected ApiRest failure(String message){ - return message(CODE_FAILURE, message, null); + return message(CODE_FAILURE, message, null); // 调用message方法构造失败响应 } /** * 请求失败,仅内容 - * @param data - * @param - * @return + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回失败的API响应 */ protected ApiRest failure(T data){ - return message(CODE_FAILURE, MSG_FAILURE, data); + return message(CODE_FAILURE, MSG_FAILURE, data); // 调用message方法构造失败响应 } - /** * 请求失败,仅内容 - * @param - * @return + * @param 数据类型 + * @return ApiRest 返回失败的API响应,数据为空 */ protected ApiRest failure(){ - return message(CODE_FAILURE, MSG_FAILURE, null); + return message(CODE_FAILURE, MSG_FAILURE, null); // 调用message方法构造失败响应 } - - /** * 请求失败,仅内容 - * @param - * @return + * @param error ApiError对象,包含错误信息 + * @param data 响应数据 + * @param 数据类型 + * @return ApiRest 返回失败的API响应 */ protected ApiRest failure(ApiError error, T data){ - return message(error.getCode(), error.msg, data); + return message(error.getCode(), error.msg, data); // 调用message方法构造失败响应 } - - /** * 请求失败,仅内容 - * @param ex - * @param - * @return + * @param ex ServiceException对象,包含异常信息 + * @param 数据类型 + * @return ApiRest 返回失败的API响应 */ protected ApiRest failure(ServiceException ex){ - ApiRest apiRest = message(ex.getCode(), ex.getMsg(), null); - return apiRest; + ApiRest apiRest = message(ex.getCode(), ex.getMsg(), null); // 调用message方法构造失败响应 + return apiRest; // 返回构造好的响应 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseDTO.java index a2f6a3e..12ae864 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseDTO.java @@ -1,7 +1,10 @@ +// 包声明,定义该类所在的包 package com.yf.exam.core.api.dto; +// 导入lombok库中的@Data注解,用于自动生成getter、setter等方法 import lombok.Data; +// 导入Serializable接口,用于对象序列化 import java.io.Serializable; /** @@ -9,7 +12,11 @@ import java.io.Serializable; * @author dav * @date 2019/3/16 15:56 */ +// 使用@Data注解,自动生成该类的getter、setter等方法 @Data +// 定义一个名为BaseDTO的公共类,实现Serializable接口 public class BaseDTO implements Serializable { + // 该类目前没有任何字段或方法 } + diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdReqDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdReqDTO.java index 074fea3..ef95013 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdReqDTO.java @@ -1,28 +1,28 @@ -package com.yf.exam.core.api.dto; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/api/dto/BaseIdReqDTO.java +package com.yf.exam.core.api.dto; // 定义包名,表示该类属于哪个包 -import com.yf.exam.core.api.dto.BaseDTO; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import com.yf.exam.core.api.dto.BaseDTO; // 导入BaseDTO类,BaseIdReqDTO类将继承自它 +import com.fasterxml.jackson.annotation.JsonIgnore; // 导入JsonIgnore注解,用于在序列化时忽略某个字段 +import io.swagger.annotations.ApiModel; // 导入ApiModel注解,用于Swagger文档生成 +import io.swagger.annotations.ApiModelProperty; // 导入ApiModelProperty注解,用于Swagger文档生成 +import lombok.Data; // 导入Lombok的Data注解,用于自动生成getter、setter等方法 /** *

* 主键通用请求类,用于根据ID查询 *

* - * @author 聪明笨狗 - * @since 2019-04-20 12:15 + * @author 聪明笨狗 // 类的作者信息 + * @since 2019-04-20 12:15 // 类的创建时间 */ -@Data -@ApiModel(value="主键通用请求类", description="主键通用请求类") -public class BaseIdReqDTO extends BaseDTO { +@Data // 使用Lombok的Data注解,自动生成toString、equals、hashCode、getter和setter方法 +@ApiModel(value="主键通用请求类", description="主键通用请求类") // Swagger文档中显示的模型信息 +public class BaseIdReqDTO extends BaseDTO { // 定义BaseIdReqDTO类,继承自BaseDTO - @ApiModelProperty(value = "主键ID", required=true) - private String id; + @ApiModelProperty(value = "主键ID", required=true) // Swagger文档中显示的属性信息,表示该字段是必需的 + private String id; // 定义主键ID字段 - @JsonIgnore - private String userId; - -} + @JsonIgnore // 在序列化时忽略该字段,不会被JSON输出 + private String userId; // 定义用户ID字段,通常用于内部逻辑,不需要暴露给外部 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdRespDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdRespDTO.java index a9a59e2..761a2be 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdRespDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdRespDTO.java @@ -1,26 +1,28 @@ package com.yf.exam.core.api.dto; -import com.yf.exam.core.api.dto.BaseDTO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +// 导入所需的类 +import com.yf.exam.core.api.dto.BaseDTO; // 导入基础DTO类 +import io.swagger.annotations.ApiModel; // 导入Swagger注解,用于API文档生成 +import io.swagger.annotations.ApiModelProperty; // 导入Swagger注解,用于API文档生成 +import lombok.AllArgsConstructor; // 导入Lombok注解,用于生成全参构造函数 +import lombok.Data; // 导入Lombok注解,用于自动生成getter、setter等方法 +import lombok.NoArgsConstructor; // 导入Lombok注解,用于生成无参构造函数 /** *

* 主键通用响应类,用于添加后返回内容 + * 该类用于封装主键ID的响应数据,通常在添加操作后返回给客户端。 *

* * @author 聪明笨狗 * @since 2019-04-20 12:15 */ -@Data -@ApiModel(value="主键通用响应类", description="主键通用响应类") -@AllArgsConstructor -@NoArgsConstructor -public class BaseIdRespDTO extends BaseDTO { +@Data // 自动生成getter、setter、toString、equals和hashCode方法 +@ApiModel(value="主键通用响应类", description="主键通用响应类") // Swagger注解,描述该类的用途 +@AllArgsConstructor // 自动生成全参构造函数 +@NoArgsConstructor // 自动生成无参构造函数 +public class BaseIdRespDTO extends BaseDTO { // 继承自BaseDTO类 - @ApiModelProperty(value = "主键ID", required=true) - private String id; -} + @ApiModelProperty(value = "主键ID", required=true) // Swagger注解,描述id属性 + private String id; // 主键ID属性,必填 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdsReqDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdsReqDTO.java index df80c18..a2befd1 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdsReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseIdsReqDTO.java @@ -1,26 +1,26 @@ package com.yf.exam.core.api.dto; -import com.yf.exam.core.api.dto.BaseDTO; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import com.yf.exam.core.api.dto.BaseDTO; // 导入基础DTO类 +import com.fasterxml.jackson.annotation.JsonIgnore; // 导入JsonIgnore注解,用于序列化时忽略字段 +import io.swagger.annotations.ApiModel; // 导入ApiModel注解,用于Swagger文档生成 +import io.swagger.annotations.ApiModelProperty; // 导入ApiModelProperty注解,用于Swagger文档生成 +import lombok.Data; // 导入Lombok的Data注解,用于自动生成getter、setter等方法 -import java.util.List; +import java.util.List; // 导入List类,用于定义ID列表 /** * 通用ID列表类操作,用于批量删除、修改状态等 + * 该类用于封装要删除的ID列表和用户ID,便于在API中传递参数 * @author bool * @date 2019-08-01 19:07 */ -@Data -@ApiModel(value="删除参数", description="删除参数") -public class BaseIdsReqDTO extends BaseDTO { +@Data // Lombok注解,自动生成getter、setter、toString等方法 +@ApiModel(value="删除参数", description="删除参数") // Swagger注解,描述该类的用途 +public class BaseIdsReqDTO extends BaseDTO { // 继承自BaseDTO类 + @JsonIgnore // 在序列化时忽略该字段 + private String userId; // 用户ID,通常用于标识请求的用户 - @JsonIgnore - private String userId; - - @ApiModelProperty(value = "要删除的ID列表", required = true) - private List ids; -} + @ApiModelProperty(value = "要删除的ID列表", required = true) // Swagger注解,描述该字段 + private List ids; // 要删除的ID列表,必填项 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseStateReqDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseStateReqDTO.java index 15f26cb..4689bd8 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/BaseStateReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/BaseStateReqDTO.java @@ -1,32 +1,32 @@ -package com.yf.exam.core.api.dto; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/api/dto/BaseStateReqDTO.java +package com.yf.exam.core.api.dto; // 定义包名,表示该类属于com.yf.exam.core.api.dto包 -import com.yf.exam.core.api.dto.BaseDTO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import com.yf.exam.core.api.dto.BaseDTO; // 导入BaseDTO类,BaseStateReqDTO类将继承自它 +import io.swagger.annotations.ApiModel; // 导入ApiModel注解,用于Swagger文档生成 +import io.swagger.annotations.ApiModelProperty; // 导入ApiModelProperty注解,用于Swagger文档生成 +import lombok.AllArgsConstructor; // 导入Lombok库的AllArgsConstructor注解,自动生成全参构造函数 +import lombok.Data; // 导入Lombok库的Data注解,自动生成getter、setter、toString等方法 +import lombok.NoArgsConstructor; // 导入Lombok库的NoArgsConstructor注解,自动生成无参构造函数 -import java.util.List; +import java.util.List; // 导入List类,用于定义ID列表 /** *

* 通用状态请求类,用于修改状态什么的 *

* - * @author 聪明笨狗 - * @since 2019-04-20 12:15 + * @author 聪明笨狗 // 类的作者 + * @since 2019-04-20 12:15 // 类的创建时间 */ -@Data -@ApiModel(value="通用状态请求类", description="通用状态请求类") -@AllArgsConstructor -@NoArgsConstructor -public class BaseStateReqDTO extends BaseDTO { +@Data // 自动生成getter、setter、toString等方法 +@ApiModel(value="通用状态请求类", description="通用状态请求类") // Swagger文档中类的描述 +@AllArgsConstructor // 自动生成全参构造函数 +@NoArgsConstructor // 自动生成无参构造函数 +public class BaseStateReqDTO extends BaseDTO { // 定义BaseStateReqDTO类,继承自BaseDTO + @ApiModelProperty(value = "要修改对象的ID列表", required=true) // Swagger文档中属性的描述,表示该属性为必填项 + private List ids; // 定义一个ID列表,用于存储要修改对象的ID - @ApiModelProperty(value = "要修改对象的ID列表", required=true) - private List ids; - - @ApiModelProperty(value = "通用状态,0为正常,1为禁用", required=true) - private Integer state; -} + @ApiModelProperty(value = "通用状态,0为正常,1为禁用", required=true) // Swagger文档中属性的描述,表示该属性为必填项 + private Integer state; // 定义一个状态字段,0表示正常,1表示禁用 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/PagingReqDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/PagingReqDTO.java index 276a0e0..1f96377 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/PagingReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/PagingReqDTO.java @@ -1,47 +1,44 @@ -package com.yf.exam.core.api.dto; +package com.yf.exam.core.api.dto; // 定义包名 -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入MyBatis分页类 +import com.fasterxml.jackson.annotation.JsonIgnore; // 导入Jackson注解,用于忽略字段 +import io.swagger.annotations.ApiModel; // 导入Swagger注解,用于API文档 +import io.swagger.annotations.ApiModelProperty; // 导入Swagger注解,用于API文档属性 +import lombok.Data; // 导入Lombok注解,用于自动生成getter和setter /** * 分页查询类 - * @param + * @param 泛型类型 * @author bool */ -@ApiModel(value="分页参数", description="分页参数") -@Data -public class PagingReqDTO { +@ApiModel(value="分页参数", description="分页参数") // Swagger模型注解 +@Data // Lombok注解,自动生成getter、setter、toString等方法 +public class PagingReqDTO { // 定义分页请求DTO类,使用泛型T + @ApiModelProperty(value = "当前页码", required = true, example = "1") // Swagger属性注解 + private Integer current; // 当前页码 - @ApiModelProperty(value = "当前页码", required = true, example = "1") - private Integer current; + @ApiModelProperty(value = "每页数量", required = true, example = "10") // Swagger属性注解 + private Integer size; // 每页数量 - @ApiModelProperty(value = "每页数量", required = true, example = "10") - private Integer size; + @ApiModelProperty(value = "查询参数") // Swagger属性注解 + private T params; // 查询参数,类型为泛型T - @ApiModelProperty(value = "查询参数") - private T params; + @ApiModelProperty(value = "排序字符") // Swagger属性注解 + private String orderBy; // 排序字段 - @ApiModelProperty(value = "排序字符") - private String orderBy; - - @JsonIgnore - @ApiModelProperty(value = "当前用户的ID") - private String userId; + @JsonIgnore // Jackson注解,忽略该字段 + @ApiModelProperty(value = "当前用户的ID") // Swagger属性注解 + private String userId; // 当前用户的ID /** * 转换成MyBatis的简单分页对象 - * @return + * @return 返回MyBatis的Page对象 */ - public Page toPage(){ - Page page = new Page(); - page.setCurrent(this.current); - page.setSize(this.size); - return page; + public Page toPage(){ // 定义转换方法 + Page page = new Page(); // 创建Page对象 + page.setCurrent(this.current); // 设置当前页码 + page.setSize(this.size); // 设置每页数量 + return page; // 返回Page对象 } - - -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/dto/PagingRespDTO.java b/src-源文件/main/java/com/yf/exam/core/api/dto/PagingRespDTO.java index 3b2a8f7..c405a4a 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/dto/PagingRespDTO.java +++ b/src-源文件/main/java/com/yf/exam/core/api/dto/PagingRespDTO.java @@ -1,30 +1,30 @@ -package com.yf.exam.core.api.dto; +package com.yf.exam.core.api.dto; // 定义包名 -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入分页类 /** * 分页响应类 * @author bool * @date 2019-07-20 15:17 - * @param + * @param 泛型参数 */ -public class PagingRespDTO extends Page { +public class PagingRespDTO extends Page { // 定义分页响应类,继承自Page类 /** * 获取页面总数量 - * @return + * @return 返回页面总数量 */ @Override - public long getPages() { - if (this.getSize() == 0L) { - return 0L; - } else { - long pages = this.getTotal() / this.getSize(); - if (this.getTotal() % this.getSize() != 0L) { - ++pages; + public long getPages() { // 重写getPages方法 + if (this.getSize() == 0L) { // 如果每页大小为0 + return 0L; // 返回0 + } else { // 否则 + long pages = this.getTotal() / this.getSize(); // 计算总页数 + if (this.getTotal() % this.getSize() != 0L) { // 如果总数不能被每页大小整除 + ++pages; // 页数加1 } - return pages; + return pages; // 返回总页数 } } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/api/utils/JsonConverter.java b/src-源文件/main/java/com/yf/exam/core/api/utils/JsonConverter.java index f9e4622..122619a 100644 --- a/src-源文件/main/java/com/yf/exam/core/api/utils/JsonConverter.java +++ b/src-源文件/main/java/com/yf/exam/core/api/utils/JsonConverter.java @@ -1,48 +1,48 @@ -package com.yf.exam.core.api.utils; +package com.yf.exam.core.api.utils; // 定义包名 -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; +import com.alibaba.fastjson.serializer.SerializerFeature; // 导入FastJson序列化特性 +import com.alibaba.fastjson.support.config.FastJsonConfig; // 导入FastJson配置类 +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; // 导入FastJson消息转换器 +import org.springframework.http.MediaType; // 导入媒体类型类 +import org.springframework.http.converter.HttpMessageConverter; // 导入HTTP消息转换器接口 -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; +import java.nio.charset.Charset; // 导入字符集类 +import java.util.ArrayList; // 导入ArrayList类 +import java.util.List; // 导入List接口 /** * JSON数据转换器,用于转换返回消息的格式 * @author dav * @date 2018/9/11 19:30 */ -public class JsonConverter { +public class JsonConverter { // 定义JsonConverter类 /** * FastJson消息转换器 * - * @return + * @return 返回HttpMessageConverter对象 */ - public static HttpMessageConverter fastConverter() { + public static HttpMessageConverter fastConverter() { // 定义静态方法fastConverter // 定义一个convert转换消息的对象 - FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); + FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); // 创建FastJson消息转换器实例 // 添加FastJson的配置信息 - FastJsonConfig fastJsonConfig = new FastJsonConfig(); + FastJsonConfig fastJsonConfig = new FastJsonConfig(); // 创建FastJson配置实例 // 默认转换器 - fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, - SerializerFeature.WriteNullNumberAsZero, - SerializerFeature.MapSortField, - SerializerFeature.WriteNullStringAsEmpty, - SerializerFeature.DisableCircularReferenceDetect, - SerializerFeature.WriteDateUseDateFormat, - SerializerFeature.WriteNullListAsEmpty); - fastJsonConfig.setCharset(Charset.forName("UTF-8")); + fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, // 设置序列化特性:格式化输出 + SerializerFeature.WriteNullNumberAsZero, // 将null数字写为0 + SerializerFeature.MapSortField, // 对Map进行排序 + SerializerFeature.WriteNullStringAsEmpty, // 将null字符串写为空 + SerializerFeature.DisableCircularReferenceDetect, // 禁用循环引用检测 + SerializerFeature.WriteDateUseDateFormat, // 使用日期格式化 + SerializerFeature.WriteNullListAsEmpty); // 将null列表写为空列表 + fastJsonConfig.setCharset(Charset.forName("UTF-8")); // 设置字符集为UTF-8 // 处理中文乱码问题 - List fastMediaTypes = new ArrayList<>(); - fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); - fastConverter.setSupportedMediaTypes(fastMediaTypes); + List fastMediaTypes = new ArrayList<>(); // 创建媒体类型列表 + fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); // 添加支持的媒体类型:UTF-8 JSON + fastConverter.setSupportedMediaTypes(fastMediaTypes); // 设置支持的媒体类型 // 在convert中添加配置信息 - fastConverter.setFastJsonConfig(fastJsonConfig); + fastConverter.setFastJsonConfig(fastJsonConfig); // 设置FastJson配置 - return fastConverter; - } -} + return fastConverter; // 返回FastJson消息转换器 + } // 结束fastConverter方法 +} // 结束JsonConverter类 \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/enums/CommonState.java b/src-源文件/main/java/com/yf/exam/core/enums/CommonState.java index 21ef637..56fa93d 100644 --- a/src-源文件/main/java/com/yf/exam/core/enums/CommonState.java +++ b/src-源文件/main/java/com/yf/exam/core/enums/CommonState.java @@ -1,19 +1,21 @@ -package com.yf.exam.core.enums; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/enums/CommonState.java +package com.yf.exam.core.enums; // 定义包名 /** * 通用的状态枚举信息 * - * @author bool - * @date 2019-09-17 17:57 + * @author bool // 作者信息 + * @date 2019-09-17 17:57 // 日期信息 */ -public interface CommonState { +public interface CommonState { // 定义一个公共接口 /** * 普通状态,正常的 */ - Integer NORMAL = 0; + Integer NORMAL = 0; // 定义正常状态的常量,值为0 + /** * 非正常状态,禁用,下架等 */ - Integer ABNORMAL = 1; -} + Integer ABNORMAL = 1; // 定义非正常状态的常量,值为1 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/enums/OpenType.java b/src-源文件/main/java/com/yf/exam/core/enums/OpenType.java index 0012db5..f1b4495 100644 --- a/src-源文件/main/java/com/yf/exam/core/enums/OpenType.java +++ b/src-源文件/main/java/com/yf/exam/core/enums/OpenType.java @@ -1,18 +1,19 @@ -package com.yf.exam.core.enums; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/enums/OpenType.java +package com.yf.exam.core.enums; // 定义包名 /** * 开放方式 * @author bool */ -public interface OpenType { +public interface OpenType { // 定义接口 OpenType /** * 完全开放 */ - Integer OPEN = 1; + Integer OPEN = 1; // 定义常量 OPEN,值为 1 /** * 部门开放 */ - Integer DEPT_OPEN = 2; -} + Integer DEPT_OPEN = 2; // 定义常量 DEPT_OPEN,值为 2 +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/exception/ServiceException.java b/src-源文件/main/java/com/yf/exam/core/exception/ServiceException.java index 2d474c1..a87d044 100644 --- a/src-源文件/main/java/com/yf/exam/core/exception/ServiceException.java +++ b/src-源文件/main/java/com/yf/exam/core/exception/ServiceException.java @@ -1,51 +1,52 @@ -package com.yf.exam.core.exception; +// 文件路径: yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/exception/ServiceException.java +package com.yf.exam.core.exception; // 定义包名 -import com.yf.exam.core.api.ApiError; -import com.yf.exam.core.api.ApiRest; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import com.yf.exam.core.api.ApiError; // 导入ApiError类 +import com.yf.exam.core.api.ApiRest; // 导入ApiRest类 +import lombok.AllArgsConstructor; // 导入AllArgsConstructor注解 +import lombok.Data; // 导入Data注解 +import lombok.NoArgsConstructor; // 导入NoArgsConstructor注解 -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ServiceException extends RuntimeException{ +@Data // 自动生成getter、setter、toString等方法 +@AllArgsConstructor // 生成包含所有字段的构造函数 +@NoArgsConstructor // 生成无参构造函数 +public class ServiceException extends RuntimeException{ // 定义ServiceException类,继承RuntimeException /** * 错误码 */ - private Integer code; + private Integer code; // 定义错误码字段 /** * 错误消息 */ - private String msg; + private String msg; // 定义错误消息字段 /** * 从结果初始化 * @param apiRest */ - public ServiceException(ApiRest apiRest){ - this.code = apiRest.getCode(); - this.msg = apiRest.getMsg(); + public ServiceException(ApiRest apiRest){ // 构造函数,接受ApiRest对象 + this.code = apiRest.getCode(); // 初始化错误码 + this.msg = apiRest.getMsg(); // 初始化错误消息 } /** * 从枚举中获取参数 * @param apiError */ - public ServiceException(ApiError apiError){ - this.code = apiError.getCode(); - this.msg = apiError.msg; + public ServiceException(ApiError apiError){ // 构造函数,接受ApiError对象 + this.code = apiError.getCode(); // 初始化错误码 + this.msg = apiError.msg; // 初始化错误消息 } /** * 异常构造 * @param msg */ - public ServiceException(String msg){ - this.code = 1; - this.msg = msg; + public ServiceException(String msg){ // 构造函数,接受错误消息 + this.code = 1; // 默认错误码为1 + this.msg = msg; // 初始化错误消息 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/exception/ServiceExceptionHandler.java b/src-源文件/main/java/com/yf/exam/core/exception/ServiceExceptionHandler.java index 1c8de5d..0e4954d 100644 --- a/src-源文件/main/java/com/yf/exam/core/exception/ServiceExceptionHandler.java +++ b/src-源文件/main/java/com/yf/exam/core/exception/ServiceExceptionHandler.java @@ -1,46 +1,46 @@ -package com.yf.exam.core.exception; +package com.yf.exam.core.exception; // 定义包名 -import com.yf.exam.core.api.ApiRest; -import org.springframework.http.HttpStatus; -import org.springframework.ui.Model; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.*; +import com.yf.exam.core.api.ApiRest; // 导入ApiRest类 +import org.springframework.http.HttpStatus; // 导入HttpStatus类 +import org.springframework.ui.Model; // 导入Model类 +import org.springframework.web.bind.WebDataBinder; // 导入WebDataBinder类 +import org.springframework.web.bind.annotation.*; // 导入所有注解 /** * 统一异常处理类 * @author bool * @date 2019-06-21 19:27 */ -@RestControllerAdvice -public class ServiceExceptionHandler { +@RestControllerAdvice // 声明这是一个全局异常处理类 +public class ServiceExceptionHandler { // 定义ServiceExceptionHandler类 /** * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器 - * @param binder + * @param binder 数据绑定器 */ - @InitBinder - public void initWebBinder(WebDataBinder binder){ - + @InitBinder // 初始化数据绑定器 + public void initWebBinder(WebDataBinder binder){ // 定义初始化方法 + // 这里可以添加自定义的初始化逻辑 } /** * 把值绑定到Model中,使全局@RequestMapping可以获取到该值 - * @param model + * @param model 模型对象 */ - @ModelAttribute - public void addAttribute(Model model) { - + @ModelAttribute // 将方法的返回值绑定到模型中 + public void addAttribute(Model model) { // 定义添加属性的方法 + // 这里可以添加需要绑定到模型的属性 } /** * 捕获ServiceException - * @param e - * @return + * @param e 捕获的异常 + * @return ApiRest 返回的API响应 */ - @ExceptionHandler({com.yf.exam.core.exception.ServiceException.class}) - @ResponseStatus(HttpStatus.OK) - public ApiRest serviceExceptionHandler(ServiceException e) { - return new ApiRest(e); + @ExceptionHandler({com.yf.exam.core.exception.ServiceException.class}) // 指定捕获的异常类型 + @ResponseStatus(HttpStatus.OK) // 设置响应状态为200 OK + public ApiRest serviceExceptionHandler(ServiceException e) { // 定义异常处理方法 + return new ApiRest(e); // 返回ApiRest对象,包含异常信息 } } \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/BeanMapper.java b/src-源文件/main/java/com/yf/exam/core/utils/BeanMapper.java index 8ee5ca4..c1e5da2 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/BeanMapper.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/BeanMapper.java @@ -1,13 +1,12 @@ -package com.yf.exam.core.utils; +package com.yf.exam.core.utils; // 定义包名 -import org.dozer.DozerBeanMapper; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; +import org.dozer.DozerBeanMapper; // 导入DozerBeanMapper类 +import java.util.ArrayList; // 导入ArrayList类 +import java.util.Collection; // 导入Collection接口 +import java.util.List; // 导入List接口 +import java.util.function.Function; // 导入Function接口 +import java.util.stream.Collectors; // 导入Collectors类 /** * 简单封装Dozer, 实现深度转换Bean<->Bean的Mapper.实现: @@ -18,42 +17,42 @@ import java.util.stream.Collectors; * 4. 区分创建新的B对象与将对象A值复制到已存在的B对象两种函数. * */ -public class BeanMapper { +public class BeanMapper { // 定义BeanMapper类 /** * 持有Dozer单例, 避免重复创建DozerMapper消耗资源. */ - private static DozerBeanMapper dozerBeanMapper = new DozerBeanMapper(); + private static DozerBeanMapper dozerBeanMapper = new DozerBeanMapper(); // 创建DozerBeanMapper的单例 /** * 基于Dozer转换对象的类型. */ - public static T map(Object source, Class destinationClass) { - return dozerBeanMapper.map(source, destinationClass); + public static T map(Object source, Class destinationClass) { // 定义map方法,转换对象类型 + return dozerBeanMapper.map(source, destinationClass); // 使用Dozer进行对象转换 } /** * 基于Dozer转换Collection中对象的类型. */ - public static List mapList(Iterable sourceList, Class destinationClass) { - List destinationList = new ArrayList(); - for (Object sourceObject : sourceList) { - T destinationObject = dozerBeanMapper.map(sourceObject, destinationClass); - destinationList.add(destinationObject); + public static List mapList(Iterable sourceList, Class destinationClass) { // 定义mapList方法,转换集合中的对象 + List destinationList = new ArrayList(); // 创建目标列表 + for (Object sourceObject : sourceList) { // 遍历源列表中的每个对象 + T destinationObject = dozerBeanMapper.map(sourceObject, destinationClass); // 转换对象 + destinationList.add(destinationObject); // 将转换后的对象添加到目标列表 } - return destinationList; + return destinationList; // 返回目标列表 } /** * 基于Dozer将对象A的值拷贝到对象B中. */ - public static void copy(Object source, Object destinationObject) { - if(source!=null) { - dozerBeanMapper.map(source, destinationObject); + public static void copy(Object source, Object destinationObject) { // 定义copy方法,拷贝对象A的值到对象B + if(source!=null) { // 检查源对象是否为null + dozerBeanMapper.map(source, destinationObject); // 使用Dozer进行值拷贝 } } - public static List mapList(Collection source, Function mapper) { - return source.stream().map(mapper).collect(Collectors.toList()); + public static List mapList(Collection source, Function mapper) { // 定义重载的mapList方法,使用自定义映射函数 + return source.stream().map(mapper).collect(Collectors.toList()); // 使用流和映射函数转换集合并返回列表 } } \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/CronUtils.java b/src-源文件/main/java/com/yf/exam/core/utils/CronUtils.java index c019b3e..9e770d1 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/CronUtils.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/CronUtils.java @@ -1,31 +1,32 @@ -package com.yf.exam.core.utils; +language:yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/utils/CronUtils.java +package com.yf.exam.core.utils; // 包声明,定义了类的包路径 -import java.text.SimpleDateFormat; -import java.util.Date; +import java.text.SimpleDateFormat; // 导入用于格式化日期的类 +import java.util.Date; // 导入日期类 /** * 时间转换quartz表达式 - * @author bool - * @date 2020/11/29 下午3:00 + * @author bool // 作者信息 + * @date 2020/11/29 下午3:00 // 日期信息 */ -public class CronUtils { +public class CronUtils { // 定义CronUtils类 /** * 格式化数据 */ - private static final String DATE_FORMAT = "ss mm HH dd MM ? yyyy"; + private static final String DATE_FORMAT = "ss mm HH dd MM ? yyyy"; // 定义日期格式的常量 /** * 准确的时间点到表达式 - * @param date - * @return + * @param date // 输入的日期 + * @return // 返回格式化后的cron表达式 */ - public static String dateToCron(final Date date){ - SimpleDateFormat fmt = new SimpleDateFormat(DATE_FORMAT); - String formatTimeStr = ""; - if (date != null) { - formatTimeStr = fmt.format(date); + public static String dateToCron(final Date date){ // 定义静态方法,将日期转换为cron表达式 + SimpleDateFormat fmt = new SimpleDateFormat(DATE_FORMAT); // 创建SimpleDateFormat对象 + String formatTimeStr = ""; // 初始化格式化后的时间字符串 + if (date != null) { // 检查日期是否为null + formatTimeStr = fmt.format(date); // 格式化日期 } - return formatTimeStr; + return formatTimeStr; // 返回格式化后的字符串 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/DateUtils.java b/src-源文件/main/java/com/yf/exam/core/utils/DateUtils.java index 4121ef5..6932d2f 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/DateUtils.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/DateUtils.java @@ -1,9 +1,9 @@ -package com.yf.exam.core.utils; +package com.yf.exam.core.utils; // 包声明,定义该类所在的包 -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; +import java.text.SimpleDateFormat; // 导入用于日期格式化的类 +import java.util.Calendar; // 导入日历类 +import java.util.Date; // 导入日期类 +import java.util.GregorianCalendar; // 导入公历日历类 /** * 日期处理工具类 @@ -13,27 +13,27 @@ import java.util.GregorianCalendar; * @author Bool * @version */ -public class DateUtils { +public class DateUtils { // 定义DateUtils类 /** * * calcExpDays:计算某个日期与当前日期相差的天数,如果计算的日期大于现在时间,将返回负数;否则返回正数
* @author Bool - * @param userCreateTime - * @return + * @param userCreateTime 用户创建时间 + * @return 相差的天数 * @since JDK 1.6 */ - public static int calcExpDays(Date userCreateTime){ + public static int calcExpDays(Date userCreateTime){ // 计算日期差异的方法 - Calendar start = Calendar.getInstance(); - start.setTime(userCreateTime); + Calendar start = Calendar.getInstance(); // 获取当前日历实例 + start.setTime(userCreateTime); // 设置开始时间为用户创建时间 - Calendar now = Calendar.getInstance(); - now.setTime(new Date()); + Calendar now = Calendar.getInstance(); // 获取当前日历实例 + now.setTime(new Date()); // 设置当前时间 - long l = now.getTimeInMillis() - start.getTimeInMillis(); - int days = new Long(l / (1000 * 60 * 60 * 24)).intValue(); - return days; + long l = now.getTimeInMillis() - start.getTimeInMillis(); // 计算时间差(毫秒) + int days = new Long(l / (1000 * 60 * 60 * 24)).intValue(); // 将毫秒转换为天数 + return days; // 返回天数 } @@ -42,36 +42,34 @@ public class DateUtils { * dateNow:获取当前时间的字符串格式,根据传入的格式化来展示.
* @author Bool * @param format 日期格式化 - * @return + * @return 当前时间的字符串 */ - public static String dateNow(String format) { - SimpleDateFormat fmt = new SimpleDateFormat(format); - Calendar c = new GregorianCalendar(); - return fmt.format(c.getTime()); + public static String dateNow(String format) { // 获取当前时间字符串的方法 + SimpleDateFormat fmt = new SimpleDateFormat(format); // 创建日期格式化对象 + Calendar c = new GregorianCalendar(); // 获取公历日历实例 + return fmt.format(c.getTime()); // 返回格式化后的当前时间字符串 } /** * formatDate:格式化日期,返回指定的格式
* @author Bool - * @param time - * @param format - * @return + * @param time 日期对象 + * @param format 日期格式 + * @return 格式化后的日期字符串 */ - public static String formatDate(Date time, String format) { - SimpleDateFormat fmt = new SimpleDateFormat(format); - return fmt.format(time.getTime()); + public static String formatDate(Date time, String format) { // 格式化日期的方法 + SimpleDateFormat fmt = new SimpleDateFormat(format); // 创建日期格式化对象 + return fmt.format(time.getTime()); // 返回格式化后的日期字符串 } - - /** * parseDate:将字符串转换成日期,使用:yyyy-MM-dd HH:mm:ss 来格式化 * @author Bool - * @param date - * @return + * @param date 日期字符串 + * @return 转换后的日期对象 */ - public static Date parseDate(String date) { - return parseDate(date, "yyyy-MM-dd HH:mm:ss"); + public static Date parseDate(String date) { // 将字符串解析为日期的方法 + return parseDate(date, "yyyy-MM-dd HH:mm:ss"); // 使用默认格式解析 } @@ -79,25 +77,23 @@ public class DateUtils { * * parseDate:将字符串转换成日期,使用指定格式化来格式化 * @author Bool - * @param date - * @param pattern - * @return + * @param date 日期字符串 + * @param pattern 日期格式 + * @return 转换后的日期对象 */ - public static Date parseDate(String date, String pattern) { + public static Date parseDate(String date, String pattern) { // 使用指定格式解析字符串为日期 - if (pattern==null) { - pattern = "yyyy-MM-dd HH:mm:ss"; + if (pattern==null) { // 如果未指定格式 + pattern = "yyyy-MM-dd HH:mm:ss"; // 使用默认格式 } - SimpleDateFormat fmt = new SimpleDateFormat(pattern); + SimpleDateFormat fmt = new SimpleDateFormat(pattern); // 创建日期格式化对象 try { - - return fmt.parse(date); - } catch (Exception ex) { - ex.printStackTrace(); + return fmt.parse(date); // 尝试解析日期字符串 + } catch (Exception ex) { // 捕获异常 + ex.printStackTrace(); // 打印异常堆栈 } - return null; - + return null; // 返回null表示解析失败 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/IpUtils.java b/src-源文件/main/java/com/yf/exam/core/utils/IpUtils.java index 91277d7..e88b23f 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/IpUtils.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/IpUtils.java @@ -1,7 +1,6 @@ -package com.yf.exam.core.utils; +package com.yf.exam.core.utils; // 定义包名 - -import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequest; // 导入HttpServletRequest类 /** * IP获取工具类,用户获取网络请求过来的真实IP @@ -11,55 +10,52 @@ import javax.servlet.http.HttpServletRequest; * @author Bool * @version */ -public class IpUtils { +public class IpUtils { // 定义IpUtils类 - /** * * getClientIp:通过请求获取客户端的真实IP地址 * @author Bool - * @param request - * @return + * @param request HttpServletRequest对象 + * @return 返回客户端的真实IP地址 */ - public static String extractClientIp(HttpServletRequest request) { + public static String extractClientIp(HttpServletRequest request) { // 定义静态方法extractClientIp,接收HttpServletRequest参数 - String ip = null; + String ip = null; // 初始化ip变量为null //X-Forwarded-For:Squid 服务代理 - String ipAddresses = request.getHeader("X-Forwarded-For"); + String ipAddresses = request.getHeader("X-Forwarded-For"); // 获取请求头中的X-Forwarded-For字段 - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { + if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { // 检查ipAddresses是否为空或未知 //Proxy-Client-IP:apache 服务代理 - ipAddresses = request.getHeader("Proxy-Client-IP"); + ipAddresses = request.getHeader("Proxy-Client-IP"); // 获取Proxy-Client-IP字段 } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { + if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { // 检查ipAddresses是否为空或未知 //WL-Proxy-Client-IP:weblogic 服务代理 - ipAddresses = request.getHeader("WL-Proxy-Client-IP"); + ipAddresses = request.getHeader("WL-Proxy-Client-IP"); // 获取WL-Proxy-Client-IP字段 } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { + if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { // 检查ipAddresses是否为空或未知 //HTTP_CLIENT_IP:有些代理服务器 - ipAddresses = request.getHeader("HTTP_CLIENT_IP"); + ipAddresses = request.getHeader("HTTP_CLIENT_IP"); // 获取HTTP_CLIENT_IP字段 } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { + if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { // 检查ipAddresses是否为空或未知 //X-Real-IP:nginx服务代理 - ipAddresses = request.getHeader("X-Real-IP"); + ipAddresses = request.getHeader("X-Real-IP"); // 获取X-Real-IP字段 } //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP - if (ipAddresses != null && ipAddresses.length() != 0) { - ip = ipAddresses.split(",")[0]; + if (ipAddresses != null && ipAddresses.length() != 0) { // 检查ipAddresses是否不为空 + ip = ipAddresses.split(",")[0]; // 通过逗号分割并获取第一个IP地址 } //还是不能获取到,最后再通过request.getRemoteAddr();获取 - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { - ip = request.getRemoteAddr(); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { // 检查ip是否为空或未知 + ip = request.getRemoteAddr(); // 最后通过getRemoteAddr获取IP地址 } - return ip; + return ip; // 返回获取到的IP地址 } - - -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/Reflections.java b/src-源文件/main/java/com/yf/exam/core/utils/Reflections.java index 4d50bf2..a735b46 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/Reflections.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/Reflections.java @@ -1,22 +1,22 @@ /** * Copyright (c) 2005-2012 springside.org.cn */ -package com.yf.exam.core.utils; - -import lombok.extern.log4j.Log4j2; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; -import org.springframework.util.Assert; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +package com.yf.exam.core.utils; // 定义包名 + +import lombok.extern.log4j.Log4j2; // 引入Log4j2日志库 +import org.apache.commons.lang3.StringUtils; // 引入Apache Commons Lang的StringUtils类 +import org.apache.commons.lang3.Validate; // 引入Apache Commons Lang的Validate类 +import org.springframework.util.Assert; // 引入Spring的Assert类 + +import java.lang.reflect.Field; // 引入反射中的Field类 +import java.lang.reflect.InvocationTargetException; // 引入反射中的InvocationTargetException类 +import java.lang.reflect.Method; // 引入反射中的Method类 +import java.lang.reflect.Modifier; // 引入反射中的Modifier类 +import java.lang.reflect.ParameterizedType; // 引入反射中的ParameterizedType类 +import java.lang.reflect.Type; // 引入反射中的Type类 +import java.util.ArrayList; // 引入ArrayList类 +import java.util.Arrays; // 引入Arrays类 +import java.util.List; // 引入List接口 /** * 反射工具类. @@ -24,32 +24,32 @@ import java.util.List; * @author calvin * @version 2016-01-15 */ -@Log4j2 -public class Reflections { +@Log4j2 // 使用Log4j2注解 +public class Reflections { // 定义Reflections类 - private static final String SETTER_PREFIX = "set"; + private static final String SETTER_PREFIX = "set"; // 定义setter方法前缀 - private static final String GETTER_PREFIX = "get"; + private static final String GETTER_PREFIX = "get"; // 定义getter方法前缀 - private static final String CGLIB_CLASS_SEPARATOR = "$$"; + private static final String CGLIB_CLASS_SEPARATOR = "$$"; // 定义CGLIB类分隔符 /** * 获取类的所有属性,包括父类 * - * @param object - * @return + * @param object 目标对象 + * @return 所有属性的数组 */ - public static Field[] getAllFields(Object object) { - Class clazz = object.getClass(); - List fieldList = new ArrayList<>(); - while (clazz != null) { - fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); - clazz = clazz.getSuperclass(); + public static Field[] getAllFields(Object object) { // 定义获取所有字段的方法 + Class clazz = object.getClass(); // 获取对象的类 + List fieldList = new ArrayList<>(); // 创建字段列表 + while (clazz != null) { // 循环直到没有父类 + fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); // 添加当前类的字段 + clazz = clazz.getSuperclass(); // 获取父类 } - Field[] fields = new Field[fieldList.size()]; - fieldList.toArray(fields); - return fields; + Field[] fields = new Field[fieldList.size()]; // 创建字段数组 + fieldList.toArray(fields); // 将列表转换为数组 + return fields; // 返回字段数组 } @@ -57,29 +57,29 @@ public class Reflections { * 调用Getter方法. * 支持多级,如:对象名.对象名.方法 */ - public static Object invokeGetter(Object obj, String propertyName) { - Object object = obj; - for (String name : StringUtils.split(propertyName, ".")){ - String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); - object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + public static Object invokeGetter(Object obj, String propertyName) { // 定义调用getter方法 + Object object = obj; // 初始化对象 + for (String name : StringUtils.split(propertyName, ".")){ // 分割属性名 + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); // 生成getter方法名 + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); // 调用getter方法 } - return object; + return object; // 返回结果 } /** * 调用Setter方法, 仅匹配方法名。 * 支持多级,如:对象名.对象名.方法 */ - public static void invokeSetter(Object obj, String propertyName, Object value) { - Object object = obj; - String[] names = StringUtils.split(propertyName, "."); - for (int i=0; i[] parameterTypes, - final Object[] args) { - Method method = getAccessibleMethod(obj, methodName, parameterTypes); - if (method == null) { - throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + final Object[] args) { // 定义调用方法的方法 + Method method = getAccessibleMethod(obj, methodName, parameterTypes); // 获取可访问的方法 + if (method == null) { // 如果方法不存在 + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); // 抛出异常 } try { - return method.invoke(obj, args); - } catch (Exception e) { - throw convertReflectionExceptionToUnchecked(e); + return method.invoke(obj, args); // 调用方法并返回结果 + } catch (Exception e) { // 捕获异常 + throw convertReflectionExceptionToUnchecked(e); // 转换异常 } } @@ -144,16 +144,16 @@ public class Reflections { * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. * 只匹配函数名,如果有多个同名函数调用第一个。 */ - public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { - Method method = getAccessibleMethodByName(obj, methodName); - if (method == null) { - throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); + public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { // 定义通过方法名调用方法 + Method method = getAccessibleMethodByName(obj, methodName); // 获取可访问的方法 + if (method == null) { // 如果方法不存在 + throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); // 抛出异常 } try { - return method.invoke(obj, args); - } catch (Exception e) { - throw convertReflectionExceptionToUnchecked(e); + return method.invoke(obj, args); // 调用方法并返回结果 + } catch (Exception e) { // 捕获异常 + throw convertReflectionExceptionToUnchecked(e); // 转换异常 } } @@ -162,20 +162,20 @@ public class Reflections { * * 如向上转型到Object仍无法找到, 返回null. */ - public static Field getAccessibleField(final Object obj, final String fieldName) { - Validate.notNull(obj, "object can't be null"); - Validate.notBlank(fieldName, "fieldName can't be blank"); - for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { + public static Field getAccessibleField(final Object obj, final String fieldName) { // 定义获取可访问字段的方法 + Validate.notNull(obj, "object can't be null"); // 验证对象不为空 + Validate.notBlank(fieldName, "fieldName can't be blank"); // 验证字段名不为空 + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { // 循环向上转型 try { - Field field = superClass.getDeclaredField(fieldName); - makeAccessible(field); - return field; - } catch (NoSuchFieldException e) {//NOSONAR + Field field = superClass.getDeclaredField(fieldName); // 获取声明的字段 + makeAccessible(field); // 设置字段为可访问 + return field; // 返回字段 + } catch (NoSuchFieldException e) { // 捕获没有该字段的异常 // Field不在当前类定义,继续向上转型 - continue;// new add + continue; // 继续循环 } } - return null; + return null; // 返回null } /** @@ -186,21 +186,21 @@ public class Reflections { * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) */ public static Method getAccessibleMethod(final Object obj, final String methodName, - final Class... parameterTypes) { - Validate.notNull(obj, "object can't be null"); - Validate.notBlank(methodName, "methodName can't be blank"); + final Class... parameterTypes) { // 定义获取可访问方法的方法 + Validate.notNull(obj, "object can't be null"); // 验证对象不为空 + Validate.notBlank(methodName, "methodName can't be blank"); // 验证方法名不为空 - for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { // 循环向上转型 try { - Method method = searchType.getDeclaredMethod(methodName, parameterTypes); - makeAccessible(method); - return method; - } catch (NoSuchMethodException e) { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); // 获取声明的方法 + makeAccessible(method); // 设置方法为可访问 + return method; // 返回方法 + } catch (NoSuchMethodException e) { // 捕获没有该方法的异常 // Method不在当前类定义,继续向上转型 - continue;// new add + continue; // 继续循环 } } - return null; + return null; // 返回null } /** @@ -210,39 +210,39 @@ public class Reflections { * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) */ - public static Method getAccessibleMethodByName(final Object obj, final String methodName) { - Validate.notNull(obj, "object can't be null"); - Validate.notBlank(methodName, "methodName can't be blank"); - - for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { - Method[] methods = searchType.getDeclaredMethods(); - for (Method method : methods) { - if (method.getName().equals(methodName)) { - makeAccessible(method); - return method; + public static Method getAccessibleMethodByName(final Object obj, final String methodName) { // 定义通过方法名获取可访问方法的方法 + Validate.notNull(obj, "object can't be null"); // 验证对象不为空 + Validate.notBlank(methodName, "methodName can't be blank"); // 验证方法名不为空 + + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { // 循环向上转型 + Method[] methods = searchType.getDeclaredMethods(); // 获取声明的方法数组 + for (Method method : methods) { // 遍历方法 + if (method.getName().equals(methodName)) { // 如果方法名匹配 + makeAccessible(method); // 设置方法为可访问 + return method; // 返回方法 } } } - return null; + return null; // 返回null } /** * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ - public static void makeAccessible(Method method) { - if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) - && !method.isAccessible()) { - method.setAccessible(true); + public static void makeAccessible(Method method) { // 定义设置方法为可访问的方法 + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) // 如果方法或类不是public + && !method.isAccessible()) { // 且方法不可访问 + method.setAccessible(true); // 设置为可访问 } } /** * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ - public static void makeAccessible(Field field) { - if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier - .isFinal(field.getModifiers())) && !field.isAccessible()) { - field.setAccessible(true); + public static void makeAccessible(Field field) { // 定义设置字段为可访问的方法 + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier // 如果字段或类不是public或字段是final + .isFinal(field.getModifiers())) && !field.isAccessible()) { // 且字段不可访问 + field.setAccessible(true); // 设置为可访问 } } @@ -256,8 +256,8 @@ public class Reflections { * @return the first generic declaration, or Object.class if cannot be determined */ @SuppressWarnings("unchecked") - public static Class getClassGenricType(final Class clazz) { - return getClassGenricType(clazz, 0); + public static Class getClassGenricType(final Class clazz) { // 定义获取类的泛型类型的方法 + return getClassGenricType(clazz, 0); // 调用重载方法 } /** @@ -270,55 +270,54 @@ public class Reflections { * @param index the Index of the generic ddeclaration,start from 0. * @return the index generic declaration, or Object.class if cannot be determined */ - public static Class getClassGenricType(final Class clazz, final int index) { + public static Class getClassGenricType(final Class clazz, final int index) { // 定义获取类的泛型类型的方法 + Type genType = clazz.getGenericSuperclass(); // 获取类的泛型超类 - Type genType = clazz.getGenericSuperclass(); - - if (!(genType instanceof ParameterizedType)) { - log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); - return Object.class; + if (!(genType instanceof ParameterizedType)) { // 如果不是参数化类型 + log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); // 记录警告 + return Object.class; // 返回Object.class } - Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); // 获取实际类型参数 - if (index >= params.length || index < 0) { + if (index >= params.length || index < 0) { // 如果索引超出范围 log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " - + params.length); - return Object.class; + + params.length); // 记录警告 + return Object.class; // 返回Object.class } - if (!(params[index] instanceof Class)) { - log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); - return Object.class; + if (!(params[index] instanceof Class)) { // 如果参数不是Class类型 + log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); // 记录警告 + return Object.class; // 返回Object.class } - return (Class) params[index]; + return (Class) params[index]; // 返回指定索引的Class类型 } - public static Class getUserClass(Object instance) { - Assert.notNull(instance, "Instance must not be null"); - Class clazz = instance.getClass(); - if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { - Class superClass = clazz.getSuperclass(); - if (superClass != null && !Object.class.equals(superClass)) { - return superClass; + public static Class getUserClass(Object instance) { // 定义获取用户类的方法 + Assert.notNull(instance, "Instance must not be null"); // 验证实例不为空 + Class clazz = instance.getClass(); // 获取实例的类 + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { // 如果类名包含CGLIB分隔符 + Class superClass = clazz.getSuperclass(); // 获取父类 + if (superClass != null && !Object.class.equals(superClass)) { // 如果父类存在且不是Object + return superClass; // 返回父类 } } - return clazz; + return clazz; // 返回当前类 } /** * 将反射时的checked exception转换为unchecked exception. */ - public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { - if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException - || e instanceof NoSuchMethodException) { - return new IllegalArgumentException(e); - } else if (e instanceof InvocationTargetException) { - return new RuntimeException(((InvocationTargetException) e).getTargetException()); - } else if (e instanceof RuntimeException) { - return (RuntimeException) e; + public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { // 定义转换异常的方法 + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException // 如果是非法访问或参数异常 + || e instanceof NoSuchMethodException) { // 或者没有该方法异常 + return new IllegalArgumentException(e); // 返回非法参数异常 + } else if (e instanceof InvocationTargetException) { // 如果是调用目标异常 + return new RuntimeException(((InvocationTargetException) e).getTargetException()); // 返回目标异常 + } else if (e instanceof RuntimeException) { // 如果是运行时异常 + return (RuntimeException) e; // 返回运行时异常 } - return new RuntimeException("Unexpected Checked Exception.", e); + return new RuntimeException("Unexpected Checked Exception.", e); // 返回未知异常 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/SpringUtils.java b/src-源文件/main/java/com/yf/exam/core/utils/SpringUtils.java index 295c827..1943685 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/SpringUtils.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/SpringUtils.java @@ -1,32 +1,33 @@ -package com.yf.exam.core.utils; +language:yfexam-exam-main/yfexam-exam-main/exam-api/src/main/java/com/yf/exam/core/utils/SpringUtils.java +package com.yf.exam.core.utils; // 定义包名 -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; +import org.springframework.beans.BeansException; // 导入BeansException类 +import org.springframework.context.ApplicationContext; // 导入ApplicationContext接口 +import org.springframework.context.ApplicationContextAware; // 导入ApplicationContextAware接口 +import org.springframework.stereotype.Component; // 导入Component注解 /** * Spring获取工具 * - * @author bool - * @date 2019-12-09 15:55 + * @author bool // 作者信息 + * @date 2019-12-09 15:55 // 日期信息 */ -@Component -public class SpringUtils implements ApplicationContextAware { +@Component // 将该类标记为Spring组件 +public class SpringUtils implements ApplicationContextAware { // 定义SpringUtils类并实现ApplicationContextAware接口 - private static ApplicationContext applicationContext; + private static ApplicationContext applicationContext; // 静态变量,用于存储ApplicationContext - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - applicationContext = context; + @Override // 重写setApplicationContext方法 + public void setApplicationContext(ApplicationContext context) throws BeansException { // 设置ApplicationContext + applicationContext = context; // 将传入的context赋值给静态变量 } - public static T getBean(Class tClass) { - return applicationContext.getBean(tClass); + public static T getBean(Class tClass) { // 泛型方法,根据类获取Bean + return applicationContext.getBean(tClass); // 从ApplicationContext中获取指定类型的Bean } - public static T getBean(String name, Class type) { - return applicationContext.getBean(name, type); + public static T getBean(String name, Class type) { // 泛型方法,根据名称和类型获取Bean + return applicationContext.getBean(name, type); // 从ApplicationContext中获取指定名称和类型的Bean } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/StringUtils.java b/src-源文件/main/java/com/yf/exam/core/utils/StringUtils.java index c0bc43b..3d03f61 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/StringUtils.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/StringUtils.java @@ -1,39 +1,38 @@ -package com.yf.exam.core.utils; +package com.yf.exam.core.utils; // 定义包名 -import java.util.Map; +import java.util.Map; // 导入Map类 /** * 字符串常用工具类 * @author bool * @date 2019-05-15 11:40 */ -public class StringUtils { +public class StringUtils { // 定义StringUtils类 /** * 判断是否为空字符 - * @param str - * @return + * @param str 输入的字符串 + * @return 如果字符串为空或null,返回true;否则返回false */ - public static boolean isBlank(String str){ - return str==null || "".equals(str); + public static boolean isBlank(String str){ // 定义静态方法isBlank + return str==null || "".equals(str); // 检查字符串是否为null或空 } - /** * 将MAP转换成一个xml格式,格式为value... - * @param params - * @return + * @param params 输入的Map参数 + * @return 返回xml格式的字符串 */ - public static String mapToXml(Map params){ - StringBuffer sb = new StringBuffer(""); - for(String key:params.keySet()){ - sb.append("<") - .append(key).append(">") - .append(params.get(key)) - .append(""); + public static String mapToXml(Map params){ // 定义静态方法mapToXml + StringBuffer sb = new StringBuffer(""); // 创建StringBuffer并初始化为 + for(String key:params.keySet()){ // 遍历Map中的每个key + sb.append("<") // 添加开始标签 + .append(key).append(">") // 添加key + .append(params.get(key)) // 添加对应的value + .append(""); // 添加结束标签 } - sb.append(""); - return sb.toString(); + sb.append(""); // 添加结束的标签 + return sb.toString(); // 返回构建的xml字符串 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/excel/ExportExcel.java b/src-源文件/main/java/com/yf/exam/core/utils/excel/ExportExcel.java index d98b557..098af26 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/excel/ExportExcel.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/excel/ExportExcel.java @@ -1,82 +1,83 @@ + /** * Copyright © 2015-2020 JeePlus All rights reserved. */ -package com.yf.exam.core.utils.excel; +package com.yf.exam.core.utils.excel; // 包声明 -import com.google.common.collect.Lists; -import com.yf.exam.core.utils.Reflections; -import com.yf.exam.core.utils.excel.annotation.ExcelField; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.DataFormat; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFClientAnchor; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; // 导入Lists类 +import com.yf.exam.core.utils.Reflections; // 导入Reflections工具类 +import com.yf.exam.core.utils.excel.annotation.ExcelField; // 导入ExcelField注解 +import org.apache.commons.lang3.StringUtils; // 导入StringUtils工具类 +import org.apache.poi.ss.usermodel.Cell; // 导入Cell类 +import org.apache.poi.ss.usermodel.CellStyle; // 导入CellStyle类 +import org.apache.poi.ss.usermodel.Comment; // 导入Comment类 +import org.apache.poi.ss.usermodel.DataFormat; // 导入DataFormat类 +import org.apache.poi.ss.usermodel.Font; // 导入Font类 +import org.apache.poi.ss.usermodel.IndexedColors; // 导入IndexedColors类 +import org.apache.poi.ss.usermodel.Row; // 导入Row类 +import org.apache.poi.ss.usermodel.Sheet; // 导入Sheet类 +import org.apache.poi.ss.usermodel.Workbook; // 导入Workbook类 +import org.apache.poi.ss.util.CellRangeAddress; // 导入CellRangeAddress类 +import org.apache.poi.xssf.streaming.SXSSFWorkbook; // 导入SXSSFWorkbook类 +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; // 导入XSSFClientAnchor类 +import org.apache.poi.xssf.usermodel.XSSFRichTextString; // 导入XSSFRichTextString类 +import org.slf4j.Logger; // 导入Logger接口 +import org.slf4j.LoggerFactory; // 导入LoggerFactory类 -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URLEncoder; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.servlet.http.HttpServletResponse; // 导入HttpServletResponse类 +import java.io.IOException; // 导入IOException类 +import java.io.OutputStream; // 导入OutputStream类 +import java.lang.reflect.Field; // 导入Field类 +import java.lang.reflect.Method; // 导入Method类 +import java.net.URLEncoder; // 导入URLEncoder类 +import java.util.Collections; // 导入Collections类 +import java.util.Comparator; // 导入Comparator接口 +import java.util.Date; // 导入Date类 +import java.util.HashMap; // 导入HashMap类 +import java.util.List; // 导入List接口 +import java.util.Map; // 导入Map接口 /** * 导出Excel文件(导出“XLSX”格式,支持大数据量导出 @see org.apache.poi.ss.SpreadsheetVersion) * @author jeeplus * @version 2016-04-21 */ -public class ExportExcel { +public class ExportExcel { // ExportExcel类定义 - private static Logger log = LoggerFactory.getLogger(ExportExcel.class); + private static Logger log = LoggerFactory.getLogger(ExportExcel.class); // 日志记录器 /** * 工作薄对象 */ - private SXSSFWorkbook wb; + private SXSSFWorkbook wb; // 工作薄对象 /** * 工作表对象 */ - private Sheet sheet; + private Sheet sheet; // 工作表对象 /** * 样式列表 */ - private Map styles; + private Map styles; // 样式列表 /** * 当前行号 */ - private int rownum; + private int rownum; // 当前行号 /** * 注解列表(Object[]{ ExcelField, Field/Method }) */ - List annotationList = Lists.newArrayList(); + List annotationList = Lists.newArrayList(); // 注解列表 /** * 构造函数 * @param title 表格标题,传“空值”,表示无标题 * @param cls 实体对象,通过annotation.ExportField获取标题 */ - public ExportExcel(String title, Class cls){ - this(title, cls, 1); + public ExportExcel(String title, Class cls){ // 构造函数 + this(title, cls, 1); // 调用另一个构造函数 } /** @@ -86,123 +87,123 @@ public class ExportExcel { * @param type 导出类型(1:导出数据;2:导出模板) * @param groups 导入分组 */ - public ExportExcel(String title, Class cls, int type, int... groups){ + public ExportExcel(String title, Class cls, int type, int... groups){ // 构造函数 // Get annotation field - Field[] fs = cls.getDeclaredFields(); - for (Field f : fs){ - ExcelField ef = f.getAnnotation(ExcelField.class); - if (ef != null && (ef.type()==0 || ef.type()==type)){ - if (groups!=null && groups.length>0){ - boolean inGroup = false; - for (int g : groups){ - if (inGroup){ - break; + Field[] fs = cls.getDeclaredFields(); // 获取类的所有字段 + for (Field f : fs){ // 遍历字段 + ExcelField ef = f.getAnnotation(ExcelField.class); // 获取ExcelField注解 + if (ef != null && (ef.type()==0 || ef.type()==type)){ // 检查注解类型 + if (groups!=null && groups.length>0){ // 检查分组 + boolean inGroup = false; // 初始化分组标志 + for (int g : groups){ // 遍历分组 + if (inGroup){ // 如果已经在分组中 + break; // 退出循环 } - for (int efg : ef.groups()){ - if (g == efg){ - inGroup = true; - annotationList.add(new Object[]{ef, f}); - break; + for (int efg : ef.groups()){ // 遍历注解中的分组 + if (g == efg){ // 如果匹配 + inGroup = true; // 设置标志 + annotationList.add(new Object[]{ef, f}); // 添加到注解列表 + break; // 退出循环 } } } - }else{ - annotationList.add(new Object[]{ef, f}); + }else{ // 如果没有分组 + annotationList.add(new Object[]{ef, f}); // 添加到注解列表 } } } // Get annotation method - Method[] ms = cls.getDeclaredMethods(); - for (Method m : ms){ - ExcelField ef = m.getAnnotation(ExcelField.class); - if (ef != null && (ef.type()==0 || ef.type()==type)){ - if (groups!=null && groups.length>0){ - boolean inGroup = false; - for (int g : groups){ - if (inGroup){ - break; + Method[] ms = cls.getDeclaredMethods(); // 获取类的所有方法 + for (Method m : ms){ // 遍历方法 + ExcelField ef = m.getAnnotation(ExcelField.class); // 获取ExcelField注解 + if (ef != null && (ef.type()==0 || ef.type()==type)){ // 检查注解类型 + if (groups!=null && groups.length>0){ // 检查分组 + boolean inGroup = false; // 初始化分组标志 + for (int g : groups){ // 遍历分组 + if (inGroup){ // 如果已经在分组中 + break; // 退出循环 } - for (int efg : ef.groups()){ - if (g == efg){ - inGroup = true; - annotationList.add(new Object[]{ef, m}); - break; + for (int efg : ef.groups()){ // 遍历注解中的分组 + if (g == efg){ // 如果匹配 + inGroup = true; // 设置标志 + annotationList.add(new Object[]{ef, m}); // 添加到注解列表 + break; // 退出循环 } } } - }else{ - annotationList.add(new Object[]{ef, m}); + }else{ // 如果没有分组 + annotationList.add(new Object[]{ef, m}); // 添加到注解列表 } } } // Field sorting - Collections.sort(annotationList, new Comparator() { + Collections.sort(annotationList, new Comparator() { // 对注解列表进行排序 @Override - public int compare(Object[] o1, Object[] o2) { - return new Integer(((ExcelField)o1[0]).sort()).compareTo( + public int compare(Object[] o1, Object[] o2) { // 比较方法 + return new Integer(((ExcelField)o1[0]).sort()).compareTo( // 比较排序值 new Integer(((ExcelField)o2[0]).sort())); } }); // Initialize - List headerList = Lists.newArrayList(); - for (Object[] os : annotationList){ - String t = ((ExcelField)os[0]).title(); + List headerList = Lists.newArrayList(); // 初始化表头列表 + for (Object[] os : annotationList){ // 遍历注解列表 + String t = ((ExcelField)os[0]).title(); // 获取标题 // 如果是导出,则去掉注释 - if (type==1){ - String[] ss = StringUtils.split(t, "**", 2); - if (ss.length==2){ - t = ss[0]; + if (type==1){ // 如果是导出数据 + String[] ss = StringUtils.split(t, "**", 2); // 分割标题 + if (ss.length==2){ // 如果有注释 + t = ss[0]; // 去掉注释 } } - headerList.add(t); + headerList.add(t); // 添加标题到表头列表 } - initialize(title, headerList); + initialize(title, headerList); // 初始化工作薄 } /** * 初始化函数 * @param title 表格标题,传“空值”,表示无标题 * @param headerList 表头列表 */ - private void initialize(String title, List headerList) { - this.wb = new SXSSFWorkbook(500); - this.sheet = wb.createSheet("Export"); - this.styles = createStyles(wb); + private void initialize(String title, List headerList) { // 初始化方法 + this.wb = new SXSSFWorkbook(500); // 创建工作薄 + this.sheet = wb.createSheet("Export"); // 创建工作表 + this.styles = createStyles(wb); // 创建样式 // Create title - if (StringUtils.isNotBlank(title)){ - Row titleRow = sheet.createRow(rownum++); - titleRow.setHeightInPoints(30); - Cell titleCell = titleRow.createCell(0); - titleCell.setCellStyle(styles.get("title")); - titleCell.setCellValue(title); - sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), + if (StringUtils.isNotBlank(title)){ // 如果标题不为空 + Row titleRow = sheet.createRow(rownum++); // 创建标题行 + titleRow.setHeightInPoints(30); // 设置行高 + Cell titleCell = titleRow.createCell(0); // 创建单元格 + titleCell.setCellStyle(styles.get("title")); // 设置单元格样式 + titleCell.setCellValue(title); // 设置单元格值 + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), // 合并单元格 titleRow.getRowNum(), titleRow.getRowNum(), headerList.size()-1)); } // Create header - if (headerList == null){ - throw new RuntimeException("headerList not null!"); + if (headerList == null){ // 如果表头列表为空 + throw new RuntimeException("headerList not null!"); // 抛出异常 } - Row headerRow = sheet.createRow(rownum++); - headerRow.setHeightInPoints(16); - for (int i = 0; i < headerList.size(); i++) { - Cell cell = headerRow.createCell(i); - cell.setCellStyle(styles.get("header")); - String[] ss = StringUtils.split(headerList.get(i), "**", 2); - if (ss.length==2){ - cell.setCellValue(ss[0]); - Comment comment = this.sheet.createDrawingPatriarch().createCellComment( + Row headerRow = sheet.createRow(rownum++); // 创建表头行 + headerRow.setHeightInPoints(16); // 设置行高 + for (int i = 0; i < headerList.size(); i++) { // 遍历表头列表 + Cell cell = headerRow.createCell(i); // 创建单元格 + cell.setCellStyle(styles.get("header")); // 设置单元格样式 + String[] ss = StringUtils.split(headerList.get(i), "**", 2); // 分割表头 + if (ss.length==2){ // 如果有注释 + cell.setCellValue(ss[0]); // 设置单元格值 + Comment comment = this.sheet.createDrawingPatriarch().createCellComment( // 创建注释 new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6)); - comment.setString(new XSSFRichTextString(ss[1])); - cell.setCellComment(comment); - }else{ - cell.setCellValue(headerList.get(i)); + comment.setString(new XSSFRichTextString(ss[1])); // 设置注释内容 + cell.setCellComment(comment); // 设置单元格注释 + }else{ // 如果没有注释 + cell.setCellValue(headerList.get(i)); // 设置单元格值 } - sheet.autoSizeColumn(i); + sheet.autoSizeColumn(i); // 自动调整列宽 } - for (int i = 0; i < headerList.size(); i++) { - int colWidth = sheet.getColumnWidth(i)*2; - sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth); + for (int i = 0; i < headerList.size(); i++) { // 遍历表头列表 + int colWidth = sheet.getColumnWidth(i)*2; // 计算列宽 + sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth); // 设置列宽 } - log.debug("Initialize success."); + log.debug("Initialize success."); // 记录初始化成功日志 } /** @@ -210,73 +211,73 @@ public class ExportExcel { * @param wb 工作薄对象 * @return 样式列表 */ - private Map createStyles(Workbook wb) { - Map styles = new HashMap<>(16); + private Map createStyles(Workbook wb) { // 创建样式方法 + Map styles = new HashMap<>(16); // 初始化样式列表 - CellStyle style = wb.createCellStyle(); - style.setAlignment(CellStyle.ALIGN_CENTER); - style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); - Font titleFont = wb.createFont(); - titleFont.setFontName("Arial"); - titleFont.setFontHeightInPoints((short) 16); - titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD); - style.setFont(titleFont); - styles.put("title", style); + CellStyle style = wb.createCellStyle(); // 创建样式 + style.setAlignment(CellStyle.ALIGN_CENTER); // 设置水平对齐方式 + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); // 设置垂直对齐方式 + Font titleFont = wb.createFont(); // 创建字体 + titleFont.setFontName("Arial"); // 设置字体名称 + titleFont.setFontHeightInPoints((short) 16); // 设置字体大小 + titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD); // 设置字体加粗 + style.setFont(titleFont); // 设置样式字体 + styles.put("title", style); // 添加样式到列表 - style = wb.createCellStyle(); - style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); - style.setBorderRight(CellStyle.BORDER_THIN); - style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderLeft(CellStyle.BORDER_THIN); - style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderTop(CellStyle.BORDER_THIN); - style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setBorderBottom(CellStyle.BORDER_THIN); - style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); - Font dataFont = wb.createFont(); - dataFont.setFontName("Arial"); - dataFont.setFontHeightInPoints((short) 10); - style.setFont(dataFont); - styles.put("data", style); + style = wb.createCellStyle(); // 创建样式 + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); // 设置垂直对齐方式 + style.setBorderRight(CellStyle.BORDER_THIN); // 设置右边框 + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置右边框颜色 + style.setBorderLeft(CellStyle.BORDER_THIN); // 设置左边框 + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置左边框颜色 + style.setBorderTop(CellStyle.BORDER_THIN); // 设置上边框 + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置上边框颜色 + style.setBorderBottom(CellStyle.BORDER_THIN); // 设置下边框 + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置下边框颜色 + Font dataFont = wb.createFont(); // 创建字体 + dataFont.setFontName("Arial"); // 设置字体名称 + dataFont.setFontHeightInPoints((short) 10); // 设置字体大小 + style.setFont(dataFont); // 设置样式字体 + styles.put("data", style); // 添加样式到列表 - style = wb.createCellStyle(); - style.cloneStyleFrom(styles.get("data")); - style.setAlignment(CellStyle.ALIGN_LEFT); - styles.put("data1", style); + style = wb.createCellStyle(); // 创建样式 + style.cloneStyleFrom(styles.get("data")); // 克隆数据样式 + style.setAlignment(CellStyle.ALIGN_LEFT); // 设置左对齐 + styles.put("data1", style); // 添加样式到列表 - style = wb.createCellStyle(); - style.cloneStyleFrom(styles.get("data")); - style.setAlignment(CellStyle.ALIGN_CENTER); - styles.put("data2", style); + style = wb.createCellStyle(); // 创建样式 + style.cloneStyleFrom(styles.get("data")); // 克隆数据样式 + style.setAlignment(CellStyle.ALIGN_CENTER); // 设置居中对齐 + styles.put("data2", style); // 添加样式到列表 - style = wb.createCellStyle(); - style.cloneStyleFrom(styles.get("data")); - style.setAlignment(CellStyle.ALIGN_RIGHT); - styles.put("data3", style); + style = wb.createCellStyle(); // 创建样式 + style.cloneStyleFrom(styles.get("data")); // 克隆数据样式 + style.setAlignment(CellStyle.ALIGN_RIGHT); // 设置右对齐 + styles.put("data3", style); // 添加样式到列表 - style = wb.createCellStyle(); - style.cloneStyleFrom(styles.get("data")); -// style.setWrapText(true); - style.setAlignment(CellStyle.ALIGN_CENTER); - style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); - style.setFillPattern(CellStyle.SOLID_FOREGROUND); - Font headerFont = wb.createFont(); - headerFont.setFontName("Arial"); - headerFont.setFontHeightInPoints((short) 10); - headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD); - headerFont.setColor(IndexedColors.WHITE.getIndex()); - style.setFont(headerFont); - styles.put("header", style); + style = wb.createCellStyle(); // 创建样式 + style.cloneStyleFrom(styles.get("data")); // 克隆数据样式 +// style.setWrapText(true); // 设置文本换行 + style.setAlignment(CellStyle.ALIGN_CENTER); // 设置居中对齐 + style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置前景色 + style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 设置填充模式 + Font headerFont = wb.createFont(); // 创建字体 + headerFont.setFontName("Arial"); // 设置字体名称 + headerFont.setFontHeightInPoints((short) 10); // 设置字体大小 + headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD); // 设置字体加粗 + headerFont.setColor(IndexedColors.WHITE.getIndex()); // 设置字体颜色 + style.setFont(headerFont); // 设置样式字体 + styles.put("header", style); // 添加样式到列表 - return styles; + return styles; // 返回样式列表 } /** * 添加一行 * @return 行对象 */ - public Row addRow(){ - return sheet.createRow(rownum++); + public Row addRow(){ // 添加行方法 + return sheet.createRow(rownum++); // 创建新行并返回 } @@ -287,8 +288,8 @@ public class ExportExcel { * @param val 添加值 * @return 单元格对象 */ - public Cell addCell(Row row, int column, Object val){ - return this.addCell(row, column, val, 0, Class.class); + public Cell addCell(Row row, int column, Object val){ // 添加单元格方法 + return this.addCell(row, column, val, 0, Class.class); // 调用重载方法 } /** @@ -299,104 +300,104 @@ public class ExportExcel { * @param align 对齐方式(1:靠左;2:居中;3:靠右) * @return 单元格对象 */ - public Cell addCell(Row row, int column, Object val, int align, Class fieldType){ - Cell cell = row.createCell(column); - CellStyle style = styles.get("data"+(align>=1&&align<=3?align:"")); - try { - if (val == null){ - cell.setCellValue(""); - } else if (val instanceof String) { - cell.setCellValue((String) val); - } else if (val instanceof Integer) { - cell.setCellValue((Integer) val); - } else if (val instanceof Long) { - cell.setCellValue((Long) val); - } else if (val instanceof Double) { - cell.setCellValue((Double) val); - } else if (val instanceof Float) { - cell.setCellValue((Float) val); - } else if (val instanceof Date) { - DataFormat format = wb.createDataFormat(); - style.setDataFormat(format.getFormat("yyyy-MM-dd")); - cell.setCellValue((Date) val); - } else { - if (fieldType != Class.class){ - cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val)); - }else{ + public Cell addCell(Row row, int column, Object val, int align, Class fieldType){ // 添加单元格重载方法 + Cell cell = row.createCell(column); // 创建单元格 + CellStyle style = styles.get("data"+(align>=1&&align<=3?align:"")); // 获取样式 + try { // 尝试设置单元格值 + if (val == null){ // 如果值为null + cell.setCellValue(""); // 设置为空字符串 + } else if (val instanceof String) { // 如果值是字符串 + cell.setCellValue((String) val); // 设置单元格值 + } else if (val instanceof Integer) { // 如果值是整数 + cell.setCellValue((Integer) val); // 设置单元格值 + } else if (val instanceof Long) { // 如果值是长整型 + cell.setCellValue((Long) val); // 设置单元格值 + } else if (val instanceof Double) { // 如果值是双精度浮点型 + cell.setCellValue((Double) val); // 设置单元格值 + } else if (val instanceof Float) { // 如果值是单精度浮点型 + cell.setCellValue((Float) val); // 设置单元格值 + } else if (val instanceof Date) { // 如果值是日期 + DataFormat format = wb.createDataFormat(); // 创建数据格式 + style.setDataFormat(format.getFormat("yyyy-MM-dd")); // 设置日期格式 + cell.setCellValue((Date) val); // 设置单元格值 + } else { // 如果值是其他类型 + if (fieldType != Class.class){ // 如果字段类型不是Class + cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val)); // 设置单元格值 + }else{ // 如果字段类型是Class cell.setCellValue((String)Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), - "fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val)); + "fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val)); // 设置单元格值 } } - } catch (Exception ex) { - log.info("Set cell value ["+row.getRowNum()+","+column+"] error: " + ex.toString()); - cell.setCellValue(val.toString()); + } catch (Exception ex) { // 捕获异常 + log.info("Set cell value ["+row.getRowNum()+","+column+"] error: " + ex.toString()); // 记录错误日志 + cell.setCellValue(val.toString()); // 设置单元格值为字符串 } - cell.setCellStyle(style); - return cell; + cell.setCellStyle(style); // 设置单元格样式 + return cell; // 返回单元格对象 } /** * 添加数据(通过annotation.ExportField添加数据) * @return list 数据列表 */ - public ExportExcel setDataList(List list){ - for (E e : list){ - int colunm = 0; - Row row = this.addRow(); - StringBuilder sb = new StringBuilder(); - for (Object[] os : annotationList){ - ExcelField ef = (ExcelField)os[0]; - Object val = null; - try{ - if (StringUtils.isNotBlank(ef.value())){ - val = Reflections.invokeGetter(e, ef.value()); - }else{ - if (os[1] instanceof Field){ - val = Reflections.invokeGetter(e, ((Field)os[1]).getName()); - }else if (os[1] instanceof Method){ - val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {}); + public ExportExcel setDataList(List list){ // 设置数据列表方法 + for (E e : list){ // 遍历数据列表 + int colunm = 0; // 初始化列号 + Row row = this.addRow(); // 添加新行 + StringBuilder sb = new StringBuilder(); // 初始化字符串构建器 + for (Object[] os : annotationList){ // 遍历注解列表 + ExcelField ef = (ExcelField)os[0]; // 获取ExcelField注解 + Object val = null; // 初始化值 + try{ // 尝试获取值 + if (StringUtils.isNotBlank(ef.value())){ // 如果注解值不为空 + val = Reflections.invokeGetter(e, ef.value()); // 通过反射获取值 + }else{ // 如果注解值为空 + if (os[1] instanceof Field){ // 如果是字段 + val = Reflections.invokeGetter(e, ((Field)os[1]).getName()); // 通过反射获取值 + }else if (os[1] instanceof Method){ // 如果是方法 + val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {}); // 通过反射获取值 } } - }catch(Exception ex) { - log.info(ex.toString()); - val = ""; + }catch(Exception ex) { // 捕获异常 + log.info(ex.toString()); // 记录错误日志 + val = ""; // 设置值为空字符串 } - this.addCell(row, colunm++, val, ef.align(), ef.fieldType()); - sb.append(val + ", "); + this.addCell(row, colunm++, val, ef.align(), ef.fieldType()); // 添加单元格 + sb.append(val + ", "); // 添加值到字符串构建器 } - log.debug("Write success: ["+row.getRowNum()+"] "+sb.toString()); + log.debug("Write success: ["+row.getRowNum()+"] "+sb.toString()); // 记录写入成功日志 } - return this; + return this; // 返回当前对象 } /** * 输出数据流 * @param os 输出数据流 */ - public ExportExcel write(OutputStream os) throws IOException{ - wb.write(os); - return this; + public ExportExcel write(OutputStream os) throws IOException{ // 输出数据流方法 + wb.write(os); // 写入工作薄到输出流 + return this; // 返回当前对象 } /** * 输出到客户端 * @param fileName 输出文件名 */ - public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{ - response.reset(); - response.setHeader("Access-Control-Allow-Origin", "*"); - response.setContentType("application/octet-stream; charset=utf-8"); - response.addHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(fileName, "utf-8")); - write(response.getOutputStream()); - return this; + public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{ // 输出到客户端方法 + response.reset(); // 重置响应 + response.setHeader("Access-Control-Allow-Origin", "*"); // 设置跨域头 + response.setContentType("application/octet-stream; charset=utf-8"); // 设置内容类型 + response.addHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(fileName, "utf-8")); // 设置下载文件名 + write(response.getOutputStream()); // 写入输出流 + return this; // 返回当前对象 } /** * 清理临时文件 */ - public ExportExcel dispose(){ - wb.dispose(); - return this; + public ExportExcel dispose(){ // 清理临时文件方法 + wb.dispose(); // 释放工作薄资源 + return this; // 返回当前对象 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/excel/ImportExcel.java b/src-源文件/main/java/com/yf/exam/core/utils/excel/ImportExcel.java index fca308a..d91f504 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/excel/ImportExcel.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/excel/ImportExcel.java @@ -1,61 +1,60 @@ /** * Copyright © 2015-2020 JeePlus All rights reserved. */ -package com.yf.exam.core.utils.excel; +package com.yf.exam.core.utils.excel; // 定义包名 -import com.google.common.collect.Lists; -import com.yf.exam.core.utils.Reflections; -import com.yf.exam.core.utils.excel.annotation.ExcelField; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.multipart.MultipartFile; +import com.google.common.collect.Lists; // 导入Google的Lists工具类 +import com.yf.exam.core.utils.Reflections; // 导入自定义的Reflections工具类 +import com.yf.exam.core.utils.excel.annotation.ExcelField; // 导入ExcelField注解 +import org.apache.commons.lang3.StringUtils; // 导入Apache Commons的StringUtils工具类 +import org.apache.poi.hssf.usermodel.HSSFDateUtil; // 导入HSSFDateUtil类用于处理日期 +import org.apache.poi.hssf.usermodel.HSSFWorkbook; // 导入HSSFWorkbook类用于处理XLS文件 +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; // 导入异常类 +import org.apache.poi.ss.usermodel.Cell; // 导入Cell类表示单元格 +import org.apache.poi.ss.usermodel.Row; // 导入Row类表示行 +import org.apache.poi.ss.usermodel.Sheet; // 导入Sheet类表示工作表 +import org.apache.poi.ss.usermodel.Workbook; // 导入Workbook类表示工作簿 +import org.apache.poi.xssf.usermodel.XSSFWorkbook; // 导入XSSFWorkbook类用于处理XLSX文件 +import org.slf4j.Logger; // 导入Logger接口 +import org.slf4j.LoggerFactory; // 导入LoggerFactory类 +import org.springframework.web.multipart.MultipartFile; // 导入MultipartFile类用于处理文件上传 -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.List; +import java.io.IOException; // 导入IOException异常 +import java.io.InputStream; // 导入InputStream类 +import java.lang.reflect.Field; // 导入Field类用于反射 +import java.lang.reflect.Method; // 导入Method类用于反射 +import java.text.NumberFormat; // 导入NumberFormat类用于格式化数字 +import java.text.SimpleDateFormat; // 导入SimpleDateFormat类用于格式化日期 +import java.util.Collections; // 导入Collections类用于集合操作 +import java.util.Comparator; // 导入Comparator接口用于比较 +import java.util.Date; // 导入Date类表示日期 +import java.util.List; // 导入List接口表示列表 /** * 导入Excel文件(支持“XLS”和“XLSX”格式) * @author jeeplus * @version 2016-03-10 */ -public class ImportExcel { +public class ImportExcel { // 定义ImportExcel类 - private static Logger log = LoggerFactory.getLogger(ImportExcel.class); + private static Logger log = LoggerFactory.getLogger(ImportExcel.class); // 创建日志记录器 /** * 工作薄对象 */ - private Workbook wb; + private Workbook wb; // 定义工作簿对象 /** * 工作表对象 */ - private Sheet sheet; + private Sheet sheet; // 定义工作表对象 /** * 标题行号 */ - private int headerNum; + private int headerNum; // 定义标题行号 - /** * 构造函数 * @param multipartFile 导入文件对象 @@ -65,8 +64,8 @@ public class ImportExcel { * @throws IOException */ public ImportExcel(MultipartFile multipartFile, int headerNum, int sheetIndex) - throws InvalidFormatException, IOException { - this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex); + throws InvalidFormatException, IOException { // 构造函数,接收文件、标题行号和工作表索引 + this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex); // 调用另一个构造函数 } /** @@ -78,22 +77,22 @@ public class ImportExcel { * @throws IOException */ public ImportExcel(String fileName, InputStream is, int headerNum, int sheetIndex) - throws IOException { - if (StringUtils.isBlank(fileName)){ - throw new RuntimeException("导入文档为空!"); - }else if(fileName.toLowerCase().endsWith("xls")){ - this.wb = new HSSFWorkbook(is); + throws IOException { // 构造函数,接收文件名、输入流、标题行号和工作表索引 + if (StringUtils.isBlank(fileName)){ // 检查文件名是否为空 + throw new RuntimeException("导入文档为空!"); // 抛出异常 + }else if(fileName.toLowerCase().endsWith("xls")){ // 检查文件格式 + this.wb = new HSSFWorkbook(is); // 创建HSSFWorkbook对象 }else if(fileName.toLowerCase().endsWith("xlsx")){ - this.wb = new XSSFWorkbook(is); + this.wb = new XSSFWorkbook(is); // 创建XSSFWorkbook对象 }else{ - throw new RuntimeException("文档格式不正确!"); + throw new RuntimeException("文档格式不正确!"); // 抛出异常 } - if (this.wb.getNumberOfSheets() List getDataList(Class cls, int... groups) throws InstantiationException, IllegalAccessException{ - List annotationList = Lists.newArrayList(); + public List getDataList(Class cls, int... groups) throws InstantiationException, IllegalAccessException{ // 获取导入数据列表 + List annotationList = Lists.newArrayList(); // 创建注解列表 // Get annotation field - Field[] fs = cls.getDeclaredFields(); - for (Field f : fs){ - ExcelField ef = f.getAnnotation(ExcelField.class); - if (ef != null && (ef.type()==0 || ef.type()==2)){ - if (groups!=null && groups.length>0){ - boolean inGroup = false; - for (int g : groups){ - if (inGroup){ - break; + Field[] fs = cls.getDeclaredFields(); // 获取类的所有字段 + for (Field f : fs){ // 遍历字段 + ExcelField ef = f.getAnnotation(ExcelField.class); // 获取字段上的ExcelField注解 + if (ef != null && (ef.type()==0 || ef.type()==2)){ // 检查注解类型 + if (groups!=null && groups.length>0){ // 检查分组 + boolean inGroup = false; // 初始化分组标志 + for (int g : groups){ // 遍历分组 + if (inGroup){ // 如果已经在分组中 + break; // 跳出循环 } - for (int efg : ef.groups()){ - if (g == efg){ - inGroup = true; - annotationList.add(new Object[]{ef, f}); - break; + for (int efg : ef.groups()){ // 遍历注解中的分组 + if (g == efg){ // 如果分组匹配 + inGroup = true; // 设置标志 + annotationList.add(new Object[]{ef, f}); // 添加到注解列表 + break; // 跳出循环 } } } }else{ - annotationList.add(new Object[]{ef, f}); + annotationList.add(new Object[]{ef, f}); // 添加到注解列表 } } } // Get annotation method - Method[] ms = cls.getDeclaredMethods(); - for (Method m : ms){ - ExcelField ef = m.getAnnotation(ExcelField.class); - if (ef != null && (ef.type()==0 || ef.type()==2)){ - if (groups!=null && groups.length>0){ - boolean inGroup = false; - for (int g : groups){ - if (inGroup){ - break; + Method[] ms = cls.getDeclaredMethods(); // 获取类的所有方法 + for (Method m : ms){ // 遍历方法 + ExcelField ef = m.getAnnotation(ExcelField.class); // 获取方法上的ExcelField注解 + if (ef != null && (ef.type()==0 || ef.type()==2)){ // 检查注解类型 + if (groups!=null && groups.length>0){ // 检查分组 + boolean inGroup = false; // 初始化分组标志 + for (int g : groups){ // 遍历分组 + if (inGroup){ // 如果已经在分组中 + break; // 跳出循环 } - for (int efg : ef.groups()){ - if (g == efg){ - inGroup = true; - annotationList.add(new Object[]{ef, m}); - break; + for (int efg : ef.groups()){ // 遍历注解中的分组 + if (g == efg){ // 如果分组匹配 + inGroup = true; // 设置标志 + annotationList.add(new Object[]{ef, m}); // 添加到注解列表 + break; // 跳出循环 } } } }else{ - annotationList.add(new Object[]{ef, m}); + annotationList.add(new Object[]{ef, m}); // 添加到注解列表 } } } // Field sorting - Collections.sort(annotationList, new Comparator() { + Collections.sort(annotationList, new Comparator() { // 对注解列表进行排序 @Override - public int compare(Object[] o1, Object[] o2) { - return new Integer(((ExcelField)o1[0]).sort()).compareTo( + public int compare(Object[] o1, Object[] o2) { // 比较两个对象 + return new Integer(((ExcelField)o1[0]).sort()).compareTo( // 根据排序值进行比较 new Integer(((ExcelField)o2[0]).sort())); } }); // Get excel data - List dataList = Lists.newArrayList(); - for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) { - E e = (E)cls.newInstance(); - int column = 0; - Row row = this.getRow(i); - StringBuilder sb = new StringBuilder(); - for (Object[] os : annotationList){ - Object val = this.getCellValue(row, column++); - if (val != null){ - ExcelField ef = (ExcelField)os[0]; + List dataList = Lists.newArrayList(); // 创建数据列表 + for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) { // 遍历数据行 + E e = (E)cls.newInstance(); // 创建对象实例 + int column = 0; // 初始化列索引 + Row row = this.getRow(i); // 获取行对象 + StringBuilder sb = new StringBuilder(); // 创建字符串构建器 + for (Object[] os : annotationList){ // 遍历注解列表 + Object val = this.getCellValue(row, column++); // 获取单元格值 + if (val != null){ // 检查值是否为空 + ExcelField ef = (ExcelField)os[0]; // 获取ExcelField注解 // Get param type and type cast - Class valType = Class.class; - if (os[1] instanceof Field){ - valType = ((Field)os[1]).getType(); - }else if (os[1] instanceof Method){ + Class valType = Class.class; // 初始化值类型 + if (os[1] instanceof Field){ // 检查是否为字段 + valType = ((Field)os[1]).getType(); // 获取字段类型 + }else if (os[1] instanceof Method){ // 检查是否为方法 Method method = ((Method)os[1]); - if ("get".equals(method.getName().substring(0, 3))){ - valType = method.getReturnType(); - }else if("set".equals(method.getName().substring(0, 3))){ - valType = ((Method)os[1]).getParameterTypes()[0]; + if ("get".equals(method.getName().substring(0, 3))){ // 检查方法名 + valType = method.getReturnType(); // 获取返回类型 + }else if("set".equals(method.getName().substring(0, 3))){ // 检查方法名 + valType = ((Method)os[1]).getParameterTypes()[0]; // 获取参数类型 } } //log.debug("Import value type: ["+i+","+column+"] " + valType); try { //如果导入的java对象,需要在这里自己进行变换。 - if (valType == String.class){ - String s = String.valueOf(val.toString()); - if(StringUtils.endsWith(s, ".0")){ - val = StringUtils.substringBefore(s, ".0"); + if (valType == String.class){ // 检查值类型 + String s = String.valueOf(val.toString()); // 转换为字符串 + if(StringUtils.endsWith(s, ".0")){ // 检查是否以.0结尾 + val = StringUtils.substringBefore(s, ".0"); // 去掉.0 }else{ - val = String.valueOf(val.toString()); + val = String.valueOf(val.toString()); // 转换为字符串 } - }else if (valType == Integer.class){ - val = Double.valueOf(val.toString()).intValue(); - }else if (valType == Long.class){ - val = Double.valueOf(val.toString()).longValue(); - }else if (valType == Double.class){ - val = Double.valueOf(val.toString()); - }else if (valType == Float.class){ - val = Float.valueOf(val.toString()); - }else if (valType == Date.class){ - SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); - val=sdf.parse(val.toString()); + }else if (valType == Integer.class){ // 检查值类型 + val = Double.valueOf(val.toString()).intValue(); // 转换为整数 + }else if (valType == Long.class){ // 检查值类型 + val = Double.valueOf(val.toString()).longValue(); // 转换为长整型 + }else if (valType == Double.class){ // 检查值类型 + val = Double.valueOf(val.toString()); // 转换为双精度浮点型 + }else if (valType == Float.class){ // 检查值类型 + val = Float.valueOf(val.toString()); // 转换为浮点型 + }else if (valType == Date.class){ // 检查值类型 + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); // 定义日期格式 + val=sdf.parse(val.toString()); // 解析日期 }else{ - if (ef.fieldType() != Class.class){ - val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString()); + if (ef.fieldType() != Class.class){ // 检查字段类型 + val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString()); // 调用getValue方法 }else{ val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), - "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString()); + "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString()); // 动态调用getValue方法 } } - } catch (Exception ex) { - log.info("Get cell value ["+i+","+column+"] error: " + ex.toString()); - val = null; + } catch (Exception ex) { // 捕获异常 + log.info("Get cell value ["+i+","+column+"] error: " + ex.toString()); // 记录错误日志 + val = null; // 设置值为null } // set entity value - if (os[1] instanceof Field){ - Reflections.invokeSetter(e, ((Field)os[1]).getName(), val); - }else if (os[1] instanceof Method){ - String mthodName = ((Method)os[1]).getName(); - if ("get".equals(mthodName.substring(0, 3))){ - mthodName = "set"+StringUtils.substringAfter(mthodName, "get"); + if (os[1] instanceof Field){ // 检查是否为字段 + Reflections.invokeSetter(e, ((Field)os[1]).getName(), val); // 设置字段值 + }else if (os[1] instanceof Method){ // 检查是否为方法 + String mthodName = ((Method)os[1]).getName(); // 获取方法名 + if ("get".equals(mthodName.substring(0, 3))){ // 检查方法名 + mthodName = "set"+StringUtils.substringAfter(mthodName, "get"); // 转换为set方法名 } - Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val}); + Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val}); // 调用set方法 } } - sb.append(val+", "); + sb.append(val+", "); // 添加值到字符串构建器 } - dataList.add(e); - log.debug("Read success: ["+i+"] "+sb.toString()); + dataList.add(e); // 添加对象到数据列表 + log.debug("Read success: ["+i+"] "+sb.toString()); // 记录读取成功的日志 } - return dataList; + return dataList; // 返回数据列表 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/excel/annotation/ExcelField.java b/src-源文件/main/java/com/yf/exam/core/utils/excel/annotation/ExcelField.java index add0d1c..bc2da91 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/excel/annotation/ExcelField.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/excel/annotation/ExcelField.java @@ -1,59 +1,87 @@ +// ... existing code ... /** * Copyright © 2015-2020 JeePlus All rights reserved. +// 版权声明,包含版权信息和链接 */ package com.yf.exam.core.utils.excel.annotation; +// 包声明,定义该类所在的包 import java.lang.annotation.ElementType; +// 导入ElementType类,用于定义注解的适用范围 import java.lang.annotation.Retention; +// 导入Retention类,用于定义注解的保留策略 import java.lang.annotation.RetentionPolicy; +// 导入RetentionPolicy类,定义注解的保留策略类型 import java.lang.annotation.Target; +// 导入Target类,用于定义注解的目标 /** * Excel注解定义 * @author jeeplus * @version 2016-03-10 */ +// 注解类的描述,包含作者和版本信息 @Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) +// 定义该注解可以应用于方法、字段和类 @Retention(RetentionPolicy.RUNTIME) +// 定义该注解在运行时可用 public @interface ExcelField { +// 定义ExcelField注解 /** * 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”) + * 字段名的描述,提供默认值和示例 */ String value() default ""; + // 字段名,默认为空字符串 /** * 导出字段标题(需要添加批注请用“**”分隔,标题**批注,仅对导出模板有效) + * 字段标题的描述,说明如何添加批注 */ String title(); + // 字段标题,必填项 /** * 字段类型(0:导出导入;1:仅导出;2:仅导入) + * 字段类型的描述,提供可选值 */ int type() default 0; + // 字段类型,默认为0(导出导入) /** * 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右) + * 对齐方式的描述,提供可选值 */ int align() default 0; + // 对齐方式,默认为0(自动) /** * 导出字段字段排序(升序) + * 字段排序的描述,说明排序方式 */ int sort() default 0; + // 字段排序,默认为0(升序) /** * 如果是字典类型,请设置字典的type值 + * 字典类型的描述,说明如何设置字典类型 */ String dictType() default ""; + // 字典类型,默认为空字符串 /** * 反射类型 + * 反射类型的描述,说明该字段的类型 */ Class fieldType() default Class.class; + // 字段类型,默认为Class.class /** * 字段归属组(根据分组导出导入) + * 字段分组的描述,说明如何根据分组导出导入 */ int[] groups() default {}; + // 字段归属组,默认为空数组 } +// ... existing code ... \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/excel/fieldtype/ListType.java b/src-源文件/main/java/com/yf/exam/core/utils/excel/fieldtype/ListType.java index 9369888..d7716a5 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/excel/fieldtype/ListType.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/excel/fieldtype/ListType.java @@ -1,56 +1,57 @@ + /** * Copyright © 2015-2020 JeePlus All rights reserved. */ -package com.yf.exam.core.utils.excel.fieldtype; +package com.yf.exam.core.utils.excel.fieldtype; // 定义包名 -import com.google.common.collect.Lists; -import com.yf.exam.core.utils.StringUtils; +import com.google.common.collect.Lists; // 导入Google的Lists工具类 +import com.yf.exam.core.utils.StringUtils; // 导入自定义的StringUtils工具类 -import java.util.List; +import java.util.List; // 导入List接口 /** * 字段类型转换 * @author jeeplus * @version 2016-5-29 */ -public class ListType { +public class ListType { // 定义ListType类 /** * 获取对象值(导入) */ - public static Object getValue(String val) { - List list = Lists.newArrayList(); - if(!StringUtils.isBlank(val)) { - for (String s : val.split(",")) { - list.add(s); + public static Object getValue(String val) { // 定义静态方法getValue,接收一个字符串参数 + List list = Lists.newArrayList(); // 创建一个新的字符串列表 + if(!StringUtils.isBlank(val)) { // 检查输入字符串是否为空 + for (String s : val.split(",")) { // 按逗号分割字符串 + list.add(s); // 将分割后的字符串添加到列表中 } } - return list; + return list; // 返回列表 } /** * 设置对象值(导出) */ - public static String setValue(Object val) { - if (val != null){ - List list = (List)val; - StringBuffer sb = null; - for (String item: list){ - if(StringUtils.isBlank(item)){ - continue; + public static String setValue(Object val) { // 定义静态方法setValue,接收一个对象参数 + if (val != null){ // 检查输入对象是否为null + List list = (List)val; // 将对象强制转换为字符串列表 + StringBuffer sb = null; // 初始化字符串缓冲区 + for (String item: list){ // 遍历列表中的每个字符串 + if(StringUtils.isBlank(item)){ // 检查字符串是否为空 + continue; // 如果为空,跳过当前循环 } - if(sb == null){ - sb = new StringBuffer(item); + if(sb == null){ // 如果字符串缓冲区为空 + sb = new StringBuffer(item); // 初始化缓冲区为当前字符串 }else{ - sb.append(",").append(item); + sb.append(",").append(item); // 否则,添加逗号和当前字符串 } } - if(sb!=null) { - return sb.toString().replace("[]", ""); + if(sb!=null) { // 如果字符串缓冲区不为空 + return sb.toString().replace("[]", ""); // 返回缓冲区内容并替换"[]"为空 } } - return ""; + return ""; // 如果输入对象为null,返回空字符串 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/file/Md5Util.java b/src-源文件/main/java/com/yf/exam/core/utils/file/Md5Util.java index d5d33cf..d74ec67 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/file/Md5Util.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/file/Md5Util.java @@ -1,7 +1,6 @@ -package com.yf.exam.core.utils.file; - -import java.security.MessageDigest; +package com.yf.exam.core.utils.file; // 包声明 +import java.security.MessageDigest; // 导入MessageDigest类,用于生成MD5哈希 /** * MD5工具类 @@ -11,27 +10,26 @@ import java.security.MessageDigest; * @author Bool * @version */ -public class Md5Util { - +public class Md5Util { // 定义MD5工具类 /** * 简单MD5 - * @param str - * @return + * @param str 输入字符串 + * @return 返回MD5哈希值 */ - public static String md5(String str) { + public static String md5(String str) { // 定义静态方法md5,接受一个字符串参数 - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] array = md.digest(str.getBytes("UTF-8")); - StringBuilder sb = new StringBuilder(); - for (byte item : array) { - sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + try { // 开始异常处理 + MessageDigest md = MessageDigest.getInstance("MD5"); // 获取MD5实例 + byte[] array = md.digest(str.getBytes("UTF-8")); // 计算输入字符串的MD5哈希值 + StringBuilder sb = new StringBuilder(); // 创建StringBuilder用于构建结果字符串 + for (byte item : array) { // 遍历哈希字节数组 + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); // 将每个字节转换为十六进制并添加到StringBuilder } - return sb.toString(); - }catch(Exception e) { - return null; + return sb.toString(); // 返回最终的MD5哈希字符串 + }catch(Exception e) { // 捕获异常 + return null; // 如果发生异常,返回null } } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassHandler.java b/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassHandler.java index 1af239e..103e097 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassHandler.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassHandler.java @@ -1,8 +1,7 @@ -package com.yf.exam.core.utils.passwd; +package com.yf.exam.core.utils.passwd; // 定义包名 - -import com.yf.exam.core.utils.file.Md5Util; -import org.apache.commons.lang3.RandomStringUtils; +import com.yf.exam.core.utils.file.Md5Util; // 导入Md5Util类 +import org.apache.commons.lang3.RandomStringUtils; // 导入RandomStringUtils类 /** * 通用的密码处理类,用于生成密码和校验密码 @@ -12,7 +11,7 @@ import org.apache.commons.lang3.RandomStringUtils; * @author Bool * @version */ -public class PassHandler { +public class PassHandler { // 定义PassHandler类 /** * checkPass:校验密码是否一致 @@ -22,9 +21,9 @@ public class PassHandler { * @param pass 数据库保存的密码MD5 * @return */ - public static boolean checkPass(String inputPass , String salt , String pass){ - String pwdMd5 = Md5Util.md5(inputPass); - return Md5Util.md5(pwdMd5 + salt).equals(pass); + public static boolean checkPass(String inputPass , String salt , String pass){ // 定义静态方法checkPass + String pwdMd5 = Md5Util.md5(inputPass); // 将输入密码进行MD5加密 + return Md5Util.md5(pwdMd5 + salt).equals(pass); // 校验加密后的密码与数据库密码是否一致 } @@ -35,23 +34,23 @@ public class PassHandler { * @param inputPass 输入的密码 * @return PassInfo 返回一个密码对象,记得保存 */ - public static PassInfo buildPassword(String inputPass) { + public static PassInfo buildPassword(String inputPass) { // 定义静态方法buildPassword //产生一个6位数的随机码 - String salt = RandomStringUtils.randomAlphabetic(6); + String salt = RandomStringUtils.randomAlphabetic(6); // 生成6位随机字母作为盐 //加密后的密码 - String encryptPassword = Md5Util.md5(Md5Util.md5(inputPass)+salt); + String encryptPassword = Md5Util.md5(Md5Util.md5(inputPass)+salt); // 对输入密码和盐进行双重MD5加密 //返回对象 - return new PassInfo(salt,encryptPassword); + return new PassInfo(salt,encryptPassword); // 返回包含盐和加密密码的PassInfo对象 } - public static void main(String[] args) { + public static void main(String[] args) { // 主方法 - PassInfo info = buildPassword("190601"); + PassInfo info = buildPassword("190601"); // 调用buildPassword方法生成密码信息 - System.out.println(info.getPassword()); - System.out.println(info.getSalt()); + System.out.println(info.getPassword()); // 输出加密后的密码 + System.out.println(info.getSalt()); // 输出生成的盐 } -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassInfo.java b/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassInfo.java index 3634fb6..cba975b 100644 --- a/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassInfo.java +++ b/src-源文件/main/java/com/yf/exam/core/utils/passwd/PassInfo.java @@ -1,38 +1,45 @@ -package com.yf.exam.core.utils.passwd; +package com.yf.exam.core.utils.passwd; // 定义包名 /** * 密码实体 * ClassName: PassInfo
* date: 2018年2月13日 下午7:13:50
* - * @author Bool - * @version + * @author Bool // 作者 + * @version // 版本信息 */ -public class PassInfo { +public class PassInfo { // 定义PassInfo类 - //密码随机串码 - private String salt; + // 密码随机串码 + private String salt; // 声明salt变量 - //MD5后的密码 - private String password; + // MD5后的密码 + private String password; // 声明password变量 - public PassInfo(String salt, String password) { - super(); - this.salt = salt; - this.password = password; + // 构造函数,初始化salt和password + public PassInfo(String salt, String password) { + super(); // 调用父类构造函数 + this.salt = salt; // 设置salt + this.password = password; // 设置password } - public String getSalt() { - return salt; + // 获取salt + public String getSalt() { + return salt; // 返回salt } - public void setSalt(String salt) { - this.salt = salt; + + // 设置salt + public void setSalt(String salt) { + this.salt = salt; // 更新salt } - public String getPassword() { - return password; + + // 获取password + public String getPassword() { + return password; // 返回password } - public void setPassword(String password) { - this.password = password; + + // 设置password + public void setPassword(String password) { + this.password = password; // 更新password } -} - +} \ No newline at end of file