29249 字
约 97 分钟
45
appendix_A
无标签

附录A 公共基础模块源码详解

模块概览(面向 0 基础读者):

  • 公共工具箱,集中维护配置、异常体系、通用工具类。
  • Spring Boot + Jackson + Hibernate Validator 提供统一序列化/校验能力。
  • MyBatis-Plus、雪花算法、加解密工具等在此模块复用。

核心目录:

  • xuecheng-plus-base/pom.xml
  • xuecheng-plus-base/src/main/java/com/xuecheng/base/config
  • xuecheng-plus-base/src/main/java/com/xuecheng/base/exception
  • xuecheng-plus-base/src/main/java/com/xuecheng/base/model
  • xuecheng-plus-base/src/main/java/com/xuecheng/base/utils

文件:xuecheng-plus-base/pom.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
    <modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->

    <parent> <!-- SQL 语句片段 -->
        <groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
        <artifactId>xuecheng-plus-parent</artifactId> <!-- SQL 语句片段 -->
        <version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
        <!--基于当前pom.xml找到父工程-->
        <relativePath>../xuecheng-plus-parent</relativePath> <!-- SQL 语句片段 -->
    </parent> <!-- SQL 语句片段 -->
    <artifactId>xuecheng-plus-base</artifactId> <!-- SQL 语句片段 -->
    <dependencies> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.projectlombok</groupId> <!-- SQL 语句片段 -->
            <artifactId>lombok</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.apache.commons</groupId> <!-- SQL 语句片段 -->
            <artifactId>commons-lang3</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!-- fast Json -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.alibaba</groupId> <!-- SQL 语句片段 -->
            <artifactId>fastjson</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <!-- servlet Api 依赖 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>javax.servlet</groupId> <!-- SQL 语句片段 -->
            <artifactId>javax.servlet-api</artifactId> <!-- SQL 语句片段 -->
            <scope>provided</scope> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <!-- 通用组件 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>commons-lang</groupId> <!-- SQL 语句片段 -->
            <artifactId>commons-lang</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>commons-codec</groupId> <!-- SQL 语句片段 -->
            <artifactId>commons-codec</artifactId> <!-- SQL 语句片段 -->
            <version>1.11</version> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>io.swagger</groupId> <!-- SQL 语句片段 -->
            <artifactId>swagger-annotations</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-web</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-validation</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
            <artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <!--根据扩展名取mimetype-->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.j256.simplemagic</groupId> <!-- SQL 语句片段 -->
            <artifactId>simplemagic</artifactId> <!-- SQL 语句片段 -->
            <version>1.17</version> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>org.apache.commons</groupId> <!-- SQL 语句片段 -->
            <artifactId>commons-lang3</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.google.zxing</groupId> <!-- SQL 语句片段 -->
            <artifactId>core</artifactId> <!-- SQL 语句片段 -->
            <version>3.3.3</version> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->

        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.google.zxing</groupId> <!-- SQL 语句片段 -->
            <artifactId>javase</artifactId> <!-- SQL 语句片段 -->
            <version>3.3.3</version> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.fasterxml.jackson.module</groupId> <!-- SQL 语句片段 -->
            <artifactId>jackson-module-parameter-names</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.fasterxml.jackson.datatype</groupId> <!-- SQL 语句片段 -->
            <artifactId>jackson-datatype-jdk8</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
        <dependency> <!-- SQL 语句片段 -->
            <groupId>com.fasterxml.jackson.datatype</groupId> <!-- SQL 语句片段 -->
            <artifactId>jackson-datatype-jsr310</artifactId> <!-- SQL 语句片段 -->
        </dependency> <!-- SQL 语句片段 -->
    </dependencies> <!-- SQL 语句片段 -->

</project> <!-- SQL 语句片段 -->

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/config/LocalDateTimeConfig.java

package com.xuecheng.base.config; // 声明类所在的包路径

import com.fasterxml.jackson.annotation.JsonInclude; // 导入 JsonInclude 类
import com.fasterxml.jackson.databind.ObjectMapper; // 导入 ObjectMapper 类
import com.fasterxml.jackson.databind.module.SimpleModule; // 导入 SimpleModule 类
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; // 导入 ToStringSerializer 类
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; // 导入 LocalDateTimeDeserializer 类
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; // 导入 LocalDateTimeSerializer 类
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; // 导入 Jackson2ObjectMapperBuilderCustomizer 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; // 导入 Jackson2ObjectMapperBuilder 类

import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.time.format.DateTimeFormatter; // 导入 DateTimeFormatter 类

@Configuration // 使用注解 @Configuration
public class LocalDateTimeConfig { // 定义 class LocalDateTimeConfig

    /* // 保留原作者写的块注释
     * 序列化内容 // 保留原作者写的块注释
     *   LocalDateTime -> String // 保留原作者写的块注释
     * 服务端返回给客户端内容 // 保留原作者写的块注释
     * */ // 保留原作者写的块注释
    @Bean // 使用注解 @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() { // 定义方法 localDateTimeSerializer(...)
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 返回 new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
    } // 代码块结束

    /* // 保留原作者写的块注释
     * 反序列化内容 // 保留原作者写的块注释
     *   String -> LocalDateTime // 保留原作者写的块注释
     * 客户端传入服务端数据 // 保留原作者写的块注释
     * */ // 保留原作者写的块注释
    @Bean // 使用注解 @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer() { // 定义方法 localDateTimeDeserializer(...)
        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 返回 new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
    } // 代码块结束
    //long转string避免精度损失 // 保留原作者写的行内注释
    @Bean // 使用注解 @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { // 定义方法 jacksonObjectMapper(...)
        ObjectMapper objectMapper = builder.createXmlMapper(false).build(); // 把 builder.createXmlMapper(false).build() 的返回值赋给 objectMapper
        //忽略value为null 时 key的输出 // 保留原作者写的行内注释
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 执行语句
        SimpleModule module = new SimpleModule(); // 创建 SimpleModule 对象并赋值给 module
        module.addSerializer(Long.class, ToStringSerializer.instance); // 执行语句
        module.addSerializer(Long.TYPE, ToStringSerializer.instance); // 执行语句
        objectMapper.registerModule(module); // 执行语句
        return objectMapper; // 返回 objectMapper
    } // 代码块结束

    // 配置 // 保留原作者写的行内注释
    @Bean // 使用注解 @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { // 定义方法 jackson2ObjectMapperBuilderCustomizer(...)
        return builder -> { // 返回 builder -> {
            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer()); // 执行语句
            builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer()); // 执行语句
        }; // 执行语句
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/exception/CommonError.java


package com.xuecheng.base.exception; // 声明类所在的包路径

/** // 保留原作者写的块注释
 * @description 通用错误信息 // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @date 2022/9/6 11:29 // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public enum CommonError { // 定义 enum CommonError

	UNKOWN_ERROR("执行过程异常,请重试。"), // 代码逻辑
	PARAMS_ERROR("非法参数"), // 代码逻辑
	OBJECT_NULL("对象为空"), // 代码逻辑
	QUERY_NULL("查询结果为空"), // 代码逻辑
	REQUEST_NULL("请求参数为空"); // 执行语句

	private String errMessage; // 执行语句

	public String getErrMessage() { // 定义方法 getErrMessage(...)
		return errMessage; // 返回 errMessage
	} // 代码块结束

	private CommonError( String errMessage) { // 定义方法 CommonError(...)
		this.errMessage = errMessage; // 把 errMessage 赋值给 this.errMessage
	} // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/exception/GlobalExceptionHandler.java

package com.xuecheng.base.exception; // 声明类所在的包路径

import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.apache.commons.lang3.StringUtils; // 导入 StringUtils 类
import org.springframework.http.HttpStatus; // 导入 HttpStatus 类
import org.springframework.validation.BindingResult; // 导入 BindingResult 类
import org.springframework.web.bind.MethodArgumentNotValidException; // 导入 MethodArgumentNotValidException 类
import org.springframework.web.bind.annotation.*; // 导入 * 类

import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description TODO // 保留原作者写的块注释
 * @date 2023/2/12 17:01 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@ControllerAdvice // 使用注解 @ControllerAdvice
//@RestControllerAdvice // 保留原作者写的行内注释
public class GlobalExceptionHandler { // 定义 class GlobalExceptionHandler

 //对项目的自定义异常类型进行处理 // 保留原作者写的行内注释
   @ResponseBody // 使用注解 @ResponseBody
   @ExceptionHandler(XueChengPlusException.class) // 使用注解 @ExceptionHandler(XueChengPlusException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 使用注解 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
 public RestErrorResponse customException(XueChengPlusException e){ // 定义方法 customException(...)

    //记录异常 // 保留原作者写的行内注释
    log.error("系统异常{}",e.getErrMessage(),e); // 执行语句
    //.. // 保留原作者写的行内注释

    //解析出异常信息 // 保留原作者写的行内注释
    String errMessage = e.getErrMessage(); // 把 e.getErrMessage() 的返回值赋给 errMessage
    RestErrorResponse restErrorResponse = new RestErrorResponse(errMessage); // 创建 RestErrorResponse 对象并赋值给 restErrorResponse
    return restErrorResponse; // 返回 restErrorResponse
   } // 代码块结束

   @ResponseBody // 使用注解 @ResponseBody
   @ExceptionHandler(Exception.class) // 使用注解 @ExceptionHandler(Exception.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 使用注解 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
 public RestErrorResponse exception(Exception e){ // 定义方法 exception(...)

    //记录异常 // 保留原作者写的行内注释
    log.error("系统异常{}",e.getMessage(),e); // 执行语句
    if(e.getMessage().equals("不允许访问")){ // 定义方法 方法(...)
        return new RestErrorResponse("您没有权限操作此功能"); // 返回 new RestErrorResponse("您没有权限操作此功能")
    } // 代码块结束

    //解析出异常信息 // 保留原作者写的行内注释
    RestErrorResponse restErrorResponse = new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage()); // 创建 RestErrorResponse 对象并赋值给 restErrorResponse
    return restErrorResponse; // 返回 restErrorResponse
   } // 代码块结束

   //MethodArgumentNotValidException // 保留原作者写的行内注释
    @ResponseBody // 使用注解 @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class) // 使用注解 @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 使用注解 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e){ // 定义方法 methodArgumentNotValidException(...)

        BindingResult bindingResult = e.getBindingResult(); // 把 e.getBindingResult() 的返回值赋给 bindingResult
        //存储错误信息 // 保留原作者写的行内注释
        List<String> errors = new ArrayList<>(); // 创建 ArrayList<> 对象并赋值给 errors
        bindingResult.getFieldErrors().stream().forEach(item->{ // 定义方法 方法(...)
            errors.add(item.getDefaultMessage()); // 执行语句
        }); // 执行语句

        //将list中的错误信息拼接起来 // 保留原作者写的行内注释
        String errMessage = StringUtils.join(errors, ","); // 把 StringUtils.join(errors, ",") 赋值给 errMessage
        //记录异常 // 保留原作者写的行内注释
        log.error("系统异常{}",e.getMessage(),errMessage); // 执行语句

        //解析出异常信息 // 保留原作者写的行内注释
        RestErrorResponse restErrorResponse = new RestErrorResponse(errMessage); // 创建 RestErrorResponse 对象并赋值给 restErrorResponse
        return restErrorResponse; // 返回 restErrorResponse
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/exception/RestErrorResponse.java

package com.xuecheng.base.exception; // 声明类所在的包路径

import java.io.Serializable; // 导入 Serializable 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 和前端约定返回的异常信息模型 // 保留原作者写的块注释
 * @date 2023/2/12 16:55 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class RestErrorResponse implements Serializable { // 定义 class RestErrorResponse

 private String errMessage; // 执行语句

 public RestErrorResponse(String errMessage){ // 定义方法 RestErrorResponse(...)
  this.errMessage= errMessage; // 把 errMessage 赋值给 this.errMessage
 } // 代码块结束

 public String getErrMessage() { // 定义方法 getErrMessage(...)
  return errMessage; // 返回 errMessage
 } // 代码块结束

 public void setErrMessage(String errMessage) { // 定义方法 setErrMessage(...)
  this.errMessage = errMessage; // 把 errMessage 赋值给 this.errMessage
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/exception/ValidationGroups.java

package com.xuecheng.base.exception; // 声明类所在的包路径

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 用于分级校验,定义一些常用的组 // 保留原作者写的块注释
 * @date 2023/2/14 9:37 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class ValidationGroups { // 定义 class ValidationGroups
 public interface Inster{}; // 定义 interface Inster{};
 public interface Update{}; // 定义 interface Update{};
 public interface Delete{}; // 定义 interface Delete{};
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/exception/XueChengPlusException.java

package com.xuecheng.base.exception; // 声明类所在的包路径

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 本项目自定义异常类型 // 保留原作者写的块注释
 * @date 2023/2/12 16:56 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class XueChengPlusException extends RuntimeException { // 定义 class XueChengPlusException

    private String errMessage; // 执行语句

    public XueChengPlusException() { // 定义方法 XueChengPlusException(...)
    } // 代码块结束

    public XueChengPlusException(String message) { // 定义方法 XueChengPlusException(...)
        super(message); // 执行语句
        this.errMessage = message; // 把 message 赋值给 this.errMessage

    } // 代码块结束

    public String getErrMessage() { // 定义方法 getErrMessage(...)
        return errMessage; // 返回 errMessage
    } // 代码块结束

    public void setErrMessage(String errMessage) { // 定义方法 setErrMessage(...)
        this.errMessage = errMessage; // 把 errMessage 赋值给 this.errMessage
    } // 代码块结束

    public static void cast(String message){ // 定义方法 cast(...)
        throw new XueChengPlusException(message); // 主动抛出异常
    } // 代码块结束
    public static void cast(CommonError error){ // 定义方法 cast(...)
        throw new XueChengPlusException(error.getErrMessage()); // 主动抛出异常
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/model/PageParams.java

package com.xuecheng.base.model; // 声明类所在的包路径

import io.swagger.annotations.ApiModelProperty; // 导入 ApiModelProperty 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 分页查询分页参数 // 保留原作者写的块注释
 * @date 2023/2/11 15:33 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PageParams { // 定义 class PageParams

    //当前页码 // 保留原作者写的行内注释
    @ApiModelProperty("页码") // 使用注解 @ApiModelProperty("页码")
    private Long pageNo = 1L; // 把 1L 赋值给 pageNo
    //每页显示记录数 // 保留原作者写的行内注释
    @ApiModelProperty("每页记录数") // 使用注解 @ApiModelProperty("每页记录数")
    private Long pageSize = 30L; // 把 30L 赋值给 pageSize

    public PageParams() { // 定义方法 PageParams(...)
    } // 代码块结束

    public PageParams(Long pageNo, Long pageSize) { // 定义方法 PageParams(...)
        this.pageNo = pageNo; // 把 pageNo 赋值给 this.pageNo
        this.pageSize = pageSize; // 把 pageSize 赋值给 this.pageSize
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/model/PageResult.java

package com.xuecheng.base.model; // 声明类所在的包路径

import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类

import java.io.Serializable; // 导入 Serializable 类
import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 * @description 分页查询结果模型类 // 保留原作者写的块注释
 * @date 2023/2/11 15:40 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PageResult<T> implements Serializable { // 定义 class PageResult<T>

    // 数据列表 // 保留原作者写的行内注释
    private List<T> items; // 执行语句

    //总记录数 // 保留原作者写的行内注释
    private long counts; // 执行语句

    //当前页码 // 保留原作者写的行内注释
    private long page; // 执行语句

    //每页记录数 // 保留原作者写的行内注释
    private long pageSize; // 执行语句

    public PageResult(List<T> items, long counts, long page, long pageSize) { // 定义方法 PageResult(...)
        this.items = items; // 把 items 赋值给 this.items
        this.counts = counts; // 把 counts 赋值给 this.counts
        this.page = page; // 把 page 赋值给 this.page
        this.pageSize = pageSize; // 把 pageSize 赋值给 this.pageSize
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/model/RestResponse.java

package com.xuecheng.base.model; // 声明类所在的包路径

import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类

/** // 保留原作者写的块注释
 * @description 通用结果类型 // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @date 2022/9/13 14:44 // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 */ // 保留原作者写的块注释

 @Data // 使用注解 @Data
 @ToString // 使用注解 @ToString
public class RestResponse<T> { // 定义 class RestResponse<T>

