Browse Source

首次提交代码

tags/v1.0.0
wanjing 1 year ago
commit
93f075881b
100 changed files with 6120 additions and 0 deletions
  1. +3
    -0
      README.md
  2. +108
    -0
      pom.xml
  3. +20
    -0
      tuoheng-common/pom.xml
  4. +145
    -0
      tuoheng-common/tuoheng-common-core/pom.xml
  5. +123
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/advice/CustomExceptionHandler.java
  6. +38
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/annotation/LockAction.java
  7. +36
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/annotation/Log.java
  8. +8
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseController.java
  9. +58
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseEntity.java
  10. +31
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseQuery.java
  11. +210
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseServiceImpl.java
  12. +23
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/ExceptionInterface.java
  13. +109
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/IBaseService.java
  14. +52
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/OperationEnum.java
  15. +177
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/RedisConfig.java
  16. +40
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/UploadFileConfig.java
  17. +27
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/ValidatorConfig.java
  18. +128
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/common/CommonConfig.java
  19. +43
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/DefaultClientHttpRequestInterceptor.java
  20. +32
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/HeadClientHttpRequestInterceptor.java
  21. +64
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/RestProperties.java
  22. +177
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/RestTemplateConfig.java
  23. +113
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/redisson/RedissonDistributedLockAspectConfiguration.java
  24. +86
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/xxl/XxlJobConfig.java
  25. +111
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/constant/CommonConstants.java
  26. +16
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/constant/SecurityHeadConstant.java
  27. +183
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/entity/UserEntity.java
  28. +27
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/HttpStatusEnum.java
  29. +20
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/LockType.java
  30. +68
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/LogType.java
  31. +23
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/OperType.java
  32. +27
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/PhotographyEnum.java
  33. +113
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/ServiceExceptionEnum.java
  34. +97
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/SysExceptionEnum.java
  35. +23
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/exception/ExceptionInterface.java
  36. +59
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/exception/ServiceException.java
  37. +26
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/interceptor/FeignRequestInterceptor.java
  38. +21
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/model/dto/LoginUser.java
  39. +76
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/CommonNumberTypeUtils.java
  40. +322
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/CommonUtils.java
  41. +274
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/DateUtils.java
  42. +64
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/EncryptUtil.java
  43. +163
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ExceptionUtil.java
  44. +224
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/FileUtils.java
  45. +180
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/HttpUtils.java
  46. +296
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/IpUtils.java
  47. +132
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/JacksonUtil.java
  48. +108
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/JsonResult.java
  49. +15
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/LogUtil.java
  50. +608
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/RedisUtils.java
  51. +69
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/SecurityUserUtils.java
  52. +188
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ServletUtils.java
  53. +102
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/SpringUtils.java
  54. +413
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/StringUtils.java
  55. +34
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ThreadLocalUtil.java
  56. +113
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ThumbnailUtil.java
  57. +74
    -0
      tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ValidatorUtils.java
  58. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/advice/CustomExceptionHandler.class
  59. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/annotation/Log.class
  60. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseController.class
  61. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseEntity.class
  62. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseQuery.class
  63. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseServiceImpl.class
  64. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/ExceptionInterface.class
  65. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/IBaseService.class
  66. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/OperationEnum.class
  67. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/RedisConfig.class
  68. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/UploadFileConfig.class
  69. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/ValidatorConfig.class
  70. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/common/CommonConfig.class
  71. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/DefaultClientHttpRequestInterceptor.class
  72. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/HeadClientHttpRequestInterceptor.class
  73. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestProperties.class
  74. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestTemplateConfig$1.class
  75. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestTemplateConfig.class
  76. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/xxl/XxlJobConfig.class
  77. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/constant/CommonConstants.class
  78. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/constant/SecurityHeadConstant.class
  79. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/entity/UserEntity.class
  80. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/HttpStatusEnum.class
  81. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/LockType.class
  82. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/LogType.class
  83. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/OperType.class
  84. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/PhotographyEnum.class
  85. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/ServiceExceptionEnum.class
  86. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/SysExceptionEnum.class
  87. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/exception/ExceptionInterface.class
  88. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/exception/ServiceException.class
  89. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/model/dto/LoginUser.class
  90. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/CommonNumberTypeUtils.class
  91. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/CommonUtils.class
  92. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/DateUtils.class
  93. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/EncryptUtil.class
  94. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/ExceptionUtil.class
  95. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/FileUtils.class
  96. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils$TrustAnyHostnameVerifier.class
  97. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils$TrustAnyTrustManager.class
  98. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils.class
  99. BIN
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/IpUtils.class
  100. +0
    -0
      tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/JacksonUtil.class

+ 3
- 0
README.md View File

@@ -0,0 +1,3 @@
# tuoheng_telecomumale

拓恒电信城管管理平台

+ 108
- 0
pom.xml View File

@@ -0,0 +1,108 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>tuoheng-common</module>
<module>tuoheng-service</module>
<module>tuoheng-feign</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tuoheng</groupId>
<artifactId>tuoheng_telecomumale</artifactId>
<version>1.0.0</version>
<name>tuoheng_telecomumale</name>
<description>tuoheng_telecomumale</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<tuoheng.version>1.0.0</tuoheng.version>
<fastjson.version>1.2.76</fastjson.version>
<poi.version>3.17</poi.version>
<commons.io.version>2.5</commons.io.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<!-- 核心模块依赖 -->
<dependency>
<groupId>com.tuoheng</groupId>
<artifactId>tuoheng-common-core</artifactId>
<version>${tuoheng.version}</version>
</dependency>
<!-- 安全认证依赖 -->
<dependency>
<groupId>com.tuoheng</groupId>
<artifactId>tuoheng-common-security</artifactId>
<version>${tuoheng.version}</version>
</dependency>
<!-- 系统服务API接口层模块依赖 -->
<dependency>
<groupId>com.tuoheng</groupId>
<artifactId>tuoheng-system-feign</artifactId>
<version>${tuoheng.version}</version>
</dependency>
<!-- telecomumale api fegin 接口模块依赖 -->
<dependency>
<groupId>com.tuoheng</groupId>
<artifactId>tuoheng-api-feign</artifactId>
<version>${tuoheng.version}</version>
</dependency>
<!-- SpringCloud依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- JSON 解析器和生成器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- IO常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>


</project>

+ 20
- 0
tuoheng-common/pom.xml View File

@@ -0,0 +1,20 @@
<?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>tuoheng_telecomumale</artifactId>
<groupId>com.tuoheng</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>tuoheng-common</artifactId>
<packaging>pom</packaging>
<version>1.0.0</version>
<modules>
<module>tuoheng-common-core</module>
<module>tuoheng-common-security</module>
</modules>

</project>

+ 145
- 0
tuoheng-common/tuoheng-common-core/pom.xml View File

@@ -0,0 +1,145 @@
<?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>tuoheng-common</artifactId>
<groupId>com.tuoheng</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>tuoheng-common-core</artifactId>

<!-- 依赖库管理 -->
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.redisson</groupId>-->
<!-- <artifactId>redisson</artifactId>-->
<!-- <version>3.17.5</version>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-log</artifactId>
<version>5.8.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.3</version>
</dependency>
<!--任务调度-->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</dependency>
<!--引入kafka依赖-->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!--mybatis-plus 起始依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- 引入阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<!-- Apache Commons Pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Excel依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
</dependency>

<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>

<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<!-- Redis 起始依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>

<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>

</dependencies>

</project>

+ 123
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/advice/CustomExceptionHandler.java View File

@@ -0,0 +1,123 @@
package com.tuoheng.common.core.advice;

import com.tuoheng.common.core.enums.SysExceptionEnum;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;

/**
* 自定义异常处理器
*
* @author zhu_zishuang
* @date 2021-03-12
*/
@RestControllerAdvice
public class CustomExceptionHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(CustomExceptionHandler.class);

/**
* 密码校验异常
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public JsonResult<Object> handleAuthenticationException(BindException e) {
BindingResult bindingResult = e.getBindingResult();
String errorMessage = "";
for (FieldError fieldError : bindingResult.getFieldErrors()) {
errorMessage += fieldError.getDefaultMessage() + "!";
}
return JsonResult.error(SysExceptionEnum.PARAMETER_EMPTY_EXCEPTION.getCode(), errorMessage);
}

/**
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public JsonResult<Object> handleConstraintViolationException(ConstraintViolationException e) {
String message = e.getConstraintViolations()
.stream()
.map(constraintViolation -> {
return constraintViolation.getPropertyPath().toString() + ": " + constraintViolation.getMessage();
})
.collect(Collectors.joining(","));
LOGGER.error("参数格式错误:{}", message);
return JsonResult.error(SysExceptionEnum.PARAMETER_EMPTY_EXCEPTION.getCode(), SysExceptionEnum.PARAMETER_EMPTY_EXCEPTION.getMsg());
}

/**
* 校验异常处理
* 处理请求参数格式错误 @RequestBody上使用@Valid 实体上使用@NotNull等
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public JsonResult<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
LOGGER.warn("系统参数校验异常,异常信息:{}", e.getMessage());

JsonResult<Object> error = JsonResult.error(SysExceptionEnum.PARAMETER_EMPTY_EXCEPTION.getCode(),
SysExceptionEnum.PARAMETER_EMPTY_EXCEPTION.getMsg());

BindingResult result = e.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
if (!CollectionUtils.isEmpty(fieldErrors)) {
error.setMsg(fieldErrors.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(",")));
} else {
if (!CollectionUtils.isEmpty(result.getAllErrors())) {
ObjectError currError = result.getAllErrors().get(0);
error.setMsg(currError.getObjectName() + currError.getDefaultMessage());
}
}
return error;
}

/**
* 系统业务异常处理
*/
@ExceptionHandler(ServiceException.class)
@ResponseBody
public JsonResult<Object> handleServiceException(ServiceException e) {
// 打印业务异常日志
LOGGER.warn("系统业务逻辑异常,异常状态码 {},异常信息:{}", e.code, e.getMessage());
return JsonResult.error(e.code, e.getMessage());
}

/**
* 系统数据访问异常处理
*/
@ExceptionHandler(DataAccessException.class)
@ResponseBody
public JsonResult<Object> handleDataAccessException(DataAccessException e) {
LOGGER.error("系统数据访问异常,异常信息:{}", e);
return JsonResult.error(SysExceptionEnum.DATAACCESS_EXCEPTION.getCode(), SysExceptionEnum.DATAACCESS_EXCEPTION.getMsg());
}

/**
* 系统异常处理
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public JsonResult<Object> handleException(Exception e) {
System.out.println(e.getSuppressed());
System.out.println(e.getCause().getMessage());
System.out.println(e.getCause().getCause());
LOGGER.error("系统异常,异常信息:{}", e);
return JsonResult.error(SysExceptionEnum.SYS_EXCEPTION.getCode(), SysExceptionEnum.SYS_EXCEPTION.getMsg());
}
}

+ 38
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/annotation/LockAction.java View File

@@ -0,0 +1,38 @@
//package com.tuoheng.common.core.annotation;
//
//import com.tuoheng.common.core.enums.LockType;
//import org.springframework.core.annotation.AliasFor;
//
//import java.lang.annotation.*;
//import java.util.concurrent.TimeUnit;
//
///**
// * @author chenyukun
// */
//@Target({ElementType.METHOD})
//@Retention(RetentionPolicy.RUNTIME)
//@Inherited
//public @interface LockAction {
//
// /** 锁的资源,key。支持spring El表达式*/
// @AliasFor("key")
// String value() default "'default'";
//
// @AliasFor("value")
// String key() default "'default'";
//
// String prefix() default "lock-";
//
// /** 锁类型*/
// LockType lockType() default LockType.REENTRANT_LOCK;
//
//
// /** 获取锁等待时间,默认3秒*/
// long waitTime() default 3000L;
//
// /** 锁自动释放时间,默认30秒*/
// long leaseTime() default 30000L;
//
// /** 时间单位(获取锁等待时间和持锁时间都用此单位)*/
// TimeUnit unit() default TimeUnit.MILLISECONDS;
//}

+ 36
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/annotation/Log.java View File

@@ -0,0 +1,36 @@
package com.tuoheng.common.core.annotation;

import com.tuoheng.common.core.enums.LogType;
import com.tuoheng.common.core.enums.OperType;

import java.lang.annotation.*;

/**
* 自定义操作日志注解
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

/**
* 模块
*/
String title() default "";

/**
* 日志类型
*/
LogType logType() default LogType.OTHER;

/**
* 操作人类别
*/
OperType operType() default OperType.MANAGE;

/**
* 是否保存请求的参数
*/
boolean isSaveRequestData() default true;

}

