提交
This commit is contained in:
261
ruoyi-base-support/ruoyi-common/pom.xml
Normal file
261
ruoyi-base-support/ruoyi-common/pom.xml
Normal file
@@ -0,0 +1,261 @@
|
||||
<?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-base-support</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
|
||||
<description>
|
||||
common通用工具
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- mybatis-plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-extension</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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>
|
||||
|
||||
<!-- 阿里JSON解析器 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 文件上传工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</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>
|
||||
|
||||
<!-- 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>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.3.7</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>
|
||||
<!-- word转图工具 -->
|
||||
<dependency>
|
||||
<groupId>com.deepoove</groupId>
|
||||
<artifactId>poi-tl</artifactId>
|
||||
<version>1.8.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-local</artifactId>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodconverter</groupId>
|
||||
<artifactId>jodconverter-spring-boot-starter</artifactId>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.libreoffice</groupId>
|
||||
<artifactId>juh</artifactId>
|
||||
<version>5.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.libreoffice</groupId>
|
||||
<artifactId>jurt</artifactId>
|
||||
<version>5.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.libreoffice</groupId>
|
||||
<artifactId>ridl</artifactId>
|
||||
<version>5.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.libreoffice</groupId>
|
||||
<artifactId>unoil</artifactId>
|
||||
<version>5.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.1065</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aspose</groupId>
|
||||
<artifactId>aspose-words</artifactId>
|
||||
<version>15.8.0-jdk16</version>
|
||||
</dependency>
|
||||
|
||||
<!--goeasy——sdk-->
|
||||
<dependency>
|
||||
<groupId>io.goeasy</groupId>
|
||||
<artifactId>goeasy-sdk</artifactId>
|
||||
<version>0.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<artifactId>cos-sts_api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,17 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 自动设置创建人
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface CreateBy {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 自动设置创建时间
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface CreateTime {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 数据权限过滤注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DataScope
|
||||
{
|
||||
/**
|
||||
* 部门表的别名
|
||||
*/
|
||||
public String deptAlias() default "";
|
||||
|
||||
/**
|
||||
* 用户表的别名
|
||||
*/
|
||||
public String userAlias() default "";
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import com.ruoyi.common.enums.DataSourceType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义多数据源切换注解
|
||||
*
|
||||
* 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface DataSource
|
||||
{
|
||||
/**
|
||||
* 切换数据源名称
|
||||
*/
|
||||
public DataSourceType value() default DataSourceType.MASTER;
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import com.ruoyi.common.utils.poi.ExcelHandlerAdapter;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 自定义导出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;
|
||||
|
||||
/**
|
||||
* 导出类型(0数字 1字符串)
|
||||
*/
|
||||
public ColumnType cellType() default ColumnType.STRING;
|
||||
|
||||
/**
|
||||
* 导出时在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 {};
|
||||
|
||||
/**
|
||||
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
|
||||
*/
|
||||
public boolean isExport() default true;
|
||||
|
||||
/**
|
||||
* 另一个类中的属性名称,支持多级获取,以小数点隔开
|
||||
*/
|
||||
public String targetAttr() default "";
|
||||
|
||||
/**
|
||||
* 是否自动统计数据,在最后追加一行统计数据总和
|
||||
*/
|
||||
public boolean isStatistics() default false;
|
||||
|
||||
/**
|
||||
* 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
|
||||
*/
|
||||
public Align align() default Align.AUTO;
|
||||
|
||||
/**
|
||||
* 自定义数据处理器
|
||||
*/
|
||||
public Class<?> handler() default ExcelHandlerAdapter.class;
|
||||
|
||||
/**
|
||||
* 自定义数据处理器参数
|
||||
*/
|
||||
public String[] args() default {};
|
||||
|
||||
public enum Align
|
||||
{
|
||||
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
|
||||
private final int value;
|
||||
|
||||
Align(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段类型(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,43 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.enums.OperatorType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义操作日志记录注解
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.enums.LimitType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 限流注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RateLimiter
|
||||
{
|
||||
/**
|
||||
* 限流key
|
||||
*/
|
||||
public String key() default Constants.RATE_LIMIT_KEY;
|
||||
|
||||
/**
|
||||
* 限流时间,单位秒
|
||||
*/
|
||||
public int time() default 60;
|
||||
|
||||
/**
|
||||
* 限流次数
|
||||
*/
|
||||
public int count() default 100;
|
||||
|
||||
/**
|
||||
* 限流类型
|
||||
*/
|
||||
public LimitType limitType() default LimitType.DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义注解防止表单重复提交
|
||||
*
|
||||
* @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,16 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 自动设置修改人
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface UpdateBy {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 自动设置修改时间
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface UpdateTime {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
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;
|
||||
|
||||
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 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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
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";
|
||||
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
public static final String HTTP = "http://";
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 验证码 redis key
|
||||
*/
|
||||
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||
|
||||
/**
|
||||
* 登录用户 redis key
|
||||
*/
|
||||
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||
|
||||
/**
|
||||
* 防重提交 redis key
|
||||
*/
|
||||
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
||||
|
||||
/**
|
||||
* 限流 redis key
|
||||
*/
|
||||
public static final String RATE_LIMIT_KEY = "rate_limit:";
|
||||
|
||||
/**
|
||||
* 验证码有效期(分钟)
|
||||
*/
|
||||
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";
|
||||
|
||||
/**
|
||||
* 参数管理 cache key
|
||||
*/
|
||||
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||
|
||||
/**
|
||||
* 字典管理 cache key
|
||||
*/
|
||||
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "/profile";
|
||||
|
||||
/**
|
||||
* RMI 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_RMI = "rmi://";
|
||||
|
||||
/**
|
||||
* LDAP 远程方法调用
|
||||
*/
|
||||
public static final String LOOKUP_LDAP = "ldap://";
|
||||
}
|
||||
@@ -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[] COLUMNTYPE_INT = { "tinyint", "smallint", "mediumint", "int", "number", "integer"};
|
||||
|
||||
/** 页面不需要编辑字段 */
|
||||
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 REQUIRE = "1";
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
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;
|
||||
}
|
||||
@@ -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 String UNIQUE = "0";
|
||||
public final static String NOT_UNIQUE = "1";
|
||||
|
||||
/**
|
||||
* 用户名长度限制
|
||||
*/
|
||||
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,209 @@
|
||||
package com.ruoyi.common.core.controller;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
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.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.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()
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = pageDomain.getPageNum();
|
||||
Integer pageSize = pageDomain.getPageSize();
|
||||
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
|
||||
{
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
Boolean reasonable = pageDomain.getReasonable();
|
||||
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求排序数据
|
||||
*/
|
||||
protected void startOrderBy()
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
|
||||
{
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
PageHelper.orderBy(orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应请求分页数据
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected TableDataInfo getDataTable(List<?> list)
|
||||
{
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(HttpStatus.SUCCESS);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setRows(list);
|
||||
Long total = new PageInfo(list).getTotal();
|
||||
rspData.setTotal(total.intValue());
|
||||
return rspData;
|
||||
}
|
||||
protected TableDataInfo getDataTable(Page<?> page)
|
||||
{
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(HttpStatus.SUCCESS);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setRows(page.getRecords());
|
||||
Long total = new PageInfo(page.getRecords()).getTotal();
|
||||
rspData.setTotal(total.intValue());
|
||||
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 error(String message)
|
||||
{
|
||||
return AjaxResult.error(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 String getDeptId()
|
||||
{
|
||||
return getLoginUser().getDeptId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户名
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return getLoginUser().getUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户名
|
||||
*/
|
||||
public Page getPage() {
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = pageDomain.getPageNum();
|
||||
Integer pageSize = pageDomain.getPageSize();
|
||||
return new Page(pageNum, pageSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class AjaxResult<T>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 响应状态码
|
||||
*/
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 响应对象
|
||||
*/
|
||||
private T data;
|
||||
|
||||
private Date currentTime = new Date();
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
|
||||
*/
|
||||
public AjaxResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
*/
|
||||
public AjaxResult(int code, String msg)
|
||||
{
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.currentTime = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
*/
|
||||
public AjaxResult(int code, String msg, T data)
|
||||
{
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = data;
|
||||
this.currentTime = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AjaxResultMap<T> 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 AjaxResultMap()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
*/
|
||||
public AjaxResultMap(int code, String msg)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
*/
|
||||
public AjaxResultMap(int code, String msg, T data)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
if (StringUtils.isNotNull(data))
|
||||
{
|
||||
super.put(DATA_TAG, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResultMap success()
|
||||
{
|
||||
return AjaxResultMap.success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功数据
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResultMap success(Object data)
|
||||
{
|
||||
return AjaxResultMap.success("操作成功", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResultMap success(String msg)
|
||||
{
|
||||
return AjaxResultMap.success(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResultMap success(String msg, Object data)
|
||||
{
|
||||
return new AjaxResultMap(HttpStatus.SUCCESS, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static AjaxResultMap error()
|
||||
{
|
||||
return AjaxResultMap.error("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResultMap error(String msg)
|
||||
{
|
||||
return AjaxResultMap.error(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResultMap error(String msg, Object data)
|
||||
{
|
||||
return new AjaxResultMap(HttpStatus.ERROR, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResultMap error(int code, String msg)
|
||||
{
|
||||
return new AjaxResultMap(code, msg, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.annotation.CreateBy;
|
||||
import com.ruoyi.common.annotation.CreateTime;
|
||||
import com.ruoyi.common.annotation.UpdateBy;
|
||||
import com.ruoyi.common.annotation.UpdateTime;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class BaseEntity implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 搜索值 */
|
||||
@TableField(exist = false)
|
||||
private String searchValue;
|
||||
|
||||
/** 创建者 */
|
||||
@CreateBy
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@CreateTime
|
||||
private Date createTime;
|
||||
|
||||
/** 更新者 */
|
||||
@UpdateBy
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@UpdateTime
|
||||
private Date updateTime;
|
||||
|
||||
/** 备注 */
|
||||
@TableField(exist = false)
|
||||
private String remark;
|
||||
|
||||
/** 请求参数 */
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> params;
|
||||
|
||||
|
||||
|
||||
public Map<String, Object> getParams()
|
||||
{
|
||||
if (params == null)
|
||||
{
|
||||
params = new HashMap<>();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setCreateData()
|
||||
{
|
||||
this.createBy = SecurityUtils.getUserId().toString();
|
||||
this.createTime = new Date();
|
||||
}
|
||||
public void setUpdateData()
|
||||
{
|
||||
this.updateBy = SecurityUtils.getUserId().toString();
|
||||
this.updateTime = new Date();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tree基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public abstract class TreeEntity extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/** 父部门ID */
|
||||
protected String parentId = "0";
|
||||
|
||||
/** 祖级列表 */
|
||||
protected String ancestors = "0,";
|
||||
|
||||
public abstract String getId();
|
||||
|
||||
public String makeSelfAsNewParentIds() {
|
||||
if (StringUtils.isEmpty(getAncestors())) {
|
||||
return getId() + ",";
|
||||
}
|
||||
return getAncestors() + getId() + ",";
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Treeselect树结构实体类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class TreeSelect implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 节点ID */
|
||||
private String 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().toString();
|
||||
this.label = menu.getMenuName();
|
||||
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String 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,55 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* All rights Reserved, Designed By www.sunseagear.com
|
||||
*
|
||||
* @version V1.0
|
||||
* @package sys
|
||||
* @title: 数据权限表控制器
|
||||
* @description: 数据权限表控制器
|
||||
* @author: 未知
|
||||
* @date: 2019-11-29 06:05:01
|
||||
* @copyright: www.sunseagear.com Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("sys_data_rule")
|
||||
@SuppressWarnings("serial")
|
||||
public class SysDataRule extends BaseEntity {
|
||||
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private String id; //id
|
||||
@TableField(value = "resource_code")
|
||||
private String resourceCode; //资源编号
|
||||
@TableField(value = "scope_name")
|
||||
private String scopeName; //数据权限名称
|
||||
@TableField(value = "scope_field")
|
||||
private String scopeField; //数据权限字段
|
||||
@TableField(value = "scope_class")
|
||||
private String scopeClass; //数据权限类名
|
||||
@TableField(value = "scope_column")
|
||||
private String scopeColumn; //数据权限字段
|
||||
@TableField(value = "table_name")
|
||||
private String tableName; //数据权限关联表名
|
||||
@TableField(value = "scope_type")
|
||||
private String scopeType; //数据权限类型
|
||||
@TableField(value = "scope_value")
|
||||
private String scopeValue; //数据权限值域
|
||||
@TableField(value = "user_column")
|
||||
private String userColumn; //用户表对应字段
|
||||
@TableField(value = "user_entity_field")
|
||||
private String userEntityField; //用户实体类对应字段
|
||||
|
||||
@TableField(exist = false)
|
||||
private boolean select; //是否选择
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import com.ruoyi.common.core.domain.TreeEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门表 sys_dept
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SysDept extends TreeEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 部门ID */
|
||||
private String deptId;
|
||||
|
||||
/** 部门名称 */
|
||||
private String deptName;
|
||||
|
||||
/** 显示顺序 */
|
||||
private String orderNum;
|
||||
|
||||
/** 负责人 */
|
||||
private String leader;
|
||||
|
||||
/** 联系电话 */
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
private String email;
|
||||
|
||||
/** 部门状态:0正常,1停用 */
|
||||
private String status;
|
||||
|
||||
/** 删除标志(0代表存在 2代表删除) */
|
||||
private String delFlag;
|
||||
|
||||
/** 父部门名称 */
|
||||
private String parentName;
|
||||
|
||||
/** 租户ID */
|
||||
private String tenantId;
|
||||
|
||||
/** 子部门 */
|
||||
private List<SysDept> children = new ArrayList<SysDept>();
|
||||
|
||||
@NotBlank(message = "部门名称不能为空")
|
||||
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
|
||||
public String getDeptName()
|
||||
{
|
||||
return deptName;
|
||||
}
|
||||
|
||||
|
||||
@NotBlank(message = "显示顺序不能为空")
|
||||
public String getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
|
||||
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
|
||||
public String getPhone()
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return getDeptId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典数据表 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;
|
||||
|
||||
/**字典编码唯一*/
|
||||
private String code;
|
||||
|
||||
/**图片*/
|
||||
private String images;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getImages() {
|
||||
return images;
|
||||
}
|
||||
|
||||
public void setImages(String images) {
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
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 = 1000, message = "字典标签长度不能超过1000个字符")
|
||||
public String getDictLabel()
|
||||
{
|
||||
return dictLabel;
|
||||
}
|
||||
|
||||
public void setDictLabel(String dictLabel)
|
||||
{
|
||||
this.dictLabel = dictLabel;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典键值不能为空")
|
||||
@Size(min = 0, max = 1000, message = "字典键值长度不能超过1000个字符")
|
||||
public String getDictValue()
|
||||
{
|
||||
return dictValue;
|
||||
}
|
||||
|
||||
public void setDictValue(String dictValue)
|
||||
{
|
||||
this.dictValue = dictValue;
|
||||
}
|
||||
|
||||
@NotBlank(message = "字典类型不能为空")
|
||||
@Size(min = 0, max = 1000, message = "字典类型长度不能超过1000个字符")
|
||||
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) ? true : false;
|
||||
}
|
||||
|
||||
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,94 @@
|
||||
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.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个字符")
|
||||
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,267 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单权限表 sys_menu
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
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 String 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 String tenantId;
|
||||
|
||||
/** 子菜单 */
|
||||
private List<SysMenu> children = new ArrayList<SysMenu>();
|
||||
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
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;
|
||||
}
|
||||
|
||||
@NotBlank(message = "显示顺序不能为空")
|
||||
public String getOrderNum()
|
||||
{
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public void setOrderNum(String 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,235 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 角色表 sys_role
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
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 String 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 String tenantId;
|
||||
|
||||
/** 菜单组 */
|
||||
private Long[] menuIds;
|
||||
|
||||
/** 部门组(数据权限) */
|
||||
private Long[] deptIds;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@NotBlank(message = "显示顺序不能为空")
|
||||
public String getRoleSort()
|
||||
{
|
||||
return roleSort;
|
||||
}
|
||||
|
||||
public void setRoleSort(String 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;
|
||||
}
|
||||
|
||||
@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,44 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* All rights Reserved, Designed By www.sunseagear.com
|
||||
*
|
||||
* @version V1.0
|
||||
* @package sys
|
||||
* @title: 租户管理控制器
|
||||
* @description: 租户管理控制器
|
||||
* @author: 未知
|
||||
* @date: 2019-11-28 06:24:52
|
||||
* @copyright: www.sunseagear.com Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("sys_tenant")
|
||||
public class SysTenant extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id; //id
|
||||
@TableField(value = "contact")
|
||||
private String contact; //联系人
|
||||
@TableField(value = "phone")
|
||||
private String phone; //电话
|
||||
@TableField(value = "name")
|
||||
private String name; //租户名称
|
||||
@TableField(value = "tenant_id")
|
||||
private String tenantId;
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
@TableField(exist = false)
|
||||
private String userName;
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.ruoyi.common.core.domain.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 用户对象 sys_user
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SysUser extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
||||
private Long userId;
|
||||
|
||||
private String userType;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
@Excel(name = "部门编号", type = Type.IMPORT)
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@Excel(name = "登录名称")
|
||||
@NotBlank(message = "用户账号不能为空")
|
||||
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@Excel(name = "用户名称")
|
||||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户邮箱
|
||||
*/
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 盐加密
|
||||
*/
|
||||
private String salt;
|
||||
|
||||
/**
|
||||
* 帐号状态(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;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
|
||||
public SysUser() {
|
||||
|
||||
}
|
||||
|
||||
public SysUser(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
|
||||
public boolean isAdmin() {
|
||||
return isAdmin(this.userId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Long userId) {
|
||||
return userId != null && 1L == userId;
|
||||
}
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
|
||||
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
|
||||
public String getPhonenumber() {
|
||||
return phonenumber;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@JsonProperty
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("userId", getUserId())
|
||||
.append("deptId", getDeptId())
|
||||
.append("userName", getUserName())
|
||||
.append("nickName", getNickName())
|
||||
.append("email", getEmail())
|
||||
.append("phonenumber", getPhonenumber())
|
||||
.append("sex", getSex())
|
||||
.append("avatar", getAvatar())
|
||||
.append("password", getPassword())
|
||||
.append("salt", getSalt())
|
||||
.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,82 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
/**
|
||||
* 用户登录对象
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class LoginBody
|
||||
{
|
||||
/**
|
||||
* 登入端口
|
||||
*/
|
||||
private String loginType = "00";
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
public String getLoginType() {
|
||||
return loginType;
|
||||
}
|
||||
|
||||
public void setLoginType(String loginType) {
|
||||
this.loginType = loginType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.ruoyi.common.core.domain.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 登录用户身份权限
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class LoginUser implements UserDetails {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private String 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;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
private SysUser user;
|
||||
|
||||
public LoginUser() {
|
||||
}
|
||||
|
||||
public LoginUser(SysUser user, Set<String> permissions) {
|
||||
this.user = user;
|
||||
this.permissions = permissions;
|
||||
this.userId = user.getUserId();
|
||||
this.deptId = user.getDeptId();
|
||||
this.tenantId = user.getTenantId();
|
||||
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getUserName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 账户是否未过期,过期无法验证
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定用户是否解锁,锁定的用户无法进行身份验证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可用 ,禁用的用户不能身份验证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@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,47 @@
|
||||
package com.ruoyi.common.core.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public interface BaseTreeMapper<T> extends BaseMapper<T> {
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
* @title: selectByPrimaryKey
|
||||
* @description: 查找主键
|
||||
* @return: Menu
|
||||
*/
|
||||
T selectByTreeId(Serializable id);
|
||||
|
||||
/**
|
||||
* @param wrapper
|
||||
* @return
|
||||
* @title: selectTreeList
|
||||
* @description: 查找列表
|
||||
* @return: List<T>
|
||||
*/
|
||||
List<T> selectTreeList(@Param("ew") Wrapper<T> wrapper);
|
||||
|
||||
/**
|
||||
* @param newParentIds
|
||||
* @param oldParentIds
|
||||
* @title: updateSunTreeParentId
|
||||
* @description: 更新ParentIds
|
||||
* @return: void
|
||||
*/
|
||||
void updateSunTreeParentIds(@Param("newParentIds") String newParentIds, @Param("oldParentIds") String oldParentIds);
|
||||
|
||||
/**
|
||||
* @param parentIds
|
||||
* @return
|
||||
* @title: selectTreeList
|
||||
* @description: 查找列表
|
||||
* @return: List<T>
|
||||
*/
|
||||
void deleteSunTree(String parentIds);
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
// if (pageNum == null) {
|
||||
// this.pageNum = 10;
|
||||
// return;
|
||||
// }
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
|
||||
public Integer getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(Integer pageSize) {
|
||||
// if (pageSize == null) {
|
||||
// this.pageSize = 1;
|
||||
// return;
|
||||
// }
|
||||
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<T> implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 总记录数 */
|
||||
private Integer total;
|
||||
|
||||
/** 列表数据 */
|
||||
private List<T> rows;
|
||||
|
||||
/** 消息状态码 */
|
||||
private int code;
|
||||
|
||||
/** 消息内容 */
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 表格数据对象
|
||||
*/
|
||||
public TableDataInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*
|
||||
* @param list 列表数据
|
||||
* @param total 总记录数
|
||||
*/
|
||||
public TableDataInfo(List<T> list, Integer total)
|
||||
{
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public long getTotal()
|
||||
{
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Integer total)
|
||||
{
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List getRows()
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<T> 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,55 @@
|
||||
package com.ruoyi.common.core.page;
|
||||
|
||||
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(ServletUtils.getParameterToInt(PAGE_NUM));
|
||||
pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE));
|
||||
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,231 @@
|
||||
package com.ruoyi.common.core.redis;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 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 缓存键值
|
||||
* @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 long deleteObject(final Collection collection)
|
||||
{
|
||||
return redisTemplate.delete(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
* @return 对象列表
|
||||
*/
|
||||
public Collection<String> keys(final String pattern)
|
||||
{
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package com.ruoyi.common.core.redis;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* spring redis 工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
**/
|
||||
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||
@Component
|
||||
public class RedisService
|
||||
{
|
||||
@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 缓存键值
|
||||
* @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 long deleteObject(final Collection collection)
|
||||
{
|
||||
return redisTemplate.delete(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
* @return 对象列表
|
||||
*/
|
||||
public Collection<String> keys(final String pattern)
|
||||
{
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ruoyi.common.core.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.common.core.domain.TreeEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ITreeCommonService<T extends TreeEntity>
|
||||
extends IService<T> {
|
||||
public List<T> selectTreeList(Wrapper<T> wrapper);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.ruoyi.common.core.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.common.core.domain.TreeEntity;
|
||||
import com.ruoyi.common.core.mapper.BaseTreeMapper;
|
||||
import com.ruoyi.common.core.service.ITreeCommonService;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Transactional
|
||||
public class TreeCommonServiceImpl<M extends BaseTreeMapper<T>, T extends TreeEntity>
|
||||
extends ServiceImpl<M, T> implements ITreeCommonService<T> {
|
||||
|
||||
@Override
|
||||
public T getById(Serializable id) {
|
||||
return baseMapper.selectByTreeId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> selectTreeList(Wrapper<T> wrapper) {
|
||||
List<T> content = baseMapper.selectTreeList(wrapper);
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean save(T entity) {
|
||||
if (!StringUtils.isEmpty(entity.getParentId()) && !"0".equals(entity.getParentId())) {
|
||||
T parent = getById(entity.getParentId());
|
||||
entity.setParentId(parent.getId());
|
||||
entity.setAncestors(parent.makeSelfAsNewParentIds());
|
||||
} else {
|
||||
entity.setParentId(null);
|
||||
}
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateById(T entity) {
|
||||
if (!StringUtils.isEmpty(entity.getParentId()) && !"0".equals(entity.getParentId())) {
|
||||
T parent = getById(entity.getParentId());
|
||||
updateSelftAndChild(entity, parent.getId(), parent.makeSelfAsNewParentIds());
|
||||
} else {
|
||||
entity.setParentId(null);
|
||||
updateSelftAndChild(entity, "0", "0,");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void updateSelftAndChild(T entity, String newParentId, String newParentIds) {
|
||||
T oldEntity = getById(entity.getId());
|
||||
String oldChildrenParentIds = oldEntity.makeSelfAsNewParentIds();
|
||||
entity.setParentId(newParentId);
|
||||
entity.setAncestors(newParentIds);
|
||||
super.updateById(entity);
|
||||
String newChildrenParentIds = entity.makeSelfAsNewParentIds();
|
||||
baseMapper.updateSunTreeParentIds(newChildrenParentIds, oldChildrenParentIds);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean removeById(Serializable id) {
|
||||
T entity = getById(id);
|
||||
baseMapper.deleteSunTree(entity.makeSelfAsNewParentIds());
|
||||
return super.removeById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeByIds(Collection<? extends Serializable> idList) {
|
||||
for (Serializable treeId: idList) {
|
||||
removeById(treeId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.ruoyi.common.core.text;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
* @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,135 @@
|
||||
package com.ruoyi.common.cos;
|
||||
|
||||
|
||||
import com.ruoyi.common.cos.auth.COSSigner;
|
||||
import com.ruoyi.common.cos.utils.VersionInfoUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PostObjectDemo {
|
||||
public static void main(String[] args) throws Exception {
|
||||
PostObjectUploadDemo();
|
||||
}
|
||||
|
||||
private static void PostObjectUploadDemo() throws Exception {
|
||||
String bucketName = "ddht-1324395003";
|
||||
String endpoint = "cos.ap-shanghai.myqcloud.com";
|
||||
String key = "images/test.png";
|
||||
String filename = "test.png";
|
||||
String inputFilePath = "C:\\Users\\admin\\Desktop\\1721376479165.jpg";
|
||||
String contentType = "image/jpeg";
|
||||
String secretId = "AKIDSBQuX5mAZvHa2jNwSzWE0lNvNuMjA9gC";
|
||||
String seretKey = "VXZWQPYaedvMC6vovAU3gJ1ogXXdvO1n";
|
||||
long startTimestamp = System.currentTimeMillis() / 1000;
|
||||
long endTimestamp = startTimestamp + 30 * 60;
|
||||
String endTimestampStr = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").
|
||||
format(endTimestamp * 1000);
|
||||
String keyTime = startTimestamp + ";" + endTimestamp;
|
||||
String boundary = "----WebKitFormBoundaryZBPbaoYE2gqeB21N";
|
||||
// 设置表单的body字段值
|
||||
Map<String, String> formFields = new HashMap<>();
|
||||
formFields.put("q-sign-algorithm", "sha1");
|
||||
formFields.put("key", key);
|
||||
formFields.put("q-ak", secretId);
|
||||
formFields.put("q-key-time", keyTime);
|
||||
// 构造policy,参考文档: https://cloud.tencent.com/document/product/436/14690
|
||||
String policy = "{\n" +
|
||||
" \"expiration\": \"" + endTimestampStr + "\",\n" +
|
||||
" \"conditions\": [\n" +
|
||||
" { \"bucket\": \"" + bucketName + "\" },\n" +
|
||||
" { \"q-sign-algorithm\": \"sha1\" },\n" +
|
||||
" { \"q-ak\": \"" + secretId + "\" },\n" +
|
||||
" { \"q-sign-time\":\"" + keyTime + "\" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
// policy需要base64后算放入表单中
|
||||
String encodedPolicy = new String(Base64.encodeBase64(policy.getBytes()));
|
||||
// 设置policy
|
||||
formFields.put("policy", encodedPolicy);
|
||||
// 根据编码后的policy和secretKey计算签名
|
||||
COSSigner cosSigner = new COSSigner();
|
||||
String signature = cosSigner.buildPostObjectSignature(seretKey,
|
||||
keyTime, policy);
|
||||
// 设置签名
|
||||
formFields.put("q-signature", signature);
|
||||
// 根据以上表单参数,构造最开始的body部分
|
||||
String formBody = buildPostObjectBody(boundary, formFields,
|
||||
filename, contentType);
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
String urlStr = "http://" + bucketName + "." + endpoint;
|
||||
URL url = new URL(urlStr);
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("User-Agent", VersionInfoUtils.getUserAgent());
|
||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
OutputStream out = new DataOutputStream(conn.getOutputStream());
|
||||
// 写入表单的最开始部分
|
||||
out.write(formBody.getBytes());
|
||||
// 将文件内容写入到输出流中
|
||||
File file = new File(inputFilePath);
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(file));
|
||||
int readBytes;
|
||||
byte[] bytes = new byte[4096];
|
||||
while ((readBytes = in.read(bytes)) != -1) {
|
||||
out.write(bytes, 0, readBytes);
|
||||
}
|
||||
in.close();
|
||||
// 添加最后一个分割符,行首和行尾都是--
|
||||
byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes();
|
||||
out.write(endData);
|
||||
out.flush();
|
||||
out.close();
|
||||
// 读取响应头部
|
||||
for (Map.Entry<String, List<String>> entries : conn.getHeaderFields().entrySet()) {
|
||||
String values = "";
|
||||
for (String value : entries.getValue()) {
|
||||
values += value + ",";
|
||||
}
|
||||
if(entries.getKey() == null) {
|
||||
System.out.println("reponse line:" + values );
|
||||
} else {
|
||||
System.out.println(entries.getKey() + ":" + values );
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String buildPostObjectBody(String boundary, Map<String, String> formFields,
|
||||
String filename, String contentType) {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
for(Map.Entry entry: formFields.entrySet()) {
|
||||
// 添加boundary行,行首以--开头
|
||||
stringBuffer.append("--").append(boundary).append("\r\n");
|
||||
// 字段名
|
||||
stringBuffer.append("Content-Disposition: form-data; name=\""
|
||||
+ entry.getKey() + "\"\r\n\r\n");
|
||||
// 字段值
|
||||
stringBuffer.append(entry.getValue() + "\r\n");
|
||||
}
|
||||
// 添加boundary行,行首以--开头
|
||||
stringBuffer.append("--").append(boundary).append("\r\n");
|
||||
// 文件名
|
||||
stringBuffer.append("Content-Disposition: form-data; name=\"file\"; "
|
||||
+ "filename=\"" + filename + "\"\r\n");
|
||||
// 文件类型
|
||||
stringBuffer.append("Content-Type: " + contentType + "\r\n\r\n");
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.ruoyi.common.cos;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import okhttp3.*;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TxApiHttpUtils {
|
||||
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
/*String secretId = "AKIDBG9FF8rkglmaSDnBMRdmtBSr7OVYP3Me";
|
||||
String secretKey = "IUVOQPIFY2fH0njq3BEGD5vkV9hEj9Vz";
|
||||
String token = "";
|
||||
String service = "tms";
|
||||
String version = "2020-12-29";
|
||||
String action = "TextModeration";
|
||||
String body = "{\"Content\":\"5L2g5aW9\"}";
|
||||
String region = "ap-shanghai";
|
||||
String resp = doRequest(secretId, secretKey, service, version, action, body, region, token);
|
||||
System.out.println(resp);*/
|
||||
|
||||
System.out.printf(checkContext("你好").toString());
|
||||
}
|
||||
|
||||
public static JSONObject checkContext(String content) {
|
||||
String secretId = "AKIDBG9FF8rkglmaSDnBMRdmtBSr7OVYP3Me";
|
||||
String secretKey = "IUVOQPIFY2fH0njq3BEGD5vkV9hEj9Vz";
|
||||
String token = "";
|
||||
String service = "tms";
|
||||
String version = "2020-12-29";
|
||||
String action = "TextModeration";
|
||||
String body = "{\"Content\":\"5L2g5aW9\"}";
|
||||
String region = "ap-shanghai";
|
||||
String resp = null;
|
||||
try {
|
||||
resp = doRequest(secretId, secretKey, service, version, action, body, region, token);
|
||||
return JSONObject.parseObject(resp);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// singleton client for connection reuse and better performance
|
||||
private static final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
public static String doRequest(
|
||||
String secretId, String secretKey,
|
||||
String service, String version, String action,
|
||||
String body, String region, String token
|
||||
) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
|
||||
Request request = buildRequest(secretId, secretKey, service, version, action, body, region, token);
|
||||
|
||||
System.out.println(request.method() + " " + request.url());
|
||||
System.out.println(request.headers());
|
||||
System.out.println(body);
|
||||
|
||||
Response response = client.newCall(request).execute();
|
||||
return response.body().string();
|
||||
}
|
||||
|
||||
public static Request buildRequest(
|
||||
String secretId, String secretKey,
|
||||
String service, String version, String action,
|
||||
String body, String region, String token
|
||||
) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
String host = "tms.ap-shanghai.tencentcloudapi.com";
|
||||
String endpoint = "https://" + host;
|
||||
String contentType = "application/json; charset=utf-8";
|
||||
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||
String auth = getAuth(secretId, secretKey, host, contentType, timestamp, body);
|
||||
return new Request.Builder()
|
||||
.header("Host", host)
|
||||
.header("X-TC-Timestamp", timestamp)
|
||||
.header("X-TC-Version", version)
|
||||
.header("X-TC-Action", action)
|
||||
.header("X-TC-Region", region)
|
||||
.header("X-TC-Token", token)
|
||||
.header("X-TC-RequestClient", "SDK_JAVA_BAREBONE")
|
||||
.header("Authorization", auth)
|
||||
.url(endpoint)
|
||||
.post(RequestBody.create(MediaType.parse(contentType), body))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static String getAuth(
|
||||
String secretId, String secretKey, String host, String contentType,
|
||||
String timestamp, String body
|
||||
) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
String canonicalUri = "/";
|
||||
String canonicalQueryString = "";
|
||||
String canonicalHeaders = "content-type:" + contentType + "\nhost:" + host + "\n";
|
||||
String signedHeaders = "content-type;host";
|
||||
|
||||
String hashedRequestPayload = sha256Hex(body.getBytes(StandardCharsets.UTF_8));
|
||||
String canonicalRequest = "POST"
|
||||
+ "\n"
|
||||
+ canonicalUri
|
||||
+ "\n"
|
||||
+ canonicalQueryString
|
||||
+ "\n"
|
||||
+ canonicalHeaders
|
||||
+ "\n"
|
||||
+ signedHeaders
|
||||
+ "\n"
|
||||
+ hashedRequestPayload;
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
|
||||
String service = host.split("\\.")[0];
|
||||
String credentialScope = date + "/" + service + "/" + "tc3_request";
|
||||
String hashedCanonicalRequest =
|
||||
sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));
|
||||
String stringToSign =
|
||||
"TC3-HMAC-SHA256\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
|
||||
|
||||
byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(StandardCharsets.UTF_8), date);
|
||||
byte[] secretService = hmac256(secretDate, service);
|
||||
byte[] secretSigning = hmac256(secretService, "tc3_request");
|
||||
String signature =
|
||||
printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
||||
return "TC3-HMAC-SHA256 "
|
||||
+ "Credential="
|
||||
+ secretId
|
||||
+ "/"
|
||||
+ credentialScope
|
||||
+ ", "
|
||||
+ "SignedHeaders="
|
||||
+ signedHeaders
|
||||
+ ", "
|
||||
+ "Signature="
|
||||
+ signature;
|
||||
}
|
||||
|
||||
public static String sha256Hex(byte[] b) throws NoSuchAlgorithmException {
|
||||
MessageDigest md;
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
byte[] d = md.digest(b);
|
||||
return printHexBinary(d).toLowerCase();
|
||||
}
|
||||
|
||||
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String printHexBinary(byte[] data) {
|
||||
StringBuilder r = new StringBuilder(data.length * 2);
|
||||
for (byte b : data) {
|
||||
r.append(hexCode[(b >> 4) & 0xF]);
|
||||
r.append(hexCode[(b & 0xF)]);
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
|
||||
public static byte[] hmac256(byte[] key, String msg) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
|
||||
mac.init(secretKeySpec);
|
||||
return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
package com.ruoyi.common.cos;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.tencent.cloud.CosStsClient;
|
||||
import com.tencent.cloud.Policy;
|
||||
import com.tencent.cloud.Response;
|
||||
import com.tencent.cloud.Statement;
|
||||
import com.tencent.cloud.cos.util.Jackson;
|
||||
import com.tencentcloudapi.common.AbstractModel;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.ims.v20201229.ImsClient;
|
||||
import com.tencentcloudapi.ims.v20201229.models.ImageModerationRequest;
|
||||
import com.tencentcloudapi.ims.v20201229.models.ImageModerationResponse;
|
||||
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
|
||||
import com.tencentcloudapi.tms.v20201229.TmsClient;
|
||||
import com.tencentcloudapi.tms.v20201229.models.TextModerationRequest;
|
||||
import com.tencentcloudapi.tms.v20201229.models.TextModerationResponse;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
public class TxApiSdkUtils
|
||||
{
|
||||
public static void main(String [] args) {
|
||||
|
||||
// System.out.printf(checkContext("你好").toString());
|
||||
// System.out.printf(checkImages("https://xgtpt.oss-cn-hangzhou.aliyuncs.com/image/1708593052292148w_181&h_180.png").toString());
|
||||
|
||||
// sendSmsMsg("18225698628","256896");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取上传临时密钥
|
||||
*/
|
||||
public void getCredential() {
|
||||
TreeMap<String, Object> config = new TreeMap<String, Object>();
|
||||
try {
|
||||
//这里的 SecretId 和 SecretKey 代表了用于申请临时密钥的永久身份(主账号、子账号等),子账号需要具有操作存储桶的权限。
|
||||
String secretId = System.getenv("AKIDMcmoeNr64nIpicWBYeU6TaR8h280uyAF");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
|
||||
String secretKey = System.getenv("yg8JEzVmriLjtqZ3KURUIrDRQ9euxmbI");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
|
||||
// 替换为您的云 api 密钥 SecretId
|
||||
config.put("secretId", secretId);
|
||||
// 替换为您的云 api 密钥 SecretKey
|
||||
config.put("secretKey", secretKey);
|
||||
|
||||
// 初始化 policy
|
||||
Policy policy = new Policy();
|
||||
|
||||
// 设置域名:
|
||||
// 如果您使用了腾讯云 cvm,可以设置内部域名
|
||||
//config.put("host", "sts.internal.tencentcloudapi.com");
|
||||
|
||||
// 临时密钥有效时长,单位是秒,默认 1800 秒,目前主账号最长 2 小时(即 7200 秒),子账号最长 36 小时(即 129600)秒
|
||||
config.put("durationSeconds", 1800);
|
||||
// 换成您的 bucket
|
||||
config.put("bucket", "examplebucket-1250000000");
|
||||
// 换成 bucket 所在地区
|
||||
config.put("region", "ap-shanghai");
|
||||
|
||||
// 开始构建一条 statement
|
||||
Statement statement = new Statement();
|
||||
// 声明设置的结果是允许操作
|
||||
statement.setEffect("allow");
|
||||
/**
|
||||
* 密钥的权限列表。必须在这里指定本次临时密钥所需要的权限。
|
||||
* 权限列表请参见 https://cloud.tencent.com/document/product/436/31923
|
||||
* 规则为 {project}:{interfaceName}
|
||||
* project : 产品缩写 cos相关授权为值为cos,数据万象(数据处理)相关授权值为ci
|
||||
* 授权所有接口用*表示,例如 cos:*,ci:*
|
||||
* 添加一批操作权限 :
|
||||
*/
|
||||
statement.addActions(new String[]{
|
||||
"cos:PutObject",
|
||||
// 表单上传、小程序上传
|
||||
"cos:PostObject",
|
||||
// 分块上传
|
||||
"cos:InitiateMultipartUpload",
|
||||
"cos:ListMultipartUploads",
|
||||
"cos:ListParts",
|
||||
"cos:UploadPart",
|
||||
"cos:CompleteMultipartUpload",
|
||||
// 处理相关接口一般为数据万象产品 权限中以ci开头
|
||||
// 创建媒体处理任务
|
||||
"ci:CreateMediaJobs",
|
||||
// 文件压缩
|
||||
"ci:CreateFileProcessJobs"
|
||||
});
|
||||
|
||||
/**
|
||||
* 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径
|
||||
* 资源表达式规则分对象存储(cos)和数据万象(ci)两种
|
||||
* 数据处理、审核相关接口需要授予ci资源权限
|
||||
* cos : qcs::cos:{region}:uid/{appid}:{bucket}/{path}
|
||||
* ci : qcs::ci:{region}:uid/{appid}:bucket/{bucket}/{path}
|
||||
* 列举几种典型的{path}授权场景:
|
||||
* 1、允许访问所有对象:"*"
|
||||
* 2、允许访问指定的对象:"a/a1.txt", "b/b1.txt"
|
||||
* 3、允许访问指定前缀的对象:"a*", "a/*", "b/*"
|
||||
* 如果填写了“*”,将允许用户访问所有资源;除非业务需要,否则请按照最小权限原则授予用户相应的访问权限范围。
|
||||
*
|
||||
* 示例:授权examplebucket-1250000000 bucket目录下的所有资源给cos和ci 授权两条Resource
|
||||
*/
|
||||
statement.addResources(new String[]{
|
||||
"qcs::cos:ap-chongqing:uid/1250000000:examplebucket-1250000000/*",
|
||||
"qcs::ci:ap-chongqing:uid/1250000000:bucket/examplebucket-1250000000/*"});
|
||||
|
||||
// 把一条 statement 添加到 policy
|
||||
// 可以添加多条
|
||||
policy.addStatement(statement);
|
||||
// 将 Policy 示例转化成 String,可以使用任何 json 转化方式,这里是本 SDK 自带的推荐方式
|
||||
config.put("policy", Jackson.toJsonPrettyString(policy));
|
||||
|
||||
Response response = CosStsClient.getCredential(config);
|
||||
System.out.println(response.credentials.tmpSecretId);
|
||||
System.out.println(response.credentials.tmpSecretKey);
|
||||
System.out.println(response.credentials.sessionToken);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("no valid secret !");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯云文件安全检测
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject checkContext(String content){
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDMcmoeNr64nIpicWBYeU6TaR8h280uyAF", "yg8JEzVmriLjtqZ3KURUIrDRQ9euxmbI");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("tms.ap-shanghai.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
TmsClient client = new TmsClient(cred, "ap-shanghai", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
TextModerationRequest req = new TextModerationRequest();
|
||||
|
||||
String str = Base64.encode(content);
|
||||
// System.out.printf(str);
|
||||
req.setContent(str);
|
||||
// 返回的resp是一个TextModerationResponse的实例,与请求对象对应
|
||||
TextModerationResponse resp = client.TextModeration(req);
|
||||
// 输出json格式的字符串回包
|
||||
|
||||
String res = (AbstractModel.toJsonString(resp));
|
||||
System.out.println(res);
|
||||
return JSONObject.parseObject(res);
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 腾讯云图片安全检测
|
||||
* @param imgUrl
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject checkImages(String imgUrl){
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDMcmoeNr64nIpicWBYeU6TaR8h280uyAF", "yg8JEzVmriLjtqZ3KURUIrDRQ9euxmbI");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("ims.ap-shanghai.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
ImsClient client = new ImsClient(cred, "ap-shanghai", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象jkighjkhgkhgkhgjhghkjj
|
||||
ImageModerationRequest req = new ImageModerationRequest();
|
||||
req.setFileUrl(imgUrl);
|
||||
// 返回的resp是一个ImageModerationResponse的实例,与请求对象对应
|
||||
ImageModerationResponse resp = client.ImageModeration(req);
|
||||
// 输出json格式的字符串回包
|
||||
String res = (AbstractModel.toJsonString(resp));
|
||||
System.out.println(res);
|
||||
return JSONObject.parseObject(res);
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 腾讯云发送短信
|
||||
* @param phoneNumber
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject sendSmsMsg(String phoneNumber, String code){
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||
Credential cred = new Credential("AKIDMcmoeNr64nIpicWBYeU6TaR8h280uyAF", "yg8JEzVmriLjtqZ3KURUIrDRQ9euxmbI");
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
SmsClient client = new SmsClient(cred, "ap-nanjing", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
SendSmsRequest req = new SendSmsRequest();
|
||||
|
||||
String[] phoneNumberSet1 = {phoneNumber};
|
||||
req.setPhoneNumberSet(phoneNumberSet1);
|
||||
|
||||
req.setSmsSdkAppId("1400926380");
|
||||
req.setTemplateId("2222045");
|
||||
req.setSignName("合肥小图科技");
|
||||
|
||||
String[] templateParamSet1 = {code};
|
||||
req.setTemplateParamSet(templateParamSet1);
|
||||
|
||||
// 返回的resp是一个SendSmsResponse的实例,与请求对象对应
|
||||
SendSmsResponse resp = client.SendSms(req);
|
||||
// 输出json格式的字符串回包
|
||||
String res = (AbstractModel.toJsonString(resp));
|
||||
return JSONObject.parseObject(res);
|
||||
} catch (TencentCloudSDKException e) {
|
||||
System.out.println(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.ruoyi.common.cos.auth;
|
||||
|
||||
/*
|
||||
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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.
|
||||
|
||||
* According to cos feature, we modify some class,comment, field name, etc.
|
||||
*/
|
||||
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.codec.digest.HmacUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class COSSigner {
|
||||
private static Set<String> needSignedHeaderSet = new HashSet<>();
|
||||
private Boolean isCIWorkflowRequest = false;
|
||||
// Time offset between local and server
|
||||
private int localTimeDelta = 0;
|
||||
|
||||
static {
|
||||
needSignedHeaderSet.add("cache-control");
|
||||
needSignedHeaderSet.add("content-disposition");
|
||||
needSignedHeaderSet.add("content-encoding");
|
||||
needSignedHeaderSet.add("content-length");
|
||||
needSignedHeaderSet.add("content-md5");
|
||||
needSignedHeaderSet.add("content-type");
|
||||
needSignedHeaderSet.add("expect");
|
||||
needSignedHeaderSet.add("expires");
|
||||
needSignedHeaderSet.add("host");
|
||||
needSignedHeaderSet.add("if-match");
|
||||
needSignedHeaderSet.add("if-modified-since");
|
||||
needSignedHeaderSet.add("if-none-match");
|
||||
needSignedHeaderSet.add("if-unmodified-since");
|
||||
needSignedHeaderSet.add("origin");
|
||||
needSignedHeaderSet.add("range");
|
||||
needSignedHeaderSet.add("transfer-encoding");
|
||||
}
|
||||
|
||||
public String buildPostObjectSignature(String secretKey, String keyTime, String policy) {
|
||||
String signKey = HmacUtils.hmacSha1Hex(secretKey, keyTime);
|
||||
String stringToSign = DigestUtils.sha1Hex(policy);
|
||||
return HmacUtils.hmacSha1Hex(signKey, stringToSign);
|
||||
}
|
||||
|
||||
public boolean needSignedHeader(String header) {
|
||||
return needSignedHeaderSet.contains(header) || header.startsWith("x-cos-");
|
||||
}
|
||||
|
||||
|
||||
private String buildSignMemberStr(Map<String, String> signHeaders) {
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
boolean seenOne = false;
|
||||
for (String key : signHeaders.keySet()) {
|
||||
if (!seenOne) {
|
||||
seenOne = true;
|
||||
} else {
|
||||
strBuilder.append(";");
|
||||
}
|
||||
strBuilder.append(key);
|
||||
}
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
private String formatMapToStr(Map<String, String> kVMap) {
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
boolean seeOne = false;
|
||||
for (Entry<String, String> entry : kVMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (!seeOne) {
|
||||
seeOne = true;
|
||||
} else {
|
||||
strBuilder.append("&");
|
||||
}
|
||||
strBuilder.append(key).append("=").append(value);
|
||||
}
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
private String buildTimeStr(Date startTime, Date endTime) {
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
long startTimestamp = startTime.getTime() / 1000 + localTimeDelta;
|
||||
long endTimestamp = endTime.getTime() / 1000 + localTimeDelta;
|
||||
strBuilder.append(startTimestamp).append(";").append(endTimestamp);
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.ruoyi.common.cos.utils;
|
||||
|
||||
/*
|
||||
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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.
|
||||
|
||||
* According to cos feature, we modify some class,comment, field name, etc.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class VersionInfoUtils {
|
||||
/** The COS SDK version info file with SDK versioning info */
|
||||
static final String VERSION_INFO_FILE = "/versionInfo.properties";
|
||||
|
||||
/** SDK version info */
|
||||
private static volatile String version;
|
||||
|
||||
/** SDK platform info */
|
||||
private static volatile String platform;
|
||||
|
||||
/** User Agent info */
|
||||
private static volatile String userAgent;
|
||||
|
||||
/** Shared logger for any issues while loading version information */
|
||||
private static final Logger log = LoggerFactory.getLogger(VersionInfoUtils.class);
|
||||
|
||||
/**
|
||||
* Returns the current version for the COS SDK in which this class is running. Version
|
||||
* information is obtained from from the versionInfo.properties file which the COS Java SDK
|
||||
* build process generates.
|
||||
*
|
||||
* @return The current version for the COS SDK, if known, otherwise returns a string indicating
|
||||
* that the version information is not available.
|
||||
*/
|
||||
public static String getVersion() {
|
||||
if (version == null) {
|
||||
synchronized (VersionInfoUtils.class) {
|
||||
if (version == null) {
|
||||
initializeVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current platform for the COS SDK in which this class is running. Version
|
||||
* information is obtained from from the versionInfo.properties file which the COS Java SDK
|
||||
* build process generates.
|
||||
*
|
||||
* @return The current platform for the COS SDK, if known, otherwise returns a string indicating
|
||||
* that the platform information is not available.
|
||||
*/
|
||||
public static String getPlatform() {
|
||||
if (platform == null) {
|
||||
synchronized (VersionInfoUtils.class) {
|
||||
if (platform == null) {
|
||||
initializeVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the User Agent string to be used when communicating with the COS services.
|
||||
* The User Agent encapsulates SDK, Java, OS and region information.
|
||||
*/
|
||||
public static String getUserAgent() {
|
||||
if (userAgent == null) {
|
||||
synchronized(VersionInfoUtils.class) {
|
||||
if (userAgent == null) {
|
||||
userAgent = String.format("cos-java-sdk-v%s/%s/jdk-%s/%s",
|
||||
getVersion(),
|
||||
System.getProperty("os.name"),
|
||||
System.getProperty("java.version"),
|
||||
System.getProperty("java.vm.name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the versionInfo.properties file from the COS Java SDK and stores the information so
|
||||
* that the file doesn't have to be read the next time the data is needed.
|
||||
*/
|
||||
private static void initializeVersion() {
|
||||
InputStream inputStream = VersionInfoUtils.class.getResourceAsStream(VERSION_INFO_FILE);
|
||||
Properties versionInfoProperties = new Properties();
|
||||
try {
|
||||
if (inputStream == null) {
|
||||
throw new Exception(VERSION_INFO_FILE + " not found on classpath");
|
||||
}
|
||||
|
||||
versionInfoProperties.load(inputStream);
|
||||
version = versionInfoProperties.getProperty("version");
|
||||
} catch (Exception e) {
|
||||
log.info("Unable to load version information for the running SDK: " + e.getMessage());
|
||||
version = "unknown-version";
|
||||
platform = "java";
|
||||
} finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,36 @@
|
||||
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,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,53 @@
|
||||
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/4/8 15:54
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class CustomException extends RuntimeException {
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
|
||||
private List objectList = new ArrayList();
|
||||
|
||||
public CustomException(Integer code, String errorMessage) {
|
||||
super(errorMessage);
|
||||
this.code = code;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public CustomException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
this.code = 500;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public CustomException(AbstractBaseExceptionEnum exception) {
|
||||
super(exception.getMessage());
|
||||
this.code = exception.getCode();
|
||||
this.errorMessage = exception.getMessage();
|
||||
}
|
||||
|
||||
public CustomException(AbstractBaseExceptionEnum exception, List objectList) {
|
||||
super(exception.getMessage());
|
||||
this.code = exception.getCode();
|
||||
this.errorMessage = exception.getMessage();
|
||||
this.objectList = objectList;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,59 @@
|
||||
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,84 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
|
||||
public ServiceException(AbstractBaseExceptionEnum exception) {
|
||||
super(exception.getMessage());
|
||||
this.code = exception.getCode();
|
||||
this.message = exception.getMessage();
|
||||
}
|
||||
}
|
||||
@@ -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,109 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 认证相关的异常的枚举
|
||||
* <p>
|
||||
* 认证和鉴权的区别:
|
||||
* <p>
|
||||
* 认证可以证明你能登录系统,认证的过程是校验token的过程
|
||||
* 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限
|
||||
*
|
||||
* @author stylefeng
|
||||
* @date 2019/7/18 22:22
|
||||
*/
|
||||
public enum AuthExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 账号或密码为空
|
||||
*/
|
||||
ACCOUNT_PWD_EMPTY(1, "账号或密码为空"),
|
||||
|
||||
/**
|
||||
* 账号密码错误
|
||||
*/
|
||||
ACCOUNT_PWD_ERROR(2, "账号或密码错误"),
|
||||
|
||||
/**
|
||||
* 验证码错误
|
||||
*/
|
||||
VALID_CODE_ERROR(3, "验证码错误,请检查captcha参数"),
|
||||
|
||||
/**
|
||||
* 请求token为空
|
||||
*/
|
||||
REQUEST_TOKEN_EMPTY(700, "请求token为空"),
|
||||
|
||||
/**
|
||||
* token格式不正确,token请以Bearer开头
|
||||
*/
|
||||
NOT_VALID_TOKEN_TYPE(700, "token格式不正确,token请以Bearer开头,并且Bearer后边带一个空格"),
|
||||
|
||||
/**
|
||||
* 请求token错误
|
||||
*/
|
||||
REQUEST_TOKEN_ERROR(700, "请求token错误"),
|
||||
|
||||
/**
|
||||
* 账号被冻结
|
||||
*/
|
||||
ACCOUNT_FREEZE_ERROR(7, "账号被冻结,请联系管理员"),
|
||||
|
||||
/**
|
||||
* 登录已过期
|
||||
*/
|
||||
LOGIN_EXPIRED(8, "登录已过期,请重新登录"),
|
||||
|
||||
/**
|
||||
* 无登录用户
|
||||
*/
|
||||
NO_LOGIN_USER(9, "无登录用户");
|
||||
|
||||
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
AuthExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* @author liwenlong
|
||||
* @date 2021/11/1 19:34
|
||||
*/
|
||||
|
||||
|
||||
public enum CoreExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
|
||||
/**
|
||||
* 用户相关
|
||||
*/
|
||||
REGISTER_FAIL( "注册失败"),
|
||||
PWD_ERROR( "密码错误"),
|
||||
ACCOUNT_NOT_EXIST( "账号不存在"),
|
||||
ACCOUNT_DISABLE( "账号被冻结"),
|
||||
|
||||
PHONE_NOT_EXIST( "手机号不存在"),
|
||||
|
||||
MOBILE_BIND_MAKE( "请使用绑定的手机号码"),
|
||||
ACCOUNT_HAS_EXIST( "账号已存在,请重新输入"),
|
||||
|
||||
PHONE_HAS_EXIST( "手机号已存在,请重新输入"),
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 邀请码
|
||||
*/
|
||||
REFEREE_CODE_ERROR( "邀请码错误"),
|
||||
|
||||
|
||||
FIGURE_CODE_ERROR( "图形验证码错误"),
|
||||
|
||||
FIGURE_CODE_NOT_EXIST( "请先获取图形验证码"),
|
||||
|
||||
|
||||
/**
|
||||
* 短信
|
||||
*/
|
||||
SMS_SEND_FAIL( "短信发送失败"),
|
||||
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
ERROR_PARAM("参数错误"),
|
||||
NOT_NULL_PARAM("参数不能为空"),
|
||||
ERROR_DATA("数据错误"),
|
||||
|
||||
ERROR_FIELD_NAME("字段名称错误"),
|
||||
|
||||
/**
|
||||
* 余额
|
||||
*/
|
||||
|
||||
PRICE_ZERO(210, "支付金额为零"),
|
||||
BALANCE_INSUFFICIENT (220, "余额不足"),
|
||||
|
||||
INTEGRAL_INSUFFICIENT (230, "积分不足"),
|
||||
|
||||
PAY_BALANCE_ERROR (240, "支付价格错误"),
|
||||
|
||||
EDIT_BALANCE_ERROR (250, "余额修改错误"),
|
||||
|
||||
|
||||
/**
|
||||
* 字典
|
||||
*/
|
||||
NO_DICTIONARIES( "未配置字典值"),
|
||||
DICTIONARIES_ERROR( "字典值格式错误"),
|
||||
|
||||
|
||||
/**
|
||||
* 渲染
|
||||
*/
|
||||
WRITE_ERROR( "渲染界面错误"),
|
||||
|
||||
RESOURCES_NOT_EXIST("资源不存在"),
|
||||
IO_ERROR("流读取异常"),
|
||||
|
||||
INVLIDE_DATE_STRING(400, "输入日期格式不对"),
|
||||
FILE_READING_ERROR(400, "FILE_READING_ERROR!"),
|
||||
FILE_NOT_FOUND(400, "FILE_NOT_FOUND!"),
|
||||
PAGE_NULL(404, "请求页面不存在"),
|
||||
REMOTE_SERVICE_NULL(404, "远程服务不存在"),
|
||||
|
||||
|
||||
ERROR_TOKEN(520,"token异常"),
|
||||
INPUT_PWD(530, "请输入支付密码"),
|
||||
NO_PWD(540, "密码为空"),
|
||||
UPDATE_PWD_ERROR("编辑密码错误"),
|
||||
UPDATE_MOBILE_ERROR("编辑手机号错误"),
|
||||
UPDATE_DATA(570, "数据更新错误"),
|
||||
INSERT_DATA(580, "数据保存错误"),
|
||||
ERROR_DICT_LACK(590,"字典表配置缺失"),
|
||||
|
||||
|
||||
ENCRYPT_ERROR(600, "加解密错误"),
|
||||
|
||||
|
||||
NO_CURRENT_USER(700, "当前没有登录的用户"),
|
||||
FIELD_VALIDATE_ERROR(700, "数据库字段与实体字段不一致!"),
|
||||
INIT_TABLE_EMPTY_PARAMS(701, "初始化数据库,存在为空的字段"),
|
||||
|
||||
|
||||
ASYNC_ERROR(5000, "数据在被别人修改,请稍后重试"),
|
||||
|
||||
;
|
||||
|
||||
private Integer code;
|
||||
private String message;
|
||||
|
||||
private CoreExceptionEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
private CoreExceptionEnum(String message) {
|
||||
this.code = 500;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 参数校验异常枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/25 20:11
|
||||
*/
|
||||
public enum ParamExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
PARAM_ERROR(1, "参数错误");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
ParamExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 授权和鉴权异常的枚举
|
||||
* <p>
|
||||
* 认证和鉴权的区别:
|
||||
* <p>
|
||||
* 认证可以证明你能登录系统,认证的过程是校验token的过程
|
||||
* 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/12 10:14
|
||||
*/
|
||||
public enum PermissionExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 资源路径不存在
|
||||
*/
|
||||
URL_NOT_EXIST(1, "资源路径不存在,请检查请求地址"),
|
||||
|
||||
/**
|
||||
* 没有权限访问资源
|
||||
*/
|
||||
NO_PERMISSION(2, "没有权限访问资源,请联系管理员"),
|
||||
|
||||
/**
|
||||
* 没有权限操作该数据
|
||||
*/
|
||||
NO_PERMISSION_OPERATE(3, "没有权限操作该数据,请联系管理员"),
|
||||
|
||||
/**
|
||||
* 手机号已存在
|
||||
*/
|
||||
MOBILE_REPEAT(4, "手机号已存在"),
|
||||
|
||||
/**
|
||||
* 账号已存在
|
||||
*/
|
||||
ACCOUNT_REPEAT(5, "账号已存在"),
|
||||
|
||||
/**
|
||||
* 请指定接收数据的操作员
|
||||
*/
|
||||
NO_CHOOSE_OPERATOR(7, "请指定接收数据的操作员");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
PermissionExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 请求方法相关异常枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/11 15:33
|
||||
*/
|
||||
public enum RequestMethodExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 不支持该请求方法,请求方法应为POST
|
||||
*/
|
||||
REQUEST_METHOD_IS_POST(1, "不支持该请求方法,请求方法应为POST"),
|
||||
|
||||
/**
|
||||
* 不支持该请求方法,请求方法应为GET
|
||||
*/
|
||||
REQUEST_METHOD_IS_GET(2, "不支持该请求方法,请求方法应为GET");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
RequestMethodExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 请求类型相关异常枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/4/2 15:42
|
||||
*/
|
||||
public enum RequestTypeExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 参数传递格式不支持
|
||||
*/
|
||||
REQUEST_TYPE_IS_JSON(1, "参数传递格式不支持,请使用JSON格式传参"),
|
||||
|
||||
/**
|
||||
* 请求JSON参数格式不正确
|
||||
*/
|
||||
REQUEST_JSON_ERROR(2, "请求JSON参数格式不正确,请检查参数格式");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
RequestTypeExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* rest异常
|
||||
*
|
||||
* @author administrator
|
||||
* @date 2016年11月12日 下午5:04:51
|
||||
*/
|
||||
public enum RestExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
|
||||
/**
|
||||
* token异常
|
||||
*/
|
||||
TOKEN_EXPIRED(700, "token过期"),
|
||||
TOKEN_ERROR(700, "token验证失败"),
|
||||
|
||||
AUTH_EXCEPTION(700, "token过期");
|
||||
|
||||
|
||||
RestExceptionEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 服务器内部相关异常枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/18 19:19
|
||||
*/
|
||||
public enum ServerExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 当前请求参数为空或数据缺失
|
||||
*/
|
||||
REQUEST_EMPTY(1, "当前请求参数为空或数据缺失,请联系管理员"),
|
||||
|
||||
/**
|
||||
* 加载中,请稍后……
|
||||
*/
|
||||
SERVER_ERROR(2, "程序异常,请联系管理员"),
|
||||
|
||||
/**
|
||||
* 常量获取存在空值
|
||||
*/
|
||||
CONSTANT_EMPTY(3, "常量获取存在空值,请检查sys_config中是否配置"),
|
||||
/**
|
||||
*
|
||||
*/
|
||||
COMMON_EXCEPTION(4, "编译异常"),
|
||||
|
||||
|
||||
/**
|
||||
* 请勿重复提交
|
||||
*/
|
||||
NO_REPEAT_REQUEST(5, "请勿重复提交");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
ServerExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 状态枚举
|
||||
*
|
||||
* @author stylefeng
|
||||
* @date 2020/4/30 22:45
|
||||
*/
|
||||
public enum StatusExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 请求状态值为空
|
||||
*/
|
||||
REQUEST_EMPTY(1, "请求状态值为空"),
|
||||
|
||||
/**
|
||||
* 请求状值为非正确状态值
|
||||
*/
|
||||
NOT_WRITE_STATUS(2, "请求状态值不合法"),
|
||||
|
||||
/**
|
||||
* 更新状态失败,试图更新被删除的记录
|
||||
*/
|
||||
UPDATE_STATUS_ERROR(3, "更新状态失败,您试图更新被删除的记录"),
|
||||
|
||||
/**
|
||||
* 操作失败
|
||||
*/
|
||||
OPERATOR_FAIL(500, "操作失败"),;
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
StatusExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(StatusExceptionEnum.NOT_WRITE_STATUS.getCode());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums;
|
||||
|
||||
|
||||
import com.ruoyi.common.exception.enums.abs.AbstractBaseExceptionEnum;
|
||||
|
||||
/**
|
||||
* 对象包装异常
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2020/7/24 14:36
|
||||
*/
|
||||
public enum WrapperExceptionEnum implements AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 被包装的值不能是基本类型
|
||||
*/
|
||||
BASIC_TYPE_ERROR(1, "被包装的值不能是基本类型"),
|
||||
|
||||
/**
|
||||
* 获取转化字段的值异常
|
||||
*/
|
||||
TRANSFER_FILED_VALUE_ERROR(2, "获取转化字段的值异常"),
|
||||
|
||||
/**
|
||||
* 字段包装转化异常
|
||||
*/
|
||||
TRANSFER_ERROR(3, "字段包装转化异常");
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
WrapperExceptionEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.exception.enums.abs;
|
||||
|
||||
/**
|
||||
* 异常枚举格式规范
|
||||
*
|
||||
* @author stylefeng
|
||||
* @date 2017/12/17 22:22
|
||||
*/
|
||||
public interface AbstractBaseExceptionEnum {
|
||||
|
||||
/**
|
||||
* 获取异常的状态码
|
||||
*
|
||||
* @return 状态码
|
||||
* @author stylefeng
|
||||
* @date 2020/7/9 14:28
|
||||
*/
|
||||
Integer getCode();
|
||||
|
||||
/**
|
||||
* 获取异常的提示信息
|
||||
*
|
||||
* @return 提示信息
|
||||
* @author stylefeng
|
||||
* @date 2020/7/9 14:28
|
||||
*/
|
||||
String getMessage();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
@@ -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,81 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
|
||||
/**
|
||||
* 文件上传 误异常类
|
||||
*
|
||||
* @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 : [" + filename + "], extension : [" + extension + "], allowed 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;
|
||||
|
||||
/**
|
||||
* 验证码错误异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CaptchaException extends UserException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CaptchaException()
|
||||
{
|
||||
super("user.jcaptcha.error", null);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.ruoyi.common.filter;
|
||||
|
||||
import com.ruoyi.common.annotation.CreateBy;
|
||||
import com.ruoyi.common.annotation.CreateTime;
|
||||
import com.ruoyi.common.annotation.UpdateBy;
|
||||
import com.ruoyi.common.annotation.UpdateTime;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlCommandType;
|
||||
import org.apache.ibatis.plugin.Interceptor;
|
||||
import org.apache.ibatis.plugin.Intercepts;
|
||||
import org.apache.ibatis.plugin.Invocation;
|
||||
import org.apache.ibatis.plugin.Signature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
/**
|
||||
* 自定义 Mybatis 插件,自动设置 createTime 和 updatTime 的值。
|
||||
* 拦截 update 操作(添加和修改)
|
||||
*/
|
||||
@Component
|
||||
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
|
||||
public class CustomInterceptor implements Interceptor {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomInterceptor.class);
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
|
||||
|
||||
// 获取 SQL 命令
|
||||
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
|
||||
//只判断新增和修改
|
||||
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
|
||||
// 获取参数
|
||||
Object parameter = invocation.getArgs()[1];
|
||||
//批量操作时
|
||||
if (parameter instanceof MapperMethod.ParamMap) {
|
||||
MapperMethod.ParamMap map = (MapperMethod.ParamMap) parameter;
|
||||
if (map.containsKey("list")) {
|
||||
Object obj = map.get("list");
|
||||
List<?> list = (List<?>) obj;
|
||||
if (list != null) {
|
||||
for (Object o : list) {
|
||||
setParameter(o, sqlCommandType);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setParameter(parameter, sqlCommandType);
|
||||
}
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
public void setParameter(Object parameter, SqlCommandType sqlCommandType) throws Throwable {
|
||||
Class<?> aClass = parameter.getClass();
|
||||
Field[] declaredFields;
|
||||
//如果常用字段提取了公共类 BaseEntity
|
||||
//判断BaseEntity是否是父类
|
||||
if (BaseEntity.class.isAssignableFrom(aClass)) {
|
||||
// 获取父类私有成员变量
|
||||
declaredFields = aClass.getSuperclass().getDeclaredFields();
|
||||
} else {
|
||||
// 获取私有成员变量
|
||||
declaredFields = aClass.getDeclaredFields();
|
||||
}
|
||||
for (Field field : declaredFields) {
|
||||
if (SqlCommandType.INSERT.equals(sqlCommandType)) { // insert 语句插入 createBy
|
||||
if (field.getAnnotation(CreateBy.class) != null) {
|
||||
field.setAccessible(true);
|
||||
|
||||
try {
|
||||
field.set(parameter, SecurityUtils.getUserId().toString());
|
||||
}catch (Exception e){
|
||||
field.set(parameter, "0");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getAnnotation(CreateTime.class) != null) { // insert 语句插入 createTime
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, new Timestamp(System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
|
||||
if (field.getAnnotation(UpdateTime.class) != null) { // update 语句插入 updateTime
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, new Timestamp(System.currentTimeMillis()));
|
||||
}
|
||||
if (field.getAnnotation(UpdateBy.class) != null) { // update 语句插入 updateBy
|
||||
field.setAccessible(true);
|
||||
|
||||
try {
|
||||
field.set(parameter, SecurityUtils.getUserId().toString());
|
||||
}catch (Exception e){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,75 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 构建可重复读取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("UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
body = HttpHelper.getBodyString(request).getBytes("UTF-8");
|
||||
}
|
||||
|
||||
@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,74 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 防止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 || method.matches("GET") || method.matches("DELETE"))
|
||||
{
|
||||
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[] escapseValues = new String[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// 防xss攻击和过滤前后空格
|
||||
escapseValues[i] = EscapeUtil.clean(values[i]).trim();
|
||||
}
|
||||
return escapseValues;
|
||||
}
|
||||
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,28 @@
|
||||
|
||||
package com.ruoyi.common.page;
|
||||
|
||||
import com.ruoyi.common.core.page.PageDomain;
|
||||
import com.ruoyi.common.core.page.TableSupport;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 手动分页
|
||||
*/
|
||||
public class ManualPagination {
|
||||
|
||||
public static <T> List<T> getPage(List<T> dataList) {
|
||||
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = pageDomain.getPageNum();
|
||||
Integer pageSize = pageDomain.getPageSize();
|
||||
int startIndex = (pageNum - 1) * pageSize;
|
||||
int endIndex = Math.min(startIndex + pageSize, dataList.size());
|
||||
List<T> pageData = dataList.subList(startIndex, endIndex);
|
||||
return pageData;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright [2020] [https://www.stylefeng.cn]
|
||||
|
||||
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.
|
||||
|
||||
Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
|
||||
1.请不要删除和修改根目录下的LICENSE文件。
|
||||
2.请不要删除和修改Guns源码头部的版权声明。
|
||||
3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns-separation
|
||||
6.若您的项目无法满足以上几点,可申请商业授权,获取Guns商业授权许可,请在官网购买授权,地址为 https://www.stylefeng.cn
|
||||
*/
|
||||
package com.ruoyi.common.page;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.PageUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页结果集
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/30 15:44
|
||||
*/
|
||||
@Data
|
||||
public class PageResult<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
/**
|
||||
* 默认分页彩虹展示数量
|
||||
*/
|
||||
public static final int RAINBOW_NUM = 5;
|
||||
|
||||
/**
|
||||
* 第几页
|
||||
*/
|
||||
private Integer pageNo = 1;
|
||||
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
private Integer pageSize = 20;
|
||||
|
||||
/**
|
||||
* 总页数
|
||||
*/
|
||||
private Integer totalPage = 0;
|
||||
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private Integer totalRows = 0;
|
||||
|
||||
/**
|
||||
* 结果集
|
||||
*/
|
||||
private List<T> rows;
|
||||
|
||||
/**
|
||||
* 分页彩虹
|
||||
*/
|
||||
private int[] rainbow;
|
||||
|
||||
public PageResult() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将mybatis-plus的page转成自定义的PageResult,扩展了totalPage总页数,和rainBow彩虹条
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/4/8 19:20
|
||||
*/
|
||||
public PageResult(IPage<T> page) {
|
||||
this.setRows(page.getRecords());
|
||||
this.setTotalRows(Convert.toInt(page.getTotal()));
|
||||
this.setPageNo(Convert.toInt(page.getCurrent()));
|
||||
this.setPageSize(Convert.toInt(page.getSize()));
|
||||
this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()),
|
||||
Convert.toInt(page.getSize())));
|
||||
this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()),
|
||||
Convert.toInt(this.getTotalPage()), RAINBOW_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将mybatis-plus的page转成自定义的PageResult,扩展了totalPage总页数,和rainBow彩虹条
|
||||
* 可单独设置rows
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/4/14 20:55
|
||||
*/
|
||||
public PageResult(Page<T> page, List<T> t) {
|
||||
this.setRows(t);
|
||||
this.setTotalRows(Convert.toInt(page.getTotal()));
|
||||
this.setPageNo(Convert.toInt(page.getCurrent()));
|
||||
this.setPageSize(Convert.toInt(page.getSize()));
|
||||
this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()),
|
||||
Convert.toInt(page.getSize())));
|
||||
this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()),
|
||||
Convert.toInt(this.getTotalPage()), RAINBOW_NUM));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.page;
|
||||
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PageUtil {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param list 返回数据
|
||||
* @param totalList 计算总数据量的数据
|
||||
* @return
|
||||
*/
|
||||
public static TableDataInfo getTableDataInfo(List list, List totalList){
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(HttpStatus.SUCCESS);
|
||||
rspData.setRows(list);
|
||||
rspData.setMsg("查询成功");
|
||||
if(totalList==null){
|
||||
rspData.setTotal(Integer.valueOf(new PageInfo(list).getTotal() + ""));
|
||||
}else {
|
||||
rspData.setTotal(Integer.valueOf(new PageInfo(totalList).getTotal()+""));
|
||||
}
|
||||
return rspData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* AES加密工具类
|
||||
*
|
||||
* @author ACGkaka
|
||||
* @since 2021-06-18 19:11:03
|
||||
*/
|
||||
public class AESUtil {
|
||||
/**
|
||||
* 日志相关
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AESUtil.class);
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private static final String ENCODING = "UTF-8";
|
||||
/**
|
||||
* 算法定义
|
||||
*/
|
||||
private static final String AES_ALGORITHM = "AES";
|
||||
/**
|
||||
* 指定填充方式
|
||||
*/
|
||||
private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";
|
||||
private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";
|
||||
/**
|
||||
* 偏移量(CBC中使用,增强加密算法强度)
|
||||
*/
|
||||
private static final String IV_SEED = "1234567812345678";
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
* @param content 待加密内容
|
||||
* @param aesKey 密码
|
||||
* @return
|
||||
*/
|
||||
public static String encrypt(String content, String aesKey){
|
||||
if(StringUtils.isBlank(content)){
|
||||
LOGGER.info("AES encrypt: the content is null!");
|
||||
return null;
|
||||
}
|
||||
//判断秘钥是否为16位
|
||||
if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
|
||||
try {
|
||||
//对密码进行编码
|
||||
byte[] bytes = aesKey.getBytes(ENCODING);
|
||||
//设置加密算法,生成秘钥
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
|
||||
// "算法/模式/补码方式"
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
|
||||
//选择加密
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
//根据待加密内容生成字节数组
|
||||
byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
|
||||
//返回base64字符串
|
||||
return Base64Utils.encodeToString(encrypted);
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("AES encrypt exception:" + e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}else {
|
||||
LOGGER.info("AES encrypt: the aesKey is null or error!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param content 待解密内容
|
||||
* @param aesKey 密码
|
||||
* @return
|
||||
*/
|
||||
public static String decrypt(String content, String aesKey){
|
||||
if(StringUtils.isBlank(content)){
|
||||
LOGGER.info("AES decrypt: the content is null!");
|
||||
return null;
|
||||
}
|
||||
//判断秘钥是否为16位
|
||||
if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
|
||||
try {
|
||||
//对密码进行编码
|
||||
byte[] bytes = aesKey.getBytes(ENCODING);
|
||||
//设置解密算法,生成秘钥
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
|
||||
// "算法/模式/补码方式"
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
|
||||
//选择解密
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
|
||||
//先进行Base64解码
|
||||
byte[] decodeBase64 = Base64Utils.decodeFromString(content);
|
||||
|
||||
//根据待解密内容进行解密
|
||||
byte[] decrypted = cipher.doFinal(decodeBase64);
|
||||
|
||||
//将字节数组转成字符串
|
||||
return new String(decrypted, ENCODING);
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("AES decrypt exception:" + e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}else {
|
||||
LOGGER.info("AES decrypt: the aesKey is null or error!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES_CBC加密
|
||||
*
|
||||
* @param content 待加密内容
|
||||
* @param aesKey 密码
|
||||
* @return
|
||||
*/
|
||||
public static String encryptCBC(String content, String aesKey){
|
||||
if(StringUtils.isBlank(content)){
|
||||
LOGGER.info("AES_CBC encrypt: the content is null!");
|
||||
return null;
|
||||
}
|
||||
//判断秘钥是否为16位
|
||||
if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
|
||||
try {
|
||||
//对密码进行编码
|
||||
byte[] bytes = aesKey.getBytes(ENCODING);
|
||||
//设置加密算法,生成秘钥
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
|
||||
// "算法/模式/补码方式"
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
|
||||
//偏移
|
||||
IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
|
||||
//选择加密
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
|
||||
//根据待加密内容生成字节数组
|
||||
byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
|
||||
//返回base64字符串
|
||||
return Base64Utils.encodeToString(encrypted);
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("AES_CBC encrypt exception:" + e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}else {
|
||||
LOGGER.info("AES_CBC encrypt: the aesKey is null or error!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES_CBC解密
|
||||
*
|
||||
* @param content 待解密内容
|
||||
* @param aesKey 密码
|
||||
* @return
|
||||
*/
|
||||
public static String decryptCBC(String content, String aesKey){
|
||||
if(StringUtils.isBlank(content)){
|
||||
LOGGER.info("AES_CBC decrypt: the content is null!");
|
||||
return null;
|
||||
}
|
||||
//判断秘钥是否为16位
|
||||
if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
|
||||
try {
|
||||
//对密码进行编码
|
||||
byte[] bytes = aesKey.getBytes(ENCODING);
|
||||
//设置解密算法,生成秘钥
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
|
||||
//偏移
|
||||
IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
|
||||
// "算法/模式/补码方式"
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
|
||||
//选择解密
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
|
||||
|
||||
//先进行Base64解码
|
||||
byte[] decodeBase64 = Base64Utils.decodeFromString(content);
|
||||
|
||||
//根据待解密内容进行解密
|
||||
byte[] decrypted = cipher.doFinal(decodeBase64);
|
||||
//将字节数组转成字符串
|
||||
return new String(decrypted, ENCODING);
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("AES_CBC decrypt exception:" + e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}else {
|
||||
LOGGER.info("AES_CBC decrypt: the aesKey is null or error!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// AES支持三种长度的密钥:128位、192位、256位。
|
||||
// 代码中这种就是128位的加密密钥,16字节 * 8位/字节 = 128位。
|
||||
String random = RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz1234567890");
|
||||
System.out.println("随机key:" + random);
|
||||
System.out.println();
|
||||
|
||||
System.out.println("---------加密---------");
|
||||
String aesResult = encrypt("测试AES加密12", "huitu@77387.uurh");
|
||||
System.out.println("aes加密结果:" + aesResult);
|
||||
System.out.println();
|
||||
|
||||
System.out.println("---------解密---------");
|
||||
String decrypt = decrypt(aesResult, "huitu@77387.uurh");
|
||||
System.out.println("aes解密结果:" + decrypt);
|
||||
System.out.println();
|
||||
|
||||
|
||||
System.out.println("--------AES_CBC加密解密---------");
|
||||
String cbcResult = encryptCBC("测试AES加密12456", random);
|
||||
System.out.println("aes_cbc加密结果:" + cbcResult);
|
||||
System.out.println();
|
||||
|
||||
System.out.println("---------解密CBC---------");
|
||||
String cbcDecrypt = decryptCBC(cbcResult, random);
|
||||
System.out.println("aes解密结果:" + cbcDecrypt);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
@@ -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,155 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
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 String getDatePoor(Date endDate, Date nowDate)
|
||||
{
|
||||
long nd = 1000 * 24 * 60 * 60;
|
||||
long nh = 1000 * 60 * 60;
|
||||
long nm = 1000 * 60;
|
||||
// long ns = 1000;
|
||||
// 获得两个时间的毫秒时间差异
|
||||
long diff = endDate.getTime() - nowDate.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 + "分钟";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.core.redis.RedisService;
|
||||
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(RedisService.class).setCacheObject(getCacheKey(key), dictDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典缓存
|
||||
*
|
||||
* @param key 参数键
|
||||
* @return dictDatas 字典数据列表
|
||||
*/
|
||||
public static List<SysDictData> getDictCache(String key)
|
||||
{
|
||||
Object cacheObj = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNotNull(cacheObj))
|
||||
{
|
||||
List<SysDictData> dictDatas = StringUtils.cast(cacheObj);
|
||||
return dictDatas;
|
||||
}
|
||||
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.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas))
|
||||
{
|
||||
for (SysDictData dict : datas)
|
||||
{
|
||||
for (String value : dictValue.split(separator))
|
||||
{
|
||||
if (value.equals(dict.getDictValue()))
|
||||
{
|
||||
propertyString.append(dict.getDictLabel() + 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() + 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(RedisService.class).deleteObject(getCacheKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
public static void clearDictCache()
|
||||
{
|
||||
Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(Constants.SYS_DICT_KEY + "*");
|
||||
SpringUtils.getBean(RedisService.class).deleteObject(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cache key
|
||||
*
|
||||
* @param configKey 参数键
|
||||
* @return 缓存键key
|
||||
*/
|
||||
public static String getCacheKey(String configKey)
|
||||
{
|
||||
return Constants.SYS_DICT_KEY + configKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
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));
|
||||
String str = sw.toString();
|
||||
return str;
|
||||
}
|
||||
|
||||
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,61 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ImageMerge {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 加载第一张图片
|
||||
BufferedImage image1 = ImageIO.read(new File("G:\\download\\output.png"));
|
||||
// 加载第二张图片
|
||||
BufferedImage image2 = ImageIO.read(new File("G:\\download\\output2.png"));
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("G:\\download\\output.png");
|
||||
list.add("G:\\download\\output2.png");
|
||||
list.add("G:\\download\\output3.png");
|
||||
|
||||
mergeImages(list,null);
|
||||
}
|
||||
|
||||
|
||||
public static void mergeImages(List<String> imagePathList,String outputPath) throws Exception {
|
||||
// 加载第一张图片
|
||||
BufferedImage image1 = ImageIO.read(new File(imagePathList.get(0)));
|
||||
|
||||
Integer height = image1.getHeight();
|
||||
Integer width = image1.getWidth();
|
||||
|
||||
for (int i = 0; i < imagePathList.size(); i++) {
|
||||
if (i == 0) {
|
||||
continue;
|
||||
}
|
||||
BufferedImage image = ImageIO.read(new File(imagePathList.get(i)));
|
||||
height = height + image.getHeight();
|
||||
}
|
||||
// 创建一个新的图片用于合并
|
||||
BufferedImage combinedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
// 合并第一张图片
|
||||
Integer heightTemp = 0;
|
||||
Graphics2D g = null;
|
||||
for (int i = 0; i < imagePathList.size(); i++) {
|
||||
BufferedImage image = ImageIO.read(new File(imagePathList.get(i)));
|
||||
g = combinedImage.createGraphics();
|
||||
if (i == 0) {
|
||||
g.drawImage(image, 0, heightTemp, null);
|
||||
|
||||
} else {
|
||||
g.drawImage(image, 0, heightTemp, null);
|
||||
}
|
||||
heightTemp = heightTemp + image.getHeight();
|
||||
// 释放图形上下文
|
||||
g.dispose();
|
||||
}
|
||||
// 保存合并后的图片
|
||||
ImageIO.write(combinedImage, "PNG", new File(outputPath));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.ruoyi.common.utils.uuid.UUID;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ImageRotator {
|
||||
public static String rotate90DegreesCounterClockwise(String image, String path) {
|
||||
// 读取原始图片
|
||||
BufferedImage originalImage = null;
|
||||
try {
|
||||
originalImage = ImageIO.read(new File(image));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 创建一个旋转后的图片,宽度和高度交换
|
||||
BufferedImage rotatedImage = new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
// 创建Graphics2D对象,用于绘制旋转后的图片
|
||||
Graphics2D g2d = rotatedImage.createGraphics();
|
||||
|
||||
// 逆时针旋转90度
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.translate(originalImage.getHeight(), 0);
|
||||
at.rotate(Math.toRadians(90));
|
||||
|
||||
g2d.setTransform(at);
|
||||
g2d.drawImage(originalImage, 0, 0, null);
|
||||
g2d.dispose();
|
||||
|
||||
String outPath = path + UUID.randomUUID() + ".png";
|
||||
// 保存旋转后的图片
|
||||
try {
|
||||
ImageIO.write(rotatedImage, "PNG", new File(outPath));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return outPath;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String path = "G:\\download\\";
|
||||
// 读取原始图片
|
||||
BufferedImage originalImage = ImageIO.read(new File(path + "input.jpg"));
|
||||
|
||||
// 创建一个旋转后的图片,宽度和高度交换
|
||||
BufferedImage rotatedImage = new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
// 创建Graphics2D对象,用于绘制旋转后的图片
|
||||
Graphics2D g2d = rotatedImage.createGraphics();
|
||||
|
||||
// 逆时针旋转90度
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.translate(originalImage.getHeight(), 0);
|
||||
at.rotate(Math.toRadians(90));
|
||||
|
||||
g2d.setTransform(at);
|
||||
g2d.drawImage(originalImage, 0, 0, null);
|
||||
g2d.dispose();
|
||||
|
||||
// 保存旋转后的图片
|
||||
ImageIO.write(rotatedImage, "PNG", new File(path + "out.jpg"));
|
||||
|
||||
System.out.println("图片旋转完成。");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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() + "]";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user