  /** // 保留原作者写的块注释
   * 响应编码,0为正常,-1错误 // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  private int code; // 执行语句

  /** // 保留原作者写的块注释
   * 响应提示信息 // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  private String msg; // 执行语句

  /** // 保留原作者写的块注释
   * 响应内容 // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  private T result; // 执行语句

  public RestResponse() { // 定义方法 RestResponse(...)
   this(0, "success"); // 执行语句
  } // 代码块结束

  public RestResponse(int code, String msg) { // 定义方法 RestResponse(...)
   this.code = code; // 把 code 赋值给 this.code
   this.msg = msg; // 把 msg 赋值给 this.msg
  } // 代码块结束

  /** // 保留原作者写的块注释
   * 错误信息的封装 // 保留原作者写的块注释
   * // 保留原作者写的块注释
   * @param msg // 保留原作者写的块注释
   * @param <T> // 保留原作者写的块注释
   * @return // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  public static <T> RestResponse<T> validfail(String msg) { // 定义方法 validfail(...)
   RestResponse<T> response = new RestResponse<T>(); // 创建 RestResponse<T> 对象并赋值给 response
   response.setCode(-1); // 执行语句
   response.setMsg(msg); // 执行语句
   return response; // 返回 response
  } // 代码块结束
  public static <T> RestResponse<T> validfail(T result,String msg) { // 定义方法 validfail(...)
   RestResponse<T> response = new RestResponse<T>(); // 创建 RestResponse<T> 对象并赋值给 response
   response.setCode(-1); // 执行语句
   response.setResult(result); // 执行语句
   response.setMsg(msg); // 执行语句
   return response; // 返回 response
  } // 代码块结束

  /** // 保留原作者写的块注释
   * 添加正常响应数据(包含响应内容) // 保留原作者写的块注释
   * // 保留原作者写的块注释
   * @return RestResponse Rest服务封装相应数据 // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  public static <T> RestResponse<T> success(T result) { // 定义方法 success(...)
   RestResponse<T> response = new RestResponse<T>(); // 创建 RestResponse<T> 对象并赋值给 response
   response.setResult(result); // 执行语句
   return response; // 返回 response
  } // 代码块结束
  public static <T> RestResponse<T> success(T result,String msg) { // 定义方法 success(...)
   RestResponse<T> response = new RestResponse<T>(); // 创建 RestResponse<T> 对象并赋值给 response
   response.setResult(result); // 执行语句
   response.setMsg(msg); // 执行语句
   return response; // 返回 response
  } // 代码块结束

  /** // 保留原作者写的块注释
   * 添加正常响应数据(不包含响应内容) // 保留原作者写的块注释
   * // 保留原作者写的块注释
   * @return RestResponse Rest服务封装相应数据 // 保留原作者写的块注释
   */ // 保留原作者写的块注释
  public static <T> RestResponse<T> success() { // 定义方法 success(...)
   return new RestResponse<T>(); // 返回 new RestResponse<T>()
  } // 代码块结束

  public Boolean isSuccessful() { // 定义方法 isSuccessful(...)
   return this.code == 0; // 返回 this.code == 0
  } // 代码块结束

 } // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/Base64Util.java

package com.xuecheng.base.utils; // 声明类所在的包路径