+ 8
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseController.java View File

@@ -0,0 +1,8 @@
package com.tuoheng.common.core.common;

/**
* 基类控制器
*/
public class BaseController {

}

+ 58
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseEntity.java View File

@@ -0,0 +1,58 @@
package com.tuoheng.common.core.common;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
* 基类实体对象
*
* @author qiujinyang
* @date 2022/7/1
*/
@Data
public class BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 主键ID
*/
@TableId(value = "id", type = IdType.UUID)
private String id;

/**
* 添加人
*/
private String createUser;

/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;

/**
* 更新人
*/
private String updateUser;

/**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;

/**
* 有效标识
*/
private Integer mark;

}

+ 31
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseQuery.java View File

@@ -0,0 +1,31 @@
package com.tuoheng.common.core.common;

import lombok.Data;

/**
* 查询对象基类
*/
@Data
public class BaseQuery {
/**
* 页码(默认1)
*/
private Integer page = 1;

/**
* 每页数(默认:20)
*/
private Integer limit = 20;

/**
* 不传参的时候默认1,10
*/
public void checkParam() {
if (this.page == null || this.page < 0) {
setPage(1);
}
if (this.limit == null || this.limit < 0 || this.limit > 100) {
setLimit(10);
}
}
}

+ 210
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/BaseServiceImpl.java View File

@@ -0,0 +1,210 @@
package com.tuoheng.common.core.common;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;

import java.io.Serializable;
import java.util.List;

public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements IBaseService<T> {

/**
* 根据查询条件获取数据列表
*
* @param page 分页
* @param query 查询条件
* @return
*/
@Override
public JsonResult getList(Page<T> page, BaseQuery query) {
return null;
}

/**
* 获取数据列表
*
* @param query 查询条件
* @return
*/
@Override
public JsonResult getList(BaseQuery query) {
return null;
}

/**
* 根据实体ID获取实体信息
*
* @param id 记录ID
* @return
*/
@Override
public JsonResult info(String id) {
if (StringUtils.isEmpty(id)) {
return JsonResult.error("记录ID不能为空");
}
Object result = this.getInfo(id);
return JsonResult.success(result, "操作成功");
}

/**
* 根据ID获取记录信息
*
* @param id 记录ID
* @return
*/
@Override
public Object getInfo(Serializable id) {
T entity = this.getById(id);
return entity;
}

/**
* 传入实体对象添加记录
*
* @param entity 实体对象
* @return
*/
@Override
public JsonResult add(T entity) {
// entity.setCreateUser(SecurityUtils.getUserId());
entity.setCreateTime(DateUtils.now());
entity.setMark(1);
boolean result = this.save(entity);
if (!result) {
return JsonResult.error();
}
return JsonResult.success();
}

/**
* 传入实体对象更新记录
*
* @param entity 实体对象
* @return
*/
@Override
public JsonResult update(T entity) {
// entity.setUpdateUser(SecurityUtils.getUserId());
entity.setUpdateTime(DateUtils.now());
boolean result = this.updateById(entity);
if (!result) {
return JsonResult.error();
}
return JsonResult.success();
}

/**
* 根据实体对象添加、编辑记录
*
* @param entity 实体对象
* @return
*/
@Override
public JsonResult edit(T entity) {
if (entity == null) {
return JsonResult.error("实体对象不存在");
}
if (entity.getId() != null && StringUtils.isNotEmpty(entity.getId())) {
// 修改记录
return this.update(entity);
} else {
// 新增记录
return this.add(entity);
}
}

/**
* 删除记录
*
* @param entity 实体对象
* @return
*/
@Override
public JsonResult delete(T entity) {
// entity.setUpdateUser(SecurityUtils.getUserId());
entity.setUpdateTime(DateUtils.now());
entity.setMark(0);
boolean result = this.updateById(entity);
if (!result) {
return JsonResult.error();
}
return JsonResult.success("删除成功");
}

/**
* 根据ID删除记录
*
* @param id 记录ID
* @return
*/
@Override
public JsonResult deleteById(String id) {
// return JsonResult.error("禁止删除,请联系管理员");
if (id == null || StringUtils.isEmpty(id)) {
return JsonResult.error("记录ID不能为空");
}
// 设置Mark=0
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.set("mark", 0);
updateWrapper.eq("id", id);
boolean result = update(updateWrapper);
if (!result) {
return JsonResult.error();
}
return JsonResult.success("删除成功");
}

/**
* 根据ID删除记录
*
* @param ids 记录ID
* @return
*/
@Override
public JsonResult deleteByIds(String[] ids) {
if (StringUtils.isNull(ids)) {
return JsonResult.error("记录ID不能为空");
}
// 设置Mark=0
Integer totalNum = 0;
for (String id : ids) {
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.set("mark", 0);
updateWrapper.eq("id", id);
boolean result = update(updateWrapper);
if (result) {
totalNum++;
}
}
if (totalNum != ids.length) {
return JsonResult.error();
}
return JsonResult.success("删除成功");
}

/**
* 设置状态
*
* @param entity 实体对象
* @return
*/
@Override
public JsonResult setStatus(T entity) {
return this.update(entity);
}

/**
* 导出Excel
*
* @return
*/
@Override
public List<T> exportExcel() {
return null;
}
}

+ 23
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/ExceptionInterface.java View File

@@ -0,0 +1,23 @@
package com.tuoheng.common.core.common;

/**
* 枚举类 封装
*
* @author zhu_zishuang
* @date 2021-03-12
*/
public interface ExceptionInterface {
/**
* 获取错误码
*
* @return
*/
int getCode();

/**
* 获取异常信息
*
* @return
*/
String getMessage();
}

+ 109
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/IBaseService.java View File

@@ -0,0 +1,109 @@
package com.tuoheng.common.core.common;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.tuoheng.common.core.utils.JsonResult;

import java.io.Serializable;
import java.util.List;


public interface IBaseService<T> extends IService<T> {

/**
* 根据查询条件获取数据列表
*
* @param page 分页
* @param query 查询条件
* @return
*/
JsonResult getList(Page<T> page, BaseQuery query);

/**
* 获取数据列表
*
* @param query 查询条件
* @return
*/
JsonResult getList(BaseQuery query);

/**
* 根据ID获取记录信息
*
* @param id 记录ID
* @return
*/
JsonResult info(String id);

/**
* 根据ID获取记录信息
*
* @param id 记录ID
* @return
*/
Object getInfo(Serializable id);

/**
* 根据实体对象添加记录
*
* @param entity 实体对象
* @return
*/
JsonResult add(T entity);

/**
* 根据实体对象更新记录
*
* @param entity 实体对象
* @return
*/
JsonResult update(T entity);

/**
* 根据实体对象添加、编辑记录
*
* @param entity 实体对象
* @return
*/
JsonResult edit(T entity);

/**
* 删除记录
*
* @param entity 实体对象
* @return
*/
JsonResult delete(T entity);

/**
* 根据ID删除记录
*
* @param id 记录ID
* @return
*/
JsonResult deleteById(String id);

/**
* 根据ID删除记录
*
* @param ids 记录ID
* @return
*/
JsonResult deleteByIds(String[] ids);

/**
* 设置状态
*
* @param entity 实体对象
* @return
*/
JsonResult setStatus(T entity);

/**
* 导出Excel
*
* @return
*/
List<T> exportExcel();

}

+ 52
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/common/OperationEnum.java View File

@@ -0,0 +1,52 @@
package com.tuoheng.common.core.common;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;

/**
* 全局枚举常量类
*
* @author zhu_zishuang
* @date 2021-03-12
*/
@Accessors(chain = true)
@AllArgsConstructor
public enum OperationEnum implements ExceptionInterface {
/**
* 登陆成功
*/
LOGIN_SUCCESS(200, "登陆成功!"),
/**
* 新增操作成功
*/
SAVE_SUCCESS(201, "新增成功!"),
/**
* 修改操作成功
*/
UPDATE_SUCCESS(202, "修改成功!"),
/**
* 删除操作成功
*/
DELETE_SUCCESS(203, "删除成功!"),

/**
* 操作异常
*/
OPERATION_ERROR(204, "操作失败!"),
/**
* 操作成功
*/
OPERATION_SUCCESS(205, "操作成功!");
/**
* 结果类型CODE
*/
@Getter
private final int code;

/**
* 结果类型描述
*/
@Getter
private final String message;
}

+ 177
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/RedisConfig.java View File

@@ -0,0 +1,177 @@
package com.tuoheng.common.core.config;


import com.tuoheng.common.core.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
//@PropertySource("classpath:redis.properties")
public class RedisConfig {

@Value("${spring.redis.host}")
private String hostName;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private Integer timeout;
/*
@Value("${redis.maxIdle}")
private Integer maxIdle;

@Value("${redis.maxTotal}")
private Integer maxTotal;

@Value("${redis.maxWaitMillis}")
private Integer maxWaitMillis;

@Value("${redis.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;

@Value("${redis.numTestsPerEvictionRun}")
private Integer numTestsPerEvictionRun;

@Value("${redis.timeBetweenEvictionRunsMillis}")
private long timeBetweenEvictionRunsMillis;

@Value("${redis.testOnBorrow}")
private boolean testOnBorrow;

@Value("${redis.testWhileIdle}")
private boolean testWhileIdle;
*/
/**
* JedisPoolConfig 连接池
* @return

@Bean public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空闲时检查有效性, 默认false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}

/**
* 单机版配置
* @Title: JedisConnectionFactory
* @param @param jedisPoolConfig
* @param @return
* @return JedisConnectionFactory
* @autor lpl
* @date 2018年2月24日
* @throws

@Bean public JedisConnectionFactory jedisConnectionFactory(){
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(hostName);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);

JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfigurationBuilder = JedisClientConfiguration.builder();
jedisClientConfigurationBuilder.connectTimeout(Duration.ofMillis(timeout));

JedisConnectionFactory factory = new JedisConnectionFactory(redisStandaloneConfiguration,jedisClientConfigurationBuilder.build());

return factory;
}
*/
/**
* 实例化 RedisTemplate 对象 jredis实现方式,springboot2.x以后使用下面的方法
*
* @return
@Bean public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}
*/
/**
* lettuce实现redis方式
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}

/**
* 设置数据存入 redis 的序列化方式,并开启事务
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
//如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 开启事务
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(factory);
}

/**
* 注入封装RedisTemplate
*
* @return RedisUtil
* @throws
* @Title: redisUtil
* @autor lpl
* @date 2017年12月21日
*/
@Bean(name = "redisUtils")
public RedisUtils redisUtils(RedisTemplate<String, Object> redisTemplate) {
RedisUtils redisUtil = new RedisUtils();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}

// @Bean("redissonClient")
// public Redisson getRedisson(){
// Config config = new Config();
// String redisson_url = String.format(Locale.ENGLISH, "redis://%s:%s", hostName, port);
// config.useSingleServer().setAddress(redisson_url).setDatabase(0);
// return (Redisson) Redisson.create(config);
// }

/**
* 创建Redis消息监听者容器
*
* @param factory
* @return
*/
@Bean("redisMessageListenerContainer")
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory){
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
return container;
}
}

+ 40
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/UploadFileConfig.java View File

@@ -0,0 +1,40 @@
package com.tuoheng.common.core.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
* 文件上传配置
*/
@Configuration
@Data
public class UploadFileConfig {
/**
* 上传目录
*/
public static String uploadFolder;
/**
* 访问路径
*/
public static String staticAccessPath;
/**
* 上传服务器的映射文件夹
*/
public static String accessPath;

@Value("${file.uploadFolder}")
public void setUploadFolder(String path) {
uploadFolder = path;
}

@Value("${file.staticAccessPath}")
public void setStaticAccessPath(String path) {
staticAccessPath = path;
}

@Value("${file.accessPath}")
public void setAccessPath(String path) {
accessPath = path;
}
}

+ 27
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/ValidatorConfig.java View File

@@ -0,0 +1,27 @@
package com.tuoheng.common.core.config;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
* 验证配置类
*/
@Configuration
public class ValidatorConfig {

@Bean
public ValidatorFactory validatorFactory() {
return Validation.byProvider(HibernateValidator.class).configure().failFast(false).buildValidatorFactory();
}

@Bean
public Validator validator(ValidatorFactory validatorFactory) {
return validatorFactory.getValidator();
}

}

+ 128
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/common/CommonConfig.java View File

