add
yj
2024-12-05 a160d838f9c0a79dfc2f18e7cd46bdd4faa59c6d
add
35个文件已添加
1246 ■■■■■ 已修改文件
dobbinfw-core/.gitignore 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/README.md 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/pom.xml 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/Const.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpMethod.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpOpenApi.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpParam.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpParamType.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/RateLimitType.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/ResultType.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/doc/ApiEntity.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/doc/ApiField.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/CustomCheck.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/NotNull.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/Range.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/TextFormat.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/Validator.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/build/AnnotationProcessor.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/SuperDTO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/inter/IdentityOwner.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/inter/PermissionOwner.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/enums/BaseEnums.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/enums/EmptyEnums.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/AdminServiceException.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/AppServiceException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/BizServiceException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/CoreExceptionDefinition.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ServiceException.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ServiceExceptionDefinition.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ThirdPartServiceException.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/model/GatewayResponse.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/GeneratorUtil.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/ISessionUtil.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/ReflectUtil.java 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/SessionUtil.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dobbinfw-core/.gitignore
New file
@@ -0,0 +1,28 @@
# Compiled class file
*.class
/target
/.idea
*.iml
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
dobbinfw-core/README.md
New file
@@ -0,0 +1,40 @@
## Dobbin Framework Logo
#### 一、项目背景
> 为了快速落地项目、快速搭建脚手架,dobbinsoft开发一套基于SpringBoot MyBatis的框架,并手搓了如参数校验、文档生成、限流、鉴权等等常用功能。core包中包括工具类、注解、模型等。
#### 二、快速开始
##### 2.1. 下载代码
您可以在国内开源社区Gitee下载(推荐):https://gitee.com/iotechn/dobbinfw-core
您可以在国际开源社区Github下载:https://github.com/iotechn/dobbinfw-core
##### 2.2. maven引入
请确定您已经将 JAVA_HOME 配置,并将mvn命令配置到PATH中,若出现找不到命令,或找不到JAVA_HOME,[请参考此文档](https://blog.csdn.net/weixin_44548718/article/details/108635409)
在项目根目录,打开命令行。并执行 :
```shell
mvn install -Dmaven.test.skip=true
```
引入maven坐标到工程pom.xml文件中。
```xml
<groupId>com.dobbinsoft</groupId>
<artifactId>fw-core</artifactId>
<version>1.0-SNAPSHOT</version>
```
#### 三、常见问题
##### 3.1. 为何分离core包?
部分项目,需要拆分微服务,这类项目需要将接口暴露给其他微服务系统,通常提供一个api包,api包不需要引入过重依赖,使用此框架则只需要引入core包即可。
#### 四、贡献 & 社区
您可以直接在仓库中发布Pull Request。本项目欢迎所有开发者一起维护,并永久开源。
dobbinfw-core/pom.xml
New file
@@ -0,0 +1,86 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dobbinsoft</groupId>
    <artifactId>fw-core</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <!-- 配置编译时保留参数名 -->
                <configuration>
                    <debuglevel>lines,vars,source</debuglevel>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!-- HuTool 工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.0</version>
        </dependency>
        <!-- 阿里巴巴 json 解析 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
        <!-- 腾讯云短信 -->
        <dependency>
            <groupId>com.github.qcloudsms</groupId>
            <artifactId>qcloudsms</artifactId>
            <version>1.0.5</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <distributionManagement>
        <repository>
            <id>rdc-snapshot</id>
            <name>Aliyun Xiao</name>
            <url>https://packages.aliyun.com/maven/repository/2084582-snapshot-Vrq4iK/</url>
        </repository>
    </distributionManagement>
</project>
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/Const.java
New file
@@ -0,0 +1,49 @@
package com.dobbinsoft.fw.core;
import java.util.*;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-11
 * Time: 下午11:43
 */
public class Const {
    public static final Set<Class> IGNORE_PARAM_LIST = new HashSet<Class>();
    static {
        IGNORE_PARAM_LIST.add(boolean.class);
        IGNORE_PARAM_LIST.add(byte.class);
        IGNORE_PARAM_LIST.add(char.class);
        IGNORE_PARAM_LIST.add(short.class);
        IGNORE_PARAM_LIST.add(int.class);
        IGNORE_PARAM_LIST.add(long.class);
        IGNORE_PARAM_LIST.add(float.class);
        IGNORE_PARAM_LIST.add(double.class);
        IGNORE_PARAM_LIST.add(Byte.class);
        IGNORE_PARAM_LIST.add(Character.class);
        IGNORE_PARAM_LIST.add(Short.class);
        IGNORE_PARAM_LIST.add(Integer.class);
        IGNORE_PARAM_LIST.add(Long.class);
        IGNORE_PARAM_LIST.add(String.class);
        IGNORE_PARAM_LIST.add(Float.class);
        IGNORE_PARAM_LIST.add(Double.class);
        IGNORE_PARAM_LIST.add(Boolean.class);
    }
    public static final int CACHE_ONE_DAY = 60 * 60 * 24;
    public static final int CACHE_ONE_YEAR = 60 * 60 * 24 * 365;
    public static final String USER_ACCESS_TOKEN = "ACCESSTOKEN";
    public static final String USER_REDIS_PREFIX = "USER_SESSION_";
    public static final String ADMIN_ACCESS_TOKEN = "ADMINTOKEN";
    public static final String ADMIN_REDIS_PREFIX = "ADMIN_SESSION_";
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpMethod.java
New file
@@ -0,0 +1,34 @@
package com.dobbinsoft.fw.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-03-25
 * Time: 下午1:12
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpMethod {
    String description();
    ResultType type() default ResultType.COMMONS;
    RateLimitType rateLimit() default RateLimitType.NONE;
    int rateWindow() default 60;
    int rate() default 1;
    String retName() default "";
    int maxAge() default -1;
    String permission() default "";
    String permissionParentName() default "";
    String permissionName() default "";
    boolean openPlatform() default false;
    /**
     * 从网关上构建一个实例
     * @return
     */
    Class loadBean() default void.class;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpOpenApi.java
New file
@@ -0,0 +1,20 @@
package com.dobbinsoft.fw.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-03-25
 * Time: 下午1:12
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpOpenApi {
    String group();
    String description();
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpParam.java
New file
@@ -0,0 +1,35 @@
package com.dobbinsoft.fw.core.annotation;
import com.dobbinsoft.fw.core.enums.BaseEnums;
import com.dobbinsoft.fw.core.enums.EmptyEnums;
import java.lang.annotation.*;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-03-25
 * Time: 下午1:12
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpParam {
    String name();
    HttpParamType type() default HttpParamType.COMMON;
    String description() default "";
    String valueDef() default "";
    Class arrayClass() default Object.class;
    /**
     * 绑定枚举
     * @return
     */
    Class<? extends BaseEnums> enums() default EmptyEnums.class;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/HttpParamType.java
New file
@@ -0,0 +1,20 @@
package com.dobbinsoft.fw.core.annotation;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-03-25
 * Time: 下午1:12
 */
public enum HttpParamType {
    HEADER,
    COMMON,
    USER_ID,
    ADMIN_ID,
    IP,
    FILE
    ;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/RateLimitType.java
New file
@@ -0,0 +1,17 @@
package com.dobbinsoft.fw.core.annotation;
/**
 * ClassName: RateLimitType
 * Description: TODO
 *
 * @author: e-weichaozheng
 * @date: 2021-04-12
 */
public enum  RateLimitType {
    USER_ID,
    IP,
    ALL,
    NONE
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/ResultType.java
New file
@@ -0,0 +1,13 @@
package com.dobbinsoft.fw.core.annotation;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-24
 * Time: 下午5:03
 */
public enum ResultType {
    COMMONS,
    COOKIE;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/doc/ApiEntity.java
New file
@@ -0,0 +1,21 @@
package com.dobbinsoft.fw.core.annotation.doc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Created with IntelliJ IDEA.
 * Description: 描述实体
 * User: rize
 * Date: 2021-03-17
 * Time: 上午9:15
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiEntity {
    String description();
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/doc/ApiField.java
New file
@@ -0,0 +1,26 @@
package com.dobbinsoft.fw.core.annotation.doc;
import com.dobbinsoft.fw.core.enums.BaseEnums;
import com.dobbinsoft.fw.core.enums.EmptyEnums;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Created with IntelliJ IDEA.
 * Description: 描述实体属性
 * User: rize
 * Date: 2021-03-17
 * Time: 上午9:15
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiField {
    String description();
    Class<? extends BaseEnums> enums() default EmptyEnums.class;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/CustomCheck.java
New file
@@ -0,0 +1,27 @@
package com.dobbinsoft.fw.core.annotation.param;
import java.lang.annotation.*;
/**
 * Created with IntelliJ IDEA.
 * Description: 自定义参数校验
 * User: rize
 * Date: 2021-03-17
 * Time: 上午9:15
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Documented
public @interface CustomCheck {
    /**
     * 校验器Class对象,会从IoC中拿取
     * @return
     */
    Class beanClass();
    boolean reqScope() default true;
    boolean respScope() default false;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/NotNull.java
New file
@@ -0,0 +1,23 @@
package com.dobbinsoft.fw.core.annotation.param;
import java.lang.annotation.*;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-20
 * Time: 上午10:51
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Documented
public @interface NotNull {
    String message() default "";
    boolean reqScope() default true;
    boolean respScope() default false;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/Range.java
New file
@@ -0,0 +1,27 @@
package com.dobbinsoft.fw.core.annotation.param;
import java.lang.annotation.*;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-20
 * Time: 上午11:11
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Documented
public @interface Range {
    long min() default Long.MIN_VALUE;
    long max() default Long.MAX_VALUE;
    String message() default "";
    boolean reqScope() default true;
    boolean respScope() default false;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/TextFormat.java
New file
@@ -0,0 +1,41 @@
package com.dobbinsoft.fw.core.annotation.param;
import java.lang.annotation.*;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-20
 * Time: 上午10:51
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Documented
public @interface TextFormat {
    String regex() default "";
    String[] contains() default {};
    String[] notContains() default {};
    String startWith() default "";
    String endsWith() default "";
    int lengthMax() default Integer.MAX_VALUE;
    int lengthMin() default 0;
    int length() default -1;
    boolean notChinese() default false;
    String message() default "";
    boolean reqScope() default true;
    boolean respScope() default false;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/annotation/param/Validator.java
New file
@@ -0,0 +1,16 @@
package com.dobbinsoft.fw.core.annotation.param;
import com.dobbinsoft.fw.core.exception.ServiceException;
/**
 * ClassName: Validator
 * Description: 校验器
 *
 * @author: e-weichaozheng
 * @date: 2021-03-17
 */
public interface Validator<T> {
    public boolean check(T param) throws ServiceException;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/build/AnnotationProcessor.java
New file
@@ -0,0 +1,26 @@
package com.dobbinsoft.fw.core.build;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import java.util.Set;
/**
 * Description:
 * User: rize
 * Date: 2021/4/4
 * Time: 13:57
 */
@SupportedAnnotationTypes(value = {"com.dobbinsoft.fw.support.annotation.Table"})
@SupportedSourceVersion(value = SourceVersion.RELEASE_8)
public class AnnotationProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return true;
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/SuperDTO.java
New file
@@ -0,0 +1,19 @@
package com.dobbinsoft.fw.core.entiy;
import lombok.Data;
import java.util.Date;
/**
 * Created by rize on 2019/7/1.
 */
@Data
public class SuperDTO {
    private Long id;
    private Date gmtUpdate;
    private Date gmtCreate;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/inter/IdentityOwner.java
New file
@@ -0,0 +1,14 @@
package com.dobbinsoft.fw.core.entiy.inter;
/**
 * ClassName: IdentityOwner
 * Description: 有身份的
 *
 * @author: e-weichaozheng
 * @date: 2021-03-17
 */
public interface IdentityOwner {
    public Long getId();
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/entiy/inter/PermissionOwner.java
New file
@@ -0,0 +1,16 @@
package com.dobbinsoft.fw.core.entiy.inter;
import java.util.List;
/**
 * ClassName: PermissionOwner
 * Description: 表示一个有权限的身份
 *
 * @author: e-weichaozheng
 * @date: 2021-03-16
 */
public interface PermissionOwner extends IdentityOwner {
    public List<String> getPerms();
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/enums/BaseEnums.java
New file
@@ -0,0 +1,76 @@
package com.dobbinsoft.fw.core.enums;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
/**
 * ClassName: BaseEnums
 * Description: TODO
 *
 * @author: e-weichaozheng
 * @date: 2021-03-19
 */
public interface BaseEnums<T extends Serializable> {
    public Serializable getCode();
    public String getMsg();
    public static <T extends Serializable> BaseEnums getByCode(T t, Class<? extends BaseEnums<T>> clazz) {
        BaseEnums<T>[] enumConstants = clazz.getEnumConstants();
        for (BaseEnums baseEnums : enumConstants) {
            if (baseEnums.getCode().equals(t)) {
                return baseEnums;
            }
        }
        return null;
    }
    public static <T extends Serializable> String getMsgByCode(T t, Class<? extends BaseEnums<T>> clazz) {
        BaseEnums baseEnums = getByCode(t, clazz);
        if (baseEnums == null) {
            return null;
        }
        return baseEnums.getMsg();
    }
    /**
     * 获取前端格式化需要的MAP
     * @return
     */
    public default String getMap() {
        Class<? extends BaseEnums> clazz = this.getClass();
        BaseEnums[] enumConstants = clazz.getEnumConstants();
        StringBuilder sb = new StringBuilder();
        sb.append("const ");
        sb.append(StrUtil.lowerFirst(clazz.getSimpleName()));
        sb.append("Map = {\n");
        for (int i = 0; i < enumConstants.length; i++) {
            sb.append("  ");
            sb.append(enumConstants[i].getCode());
            sb.append(": '");
            sb.append(enumConstants[i].getMsg());
            if (i == enumConstants.length -1) {
                sb.append("'\n}");
            } else {
                sb.append("',\n");
            }
        }
        return sb.toString();
    }
    /**
     * 获取前端格式化需要的过滤器
     * @return
     */
    public default String getFilter() {
        Class<? extends BaseEnums> clazz = this.getClass();
        return
                "    " + StrUtil.lowerFirst(clazz.getSimpleName()) + "Filter(status) {\n" +
                "      return " + StrUtil.lowerFirst(clazz.getSimpleName()) + "Map[status]\n" +
                "    }";
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/enums/EmptyEnums.java
New file
@@ -0,0 +1,22 @@
package com.dobbinsoft.fw.core.enums;
import java.io.Serializable;
/**
 * ClassName: EmptyEnums
 * Description: TODO
 *
 * @author: e-weichaozheng
 * @date: 2021-03-19
 */
public enum EmptyEnums implements BaseEnums<Integer> {
    ;
    public Integer getCode() {
        return 0;
    }
    public String getMsg() {
        return null;
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/AdminServiceException.java
New file
@@ -0,0 +1,20 @@
package com.dobbinsoft.fw.core.exception;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: kbq
 * Date: 2019-07-07
 * Time: 下午4:21
 */
public class AdminServiceException extends ServiceException {
    public AdminServiceException(ServiceExceptionDefinition definition) {
        super(definition);
    }
    public AdminServiceException(String message, int code) {
        super(message,code);
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/AppServiceException.java
New file
@@ -0,0 +1,15 @@
package com.dobbinsoft.fw.core.exception;
/**
 * Created by rize on 2019/7/1.
 */
public class AppServiceException extends ServiceException {
    public AppServiceException(ServiceExceptionDefinition definition) {
        super(definition);
    }
    public AppServiceException(String message, int code) {
        super(message,code);
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/BizServiceException.java
New file
@@ -0,0 +1,15 @@
package com.dobbinsoft.fw.core.exception;
/**
 * Created by rize on 2019/7/1.
 */
public class BizServiceException extends ServiceException {
    public BizServiceException(ServiceExceptionDefinition definition) {
        super(definition);
    }
    public BizServiceException(String message, int code) {
        super(message,code);
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/CoreExceptionDefinition.java
New file
@@ -0,0 +1,25 @@
package com.dobbinsoft.fw.core.exception;
/**
 * Created by rize on 2019/7/1.
 */
public class CoreExceptionDefinition {
    public static final ServiceExceptionDefinition THIRD_PART_SERVICE_EXCEPTION =
            new ServiceExceptionDefinition(0, "第三方服务异常");
    public static final ServiceExceptionDefinition THIRD_PART_IO_EXCEPTION =
            new ServiceExceptionDefinition(0, "第三方服务网络异常");
    public static ServiceExceptionDefinition buildVariableException(ServiceExceptionDefinition definition, String ...args) {
        String msg = definition.getMsg();
        for (int i = 0; i < args.length; i++) {
            msg = msg.replace("${" + i + "}", args[i]);
        }
        return new ServiceExceptionDefinition(definition.getCode(), msg);
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ServiceException.java
New file
@@ -0,0 +1,47 @@
package com.dobbinsoft.fw.core.exception;
import java.io.Serializable;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2019-01-31
 * Time: 下午8:07
 */
public abstract class ServiceException extends Exception implements Serializable {
    private int code;
    private Object attach;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public Object getAttach() {
        return attach;
    }
    public ServiceException() {
    }
    public ServiceException(String message, int code) {
        super(message);
        this.code = code;
    }
    public ServiceException(ServiceExceptionDefinition definition) {
        super(definition.getMsg());
        this.code = definition.getCode();
    }
    public ServiceException attach(Object attach) {
        this.attach = attach;
        return this;
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ServiceExceptionDefinition.java
New file
@@ -0,0 +1,13 @@
package com.dobbinsoft.fw.core.exception;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ServiceExceptionDefinition {
    private int code;
    private String msg;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/exception/ThirdPartServiceException.java
New file
@@ -0,0 +1,17 @@
package com.dobbinsoft.fw.core.exception;
/**
 * 第三方接口服务异常
 * Created by rize on 2019/7/3.
 */
public class ThirdPartServiceException extends ServiceException {
    public ThirdPartServiceException(ServiceExceptionDefinition definition) {
        super(definition);
    }
    public ThirdPartServiceException(String message, int code) {
        super(message, code);
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/model/GatewayResponse.java
New file
@@ -0,0 +1,19 @@
package com.dobbinsoft.fw.core.model;
import lombok.Data;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2018-08-12
 * Time: 上午10:35
 */
@Data
public class GatewayResponse<T> {
    private int errno;
    private String errmsg;
    private T data;
    private long timestamp;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/GeneratorUtil.java
New file
@@ -0,0 +1,45 @@
package com.dobbinsoft.fw.core.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * Created by rize on 2019/7/1.
 */
public class GeneratorUtil {
    private static AtomicInteger orderIdCount = new AtomicInteger();
    private static final SimpleDateFormat ORDER_ID_FORMAT = new SimpleDateFormat("yyyyMMHHmmss");
    public static final String genSalt() {
        return genUUId().substring(0, 7);
    }
    public static String genSixVerifyCode() {
        String time = System.nanoTime() + "";
        return time.substring(time.length() - 6);
    }
    public static String genSessionId() {
        return UUID.randomUUID().toString().replace("-","").toUpperCase();
    }
    public static String genOrderId(String machineNo, String env) {
        int i = orderIdCount.incrementAndGet() % 1000;
        if (i < 1000)
            i += 1000;
        return env + machineNo + ORDER_ID_FORMAT.format(new Date()) + i;
    }
    public static String genFileName(){
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
    public static String genUUId() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/ISessionUtil.java
New file
@@ -0,0 +1,28 @@
package com.dobbinsoft.fw.core.util;
import com.dobbinsoft.fw.core.entiy.inter.IdentityOwner;
import com.dobbinsoft.fw.core.entiy.inter.PermissionOwner;
import com.dobbinsoft.fw.core.exception.ServiceException;
import java.util.List;
/**
 * Session 相关抽取接口
 */
public interface ISessionUtil<U extends IdentityOwner, A extends PermissionOwner> {
    public void setUser(U userDTO);
    public U getUser();
    public void setAdmin(A adminDTO);
    public A getAdmin();
    public Class<U> getUserClass();
    public Class<A> getAdminClass();
    public boolean hasPerm(String permission) throws ServiceException;
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/ReflectUtil.java
New file
@@ -0,0 +1,223 @@
package com.dobbinsoft.fw.core.util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
 * Description:
 * User: rize
 * Date: 2020/8/15
 * Time: 11:01
 */
public class ReflectUtil {
    /**
     * 通过Getter方法名称获取属性
     * @param getterName
     * @return
     */
    public static String getField(String getterName) {
        char[] dst = new char[getterName.length() - 3];
        getterName.getChars(3, getterName.length(), dst, 0);
        if ('A' <= dst[0] && 'Z' >= dst[0]) {
            dst[0] = (char) (dst[0] + 32);
        }
        return new String(dst);
    }
    /**
     * 通过属性名获取 Getter 或 Setter
     * @param fieldName
     * @param prefix "get" | "set"
     * @return
     */
    public static String getMethodName(String fieldName, String prefix) {
        char[] dst = new char[fieldName.length() + 3];
        // 1. 将prefix搞进去
        prefix.getChars(0, 3, dst, 0);
        // 2. 跟随考进去
        fieldName.getChars(0, fieldName.length(), dst, 3);
        if ('a' <= dst[3] && 'z' >= dst[3]) {
            dst[3] = (char) (dst[3] - 32);
        }
        return new String(dst);
    }
    /**
     * 加载包字节码
     * @return
     */
    public static Map<String, byte[]> loadPackageBytes(String basePackage, boolean subPackage, boolean isInterface) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String fsBasePackage = basePackage.replace(".","/");
        Map<String, byte[]> map = new HashMap<>();
        try {
            Enumeration<URL> resources = classLoader.getResources(fsBasePackage);
            while(resources.hasMoreElements()) {
                //先获得本类的所在位置
                URL url = resources.nextElement();
                //url.getProtocol()是获取URL的HTTP协议。
                if(url.getProtocol().equals("jar")) {
                    //判断是不是jar包
                    JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
                    JarFile jarfile = urlConnection.getJarFile();
                    Enumeration<JarEntry> jarEntries = jarfile.entries();
                    while(jarEntries.hasMoreElements()) {
                        JarEntry jarEntry = jarEntries.nextElement();
                        String jarName = jarEntry.getName();
                        if(!jarName.endsWith(".class")) {
                            continue;
                        }
                        String className = jarName.replace(".class", "").replaceAll("/", ".");
                        if (!className.startsWith(basePackage)) {
                            continue;
                        }
                        if (!subPackage) {
                            if (!className.substring(0, className.lastIndexOf(".")).equals(basePackage)) {
                                continue;
                            }
                        }
                        if (checkClassType(isInterface, className)) {
                            continue;
                        }
                        InputStream inputStream = null;
                        try {
                            String newUrl = url.toString().substring(0, url.toString().lastIndexOf("!") + 2) + jarName;
                            URL classUrl = new URL(newUrl);
                            URLConnection classUrlConnection = classUrl.openConnection();
                            inputStream = classUrlConnection.getInputStream();
                            byte[] bytes = IoUtil.readBytes(inputStream);
                            map.put(className, bytes);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            if (inputStream != null) {
                                inputStream.close();
                            }
                        }
                    }
                } else if (url.getProtocol().equals("file")) {
                    // 文件系统,这是在开发的时候会用到
                    // file:/D:/develop/workspace/ideawork/unierp/unierp-data/target/classes/com/dobbinsoft/unierp/data/dto
                    Map<String, File> classNameFileMap = getClassNameFileMap(new HashMap<>(), new File(url.getFile()), basePackage, subPackage);
                    for (String className : classNameFileMap.keySet()) {
                        if (checkClassType(isInterface, className)) {
                            continue;
                        }
                        InputStream inputStream = null;
                        try {
                            File file = classNameFileMap.get(className);
                            inputStream = new FileInputStream(file);
                            byte[] bytes = IoUtil.readBytes(inputStream);
                            map.put(className, bytes);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            if (inputStream != null) {
                                inputStream.close();
                            }
                        }
                    }
                } else {
                    throw new RuntimeException("不支持本包对象,请不要将接口和实体放入启动器中");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }
    private static boolean checkClassType(boolean isInterface, String className) {
        try {
            Class<?> klass = Class.forName(className);
            if (klass.isAnnotation()
                    || klass.isEnum()
                    || klass.isPrimitive()) {
                return true;
            }
            if (isInterface && !klass.isInterface()) {
                return true;
            } else if (!isInterface && klass.isInterface()) {
                return true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("未找到类:" + className);
        }
        return false;
    }
    /**
     * 递归获取baseDir下的类与文件映射
     * @param map
     * @param baseDir
     * @return
     */
    private static Map<String, File> getClassNameFileMap(Map<String, File> map, File baseDir, String basePackage, boolean subPackage) {
        if (baseDir == null || !baseDir.isDirectory()) {
            return map;
        }
        File[] files = baseDir.listFiles();
        for (File file : files) {
            if (file.isDirectory() && subPackage) {
                // 不这么写 true idea 报黄,看着胀眼睛
                getClassNameFileMap(map, file, basePackage, true);
            } else if (file.getName().endsWith("class")) {
                // 兼容 Windows
                String rawPackage = baseDir.toString().replace("\\", ".").replace("/", ".");
                String className = rawPackage.substring(rawPackage.indexOf(basePackage)) + "." + file.getName().replace(".class", "");
                map.put(className, file);
            }
        }
        return map;
    }
    /**
     * 清理掉对象的空串属性
     * @param object
     */
    public static void clearEmptyString(Object object) {
        try {
            Class<?> clazz = object.getClass();
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                String getter = getMethodName(field.getName(), "get");
                Method getterMethod = clazz.getMethod(getter);
                if (getterMethod != null) {
                    Object res = getterMethod.invoke(object);
                    if (res != null && res instanceof String) {
                        // 若是返回String
                        if (!"".equals(res)) {
                            //设置为空
                            String setter = getMethodName(field.getName(), "set");
                            Method setterMethod = clazz.getMethod(setter);
                            if (setterMethod != null) {
                                setterMethod.invoke(object, null);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
dobbinfw-core/src/main/java/com/dobbinsoft/fw/core/util/SessionUtil.java
New file
@@ -0,0 +1,83 @@
package com.dobbinsoft.fw.core.util;
import com.dobbinsoft.fw.core.entiy.inter.IdentityOwner;
import com.dobbinsoft.fw.core.entiy.inter.PermissionOwner;
import com.dobbinsoft.fw.core.exception.ServiceException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
/**
 * Created by rize on 2019/2/27.
 * Edit by rize on 2021/3/16.
 */
public class SessionUtil<U extends IdentityOwner, A extends PermissionOwner> implements ISessionUtil<U, A> {
    private ThreadLocal<U> userLocal = new ThreadLocal<U>();
    private ThreadLocal<A> adminLocal = new ThreadLocal<A>();
    private Class<U> userClass;
    private Class<A> adminClass;
    public SessionUtil(Class<U> userClass, Class<A> adminClass) {
        this.userClass = userClass;
        this.adminClass = adminClass;
    }
    public void setUser(U userDTO) {
        userLocal.set(userDTO);
    }
    public U getUser() {
        return userLocal.get();
    }
    public void setAdmin(A adminDTO) {
        adminLocal.set(adminDTO);
    }
    public A getAdmin() {
        return adminLocal.get();
    }
    public Class<U> getUserClass() {
        return this.userClass;
    }
    public Class<A> getAdminClass() {
        return this.adminClass;
    }
    public boolean hasPerm(String permission) throws ServiceException {
        //拥有的权限
        List<String> perms = getAdmin().getPerms();
        boolean hasPerm = false;
        //目标匹配权限
        String[] permissions = permission.split(":");
        outer : for(String item : perms) {
            //拥有的权限点
            String[] hasPer = item.split(":");
            inner : for (int i = 0; i < permissions.length; i++) {
                if ("*".equals(hasPer[i])) {
                    hasPerm = true;
                    break outer;
                } else if (hasPer[i].equals(permissions[i])){
                    //此层合格
                    if (i == permissions.length - 1) {
                        //若是目标层的最后一层。则表示所有层校验通过
                        hasPerm = true;
                    }
                } else {
                    break inner;
                }
            }
        }
        return hasPerm;
    }
}