/** // 保留原作者写的块注释
 * Base64 工具类 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class Base64Util { // 定义 class Base64Util
    private static final char last2byte = (char) Integer.parseInt("00000011", 2); // 把 (char) Integer.parseInt("00000011", 2) 赋值给 last2byte
    private static final char last4byte = (char) Integer.parseInt("00001111", 2); // 把 (char) Integer.parseInt("00001111", 2) 赋值给 last4byte
    private static final char last6byte = (char) Integer.parseInt("00111111", 2); // 把 (char) Integer.parseInt("00111111", 2) 赋值给 last6byte
    private static final char lead6byte = (char) Integer.parseInt("11111100", 2); // 把 (char) Integer.parseInt("11111100", 2) 赋值给 lead6byte
    private static final char lead4byte = (char) Integer.parseInt("11110000", 2); // 把 (char) Integer.parseInt("11110000", 2) 赋值给 lead4byte
    private static final char lead2byte = (char) Integer.parseInt("11000000", 2); // 把 (char) Integer.parseInt("11000000", 2) 赋值给 lead2byte
    private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; // 创建 char[]{'A', 对象并赋值给 encodeTable

    public Base64Util() { // 定义方法 Base64Util(...)
    } // 代码块结束

    public static String encode(byte[] from) { // 定义方法 encode(...)
        StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); // 创建 StringBuilder 对象并赋值给 to
        int num = 0; // 把 0 赋值给 num
        char currentByte = 0; // 把 0 赋值给 currentByte

        int i; // 执行语句
        for (i = 0; i < from.length; ++i) { // 定义方法 方法(...)
            for (num %= 8; num < 8; num += 6) { // 定义方法 方法(...)
                switch (num) { // 开始 switch 分支判断
                    case 0: // 处理\u67d0个 case 分支
                        currentByte = (char) (from[i] & lead6byte); // 把 (char) (from[i] & lead6byte) 赋值给 currentByte
                        currentByte = (char) (currentByte >>> 2); // 把 (char) (currentByte >>> 2) 赋值给 currentByte
                    case 1: // 处理\u67d0个 case 分支
                    case 3: // 处理\u67d0个 case 分支
                    case 5: // 处理\u67d0个 case 分支
                    default: // switch 的默认分支
                        break; // 跳出当前循环\u6216分支
                    case 2: // 处理\u67d0个 case 分支
                        currentByte = (char) (from[i] & last6byte); // 把 (char) (from[i] & last6byte) 赋值给 currentByte
                        break; // 跳出当前循环\u6216分支
                    case 4: // 处理\u67d0个 case 分支
                        currentByte = (char) (from[i] & last4byte); // 把 (char) (from[i] & last4byte) 赋值给 currentByte
                        currentByte = (char) (currentByte << 2); // 把 (char) (currentByte << 2) 赋值给 currentByte
                        if (i + 1 < from.length) { // 定义方法 方法(...)
                            currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); // 把 (char) (currentByte | (from[i + 1] & lead2byte) >>> 6) 赋值给 currentByte
                        } // 代码块结束
                        break; // 跳出当前循环\u6216分支
                    case 6: // 处理\u67d0个 case 分支
                        currentByte = (char) (from[i] & last2byte); // 把 (char) (from[i] & last2byte) 赋值给 currentByte
                        currentByte = (char) (currentByte << 4); // 把 (char) (currentByte << 4) 赋值给 currentByte
                        if (i + 1 < from.length) { // 定义方法 方法(...)
                            currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); // 把 (char) (currentByte | (from[i + 1] & lead4byte) >>> 4) 赋值给 currentByte
                        } // 代码块结束
                } // 代码块结束

                to.append(encodeTable[currentByte]); // 执行语句
            } // 代码块结束
        } // 代码块结束

        if (to.length() % 4 != 0) { // 定义方法 方法(...)
            for (i = 4 - to.length() % 4; i > 0; --i) { // 定义方法 方法(...)
                to.append("="); // 把 ") 赋值给 to.append("
            } // 代码块结束
        } // 代码块结束

        return to.toString(); // 返回 to.toString()
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/CommonUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import org.apache.commons.lang.StringUtils; // 导入 StringUtils 类
import org.apache.commons.lang.math.NumberUtils; // 导入 NumberUtils 类

import java.math.BigDecimal; // 导入 BigDecimal 类
import java.time.Duration; // 导入 Duration 类
import java.time.Instant; // 导入 Instant 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.time.temporal.ChronoUnit; // 导入 ChronoUnit 类
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.Collections; // 导入 Collections 类
import java.util.List; // 导入 List 类
import java.util.StringTokenizer; // 导入 StringTokenizer 类
import java.util.regex.Matcher; // 导入 Matcher 类
import java.util.regex.Pattern; // 导入 Pattern 类

/** // 保留原作者写的块注释
 * <P> // 保留原作者写的块注释
 * 通用工具类 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class CommonUtil { // 定义 class CommonUtil

	public static String hiddenMobile(String mobile) { // 定义方法 hiddenMobile(...)
		if (StringUtils.isBlank(mobile)) { // 定义方法 方法(...)
			return ""; // 返回 ""
		} // 代码块结束
		return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"); // 返回 mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2")
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * @param s // 保留原作者写的块注释
	 * @param isFen // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static BigDecimal strToBigDecimal(String s, Boolean isFen) { // 定义方法 strToBigDecimal(...)
		if (StringUtils.isBlank(s)) { // 定义方法 方法(...)
			return null; // 返回 null
		} // 代码块结束
		if (!NumberUtils.isNumber(s)) { // 定义方法 方法(...)
			return null; // 返回 null
		} // 代码块结束
		BigDecimal bd = new BigDecimal(s); // 创建 BigDecimal 对象并赋值给 bd
		if (isFen != null && isFen.booleanValue()){ // 定义方法 方法(...)
			bd = bd.divide(new BigDecimal(100), 2); // 把 bd.divide(new BigDecimal(100), 2) 赋值给 bd
		} // 代码块结束
		return bd; // 返回 bd
	} // 代码块结束

	public static final Pattern shiFenMiaoPattern = Pattern.compile("(\\d{1,2}[::]){0,2}\\d{1,2}"); // 把 Pattern.compile("(\\d{1,2}[::]){0,2}\\d{1,2}") 赋值给 shiFenMiaoPattern

	public static Long shiFenMiaoToSeconds (String shifenmiao) { // 定义方法 shiFenMiaoToSeconds(...)
		if (StringUtils.isBlank(shifenmiao)) { // 定义方法 方法(...)
			return 0L; // 返回 0L
		} // 代码块结束
		Long totalSeconds = 0L; // 把 0L 赋值给 totalSeconds
		shifenmiao = shifenmiao.replaceAll(" ", ""); // 把 shifenmiao.replaceAll(" ", "") 赋值给 shifenmiao
		boolean matched = shiFenMiaoPattern.matcher(shifenmiao).matches(); // 把 shiFenMiaoPattern.matcher(shifenmiao).matches() 的返回值赋给 matched
		if (matched) { // 定义方法 方法(...)
			List<String> sfmList = new ArrayList<>(); // 创建 ArrayList<> 对象并赋值给 sfmList
			StringTokenizer st = new StringTokenizer(shifenmiao,"::"); // 创建 StringTokenizer 对象并赋值给 st
			while (st.hasMoreTokens()) { // 定义方法 方法(...)
				sfmList.add(st.nextToken()); // 执行语句
			} // 代码块结束
			Collections.reverse(sfmList); // 执行语句
			String[] sfmArr = sfmList.toArray(new String[0]); // 把 sfmList.toArray(new String[0]) 赋值给 sfmArr
			for (int i = 0; i < sfmArr.length; i++) { // 定义方法 方法(...)
				if (i == 0) { // 定义方法 方法(...)
					totalSeconds += Long.valueOf(sfmArr[i]); // 把 Long.valueOf(sfmArr[i]) 赋值给 +
				} else if (i == 1) { // 定义方法 if(...)
					totalSeconds += Long.valueOf(sfmArr[i]) * 60; // 把 Long.valueOf(sfmArr[i]) * 60 赋值给 +
				} else if (i == 2) { // 定义方法 if(...)
					totalSeconds += Long.valueOf(sfmArr[i]) * 3600; // 把 Long.valueOf(sfmArr[i]) * 3600 赋值给 +
				} // 代码块结束
			} // 代码块结束
		} // 代码块结束
		return totalSeconds; // 返回 totalSeconds
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 将下划线映射到骆驼命名使用的正则表达式, 预编译正则用于提高效率 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	private static Pattern patternForUTC = Pattern.compile("_([a-z]){1}"); // 把 Pattern.compile("_([a-z]){1}") 赋值给 patternForUTC

	/** // 保留原作者写的块注释
	 * 将下划线映射到骆驼命名 // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String mapUnderscoreToCamelCase(String str) { // 定义方法 mapUnderscoreToCamelCase(...)
		// 先转成全小写 // 保留原作者写的行内注释
		str = str.toLowerCase(); // 把 str.toLowerCase() 的返回值赋给 str
		final Matcher matcher = patternForUTC.matcher(str); // 把 patternForUTC.matcher(str) 赋值给 matcher
		while (matcher.find()) { // 定义方法 方法(...)
			str = str.replaceAll(matcher.group(), matcher.group(1).toUpperCase()); // 把 str.replaceAll(matcher.group(), matcher.group(1).toUpperCase()) 赋值给 str
		} // 代码块结束
		return str; // 返回 str
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 将骆驼命名映射到下划线, 必须是标准的驼峰命名, 否则会出现奇怪的结果 // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String mapCamelCaseToUnderscore(String str) { // 定义方法 mapCamelCaseToUnderscore(...)
		return str.replaceAll("([A-Z]){1}","_$1").toUpperCase(); // 返回 str.replaceAll("([A-Z]){1}","_$1").toUpperCase()
	} // 代码块结束

	public static void main(String[] args) { // 定义方法 main(...)
		Instant start = Instant.parse("2017-10-03T10:15:30.00Z"); // 把 Instant.parse("2017-10-03T10:15:30.00Z") 赋值给 start
		Instant end = Instant.parse("2018-10-04T10:16:30.00Z"); // 把 Instant.parse("2018-10-04T10:16:30.00Z") 赋值给 end

		LocalDateTime time1 = LocalDateTime.of(2019,8,8,8,8); // 把 LocalDateTime.of(2019,8,8,8,8) 赋值给 time1
		LocalDateTime time2 = LocalDateTime.of(2019,9,9,8,8); // 把 LocalDateTime.of(2019,9,9,8,8) 赋值给 time2
		Duration duration = Duration.between(time1, time2); // 把 Duration.between(time1, time2) 赋值给 duration
		System.out.println(duration.getSeconds()); // 执行语句
		System.out.println(duration.isNegative()); // 执行语句
		System.out.println(time1.until(time2, ChronoUnit.SECONDS)); // 执行语句
	} // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/DateUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import org.apache.commons.lang.StringUtils; // 导入 StringUtils 类

import java.text.DateFormat; // 导入 DateFormat 类
import java.text.ParseException; // 导入 ParseException 类
import java.text.SimpleDateFormat; // 导入 SimpleDateFormat 类
import java.time.LocalDate; // 导入 LocalDate 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.time.ZoneId; // 导入 ZoneId 类
import java.time.ZoneOffset; // 导入 ZoneOffset 类
import java.time.format.DateTimeFormatter; // 导入 DateTimeFormatter 类
import java.util.*; // 导入 * 类

/** // 保留原作者写的块注释
 * 日期处理 // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class DateUtil { // 定义 class DateUtil

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; // 把 "yyyy-MM-dd HH:mm:ss" 赋值给 YYYY_MM_DD_HH_MM_SS

    public static final String YYYYMMDD = "yyyyMMdd"; // 把 "yyyyMMdd" 赋值给 YYYYMMDD

    public static final String HHmmss = "HHmmss"; // 把 "HHmmss" 赋值给 HHmmss

    public static final String YYYYMM = "yyyyMM"; // 把 "yyyyMM" 赋值给 YYYYMM

    private DateUtil() { // 定义方法 DateUtil(...)
    } // 代码块结束

    public static String toDateTime(LocalDateTime date) { // 定义方法 toDateTime(...)
        return toDateTime(date, YYYY_MM_DD_HH_MM_SS); // 返回 toDateTime(date, YYYY_MM_DD_HH_MM_SS)
    } // 代码块结束

    public static String toDateTime(LocalDateTime dateTime, String pattern) { // 定义方法 toDateTime(...)
        return dateTime.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE)); // 返回 dateTime.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE))
    } // 代码块结束

    public static String toDateText(LocalDate date, String pattern) { // 定义方法 toDateText(...)
        if (date == null || pattern == null) { // 定义方法 方法(...)
            return null; // 返回 null
        } // 代码块结束
        return date.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE)); // 返回 date.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE))
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 从给定的date,加上hour小时 求指定date时间后hour小时的时间 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param date 指定的时间 // 保留原作者写的块注释
     * @param hour 多少小时后 // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static Date addExtraHour(Date date, int hour) { // 定义方法 addExtraHour(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        if (date != null) { // 定义方法 方法(...)
            cal.setTime(date); // 执行语句
        } // 代码块结束
        cal.add(Calendar.HOUR_OF_DAY, hour); // 执行语句
        return cal.getTime(); // 返回 cal.getTime()
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 从给定的date,加上increase天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param date // 保留原作者写的块注释
     * @param increase // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static Date increaseDay2Date(Date date, int increase) { // 定义方法 increaseDay2Date(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        if (date != null) { // 定义方法 方法(...)
            cal.setTime(date); // 执行语句
        } // 代码块结束
        cal.add(Calendar.DAY_OF_MONTH, increase); // 执行语句
        return cal.getTime(); // 返回 cal.getTime()
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 从给定的LocalDateTime,加上increase月 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param date // 保留原作者写的块注释
     * @param increase // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static LocalDateTime localDateTimeAddMonth(LocalDateTime date, int increase) { // 定义方法 localDateTimeAddMonth(...)
        // LocalDateTime --> Date // 保留原作者写的行内注释
        Date temp = Date.from(date.atZone(ZoneId.systemDefault()).toInstant()); // 把 Date.from(date.atZone(ZoneId.systemDefault()).toInstant()) 赋值给 temp
        // 日期加 // 保留原作者写的行内注释
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        if (temp != null) { // 定义方法 方法(...)
            cal.setTime(temp); // 执行语句
        } // 代码块结束
        cal.add(Calendar.MONTH, increase); // 执行语句
        // LocalDateTime <-- Date // 保留原作者写的行内注释
        return LocalDateTime.ofInstant(cal.getTime().toInstant(), ZoneId.systemDefault()); // 返回 LocalDateTime.ofInstant(cal.getTime().toInstant(), ZoneId.systemDefault())
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 把字符串日期默认转换为yyyy-mm-dd格式的Data对象 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param strDate // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static Date format(String strDate, String format) { // 定义方法 format(...)
        Date d = null; // 把变量 d 初始化为 null
        if (null == strDate || "".equals(strDate)) // 条件判断
            return null; // 返回 null
        else // 条件不满时的处理
            try { // 尝试执行可能抛出异常的代码
                d = getFormatter(format).parse(strDate); // 把 getFormatter(format).parse(strDate) 赋值给 d
            } catch (ParseException pex) { // 定义方法 catch(...)
                return null; // 返回 null
            } // 代码块结束
        return d; // 返回 d
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取一个简单的日期格式化对象 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return 一个简单的日期格式化对象 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    private static SimpleDateFormat getFormatter(String parttern) { // 定义方法 getFormatter(...)
        return new SimpleDateFormat(parttern); // 返回 new SimpleDateFormat(parttern)
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取month所在月的所有天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param month      要查询的日期(如果为null 则默认为当前月) // 保留原作者写的块注释
     * @param dateFormat 返回日期的格式(如果为null 则返回yyyy-MM-dd 格式结果) // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static List<String> getAllDaysOfMonthInString(Date month, DateFormat dateFormat) { // 定义方法 getAllDaysOfMonthInString(...)
        List<String> rs = new ArrayList<String>(); // 创建 ArrayList<String> 对象并赋值给 rs
        DateFormat df = null; // 把变量 df 初始化为 null
        if (null == dateFormat) { // 定义方法 方法(...)
            df = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 df
        } // 代码块结束
        Calendar cad = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cad
        if (null != month) { // 定义方法 方法(...)
            cad.setTime(month); // 执行语句
        } // 代码块结束
        int day_month = cad.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取当月天数 // 把 cad.getActualMaximum(Calendar.DAY_OF_MONTH) 赋值给 day_month
        for (int i = 0; i < day_month; i++) { // 定义方法 方法(...)
            cad.set(Calendar.DAY_OF_MONTH, i + 1); // 执行语句
            rs.add(df.format(cad.getTime())); // 执行语句

        } // 代码块结束
        return rs; // 返回 rs
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取month所在月的所有天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param month 要查询的日期(如果为null 则默认为当前月) // 保留原作者写的块注释
     * @return 日期List // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static List<Date> getAllDaysOfMonth(Date month) { // 定义方法 getAllDaysOfMonth(...)
        List<Date> rs = new ArrayList<Date>(); // 创建 ArrayList<Date> 对象并赋值给 rs
        Calendar cad = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cad
        if (null != month) { // 定义方法 方法(...)
            cad.setTime(month); // 执行语句
        } // 代码块结束
        int day_month = cad.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取当月天数 // 把 cad.getActualMaximum(Calendar.DAY_OF_MONTH) 赋值给 day_month
        for (int i = 0; i < day_month; i++) { // 定义方法 方法(...)
            cad.set(Calendar.DAY_OF_MONTH, i + 1); // 执行语句
            rs.add(cad.getTime()); // 执行语句

        } // 代码块结束
        return rs; // 返回 rs
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取指定日期区间所有天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param begin // 保留原作者写的块注释
     * @param end // 保留原作者写的块注释
     * @param dateFormat (如果为null 则返回yyyy-MM-dd格式的日期) // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static List<String> getSpecifyDaysOfMonthInString(Date begin, Date end, DateFormat dateFormat) { // 定义方法 getSpecifyDaysOfMonthInString(...)
        DateFormat df = null; // 把变量 df 初始化为 null
        if (null == dateFormat) { // 定义方法 方法(...)
            df = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 df
        } // 代码块结束
        List<String> rs = new ArrayList<String>(); // 创建 ArrayList<String> 对象并赋值给 rs
        List<Date> tmplist = getSpecifyDaysOfMonth(begin, end); // 把 getSpecifyDaysOfMonth(begin, end) 赋值给 tmplist
        for (Date date : tmplist) // 遍历循环
            rs.add(df.format(date)); // 执行语句
        return rs; // 返回 rs
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取指定日期区间所有天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param begin // 保留原作者写的块注释
     * @param end // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static List<Date> getSpecifyDaysOfMonth(Date begin, Date end) { // 定义方法 getSpecifyDaysOfMonth(...)
        List<Date> rs = new ArrayList<Date>(); // 创建 ArrayList<Date> 对象并赋值给 rs
        Calendar cad = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cad
        int day_month = -1; // 把 -1 赋值给 day_month
        if (null == begin) {// 设置开始日期为指定日期 // 定义方法 方法(...)
            // day_month = cad.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取当月天数 // 保留原作者写的行内注释
            cad.set(Calendar.DAY_OF_MONTH, 1);// 设置开始日期为当前月的第一天 // 执行语句
            begin = cad.getTime(); // 把 cad.getTime() 的返回值赋给 begin
        } // 代码块结束
        cad.setTime(begin); // 执行语句
        if (null == end) {// 如果结束日期为空 ,设置结束日期为下月的第一天 // 定义方法 方法(...)
            day_month = cad.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取当月天数 // 把 cad.getActualMaximum(Calendar.DAY_OF_MONTH) 赋值给 day_month
            cad.set(Calendar.DAY_OF_MONTH, day_month + 1); // 执行语句
            end = cad.getTime(); // 把 cad.getTime() 的返回值赋给 end
        } // 代码块结束
        cad.set(Calendar.DAY_OF_MONTH, 1);// 设置开始日期为当前月的第一天 // 执行语句
        Date tmp = begin; // 把 begin 赋值给 tmp
        int i = 1; // 把 1 赋值给 i
        while (true) { // 定义方法 方法(...)
            cad.set(Calendar.DAY_OF_MONTH, i); // 执行语句
            i++; // 让 i 自增 1
            tmp = cad.getTime(); // 把 cad.getTime() 的返回值赋给 tmp
            if (tmp.before(end)) { // 定义方法 方法(...)
                rs.add(cad.getTime()); // 执行语句
            } else { // 代码逻辑
                break; // 跳出当前循环\u6216分支
            } // 代码块结束
        } // 代码块结束
        return rs; // 返回 rs
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取当前日期 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return 一个包含年月日的<code>Date</code>型日期 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static synchronized Date getCurrDate() { // 定义方法 getCurrDate(...)
        Calendar calendar = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 calendar
        return calendar.getTime(); // 返回 calendar.getTime()
    } // 代码块结束

    public static String format(Date date, String pattern) { // 定义方法 format(...)
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); // 创建 SimpleDateFormat 对象并赋值给 dateFormat
        return dateFormat.format(date); // 返回 dateFormat.format(date)
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取当前完整时间,样式: yyyy-MM-dd hh:mm:ss // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return 一个包含年月日时分秒的<code>String</code>型日期。yyyy-MM-dd hh:mm:ss // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static String getCurrDateTimeStr() { // 定义方法 getCurrDateTimeStr(...)
        return format(getCurrDate(), YYYY_MM_DD_HH_MM_SS); // 返回 format(getCurrDate(), YYYY_MM_DD_HH_MM_SS)
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获得指定日期的前一天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param specifiedDay YYYY_MM_DD_HH_MM_SS 格式 // 保留原作者写的块注释
     * @param formatStr    日期类型 // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static String getSpecifiedDayBefore(String specifiedDay, String formatStr) {// 可以用new // 定义方法 getSpecifiedDayBefore(...)
        // Date().toLocalString()传递参数 // 保留原作者写的行内注释
        Calendar c = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 c
        Date date = null; // 把变量 date 初始化为 null
        try { // 尝试执行可能抛出异常的代码
            date = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).parse(specifiedDay); // 创建 SimpleDateFormat 对象并赋值给 date
        } catch (ParseException e) { // 定义方法 catch(...)
            e.printStackTrace(); // 执行语句
        } // 代码块结束
        c.setTime(date); // 执行语句
        int day = c.get(Calendar.DATE); // 把 c.get(Calendar.DATE) 赋值给 day
        c.set(Calendar.DATE, day - 1); // 执行语句

        String dayBefore = new SimpleDateFormat(formatStr).format(c.getTime()); // 创建 SimpleDateFormat 对象并赋值给 dayBefore
        return dayBefore; // 返回 dayBefore
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获得指定日期的后一天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param specifiedDay YYYY_MM_DD_HH_MM_SS 格式 // 保留原作者写的块注释
     * @param formatStr    日期类型 // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static String getSpecifiedDayAfter(String specifiedDay, String formatStr) { // 定义方法 getSpecifiedDayAfter(...)
        Calendar c = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 c
        Date date = null; // 把变量 date 初始化为 null
        try { // 尝试执行可能抛出异常的代码
            date = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).parse(specifiedDay); // 创建 SimpleDateFormat 对象并赋值给 date
        } catch (ParseException e) { // 定义方法 catch(...)
            e.printStackTrace(); // 执行语句
        } // 代码块结束
        c.setTime(date); // 执行语句
        int day = c.get(Calendar.DATE); // 把 c.get(Calendar.DATE) 赋值给 day
        c.set(Calendar.DATE, day + 1); // 执行语句

        String dayAfter = new SimpleDateFormat(formatStr).format(c.getTime()); // 创建 SimpleDateFormat 对象并赋值给 dayAfter
        return dayAfter; // 返回 dayAfter
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取本周第一天的日期 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final String getWeekFirstDay() { // 定义方法 getWeekFirstDay(...)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        int day_of_week = cal.get(Calendar.DAY_OF_WEEK) - 2; // 把 cal.get(Calendar.DAY_OF_WEEK) - 2 赋值给 day_of_week
        cal.add(Calendar.DATE, -day_of_week); // 执行语句
        return sdf.format(cal.getTime()); // 返回 sdf.format(cal.getTime())
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取当前月的第一天 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final String getCurrentMonthFirstDay() { // 定义方法 getCurrentMonthFirstDay(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        // 当前月的第一天 // 保留原作者写的行内注释
        cal.set(GregorianCalendar.DAY_OF_MONTH, 1); // 执行语句
        Date beginTime = cal.getTime(); // 把 cal.getTime() 的返回值赋给 beginTime
        return sdf.format(beginTime); // 返回 sdf.format(beginTime)
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取昨天开始时间 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final String getYesterdayStart() { // 定义方法 getYesterdayStart(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        cal.add(Calendar.DATE, -1); // 执行语句
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        return sdf.format(cal.getTime()); // 返回 sdf.format(cal.getTime())
    } // 代码块结束

    public static final String getYesterdayEnd() { // 定义方法 getYesterdayEnd(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        cal.add(Calendar.DATE, -1); // 执行语句
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        return sdf.format(cal.getTime()) + " 23:59:59"; // 返回 sdf.format(cal.getTime()) + " 23:59:59"
    } // 代码块结束

    public static final String getCurrDayStart() { // 定义方法 getCurrDayStart(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        return sdf.format(cal.getTime()); // 返回 sdf.format(cal.getTime())
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 功能:获取指定月份的第一天<br/> // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final String getStartDayWithMonth(String month) throws ParseException { // 定义方法 getStartDayWithMonth(...)
        Calendar calendar = new GregorianCalendar(); // 创建 GregorianCalendar 对象并赋值给 calendar
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        SimpleDateFormat mf = new SimpleDateFormat("yyyy-MM"); // 创建 SimpleDateFormat 对象并赋值给 mf
        Date date = mf.parse(month); // 把 mf.parse(month) 赋值给 date
        calendar.setTime(date); // 执行语句
        calendar.add(Calendar.DATE, 0);// 因为格式化时默认了DATE为本月第一天所以此处为0 // 执行语句
        return sdf.format(calendar.getTime()); // 返回 sdf.format(calendar.getTime())
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 功能:获取指定月份的最后一天<br/> // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final String getEndDayWithMonth(String month) throws ParseException { // 定义方法 getEndDayWithMonth(...)
        Calendar calendar = new GregorianCalendar(); // 创建 GregorianCalendar 对象并赋值给 calendar
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        SimpleDateFormat mf = new SimpleDateFormat("yyyy-MM"); // 创建 SimpleDateFormat 对象并赋值给 mf
        Date date = mf.parse(month); // 把 mf.parse(month) 赋值给 date
        calendar.setTime(date); // 执行语句
        calendar.roll(Calendar.DATE, -1);// api解释roll():向指定日历字段添加指定(有符号的)时间量,不更改更大的字段 // 执行语句
        return sdf.format(calendar.getTime()); // 返回 sdf.format(calendar.getTime())
    } // 代码块结束

    public static final String formatYearMonthDay(String dateStr) throws ParseException { // 定义方法 formatYearMonthDay(...)
        if (StringUtils.isNotBlank(dateStr)) { // 定义方法 方法(...)
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
            Date date = sdf.parse(dateStr); // 把 sdf.parse(dateStr) 赋值给 date
            return sdf.format(date); // 返回 sdf.format(date)
        } else { // 代码逻辑
            return ""; // 返回 ""
        } // 代码块结束
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 功能:<br/> // 保留原作者写的块注释
     * 根据时间 yyyy-MM-dd 获取该日期是本月第几周 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final int getWeekIndexOfMonth(String dateStr) throws ParseException { // 定义方法 getWeekIndexOfMonth(...)

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdf
        Date date = sdf.parse(dateStr); // 把 sdf.parse(dateStr) 赋值给 date
        Calendar calendar = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 calendar
        calendar.setTime(date); // 执行语句
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH); // 把 calendar.get(Calendar.WEEK_OF_MONTH) 赋值给 weekOfMonth
        return weekOfMonth; // 返回 weekOfMonth
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 获取当前时间到指定时间距离多少秒 功能:<br/> // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static final int getSecondToDesignationTime(String designationTime) { // 定义方法 getSecondToDesignationTime(...)
        // 24小时制 // 保留原作者写的行内注释
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建 SimpleDateFormat 对象并赋值给 dateFormat
        Date toDate; // 执行语句
        try { // 尝试执行可能抛出异常的代码
            toDate = dateFormat.parse(designationTime); // 把 dateFormat.parse(designationTime) 赋值给 toDate
            int u = (int) ((toDate.getTime() - dateFormat.parse(DateUtil.getCurrDateTimeStr()).getTime()) / 1000); // 把 (int) ((toDate.getTime() - dateFormat.parse(DateUtil.getCurrDateTimeStr()).getTime()) / 1000) 赋值给 u
            return u; // 返回 u
        } catch (ParseException e) { // 定义方法 catch(...)
            e.printStackTrace(); // 执行语句
        } // 代码块结束
        return 0; // 返回 0
    } // 代码块结束

    public static final int getYear() { // 定义方法 getYear(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        return cal.get(cal.YEAR); // 返回 cal.get(cal.YEAR)
    } // 代码块结束

    public static final int getMonth() { // 定义方法 getMonth(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        return cal.get(cal.MONTH) + 1; // 返回 cal.get(cal.MONTH) + 1
    } // 代码块结束

    public static final int getDay() { // 定义方法 getDay(...)
        Calendar cal = Calendar.getInstance(); // 把 Calendar.getInstance() 的返回值赋给 cal
        return cal.get(cal.DATE); // 返回 cal.get(cal.DATE)
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 通过时间秒毫秒数判断两个时间的间隔 // 保留原作者写的块注释
     * // 保留原作者写的块注释
     * @param start // 保留原作者写的块注释
     * @param end // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static int differentDaysByMillisecond(LocalDateTime start, LocalDateTime end) { // 定义方法 differentDaysByMillisecond(...)
        // ZoneOffset.of("+8") 是指定为东8区 // 保留原作者写的行内注释
        return (int) ((end.toInstant(ZoneOffset.of("+8")).toEpochMilli() - start.toInstant(ZoneOffset.of("+8")).toEpochMilli()) / (1000 * 3600 * 24)); // 返回 (int) ((end.toInstant(ZoneOffset.of("+8")).toEpochMilli() - start.toInstant(ZoneOffset.of("+8")).toEpochMilli()) / (1000 * 3600 * 24))
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/EncryptUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import org.slf4j.Logger; // 导入 Logger 类
import org.slf4j.LoggerFactory; // 导入 LoggerFactory 类

import java.io.UnsupportedEncodingException; // 导入 UnsupportedEncodingException 类
import java.net.URLDecoder; // 导入 URLDecoder 类
import java.net.URLEncoder; // 导入 URLEncoder 类
import java.util.Base64; // 导入 Base64 类

public class EncryptUtil { // 定义 class EncryptUtil
    private static final Logger logger = LoggerFactory.getLogger(EncryptUtil.class); // 把 LoggerFactory.getLogger(EncryptUtil.class) 赋值给 logger

    public static String encodeBase64(byte[] bytes){ // 定义方法 encodeBase64(...)
        String encoded = Base64.getEncoder().encodeToString(bytes); // 把 Base64.getEncoder().encodeToString(bytes) 赋值给 encoded
        return encoded; // 返回 encoded
    } // 代码块结束

    public static byte[]  decodeBase64(String str){ // 定义方法 decodeBase64(...)
        byte[] bytes = null; // 把变量 bytes 初始化为 null
        bytes = Base64.getDecoder().decode(str); // 把 Base64.getDecoder().decode(str) 赋值给 bytes
        return bytes; // 返回 bytes
    } // 代码块结束

    public static String encodeUTF8StringBase64(String str){ // 定义方法 encodeUTF8StringBase64(...)
        String encoded = null; // 把变量 encoded 初始化为 null
        try { // 尝试执行可能抛出异常的代码
            encoded = Base64.getEncoder().encodeToString(str.getBytes("utf-8")); // 把 Base64.getEncoder().encodeToString(str.getBytes("utf-8")) 赋值给 encoded
        } catch (UnsupportedEncodingException e) { // 定义方法 catch(...)
            logger.warn("不支持的编码格式",e); // 执行语句
        } // 代码块结束
        return encoded; // 返回 encoded

    } // 代码块结束

    public static String  decodeUTF8StringBase64(String str){ // 定义方法 decodeUTF8StringBase64(...)
        String decoded = null; // 把变量 decoded 初始化为 null
        byte[] bytes = Base64.getDecoder().decode(str); // 把 Base64.getDecoder().decode(str) 赋值给 bytes
        try { // 尝试执行可能抛出异常的代码
            decoded = new String(bytes,"utf-8"); // 创建 String 对象并赋值给 decoded
        }catch(UnsupportedEncodingException e){ // 定义方法 方法(...)
            logger.warn("不支持的编码格式",e); // 执行语句
        } // 代码块结束
        return decoded; // 返回 decoded
    } // 代码块结束

    public static String encodeURL(String url) { // 定义方法 encodeURL(...)
    	String encoded = null; // 把变量 encoded 初始化为 null
		try { // 尝试执行可能抛出异常的代码
			encoded =  URLEncoder.encode(url, "utf-8"); // 把 URLEncoder.encode(url, "utf-8") 赋值给 encoded
		} catch (UnsupportedEncodingException e) { // 定义方法 catch(...)
			logger.warn("URLEncode失败", e); // 执行语句
		} // 代码块结束
		return encoded; // 返回 encoded
	} // 代码块结束

	public static String decodeURL(String url) { // 定义方法 decodeURL(...)
    	String decoded = null; // 把变量 decoded 初始化为 null
		try { // 尝试执行可能抛出异常的代码
			decoded = URLDecoder.decode(url, "utf-8"); // 把 URLDecoder.decode(url, "utf-8") 赋值给 decoded
		} catch (UnsupportedEncodingException e) { // 定义方法 catch(...)
			logger.warn("URLDecode失败", e); // 执行语句
		} // 代码块结束
		return decoded; // 返回 decoded
	} // 代码块结束

    public static void main(String [] args){ // 定义方法 main(...)
        String str = "abcd{'a':'b'}"; // 把 "abcd{'a':'b'}" 赋值给 str
        String encoded = EncryptUtil.encodeUTF8StringBase64(str); // 把 EncryptUtil.encodeUTF8StringBase64(str) 赋值给 encoded
        String decoded = EncryptUtil.decodeUTF8StringBase64(encoded); // 把 EncryptUtil.decodeUTF8StringBase64(encoded) 赋值给 decoded
        System.out.println(str); // 执行语句
        System.out.println(encoded); // 执行语句
        System.out.println(decoded); // 执行语句

        String url = "== wo"; // 执行语句
        String urlEncoded = EncryptUtil.encodeURL(url); // 把 EncryptUtil.encodeURL(url) 赋值给 urlEncoded
        String urlDecoded = EncryptUtil.decodeURL(urlEncoded); // 把 EncryptUtil.decodeURL(urlEncoded) 赋值给 urlDecoded
        
        System.out.println(url); // 执行语句
        System.out.println(urlEncoded); // 执行语句
        System.out.println(urlDecoded); // 执行语句
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/FileUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.io.*; // 导入 * 类

/** // 保留原作者写的块注释
 * 文件读取工具类 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class FileUtil { // 定义 class FileUtil

    /** // 保留原作者写的块注释
     * 读取文件内容,作为字符串返回 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static String readFileAsString(String filePath) throws IOException { // 定义方法 readFileAsString(...)
        File file = new File(filePath); // 创建 File 对象并赋值给 file
        if (!file.exists()) { // 定义方法 方法(...)
            throw new FileNotFoundException(filePath); // 主动抛出异常
        }  // 代码块结束

        if (file.length() > 1024 * 1024 * 1024) { // 定义方法 方法(...)
            throw new IOException("File is too large"); // 主动抛出异常
        }  // 代码块结束

        StringBuilder sb = new StringBuilder((int) (file.length())); // 创建 StringBuilder 对象并赋值给 sb
        // 创建字节输入流   // 保留原作者写的行内注释
        FileInputStream fis = new FileInputStream(filePath);   // 创建 FileInputStream 对象并赋值给 fis
        // 创建一个长度为10240的Buffer // 保留原作者写的行内注释
        byte[] bbuf = new byte[10240];   // 创建 byte[10240] 对象并赋值给 bbuf
        // 用于保存实际读取的字节数   // 保留原作者写的行内注释
        int hasRead = 0;   // 把 0 赋值给 hasRead
        while ( (hasRead = fis.read(bbuf)) > 0 ) {   // 定义方法 方法(...)
            sb.append(new String(bbuf, 0, hasRead));   // 执行语句
        }   // 代码块结束
        fis.close();   // 执行语句
        return sb.toString(); // 返回 sb.toString()
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 根据文件路径读取byte[] 数组 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static byte[] readFileByBytes(String filePath) throws IOException { // 定义方法 readFileByBytes(...)
        File file = new File(filePath); // 创建 File 对象并赋值给 file
        if (!file.exists()) { // 定义方法 方法(...)
            throw new FileNotFoundException(filePath); // 主动抛出异常
        } else { // 代码逻辑
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); // 创建 ByteArrayOutputStream 对象并赋值给 bos
            BufferedInputStream in = null; // 把变量 in 初始化为 null

            try { // 尝试执行可能抛出异常的代码
                in = new BufferedInputStream(new FileInputStream(file)); // 创建 BufferedInputStream 对象并赋值给 in
                short bufSize = 1024; // 把 1024 赋值给 bufSize
                byte[] buffer = new byte[bufSize]; // 创建 byte[bufSize] 对象并赋值给 buffer
                int len1; // 执行语句
                while (-1 != (len1 = in.read(buffer, 0, bufSize))) { // 定义方法 方法(...)
                    bos.write(buffer, 0, len1); // 执行语句
                } // 代码块结束

                byte[] var7 = bos.toByteArray(); // 把 bos.toByteArray() 的返回值赋给 var7
                return var7; // 返回 var7
            } finally { // 代码逻辑
                try { // 尝试执行可能抛出异常的代码
                    if (in != null) { // 定义方法 方法(...)
                        in.close(); // 执行语句
                    } // 代码块结束
                } catch (IOException var14) { // 定义方法 catch(...)
                    var14.printStackTrace(); // 执行语句
                } // 代码块结束

                bos.close(); // 执行语句
            } // 代码块结束
        } // 代码块结束
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/HttpUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类

import javax.servlet.http.HttpServletResponse; // 导入 HttpServletResponse 类
import java.io.BufferedReader; // 导入 BufferedReader 类
import java.io.DataOutputStream; // 导入 DataOutputStream 类
import java.io.IOException; // 导入 IOException 类
import java.io.InputStreamReader; // 导入 InputStreamReader 类
import java.net.HttpURLConnection; // 导入 HttpURLConnection 类
import java.net.URL; // 导入 URL 类
import java.util.List; // 导入 List 类
import java.util.Map; // 导入 Map 类

/** // 保留原作者写的块注释
 * http 工具类 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class HttpUtil { // 定义 class HttpUtil

    public static void writerError(RestResponse restResponse, HttpServletResponse response) throws IOException { // 定义方法 writerError(...)
        response.setContentType("application/json,charset=utf-8"); // 把 utf-8") 赋值给 response.setContentType("application/json,charset
        response.setStatus(Integer.valueOf(restResponse.getCode())); // 执行语句
        JSON.writeJSONString(response.getOutputStream(), restResponse); // 执行语句
    } // 代码块结束

    public static String getAccessToken(String ak,String sk) throws  Exception { // 定义方法 getAccessToken(...)
        // 获取token地址 // 保留原作者写的行内注释
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?"; // 代码逻辑
        String getAccessTokenUrl = authHost // 代码逻辑
                // 1. grant_type为固定参数 // 保留原作者写的行内注释
                + "grant_type=client_credentials" // 代码逻辑
                // 2. 官网获取的 API Key // 保留原作者写的行内注释
                + "&client_id=" + ak // 代码逻辑
                // 3. 官网获取的 Secret Key // 保留原作者写的行内注释
                + "&client_secret=" + sk; // 把 " + sk 赋值给 "&client_secret
            URL realUrl = new URL(getAccessTokenUrl); // 创建 URL 对象并赋值给 realUrl
            // 打开和URL之间的连接 // 保留原作者写的行内注释
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); // 把 (HttpURLConnection) realUrl.openConnection() 的返回值赋给 connection
            connection.setRequestMethod("GET"); // 执行语句
            connection.connect(); // 执行语句
            // 获取所有响应头字段 // 保留原作者写的行内注释
            /*Map<String, List<String>> map = connection.getHeaderFields(); // 保留原作者写的块注释
            // 遍历所有的响应头字段 // 保留原作者写的行内注释
            for (String key : map.keySet()) { // 定义方法 方法(...)
                System.err.println(key + "--->" + map.get(key)); // 执行语句
            }*/ // 代码逻辑
            // 定义 BufferedReader输入流来读取URL的响应 // 保留原作者写的行内注释
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // 创建 BufferedReader 对象并赋值给 in
            String result = ""; // 把 "" 赋值给 result
            String line; // 执行语句
            while ((line = in.readLine()) != null) { // 定义方法 方法(...)
                result += line; // 把 line 赋值给 +
            } // 代码块结束
            in.close(); // 执行语句
            connection.disconnect(); // 执行语句
            /** // 保留原作者写的块注释
             * 返回结果 // 保留原作者写的块注释
             */ // 保留原作者写的块注释
            Map<String,Object> resultMap= JsonUtil.jsonToMap(result); // 把 JsonUtil.jsonToMap(result) 赋值给 resultMap
            return resultMap.get("access_token").toString(); // 返回 resultMap.get("access_token").toString()
    } // 代码块结束

    public static String post(String requestUrl, String accessToken, String params) // 代码逻辑
            throws Exception { // 代码逻辑
        String contentType = "application/x-www-form-urlencoded"; // 把 "application/x-www-form-urlencoded" 赋值给 contentType
        return HttpUtil.post(requestUrl, accessToken, contentType, params); // 返回 HttpUtil.post(requestUrl, accessToken, contentType, params)
    } // 代码块结束

    public static String post(String requestUrl, String accessToken, String contentType, String params) // 代码逻辑
            throws Exception { // 代码逻辑
        String encoding = "UTF-8"; // 把 "UTF-8" 赋值给 encoding
        if (requestUrl.contains("nlp")) { // 定义方法 方法(...)
            encoding = "GBK"; // 把 "GBK" 赋值给 encoding
        } // 代码块结束
        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding); // 返回 HttpUtil.post(requestUrl, accessToken, contentType, params, encoding)
    } // 代码块结束

    public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding) // 代码逻辑
            throws Exception { // 代码逻辑
        String url = requestUrl + "?access_token=" + accessToken; // 把 requestUrl + "?access_token=" + accessToken 赋值给 url
        return HttpUtil.postGeneralUrl(url, contentType, params, encoding); // 返回 HttpUtil.postGeneralUrl(url, contentType, params, encoding)
    } // 代码块结束

    public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding) // 代码逻辑
            throws Exception { // 代码逻辑
        URL url = new URL(generalUrl); // 创建 URL 对象并赋值给 url
        // 打开和URL之间的连接 // 保留原作者写的行内注释
        HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 把 (HttpURLConnection) url.openConnection() 的返回值赋给 connection
        connection.setRequestMethod("POST"); // 执行语句
        // 设置通用的请求属性 // 保留原作者写的行内注释
        connection.setRequestProperty("Content-Type", contentType); // 执行语句
        connection.setRequestProperty("Connection", "Keep-Alive"); // 执行语句
        connection.setUseCaches(false); // 执行语句
        connection.setDoOutput(true); // 执行语句
        connection.setDoInput(true); // 执行语句
        connection.setConnectTimeout(20000); // 执行语句
        connection.setReadTimeout(20000); // 执行语句

        // 得到请求的输出流对象 // 保留原作者写的行内注释
        DataOutputStream out = new DataOutputStream(connection.getOutputStream()); // 创建 DataOutputStream 对象并赋值给 out
        out.write(params.getBytes(encoding)); // 执行语句
        out.flush(); // 执行语句
        out.close(); // 执行语句

        // 建立实际的连接 // 保留原作者写的行内注释
        connection.connect(); // 执行语句
        // 获取所有响应头字段 // 保留原作者写的行内注释
        Map<String, List<String>> headers = connection.getHeaderFields(); // 把 connection.getHeaderFields() 的返回值赋给 headers
        // 遍历所有的响应头字段 // 保留原作者写的行内注释
        /*for (String key : headers.keySet()) { // 保留原作者写的块注释
            System.err.println(key + "--->" + headers.get(key)); // 执行语句
        }*/ // 代码逻辑
        // 定义 BufferedReader输入流来读取URL的响应 // 保留原作者写的行内注释
        BufferedReader in = null; // 把变量 in 初始化为 null
        in = new BufferedReader( // 代码逻辑
                new InputStreamReader(connection.getInputStream(), encoding)); // 执行语句
        String result = ""; // 把 "" 赋值给 result
        String getLine; // 执行语句
        while ((getLine = in.readLine()) != null) { // 定义方法 方法(...)
            result += getLine; // 把 getLine 赋值给 +
        } // 代码块结束
        in.close(); // 执行语句
        connection.disconnect(); // 执行语句
        //System.err.println("result:" + result); // 保留原作者写的行内注释
        return result; // 返回 result
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/IDCardUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.util.Calendar; // 导入 Calendar 类
import java.util.HashMap; // 导入 HashMap 类
import java.util.Map; // 导入 Map 类

/** // 保留原作者写的块注释
 * <P> // 保留原作者写的块注释
 * 身份证号工具类 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class IDCardUtil { // 定义 class IDCardUtil

	/** // 保留原作者写的块注释
	 * 通过身份证号码获取出生日期、性别、年龄 // 保留原作者写的块注释
	 * @param idNumber // 保留原作者写的块注释
	 * @return 返回的出生日期格式:1990-01-01   性别格式:F-女,M-男 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static Map<String, String> getInfo(String idNumber) { // 定义方法 getInfo(...)
		String birthday = ""; // 把 "" 赋值给 birthday
		String age = ""; // 把 "" 赋值给 age
		String gender = ""; // 把 "" 赋值给 gender

		int year = Calendar.getInstance().get(Calendar.YEAR); // 把 Calendar.getInstance().get(Calendar.YEAR) 赋值给 year
		char[] number = idNumber.toCharArray(); // 把 idNumber.toCharArray() 的返回值赋给 number
		if (idNumber.length() == 15) { // 定义方法 方法(...)
			birthday = "19" + idNumber.substring(6, 8) + "-" + idNumber.substring(8, 10) + "-" + idNumber // 代码逻辑
					.substring(10, 12); // 执行语句
			gender = // 代码逻辑
					Integer.parseInt(idNumber.substring(idNumber.length() - 3, idNumber.length())) % 2 == 0 ? "F" : "M"; // 执行语句
			age = (year - Integer.parseInt("19" + idNumber.substring(6, 8))) + ""; // 把 (year - Integer.parseInt("19" + idNumber.substring(6, 8))) + "" 赋值给 age
		} else if (idNumber.length() == 18) { // 定义方法 if(...)
			birthday = idNumber.substring(6, 10) + "-" + idNumber.substring(10, 12) + "-" + idNumber.substring(12, 14); // 把 idNumber.substring(6, 10) + "-" + idNumber.substring(10, 12) + "-" + idNumber.substring(12, 14) 赋值给 birthday
			gender = Integer.parseInt(idNumber.substring(idNumber.length() - 4, idNumber.length() - 1)) % 2 == 0 ? // 代码逻辑
					"女" : // 代码逻辑
					"男"; // 执行语句
			age = (year - Integer.parseInt(idNumber.substring(6, 10))) + ""; // 把 (year - Integer.parseInt(idNumber.substring(6, 10))) + "" 赋值给 age
		} // 代码块结束
		Map<String, String> map = new HashMap(); // 创建 HashMap 对象并赋值给 map
		map.put("birthday", birthday); // 执行语句
		map.put("age", age); // 执行语句
		map.put("gender", gender); // 执行语句
		return map; // 返回 map
	} // 代码块结束

	public static void main(String[] args) { // 定义方法 main(...)
		System.out.println(getInfo("658182198109222913")); // 执行语句
	} // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/IdWorkerUtils.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.util.Random; // 导入 Random 类

/** // 保留原作者写的块注释
 * snow flow . // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public final class IdWorkerUtils { // 代码逻辑

	private static final Random RANDOM = new Random(); // 创建 Random 对象并赋值给 RANDOM

	private static final long WORKER_ID_BITS = 5L; // 把 5L 赋值给 WORKER_ID_BITS

	private static final long DATACENTERIDBITS = 5L; // 把 5L 赋值给 DATACENTERIDBITS

	private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS); // 把 ~(-1L << WORKER_ID_BITS) 赋值给 MAX_WORKER_ID

	private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTERIDBITS); // 把 ~(-1L << DATACENTERIDBITS) 赋值给 MAX_DATACENTER_ID

	private static final long SEQUENCE_BITS = 12L; // 把 12L 赋值给 SEQUENCE_BITS

	private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; // 把 SEQUENCE_BITS 赋值给 WORKER_ID_SHIFT

	private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; // 把 SEQUENCE_BITS + WORKER_ID_BITS 赋值给 DATACENTER_ID_SHIFT

	private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTERIDBITS; // 把 SEQUENCE_BITS + WORKER_ID_BITS + DATACENTERIDBITS 赋值给 TIMESTAMP_LEFT_SHIFT

	private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); // 把 ~(-1L << SEQUENCE_BITS) 赋值给 SEQUENCE_MASK

	private static final IdWorkerUtils ID_WORKER_UTILS = new IdWorkerUtils(); // 创建 IdWorkerUtils 对象并赋值给 ID_WORKER_UTILS

	private long workerId; // 执行语句

	private long datacenterId; // 执行语句

	private long idepoch; // 执行语句

	private long sequence = '0'; // 把 '0' 赋值给 sequence

	private long lastTimestamp = -1L; // 把 -1L 赋值给 lastTimestamp

	private IdWorkerUtils() { // 定义方法 IdWorkerUtils(...)
		this(RANDOM.nextInt((int) MAX_WORKER_ID), RANDOM.nextInt((int) MAX_DATACENTER_ID), 1288834974657L); // 执行语句
	} // 代码块结束

	private IdWorkerUtils(final long workerId, final long datacenterId, final long idepoch) { // 定义方法 IdWorkerUtils(...)
		if (workerId > MAX_WORKER_ID || workerId < 0) { // 定义方法 方法(...)
			throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID)); // 主动抛出异常
		} // 代码块结束
		if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) { // 定义方法 方法(...)
			throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", MAX_DATACENTER_ID)); // 主动抛出异常
		} // 代码块结束
		this.workerId = workerId; // 把 workerId 赋值给 this.workerId
		this.datacenterId = datacenterId; // 把 datacenterId 赋值给 this.datacenterId
		this.idepoch = idepoch; // 把 idepoch 赋值给 this.idepoch
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * Gets instance. // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @return the instance // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static IdWorkerUtils getInstance() { // 定义方法 getInstance(...)
		return ID_WORKER_UTILS; // 返回 ID_WORKER_UTILS
	} // 代码块结束

	public synchronized long nextId() { // 定义方法 nextId(...)
		long timestamp = timeGen(); // 把 timeGen() 的返回值赋给 timestamp
		if (timestamp < lastTimestamp) { // 定义方法 方法(...)
			throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); // 主动抛出异常
		} // 代码块结束
		if (lastTimestamp == timestamp) { // 定义方法 方法(...)
			sequence = (sequence + 1) & SEQUENCE_MASK; // 把 (sequence + 1) & SEQUENCE_MASK 赋值给 sequence
			if (sequence == 0) { // 定义方法 方法(...)
				timestamp = tilNextMillis(lastTimestamp); // 把 tilNextMillis(lastTimestamp) 赋值给 timestamp
			} // 代码块结束
		} else { // 代码逻辑
			sequence = 0L; // 把 0L 赋值给 sequence
		} // 代码块结束

		lastTimestamp = timestamp; // 把 timestamp 赋值给 lastTimestamp

		return ((timestamp - idepoch) << TIMESTAMP_LEFT_SHIFT) // 返回 ((timestamp - idepoch) << TIMESTAMP_LEFT_SHIFT)
				| (datacenterId << DATACENTER_ID_SHIFT) // 代码逻辑
				| (workerId << WORKER_ID_SHIFT) | sequence; // 执行语句
	} // 代码块结束

	private long tilNextMillis(final long lastTimestamp) { // 定义方法 tilNextMillis(...)
		long timestamp = timeGen(); // 把 timeGen() 的返回值赋给 timestamp
		while (timestamp <= lastTimestamp) { // 定义方法 方法(...)
			timestamp = timeGen(); // 把 timeGen() 的返回值赋给 timestamp
		} // 代码块结束
		return timestamp; // 返回 timestamp
	} // 代码块结束

	private long timeGen() { // 定义方法 timeGen(...)
		return System.currentTimeMillis(); // 返回 System.currentTimeMillis()
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * Build part number string. // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @return the string // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public String buildPartNumber() { // 定义方法 buildPartNumber(...)
		return String.valueOf(ID_WORKER_UTILS.nextId()); // 返回 String.valueOf(ID_WORKER_UTILS.nextId())
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * Create uuid string. // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @return the string // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public String createUUID() { // 定义方法 createUUID(...)
		return String.valueOf(ID_WORKER_UTILS.nextId()); // 返回 String.valueOf(ID_WORKER_UTILS.nextId())
	} // 代码块结束

	public static void main(String[] args) { // 定义方法 main(...)
		System.out.println(IdWorkerUtils.getInstance().nextId()); // 执行语句
	} // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/IPUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类
import java.net.InetAddress; // 导入 InetAddress 类
import java.net.UnknownHostException; // 导入 UnknownHostException 类

public class IPUtil { // 定义 class IPUtil

    public static String getIpAddr(HttpServletRequest request) { // 定义方法 getIpAddr(...)

        String ip = request.getHeader("x-forwarded-for"); // 把 request.getHeader("x-forwarded-for") 赋值给 ip
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip // 保留原作者写的行内注释
            if( ip.indexOf(",")!=-1 ){ // 定义方法 方法(...)
                ip = ip.split(",")[0]; // 把 ip.split(",")[0] 赋值给 ip
            } // 代码块结束
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getHeader("Proxy-Client-IP"); // 把 request.getHeader("Proxy-Client-IP") 赋值给 ip
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getHeader("WL-Proxy-Client-IP"); // 把 request.getHeader("WL-Proxy-Client-IP") 赋值给 ip
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getHeader("HTTP_CLIENT_IP"); // 把 request.getHeader("HTTP_CLIENT_IP") 赋值给 ip
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getHeader("HTTP_X_FORWARDED_FOR"); // 把 request.getHeader("HTTP_X_FORWARDED_FOR") 赋值给 ip
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getHeader("X-Real-IP"); // 把 request.getHeader("X-Real-IP") 赋值给 ip
        } // 代码块结束
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { // 定义方法 方法(...)
            ip = request.getRemoteAddr(); // 把 request.getRemoteAddr() 的返回值赋给 ip
            if (ip.equals("127.0.0.1")  || ip.endsWith("0:0:0:0:0:0:1")) { // 定义方法 方法(...)
                // 根据网卡取本机配置的IP // 保留原作者写的行内注释
                InetAddress inet = null; // 把变量 inet 初始化为 null
                try { // 尝试执行可能抛出异常的代码
                    inet = InetAddress.getLocalHost(); // 把 InetAddress.getLocalHost() 的返回值赋给 inet
                } catch (UnknownHostException e) { // 定义方法 catch(...)
                    e.printStackTrace(); // 执行语句
                } // 代码块结束
                ip = inet.getHostAddress(); // 把 inet.getHostAddress() 的返回值赋给 ip
            } // 代码块结束
        } // 代码块结束
        return ip; // 返回 ip
    } // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/JsonUtil.java

/** // 保留原作者写的块注释
 * @(#)JsonUtil.java 2014-2-23 下午5:44:19 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
package com.xuecheng.base.utils; // 声明类所在的包路径

import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.alibaba.fastjson.JSONException; // 导入 JSONException 类
import com.alibaba.fastjson.JSONObject; // 导入 JSONObject 类
import com.alibaba.fastjson.serializer.SerializerFeature; // 导入 SerializerFeature 类

import java.util.HashMap; // 导入 HashMap 类
import java.util.List; // 导入 List 类
import java.util.Map; // 导入 Map 类

public class JsonUtil { // 定义 class JsonUtil
    
    public static String objectTojson(Object object){ // 定义方法 objectTojson(...)
        return JSON.toJSONString(object,SerializerFeature.WriteDateUseDateFormat); // 返回 JSON.toJSONString(object,SerializerFeature.WriteDateUseDateFormat)
    } // 代码块结束
    

    public static String listTojson(List list){ // 定义方法 listTojson(...)
        return JSON.toJSONString(list, SerializerFeature.WriteDateUseDateFormat); // 返回 JSON.toJSONString(list, SerializerFeature.WriteDateUseDateFormat)
    } // 代码块结束
    /** // 保留原作者写的块注释
     * 字符串Json格式转换为对象Map // 保留原作者写的块注释
     * @param strJson {"username":"sxb"} // 保留原作者写的块注释
     * @return 根据json转换为Map对象 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static Map<String, Object> jsonToMap(String strJson){ // 定义方法 jsonToMap(...)
        Map<String, Object> jsoMap = new HashMap<String, Object>(); // 创建 HashMap<String, 对象并赋值给 jsoMap
        try { // 尝试执行可能抛出异常的代码
            jsoMap = JSONObject.parseObject(strJson,Map.class); // 把 JSONObject.parseObject(strJson,Map.class) 赋值给 jsoMap
        } catch (JSONException e) { // 定义方法 catch(...)
            System.out.println("json转换Map出错:"+e.getMessage()); // 执行语句
        } // 代码块结束
        
        return jsoMap; // 返回 jsoMap
    } // 代码块结束

    public static <T> T jsonToObject(String strJson, Class<T> tClass){ // 定义方法 jsonToObject(...)
        try { // 尝试执行可能抛出异常的代码
            return JSON.parseObject(strJson, tClass); // 返回 JSON.parseObject(strJson, tClass)
        } catch (JSONException e) { // 定义方法 catch(...)
            System.out.println("json转换Map出错:"+e.getMessage()); // 执行语句
        } // 代码块结束
        return null; // 返回 null
    } // 代码块结束

    /** // 保留原作者写的块注释
     * 字符串Json 转换为对象List // 保留原作者写的块注释
     * @param strJson [{"username":"sxb"}] // 保留原作者写的块注释
     * @return 根据json转换List // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static <T> List<T> jsonToList(String strJson, Class<T> tClass){ // 定义方法 jsonToList(...)
        try { // 尝试执行可能抛出异常的代码
            return JSONObject.parseArray(strJson, tClass); // 返回 JSONObject.parseArray(strJson, tClass)
        } catch (JSONException e) { // 定义方法 catch(...)
            System.out.println("json转换List出错:"+e.getMessage()); // 执行语句
        } // 代码块结束
        return null; // 返回 null
    } // 代码块结束
    

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/MD5Util.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.security.MessageDigest; // 导入 MessageDigest 类
import java.security.NoSuchAlgorithmException; // 导入 NoSuchAlgorithmException 类

public class MD5Util { // 定义 class MD5Util
	/** // 保留原作者写的块注释
	 * 获取字符串的MD5摘要计算结果 // 保留原作者写的块注释
	 * @param plainText // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
    public static String getMd5(String plainText) {   // 定义方法 getMd5(...)
        try {   // 尝试执行可能抛出异常的代码
            MessageDigest md = MessageDigest.getInstance("MD5");   // 把 MessageDigest.getInstance("MD5") 赋值给 md
            md.update(plainText.getBytes());   // 执行语句
            byte b[] = md.digest();   // 把 md.digest() 的返回值赋给 b[]
  
            int i;   // 执行语句
  
            StringBuffer buf = new StringBuffer("");   // 创建 StringBuffer 对象并赋值给 buf
            for (int offset = 0; offset < b.length; offset++) {   // 定义方法 方法(...)
                i = b[offset];   // 把 b[offset] 赋值给 i
                if (i < 0)   // 条件判断
                    i += 256;   // 把 256 赋值给 +
                if (i < 16)   // 条件判断
                    buf.append("0");   // 执行语句
                buf.append(Integer.toHexString(i));   // 执行语句
            }   // 代码块结束
            //32位加密   // 保留原作者写的行内注释
            return buf.toString();   // 返回 buf.toString()
            // 16位的加密   // 保留原作者写的行内注释
            //return buf.toString().substring(8, 24);   // 保留原作者写的行内注释
        } catch (NoSuchAlgorithmException e) {   // 定义方法 catch(...)
            e.printStackTrace();   // 执行语句
            return null;   // 返回 null
        }   // 代码块结束
  
    }   // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/Mp4VideoUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.io.File; // 导入 File 类
import java.io.IOException; // 导入 IOException 类
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类

public class Mp4VideoUtil extends VideoUtil { // 定义 class Mp4VideoUtil

    String ffmpeg_path = "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe";//ffmpeg的安装位置 // 把 "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe" 赋值给 ffmpeg_path
    String video_path = "D:\\BaiduNetdiskDownload\\test1.avi"; // 把 "D:\\BaiduNetdiskDownload\\test1.avi" 赋值给 video_path
    String mp4_name = "test1.mp4"; // 把 "test1.mp4" 赋值给 mp4_name
    String mp4folder_path = "D:/BaiduNetdiskDownload/Movies/test1/"; // 把 "D:/BaiduNetdiskDownload/Movies/test1/" 赋值给 mp4folder_path
    public Mp4VideoUtil(String ffmpeg_path, String video_path, String mp4_name, String mp4folder_path){ // 定义方法 Mp4VideoUtil(...)
        super(ffmpeg_path); // 执行语句
        this.ffmpeg_path = ffmpeg_path; // 把 ffmpeg_path 赋值给 this.ffmpeg_path
        this.video_path = video_path; // 把 video_path 赋值给 this.video_path
        this.mp4_name = mp4_name; // 把 mp4_name 赋值给 this.mp4_name
        this.mp4folder_path = mp4folder_path; // 把 mp4folder_path 赋值给 this.mp4folder_path
    } // 代码块结束
    //清除已生成的mp4 // 保留原作者写的行内注释
    private void clear_mp4(String mp4_path){ // 定义方法 clear_mp4(...)
        //删除原来已经生成的m3u8及ts文件 // 保留原作者写的行内注释
        File mp4File = new File(mp4_path); // 创建 File 对象并赋值给 mp4File
        if(mp4File.exists() && mp4File.isFile()){ // 定义方法 方法(...)
            mp4File.delete(); // 执行语句
        } // 代码块结束
    } // 代码块结束
    /** // 保留原作者写的块注释
     * 视频编码,生成mp4文件 // 保留原作者写的块注释
     * @return 成功返回success,失败返回控制台日志 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public String generateMp4(){ // 定义方法 generateMp4(...)
        //清除已生成的mp4 // 保留原作者写的行内注释
//        clear_mp4(mp4folder_path+mp4_name); // 保留原作者写的行内注释
        clear_mp4(mp4folder_path); // 执行语句
        /* // 保留原作者写的块注释
        ffmpeg.exe -i  lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\lucene.mp4 // 代码逻辑
         */ // 保留原作者写的块注释
        List<String> commend = new ArrayList<String>(); // 创建 ArrayList<String> 对象并赋值给 commend
        //commend.add("D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe"); // 保留原作者写的行内注释
        commend.add(ffmpeg_path); // 执行语句
        commend.add("-i"); // 执行语句
//        commend.add("D:\\BaiduNetdiskDownload\\test1.avi"); // 保留原作者写的行内注释
        commend.add(video_path); // 执行语句
        commend.add("-c:v"); // 执行语句
        commend.add("libx264"); // 执行语句
        commend.add("-y");//覆盖输出文件 // 执行语句
        commend.add("-s"); // 执行语句
        commend.add("1280x720"); // 执行语句
        commend.add("-pix_fmt"); // 执行语句
        commend.add("yuv420p"); // 执行语句
        commend.add("-b:a"); // 执行语句
        commend.add("63k"); // 执行语句
        commend.add("-b:v"); // 执行语句
        commend.add("753k"); // 执行语句
        commend.add("-r"); // 执行语句
        commend.add("18"); // 执行语句
//        commend.add(mp4folder_path  + mp4_name ); // 保留原作者写的行内注释
        commend.add(mp4folder_path  ); // 执行语句
        String outstring = null; // 把变量 outstring 初始化为 null
        try { // 尝试执行可能抛出异常的代码
            ProcessBuilder builder = new ProcessBuilder(); // 创建 ProcessBuilder 对象并赋值给 builder
            builder.command(commend); // 执行语句
            //将标准输入流和错误输入流合并,通过标准输入流程读取信息 // 保留原作者写的行内注释
            builder.redirectErrorStream(true); // 执行语句
            Process p = builder.start(); // 把 builder.start() 的返回值赋给 p
            outstring = waitFor(p); // 把 waitFor(p) 赋值给 outstring

        } catch (Exception ex) { // 定义方法 catch(...)

            ex.printStackTrace(); // 执行语句

        } // 代码块结束
//        Boolean check_video_time = this.check_video_time(video_path, mp4folder_path + mp4_name); // 保留原作者写的行内注释
        Boolean check_video_time = this.check_video_time(video_path, mp4folder_path); // 把 this.check_video_time(video_path, mp4folder_path) 赋值给 check_video_time
        if(!check_video_time){ // 定义方法 方法(...)
            return outstring; // 返回 outstring
        }else{ // 代码逻辑
            return "success"; // 返回 "success"
        } // 代码块结束
    } // 代码块结束

    public static void main(String[] args) throws IOException { // 定义方法 main(...)

//        ProcessBuilder builder = new ProcessBuilder(); // 保留原作者写的行内注释
//        builder.command("D:\\Program Files\\EditPlus\\EditPlus.exe"); // 保留原作者写的行内注释
//        //将标准输入流和错误输入流合并,通过标准输入流程读取信息 // 保留原作者写的行内注释
//        builder.redirectErrorStream(true); // 保留原作者写的行内注释
//        Process p = builder.start(); // 保留原作者写的行内注释

        //ffmpeg的路径 // 保留原作者写的行内注释
        String ffmpeg_path = "D:\\soft\\ffmpeg\\ffmpeg.exe";//ffmpeg的安装位置 // 把 "D:\\soft\\ffmpeg\\ffmpeg.exe" 赋值给 ffmpeg_path
        //源avi视频的路径 // 保留原作者写的行内注释
        String video_path = "D:\\develop\\upload\\02-概述-分库分表是什么.avi"; // 把 "D:\\develop\\upload\\02-概述-分库分表是什么.avi" 赋值给 video_path
        //转换后mp4文件的名称 // 保留原作者写的行内注释
        String mp4_name = "02-概述-分库分表是什么.mp4"; // 把 "02-概述-分库分表是什么.mp4" 赋值给 mp4_name
        //转换后mp4文件的路径 // 保留原作者写的行内注释
        String mp4_path = "D:\\develop\\upload\\02-概述-分库分表是什么.mp4"; // 把 "D:\\develop\\upload\\02-概述-分库分表是什么.mp4" 赋值给 mp4_path
        //创建工具类对象 // 保留原作者写的行内注释
        Mp4VideoUtil videoUtil = new Mp4VideoUtil(ffmpeg_path,video_path,mp4_name,mp4_path); // 创建 Mp4VideoUtil 对象并赋值给 videoUtil
        //开始视频转换,成功将返回success // 保留原作者写的行内注释
        String s = videoUtil.generateMp4(); // 把 videoUtil.generateMp4() 的返回值赋给 s
        System.out.println(s); // 执行语句
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/PasswordUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import org.apache.commons.codec.binary.Hex; // 导入 Hex 类

import java.security.MessageDigest; // 导入 MessageDigest 类
import java.util.Random; // 导入 Random 类

/** // 保留原作者写的块注释
 * <P> // 保留原作者写的块注释
 * MD5加盐加密 // 保留原作者写的块注释
 * </p> // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释

public class PasswordUtil { // 定义 class PasswordUtil
	/** // 保留原作者写的块注释
	 * 生成含有随机盐的密码 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String generate(String password) { // 定义方法 generate(...)
		Random r = new Random(); // 创建 Random 对象并赋值给 r
		StringBuilder sb = new StringBuilder(16); // 创建 StringBuilder 对象并赋值给 sb
		sb.append(r.nextInt(99999999)).append(r.nextInt(99999999)); // 执行语句
		int len = sb.length(); // 把 sb.length() 的返回值赋给 len
		if (len < 16) { // 定义方法 方法(...)
			for (int i = 0; i < 16 - len; i++) { // 定义方法 方法(...)
				sb.append("0"); // 执行语句
			} // 代码块结束
		} // 代码块结束
		String salt = sb.toString(); // 把 sb.toString() 的返回值赋给 salt
		password = md5Hex(password + salt); // 把 md5Hex(password + salt) 赋值给 password
		char[] cs = new char[48]; // 创建 char[48] 对象并赋值给 cs
		for (int i = 0; i < 48; i += 3) { // 定义方法 方法(...)
			cs[i] = password.charAt(i / 3 * 2); // 把 password.charAt(i / 3 * 2) 赋值给 cs[i]
			char c = salt.charAt(i / 3); // 把 salt.charAt(i / 3) 赋值给 c
			cs[i + 1] = c; // 把 c 赋值给 1]
			cs[i + 2] = password.charAt(i / 3 * 2 + 1); // 把 password.charAt(i / 3 * 2 + 1) 赋值给 2]
		} // 代码块结束
		return new String(cs); // 返回 new String(cs)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 校验密码是否正确 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean verify(String password, String md5) { // 定义方法 verify(...)
		char[] cs1 = new char[32]; // 创建 char[32] 对象并赋值给 cs1
		char[] cs2 = new char[16]; // 创建 char[16] 对象并赋值给 cs2
		for (int i = 0; i < 48; i += 3) { // 定义方法 方法(...)
			cs1[i / 3 * 2] = md5.charAt(i); // 把 md5.charAt(i) 赋值给 2]
			cs1[i / 3 * 2 + 1] = md5.charAt(i + 2); // 把 md5.charAt(i + 2) 赋值给 1]
			cs2[i / 3] = md5.charAt(i + 1); // 把 md5.charAt(i + 1) 赋值给 3]
		} // 代码块结束
		String salt = new String(cs2); // 创建 String 对象并赋值给 salt
		return md5Hex(password + salt).equals(new String(cs1)); // 返回 md5Hex(password + salt).equals(new String(cs1))
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 获取十六进制字符串形式的MD5摘要 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String md5Hex(String src) { // 定义方法 md5Hex(...)
		try { // 尝试执行可能抛出异常的代码
			MessageDigest md5 = MessageDigest.getInstance("MD5"); // 把 MessageDigest.getInstance("MD5") 赋值给 md5
			byte[] bs = md5.digest(src.getBytes()); // 把 md5.digest(src.getBytes()) 赋值给 bs
			return new String(new Hex().encode(bs)); // 返回 new String(new Hex().encode(bs))
		} catch (Exception e) { // 定义方法 catch(...)
			return null; // 返回 null
		} // 代码块结束
	} // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/PaymentUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import org.apache.commons.lang.RandomStringUtils; // 导入 RandomStringUtils 类
import org.apache.commons.lang.StringUtils; // 导入 StringUtils 类

import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.time.format.DateTimeFormatter; // 导入 DateTimeFormatter 类
import java.util.regex.Pattern; // 导入 Pattern 类

public class PaymentUtil { // 定义 class PaymentUtil
    private static final Pattern pattern = Pattern.compile("SJPAY(,\\S+){4}"); // 把 Pattern.compile("SJPAY(,\\S+){4}") 赋值给 pattern
    public static final String SHANJUPAY_PREFIX = "XC"; // 把 "XC" 赋值给 SHANJUPAY_PREFIX

    public static boolean checkPayOrderAttach (String attach) { // 定义方法 checkPayOrderAttach(...)
        if (StringUtils.isBlank(attach)) { // 定义方法 方法(...)
            return false; // 返回 false
        } // 代码块结束
        return pattern.matcher(attach).matches(); // 返回 pattern.matcher(attach).matches()
    } // 代码块结束

    public static String genUniquePayOrderNo() { // 定义方法 genUniquePayOrderNo(...)
        String dateTime = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS").format(LocalDateTime.now()); // 把 DateTimeFormatter.ofPattern("yyMMddHHmmssSSS").format(LocalDateTime.now()) 赋值给 dateTime
        return SHANJUPAY_PREFIX + dateTime + RandomStringUtils.randomAlphanumeric(15); // 返回 SHANJUPAY_PREFIX + dateTime + RandomStringUtils.randomAlphanumeric(15)
    } // 代码块结束

    public static void main(String[] args) { // 定义方法 main(...)
        System.out.println(genUniquePayOrderNo()); // 执行语句
        System.out.println(genUniquePayOrderNo().length()); // 执行语句
    } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/PhoneUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.util.regex.Matcher; // 导入 Matcher 类
import java.util.regex.Pattern; // 导入 Pattern 类

public class PhoneUtil { // 定义 class PhoneUtil
    /** // 保留原作者写的块注释
     * 校验用户手机号是否合法 // 保留原作者写的块注释
     * @param phone // 保留原作者写的块注释
     * @return // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    public static Boolean isMatches(String phone){ // 定义方法 isMatches(...)
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$"; // 把 "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$" 赋值给 regex
        Pattern p = Pattern.compile(regex); // 把 Pattern.compile(regex) 赋值给 p
        Matcher m = p.matcher(phone); // 把 p.matcher(phone) 赋值给 m
        return m.matches(); // 返回 m.matches()
    } // 代码块结束

    //public static void main(String[] args) { // 保留原作者写的行内注释
    //    System.out.println(isMatches("13512341233")); // 保留原作者写的行内注释
    //} // 保留原作者写的行内注释
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/QRCodeUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import com.google.zxing.BarcodeFormat; // 导入 BarcodeFormat 类
import com.google.zxing.EncodeHintType; // 导入 EncodeHintType 类
import com.google.zxing.client.j2se.MatrixToImageWriter; // 导入 MatrixToImageWriter 类
import com.google.zxing.common.BitMatrix; // 导入 BitMatrix 类
import com.google.zxing.qrcode.QRCodeWriter; // 导入 QRCodeWriter 类
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; // 导入 ErrorCorrectionLevel 类
import org.apache.commons.lang3.StringUtils; // 导入 StringUtils 类

import javax.imageio.ImageIO; // 导入 ImageIO 类
import javax.servlet.ServletOutputStream; // 导入 ServletOutputStream 类
import java.awt.image.BufferedImage; // 导入 BufferedImage 类
import java.io.ByteArrayOutputStream; // 导入 ByteArrayOutputStream 类
import java.io.IOException; // 导入 IOException 类
import java.util.HashMap; // 导入 HashMap 类

/** // 保留原作者写的块注释
 * @description 二维码生成工具 // 保留原作者写的块注释
 * @author Mr.M // 保留原作者写的块注释
 * @date 2022/10/3 0:03 // 保留原作者写的块注释
 * @version 1.0 // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class QRCodeUtil { // 定义 class QRCodeUtil
 /** // 保留原作者写的块注释
  * 生成二维码 // 保留原作者写的块注释
  * // 保留原作者写的块注释
  * @param content 二维码对应的URL // 保留原作者写的块注释
  * @param width   二维码图片宽度 // 保留原作者写的块注释
  * @param height  二维码图片高度 // 保留原作者写的块注释
  * @return // 保留原作者写的块注释
  */ // 保留原作者写的块注释
 public String createQRCode(String content, int width, int height) throws IOException { // 定义方法 createQRCode(...)
  String resultImage = ""; // 把 "" 赋值给 resultImage
  //除了尺寸,传入内容不能为空 // 保留原作者写的行内注释
  if (!StringUtils.isEmpty(content)) { // 定义方法 方法(...)
   ServletOutputStream stream = null; // 把变量 stream 初始化为 null
   ByteArrayOutputStream os = new ByteArrayOutputStream(); // 创建 ByteArrayOutputStream 对象并赋值给 os
   //二维码参数 // 保留原作者写的行内注释
   @SuppressWarnings("rawtypes") // 使用注解 @SuppressWarnings("rawtypes")
   HashMap<EncodeHintType, Comparable> hints = new HashMap<>(); // 创建 HashMap<> 对象并赋值给 hints
   //指定字符编码为“utf-8” // 保留原作者写的行内注释
   hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 执行语句
   //L M Q H四个纠错等级从低到高,指定二维码的纠错等级为M // 保留原作者写的行内注释
   //纠错级别越高,可以修正的错误就越多,需要的纠错码的数量也变多,相应的二维吗可储存的数据就会减少 // 保留原作者写的行内注释
   hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 执行语句
   //设置图片的边距 // 保留原作者写的行内注释
   hints.put(EncodeHintType.MARGIN, 1); // 执行语句

   try { // 尝试执行可能抛出异常的代码
    //zxing生成二维码核心类 // 保留原作者写的行内注释
    QRCodeWriter writer = new QRCodeWriter(); // 创建 QRCodeWriter 对象并赋值给 writer
    //把输入文本按照指定规则转成二维吗 // 保留原作者写的行内注释
    BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); // 把 writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints) 赋值给 bitMatrix
    //生成二维码图片流 // 保留原作者写的行内注释
    BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix); // 把 MatrixToImageWriter.toBufferedImage(bitMatrix) 赋值给 bufferedImage
    //输出流 // 保留原作者写的行内注释
    ImageIO.write(bufferedImage, "png", os); // 执行语句
    /** // 保留原作者写的块注释
     * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析,所以加上前缀 // 保留原作者写的块注释
     */ // 保留原作者写的块注释
    resultImage = new String("data:image/png;base64," + EncryptUtil.encodeBase64(os.toByteArray())); // 创建 String 对象并赋值给 resultImage
    return resultImage; // 返回 resultImage
   } catch (Exception e) { // 定义方法 catch(...)
    e.printStackTrace(); // 执行语句
    throw new RuntimeException("生成二维码出错"); // 主动抛出异常
   } finally { // 代码逻辑
    if (stream != null) { // 定义方法 方法(...)
     stream.flush(); // 执行语句
     stream.close(); // 执行语句
    } // 代码块结束
   } // 代码块结束
  } // 代码块结束
  return null; // 返回 null
 } // 代码块结束

 public static void main(String[] args) throws IOException { // 定义方法 main(...)
  QRCodeUtil qrCodeUtil = new QRCodeUtil(); // 创建 QRCodeUtil 对象并赋值给 qrCodeUtil
  System.out.println(qrCodeUtil.createQRCode("http://192.168.101.1:63030/orders/alipaytest", 200, 200)); // 代码逻辑
 } // 代码块结束
} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/RandomStringUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.util.Random; // 导入 Random 类