@@ -0,0 +1,128 @@
package com.tuoheng.common.core.config.common;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
@Data
public class CommonConfig {

/**
* 图片域名
*/
public static String imageURL;

/**
* OSS域名
*/
public static String ossURL;

/**
* 视频域名
*/
public static String videoURL;

/**
* 高德KEY
*/
public static String gaodeKey;

/**
* 通道地址
*/
public static String channelUrl;

/**
* 飞手平台URL
*/
public static String pilotURL;

/**
* oidc地址
*/
public static String oidcUrl;

/**
* 机场地址
*/
public static String airportURL;

/**
* 图片域名赋值
*
* @param url 域名地址
*/
@Value("${tuoheng.image-url}")
public void setImageURL(String url) {
imageURL = url;
}

/**
* 阿里云OSS域名
*
* @param url 图片地址
*/
@Value("${tuoheng.oss-url:}")
public void setOssURL(String url) {
ossURL = url;
}

/**
* 视频域名赋值
*
* @param url 域名地址
*/
@Value("${tuoheng.video-url:}")
public void setVideoURL(String url) {
videoURL = url;
}

/**
* 高德KEY赋值
*
* @param key 高德KEY
*/
@Value("${tuoheng.gaodeKey:}")
public void setGaodeKey(String key) {
gaodeKey = key;
}

/**
* 通道域名赋值
*
* @param url 通道地址
*/
@Value("${tuoheng.live-channel-domain-url:}")
public void setChannelUrl(String url) {
channelUrl = url;
}

/**
* 飞手平台
* @param url 不同环境对应不同的url
*/
@Value("${tuoheng.pilot-url}")
public void setPilotURL(String url) {
pilotURL = url;
}

/**
* OICD平台
* @param url 不同环境对应不同的url
*/
@Value("${tuoheng.oidc-url}")
public void setOidcUrlL(String url) {
oidcUrl = url;
}

/**
* 机场url
* @param url
*/
@Value("${tuoheng.airport-url}")
public void airportURL(String url) {
airportURL = url;
}

}

+ 43
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/DefaultClientHttpRequestInterceptor.java View File

@@ -0,0 +1,43 @@
package com.tuoheng.common.core.config.http;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
* 默认拦截器
*/
public class DefaultClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClientHttpRequestInterceptor.class);

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
trackRequest(request,body);
ClientHttpResponse httpResponse = execution.execute(request, body);
trackResponse(httpResponse);
return httpResponse;
}

private void trackResponse(ClientHttpResponse httpResponse)throws IOException {
LOGGER.info("============================response begin==========================================");
LOGGER.info("Status code : {}", httpResponse.getStatusCode());
LOGGER.info("Status text : {}", httpResponse.getStatusText());
LOGGER.info("Headers : {}", httpResponse.getHeaders());
LOGGER.info("=======================response end=================================================");
}

private void trackRequest(HttpRequest request, byte[] body)throws UnsupportedEncodingException {
LOGGER.info("======= request begin ========");
LOGGER.info("uri : {}", request.getURI());
LOGGER.info("method : {}", request.getMethod());
LOGGER.info("headers : {}", request.getHeaders());
LOGGER.info("request body : {}", new String(body, "UTF-8"));
LOGGER.info("======= request end ========");
}
}

+ 32
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/HeadClientHttpRequestInterceptor.java View File

@@ -0,0 +1,32 @@
package com.tuoheng.common.core.config.http;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

/**
* 默认拦截器
*/
public class HeadClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(HeadClientHttpRequestInterceptor.class);

@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
LOGGER.info("#####head handle########");
HttpHeaders headers = httpRequest.getHeaders();
headers.add("Accept", "application/json");
headers.add("Accept-Encoding", "gzip");
headers.add("Content-Encoding", "UTF-8");
headers.add("Content-Type", "application/json; charset=UTF-8");
ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes);
HttpHeaders headersResponse = response.getHeaders();
headersResponse.add("Accept", "application/json");
return response;
}
}

+ 64
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/RestProperties.java View File

@@ -0,0 +1,64 @@
package com.tuoheng.common.core.config.http;

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
@Getter
@Setter
public class RestProperties {

public final static String HTTP = "http";

public final static String HTTPS = "https";

/**
* 连接超时, 默认10秒
*/
@Value("${spring.http.restTemplate.connect.timeout: 10000}")
private Integer connectTimeout;

/**
* 响应超时, 默认2分钟
*/
@Value("${spring.http.restTemplate.read.timeout: 120000}")
private Integer readTimeout;

/**
* 请求超时时间, 默认10秒
*/
@Value("${spring.http.restTemplate.connection.request.timeout: 10000}")
private Integer connectionRequestTimeout;

/**
* 请求失败重试次数, 默认重试3次
*/
@Value("${spring.http.restTemplate.retryCount: 3}")
private Integer retryCount;

/**
* 请求失败重试开关,默认开启
*/
@Value("${spring.http.restTemplate.requestSentRetryEnabled: true}")
private Boolean requestSentRetryEnabled;

/**
* 线程池最大连接数,默认1000
*/
@Value("${spring.http.restTemplate.pool.maxTotal: 1000}")
private Integer maxTotal;

/**
* 线程池主机最大并发数,默认100
*/
@Value("${spring.http.restTemplate.pool.maxPerRoute: 100}")
private Integer maxPerRoute;

/**
* 线程池空闲连接过期时间,默认60秒
*/
@Value("${spring.http.restTemplate.pool.validateAfterInactivity: 60000}")
private Integer validateAfterInactivity;
}

+ 177
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/http/RestTemplateConfig.java View File

@@ -0,0 +1,177 @@
package com.tuoheng.common.core.config.http;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class RestTemplateConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateConfig.class);

@Bean
public RestTemplate restTemplate(RestProperties restProperties) {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory(restProperties));
// 获取restTemplate中的转换器集合
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
// 遍历转换器集合,找到对应的StringHttpMessageConverter转换器
for (HttpMessageConverter<?> converter : converterList) {
if(converter.getClass() == StringHttpMessageConverter.class){
converterList.remove(converter);
break;
}
}
// 添加新的StringHttpMessageConverter转换器,并设置字符集为UTF-8
converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
// 添加拦截器
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
// interceptors.add(new DefaultClientHttpRequestInterceptor());
interceptors.add(new HeadClientHttpRequestInterceptor());
restTemplate.setInterceptors(interceptors);
return restTemplate;
}

private ClientHttpRequestFactory clientHttpRequestFactory(RestProperties restProperties) {
// httpClientBuilder配置构架器
HttpClientBuilder httpClientBuilder = HttpClients.custom();
// 设置重试次数,此处注意,如果使用无参构造,重试次数为3。this(3, false);
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(restProperties.getRetryCount(), restProperties.getRequestSentRetryEnabled()));
// 设置保持长连接
httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
// 使用连接池
httpClientBuilder.setConnectionManager(poolingConnectionManager(restProperties));
// 获取httpClient
CloseableHttpClient httpClient = httpClientBuilder.build();
// 配置HttpClient的对应工厂HttpComponentsClientHttpRequestFactory
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
factory.setConnectTimeout(restProperties.getConnectTimeout());
factory.setReadTimeout(restProperties.getReadTimeout());
factory.setConnectionRequestTimeout(restProperties.getConnectionRequestTimeout());
return factory;
}

private HttpClientConnectionManager poolingConnectionManager(RestProperties restProperties) {
// 注册http和https请求
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(RestProperties.HTTP, PlainConnectionSocketFactory.getSocketFactory())
.register(RestProperties.HTTPS, createSSLConn())
.build();
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(registry);
// 最大连接数
poolingConnectionManager.setMaxTotal(restProperties.getMaxTotal());
// 每个主机的并发
poolingConnectionManager.setDefaultMaxPerRoute(restProperties.getMaxPerRoute());
// 空闲连接过期时间
poolingConnectionManager.setValidateAfterInactivity(restProperties.getValidateAfterInactivity());
return poolingConnectionManager;
}

private SSLConnectionSocketFactory createSSLConn() {
SSLConnectionSocketFactory sslsf = null;
try
{
SSLContext sslContext = new SSLContextBuilder()
// 不检查证书
.loadTrustMaterial(null, (X509Certificate[] chain, String authType) -> true)
.build();
// 不检查hostname
sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
} catch (GeneralSecurityException e){
LOGGER.error("restTemplate开启SSL校验失败", e);
}
return sslsf;
}


/**
* 自定义的重试策略,需要的时候使用
*/
private void customHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled){
// 请求失败时,进行请求重试
HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int currentRetryCount, HttpContext httpContext) {
if(!requestSentRetryEnabled){
return false;
}
if (currentRetryCount > retryCount){
// 重试超过3次,放弃请求
LOGGER.error("retry has more than 3 time, give up request");
return false;
}
if (e instanceof NoHttpResponseException){
// 服务器没有响应,可能是服务器断开了连接,应该重试
LOGGER.error("receive no response from server, retry");
return true;
}
if (e instanceof SSLHandshakeException){
// SSL握手异常
LOGGER.error("SSL hand shake exception");
return false;
}
if (e instanceof InterruptedIOException){
// 超时
LOGGER.error("InterruptedIOException");
return false;
}
if (e instanceof UnknownHostException){
// 服务器不可达
LOGGER.error("server host unknown");
return false;
}
if (e instanceof ConnectTimeoutException){
// 连接超时
LOGGER.error("Connection Time out");
return false;
}
if (e instanceof SSLException){
LOGGER.error("SSLException");
return false;
}
HttpClientContext context = HttpClientContext.adapt(httpContext);
HttpRequest request = context.getRequest();
if (!(request instanceof HttpEntityEnclosingRequest)){
// 如果请求不是关闭连接的请求
return true;

}
return false;
}
};
}
}

+ 113
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/redisson/RedissonDistributedLockAspectConfiguration.java View File

@@ -0,0 +1,113 @@
//package com.tuoheng.common.core.config.redisson;
//
//import com.tuoheng.common.core.annotation.LockAction;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.redisson.api.RLock;
//import org.redisson.api.RedissonClient;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
//import org.springframework.expression.EvaluationContext;
//import org.springframework.expression.ExpressionParser;
//import org.springframework.expression.spel.standard.SpelExpressionParser;
//import org.springframework.expression.spel.support.StandardEvaluationContext;
//import org.springframework.util.StringUtils;
//
//import java.lang.reflect.Method;
//import java.util.Locale;
//
///**
// * @author chenyukun
// */
//@Aspect
//@Configuration
//@ConditionalOnProperty(name = "spring.redis.consumer.enable", havingValue = "true")
//public class RedissonDistributedLockAspectConfiguration {
//
// private final Logger logger = LoggerFactory.getLogger(RedissonDistributedLockAspectConfiguration.class);
//
// @Autowired
// @Qualifier("redissonClient")
// private RedissonClient redissonClient;
//
// private final ExpressionParser parser = new SpelExpressionParser();
//
// private final LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
//
// @Pointcut("@annotation(com.tuoheng.common.core.annotation.LockAction)")
// private void lockPoint(){
// }
//
// @Around("lockPoint()")
// public Object around(ProceedingJoinPoint pjp) throws Throwable{
// Method method = ((MethodSignature) pjp.getSignature()).getMethod();
// LockAction lockAction = method.getAnnotation(LockAction.class);
// String key = lockAction.value();
// String prefix = lockAction.prefix();
// Object[] args = pjp.getArgs();
// key = parse(key, method, args);
// if(!StringUtils.hasLength(key) || !StringUtils.hasLength(prefix)){
// logger.error("get key or prefix failed. key is null or prefix is null");
// return null;
// }
// RLock lock = getLock(String.format(Locale.ENGLISH,"%s%s", prefix, key), lockAction);
// if(!lock.tryLock(lockAction.waitTime(), lockAction.leaseTime(), lockAction.unit())) {
// logger.debug("get lock failed [{}]", key);
// return null;
// }
//
// //得到锁,执行方法,释放锁
// logger.debug("get lock success [{}]", key);
// try {
// return pjp.proceed();
// } finally {
// lock.unlock();
// logger.debug("release lock [{}]", key);
// }
// }
//
// /**
// * 解析spring EL表达式
// * @param key 表达式
// * @param method 方法
// * @param args 方法参数
// * @return string
// */
// private String parse(String key, Method method, Object[] args) {
// String[] params = discoverer.getParameterNames(method);
// if(params == null || params.length == 0){
// return null;
// }
// EvaluationContext context = new StandardEvaluationContext();
// for (int i = 0; i < params.length; i ++) {
// context.setVariable(params[i], args[i]);
// }
// return parser.parseExpression(key).getValue(context, String.class);
// }
//
// private RLock getLock(String key, LockAction lockAction) {
// switch (lockAction.lockType()) {
// case REENTRANT_LOCK:
// return redissonClient.getLock(key);
//
// case FAIR_LOCK:
// return redissonClient.getFairLock(key);
//
// case READ_LOCK:
// return redissonClient.getReadWriteLock(key).readLock();
//
// case WRITE_LOCK:
// return redissonClient.getReadWriteLock(key).writeLock();
// default:
// throw new RuntimeException("do not support lock type:" + lockAction.lockType().name());
// }
// }
//}

