init
This commit is contained in:
71
common/common-core/pom.xml
Normal file
71
common/common-core/pom.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>common</artifactId>
|
||||
<groupId>cn.fateverse</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>common-core</artifactId>
|
||||
|
||||
<description>common-core核心模块</description>
|
||||
|
||||
<properties>
|
||||
<guava.version>30.1-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!-- Alibaba Fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- Apache Lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
import cn.fateverse.common.core.enums.MethodEnum;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* mybatis自动注入时间
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AutoTime {
|
||||
|
||||
/**
|
||||
* sql 方法 INSERT,UPDATE
|
||||
* @return 方法类型
|
||||
*/
|
||||
MethodEnum method();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
import cn.fateverse.common.core.enums.AutoUserEnum;
|
||||
import cn.fateverse.common.core.enums.MethodEnum;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* mybatis自动注入用户信息
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AutoUser {
|
||||
|
||||
AutoUserEnum value() default AutoUserEnum.USER_NAME;
|
||||
|
||||
/**
|
||||
* sql 方法 INSERT,UPDATE
|
||||
*
|
||||
* @return 方法类型
|
||||
*/
|
||||
MethodEnum method();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 开启mybatis自动注入的能力
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EnableAutoField {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 用户实体类需要excel导出的字段
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/12/19
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface Excel {
|
||||
/**
|
||||
* 字段描述
|
||||
*/
|
||||
String value() default "";
|
||||
/**
|
||||
* 字段排序
|
||||
*/
|
||||
int order() default Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* 时间格式
|
||||
*/
|
||||
String dateFormat() default "yyyy-MM-dd";
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
String dictType() default "";
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的高度 单位为字符
|
||||
* 占时未实现后其迭代
|
||||
*/
|
||||
double height() default 14;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的宽 单位为字符
|
||||
* 占时未实现后其迭代
|
||||
*/
|
||||
double width() default 16;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 用于标注当前对象中存在@Excel注解标注的需要导出的字段
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/12/19
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface Excels {
|
||||
|
||||
/**
|
||||
* 字段描述
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
|
||||
/**
|
||||
* 字段排序
|
||||
*/
|
||||
int order() default Integer.MAX_VALUE;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.fateverse.common.core.annotaion;
|
||||
|
||||
|
||||
import cn.fateverse.common.core.enums.GenIdEnum;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自动生成id
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GenerateId {
|
||||
|
||||
GenIdEnum idType() default GenIdEnum.UUID;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.fateverse.common.core.constant;
|
||||
|
||||
/**
|
||||
* 缓存key
|
||||
* @author Clay
|
||||
* @date 2022/11/9
|
||||
*/
|
||||
public class CacheConstants {
|
||||
|
||||
/**
|
||||
* 验证码 redis key
|
||||
*/
|
||||
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||
/**
|
||||
* 路由缓存地址
|
||||
*/
|
||||
public static final String ROUTE_CACHE_KEY = "router_key:";
|
||||
/**
|
||||
* 登录用户 redis key
|
||||
*/
|
||||
public static final String LOGIN_TOKEN_KEY = "login_info:";
|
||||
/**
|
||||
* 字典类型 redis key
|
||||
*/
|
||||
public static final String DICT_KEY = "dict:";
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.fateverse.common.core.constant;
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author Clay
|
||||
*/
|
||||
public class Constants {
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String TOKEN_PREFIX = "Bearer ";
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
public static final String HTTP = "http://";
|
||||
|
||||
/**
|
||||
* https请求
|
||||
*/
|
||||
public static final String HTTPS = "https://";
|
||||
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY = "login_user_key";
|
||||
|
||||
/**
|
||||
* 验证码有效期(分钟)
|
||||
*/
|
||||
public static final long CAPTCHA_EXPIRATION = 2;
|
||||
|
||||
|
||||
public static final String UTF8 = "UTF-8";
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.fateverse.common.core.constant;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-25
|
||||
*/
|
||||
public class DateConstants {
|
||||
|
||||
public static String YYYY = "yyyy";
|
||||
|
||||
public static String YYYY_MM = "yyyy-MM";
|
||||
|
||||
public static String YYYY_MM_DD = "yyyy-MM-dd";
|
||||
|
||||
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||||
|
||||
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package cn.fateverse.common.core.constant;
|
||||
|
||||
/**
|
||||
* 用户常量信息
|
||||
*
|
||||
* @author Clay
|
||||
*/
|
||||
public class UserConstants {
|
||||
|
||||
/**
|
||||
* 平台内系统用户的唯一标志
|
||||
*/
|
||||
public static final String SYS_USER = "SYS_USER";
|
||||
|
||||
/**
|
||||
* 匿名用户
|
||||
*/
|
||||
public static final String ANONYMOUS_USER = "anonymousUser";
|
||||
|
||||
/**
|
||||
* 正常状态
|
||||
*/
|
||||
public static final String NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 异常状态
|
||||
*/
|
||||
public static final String EXCEPTION = "1";
|
||||
|
||||
|
||||
/**
|
||||
* 部门停用状态
|
||||
*/
|
||||
public static final String DEPT_DISABLE = "1";
|
||||
|
||||
|
||||
/**
|
||||
* Layout组件标识
|
||||
*/
|
||||
public final static String LAYOUT = "Layout";
|
||||
|
||||
/**
|
||||
* 校验返回结果码
|
||||
*/
|
||||
public final static String UNIQUE = "0";
|
||||
|
||||
public final static String NOT_UNIQUE = "1";
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import cn.fateverse.common.core.annotaion.AutoTime;
|
||||
import cn.fateverse.common.core.annotaion.AutoUser;
|
||||
import cn.fateverse.common.core.enums.MethodEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public class BaseEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@AutoUser(method = MethodEnum.INSERT)
|
||||
private Object createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@AutoTime(method = MethodEnum.INSERT)
|
||||
@JsonFormat(locale = "zh",timezone = "GMT+8",pattern = "yyyy-MM-dd")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@AutoUser(method = MethodEnum.UPDATE)
|
||||
private Object updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@AutoTime(method = MethodEnum.UPDATE)
|
||||
@JsonFormat(locale = "zh",timezone = "GMT+8",pattern = "yyyy-MM-dd")
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
/**
|
||||
* 备注信息
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
public Object getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
public void setCreateBy(Object createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Object getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
public void setUpdateBy(Object updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-11-14 21:11
|
||||
*/
|
||||
@Data
|
||||
public class IdWrapper implements Serializable {
|
||||
|
||||
private Long id;
|
||||
|
||||
private List<Long> ids;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/4
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Option {
|
||||
/**
|
||||
* 节点ID
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String label;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Treeselect树结构实体类
|
||||
*
|
||||
* @author Clay
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OptionTree implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 节点ID
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private Object label;
|
||||
|
||||
/**
|
||||
* 子节点
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<OptionTree> children;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
@Data
|
||||
public class PageInfo {
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
private Integer pageNum;
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
private Integer pageSize;
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
private String orderByColumn;
|
||||
|
||||
/**
|
||||
* 排序的方向desc或者asc
|
||||
*/
|
||||
private String isAsc = "asc";
|
||||
|
||||
/**
|
||||
* 分页参数合理化
|
||||
*/
|
||||
private Boolean reasonable = true;
|
||||
|
||||
public String getOrderBy() {
|
||||
if (StrUtil.isEmpty(orderByColumn)) {
|
||||
return "";
|
||||
}
|
||||
return StrUtil.toUnderlineCase(orderByColumn) + " " + isAsc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.fateverse.common.core.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/9
|
||||
*/
|
||||
@Data
|
||||
public class QueryTime implements Serializable {
|
||||
|
||||
/**
|
||||
* 筛选创建时间的开始时间
|
||||
*/
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 筛选创建时间的结束时间
|
||||
*/
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
public enum AutoUserEnum {
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
USER_NAME,
|
||||
USER_ID,
|
||||
NICK_NAME,
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
public enum GenIdEnum {
|
||||
/**
|
||||
* id生成类型
|
||||
*/
|
||||
UUID,
|
||||
SNOWFLAKE
|
||||
;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/9
|
||||
*/
|
||||
public enum MenuEnum {
|
||||
|
||||
/**
|
||||
* 状态信息
|
||||
*/
|
||||
DIRECTORY("D", "目录"),
|
||||
MENU("M", "菜单"),
|
||||
BUTTON("B", "按钮"),
|
||||
LAYOUT("LAYOUT", "Layout"),
|
||||
PARENT_VIEW("PARENT_VIEW", "ParentView"),
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
MenuEnum(String code, String info) {
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-05
|
||||
*/
|
||||
public enum MethodEnum {
|
||||
|
||||
/**
|
||||
* 需要设置的方法
|
||||
*/
|
||||
UPDATE,
|
||||
INSERT,
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-10
|
||||
*/
|
||||
public enum ResultEnum {
|
||||
/**
|
||||
* 返回状态枚举
|
||||
*/
|
||||
SUCCESS(1000, "操作成功", HttpStatus.OK),
|
||||
|
||||
NO_DATA(1001, "查询结果为空", HttpStatus.OK),
|
||||
|
||||
RESUBMIT_LOCK(2002, "重复提交", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
ERROR(2000, "操作失败", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
SYS_ERROR(2001, "系统异常", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
SENTINEL_FLOW(3000, "限流了", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
SENTINEL_PARAM_FLOW(3000, "热点参数限流", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
SENTINEL_SYSTEM(3000, "系统规则负载等不满足要求", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
|
||||
SENTINEL_AUTHORITY(3000, "授权规则不通过", HttpStatus.UNAUTHORIZED),
|
||||
|
||||
SENTINEL_DEGRADE(3000, "降级了", HttpStatus.INTERNAL_SERVER_ERROR),
|
||||
;
|
||||
|
||||
ResultEnum(int code, String msg, HttpStatus status) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public final int code;
|
||||
|
||||
public final String msg;
|
||||
|
||||
public final transient HttpStatus status;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/6
|
||||
*/
|
||||
public enum StateEnum {
|
||||
|
||||
/**
|
||||
* 状态信息
|
||||
*/
|
||||
NORMAL("1", "正常"),
|
||||
DISABLE("0", "停用");
|
||||
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
StateEnum(String code, String info) {
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.fateverse.common.core.enums;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public enum UserState {
|
||||
/**
|
||||
* 用户状态信息
|
||||
*/
|
||||
DISABLE("0", "停用"),
|
||||
OK("1", "正常"),
|
||||
DELETED("2", "删除");
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
UserState(String code, String info) {
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package cn.fateverse.common.core.exception;
|
||||
|
||||
/**
|
||||
* 基础异常
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
|
||||
/**
|
||||
* 所属模块
|
||||
*/
|
||||
private String module;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 错误码对应的参数
|
||||
*/
|
||||
private Object[] args;
|
||||
|
||||
/**
|
||||
* 错误消息
|
||||
*/
|
||||
private String defaultMessage;
|
||||
|
||||
public BaseException(String module, String code, Object[] args, String defaultMessage) {
|
||||
this.module = module;
|
||||
this.code = code;
|
||||
this.args = args;
|
||||
this.defaultMessage = defaultMessage;
|
||||
}
|
||||
|
||||
public BaseException(String module, String code, Object[] args) {
|
||||
this(module, code, args, null);
|
||||
}
|
||||
|
||||
public BaseException(String module, String defaultMessage) {
|
||||
this(module, null, null, defaultMessage);
|
||||
}
|
||||
|
||||
public BaseException(String code, Object[] args) {
|
||||
this(null, code, args, null);
|
||||
}
|
||||
|
||||
public BaseException(String defaultMessage) {
|
||||
this(null, null, null, defaultMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
String message = null;
|
||||
if (message == null) {
|
||||
message = defaultMessage;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public String getDefaultMessage() {
|
||||
return defaultMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.fateverse.common.core.exception;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/29
|
||||
*/
|
||||
public class CustomException extends RuntimeException {
|
||||
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
public CustomException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public CustomException(String message, Integer code) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public CustomException(String message, Throwable e) {
|
||||
super(message, e);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public CustomException() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.fateverse.common.core.exception;
|
||||
|
||||
import cn.fateverse.common.core.enums.ResultEnum;
|
||||
|
||||
public class TierDownException extends CustomException {
|
||||
|
||||
public TierDownException(String message) {
|
||||
super(ResultEnum.SYS_ERROR.msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.fateverse.common.core.exception;
|
||||
|
||||
/**
|
||||
* 用户信息异常类
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public class UserException extends BaseException {
|
||||
|
||||
|
||||
public UserException(String code, Object[] args) {
|
||||
super("user", code, args, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.fateverse.common.core.exception;
|
||||
|
||||
|
||||
/**
|
||||
* 用户密码不正确或不符合规范异常类
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public class UserPasswordNotMatchException extends UserException {
|
||||
|
||||
|
||||
public UserPasswordNotMatchException() {
|
||||
super("user.password.not.match", null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package cn.fateverse.common.core.result;
|
||||
|
||||
|
||||
import cn.fateverse.common.core.enums.ResultEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 返回结果集
|
||||
*
|
||||
* @author: Clay
|
||||
* @date: 2022/5/31 10:00
|
||||
*/
|
||||
public class Result<T> implements Serializable {
|
||||
private Integer code;
|
||||
private String msg;
|
||||
private T data;
|
||||
private transient HttpStatus status;
|
||||
|
||||
|
||||
public Result() {
|
||||
}
|
||||
|
||||
public Result(Integer code, String msg, T data, HttpStatus status) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = data;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(Integer code, String msg, T data) {
|
||||
return new Result<>(code, msg, data, HttpStatus.OK);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(Integer code, String msg, T data, HttpStatus status) {
|
||||
return new Result<>(code, msg, data, status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(String msg, T data) {
|
||||
return Result.ok(ResultEnum.SUCCESS.code, msg, data, ResultEnum.SUCCESS.status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(Integer code, T data) {
|
||||
return Result.ok(code, ResultEnum.SUCCESS.msg, data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(String msg) {
|
||||
return ok(ResultEnum.SUCCESS.code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(T data) {
|
||||
return Result.ok(ResultEnum.SUCCESS.msg, data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok() {
|
||||
return Result.ok(ResultEnum.SUCCESS.msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String msg, T data) {
|
||||
return Result.error(ResultEnum.ERROR.code, msg, data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(Integer code, String msg) {
|
||||
return Result.error(code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> notFound(String msg) {
|
||||
return Result.error(HttpStatus.NOT_FOUND.value(), msg, null, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(Integer code, String msg, T data) {
|
||||
return new Result<>(code, msg, data, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(Integer code, String msg, T data, HttpStatus status) {
|
||||
return new Result<>(code, msg, data, status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> unauthorized(String msg) {
|
||||
return new Result<>(HttpStatus.UNAUTHORIZED.value(), msg, null, HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(HttpStatus status, String msg) {
|
||||
return new Result<>(status.value(), msg, null, status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(ResultEnum resultEnum) {
|
||||
return Result.error(resultEnum.code, resultEnum.msg, null, resultEnum.status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String msg) {
|
||||
return Result.error(ResultEnum.ERROR.code, msg, null, ResultEnum.ERROR.status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error() {
|
||||
return Result.error(ResultEnum.ERROR.code, ResultEnum.ERROR.msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> info(String msg) {
|
||||
return Result.ok(ResultEnum.NO_DATA.code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> info(ResultEnum resultEnum) {
|
||||
return Result.error(resultEnum.code, resultEnum.msg, null, resultEnum.status);
|
||||
}
|
||||
|
||||
public static <T> Result<T> noData() {
|
||||
return Result.ok(ResultEnum.NO_DATA.code, ResultEnum.NO_DATA.msg, null);
|
||||
}
|
||||
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public HttpStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setStatus(HttpStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.fateverse.common.core.result.page;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表格分页数据对象
|
||||
*
|
||||
* @author binlin
|
||||
*/
|
||||
@Data
|
||||
public class TableDataInfo<T> implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private long total;
|
||||
|
||||
/**
|
||||
* 列表数据
|
||||
*/
|
||||
private List<T> rows;
|
||||
|
||||
/**
|
||||
* 表格数据对象
|
||||
*/
|
||||
public TableDataInfo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*
|
||||
* @param list 列表数据
|
||||
* @param total 总记录数
|
||||
*/
|
||||
public TableDataInfo(List<T> list, int total) {
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.annotaion.AutoTime;
|
||||
import cn.fateverse.common.core.annotaion.AutoUser;
|
||||
import cn.fateverse.common.core.constant.UserConstants;
|
||||
import cn.fateverse.common.core.enums.AutoUserEnum;
|
||||
import cn.fateverse.common.core.enums.MethodEnum;
|
||||
import cn.fateverse.common.core.exception.CustomException;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-25
|
||||
*/
|
||||
public class AutoSetValueUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AutoSetValueUtils.class);
|
||||
|
||||
public static final String LONG_TYPE = "java.lang.Long";
|
||||
public static final String OBJECT_TYPE = "java.lang.Object";
|
||||
public static final String STRING_TYPE = "java.lang.String";
|
||||
public static String BASE_PACKAGE;
|
||||
|
||||
|
||||
static {
|
||||
BASE_PACKAGE = getBasePackage(AutoSetValueUtils.class);
|
||||
}
|
||||
|
||||
public static String getBasePackage(Class<?> clazz) {
|
||||
String typeName = clazz.getTypeName();
|
||||
int fastIndex = typeName.indexOf(".");
|
||||
return typeName.substring(0, typeName.indexOf(".", fastIndex + 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 自动设置userID
|
||||
*
|
||||
* @param parameter 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param field 字段
|
||||
*/
|
||||
public static void autoUser(Object parameter, MethodEnum methodEnum, Field field) {
|
||||
//获取到设置用户id的注解
|
||||
AutoUser autoUser = field.getAnnotation(AutoUser.class);
|
||||
if (null != autoUser && autoUser.method() == methodEnum) {
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Object principal = context.getAuthentication().getPrincipal();
|
||||
if (null == principal || UserConstants.ANONYMOUS_USER.equals(principal)) {
|
||||
return;
|
||||
}
|
||||
JSONObject user = ReflectUserUtils.getUser(principal);
|
||||
AutoUserEnum value = autoUser.value();
|
||||
Class<?> type = field.getType();
|
||||
Object object = null;
|
||||
String typeName = type.getTypeName();
|
||||
if (value == AutoUserEnum.USER_ID) {
|
||||
//设置用户id
|
||||
long userId = user.getLongValue("userId");
|
||||
switch (typeName) {
|
||||
case OBJECT_TYPE:
|
||||
case LONG_TYPE:
|
||||
object = userId;
|
||||
break;
|
||||
case STRING_TYPE:
|
||||
object = Long.toString(userId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (value == AutoUserEnum.USER_NAME || value == AutoUserEnum.NICK_NAME) {
|
||||
object = value == AutoUserEnum.USER_NAME ? user.getString("userName") : user.getString("nickName");
|
||||
if (!(OBJECT_TYPE.equals(typeName) || STRING_TYPE.equals(typeName))) {
|
||||
throw new CustomException("数据类型不配配,Field字段类型为" + typeName + "不能放入String类型的数据");
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, object);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("字段:{}自动设置参数失败", field.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动设置时间
|
||||
*
|
||||
* @param parameter 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param field 字段
|
||||
*/
|
||||
public static void autoTime(Object parameter, MethodEnum methodEnum, Field field) {
|
||||
//获取到设置时间的注解
|
||||
AutoTime autoTime = field.getAnnotation(AutoTime.class);
|
||||
if (null != autoTime && autoTime.method() == methodEnum) {
|
||||
field.setAccessible(true);
|
||||
Class<?> type = field.getType();
|
||||
Object time = null;
|
||||
try {
|
||||
time = type.newInstance();
|
||||
field.set(parameter, time);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
log.error("字段:{}自动设置参数失败,参数为:{}", field.getName(), time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动设置userID
|
||||
*
|
||||
* @param parameter 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param fields 字段
|
||||
*/
|
||||
public static void autoUserNew(Object parameter, MethodEnum methodEnum, Set<Field> fields) {
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Authentication authentication = context.getAuthentication();
|
||||
if (null == authentication) {
|
||||
return;
|
||||
}
|
||||
Object principal = authentication.getPrincipal();
|
||||
if (null == principal || UserConstants.ANONYMOUS_USER.equals(principal)) {
|
||||
return;
|
||||
}
|
||||
JSONObject user = ReflectUserUtils.getUser(principal);
|
||||
for (Field field : fields) {
|
||||
setUser(methodEnum, user, parameter, field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动设置时间
|
||||
*
|
||||
* @param parameter 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param fields 字段
|
||||
*/
|
||||
public static void autoTimeNew(Object parameter, MethodEnum methodEnum, Set<Field> fields) {
|
||||
for (Field field : fields) {
|
||||
setTime(methodEnum, parameter, field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动设置userID
|
||||
*
|
||||
* @param list 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param fields 字段
|
||||
*/
|
||||
public static void autoUserList(List<Object> list, MethodEnum methodEnum, Set<Field> fields) {
|
||||
if (fields.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
Object principal = context.getAuthentication().getPrincipal();
|
||||
if (null == principal || UserConstants.ANONYMOUS_USER.equals(principal)) {
|
||||
return;
|
||||
}
|
||||
JSONObject user = ReflectUserUtils.getUser(principal);
|
||||
for (Object param : list) {
|
||||
for (Field field : fields) {
|
||||
setUser(methodEnum, user, param, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置用户通用函数
|
||||
*
|
||||
* @param methodEnum 方法类型
|
||||
* @param user 用户信息
|
||||
* @param param 参数对象
|
||||
* @param field 字段对象
|
||||
*/
|
||||
private static void setUser(MethodEnum methodEnum, JSONObject user, Object param, Field field) {
|
||||
long userId = user.getLongValue("userId");
|
||||
//获取到设置用户id的注解
|
||||
AutoUser autoUser = field.getAnnotation(AutoUser.class);
|
||||
if (null != autoUser && autoUser.method() == methodEnum) {
|
||||
AutoUserEnum value = autoUser.value();
|
||||
Class<?> type = field.getType();
|
||||
Object object = null;
|
||||
String typeName = type.getTypeName();
|
||||
if (value == AutoUserEnum.USER_ID) {
|
||||
//设置用户id
|
||||
if (type == Object.class || type == Long.class) {
|
||||
object = userId;
|
||||
} else if (type == String.class) {
|
||||
object = Long.toString(userId);
|
||||
}
|
||||
} else if (value == AutoUserEnum.USER_NAME || value == AutoUserEnum.NICK_NAME) {
|
||||
object = value == AutoUserEnum.USER_NAME ? user.getString("userName") : user.getString("nickName");
|
||||
if (!(type == Object.class || type == Long.class)) {
|
||||
throw new CustomException("数据类型不配配,Field字段类型为" + typeName + "不能放入String类型的数据");
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
field.set(param, object);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("字段:{}自动设置参数失败", field.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动设置时间
|
||||
*
|
||||
* @param list 参数
|
||||
* @param methodEnum sql方法
|
||||
* @param fields 时间
|
||||
*/
|
||||
public static void autoTimeList(List<Object> list, MethodEnum methodEnum, Set<Field> fields) {
|
||||
if (fields.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (Object param : list) {
|
||||
for (Field field : fields) {
|
||||
setTime(methodEnum, param, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间
|
||||
*
|
||||
* @param methodEnum 方法类型
|
||||
* @param param 参数对象
|
||||
* @param field 字段
|
||||
*/
|
||||
private static void setTime(MethodEnum methodEnum, Object param, Field field) {
|
||||
//获取到设置时间的注解
|
||||
AutoTime autoTime = field.getAnnotation(AutoTime.class);
|
||||
if (null != autoTime && autoTime.method() == methodEnum) {
|
||||
field.setAccessible(true);
|
||||
Class<?> type = field.getType();
|
||||
Object time = null;
|
||||
try {
|
||||
time = type.newInstance();
|
||||
field.set(param, time);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
log.error("字段:{}自动设置参数失败,参数为:{}", field.getName(), time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-10
|
||||
*/
|
||||
public class HttpServletUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 获取request信息
|
||||
* @return
|
||||
*/
|
||||
public static HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return attributes.getRequest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取http响应对象
|
||||
*
|
||||
* @return response
|
||||
*/
|
||||
public static HttpServletResponse getResponse() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return attributes.getResponse();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.exception.CustomException;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-10-15
|
||||
*/
|
||||
public class IpBackUtils {
|
||||
|
||||
public static final String BLACK_LIST = "black:list:";
|
||||
public final static String BLACK_LIST_IPV_4 = BLACK_LIST + "ipv4";
|
||||
public final static String BLACK_LIST_IPV_6 = BLACK_LIST + "ipv6";
|
||||
public final static String BLACK_LIST_IP = BLACK_LIST + "ip";
|
||||
public final static String IPV_4 = "ipv4";
|
||||
public final static String IPV_6 = "ipv6";
|
||||
|
||||
|
||||
public static long ipToDecimal(String ipAddress) {
|
||||
try {
|
||||
// 将IP地址拆分为四个部分
|
||||
String[] ipParts = ipAddress.split("\\.");
|
||||
// 将每个部分转换为整数
|
||||
long decimalNumber = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
long ipPart = Long.parseLong(ipParts[i]);
|
||||
// 每个部分的权重为256的(3-i)次方
|
||||
decimalNumber += ipPart * Math.pow(256, 3 - i);
|
||||
}
|
||||
return decimalNumber;
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getIpType(String ip) {
|
||||
try {
|
||||
InetAddress address = InetAddress.getByName(ip);
|
||||
if (address instanceof Inet4Address) {
|
||||
return IPV_4;
|
||||
} else if (address instanceof Inet6Address) {
|
||||
return IPV_6;
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
throw new CustomException("无效ip地址");
|
||||
}
|
||||
throw new CustomException("无效ip地址");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* 获取IP方法
|
||||
*
|
||||
* @author binlin
|
||||
*/
|
||||
public class IpUtils {
|
||||
|
||||
public static String getIpAdder(HttpServletRequest request) {
|
||||
if (request == null) {
|
||||
return "unknown";
|
||||
}
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.removeHtmlTag(ip);
|
||||
}
|
||||
|
||||
public static boolean internalIp(String ip) {
|
||||
byte[] addr = textToNumericFormatV4(ip);
|
||||
return internalIp(addr) || "127.0.0.1".equals(ip);
|
||||
}
|
||||
|
||||
private static boolean internalIp(byte[] addr) {
|
||||
if (ObjectUtils.isEmpty(addr) || addr.length < 2) {
|
||||
return true;
|
||||
}
|
||||
final byte b0 = addr[0];
|
||||
final byte b1 = addr[1];
|
||||
// 10.x.x.x/8
|
||||
final byte SECTION_1 = 0x0A;
|
||||
// 172.16.x.x/12
|
||||
final byte SECTION_2 = (byte) 0xAC;
|
||||
final byte SECTION_3 = (byte) 0x10;
|
||||
final byte SECTION_4 = (byte) 0x1F;
|
||||
// 192.168.x.x/16
|
||||
final byte SECTION_5 = (byte) 0xC0;
|
||||
final byte SECTION_6 = (byte) 0xA8;
|
||||
switch (b0) {
|
||||
case SECTION_1:
|
||||
return true;
|
||||
case SECTION_2:
|
||||
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
|
||||
return true;
|
||||
}
|
||||
case SECTION_5:
|
||||
switch (b1) {
|
||||
case SECTION_6:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将IPv4地址转换成字节
|
||||
*
|
||||
* @param text IPv4地址
|
||||
* @return byte 字节
|
||||
*/
|
||||
public static byte[] textToNumericFormatV4(String text) {
|
||||
if (text.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
String[] elements = text.split("\\.", -1);
|
||||
try {
|
||||
long l;
|
||||
int i;
|
||||
switch (elements.length) {
|
||||
case 1:
|
||||
l = Long.parseLong(elements[0]);
|
||||
if ((l < 0L) || (l > 4294967295L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
|
||||
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 2:
|
||||
l = Integer.parseInt(elements[0]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l & 0xFF);
|
||||
l = Integer.parseInt(elements[1]);
|
||||
if ((l < 0L) || (l > 16777215L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 3:
|
||||
for (i = 0; i < 2; ++i) {
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
l = Integer.parseInt(elements[2]);
|
||||
if ((l < 0L) || (l > 65535L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 4:
|
||||
for (i = 0; i < 4; ++i) {
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getHostIp() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
public static String getHostName() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.exception.CustomException;
|
||||
|
||||
/**
|
||||
* Long工具类
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/11/6
|
||||
*/
|
||||
public class LongUtils {
|
||||
|
||||
|
||||
public static boolean isNull(Long num){
|
||||
return null == num || 0L == num;
|
||||
}
|
||||
|
||||
public static boolean isNotNull(Long num){
|
||||
return !isNull(num);
|
||||
}
|
||||
|
||||
public static void checkId(Long pk){
|
||||
checkId(pk,"缺少必要参数!");
|
||||
}
|
||||
|
||||
public static void checkId(Long pk, String message){
|
||||
if (isNull(pk)) {
|
||||
throw new CustomException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.enums.MenuEnum;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/9
|
||||
*/
|
||||
public class MenuTypeUtils {
|
||||
|
||||
public static boolean checkMenuTypeLegal(String menuType){
|
||||
return MenuEnum.MENU.getInfo().equals(menuType) ||
|
||||
MenuEnum.DIRECTORY.getInfo().equals(menuType)||
|
||||
MenuEnum.BUTTON.getInfo().equals(menuType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.exception.CustomException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/12/18
|
||||
*/
|
||||
public class ObjectUtils extends org.springframework.util.ObjectUtils {
|
||||
/**
|
||||
* 检查主键
|
||||
* @param pk 主键
|
||||
*/
|
||||
public static void checkPk(Object pk) {
|
||||
checkPk(pk, "缺少必要参数!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查主键
|
||||
* @param pk 主键
|
||||
* @param message 错误提示消息
|
||||
*/
|
||||
public static void checkPk(Object pk, String message) {
|
||||
if (pk instanceof Long) {
|
||||
LongUtils.checkId((Long) pk, message);
|
||||
} else if (pk instanceof String) {
|
||||
if (isEmpty(pk)) {
|
||||
throw new CustomException(message);
|
||||
}
|
||||
} else {
|
||||
if (null == pk) {
|
||||
throw new CustomException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查主键list
|
||||
* @param pkList 主键list
|
||||
*/
|
||||
public static void checkPkList(List<?> pkList) {
|
||||
checkPkList(pkList,"缺少必要参数!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查主键list
|
||||
* @param pkList 主键list
|
||||
* @param message 错误提示消息
|
||||
*/
|
||||
public static void checkPkList(List<?> pkList, String message) {
|
||||
if (isEmpty(pkList)){
|
||||
throw new CustomException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2023-05-10
|
||||
*/
|
||||
public class ReflectUserUtils {
|
||||
|
||||
/**
|
||||
* 从loginUser中获取到用户信息
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return 用户的字段信息
|
||||
*/
|
||||
private static Field getUserField(Object loginUser) {
|
||||
Class<?> userClass = loginUser.getClass();
|
||||
try {
|
||||
return userClass.getDeclaredField("user");
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到token 信息
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return token
|
||||
*/
|
||||
public static String getToken(Object loginUser) {
|
||||
Class<?> loginUserClass = loginUser.getClass();
|
||||
Field token;
|
||||
try {
|
||||
token = loginUserClass.getDeclaredField("token");
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return getValue(loginUser, token).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return 用户信息
|
||||
*/
|
||||
public static JSONObject getUser(Object loginUser) {
|
||||
Field userField = getUserField(loginUser);
|
||||
Object user = getValue(loginUser, userField);
|
||||
return (JSONObject) JSON.toJSON(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到用户Id
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return 用户id
|
||||
*/
|
||||
public static String getUserId(Object loginUser) {
|
||||
return getFieldValue(loginUser, "userId");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到用户名
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return 用户名
|
||||
*/
|
||||
public static String getUsername(Object loginUser) {
|
||||
return getFieldValue(loginUser, "userName");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到用户别名
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @return 用户别名
|
||||
*/
|
||||
public static String getNickname(Object loginUser) {
|
||||
return getFieldValue(loginUser, "nickName");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到值
|
||||
*
|
||||
* @param user 登录后的用户
|
||||
* @param field 字段
|
||||
* @return 值
|
||||
*/
|
||||
private static Object getValue(Object user, Field field) {
|
||||
field.setAccessible(true);
|
||||
return ReflectionUtils.getField(field, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过字段名获取到值
|
||||
*
|
||||
* @param loginUser 登录后的用户
|
||||
* @param fieldName 字段名
|
||||
* @return 值
|
||||
*/
|
||||
private static String getFieldValue(Object loginUser, String fieldName) {
|
||||
Field userField = getUserField(loginUser);
|
||||
Class<?> userClass = userField.getType().getSuperclass();
|
||||
Object user = getValue(loginUser, userField);
|
||||
Field field = null;
|
||||
try {
|
||||
field = userClass.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return getValue(user, field).toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
/**
|
||||
* Spring 事件发布工具类
|
||||
* @author Clay
|
||||
* @date 2022/11/1
|
||||
*/
|
||||
@Slf4j
|
||||
@Lazy(false)
|
||||
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
|
||||
/**
|
||||
* 从applicationContext中获取到Bean,并转换成为requiredType对应的类型
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType){
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从applicationContext中获取Bean,并自动转成对应接受的类型
|
||||
*/
|
||||
public static <T> T getBean(String name){
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布事件,实现异步执行功能
|
||||
* @param event
|
||||
*/
|
||||
public static void publishEvent(ApplicationEvent event){
|
||||
if (applicationContext == null){
|
||||
return;
|
||||
}
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
public static ApplicationContext getApplicationContext(){
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除SpringContextHolder中的applicationContext
|
||||
*/
|
||||
public static void clearHolder(){
|
||||
//如果是debug环境下,打印清除ApplicationContext的日志
|
||||
if (log.isDebugEnabled()){
|
||||
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
SpringContextHolder.clearHolder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.enums.StateEnum;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/6
|
||||
*/
|
||||
public class StateUtils {
|
||||
|
||||
public static boolean checkStateLegal(String state){
|
||||
return StateEnum.NORMAL.getCode().equals(state) ||
|
||||
StateEnum.DISABLE.getCode().equals(state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package cn.fateverse.common.core.utils;
|
||||
|
||||
import cn.fateverse.common.core.entity.PageInfo;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 表格数据处理
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public class TableSupport {
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
public static final String PAGE_NUM = "pageNum";
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String PAGE_SIZE = "pageSize";
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
public static final String ORDER_BY_COLUMN = "orderByColumn";
|
||||
|
||||
/**
|
||||
* 排序的方向 "desc" 或者 "asc".
|
||||
*/
|
||||
public static final String IS_ASC = "isAsc";
|
||||
|
||||
/**
|
||||
* 分页参数合理化
|
||||
*/
|
||||
public static final String REASONABLE = "reasonable";
|
||||
|
||||
/**
|
||||
* 封装分页对象
|
||||
*/
|
||||
public static PageInfo getPageInfo() {
|
||||
PageInfo pageInfo = new PageInfo();
|
||||
pageInfo.setPageNum(Convert.toInt(getParameter(PAGE_NUM), 1));
|
||||
pageInfo.setPageSize(Convert.toInt(getParameter(PAGE_SIZE), 10));
|
||||
pageInfo.setOrderByColumn(getParameter(ORDER_BY_COLUMN));
|
||||
pageInfo.setIsAsc(getParameter(IS_ASC));
|
||||
pageInfo.setReasonable(getParameterToBool(REASONABLE));
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
public static PageInfo buildPageRequest() {
|
||||
return getPageInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Boolean参数
|
||||
*/
|
||||
public static Boolean getParameterToBool(String name) {
|
||||
return Convert.toBool(getRequest().getParameter(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取String参数
|
||||
*/
|
||||
public static String getParameter(String name) {
|
||||
return Convert.toStr(getRequest().getParameter(name));
|
||||
}
|
||||
|
||||
|
||||
public static HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return attributes.getRequest();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.fateverse.common.core.utils.convert;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/16
|
||||
*/
|
||||
public class ObjectConfig {
|
||||
|
||||
|
||||
private boolean copy;
|
||||
private Map<String,String> mapper;
|
||||
private Set<String> exclude;
|
||||
|
||||
public ObjectConfig() {
|
||||
mapper = new LinkedHashMap<>();
|
||||
exclude = new LinkedHashSet<>();
|
||||
copy = true;
|
||||
}
|
||||
|
||||
public void setMapper(String targetKey, String sourceKey){
|
||||
mapper.put(targetKey,sourceKey);
|
||||
}
|
||||
|
||||
public void setExclude(String excludeKey){
|
||||
exclude.add(excludeKey);
|
||||
}
|
||||
|
||||
public Map<String,String> getMapper(){
|
||||
return mapper;
|
||||
}
|
||||
|
||||
public Set<String> getExclude() {
|
||||
return exclude;
|
||||
}
|
||||
|
||||
|
||||
public void setOption(String value,String label){
|
||||
this.copy = false;
|
||||
mapper.put("label",label);
|
||||
mapper.put("value",value);
|
||||
}
|
||||
|
||||
public boolean isCopy() {
|
||||
return copy;
|
||||
}
|
||||
|
||||
public void setCopy(boolean copy) {
|
||||
this.copy = copy;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package cn.fateverse.common.core.utils.convert;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/16
|
||||
* 对象之间的转换
|
||||
*/
|
||||
public class ObjectConvertUtil {
|
||||
|
||||
private static TreeConfig treeConfig;
|
||||
|
||||
|
||||
private static Map<String, Field> cacheTargetField;
|
||||
|
||||
private static Map<String,Field> cacheSourceField;
|
||||
|
||||
/**
|
||||
* 目标class
|
||||
*/
|
||||
private static Class<?> targetClass;
|
||||
|
||||
private static Class<?> sourceClass;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param list
|
||||
* @param target
|
||||
* @param config
|
||||
* @return
|
||||
* @param <T>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> build(List<?> list, Class<T> target, Consumer<TreeConfig> config) {
|
||||
if (list.isEmpty()){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
//将目标class对象设置为全局对象
|
||||
targetClass = target;
|
||||
sourceClass = list.get(0).getClass();
|
||||
//初始化config
|
||||
treeConfig = new TreeConfig();
|
||||
//将目标class对象设置为全局对象
|
||||
//提供给实现类对config进行修改
|
||||
config.accept(treeConfig);
|
||||
List<Object> collect = list.stream().map(ObjectConvertUtil::conversion).collect(Collectors.toList());
|
||||
return (List<T>) collect;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T conversion(Object object) {
|
||||
try {
|
||||
Object targetObject = targetClass.newInstance();
|
||||
//相同字段名称直接赋值
|
||||
if (treeConfig.isCopy()) {
|
||||
BeanUtils.copyProperties(object, targetObject);
|
||||
}
|
||||
//不同字段名进行赋值
|
||||
for (Map.Entry<String, String> entry : treeConfig.getMapper().entrySet()) {
|
||||
Object value = getSourceValue(object,entry.getValue());
|
||||
setTargetValue(targetObject,entry.getKey(),value);
|
||||
}
|
||||
for (String key : treeConfig.getExclude()) {
|
||||
setTargetValue(targetObject,key,null);
|
||||
}
|
||||
//返回结果
|
||||
return (T) targetObject;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getSourceValue(Object source,String sourceFiled){
|
||||
Field field = cacheSourceField.get(sourceFiled);
|
||||
if (null == field){
|
||||
try {
|
||||
field = sourceClass.getDeclaredField(sourceFiled);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cacheSourceField.put(sourceFiled,field);
|
||||
}
|
||||
field.setAccessible(true);
|
||||
return ReflectionUtils.getField(field,source);
|
||||
}
|
||||
|
||||
|
||||
private static void setTargetValue(Object target,String targetFiled,Object value){
|
||||
Field field = cacheTargetField.get(targetFiled);
|
||||
if (null == field){
|
||||
try {
|
||||
field = targetClass.getDeclaredField(targetFiled);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cacheTargetField.put(targetFiled,field);
|
||||
}
|
||||
field.setAccessible(true);
|
||||
ReflectionUtils.setField(field,target,value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package cn.fateverse.common.core.utils.convert;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/16
|
||||
* TreeConfig的配置文件
|
||||
*/
|
||||
public class TreeConfig {
|
||||
|
||||
|
||||
private boolean copy;
|
||||
|
||||
private final Map<String, String> mapper;
|
||||
private final Set<String> exclude;
|
||||
|
||||
private String idField;
|
||||
|
||||
private String parentField;
|
||||
|
||||
private String childrenField;
|
||||
|
||||
private Boolean isStore = false;
|
||||
|
||||
private String storeField;
|
||||
|
||||
|
||||
public TreeConfig() {
|
||||
mapper = new LinkedHashMap<>();
|
||||
exclude = new LinkedHashSet<>();
|
||||
copy = true;
|
||||
this.idField = "id";
|
||||
this.parentField = "parentId";
|
||||
this.childrenField = "children";
|
||||
}
|
||||
|
||||
public void setParentField(String parentField) {
|
||||
if (StrUtil.isEmpty(parentField)) {
|
||||
return;
|
||||
}
|
||||
this.parentField = parentField;
|
||||
}
|
||||
|
||||
public Boolean getStore() {
|
||||
return isStore;
|
||||
}
|
||||
|
||||
public String getStoreField() {
|
||||
return storeField;
|
||||
}
|
||||
|
||||
public String getParentField() {
|
||||
return parentField;
|
||||
}
|
||||
|
||||
|
||||
public String getIdField() {
|
||||
return idField;
|
||||
}
|
||||
|
||||
public void setIdField(String idField) {
|
||||
if (StrUtil.isEmpty(idField)) {
|
||||
return;
|
||||
}
|
||||
this.idField = idField;
|
||||
}
|
||||
|
||||
public void setSortOrder(Boolean isStore,String storeField) {
|
||||
this.isStore = isStore;
|
||||
this.storeField = storeField;
|
||||
}
|
||||
|
||||
public String getChildrenField() {
|
||||
return childrenField;
|
||||
}
|
||||
|
||||
public void setChildrenField(String childrenField) {
|
||||
if (StrUtil.isEmpty(childrenField)) {
|
||||
return;
|
||||
}
|
||||
this.childrenField = childrenField;
|
||||
}
|
||||
|
||||
public void setMapper(String targetKey, String sourceKey) {
|
||||
mapper.put(targetKey, sourceKey);
|
||||
}
|
||||
|
||||
public void setExclude(String excludeKey) {
|
||||
exclude.add(excludeKey);
|
||||
}
|
||||
|
||||
public Map<String, String> getMapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
public Set<String> getExclude() {
|
||||
return exclude;
|
||||
}
|
||||
|
||||
public void setOption(String valueField, String labelField) {
|
||||
this.copy = false;
|
||||
mapper.put("value", valueField);
|
||||
mapper.put("label", labelField);
|
||||
}
|
||||
|
||||
public boolean isCopy() {
|
||||
return copy;
|
||||
}
|
||||
|
||||
public void setCopy(boolean copy) {
|
||||
this.copy = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 空实现
|
||||
*/
|
||||
//@Override
|
||||
//public void build(TreeConfig treeConfig) {
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package cn.fateverse.common.core.utils.convert;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2022/11/16
|
||||
* 树形结构转换递归方式
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class TreeUtil {
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
private static TreeConfig treeConfig;
|
||||
|
||||
private static Map<String, Field> cacheTargetField;
|
||||
|
||||
private static Map<String, Field> cacheSourceField;
|
||||
|
||||
/**
|
||||
* 目标class
|
||||
*/
|
||||
private static Class<?> targetClass;
|
||||
|
||||
private static Class<?> sourceClass;
|
||||
|
||||
/**
|
||||
* 构建tree结构
|
||||
*
|
||||
* @param list 需要转换的list
|
||||
* @param target 目标class对象
|
||||
* @param config 配置项
|
||||
* @param <T> 目标对象类型
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> build(List<?> list, Class<T> target, Consumer<TreeConfig> config) {
|
||||
if (list.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
//将目标class对象设置为全局对象
|
||||
targetClass = target;
|
||||
sourceClass = list.get(0).getClass();
|
||||
//初始化config
|
||||
treeConfig = new TreeConfig();
|
||||
//初始化字段缓存
|
||||
cacheTargetField = new HashMap<>();
|
||||
cacheSourceField = new HashMap<>();
|
||||
//提供给实现类对config进行修改
|
||||
config.accept(treeConfig);
|
||||
//获取到最小的
|
||||
Object min = list.stream().min(Comparator.comparing(object -> getParentId(object).toString())).get();
|
||||
//获取到最小的父级id
|
||||
Object minPid = getParentId(min);
|
||||
//将数据通过他们的各自的父id进行分组
|
||||
Map<Object, List<Object>> listMap = list.stream().collect(Collectors.groupingBy(TreeUtil::getParentId));
|
||||
//最终开始进行tree的构建
|
||||
return getChildren(listMap, minPid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到子节点
|
||||
*
|
||||
* @param listMap
|
||||
* @param parentId
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
private static <T> List<T> getChildren(Map<Object, List<Object>> listMap, Object parentId) {
|
||||
//获取到缓存中的list
|
||||
List<?> objects = listMap.get(parentId);
|
||||
if (chickList(objects)) {
|
||||
return null;
|
||||
}
|
||||
if (treeConfig.getStore()) {
|
||||
objects = objects.stream().sorted(Comparator.comparing(item ->
|
||||
Convert.toInt(getSourceValue(item, treeConfig.getStoreField()))
|
||||
)).collect(Collectors.toList());
|
||||
}
|
||||
listMap.remove(parentId);
|
||||
//遍历数组,并将对象一一的转换
|
||||
List<Object> collect = objects.stream().map(object ->
|
||||
conversion(object, listMap)).collect(Collectors.toList());
|
||||
return (List<T>) collect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象直接的字段进行转换
|
||||
*
|
||||
* @param object
|
||||
* @param listMap
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
private static <T> T conversion(Object object, Map<Object, List<Object>> listMap) {
|
||||
try {
|
||||
Object targetObject = targetClass.newInstance();
|
||||
//相同字段名称直接赋值
|
||||
if (treeConfig.isCopy()) {
|
||||
BeanUtils.copyProperties(object, targetObject);
|
||||
}
|
||||
//不同字段名进行赋值
|
||||
for (Map.Entry<String, String> entry : treeConfig.getMapper().entrySet()) {
|
||||
Object value = getSourceValue(object, entry.getValue());
|
||||
setTargetValue(targetObject, entry.getKey(), value);
|
||||
}
|
||||
//设置子节点
|
||||
Object id = getSourceValue(object, treeConfig.getIdField());
|
||||
List<Object> children = getChildren(listMap, id);
|
||||
if (!chickList(children)) {
|
||||
setTargetValue(targetObject, treeConfig.getChildrenField(), children);
|
||||
}
|
||||
//设置完毕后,将需要排除的字段进行置空
|
||||
for (String key : treeConfig.getExclude()) {
|
||||
setTargetValue(targetObject, key, null);
|
||||
}
|
||||
//返回结果
|
||||
return (T) targetObject;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getSourceValue(Object source, String sourceFiled) {
|
||||
Field field = cacheSourceField.get(sourceFiled);
|
||||
if (null == field) {
|
||||
try {
|
||||
field = sourceClass.getDeclaredField(sourceFiled);
|
||||
field.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cacheSourceField.put(sourceFiled, field);
|
||||
}
|
||||
return ReflectionUtils.getField(field, source);
|
||||
}
|
||||
|
||||
|
||||
private static void setTargetValue(Object target, String targetFiled, Object value) {
|
||||
Field field = cacheTargetField.get(targetFiled);
|
||||
if (null == field) {
|
||||
try {
|
||||
field = targetClass.getDeclaredField(targetFiled);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
field.setAccessible(true);
|
||||
cacheTargetField.put(targetFiled, field);
|
||||
}
|
||||
ReflectionUtils.setField(field, target, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查list是否为空
|
||||
*
|
||||
* @param objects
|
||||
* @return
|
||||
*/
|
||||
private static boolean chickList(List<?> objects) {
|
||||
return null == objects || objects.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取到父级id
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
private static Object getParentId(Object object) {
|
||||
try {
|
||||
return getSourceValue(object, treeConfig.getParentField());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.fateverse.common.core.utils.sql;
|
||||
|
||||
import cn.fateverse.common.core.exception.CustomException;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* sql操作工具类
|
||||
*
|
||||
* @author Clay
|
||||
* @date 2022/10/30
|
||||
*/
|
||||
public class SqlUtil {
|
||||
/**
|
||||
* 定义常用的 sql关键字
|
||||
*/
|
||||
public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
|
||||
|
||||
/**
|
||||
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
||||
*/
|
||||
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
||||
|
||||
/**
|
||||
* 检查字符,防止注入绕过
|
||||
*/
|
||||
public static String escapeOrderBySql(String value) {
|
||||
if (!StrUtil.isEmpty(value) && !isValidOrderBySql(value)) {
|
||||
throw new CustomException("参数不符合规范,不能进行查询");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 order by 语法是否符合规范
|
||||
*/
|
||||
public static boolean isValidOrderBySql(String value) {
|
||||
return value.matches(SQL_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL关键字检查
|
||||
*/
|
||||
public static void filterKeyword(String value) {
|
||||
if (StrUtil.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
||||
for (String sqlKeyword : sqlKeywords) {
|
||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
|
||||
throw new CustomException("参数存在SQL注入风险");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.fateverse.common.core.utils.uuid;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
|
||||
/**
|
||||
* ID生成器工具类
|
||||
*
|
||||
* @author Clay
|
||||
*/
|
||||
public class IdUtils {
|
||||
/**
|
||||
* 获取随机UUID
|
||||
*
|
||||
* @return 随机UUID
|
||||
*/
|
||||
public static String randomUUID() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
*/
|
||||
public static String simpleUUID() {
|
||||
return UUID.randomUUID().toString(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
* @return 随机UUID
|
||||
*/
|
||||
public static String fastUUID() {
|
||||
return UUID.fastUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
*/
|
||||
public static String fastSimpleUUID() {
|
||||
return UUID.fastUUID().toString(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
cn.fateverse.common.core.utils.SpringContextHolder
|
||||
Reference in New Issue
Block a user