/** // 保留原作者写的块注释
 * 随机字符串工具 // 保留原作者写的块注释
 * // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class RandomStringUtil { // 定义 class RandomStringUtil
        /** // 保留原作者写的块注释
         * 获取指定长度随机字符串 // 保留原作者写的块注释
         * // 保留原作者写的块注释
         * @param length // 保留原作者写的块注释
         * @return // 保留原作者写的块注释
         */ // 保留原作者写的块注释
        public static String getRandomString(int length) { // 定义方法 getRandomString(...)
            Random random = new Random(); // 创建 Random 对象并赋值给 random
            StringBuffer sb = new StringBuffer(); // 创建 StringBuffer 对象并赋值给 sb
            for (int i = 0; i < length; i++) { // 定义方法 方法(...)
                int number = random.nextInt(3); // 把 random.nextInt(3) 赋值给 number
                long result = 0; // 把 0 赋值给 result
                switch (number) { // 开始 switch 分支判断
                    case 0: // 处理\u67d0个 case 分支
                        result = Math.round(Math.random() * 25 + 65); // 把 Math.round(Math.random() * 25 + 65) 赋值给 result
                        sb.append(String.valueOf((char) result)); // 执行语句
                        break; // 跳出当前循环\u6216分支
                    case 1: // 处理\u67d0个 case 分支
                        result = Math.round(Math.random() * 25 + 97); // 把 Math.round(Math.random() * 25 + 97) 赋值给 result
                        sb.append(String.valueOf((char) result)); // 执行语句
                        break; // 跳出当前循环\u6216分支
                    case 2: // 处理\u67d0个 case 分支
                        sb.append(String.valueOf(new Random().nextInt(10))); // 执行语句
                        break; // 跳出当前循环\u6216分支
                } // 代码块结束
            } // 代码块结束
            return sb.toString(); // 返回 sb.toString()
        } // 代码块结束

        /** // 保留原作者写的块注释
         * 测试验证 // 保留原作者写的块注释
         * // 保留原作者写的块注释
         * @param args // 保留原作者写的块注释
         */ // 保留原作者写的块注释
        //public static void main(String[] args) { // 保留原作者写的行内注释
        //    System.out.println(RandomStringUtil.getRandomString(5)); // 保留原作者写的行内注释
        //    String  str2 = RandomStringUtils.random(12,"123456789"); // 保留原作者写的行内注释
        //    System.out.println(str2); // 保留原作者写的行内注释
        //} // 保留原作者写的行内注释

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/RSAUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import javax.crypto.Cipher; // 导入 Cipher 类
import java.io.ByteArrayInputStream; // 导入 ByteArrayInputStream 类
import java.io.ByteArrayOutputStream; // 导入 ByteArrayOutputStream 类
import java.io.InputStream; // 导入 InputStream 类
import java.security.*; // 导入 * 类
import java.security.spec.PKCS8EncodedKeySpec; // 导入 PKCS8EncodedKeySpec 类
import java.security.spec.X509EncodedKeySpec; // 导入 X509EncodedKeySpec 类
import java.util.Base64; // 导入 Base64 类