+ 86
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/config/xxl/XxlJobConfig.java View File

@@ -0,0 +1,86 @@
package com.tuoheng.common.core.config.xxl;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
@ConditionalOnProperty(name = XxlJobConfig.XXL_ENABLE, havingValue = XxlJobConfig.TRUE)
public class XxlJobConfig {

public static final String XXL_ENABLE = "xxl.enable";

public static final String TRUE = "true";

private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

@Value("${xxl.job.admin.addresses}")
private String adminAddresses;

@Value("${xxl.job.accessToken}")
private String accessToken;

@Value("${xxl.job.executor.appname}")
private String appname;

@Value("${xxl.job.executor.address}")
private String address;

@Value("${xxl.job.executor.ip}")
private String ip;

@Value("${xxl.job.executor.port}")
private int port;

@Value("${xxl.job.executor.logpath}")
private String logPath;

@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;


@Bean
public XxlJobSpringExecutor xxlJobExecutor() throws InterruptedException {
logger.info(">>>>>>>>>>> xxl-job config init.");
Thread.sleep(5000);
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

return xxlJobSpringExecutor;
}

/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/


}

+ 111
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/constant/CommonConstants.java View File

@@ -0,0 +1,111 @@
package com.tuoheng.common.core.constant;

/**
* 系统公共常量
*/
public class CommonConstants {

/**
* 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 Integer SUCCESS = 200;

/**
* 失败标记
*/
public static final Integer FAIL = 500;

/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";

/**
* 注销
*/
public static final String LOGOUT = "Logout";

/**
* 注册
*/
public static final String REGISTER = "Register";

/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";

/**
* 当前记录起始索引
*/
public static final 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";

/**
* 验证码 redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";

/**
* 验证码有效期(分钟)
*/
public static final Integer CAPTCHA_EXPIRATION = 2;

/**
* 参数管理 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";

/**
* 类型:1巡检任务
*/
public static final int INSPECTION_TASK_TYPE = 1;
//常用数值
public static final int ONE = 1;


}

+ 16
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/constant/SecurityHeadConstant.java View File

@@ -0,0 +1,16 @@
package com.tuoheng.common.core.constant;

/**
* @Author: 吴彬
* @CreateTime: 2022-09-19 08:57
* @Description: 服务间请求头身份信息配置常量
* @Version: 1.0
*/
public class SecurityHeadConstant {

/**
* 用户信息加密串
*/
public static final String JSON_TOKEN = "json-token";

}

+ 183
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/entity/UserEntity.java View File

@@ -0,0 +1,183 @@
package com.tuoheng.common.core.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.fasterxml.jackson.annotation.JsonFormat;
import com.tuoheng.common.core.common.BaseEntity;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.util.Date;

/**
* <p>
* 后台用户管理表
* </p>
*
* @author 拓恒
* @since 2022-06-21
*/
@Data
@TableName("th_oauth_user")
public class UserEntity extends BaseEntity {


/**
* 用户编号
*/
private String code;

/**
* 真实姓名
*/
private String realname;

/**
* 昵称
*/
private String nickname;

/**
* 性别:1男 2女 3保密
*/
private Integer gender;

/**
* 头像
*/
private String avatar;

/**
* 手机号码
*/
private String mobile;

/**
* 邮箱地址
*/
private String email;

/**
* 出生日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date birthday;

/**
* 部门ID
*/
private String deptId;

/**
* 省份编码
*/
private String provinceCode;

/**
* 城市编码
*/
private String cityCode;

/**
* 区县编码
*/
private String districtCode;
/**
* 街道编码
*/
private String streetCode;
/**
* 详细地址
*/
private String address;

/**
* 所属城市
*/
private String cityName;

/**
* 登录用户名
*/
private String username;

/**
* 登录密码
*/
private String password;

/**
* 用户类型:1管理员
*/
private Integer type;

/**
* 驾照类型:1飞行执照 2飞行许可证
*/
private Integer driverType;

/**
* 驾照编号
*/
private String driverCode;

/**
* 盐加密
*/
private String salt;

/**
* 个人简介
*/
private String intro;

/**
* 状态:1正常 2禁用
*/
private Integer status;

/**
* 备注
*/
private String note;

/**
* 显示顺序
*/
private Integer sort;

/**
* 登录次数
*/
private Integer loginNum;

/**
* 最近登录IP
*/
private String loginIp;

/**
* 最近登录时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date loginTime;

/**
* 角色ID
*/
@TableField(exist = false)
private String[] roleIds;

/**
* 城市集合
*/
@TableField(exist = false)
private String[] city;

}

+ 27
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/HttpStatusEnum.java View File

@@ -0,0 +1,27 @@
package com.tuoheng.common.core.enums;

import lombok.Getter;

/**
* 请求状态
*
* @author chenyukun
* @date 2022/06/14
*/
public enum HttpStatusEnum {

NO_RESOURCES(600,"暂无可用的服务资源, 请稍后再试!"),

;

HttpStatusEnum(int code, String description){
this.code = code;
this.description = description;
}

@Getter
private int code;

@Getter
private String description;
}

+ 20
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/LockType.java View File

@@ -0,0 +1,20 @@
package com.tuoheng.common.core.enums;

/**
* @author chenyukun
*/

public enum LockType {

/** 可重入锁*/
REENTRANT_LOCK,

/** 公平锁*/
FAIR_LOCK,

/** 读锁*/
READ_LOCK,

/** 写锁*/
WRITE_LOCK;
}

+ 68
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/LogType.java View File

@@ -0,0 +1,68 @@
package com.tuoheng.common.core.enums;

/**
* 日志类型
*/
public enum LogType {

/**
* 其它
*/
OTHER,

/**
* 新增
*/
INSERT,

/**
* 修改
*/
UPDATE,

/**
* 删除
*/
DELETE,

/**
* 授权
*/
GRANT,

/**
* 导出
*/
EXPORT,

/**
* 导入
*/
IMPORT,

/**
* 强退
*/
FORCE,

/**
* 生成代码
*/
GENCODE,

/**
* 清空数据
*/
CLEAN,

/**
* 状态
*/
STATUS,

/**
* 重置密码
*/
RESETPWD,

}

+ 23
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/OperType.java View File

@@ -0,0 +1,23 @@
package com.tuoheng.common.core.enums;

/**
* 操作类型
*/
public enum OperType {

/**
* 其它
*/
OTHER,

/**
* 后台用户
*/
MANAGE,

/**
* 手机端用户
*/
MOBILE

}

+ 27
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/PhotographyEnum.java View File

@@ -0,0 +1,27 @@
package com.tuoheng.common.core.enums;

import lombok.Getter;

/**
* 摄影方式枚举类
*
* @Author xiaoying
* @Date 2022/10/11 17:37
*/
public enum PhotographyEnum {

INSPECTION(1, "普通巡检"),
ORTHOIMAGE(2, "正射影像"),
INCLINEDIMAGE(3, "倾斜摄影");

PhotographyEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}

@Getter
private final int code;

@Getter
private final String msg;
}

+ 113
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/ServiceExceptionEnum.java View File

@@ -0,0 +1,113 @@
package com.tuoheng.common.core.enums;


import com.tuoheng.common.core.exception.ExceptionInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* 业务异常 枚举
*
* @author zhu_zishuang
* @date 2021-03-12
*/
@AllArgsConstructor
public enum ServiceExceptionEnum implements ExceptionInterface {

/**
* 未查询到数据
*/
GET_NO_DATA(10001, "未查到该记录!"),
/**
* 参数为空
*/
PARAMETER_IS_NULL(10002, "参数为空!"),

/**
* 获取用户ID失败
*/
GET_NO_USER_ID(10003, "获取用户ID失败!"),

/**
* websocket连接异常!
*/
WEB_SOCKET_CONNECTION_ERROR(10004, "websocket连接异常!"),

/**
* 文件不能为空!
*/
FILE_IS_EMPTY(10005, "上传文件不能为空!"),

/**
* 上传文件格式错误!
*/
FILE_FORMAT_IS_ERROR(10006, "上传文件格式错误!"),

/**
* 获取租户信息失败!
*/
GET_NO_TENANT(10007, "获取租户信息失败!"),

/**
* 上传文件数据错误,请检查文件!
*/
FILE_DATA_IS_ERROR(10101, "上传文件数据错误,请检查文件!"),

/**
* 上传文件数据错误,请检查文件!
*/
FILE_DATA_TIME_IS_ERROR(10102, "上传文件数据错误,请检查文件!"),

/**
* 上传文件数据错误,请检查文件!
*/
FILE_DATA_LNG_IS_ERROR(10103, "上传文件数据错误,请检查文件!"),

/**
* 上传文件数据错误,请检查文件!
*/
FILE_DATA_LAT_IS_ERROR(10104, "上传文件数据错误,请检查文件!"),

/**
* 读取图片经纬度失败,请手动填写!
*/
IMAGE_LOCATION_IS_ERROR(11001, "读取图片经纬度失败,请手动填写!"),

/**
* 任务不存在!
*/
TASK_DOES_NOT_EXIST(11111, "巡检任务不存在,请先创建巡检任务!"),

/**
* 视频分析中,请稍后再试
*/
VIDEO_ANALYSIS_IN_PROGRESS(11112, "视频分析中,请稍后再试!"),

/**
* 只有飞行完成状态可以操作
*/
TASK_NOT_OPERATION(11113, "只有飞行完成状态可以操作!"),

/**
* 没有这个飞行状态
*/
TASK_NOT_STATUS(11114, "飞行状态出错!"),

/**
* 巡检时间已过期
*/
INSPECTION_TIME_EXPIRE(11115, "巡检时间已过期,无法审核通过!"),
/**
* 巡检时间已过期
*/
USER_NOT_EXIST(11116, "用户不存在"),
;

@Getter
private final int code;

@Getter
private final String msg;


}

+ 97
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/enums/SysExceptionEnum.java View File

@@ -0,0 +1,97 @@
package com.tuoheng.common.core.enums;

import com.tuoheng.common.core.exception.ExceptionInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* 系统异常 枚举
*
* @author zhu_zishuang
* @date 2021-03-12
*/
@AllArgsConstructor
public enum SysExceptionEnum implements ExceptionInterface {
/* ===========================User====================================== */
/**
* 数据校验异常
*/
PARAMETER_EMPTY_EXCEPTION(10000, "非法参数!"),

/**
* 登录用户名不能为空
*/
ACCOUNT_IS_EMPTY(10001, "登录用户名不能为空!"),

/**
* 用户名不存在
*/
PASSWORD_IS_EMPTY(10002, "登录密码不能为空!"),

/**
* 用户信息不存在
*/
ACCOUNT_NOT_EXIST(10003, "用户信息不存在!"),

/**
* 用户名或密码错误
*/
ACCOUNT_OR_PASSWORD_ERROR(10004, "用户名或密码错误,请重新输入!"),

/**
* token为空,鉴权失败
*/
TOKEN_IS_EMPTY(10005, "token不能为空!"),

/**
* token已失效
*/
TOKEN_EXPIRED_EXCEPTION(10006,"token 已失效!"),

/**
* token 验证异常
*/
JWT_VERIFICATION_EXCEPTION(10007,"token 验证异常!"),

/**
* 无权访问
*/
PERMISSION_NOT(10008, "无访问权限"),

/**
* 系统发生异常
*/
SYS_EXCEPTION(10009, "系统发生异常!"),

/**
* 系统数据访问异常
*/
DATAACCESS_EXCEPTION(100010, "系统数据访问异常!"),

/**
* 创建线程失败异常
*/
INCREMENT_LESS_THAN_ZERO(10011, "递增因子小于0!"),

/**
* 文件导出关闭流异常
*/
EXPORT_EXCEPTION(10012, "文件导出关闭流异常!"),

/**
* 文件读取异常
*/
EXPORT_READ_EXCEPTION(10013, "文件读取异常!"),

/**
* 账号已被禁用
*/
ACCOUNT_IS_DISABLE(123,"您的账号已被禁用,请联系管理员"),
;

@Getter
private final int code;

@Getter
private final String msg;
}

+ 23
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/exception/ExceptionInterface.java View File

@@ -0,0 +1,23 @@
package com.tuoheng.common.core.exception;

/**
* 枚举类 封装
*
* @author zhu_zishuang
* @date 2021-03-12
*/
public interface ExceptionInterface {
/**
* 获取错误码
*
* @return
*/
int getCode();

/**
* 获取异常信息
*
* @return
*/
String getMsg();
}

