mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-19 09:55:16 +08:00
Pre Merge pull request !7 from yinguofeng/master
This commit is contained in:
commit
b46b87ea83
@ -24,6 +24,7 @@
|
|||||||
* 容器改动 Tomcat 改为 并发性能更好的 undertow
|
* 容器改动 Tomcat 改为 并发性能更好的 undertow
|
||||||
* 代码生成模板 改为适配 Mybatis-Plus 的代码
|
* 代码生成模板 改为适配 Mybatis-Plus 的代码
|
||||||
* 项目修改为 maven多环境配置
|
* 项目修改为 maven多环境配置
|
||||||
|
* 集成 Hutool 5.X 并重写RuoYi部分功能
|
||||||
* 集成 Feign 接口化管理 Http 请求(如三方请求 支付,短信,推送等)
|
* 集成 Feign 接口化管理 Http 请求(如三方请求 支付,短信,推送等)
|
||||||
* 升级MybatisPlus 3.4.2
|
* 升级MybatisPlus 3.4.2
|
||||||
* 增加demo模块示例(给不会增加模块的小伙伴做参考)
|
* 增加demo模块示例(给不会增加模块的小伙伴做参考)
|
||||||
|
|||||||
16
pom.xml
16
pom.xml
@ -21,18 +21,17 @@
|
|||||||
<druid.version>1.2.4</druid.version>
|
<druid.version>1.2.4</druid.version>
|
||||||
<bitwalker.version>1.21</bitwalker.version>
|
<bitwalker.version>1.21</bitwalker.version>
|
||||||
<swagger.version>2.9.2</swagger.version>
|
<swagger.version>2.9.2</swagger.version>
|
||||||
<kaptcha.version>2.3.2</kaptcha.version>
|
|
||||||
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
|
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
|
||||||
<fastjson.version>1.2.75</fastjson.version>
|
<fastjson.version>1.2.75</fastjson.version>
|
||||||
<oshi.version>5.3.6</oshi.version>
|
<oshi.version>5.6.0</oshi.version>
|
||||||
<jna.version>5.6.0</jna.version>
|
<jna.version>5.7.0</jna.version>
|
||||||
<commons.io.version>2.5</commons.io.version>
|
<commons.io.version>2.5</commons.io.version>
|
||||||
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
||||||
<poi.version>4.1.2</poi.version>
|
<poi.version>4.1.2</poi.version>
|
||||||
<velocity.version>1.7</velocity.version>
|
<velocity.version>1.7</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
<mybatis-plus.version>3.4.2</mybatis-plus.version>
|
<mybatis-plus.version>3.4.2</mybatis-plus.version>
|
||||||
<hutool.version>5.4.0</hutool.version>
|
<hutool.version>5.5.8</hutool.version>
|
||||||
<feign.version>2.2.6.RELEASE</feign.version>
|
<feign.version>2.2.6.RELEASE</feign.version>
|
||||||
<feign-okhttp.version>11.0</feign-okhttp.version>
|
<feign-okhttp.version>11.0</feign-okhttp.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -76,7 +75,7 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 获取系统信息 -->
|
<!-- 获取系统信息 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.oshi</groupId>
|
<groupId>com.github.oshi</groupId>
|
||||||
@ -162,13 +161,6 @@
|
|||||||
<version>${jwt.version}</version>
|
<version>${jwt.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--验证码 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.penggle</groupId>
|
|
||||||
<artifactId>kaptcha</artifactId>
|
|
||||||
<version>${kaptcha.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
|||||||
@ -1,86 +1,120 @@
|
|||||||
package com.ruoyi.web.controller.common;
|
package com.ruoyi.web.controller.common;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.imageio.ImageIO;
|
import cn.hutool.captcha.CircleCaptcha;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import cn.hutool.captcha.ICaptcha;
|
||||||
|
import cn.hutool.captcha.LineCaptcha;
|
||||||
|
import cn.hutool.captcha.ShearCaptcha;
|
||||||
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
|
import cn.hutool.captcha.generator.MathGenerator;
|
||||||
|
import cn.hutool.captcha.generator.RandomGenerator;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.ruoyi.common.core.text.Convert;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.util.FastByteArrayOutputStream;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.google.code.kaptcha.Producer;
|
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
import com.ruoyi.common.utils.sign.Base64;
|
|
||||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码操作处理
|
* 验证码操作处理
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
public class CaptchaController
|
public class CaptchaController {
|
||||||
{
|
|
||||||
@Resource(name = "captchaProducer")
|
|
||||||
private Producer captchaProducer;
|
|
||||||
|
|
||||||
@Resource(name = "captchaProducerMath")
|
// 圆圈干扰验证码
|
||||||
private Producer captchaProducerMath;
|
@Resource(name = "CircleCaptcha")
|
||||||
|
private CircleCaptcha circleCaptcha;
|
||||||
|
// 线段干扰的验证码
|
||||||
|
@Resource(name = "LineCaptcha")
|
||||||
|
private LineCaptcha lineCaptcha;
|
||||||
|
// 扭曲干扰验证码
|
||||||
|
@Resource(name = "ShearCaptcha")
|
||||||
|
private ShearCaptcha shearCaptcha;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisCache redisCache;
|
private RedisCache redisCache;
|
||||||
|
|
||||||
// 验证码类型
|
// 验证码类型
|
||||||
@Value("${ruoyi.captchaType}")
|
@Value("${captcha.captchaType}")
|
||||||
private String captchaType;
|
private String captchaType;
|
||||||
|
// 验证码类别
|
||||||
|
@Value("${captcha.captchaCategory}")
|
||||||
|
private String captchaCategory;
|
||||||
|
// 数字验证码位数
|
||||||
|
@Value("${captcha.captchaNumberLength}")
|
||||||
|
private int numberLength;
|
||||||
|
// 字符验证码长度
|
||||||
|
@Value("${captcha.captchaCharLength}")
|
||||||
|
private int charLength;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*/
|
*/
|
||||||
@GetMapping("/captchaImage")
|
@GetMapping("/captchaImage")
|
||||||
public AjaxResult getCode(HttpServletResponse response) throws IOException
|
public AjaxResult getCode() {
|
||||||
{
|
|
||||||
// 保存验证码信息
|
// 保存验证码信息
|
||||||
String uuid = IdUtils.simpleUUID();
|
String uuid = IdUtil.simpleUUID();
|
||||||
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
|
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
|
||||||
|
|
||||||
String capStr = null, code = null;
|
String capStr = null, code = null;
|
||||||
BufferedImage image = null;
|
|
||||||
|
|
||||||
// 生成验证码
|
// 生成验证码
|
||||||
if ("math".equals(captchaType))
|
CodeGenerator codeGenerator;
|
||||||
{
|
if ("math".equals(captchaType)) {
|
||||||
String capText = captchaProducerMath.createText();
|
codeGenerator = new MathGenerator(numberLength);
|
||||||
capStr = capText.substring(0, capText.lastIndexOf("@"));
|
} else if ("char".equals(captchaType)) {
|
||||||
code = capText.substring(capText.lastIndexOf("@") + 1);
|
codeGenerator = new RandomGenerator(charLength);
|
||||||
image = captchaProducerMath.createImage(capStr);
|
} else {
|
||||||
|
throw new IllegalArgumentException("验证码类型异常");
|
||||||
}
|
}
|
||||||
else if ("char".equals(captchaType))
|
if ("line".equals(captchaCategory)) {
|
||||||
{
|
lineCaptcha.setGenerator(codeGenerator);
|
||||||
capStr = code = captchaProducer.createText();
|
capStr = lineCaptcha.getCode();
|
||||||
image = captchaProducer.createImage(capStr);
|
} else if ("circle".equals(captchaCategory)) {
|
||||||
|
circleCaptcha.setGenerator(codeGenerator);
|
||||||
|
capStr = circleCaptcha.getCode();
|
||||||
|
} else if ("shear".equals(captchaCategory)) {
|
||||||
|
shearCaptcha.setGenerator(codeGenerator);
|
||||||
|
capStr = shearCaptcha.getCode();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("验证码类别异常");
|
||||||
|
}
|
||||||
|
if ("math".equals(captchaType)) {
|
||||||
|
code = getCodeResult(capStr);
|
||||||
|
} else if ("char".equals(captchaType)) {
|
||||||
|
code = capStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||||
// 转换流信息写出
|
|
||||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ImageIO.write(image, "jpg", os);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
return AjaxResult.error(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
circleCaptcha.createImage(capStr);
|
||||||
AjaxResult ajax = AjaxResult.success();
|
AjaxResult ajax = AjaxResult.success();
|
||||||
ajax.put("uuid", uuid);
|
ajax.put("uuid", uuid);
|
||||||
ajax.put("img", Base64.encode(os.toByteArray()));
|
ajax.put("img", circleCaptcha.getImageBase64());
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCodeResult(String capStr) {
|
||||||
|
int a = Convert.toInt(StrUtil.sub(capStr, 0, numberLength).trim());
|
||||||
|
char operator = capStr.charAt(numberLength);
|
||||||
|
int b = Convert.toInt(StrUtil.sub(capStr, numberLength + 1, numberLength + 1 + numberLength).trim());
|
||||||
|
switch (operator) {
|
||||||
|
case '*':
|
||||||
|
return a * b + "";
|
||||||
|
case '+':
|
||||||
|
return a + b + "";
|
||||||
|
case '-':
|
||||||
|
return a - b + "";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,16 @@ ruoyi:
|
|||||||
profile: ${user.dir}/ruoyi/uploadPath
|
profile: ${user.dir}/ruoyi/uploadPath
|
||||||
# 获取ip地址开关
|
# 获取ip地址开关
|
||||||
addressEnabled: false
|
addressEnabled: false
|
||||||
|
|
||||||
|
captcha:
|
||||||
# 验证码类型 math 数组计算 char 字符验证
|
# 验证码类型 math 数组计算 char 字符验证
|
||||||
captchaType: math
|
captchaType: math
|
||||||
|
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
|
||||||
|
captchaCategory: circle
|
||||||
|
# 数字验证码位数
|
||||||
|
captchaNumberLength: 1
|
||||||
|
# 字符验证码长度
|
||||||
|
captchaCharLength: 4
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
server:
|
server:
|
||||||
@ -153,7 +161,7 @@ mybatis-plus:
|
|||||||
# 全局的entity的逻辑删除字段属性名
|
# 全局的entity的逻辑删除字段属性名
|
||||||
logicDeleteField: null
|
logicDeleteField: null
|
||||||
# 逻辑已删除值
|
# 逻辑已删除值
|
||||||
logicDeleteValue: 1
|
logicDeleteValue: 2
|
||||||
# 逻辑未删除值
|
# 逻辑未删除值
|
||||||
logicNotDeleteValue: 0
|
logicNotDeleteValue: 0
|
||||||
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
|
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
|
||||||
|
|||||||
@ -7,10 +7,11 @@ import java.nio.charset.Charset;
|
|||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型转换器
|
* 类型转换器
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class Convert
|
public class Convert
|
||||||
@ -19,7 +20,7 @@ public class Convert
|
|||||||
* 转换为字符串<br>
|
* 转换为字符串<br>
|
||||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -41,7 +42,7 @@ public class Convert
|
|||||||
* 转换为字符串<br>
|
* 转换为字符串<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -54,7 +55,7 @@ public class Convert
|
|||||||
* 转换为字符<br>
|
* 转换为字符<br>
|
||||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -78,7 +79,7 @@ public class Convert
|
|||||||
* 转换为字符<br>
|
* 转换为字符<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -91,7 +92,7 @@ public class Convert
|
|||||||
* 转换为byte<br>
|
* 转换为byte<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -129,7 +130,7 @@ public class Convert
|
|||||||
* 转换为byte<br>
|
* 转换为byte<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -142,7 +143,7 @@ public class Convert
|
|||||||
* 转换为Short<br>
|
* 转换为Short<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -180,7 +181,7 @@ public class Convert
|
|||||||
* 转换为Short<br>
|
* 转换为Short<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -193,7 +194,7 @@ public class Convert
|
|||||||
* 转换为Number<br>
|
* 转换为Number<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -227,7 +228,7 @@ public class Convert
|
|||||||
* 转换为Number<br>
|
* 转换为Number<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -240,7 +241,7 @@ public class Convert
|
|||||||
* 转换为int<br>
|
* 转换为int<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -278,7 +279,7 @@ public class Convert
|
|||||||
* 转换为int<br>
|
* 转换为int<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -289,7 +290,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为Integer数组<br>
|
* 转换为Integer数组<br>
|
||||||
*
|
*
|
||||||
* @param str 被转换的值
|
* @param str 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -300,7 +301,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为Long数组<br>
|
* 转换为Long数组<br>
|
||||||
*
|
*
|
||||||
* @param str 被转换的值
|
* @param str 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -311,7 +312,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为Integer数组<br>
|
* 转换为Integer数组<br>
|
||||||
*
|
*
|
||||||
* @param split 分隔符
|
* @param split 分隔符
|
||||||
* @param split 被转换的值
|
* @param split 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -334,7 +335,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为Long数组<br>
|
* 转换为Long数组<br>
|
||||||
*
|
*
|
||||||
* @param split 分隔符
|
* @param split 分隔符
|
||||||
* @param str 被转换的值
|
* @param str 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -357,7 +358,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为String数组<br>
|
* 转换为String数组<br>
|
||||||
*
|
*
|
||||||
* @param str 被转换的值
|
* @param str 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -368,7 +369,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为String数组<br>
|
* 转换为String数组<br>
|
||||||
*
|
*
|
||||||
* @param split 分隔符
|
* @param split 分隔符
|
||||||
* @param split 被转换的值
|
* @param split 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -382,7 +383,7 @@ public class Convert
|
|||||||
* 转换为long<br>
|
* 转换为long<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -421,7 +422,7 @@ public class Convert
|
|||||||
* 转换为long<br>
|
* 转换为long<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -434,7 +435,7 @@ public class Convert
|
|||||||
* 转换为double<br>
|
* 转换为double<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -473,7 +474,7 @@ public class Convert
|
|||||||
* 转换为double<br>
|
* 转换为double<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -486,7 +487,7 @@ public class Convert
|
|||||||
* 转换为Float<br>
|
* 转换为Float<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -524,7 +525,7 @@ public class Convert
|
|||||||
* 转换为Float<br>
|
* 转换为Float<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -537,7 +538,7 @@ public class Convert
|
|||||||
* 转换为boolean<br>
|
* 转换为boolean<br>
|
||||||
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
|
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -583,7 +584,7 @@ public class Convert
|
|||||||
* 转换为boolean<br>
|
* 转换为boolean<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -595,7 +596,7 @@ public class Convert
|
|||||||
/**
|
/**
|
||||||
* 转换为Enum对象<br>
|
* 转换为Enum对象<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
*
|
*
|
||||||
* @param clazz Enum的Class
|
* @param clazz Enum的Class
|
||||||
* @param value 值
|
* @param value 值
|
||||||
* @param defaultValue 默认值
|
* @param defaultValue 默认值
|
||||||
@ -631,7 +632,7 @@ public class Convert
|
|||||||
/**
|
/**
|
||||||
* 转换为Enum对象<br>
|
* 转换为Enum对象<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
*
|
*
|
||||||
* @param clazz Enum的Class
|
* @param clazz Enum的Class
|
||||||
* @param value 值
|
* @param value 值
|
||||||
* @return Enum
|
* @return Enum
|
||||||
@ -645,7 +646,7 @@ public class Convert
|
|||||||
* 转换为BigInteger<br>
|
* 转换为BigInteger<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -683,7 +684,7 @@ public class Convert
|
|||||||
* 转换为BigInteger<br>
|
* 转换为BigInteger<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -696,7 +697,7 @@ public class Convert
|
|||||||
* 转换为BigDecimal<br>
|
* 转换为BigDecimal<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @param defaultValue 转换错误时的默认值
|
* @param defaultValue 转换错误时的默认值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
@ -742,7 +743,7 @@ public class Convert
|
|||||||
* 转换为BigDecimal<br>
|
* 转换为BigDecimal<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -754,7 +755,7 @@ public class Convert
|
|||||||
/**
|
/**
|
||||||
* 将对象转为字符串<br>
|
* 将对象转为字符串<br>
|
||||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||||
*
|
*
|
||||||
* @param obj 对象
|
* @param obj 对象
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
*/
|
*/
|
||||||
@ -766,7 +767,7 @@ public class Convert
|
|||||||
/**
|
/**
|
||||||
* 将对象转为字符串<br>
|
* 将对象转为字符串<br>
|
||||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||||
*
|
*
|
||||||
* @param obj 对象
|
* @param obj 对象
|
||||||
* @param charsetName 字符集
|
* @param charsetName 字符集
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
@ -779,7 +780,7 @@ public class Convert
|
|||||||
/**
|
/**
|
||||||
* 将对象转为字符串<br>
|
* 将对象转为字符串<br>
|
||||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||||
*
|
*
|
||||||
* @param obj 对象
|
* @param obj 对象
|
||||||
* @param charset 字符集
|
* @param charset 字符集
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
@ -795,9 +796,14 @@ public class Convert
|
|||||||
{
|
{
|
||||||
return (String) obj;
|
return (String) obj;
|
||||||
}
|
}
|
||||||
else if (obj instanceof byte[] || obj instanceof Byte[])
|
else if (obj instanceof byte[])
|
||||||
{
|
{
|
||||||
return str((Byte[]) obj, charset);
|
return str((byte[]) obj, charset);
|
||||||
|
}
|
||||||
|
else if (obj instanceof Byte[])
|
||||||
|
{
|
||||||
|
byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj);
|
||||||
|
return str(bytes, charset);
|
||||||
}
|
}
|
||||||
else if (obj instanceof ByteBuffer)
|
else if (obj instanceof ByteBuffer)
|
||||||
{
|
{
|
||||||
@ -808,7 +814,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将byte数组转为字符串
|
* 将byte数组转为字符串
|
||||||
*
|
*
|
||||||
* @param bytes byte数组
|
* @param bytes byte数组
|
||||||
* @param charset 字符集
|
* @param charset 字符集
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
@ -820,7 +826,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 解码字节码
|
* 解码字节码
|
||||||
*
|
*
|
||||||
* @param data 字符串
|
* @param data 字符串
|
||||||
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
|
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
|
||||||
* @return 解码后的字符串
|
* @return 解码后的字符串
|
||||||
@ -841,7 +847,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将编码的byteBuffer数据转换为字符串
|
* 将编码的byteBuffer数据转换为字符串
|
||||||
*
|
*
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
* @param charset 字符集,如果为空使用当前系统字符集
|
* @param charset 字符集,如果为空使用当前系统字符集
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
@ -858,7 +864,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将编码的byteBuffer数据转换为字符串
|
* 将编码的byteBuffer数据转换为字符串
|
||||||
*
|
*
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
* @param charset 字符集,如果为空使用当前系统字符集
|
* @param charset 字符集,如果为空使用当前系统字符集
|
||||||
* @return 字符串
|
* @return 字符串
|
||||||
@ -875,7 +881,7 @@ public class Convert
|
|||||||
// ----------------------------------------------------------------------- 全角半角转换
|
// ----------------------------------------------------------------------- 全角半角转换
|
||||||
/**
|
/**
|
||||||
* 半角转全角
|
* 半角转全角
|
||||||
*
|
*
|
||||||
* @param input String.
|
* @param input String.
|
||||||
* @return 全角字符串.
|
* @return 全角字符串.
|
||||||
*/
|
*/
|
||||||
@ -886,7 +892,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 半角转全角
|
* 半角转全角
|
||||||
*
|
*
|
||||||
* @param input String
|
* @param input String
|
||||||
* @param notConvertSet 不替换的字符集合
|
* @param notConvertSet 不替换的字符集合
|
||||||
* @return 全角字符串.
|
* @return 全角字符串.
|
||||||
@ -917,7 +923,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 全角转半角
|
* 全角转半角
|
||||||
*
|
*
|
||||||
* @param input String.
|
* @param input String.
|
||||||
* @return 半角字符串
|
* @return 半角字符串
|
||||||
*/
|
*/
|
||||||
@ -928,7 +934,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 替换全角为半角
|
* 替换全角为半角
|
||||||
*
|
*
|
||||||
* @param text 文本
|
* @param text 文本
|
||||||
* @param notConvertSet 不替换的字符集合
|
* @param notConvertSet 不替换的字符集合
|
||||||
* @return 替换后的字符
|
* @return 替换后的字符
|
||||||
@ -960,7 +966,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
|
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
|
||||||
*
|
*
|
||||||
* @param n 数字
|
* @param n 数字
|
||||||
* @return 中文大写数字
|
* @return 中文大写数字
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,114 +0,0 @@
|
|||||||
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 = new BigDecimal("1");
|
|
||||||
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,228 +0,0 @@
|
|||||||
package com.ruoyi.common.utils;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.geom.AffineTransform;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Random;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码工具类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class VerifyCodeUtils
|
|
||||||
{
|
|
||||||
// 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
|
|
||||||
public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
private static Random random = new SecureRandom();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用系统默认字符源生成验证码
|
|
||||||
*
|
|
||||||
* @param verifySize 验证码长度
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String generateVerifyCode(int verifySize)
|
|
||||||
{
|
|
||||||
return generateVerifyCode(verifySize, VERIFY_CODES);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用指定源生成验证码
|
|
||||||
*
|
|
||||||
* @param verifySize 验证码长度
|
|
||||||
* @param sources 验证码字符源
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String generateVerifyCode(int verifySize, String sources)
|
|
||||||
{
|
|
||||||
if (sources == null || sources.length() == 0)
|
|
||||||
{
|
|
||||||
sources = VERIFY_CODES;
|
|
||||||
}
|
|
||||||
int codesLen = sources.length();
|
|
||||||
Random rand = new Random(System.currentTimeMillis());
|
|
||||||
StringBuilder verifyCode = new StringBuilder(verifySize);
|
|
||||||
for (int i = 0; i < verifySize; i++)
|
|
||||||
{
|
|
||||||
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
|
|
||||||
}
|
|
||||||
return verifyCode.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 输出指定验证码图片流
|
|
||||||
*
|
|
||||||
* @param w
|
|
||||||
* @param h
|
|
||||||
* @param os
|
|
||||||
* @param code
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException
|
|
||||||
{
|
|
||||||
int verifySize = code.length();
|
|
||||||
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
|
||||||
Random rand = new Random();
|
|
||||||
Graphics2D g2 = image.createGraphics();
|
|
||||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
Color[] colors = new Color[5];
|
|
||||||
Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
|
|
||||||
Color.ORANGE, Color.PINK, Color.YELLOW };
|
|
||||||
float[] fractions = new float[colors.length];
|
|
||||||
for (int i = 0; i < colors.length; i++)
|
|
||||||
{
|
|
||||||
colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
|
|
||||||
fractions[i] = rand.nextFloat();
|
|
||||||
}
|
|
||||||
Arrays.sort(fractions);
|
|
||||||
|
|
||||||
g2.setColor(Color.GRAY);// 设置边框色
|
|
||||||
g2.fillRect(0, 0, w, h);
|
|
||||||
|
|
||||||
Color c = getRandColor(200, 250);
|
|
||||||
g2.setColor(c);// 设置背景色
|
|
||||||
g2.fillRect(0, 2, w, h - 4);
|
|
||||||
|
|
||||||
// 绘制干扰线
|
|
||||||
Random random = new Random();
|
|
||||||
g2.setColor(getRandColor(160, 200));// 设置线条的颜色
|
|
||||||
for (int i = 0; i < 20; i++)
|
|
||||||
{
|
|
||||||
int x = random.nextInt(w - 1);
|
|
||||||
int y = random.nextInt(h - 1);
|
|
||||||
int xl = random.nextInt(6) + 1;
|
|
||||||
int yl = random.nextInt(12) + 1;
|
|
||||||
g2.drawLine(x, y, x + xl + 40, y + yl + 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加噪点
|
|
||||||
float yawpRate = 0.05f;// 噪声率
|
|
||||||
int area = (int) (yawpRate * w * h);
|
|
||||||
for (int i = 0; i < area; i++)
|
|
||||||
{
|
|
||||||
int x = random.nextInt(w);
|
|
||||||
int y = random.nextInt(h);
|
|
||||||
int rgb = getRandomIntColor();
|
|
||||||
image.setRGB(x, y, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
shear(g2, w, h, c);// 使图片扭曲
|
|
||||||
|
|
||||||
g2.setColor(getRandColor(100, 160));
|
|
||||||
int fontSize = h - 4;
|
|
||||||
Font font = new Font("Algerian", Font.ITALIC, fontSize);
|
|
||||||
g2.setFont(font);
|
|
||||||
char[] chars = code.toCharArray();
|
|
||||||
for (int i = 0; i < verifySize; i++)
|
|
||||||
{
|
|
||||||
AffineTransform affine = new AffineTransform();
|
|
||||||
affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
|
|
||||||
(w / verifySize) * i + fontSize / 2, h / 2);
|
|
||||||
g2.setTransform(affine);
|
|
||||||
g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
g2.dispose();
|
|
||||||
ImageIO.write(image, "jpg", os);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Color getRandColor(int fc, int bc)
|
|
||||||
{
|
|
||||||
if (fc > 255) {
|
|
||||||
fc = 255;
|
|
||||||
}
|
|
||||||
if (bc > 255) {
|
|
||||||
bc = 255;
|
|
||||||
}
|
|
||||||
int r = fc + random.nextInt(bc - fc);
|
|
||||||
int g = fc + random.nextInt(bc - fc);
|
|
||||||
int b = fc + random.nextInt(bc - fc);
|
|
||||||
return new Color(r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getRandomIntColor()
|
|
||||||
{
|
|
||||||
int[] rgb = getRandomRgb();
|
|
||||||
int color = 0;
|
|
||||||
for (int c : rgb)
|
|
||||||
{
|
|
||||||
color = color << 8;
|
|
||||||
color = color | c;
|
|
||||||
}
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int[] getRandomRgb()
|
|
||||||
{
|
|
||||||
int[] rgb = new int[3];
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
rgb[i] = random.nextInt(255);
|
|
||||||
}
|
|
||||||
return rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void shear(Graphics g, int w1, int h1, Color color)
|
|
||||||
{
|
|
||||||
shearX(g, w1, h1, color);
|
|
||||||
shearY(g, w1, h1, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void shearX(Graphics g, int w1, int h1, Color color)
|
|
||||||
{
|
|
||||||
|
|
||||||
int period = random.nextInt(2);
|
|
||||||
|
|
||||||
boolean borderGap = true;
|
|
||||||
int frames = 1;
|
|
||||||
int phase = random.nextInt(2);
|
|
||||||
|
|
||||||
for (int i = 0; i < h1; i++)
|
|
||||||
{
|
|
||||||
double d = (double) (period >> 1)
|
|
||||||
* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
|
|
||||||
g.copyArea(0, i, w1, 1, (int) d, 0);
|
|
||||||
if (borderGap)
|
|
||||||
{
|
|
||||||
g.setColor(color);
|
|
||||||
g.drawLine((int) d, i, 0, i);
|
|
||||||
g.drawLine((int) d + w1, i, w1, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void shearY(Graphics g, int w1, int h1, Color color)
|
|
||||||
{
|
|
||||||
|
|
||||||
int period = random.nextInt(40) + 10; // 50;
|
|
||||||
|
|
||||||
boolean borderGap = true;
|
|
||||||
int frames = 20;
|
|
||||||
int phase = 7;
|
|
||||||
for (int i = 0; i < w1; i++)
|
|
||||||
{
|
|
||||||
double d = (double) (period >> 1)
|
|
||||||
* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
|
|
||||||
g.copyArea(i, 0, 1, h1, 0, (int) d);
|
|
||||||
if (borderGap)
|
|
||||||
{
|
|
||||||
g.setColor(color);
|
|
||||||
g.drawLine(i, (int) d, i, 0);
|
|
||||||
g.drawLine(i, (int) d + h1, i, h1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,6 +2,8 @@ package com.ruoyi.common.utils.file;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
@ -11,7 +13,6 @@ import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
|
|||||||
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传工具类
|
* 文件上传工具类
|
||||||
@ -123,7 +124,7 @@ public class FileUploadUtils
|
|||||||
{
|
{
|
||||||
String fileName = file.getOriginalFilename();
|
String fileName = file.getOriginalFilename();
|
||||||
String extension = getExtension(file);
|
String extension = getExtension(file);
|
||||||
fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
|
fileName = DateUtils.datePath() + "/" + IdUtil.fastUUID() + "." + extension;
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
package com.ruoyi.common.utils.sign;
|
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Md5加密方法
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class Md5Utils
|
|
||||||
{
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(Md5Utils.class);
|
|
||||||
|
|
||||||
private static byte[] md5(String s)
|
|
||||||
{
|
|
||||||
MessageDigest algorithm;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
algorithm = MessageDigest.getInstance("MD5");
|
|
||||||
algorithm.reset();
|
|
||||||
algorithm.update(s.getBytes("UTF-8"));
|
|
||||||
byte[] messageDigest = algorithm.digest();
|
|
||||||
return messageDigest;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.error("MD5 Error...", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String toHex(byte hash[])
|
|
||||||
{
|
|
||||||
if (hash == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
StringBuffer buf = new StringBuffer(hash.length * 2);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hash.length; i++)
|
|
||||||
{
|
|
||||||
if ((hash[i] & 0xff) < 0x10)
|
|
||||||
{
|
|
||||||
buf.append("0");
|
|
||||||
}
|
|
||||||
buf.append(Long.toString(hash[i] & 0xff, 16));
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String hash(String s)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.error("not supported charset...{}", e);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package com.ruoyi.common.utils.uuid;
|
|
||||||
|
|
||||||
import com.ruoyi.common.utils.uuid.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ID生成器工具类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class IdUtils
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 获取随机UUID
|
|
||||||
*
|
|
||||||
* @return 随机UUID
|
|
||||||
*/
|
|
||||||
public static String randomUUID()
|
|
||||||
{
|
|
||||||
return UUID.randomUUID().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 简化的UUID,去掉了横线
|
|
||||||
*
|
|
||||||
* @return 简化的UUID,去掉了横线
|
|
||||||
*/
|
|
||||||
public static String simpleUUID()
|
|
||||||
{
|
|
||||||
return UUID.randomUUID().toString(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
|
|
||||||
*
|
|
||||||
* @return 随机UUID
|
|
||||||
*/
|
|
||||||
public static String fastUUID()
|
|
||||||
{
|
|
||||||
return UUID.fastUUID().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
|
|
||||||
*
|
|
||||||
* @return 简化的UUID,去掉了横线
|
|
||||||
*/
|
|
||||||
public static String fastSimpleUUID()
|
|
||||||
{
|
|
||||||
return UUID.fastUUID().toString(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,484 +0,0 @@
|
|||||||
package com.ruoyi.common.utils.uuid;
|
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
import com.ruoyi.common.exception.UtilException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提供通用唯一识别码(universally unique identifier)(UUID)实现
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = -1185015143654744140L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SecureRandom 的单例
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static class Holder
|
|
||||||
{
|
|
||||||
static final SecureRandom numberGenerator = getSecureRandom();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 此UUID的最高64有效位 */
|
|
||||||
private final long mostSigBits;
|
|
||||||
|
|
||||||
/** 此UUID的最低64有效位 */
|
|
||||||
private final long leastSigBits;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 私有构造
|
|
||||||
*
|
|
||||||
* @param data 数据
|
|
||||||
*/
|
|
||||||
private UUID(byte[] data)
|
|
||||||
{
|
|
||||||
long msb = 0;
|
|
||||||
long lsb = 0;
|
|
||||||
assert data.length == 16 : "data must be 16 bytes in length";
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
msb = (msb << 8) | (data[i] & 0xff);
|
|
||||||
}
|
|
||||||
for (int i = 8; i < 16; i++)
|
|
||||||
{
|
|
||||||
lsb = (lsb << 8) | (data[i] & 0xff);
|
|
||||||
}
|
|
||||||
this.mostSigBits = msb;
|
|
||||||
this.leastSigBits = lsb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用指定的数据构造新的 UUID。
|
|
||||||
*
|
|
||||||
* @param mostSigBits 用于 {@code UUID} 的最高有效 64 位
|
|
||||||
* @param leastSigBits 用于 {@code UUID} 的最低有效 64 位
|
|
||||||
*/
|
|
||||||
public UUID(long mostSigBits, long leastSigBits)
|
|
||||||
{
|
|
||||||
this.mostSigBits = mostSigBits;
|
|
||||||
this.leastSigBits = leastSigBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。
|
|
||||||
*
|
|
||||||
* @return 随机生成的 {@code UUID}
|
|
||||||
*/
|
|
||||||
public static UUID fastUUID()
|
|
||||||
{
|
|
||||||
return randomUUID(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
|
||||||
*
|
|
||||||
* @return 随机生成的 {@code UUID}
|
|
||||||
*/
|
|
||||||
public static UUID randomUUID()
|
|
||||||
{
|
|
||||||
return randomUUID(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
|
||||||
*
|
|
||||||
* @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
|
|
||||||
* @return 随机生成的 {@code UUID}
|
|
||||||
*/
|
|
||||||
public static UUID randomUUID(boolean isSecure)
|
|
||||||
{
|
|
||||||
final Random ng = isSecure ? Holder.numberGenerator : getRandom();
|
|
||||||
|
|
||||||
byte[] randomBytes = new byte[16];
|
|
||||||
ng.nextBytes(randomBytes);
|
|
||||||
randomBytes[6] &= 0x0f; /* clear version */
|
|
||||||
randomBytes[6] |= 0x40; /* set to version 4 */
|
|
||||||
randomBytes[8] &= 0x3f; /* clear variant */
|
|
||||||
randomBytes[8] |= 0x80; /* set to IETF variant */
|
|
||||||
return new UUID(randomBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。
|
|
||||||
*
|
|
||||||
* @param name 用于构造 UUID 的字节数组。
|
|
||||||
*
|
|
||||||
* @return 根据指定数组生成的 {@code UUID}
|
|
||||||
*/
|
|
||||||
public static UUID nameUUIDFromBytes(byte[] name)
|
|
||||||
{
|
|
||||||
MessageDigest md;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException nsae)
|
|
||||||
{
|
|
||||||
throw new InternalError("MD5 not supported");
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(name);
|
|
||||||
md5Bytes[6] &= 0x0f; /* clear version */
|
|
||||||
md5Bytes[6] |= 0x30; /* set to version 3 */
|
|
||||||
md5Bytes[8] &= 0x3f; /* clear variant */
|
|
||||||
md5Bytes[8] |= 0x80; /* set to IETF variant */
|
|
||||||
return new UUID(md5Bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。
|
|
||||||
*
|
|
||||||
* @param name 指定 {@code UUID} 字符串
|
|
||||||
* @return 具有指定值的 {@code UUID}
|
|
||||||
* @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static UUID fromString(String name)
|
|
||||||
{
|
|
||||||
String[] components = name.split("-");
|
|
||||||
if (components.length != 5)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Invalid UUID string: " + name);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
components[i] = "0x" + components[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
long mostSigBits = Long.decode(components[0]).longValue();
|
|
||||||
mostSigBits <<= 16;
|
|
||||||
mostSigBits |= Long.decode(components[1]).longValue();
|
|
||||||
mostSigBits <<= 16;
|
|
||||||
mostSigBits |= Long.decode(components[2]).longValue();
|
|
||||||
|
|
||||||
long leastSigBits = Long.decode(components[3]).longValue();
|
|
||||||
leastSigBits <<= 48;
|
|
||||||
leastSigBits |= Long.decode(components[4]).longValue();
|
|
||||||
|
|
||||||
return new UUID(mostSigBits, leastSigBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回此 UUID 的 128 位值中的最低有效 64 位。
|
|
||||||
*
|
|
||||||
* @return 此 UUID 的 128 位值中的最低有效 64 位。
|
|
||||||
*/
|
|
||||||
public long getLeastSignificantBits()
|
|
||||||
{
|
|
||||||
return leastSigBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回此 UUID 的 128 位值中的最高有效 64 位。
|
|
||||||
*
|
|
||||||
* @return 此 UUID 的 128 位值中最高有效 64 位。
|
|
||||||
*/
|
|
||||||
public long getMostSignificantBits()
|
|
||||||
{
|
|
||||||
return mostSigBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。
|
|
||||||
* <p>
|
|
||||||
* 版本号具有以下含意:
|
|
||||||
* <ul>
|
|
||||||
* <li>1 基于时间的 UUID
|
|
||||||
* <li>2 DCE 安全 UUID
|
|
||||||
* <li>3 基于名称的 UUID
|
|
||||||
* <li>4 随机生成的 UUID
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @return 此 {@code UUID} 的版本号
|
|
||||||
*/
|
|
||||||
public int version()
|
|
||||||
{
|
|
||||||
// Version is bits masked by 0x000000000000F000 in MS long
|
|
||||||
return (int) ((mostSigBits >> 12) & 0x0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。
|
|
||||||
* <p>
|
|
||||||
* 变体号具有以下含意:
|
|
||||||
* <ul>
|
|
||||||
* <li>0 为 NCS 向后兼容保留
|
|
||||||
* <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF RFC 4122</a>(Leach-Salz), 用于此类
|
|
||||||
* <li>6 保留,微软向后兼容
|
|
||||||
* <li>7 保留供以后定义使用
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @return 此 {@code UUID} 相关联的变体号
|
|
||||||
*/
|
|
||||||
public int variant()
|
|
||||||
{
|
|
||||||
// This field is composed of a varying number of bits.
|
|
||||||
// 0 - - Reserved for NCS backward compatibility
|
|
||||||
// 1 0 - The IETF aka Leach-Salz variant (used by this class)
|
|
||||||
// 1 1 0 Reserved, Microsoft backward compatibility
|
|
||||||
// 1 1 1 Reserved for future definition.
|
|
||||||
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与此 UUID 相关联的时间戳值。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。<br>
|
|
||||||
* 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。<br>
|
|
||||||
* 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。
|
|
||||||
*/
|
|
||||||
public long timestamp() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
checkTimeBase();
|
|
||||||
return (mostSigBits & 0x0FFFL) << 48//
|
|
||||||
| ((mostSigBits >> 16) & 0x0FFFFL) << 32//
|
|
||||||
| mostSigBits >>> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与此 UUID 相关联的时钟序列值。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。
|
|
||||||
* <p>
|
|
||||||
* {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出
|
|
||||||
* UnsupportedOperationException。
|
|
||||||
*
|
|
||||||
* @return 此 {@code UUID} 的时钟序列
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
|
||||||
*/
|
|
||||||
public int clockSequence() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
checkTimeBase();
|
|
||||||
return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与此 UUID 相关的节点值。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。
|
|
||||||
* <p>
|
|
||||||
* 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。<br>
|
|
||||||
* 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
|
||||||
*
|
|
||||||
* @return 此 {@code UUID} 的节点值
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
|
||||||
*/
|
|
||||||
public long node() throws UnsupportedOperationException
|
|
||||||
{
|
|
||||||
checkTimeBase();
|
|
||||||
return leastSigBits & 0x0000FFFFFFFFFFFFL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回此{@code UUID} 的字符串表现形式。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* UUID 的字符串表示形式由此 BNF 描述:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
|
||||||
* time_low = 4*<hexOctet>
|
|
||||||
* time_mid = 2*<hexOctet>
|
|
||||||
* time_high_and_version = 2*<hexOctet>
|
|
||||||
* variant_and_sequence = 2*<hexOctet>
|
|
||||||
* node = 6*<hexOctet>
|
|
||||||
* hexOctet = <hexDigit><hexDigit>
|
|
||||||
* hexDigit = [0-9a-fA-F]
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* </blockquote>
|
|
||||||
*
|
|
||||||
* @return 此{@code UUID} 的字符串表现形式
|
|
||||||
* @see #toString(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return toString(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回此{@code UUID} 的字符串表现形式。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* UUID 的字符串表示形式由此 BNF 描述:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
|
||||||
* time_low = 4*<hexOctet>
|
|
||||||
* time_mid = 2*<hexOctet>
|
|
||||||
* time_high_and_version = 2*<hexOctet>
|
|
||||||
* variant_and_sequence = 2*<hexOctet>
|
|
||||||
* node = 6*<hexOctet>
|
|
||||||
* hexOctet = <hexDigit><hexDigit>
|
|
||||||
* hexDigit = [0-9a-fA-F]
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* </blockquote>
|
|
||||||
*
|
|
||||||
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
|
|
||||||
* @return 此{@code UUID} 的字符串表现形式
|
|
||||||
*/
|
|
||||||
public String toString(boolean isSimple)
|
|
||||||
{
|
|
||||||
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
|
|
||||||
// time_low
|
|
||||||
builder.append(digits(mostSigBits >> 32, 8));
|
|
||||||
if (false == isSimple)
|
|
||||||
{
|
|
||||||
builder.append('-');
|
|
||||||
}
|
|
||||||
// time_mid
|
|
||||||
builder.append(digits(mostSigBits >> 16, 4));
|
|
||||||
if (false == isSimple)
|
|
||||||
{
|
|
||||||
builder.append('-');
|
|
||||||
}
|
|
||||||
// time_high_and_version
|
|
||||||
builder.append(digits(mostSigBits, 4));
|
|
||||||
if (false == isSimple)
|
|
||||||
{
|
|
||||||
builder.append('-');
|
|
||||||
}
|
|
||||||
// variant_and_sequence
|
|
||||||
builder.append(digits(leastSigBits >> 48, 4));
|
|
||||||
if (false == isSimple)
|
|
||||||
{
|
|
||||||
builder.append('-');
|
|
||||||
}
|
|
||||||
// node
|
|
||||||
builder.append(digits(leastSigBits, 12));
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回此 UUID 的哈希码。
|
|
||||||
*
|
|
||||||
* @return UUID 的哈希码值。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode()
|
|
||||||
{
|
|
||||||
long hilo = mostSigBits ^ leastSigBits;
|
|
||||||
return ((int) (hilo >> 32)) ^ (int) hilo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将此对象与指定对象比较。
|
|
||||||
* <p>
|
|
||||||
* 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。
|
|
||||||
*
|
|
||||||
* @param obj 要与之比较的对象
|
|
||||||
*
|
|
||||||
* @return 如果对象相同,则返回 {@code true};否则返回 {@code false}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
|
||||||
if ((null == obj) || (obj.getClass() != UUID.class))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UUID id = (UUID) obj;
|
|
||||||
return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comparison Operations
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将此 UUID 与指定的 UUID 比较。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。
|
|
||||||
*
|
|
||||||
* @param val 与此 UUID 比较的 UUID
|
|
||||||
*
|
|
||||||
* @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int compareTo(UUID val)
|
|
||||||
{
|
|
||||||
// The ordering is intentionally set up so that the UUIDs
|
|
||||||
// can simply be numerically compared as two numbers
|
|
||||||
return (this.mostSigBits < val.mostSigBits ? -1 : //
|
|
||||||
(this.mostSigBits > val.mostSigBits ? 1 : //
|
|
||||||
(this.leastSigBits < val.leastSigBits ? -1 : //
|
|
||||||
(this.leastSigBits > val.leastSigBits ? 1 : //
|
|
||||||
0))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------
|
|
||||||
// Private method start
|
|
||||||
/**
|
|
||||||
* 返回指定数字对应的hex值
|
|
||||||
*
|
|
||||||
* @param val 值
|
|
||||||
* @param digits 位
|
|
||||||
* @return 值
|
|
||||||
*/
|
|
||||||
private static String digits(long val, int digits)
|
|
||||||
{
|
|
||||||
long hi = 1L << (digits * 4);
|
|
||||||
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查是否为time-based版本UUID
|
|
||||||
*/
|
|
||||||
private void checkTimeBase()
|
|
||||||
{
|
|
||||||
if (version() != 1)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException("Not a time-based UUID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
|
|
||||||
*
|
|
||||||
* @return {@link SecureRandom}
|
|
||||||
*/
|
|
||||||
public static SecureRandom getSecureRandom()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return SecureRandom.getInstance("SHA1PRNG");
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException e)
|
|
||||||
{
|
|
||||||
throw new UtilException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取随机数生成器对象<br>
|
|
||||||
* ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
|
|
||||||
*
|
|
||||||
* @return {@link ThreadLocalRandom}
|
|
||||||
*/
|
|
||||||
public static ThreadLocalRandom getRandom()
|
|
||||||
{
|
|
||||||
return ThreadLocalRandom.current();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -55,18 +55,6 @@
|
|||||||
<artifactId>druid-spring-boot-starter</artifactId>
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 验证码 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.penggle</groupId>
|
|
||||||
<artifactId>kaptcha</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 获取系统信息 -->
|
<!-- 获取系统信息 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.oshi</groupId>
|
<groupId>com.github.oshi</groupId>
|
||||||
|
|||||||
@ -1,83 +1,55 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.awt.*;
|
||||||
|
|
||||||
|
import cn.hutool.captcha.*;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
|
||||||
import com.google.code.kaptcha.util.Config;
|
|
||||||
import static com.google.code.kaptcha.Constants.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码配置
|
* 验证码配置
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class CaptchaConfig
|
public class CaptchaConfig {
|
||||||
{
|
|
||||||
@Bean(name = "captchaProducer")
|
private final int width = 160;
|
||||||
public DefaultKaptcha getKaptchaBean()
|
private final int height = 60;
|
||||||
{
|
private final Color background = Color.PINK;
|
||||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
private final Font font = new Font("Arial", Font.BOLD, 48);
|
||||||
Properties properties = new Properties();
|
|
||||||
// 是否有边框 默认为true 我们可以自己设置yes,no
|
/**
|
||||||
properties.setProperty(KAPTCHA_BORDER, "yes");
|
* 圆圈干扰验证码
|
||||||
// 验证码文本字符颜色 默认为Color.BLACK
|
*/
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
|
@Bean(name = "CircleCaptcha")
|
||||||
// 验证码图片宽度 默认为200
|
public CircleCaptcha getCircleCaptcha() {
|
||||||
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
|
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height);
|
||||||
// 验证码图片高度 默认为50
|
captcha.setBackground(background);
|
||||||
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
|
captcha.setFont(font);
|
||||||
// 验证码文本字符大小 默认为40
|
return captcha;
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
|
|
||||||
// KAPTCHA_SESSION_KEY
|
|
||||||
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
|
|
||||||
// 验证码文本字符长度 默认为5
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
|
|
||||||
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
|
|
||||||
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
|
|
||||||
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
|
|
||||||
Config config = new Config(properties);
|
|
||||||
defaultKaptcha.setConfig(config);
|
|
||||||
return defaultKaptcha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "captchaProducerMath")
|
/**
|
||||||
public DefaultKaptcha getKaptchaBeanMath()
|
* 线段干扰的验证码
|
||||||
{
|
*/
|
||||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
@Bean(name = "LineCaptcha")
|
||||||
Properties properties = new Properties();
|
public LineCaptcha getLineCaptcha() {
|
||||||
// 是否有边框 默认为true 我们可以自己设置yes,no
|
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
|
||||||
properties.setProperty(KAPTCHA_BORDER, "yes");
|
captcha.setBackground(background);
|
||||||
// 边框颜色 默认为Color.BLACK
|
captcha.setFont(font);
|
||||||
properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
|
return captcha;
|
||||||
// 验证码文本字符颜色 默认为Color.BLACK
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
|
|
||||||
// 验证码图片宽度 默认为200
|
|
||||||
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
|
|
||||||
// 验证码图片高度 默认为50
|
|
||||||
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
|
|
||||||
// 验证码文本字符大小 默认为40
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
|
|
||||||
// KAPTCHA_SESSION_KEY
|
|
||||||
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
|
|
||||||
// 验证码文本生成器
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator");
|
|
||||||
// 验证码文本字符间距 默认为2
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
|
|
||||||
// 验证码文本字符长度 默认为5
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
|
|
||||||
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
|
|
||||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
|
|
||||||
// 验证码噪点颜色 默认为Color.BLACK
|
|
||||||
properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
|
|
||||||
// 干扰实现类
|
|
||||||
properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
|
|
||||||
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
|
|
||||||
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
|
|
||||||
Config config = new Config(properties);
|
|
||||||
defaultKaptcha.setConfig(config);
|
|
||||||
return defaultKaptcha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扭曲干扰验证码
|
||||||
|
*/
|
||||||
|
@Bean(name = "ShearCaptcha")
|
||||||
|
public ShearCaptcha getShearCaptcha() {
|
||||||
|
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height);
|
||||||
|
captcha.setBackground(background);
|
||||||
|
captcha.setFont(font);
|
||||||
|
return captcha;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,75 +0,0 @@
|
|||||||
package com.ruoyi.framework.config;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码文本生成器
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class KaptchaTextCreator extends DefaultTextCreator
|
|
||||||
{
|
|
||||||
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText()
|
|
||||||
{
|
|
||||||
Integer result = 0;
|
|
||||||
Random random = new Random();
|
|
||||||
int x = random.nextInt(10);
|
|
||||||
int y = random.nextInt(10);
|
|
||||||
StringBuilder suChinese = new StringBuilder();
|
|
||||||
int randomoperands = (int) Math.round(Math.random() * 2);
|
|
||||||
if (randomoperands == 0)
|
|
||||||
{
|
|
||||||
result = x * y;
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
suChinese.append("*");
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
}
|
|
||||||
else if (randomoperands == 1)
|
|
||||||
{
|
|
||||||
if (!(x == 0) && y % x == 0)
|
|
||||||
{
|
|
||||||
result = y / x;
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
suChinese.append("/");
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = x + y;
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
suChinese.append("+");
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (randomoperands == 2)
|
|
||||||
{
|
|
||||||
if (x >= y)
|
|
||||||
{
|
|
||||||
result = x - y;
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
suChinese.append("-");
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = y - x;
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
suChinese.append("-");
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = x + y;
|
|
||||||
suChinese.append(CNUMBERS[x]);
|
|
||||||
suChinese.append("+");
|
|
||||||
suChinese.append(CNUMBERS[y]);
|
|
||||||
}
|
|
||||||
suChinese.append("=?@" + result);
|
|
||||||
return suChinese.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +1,35 @@
|
|||||||
package com.ruoyi.framework.web.domain;
|
package com.ruoyi.framework.web.domain;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import com.ruoyi.common.utils.Arith;
|
|
||||||
import com.ruoyi.common.utils.ip.IpUtils;
|
import cn.hutool.core.net.NetUtil;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.system.*;
|
||||||
|
import cn.hutool.system.oshi.CpuInfo;
|
||||||
|
import cn.hutool.system.oshi.OshiUtil;
|
||||||
import com.ruoyi.framework.web.domain.server.Cpu;
|
import com.ruoyi.framework.web.domain.server.Cpu;
|
||||||
import com.ruoyi.framework.web.domain.server.Jvm;
|
import com.ruoyi.framework.web.domain.server.Jvm;
|
||||||
import com.ruoyi.framework.web.domain.server.Mem;
|
import com.ruoyi.framework.web.domain.server.Mem;
|
||||||
import com.ruoyi.framework.web.domain.server.Sys;
|
import com.ruoyi.framework.web.domain.server.Sys;
|
||||||
import com.ruoyi.framework.web.domain.server.SysFile;
|
import com.ruoyi.framework.web.domain.server.SysFile;
|
||||||
import oshi.SystemInfo;
|
import lombok.Data;
|
||||||
import oshi.hardware.CentralProcessor;
|
|
||||||
import oshi.hardware.CentralProcessor.TickType;
|
|
||||||
import oshi.hardware.GlobalMemory;
|
import oshi.hardware.GlobalMemory;
|
||||||
import oshi.hardware.HardwareAbstractionLayer;
|
|
||||||
import oshi.software.os.FileSystem;
|
import oshi.software.os.FileSystem;
|
||||||
import oshi.software.os.OSFileStore;
|
import oshi.software.os.OSFileStore;
|
||||||
import oshi.software.os.OperatingSystem;
|
import oshi.software.os.OperatingSystem;
|
||||||
import oshi.util.Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务器相关信息
|
* 服务器相关信息
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class Server
|
@Data
|
||||||
{
|
public class Server {
|
||||||
private static final int OSHI_WAIT_SECOND = 1000;
|
private static final int OSHI_WAIT_SECOND = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPU相关信息
|
* CPU相关信息
|
||||||
*/
|
*/
|
||||||
@ -55,103 +55,33 @@ public class Server
|
|||||||
*/
|
*/
|
||||||
private List<SysFile> sysFiles = new LinkedList<SysFile>();
|
private List<SysFile> sysFiles = new LinkedList<SysFile>();
|
||||||
|
|
||||||
public Cpu getCpu()
|
|
||||||
{
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCpu(Cpu cpu)
|
|
||||||
{
|
|
||||||
this.cpu = cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mem getMem()
|
|
||||||
{
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMem(Mem mem)
|
|
||||||
{
|
|
||||||
this.mem = mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jvm getJvm()
|
|
||||||
{
|
|
||||||
return jvm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJvm(Jvm jvm)
|
|
||||||
{
|
|
||||||
this.jvm = jvm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sys getSys()
|
|
||||||
{
|
|
||||||
return sys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSys(Sys sys)
|
|
||||||
{
|
|
||||||
this.sys = sys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SysFile> getSysFiles()
|
|
||||||
{
|
|
||||||
return sysFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSysFiles(List<SysFile> sysFiles)
|
|
||||||
{
|
|
||||||
this.sysFiles = sysFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void copyTo() throws Exception
|
|
||||||
{
|
|
||||||
SystemInfo si = new SystemInfo();
|
|
||||||
HardwareAbstractionLayer hal = si.getHardware();
|
|
||||||
|
|
||||||
setCpuInfo(hal.getProcessor());
|
|
||||||
|
|
||||||
setMemInfo(hal.getMemory());
|
|
||||||
|
|
||||||
|
public void copyTo() {
|
||||||
|
setCpuInfo();
|
||||||
|
setMemInfo();
|
||||||
setSysInfo();
|
setSysInfo();
|
||||||
|
|
||||||
setJvmInfo();
|
setJvmInfo();
|
||||||
|
setSysFiles();
|
||||||
setSysFiles(si.getOperatingSystem());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置CPU信息
|
* 设置CPU信息
|
||||||
*/
|
*/
|
||||||
private void setCpuInfo(CentralProcessor processor)
|
private void setCpuInfo() {
|
||||||
{
|
CpuInfo cpuInfo = OshiUtil.getCpuInfo(OSHI_WAIT_SECOND);
|
||||||
// CPU信息
|
cpu.setCpuNum(cpuInfo.getCpuNum());
|
||||||
long[] prevTicks = processor.getSystemCpuLoadTicks();
|
cpu.setTotal(cpuInfo.getToTal());
|
||||||
Util.sleep(OSHI_WAIT_SECOND);
|
cpu.setSys(cpuInfo.getSys());
|
||||||
long[] ticks = processor.getSystemCpuLoadTicks();
|
cpu.setUsed(cpuInfo.getUsed());
|
||||||
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
|
cpu.setWait(cpuInfo.getWait());
|
||||||
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
|
cpu.setFree(cpuInfo.getFree());
|
||||||
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
|
|
||||||
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
|
|
||||||
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
|
|
||||||
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
|
|
||||||
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
|
|
||||||
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
|
|
||||||
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
|
|
||||||
cpu.setCpuNum(processor.getLogicalProcessorCount());
|
|
||||||
cpu.setTotal(totalCpu);
|
|
||||||
cpu.setSys(cSys);
|
|
||||||
cpu.setUsed(user);
|
|
||||||
cpu.setWait(iowait);
|
|
||||||
cpu.setFree(idle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置内存信息
|
* 设置内存信息
|
||||||
*/
|
*/
|
||||||
private void setMemInfo(GlobalMemory memory)
|
private void setMemInfo() {
|
||||||
{
|
GlobalMemory memory = OshiUtil.getMemory();
|
||||||
mem.setTotal(memory.getTotal());
|
mem.setTotal(memory.getTotal());
|
||||||
mem.setUsed(memory.getTotal() - memory.getAvailable());
|
mem.setUsed(memory.getTotal() - memory.getAvailable());
|
||||||
mem.setFree(memory.getAvailable());
|
mem.setFree(memory.getAvailable());
|
||||||
@ -160,38 +90,39 @@ public class Server
|
|||||||
/**
|
/**
|
||||||
* 设置服务器信息
|
* 设置服务器信息
|
||||||
*/
|
*/
|
||||||
private void setSysInfo()
|
private void setSysInfo() {
|
||||||
{
|
HostInfo hostInfo = SystemUtil.getHostInfo();
|
||||||
Properties props = System.getProperties();
|
OsInfo osInfo = SystemUtil.getOsInfo();
|
||||||
sys.setComputerName(IpUtils.getHostName());
|
UserInfo userInfo = SystemUtil.getUserInfo();
|
||||||
sys.setComputerIp(IpUtils.getHostIp());
|
sys.setComputerName(hostInfo.getName());
|
||||||
sys.setOsName(props.getProperty("os.name"));
|
sys.setComputerIp(hostInfo.getAddress());
|
||||||
sys.setOsArch(props.getProperty("os.arch"));
|
sys.setOsName(osInfo.getName());
|
||||||
sys.setUserDir(props.getProperty("user.dir"));
|
sys.setOsArch(osInfo.getArch());
|
||||||
|
sys.setUserDir(userInfo.getCurrentDir());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置Java虚拟机
|
* 设置Java虚拟机
|
||||||
*/
|
*/
|
||||||
private void setJvmInfo() throws UnknownHostException
|
private void setJvmInfo() {
|
||||||
{
|
JavaInfo javaInfo = SystemUtil.getJavaInfo();
|
||||||
Properties props = System.getProperties();
|
RuntimeInfo runtimeInfo = SystemUtil.getRuntimeInfo();
|
||||||
jvm.setTotal(Runtime.getRuntime().totalMemory());
|
JavaRuntimeInfo javaRuntimeInfo = SystemUtil.getJavaRuntimeInfo();
|
||||||
jvm.setMax(Runtime.getRuntime().maxMemory());
|
jvm.setTotal(runtimeInfo.getTotalMemory());
|
||||||
jvm.setFree(Runtime.getRuntime().freeMemory());
|
jvm.setMax(runtimeInfo.getMaxMemory());
|
||||||
jvm.setVersion(props.getProperty("java.version"));
|
jvm.setFree(runtimeInfo.getFreeMemory());
|
||||||
jvm.setHome(props.getProperty("java.home"));
|
jvm.setVersion(javaInfo.getVersion());
|
||||||
|
jvm.setHome(javaRuntimeInfo.getHomeDir());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置磁盘信息
|
* 设置磁盘信息
|
||||||
*/
|
*/
|
||||||
private void setSysFiles(OperatingSystem os)
|
private void setSysFiles() {
|
||||||
{
|
OperatingSystem os = OshiUtil.getOs();
|
||||||
FileSystem fileSystem = os.getFileSystem();
|
FileSystem fileSystem = os.getFileSystem();
|
||||||
List<OSFileStore> fsArray = fileSystem.getFileStores();
|
List<OSFileStore> fsArray = fileSystem.getFileStores();
|
||||||
for (OSFileStore fs : fsArray)
|
for (OSFileStore fs : fsArray) {
|
||||||
{
|
|
||||||
long free = fs.getUsableSpace();
|
long free = fs.getUsableSpace();
|
||||||
long total = fs.getTotalSpace();
|
long total = fs.getTotalSpace();
|
||||||
long used = total - free;
|
long used = total - free;
|
||||||
@ -202,39 +133,31 @@ public class Server
|
|||||||
sysFile.setTotal(convertFileSize(total));
|
sysFile.setTotal(convertFileSize(total));
|
||||||
sysFile.setFree(convertFileSize(free));
|
sysFile.setFree(convertFileSize(free));
|
||||||
sysFile.setUsed(convertFileSize(used));
|
sysFile.setUsed(convertFileSize(used));
|
||||||
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
|
sysFile.setUsage(NumberUtil.mul(NumberUtil.div(used, total, 4), 100));
|
||||||
sysFiles.add(sysFile);
|
sysFiles.add(sysFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字节转换
|
* 字节转换
|
||||||
*
|
*
|
||||||
* @param size 字节大小
|
* @param size 字节大小
|
||||||
* @return 转换后值
|
* @return 转换后值
|
||||||
*/
|
*/
|
||||||
public String convertFileSize(long size)
|
public String convertFileSize(long size) {
|
||||||
{
|
|
||||||
long kb = 1024;
|
long kb = 1024;
|
||||||
long mb = kb * 1024;
|
long mb = kb * 1024;
|
||||||
long gb = mb * 1024;
|
long gb = mb * 1024;
|
||||||
if (size >= gb)
|
if (size >= gb) {
|
||||||
{
|
return StrUtil.format("%.1f GB", (float) size / gb);
|
||||||
return String.format("%.1f GB", (float) size / gb);
|
} else if (size >= mb) {
|
||||||
}
|
|
||||||
else if (size >= mb)
|
|
||||||
{
|
|
||||||
float f = (float) size / mb;
|
float f = (float) size / mb;
|
||||||
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
|
return StrUtil.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
|
||||||
}
|
} else if (size >= kb) {
|
||||||
else if (size >= kb)
|
|
||||||
{
|
|
||||||
float f = (float) size / kb;
|
float f = (float) size / kb;
|
||||||
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
|
return StrUtil.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
|
||||||
}
|
} else {
|
||||||
else
|
return StrUtil.format("%d B", size);
|
||||||
{
|
|
||||||
return String.format("%d B", size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
package com.ruoyi.framework.web.domain.server;
|
package com.ruoyi.framework.web.domain.server;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.Arith;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPU相关信息
|
* CPU相关信息
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class Cpu
|
public class Cpu {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* 核心数
|
* 核心数
|
||||||
*/
|
*/
|
||||||
@ -39,63 +38,51 @@ public class Cpu
|
|||||||
*/
|
*/
|
||||||
private double free;
|
private double free;
|
||||||
|
|
||||||
public int getCpuNum()
|
public int getCpuNum() {
|
||||||
{
|
|
||||||
return cpuNum;
|
return cpuNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCpuNum(int cpuNum)
|
public void setCpuNum(int cpuNum) {
|
||||||
{
|
|
||||||
this.cpuNum = cpuNum;
|
this.cpuNum = cpuNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotal()
|
public double getTotal() {
|
||||||
{
|
return NumberUtil.round(NumberUtil.mul(total, 100), 2).doubleValue();
|
||||||
return Arith.round(Arith.mul(total, 100), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTotal(double total)
|
public void setTotal(double total) {
|
||||||
{
|
|
||||||
this.total = total;
|
this.total = total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getSys()
|
public double getSys() {
|
||||||
{
|
return NumberUtil.round(NumberUtil.mul(sys / total, 100), 2).doubleValue();
|
||||||
return Arith.round(Arith.mul(sys / total, 100), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSys(double sys)
|
public void setSys(double sys) {
|
||||||
{
|
|
||||||
this.sys = sys;
|
this.sys = sys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getUsed()
|
public double getUsed() {
|
||||||
{
|
return NumberUtil.round(NumberUtil.mul(used / total, 100), 2).doubleValue();
|
||||||
return Arith.round(Arith.mul(used / total, 100), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsed(double used)
|
public void setUsed(double used) {
|
||||||
{
|
|
||||||
this.used = used;
|
this.used = used;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getWait()
|
public double getWait() {
|
||||||
{
|
return NumberUtil.round(NumberUtil.mul(wait / total, 100), 2).doubleValue();
|
||||||
return Arith.round(Arith.mul(wait / total, 100), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWait(double wait)
|
public void setWait(double wait) {
|
||||||
{
|
|
||||||
this.wait = wait;
|
this.wait = wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFree()
|
public double getFree() {
|
||||||
{
|
return NumberUtil.round(NumberUtil.mul(free / total, 100), 2).doubleValue();
|
||||||
return Arith.round(Arith.mul(free / total, 100), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFree(double free)
|
public void setFree(double free) {
|
||||||
{
|
|
||||||
this.free = free;
|
this.free = free;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
package com.ruoyi.framework.web.domain.server;
|
package com.ruoyi.framework.web.domain.server;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import com.ruoyi.common.utils.Arith;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.BetweenFormatter;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JVM相关信息
|
* JVM相关信息
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class Jvm
|
public class Jvm {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* 当前JVM占用的内存总数(M)
|
* 当前JVM占用的内存总数(M)
|
||||||
*/
|
*/
|
||||||
@ -36,71 +39,58 @@ public class Jvm
|
|||||||
*/
|
*/
|
||||||
private String home;
|
private String home;
|
||||||
|
|
||||||
public double getTotal()
|
public double getTotal() {
|
||||||
{
|
return NumberUtil.div(total, (1024 * 1024), 2);
|
||||||
return Arith.div(total, (1024 * 1024), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTotal(double total)
|
public void setTotal(double total) {
|
||||||
{
|
|
||||||
this.total = total;
|
this.total = total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMax()
|
public double getMax() {
|
||||||
{
|
return NumberUtil.div(max, (1024 * 1024), 2);
|
||||||
return Arith.div(max, (1024 * 1024), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMax(double max)
|
public void setMax(double max) {
|
||||||
{
|
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFree()
|
public double getFree() {
|
||||||
{
|
return NumberUtil.div(free, (1024 * 1024), 2);
|
||||||
return Arith.div(free, (1024 * 1024), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFree(double free)
|
public void setFree(double free) {
|
||||||
{
|
|
||||||
this.free = free;
|
this.free = free;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getUsed()
|
public double getUsed() {
|
||||||
{
|
return NumberUtil.div(total - free, (1024 * 1024), 2);
|
||||||
return Arith.div(total - free, (1024 * 1024), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getUsage()
|
public double getUsage() {
|
||||||
{
|
return NumberUtil.mul(NumberUtil.div(total - free, total, 4), 100);
|
||||||
return Arith.mul(Arith.div(total - free, total, 4), 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取JDK名称
|
* 获取JDK名称
|
||||||
*/
|
*/
|
||||||
public String getName()
|
public String getName() {
|
||||||
{
|
|
||||||
return ManagementFactory.getRuntimeMXBean().getVmName();
|
return ManagementFactory.getRuntimeMXBean().getVmName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVersion()
|
public String getVersion() {
|
||||||
{
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersion(String version)
|
public void setVersion(String version) {
|
||||||
{
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHome()
|
public String getHome() {
|
||||||
{
|
|
||||||
return home;
|
return home;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHome(String home)
|
public void setHome(String home) {
|
||||||
{
|
|
||||||
this.home = home;
|
this.home = home;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.ruoyi.framework.web.domain.server;
|
package com.ruoyi.framework.web.domain.server;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.Arith;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 內存相关信息
|
* 內存相关信息
|
||||||
@ -26,7 +26,7 @@ public class Mem
|
|||||||
|
|
||||||
public double getTotal()
|
public double getTotal()
|
||||||
{
|
{
|
||||||
return Arith.div(total, (1024 * 1024 * 1024), 2);
|
return NumberUtil.div(total, (1024 * 1024 * 1024), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTotal(long total)
|
public void setTotal(long total)
|
||||||
@ -36,7 +36,7 @@ public class Mem
|
|||||||
|
|
||||||
public double getUsed()
|
public double getUsed()
|
||||||
{
|
{
|
||||||
return Arith.div(used, (1024 * 1024 * 1024), 2);
|
return NumberUtil.div(used, (1024 * 1024 * 1024), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsed(long used)
|
public void setUsed(long used)
|
||||||
@ -46,7 +46,7 @@ public class Mem
|
|||||||
|
|
||||||
public double getFree()
|
public double getFree()
|
||||||
{
|
{
|
||||||
return Arith.div(free, (1024 * 1024 * 1024), 2);
|
return NumberUtil.div(free, (1024 * 1024 * 1024), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFree(long free)
|
public void setFree(long free)
|
||||||
@ -56,6 +56,6 @@ public class Mem
|
|||||||
|
|
||||||
public double getUsage()
|
public double getUsage()
|
||||||
{
|
{
|
||||||
return Arith.mul(Arith.div(used, total, 4), 100);
|
return NumberUtil.mul(NumberUtil.div(used, total, 4), 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -14,7 +16,6 @@ import com.ruoyi.common.utils.ServletUtils;
|
|||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.ip.AddressUtils;
|
import com.ruoyi.common.utils.ip.AddressUtils;
|
||||||
import com.ruoyi.common.utils.ip.IpUtils;
|
import com.ruoyi.common.utils.ip.IpUtils;
|
||||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
|
||||||
import eu.bitwalker.useragentutils.UserAgent;
|
import eu.bitwalker.useragentutils.UserAgent;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
@ -101,7 +102,7 @@ public class TokenService
|
|||||||
*/
|
*/
|
||||||
public String createToken(LoginUser loginUser)
|
public String createToken(LoginUser loginUser)
|
||||||
{
|
{
|
||||||
String token = IdUtils.fastUUID();
|
String token = IdUtil.fastUUID();
|
||||||
loginUser.setToken(token);
|
loginUser.setToken(token);
|
||||||
setUserAgent(loginUser);
|
setUserAgent(loginUser);
|
||||||
refreshToken(loginUser);
|
refreshToken(loginUser);
|
||||||
|
|||||||
@ -26,6 +26,11 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
/* 只读 */
|
||||||
|
readOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -51,7 +56,7 @@ export default {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
placeholder: "请输入内容",
|
placeholder: "请输入内容",
|
||||||
readOnly: false,
|
readOnly: this.readOnly,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -19,10 +19,8 @@ router.beforeEach((to, from, next) => {
|
|||||||
} else {
|
} else {
|
||||||
if (store.getters.roles.length === 0) {
|
if (store.getters.roles.length === 0) {
|
||||||
// 判断当前用户是否已拉取完user_info信息
|
// 判断当前用户是否已拉取完user_info信息
|
||||||
store.dispatch('GetInfo').then(res => {
|
store.dispatch('GetInfo').then(() => {
|
||||||
// 拉取user_info
|
store.dispatch('GenerateRoutes').then(accessRoutes => {
|
||||||
const roles = res.roles
|
|
||||||
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
|
|
||||||
// 根据roles权限生成可访问的路由表
|
// 根据roles权限生成可访问的路由表
|
||||||
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
||||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||||
|
|||||||
@ -49,7 +49,7 @@ const user = {
|
|||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
GetInfo({ commit, state }) {
|
GetInfo({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getInfo(state.token).then(res => {
|
getInfo().then(res => {
|
||||||
const user = res.user
|
const user = res.user
|
||||||
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
|
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
|
||||||
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||||
|
|||||||
@ -119,9 +119,9 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i class="el-icon-user-solid"></i> QQ群:<s>满937441</s>
|
<i class="el-icon-user-solid"></i> QQ群:<s>满937441</s>
|
||||||
<s>满887144332</s> <s>满180251782</s>
|
<s>满887144332</s> <s>满180251782</s> <s>满104180207</s>
|
||||||
<a href="https://jq.qq.com/?_wv=1027&k=4WWwqNxN" target="_blank"
|
<a href="https://jq.qq.com/?_wv=1027&k=VvjN2nvu" target="_blank"
|
||||||
> 104180207</a
|
> 186866453</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@ -84,7 +84,7 @@
|
|||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:logininfor:export']"
|
v-hasPermi="['monitor:logininfor:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
|||||||
@ -100,7 +100,7 @@
|
|||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['system:config:export']"
|
v-hasPermi="['monitor:operlog:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user