public class RSAUtil { // 定义 class RSAUtil

	public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; // 把 "SHA1WithRSA" 赋值给 SIGN_ALGORITHMS
	final static Base64.Decoder decoder = Base64.getDecoder(); // 把 Base64.getDecoder() 的返回值赋给 decoder
	final static Base64.Encoder encoder = Base64.getEncoder(); // 把 Base64.getEncoder() 的返回值赋给 encoder

	/** // 保留原作者写的块注释
	 * RSA签名 // 保留原作者写的块注释
	 * @param content 待签名数据 // 保留原作者写的块注释
	 * @param privateKey 商户私钥 // 保留原作者写的块注释
	 * @param input_charset 编码格式 // 保留原作者写的块注释
	 * @return 签名值 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String sign(String content, String privateKey, String input_charset) { // 定义方法 sign(...)
		try { // 尝试执行可能抛出异常的代码
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decoder.decode(privateKey)); // 创建 PKCS8EncodedKeySpec 对象并赋值给 priPKCS8
			KeyFactory keyf = KeyFactory.getInstance("RSA"); // 把 KeyFactory.getInstance("RSA") 赋值给 keyf
			PrivateKey priKey = keyf.generatePrivate(priPKCS8); // 把 keyf.generatePrivate(priPKCS8) 赋值给 priKey

			Signature signature = Signature.getInstance(SIGN_ALGORITHMS); // 把 Signature.getInstance(SIGN_ALGORITHMS) 赋值给 signature

			signature.initSign(priKey); // 执行语句
			signature.update(content.getBytes(input_charset)); // 执行语句

			byte[] signed = signature.sign(); // 把 signature.sign() 的返回值赋给 signed

			return encoder.encodeToString(signed); // 返回 encoder.encodeToString(signed)
		} catch (Exception e) { // 定义方法 catch(...)
			e.printStackTrace(); // 执行语句
		} // 代码块结束

		return null; // 返回 null
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * RSA验签名检查 // 保留原作者写的块注释
	 * @param content 待签名数据 // 保留原作者写的块注释
	 * @param sign 签名值 // 保留原作者写的块注释
	 * @param public_key 公钥 // 保留原作者写的块注释
	 * @param input_charset 编码格式 // 保留原作者写的块注释
	 * @return 布尔值 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean verify(String content, String sign, String public_key, String input_charset) { // 定义方法 verify(...)
		try { // 尝试执行可能抛出异常的代码
			KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 把 KeyFactory.getInstance("RSA") 赋值给 keyFactory
			byte[] encodedKey = decoder.decode(public_key); // 把 decoder.decode(public_key) 赋值给 encodedKey
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); // 把 keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)) 赋值给 pubKey

			Signature signature = Signature.getInstance(SIGN_ALGORITHMS); // 把 Signature.getInstance(SIGN_ALGORITHMS) 赋值给 signature

			signature.initVerify(pubKey); // 执行语句
			signature.update(content.getBytes(input_charset)); // 执行语句

			boolean bverify = signature.verify(decoder.decode(sign)); // 把 signature.verify(decoder.decode(sign)) 赋值给 bverify
			return bverify; // 返回 bverify

		} catch (Exception e) { // 定义方法 catch(...)
			e.printStackTrace(); // 执行语句
		} // 代码块结束

		return false; // 返回 false
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 解密 // 保留原作者写的块注释
	 * @param content 密文 // 保留原作者写的块注释
	 * @param private_key 商户私钥 // 保留原作者写的块注释
	 * @param input_charset 编码格式 // 保留原作者写的块注释
	 * @return 解密后的字符串 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String decrypt(String content, String private_key, String input_charset) throws Exception { // 定义方法 decrypt(...)
		PrivateKey prikey = getPrivateKey(private_key); // 把 getPrivateKey(private_key) 赋值给 prikey

		Cipher cipher = Cipher.getInstance("RSA"); // 把 Cipher.getInstance("RSA") 赋值给 cipher
		cipher.init(Cipher.DECRYPT_MODE, prikey); // 执行语句

		InputStream ins = new ByteArrayInputStream(decoder.decode(content)); // 创建 ByteArrayInputStream 对象并赋值给 ins
		ByteArrayOutputStream writer = new ByteArrayOutputStream(); // 创建 ByteArrayOutputStream 对象并赋值给 writer
		//rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密 // 保留原作者写的行内注释
		byte[] buf = new byte[128]; // 创建 byte[128] 对象并赋值给 buf
		int bufl; // 执行语句

		while ((bufl = ins.read(buf)) != -1) { // 定义方法 方法(...)
			byte[] block = null; // 把变量 block 初始化为 null

			if (buf.length == bufl) { // 定义方法 方法(...)
				block = buf; // 把 buf 赋值给 block
			} else { // 代码逻辑
				block = new byte[bufl]; // 创建 byte[bufl] 对象并赋值给 block
				for (int i = 0; i < bufl; i++) { // 定义方法 方法(...)
					block[i] = buf[i]; // 把 buf[i] 赋值给 block[i]
				} // 代码块结束
			} // 代码块结束

			writer.write(cipher.doFinal(block)); // 执行语句
		} // 代码块结束

		return new String(writer.toByteArray(), input_charset); // 返回 new String(writer.toByteArray(), input_charset)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 得到私钥 // 保留原作者写的块注释
	 * @param key 密钥字符串(经过base64编码) // 保留原作者写的块注释
	 * @throws Exception // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static PrivateKey getPrivateKey(String key) throws Exception { // 定义方法 getPrivateKey(...)

		byte[] keyBytes; // 执行语句

		keyBytes = decoder.decode(key); // 把 decoder.decode(key) 赋值给 keyBytes

		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); // 创建 PKCS8EncodedKeySpec 对象并赋值给 keySpec

		KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 把 KeyFactory.getInstance("RSA") 赋值给 keyFactory

		PrivateKey privateKey = keyFactory.generatePrivate(keySpec); // 把 keyFactory.generatePrivate(keySpec) 赋值给 privateKey

		return privateKey; // 返回 privateKey
	} // 代码块结束

	//生成密钥对 // 保留原作者写的行内注释
	public static KeyPair getKeyPair() throws Exception { // 定义方法 getKeyPair(...)
		KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); // 把 KeyPairGenerator.getInstance("RSA") 赋值给 keyGen
		keyGen.initialize(512); //可以理解为:加密后的密文长度,实际原文要小些 越大 加密解密越慢 // 执行语句
		KeyPair keyPair = keyGen.generateKeyPair(); // 把 keyGen.generateKeyPair() 的返回值赋给 keyPair
		return keyPair; // 返回 keyPair
	} // 代码块结束

	public static final String depository_publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJKcP4TjCb9+OKf0uvHkDO6njI8b9KKlu3ZdCkom4SONf8KkZ1jVl6A7XWnJ33gBLnbTGVUm5I+XvFEG5bSWVbkCAwEAAQ=="; // 执行语句

	public static final String depository_privateKey = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkpw/hOMJv344p/S68eQM7qeMjxv0oqW7dl0KSibhI41/wqRnWNWXoDtdacnfeAEudtMZVSbkj5e8UQbltJZVuQIDAQABAkBrkkVw5X0DikNbyM9aKG/ss/cIEgT/SgcwI7gnDDvo7wntxxPuVZ7P+gkhFqb1ByCLdH/GlsXEZW88HCA9M2ZhAiEA65BsW0uGPhnVRS7hJhLZpuuugKVNyJBBO6jGATe0g/UCIQCfVEZ0bvYd5pA165XwXs7ZFGU99rG410EEh7JRxzx0NQIgdNL9ShGck/PP1y22r2Et3CCKPHa+qrcQAvxipnvv5HkCIBITUoblC8DqplOnrXP+nYLdIHs+IH1y1ip4Zo+GheI9AiBdsG0ql4Unbt1ctYm6XdmqE5rdFD+iDFQRS1FFmUVNUQ=="; // 执行语句

	public static final String p2p_publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKZKjaBEvudPDolCyuVCBLmfVsSFBu3wfdldLxItRcjSYMzHNoIuYcvHhnMmMi1iXRLeYdbwvI3JQoBHDGN5ad0CAwEAAQ=="; // 执行语句

	public static final String p2p_privateKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApkqNoES+508OiULK5UIEuZ9WxIUG7fB92V0vEi1FyNJgzMc2gi5hy8eGcyYyLWJdEt5h1vC8jclCgEcMY3lp3QIDAQABAkAUhQia6UDBXEEH8QUGazIYEbBsSZoETHPLGbOQQ6Pj1tb6CVC57kioBjwtNBnY2jBDWi5K815LnOBcJSSjJPwhAiEA2eO6VZMTkdjQAkpB5dhy/0C3i8zs0c0M1rPoTA/RpkUCIQDDYHJPqHLkQyd//7sEeYcm8cMBTvDKBXyiuGk8eLRauQIgQo6IlalGmg+Dgp+SP5Z9kjD/oCmp0XB0UoVEGS/f140CIQCsG9YXHgi31ACD3T9eHcBVKjvidyveix7UKSdrQdl+4QIgNCtRVLV+783e7PX5hRXD+knsWTQxDEMEsHi1KsAWtPk="; // 代码逻辑

	public static void main(String[] args) throws Exception { // 定义方法 main(...)
		//生成公私钥对 // 保留原作者写的行内注释
       /* KeyPair keyPair = RSAUtil.getKeyPair(); // 保留原作者写的块注释
        PublicKey publicKey =  keyPair.getPublic(); // 把 keyPair.getPublic() 的返回值赋给 publicKey
        PrivateKey privateKey = keyPair.getPrivate(); // 把 keyPair.getPrivate() 的返回值赋给 privateKey

        System.out.println("-----------------publicKey--------------------- "); // 执行语句
        System.out.println(Base64.encode(publicKey.getEncoded())); // 执行语句

        System.out.println("-----------------privateKey--------------------- "); // 执行语句
        System.out.println(Base64.encode(privateKey.getEncoded()));*/ // 代码逻辑