+ 59
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/exception/ServiceException.java View File

@@ -0,0 +1,59 @@
package com.tuoheng.common.core.exception;

import com.tuoheng.common.core.utils.JsonResult;

/**
* 业务异常类(业务处理时手动抛出异常)
*
* @author zhu_zishuang
* @date 2021-03-12
*/
public class ServiceException extends RuntimeException {

/**
* 异常码
*/
public int code;

/**
* 异常描述,兼容JsonResult
*/
private String msg;


/**
* 构造器
*
* @param exceptionInfo
*/
public ServiceException(ExceptionInterface exceptionInfo) {
super(exceptionInfo.getMsg());
this.msg = exceptionInfo.getMsg();
this.code = exceptionInfo.getCode();
}

/**
* 构造器
*
* @param code
* @param msg
*/
public ServiceException(int code, String msg) {
super(msg);
this.msg = msg;
this.code = code;
}

/**
* 构造器
*
* @param msg
*/
public ServiceException(String msg) {
super(msg);
this.msg = msg;
this.code = JsonResult.ERROR;
}

}


+ 26
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/interceptor/FeignRequestInterceptor.java View File

@@ -0,0 +1,26 @@
//package com.tuoheng.common.core.interceptor;
//
//import com.tuoheng.common.core.constant.SecurityHeadConstant;
//import feign.RequestInterceptor;
//import feign.RequestTemplate;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//
///**
// * @Author: 吴彬
// * @CreateTime: 2022-09-19 08:57
// * @Description: gateway feign请求全局添加用户加密json-token
// * @Version: 1.0
// */
//@Configuration
//public class FeignRequestInterceptor implements RequestInterceptor {
//
// @Override
// public void apply(RequestTemplate requestTemplate) {
// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// requestTemplate.header(SecurityHeadConstant.JSON_TOKEN, request.getHeader(SecurityHeadConstant.JSON_TOKEN));
// }
//}

+ 21
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/model/dto/LoginUser.java View File

@@ -0,0 +1,21 @@
package com.tuoheng.common.core.model.dto;

import lombok.Data;
import lombok.experimental.Accessors;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/10/27 11:34
*/
@Data
@Accessors(chain = true)
public class LoginUser {

private String username;

private Long userId;

private String thToken;

}

+ 76
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/CommonNumberTypeUtils.java View File

@@ -0,0 +1,76 @@
package com.tuoheng.common.core.utils;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;

/**
* 数字处理
* @Author ChengWang
* @Date 2023/5/5
*/
public class CommonNumberTypeUtils {

/***
* @Description: 数字截取后几位,四舍五入
* @param: d
* @param: digit
*/
public static double round(double d, int digit) {

BigDecimal b = new BigDecimal(d);
return b.setScale(digit, BigDecimal.ROUND_HALF_UP).doubleValue();
}

/***
*
* @Description: 四舍五入
* @param d
* @param type 如: "#.00" 即表示为保留小数点后两位 几个0代表保留的位数
* @return
* @return double
* @throws @throws
*/
public static double subDecimalFormat(double d, String type) {
if (StringUtils.isBlank(type)) {
type = "#";
}
java.text.DecimalFormat df = new java.text.DecimalFormat(type);
double d1 = Double.parseDouble(df.format(d));
return d1;
}

/**
* @Description: 将浮点数转为百分数
* @param d
* @param IntegerDigits 小数点前保留的位数
* @param FractionDigits 小数点后保留的位数
* @return String
* @time 2018年10月1日 上午11:09:35
*/
public static String getPercentFormat(double d,int IntegerDigits,int FractionDigits){
NumberFormat nf = java.text.NumberFormat.getPercentInstance();
nf.setMaximumIntegerDigits(IntegerDigits);//小数点前保留几位
nf.setMinimumFractionDigits(FractionDigits);// 小数点后保留几位
String str = nf.format(d);
return str;
}

/**
* @Description: 将百分数转为浮点数
* @param d
* @return double
* @time 2018年10月1日 上午11:09:35
*/
public static double getPercentToDouble(String d, int digit){
NumberFormat nf=NumberFormat.getPercentInstance();
Number m = null;
try {
m = nf.parse(d);
} catch (ParseException e) {
e.printStackTrace();
}
return round(Double.parseDouble(String.valueOf(m.toString())), digit) ;
}

}

+ 322
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/CommonUtils.java View File

@@ -0,0 +1,322 @@
package com.tuoheng.common.core.utils;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.tuoheng.common.core.config.common.CommonConfig;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* 公共函数类
*/
public class CommonUtils {

private static final Pattern VOD_URL_PATTERN = Pattern.compile("^((https|http|ftp|rtsp|mms|rtmp|artc)://)"
+ "(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?"
+ "(([0-9]{1,3}\\.){3}[0-9]{1,3}"
+ "|"
+ "([0-9a-z_!~*'()-]+\\.)*"
+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\."
+ "[a-z]{2,6})"
+ "(:[0-9]{1,5})?"
+ "((/?)|"
+ "(/[0-9a-z_!~*'(){}.;?:@&=+$,%#-]+)+/?)$");

/**
* 获取到图片域名的地址
*
* @param imageUrl
* @return
*/
public static String getImageURL(String imageUrl) {
return CommonConfig.imageURL + imageUrl;
}

/**
* 正则匹配富文本图片
*
* @param htmlStr 富文本内容
* @return
*/
public static List<String> getImgStr(String htmlStr) {
Pattern p_image = Pattern.compile("<img.*src\\s*=\\s*(.*?)[^>]*?>", Pattern.CASE_INSENSITIVE);
Pattern r_image = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)");
List<String> list = new ArrayList<>();
Matcher m_image = p_image.matcher(htmlStr);
while (m_image.find()) {
// 得到<img />数据
String img = m_image.group();
System.out.println(img);
// 匹配<img>中的src数据
Matcher m = r_image.matcher(img);
while (m.find()) {
list.add(m.group(1));
}
}
return list;
}

/**
* 验证邮箱是否正确
*
* @param email
* @return
*/
public static boolean isEmail(String email) {
boolean flag = false;
try {
String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
Pattern regex = Pattern.compile(check);
Matcher matcher = regex.matcher(email);
flag = matcher.matches();
} catch (Exception e) {
flag = false;
}
return flag;
}

/**
* 验证手机号是否正确
*
* @param mobile
* @return
*/
public static boolean isMobile(String mobile) {
boolean flag = false;
try {
Pattern p = Pattern.compile("^((13[0-9])|(14[5|7])|(15[0-9])|(17[013678])|(18[0-9]))\\d{8}$");
Matcher m = p.matcher(mobile);
flag = m.matches();
} catch (Exception e) {
flag = false;
}
return flag;
}

/**
* 生成指定位数的随机字符串
*
* @param isNum 是否是纯数字
* @param length 长度
* @return
*/
public static String getRandomStr(boolean isNum, int length) {
String resultStr = "";
String str = isNum ? "1234567890" : "1234567890abcdefghijkmnpqrstuvwxyz";
int len = str.length();
boolean isStop = true;
do {
resultStr = "";
int count = 0;
for (int i = 0; i < length; i++) {
double dblR = Math.random() * len;
int intR = (int) Math.floor(dblR);
char c = str.charAt(intR);
if (('0' <= c) && (c <= '9')) {
count++;
}
resultStr += str.charAt(intR);
}
if (count >= 2) {
isStop = false;
}
} while (isStop);
return resultStr;
}

/**
* 判断是否在数组中
*
* @param s
* @param array
* @return
*/
public static boolean inArray(final String s, final String[] array) {
for (String item : array) {
if (item != null && item.equals(s)) {
return true;
}
}
return false;
}

/**
* 从html中提取纯文本
*
* @param strHtml
* @return
*/
public static String stripHtml(String strHtml) {
String content = strHtml.replaceAll("</?[^>]+>", ""); //剔出<html>的标签
content = content.replaceAll("\\s*|\t|\r|\n", "");//去除字符串中的空格,回车,换行符,制表符
return content;
}

/**
* 去除字符串中的空格、回车、换行符、制表符等
*
* @param str 原始字符串
* @return
*/
public static String replaceSpecialStr(String str) {
String repl = "";
if (str != null) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(str);
repl = m.replaceAll("");
}
return repl;
}

/**
* 判断某个元素是否在数组中
*
* @param key 元素
* @param map 数组
* @return
*/
public static boolean inArray(String key, Map<String, String> map) {
boolean flag = false;
for (String k : map.keySet()) {
if (k.equals(key)) {
flag = true;
}
}
return flag;
}

/**
* 对象转Map
*
* @param obj 对象
* @return
* @throws IllegalAccessException
*/
public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
Map<String, Object> map = new HashMap<>();
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = field.get(obj);
map.put(fieldName, value);
}
return map;
}

/**
* 判断是否是JSON格式
*
* @param str JSON字符串
* @return
*/
private boolean isJson(String str) {
try {
JSONObject jsonStr = JSONObject.parseObject(str);
return true;
} catch (Exception e) {
return false;
}
}

/**
* MD5方法
*
* @param source
* @return
*/
public static String md5(byte[] source) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(source);
StringBuffer buf = new StringBuffer();
for (byte b : md.digest()) {
buf.append(String.format("%02x", b & 0xff));
}
return buf.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 密码加密
*
* @param password 密码
* @return
*/
public static String password(String password) {
String md51 = md5(password.getBytes());
String pwd = md5((md51 + "IgtUdEQJyVevaCxQnY").getBytes());
return pwd;
}

/**
* 对数组进行分组
*
* @param list 数据源
* @param size 每组几个
* @param <T>
* @return
*/
public static <T> List<List<T>> split(List<T> list, Integer size) {
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>();
}
Integer count = list.size() / size;
List<List<T>> arrayList = new ArrayList<>();
for (int i = 0; i < count; i++) {
List<T> temp = list.subList(i * size, (i + 1) * size);
arrayList.add(temp);
}
Integer extra = list.size() % size;
if (extra != 0) {
List<T> temp = list.subList(count * size, count * size + extra);
arrayList.add(temp);
}
return arrayList;
}

/**
* 批量处理方法
*
* @param operater 回调方法,有入参无返回值
* @param sourceList 批量处理list对象
* @param threshold 阀值,比如有5000个对象,阀值设置1000,就是1000执行一次
* @param <T> 对象类型
*/
public static <T> void batchOperate(Consumer<List<T>> operater, List<T> sourceList, Integer threshold) {
int size = sourceList.size();
int fromIndex = 0;
List<T> list = null;
while (size > fromIndex){
list = sourceList.stream().skip(fromIndex).limit(threshold).collect(Collectors.toList());
operater.accept(list);
fromIndex += threshold;
}
}

/**
* 验证URL是否合法
*
* @param str 字符串url
* @return 布尔值
*/
public static boolean isURL(String str){
str = str.toLowerCase();
Matcher matcher = VOD_URL_PATTERN.matcher(str);
return matcher.find();
}

}

+ 274
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/DateUtils.java View File

@@ -0,0 +1,274 @@
package com.tuoheng.common.core.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
* 时间工具类
*/
public final 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"};


/**
* 获取当前时间
*
* @return
*/
public static Date now() {
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);
}
}

/**
* 检查字符串是否使时间格式
*
* @param format 格式
* @param ts 时间字符串
* @return 布尔值
*/
public static boolean checkStrIsDate(final String format, final String ts) {
try {
new SimpleDateFormat(format).parse(ts);
return true;
} catch (ParseException e) {
return false;
}
}

/**
* 日期路径 即年/月/日 如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 + "分钟";
}

/**
* 根据时间生成code
*/
public static String generateCode(String prefix) {
// 根据当前时间,生成任务编码
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
return prefix + formatter.format(date);
}

/**
* 生成图片编号,P+年月日时分秒+随机三位数
*
* @return
*/
public static String generateFileCode() {
String Date = DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS);
int randomNum = (int) (Math.random() * 900) + 100;
String fileCode = "P" + Date + randomNum;

return fileCode;
}

/**
* 返回字符串
* <p>
* 给原本的时间originDate加上自定义的时间
*
* @param originDate 原本的时间
* @param day 要加的天数
* @param hour 要加的小时数
* @param minute 要加的分钟数
* @param second 要加的秒数
* @return 返回加完时间后的时间str_goalDate
*/
public static String addDateTimeToStr(Date originDate, int day, int hour, int minute, int second) {
SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
cal.setTime(originDate);
cal.add(Calendar.DATE, day);// 24小时制,加天
cal.add(Calendar.HOUR, hour);// 24小时制 ,加小时
cal.add(Calendar.MINUTE, minute);// 24小时制,加分钟
cal.add(Calendar.SECOND, second);// 24小时制,加秒

String str_goalDate = dateFormate.format(cal.getTime());
return str_goalDate;
}

