调解系统初始化版本
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
<?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>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
|
||||
|
||||
<description>
|
||||
common通用工具
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--docx文件下载问题-->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>4.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- POI依赖,读取.doc型文档-->
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-local</artifactId>
|
||||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-spring-boot-starter</artifactId>
|
||||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.artofsolving</groupId>
|
||||
<artifactId>jodconverter</artifactId>
|
||||
<version>2.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>jurt</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>ridl</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>juh</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>unoil</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringWeb模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring security 安全认证 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- pagehelper 分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 动态数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里JSON解析器 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- yml解析器 -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Token生成与解析-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jaxb -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- redis 缓存操作 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- pool 对象池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 解析客户端操作系统、浏览器等 -->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- servlet包 -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.22</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 腾讯短信sdk -->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.876</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-faceid</artifactId>
|
||||
<version>3.1.875</version>
|
||||
</dependency>
|
||||
<!--用户信息解密-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.7.15</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15to18</artifactId>
|
||||
<version>1.69</version>
|
||||
</dependency>
|
||||
|
||||
<!-- poi-tl-->
|
||||
<dependency>
|
||||
<groupId>com.deepoove</groupId>
|
||||
<artifactId>poi-tl</artifactId>
|
||||
<version>1.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.documents4j</groupId>
|
||||
<artifactId>documents4j-local</artifactId>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.documents4j</groupId>
|
||||
<artifactId>documents4j-transformer-msoffice-word</artifactId>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.27</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itextpdf</artifactId>
|
||||
<version>5.5.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf.tool</groupId>
|
||||
<artifactId>xmlworker</artifactId>
|
||||
<version>5.5.13</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 发送邮件-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
<version>3.1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 匿名访问不鉴权注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Anonymous
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 数据权限过滤注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DataScope
|
||||
{
|
||||
/**
|
||||
* 部门表的别名
|
||||
*/
|
||||
public String deptAlias() default "";
|
||||
|
||||
/**
|
||||
* 用户表的别名
|
||||
*/
|
||||
public String userAlias() default "";
|
||||
|
||||
/**
|
||||
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
|
||||
*/
|
||||
public String permission() default "";
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import com.ruoyi.common.enums.DataSourceType;
|
||||
|
||||
/**
|
||||
* 自定义多数据源切换注解
|
||||
*
|
||||
* 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface DataSource
|
||||
{
|
||||
/**
|
||||
* 切换数据源名称
|
||||
*/
|
||||
public DataSourceType value() default DataSourceType.MASTER;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||
import com.ruoyi.common.utils.poi.ExcelHandlerAdapter;
|
||||
|
||||
/**
|
||||
* 自定义导出Excel数据注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Excel
|
||||
{
|
||||
/**
|
||||
* 导出时在excel中排序
|
||||
*/
|
||||
public int sort() default Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* 导出到Excel中的名字.
|
||||
*/
|
||||
public String name() default "";
|
||||
|
||||
/**
|
||||
* 日期格式, 如: yyyy-MM-dd
|
||||
*/
|
||||
public String dateFormat() default "";
|
||||
|
||||
/**
|
||||
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
|
||||
*/
|
||||
public String dictType() default "";
|
||||
|
||||
/**
|
||||
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
|
||||
*/
|
||||
public String readConverterExp() default "";
|
||||
|
||||
/**
|
||||
* 分隔符,读取字符串组内容
|
||||
*/
|
||||
public String separator() default ",";
|
||||
|
||||
/**
|
||||
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
|
||||
*/
|
||||
public int scale() default -1;
|
||||
|
||||
/**
|
||||
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
|
||||
*/
|
||||
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的高度
|
||||
*/
|
||||
public double height() default 14;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的宽度
|
||||
*/
|
||||
public double width() default 16;
|
||||
|
||||
/**
|
||||
* 文字后缀,如% 90 变成90%
|
||||
*/
|
||||
public String suffix() default "";
|
||||
|
||||
/**
|
||||
* 当值为空时,字段的默认值
|
||||
*/
|
||||
public String defaultValue() default "";
|
||||
|
||||
/**
|
||||
* 提示信息
|
||||
*/
|
||||
public String prompt() default "";
|
||||
|
||||
/**
|
||||
* 设置只能选择不能输入的列内容.
|
||||
*/
|
||||
public String[] combo() default {};
|
||||
|
||||
/**
|
||||
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
|
||||
*/
|
||||
public boolean needMerge() default false;
|
||||
|
||||
/**
|
||||
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
|
||||
*/
|
||||
public boolean isExport() default true;
|
||||
|
||||
/**
|
||||
* 另一个类中的属性名称,支持多级获取,以小数点隔开
|
||||
*/
|
||||
public String targetAttr() default "";
|
||||
|
||||
/**
|
||||
* 是否自动统计数据,在最后追加一行统计数据总和
|
||||
*/
|
||||
public boolean isStatistics() default false;
|
||||
|
||||
/**
|
||||
* 导出类型(0数字 1字符串 2图片)
|
||||
*/
|
||||
public ColumnType cellType() default ColumnType.STRING;
|
||||
|
||||
/**
|
||||
* 导出列头背景颜色
|
||||
*/
|
||||
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
|
||||
|
||||
/**
|
||||
* 导出列头字体颜色
|
||||
*/
|
||||
public IndexedColors headerColor() default IndexedColors.WHITE;
|
||||
|
||||
/**
|
||||
* 导出单元格背景颜色
|
||||
*/
|
||||
public IndexedColors backgroundColor() default IndexedColors.WHITE;
|
||||
|
||||
/**
|
||||
* 导出单元格字体颜色
|
||||
*/
|
||||
public IndexedColors color() default IndexedColors.BLACK;
|
||||
|
||||
/**
|
||||
* 导出字段对齐方式
|
||||
*/
|
||||
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
|
||||
|
||||
/**
|
||||
* 自定义数据处理器
|
||||
*/
|
||||
public Class<?> handler() default ExcelHandlerAdapter.class;
|
||||
|
||||
/**
|
||||
* 自定义数据处理器参数
|
||||
*/
|
||||
public String[] args() default {};
|
||||
|
||||
/**
|
||||
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
|
||||
*/
|
||||
Type type() default Type.ALL;
|
||||
|
||||
public enum Type
|
||||
{
|
||||
ALL(0), EXPORT(1), IMPORT(2);
|
||||
private final int value;
|
||||
|
||||
Type(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ColumnType
|
||||
{
|
||||
NUMERIC(0), STRING(1), IMAGE(2);
|
||||
private final int value;
|
||||
|
||||
ColumnType(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Excel注解集
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Excels
|
||||
{
|
||||
public Excel[] value();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.enums.OperatorType;
|
||||
|
||||
/**
|
||||
* 自定义操作日志记录注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Log
|
||||
{
|
||||
/**
|
||||
* 模块
|
||||
*/
|
||||
public String title() default "";
|
||||
|
||||
/**
|
||||
* 功能
|
||||
*/
|
||||
public BusinessType businessType() default BusinessType.OTHER;
|
||||
|
||||
/**
|
||||
* 操作人类别
|
||||
*/
|
||||
public OperatorType operatorType() default OperatorType.MANAGE;
|
||||
|
||||
/**
|
||||
* 是否保存请求的参数
|
||||
*/
|
||||
public boolean isSaveRequestData() default true;
|
||||
|
||||
/**
|
||||
* 是否保存响应的参数
|
||||
*/
|
||||
public boolean isSaveResponseData() default true;
|
||||
|
||||
/**
|
||||
* 排除指定的请求参数
|
||||
*/
|
||||
public String[] excludeParamNames() default {};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.enums.LimitType;
|
||||
|
||||
/**
|
||||
* 限流注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RateLimiter
|
||||
{
|
||||
/**
|
||||
* 限流key
|
||||
*/
|
||||
public String key() default CacheConstants.RATE_LIMIT_KEY;
|
||||
|
||||
/**
|
||||
* 限流时间,单位秒
|
||||
*/
|
||||
public int time() default 60;
|
||||
|
||||
/**
|
||||
* 限流次数
|
||||
*/
|
||||
public int count() default 100;
|
||||
|
||||
/**
|
||||
* 限流类型
|
||||
*/
|
||||
public LimitType limitType() default LimitType.DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自定义注解防止表单重复提交
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
@Inherited
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RepeatSubmit
|
||||
{
|
||||
/**
|
||||
* 间隔时间(ms),小于此时间视为重复提交
|
||||
*/
|
||||
public int interval() default 5000;
|
||||
|
||||
/**
|
||||
* 提示消息
|
||||
*/
|
||||
public String message() default "不允许重复提交,请稍候再试";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
/**
|
||||
* 一个参数、没有返回
|
||||
* @author wangqiong
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface VoidFunction<T> {
|
||||
/**
|
||||
* 有一个参数
|
||||
* @param param
|
||||
*/
|
||||
void apply(T param);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
public class EsignDemoConfig {
|
||||
|
||||
// 应用ID
|
||||
public static final String EsignAppId = "7438987614";
|
||||
// 应用密钥
|
||||
public static final String EsignAppSecret = "9d7844f13830931037772b9d20cf1529";
|
||||
// e签宝接口调用域名(模拟环境)
|
||||
public static final String EsignHost = "https://smlopenapi.esign.cn";
|
||||
// e签宝接口调用域名(正式环境)
|
||||
// public static final String EsignHost = "https://openapi.esign.cn";
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 读取项目相关配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "ruoyi")
|
||||
public class RuoYiConfig
|
||||
{
|
||||
/** 项目名称 */
|
||||
private String name;
|
||||
|
||||
/** 版本 */
|
||||
private String version;
|
||||
|
||||
/** 版权年份 */
|
||||
private String copyrightYear;
|
||||
|
||||
/** 实例演示开关 */
|
||||
private boolean demoEnabled;
|
||||
|
||||
/** 上传路径 */
|
||||
private static String profile;
|
||||
|
||||
/** 获取地址开关 */
|
||||
private static boolean addressEnabled;
|
||||
|
||||
/** 验证码类型 */
|
||||
private static String captchaType;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getCopyrightYear()
|
||||
{
|
||||
return copyrightYear;
|
||||
}
|
||||
|
||||
public void setCopyrightYear(String copyrightYear)
|
||||
{
|
||||
this.copyrightYear = copyrightYear;
|
||||
}
|
||||
|
||||
public boolean isDemoEnabled()
|
||||
{
|
||||
return demoEnabled;
|
||||
}
|
||||
|
||||
public void setDemoEnabled(boolean demoEnabled)
|
||||
{
|
||||
this.demoEnabled = demoEnabled;
|
||||
}
|
||||
|
||||
public static String getProfile()
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setProfile(String profile)
|
||||
{
|
||||
RuoYiConfig.profile = profile;
|
||||
}
|
||||
|
||||
public static boolean isAddressEnabled()
|
||||
{
|
||||
return addressEnabled;
|
||||
}
|
||||
|
||||
public void setAddressEnabled(boolean addressEnabled)
|
||||
{
|
||||
RuoYiConfig.addressEnabled = addressEnabled;
|
||||
}
|
||||
|
||||
public static String getCaptchaType() {
|
||||
return captchaType;
|
||||
}
|
||||
|
||||
public void setCaptchaType(String captchaType) {
|
||||
RuoYiConfig.captchaType = captchaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导入上传路径
|
||||
*/
|
||||
public static String getImportPath()
|
||||
{
|
||||
return getProfile() + "/import";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取头像上传路径
|
||||
*/
|
||||
public static String getAvatarPath()
|
||||
{
|
||||
return getProfile() + "/avatar";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载路径
|
||||
*/
|
||||
public static String getDownloadPath()
|
||||
{
|
||||
return getProfile() + "/download/";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传路径
|
||||
*/
|
||||
public static String getUploadPath()
|
||||
{
|
||||
return getProfile() + "/upload";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传路径
|
||||
*/
|
||||
public static String getVideoUploadPath()
|
||||
{
|
||||
return getProfile() + "/video";
|
||||
}
|
||||
public static String getHtml2PDFPath()
|
||||
{
|
||||
return getProfile() + "/upload/html2PDF";
|
||||
}
|
||||
// https://1304001529.vod-qcloud.com/b78823bbvodcq1304001529/3ce565bf3270835011486046286/f0.mp4
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 缓存的key 常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CacheConstants
|
||||
{
|
||||
/**
|
||||
* 登录用户 redis key
|
||||
*/
|
||||
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||
|
||||
/**
|
||||
* 验证码 redis key
|
||||
*/
|
||||
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||
|
||||
/**
|
||||
* 参数管理 cache key
|
||||
*/
|
||||
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||
|
||||
/**
|
||||
* 字典管理 cache key
|
||||
*/
|
||||
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||
|
||||
/**
|
||||
* 防重提交 redis key
|
||||
*/
|
||||
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
||||
|
||||
/**
|
||||
* 限流 redis key
|
||||
*/
|
||||
public static final String RATE_LIMIT_KEY = "rate_limit:";
|
||||
|
||||
/**
|
||||
* 登录账户密码错误次数 redis key
|
||||
*/
|
||||
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
|
||||
public static final String WE_CHAT_SMS_VERIFY_CODE_KEY="we_chat_sms_verify_code:";
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.ruoyi.common.constant;
|
||||
/**
|
||||
* 立案申请案件状态
|
||||
*
|
||||
*/
|
||||
public class CaseApplicationConstants {
|
||||
/** 立案申请 */
|
||||
public static final int CASE_APPLICATION = 0;
|
||||
/** 待立案审查 */
|
||||
public static final int CASE_CHECK = 1;
|
||||
/** 待缴费 */
|
||||
public static final int PENDING_PAYMENT = 2;
|
||||
/** 待缴费确认 */
|
||||
public static final int PENDING_PAYMENT_CONFIRM = 3;
|
||||
/** 待案件质证 */
|
||||
public static final int CASE_CROSSEXAMI = 4;
|
||||
|
||||
/** 待组庭 */
|
||||
public static final int PENDING_TRIAL = 26;
|
||||
/** 待组庭审核 */
|
||||
public static final int CONFIRMDED_PENDING_TRIAL_SUBMMIT = 5;
|
||||
/** 待组庭确定 */
|
||||
public static final int CONFIRMDED_PENDING_TRIAL = 6;
|
||||
|
||||
/** 待审核仲裁方式 */
|
||||
public static final int CHECK_ARBITRATION_METHOD = 7;
|
||||
/** 待开庭审理 */
|
||||
public static final int PENDING_OPENCOURT_HEAR = 8;
|
||||
/** 待书面审理 */
|
||||
public static final int PENDING_WRIITEN_HEAR = 9;
|
||||
/** 待生成仲裁文书 */
|
||||
public static final int GENERATED_ARBITRATION = 10;
|
||||
/**待秘书核验仲裁文书*/
|
||||
public static final int VERPRIF_ARBITRATION = 11;
|
||||
/**待部门长审核仲裁文书*/
|
||||
public static final int CHECK_ARBITRATION = 12;
|
||||
/**待仲裁文书签名*/
|
||||
public static final int SIGN_ARBITRATION = 13;
|
||||
/** 待仲裁文书用印 */
|
||||
public static final int ARBITRATED_SEAL = 14;
|
||||
/** 待仲裁文书送达 */
|
||||
public static final int ARBITRATION_DELIVERY = 15;
|
||||
/** 待案件归档*/
|
||||
public static final int CASE_FILING = 16;
|
||||
/** 已归档*/
|
||||
public static final int CASE_ARCHIVED = 17;
|
||||
|
||||
/** 待修改开庭时间*/
|
||||
public static final int MODIFY_HEARDATE = 31;
|
||||
/**待仲裁员审核仲裁文书*/
|
||||
public static final int HEAD_CHECK_ARBITRATION = 18;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Constants
|
||||
{
|
||||
/**
|
||||
* UTF-8 字符集
|
||||
*/
|
||||
public static final String UTF8 = "UTF-8";
|
||||
|
||||
/**
|
||||
* GBK 字符集
|
||||
*/
|
||||
public static final String GBK = "GBK";
|
||||
|
||||
/**
|
||||
* www主域
|
||||
*/
|
||||
public static final String WWW = "www.";
|
||||
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
public static final String HTTP = "http://";
|
||||
/**
|
||||
* br标签
|
||||
*/
|
||||
public static final String BR = "</br>";
|
||||
/**
|
||||
* pdf拼接符
|
||||
*/
|
||||
public static final String PDFSTR = "∰";
|
||||
|
||||
/**
|
||||
* https请求
|
||||
*/
|
||||
public static final String HTTPS = "https://";
|
||||
|
||||
/**
|
||||
* 通用成功标识
|
||||
*/
|
||||
public static final String SUCCESS = "0";
|
||||
|
||||
/**
|
||||
* 通用失败标识
|
||||
*/
|
||||
public static final String FAIL = "1";
|
||||
|
||||
/**
|
||||
* 登录成功
|
||||
*/
|
||||
public static final String LOGIN_SUCCESS = "Success";
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
public static final String LOGOUT = "Logout";
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
public static final String REGISTER = "Register";
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 验证码有效期(分钟)
|
||||
*/
|
||||
public static final Integer CAPTCHA_EXPIRATION = 2;
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*/
|
||||
public static final String TOKEN = "token";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY = "login_user_key";
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
public static final String JWT_USERID = "userid";
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
public static final String JWT_USERNAME = Claims.SUBJECT;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
public static final String JWT_AVATAR = "avatar";
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
public static final String JWT_CREATED = "created";
|
||||
|
||||
/**
|
||||
* 用户权限
|
||||
*/
|
||||
public static final String JWT_AUTHORITIES = "authorities";
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "/profile";
|
||||
|
||||
/**
|
||||
* RMI 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_RMI = "rmi:";
|
||||
|
||||
/**
|
||||
* LDAP 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_LDAP = "ldap:";
|
||||
|
||||
/**
|
||||
* LDAPS 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_LDAPS = "ldaps:";
|
||||
public static final String DEFAULT_PASSWORD = "123456";
|
||||
public static final String SPLIT_COMMA =",";
|
||||
|
||||
/**
|
||||
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||
*/
|
||||
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
|
||||
|
||||
/**
|
||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||
*/
|
||||
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
|
||||
|
||||
/**
|
||||
* 定时任务违规的字符
|
||||
*/
|
||||
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
|
||||
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package com.ruoyi.common.constant;
|
||||
import com.ruoyi.common.exception.EsignDemoException;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.Collator;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @description 请求数据通用处理类
|
||||
* @author 澄泓
|
||||
* @date 2020年10月22日 下午14:25:31
|
||||
* @since JDK1.7
|
||||
*/
|
||||
public class EsignEncryption {
|
||||
|
||||
/**
|
||||
* 不允许外部创建实例
|
||||
*/
|
||||
private EsignEncryption(){}
|
||||
|
||||
/**
|
||||
* 拼接待签名字符串
|
||||
* @param httpMethod
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String appendSignDataString(String httpMethod, String contentMd5,String accept,String contentType,String headers,String date, String url) throws EsignDemoException {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(httpMethod).append("\n").append(accept).append("\n").append(contentMd5).append("\n")
|
||||
.append(contentType).append("\n");
|
||||
|
||||
if ("".equals(date) || date == null) {
|
||||
sb.append("\n");
|
||||
} else {
|
||||
sb.append(date).append("\n");
|
||||
}
|
||||
if ("".equals(headers) || headers == null) {
|
||||
sb.append(url);
|
||||
} else {
|
||||
sb.append(headers).append("\n").append(url);
|
||||
}
|
||||
return new String(sb);
|
||||
}
|
||||
|
||||
/***
|
||||
* Content-MD5的计算方法
|
||||
* @param str 待计算的消息
|
||||
* @return MD5计算后摘要值的Base64编码(ContentMD5)
|
||||
* @throws EsignDemoException 加密过程中的异常信息
|
||||
*/
|
||||
public static String doContentMD5(String str) throws EsignDemoException {
|
||||
byte[] md5Bytes = null;
|
||||
MessageDigest md5 = null;
|
||||
String contentMD5 = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
// 计算md5函数
|
||||
md5.update(str.getBytes("UTF-8"));
|
||||
// 获取文件MD5的二进制数组(128位)
|
||||
md5Bytes = md5.digest();
|
||||
// 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码(而不是对32位的16进制字符串进行编码)
|
||||
contentMD5 = Base64.encodeBase64String(md5Bytes);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
EsignDemoException ex = new EsignDemoException("不支持此算法",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/***
|
||||
* 计算请求签名值-HmacSHA256摘要
|
||||
* @param message 待签名字符串
|
||||
* @param secret 密钥APP KEY
|
||||
* @return reqSignature HmacSHA256计算后摘要值的Base64编码
|
||||
* @throws EsignDemoException 加密过程中的异常信息
|
||||
*/
|
||||
public static String doSignatureBase64(String message, String secret) throws EsignDemoException {
|
||||
String algorithm = "HmacSHA256";
|
||||
Mac hmacSha256;
|
||||
String digestBase64 = null;
|
||||
try {
|
||||
hmacSha256 = Mac.getInstance(algorithm);
|
||||
byte[] keyBytes = secret.getBytes("UTF-8");
|
||||
byte[] messageBytes = message.getBytes("UTF-8");
|
||||
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
|
||||
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
|
||||
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
|
||||
// 把摘要后的结果digestBytes使用Base64进行编码
|
||||
digestBase64 = Base64.encodeBase64String(digestBytes);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
EsignDemoException ex = new EsignDemoException("不支持此算法",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (InvalidKeyException e) {
|
||||
EsignDemoException ex = new EsignDemoException("无效的密钥规范",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return digestBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间戳
|
||||
* @return
|
||||
*/
|
||||
public static String timeStamp() {
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
return String.valueOf(timeStamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* byte字节数组转换成字符串
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static String byteArrayToHexString(byte[] b) {
|
||||
StringBuilder hs = new StringBuilder();
|
||||
String stmp;
|
||||
for (int n = 0; b != null && n < b.length; n++) {
|
||||
stmp = Integer.toHexString(b[n] & 0XFF);
|
||||
if (stmp.length() == 1)
|
||||
hs.append('0');
|
||||
hs.append(stmp);
|
||||
}
|
||||
return hs.toString().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* hash散列加密算法
|
||||
* @return
|
||||
*/
|
||||
public static String Hmac_SHA256(String message,String key) throws EsignDemoException {
|
||||
byte[] rawHmac=null;
|
||||
try {
|
||||
SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA256");
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(sk);
|
||||
rawHmac = mac.doFinal(message.getBytes());
|
||||
}catch (InvalidKeyException e){
|
||||
EsignDemoException ex = new EsignDemoException("无效的密钥规范",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
EsignDemoException ex = new EsignDemoException("不支持此算法",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}catch (Exception e){
|
||||
EsignDemoException ex = new EsignDemoException("hash散列加密算法报错",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}finally {
|
||||
return byteArrayToHexString(rawHmac);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密32位
|
||||
*/
|
||||
public static String MD5Digest(String text) throws EsignDemoException {
|
||||
byte[] digest=null;
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(text.getBytes());
|
||||
digest = md5.digest();
|
||||
}catch (NoSuchAlgorithmException e){
|
||||
EsignDemoException ex = new EsignDemoException("不支持此算法",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}finally {
|
||||
return byteArrayToHexString(digest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void formDataSort(List<BasicNameValuePair> param) {
|
||||
Collections.sort(param, new Comparator<BasicNameValuePair>() {
|
||||
@Override
|
||||
public int compare(BasicNameValuePair o1, BasicNameValuePair o2) {
|
||||
Comparator<Object> com = Collator.getInstance(Locale.CHINA);
|
||||
return com.compare(o1.getName(), o2.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/***
|
||||
* 字符串是否为空(含空格校验)
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isBlank(String str) {
|
||||
if (null == str || 0 == str.length()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int strLen = str.length();
|
||||
|
||||
for (int i = 0; i < strLen; i++) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 对请求URL中的Query参数按照字段名的 ASCII 码从小到大排序(字典排序)
|
||||
*
|
||||
* @param apiUrl
|
||||
* @return 排序后的API接口地址
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String sortApiUrl(String apiUrl) throws EsignDemoException {
|
||||
|
||||
if (!apiUrl.contains("?")) {
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
int queryIndex = apiUrl.indexOf("?");
|
||||
String apiUrlPath =apiUrl.substring(0,queryIndex+1);
|
||||
String apiUrlQuery = apiUrl.substring(queryIndex+1);
|
||||
//apiUrlQuery为空时返回
|
||||
if(isBlank(apiUrlQuery)){
|
||||
return apiUrl.substring(0,apiUrl.length()-1);
|
||||
}
|
||||
// 请求URL中Query参数转成Map
|
||||
Map<Object, Object> queryParamsMap = new HashMap<Object, Object>();
|
||||
String[] params = apiUrlQuery.split("&");
|
||||
for (String str : params) {
|
||||
int index = str.indexOf("=");
|
||||
String key = str.substring(0, index);
|
||||
String value = str.substring(index + 1);
|
||||
if (queryParamsMap.containsKey(key)) {
|
||||
String msg = MessageFormat.format("请求URL中的Query参数的{0}重复", key);
|
||||
throw new EsignDemoException(msg);
|
||||
}
|
||||
queryParamsMap.put(key, value);
|
||||
}
|
||||
|
||||
ArrayList<String> queryMapKeys = new ArrayList<String>();
|
||||
for (Map.Entry<Object, Object> entry : queryParamsMap.entrySet()) {
|
||||
queryMapKeys.add((String) entry.getKey());
|
||||
}
|
||||
// 按照字段名的 ASCII 码从小到大排序(字典排序)
|
||||
Collections.sort(queryMapKeys, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return (o1.compareToIgnoreCase(o2) == 0 ? -o1.compareTo(o2) : o1.compareToIgnoreCase(o2));
|
||||
}
|
||||
});
|
||||
|
||||
StringBuffer queryString = new StringBuffer();
|
||||
// 构造Query参数键值对值对的格式
|
||||
for (int i = 0; i < queryMapKeys.size(); i++) {
|
||||
String key = queryMapKeys.get(i);
|
||||
String value = (String) queryParamsMap.get(key);
|
||||
queryString.append(key);
|
||||
queryString.append("=");
|
||||
queryString.append(value);
|
||||
queryString.append("&");
|
||||
}
|
||||
if (queryString.length() > 0) {
|
||||
queryString = queryString.deleteCharAt(queryString.length() - 1);
|
||||
}
|
||||
|
||||
// Query参数排序后的接口请求地址
|
||||
StringBuffer sortApiUrl = new StringBuffer();
|
||||
sortApiUrl.append(apiUrlPath);
|
||||
sortApiUrl.append(queryString.toString());
|
||||
return sortApiUrl.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*获取query
|
||||
* @param apiUrl
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
*/
|
||||
public static ArrayList<BasicNameValuePair> getQuery(String apiUrl) throws EsignDemoException {
|
||||
ArrayList<BasicNameValuePair> BasicNameValuePairList = new ArrayList<>();
|
||||
|
||||
if (!apiUrl.contains("?")) {
|
||||
return BasicNameValuePairList;
|
||||
}
|
||||
|
||||
int queryIndex = apiUrl.indexOf("\\?");
|
||||
String apiUrlQuery = apiUrl.substring(queryIndex,apiUrl.length());
|
||||
|
||||
// 请求URL中Query参数转成Map
|
||||
Map<Object, Object> queryParamsMap = new HashMap<Object, Object>();
|
||||
String[] params = apiUrlQuery.split("&");
|
||||
for (String str : params) {
|
||||
int index = str.indexOf("=");
|
||||
String key = str.substring(0, index);
|
||||
String value = str.substring(index + 1);
|
||||
if (queryParamsMap.containsKey(key)) {
|
||||
String msg = MessageFormat.format("请求URL中的Query参数的{0}重复", key);
|
||||
throw new EsignDemoException(msg);
|
||||
}
|
||||
BasicNameValuePairList.add(new BasicNameValuePair(key,value));
|
||||
queryParamsMap.put(key, value);
|
||||
}
|
||||
return BasicNameValuePairList;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static boolean callBackCheck(String timestamp,String requestQuery,String body,String key,String signature){
|
||||
String algorithm="HmacSHA256";
|
||||
String encoding="UTF-8";
|
||||
Mac mac = null;
|
||||
try {
|
||||
String data = timestamp + requestQuery + body;
|
||||
mac = Mac.getInstance(algorithm);
|
||||
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(encoding), algorithm);
|
||||
mac.init(secretKey);
|
||||
mac.update(data.getBytes(encoding));
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("获取Signature签名信息异常:" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return byte2hex(mac.doFinal()).equalsIgnoreCase(signature);
|
||||
}
|
||||
|
||||
/***
|
||||
* 将byte[]转成16进制字符串
|
||||
*
|
||||
* @param data
|
||||
*
|
||||
* @return 16进制字符串
|
||||
*/
|
||||
public static String byte2hex(byte[] data) {
|
||||
StringBuilder hash = new StringBuilder();
|
||||
String stmp;
|
||||
for (int n = 0; data != null && n < data.length; n++) {
|
||||
stmp = Integer.toHexString(data[n] & 0XFF);
|
||||
if (stmp.length() == 1)
|
||||
hash.append('0');
|
||||
hash.append(stmp);
|
||||
}
|
||||
return hash.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.common.constant;
|
||||
/**
|
||||
* @description 头部信息常量
|
||||
* @author 澄泓
|
||||
* @date 2020/10/22 15:05
|
||||
* @version JDK1.7
|
||||
*/
|
||||
public enum EsignHeaderConstant {
|
||||
ACCEPT("*/*"),
|
||||
DATE(""),
|
||||
HEADERS( ""),
|
||||
CONTENTTYPE_FORMDATA("application/x-www-form-urlencoded"),
|
||||
CONTENTTYPE_JSON("application/json; charset=UTF-8"),
|
||||
CONTENTTYPE_PDF("application/pdf"),
|
||||
CONTENTTYPE_STREAM("application/octet-stream"),
|
||||
AUTHMODE("Signature");
|
||||
|
||||
private String value;
|
||||
private EsignHeaderConstant(String value) {
|
||||
this.value=value;
|
||||
}
|
||||
|
||||
public String VALUE(){
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package com.ruoyi.common.constant;
|
||||
import com.ruoyi.common.core.domain.entity.EsignHttpResponse;
|
||||
import com.ruoyi.common.enums.EsignRequestType;
|
||||
import com.ruoyi.common.exception.EsignDemoException;
|
||||
import org.apache.http.*;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.HttpRequestRetryHandler;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description Http请求 辅助类
|
||||
* @author 澄泓
|
||||
* @since JDK1.7
|
||||
*/
|
||||
public class EsignHttpCfgHelper {
|
||||
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(EsignHttpCfgHelper.class);
|
||||
/**
|
||||
* 超时时间,默认15000毫秒
|
||||
*/
|
||||
private static int MAX_TIMEOUT = 15000;
|
||||
/**
|
||||
* 请求池最大连接数,默认100个
|
||||
*/
|
||||
private static int MAX_TOTAL=100;
|
||||
/**
|
||||
* 单域名最大的连接数,默认50个
|
||||
*/
|
||||
private static int ROUTE_MAX_TOTAL=50;
|
||||
/**
|
||||
* 请求失败重试次数,默认3次
|
||||
*/
|
||||
private static int MAX_RETRY = 3;
|
||||
/**
|
||||
* 是否需要域名校验,默认不需要校验
|
||||
*/
|
||||
private static boolean SSL_VERIFY=false;
|
||||
|
||||
/**
|
||||
* 正向代理IP
|
||||
*/
|
||||
private static String PROXY_IP;
|
||||
/**
|
||||
* 正向代理端口,默认8888
|
||||
*/
|
||||
private static int PROXY_PORT=8888;
|
||||
/**
|
||||
* 代理协议,默认http
|
||||
*/
|
||||
private static String PROXY_AGREEMENT="http";
|
||||
|
||||
/**
|
||||
* 是否开启代理,默认false
|
||||
*/
|
||||
private static boolean OPEN_PROXY=false;
|
||||
|
||||
/**
|
||||
* 代理服务器用户名
|
||||
*/
|
||||
private static String PROXY_USERNAME="";
|
||||
|
||||
/**
|
||||
* 代理服务器密码
|
||||
*/
|
||||
private static String PROXY_PASSWORD="";
|
||||
|
||||
|
||||
private static PoolingHttpClientConnectionManager connMgr; //连接池
|
||||
private static HttpRequestRetryHandler retryHandler; //重试机制
|
||||
|
||||
private static CloseableHttpClient httpClient=null;
|
||||
|
||||
public static int getMaxTimeout() {
|
||||
return MAX_TIMEOUT;
|
||||
}
|
||||
|
||||
public static void setMaxTimeout(int maxTimeout) {
|
||||
MAX_TIMEOUT = maxTimeout;
|
||||
}
|
||||
|
||||
public static int getMaxTotal() {
|
||||
return MAX_TOTAL;
|
||||
}
|
||||
|
||||
public static void setMaxTotal(int maxTotal) {
|
||||
MAX_TOTAL = maxTotal;
|
||||
}
|
||||
|
||||
public static int getRouteMaxTotal() {
|
||||
return ROUTE_MAX_TOTAL;
|
||||
}
|
||||
|
||||
public static void setRouteMaxTotal(int routeMaxTotal) {
|
||||
ROUTE_MAX_TOTAL = routeMaxTotal;
|
||||
}
|
||||
|
||||
public static int getMaxRetry() {
|
||||
return MAX_RETRY;
|
||||
}
|
||||
|
||||
public static void setMaxRetry(int maxRetry) {
|
||||
MAX_RETRY = maxRetry;
|
||||
}
|
||||
|
||||
public static boolean isSslVerify() {
|
||||
return SSL_VERIFY;
|
||||
}
|
||||
|
||||
public static void setSslVerify(boolean sslVerify) {
|
||||
SSL_VERIFY = sslVerify;
|
||||
}
|
||||
|
||||
public static String getProxyIp() {
|
||||
return PROXY_IP;
|
||||
}
|
||||
|
||||
public static void setProxyIp(String proxyIp) {
|
||||
PROXY_IP = proxyIp;
|
||||
}
|
||||
|
||||
public static int getProxyPort() {
|
||||
return PROXY_PORT;
|
||||
}
|
||||
|
||||
public static void setProxyPort(int proxyPort) {
|
||||
PROXY_PORT = proxyPort;
|
||||
}
|
||||
|
||||
public static String getProxyAgreement() {
|
||||
return PROXY_AGREEMENT;
|
||||
}
|
||||
|
||||
public static void setProxyAgreement(String proxyAgreement) {
|
||||
PROXY_AGREEMENT = proxyAgreement;
|
||||
}
|
||||
|
||||
public static boolean getOpenProxy() {
|
||||
return OPEN_PROXY;
|
||||
}
|
||||
|
||||
public static void setOpenProxy(boolean openProxy) {
|
||||
OPEN_PROXY = openProxy;
|
||||
}
|
||||
|
||||
public static String getProxyUsername() {
|
||||
return PROXY_USERNAME;
|
||||
}
|
||||
|
||||
public static void setProxyUserame(String proxyUsername) {
|
||||
PROXY_USERNAME = proxyUsername;
|
||||
}
|
||||
|
||||
public static String getProxyPassword() {
|
||||
return PROXY_PASSWORD;
|
||||
}
|
||||
|
||||
public static void setProxyPassword(String proxyPassword) {
|
||||
PROXY_PASSWORD = proxyPassword;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 不允许外部创建实例
|
||||
*/
|
||||
private EsignHttpCfgHelper() {
|
||||
}
|
||||
|
||||
//------------------------------公有方法start--------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @description 发起HTTP / HTTPS 请求
|
||||
*
|
||||
* @param reqType
|
||||
* {@link EsignRequestType} 请求类型 GET、 POST 、 DELETE 、 PUT
|
||||
* @param httpUrl
|
||||
* {@link String} 请求目标地址
|
||||
* @param headers
|
||||
* {@link Map} 请求头
|
||||
* @param param
|
||||
* {@link Object} 参数
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static EsignHttpResponse sendHttp(EsignRequestType reqType, String httpUrl, Map<String, String> headers, Object param, boolean debug)
|
||||
throws EsignDemoException {
|
||||
HttpRequestBase reqBase=null;
|
||||
if(httpUrl.startsWith("http")){
|
||||
reqBase=reqType.getHttpType(httpUrl);
|
||||
}else{
|
||||
throw new EsignDemoException("请求url地址格式错误");
|
||||
}
|
||||
if(debug){
|
||||
LOGGER.info("请求头:{}",headers+"\n");
|
||||
LOGGER.info("请求参数\n{}", param+"\n");
|
||||
LOGGER.info("请求地址\n:{}\n请求方式\n:{}",reqBase.getURI(),reqType+"\n");
|
||||
}
|
||||
//请求方法不是GET或者DELETE时传入body体,否则不传入。
|
||||
String[] methods = {"DELETE", "GET"};
|
||||
if(param instanceof String&&Arrays.binarySearch(methods, reqType.name())<0){//POST或者PUT请求
|
||||
((HttpEntityEnclosingRequest) reqBase).setEntity(
|
||||
new StringEntity(String.valueOf(param), ContentType.create("application/json", "UTF-8")));
|
||||
}
|
||||
//参数时字节流数组
|
||||
else if(param instanceof byte[]) {
|
||||
reqBase=reqType.getHttpType(httpUrl);
|
||||
byte[] paramBytes = (byte[])param;
|
||||
((HttpEntityEnclosingRequest) reqBase).setEntity(new ByteArrayEntity(paramBytes));
|
||||
}
|
||||
//参数是form表单时
|
||||
else if(param instanceof List){
|
||||
((HttpEntityEnclosingRequest) reqBase).setEntity(new UrlEncodedFormEntity((Iterable<? extends NameValuePair>) param));
|
||||
}
|
||||
httpClient = getHttpClient();
|
||||
config(reqBase);
|
||||
|
||||
//设置请求头
|
||||
if(headers != null &&headers.size()>0) {
|
||||
for(Map.Entry<String, String> entry :headers.entrySet()) {
|
||||
reqBase.setHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
//响应对象
|
||||
CloseableHttpResponse res = null;
|
||||
//响应内容
|
||||
String resCtx = null;
|
||||
int status;
|
||||
EsignHttpResponse esignHttpResponse = new EsignHttpResponse();
|
||||
try {
|
||||
//执行请求
|
||||
res = httpClient.execute(reqBase);
|
||||
status=res.getStatusLine().getStatusCode();
|
||||
|
||||
//获取请求响应对象和响应entity
|
||||
HttpEntity httpEntity = res.getEntity();
|
||||
if(httpEntity != null) {
|
||||
resCtx = EntityUtils.toString(httpEntity,"utf-8");
|
||||
}
|
||||
if(debug) {
|
||||
LOGGER.info("响应\n{}", resCtx + "\n");
|
||||
LOGGER.info("----------------------------end------------------------");
|
||||
}
|
||||
} catch (NoHttpResponseException e) {
|
||||
throw new EsignDemoException("服务器丢失了",e);
|
||||
} catch (SSLHandshakeException e){
|
||||
String msg = MessageFormat.format("SSL握手异常", e);
|
||||
EsignDemoException ex = new EsignDemoException(msg, e);
|
||||
throw ex;
|
||||
} catch (UnknownHostException e){
|
||||
EsignDemoException ex = new EsignDemoException("服务器找不到", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch(ConnectTimeoutException e){
|
||||
EsignDemoException ex = new EsignDemoException("连接超时", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch(SSLException e){
|
||||
EsignDemoException ex = new EsignDemoException("SSL异常",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (ClientProtocolException e) {
|
||||
EsignDemoException ex = new EsignDemoException("请求头异常",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("网络请求失败",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} finally {
|
||||
if(res != null) {
|
||||
try {
|
||||
res.close();
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("--->>关闭请求响应失败",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
esignHttpResponse.setStatus(status);
|
||||
esignHttpResponse.setBody(resCtx);
|
||||
return esignHttpResponse;
|
||||
}
|
||||
//------------------------------公有方法end----------------------------------------------
|
||||
|
||||
//------------------------------私有方法start--------------------------------------------
|
||||
|
||||
/**
|
||||
* @description 请求头和超时时间配置
|
||||
*
|
||||
* @param httpReqBase
|
||||
* @author 澄泓
|
||||
*/
|
||||
private static void config(HttpRequestBase httpReqBase) {
|
||||
// 配置请求的超时设置
|
||||
RequestConfig.Builder builder = RequestConfig.custom()
|
||||
.setConnectionRequestTimeout(MAX_TIMEOUT)
|
||||
.setConnectTimeout(MAX_TIMEOUT)
|
||||
.setSocketTimeout(MAX_TIMEOUT);
|
||||
if(OPEN_PROXY){
|
||||
HttpHost proxy=new HttpHost(PROXY_IP,PROXY_PORT,PROXY_AGREEMENT);
|
||||
builder.setProxy(proxy);
|
||||
}
|
||||
RequestConfig requestConfig = builder.build();
|
||||
httpReqBase.setConfig(requestConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 连接池配置
|
||||
*
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
private static void cfgPoolMgr() throws EsignDemoException {
|
||||
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
|
||||
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
|
||||
if(!SSL_VERIFY){
|
||||
sslsf=sslConnectionSocketFactory();
|
||||
}
|
||||
|
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", plainsf)
|
||||
.register("https", sslsf)
|
||||
.build();
|
||||
|
||||
//连接池管理器
|
||||
connMgr = new PoolingHttpClientConnectionManager(registry);
|
||||
//请求池最大连接数
|
||||
connMgr.setMaxTotal(MAX_TOTAL);
|
||||
//但域名最大的连接数
|
||||
connMgr.setDefaultMaxPerRoute(ROUTE_MAX_TOTAL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description 设置重试机制
|
||||
*
|
||||
* @author 澄泓
|
||||
*/
|
||||
private static void cfgRetryHandler() {
|
||||
retryHandler = new HttpRequestRetryHandler() {
|
||||
|
||||
@Override
|
||||
public boolean retryRequest(IOException e, int excCount, HttpContext ctx) {
|
||||
//超过最大重试次数,就放弃
|
||||
if(excCount > MAX_RETRY) {
|
||||
return false;
|
||||
}
|
||||
//服务器丢掉了链接,就重试
|
||||
if(e instanceof NoHttpResponseException) {
|
||||
return true;
|
||||
}
|
||||
//不重试SSL握手异常
|
||||
if(e instanceof SSLHandshakeException) {
|
||||
return false;
|
||||
}
|
||||
//中断
|
||||
if(e instanceof InterruptedIOException) {
|
||||
return false;
|
||||
}
|
||||
//目标服务器不可达
|
||||
if(e instanceof UnknownHostException) {
|
||||
return false;
|
||||
}
|
||||
//连接超时
|
||||
//SSL异常
|
||||
if(e instanceof SSLException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HttpClientContext clientCtx = HttpClientContext.adapt(ctx);
|
||||
HttpRequest req = clientCtx.getRequest();
|
||||
//如果是幂等请求,就再次尝试
|
||||
if(!(req instanceof HttpEntityEnclosingRequest)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略域名校验
|
||||
*/
|
||||
private static SSLConnectionSocketFactory sslConnectionSocketFactory() throws EsignDemoException {
|
||||
try {
|
||||
SSLContext ctx = SSLContext.getInstance("TLS"); // 创建一个上下文(此处指定的协议类型似乎不是重点)
|
||||
X509TrustManager tm = new X509TrustManager() { // 创建一个跳过SSL证书的策略
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
||||
}
|
||||
};
|
||||
ctx.init(null, new TrustManager[] { tm }, null); // 使用上面的策略初始化上下文
|
||||
return new SSLConnectionSocketFactory(ctx, new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
|
||||
}catch (Exception e){
|
||||
EsignDemoException ex = new EsignDemoException("忽略域名校验失败",e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取单例HttpClient
|
||||
*
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
private static synchronized CloseableHttpClient getHttpClient() throws EsignDemoException {
|
||||
if(httpClient==null) {
|
||||
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
credsProvider.setCredentials(new AuthScope(PROXY_IP,PROXY_PORT),new UsernamePasswordCredentials(PROXY_USERNAME, PROXY_PASSWORD));
|
||||
cfgPoolMgr();
|
||||
cfgRetryHandler();
|
||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||
httpClient = httpClientBuilder.setDefaultCredentialsProvider(credsProvider).setConnectionManager(connMgr).setRetryHandler(retryHandler).build();
|
||||
}
|
||||
return httpClient;
|
||||
|
||||
}
|
||||
//------------------------------私有方法end----------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
import com.ruoyi.common.exception.EsignDemoException;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 澄泓
|
||||
* @version JDK1.7
|
||||
* @description 文件转换类
|
||||
* @date 2020/10/26 10:47
|
||||
*/
|
||||
public class FileTransformation {
|
||||
|
||||
/**
|
||||
* 传入本地文件路径转二进制byte
|
||||
*
|
||||
* @param srcFilePath 本地文件路径
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
*/
|
||||
public static byte[] fileToBytes(String srcFilePath) throws EsignDemoException {
|
||||
return getBytes(srcFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片转base64
|
||||
*
|
||||
* @param filePath 本地文件路径
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
*/
|
||||
public static String fileToBase64(String filePath) throws EsignDemoException {
|
||||
byte[] bytes;
|
||||
String base64 = null;
|
||||
bytes = fileToBytes(filePath);
|
||||
base64 = Base64.encodeBase64String(bytes);
|
||||
base64 = base64.replaceAll("\r\n", "");
|
||||
return base64;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws EsignDemoException {
|
||||
System.out.println(getFileContentMD5("D:\\文档\\PLT2022-02124CT.pdf"));
|
||||
}
|
||||
|
||||
/***
|
||||
* 计算文件内容的Content-MD5
|
||||
* @param filePath 文件路径
|
||||
* @return
|
||||
*/
|
||||
public static String getFileContentMD5(String filePath) throws EsignDemoException {
|
||||
// 获取文件MD5的二进制数组(128位)
|
||||
byte[] bytes = getFileMD5Bytes128(filePath);
|
||||
// 对文件MD5的二进制数组进行base64编码
|
||||
return new String(Base64.encodeBase64String(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param httpUrl 网络文件地址url
|
||||
* @return
|
||||
*/
|
||||
public static boolean downLoadFileByUrl(String httpUrl, String dir) throws EsignDemoException {
|
||||
boolean downLoadFileFlag = false;
|
||||
InputStream fis = null;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
try {
|
||||
URL url = new URL(httpUrl);
|
||||
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
||||
httpConn.connect();
|
||||
fis = httpConn.getInputStream();
|
||||
fileOutputStream = new FileOutputStream(new File(dir));
|
||||
byte[] md5Bytes = null;
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
fileOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
downLoadFileFlag = true;
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("获取文件流异常", e);
|
||||
ex.initCause(e);
|
||||
return downLoadFileFlag;
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("关闭文件流异常", e);
|
||||
ex.initCause(e);
|
||||
return downLoadFileFlag;
|
||||
}
|
||||
}
|
||||
return downLoadFileFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 网络文件转二进制MD5数组并获取文件大小
|
||||
*
|
||||
* @param fileUrl 网络文件地址url
|
||||
* @return
|
||||
*/
|
||||
public static Map fileUrlToBytes(String fileUrl) throws EsignDemoException {
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
try {
|
||||
URL url = new URL(fileUrl);
|
||||
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
||||
httpConn.connect();
|
||||
InputStream fis = httpConn.getInputStream();
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
outStream.close();
|
||||
map.put("fileSize", fis.available());
|
||||
byte[] md5Bytes = null;
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
md5.update(buffer, 0, length);
|
||||
outStream.write(buffer, 0, length);
|
||||
}
|
||||
md5Bytes = md5.digest();
|
||||
byte[] fileData = outStream.toByteArray();
|
||||
map.put("fileData", fileData);
|
||||
outStream.close();
|
||||
fis.close();
|
||||
map.put("md5Bytes", md5Bytes);
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("获取文件流异常", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
EsignDemoException ex = new EsignDemoException("文件计算异常", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/***
|
||||
* 获取文件MD5的二进制数组(128位)
|
||||
* @param filePath
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
*/
|
||||
public static byte[] getFileMD5Bytes128(String filePath) throws EsignDemoException {
|
||||
FileInputStream fis = null;
|
||||
byte[] md5Bytes = null;
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
fis = new FileInputStream(file);
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
md5.update(buffer, 0, length);
|
||||
}
|
||||
md5Bytes = md5.digest();
|
||||
fis.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
EsignDemoException ex = new EsignDemoException("文件找不到", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("输入流或输出流异常", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("关闭文件输入流失败", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return md5Bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
* @description 根据文件路径,获取文件base64
|
||||
* @author 宫清
|
||||
* @date 2019年7月21日 下午4:22:08
|
||||
*/
|
||||
public static String getBase64Str(String path) throws EsignDemoException {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(new File(path));
|
||||
byte[] bytes = new byte[is.available()];
|
||||
is.read(bytes);
|
||||
return Base64.encodeBase64String(bytes);
|
||||
} catch (Exception e) {
|
||||
EsignDemoException ex = new EsignDemoException("获取文件输入流失败", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("关闭文件输入流失败", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path 文件路径
|
||||
* @return
|
||||
* @description 获取文件名称
|
||||
* @author 宫清
|
||||
* @date 2019年7月21日 下午8:21:16
|
||||
*/
|
||||
public static String getFileName(String path) {
|
||||
return new File(path).getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePath {@link String} 文件地址
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
* @description 获取文件字节流
|
||||
* @date 2019年7月10日 上午9:17:00
|
||||
* @author 宫清
|
||||
*/
|
||||
public static byte[] getBytes(String filePath) throws EsignDemoException {
|
||||
File file = new File(filePath);
|
||||
FileInputStream fis = null;
|
||||
byte[] buffer = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
buffer = new byte[(int) file.length()];
|
||||
fis.read(buffer);
|
||||
} catch (Exception e) {
|
||||
EsignDemoException ex = new EsignDemoException("获取文件字节流失败", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
EsignDemoException ex = new EsignDemoException("关闭文件字节流失败", e);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 代码生成通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class GenConstants
|
||||
{
|
||||
/** 单表(增删改查) */
|
||||
public static final String TPL_CRUD = "crud";
|
||||
|
||||
/** 树表(增删改查) */
|
||||
public static final String TPL_TREE = "tree";
|
||||
|
||||
/** 主子表(增删改查) */
|
||||
public static final String TPL_SUB = "sub";
|
||||
|
||||
/** 树编码字段 */
|
||||
public static final String TREE_CODE = "treeCode";
|
||||
|
||||
/** 树父编码字段 */
|
||||
public static final String TREE_PARENT_CODE = "treeParentCode";
|
||||
|
||||
/** 树名称字段 */
|
||||
public static final String TREE_NAME = "treeName";
|
||||
|
||||
/** 上级菜单ID字段 */
|
||||
public static final String PARENT_MENU_ID = "parentMenuId";
|
||||
|
||||
/** 上级菜单名称字段 */
|
||||
public static final String PARENT_MENU_NAME = "parentMenuName";
|
||||
|
||||
/** 数据库字符串类型 */
|
||||
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
|
||||
|
||||
/** 数据库文本类型 */
|
||||
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
|
||||
|
||||
/** 数据库时间类型 */
|
||||
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
|
||||
|
||||
/** 数据库数字类型 */
|
||||
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
|
||||
"bit", "bigint", "float", "double", "decimal" };
|
||||
|
||||
/** 页面不需要编辑字段 */
|
||||
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
|
||||
|
||||
/** 页面不需要显示的列表字段 */
|
||||
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
|
||||
"update_time" };
|
||||
|
||||
/** 页面不需要查询字段 */
|
||||
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
|
||||
"update_time", "remark" };
|
||||
|
||||
/** Entity基类字段 */
|
||||
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
|
||||
|
||||
/** Tree基类字段 */
|
||||
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
|
||||
|
||||
/** 文本框 */
|
||||
public static final String HTML_INPUT = "input";
|
||||
|
||||
/** 文本域 */
|
||||
public static final String HTML_TEXTAREA = "textarea";
|
||||
|
||||
/** 下拉框 */
|
||||
public static final String HTML_SELECT = "select";
|
||||
|
||||
/** 单选框 */
|
||||
public static final String HTML_RADIO = "radio";
|
||||
|
||||
/** 复选框 */
|
||||
public static final String HTML_CHECKBOX = "checkbox";
|
||||
|
||||
/** 日期控件 */
|
||||
public static final String HTML_DATETIME = "datetime";
|
||||
|
||||
/** 图片上传控件 */
|
||||
public static final String HTML_IMAGE_UPLOAD = "imageUpload";
|
||||
|
||||
/** 文件上传控件 */
|
||||
public static final String HTML_FILE_UPLOAD = "fileUpload";
|
||||
|
||||
/** 富文本控件 */
|
||||
public static final String HTML_EDITOR = "editor";
|
||||
|
||||
/** 字符串类型 */
|
||||
public static final String TYPE_STRING = "String";
|
||||
|
||||
/** 整型 */
|
||||
public static final String TYPE_INTEGER = "Integer";
|
||||
|
||||
/** 长整型 */
|
||||
public static final String TYPE_LONG = "Long";
|
||||
|
||||
/** 浮点型 */
|
||||
public static final String TYPE_DOUBLE = "Double";
|
||||
|
||||
/** 高精度计算类型 */
|
||||
public static final String TYPE_BIGDECIMAL = "BigDecimal";
|
||||
|
||||
/** 时间类型 */
|
||||
public static final String TYPE_DATE = "Date";
|
||||
|
||||
/** 模糊查询 */
|
||||
public static final String QUERY_LIKE = "LIKE";
|
||||
|
||||
/** 相等查询 */
|
||||
public static final String QUERY_EQ = "EQ";
|
||||
|
||||
/** 需要 */
|
||||
public static final String REQUIRE = "1";
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 返回状态码
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class HttpStatus
|
||||
{
|
||||
/**
|
||||
* 操作成功
|
||||
*/
|
||||
public static final int SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* 对象创建成功
|
||||
*/
|
||||
public static final int CREATED = 201;
|
||||
|
||||
/**
|
||||
* 请求已经被接受
|
||||
*/
|
||||
public static final int ACCEPTED = 202;
|
||||
|
||||
/**
|
||||
* 操作已经执行成功,但是没有返回数据
|
||||
*/
|
||||
public static final int NO_CONTENT = 204;
|
||||
|
||||
/**
|
||||
* 资源已被移除
|
||||
*/
|
||||
public static final int MOVED_PERM = 301;
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*/
|
||||
public static final int SEE_OTHER = 303;
|
||||
|
||||
/**
|
||||
* 资源没有被修改
|
||||
*/
|
||||
public static final int NOT_MODIFIED = 304;
|
||||
|
||||
/**
|
||||
* 参数列表错误(缺少,格式不匹配)
|
||||
*/
|
||||
public static final int BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* 未授权
|
||||
*/
|
||||
public static final int UNAUTHORIZED = 401;
|
||||
|
||||
/**
|
||||
* 访问受限,授权过期
|
||||
*/
|
||||
public static final int FORBIDDEN = 403;
|
||||
|
||||
/**
|
||||
* 资源,服务未找到
|
||||
*/
|
||||
public static final int NOT_FOUND = 404;
|
||||
|
||||
/**
|
||||
* 不允许的http方法
|
||||
*/
|
||||
public static final int BAD_METHOD = 405;
|
||||
|
||||
/**
|
||||
* 资源冲突,或者资源被锁
|
||||
*/
|
||||
public static final int CONFLICT = 409;
|
||||
|
||||
/**
|
||||
* 不支持的数据,媒体类型
|
||||
*/
|
||||
public static final int UNSUPPORTED_TYPE = 415;
|
||||
|
||||
/**
|
||||
* 系统内部错误
|
||||
*/
|
||||
public static final int ERROR = 500;
|
||||
|
||||
/**
|
||||
* 接口未实现
|
||||
*/
|
||||
public static final int NOT_IMPLEMENTED = 501;
|
||||
|
||||
/**
|
||||
* 系统警告消息
|
||||
*/
|
||||
public static final int WARN = 601;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 任务调度通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class ScheduleConstants
|
||||
{
|
||||
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
|
||||
|
||||
/** 执行目标key */
|
||||
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
|
||||
|
||||
/** 默认 */
|
||||
public static final String MISFIRE_DEFAULT = "0";
|
||||
|
||||
/** 立即触发执行 */
|
||||
public static final String MISFIRE_IGNORE_MISFIRES = "1";
|
||||
|
||||
/** 触发一次执行 */
|
||||
public static final String MISFIRE_FIRE_AND_PROCEED = "2";
|
||||
|
||||
/** 不触发立即执行 */
|
||||
public static final String MISFIRE_DO_NOTHING = "3";
|
||||
|
||||
public enum Status
|
||||
{
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL("0"),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE("1");
|
||||
|
||||
private String value;
|
||||
|
||||
private Status(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 用户常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserConstants
|
||||
{
|
||||
/**
|
||||
* 平台内系统用户的唯一标志
|
||||
*/
|
||||
public static final String SYS_USER = "SYS_USER";
|
||||
|
||||
/** 正常状态 */
|
||||
public static final String NORMAL = "0";
|
||||
|
||||
/** 异常状态 */
|
||||
public static final String EXCEPTION = "1";
|
||||
|
||||
/** 用户封禁状态 */
|
||||
public static final String USER_DISABLE = "1";
|
||||
|
||||
/** 角色封禁状态 */
|
||||
public static final String ROLE_DISABLE = "1";
|
||||
|
||||
/** 部门正常状态 */
|
||||
public static final String DEPT_NORMAL = "0";
|
||||
|
||||
/** 部门停用状态 */
|
||||
public static final String DEPT_DISABLE = "1";
|
||||
|
||||
/** 字典正常状态 */
|
||||
public static final String DICT_NORMAL = "0";
|
||||
|
||||
/** 是否为系统默认(是) */
|
||||
public static final String YES = "Y";
|
||||
|
||||
/** 是否菜单外链(是) */
|
||||
public static final String YES_FRAME = "0";
|
||||
|
||||
/** 是否菜单外链(否) */
|
||||
public static final String NO_FRAME = "1";
|
||||
|
||||
/** 菜单类型(目录) */
|
||||
public static final String TYPE_DIR = "M";
|
||||
|
||||
/** 菜单类型(菜单) */
|
||||
public static final String TYPE_MENU = "C";
|
||||
|
||||
/** 菜单类型(按钮) */
|
||||
public static final String TYPE_BUTTON = "F";
|
||||
|
||||
/** Layout组件标识 */
|
||||
public final static String LAYOUT = "Layout";
|
||||
|
||||
/** ParentView组件标识 */
|
||||
public final static String PARENT_VIEW = "ParentView";
|
||||
|
||||
/** InnerLink组件标识 */
|
||||
public final static String INNER_LINK = "InnerLink";
|
||||
|
||||
/** 校验是否唯一的返回标识 */
|
||||
public final static boolean UNIQUE = true;
|
||||
public final static boolean NOT_UNIQUE = false;
|
||||
|
||||
/**
|
||||
* 用户名长度限制
|
||||
*/
|
||||
public static final int USERNAME_MIN_LENGTH = 2;
|
||||
public static final int USERNAME_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 密码长度限制
|
||||
*/
|
||||
public static final int PASSWORD_MIN_LENGTH = 5;
|
||||
public static final int PASSWORD_MAX_LENGTH = 20;
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package com.ruoyi.common.core.controller;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.page.PageDomain;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.page.TableSupport;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.PageUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||
|
||||
/**
|
||||
* web层通用数据处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BaseController
|
||||
{
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 将前台传递过来的日期格式的字符串,自动转化为Date类型
|
||||
*/
|
||||
@InitBinder
|
||||
public void initBinder(WebDataBinder binder)
|
||||
{
|
||||
// Date 类型转换
|
||||
binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
|
||||
{
|
||||
@Override
|
||||
public void setAsText(String text)
|
||||
{
|
||||
setValue(DateUtils.parseDate(text));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求分页数据
|
||||
*/
|
||||
protected void startPage()
|
||||
{
|
||||
PageUtils.startPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求排序数据
|
||||
*/
|
||||
protected void startOrderBy()
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
|
||||
{
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
PageHelper.orderBy(orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理分页的线程变量
|
||||
*/
|
||||
protected void clearPage()
|
||||
{
|
||||
PageUtils.clearPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应请求分页数据
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected TableDataInfo getDataTable(List<?> list)
|
||||
{
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(HttpStatus.SUCCESS);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setRows(list);
|
||||
rspData.setTotal(new PageInfo(list).getTotal());
|
||||
return rspData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功
|
||||
*/
|
||||
public AjaxResult success()
|
||||
{
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回失败消息
|
||||
*/
|
||||
public AjaxResult error()
|
||||
{
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*/
|
||||
public AjaxResult success(String message)
|
||||
{
|
||||
return AjaxResult.success(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*/
|
||||
public AjaxResult success(Object data)
|
||||
{
|
||||
return AjaxResult.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回失败消息
|
||||
*/
|
||||
public AjaxResult error(String message)
|
||||
{
|
||||
return AjaxResult.error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*/
|
||||
public AjaxResult warn(String message)
|
||||
{
|
||||
return AjaxResult.warn(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应返回结果
|
||||
*
|
||||
* @param rows 影响行数
|
||||
* @return 操作结果
|
||||
*/
|
||||
protected AjaxResult toAjax(int rows)
|
||||
{
|
||||
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应返回结果
|
||||
*
|
||||
* @param result 结果
|
||||
* @return 操作结果
|
||||
*/
|
||||
protected AjaxResult toAjax(boolean result)
|
||||
{
|
||||
return result ? success() : error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面跳转
|
||||
*/
|
||||
public String redirect(String url)
|
||||
{
|
||||
return StringUtils.format("redirect:{}", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户缓存信息
|
||||
*/
|
||||
public LoginUser getLoginUser()
|
||||
{
|
||||
return SecurityUtils.getLoginUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户id
|
||||
*/
|
||||
public Long getUserId()
|
||||
{
|
||||
return getLoginUser().getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录部门id
|
||||
*/
|
||||
public Long getDeptId()
|
||||
{
|
||||
return getLoginUser().getDeptId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户名
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return getLoginUser().getUsername();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AjaxResult extends HashMap<String, Object>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 状态码 */
|
||||
public static final String CODE_TAG = "code";
|
||||
|
||||
/** 返回内容 */
|
||||
public static final String MSG_TAG = "msg";
|
||||
|
||||
/** 数据对象 */
|
||||
public static final String DATA_TAG = "data";
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
|
||||
*/
|
||||
public AjaxResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
*/
|
||||
public AjaxResult(int code, String msg)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
*/
|
||||
public AjaxResult(int code, String msg, Object data)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
if (StringUtils.isNotNull(data))
|
||||
{
|
||||
super.put(DATA_TAG, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success()
|
||||
{
|
||||
return AjaxResult.success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功数据
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(Object data)
|
||||
{
|
||||
return AjaxResult.success("操作成功", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(String msg)
|
||||
{
|
||||
return AjaxResult.success(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResult warn(String msg)
|
||||
{
|
||||
return AjaxResult.warn(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResult warn(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.WARN, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error()
|
||||
{
|
||||
return AjaxResult.error("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(String msg)
|
||||
{
|
||||
return AjaxResult.error(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.ERROR, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(int code, String msg)
|
||||
{
|
||||
return new AjaxResult(code, msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为成功消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为警告消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isWarn()
|
||||
{
|
||||
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为错误消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isError()
|
||||
{
|
||||
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 方便链式调用
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 数据对象
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult put(String key, Object value)
|
||||
{
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BaseEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 搜索值
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String searchValue;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private Map<String, Object> params;
|
||||
|
||||
public String getSearchValue() {
|
||||
return searchValue;
|
||||
}
|
||||
|
||||
public void setSearchValue(String searchValue) {
|
||||
this.searchValue = searchValue;
|
||||
}
|
||||
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
public void setUpdateBy(String 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;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
if (params == null) {
|
||||
params = new HashMap<>();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class R<T> implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 成功 */
|
||||
public static final int SUCCESS = HttpStatus.SUCCESS;
|
||||
|
||||
/** 失败 */
|
||||
public static final int FAIL = HttpStatus.ERROR;
|
||||
|
||||
private int code;
|
||||
|
||||
private String msg;
|
||||
|
||||
private T data;
|
||||
|
||||
public static <T> R<T> ok()
|
||||
{
|
||||
return restResult(null, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(T data)
|
||||
{
|
||||
return restResult(data, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(T data, String msg)
|
||||
{
|
||||
return restResult(data, SUCCESS, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail()
|
||||
{
|
||||
return restResult(null, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg)
|
||||
{
|
||||
return restResult(null, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(T data)
|
||||
{
|
||||
return restResult(data, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(T data, String msg)
|
||||
{
|
||||
return restResult(data, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(int code, String msg)
|
||||
{
|
||||
return restResult(null, code, msg);
|
||||
}
|
||||
|
||||
private static <T> R<T> restResult(T data, int code, String msg)
|
||||
{
|
||||
R<T> apiResult = new R<>();
|
||||
apiResult.setCode(code);
|
||||
apiResult.setData(data);
|
||||
apiResult.setMsg(msg);
|
||||
return apiResult;
|
||||
}
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg()
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg)
|
||||
{
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public T getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> Boolean isError(R<T> ret)
|
||||
{
|
||||
return !isSuccess(ret);
|
||||
}
|
||||
|
||||
public static <T> Boolean isSuccess(R<T> ret)
|
||||
{
|
||||
return R.SUCCESS == ret.getCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tree基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TreeEntity extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 父菜单名称 */
|
||||
private String parentName;
|
||||
|
||||
/** 父菜单ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 显示顺序 */
|
||||
private Integer orderNum;
|
||||
|
||||
/** 祖级列表 */
|
||||
private String ancestors;
|
||||
|
||||
/** 子部门 */
|
||||
private List<?> children = new ArrayList<>();
|
||||
|
||||
public String getParentName()
|
||||
{
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName)
|
||||
{
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public Long getParentId()
|
||||
{
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId)
|
||||
{
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public Integer getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public void setOrderNum(Integer orderNum)
|
||||
{
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
public String getAncestors()
|
||||
{
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
public void setAncestors(String ancestors)
|
||||
{
|
||||
this.ancestors = ancestors;
|
||||
}
|
||||
|
||||
public List<?> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<?> children)
|
||||
{
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||
|
||||
|
||||
/**
|
||||
* Treeselect树结构实体类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TreeSelect implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 节点ID */
|
||||
private Long id;
|
||||
|
||||
/** 节点名称 */
|
||||
private String label;
|
||||
|
||||
/** 子节点 */
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<TreeSelect> children;
|
||||
|
||||
public TreeSelect()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TreeSelect(SysDept dept)
|
||||
{
|
||||
this.id = dept.getDeptId();
|
||||
this.label = dept.getDeptName();
|
||||
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public TreeSelect(SysMenu menu)
|
||||
{
|
||||
this.id = menu.getMenuId();
|
||||
this.label = menu.getMenuName();
|
||||
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public List<TreeSelect> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<TreeSelect> children)
|
||||
{
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
/**
|
||||
* esignSDK-core信息类
|
||||
* @author 澄泓
|
||||
* @date 2022/2/22 13:59
|
||||
* @version
|
||||
*/
|
||||
public class EsignCoreSdkInfo {
|
||||
private static final String SdkVersion="Esign-Sdk-Core1.0";
|
||||
private static final String SupportedVersion="JDK1.7 MORE THAN";
|
||||
|
||||
private static final String Info="sdk-esign-api核心工具包,主要处理e签宝公有云产品接口调用时的签名计算以及网络请求,通过EsignHttpHelper.signAndBuildSignAndJsonHeader构造签名鉴权+json数据格式的请求头,通过HttpHelper.doCommHttp方法入参发起网络请求。让开发者无需关注具体的请求签名算法,专注于接口业务的json参数构造";
|
||||
public static String getSdkVersion() {
|
||||
return SdkVersion;
|
||||
}
|
||||
|
||||
public static String getInfo() {
|
||||
return Info;
|
||||
}
|
||||
|
||||
public static String getSupportedVersion() {
|
||||
return SupportedVersion;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
/**
|
||||
* 网络请求的response类
|
||||
*/
|
||||
public class EsignHttpResponse {
|
||||
private int status;
|
||||
private String body;
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 部门表 sys_dept
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysDept extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 部门ID */
|
||||
private Long deptId;
|
||||
|
||||
/** 父部门ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 祖级列表 */
|
||||
private String ancestors;
|
||||
|
||||
/** 部门名称 */
|
||||
private String deptName;
|
||||
|
||||
/** 部门类型 */
|
||||
private Integer deptType;
|
||||
|
||||
/** 显示顺序 */
|
||||
private Integer orderNum;
|
||||
|
||||
/** 负责人 */
|
||||
private String leader;
|
||||
|
||||
/** 联系电话 */
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
private String email;
|
||||
|
||||
/** 部门状态:0正常,1停用 */
|
||||
private String status;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
private String delFlag;
|
||||
|
||||
/** 父部门名称 */
|
||||
private String parentName;
|
||||
|
||||
public Integer getDeptType() {
|
||||
return deptType;
|
||||
}
|
||||
|
||||
public void setDeptType(Integer deptType) {
|
||||
this.deptType = deptType;
|
||||
}
|
||||
|
||||
/** 子部门 */
|
||||
private List<SysDept> children = new ArrayList<SysDept>();
|
||||
|
||||
public Long getDeptId()
|
||||
{
|
||||
return deptId;
|
||||
}
|
||||
|
||||
public void setDeptId(Long deptId)
|
||||
{
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
public Long getParentId()
|
||||
{
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId)
|
||||
{
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getAncestors()
|
||||
{
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
public void setAncestors(String ancestors)
|
||||
{
|
||||
this.ancestors = ancestors;
|
||||
}
|
||||
|
||||
@NotBlank(message = "部门名称不能为空")
|
||||
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
|
||||
public String getDeptName()
|
||||
{
|
||||
return deptName;
|
||||
}
|
||||
|
||||
public void setDeptName(String deptName)
|
||||
{
|
||||
this.deptName = deptName;
|
||||
}
|
||||
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
public Integer getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public void setOrderNum(Integer orderNum)
|
||||
{
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
public String getLeader()
|
||||
{
|
||||
return leader;
|
||||
}
|
||||
|
||||
public void setLeader(String leader)
|
||||
{
|
||||
this.leader = leader;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
|
||||
public String getPhone()
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone)
|
||||
{
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getDelFlag()
|
||||
{
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
public void setDelFlag(String delFlag)
|
||||
{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
|
||||
public String getParentName()
|
||||
{
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName)
|
||||
{
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public List<SysDept> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<SysDept> children)
|
||||
{
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("deptId", getDeptId())
|
||||
.append("parentId", getParentId())
|
||||
.append("ancestors", getAncestors())
|
||||
.append("deptName", getDeptName())
|
||||
.append("orderNum", getOrderNum())
|
||||
.append("leader", getLeader())
|
||||
.append("phone", getPhone())
|
||||
.append("email", getEmail())
|
||||
.append("status", getStatus())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 字典数据表 sys_dict_data
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysDictData extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 字典编码 */
|
||||
@Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
|
||||
private Long dictCode;
|
||||
|
||||
/** 字典排序 */
|
||||
@Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
|
||||
private Long dictSort;
|
||||
|
||||
/** 字典标签 */
|
||||
@Excel(name = "字典标签")
|
||||
private String dictLabel;
|
||||
|
||||
/** 字典键值 */
|
||||
@Excel(name = "字典键值")
|
||||
private String dictValue;
|
||||
|
||||
/** 字典类型 */
|
||||
@Excel(name = "字典类型")
|
||||
private String dictType;
|
||||
|
||||
/** 样式属性(其他样式扩展) */
|
||||
private String cssClass;
|
||||
|
||||
/** 表格字典样式 */
|
||||
private String listClass;
|
||||
|
||||
/** 是否默认(Y是 N否) */
|
||||
@Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
|
||||
private String isDefault;
|
||||
|
||||
/** 状态(0正常 1停用) */
|
||||
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
public Long getDictCode()
|
||||
{
|
||||
return dictCode;
|
||||
}
|
||||
|
||||
public void setDictCode(Long dictCode)
|
||||
{
|
||||
this.dictCode = dictCode;
|
||||
}
|
||||
|
||||
public Long getDictSort()
|
||||
{
|
||||
return dictSort;
|
||||
}
|
||||
|
||||
public void setDictSort(Long dictSort)
|
||||
{
|
||||
this.dictSort = dictSort;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典标签不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
|
||||
public String getDictLabel()
|
||||
{
|
||||
return dictLabel;
|
||||
}
|
||||
|
||||
public void setDictLabel(String dictLabel)
|
||||
{
|
||||
this.dictLabel = dictLabel;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典键值不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
|
||||
public String getDictValue()
|
||||
{
|
||||
return dictValue;
|
||||
}
|
||||
|
||||
public void setDictValue(String dictValue)
|
||||
{
|
||||
this.dictValue = dictValue;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典类型不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
|
||||
public String getDictType()
|
||||
{
|
||||
return dictType;
|
||||
}
|
||||
|
||||
public void setDictType(String dictType)
|
||||
{
|
||||
this.dictType = dictType;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
|
||||
public String getCssClass()
|
||||
{
|
||||
return cssClass;
|
||||
}
|
||||
|
||||
public void setCssClass(String cssClass)
|
||||
{
|
||||
this.cssClass = cssClass;
|
||||
}
|
||||
|
||||
public String getListClass()
|
||||
{
|
||||
return listClass;
|
||||
}
|
||||
|
||||
public void setListClass(String listClass)
|
||||
{
|
||||
this.listClass = listClass;
|
||||
}
|
||||
|
||||
public boolean getDefault()
|
||||
{
|
||||
return UserConstants.YES.equals(this.isDefault);
|
||||
}
|
||||
|
||||
public String getIsDefault()
|
||||
{
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void setIsDefault(String isDefault)
|
||||
{
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("dictCode", getDictCode())
|
||||
.append("dictSort", getDictSort())
|
||||
.append("dictLabel", getDictLabel())
|
||||
.append("dictValue", getDictValue())
|
||||
.append("dictType", getDictType())
|
||||
.append("cssClass", getCssClass())
|
||||
.append("listClass", getListClass())
|
||||
.append("isDefault", getIsDefault())
|
||||
.append("status", getStatus())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 字典类型表 sys_dict_type
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysDictType extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 字典主键 */
|
||||
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
|
||||
private Long dictId;
|
||||
|
||||
/** 字典名称 */
|
||||
@Excel(name = "字典名称")
|
||||
private String dictName;
|
||||
|
||||
/** 字典类型 */
|
||||
@Excel(name = "字典类型")
|
||||
private String dictType;
|
||||
|
||||
/** 状态(0正常 1停用) */
|
||||
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
public Long getDictId()
|
||||
{
|
||||
return dictId;
|
||||
}
|
||||
|
||||
public void setDictId(Long dictId)
|
||||
{
|
||||
this.dictId = dictId;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典名称不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
|
||||
public String getDictName()
|
||||
{
|
||||
return dictName;
|
||||
}
|
||||
|
||||
public void setDictName(String dictName)
|
||||
{
|
||||
this.dictName = dictName;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典类型不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
|
||||
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
|
||||
public String getDictType()
|
||||
{
|
||||
return dictType;
|
||||
}
|
||||
|
||||
public void setDictType(String dictType)
|
||||
{
|
||||
this.dictType = dictType;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("dictId", getDictId())
|
||||
.append("dictName", getDictName())
|
||||
.append("dictType", getDictType())
|
||||
.append("status", getStatus())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 菜单权限表 sys_menu
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysMenu extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 菜单ID */
|
||||
private Long menuId;
|
||||
|
||||
/** 菜单名称 */
|
||||
private String menuName;
|
||||
|
||||
/** 父菜单名称 */
|
||||
private String parentName;
|
||||
|
||||
/** 父菜单ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 显示顺序 */
|
||||
private Integer orderNum;
|
||||
|
||||
/** 路由地址 */
|
||||
private String path;
|
||||
|
||||
/** 组件路径 */
|
||||
private String component;
|
||||
|
||||
/** 路由参数 */
|
||||
private String query;
|
||||
|
||||
/** 是否为外链(0是 1否) */
|
||||
private String isFrame;
|
||||
|
||||
/** 是否缓存(0缓存 1不缓存) */
|
||||
private String isCache;
|
||||
|
||||
/** 类型(M目录 C菜单 F按钮) */
|
||||
private String menuType;
|
||||
|
||||
/** 显示状态(0显示 1隐藏) */
|
||||
private String visible;
|
||||
|
||||
/** 菜单状态(0正常 1停用) */
|
||||
private String status;
|
||||
|
||||
/** 权限字符串 */
|
||||
private String perms;
|
||||
|
||||
/** 菜单图标 */
|
||||
private String icon;
|
||||
|
||||
/** 子菜单 */
|
||||
private List<SysMenu> children = new ArrayList<SysMenu>();
|
||||
|
||||
public Long getMenuId()
|
||||
{
|
||||
return menuId;
|
||||
}
|
||||
|
||||
public void setMenuId(Long menuId)
|
||||
{
|
||||
this.menuId = menuId;
|
||||
}
|
||||
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
|
||||
public String getMenuName()
|
||||
{
|
||||
return menuName;
|
||||
}
|
||||
|
||||
public void setMenuName(String menuName)
|
||||
{
|
||||
this.menuName = menuName;
|
||||
}
|
||||
|
||||
public String getParentName()
|
||||
{
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName)
|
||||
{
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public Long getParentId()
|
||||
{
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Long parentId)
|
||||
{
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
public Integer getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public void setOrderNum(Integer orderNum)
|
||||
{
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path)
|
||||
{
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
|
||||
public String getComponent()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setComponent(String component)
|
||||
{
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public String getQuery()
|
||||
{
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(String query)
|
||||
{
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public String getIsFrame()
|
||||
{
|
||||
return isFrame;
|
||||
}
|
||||
|
||||
public void setIsFrame(String isFrame)
|
||||
{
|
||||
this.isFrame = isFrame;
|
||||
}
|
||||
|
||||
public String getIsCache()
|
||||
{
|
||||
return isCache;
|
||||
}
|
||||
|
||||
public void setIsCache(String isCache)
|
||||
{
|
||||
this.isCache = isCache;
|
||||
}
|
||||
|
||||
@NotBlank(message = "菜单类型不能为空")
|
||||
public String getMenuType()
|
||||
{
|
||||
return menuType;
|
||||
}
|
||||
|
||||
public void setMenuType(String menuType)
|
||||
{
|
||||
this.menuType = menuType;
|
||||
}
|
||||
|
||||
public String getVisible()
|
||||
{
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(String visible)
|
||||
{
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
|
||||
public String getPerms()
|
||||
{
|
||||
return perms;
|
||||
}
|
||||
|
||||
public void setPerms(String perms)
|
||||
{
|
||||
this.perms = perms;
|
||||
}
|
||||
|
||||
public String getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon)
|
||||
{
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public List<SysMenu> getChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<SysMenu> children)
|
||||
{
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("menuId", getMenuId())
|
||||
.append("menuName", getMenuName())
|
||||
.append("parentId", getParentId())
|
||||
.append("orderNum", getOrderNum())
|
||||
.append("path", getPath())
|
||||
.append("component", getComponent())
|
||||
.append("isFrame", getIsFrame())
|
||||
.append("IsCache", getIsCache())
|
||||
.append("menuType", getMenuType())
|
||||
.append("visible", getVisible())
|
||||
.append("status ", getStatus())
|
||||
.append("perms", getPerms())
|
||||
.append("icon", getIcon())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 角色表 sys_role
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysRole extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 角色ID */
|
||||
@Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
|
||||
private Long roleId;
|
||||
|
||||
/** 角色名称 */
|
||||
@Excel(name = "角色名称")
|
||||
private String roleName;
|
||||
|
||||
/** 角色权限 */
|
||||
@Excel(name = "角色权限")
|
||||
private String roleKey;
|
||||
|
||||
/** 角色排序 */
|
||||
@Excel(name = "角色排序")
|
||||
private Integer roleSort;
|
||||
|
||||
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
||||
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
||||
private String dataScope;
|
||||
|
||||
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
|
||||
private boolean menuCheckStrictly;
|
||||
|
||||
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
|
||||
private boolean deptCheckStrictly;
|
||||
|
||||
/** 角色状态(0正常 1停用) */
|
||||
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
private String delFlag;
|
||||
|
||||
/** 用户是否存在此角色标识 默认不存在 */
|
||||
private boolean flag = false;
|
||||
|
||||
/** 菜单组 */
|
||||
private Long[] menuIds;
|
||||
|
||||
/** 部门组(数据权限) */
|
||||
private Long[] deptIds;
|
||||
|
||||
/** 角色菜单权限 */
|
||||
private Set<String> permissions;
|
||||
|
||||
public SysRole()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SysRole(Long roleId)
|
||||
{
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public Long getRoleId()
|
||||
{
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(Long roleId)
|
||||
{
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public boolean isAdmin()
|
||||
{
|
||||
return isAdmin(this.roleId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Long roleId)
|
||||
{
|
||||
return roleId != null && 1L == roleId;
|
||||
}
|
||||
|
||||
@NotBlank(message = "角色名称不能为空")
|
||||
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
|
||||
public String getRoleName()
|
||||
{
|
||||
return roleName;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName)
|
||||
{
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
@NotBlank(message = "权限字符不能为空")
|
||||
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
|
||||
public String getRoleKey()
|
||||
{
|
||||
return roleKey;
|
||||
}
|
||||
|
||||
public void setRoleKey(String roleKey)
|
||||
{
|
||||
this.roleKey = roleKey;
|
||||
}
|
||||
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
public Integer getRoleSort()
|
||||
{
|
||||
return roleSort;
|
||||
}
|
||||
|
||||
public void setRoleSort(Integer roleSort)
|
||||
{
|
||||
this.roleSort = roleSort;
|
||||
}
|
||||
|
||||
public String getDataScope()
|
||||
{
|
||||
return dataScope;
|
||||
}
|
||||
|
||||
public void setDataScope(String dataScope)
|
||||
{
|
||||
this.dataScope = dataScope;
|
||||
}
|
||||
|
||||
public boolean isMenuCheckStrictly()
|
||||
{
|
||||
return menuCheckStrictly;
|
||||
}
|
||||
|
||||
public void setMenuCheckStrictly(boolean menuCheckStrictly)
|
||||
{
|
||||
this.menuCheckStrictly = menuCheckStrictly;
|
||||
}
|
||||
|
||||
public boolean isDeptCheckStrictly()
|
||||
{
|
||||
return deptCheckStrictly;
|
||||
}
|
||||
|
||||
public void setDeptCheckStrictly(boolean deptCheckStrictly)
|
||||
{
|
||||
this.deptCheckStrictly = deptCheckStrictly;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getDelFlag()
|
||||
{
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
public void setDelFlag(String delFlag)
|
||||
{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
|
||||
public boolean isFlag()
|
||||
{
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(boolean flag)
|
||||
{
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public Long[] getMenuIds()
|
||||
{
|
||||
return menuIds;
|
||||
}
|
||||
|
||||
public void setMenuIds(Long[] menuIds)
|
||||
{
|
||||
this.menuIds = menuIds;
|
||||
}
|
||||
|
||||
public Long[] getDeptIds()
|
||||
{
|
||||
return deptIds;
|
||||
}
|
||||
|
||||
public void setDeptIds(Long[] deptIds)
|
||||
{
|
||||
this.deptIds = deptIds;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions()
|
||||
{
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<String> permissions)
|
||||
{
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("roleId", getRoleId())
|
||||
.append("roleName", getRoleName())
|
||||
.append("roleKey", getRoleKey())
|
||||
.append("roleSort", getRoleSort())
|
||||
.append("dataScope", getDataScope())
|
||||
.append("menuCheckStrictly", isMenuCheckStrictly())
|
||||
.append("deptCheckStrictly", isDeptCheckStrictly())
|
||||
.append("status", getStatus())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.*;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.annotation.Excel.Type;
|
||||
import com.ruoyi.common.annotation.Excels;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.xss.Xss;
|
||||
|
||||
/**
|
||||
* 用户对象 sys_user
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysUser extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 用户ID */
|
||||
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
||||
private Long userId;
|
||||
|
||||
/** 部门ID */
|
||||
@Excel(name = "部门编号", type = Type.IMPORT)
|
||||
private Long deptId;
|
||||
|
||||
/** 用户账号 */
|
||||
@Excel(name = "登录名称")
|
||||
private String userName;
|
||||
|
||||
|
||||
|
||||
/** 用户昵称 */
|
||||
@Excel(name = "用户名称")
|
||||
private String nickName;
|
||||
|
||||
/** 用户昵称和待办数量 */
|
||||
private String nickNameAndNum;
|
||||
|
||||
public String getNickNameAndNum() {
|
||||
return nickNameAndNum;
|
||||
}
|
||||
|
||||
public void setNickNameAndNum(String nickNameAndNum) {
|
||||
this.nickNameAndNum = nickNameAndNum;
|
||||
}
|
||||
|
||||
/** 用户身份证号 */
|
||||
@Excel(name = "身份证号")
|
||||
private String idCard;
|
||||
|
||||
/** 用户邮箱 */
|
||||
@Excel(name = "用户邮箱")
|
||||
private String email;
|
||||
|
||||
/** 手机号码 */
|
||||
@Excel(name = "手机号码")
|
||||
private String phonenumber;
|
||||
|
||||
/** 用户性别 */
|
||||
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
|
||||
private String sex;
|
||||
|
||||
/** 用户头像 */
|
||||
private String avatar;
|
||||
|
||||
/** 密码 */
|
||||
private String password;
|
||||
|
||||
/** 帐号状态(0正常 1停用) */
|
||||
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
private String delFlag;
|
||||
|
||||
/** 最后登录IP */
|
||||
@Excel(name = "最后登录IP", type = Type.EXPORT)
|
||||
private String loginIp;
|
||||
|
||||
/** 最后登录时间 */
|
||||
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
||||
private Date loginDate;
|
||||
|
||||
/** 部门对象 */
|
||||
@Excels({
|
||||
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
|
||||
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
|
||||
})
|
||||
private SysDept dept;
|
||||
|
||||
/** 角色对象 */
|
||||
private List<SysRole> roles;
|
||||
|
||||
/** 角色组 */
|
||||
private Long[] roleIds;
|
||||
|
||||
/** 岗位组 */
|
||||
private Long[] postIds;
|
||||
|
||||
/** 角色ID */
|
||||
private Long roleId;
|
||||
|
||||
public SysUser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SysUser(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public boolean isAdmin()
|
||||
{
|
||||
return isAdmin(this.userId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Long userId)
|
||||
{
|
||||
return userId != null && 1L == userId;
|
||||
}
|
||||
|
||||
public Long getDeptId()
|
||||
{
|
||||
return deptId;
|
||||
}
|
||||
|
||||
public void setDeptId(Long deptId)
|
||||
{
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
@Xss(message = "用户昵称不能包含脚本字符")
|
||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||
public String getNickName()
|
||||
{
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName)
|
||||
{
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
@Xss(message = "用户账号不能包含脚本字符")
|
||||
@NotBlank(message = "用户账号不能为空")
|
||||
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
|
||||
public String getUserName()
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName)
|
||||
{
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
|
||||
public String getPhonenumber()
|
||||
{
|
||||
return phonenumber;
|
||||
}
|
||||
|
||||
public void setPhonenumber(String phonenumber)
|
||||
{
|
||||
this.phonenumber = phonenumber;
|
||||
}
|
||||
|
||||
public String getSex()
|
||||
{
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex)
|
||||
{
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getAvatar()
|
||||
{
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar)
|
||||
{
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getDelFlag()
|
||||
{
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
public void setDelFlag(String delFlag)
|
||||
{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
|
||||
public String getLoginIp()
|
||||
{
|
||||
return loginIp;
|
||||
}
|
||||
|
||||
public void setLoginIp(String loginIp)
|
||||
{
|
||||
this.loginIp = loginIp;
|
||||
}
|
||||
|
||||
public Date getLoginDate()
|
||||
{
|
||||
return loginDate;
|
||||
}
|
||||
|
||||
public void setLoginDate(Date loginDate)
|
||||
{
|
||||
this.loginDate = loginDate;
|
||||
}
|
||||
|
||||
public SysDept getDept()
|
||||
{
|
||||
return dept;
|
||||
}
|
||||
|
||||
public void setDept(SysDept dept)
|
||||
{
|
||||
this.dept = dept;
|
||||
}
|
||||
|
||||
public List<SysRole> getRoles()
|
||||
{
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<SysRole> roles)
|
||||
{
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Long[] getRoleIds()
|
||||
{
|
||||
return roleIds;
|
||||
}
|
||||
|
||||
public void setRoleIds(Long[] roleIds)
|
||||
{
|
||||
this.roleIds = roleIds;
|
||||
}
|
||||
|
||||
public Long[] getPostIds()
|
||||
{
|
||||
return postIds;
|
||||
}
|
||||
|
||||
public void setPostIds(Long[] postIds)
|
||||
{
|
||||
this.postIds = postIds;
|
||||
}
|
||||
|
||||
public Long getRoleId()
|
||||
{
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(Long roleId)
|
||||
{
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public String getIdCard() {
|
||||
return idCard;
|
||||
}
|
||||
|
||||
public void setIdCard(String idCard) {
|
||||
this.idCard = idCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("userId", getUserId())
|
||||
.append("deptId", getDeptId())
|
||||
.append("userName", getUserName())
|
||||
.append("idCard", getIdCard())
|
||||
.append("nickName", getNickName())
|
||||
.append("email", getEmail())
|
||||
.append("phonenumber", getPhonenumber())
|
||||
.append("sex", getSex())
|
||||
.append("avatar", getAvatar())
|
||||
.append("password", getPassword())
|
||||
.append("status", getStatus())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("loginIp", getLoginIp())
|
||||
.append("loginDate", getLoginDate())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.append("dept", getDept())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
/**
|
||||
* 用户登录对象
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class LoginBody
|
||||
{
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getUuid()
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid)
|
||||
{
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 登录用户身份权限
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class LoginUser implements UserDetails
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户唯一标识
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
private Long loginTime;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Long expireTime;
|
||||
|
||||
/**
|
||||
* 登录IP地址
|
||||
*/
|
||||
private String ipaddr;
|
||||
|
||||
/**
|
||||
* 登录地点
|
||||
*/
|
||||
private String loginLocation;
|
||||
|
||||
/**
|
||||
* 浏览器类型
|
||||
*/
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 操作系统
|
||||
*/
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* 权限列表
|
||||
*/
|
||||
private Set<String> permissions;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
private SysUser user;
|
||||
|
||||
public LoginUser()
|
||||
{
|
||||
}
|
||||
|
||||
public LoginUser(SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getDeptId()
|
||||
{
|
||||
return deptId;
|
||||
}
|
||||
|
||||
public void setDeptId(Long deptId)
|
||||
{
|
||||
this.deptId = deptId;
|
||||
}
|
||||
|
||||
public String getToken()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token)
|
||||
{
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public String getPassword()
|
||||
{
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername()
|
||||
{
|
||||
return user.getUserName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 账户是否未过期,过期无法验证
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isAccountNonExpired()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定用户是否解锁,锁定的用户无法进行身份验证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isAccountNonLocked()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可用 ,禁用的用户不能身份验证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public Long getLoginTime()
|
||||
{
|
||||
return loginTime;
|
||||
}
|
||||
|
||||
public void setLoginTime(Long loginTime)
|
||||
{
|
||||
this.loginTime = loginTime;
|
||||
}
|
||||
|
||||
public String getIpaddr()
|
||||
{
|
||||
return ipaddr;
|
||||
}
|
||||
|
||||
public void setIpaddr(String ipaddr)
|
||||
{
|
||||
this.ipaddr = ipaddr;
|
||||
}
|
||||
|
||||
public String getLoginLocation()
|
||||
{
|
||||
return loginLocation;
|
||||
}
|
||||
|
||||
public void setLoginLocation(String loginLocation)
|
||||
{
|
||||
this.loginLocation = loginLocation;
|
||||
}
|
||||
|
||||
public String getBrowser()
|
||||
{
|
||||
return browser;
|
||||
}
|
||||
|
||||
public void setBrowser(String browser)
|
||||
{
|
||||
this.browser = browser;
|
||||
}
|
||||
|
||||
public String getOs()
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
public void setOs(String os)
|
||||
{
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public Long getExpireTime()
|
||||
{
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
public void setExpireTime(Long expireTime)
|
||||
{
|
||||
this.expireTime = expireTime;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions()
|
||||
{
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<String> permissions)
|
||||
{
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public SysUser getUser()
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(SysUser user)
|
||||
{
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
/**
|
||||
* 用户注册对象
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RegisterBody extends LoginBody
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.ruoyi.common.core.page;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 分页数据
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class PageDomain
|
||||
{
|
||||
/** 当前记录起始索引 */
|
||||
private Integer pageNum;
|
||||
|
||||
/** 每页显示记录数 */
|
||||
private Integer pageSize;
|
||||
|
||||
/** 排序列 */
|
||||
private String orderByColumn;
|
||||
|
||||
/** 排序的方向desc或者asc */
|
||||
private String isAsc = "asc";
|
||||
|
||||
/** 分页参数合理化 */
|
||||
private Boolean reasonable = true;
|
||||
|
||||
public String getOrderBy()
|
||||
{
|
||||
if (StringUtils.isEmpty(orderByColumn))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
|
||||
}
|
||||
|
||||
public Integer getPageNum()
|
||||
{
|
||||
return pageNum;
|
||||
}
|
||||
|
||||
public void setPageNum(Integer pageNum)
|
||||
{
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
|
||||
public Integer getPageSize()
|
||||
{
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(Integer pageSize)
|
||||
{
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public String getOrderByColumn()
|
||||
{
|
||||
return orderByColumn;
|
||||
}
|
||||
|
||||
public void setOrderByColumn(String orderByColumn)
|
||||
{
|
||||
this.orderByColumn = orderByColumn;
|
||||
}
|
||||
|
||||
public String getIsAsc()
|
||||
{
|
||||
return isAsc;
|
||||
}
|
||||
|
||||
public void setIsAsc(String isAsc)
|
||||
{
|
||||
if (StringUtils.isNotEmpty(isAsc))
|
||||
{
|
||||
// 兼容前端排序类型
|
||||
if ("ascending".equals(isAsc))
|
||||
{
|
||||
isAsc = "asc";
|
||||
}
|
||||
else if ("descending".equals(isAsc))
|
||||
{
|
||||
isAsc = "desc";
|
||||
}
|
||||
this.isAsc = isAsc;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean getReasonable()
|
||||
{
|
||||
if (StringUtils.isNull(reasonable))
|
||||
{
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return reasonable;
|
||||
}
|
||||
|
||||
public void setReasonable(Boolean reasonable)
|
||||
{
|
||||
this.reasonable = reasonable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.ruoyi.common.core.page;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表格分页数据对象
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TableDataInfo implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 总记录数 */
|
||||
private long total;
|
||||
|
||||
/** 列表数据 */
|
||||
private List<?> rows;
|
||||
|
||||
/** 消息状态码 */
|
||||
private int code;
|
||||
|
||||
/** 消息内容 */
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 表格数据对象
|
||||
*/
|
||||
public TableDataInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*
|
||||
* @param list 列表数据
|
||||
* @param total 总记录数
|
||||
*/
|
||||
public TableDataInfo(List<?> list, int total)
|
||||
{
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public long getTotal()
|
||||
{
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total)
|
||||
{
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<?> getRows()
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<?> rows)
|
||||
{
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg()
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg)
|
||||
{
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.ruoyi.common.core.page;
|
||||
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
|
||||
/**
|
||||
* 表格数据处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
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 PageDomain getPageDomain()
|
||||
{
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
|
||||
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
|
||||
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
|
||||
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
|
||||
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
|
||||
return pageDomain;
|
||||
}
|
||||
|
||||
public static PageDomain buildPageRequest()
|
||||
{
|
||||
return getPageDomain();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.ruoyi.common.core.redis;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.BoundSetOperations;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* spring redis 工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
**/
|
||||
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||
@Component
|
||||
public class RedisCache
|
||||
{
|
||||
@Autowired
|
||||
public RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @param value 缓存的值
|
||||
*/
|
||||
public <T> void setCacheObject(final String key, final T value)
|
||||
{
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @param value 缓存的值
|
||||
* @param timeout 时间
|
||||
* @param timeUnit 时间颗粒度
|
||||
*/
|
||||
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
|
||||
{
|
||||
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire(final String key, final long timeout)
|
||||
{
|
||||
return expire(key, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
* @param unit 时间单位
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire(final String key, final long timeout, final TimeUnit unit)
|
||||
{
|
||||
return redisTemplate.expire(key, timeout, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
* @return 有效时间
|
||||
*/
|
||||
public long getExpire(final String key)
|
||||
{
|
||||
return redisTemplate.getExpire(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public Boolean hasKey(String key)
|
||||
{
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象。
|
||||
*
|
||||
* @param key 缓存键值
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> T getCacheObject(final String key)
|
||||
{
|
||||
ValueOperations<String, T> operation = redisTemplate.opsForValue();
|
||||
return operation.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单个对象
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public boolean deleteObject(final String key)
|
||||
{
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除集合对象
|
||||
*
|
||||
* @param collection 多个对象
|
||||
* @return
|
||||
*/
|
||||
public boolean deleteObject(final Collection collection)
|
||||
{
|
||||
return redisTemplate.delete(collection) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存List数据
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @param dataList 待缓存的List数据
|
||||
* @return 缓存的对象
|
||||
*/
|
||||
public <T> long setCacheList(final String key, final List<T> dataList)
|
||||
{
|
||||
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||
return count == null ? 0 : count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的list对象
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> List<T> getCacheList(final String key)
|
||||
{
|
||||
return redisTemplate.opsForList().range(key, 0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Set
|
||||
*
|
||||
* @param key 缓存键值
|
||||
* @param dataSet 缓存的数据
|
||||
* @return 缓存数据的对象
|
||||
*/
|
||||
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
|
||||
{
|
||||
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
|
||||
Iterator<T> it = dataSet.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
setOperation.add(it.next());
|
||||
}
|
||||
return setOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的set
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T> Set<T> getCacheSet(final String key)
|
||||
{
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Map
|
||||
*
|
||||
* @param key
|
||||
* @param dataMap
|
||||
*/
|
||||
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
|
||||
{
|
||||
if (dataMap != null) {
|
||||
redisTemplate.opsForHash().putAll(key, dataMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的Map
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T> Map<String, T> getCacheMap(final String key)
|
||||
{
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 往Hash中存入数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
* @param value 值
|
||||
*/
|
||||
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
|
||||
{
|
||||
redisTemplate.opsForHash().put(key, hKey, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Hash中的数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
* @return Hash中的对象
|
||||
*/
|
||||
public <T> T getCacheMapValue(final String key, final String hKey)
|
||||
{
|
||||
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
|
||||
return opsForHash.get(key, hKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多个Hash中的数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKeys Hash键集合
|
||||
* @return Hash对象集合
|
||||
*/
|
||||
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
|
||||
{
|
||||
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Hash中的某条数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean deleteCacheMapValue(final String key, final String hKey)
|
||||
{
|
||||
return redisTemplate.opsForHash().delete(key, hKey) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
* @return 对象列表
|
||||
*/
|
||||
public Collection<String> keys(final String pattern)
|
||||
{
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.ruoyi.common.core.text;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CharsetKit
|
||||
{
|
||||
/** ISO-8859-1 */
|
||||
public static final String ISO_8859_1 = "ISO-8859-1";
|
||||
/** UTF-8 */
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
/** GBK */
|
||||
public static final String GBK = "GBK";
|
||||
|
||||
/** ISO-8859-1 */
|
||||
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
|
||||
/** UTF-8 */
|
||||
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
|
||||
/** GBK */
|
||||
public static final Charset CHARSET_GBK = Charset.forName(GBK);
|
||||
|
||||
/**
|
||||
* 转换为Charset对象
|
||||
*
|
||||
* @param charset 字符集,为空则返回默认字符集
|
||||
* @return Charset
|
||||
*/
|
||||
public static Charset charset(String charset)
|
||||
{
|
||||
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, String srcCharset, String destCharset)
|
||||
{
|
||||
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, Charset srcCharset, Charset destCharset)
|
||||
{
|
||||
if (null == srcCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
if (null == destCharset)
|
||||
{
|
||||
destCharset = StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
return new String(source.getBytes(srcCharset), destCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 系统字符集编码
|
||||
*/
|
||||
public static String systemCharset()
|
||||
{
|
||||
return Charset.defaultCharset().name();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
package com.ruoyi.common.core.text;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符串格式化
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class StrFormatter
|
||||
{
|
||||
public static final String EMPTY_JSON = "{}";
|
||||
public static final char C_BACKSLASH = '\\';
|
||||
public static final char C_DELIM_START = '{';
|
||||
public static final char C_DELIM_END = '}';
|
||||
|
||||
/**
|
||||
* 格式化字符串<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param strPattern 字符串模板
|
||||
* @param argArray 参数列表
|
||||
* @return 结果
|
||||
*/
|
||||
public static String format(final String strPattern, final Object... argArray)
|
||||
{
|
||||
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
final int strPatternLength = strPattern.length();
|
||||
|
||||
// 初始化定义好的长度以获得更好的性能
|
||||
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
|
||||
|
||||
int handledPosition = 0;
|
||||
int delimIndex;// 占位符所在位置
|
||||
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
|
||||
{
|
||||
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
|
||||
if (delimIndex == -1)
|
||||
{
|
||||
if (handledPosition == 0)
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
else
|
||||
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
|
||||
sbuf.append(strPattern, handledPosition, strPatternLength);
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
|
||||
{
|
||||
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
|
||||
{
|
||||
// 转义符之前还有一个转义符,占位符依旧有效
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 占位符被转义
|
||||
argIndex--;
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(C_DELIM_START);
|
||||
handledPosition = delimIndex + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常占位符
|
||||
sbuf.append(strPattern, handledPosition, delimIndex);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 加入最后一个占位符后所有的字符
|
||||
sbuf.append(strPattern, handledPosition, strPattern.length());
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 操作状态
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public enum BusinessStatus
|
||||
{
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
SUCCESS,
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
FAIL,
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 业务操作类型
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum BusinessType
|
||||
{
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
INSERT,
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
UPDATE,
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
DELETE,
|
||||
|
||||
/**
|
||||
* 授权
|
||||
*/
|
||||
GRANT,
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*/
|
||||
EXPORT,
|
||||
|
||||
/**
|
||||
* 导入
|
||||
*/
|
||||
IMPORT,
|
||||
|
||||
/**
|
||||
* 强退
|
||||
*/
|
||||
FORCE,
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*/
|
||||
GENCODE,
|
||||
|
||||
/**
|
||||
* 清空数据
|
||||
*/
|
||||
CLEAN,
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 数据源
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum DataSourceType
|
||||
{
|
||||
/**
|
||||
* 主库
|
||||
*/
|
||||
MASTER,
|
||||
|
||||
/**
|
||||
* 从库
|
||||
*/
|
||||
SLAVE
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
import org.apache.http.client.methods.*;
|
||||
|
||||
/**
|
||||
* @description 请求类型
|
||||
* @author 澄泓
|
||||
* @since JDK1.7
|
||||
*/
|
||||
public enum EsignRequestType {
|
||||
|
||||
POST{
|
||||
@Override
|
||||
public HttpRequestBase getHttpType(String url) {
|
||||
return new HttpPost(url);
|
||||
}
|
||||
},
|
||||
GET{
|
||||
@Override
|
||||
public HttpRequestBase getHttpType(String url) {
|
||||
return new HttpGet(url);
|
||||
}
|
||||
},
|
||||
DELETE{
|
||||
@Override
|
||||
public HttpRequestBase getHttpType(String url) {
|
||||
return new HttpDelete(url);
|
||||
}
|
||||
},
|
||||
PUT{
|
||||
@Override
|
||||
public HttpRequestBase getHttpType(String url) {
|
||||
return new HttpPut(url);
|
||||
}
|
||||
},
|
||||
;
|
||||
|
||||
public abstract HttpRequestBase getHttpType(String url);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum HttpMethod {
|
||||
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
|
||||
|
||||
private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
|
||||
|
||||
static {
|
||||
for (HttpMethod httpMethod : values()) {
|
||||
mappings.put(httpMethod.name(), httpMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HttpMethod resolve(@Nullable String method) {
|
||||
return (method != null ? mappings.get(method) : null);
|
||||
}
|
||||
|
||||
public boolean matches(String method) {
|
||||
return (this == resolve(method));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 限流类型
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
|
||||
public enum LimitType
|
||||
{
|
||||
/**
|
||||
* 默认策略全局限流
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
/**
|
||||
* 根据请求者IP进行限流
|
||||
*/
|
||||
IP
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 操作人类别
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum OperatorType
|
||||
{
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* 后台用户
|
||||
*/
|
||||
MANAGE,
|
||||
|
||||
/**
|
||||
* 手机端用户
|
||||
*/
|
||||
MOBILE
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description 修改案件的提交状态
|
||||
* @date 2023-11-17 14:05
|
||||
*/
|
||||
public enum UpdateSubmitStatus
|
||||
{
|
||||
UNCOMMITTED(0, "未提交"),
|
||||
COMMITTED(1, "已提交"),
|
||||
REVOKE(2, "撤销"),
|
||||
AGREE(3, "同意已修改的案件"),
|
||||
REFUSE(4, "拒绝已修改的案件"),
|
||||
|
||||
AGREE_REVOKE(5, "同意撤销修改"),
|
||||
REFUSE_REVOKE(6, "拒绝撤销修改"),
|
||||
;
|
||||
|
||||
private final Integer code;
|
||||
private final String text;
|
||||
|
||||
UpdateSubmitStatus(Integer code, String text)
|
||||
{
|
||||
this.code = code;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Integer getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum UserStatus
|
||||
{
|
||||
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
UserStatus(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 com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description 是否枚举
|
||||
* @date 2023-11-17 14:05
|
||||
*/
|
||||
public enum YesOrNoEnum
|
||||
{
|
||||
NO(0, "否"),
|
||||
YES(1, "是"),
|
||||
|
||||
;
|
||||
|
||||
private final Integer code;
|
||||
private final String text;
|
||||
|
||||
YesOrNoEnum(Integer code, String text)
|
||||
{
|
||||
this.code = code;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Integer getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* 演示模式异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DemoModeException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DemoModeException()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* description 自定义全局异常
|
||||
* @author 澄泓
|
||||
* datetime 2019年7月1日上午10:43:24
|
||||
*/
|
||||
public class EsignDemoException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 4359180081622082792L;
|
||||
private Exception e;
|
||||
|
||||
public EsignDemoException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public EsignDemoException(String msg, Throwable cause) {
|
||||
super(msg,cause);
|
||||
}
|
||||
|
||||
public EsignDemoException(){
|
||||
|
||||
}
|
||||
|
||||
public Exception getE() {
|
||||
return e;
|
||||
}
|
||||
|
||||
public void setE(Exception e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* 全局异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class GlobalException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 错误明细,内部调试错误
|
||||
*
|
||||
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
|
||||
*/
|
||||
private String detailMessage;
|
||||
|
||||
/**
|
||||
* 空构造方法,避免反序列化问题
|
||||
*/
|
||||
public GlobalException()
|
||||
{
|
||||
}
|
||||
|
||||
public GlobalException(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getDetailMessage()
|
||||
{
|
||||
return detailMessage;
|
||||
}
|
||||
|
||||
public GlobalException setDetailMessage(String detailMessage)
|
||||
{
|
||||
this.detailMessage = detailMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public GlobalException setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public final class ServiceException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 错误提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 错误明细,内部调试错误
|
||||
*
|
||||
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
|
||||
*/
|
||||
private String detailMessage;
|
||||
|
||||
/**
|
||||
* 空构造方法,避免反序列化问题
|
||||
*/
|
||||
public ServiceException()
|
||||
{
|
||||
}
|
||||
|
||||
public ServiceException(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ServiceException(String message, Integer code)
|
||||
{
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getDetailMessage()
|
||||
{
|
||||
return detailMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public Integer getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public ServiceException setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServiceException setDetailMessage(String detailMessage)
|
||||
{
|
||||
this.detailMessage = detailMessage;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* 工具类异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UtilException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 8247610319171014183L;
|
||||
|
||||
public UtilException(Throwable e)
|
||||
{
|
||||
super(e.getMessage(), e);
|
||||
}
|
||||
|
||||
public UtilException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UtilException(String message, Throwable throwable)
|
||||
{
|
||||
super(message, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.ruoyi.common.exception.base;
|
||||
|
||||
import com.ruoyi.common.utils.MessageUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 基础异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BaseException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 所属模块
|
||||
*/
|
||||
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 (!StringUtils.isEmpty(code))
|
||||
{
|
||||
message = MessageUtils.message(code, args);
|
||||
}
|
||||
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,19 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import com.ruoyi.common.exception.base.BaseException;
|
||||
|
||||
/**
|
||||
* 文件信息异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileException extends BaseException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FileException(String code, Object[] args)
|
||||
{
|
||||
super("file", code, args, null);
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
/**
|
||||
* 文件名称超长限制异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileNameLengthLimitExceededException extends FileException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FileNameLengthLimitExceededException(int defaultFileNameLength)
|
||||
{
|
||||
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
/**
|
||||
* 文件名大小限制异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileSizeLimitExceededException extends FileException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FileSizeLimitExceededException(long defaultMaxSize)
|
||||
{
|
||||
super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* 文件上传异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileUploadException extends Exception
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Throwable cause;
|
||||
|
||||
public FileUploadException()
|
||||
{
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public FileUploadException(final String msg)
|
||||
{
|
||||
this(msg, null);
|
||||
}
|
||||
|
||||
public FileUploadException(String msg, Throwable cause)
|
||||
{
|
||||
super(msg);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintStream stream)
|
||||
{
|
||||
super.printStackTrace(stream);
|
||||
if (cause != null)
|
||||
{
|
||||
stream.println("Caused by:");
|
||||
cause.printStackTrace(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter writer)
|
||||
{
|
||||
super.printStackTrace(writer);
|
||||
if (cause != null)
|
||||
{
|
||||
writer.println("Caused by:");
|
||||
cause.printStackTrace(writer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause()
|
||||
{
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 文件上传 误异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class InvalidExtensionException extends FileUploadException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String[] allowedExtension;
|
||||
private String extension;
|
||||
private String filename;
|
||||
|
||||
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式");
|
||||
this.allowedExtension = allowedExtension;
|
||||
this.extension = extension;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String[] getAllowedExtension()
|
||||
{
|
||||
return allowedExtension;
|
||||
}
|
||||
|
||||
public String getExtension()
|
||||
{
|
||||
return extension;
|
||||
}
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
public static class InvalidImageExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidFlashExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidMediaExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidVideoExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.ruoyi.common.exception.job;
|
||||
|
||||
/**
|
||||
* 计划策略异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TaskException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Code code;
|
||||
|
||||
public TaskException(String msg, Code code)
|
||||
{
|
||||
this(msg, code, null);
|
||||
}
|
||||
|
||||
public TaskException(String msg, Code code, Exception nestedEx)
|
||||
{
|
||||
super(msg, nestedEx);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Code getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public enum Code
|
||||
{
|
||||
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 黑名单IP异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BlackListException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BlackListException()
|
||||
{
|
||||
super("login.blocked", null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 验证码错误异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CaptchaException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CaptchaException()
|
||||
{
|
||||
super("user.jcaptcha.error", null);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 验证码失效异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CaptchaExpireException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CaptchaExpireException()
|
||||
{
|
||||
super("user.jcaptcha.expire", null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
import com.ruoyi.common.exception.base.BaseException;
|
||||
|
||||
/**
|
||||
* 用户信息异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserException extends BaseException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UserException(String code, Object[] args)
|
||||
{
|
||||
super("user", code, args, null);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 用户不存在异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserNotExistsException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UserNotExistsException()
|
||||
{
|
||||
super("user.not.exists", null);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 用户密码不正确或不符合规范异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserPasswordNotMatchException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UserPasswordNotMatchException()
|
||||
{
|
||||
super("user.password.not.match", null);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.common.exception.user;
|
||||
|
||||
/**
|
||||
* 用户错误最大次数异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserPasswordRetryLimitExceedException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime)
|
||||
{
|
||||
super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
|
||||
|
||||
/**
|
||||
* 排除JSON敏感属性
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class PropertyPreExcludeFilter extends SimplePropertyPreFilter
|
||||
{
|
||||
public PropertyPreExcludeFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public PropertyPreExcludeFilter addExcludes(String... filters)
|
||||
{
|
||||
for (int i = 0; i < filters.length; i++)
|
||||
{
|
||||
this.getExcludes().add(filters[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.http.MediaType;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Repeatable 过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatableFilter implements Filter
|
||||
{
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
ServletRequest requestWrapper = null;
|
||||
if (request instanceof HttpServletRequest
|
||||
&& StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE))
|
||||
{
|
||||
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
||||
}
|
||||
if (null == requestWrapper)
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
chain.doFilter(requestWrapper, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import com.ruoyi.common.utils.http.HttpHelper;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
|
||||
/**
|
||||
* 构建可重复读取inputStream的request
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
|
||||
{
|
||||
private final byte[] body;
|
||||
|
||||
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
|
||||
{
|
||||
super(request);
|
||||
request.setCharacterEncoding(Constants.UTF8);
|
||||
response.setCharacterEncoding(Constants.UTF8);
|
||||
|
||||
body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException
|
||||
{
|
||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException
|
||||
{
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||
return new ServletInputStream()
|
||||
{
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
return bais.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException
|
||||
{
|
||||
return body.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.enums.HttpMethod;
|
||||
|
||||
/**
|
||||
* 防止XSS攻击的过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* 排除链接
|
||||
*/
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
String tempExcludes = filterConfig.getInitParameter("excludes");
|
||||
if (StringUtils.isNotEmpty(tempExcludes))
|
||||
{
|
||||
String[] url = tempExcludes.split(",");
|
||||
for (int i = 0; url != null && i < url.length; i++)
|
||||
{
|
||||
excludes.add(url[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if (handleExcludeURL(req, resp))
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
String url = request.getServletPath();
|
||||
String method = request.getMethod();
|
||||
// GET DELETE 不过滤
|
||||
if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return StringUtils.matches(url, excludes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.html.EscapeUtil;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
||||
{
|
||||
/**
|
||||
* @param request
|
||||
*/
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request)
|
||||
{
|
||||
super(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name)
|
||||
{
|
||||
String[] values = super.getParameterValues(name);
|
||||
if (values != null)
|
||||
{
|
||||
int length = values.length;
|
||||
String[] escapesValues = new String[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// 防xss攻击和过滤前后空格
|
||||
escapesValues[i] = EscapeUtil.clean(values[i]).trim();
|
||||
}
|
||||
return escapesValues;
|
||||
}
|
||||
return super.getParameterValues(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException
|
||||
{
|
||||
// 非json类型,直接返回
|
||||
if (!isJsonRequest())
|
||||
{
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
// 为空,直接返回
|
||||
String json = IOUtils.toString(super.getInputStream(), "utf-8");
|
||||
if (StringUtils.isEmpty(json))
|
||||
{
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
// xss过滤
|
||||
json = EscapeUtil.clean(json).trim();
|
||||
byte[] jsonBytes = json.getBytes("utf-8");
|
||||
final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes);
|
||||
return new ServletInputStream()
|
||||
{
|
||||
@Override
|
||||
public boolean isFinished()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException
|
||||
{
|
||||
return jsonBytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
return bis.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Json请求
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public boolean isJsonRequest()
|
||||
{
|
||||
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* 精确的浮点数运算
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Arith
|
||||
{
|
||||
|
||||
/** 默认除法运算精度 */
|
||||
private static final int DEF_DIV_SCALE = 10;
|
||||
|
||||
/** 这个类不能实例化 */
|
||||
private Arith()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的加法运算。
|
||||
* @param v1 被加数
|
||||
* @param v2 加数
|
||||
* @return 两个参数的和
|
||||
*/
|
||||
public static double add(double v1, double v2)
|
||||
{
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||
return b1.add(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的减法运算。
|
||||
* @param v1 被减数
|
||||
* @param v2 减数
|
||||
* @return 两个参数的差
|
||||
*/
|
||||
public static double sub(double v1, double v2)
|
||||
{
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||
return b1.subtract(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的乘法运算。
|
||||
* @param v1 被乘数
|
||||
* @param v2 乘数
|
||||
* @return 两个参数的积
|
||||
*/
|
||||
public static double mul(double v1, double v2)
|
||||
{
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||
return b1.multiply(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
|
||||
* 小数点以后10位,以后的数字四舍五入。
|
||||
* @param v1 被除数
|
||||
* @param v2 除数
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static double div(double v1, double v2)
|
||||
{
|
||||
return div(v1, v2, DEF_DIV_SCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
|
||||
* 定精度,以后的数字四舍五入。
|
||||
* @param v1 被除数
|
||||
* @param v2 除数
|
||||
* @param scale 表示表示需要精确到小数点以后几位。
|
||||
* @return 两个参数的商
|
||||
*/
|
||||
public static double div(double v1, double v2, int scale)
|
||||
{
|
||||
if (scale < 0)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"The scale must be a positive integer or zero");
|
||||
}
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||
if (b1.compareTo(BigDecimal.ZERO) == 0)
|
||||
{
|
||||
return BigDecimal.ZERO.doubleValue();
|
||||
}
|
||||
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供精确的小数位四舍五入处理。
|
||||
* @param v 需要四舍五入的数字
|
||||
* @param scale 小数点后保留几位
|
||||
* @return 四舍五入后的结果
|
||||
*/
|
||||
public static double round(double v, int scale)
|
||||
{
|
||||
if (scale < 0)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"The scale must be a positive integer or zero");
|
||||
}
|
||||
BigDecimal b = new BigDecimal(Double.toString(v));
|
||||
BigDecimal one = BigDecimal.ONE;
|
||||
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
/**
|
||||
* 时间工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
{
|
||||
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";
|
||||
|
||||
private static String[] parsePatterns = {
|
||||
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
|
||||
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
|
||||
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
|
||||
|
||||
/**
|
||||
* 获取当前Date型日期
|
||||
*
|
||||
* @return Date() 当前日期
|
||||
*/
|
||||
public static Date getNowDate()
|
||||
{
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期, 默认格式为yyyy-MM-dd
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getDate()
|
||||
{
|
||||
return dateTimeNow(YYYY_MM_DD);
|
||||
}
|
||||
|
||||
public static final String getTime()
|
||||
{
|
||||
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
|
||||
}
|
||||
|
||||
public static final String dateTimeNow()
|
||||
{
|
||||
return dateTimeNow(YYYYMMDDHHMMSS);
|
||||
}
|
||||
|
||||
public static final String dateTimeNow(final String format)
|
||||
{
|
||||
return parseDateToStr(format, new Date());
|
||||
}
|
||||
|
||||
public static final String dateTime(final Date date)
|
||||
{
|
||||
return parseDateToStr(YYYY_MM_DD, date);
|
||||
}
|
||||
|
||||
public static final String parseDateToStr(final String format, final Date date)
|
||||
{
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
}
|
||||
|
||||
public static final Date dateTime(final String format, final String ts)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SimpleDateFormat(format).parse(ts);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期路径 即年/月/日 如2018/08/08
|
||||
*/
|
||||
public static final String datePath()
|
||||
{
|
||||
Date now = new Date();
|
||||
return DateFormatUtils.format(now, "yyyy/MM/dd");
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期路径 即年/月/日 如20180808
|
||||
*/
|
||||
public static final String dateTime()
|
||||
{
|
||||
Date now = new Date();
|
||||
return DateFormatUtils.format(now, "yyyyMMdd");
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期型字符串转化为日期 格式
|
||||
*/
|
||||
public static Date parseDate(Object str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return parseDate(str.toString(), parsePatterns);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器启动时间
|
||||
*/
|
||||
public static Date getServerStartDate()
|
||||
{
|
||||
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算相差天数
|
||||
*/
|
||||
public static int differentDaysByMillisecond(Date date1, Date date2)
|
||||
{
|
||||
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算时间差
|
||||
*
|
||||
* @param endDate 最后时间
|
||||
* @param startTime 开始时间
|
||||
* @return 时间差(天/小时/分钟)
|
||||
*/
|
||||
public static String timeDistance(Date endDate, Date startTime)
|
||||
{
|
||||
long nd = 1000 * 24 * 60 * 60;
|
||||
long nh = 1000 * 60 * 60;
|
||||
long nm = 1000 * 60;
|
||||
// long ns = 1000;
|
||||
// 获得两个时间的毫秒时间差异
|
||||
long diff = endDate.getTime() - startTime.getTime();
|
||||
// 计算差多少天
|
||||
long day = diff / nd;
|
||||
// 计算差多少小时
|
||||
long hour = diff % nd / nh;
|
||||
// 计算差多少分钟
|
||||
long min = diff % nd % nh / nm;
|
||||
// 计算差多少秒//输出结果
|
||||
// long sec = diff % nd % nh % nm / ns;
|
||||
return day + "天" + hour + "小时" + min + "分钟";
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDateTime ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDateTime temporalAccessor)
|
||||
{
|
||||
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDate ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDate temporalAccessor)
|
||||
{
|
||||
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
|
||||
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DictUtils
|
||||
{
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
/**
|
||||
* 设置字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @param dictDatas 字典数据列表
|
||||
*/
|
||||
public static void setDictCache(String key, List<SysDictData> dictDatas)
|
||||
{
|
||||
SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @return dictDatas 字典数据列表
|
||||
*/
|
||||
public static List<SysDictData> getDictCache(String key)
|
||||
{
|
||||
JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNotNull(arrayCache))
|
||||
{
|
||||
return arrayCache.toList(SysDictData.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @return 字典标签
|
||||
*/
|
||||
public static String getDictLabel(String dictType, String dictValue)
|
||||
{
|
||||
return getDictLabel(dictType, dictValue, SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValue(String dictType, String dictLabel)
|
||||
{
|
||||
return getDictValue(dictType, dictLabel, SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典值获取字典标签
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
* @param separator 分隔符
|
||||
* @return 字典标签
|
||||
*/
|
||||
public static String getDictLabel(String dictType, String dictValue, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<SysDictData> datas = getDictCache(dictType);
|
||||
|
||||
if (StringUtils.isNotNull(datas))
|
||||
{
|
||||
if (StringUtils.containsAny(separator, dictValue))
|
||||
{
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
for (String value : dictValue.split(separator))
|
||||
{
|
||||
if (value.equals(dict.getDictValue()))
|
||||
{
|
||||
propertyString.append(dict.getDictLabel()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
if (dictValue.equals(dict.getDictValue()))
|
||||
{
|
||||
return dict.getDictLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典标签获取字典值
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictLabel 字典标签
|
||||
* @param separator 分隔符
|
||||
* @return 字典值
|
||||
*/
|
||||
public static String getDictValue(String dictType, String dictLabel, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
List<SysDictData> datas = getDictCache(dictType);
|
||||
|
||||
if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas))
|
||||
{
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
for (String label : dictLabel.split(separator))
|
||||
{
|
||||
if (label.equals(dict.getDictLabel()))
|
||||
{
|
||||
propertyString.append(dict.getDictValue()).append(separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
if (dictLabel.equals(dict.getDictLabel()))
|
||||
{
|
||||
return dict.getDictValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定字典缓存
|
||||
*
|
||||
* @param key 字典键
|
||||
*/
|
||||
public static void removeDictCache(String key)
|
||||
{
|
||||
SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
public static void clearDictCache()
|
||||
{
|
||||
Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*");
|
||||
SpringUtils.getBean(RedisCache.class).deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
public static String getCacheKey(String configKey)
|
||||
{
|
||||
return CacheConstants.SYS_DICT_KEY + configKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
|
||||
|
||||
import com.ruoyi.common.utils.uuid.UUID;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.mail.*;
|
||||
import javax.mail.internet.*;
|
||||
import javax.mail.search.*;
|
||||
import javax.mail.util.ByteArrayDataSource;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Security;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @ClassName EmailInUtil
|
||||
* @Description 邮件发送工具
|
||||
*/
|
||||
@Component
|
||||
@Data
|
||||
@Slf4j
|
||||
public class EmailOutUtil {
|
||||
private static Pattern emailPattern = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
|
||||
// private static Pattern phonePattern = Pattern.compile("0?(13|14|15|18)[0-9]{9}");
|
||||
private static Pattern phonePattern = Pattern.compile("^1\\d{10}$");
|
||||
|
||||
|
||||
// @Autowired
|
||||
// private JavaMailSender mailSender;
|
||||
|
||||
// 发送发邮箱地址(外网地址)
|
||||
// @Value("${spring.mail-out-network.from}")
|
||||
// private static String fromOut;
|
||||
@Value("${spring.mail.host}")
|
||||
private String hostOut;
|
||||
// @Value("${spring.mail.username}")
|
||||
// private String usernameOut;
|
||||
private String usernameOut="wq18792927508@163.com";
|
||||
// @Value("${spring.mail.password}")
|
||||
// private String passwordOut;
|
||||
private String passwordOut= "WDFHKSEMCKVRELEA";
|
||||
@Value("${spring.mail.port}")
|
||||
private Integer portOut;
|
||||
|
||||
public JavaMailSender rebuildMailSender() {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setHost(hostOut);
|
||||
mailSender.setUsername(usernameOut);
|
||||
mailSender.setPassword(passwordOut);
|
||||
mailSender.setPort(portOut);
|
||||
mailSender.setProtocol("smtp");
|
||||
mailSender.setDefaultEncoding("UTF-8");
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送纯文本邮件信息
|
||||
*
|
||||
* @param to 接收方
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容(发送内容)
|
||||
*/
|
||||
public void sendMessage(String to, String subject, String content, String from, JavaMailSender mailSender) {
|
||||
// 创建一个邮件对象
|
||||
SimpleMailMessage msg = new SimpleMailMessage();
|
||||
msg.setFrom(from);
|
||||
msg.setTo(to);
|
||||
// 设置邮件主题
|
||||
msg.setSubject(subject);
|
||||
// 设置邮件内容
|
||||
msg.setText(content);
|
||||
// 发送邮件
|
||||
mailSender.send(msg);
|
||||
////System.out.println("发送成功:" + from + ":to:" + to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param to 收件人
|
||||
* @param message 邮件内容
|
||||
* @param subject 邮件主题
|
||||
* @param fileList 邮件附件
|
||||
*/
|
||||
public Boolean sendEmil(String to, String message, String subject, List<File> fileList, File file) {
|
||||
try {
|
||||
String messageContent = "<html><body><p style=\"font-family: Arial, sans-serif; font-size: 18px;\">"+message+"。</p></body></html>";
|
||||
MimeBodyPart messageBodyPart = new MimeBodyPart();
|
||||
messageBodyPart.setContent(messageContent, "text/html;charset=utf-8");
|
||||
messageBodyPart.setContentID(UUID.randomUUID().toString());
|
||||
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
|
||||
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
|
||||
//设置邮件会话参数
|
||||
Properties props = new Properties();
|
||||
//邮箱的发送服务器地址
|
||||
props.setProperty("mail.smtp.host", "smtp.163.com");
|
||||
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
|
||||
props.setProperty("mail.smtp.socketFactory.fallback", "false");
|
||||
//邮箱发送服务器端口,这里设置为465端口
|
||||
props.setProperty("mail.smtp.port", "465");
|
||||
props.setProperty("mail.smtp.socketFactory.port", "465");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
//获取到邮箱会话,利用匿名内部类的方式,将发送者邮箱用户名和密码授权给jvm
|
||||
Session session = Session.getDefaultInstance(props, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(usernameOut, passwordOut);
|
||||
}
|
||||
});
|
||||
//通过会话,得到一个邮件,用于发送
|
||||
Message msg = new MimeMessage(session);
|
||||
//设置发件人
|
||||
msg.setFrom(new InternetAddress(usernameOut));
|
||||
//设置收件人,to为收件人,cc为抄送,bcc为密送
|
||||
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
|
||||
msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(to, false));
|
||||
msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(to, false));
|
||||
//设置邮件消息
|
||||
msg.setSubject(subject);
|
||||
msg.setText(message);
|
||||
msg.setDescription("messageutf-8html");
|
||||
//设置发送的日期
|
||||
msg.setSentDate(new Date());
|
||||
// 创建邮件正文
|
||||
MimeMultipart multipart = new MimeMultipart();
|
||||
// MimeBodyPart bodyPart = new MimeBodyPart();
|
||||
// bodyPart.setContent("This is the body of the email", "text/html");
|
||||
multipart.addBodyPart(messageBodyPart);
|
||||
// 添加附件
|
||||
if (file != null) {
|
||||
MimeBodyPart attachmentPart = new MimeBodyPart();
|
||||
attachmentPart.attachFile(file);
|
||||
attachmentPart.setFileName(MimeUtility.encodeText(file.getName()));
|
||||
multipart.addBodyPart(attachmentPart);
|
||||
//将multipart对象放入邮件
|
||||
msg.setContent(multipart);
|
||||
} else if (fileList != null && fileList.size() > 0) {
|
||||
// 添加附件(多个)
|
||||
if (fileList != null && fileList.size() > 0) {
|
||||
for (File tempfile : fileList) {
|
||||
MimeBodyPart attachmentPart = new MimeBodyPart();
|
||||
attachmentPart.attachFile(tempfile);
|
||||
attachmentPart.setFileName(MimeUtility.encodeText(tempfile.getName()));
|
||||
multipart.addBodyPart(attachmentPart);
|
||||
}
|
||||
msg.setContent(multipart);
|
||||
}
|
||||
}
|
||||
//调用Transport的send方法去发送邮件
|
||||
Transport.send(msg);
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带附件的邮件信息
|
||||
*
|
||||
* @param to 接收方
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容(发送内容)
|
||||
* @param fileList 文件集合 // 可发送多个附件
|
||||
*/
|
||||
public void sendMessageCarryFiles(String to, String subject, String content, List<File> fileList, String from, @NotNull JavaMailSender mailSender) {
|
||||
MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
try {
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
// 设置邮件主题
|
||||
helper.setSubject(subject);
|
||||
// 设置邮件内容
|
||||
helper.setText(content);
|
||||
// 添加附件(多个)
|
||||
if (fileList != null && fileList.size() > 0) {
|
||||
for (File file : fileList) {
|
||||
helper.addAttachment(file.getName(), file);
|
||||
}
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 发送邮件
|
||||
mailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带附件的邮件信息
|
||||
*
|
||||
* @param to 接收方
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容(发送内容)
|
||||
* @param file 单个文件
|
||||
*/
|
||||
public void sendMessageCarryFile(String to, String subject, String content, File file, String from, JavaMailSender mailSender) {
|
||||
MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
try {
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
// 设置邮件主题
|
||||
helper.setSubject(subject);
|
||||
// 设置邮件内容
|
||||
helper.setText(content);
|
||||
// 单个附件
|
||||
helper.addAttachment(file.getName(), file);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 发送邮件
|
||||
mailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化内外网邮件发送对象
|
||||
*
|
||||
* @param num
|
||||
*/
|
||||
// public static JavaMailSender initJavaMailSender(Integer num) {
|
||||
// if (num != null && num == 1) {
|
||||
// //内网
|
||||
// return rebuildMailSender(hostIn, usernameIn, passwordIn, Integer.parseInt(portIn), "smtps");
|
||||
// } else {
|
||||
// //外网
|
||||
// return rebuildMailSender(hostOut, usernameOut, passwordOut, Integer.parseInt(portOut), "smtps");
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static String getInnerFrom() {
|
||||
// return EmailInUtil;
|
||||
// }
|
||||
//
|
||||
// public static String getOutterFrom() {
|
||||
// return fromOut;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 验证邮箱格式
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEmail(String str) {
|
||||
boolean flag = false;
|
||||
Matcher matcher = emailPattern.matcher(str);
|
||||
if (matcher.matches()) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean isPhoneNumber(String str) {
|
||||
boolean flag = false;
|
||||
Matcher matcher = phonePattern.matcher(str);
|
||||
if (matcher.matches()) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
public void buildReceiveConnect() throws Exception {
|
||||
|
||||
//POP3主机名
|
||||
String host = "pop3.163.com";
|
||||
//设置传输协议
|
||||
String protocol = "pop3";
|
||||
//用户账号
|
||||
String username = "wq18792927508@163.com";
|
||||
//密码或者授权码
|
||||
String password = "WDFHKSEMCKVRELEA";
|
||||
/*
|
||||
* 获取Session
|
||||
*/
|
||||
Properties props = new Properties();
|
||||
//协议
|
||||
props.setProperty("mail.store.protocol", protocol);
|
||||
//POP3主机名
|
||||
props.setProperty("mail.pop3.host", host);
|
||||
props.setProperty("mail.smtp.auth", "true");
|
||||
props.setProperty("mail.pop3.default-encoding", "UTF-8");
|
||||
Session session = Session.getDefaultInstance(props, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(usernameOut, passwordOut);
|
||||
}
|
||||
});
|
||||
URLName urlName = new URLName(protocol, host, 110, null, username, password);
|
||||
Store store = session.getStore(urlName);
|
||||
store.connect(username, password);
|
||||
|
||||
|
||||
Folder folder = store.getFolder("INBOX");
|
||||
|
||||
folder.open(Folder.READ_ONLY);
|
||||
|
||||
}
|
||||
/**
|
||||
* 接收邮件
|
||||
*/
|
||||
public List<String> receiverMail() {
|
||||
List<String> messageIds=new ArrayList<>();
|
||||
|
||||
// session.setDebug(true);
|
||||
|
||||
try {
|
||||
//POP3主机名
|
||||
String host = "pop3.163.com";
|
||||
//设置传输协议
|
||||
String protocol = "pop3";
|
||||
//用户账号
|
||||
String username = "wq18792927508@163.com";
|
||||
//密码或者授权码
|
||||
String password = "WDFHKSEMCKVRELEA";
|
||||
/*
|
||||
* 获取Session
|
||||
*/
|
||||
Properties props = new Properties();
|
||||
//协议
|
||||
props.setProperty("mail.store.protocol", protocol);
|
||||
//POP3主机名
|
||||
props.setProperty("mail.pop3.host", host);
|
||||
props.setProperty("mail.smtp.auth", "true");
|
||||
props.setProperty("mail.pop3.default-encoding", "UTF-8");
|
||||
Session session = Session.getDefaultInstance(props, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(usernameOut, passwordOut);
|
||||
}
|
||||
});
|
||||
URLName urlName = new URLName(protocol, host, 110, null, username, password);
|
||||
Store store = session.getStore(urlName);
|
||||
store.connect(username, password);
|
||||
|
||||
|
||||
Folder folder = store.getFolder("INBOX");
|
||||
folder.open(Folder.READ_ONLY);
|
||||
SearchTerm orTerm = new SubjectTerm("退信");
|
||||
// Message[] messages = folder.search(orTerm);
|
||||
Date endTime= new Date();
|
||||
long oneDayMillis=24*60*60*1000L;
|
||||
Date startTime=new Date(endTime.getTime()-oneDayMillis);
|
||||
// SearchTerm comparisonTermGe = new SentDateTerm(ComparisonTerm.GE, startTime);
|
||||
// SearchTerm comparisonTermLe = new SentDateTerm(ComparisonTerm.LE, endTime);
|
||||
// SearchTerm comparisonAndTerm = new AndTerm(comparisonTermGe, comparisonTermLe);
|
||||
// SearchTerm searchTerm = new AndTerm(comparisonAndTerm, orTerm);
|
||||
Message[] messages = folder.search(orTerm);
|
||||
if (messages != null) {
|
||||
|
||||
Arrays.stream(messages).forEach(message -> {
|
||||
String messageId="";
|
||||
try {
|
||||
messageId = EmailUtil.getMessageId(message,session);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
messageIds.add(messageId);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
folder.close(false);
|
||||
store.close();
|
||||
} catch (Exception e) {
|
||||
return messageIds;
|
||||
}
|
||||
return messageIds;
|
||||
}
|
||||
|
||||
public void analyseMail(Session session, Object content) throws Exception {
|
||||
|
||||
if (content instanceof Multipart) {
|
||||
Multipart multipart = (Multipart) content;
|
||||
for (int i = 0; i < multipart.getCount(); i++) {
|
||||
BodyPart bodyPart = multipart.getBodyPart(i);
|
||||
// if (bodyPart.isMimeType("message/rfc822")) { if(bodyPart.getContentType().startsWith("Message/Rfc822"));
|
||||
// MimeMessage mimeMessage = new MimeMessage(session, bodyPart.getInputStream());
|
||||
// }
|
||||
if(bodyPart.isMimeType("Message/Rfc822")){
|
||||
MimeMessage mimeMessage = new MimeMessage(session, bodyPart.getInputStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static String getMessageId(Part part) throws Exception {
|
||||
if (!part.isMimeType("multipart/*")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Multipart multipart = (Multipart) part.getContent();
|
||||
for (int i = 0; i < multipart.getCount(); i++) {
|
||||
BodyPart bodyPart = multipart.getBodyPart(i);
|
||||
|
||||
if (part.isMimeType("message/rfc822")) {
|
||||
return getMessageId((Part) part.getContent());
|
||||
}
|
||||
InputStream inputStream = bodyPart.getInputStream();
|
||||
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String strLine;
|
||||
while ((strLine = br.readLine()) != null) {
|
||||
if (strLine.startsWith("Message_Id:")) {
|
||||
String[] split = strLine.split("Message_Id:");
|
||||
return split.length > 1 ? split[1].trim() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//检查退信邮件
|
||||
// Folder folder = ...; //打开收件箱
|
||||
// Message[] messages = folder.getMessages();
|
||||
// for (Message message : messages) {
|
||||
// if (message.getSubject().contains("Delivery Status Notification")) {
|
||||
// System.out.println("Delivery failed for recipient: " + message.getRecipients()[0]);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.mail.*;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
@Slf4j
|
||||
public final class EmailUtil {
|
||||
|
||||
private static final String multipart = "multipart/*";
|
||||
|
||||
|
||||
|
||||
public static String getMessageId(Part part, Session session) throws Exception {
|
||||
if (!part.isMimeType(multipart)) {
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
Multipart multipart = (Multipart) part.getContent();
|
||||
for (int i = 0; i < multipart.getCount(); i++) {
|
||||
BodyPart bodyPart = multipart.getBodyPart(i);
|
||||
if(bodyPart.getContentType().contains("Message/Rfc822")){
|
||||
MimeMessage mimeMessage = new MimeMessage(session, bodyPart.getInputStream());
|
||||
if(mimeMessage.getSubject()!=null&&mimeMessage.getSubject().contains("裁决书")){
|
||||
String[] split = mimeMessage.getSubject().split("裁决书");
|
||||
if(split.length>0){
|
||||
return split[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} return "";
|
||||
}
|
||||
|
||||
public static boolean isContainAttachment(Part part) {
|
||||
boolean attachFlag = false;
|
||||
try {
|
||||
if (part.isMimeType(multipart)) {
|
||||
Multipart mp = (Multipart) part.getContent();
|
||||
for (int i = 0; i < mp.getCount(); i++) {
|
||||
BodyPart mpart = mp.getBodyPart(i);
|
||||
String disposition = mpart.getDisposition();
|
||||
if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition.equals(Part.INLINE))))
|
||||
attachFlag = true;
|
||||
else if (mpart.isMimeType(multipart)) {
|
||||
attachFlag = isContainAttachment((Part) mpart);
|
||||
} else {
|
||||
String contype = mpart.getContentType();
|
||||
if (contype.toLowerCase().contains("application"))
|
||||
attachFlag = true;
|
||||
if (contype.toLowerCase().contains("name"))
|
||||
attachFlag = true;
|
||||
}
|
||||
}
|
||||
} else if (part.isMimeType("message/rfc822")) {
|
||||
attachFlag = isContainAttachment((Part) part.getContent());
|
||||
}
|
||||
} catch (MessagingException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return attachFlag;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
public class EsignApplicaConfig {
|
||||
|
||||
// 应用ID
|
||||
public static final String EsignAppId = "7438987614";
|
||||
// 应用密钥
|
||||
public static final String EsignAppSecret = "9d7844f13830931037772b9d20cf1529";
|
||||
// e签宝接口调用域名(模拟环境)
|
||||
public static final String EsignHost = "https://smlopenapi.esign.cn";
|
||||
// e签宝接口调用域名(正式环境)
|
||||
// public static final String EsignHost = "https://openapi.esign.cn";
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
|
||||
import com.ruoyi.common.constant.EsignEncryption;
|
||||
import com.ruoyi.common.constant.EsignHeaderConstant;
|
||||
import com.ruoyi.common.constant.EsignHttpCfgHelper;
|
||||
import com.ruoyi.common.core.domain.entity.EsignCoreSdkInfo;
|
||||
import com.ruoyi.common.core.domain.entity.EsignHttpResponse;
|
||||
import com.ruoyi.common.enums.EsignRequestType;
|
||||
import com.ruoyi.common.exception.EsignDemoException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description Http 请求 辅助类
|
||||
* @author 澄泓
|
||||
* @since JDK1.7
|
||||
*/
|
||||
public class EsignHttpHelper {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EsignHttpHelper.class);
|
||||
|
||||
/**
|
||||
* 不允许外部创建实例
|
||||
*/
|
||||
private EsignHttpHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 发送常规HTTP 请求
|
||||
*
|
||||
* @param reqType 请求方式
|
||||
* @param url 请求路径
|
||||
* @param paramStr 请求参数
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static EsignHttpResponse doCommHttp(String host, String url, EsignRequestType reqType, Object paramStr , Map<String,String> httpHeader, boolean debug) throws EsignDemoException {
|
||||
|
||||
return EsignHttpCfgHelper.sendHttp(reqType, host+url,httpHeader, paramStr, debug);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 发送文件流上传 HTTP 请求
|
||||
*
|
||||
* @param reqType 请求方式
|
||||
* @param uploadUrl 请求路径
|
||||
* @param param 请求参数
|
||||
* @param fileContentMd5 文件fileContentMd5
|
||||
* @param contentType 文件MIME类型
|
||||
* @return
|
||||
* @throws EsignDemoException
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static EsignHttpResponse doUploadHttp( String uploadUrl,EsignRequestType reqType,byte[] param, String fileContentMd5,
|
||||
String contentType, boolean debug) throws EsignDemoException {
|
||||
Map<String, String> uploadHeader = buildUploadHeader(fileContentMd5, contentType);
|
||||
if(debug){
|
||||
LOGGER.info("----------------------------start------------------------");
|
||||
LOGGER.info("fileContentMd5:{}",fileContentMd5);
|
||||
LOGGER.info("contentType:{}",contentType);
|
||||
}
|
||||
return EsignHttpCfgHelper.sendHttp(reqType,uploadUrl, uploadHeader, param,debug);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description 构建一个签名鉴权+json数据的esign请求头
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static Map<String, String> buildSignAndJsonHeader(String projectId,String contentMD5,String accept,String contentType,String authMode) {
|
||||
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("X-Tsign-Open-App-Id", projectId);
|
||||
header.put("X-Tsign-Open-Version-Sdk",EsignCoreSdkInfo.getSdkVersion());
|
||||
header.put("X-Tsign-Open-Ca-Timestamp", EsignEncryption.timeStamp());
|
||||
header.put("Accept",accept);
|
||||
header.put("Content-MD5",contentMD5);
|
||||
header.put("Content-Type", contentType);
|
||||
header.put("X-Tsign-Open-Auth-Mode", authMode);
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名计算并且构建一个签名鉴权+json数据的esign请求头
|
||||
* @param httpMethod
|
||||
* * The name of a supported {@linkplain java.nio.charset.Charset
|
||||
* * charset}
|
||||
* @return
|
||||
*/
|
||||
public static Map<String,String> signAndBuildSignAndJsonHeader(String projectId, String secret,String paramStr,String httpMethod,String url,boolean debug) throws EsignDemoException {
|
||||
String contentMD5="";
|
||||
//统一转大写处理
|
||||
httpMethod = httpMethod.toUpperCase();
|
||||
if("GET".equals(httpMethod)||"DELETE".equals(httpMethod)){
|
||||
paramStr=null;
|
||||
contentMD5="";
|
||||
} else if("PUT".equals(httpMethod)||"POST".equals(httpMethod)){
|
||||
//对body体做md5摘要
|
||||
contentMD5= EsignEncryption.doContentMD5(paramStr);
|
||||
}else{
|
||||
throw new EsignDemoException(String.format("不支持的请求方法%s",httpMethod));
|
||||
}
|
||||
//构造一个初步的请求头
|
||||
Map<String, String> esignHeaderMap = buildSignAndJsonHeader(projectId, contentMD5, EsignHeaderConstant.ACCEPT.VALUE(), EsignHeaderConstant.CONTENTTYPE_JSON.VALUE(), EsignHeaderConstant.AUTHMODE.VALUE());
|
||||
//排序
|
||||
url=EsignEncryption.sortApiUrl(url);
|
||||
//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串
|
||||
String message = EsignEncryption.appendSignDataString(httpMethod, esignHeaderMap.get("Content-MD5"),esignHeaderMap.get("Accept"),esignHeaderMap.get("Content-Type"),esignHeaderMap.get("Headers"),esignHeaderMap.get("Date"), url);
|
||||
//整体做sha256签名
|
||||
String reqSignature = EsignEncryption.doSignatureBase64(message, secret);
|
||||
//请求头添加签名值
|
||||
esignHeaderMap.put("X-Tsign-Open-Ca-Signature",reqSignature);
|
||||
if(debug){
|
||||
LOGGER.info("----------------------------start------------------------");
|
||||
LOGGER.info("待计算body值:{}", paramStr+"\n");
|
||||
LOGGER.info("MD5值:{}",contentMD5+"\n");
|
||||
LOGGER.info("待签名字符串:{}",message+"\n");
|
||||
LOGGER.info("签名值:{}",reqSignature+"\n");
|
||||
}
|
||||
return esignHeaderMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 构建一个Token鉴权+jsons数据的esign请求头
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static Map<String, String> buildTokenAndJsonHeader(String appid,String token) {
|
||||
Map<String, String> esignHeader = new HashMap<>();
|
||||
esignHeader.put("X-Tsign-Open-Version-Sdk", EsignCoreSdkInfo.getSdkVersion());
|
||||
esignHeader.put("Content-Type", EsignHeaderConstant.CONTENTTYPE_JSON.VALUE());
|
||||
esignHeader.put("X-Tsign-Open-App-Id", appid);
|
||||
esignHeader.put("X-Tsign-Open-Token", token);
|
||||
return esignHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 构建一个form表单数据的esign请求头
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static Map<String, String> buildFormDataHeader(String appid) {
|
||||
Map<String, String> esignHeader = new HashMap<>();
|
||||
esignHeader.put("X-Tsign-Open-Version-Sdk",EsignCoreSdkInfo.getSdkVersion());
|
||||
esignHeader.put("X-Tsign-Open-Authorization-Version","v2");
|
||||
esignHeader.put("Content-Type", EsignHeaderConstant.CONTENTTYPE_FORMDATA.VALUE());
|
||||
esignHeader.put("X-Tsign-Open-App-Id", appid);
|
||||
return esignHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建文件流上传 请求头
|
||||
*
|
||||
* @param fileContentMd5
|
||||
* @param contentType
|
||||
* @return
|
||||
* @author 澄泓
|
||||
*/
|
||||
public static Map<String, String> buildUploadHeader(String fileContentMd5, String contentType) {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("Content-MD5", fileContentMd5);
|
||||
header.put("Content-Type", contentType);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
// ------------------------------私有方法end----------------------------------------------
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
/**
|
||||
* 错误信息处理类。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class ExceptionUtil
|
||||
{
|
||||
/**
|
||||
* 获取exception的详细错误信息。
|
||||
*/
|
||||
public static String getExceptionMessage(Throwable e)
|
||||
{
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw, true));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static String getRootErrorMessage(Exception e)
|
||||
{
|
||||
Throwable root = ExceptionUtils.getRootCause(e);
|
||||
root = (root == null ? e : root);
|
||||
if (root == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
String msg = root.getMessage();
|
||||
if (msg == null)
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
return StringUtils.defaultString(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description 根据身份证号提取有效信息
|
||||
* @date 2023-12-11 11:45
|
||||
*/
|
||||
public class IdCardUtils {
|
||||
/**
|
||||
* 通过身份证号码获取出生日期、性别、年龄
|
||||
* @param certificateNo
|
||||
* @return 返回的出生日期格式:1990-01-01 性别格式:1-女,0-男
|
||||
*/
|
||||
public static Map<String, String> getBirAgeSex(String certificateNo) {
|
||||
String birthday = "";
|
||||
String age = "";
|
||||
String sexCode = "";
|
||||
|
||||
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||
char[] number = certificateNo.toCharArray();
|
||||
boolean flag = true;
|
||||
if (number.length == 15) {
|
||||
for (int x = 0; x < number.length; x++) {
|
||||
if (!flag) return new HashMap<String, String>();
|
||||
flag = Character.isDigit(number[x]);
|
||||
}
|
||||
} else if (number.length == 18) {
|
||||
for (int x = 0; x < number.length - 1; x++) {
|
||||
if (!flag) return new HashMap<String, String>();
|
||||
flag = Character.isDigit(number[x]);
|
||||
}
|
||||
}
|
||||
if (flag && certificateNo.length() == 15) {
|
||||
birthday = "19" + certificateNo.substring(6, 8) + "-"
|
||||
+ certificateNo.substring(8, 10) + "-"
|
||||
+ certificateNo.substring(10, 12);
|
||||
sexCode = Integer.parseInt(certificateNo.substring(certificateNo.length() - 3, certificateNo.length())) % 2 == 0 ? "1" : "0";
|
||||
age = (year - Integer.parseInt("19" + certificateNo.substring(6, 8))) + "";
|
||||
} else if (flag && certificateNo.length() == 18) {
|
||||
birthday = certificateNo.substring(6, 10) + "-"
|
||||
+ certificateNo.substring(10, 12) + "-"
|
||||
+ certificateNo.substring(12, 14);
|
||||
sexCode = Integer.parseInt(certificateNo.substring(certificateNo.length() - 4, certificateNo.length() - 1)) % 2 == 0 ? "1" : "0";
|
||||
age = (year - Integer.parseInt(certificateNo.substring(6, 10))) + "";
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("birthday", birthday);
|
||||
map.put("age", age);
|
||||
map.put("sexCode", sexCode);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.ruoyi.common.utils.uuid.UUID;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 雪花算法工具类
|
||||
* zq
|
||||
* @since 2020/10/30 9:59
|
||||
**/
|
||||
public class IdWorkerUtil {
|
||||
private static final long EPOCH = 1479533469598L; //开始时间,固定一个小于当前时间的毫秒数
|
||||
private static final int max12bit = 4095;
|
||||
private static final long max41bit= 1099511627775L;
|
||||
private static String machineId = "" ; // 机器ID
|
||||
|
||||
/**
|
||||
*
|
||||
* 创建ID
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static Long getId(){
|
||||
|
||||
long time = System.currentTimeMillis() - EPOCH + max41bit;
|
||||
// 二进制的 毫秒级时间戳
|
||||
String base = Long.toBinaryString(time);
|
||||
|
||||
// 序列数
|
||||
String randomStr = StringUtils.leftPad(Integer.toBinaryString(new Random().nextInt(max12bit)),12,'0');
|
||||
if(StringUtils.isNotEmpty(machineId)){
|
||||
machineId = StringUtils.leftPad(machineId, 10, '0');
|
||||
}
|
||||
|
||||
//拼接
|
||||
String appendStr = base + machineId + randomStr;
|
||||
// 转化为十进制 返回
|
||||
BigInteger bi = new BigInteger(appendStr, 2);
|
||||
|
||||
return Long.valueOf(bi.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
/**
|
||||
* 处理并记录日志文件
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class LogUtils
|
||||
{
|
||||
public static String getBlock(Object msg)
|
||||
{
|
||||
if (msg == null)
|
||||
{
|
||||
msg = "";
|
||||
}
|
||||
return "[" + msg.toString() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
|
||||
/**
|
||||
* 获取i18n资源文件
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class MessageUtils
|
||||
{
|
||||
/**
|
||||
* 根据消息键和参数 获取消息 委托给spring messageSource
|
||||
*
|
||||
* @param code 消息键
|
||||
* @param args 参数
|
||||
* @return 获取国际化翻译值
|
||||
*/
|
||||
public static String message(String code, Object... args)
|
||||
{
|
||||
MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
|
||||
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description 金额格式化
|
||||
* @date 2023-12-11 11:45
|
||||
*/
|
||||
public class MoneyFormatUtils {
|
||||
|
||||
/**
|
||||
* 增加千分位
|
||||
* @param money
|
||||
* @return
|
||||
*/
|
||||
public static String moneyFormat(String money) {
|
||||
// 金额格式化
|
||||
try {
|
||||
Double.parseDouble(money);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
String regEx = "[^0-9]";
|
||||
Pattern p = Pattern.compile(regEx);
|
||||
Matcher m = p.matcher(money);
|
||||
String result = m.replaceAll("").trim();
|
||||
BigDecimal bigDecimal = null;
|
||||
if (money.contains("百")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("100"));
|
||||
} else if (money.contains("千")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("1000"));
|
||||
} else if (money.contains("万")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("10000"));
|
||||
} else if (money.contains("百万")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("1000000"));
|
||||
} else if (money.contains("千万")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("10000000"));
|
||||
} else if (money.contains("亿")) {
|
||||
bigDecimal = new BigDecimal(result).multiply(new BigDecimal("100000000"));
|
||||
}
|
||||
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
return format.format(bigDecimal);
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* 反射工具类
|
||||
*/
|
||||
public class ObjectFieldUtils {
|
||||
public static String getValue(Object obj,String fieldName){
|
||||
if(obj==null || StrUtil.isEmpty(fieldName)){
|
||||
return "";
|
||||
}
|
||||
Field field=null;
|
||||
try{
|
||||
field=obj.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return String.valueOf(field.get(obj)==null?"":field.get(obj));
|
||||
}catch (Exception e){
|
||||
if(obj.getClass().getSuperclass()!=Object.class){
|
||||
try{
|
||||
field=obj.getClass().getSuperclass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return String.valueOf(field.get(obj)==null?"":field.get(obj));
|
||||
}catch (Exception e1){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setValue(Object obj,String fieldName,Object value){
|
||||
if(obj==null || StrUtil.isEmpty(fieldName)||value==null){
|
||||
return;
|
||||
}
|
||||
Field field=null;
|
||||
try{
|
||||
field=obj.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(obj,value);
|
||||
}catch (Exception e){
|
||||
if(obj.getClass().getSuperclass()!=Object.class){
|
||||
try{
|
||||
field=obj.getClass().getSuperclass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(obj,value);
|
||||
}catch (Exception e1){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.ruoyi.common.core.page.PageDomain;
|
||||
import com.ruoyi.common.core.page.TableSupport;
|
||||
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||
|
||||
/**
|
||||
* 分页工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class PageUtils extends PageHelper
|
||||
{
|
||||
/**
|
||||
* 设置请求分页数据
|
||||
*/
|
||||
public static void startPage()
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = pageDomain.getPageNum();
|
||||
Integer pageSize = pageDomain.getPageSize();
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
Boolean reasonable = pageDomain.getReasonable();
|
||||
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理分页的线程变量
|
||||
*/
|
||||
public static void clearPage()
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.documents4j.api.DocumentType;
|
||||
import com.documents4j.api.IConverter;
|
||||
import com.documents4j.job.LocalConverter;
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.Font;
|
||||
import com.itextpdf.text.PageSize;
|
||||
import com.itextpdf.text.pdf.BaseFont;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
|
||||
import com.itextpdf.tool.xml.XMLWorkerHelper;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.tencentcloudapi.teo.v20220901.models.CC;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static cn.hutool.core.util.ClassLoaderUtil.getClassLoader;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description pdf转换工具类
|
||||
* @date 2023-11-28 15:20
|
||||
*/
|
||||
@Slf4j
|
||||
public class PdfUtils {
|
||||
/**
|
||||
* 将html字符串转为pdf
|
||||
* @param pdfFilePath 保存的路径
|
||||
* @param htmlcontent:必须是完整的html格式,比如<html><body>123</body></html>
|
||||
*/
|
||||
public static boolean htmlStringConvertToPDF(String pdfFilePath, String htmlcontent) {
|
||||
Document document = new Document();
|
||||
PdfWriter writer = null;
|
||||
try {
|
||||
writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
|
||||
// 设置底部距离60,解决重叠问题
|
||||
|
||||
document.setPageSize(PageSize.A4);
|
||||
document.setMargins(50, 45, 50, 60);
|
||||
document.setMarginMirroring(false);
|
||||
document.open();
|
||||
// 解决PDF中文不显示
|
||||
String fontPath = "/D:/simsun.ttf"; //字体文件路径
|
||||
XMLWorkerFontProvider provider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
|
||||
provider.register(fontPath);//注册字体
|
||||
log.error("注册字体");
|
||||
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmlcontent.getBytes("UTF-8")), Charset.forName("UTF-8"), provider);
|
||||
} catch (Exception e) {
|
||||
log.error("htmlStringConvertToPDF error", e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (null != document) {
|
||||
document.close();
|
||||
}
|
||||
if (null != writer) {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 根据html文件生成pdf
|
||||
* @param pdfFilePath pdf文件生成路径
|
||||
* @param htmlFilePath html文件路径
|
||||
*/
|
||||
public static boolean htmlFileConvertToPDF(String pdfFilePath, String htmlFilePath) {
|
||||
Document document = new Document();
|
||||
PdfWriter writer = null;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(pdfFilePath);
|
||||
writer = PdfWriter.getInstance(document, fileOutputStream);
|
||||
// 设置底部距离60,解决重叠问题
|
||||
document.setPageSize(PageSize.A4);
|
||||
document.setMargins(50, 45, 50, 60);
|
||||
document.setMarginMirroring(false);
|
||||
document.open();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
fileInputStream = new FileInputStream(htmlFilePath);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
|
||||
String readStr = "";
|
||||
while ((readStr = br.readLine()) != null) {
|
||||
sb.append(readStr);
|
||||
}
|
||||
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(sb.toString().getBytes("Utf-8")), null, Charset.forName("UTF-8"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (null != document) {
|
||||
document.close();
|
||||
}
|
||||
if (null != writer) {
|
||||
writer.close();
|
||||
}
|
||||
if (null != fileInputStream) {
|
||||
try {
|
||||
fileInputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != fileOutputStream) {
|
||||
try {
|
||||
fileOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* docx转pdf
|
||||
* @param pdfSaveDirectory:文件保存目录,例:D:\\pdf\\
|
||||
* @param fileName:保存的文件名称,例:test.pdf
|
||||
* @param docxFile:需要转换的docx文件
|
||||
* @return
|
||||
*/
|
||||
private static boolean docxConvertToPDF(String pdfSaveDirectory,String fileName,File docxFile) {
|
||||
// 不存在则新建
|
||||
File directory = new File(pdfSaveDirectory);
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs();
|
||||
}
|
||||
String pdfFilePath = pdfSaveDirectory + fileName;
|
||||
File outputFile = new File(pdfFilePath);
|
||||
try {
|
||||
InputStream docxInputStream = Files.newInputStream(docxFile.toPath());
|
||||
OutputStream outputStream = Files.newOutputStream(outputFile.toPath());
|
||||
IConverter converter = LocalConverter.builder().build();
|
||||
converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
|
||||
docxInputStream.close();
|
||||
outputStream.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.apache.poi.hwpf.extractor.WordExtractor;
|
||||
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @description 读取文件内容
|
||||
* @date 2023-12-11 11:45
|
||||
*/
|
||||
public class ReadFileUtils {
|
||||
|
||||
|
||||
public static String readerTxtFile(String filePath){
|
||||
BufferedReader br=null;
|
||||
StringBuilder result=new StringBuilder();
|
||||
try {
|
||||
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(filePath)),"GBK"));
|
||||
String line=null;
|
||||
while ((line=br.readLine())!=null) {
|
||||
result.append(line).append("\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (null!=br){
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
public static String readWord(String filePath) throws Exception{
|
||||
|
||||
File file = new File(filePath);
|
||||
if(file.length()==0) return ""; // 需要操作原因是可能会空文件问题,如果不做处理,在下面读取中会报错
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String buffer = "";
|
||||
try {
|
||||
if (filePath.endsWith(".doc")) {
|
||||
InputStream is = new FileInputStream(file);
|
||||
WordExtractor ex = new WordExtractor(is);
|
||||
buffer = ex.getText();
|
||||
if(buffer.length() > 0){
|
||||
//使用回车换行符分割字符串
|
||||
String [] arry = buffer.split("r\\n");
|
||||
for (String string : arry) {
|
||||
sb.append(string.trim());
|
||||
}
|
||||
}
|
||||
} else if (filePath.endsWith(".docx")) {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
XWPFDocument xdoc = new XWPFDocument(fis);
|
||||
XWPFWordExtractor extractor = new XWPFWordExtractor(xdoc);
|
||||
buffer = extractor.getText();
|
||||
sb.append(buffer!=null?buffer:"");
|
||||
|
||||
|
||||
// OPCPackage opcPackage = POIXMLDocument.openPackage(filePath);
|
||||
// XWPFWordExtractor extractor = new XWPFWordExtractor(opcPackage);
|
||||
// buffer = extractor.getText();
|
||||
// if(buffer.length() > 0){
|
||||
// //使用换行符分割字符串
|
||||
// String [] arry = buffer.split("\n");
|
||||
// for (String string : arry) {
|
||||
// sb.append(string.trim());
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
System.out.print("error---->"+filePath);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.ruoyi.common.config.EsignDemoConfig;
|
||||
import com.ruoyi.common.constant.EsignHeaderConstant;
|
||||
import com.ruoyi.common.core.domain.entity.EsignHttpResponse;
|
||||
import com.ruoyi.common.enums.EsignRequestType;
|
||||
import com.ruoyi.common.exception.EsignDemoException;
|
||||
import com.ruoyi.common.utils.bean.EsignFileBean;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SealUtil {
|
||||
private static String eSignHost = EsignDemoConfig.EsignHost;
|
||||
private static String eSignAppId = EsignDemoConfig.EsignAppId;
|
||||
private static String eSignAppSecret = EsignDemoConfig.EsignAppSecret;
|
||||
|
||||
/**
|
||||
* 获取机构认证&授权页面链接
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static EsignHttpResponse getOrgEmpower() throws EsignDemoException {
|
||||
String apiaddr = "/v3/org-auth-url";
|
||||
String nickName = "何进波";
|
||||
String phonenumber = "15191509780";
|
||||
String deptName = "西安云美公司";
|
||||
String jsonParm = "{\n" +
|
||||
" \"orgAuthConfig\": {\n" +
|
||||
" \"orgName\": \"" + deptName + " \",\n" +
|
||||
" \"transactorInfo\": {\n" +
|
||||
" \"psnAccount\": \"" + phonenumber + "\",\n" +
|
||||
" \"psnInfo\": {\n" +
|
||||
" \"psnName\": \"" + nickName + "\",\n" +
|
||||
" \"psnMobile\": \"" + phonenumber + "\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"authorizeConfig\": {\n" +
|
||||
" \"authorizedScopes\": [\n" +
|
||||
" \"get_org_identity_info\",\n" +
|
||||
" \"get_psn_identity_info\",\n" +
|
||||
" \"org_initiate_sign\",\n" +
|
||||
" \"psn_initiate_sign\",\n" +
|
||||
" \"manage_org_resource\",\n" +
|
||||
" \"manage_psn_resource\",\n" +
|
||||
" \"use_org_order\"\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
//请求方法
|
||||
EsignRequestType requestType = EsignRequestType.POST;
|
||||
//生成请求签名鉴权方式的Header
|
||||
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(eSignAppId, eSignAppSecret, jsonParm, requestType.name(), apiaddr, true);
|
||||
//发起接口请求
|
||||
return EsignHttpHelper.doCommHttp(eSignHost, apiaddr, requestType, jsonParm, header, true);
|
||||
|
||||
}
|
||||
/**
|
||||
* 查询认证授权流程详情
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static EsignHttpResponse queryAuthProcess(String authFlowId ) throws EsignDemoException {
|
||||
String apiaddr = "/v3/auth-flow/" + authFlowId;
|
||||
//请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
|
||||
String jsonParm=null;
|
||||
//请求方法
|
||||
EsignRequestType requestType= EsignRequestType.GET;
|
||||
//生成签名鉴权方式的的header
|
||||
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(eSignAppId,eSignAppSecret,jsonParm,requestType.name(),apiaddr,true);
|
||||
//发起接口请求
|
||||
return EsignHttpHelper.doCommHttp(eSignHost, apiaddr,requestType , jsonParm, header,true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 步骤一:获取印章图片上传地址fileUploadUrl
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static EsignHttpResponse getFileUploadUrl(String filePath) throws EsignDemoException {
|
||||
//自定义的文件封装类,传入文件地址可以获取文件的名称大小,文件流等数据
|
||||
EsignFileBean esignFileBean = new EsignFileBean(filePath);
|
||||
String apiaddr="/v3/files/file-key";
|
||||
//请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
|
||||
String jsonParm="{\n" +
|
||||
" \"contentMd5\": \""+esignFileBean.getFileContentMD5()+"\",\n" +
|
||||
" \"fileName\":\""+esignFileBean.getFileName()+"\"," +
|
||||
" \"fileSize\": "+esignFileBean.getFileSize()+",\n" +
|
||||
" \"contentType\": \""+ EsignHeaderConstant.CONTENTTYPE_STREAM.VALUE()+"\"\n" +
|
||||
"}";
|
||||
//请求方法
|
||||
EsignRequestType requestType= EsignRequestType.POST;
|
||||
//生成签名鉴权方式的的header
|
||||
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(eSignAppId,eSignAppSecret,jsonParm,requestType.name(),apiaddr,true);
|
||||
//发起接口请求
|
||||
return EsignHttpHelper.doCommHttp(eSignHost, apiaddr, requestType, jsonParm, header, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 步骤二:将印章图片文件流上传到fileUploadUrl
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static EsignHttpResponse fileStreamUpload(String uploadUrl,String filePath) throws EsignDemoException {
|
||||
//根据文件地址获取文件contentMd5
|
||||
EsignFileBean esignFileBean = new EsignFileBean(filePath);
|
||||
//请求方法
|
||||
EsignRequestType requestType= EsignRequestType.PUT;
|
||||
return EsignHttpHelper.doUploadHttp(uploadUrl,requestType,esignFileBean.getFileBytes(),esignFileBean.getFileContentMD5(), EsignHeaderConstant.CONTENTTYPE_STREAM.VALUE(),true);
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
queryAuthProcess("OF-2b1e52987408005c");
|
||||
// createOrgByImage();
|
||||
// getOrgEmpower();
|
||||
// queryAuthProcess("OF-2b00885895080028");
|
||||
// getFileUploadUrl();
|
||||
// String uplodUrl = "https://esignoss.esign.cn/7438987614/8e278262-5960-4004-bff3-297c11e2652e/Snipaste_2023-10-27_09-59-23.jpg?Expires=1699439095&OSSAccessKeyId=STS.NTZ8NBHcTVQXgsxVRH4iyC5AY&Signature=3yu3ZQifphZsnOgN0CI0SJdqFhY%3D&callback-var=eyJ4OmZpbGVfa2V5IjoiJDliM2Y3ZjkyLTdkOWUtNGZkZi04NWU4LWE4ZDU4MzEwZjIzOCQ0MTQwNTE2ODk5In0%3D%0A&callback=eyJjYWxsYmFja1VybCI6Imh0dHA6Ly9zbWx0YXBpLnRzaWduLmNuL2FueWRvb3IvZmlsZS1zeXN0ZW0vY2FsbGJhY2svYWxpb3NzIiwiY2FsbGJhY2tCb2R5IjogIntcIm1pbWVUeXBlXCI6JHttaW1lVHlwZX0sXCJzaXplXCI6ICR7c2l6ZX0sXCJidWNrZXRcIjogJHtidWNrZXR9LFwib2JqZWN0XCI6ICR7b2JqZWN0fSxcImV0YWdcIjogJHtldGFnfSxcImZpbGVfa2V5XCI6JHt4OmZpbGVfa2V5fX0iLCJjYWxsYmFja0JvZHlUeXBlIjogImFwcGxpY2F0aW9uL2pzb24ifQ%3D%3D%0A&security-token=CAIS%2BAF1q6Ft5B2yfSjIr5fvc%2FT2pbx14ZOzZVXJslIdOOZVrPDquzz2IHtKdXRvBu8Xs%2F4wnmxX7f4YlqB6T55OSAmcNZEoWWWTbdH4MeT7oMWQweEurv%2FMQBqyaXPS2MvVfJ%2BOLrf0ceusbFbpjzJ6xaCAGxypQ12iN%2B%2Fm6%2FNgdc9FHHPPD1x8CcxROxFppeIDKHLVLozNCBPxhXfKB0ca0WgVy0EHsPnvm5DNs0uH1AKjkbRM9r6ceMb0M5NeW75kSMqw0eBMca7M7TVd8RAi9t0t1%2FIVpGiY4YDAWQYLv0rda7DOltFiMkpla7MmXqlft%2BhzcgeQY0pc%2FRqAAXGx8FDtPQxW3RSasFgOFBJaxbYjH3WFFrbV25v8a%2BS9OWPAYqOCvmkxbM7N4hOge2iaBAG4SRLMb6ypPJ15YEpoZI8KkdeDvQJryZEWchmc0Lhz0yDRqrN%2BzYhgu4VpBJu1WJg%2FyXrvAZ0gWhBN%2BILrblSR9QHVWVVYZTAKN4ejIAA%3D";
|
||||
// fileStreamUpload(uplodUrl,"D:\\develop\\Snipaste_2023-10-27_09-59-23.jpg");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
|
||||
/**
|
||||
* 安全服务工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SecurityUtils
|
||||
{
|
||||
/**
|
||||
* 用户ID
|
||||
**/
|
||||
public static Long getUserId()
|
||||
{
|
||||
try
|
||||
{
|
||||
return getLoginUser().getUserId();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门ID
|
||||
**/
|
||||
public static Long getDeptId()
|
||||
{
|
||||
try
|
||||
{
|
||||
return getLoginUser().getDeptId();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户账户
|
||||
**/
|
||||
public static String getUsername()
|
||||
{
|
||||
try
|
||||
{
|
||||
return getLoginUser().getUsername();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
**/
|
||||
public static LoginUser getLoginUser()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (LoginUser) getAuthentication().getPrincipal();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Authentication
|
||||
*/
|
||||
public static Authentication getAuthentication()
|
||||
{
|
||||
return SecurityContextHolder.getContext().getAuthentication();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成BCryptPasswordEncoder密码
|
||||
*
|
||||
* @param password 密码
|
||||
* @return 加密字符串
|
||||
*/
|
||||
public static String encryptPassword(String password)
|
||||
{
|
||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
return passwordEncoder.encode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断密码是否相同
|
||||
*
|
||||
* @param rawPassword 真实密码
|
||||
* @param encodedPassword 加密后字符
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean matchesPassword(String rawPassword, String encodedPassword)
|
||||
{
|
||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
return passwordEncoder.matches(rawPassword, encodedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为管理员
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isAdmin(Long userId)
|
||||
{
|
||||
return userId != null && 1L == userId;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user