		String content = "加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890"; // 把 "加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890加密原文1234567890" 赋值给 content

		System.out.println("-----------------p2p向存管发送数据--------------------- "); // 执行语句
		String signature = RSAUtil.sign(content, p2p_privateKey, "utf-8"); // 把 RSAUtil.sign(content, p2p_privateKey, "utf-8") 赋值给 signature
		System.out.println("生成签名,原文为:" + content); // 执行语句
		if (RSAUtil.verify(content, signature, p2p_publicKey, "utf-8")) { // 定义方法 方法(...)
			System.out.println("验证签名成功:" + signature); // 执行语句
		} else { // 代码逻辑
			System.out.println("验证签名失败!"); // 执行语句
		} // 代码块结束

		System.out.println("-----------------存管向p2p返回数据--------------------- "); // 执行语句
		String signature1 = RSAUtil.sign(content, depository_privateKey, "utf-8"); // 把 RSAUtil.sign(content, depository_privateKey, "utf-8") 赋值给 signature1
		System.out.println("生成签名,原文为:" + content); // 执行语句
		if (RSAUtil.verify(content, signature1, depository_publicKey, "utf-8")) { // 定义方法 方法(...)
			System.out.println("验证签名成功:" + signature1); // 执行语句
		} else { // 代码逻辑
			System.out.println("验证签名失败!"); // 执行语句
		} // 代码块结束

	} // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/StringUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.io.File; // 导入 File 类