/**
* 返回java.util.Date
* <p>
* 给原本的时间originDate加上自定义的时间
*
* @param originDate 原本的时间
* @param day 要加的天数
* @param hour 要加的小时数
* @param minute 要加的分钟数
* @param second 要加的秒数
* @return 返回加完时间后的时间goalDate
*/
public static Date addDateTimeToDate(Date originDate, int day, int hour, int minute, int second) {
Calendar cal = Calendar.getInstance();
cal.setTime(originDate);
cal.add(Calendar.DATE, day);// 24小时制,加天
cal.add(Calendar.HOUR, hour);// 24小时制 ,加小时
cal.add(Calendar.MINUTE, minute);// 24小时制,加分钟
cal.add(Calendar.SECOND, second);// 24小时制,加秒

Date goalDate = cal.getTime();
return goalDate;
}

/**
* 比较2个时间
*
* @param date1
* @param date2
* @return -1:时间格式不对
* 0:date1 == date2
* 1:date1 < date2
* 2:date1 > date2
*/
public static int compareToDate(Date date1, Date date2) {
String dateStr1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date1);
String dateStr2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date2);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
try {
c1.setTime(df.parse(dateStr1));
c2.setTime(df.parse(dateStr2));
} catch (java.text.ParseException e) {
System.err.println("格式不正确");
return -1;
}
int result = c1.compareTo(c2);
if (result == 0) {
return 0;
} else if (result < 0) {
return 1;
} else {
return 2;
}
}

public static void main(String[] args) {
// 当前时间
Date date = new Date(System.currentTimeMillis());
System.out.println("当前时间 = " + date);

// 想加2小时5分10秒,且返回字符串
String strDate = addDateTimeToStr(date, 0, 2, 5, 10);
System.out.println("转换后的时间 = " + strDate);

System.out.println("-------------");
System.out.println("当前时间=" + date);
// 想加3小时2分5秒,且返回Date
Date goalDate = addDateTimeToDate(date, 0, 3, 2, 5);
System.out.println("转换后的时间 = " + goalDate);
}

}

+ 64
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/EncryptUtil.java View File

@@ -0,0 +1,64 @@
package com.tuoheng.common.core.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
* 加密工具类
* @Author: rosh
*/
public final class EncryptUtil {

private EncryptUtil() {

}

private static final Logger logger = LoggerFactory.getLogger(EncryptUtil.class);

public static String encodeBase64(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}

public static byte[] decodeBase64(String str) {

return Base64.getDecoder().decode(str);
}

public static String encodeUTF8StringBase64(String str) {
return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
}

public static String decodeUTF8StringBase64(String str) {
byte[] bytes = Base64.getDecoder().decode(str);
return new String(bytes, StandardCharsets.UTF_8);
}

public static String encodeURL(String url) {
String encoded = null;
try {
encoded = URLEncoder.encode(url, String.valueOf(StandardCharsets.UTF_8));
} catch (UnsupportedEncodingException e) {
logger.warn("URLEncode失败", e);
}
return encoded;
}


public static String decodeURL(String url) {
String decoded = null;
try {
decoded = URLDecoder.decode(url, String.valueOf(StandardCharsets.UTF_8));
} catch (UnsupportedEncodingException e) {
logger.warn("URLDecode失败", e);
}
return decoded;
}

}

+ 163
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ExceptionUtil.java View File

@@ -0,0 +1,163 @@
package com.tuoheng.common.core.utils;

import cn.hutool.core.util.ObjectUtil;
import com.tuoheng.common.core.exception.ExceptionInterface;
import com.tuoheng.common.core.exception.ServiceException;

import java.util.Optional;

/**
* 异常工具
* @author chenyukun
*/
public class ExceptionUtil {

private ExceptionUtil(){}

/**
* 抛服务异常
*
* @param code 异常编码
* @param exceptionMsg 异常信息
*/
public static void throwServiceExcetion(Integer code, String exceptionMsg){
throw new ServiceException(code, exceptionMsg);
}

/**
* 抛服务异常
*
* @param code 异常编码
* @param exceptionMsg 异常信息
* @param logMsg 日志消息
* @param logObj 日志消息占位对象
*/
public static void throwServiceExcetion(Integer code, String exceptionMsg, String logMsg, String ...logObj){
if(StringUtils.isNotEmpty(logObj)){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj));
}
if(StringUtils.isEmpty(logObj)){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x));
}
throw new ServiceException(code, exceptionMsg);
}

/**
* 抛服务异常
*
* @param code 异常编码
* @param exceptionMsg 异常信息
* @param exception 异常
* @param logMsg 日志消息
* @param logObj 日志消息占位对象
*/
public static void throwServiceExcetion(Integer code, String exceptionMsg, Exception exception, String logMsg,
String ...logObj){
if(StringUtils.isNotEmpty(logObj) && exception != null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj, exception));
}
if(StringUtils.isNotEmpty(logObj) && exception == null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj));
}
if(StringUtils.isEmpty(logObj) && exception != null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, exception));
}
if(StringUtils.isEmpty(logObj) && exception == null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x));
}
throw new ServiceException(code, exceptionMsg);
}

/**
* 抛服务异常
*
* @param exceptionInterface 异常接口
*/
public static void throwServiceExcetion(ExceptionInterface exceptionInterface){
throw new ServiceException(exceptionInterface);
}

/**
* 抛服务异常
*
* @param exceptionInterface 异常接口
* @param logMsg 日志消息
* @param logObj 日志对象
*/
public static void throwServiceExcetion(ExceptionInterface exceptionInterface, String logMsg, String ...logObj){
if(StringUtils.isNotEmpty(logObj)){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj));
}
if(StringUtils.isEmpty(logObj)){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x));
}
throw new ServiceException(exceptionInterface);
}

/**
* 抛服务异常
*
* @param exceptionInterface 异常接口
* @param exception 异常
* @param logMsg 日志消息
* @param logObj 日志对象
*/
public static void throwServiceExcetion(ExceptionInterface exceptionInterface, Exception exception, String logMsg,
String ...logObj){
if(StringUtils.isNotEmpty(logObj) && exception != null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj, exception));
}
if(StringUtils.isNotEmpty(logObj) && exception == null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, logObj));
}
if(StringUtils.isEmpty(logObj) && exception != null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x, exception));
}
if(StringUtils.isEmpty(logObj) && exception == null){
Optional.ofNullable(logMsg).ifPresent(x -> LogUtil.LOGGER.error(x));
}
throw new ServiceException(exceptionInterface);
}

/**
* 校验参数是否为空,为空抛异常
*
* @param obj 参数对象
* @param exceptionInterface 异常接口
*/
public static void paramIsNull(Object obj, ExceptionInterface exceptionInterface){
if(ObjectUtil.isEmpty(obj)){
throwServiceExcetion(exceptionInterface);
}
}

/**
* 校验参数是否为空,为空抛异常
*
* @param obj 参数对象
* @param exceptionInterface 异常接口
* @param logMsg 日志消息
* @param logObj 日志对象
*/
public static void paramIsNull(Object obj, ExceptionInterface exceptionInterface, String logMsg, String ...logObj){
if(ObjectUtil.isEmpty(obj)){
throwServiceExcetion(exceptionInterface, logMsg, logObj);
}
}

/**
* 校验参数是否为空,为空抛异常
*
* @param obj 参数对象
* @param exceptionInterface 异常接口
* @param exception 异常
* @param logMsg 日志消息
* @param logObj 日志对象
*/
public static void paramIsNull(Object obj, ExceptionInterface exceptionInterface, Exception exception,
String logMsg, String ...logObj){
if(ObjectUtil.isEmpty(obj)){
throwServiceExcetion(exceptionInterface, exception, logMsg, logObj);
}
}
}

+ 224
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/FileUtils.java View File

@@ -0,0 +1,224 @@
package com.tuoheng.common.core.utils;

import cn.hutool.core.util.ObjectUtil;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
* 文件处理工具类
*/
public class FileUtils {

public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";

/**
* 验证文件名是否含有特殊字符
*
* @param filename
* @return
*/
public static boolean isValidFilename(String filename) {
return filename.matches(FILENAME_PATTERN);
}

/**
* 下载文件并重新编码
*
* @param request 网络请求
* @param fileName 文件名
* @return
* @throws UnsupportedEncodingException
*/
public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
throws UnsupportedEncodingException {
final String agent = request.getHeader("USER-AGENT");
String filename = fileName;
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
filename = new String(fileName.getBytes(), "ISO8859-1");
} else if (agent.contains("Chrome")) {
// google浏览器
filename = URLEncoder.encode(filename, "utf-8");
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}

/**
* 输出指定文件的Byte数组
*
* @param filePath
* @param os
* @throws IOException
*/
public static void writeBytes(String filePath, OutputStream os) throws IOException {
FileInputStream fis = null;
try {
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(filePath);
}
fis = new FileInputStream(file);
byte[] b = new byte[1024];
int length;
while ((length = fis.read(b)) > 0) {
os.write(b, 0, length);
}
} catch (IOException e) {
throw e;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

/**
* 删除文件
*
* @param filePath 文件路径
* @return
*/
public static boolean deleteFile(String filePath) {
boolean flag = false;
File file = new File(filePath);
// 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}

/**
* MultipartFile 转 File
*
* @param mFile
* @param filePathName
*/
public static File multipartFileToFile(MultipartFile mFile, String filePathName) {
File file = null;
if (ObjectUtil.isNull(mFile)) {
throw new RuntimeException("图片不能为空!");
} else {
InputStream ins = null;
try {
ins = mFile.getInputStream();
file = new File(filePathName);
inputStreamToFile(ins, file);
ins.close();

} catch (IOException e) {
e.printStackTrace();
}
ThumbnailUtil.cenerateCompression(filePathName, filePathName, 300, 0.8);
return file;
}
}

/**
* File 转 MultipartFile
*
* @param file
* @throws Exception
*/
public static void fileToMultipartFile(File file) throws Exception {
// FileInputStream fileInput = new FileInputStream(file);
// MultipartFile toMultipartFile = new MockMultipartFile("file", file.getName(), "text/plain", getBytesByFile(fileInput));
// toMultipartFile.getInputStream();
}

public static String txtToString(String fileUrl) throws Exception {
StringBuilder sb = new StringBuilder();
int HttpResult; // 服务器返回的状态
try {
URL url = new URL(fileUrl); // 创建URL
URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
HttpResult = httpconn.getResponseCode();
if (HttpResult != HttpURLConnection.HTTP_OK) {
throw new RuntimeException("无法连接");
} else {
InputStreamReader isReader = new InputStreamReader(urlconn.getInputStream(), "UTF-8");
BufferedReader reader = new BufferedReader(isReader);
String line; // 用来保存每行读取的内容
line = reader.readLine(); // 读取第一行
while (line != null) { // 如果 line 为空说明读完了
sb.append(line); // 将读到的内容添加到 buffer 中
sb.append(" "); // 添加换行符
line = reader.readLine(); // 读取下一行
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}


public static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 将 File 转换成 Byte数组
*
* @param fis
* @return
*/
public static byte[] getBytesByFile(FileInputStream fis) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024 * 1024 * 10];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

}

+ 180
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/HttpUtils.java View File

@@ -0,0 +1,180 @@
package com.tuoheng.common.core.utils;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
* 通用http发送方法
*/
public class HttpUtils {

private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
StringBuilder result = new StringBuilder();
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.connect();
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
log.info("recv - {}", result);
} catch (ConnectException e) {
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
} catch (Exception e) {
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception ex) {
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
}
}
return result.toString();
}

/**
* 处理post请求
* @param urlStr 请求url
* @param data 请求体数据
* @param properties 请求头参数
* @return
*/
public static String doSend(String urlStr, JSONObject data, Map<String, String> properties, String method){
try {
log.info("请求url={}", urlStr);
log.info("请求体数据data={}", data.toJSONString());
log.info("请求头参数properties={}", properties);
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

connection.setDoInput(true); // 设置可输入
connection.setDoOutput(true); // 设置该连接是可以输出的
//设置连接超时时间和读取超时时间
connection.setConnectTimeout(15000);
connection.setReadTimeout(60000);
//设置请求方式
connection.setRequestMethod(method);
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
if(null != properties && !properties.isEmpty()){
for (String key:properties.keySet()){
connection.setRequestProperty(key, properties.get(key));
}
}

PrintWriter pw = new PrintWriter(new BufferedOutputStream(connection.getOutputStream()));
pw.write(data.toJSONString());
pw.flush();
pw.close();

BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
String line = null;
StringBuilder result = new StringBuilder();
while ((line = br.readLine()) != null) { // 读取数据
result.append(line).append("\n");
}
connection.disconnect();
log.info(result.toString());
return result.toString();
} catch (Exception e) {
log.error("post请求失败,{}",e.getMessage());
return "";
}
}

public static String sendSSLPost(String url, String param) {
StringBuilder result = new StringBuilder();
String urlNameString = url + "?" + param;
try {
log.info("sendSSLPost - {}", urlNameString);
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
URL console = new URL(urlNameString);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true);
conn.setDoInput(true);

conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.connect();
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String ret = "";
while ((ret = br.readLine()) != null) {
if (ret != null && !ret.trim().equals("")) {
result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
}
}
log.info("recv - {}", result);
conn.disconnect();
br.close();
} catch (ConnectException e) {
log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
} catch (Exception e) {
log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
}
return result.toString();
}

private static class TrustAnyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}

private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}

}

+ 296
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/IpUtils.java View File

@@ -0,0 +1,296 @@
package com.tuoheng.common.core.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
* 获取IP方法
*
* @author ruoyi
*/
@Slf4j
public class IpUtils
{
/**
* 获取客户端IP
*
* @param request 请求对象
* @return IP地址
*/
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Real-IP");
}

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getRemoteAddr();
}

return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}

/**
* 检查是否为内部IP地址
*
* @param ip IP地址
* @return 结果
*/
public static boolean internalIp(String ip)
{
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}

/**
* 检查是否为内部IP地址
*
* @param addr byte地址
* @return 结果
*/
private static boolean internalIp(byte[] addr)
{
if (StringUtils.isNull(addr) || addr.length < 2)
{
return true;
}
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte SECTION_1 = 0x0A;
// 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
switch (b0)
{
case SECTION_1:
return true;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4)
{
return true;
}
case SECTION_5:
switch (b1)
{
case SECTION_6:
return true;
}
default:
return false;
}
}

/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
return null;
}

byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
long l;
int i;
switch (elements.length)
{
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
{
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
{
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
{
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
}
catch (NumberFormatException e)
{
return null;
}
return bytes;
}

/**
* 获取IP地址
*
* @return 本地IP地址
*/
public static String getHostIp()
{
try
{
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
}
return "127.0.0.1";
}

/**
* 获取主机名
*
* @return 本地主机名
*/
public static String getHostName()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
}
return "未知";
}

/**
* 从多级反向代理中获得第一个非unknown IP地址
*
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip)
{
// 多级反向代理检测
if (ip != null && ip.indexOf(",") > 0)
{
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
ip = subIp;
break;
}
}
}
return ip;
}

/**
* 检测给定字符串是否为未知,多用于检测HTTP请求相关
*
* @param checkString 被检测的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString)
{
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}

/**
* 根据IP查询地区
*
* @param ip IP地址
* @return
*/
public static String getRealAddressByIP(String ip) {
String address = "XX XX";
// 内网不查询
if (IpUtils.internalIp(ip)) {
return "内网IP";
}
try {
String rspStr = HttpUtils.doSend("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip, new JSONObject(), null, "GET");
if (org.springframework.util.StringUtils.isEmpty(rspStr)) {
log.error("获取地理位置异常 {}", ip);
return address;
}
JSONObject obj = JSONObject.parseObject(rspStr);
JSONObject data = obj.getObject("data", JSONObject.class);
String region = data.getString("region");
String city = data.getString("city");
address = region + " " + city;
}catch (Exception e){
log.info("获取ip地址信息失败。{}",ip);
}
return address;
}
}

+ 132
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/JacksonUtil.java View File

@@ -0,0 +1,132 @@
package com.tuoheng.common.core.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Map;

public class JacksonUtil {

private final static Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);

private final static ObjectMapper objectMapper = new ObjectMapper();

private final static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

private JacksonUtil(){}

static {
//序列化的时候序列对象的所有属性
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
//反序列化的时候如果多了其他属性,不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//如果是空对象的时候,不抛异常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(dateformat);
}

/**
* 转换为 JSON 字符串
*
* @param obj
* @return
*/
public static <T> String obj2json(T obj) {
if(obj != null){
try {
return obj instanceof String ? (String)obj : objectMapper.writeValueAsString(obj);
} catch (Exception e) {
LOGGER.error("对象转字符串异常: {}", e);
}
}
return null;
}

/**
* 漂亮的转换为 JSON 字符串
*
* @param obj
* @return
*/
public static <T> String obj2StringPretty(T obj) {
if(obj != null){
try {
return obj instanceof String ? (String)obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (Exception e) {
LOGGER.error("对象转字符串异常: {}", e);
}
}
return null;
}

/**
* 转换为 JavaBean
*
* @param str
* @param clazz
* @return
* @throws Exception
*/
public static <T> T json2pojo(String str, Class<T> clazz) {
if(StringUtils.hasLength(str) && clazz != null){
try {
return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
} catch (Exception e) {
LOGGER.error("字符串转对象异常: {}", e);
}
}
return null;
}

/**
* 将 Map 转换为 JavaBean
*
* @param map
* @param clazz
* @return
*/
public static <T> T map2pojo(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}

/**
* 将 JSON 对象转换为 JavaBean
*
* @param obj
* @param clazz
* @return
*/
public static <T> T obj2pojo(Object obj, Class<T> clazz) {
return objectMapper.convertValue(obj, clazz);
}

/**
* 将指定节点的 JSON 数据转换为 JavaBean
*
* @param str
* @param treeNode
* @param clazz
* @return
*/
public static <T> T json2pojoByTree(String str, String treeNode, Class<T> clazz) {
if(StringUtils.hasLength(str) && StringUtils.hasLength(str) && clazz == null){
try {
JsonNode jsonNode = objectMapper.readTree(str);
JsonNode data = jsonNode.findPath(treeNode);
return json2pojo(data.toString(), clazz);
} catch (Exception e) {
LOGGER.error("字符串按节点转对象异常: {}", e);
}
}
return null;
}
}

+ 108
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/JsonResult.java View File

@@ -0,0 +1,108 @@
package com.tuoheng.common.core.utils;

import java.io.Serializable;

/**
* JSON回应类
*
* @author 牧羊人
* @date 2019/11/28
*/
public class JsonResult<T> implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 成功
*/
public static final int SUCCESS = 0;

/**
* 失败
*/
public static final int ERROR = -1;

private int code;

private String msg;

private T data;

public static <T> JsonResult<T> success() {
return jsonResult(null, SUCCESS, "操作成功");
}

public static <T> JsonResult<T> success(String msg) {
return jsonResult(null, SUCCESS, msg);
}

public static <T> JsonResult<T> success(T data) {
return jsonResult(data, SUCCESS, "操作成功");
}

public static <T> JsonResult<T> success(T data, String msg) {
return jsonResult(data, SUCCESS, msg);
}

public static <T> JsonResult<T> error() {
return jsonResult(null, ERROR, "操作失败");
}

public static <T> JsonResult<T> error(String msg) {
return jsonResult(null, ERROR, msg);
}

public static <T> JsonResult<T> error(T data) {
return jsonResult(data, ERROR, "操作失败");
}

public static <T> JsonResult<T> error(T data, String msg) {
return jsonResult(data, ERROR, msg);
}

public static <T> JsonResult<T> error(int code, String msg) {
return jsonResult(null, code, msg);
}

private static <T> JsonResult<T> jsonResult(T data, int code, String msg) {
JsonResult<T> result = new JsonResult<>();
result.setCode(code);
result.setData(data);
result.setMsg(msg);
return result;
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}


@Override
public String toString() {
return "JsonResult{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}

+ 15
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/LogUtil.java View File

@@ -0,0 +1,15 @@
package com.tuoheng.common.core.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 日志工具类
* @author chenyukun
*/
public class LogUtil {

private LogUtil(){}

public static final Logger LOGGER = LoggerFactory.getLogger(LogUtil.class);
}

+ 608
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/RedisUtils.java View File

@@ -0,0 +1,608 @@
package com.tuoheng.common.core.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisUtils {

private RedisTemplate<String, Object> redisTemplate;

public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
// =============================common============================

/**
* 普通缓存获取
*
* @param
* @return 值
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Set<String> keys(String pattern) {
return redisTemplate.keys(pattern);
}

/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}

/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}

// ============================String=============================

/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}

/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}

}

/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}

/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}

// ================================Map=================================

/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}

/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}

/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}

/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}

/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}

/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}

// ============================set=============================

/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}

/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}

/**
* 获取set缓存的长度
*
* @param key 键
* @return
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}

/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================

/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 获取list缓存的长度
*
* @param key 键
* @return
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}

/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}

/**
* 按键的排序获取对应的值
*
* @param keys 多个键
* @return List<Object>
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public List<Object> mget(Collection<String> keys) {
return redisTemplate.opsForValue().multiGet(keys);
}

}

+ 69
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/SecurityUserUtils.java View File

@@ -0,0 +1,69 @@
package com.tuoheng.common.core.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.model.dto.LoginUser;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class SecurityUserUtils {
/**
* 获取认证信息
*
* @return
*/
public static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}

/**
* 获取用户登录信息
*
* @return
*/
public static LoginUser getLoginUser() {
// header中获取用户token
String token = ServletUtils.getRequest().getHeader("th-token");
String oUserJson = ServletUtils.getRequest().getHeader("o-user-json");
String json = EncryptUtil.decodeUTF8StringBase64(oUserJson);
JSONObject jsonObject = JSON.parseObject(json);
String username = jsonObject.getString("username");
Long oidcUserId = jsonObject.getLong("oUserId");
// 这里可以自定义封装自己的用户信息
//UserPo userPo = clientUserMapper.getUserByUserName(username);
LoginUser user = new LoginUser()
.setUsername(username)
.setUserId(oidcUserId)
.setThToken(token);
return user;
}

public static String token() {
// header中获取用户token
String token = ServletUtils.getRequest().getHeader("th-token");
if (StringUtils.isEmpty(token)) {
throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "token不能为空");
}
return token;
}

/**
* 获取username
*
* @return
*/
public static String username() {
// header中获取用户token
String oUserJson = ServletUtils.getRequest().getHeader("o-user-json");
if (StringUtils.isEmpty(oUserJson)) {
throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "oUserJson不能为空");
}
String json = EncryptUtil.decodeUTF8StringBase64(oUserJson);
JSONObject jsonObject = JSON.parseObject(json);
String username = jsonObject.getString("username");
return username;
}

}

+ 188
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ServletUtils.java View File

@@ -0,0 +1,188 @@
package com.tuoheng.common.core.utils;

import cn.hutool.core.convert.Convert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

/**
* 客户端工具类
*
* @author ruoyi
*/
public class ServletUtils
{
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}

/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue)
{
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}

/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name)
{
return Convert.toInt(getRequest().getParameter(name));
}

/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue)
{
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}

/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name)
{
return Convert.toBool(getRequest().getParameter(name));
}

/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue)
{
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}

/**
* 获取request
*/
public static HttpServletRequest getRequest()
{
try
{
return getRequestAttributes().getRequest();
}
catch (Exception e)
{
return null;
}
}

/**
* 获取response
*/
public static HttpServletResponse getResponse()
{
try
{
return getRequestAttributes().getResponse();
}
catch (Exception e)
{
return null;
}
}

/**
* 获取session
*/
public static HttpSession getSession()
{
return getRequest().getSession();
}

public static ServletRequestAttributes getRequestAttributes()
{
try
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
catch (Exception e)
{
return null;
}
}


public static Map<String, String> getHeaders(HttpServletRequest request)
{
Map<String, String> map = new LinkedCaseInsensitiveMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null)
{
while (enumeration.hasMoreElements())
{
String key = enumeration.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
}
return map;
}

/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
*/
public static void renderString(HttpServletResponse response, String string)
{
try
{
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
}

/**
* 是否是Ajax异步请求
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request)
{
String accept = request.getHeader("accept");
if (accept != null && accept.contains("application/json"))
{
return true;
}

String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
{
return true;
}

String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
{
return true;
}

String ajax = request.getParameter("__ajax");
return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
}
}

+ 102
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/SpringUtils.java View File

@@ -0,0 +1,102 @@
package com.tuoheng.common.core.utils;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
* spring工具类 方便在非spring管理环境中获取bean
*/
@Component
public class SpringUtils implements BeanFactoryPostProcessor {

/**
* Spring应用上下文环境
*/
private static ConfigurableListableBeanFactory beanFactory;

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}

/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}

/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
T result = (T) beanFactory.getBean(clz);
return result;
}