import java.nio.charset.Charset; // 导入 Charset 类
import java.text.SimpleDateFormat; // 导入 SimpleDateFormat 类
import java.util.regex.Matcher; // 导入 Matcher 类
import java.util.regex.Pattern; // 导入 Pattern 类

public class StringUtil { // 定义 class StringUtil

	/** yyyy-MM-dd日期格式 */ // 保留原作者写的块注释
	public static final SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); // 创建 SimpleDateFormat 对象并赋值给 sdfDate

	public static final String SPACE = " "; // 把 " " 赋值给 SPACE
	public static final String DOT = "."; // 把 "." 赋值给 DOT
	public static final String SLASH = "/"; // 把 "/" 赋值给 SLASH
	public static final String BACKSLASH = "\\"; // 把 "\\" 赋值给 BACKSLASH
	public static final String EMPTY = ""; // 把 "" 赋值给 EMPTY
	public static final String CRLF = "\r\n"; // 把 "\r\n" 赋值给 CRLF
	public static final String NEWLINE = "\n"; // 把 "\n" 赋值给 NEWLINE
	public static final String UNDERLINE = "_"; // 把 "_" 赋值给 UNDERLINE
	public static final String COMMA = ","; // 把 "," 赋值给 COMMA

	public static final String HTML_NBSP = "&nbsp;"; // 把 "&nbsp;" 赋值给 HTML_NBSP
	public static final String HTML_AMP = "&amp"; // 把 "&amp" 赋值给 HTML_AMP
	public static final String HTML_QUOTE = "&quot;"; // 把 "&quot;" 赋值给 HTML_QUOTE
	public static final String HTML_LT = "&lt;"; // 把 "&lt;" 赋值给 HTML_LT
	public static final String HTML_GT = "&gt;"; // 把 "&gt;" 赋值给 HTML_GT

	public static final String EMPTY_JSON = "{}"; // 把 "{}" 赋值给 EMPTY_JSON

	/** // 保留原作者写的块注释
	 * 字符串是否为空白 空白的定义如下: <br> // 保留原作者写的块注释
	 * 1、为null <br> // 保留原作者写的块注释
	 * 2、为不可见字符(如空格)<br> // 保留原作者写的块注释
	 * 3、""<br> // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            被检测的字符串 // 保留原作者写的块注释
	 * @return 是否为空 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isBlank(String str) { // 定义方法 isBlank(...)
		return str == null || str.trim().length() == 0; // 返回 str == null || str.trim().length() == 0
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 字符串是否为非空白 空白的定义如下: <br> // 保留原作者写的块注释
	 * 1、不为null <br> // 保留原作者写的块注释
	 * 2、不为不可见字符(如空格)<br> // 保留原作者写的块注释
	 * 3、不为""<br> // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str 被检测的字符串 // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @return 是否为非空 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isNotBlank(String str) { // 定义方法 isNotBlank(...)
		return false == isBlank(str); // 返回 false == isBlank(str)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 字符串是否为空,空的定义如下 1、为null <br> // 保留原作者写的块注释
	 * 2、为""<br> // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            被检测的字符串 // 保留原作者写的块注释
	 * @return 是否为空 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isEmpty(String str) { // 定义方法 isEmpty(...)
		return str == null || str.length() == 0; // 返回 str == null || str.length() == 0
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 字符串是否为非空白 空白的定义如下: <br> // 保留原作者写的块注释
	 * 1、不为null <br> // 保留原作者写的块注释
	 * 2、不为""<br> // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            被检测的字符串 // 保留原作者写的块注释
	 * @return 是否为非空 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isNotEmpty(String str) { // 定义方法 isNotEmpty(...)
		return false == isEmpty(str); // 返回 false == isEmpty(str)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 指定字符串是否被包装 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param prefix // 保留原作者写的块注释
	 *            前缀 // 保留原作者写的块注释
	 * @param suffix // 保留原作者写的块注释
	 *            后缀 // 保留原作者写的块注释
	 * @return 是否被包装 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isWrap(String str, String prefix, String suffix) { // 定义方法 isWrap(...)
		return str.startsWith(prefix) && str.endsWith(suffix); // 返回 str.startsWith(prefix) && str.endsWith(suffix)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 指定字符串是否被同一字符包装(前后都有这些字符串) // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param wrapper // 保留原作者写的块注释
	 *            包装字符串 // 保留原作者写的块注释
	 * @return 是否被包装 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isWrap(String str, String wrapper) { // 定义方法 isWrap(...)
		return isWrap(str, wrapper, wrapper); // 返回 isWrap(str, wrapper, wrapper)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 指定字符串是否被同一字符包装(前后都有这些字符串) // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param wrapper // 保留原作者写的块注释
	 *            包装字符 // 保留原作者写的块注释
	 * @return 是否被包装 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isWrap(String str, char wrapper) { // 定义方法 isWrap(...)
		return isWrap(str, wrapper, wrapper); // 返回 isWrap(str, wrapper, wrapper)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 指定字符串是否被包装 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param prefixChar // 保留原作者写的块注释
	 *            前缀 // 保留原作者写的块注释
	 * @param suffixChar // 保留原作者写的块注释
	 *            后缀 // 保留原作者写的块注释
	 * @return 是否被包装 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isWrap(String str, char prefixChar, char suffixChar) { // 定义方法 isWrap(...)
		return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar; // 返回 str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 补充字符串以满足最小长度 StrUtil.padPre("1", 3, '0');//"001" // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param minLength // 保留原作者写的块注释
	 *            最小长度 // 保留原作者写的块注释
	 * @param padChar // 保留原作者写的块注释
	 *            补充的字符 // 保留原作者写的块注释
	 * @return 补充后的字符串 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String padPre(String str, int minLength, char padChar) { // 定义方法 padPre(...)
		if (str.length() >= minLength) { // 定义方法 方法(...)
			return str; // 返回 str
		} // 代码块结束
		StringBuilder sb = new StringBuilder(minLength); // 创建 StringBuilder 对象并赋值给 sb
		for (int i = str.length(); i < minLength; i++) { // 定义方法 方法(...)
			sb.append(padChar); // 执行语句
		} // 代码块结束
		sb.append(str); // 执行语句
		return sb.toString(); // 返回 sb.toString()
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 补充字符串以满足最小长度 StrUtil.padEnd("1", 3, '0');//"100" // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param minLength // 保留原作者写的块注释
	 *            最小长度 // 保留原作者写的块注释
	 * @param padChar // 保留原作者写的块注释
	 *            补充的字符 // 保留原作者写的块注释
	 * @return 补充后的字符串 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String padEnd(String str, int minLength, char padChar) { // 定义方法 padEnd(...)
		if (str.length() >= minLength) { // 定义方法 方法(...)
			return str; // 返回 str
		} // 代码块结束
		StringBuilder sb = new StringBuilder(minLength); // 创建 StringBuilder 对象并赋值给 sb
		sb.append(str); // 执行语句
		for (int i = str.length(); i < minLength; i++) { // 定义方法 方法(...)
			sb.append(padChar); // 执行语句
		} // 代码块结束
		return sb.toString(); // 返回 sb.toString()
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 创建StringBuilder对象 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @return StringBuilder对象 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static StringBuilder builder() { // 定义方法 builder(...)
		return new StringBuilder(); // 返回 new StringBuilder()
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 创建StringBuilder对象 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @return StringBuilder对象 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static StringBuilder builder(int capacity) { // 定义方法 builder(...)
		return new StringBuilder(capacity); // 返回 new StringBuilder(capacity)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 创建StringBuilder对象 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @return StringBuilder对象 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static StringBuilder builder(String... strs) { // 定义方法 builder(...)
		final StringBuilder sb = new StringBuilder(); // 创建 StringBuilder 对象并赋值给 sb
		for (String str : strs) { // 定义方法 方法(...)
			sb.append(str); // 执行语句
		} // 代码块结束
		return sb; // 返回 sb
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 获得字符串对应字符集的byte数组 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            字符串 // 保留原作者写的块注释
	 * @param charset // 保留原作者写的块注释
	 *            字符集编码 // 保留原作者写的块注释
	 * @return byte数组 // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static byte[] bytes(String str, String charset) { // 定义方法 bytes(...)
		if (null == str) { // 定义方法 方法(...)
			return null; // 返回 null
		} // 代码块结束
		if (isBlank(charset)) { // 定义方法 方法(...)
			return null; // 返回 null
		} // 代码块结束
		return str.getBytes(Charset.forName(charset)); // 返回 str.getBytes(Charset.forName(charset))
	} // 代码块结束

	/*** // 保留原作者写的块注释
	 * 判断 String 是否int // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param input // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isInteger(String input) { // 定义方法 isInteger(...)
		Matcher mer = Pattern.compile("^[+-]?[0-9]+$").matcher(input); // 把 Pattern.compile("^[+-]?[0-9]+$").matcher(input) 赋值给 mer
		return mer.find(); // 返回 mer.find()
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 数字型String字符串转换成int型数组 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            string类型的数组 // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static Integer[] stringToIntegerArray(String[] str) { // 定义方法 stringToIntegerArray(...)
		Integer array[] = new Integer[str.length]; // 创建 Integer[str.length] 对象并赋值给 array[]
		for (int i = 0; i < str.length; i++) { // 定义方法 方法(...)
			array[i] = Integer.parseInt(str[i]); // 把 Integer.parseInt(str[i]) 赋值给 array[i]
		} // 代码块结束
		return array; // 返回 array
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 数字型String字符串转换成Long型数组 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param str // 保留原作者写的块注释
	 *            string类型的数组 // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static Long[] stringTOLongArray(String[] str) { // 定义方法 stringTOLongArray(...)
		Long array[] = new Long[str.length]; // 创建 Long[str.length] 对象并赋值给 array[]
		for (int i = 0; i < str.length; i++) { // 定义方法 方法(...)
			array[i] = Long.parseLong(str[i]); // 把 Long.parseLong(str[i]) 赋值给 array[i]
		} // 代码块结束
		return array; // 返回 array
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 获取文件后缀 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param src // 保留原作者写的块注释
	 *            文件路径/名称 文件路径 C:\Users\Public\Pictures\Sample Pictures\test.jpg // 保留原作者写的块注释
	 * @return 如果文件后缀 jpg // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String getFileExt(String src) { // 定义方法 getFileExt(...)

		String filename = src.substring(src.lastIndexOf(File.separator) + 1, src.length());// 获取到文件名 // 把 src.substring(src.lastIndexOf(File.separator) + 1, src.length()) 赋值给 filename

		return filename.substring(filename.lastIndexOf(".") + 1); // 返回 filename.substring(filename.lastIndexOf(".") + 1)
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 获取文件名称,不带文件后缀部分 // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param src // 保留原作者写的块注释
	 *            文件路径 C:\Users\Public\Pictures\Sample Pictures\test.jpg // 保留原作者写的块注释
	 * @return 文件名称 不带文件后缀 test // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static String getFileName(String src) { // 定义方法 getFileName(...)

		String filename = src.substring(src.lastIndexOf(File.separator) + 1, src.length());// 获取到文件名 // 把 src.substring(src.lastIndexOf(File.separator) + 1, src.length()) 赋值给 filename

		return filename.substring(0, filename.lastIndexOf(".")); // 返回 filename.substring(0, filename.lastIndexOf("."))
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 判断字符串是否为空(不能为空字符串) // 保留原作者写的块注释
	 *  // 保留原作者写的块注释
	 * @param src // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static boolean isNull(String src) { // 定义方法 isNull(...)

		return src == null || src.length() == 0 || src.trim().length() == 0; // 返回 src == null || src.length() == 0 || src.trim().length() == 0
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 检查数组中,是否含有当前元素 // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @param arr // 保留原作者写的块注释
	 * @param checkValue // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static Boolean checkArrayValue(String[] arr, String checkValue) { // 定义方法 checkArrayValue(...)
		Boolean checkFlag = false; // 把 false 赋值给 checkFlag
		if (arr != null && arr.length > 0) { // 定义方法 方法(...)
			for (int i = 0; i < arr.length; i++) { // 定义方法 方法(...)
				if (arr[i].equals(checkValue)) { // 定义方法 方法(...)
					checkFlag = true; // 把 true 赋值给 checkFlag
					break; // 跳出当前循环\u6216分支
				} // 代码块结束
			} // 代码块结束
		} // 代码块结束
		return checkFlag; // 返回 checkFlag
	} // 代码块结束

	/** // 保留原作者写的块注释
	 * 检查数组中元素,是否在checkValue中出现 // 保留原作者写的块注释
	 * // 保留原作者写的块注释
	 * @param arr // 保留原作者写的块注释
	 * @param checkValue // 保留原作者写的块注释
	 * @return // 保留原作者写的块注释
	 */ // 保留原作者写的块注释
	public static Boolean isContains(String[] arr, String checkValue) { // 定义方法 isContains(...)
		Boolean checkFlag = false; // 把 false 赋值给 checkFlag
		if (arr != null && arr.length > 0) { // 定义方法 方法(...)
			for (String str : arr) { // 定义方法 方法(...)
				if (checkValue.indexOf(str)!=-1) { // 定义方法 方法(...)
					checkFlag = true; // 把 true 赋值给 checkFlag
					break; // 跳出当前循环\u6216分支
				} // 代码块结束
			} // 代码块结束
		} // 代码块结束
		return checkFlag; // 返回 checkFlag
	} // 代码块结束

} // 代码块结束