/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return beanFactory.containsBean(name);
}

/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}

/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}

/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getAliases(name);
}

/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}

}

+ 413
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/StringUtils.java View File

@@ -0,0 +1,413 @@
package com.tuoheng.common.core.utils;

import java.util.*;

/**
* 字符串工具类
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {

/**
* 空字符串
*/
private static final String NULLSTR = "";

/**
* 下划线
*/
private static final char SEPARATOR = '_';

/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public static <T> T nvl(T value, T defaultValue) {
return value != null ? value : defaultValue;
}

/**
* * 判断一个Collection是否为空, 包含List,Set,Queue
*
* @param coll 要判断的Collection
* @return true:为空 false:非空
*/
public static boolean isEmpty(Collection<?> coll) {
return isNull(coll) || coll.isEmpty();
}

/**
* * 判断一个Collection是否非空,包含List,Set,Queue
*
* @param coll 要判断的Collection
* @return true:非空 false:空
*/
public static boolean isNotEmpty(Collection<?> coll) {
return !isEmpty(coll);
}

/**
* * 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
* * @return true:为空 false:非空
*/
public static boolean isEmpty(Object[] objects) {
return isNull(objects) || (objects.length == 0);
}

/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true:非空 false:空
*/
public static boolean isNotEmpty(Object[] objects) {
return !isEmpty(objects);
}

/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:为空 false:非空
*/
public static boolean isEmpty(Map<?, ?> map) {
return isNull(map) || map.isEmpty();
}

/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:非空 false:空
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}

/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true:为空 false:非空
*/
public static boolean isEmpty(String str) {
return isNull(str) || NULLSTR.equals(str.trim());
}

/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true:非空串 false:空串
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}

/**
* * 判断一个对象是否为空
*
* @param object Object
* @return true:为空 false:非空
*/
public static boolean isNull(Object object) {
return object == null;
}

/**
* * 判断一个对象是否非空
*
* @param object Object
* @return true:非空 false:空
*/
public static boolean isNotNull(Object object) {
return !isNull(object);
}

/**
* * 判断一个对象是否是数组类型(Java基本型别的数组)
*
* @param object 对象
* @return true:是数组 false:不是数组
*/
public static boolean isArray(Object object) {
return isNotNull(object) && object.getClass().isArray();
}

/**
* 去空格
*/
public static String trim(String str) {
return (str == null ? "" : str.trim());
}

/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public static String substring(final String str, int start) {
if (str == null) {
return NULLSTR;
}

if (start < 0) {
start = str.length() + start;
}

if (start < 0) {
start = 0;
}
if (start > str.length()) {
return NULLSTR;
}

return str.substring(start);
}

/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public static String substring(final String str, int start, int end) {
if (str == null) {
return NULLSTR;
}

if (end < 0) {
end = str.length() + end;
}
if (start < 0) {
start = str.length() + start;
}

if (end > str.length()) {
end = str.length();
}

if (start > end) {
return NULLSTR;
}

if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}

return str.substring(start, end);
}

/**
* 截取字符串str中指定字符 strStart、strEnd之间的字符串
*
* @param str
* @param strStart
* @param strEnd
* @return
*/
public static String subString(String str, String strStart, String strEnd) {

/* 找出指定的2个字符在 该字符串里面的 位置 */
int strStartIndex = str.indexOf(strStart);
int strEndIndex = str.indexOf(strEnd);

/* index 为负数 即表示该字符串中 没有该字符 */
if (strStartIndex < 0) {
return "字符串 :---->" + str + "<---- 中不存在 " + strStart + ", 无法截取目标字符串";
}
if (strEndIndex < 0) {
return "字符串 :---->" + str + "<---- 中不存在 " + strEnd + ", 无法截取目标字符串";
}
/* 开始截取 */
String result = str.substring(strStartIndex, strEndIndex).substring(strStart.length());
return result;
}


/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public static final Set<String> str2Set(String str, String sep) {
return new HashSet<String>(str2List(str, sep, true, false));
}

/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
List<String> list = new ArrayList<String>();
if (StringUtils.isEmpty(str)) {
return list;
}

// 过滤空白字符串
if (filterBlank && StringUtils.isBlank(str)) {
return list;
}
String[] split = str.split(sep);
for (String string : split) {
if (filterBlank && StringUtils.isBlank(string)) {
continue;
}
if (trim) {
string = string.trim();
}
list.add(string);
}

return list;
}

/**
* 下划线转驼峰命名
*/
public static String toUnderScoreCase(String str) {
if (str == null) {
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (i > 0) {
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
} else {
preCharIsUpperCase = false;
}

curreCharIsUpperCase = Character.isUpperCase(c);

if (i < (str.length() - 1)) {
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}

if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
sb.append(SEPARATOR);
} else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}

return sb.toString();
}

/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inStringIgnoreCase(String str, String... strs) {
if (str != null && strs != null) {
for (String s : strs) {
if (str.equalsIgnoreCase(trim(s))) {
return true;
}
}
}
return false;
}

/**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name) {
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty()) {
// 没必要转换
return "";
} else if (!name.contains("_")) {
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels) {
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) {
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}

/**
* 驼峰式命名法 例如:user_name->userName
*/
public static String toCamelCase(String s) {
if (s == null) {
return null;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);

if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}

/**
* 替换字符串中的域名
*/
public static String removeHost(String str, String host) {
if (!StringUtils.isEmpty(str) && str.contains(host)) {
return str.replaceAll(host, "");
}
return str;
}

/**
* 添加字符串中的域名
*/
public static String addHost(String str, String host) {
if (!StringUtils.isEmpty(str) && !str.contains(host)) {
return host + str;
}
return str;
}
}

+ 34
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ThreadLocalUtil.java View File

@@ -0,0 +1,34 @@



package com.tuoheng.common.core.utils;


/**
* @Author xiaoying
* @Date 2022/10/31 11:01
*/


public class ThreadLocalUtil {

private final static ThreadLocal<Object> USER_THREAD_LOCAL = new ThreadLocal<>();

// 存放
public static void set(Object user) {
USER_THREAD_LOCAL.set(user);
}

// 获取
public static Object get() {
return USER_THREAD_LOCAL.get();
}

// 移除
public static void remove() {
USER_THREAD_LOCAL.remove();
}
}




+ 113
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ThumbnailUtil.java View File

@@ -0,0 +1,113 @@
package com.tuoheng.common.core.utils;

import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;

public class ThumbnailUtil {
/**
* 生成压缩图
* @param url 原图地址
* @param desFileSize 指定图片大小,单位kb
* @param accuracy 精度,递归压缩的比率,建议小于0.9
* @return
*/
public static String cenerateCompression(String url,String urlThumbnail,long desFileSize , double accuracy){
//String urlThumbnail= UploadFileConfig.uploadFolder +"Thumbnail"+ imgUrl;
String root= urlThumbnail.substring(0,urlThumbnail.lastIndexOf("/"));
//如果指定的文件夹不存在 则创建
File filedir=new File(root);
if (!filedir.exists()) {
filedir.mkdirs();//创建文件夹
}
//图片文件
File fileThumbnail = new File(urlThumbnail);
if (fileThumbnail.exists()&&fileThumbnail.length() <= desFileSize * 1024) {
System.out.println("已存在压缩文件!");
return urlThumbnail;
}
//原图
File file = new File(url);
if (!file.exists() || !file.isFile()) {
System.out.println("文件不存在");
}
try {
if(!fileThumbnail.exists()) {
copyFileUsingFileStreams(file, new File(urlThumbnail));
}
}catch (IOException e){
e.printStackTrace();
}
urlThumbnail = commpressPicForScale(url, urlThumbnail, desFileSize, accuracy);
return urlThumbnail;
}

/**
*
* @param srcPath 原图片地址
* @param desPath 目标图片地址
* @param desFileSize 指定图片大小,单位kb
* @param accuracy 精度,递归压缩的比率,建议小于0.9
* @return
*/
public static String commpressPicForScale(String srcPath,String desPath,
long desFileSize , double accuracy){
try {
File srcFile = new File(srcPath);
long srcFilesize = srcFile.length();
System.out.println("原图片:"+srcPath + ",大小:" + srcFilesize/1024 + "kb");
//递归压缩,直到目标文件大小小于desFileSize
commpressPicCycle(desPath, desFileSize, accuracy);

File desFile = new File(desPath);
System.out.println("目标图片:" + desPath + ",大小" + desFile.length()/1024 + "kb");
System.out.println("图片压缩完成!");
} catch (Exception e) {
e.printStackTrace();
}
return desPath;
}
public static void commpressPicCycle(String desPath , long desFileSize,
double accuracy) throws IOException{
File imgFile = new File(desPath);
long fileSize = imgFile.length();
//判断大小,如果小于desFileSizek,不压缩,如果大于等于desFileSizek,压缩
if(fileSize <= desFileSize * 1024){
return;
}
//计算宽高
BufferedImage bim = ImageIO.read(imgFile);
int imgWidth = bim.getWidth();
int imgHeight = bim.getHeight();
int desWidth = new BigDecimal(imgWidth).multiply(
new BigDecimal(accuracy)).intValue();
int desHeight = new BigDecimal(imgHeight).multiply(
new BigDecimal(accuracy)).intValue();
Thumbnails.of(desPath).size(desWidth, desHeight).outputQuality(accuracy).toFile(desPath);
//如果不满足要求,递归直至满足小于1M的要求
commpressPicCycle(desPath, desFileSize, accuracy);
}

private static void copyFileUsingFileStreams(File source, File dest)
throws IOException {
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
} finally {
input.close();
output.close();
}
}


}

+ 74
- 0
tuoheng-common/tuoheng-common-core/src/main/java/com/tuoheng/common/core/utils/ValidatorUtils.java View File

@@ -0,0 +1,74 @@
package com.tuoheng.common.core.utils;


import com.tuoheng.common.core.exception.ServiceException;
import org.hibernate.validator.HibernateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
* @author chenyukun
*/
public class ValidatorUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorUtils.class);

private static Validator validatorFast = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()
.getValidator();

private static Validator validatorAll = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(false)
.buildValidatorFactory()
.getValidator();

/**
* 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
* @param t t
*/
public static <T> void validateFast(T t) {
Set<ConstraintViolation<T>> validateResult = validatorFast.validate(t);
buildResult(validateResult);
}

/**
* 校验所有字段并返回不合法字段
* @param t t
*/
public static <T> void validateAll(T t) {
Set<ConstraintViolation<T>> validateResult = validatorAll.validate(t);
buildResult(validateResult);
}

/**
* 封装验证结果
* @param validateResult 验证结果
* @param <T>
*/
private static <T> void buildResult(Set<ConstraintViolation<T>> validateResult){
Map<String, String> result = new HashMap<>(validateResult.size());
if(!CollectionUtils.isEmpty(validateResult)) {
Iterator<ConstraintViolation<T>> it = validateResult.iterator();
while(it.hasNext()) {
ConstraintViolation<T> cv = it.next();
result.put(cv.getPropertyPath().toString(), cv.getMessage());
}
LOGGER.error("参数验证未通过,校验结果:{}", JacksonUtil.obj2json(result));
throw new ServiceException(HttpStatus.BAD_REQUEST.value(), JacksonUtil.obj2json(result));
}
LOGGER.info("参数验证通过,校验异常数量:{}", validateResult.size());
}
}

BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/advice/CustomExceptionHandler.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/annotation/Log.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseController.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseEntity.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseQuery.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/BaseServiceImpl.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/ExceptionInterface.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/IBaseService.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/common/OperationEnum.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/RedisConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/UploadFileConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/ValidatorConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/common/CommonConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/DefaultClientHttpRequestInterceptor.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/HeadClientHttpRequestInterceptor.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestProperties.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestTemplateConfig$1.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/http/RestTemplateConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/config/xxl/XxlJobConfig.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/constant/CommonConstants.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/constant/SecurityHeadConstant.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/entity/UserEntity.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/HttpStatusEnum.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/LockType.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/LogType.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/OperType.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/PhotographyEnum.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/ServiceExceptionEnum.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/enums/SysExceptionEnum.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/exception/ExceptionInterface.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/exception/ServiceException.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/model/dto/LoginUser.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/CommonNumberTypeUtils.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/CommonUtils.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/DateUtils.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/EncryptUtil.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/ExceptionUtil.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/FileUtils.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils$TrustAnyHostnameVerifier.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils$TrustAnyTrustManager.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/HttpUtils.class View File


BIN
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/IpUtils.class View File


+ 0
- 0
tuoheng-common/tuoheng-common-core/target/classes/com/tuoheng/common/core/utils/JacksonUtil.class View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save