文件:xuecheng-plus-base/src/main/java/com/xuecheng/base/utils/VideoUtil.java

package com.xuecheng.base.utils; // 声明类所在的包路径

import java.io.IOException; // 导入 IOException 类
import java.io.InputStream; // 导入 InputStream 类
import java.util.ArrayList; // 导入 ArrayList 类
import java.util.List; // 导入 List 类

/** // 保留原作者写的块注释
 * 此文件作为视频文件处理父类,提供: // 保留原作者写的块注释
 * 1、查看视频时长 // 保留原作者写的块注释
 * 2、校验两个视频的时长是否相等 // 保留原作者写的块注释
 * // 保留原作者写的块注释
 */ // 保留原作者写的块注释
public class VideoUtil { // 定义 class VideoUtil

    String ffmpeg_path = "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe";//ffmpeg的安装位置 // 把 "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe" 赋值给 ffmpeg_path

    public VideoUtil(String ffmpeg_path){ // 定义方法 VideoUtil(...)
        this.ffmpeg_path = ffmpeg_path; // 把 ffmpeg_path 赋值给 this.ffmpeg_path
    } // 代码块结束

    //检查视频时间是否一致 // 保留原作者写的行内注释
    public Boolean check_video_time(String source,String target) { // 定义方法 check_video_time(...)
        String source_time = get_video_time(source); // 把 get_video_time(source) 赋值给 source_time
        //取出时分秒 // 保留原作者写的行内注释
        source_time = source_time.substring(0,source_time.lastIndexOf(".")); // 把 source_time.substring(0,source_time.lastIndexOf(".")) 赋值给 source_time
        String target_time = get_video_time(target); // 把 get_video_time(target) 赋值给 target_time
        //取出时分秒 // 保留原作者写的行内注释
        target_time = target_time.substring(0,target_time.lastIndexOf(".")); // 把 target_time.substring(0,target_time.lastIndexOf(".")) 赋值给 target_time
        if(source_time == null || target_time == null){ // 定义方法 方法(...)
            return false; // 返回 false
        } // 代码块结束
        if(source_time.equals(target_time)){ // 定义方法 方法(...)
            return true; // 返回 true
        } // 代码块结束
        return false; // 返回 false
    } // 代码块结束

    //获取视频时间(时:分:秒:毫秒) // 保留原作者写的行内注释
    public String get_video_time(String video_path) { // 定义方法 get_video_time(...)
        /* // 保留原作者写的块注释
        ffmpeg -i  lucene.mp4 // 代码逻辑
         */ // 保留原作者写的块注释
        List<String> commend = new ArrayList<String>(); // 创建 ArrayList<String> 对象并赋值给 commend
        commend.add(ffmpeg_path); // 执行语句
        commend.add("-i"); // 执行语句
        commend.add(video_path); // 执行语句
        try { // 尝试执行可能抛出异常的代码
            ProcessBuilder builder = new ProcessBuilder(); // 创建 ProcessBuilder 对象并赋值给 builder
            builder.command(commend); // 执行语句
            //将标准输入流和错误输入流合并,通过标准输入流程读取信息 // 保留原作者写的行内注释
            builder.redirectErrorStream(true); // 执行语句
            Process p = builder.start(); // 把 builder.start() 的返回值赋给 p
            String outstring = waitFor(p); // 把 waitFor(p) 赋值给 outstring
            System.out.println(outstring); // 执行语句
            int start = outstring.trim().indexOf("Duration: "); // 把 outstring.trim().indexOf("Duration: ") 赋值给 start
            if(start>=0){ // 定义方法 方法(...)
                int end = outstring.trim().indexOf(", start:"); // 把 outstring.trim().indexOf(", start:") 赋值给 end
                if(end>=0){ // 定义方法 方法(...)
                    String time = outstring.substring(start+10,end); // 把 outstring.substring(start+10,end) 赋值给 time
                    if(time!=null && !time.equals("")){ // 定义方法 方法(...)
                        return time.trim(); // 返回 time.trim()
                    } // 代码块结束
                } // 代码块结束
            } // 代码块结束

        } catch (Exception ex) { // 定义方法 catch(...)

            ex.printStackTrace(); // 执行语句

        } // 代码块结束
        return null; // 返回 null
    } // 代码块结束

    public String waitFor(Process p) { // 定义方法 waitFor(...)
        InputStream in = null; // 把变量 in 初始化为 null
        InputStream error = null; // 把变量 error 初始化为 null
        String result = "error"; // 把 "error" 赋值给 result
        int exitValue = -1; // 把 -1 赋值给 exitValue
        StringBuffer outputString = new StringBuffer(); // 创建 StringBuffer 对象并赋值给 outputString
        try { // 尝试执行可能抛出异常的代码
            in = p.getInputStream(); // 把 p.getInputStream() 的返回值赋给 in
            error = p.getErrorStream(); // 把 p.getErrorStream() 的返回值赋给 error
            boolean finished = false; // 把 false 赋值给 finished
            int maxRetry = 600;//每次休眠1秒,最长执行时间10分种 // 把 600 赋值给 maxRetry
            int retry = 0; // 把 0 赋值给 retry
            while (!finished) { // 定义方法 方法(...)
                if (retry > maxRetry) { // 定义方法 方法(...)
                    return "error"; // 返回 "error"
                } // 代码块结束
                try { // 尝试执行可能抛出异常的代码
                    while (in.available() > 0) { // 定义方法 方法(...)
                        Character c = new Character((char) in.read()); // 创建 Character 对象并赋值给 c
                        outputString.append(c); // 执行语句
                        System.out.print(c); // 执行语句
                    } // 代码块结束
                    while (error.available() > 0) { // 定义方法 方法(...)
                        Character c = new Character((char) in.read()); // 创建 Character 对象并赋值给 c
                        outputString.append(c); // 执行语句
                        System.out.print(c); // 执行语句
                    } // 代码块结束
                    //进程未结束时调用exitValue将抛出异常 // 保留原作者写的行内注释
                    exitValue = p.exitValue(); // 把 p.exitValue() 的返回值赋给 exitValue
                    finished = true; // 把 true 赋值给 finished

                } catch (IllegalThreadStateException e) { // 定义方法 catch(...)
                    Thread.currentThread().sleep(1000);//休眠1秒 // 执行语句
                    retry++; // 让 retry 自增 1
                } // 代码块结束
            } // 代码块结束

        } catch (Exception e) { // 定义方法 catch(...)
            e.printStackTrace(); // 执行语句
        } finally { // 代码逻辑
            if (in != null) { // 定义方法 方法(...)
                try { // 尝试执行可能抛出异常的代码
                    in.close(); // 执行语句
                } catch (IOException e) { // 定义方法 catch(...)
                    System.out.println(e.getMessage()); // 执行语句
                } // 代码块结束
            } // 代码块结束
        } // 代码块结束
        return outputString.toString(); // 返回 outputString.toString()

    } // 代码块结束

    public static void main(String[] args) throws IOException { // 定义方法 main(...)
        String ffmpeg_path = "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe";//ffmpeg的安装位置 // 把 "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe" 赋值给 ffmpeg_path
        VideoUtil videoUtil = new VideoUtil(ffmpeg_path); // 创建 VideoUtil 对象并赋值给 videoUtil
        String video_time = videoUtil.get_video_time("E:\\ffmpeg_test\\1.avi"); // 把 videoUtil.get_video_time("E:\\ffmpeg_test\\1.avi") 赋值给 video_time
        System.out.println(video_time); // 执行语句
    } // 代码块结束
} // 代码块结束
appendix_A
https://clxhxhhr.top/posts/4368/
作者
clxstart
发布于
2026-09-26
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。