Commit 54e88191b3cb0d250ee3a3cfce65523b6f29f28c

Authored by 谢茂盛
0 parents

feat: init项目

Showing 26 changed files with 3526 additions and 0 deletions

Too many changes to show.

To preserve performance only 26 of 62 files are displayed.

pom.xml 0 → 100644
  1 +++ a/pom.xml
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>org.springframework.boot</groupId>
  7 + <artifactId>spring-boot-starter-parent</artifactId>
  8 + <version>2.2.5.RELEASE</version>
  9 + <relativePath/> <!-- lookup parent from repository -->
  10 + </parent>
  11 + <modelVersion>4.0.0</modelVersion>
  12 +
  13 + <groupId>org.canrd</groupId>
  14 + <artifactId>webmagic-canrd-service</artifactId>
  15 + <version>1.0-SNAPSHOT</version>
  16 +
  17 + <properties>
  18 + <maven-compiler-plugin>3.7.0</maven-compiler-plugin>
  19 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  20 + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  21 + <java.version>1.8</java.version>
  22 + <joda-time.version>2.9.9</joda-time.version>
  23 + <springboot.version>2.2.5.RELEASE</springboot.version>
  24 + <lombok.version>1.18.12</lombok.version>
  25 + <baomidou.version>3.4.0</baomidou.version>
  26 + <hutool-crypto.version>5.6.1</hutool-crypto.version>
  27 + <hutool-all.version>5.0.6</hutool-all.version>
  28 + <mysql-connector.version>8.0.11</mysql-connector.version>
  29 + <druid.version>1.1.23</druid.version>
  30 + <fastjson.version>1.2.28</fastjson.version>
  31 + <poi.version>3.17</poi.version>
  32 + <poi-ooxml.version>3.17</poi-ooxml.version>
  33 + <poi-excel.version>poi-317.8</poi-excel.version>
  34 + <commons-csv.version>1.6</commons-csv.version>
  35 + <commons-lang3.version>3.8.1</commons-lang3.version>
  36 + <commons-pool2.version>2.11.1</commons-pool2.version>
  37 + <ip2region.version>1.7.2</ip2region.version>
  38 + <userAgentUtils.version>1.20</userAgentUtils.version>
  39 + <swagger.version>2.9.2</swagger.version>
  40 + <swagger-annotations.version>1.5.21</swagger-annotations.version>
  41 + <swagger-models.version>1.5.21</swagger-models.version>
  42 + <guava.version>20.0</guava.version>
  43 + <easy-captcha.version>1.6.2</easy-captcha.version>
  44 + <aliyun-java-sdk-core.version>4.0.3</aliyun-java-sdk-core.version>
  45 + <aliyun-sdk-oss.version>3.15.0</aliyun-sdk-oss.version>
  46 + <thumbnailator.version>0.4.8</thumbnailator.version>
  47 + <jjwt.version>0.10.6</jjwt.version>
  48 + <easyexcel.version>2.2.3</easyexcel.version>
  49 + <webmagic.version>0.10.0</webmagic.version>
  50 + </properties>
  51 +
  52 + <dependencies>
  53 +
  54 + <dependency>
  55 + <groupId>org.springframework.boot</groupId>
  56 + <artifactId>spring-boot-starter-web</artifactId>
  57 + <version>2.2.5.RELEASE</version>
  58 + <exclusions>
  59 + <exclusion>
  60 + <groupId>org.springframework.boot</groupId>
  61 + <artifactId>spring-boot-starter-logging</artifactId>
  62 + </exclusion>
  63 + </exclusions>
  64 + </dependency>
  65 +
  66 + <!-- webmagic核心库 -->
  67 + <dependency>
  68 + <groupId>us.codecraft</groupId>
  69 + <artifactId>webmagic-core</artifactId>
  70 + <version>${webmagic.version}</version>
  71 + </dependency>
  72 +
  73 +
  74 + <!-- webmagic扩展库 -->
  75 + <dependency>
  76 + <groupId>us.codecraft</groupId>
  77 + <artifactId>webmagic-extension</artifactId>
  78 + <version>${webmagic.version}</version>
  79 + </dependency>
  80 +
  81 +
  82 + <!-- Lombok 依赖-->
  83 + <dependency>
  84 + <groupId>org.projectlombok</groupId>
  85 + <artifactId>lombok</artifactId>
  86 + <version>${lombok.version}</version>
  87 + <optional>true</optional>
  88 + </dependency>
  89 + <dependency>
  90 + <groupId>org.springframework.boot</groupId>
  91 + <artifactId>spring-boot-starter-aop</artifactId>
  92 + <version>${springboot.version}</version>
  93 + </dependency>
  94 + <dependency>
  95 + <groupId>org.springframework.boot</groupId>
  96 + <artifactId>spring-boot-starter-test</artifactId>
  97 + <version>${springboot.version}</version>
  98 + <scope>test</scope>
  99 + </dependency>
  100 +
  101 + <dependency>
  102 + <groupId>com.baomidou</groupId>
  103 + <artifactId>mybatis-plus-boot-starter</artifactId>
  104 + <version>${baomidou.version}</version>
  105 + </dependency>
  106 + <!-- <dependency>-->
  107 + <!-- <groupId>com.baomidou</groupId>-->
  108 + <!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>-->
  109 + <!-- </dependency>-->
  110 + <dependency>
  111 + <groupId>mysql</groupId>
  112 + <artifactId>mysql-connector-java</artifactId>
  113 + <version>${mysql-connector.version}</version>
  114 + </dependency>
  115 + <dependency>
  116 + <groupId>com.alibaba</groupId>
  117 + <artifactId>druid-spring-boot-starter</artifactId>
  118 + <version>${druid.version}</version>
  119 + </dependency>
  120 +
  121 + <dependency>
  122 + <groupId>org.springframework.boot</groupId>
  123 + <artifactId>spring-boot-starter-log4j2</artifactId>
  124 + <version>${springboot.version}</version>
  125 + </dependency>
  126 +
  127 +
  128 + <dependency>
  129 + <groupId>com.alibaba</groupId>
  130 + <artifactId>fastjson</artifactId>
  131 + <version>${fastjson.version}</version>
  132 + </dependency>
  133 +
  134 + <dependency>
  135 + <groupId>cn.hutool</groupId>
  136 + <artifactId>hutool-crypto</artifactId>
  137 + <version>${hutool-crypto.version}</version>
  138 + </dependency>
  139 +
  140 + <dependency>
  141 + <groupId>org.springframework.boot</groupId>
  142 + <artifactId>spring-boot-starter-data-redis</artifactId>
  143 + <version>${springboot.version}</version>
  144 + </dependency>
  145 +
  146 + <dependency>
  147 + <groupId>org.apache.commons</groupId>
  148 + <artifactId>commons-pool2</artifactId>
  149 + <version>${commons-pool2.version}</version>
  150 + </dependency>
  151 +
  152 +
  153 + <dependency>
  154 + <groupId>org.apache.commons</groupId>
  155 + <artifactId>commons-lang3</artifactId>
  156 + <version>${commons-lang3.version}</version>
  157 + </dependency>
  158 + <dependency>
  159 + <groupId>org.lionsoul</groupId>
  160 + <artifactId>ip2region</artifactId>
  161 + <version>${ip2region.version}</version>
  162 + </dependency>
  163 + <dependency>
  164 + <groupId>eu.bitwalker</groupId>
  165 + <artifactId>UserAgentUtils</artifactId>
  166 + <version>${userAgentUtils.version}</version>
  167 + </dependency>
  168 +
  169 + <!--工具包-->
  170 + <dependency>
  171 + <groupId>cn.hutool</groupId>
  172 + <artifactId>hutool-all</artifactId>
  173 + <version>${hutool-all.version}</version>
  174 + </dependency>
  175 + <dependency>
  176 + <groupId>org.apache.poi</groupId>
  177 + <artifactId>poi</artifactId>
  178 + <version>${poi.version}</version>
  179 + </dependency>
  180 + <dependency>
  181 + <groupId>org.apache.poi</groupId>
  182 + <artifactId>poi-ooxml</artifactId>
  183 + <version>${poi-ooxml.version}</version>
  184 + </dependency>
  185 +
  186 + <dependency>
  187 + <groupId>joda-time</groupId>
  188 + <artifactId>joda-time</artifactId>
  189 + <version>${joda-time.version}</version>
  190 + </dependency>
  191 +
  192 +
  193 +
  194 + </dependencies>
  195 + <build>
  196 + <finalName>webmagic-canrd.service-1.0-SNAPSHOT</finalName>
  197 + <plugins>
  198 + <plugin>
  199 + <groupId>org.apache.maven.plugins</groupId>
  200 + <artifactId>maven-source-plugin</artifactId>
  201 + </plugin>
  202 +
  203 + <plugin>
  204 + <groupId>org.springframework.boot</groupId>
  205 + <artifactId>spring-boot-maven-plugin</artifactId>
  206 + <configuration>
  207 + <executable>true</executable>
  208 + </configuration>
  209 + </plugin>
  210 +
  211 + </plugins>
  212 + </build>
  213 +</project>
0 214 \ No newline at end of file
... ...
src/main/java/com/canrd/webmagic/Application.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/Application.java
  1 +package com.canrd.webmagic;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.DbType;
  4 +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  5 +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  6 +import com.canrd.webmagic.common.directory.Path;
  7 +import com.canrd.webmagic.common.utils.SpringContextHolder;
  8 +import org.mybatis.spring.annotation.MapperScan;
  9 +import org.springframework.boot.SpringApplication;
  10 +import org.springframework.boot.autoconfigure.SpringBootApplication;
  11 +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  12 +import org.springframework.context.annotation.Bean;
  13 +import org.springframework.scheduling.annotation.EnableAsync;
  14 +import org.springframework.scheduling.annotation.EnableScheduling;
  15 +import org.springframework.transaction.annotation.EnableTransactionManagement;
  16 +
  17 +/**
  18 + * @author: xms
  19 + * @description:
  20 + * @date: 2024/1/12 14:00
  21 + * @version: 1.0
  22 + */
  23 +@EnableAsync
  24 +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.canrd.webmagic"})
  25 +@MapperScan("com.canrd.webmagic.**.mapper")
  26 +@EnableScheduling
  27 +@EnableTransactionManagement
  28 +public class Application {
  29 +
  30 + private static void setLogPath() {
  31 + String appPath = Path.getAppPath(Application.class);
  32 + System.setProperty("logging.path", appPath);
  33 + }
  34 +
  35 + @Bean
  36 + public SpringContextHolder springContextHolder() {
  37 + return new SpringContextHolder();
  38 + }
  39 +
  40 + public static void main(String[] args) {
  41 + setLogPath();
  42 + SpringApplication.run(Application.class, args);
  43 + }
  44 +
  45 + /**
  46 + * 分页插件
  47 + *
  48 + * @return
  49 + */
  50 + @Bean
  51 + public MybatisPlusInterceptor mybatisPlusInterceptor() {
  52 + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  53 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
  54 + return interceptor;
  55 + }
  56 +}
... ...
src/main/java/com/canrd/webmagic/common/annotation/AnonymousAccess.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/annotation/AnonymousAccess.java
  1 +package com.canrd.webmagic.common.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +/**
  9 + * 用于标记匿名访问方法
  10 + */
  11 +@Target(ElementType.METHOD)
  12 +@Retention(RetentionPolicy.RUNTIME)
  13 +public @interface AnonymousAccess {
  14 +
  15 +}
... ...
src/main/java/com/canrd/webmagic/common/constant/Constant.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/constant/Constant.java
  1 +package com.canrd.webmagic.common.constant;
  2 +
  3 +import java.util.Arrays;
  4 +import java.util.List;
  5 +
  6 +public class Constant {
  7 + /**
  8 + * 分隔符英文的横杠
  9 + */
  10 + public static final String CROSS_BAR_CHARACTER = "-";
  11 + /**
  12 + * 英文的 .
  13 + */
  14 + public static final String POINT_BAR_CHARACTER = ".";
  15 + /**
  16 + * 英文的 !
  17 + */
  18 + public static final String EXCLAMATION_MARK_CHARACTER = "!";
  19 + /**
  20 + * 英文的 /
  21 + */
  22 + public static final String SLASH_MARK_CHARACTER = "/";
  23 + /**
  24 + * 英文的 :
  25 + */
  26 + public static final String COLON_CHARACTER = ":";
  27 +
  28 + /**
  29 + * 英文的 ;
  30 + */
  31 + public static final String SEMICOLON_CHARACTER = ";";
  32 +
  33 + /**
  34 + * 英文的逗号
  35 + */
  36 + public static final String COMMA_CHARACTER = ",";
  37 + /**
  38 + * 英文的*号
  39 + */
  40 + public static final String START_CHARACTER = "*";
  41 + /**
  42 + * 分隔符
  43 + */
  44 + public static final String SPLIT_SYMBOL = ",|,";
  45 +
  46 + /**
  47 + * 特殊分隔符 _
  48 + */
  49 + public static final String SPECIAL_KEY = "_";
  50 +
  51 +
  52 + /**
  53 + * 括号
  54 + */
  55 + public static final String BRACKETS_RIGHT = "]";
  56 + /**
  57 + * 括号
  58 + */
  59 + public static final String BRACKETS_LEFT = "[";
  60 +
  61 + /**
  62 + * 手机号码正则校验
  63 + */
  64 + public static final String PHONE_REGEXP = "^[1][3,4,5,6,7,8,9][0-9]{9}$";
  65 +
  66 + /**
  67 + * 脱敏手机号
  68 + */
  69 + public static final String PHONE_DESENSITIZATION_REGEXP = "^[1][3,4,5,6,7,8,9][0-9][*]{4}[0-9]{4}$";
  70 +
  71 + /**
  72 + * 邮箱
  73 + */
  74 + public static final String EMAIL_REGEXP = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$";
  75 +
  76 + /**
  77 + * 三位数字
  78 + */
  79 + public static final String THREE_DIGITS_REGEXP = "\\d{3}";
  80 +
  81 + /**
  82 + * 中文 英文 数字
  83 + */
  84 + public static final String CHI_EN_NUM_REGEXP = "^[A-z0-9\\u4e00-\\u9fa5]*$";
  85 +
  86 +
  87 + /**
  88 + * 仅包含英文和数字
  89 + */
  90 + public static final String EN_REGEXP = "^[a-zA-Z]+$";
  91 +
  92 + public static final String EN_NUM_REGEXP = "^[a-z0-9A-Z]+$";
  93 +
  94 + public static final String LINE_EN_NUM_REGEXP = "^[a-z0-9A-Z\\-]+$";
  95 +
  96 + /**
  97 + * 仅包含英文和中文
  98 + */
  99 + public static final String CHI_EN_REGEXP = "^[A-z\\u4e00-\\u9fa5]*$";
  100 +
  101 + /**
  102 + * 纯数字
  103 + */
  104 + public static final String NUMERIC_REGEXP = "^\\d+$";
  105 + /**
  106 + * 纯中文
  107 + */
  108 + public static final String CHI_REGEXP = "^[\u4e00-\u9fa5]+$";
  109 + /**
  110 + * 不超过两位小数
  111 + */
  112 + public static final String DICMAL_REGEXP = "^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,3})?$";
  113 +
  114 + /**
  115 + * 默认空字符串
  116 + */
  117 + public static final String EMPTY_STRING = "";
  118 +
  119 + /**
  120 + * 统一返回data的key
  121 + */
  122 + public static final String RESULT_CHARACTER = "result";
  123 +
  124 + /**
  125 + * 统一返回data的key
  126 + */
  127 + public static final String SUCCESS_RESULT_CHARACTER = "success";
  128 +
  129 + /**
  130 + * 返回的默认结果集
  131 + */
  132 + public static final String RESULT_FAIL = null;
  133 +
  134 + /**
  135 + * ENABLE_FLAG
  136 + */
  137 + public static final String ENABLE_FLAG = "enable_flag";
  138 +
  139 + /**
  140 + * 是否可用 10-可用 20-删除
  141 + */
  142 + public static final int ENABLE_TEN = 10;
  143 + /**
  144 + * 是否可用 10-可用 20-删除
  145 + */
  146 + public static final int UNABLE_TWENTY = 20;
  147 +
  148 + public static final int ONE = 1;
  149 +
  150 + public static final Integer INTEGER_ONE = 1;
  151 +
  152 + public static final int TWO = 2;
  153 +
  154 + public static final int THREE = 3;
  155 +
  156 + public static final int FOUR = 4;
  157 +
  158 + public static final int FIVE = 5;
  159 +
  160 + public static final int SIX = 6;
  161 +
  162 + public static final int SEVEN = 7;
  163 +
  164 + public static final int THIRTY = 30;
  165 +
  166 + public static final int NINETEEN = 19;
  167 +
  168 + public static final int THOUSAND = 1000;
  169 +
  170 + public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
  171 +
  172 + public static final int ZERO = 0;
  173 +
  174 + public static final String STRING_ZERO = "0";
  175 +
  176 + public static final String ZERO_STRING = "0";
  177 +
  178 + public static final String THOUSAND_STRING = "1000";
  179 +
  180 + public static final String SYSTEM_USER = "System";
  181 +
  182 + public static final String percent50 = "0.5";
  183 +
  184 + public static final String DELETE_SUCCESS_RESULT_CHARACTER = "删除成功";
  185 +
  186 +
  187 + /**
  188 + * token rediskey
  189 + */
  190 + public static final String TOKEN_FLAG = "token:";
  191 + /**
  192 + * token 限制api请求
  193 + */
  194 + public static final String PERMISSION_API_LIMIT = "token_api_limit:";
  195 +
  196 + /**
  197 + * token过期时间
  198 + */
  199 + public static final Integer TOKEN_EXPIRE_HOURS = 1;
  200 + /**
  201 + * 密码3次错误锁定
  202 + */
  203 + public static final int LOCK_ERROR_TIMES = 3;
  204 +
  205 + /**
  206 + * session字段
  207 + */
  208 + public static final String HEAD_TOKEN = "Authorization";
  209 + public static final String ACCESS_TOKEN = "token";
  210 + public static final String REQUEST_ORIGIN = "source";
  211 + public static final String REQUEST_IP = "ip";
  212 + public static final String USER_INFO = "userInfo";
  213 + public static final String FILED_ID = "id";
  214 + public static final String FILED_USER_NAME = "username";
  215 + public static final String FILED_DEVICE_NUM = "deviceNum";
  216 +
  217 + /**
  218 + * 请求来源
  219 + */
  220 + public static final String ORIGIN_WEB = "WEB";
  221 + public static final String ORIGIN_PDA = "PDA";
  222 +
  223 + /**
  224 + * 1001 参数校验不通过
  225 + * 1002 签名验证不通过
  226 + */
  227 + public static final List<String> ERROR_CODE_LIST = Arrays.asList("1001", "1002");
  228 +
  229 + /**
  230 + * 分布式锁超时时间
  231 + */
  232 + public static final long REDIS_LOCK_DEFAULT_TIME_OUT_MILLIS = 3000;
  233 + public static final long REDIS_LOCK_FIVE_SECONDS_TIME_OUT_MILLIS = 5000;
  234 +
  235 + /**
  236 + * 系统来源WMS
  237 + */
  238 + public static final String SYS_ORIGIN_WMS = "WMS";
  239 +
  240 + public static final String STRING_ONE = "1";
  241 +
  242 +
  243 + public static final String STRING_TWO = "2";
  244 +
  245 + public static final String STRING_THREE = "3";
  246 +
  247 + public static final String STRING_FOUR = "4";
  248 +
  249 + public static final String STRING_FIVE = "5";
  250 +
  251 + public static final String STRING_SIX = "6";
  252 +
  253 + public static final String STRING_SEVEN = "7";
  254 +
  255 + public static final String STRING_EIGHT = "8";
  256 +
  257 + public static final String STRING_NINE = "9";
  258 +
  259 + public static final String STRING_TEN = "10";
  260 +
  261 + public static final String STRING_ELEVEN = "11";
  262 +
  263 + public static final String STRING_TWELVE = "12";
  264 +
  265 + /**
  266 + * 异常延时队列后缀
  267 + */
  268 + public static final String ERROR_DELAY_QUEUE_SUFFIX = "error";
  269 +
  270 + /**
  271 + * 推送出库数据延时队列 redis key prefix
  272 + */
  273 + public static final String OUTBOUND_NOTIFY_DELAY_QUEUE_PREFIX = "outbound:notify:";
  274 +
  275 + /**
  276 + * 同步MES库存队列 redis key prefix
  277 + */
  278 + public static final String MES_STOCK_SYNC_QUEUE_PREFIX = "mes:stock_sync:";
  279 +
  280 + /**
  281 + * 分拣详情 错误码: 157205 返回值段
  282 + */
  283 + public static final String SEPARATE_PICK_QUERY_RETURN_FIELD = "separatePickQuery";
  284 + /**
  285 + * 限制上限值
  286 + */
  287 + public static final Integer LIMIT_999 = 999;
  288 +
  289 + /**
  290 + * 东八区
  291 + */
  292 + public static final String GMT_8 = "GMT+8";
  293 +
  294 + /**
  295 + * 英文的 "
  296 + */
  297 + public static final String QUOTATION_MARK_CHARACTER = "\"";
  298 +
  299 +
  300 + /**
  301 + * 英文的 \"
  302 + */
  303 + public static final String QUOTATION_SLASH_MARK_CHARACTER = "\\\"";
  304 +
  305 + public static final String SUCCESS_VALUE = "success";
  306 +
  307 +
  308 + public static final String TRUE = "true";
  309 +
  310 + public static final String ROOT_PARENT_ID = "0";
  311 +
  312 + public static final Long ROOT_PARENT_ID_LONG = 0L;
  313 +
  314 +
  315 + /**
  316 + * 短信验证码 redis key
  317 + */
  318 + public static final String SMS_AUTH_CODE_PREFIX = "sms:auth:code:";
  319 +
  320 + public static final String DEFAULT_PASSWORD = "JBXT123456";
  321 +
  322 + /**
  323 + * 账号在线队列 redis key
  324 + */
  325 + public static final String ACCOUNT_ONLINE_LIST = "account:online:";
  326 +
  327 + /**
  328 + * 缓存导入excel错误信息 redis key
  329 + */
  330 + public static final String EXCEL_IMPORT_ERROR_PREFIX = "excel:import:error:";
  331 +
  332 +}
... ...
src/main/java/com/canrd/webmagic/common/constant/ElAdminConstant.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/constant/ElAdminConstant.java
  1 +package com.canrd.webmagic.common.constant;
  2 +
  3 +/**
  4 + * 常用静态常量
  5 + *
  6 + * @date 2018-12-26
  7 + */
  8 +public class ElAdminConstant {
  9 +
  10 + public static final String RESET_PASS = "重置密码";
  11 +
  12 + public static final String RESET_MAIL = "重置邮箱";
  13 +
  14 + /**
  15 + * 用于IP定位转换
  16 + */
  17 + public static final String REGION = "内网IP|内网IP";
  18 +
  19 + /**
  20 + * 常用接口
  21 + */
  22 + public static class Url {
  23 + public static final String SM_MS_URL = "https://sm.ms/api";
  24 + }
  25 +}
... ...
src/main/java/com/canrd/webmagic/common/constant/ServerResult.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/constant/ServerResult.java
  1 +package com.canrd.webmagic.common.constant;
  2 +
  3 +
  4 +import java.io.Serializable;
  5 +import java.util.HashMap;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * @Date: 2020/9/5
  10 + * 统一的返回结果实体
  11 + */
  12 +public class ServerResult<T> implements Serializable {
  13 + /**
  14 + * 序列化ID
  15 + */
  16 + private static final long serialVersionUID = -5809782578272943999L;
  17 + /**
  18 + * 返回的状态码
  19 + */
  20 + private int result = ServerResultCode.SUCCESS.getErrorCode();
  21 + /**
  22 + * 返回的消息
  23 + */
  24 + private String message = ServerResultCode.SUCCESS.getErrorDesc();
  25 + /**
  26 + * 返回的数据实体
  27 + */
  28 + private T data = null;
  29 + /**
  30 + *
  31 + */
  32 + final int INIT_SIZE = 128;
  33 +
  34 + /**
  35 + *
  36 + */
  37 + public ServerResult() {
  38 + }
  39 +
  40 + @Override
  41 + public String toString() {
  42 + StringBuilder buffer = new StringBuilder(INIT_SIZE);
  43 + buffer.append("{\"result\":").append(this.result);
  44 + buffer.append(",\"message\":\"").append(this.message != null ? message : "").append("\"");
  45 + buffer.append(",\"data\":").append(data).append("}");
  46 + return buffer.toString();
  47 + }
  48 +
  49 + public int getResult() {
  50 + return result;
  51 + }
  52 +
  53 + public ServerResult setResult(int result) {
  54 + this.result = result;
  55 + return this;
  56 + }
  57 +
  58 + public ServerResult setResult(ServerResultCode serverResultCode) {
  59 + this.result = serverResultCode.getErrorCode();
  60 + this.message = serverResultCode.getErrorDesc();
  61 + return this;
  62 + }
  63 +
  64 + public ServerResult setResult(int errorCode, String errorDesc) {
  65 + this.result = errorCode;
  66 + this.message = errorDesc;
  67 + return this;
  68 + }
  69 +
  70 + public String getMessage() {
  71 + return message;
  72 + }
  73 +
  74 + public ServerResult<T> setMessage(String message) {
  75 + this.message = message;
  76 + return this;
  77 + }
  78 +
  79 + public T getData() {
  80 + return data;
  81 + }
  82 +
  83 + public ServerResult setData(T data) {
  84 + this.data = data;
  85 + return this;
  86 + }
  87 +
  88 + public static <T> ServerResult<T> success() {
  89 + return new ServerResult()
  90 + .setResult(ServerResultCode.SUCCESS)
  91 + .setMessage(ServerResultCode.SUCCESS.getErrorDesc())
  92 + .setData(defaultResult(ServerResultCode.SUCCESS));
  93 + }
  94 +
  95 + public static <T> ServerResult<T> success(T data) {
  96 + return new ServerResult()
  97 + .setResult(ServerResultCode.SUCCESS)
  98 + .setMessage(ServerResultCode.SUCCESS.getErrorDesc())
  99 + .setData(data);
  100 + }
  101 +
  102 + public static <T> ServerResult<T> success(T data, String message) {
  103 + return new ServerResult()
  104 + .setResult(ServerResultCode.SUCCESS)
  105 + .setMessage(message)
  106 + .setData(data);
  107 + }
  108 +
  109 + /**
  110 + * @description 错误码使用系统错误 1000 错误类型自定义
  111 + * @author dengbin
  112 + * @date 2020/9/12
  113 + */
  114 + public static <T> ServerResult<T> fail(String message) {
  115 + return new ServerResult()
  116 + .setResult(ServerResultCode.FAIL)
  117 + .setMessage(message)
  118 + .setData(defaultResult(Constant.RESULT_FAIL));
  119 + }
  120 +
  121 + /**
  122 + * 错误时需要返回相关数据时使用
  123 + *
  124 + * @param data
  125 + * @param <T>
  126 + * @return
  127 + */
  128 + public static <T> ServerResult<T> fail(T data, ServerResultCode serverResultCode) {
  129 + return new ServerResult()
  130 + .setData(data)
  131 + .setResult(serverResultCode)
  132 + .setMessage(serverResultCode.getErrorDesc());
  133 + }
  134 +
  135 + /**
  136 + * 错误时需要返回相关数据时使用(不设值 data)
  137 + *
  138 + * @param sr
  139 + * @param
  140 + * @return
  141 + */
  142 + public static <T> ServerResult<T> fail(ServerResult<?> sr) {
  143 + return new ServerResult<>()
  144 + .setMessage(sr.getMessage())
  145 + .setResult(sr.getResult());
  146 +
  147 + }
  148 +
  149 + /**
  150 + * @description 错误码使用上面的枚举定义的,错误信息重新定义
  151 + * @author dengbin
  152 + * @date 2020/9/12
  153 + */
  154 + public static <T> ServerResult<T> fail(ServerResultCode serverResultCode, String msg) {
  155 + return new ServerResult()
  156 + .setResult(serverResultCode)
  157 + .setMessage(msg)
  158 + .setData(defaultResult(Constant.RESULT_FAIL));
  159 + }
  160 +
  161 + /**
  162 + * @return
  163 + * @description 直接选用上面的枚举错误码,输出定义的错误信息
  164 + * @author dengbin
  165 + * @date 2020/9/12
  166 + */
  167 + public static <T> ServerResult<T> fail(ServerResultCode serverResultCode) {
  168 + return new ServerResult()
  169 + .setResult(serverResultCode)
  170 + .setMessage(serverResultCode.getErrorDesc())
  171 + .setData(defaultResult(Constant.RESULT_FAIL));
  172 + }
  173 +
  174 + /**
  175 + * 错误时需要返回相关数据时使用
  176 + *
  177 + * @param data
  178 + * @param <T>
  179 + * @return
  180 + */
  181 + public static <T> ServerResult<T> fail(T data, int errorCode, String errorDesc) {
  182 + return new ServerResult()
  183 + .setData(data)
  184 + .setResult(errorCode, errorDesc);
  185 + }
  186 +
  187 +
  188 + public static <T> ServerResult<T> fail() {
  189 + return new ServerResult()
  190 + .setResult(ServerResultCode.FAIL.getErrorCode())
  191 + .setMessage(ServerResultCode.FAIL.getErrorDesc())
  192 + .setData(defaultResult(Constant.RESULT_FAIL));
  193 + }
  194 +
  195 +
  196 + /**
  197 + * @description 直接选用上面的枚举错误码,输出定义的错误信息
  198 + * @author dengbin
  199 + * @date 2020/9/12
  200 + */
  201 + public ServerResult failEnum(ServerResultCode serverResultCode) {
  202 + setResult(serverResultCode);
  203 + setMessage(serverResultCode.getErrorDesc());
  204 + return this;
  205 + }
  206 +
  207 + public static <T> ServerResult<T> fail(int errorCode, String errorDesc) {
  208 + return new ServerResult()
  209 + .setResult(errorCode, errorDesc)
  210 + .setData(defaultResult(Constant.RESULT_FAIL));
  211 +
  212 + }
  213 +
  214 + /**
  215 + * 判断当前的状态码是否是SUCCESS
  216 + *
  217 + * @return 结果 ture or false
  218 + */
  219 + public boolean checkSuccess() {
  220 + return result == ServerResultCode.SUCCESS.getErrorCode();
  221 + }
  222 +
  223 + public boolean checkNotSuccess() {
  224 + return !checkSuccess();
  225 + }
  226 +
  227 + private static Map<String, Object> defaultResult(Object object) {
  228 + Map<String, Object> map = new HashMap<>(Constant.ONE);
  229 + map.put(Constant.RESULT_CHARACTER, null);
  230 + return map;
  231 + }
  232 +}
... ...
src/main/java/com/canrd/webmagic/common/constant/ServerResultCode.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/constant/ServerResultCode.java
  1 +package com.canrd.webmagic.common.constant;
  2 +
  3 +
  4 +import com.canrd.webmagic.common.exception.ErrorInfo;
  5 +import lombok.Setter;
  6 +
  7 +
  8 +/**
  9 + * 请求成功 返回 0
  10 + */
  11 +public enum ServerResultCode implements ErrorInfo {
  12 + //成功 "0"
  13 + SUCCESS(0, "成功"),
  14 + FAIL(1000, "系统内部错误,请联系业务系统运维管理员"),
  15 + FIlE_UPLOAD_TOO_LARGE(1051, "上传文件太大,图片文件一般小于2兆"),
  16 +
  17 + UNAUTHORIZED(401, "登录状态过期"),
  18 +
  19 + //空指针异常
  20 + NULL_POINT(1001, "空指针异常"),
  21 +
  22 + //校验异常
  23 + RUN_ERROR(1002, "程序运行报错"),
  24 + ILLEGAL_ARGUMENT(1003, "参数非法"),
  25 + FILED_ERROR(1004, "传入参数错误"),
  26 + PARAM_ERROR(1005, "入参为空"),
  27 + EMPTY_RESULT(1006, "数据不存在"),
  28 + EMPTY_LIST(1007, "查询结果为空"),
  29 + IMG_CAPTCHA_ERROR(1008, "图片验证码错误"),
  30 + IMG_CAPTCHA_EXPIRE_ERROR(1009, "图片验证码不存在或已过期"),
  31 + SMS_CAPTCHA_ERROR(1010, "短信验证码错误"),
  32 + SMS_CAPTCHA_EXPIRE_ERROR(1011, "短信验证码不存在或已过期"),
  33 +
  34 + //认证授权异常
  35 + UNAUTHENTICATION(401, "未登录"),
  36 +
  37 +
  38 + //用户
  39 + USER_NOT_EXIT(20001, "用户不存在"),
  40 + USER_UN_ENABLE(20002, "用户未激活"),
  41 +
  42 +
  43 + // 公司
  44 + COMPANY_NOT_EXIT(30001, "公司不存在"),
  45 +
  46 + // 短信
  47 + SMS_SEND_OVER_LIMIT_ERROR(40001, "发送频次过高,请一分钟后再发送"),
  48 + EMAIL_SEND_OVER_LIMIT_ERROR(40002, "发送频次过高(一天最多修改三次),请第二天后再发送"),
  49 +
  50 + // 会员
  51 + MEMBER_PHONE_REGISTER_ERROR(50001, "手机已经被注册使用!"),
  52 + MEMBER_AGREE_AGREEMENT_CHOOSE_ERROR(50002, "必须同意注册协议才可进行注册操作!"),
  53 + MEMBER_CONFIRM_PASSWORD_ERROR(50003, "两次密码输入不一致!"),
  54 + MEMBER_LOGIN_PHONE_ERROR(50004, "手机号没有注册,请注册后登录!"),
  55 + MEMBER_LOGIN_LOCKED_TIME_ERROR(50005, "账号被锁定,请稍后再试试!"),
  56 + MEMBER_RECOVER_PASSWORD_ERROR(50006, "对不起,此密码找回链接已失效!"),
  57 + MEMBER_RECOVER_PASSWORD_EXPIRE_ERROR(50007, "对不起,此密码找回链接已过期!"),
  58 +
  59 + //产品
  60 + PRODUCT_NOT_EXIST_ERROR(60001, "此商品已下架!"),
  61 + PRODUCT_NOT_MORE_STORE_ERROR(60002, "添加购物车失败,商品库存不足!"),
  62 +
  63 + //订单
  64 + ORDER_BASE_INFO_EMPTY(70001, "订单基础信息不能为空!"),
  65 +
  66 + //申请
  67 + APPLY_UNLOCK_FIELD_EXIST(80001, "还有未审批完结的申请,请等上一个申请单完结!"),
  68 + APPLY_NOT_EXIST(80002, "申请单不存在!"),
  69 +
  70 + //上传图片
  71 + UPLOAD_IMAGES_ERROR(900021, "上传图片失败!"),
  72 + ;
  73 +
  74 +
  75 + ServerResultCode(Integer errorCode, String errorDesc) {
  76 + this.errorCode = errorCode;
  77 + this.errorDesc = errorDesc;
  78 + }
  79 +
  80 + @Setter
  81 + private Integer errorCode;
  82 + @Setter
  83 + private String errorDesc;
  84 +
  85 + @Override
  86 + public Integer getErrorCode() {
  87 + return this.errorCode;
  88 + }
  89 +
  90 + @Override
  91 + public String getErrorDesc() {
  92 + return this.errorDesc;
  93 + }
  94 +
  95 + /**
  96 + * 根据errorCode获得枚举
  97 + *
  98 + * @param errorCode
  99 + * @return
  100 + */
  101 + public static String getDescByCode(Integer errorCode) {
  102 + if (errorCode == null) {
  103 + return null;
  104 + }
  105 + ServerResultCode[] serverResults = values();
  106 + for (ServerResultCode serverResult : serverResults) {
  107 + if (serverResult.getErrorCode().equals(errorCode)) {
  108 + return serverResult.getErrorDesc();
  109 + }
  110 + }
  111 + return null;
  112 + }
  113 +
  114 +}
0 115 \ No newline at end of file
... ...
src/main/java/com/canrd/webmagic/common/directory/Path.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/directory/Path.java
  1 +package com.canrd.webmagic.common.directory;
  2 +
  3 +import com.canrd.webmagic.common.constant.Constant;
  4 +
  5 +/**
  6 + * @author xms
  7 + */
  8 +public class Path {
  9 + /**
  10 + * 获取程序启动路径
  11 + *
  12 + * @param cls,建议直接传 ServiceApplication.class
  13 + * @return 应用启动路径
  14 + */
  15 + public static String getAppPath(Class cls) {
  16 + String path = cls.getResource(Constant.SLASH_MARK_CHARACTER).getPath();
  17 + String os = System.getProperty("os.name").toLowerCase();
  18 + final String OSWINDOW = "windows";
  19 + if (os.indexOf(OSWINDOW) != -1 && path.length() > 1) {
  20 + //windows路径样例: /D:/work/code/shop-services/online-shop-oss/target/classes/
  21 + return path.substring(1);
  22 + }
  23 +
  24 + //linux 路径样例 file:/opt/target/online-shop-oss-SNAPSHOT.jar!/BOOT-INF/classes!/";
  25 + final String FILE = "file:";
  26 + if (path.indexOf(FILE) != -1) {
  27 + path = path.substring(FILE.length());
  28 + }
  29 +
  30 + int pos = -1;
  31 + if ((pos = path.indexOf(Constant.EXCLAMATION_MARK_CHARACTER)) != -1) {
  32 + if (-1 != (pos = path.lastIndexOf(Constant.SLASH_MARK_CHARACTER, pos))) {
  33 + path = path.substring(0, pos + 1);
  34 + }
  35 + }
  36 +
  37 + return path;
  38 + }
  39 +}
... ...
src/main/java/com/canrd/webmagic/common/exception/BadRequestException.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/BadRequestException.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +import lombok.Getter;
  4 +import org.springframework.http.HttpStatus;
  5 +
  6 +import static org.springframework.http.HttpStatus.BAD_REQUEST;
  7 +
  8 +/**
  9 + *
  10 + * @date 2018-11-23
  11 + * 统一异常处理
  12 + */
  13 +@Getter
  14 +public class BadRequestException extends RuntimeException {
  15 +
  16 + private Integer status = BAD_REQUEST.value();
  17 +
  18 + public BadRequestException(String msg) {
  19 + super(msg);
  20 + }
  21 +
  22 + public BadRequestException(HttpStatus status, String msg) {
  23 + super(msg);
  24 + this.status = status.value();
  25 + }
  26 +}
... ...
src/main/java/com/canrd/webmagic/common/exception/BusinessException.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/BusinessException.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +import com.canrd.webmagic.common.constant.ServerResult;
  4 +import com.canrd.webmagic.common.constant.ServerResultCode;
  5 +import lombok.Getter;
  6 +import lombok.Setter;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +
  9 +/**
  10 + * <p>基础异常类,所有自定义异常类都需要继承本类</p>
  11 + */
  12 +@Slf4j
  13 +public class BusinessException extends RuntimeException {
  14 +
  15 + private static final long serialVersionUID = 3152549963899218489L;
  16 + @Setter
  17 + @Getter
  18 + private String errorDesc;
  19 + @Setter
  20 + @Getter
  21 + private Integer errorCode;
  22 + @Setter
  23 + @Getter
  24 + private Object data;
  25 +
  26 + public BusinessException() {
  27 + super(ServerResultCode.FAIL.getErrorDesc());
  28 + this.errorCode = ServerResultCode.FAIL.getErrorCode();
  29 + this.errorDesc = ServerResultCode.FAIL.getErrorDesc();
  30 + }
  31 +
  32 + public BusinessException(int errorCode, String errorDesc) {
  33 + super(errorDesc);
  34 + this.errorCode = errorCode;
  35 + this.errorDesc = errorDesc;
  36 + }
  37 +
  38 + public BusinessException(ServerResultCode serverResultCode) {
  39 + super(serverResultCode.getErrorDesc());
  40 + this.errorCode = serverResultCode.getErrorCode();
  41 + this.errorDesc = serverResultCode.getErrorDesc();
  42 + log.error("业务异常: ", this);
  43 + }
  44 +
  45 + public BusinessException(ErrorInfo errorInfo) {
  46 + super(errorInfo.getErrorDesc());
  47 + this.errorCode = errorInfo.getErrorCode();
  48 + this.errorDesc = errorInfo.getErrorDesc();
  49 + log.error("业务异常: ", this);
  50 + }
  51 +
  52 + public BusinessException(ServerResult<?> serverResult) {
  53 + super(serverResult == null ? ServerResultCode.FAIL.getErrorDesc() : serverResult.getMessage());
  54 + if (serverResult == null) {
  55 + this.errorCode = ServerResultCode.FAIL.getErrorCode();
  56 + this.errorDesc = ServerResultCode.FAIL.getErrorDesc();
  57 + } else {
  58 + this.errorCode = serverResult.getResult();
  59 + this.errorDesc = serverResult.getMessage();
  60 + this.data = serverResult.getData();
  61 + }
  62 + log.error("业务异常: ", this);
  63 + }
  64 +
  65 + public BusinessException(String message) {
  66 + super(message);
  67 + }
  68 +
  69 + public BusinessException(Throwable cause) {
  70 + super(cause);
  71 + log.error("业务异常: ", this);
  72 + }
  73 +
  74 + public BusinessException(String message, Throwable cause) {
  75 + super(message, cause);
  76 + log.error("业务异常: ", this);
  77 + }
  78 +}
... ...
src/main/java/com/canrd/webmagic/common/exception/BusinessExceptionHandlerAdvice.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/BusinessExceptionHandlerAdvice.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +import com.canrd.webmagic.common.constant.ServerResult;
  4 +import com.canrd.webmagic.common.constant.ServerResultCode;
  5 +import org.springframework.core.annotation.Order;
  6 +import org.springframework.http.HttpStatus;
  7 +import org.springframework.http.ResponseEntity;
  8 +import org.springframework.web.bind.annotation.ControllerAdvice;
  9 +import org.springframework.web.bind.annotation.ExceptionHandler;
  10 +import org.springframework.web.bind.annotation.ResponseStatus;
  11 +
  12 +import java.util.Optional;
  13 +
  14 +/**
  15 + * 业务异常统一处理类
  16 + *
  17 + * @date 2021/1/11
  18 + */
  19 +@ControllerAdvice
  20 +@Order(5)
  21 +public class BusinessExceptionHandlerAdvice {
  22 +
  23 +
  24 + @ExceptionHandler(value = {BusinessException.class})
  25 + @ResponseStatus(value = HttpStatus.OK)
  26 + public ResponseEntity<Object> handleException(BusinessException exception) throws Exception {
  27 + return new ResponseEntity<Object>(handleBusinessException(exception), HttpStatus.OK);
  28 + }
  29 +
  30 + private ServerResult handleBusinessException(BusinessException exception) {
  31 + Integer code = Optional.ofNullable(exception.getErrorCode()).orElse(ServerResultCode.FAIL.getErrorCode());
  32 + String msg = Optional.ofNullable(exception.getMessage()).orElse(ServerResultCode.FAIL.getErrorDesc());
  33 + Object data = Optional.ofNullable(exception.getData()).orElse(null);
  34 + return ServerResult.fail(data, code, msg);
  35 + }
  36 +}
... ...
src/main/java/com/canrd/webmagic/common/exception/EntityExistException.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/EntityExistException.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +import org.springframework.util.StringUtils;
  4 +
  5 +/**
  6 + *
  7 + * @date 2018-11-23
  8 + */
  9 +public class EntityExistException extends RuntimeException {
  10 +
  11 + public EntityExistException(Class clazz, String field, String val) {
  12 + super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val));
  13 + }
  14 +
  15 + private static String generateMessage(String entity, String field, String val) {
  16 + return StringUtils.capitalize(entity)
  17 + + " with " + field + " " + val + " existed";
  18 + }
  19 +}
0 20 \ No newline at end of file
... ...
src/main/java/com/canrd/webmagic/common/exception/EntityNotFoundException.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/EntityNotFoundException.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +import org.springframework.util.StringUtils;
  4 +
  5 +/**
  6 + *
  7 + * @date 2018-11-23
  8 + */
  9 +public class EntityNotFoundException extends RuntimeException {
  10 +
  11 + public EntityNotFoundException(Class clazz, String field, String val) {
  12 + super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val));
  13 + }
  14 +
  15 + private static String generateMessage(String entity, String field, String val) {
  16 + return StringUtils.capitalize(entity)
  17 + + " with " + field + " " + val + " does not exist";
  18 + }
  19 +}
0 20 \ No newline at end of file
... ...
src/main/java/com/canrd/webmagic/common/exception/ErrorInfo.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/ErrorInfo.java
  1 +package com.canrd.webmagic.common.exception;
  2 +
  3 +/**
  4 + * @date 2023-01-12
  5 + */
  6 +public interface ErrorInfo {
  7 +
  8 + Integer getErrorCode();
  9 +
  10 + String getErrorDesc();
  11 +}
... ...
src/main/java/com/canrd/webmagic/common/exception/handler/ApiError.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/handler/ApiError.java
  1 +package com.canrd.webmagic.common.exception.handler;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + *
  10 + * @date 2018-11-23
  11 + */
  12 +@Data
  13 +class ApiError {
  14 +
  15 + private Integer status = 200;
  16 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  17 + private LocalDateTime timestamp;
  18 + private String message;
  19 + private String errorCode;
  20 +
  21 + private ApiError() {
  22 + timestamp = LocalDateTime.now();
  23 + }
  24 +
  25 + public static ApiError error(String message){
  26 + ApiError apiError = new ApiError();
  27 + apiError.setMessage(message);
  28 + return apiError;
  29 + }
  30 +
  31 + public static ApiError error(Integer status, String message){
  32 + ApiError apiError = new ApiError();
  33 + apiError.setStatus(status);
  34 + apiError.setMessage(message);
  35 + return apiError;
  36 + }
  37 +}
  38 +
  39 +
... ...
src/main/java/com/canrd/webmagic/common/exception/handler/GlobalExceptionHandler.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/exception/handler/GlobalExceptionHandler.java
  1 +package com.canrd.webmagic.common.exception.handler;
  2 +
  3 +import com.canrd.webmagic.common.constant.ServerResult;
  4 +import com.canrd.webmagic.common.constant.ServerResultCode;
  5 +import com.canrd.webmagic.common.exception.BusinessException;
  6 +import com.canrd.webmagic.common.exception.EntityExistException;
  7 +import com.canrd.webmagic.common.exception.EntityNotFoundException;
  8 +import com.canrd.webmagic.common.utils.ThrowableUtil;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.springframework.http.HttpStatus;
  11 +import org.springframework.http.ResponseEntity;
  12 +import org.springframework.web.bind.MethodArgumentNotValidException;
  13 +import org.springframework.web.bind.annotation.ExceptionHandler;
  14 +import org.springframework.web.bind.annotation.ResponseStatus;
  15 +import org.springframework.web.bind.annotation.RestControllerAdvice;
  16 +import org.springframework.web.multipart.MaxUploadSizeExceededException;
  17 +
  18 +import java.util.Objects;
  19 +
  20 +/**
  21 + * @date 2018-11-23
  22 + */
  23 +@Slf4j
  24 +@RestControllerAdvice
  25 +public class GlobalExceptionHandler {
  26 + /**
  27 + * @param exception
  28 + * @return
  29 + * @throws Exception
  30 + */
  31 + @ExceptionHandler(value = RuntimeException.class)
  32 + public ResponseEntity<Object> handleServiceException(Exception exception) throws Exception {
  33 + return new ResponseEntity(translateException(exception), HttpStatus.OK);
  34 + }
  35 +
  36 + /**
  37 + * @param exception
  38 + * @return
  39 + * @throws Exception
  40 + */
  41 + @ExceptionHandler(value = Exception.class)
  42 + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
  43 + public ResponseEntity<Object> handleException(Exception exception) throws Exception {
  44 + return new ResponseEntity<Object>(translateException(exception), HttpStatus.OK);
  45 + }
  46 +
  47 +
  48 + /**
  49 + * 处理所有接口数据验证异常
  50 + *
  51 + * @param e
  52 + * @return
  53 + */
  54 + @ExceptionHandler(MethodArgumentNotValidException.class)
  55 + public ResponseEntity<ServerResult> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
  56 + // 打印堆栈信息
  57 + log.error(ThrowableUtil.getStackTrace(e));
  58 + String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
  59 + String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
  60 + String msg = "不能为空";
  61 + if (msg.equals(message)) {
  62 + message = str[1] + ":" + message;
  63 + }
  64 + return buildResponseEntity(ServerResult.fail(message));
  65 + }
  66 +
  67 + /**
  68 + * 处理自定义异常
  69 + *
  70 + * @param e
  71 + * @return
  72 + */
  73 + @ExceptionHandler(value = BusinessException.class)
  74 + public ResponseEntity<ServerResult> badRequestException(BusinessException e) {
  75 + // 打印堆栈信息
  76 + log.error(ThrowableUtil.getStackTrace(e));
  77 + return buildResponseEntity(ServerResult.fail(e.getErrorCode(), e.getMessage()));
  78 + }
  79 +
  80 + /**
  81 + * 处理 EntityExist
  82 + */
  83 + @ExceptionHandler(value = EntityExistException.class)
  84 + public ResponseEntity<ServerResult> entityExistException(EntityExistException e) {
  85 + // 打印堆栈信息
  86 + log.error(ThrowableUtil.getStackTrace(e));
  87 + return buildResponseEntity(ServerResult.fail(e.getMessage()));
  88 + }
  89 +
  90 + /**
  91 + * 处理 EntityNotFound
  92 + *
  93 + * @param e
  94 + * @return
  95 + */
  96 + @ExceptionHandler(value = EntityNotFoundException.class)
  97 + public ResponseEntity<ServerResult> entityNotFoundException(EntityNotFoundException e) {
  98 + // 打印堆栈信息
  99 + log.error(ThrowableUtil.getStackTrace(e));
  100 + return buildResponseEntity(ServerResult.fail(HttpStatus.NOT_FOUND.value(), e.getMessage()));
  101 + }
  102 +
  103 + /**
  104 + * @param serverResult
  105 + * @return
  106 + */
  107 + private ResponseEntity<ServerResult> buildResponseEntity(ServerResult serverResult) {
  108 + return new ResponseEntity<>(serverResult, HttpStatus.valueOf(200));
  109 + }
  110 +
  111 + /**
  112 + * @param e
  113 + * @return
  114 + * @throws Exception
  115 + */
  116 + private Object translateException(Exception e) throws Exception {
  117 + ServerResult serverResult = null;
  118 + if (e instanceof NullPointerException) {
  119 + serverResult = ServerResult.fail(ServerResultCode.NULL_POINT);
  120 + } else if (e instanceof IllegalArgumentException) {
  121 + serverResult = ServerResult.fail(ServerResultCode.FAIL);
  122 + } else if (e instanceof MaxUploadSizeExceededException) {
  123 + serverResult = ServerResult.fail(ServerResultCode.FIlE_UPLOAD_TOO_LARGE);
  124 + } else if (e instanceof BusinessException) {
  125 + serverResult = ServerResult.fail(((BusinessException) e).getErrorCode(), ((BusinessException) e).getErrorDesc());
  126 + } else {
  127 + serverResult = ServerResult.fail(ServerResultCode.FAIL);
  128 + serverResult.setMessage(serverResult.getMessage() + "|,业务异常:" + e.getMessage());
  129 + }
  130 +
  131 + log.error("业务异常", e);
  132 + return serverResult;
  133 + }
  134 +}
... ...
src/main/java/com/canrd/webmagic/common/jsr303/ListValueConstraintValidator.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/jsr303/ListValueConstraintValidator.java
  1 +package com.canrd.webmagic.common.jsr303;
  2 +
  3 +
  4 +import com.canrd.webmagic.common.jsr303.annotation.ListIntValue;
  5 +
  6 +import javax.validation.ConstraintValidator;
  7 +import javax.validation.ConstraintValidatorContext;
  8 +import java.util.HashSet;
  9 +import java.util.Set;
  10 +
  11 +/**
  12 + * 自定义校验注解 -枚举值校验
  13 + *
  14 + * @author fanzhenyu
  15 + * @date 2023-01-15
  16 + */
  17 +public class ListValueConstraintValidator implements ConstraintValidator<ListIntValue, Integer> {
  18 + private Set<Integer> set = new HashSet<>();
  19 + // 是否必填
  20 + private boolean require;
  21 +
  22 + @Override
  23 + public void initialize(ListIntValue constraintAnnotation) {
  24 + for (int i : constraintAnnotation.enumValue()) {
  25 + set.add(i);
  26 + }
  27 + require = constraintAnnotation.require();
  28 + }
  29 +
  30 + /**
  31 + * 判断是否通过校验
  32 + *
  33 + * @param value 传入的值
  34 + * @param context
  35 + * @return
  36 + */
  37 + @Override
  38 + public boolean isValid(Integer value, ConstraintValidatorContext context) {
  39 + if (!require && value == null) {
  40 + return true;
  41 + }
  42 + return set.contains(value);
  43 + }
  44 +
  45 +}
... ...
src/main/java/com/canrd/webmagic/common/jsr303/OperateGroup.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/jsr303/OperateGroup.java
  1 +package com.canrd.webmagic.common.jsr303;
  2 +
  3 +
  4 +public class OperateGroup {
  5 + /**
  6 + * 新增校验
  7 + */
  8 + public interface Save {
  9 + }
  10 +
  11 + /**
  12 + * 删除校验
  13 + */
  14 + public interface Delete {
  15 + }
  16 +
  17 + /**
  18 + * 修改校验
  19 + */
  20 + public interface Update {
  21 + }
  22 +
  23 + /**
  24 + * 查询列表
  25 + */
  26 + public interface List {
  27 + }
  28 +
  29 + /**
  30 + * 分页查询
  31 + */
  32 + public interface Page {
  33 + }
  34 +
  35 + /**
  36 + * 长度校验
  37 + */
  38 + public interface Length {
  39 + }
  40 +
  41 + /**
  42 + * 格式校验
  43 + */
  44 + public interface Format {
  45 + }
  46 +
  47 + /**
  48 + * 详情
  49 + */
  50 + public interface Detail {
  51 + }
  52 +
  53 + /**
  54 + * 单条
  55 + */
  56 + public interface One {
  57 + }
  58 +
  59 +
  60 + public interface Trace {
  61 +
  62 + }
  63 +
  64 + /**
  65 + * 批量查询
  66 + */
  67 + public interface BatchQuery {
  68 + }
  69 +
  70 +
  71 + /**
  72 + * 导出
  73 + */
  74 + public interface Export {
  75 + }
  76 +
  77 +}
... ...
src/main/java/com/canrd/webmagic/common/jsr303/annotation/ListIntValue.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/jsr303/annotation/ListIntValue.java
  1 +package com.canrd.webmagic.common.jsr303.annotation;
  2 +
  3 +
  4 +import com.canrd.webmagic.common.jsr303.ListValueConstraintValidator;
  5 +
  6 +import javax.validation.Constraint;
  7 +import javax.validation.Payload;
  8 +import java.lang.annotation.*;
  9 +
  10 +/**
  11 + * @date 2023-01-15
  12 + */
  13 +@Constraint(validatedBy = {ListValueConstraintValidator.class})
  14 +@Documented
  15 +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
  16 +@Retention(RetentionPolicy.RUNTIME)
  17 +public @interface ListIntValue {
  18 +
  19 +
  20 + // 配置文件中错误提示信息的名称
  21 + String message() default "非法的类型";
  22 +
  23 + Class<?>[] groups() default {};
  24 +
  25 + Class<? extends Payload>[] payload() default {};
  26 +
  27 + // 自定义值的类型
  28 + int[] enumValue() default {};
  29 +
  30 + // 是否必填,默认允许为空
  31 + boolean require() default false;
  32 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/DateUtil.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/DateUtil.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +
  4 +import java.text.DateFormat;
  5 +import java.text.ParseException;
  6 +import java.text.SimpleDateFormat;
  7 +import java.time.*;
  8 +import java.time.format.DateTimeFormatter;
  9 +import java.time.temporal.ChronoField;
  10 +import java.time.temporal.TemporalAdjusters;
  11 +import java.util.Date;
  12 +import java.util.Locale;
  13 +import java.util.TimeZone;
  14 +
  15 +/**
  16 + * @Date: 2020/9/1
  17 + * 基于Java8的时间工具类
  18 + */
  19 +public class DateUtil {
  20 + /**
  21 + * 例如:2018-12-28
  22 + */
  23 + public static final String DATE = "yyyy-MM-dd";
  24 + /**
  25 + * 例如:2018.12.28
  26 + */
  27 + public static final String DATE_WITH_POINT = "yyyy.MM.dd";
  28 + /**
  29 + * 例如:2018-12-28 10:00:00
  30 + */
  31 + public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
  32 + /**
  33 + * 例如:2018-12-28 10:00:00:215
  34 + */
  35 + public static final String DATE_TIME_MS = "yyyy-MM-dd HH:mm:ss.SSS";
  36 + /**
  37 + * 例如:10:00:00
  38 + */
  39 + public static final String TIME = "HHmmss";
  40 + /**
  41 + * 例如:10:00:00
  42 + */
  43 + public static final String TIME_HAVE_SECOND = "HH:mm:ss";
  44 + /**
  45 + * 例如:10:00
  46 + */
  47 + public static final String TIME_WITHOUT_SECOND = "HH:mm";
  48 +
  49 + /**
  50 + * 例如:2018-12-28 10:00
  51 + */
  52 + public static final String DATE_TIME_WITHOUT_SECONDS = "yyyy-MM-dd HH:mm";
  53 +
  54 + /**
  55 + * 例如 2020/04/16 12:23:0
  56 + */
  57 + public static final String DATE_TIME_WITHOUT_SECONDS_OTHER = "yyyy/MM/dd HH:mm:ss";
  58 +
  59 + /**
  60 + * 例如:2020年04月23日 10:00
  61 + */
  62 + public static final String DATE_CHINESE_TIME = "yyyy年MM月dd日 HH:mm";
  63 +
  64 + /**
  65 + * 例如:20181228100000215
  66 + */
  67 + public static final String MAX_DATE = "9999-12-31 59:59:59";
  68 +
  69 + /**
  70 + * 例如:20210822082134
  71 + */
  72 + public static final String DATE_TIME_HMS = "yyyyMMddHHmmssSSS";
  73 +
  74 + public static final String YYMMDD = "yyyyMMdd";
  75 +
  76 + public static final String YMMDD = "yyMMdd";
  77 +
  78 + public static final String YYMMDDHHMMSS = "yyMMddHHmmss";
  79 +
  80 + public static final String MONTH_TIME = "MM-dd HH:mm:ss";
  81 +
  82 + /**
  83 + * 例如:2018-12-28 10:00
  84 + */
  85 + public static final String DDMMYYYYHHMMSS = "dd/MM/yyyy HH:mm:ss";
  86 +
  87 + public static LocalDateTime getCurrentTime() {
  88 + LocalDateTime now = LocalDateTime.now();
  89 + return now;
  90 + }
  91 +
  92 + public static Date getNextDay() {
  93 + LocalDateTime now = LocalDateTime.now();
  94 + LocalDateTime tomorrow = now.minusDays(-1);
  95 + return Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant());
  96 + }
  97 +
  98 + public static Date getAppointDay(Integer count) {
  99 + LocalDateTime now = LocalDateTime.now();
  100 + LocalDateTime tomorrow = now.minusDays(count);
  101 + return Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant());
  102 + }
  103 +
  104 + /**
  105 + * 获取年
  106 + *
  107 + * @return 年
  108 + */
  109 + public static int getYear() {
  110 + LocalDateTime localDateTime = LocalDateTime.now();
  111 + return localDateTime.get(ChronoField.YEAR);
  112 + }
  113 +
  114 + /**
  115 + * 获取月份
  116 + *
  117 + * @return 月份
  118 + */
  119 + public static int getMonth() {
  120 + LocalDateTime localDateTime = LocalDateTime.now();
  121 + return localDateTime.get(ChronoField.MONTH_OF_YEAR);
  122 + }
  123 +
  124 + /**
  125 + * 获取某月的第几天
  126 + *
  127 + * @return 几号
  128 + */
  129 + public static int getMonthOfDay() {
  130 + LocalDateTime localDateTime = LocalDateTime.now();
  131 + return localDateTime.get(ChronoField.DAY_OF_MONTH);
  132 + }
  133 +
  134 + /**
  135 + * 格式化日期为字符串
  136 + *
  137 + * @param date date
  138 + * @param pattern 格式
  139 + * @return 日期字符串
  140 + */
  141 + public static String formatOrElseBlank(Date date, String pattern) {
  142 + if (date == null || pattern == null) {
  143 + return "";
  144 + }
  145 + Instant instant = date.toInstant();
  146 +
  147 + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  148 +
  149 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  150 + }
  151 +
  152 + /**
  153 + * 格式化日期为字符串
  154 + *
  155 + * @param date date
  156 + * @param pattern 格式
  157 + * @return 日期字符串
  158 + */
  159 + public static String format(Date date, String pattern) {
  160 +
  161 + Instant instant = date.toInstant();
  162 +
  163 + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  164 +
  165 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  166 + }
  167 +
  168 + public static String formatNow(String pattern) {
  169 + LocalDateTime localDateTime = LocalDateTime.now();
  170 +
  171 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  172 + }
  173 +
  174 +
  175 + public static String format(LocalDateTime date, String pattern) {
  176 + return date.format(DateTimeFormatter.ofPattern(pattern));
  177 + }
  178 +
  179 + public static String format(LocalDate date, String pattern) {
  180 + return date.format(DateTimeFormatter.ofPattern(pattern));
  181 + }
  182 +
  183 + /**
  184 + * 解析字符串日期为LocalDateTime
  185 + *
  186 + * @param dateStr 日期字符串
  187 + * @param pattern 格式
  188 + * @return Date
  189 + */
  190 + public static LocalDateTime parse(String dateStr, String pattern) {
  191 + return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
  192 + }
  193 +
  194 + /**
  195 + * 解析字符串日期为LocalDateTime
  196 + *
  197 + * @param dateStr 日期字符串
  198 + * @param pattern 格式
  199 + * @return Date
  200 + */
  201 + public static LocalDateTime parseStrByPattern(String dateStr, String pattern) {
  202 + try {
  203 + return parse(dateStr, pattern);
  204 + } catch (Exception e) {
  205 + return getCurrentTime();
  206 + }
  207 + }
  208 +
  209 + /**
  210 + * 解析字符串日期为LocalDate
  211 + *
  212 + * @param dateStr
  213 + * @param pattern
  214 + * @return
  215 + */
  216 + public static LocalDate parseDate(String dateStr, String pattern) {
  217 + return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
  218 + }
  219 +
  220 + /**
  221 + * @param dateTimeStr
  222 + * @param prePattern
  223 + * @param expectPattern
  224 + * @return
  225 + */
  226 + public static String format(String dateTimeStr, String prePattern, String expectPattern) {
  227 + LocalDateTime localDateTime = parseDate(dateTimeStr, prePattern).atStartOfDay();
  228 + return localDateTime.format(DateTimeFormatter.ofPattern(expectPattern));
  229 + }
  230 +
  231 + /**
  232 + * String -> Date
  233 + *
  234 + * @param date
  235 + * @return
  236 + */
  237 + public static Date parseStringToDate(String date, String pattern) {
  238 + SimpleDateFormat sdf = new SimpleDateFormat(pattern);
  239 + try {
  240 + return sdf.parse(date);
  241 + } catch (ParseException e) {
  242 + return null;
  243 + }
  244 + }
  245 +
  246 + /**
  247 + * 为Date增加分钟,减传负数
  248 + *
  249 + * @param date 日期
  250 + * @param plusMinutes 要增加的分钟数
  251 + * @return 新的日期
  252 + */
  253 + public static Date addMinutes(Date date, Long plusMinutes) {
  254 + LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
  255 + LocalDateTime newDateTime = dateTime.plusMinutes(plusMinutes);
  256 + return Date.from(newDateTime.atZone(ZoneId.systemDefault()).toInstant());
  257 + }
  258 +
  259 + /**
  260 + * 增加时间
  261 + *
  262 + * @param date date
  263 + * @param hour 要增加的小时数
  264 + * @return new date
  265 + */
  266 + public static Date addHour(Date date, Long hour) {
  267 + LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
  268 + LocalDateTime localDateTime = dateTime.plusHours(hour);
  269 + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  270 + }
  271 +
  272 + /**
  273 + * @return 返回当天的起始时间
  274 + */
  275 + public static Date getStartTime() {
  276 +
  277 + LocalDateTime now = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
  278 + return localDateTime2Date(now);
  279 + }
  280 +
  281 +
  282 + /**
  283 + * @return 返回当天的结束时间
  284 + */
  285 + public static Date getEndTime() {
  286 + LocalDateTime now = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
  287 + return localDateTime2Date(now);
  288 + }
  289 +
  290 + /**
  291 + * @return 获取入参当天结束时间
  292 + */
  293 + public static LocalDateTime getEndTime(LocalDate localDate) {
  294 + return localDate.atTime(23, 59, 59, 999999999);
  295 + }
  296 +
  297 + /**
  298 + * 减月份
  299 + *
  300 + * @param monthsToSubtract 月份
  301 + * @return Date
  302 + */
  303 + public static Date minusMonths(long monthsToSubtract) {
  304 + LocalDate localDate = LocalDate.now().minusMonths(monthsToSubtract);
  305 +
  306 + return localDate2Date(localDate);
  307 + }
  308 +
  309 + /**
  310 + * LocalDate类型转为Date
  311 + *
  312 + * @param localDate LocalDate object
  313 + * @return Date object
  314 + */
  315 + public static Date localDate2Date(LocalDate localDate) {
  316 +
  317 + ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
  318 +
  319 + return Date.from(zonedDateTime.toInstant());
  320 + }
  321 +
  322 + /**
  323 + * Date类型转为LocalDateTime
  324 + *
  325 + * @param date Date object
  326 + * @return localDate LocalDateTime
  327 + */
  328 + public static LocalDateTime date2LocalDateTime(Date date) {
  329 +
  330 + Instant instant = date.toInstant();
  331 + ZoneId zoneId = ZoneId.systemDefault();
  332 + LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
  333 + return localDateTime;
  334 + }
  335 +
  336 +
  337 + /**
  338 + * LocalDateTime类型转为Date
  339 + *
  340 + * @param localDateTime LocalDateTime object
  341 + * @return Date object
  342 + */
  343 + public static Date localDateTime2Date(LocalDateTime localDateTime) {
  344 + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  345 + }
  346 +
  347 + /**
  348 + * 查询当前年的第一天
  349 + *
  350 + * @param pattern 格式,默认格式yyyyMMdd
  351 + * @return 20190101
  352 + */
  353 + public static String getFirstDayOfCurrentYear(String pattern) {
  354 + LocalDateTime localDateTime = LocalDateTime.now().withMonth(1).withDayOfMonth(1);
  355 +
  356 + if (StringUtils.isEmpty(pattern)) {
  357 + pattern = "yyyyMMdd";
  358 + }
  359 +
  360 + return format(localDateTime2Date(localDateTime), pattern);
  361 + }
  362 +
  363 + /**
  364 + * 查询前一年最后一个月第一天
  365 + *
  366 + * @param pattern 格式,默认格式yyyyMMdd
  367 + * @return 20190101
  368 + */
  369 + public static String getLastMonthFirstDayOfPreviousYear(String pattern) {
  370 + LocalDateTime localDateTime = LocalDateTime.now().minusYears(1L).withMonth(12).withDayOfMonth(1);
  371 +
  372 + if (StringUtils.isEmpty(pattern)) {
  373 + pattern = "yyyyMMdd";
  374 + }
  375 +
  376 + return format(localDateTime2Date(localDateTime), pattern);
  377 + }
  378 +
  379 + /**
  380 + * 查询前一年最后一个月第一天
  381 + *
  382 + * @param pattern 格式,默认格式yyyyMMdd
  383 + * @return 20190101
  384 + */
  385 + public static String getLastMonthLastDayOfPreviousYear(String pattern) {
  386 + LocalDateTime localDateTime = LocalDateTime.now().minusYears(1L).with(TemporalAdjusters.lastDayOfYear());
  387 +
  388 + if (StringUtils.isEmpty(pattern)) {
  389 + pattern = "yyyyMMdd";
  390 + }
  391 +
  392 + return format(localDateTime2Date(localDateTime), pattern);
  393 + }
  394 +
  395 + /**
  396 + * 获取当前日期
  397 + *
  398 + * @param pattern 格式,默认格式yyyyMMdd
  399 + * @return 20190101
  400 + */
  401 + public static String getCurrentDay(String pattern) {
  402 + LocalDateTime localDateTime = LocalDateTime.now();
  403 +
  404 + if (StringUtils.isEmpty(pattern)) {
  405 + pattern = "yyyyMMdd";
  406 + }
  407 +
  408 + return format(localDateTime2Date(localDateTime), pattern);
  409 + }
  410 +
  411 + public static String getTransitionTime(LocalDateTime time, String pattern) {
  412 + if (StringUtils.isEmpty(pattern)) {
  413 + pattern = "yyyyMMdd";
  414 + }
  415 + return format(localDateTime2Date(time), pattern);
  416 + }
  417 +
  418 +
  419 + /**
  420 + * 用于判断两个时间段有没有重合, 重合: true,未重合: false
  421 + *
  422 + * @param aStartTime
  423 + * @param aEndTime
  424 + * @param bStartTime
  425 + * @param bEndTime
  426 + * @return
  427 + * @author A80068
  428 + */
  429 + public static boolean judgeTimeSlotCoincidence(LocalDateTime aStartTime, LocalDateTime aEndTime, LocalDateTime bStartTime, LocalDateTime bEndTime) {
  430 + /**
  431 + * 旧版
  432 + */
  433 + //boolean flag;
  434 + //if(aStartTime.isAfter(bStartTime)){
  435 + // if (aStartTime.isBefore(bEndTime) || aStartTime.isEqual(bEndTime)){
  436 + // flag = true;
  437 + // }else{
  438 + // flag = false;
  439 + // }
  440 + //}else if(aStartTime.isBefore(bStartTime)){
  441 + // if(aEndTime.isAfter(bStartTime) || aEndTime.isEqual(bStartTime)){
  442 + // flag = true;
  443 + // }else{
  444 + // flag = false;
  445 + // }
  446 + //}else{
  447 + // flag = true;
  448 + //}
  449 + //return flag;
  450 + /**
  451 + * 优化版
  452 + */
  453 + boolean flag = false;
  454 + if ((aStartTime.isBefore(bEndTime) || aStartTime.isEqual(bEndTime))) {
  455 + if ((aEndTime.isAfter(bStartTime)) || aEndTime.isEqual(bStartTime)) {
  456 + flag = true;
  457 + }
  458 + }
  459 + return flag;
  460 + }
  461 +
  462 + /**
  463 + * @param aStartTimeStr
  464 + * @param aEndTimeStr
  465 + * @param bStartTimeStr
  466 + * @param bEndTimeStr
  467 + * @return
  468 + * @author A80068
  469 + */
  470 + public static boolean judgeTimeSlotCoincidenceString(String aStartTimeStr, String aEndTimeStr, String bStartTimeStr, String bEndTimeStr) {
  471 +
  472 + LocalDateTime aStartTime = parse(aStartTimeStr, DATE_TIME);
  473 + LocalDateTime aEndTime = parse(aEndTimeStr, DATE_TIME);
  474 + LocalDateTime bStartTime = parse(bStartTimeStr, DATE_TIME);
  475 + LocalDateTime bEndTime = parse(bEndTimeStr, DATE_TIME);
  476 +
  477 + return judgeTimeSlotCoincidence(aStartTime, aEndTime, bStartTime, bEndTime);
  478 + }
  479 +
  480 + /**
  481 + * @param strGMT
  482 + * @return
  483 + * @throws ParseException
  484 + * @throws ParseException
  485 + */
  486 + public static Date getCST(String strGMT) throws ParseException, ParseException {
  487 + DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
  488 + return df.parse(strGMT);
  489 + }
  490 +
  491 + /**
  492 + * @param dateCST
  493 + * @return
  494 + */
  495 + public static Date getGMT(Date dateCST) throws ParseException {
  496 + DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
  497 + df.setTimeZone(TimeZone.getTimeZone("GMT")); // modify Time Zone.
  498 + return df.parse(df.format(dateCST));
  499 + }
  500 +
  501 + /**
  502 + * LocalDateTime转化为cron表达式
  503 + *
  504 + * @param dateTime
  505 + * @return
  506 + */
  507 + public static String dateToCron(LocalDateTime dateTime) {
  508 + if (dateTime == null) {
  509 + return "";
  510 + }
  511 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy");
  512 + return formatter.format(dateTime);
  513 + }
  514 +
  515 + /**
  516 + * cron表达式转为LocalDateTime
  517 + *
  518 + * @param cron
  519 + * @return
  520 + */
  521 + public static LocalDateTime cronToDate(String cron) {
  522 + if (StringUtils.isNotBlank(cron)) {
  523 + return null;
  524 + }
  525 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy");
  526 + return LocalDateTime.parse(cron, formatter);
  527 + }
  528 +
  529 + public static String timeToString(long time) {
  530 + DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  531 + return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
  532 + }
  533 +
  534 + public static String timeToString(String time) {
  535 + try {
  536 + return timeToString(Long.parseLong(time));
  537 + } catch (Exception e) {
  538 + }
  539 + return time;
  540 + }
  541 +
  542 + /**
  543 + * 比较时间大小
  544 + *
  545 + * @param date1
  546 + * @param date2
  547 + * @return
  548 + */
  549 + public static int compareDate(Date date1, Date date2) {
  550 + if (date1 == null || date2 == null) {
  551 + return -2;
  552 + }
  553 + if (date1.getTime() < date2.getTime()) {
  554 + return -1;
  555 + } else if (date1.getTime() > date2.getTime()) {
  556 + return 1;
  557 + }
  558 + return 0;
  559 + }
  560 +
  561 + /**
  562 + * 判斷两个时间是否在同一分钟
  563 + */
  564 + public static boolean isMinuteIdentical(LocalDateTime date1, LocalDateTime date2) {
  565 + return date1.getYear() == date2.getYear() && date1.getMonth() == date2.getMonth() && date1.getMinute() == date2.getMinute();
  566 + }
  567 +
  568 + /**
  569 + * 时区
  570 + */
  571 + public static class Zone {
  572 + public static final String GMT8 = "GMT+8";
  573 + }
  574 +
  575 + public static LocalDateTime parseProductDate(String dateStr) {
  576 + if (StringUtils.isBlank(dateStr)) {
  577 + return null;
  578 + }
  579 + if (dateStr.length() == 8) {
  580 + dateStr = dateStr + " 00:00:00";
  581 + }
  582 + if (dateStr.contains("/")) {
  583 + dateStr = dateStr.replaceAll("/", "-");
  584 + }
  585 + try {
  586 + return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  587 + } catch (Exception e) {
  588 + return null;
  589 + }
  590 + }
  591 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/DateUtils.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/DateUtils.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +
  4 +import java.text.DateFormat;
  5 +import java.text.ParseException;
  6 +import java.text.SimpleDateFormat;
  7 +import java.time.*;
  8 +import java.time.format.DateTimeFormatter;
  9 +import java.time.temporal.ChronoField;
  10 +import java.time.temporal.TemporalAdjusters;
  11 +import java.util.Date;
  12 +import java.util.Locale;
  13 +import java.util.TimeZone;
  14 +
  15 +/**
  16 + * @Date: 2020/9/1
  17 + * 基于Java8的时间工具类
  18 + */
  19 +public class DateUtils {
  20 + /**
  21 + * 例如:2018-12-28
  22 + */
  23 + public static final String DATE = "yyyy-MM-dd";
  24 + /**
  25 + * 例如:2018.12.28
  26 + */
  27 + public static final String DATE_WITH_POINT = "yyyy.MM.dd";
  28 + /**
  29 + * 例如:2018-12-28 10:00:00
  30 + */
  31 + public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
  32 + /**
  33 + * 例如:2018-12-28 10:00:00:215
  34 + */
  35 + public static final String DATE_TIME_MS = "yyyy-MM-dd HH:mm:ss.SSS";
  36 + /**
  37 + * 例如:10:00:00
  38 + */
  39 + public static final String TIME = "HHmmss";
  40 + /**
  41 + * 例如:10:00:00
  42 + */
  43 + public static final String TIME_HAVE_SECOND = "HH:mm:ss";
  44 + /**
  45 + * 例如:10:00
  46 + */
  47 + public static final String TIME_WITHOUT_SECOND = "HH:mm";
  48 +
  49 + /**
  50 + * 例如:2018-12-28 10:00
  51 + */
  52 + public static final String DATE_TIME_WITHOUT_SECONDS = "yyyy-MM-dd HH:mm";
  53 +
  54 + /**
  55 + * 例如 2020/04/16 12:23:0
  56 + */
  57 + public static final String DATE_TIME_WITHOUT_SECONDS_OTHER = "yyyy/MM/dd HH:mm:ss";
  58 +
  59 + /**
  60 + * 例如:2020年04月23日 10:00
  61 + */
  62 + public static final String DATE_CHINESE_TIME = "yyyy年MM月dd日 HH:mm";
  63 +
  64 + /**
  65 + * 例如:20181228100000215
  66 + */
  67 + public static final String MAX_DATE = "9999-12-31 59:59:59";
  68 +
  69 + /**
  70 + * 例如:20210822082134
  71 + */
  72 + public static final String DATE_TIME_HMS = "yyyyMMddHHmmssSSS";
  73 +
  74 + public static final String YYMMDD = "yyyyMMdd";
  75 +
  76 + public static final String YMMDD = "yyMMdd";
  77 +
  78 + public static final String YYMMDDHHMMSS = "yyMMddHHmmss";
  79 +
  80 + public static final String MONTH_TIME = "MM-dd HH:mm:ss";
  81 +
  82 + public static LocalDateTime getCurrentTime() {
  83 + LocalDateTime now = LocalDateTime.now();
  84 + return now;
  85 + }
  86 +
  87 + public static Date getNextDay() {
  88 + LocalDateTime now = LocalDateTime.now();
  89 + LocalDateTime tomorrow = now.minusDays(-1);
  90 + return Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant());
  91 + }
  92 +
  93 + public static Date getAppointDay(Integer count) {
  94 + LocalDateTime now = LocalDateTime.now();
  95 + LocalDateTime tomorrow = now.minusDays(count);
  96 + return Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant());
  97 + }
  98 +
  99 + /**
  100 + * 获取年
  101 + *
  102 + * @return 年
  103 + */
  104 + public static int getYear() {
  105 + LocalDateTime localDateTime = LocalDateTime.now();
  106 + return localDateTime.get(ChronoField.YEAR);
  107 + }
  108 +
  109 + /**
  110 + * 获取月份
  111 + *
  112 + * @return 月份
  113 + */
  114 + public static int getMonth() {
  115 + LocalDateTime localDateTime = LocalDateTime.now();
  116 + return localDateTime.get(ChronoField.MONTH_OF_YEAR);
  117 + }
  118 +
  119 + /**
  120 + * 获取某月的第几天
  121 + *
  122 + * @return 几号
  123 + */
  124 + public static int getMonthOfDay() {
  125 + LocalDateTime localDateTime = LocalDateTime.now();
  126 + return localDateTime.get(ChronoField.DAY_OF_MONTH);
  127 + }
  128 +
  129 + /**
  130 + * 格式化日期为字符串
  131 + *
  132 + * @param date date
  133 + * @param pattern 格式
  134 + * @return 日期字符串
  135 + */
  136 + public static String formatOrElseBlank(Date date, String pattern) {
  137 + if (date == null || pattern == null) {
  138 + return "";
  139 + }
  140 + Instant instant = date.toInstant();
  141 +
  142 + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  143 +
  144 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  145 + }
  146 +
  147 + /**
  148 + * 格式化日期为字符串
  149 + *
  150 + * @param date date
  151 + * @param pattern 格式
  152 + * @return 日期字符串
  153 + */
  154 + public static String format(Date date, String pattern) {
  155 +
  156 + Instant instant = date.toInstant();
  157 +
  158 + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  159 +
  160 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  161 + }
  162 +
  163 + public static String formatNow(String pattern) {
  164 + LocalDateTime localDateTime = LocalDateTime.now();
  165 +
  166 + return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
  167 + }
  168 +
  169 +
  170 + public static String format(LocalDateTime date, String pattern) {
  171 + return date.format(DateTimeFormatter.ofPattern(pattern));
  172 + }
  173 +
  174 + public static String format(LocalDate date, String pattern) {
  175 + return date.format(DateTimeFormatter.ofPattern(pattern));
  176 + }
  177 +
  178 + /**
  179 + * 解析字符串日期为LocalDateTime
  180 + *
  181 + * @param dateStr 日期字符串
  182 + * @param pattern 格式
  183 + * @return Date
  184 + */
  185 + public static LocalDateTime parse(String dateStr, String pattern) {
  186 + return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
  187 + }
  188 +
  189 + /**
  190 + * 解析字符串日期为LocalDateTime
  191 + *
  192 + * @param dateStr 日期字符串
  193 + * @param pattern 格式
  194 + * @return Date
  195 + */
  196 + public static LocalDateTime parseStrByPattern(String dateStr, String pattern) {
  197 + try {
  198 + return parse(dateStr, pattern);
  199 + } catch (Exception e) {
  200 + return getCurrentTime();
  201 + }
  202 + }
  203 +
  204 + /**
  205 + * 解析字符串日期为LocalDate
  206 + *
  207 + * @param dateStr
  208 + * @param pattern
  209 + * @return
  210 + */
  211 + public static LocalDate parseDate(String dateStr, String pattern) {
  212 + return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
  213 + }
  214 +
  215 + /**
  216 + * @param dateTimeStr
  217 + * @param prePattern
  218 + * @param expectPattern
  219 + * @return
  220 + */
  221 + public static String format(String dateTimeStr, String prePattern, String expectPattern) {
  222 + LocalDateTime localDateTime = parseDate(dateTimeStr, prePattern).atStartOfDay();
  223 + return localDateTime.format(DateTimeFormatter.ofPattern(expectPattern));
  224 + }
  225 +
  226 + /**
  227 + * String -> Date
  228 + *
  229 + * @param date
  230 + * @return
  231 + */
  232 + public static Date parseStringToDate(String date, String pattern) {
  233 + SimpleDateFormat sdf = new SimpleDateFormat(pattern);
  234 + try {
  235 + return sdf.parse(date);
  236 + } catch (ParseException e) {
  237 + return null;
  238 + }
  239 + }
  240 +
  241 + /**
  242 + * 为Date增加分钟,减传负数
  243 + *
  244 + * @param date 日期
  245 + * @param plusMinutes 要增加的分钟数
  246 + * @return 新的日期
  247 + */
  248 + public static Date addMinutes(Date date, Long plusMinutes) {
  249 + LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
  250 + LocalDateTime newDateTime = dateTime.plusMinutes(plusMinutes);
  251 + return Date.from(newDateTime.atZone(ZoneId.systemDefault()).toInstant());
  252 + }
  253 +
  254 + /**
  255 + * 增加时间
  256 + *
  257 + * @param date date
  258 + * @param hour 要增加的小时数
  259 + * @return new date
  260 + */
  261 + public static Date addHour(Date date, Long hour) {
  262 + LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
  263 + LocalDateTime localDateTime = dateTime.plusHours(hour);
  264 + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  265 + }
  266 +
  267 + /**
  268 + * @return 返回当天的起始时间
  269 + */
  270 + public static Date getStartTime() {
  271 +
  272 + LocalDateTime now = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
  273 + return localDateTime2Date(now);
  274 + }
  275 +
  276 +
  277 + /**
  278 + * @return 返回当天的结束时间
  279 + */
  280 + public static Date getEndTime() {
  281 + LocalDateTime now = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
  282 + return localDateTime2Date(now);
  283 + }
  284 +
  285 + /**
  286 + * @return 获取入参当天结束时间
  287 + */
  288 + public static LocalDateTime getEndTime(LocalDate localDate) {
  289 + return localDate.atTime(23, 59, 59, 999999999);
  290 + }
  291 +
  292 + /**
  293 + * 减月份
  294 + *
  295 + * @param monthsToSubtract 月份
  296 + * @return Date
  297 + */
  298 + public static Date minusMonths(long monthsToSubtract) {
  299 + LocalDate localDate = LocalDate.now().minusMonths(monthsToSubtract);
  300 +
  301 + return localDate2Date(localDate);
  302 + }
  303 +
  304 + /**
  305 + * LocalDate类型转为Date
  306 + *
  307 + * @param localDate LocalDate object
  308 + * @return Date object
  309 + */
  310 + public static Date localDate2Date(LocalDate localDate) {
  311 +
  312 + ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
  313 +
  314 + return Date.from(zonedDateTime.toInstant());
  315 + }
  316 +
  317 + /**
  318 + * Date类型转为LocalDateTime
  319 + *
  320 + * @param date Date object
  321 + * @return localDate LocalDateTime
  322 + */
  323 + public static LocalDateTime date2LocalDateTime(Date date) {
  324 +
  325 + Instant instant = date.toInstant();
  326 + ZoneId zoneId = ZoneId.systemDefault();
  327 + LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
  328 + return localDateTime;
  329 + }
  330 +
  331 +
  332 + /**
  333 + * LocalDateTime类型转为Date
  334 + *
  335 + * @param localDateTime LocalDateTime object
  336 + * @return Date object
  337 + */
  338 + public static Date localDateTime2Date(LocalDateTime localDateTime) {
  339 + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  340 + }
  341 +
  342 + /**
  343 + * 查询当前年的第一天
  344 + *
  345 + * @param pattern 格式,默认格式yyyyMMdd
  346 + * @return 20190101
  347 + */
  348 + public static String getFirstDayOfCurrentYear(String pattern) {
  349 + LocalDateTime localDateTime = LocalDateTime.now().withMonth(1).withDayOfMonth(1);
  350 +
  351 + if (StringUtils.isEmpty(pattern)) {
  352 + pattern = "yyyyMMdd";
  353 + }
  354 +
  355 + return format(localDateTime2Date(localDateTime), pattern);
  356 + }
  357 +
  358 + /**
  359 + * 查询前一年最后一个月第一天
  360 + *
  361 + * @param pattern 格式,默认格式yyyyMMdd
  362 + * @return 20190101
  363 + */
  364 + public static String getLastMonthFirstDayOfPreviousYear(String pattern) {
  365 + LocalDateTime localDateTime = LocalDateTime.now().minusYears(1L).withMonth(12).withDayOfMonth(1);
  366 +
  367 + if (StringUtils.isEmpty(pattern)) {
  368 + pattern = "yyyyMMdd";
  369 + }
  370 +
  371 + return format(localDateTime2Date(localDateTime), pattern);
  372 + }
  373 +
  374 + /**
  375 + * 查询前一年最后一个月第一天
  376 + *
  377 + * @param pattern 格式,默认格式yyyyMMdd
  378 + * @return 20190101
  379 + */
  380 + public static String getLastMonthLastDayOfPreviousYear(String pattern) {
  381 + LocalDateTime localDateTime = LocalDateTime.now().minusYears(1L).with(TemporalAdjusters.lastDayOfYear());
  382 +
  383 + if (StringUtils.isEmpty(pattern)) {
  384 + pattern = "yyyyMMdd";
  385 + }
  386 +
  387 + return format(localDateTime2Date(localDateTime), pattern);
  388 + }
  389 +
  390 + /**
  391 + * 获取当前日期
  392 + *
  393 + * @param pattern 格式,默认格式yyyyMMdd
  394 + * @return 20190101
  395 + */
  396 + public static String getCurrentDay(String pattern) {
  397 + LocalDateTime localDateTime = LocalDateTime.now();
  398 +
  399 + if (StringUtils.isEmpty(pattern)) {
  400 + pattern = "yyyyMMdd";
  401 + }
  402 +
  403 + return format(localDateTime2Date(localDateTime), pattern);
  404 + }
  405 +
  406 + public static String getTransitionTime(LocalDateTime time, String pattern) {
  407 + if (StringUtils.isEmpty(pattern)) {
  408 + pattern = "yyyyMMdd";
  409 + }
  410 + return format(localDateTime2Date(time), pattern);
  411 + }
  412 +
  413 +
  414 + /**
  415 + * 用于判断两个时间段有没有重合, 重合: true,未重合: false
  416 + *
  417 + * @param aStartTime
  418 + * @param aEndTime
  419 + * @param bStartTime
  420 + * @param bEndTime
  421 + * @return
  422 + * @author A80068
  423 + */
  424 + public static boolean judgeTimeSlotCoincidence(LocalDateTime aStartTime, LocalDateTime aEndTime, LocalDateTime bStartTime, LocalDateTime bEndTime) {
  425 + /**
  426 + * 旧版
  427 + */
  428 + //boolean flag;
  429 + //if(aStartTime.isAfter(bStartTime)){
  430 + // if (aStartTime.isBefore(bEndTime) || aStartTime.isEqual(bEndTime)){
  431 + // flag = true;
  432 + // }else{
  433 + // flag = false;
  434 + // }
  435 + //}else if(aStartTime.isBefore(bStartTime)){
  436 + // if(aEndTime.isAfter(bStartTime) || aEndTime.isEqual(bStartTime)){
  437 + // flag = true;
  438 + // }else{
  439 + // flag = false;
  440 + // }
  441 + //}else{
  442 + // flag = true;
  443 + //}
  444 + //return flag;
  445 + /**
  446 + * 优化版
  447 + */
  448 + boolean flag = false;
  449 + if ((aStartTime.isBefore(bEndTime) || aStartTime.isEqual(bEndTime))) {
  450 + if ((aEndTime.isAfter(bStartTime)) || aEndTime.isEqual(bStartTime)) {
  451 + flag = true;
  452 + }
  453 + }
  454 + return flag;
  455 + }
  456 +
  457 + /**
  458 + * @param aStartTimeStr
  459 + * @param aEndTimeStr
  460 + * @param bStartTimeStr
  461 + * @param bEndTimeStr
  462 + * @return
  463 + * @author A80068
  464 + */
  465 + public static boolean judgeTimeSlotCoincidenceString(String aStartTimeStr, String aEndTimeStr, String bStartTimeStr, String bEndTimeStr) {
  466 +
  467 + LocalDateTime aStartTime = parse(aStartTimeStr, DATE_TIME);
  468 + LocalDateTime aEndTime = parse(aEndTimeStr, DATE_TIME);
  469 + LocalDateTime bStartTime = parse(bStartTimeStr, DATE_TIME);
  470 + LocalDateTime bEndTime = parse(bEndTimeStr, DATE_TIME);
  471 +
  472 + return judgeTimeSlotCoincidence(aStartTime, aEndTime, bStartTime, bEndTime);
  473 + }
  474 +
  475 + /**
  476 + * @param strGMT
  477 + * @return
  478 + * @throws ParseException
  479 + * @throws ParseException
  480 + */
  481 + public static Date getCST(String strGMT) throws ParseException, ParseException {
  482 + DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
  483 + return df.parse(strGMT);
  484 + }
  485 +
  486 + /**
  487 + * @param dateCST
  488 + * @return
  489 + */
  490 + public static Date getGMT(Date dateCST) throws ParseException {
  491 + DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
  492 + df.setTimeZone(TimeZone.getTimeZone("GMT")); // modify Time Zone.
  493 + return df.parse(df.format(dateCST));
  494 + }
  495 +
  496 + /**
  497 + * LocalDateTime转化为cron表达式
  498 + *
  499 + * @param dateTime
  500 + * @return
  501 + */
  502 + public static String dateToCron(LocalDateTime dateTime) {
  503 + if (dateTime == null) {
  504 + return "";
  505 + }
  506 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy");
  507 + return formatter.format(dateTime);
  508 + }
  509 +
  510 + /**
  511 + * cron表达式转为LocalDateTime
  512 + *
  513 + * @param cron
  514 + * @return
  515 + */
  516 + public static LocalDateTime cronToDate(String cron) {
  517 + if (StringUtils.isNotBlank(cron)) {
  518 + return null;
  519 + }
  520 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy");
  521 + return LocalDateTime.parse(cron, formatter);
  522 + }
  523 +
  524 + public static String timeToString(long time) {
  525 + DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  526 + return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
  527 + }
  528 +
  529 + public static String timeToString(String time) {
  530 + try {
  531 + return timeToString(Long.parseLong(time));
  532 + } catch (Exception e) {
  533 + }
  534 + return time;
  535 + }
  536 +
  537 + /**
  538 + * 比较时间大小
  539 + *
  540 + * @param date1
  541 + * @param date2
  542 + * @return
  543 + */
  544 + public static int compareDate(Date date1, Date date2) {
  545 + if (date1 == null || date2 == null) {
  546 + return -2;
  547 + }
  548 + if (date1.getTime() < date2.getTime()) {
  549 + return -1;
  550 + } else if (date1.getTime() > date2.getTime()) {
  551 + return 1;
  552 + }
  553 + return 0;
  554 + }
  555 +
  556 + /**
  557 + * 判斷两个时间是否在同一分钟
  558 + */
  559 + public static boolean isMinuteIdentical(LocalDateTime date1, LocalDateTime date2) {
  560 + return date1.getYear() == date2.getYear() && date1.getMonth() == date2.getMonth() && date1.getMinute() == date2.getMinute();
  561 + }
  562 +
  563 + /**
  564 + * 时区
  565 + */
  566 + public static class Zone {
  567 + public static final String GMT8 = "GMT+8";
  568 + }
  569 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/EncryptUtils.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/EncryptUtils.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +import javax.crypto.Cipher;
  4 +import javax.crypto.SecretKey;
  5 +import javax.crypto.SecretKeyFactory;
  6 +import javax.crypto.spec.DESKeySpec;
  7 +import javax.crypto.spec.IvParameterSpec;
  8 +import java.nio.charset.StandardCharsets;
  9 +
  10 +/**
  11 + * 加密
  12 + *
  13 + * @date 2018-11-23
  14 + */
  15 +public class EncryptUtils {
  16 +
  17 + private static String strParam = "Passw0rd";
  18 +
  19 + private static Cipher cipher;
  20 +
  21 + private static IvParameterSpec iv = new IvParameterSpec(strParam.getBytes(StandardCharsets.UTF_8));
  22 +
  23 + private static DESKeySpec getDesKeySpec(String source) throws Exception {
  24 + if (source == null || source.length() == 0) {
  25 + return null;
  26 + }
  27 + cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
  28 + String strKey = "Passw0rd";
  29 + return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8));
  30 + }
  31 +
  32 + /**
  33 + * 对称加密
  34 + */
  35 + public static String desEncrypt(String source) throws Exception {
  36 + DESKeySpec desKeySpec = getDesKeySpec(source);
  37 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  38 + SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
  39 + cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
  40 + return byte2hex(
  41 + cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase();
  42 + }
  43 +
  44 + /**
  45 + * 对称解密
  46 + */
  47 + public static String desDecrypt(String source) throws Exception {
  48 + byte[] src = hex2byte(source.getBytes());
  49 + DESKeySpec desKeySpec = getDesKeySpec(source);
  50 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  51 + SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
  52 + cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
  53 + byte[] retByte = cipher.doFinal(src);
  54 + return new String(retByte);
  55 + }
  56 +
  57 + private static String byte2hex(byte[] inStr) {
  58 + String stmp;
  59 + StringBuilder out = new StringBuilder(inStr.length * 2);
  60 + for (byte b : inStr) {
  61 + stmp = Integer.toHexString(b & 0xFF);
  62 + if (stmp.length() == 1) {
  63 + // 如果是0至F的单位字符串,则添加0
  64 + out.append("0").append(stmp);
  65 + } else {
  66 + out.append(stmp);
  67 + }
  68 + }
  69 + return out.toString();
  70 + }
  71 +
  72 + private static byte[] hex2byte(byte[] b) {
  73 + int size = 2;
  74 + if ((b.length % size) != 0) {
  75 + throw new IllegalArgumentException("长度不是偶数");
  76 + }
  77 + byte[] b2 = new byte[b.length / 2];
  78 + for (int n = 0; n < b.length; n += size) {
  79 + String item = new String(b, n, 2);
  80 + b2[n / 2] = (byte) Integer.parseInt(item, 16);
  81 + }
  82 + return b2;
  83 + }
  84 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/FileUtil.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/FileUtil.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +import cn.hutool.core.codec.Base64;
  4 +import cn.hutool.core.io.IoUtil;
  5 +import cn.hutool.core.util.IdUtil;
  6 +import cn.hutool.poi.excel.BigExcelWriter;
  7 +import cn.hutool.poi.excel.ExcelUtil;
  8 +import org.apache.poi.util.IOUtils;
  9 +import org.springframework.web.multipart.MultipartFile;
  10 +
  11 +import javax.activation.MimetypesFileTypeMap;
  12 +import javax.servlet.ServletOutputStream;
  13 +import javax.servlet.http.HttpServletRequest;
  14 +import javax.servlet.http.HttpServletResponse;
  15 +import java.io.*;
  16 +import java.security.MessageDigest;
  17 +import java.text.DecimalFormat;
  18 +import java.text.SimpleDateFormat;
  19 +import java.util.Date;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
  23 +/**
  24 + * File工具类,扩展 hutool 工具包
  25 + *
  26 + * @date 2018-12-27
  27 + */
  28 +public class FileUtil extends cn.hutool.core.io.FileUtil {
  29 +
  30 + /**
  31 + * 定义GB的计算常量
  32 + */
  33 + private static final int GB = 1024 * 1024 * 1024;
  34 + /**
  35 + * 定义MB的计算常量
  36 + */
  37 + private static final int MB = 1024 * 1024;
  38 + /**
  39 + * 定义KB的计算常量
  40 + */
  41 + private static final int KB = 1024;
  42 +
  43 + /**
  44 + * 格式化小数
  45 + */
  46 + private static final DecimalFormat DF = new DecimalFormat("0.00");
  47 +
  48 + /**
  49 + * MultipartFile转File
  50 + */
  51 + public static File toFile(MultipartFile multipartFile) {
  52 + // 获取文件名
  53 + String fileName = multipartFile.getOriginalFilename();
  54 + // 获取文件后缀
  55 + String prefix = "." + getExtensionName(fileName);
  56 + File file = null;
  57 + try {
  58 + // 用uuid作为文件名,防止生成的临时文件重复
  59 + file = File.createTempFile(IdUtil.simpleUUID(), prefix);
  60 + // MultipartFile to File
  61 + multipartFile.transferTo(file);
  62 + } catch (IOException e) {
  63 + e.printStackTrace();
  64 + }
  65 + return file;
  66 + }
  67 +
  68 + /**
  69 + * 获取文件扩展名,不带 .
  70 + */
  71 + public static String getExtensionName(String filename) {
  72 + if ((filename != null) && (filename.length() > 0)) {
  73 + int dot = filename.lastIndexOf('.');
  74 + if ((dot > -1) && (dot < (filename.length() - 1))) {
  75 + return filename.substring(dot + 1);
  76 + }
  77 + }
  78 + return filename;
  79 + }
  80 +
  81 + /**
  82 + * Java文件操作 获取不带扩展名的文件名
  83 + */
  84 + public static String getFileNameNoEx(String filename) {
  85 + if ((filename != null) && (filename.length() > 0)) {
  86 + int dot = filename.lastIndexOf('.');
  87 + if ((dot > -1) && (dot < (filename.length()))) {
  88 + return filename.substring(0, dot);
  89 + }
  90 + }
  91 + return filename;
  92 + }
  93 +
  94 + /**
  95 + * 文件大小转换
  96 + */
  97 + public static String getSize(long size) {
  98 + String resultSize;
  99 + if (size / GB >= 1) {
  100 + //如果当前Byte的值大于等于1GB
  101 + resultSize = DF.format(size / (float) GB) + "GB ";
  102 + } else if (size / MB >= 1) {
  103 + //如果当前Byte的值大于等于1MB
  104 + resultSize = DF.format(size / (float) MB) + "MB ";
  105 + } else if (size / KB >= 1) {
  106 + //如果当前Byte的值大于等于1KB
  107 + resultSize = DF.format(size / (float) KB) + "KB ";
  108 + } else {
  109 + resultSize = size + "B ";
  110 + }
  111 + return resultSize;
  112 + }
  113 +
  114 + /**
  115 + * inputStream 转 File
  116 + */
  117 + public static File inputStreamToFile(InputStream ins, String name) throws Exception {
  118 + File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
  119 + if (file.exists()) {
  120 + return file;
  121 + }
  122 + OutputStream os = new FileOutputStream(file);
  123 + int bytesRead;
  124 + int len = 8192;
  125 + byte[] buffer = new byte[len];
  126 + while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
  127 + os.write(buffer, 0, bytesRead);
  128 + }
  129 + os.close();
  130 + ins.close();
  131 + return file;
  132 + }
  133 +
  134 + /**
  135 + * 将文件转换为byte数组,作为图片数据导入
  136 + *
  137 + * @param file
  138 + * @return byte[]
  139 + */
  140 + public static byte[] imageParseBytes(File file) {
  141 + FileInputStream fileInputStream = null;
  142 + try {
  143 + fileInputStream = new FileInputStream(file);
  144 + } catch (FileNotFoundException e) {
  145 + e.printStackTrace();
  146 + }
  147 + return imageParseBytes(fileInputStream);
  148 + }
  149 +
  150 + /**
  151 + * 将流转换为byte数组,作为图片数据导入
  152 + *
  153 + * @param fis
  154 + * @return byte[]
  155 + */
  156 + public static byte[] imageParseBytes(InputStream fis) {
  157 + byte[] buffer = null;
  158 + ByteArrayOutputStream bos = null;
  159 + try {
  160 + bos = new ByteArrayOutputStream(1024);
  161 + byte[] b = new byte[1024];
  162 + int n;
  163 + while ((n = fis.read(b)) != -1) {
  164 + bos.write(b, 0, n);
  165 + }
  166 + buffer = bos.toByteArray();
  167 + } catch (Exception e) {
  168 + e.printStackTrace();
  169 + } finally {
  170 + try {
  171 + fis.close();
  172 + bos.close();
  173 + } catch (IOException e) {
  174 + e.printStackTrace();
  175 + }
  176 + }
  177 + return buffer;
  178 + }
  179 +
  180 + /**
  181 + * 将文件名解析成文件的上传路径
  182 + */
  183 + public static File upload(MultipartFile file, String filePath) {
  184 + Date date = new Date();
  185 + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
  186 + String name = getFileNameNoEx(file.getOriginalFilename());
  187 + String suffix = getExtensionName(file.getOriginalFilename());
  188 + String nowStr = "-" + format.format(date);
  189 + try {
  190 + String fileName = name + nowStr + "." + suffix;
  191 + String path = filePath + fileName;
  192 + // getCanonicalFile 可解析正确各种路径
  193 + File dest = new File(path).getCanonicalFile();
  194 + // 检测是否存在目录
  195 + if (!dest.getParentFile().exists()) {
  196 + dest.getParentFile().mkdirs();
  197 + }
  198 + // 文件写入
  199 + file.transferTo(dest);
  200 + return dest;
  201 + } catch (Exception e) {
  202 + e.printStackTrace();
  203 + }
  204 + return null;
  205 + }
  206 +
  207 + public static String fileToBase64(File file) throws Exception {
  208 + FileInputStream inputFile = new FileInputStream(file);
  209 + String base64;
  210 + byte[] buffer = new byte[(int) file.length()];
  211 + inputFile.read(buffer);
  212 + inputFile.close();
  213 + base64 = Base64.encode(buffer);
  214 + return base64.replaceAll("[\\s*\t\n\r]", "");
  215 + }
  216 +
  217 + /**
  218 + * 导出excel
  219 + */
  220 + public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
  221 + String tempPath = System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx";
  222 + File file = new File(tempPath);
  223 + BigExcelWriter writer = ExcelUtil.getBigWriter(file);
  224 + // 一次性写出内容,使用默认样式,强制输出标题
  225 + writer.write(list, true);
  226 + //response为HttpServletResponse对象
  227 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  228 + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
  229 + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
  230 + ServletOutputStream out = response.getOutputStream();
  231 + // 终止后删除临时文件
  232 + file.deleteOnExit();
  233 + writer.flush(out, true);
  234 + //此处记得关闭输出Servlet流
  235 + IoUtil.close(out);
  236 + }
  237 +
  238 + public static String getFileType(String type) {
  239 + String documents = "txt doc pdf ppt pps xlsx xls docx";
  240 + String music = "mp3 wav wma mpa ram ra aac aif m4a";
  241 + String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
  242 + String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
  243 + if (image.contains(type)) {
  244 + return "images";
  245 + } else if (documents.contains(type)) {
  246 + return "docs";
  247 + } else if (music.contains(type)) {
  248 + return "musics";
  249 + } else if (video.contains(type)) {
  250 + return "videos";
  251 + } else {
  252 + return "others";
  253 + }
  254 + }
  255 +
  256 + public static String getFileTypeByMimeType(String type) {
  257 + String mimeType = new MimetypesFileTypeMap().getContentType("." + type);
  258 + return mimeType.split("/")[0];
  259 + }
  260 +
  261 + public static void checkSize(long maxSize, long size) {
  262 + // 1M
  263 + int len = 1024 * 1024;
  264 + if (size > (maxSize * len)) {
  265 + throw new RuntimeException("文件超出规定大小");
  266 + }
  267 + }
  268 +
  269 + /**
  270 + * 判断两个文件是否相同
  271 + */
  272 + public static boolean check(File file1, File file2) {
  273 + String img1Md5 = getMd5(file1);
  274 + String img2Md5 = getMd5(file2);
  275 + return img1Md5.equals(img2Md5);
  276 + }
  277 +
  278 + /**
  279 + * 判断两个文件是否相同
  280 + */
  281 + public static boolean check(String file1Md5, String file2Md5) {
  282 + return file1Md5.equals(file2Md5);
  283 + }
  284 +
  285 + private static byte[] getByte(File file) {
  286 + // 得到文件长度
  287 + byte[] b = new byte[(int) file.length()];
  288 + try {
  289 + InputStream in = new FileInputStream(file);
  290 + try {
  291 + in.read(b);
  292 + } catch (IOException e) {
  293 + e.printStackTrace();
  294 + }
  295 + } catch (FileNotFoundException e) {
  296 + e.printStackTrace();
  297 + return null;
  298 + }
  299 + return b;
  300 + }
  301 +
  302 + private static String getMd5(byte[] bytes) {
  303 + // 16进制字符
  304 + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  305 + try {
  306 + MessageDigest mdTemp = MessageDigest.getInstance("MD5");
  307 + mdTemp.update(bytes);
  308 + byte[] md = mdTemp.digest();
  309 + int j = md.length;
  310 + char[] str = new char[j * 2];
  311 + int k = 0;
  312 + // 移位 输出字符串
  313 + for (byte byte0 : md) {
  314 + str[k++] = hexDigits[byte0 >>> 4 & 0xf];
  315 + str[k++] = hexDigits[byte0 & 0xf];
  316 + }
  317 + return new String(str);
  318 + } catch (Exception e) {
  319 + e.printStackTrace();
  320 + }
  321 + return null;
  322 + }
  323 +
  324 + /**
  325 + * 下载文件
  326 + *
  327 + * @param request /
  328 + * @param response /
  329 + * @param file /
  330 + */
  331 + public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {
  332 + response.setCharacterEncoding(request.getCharacterEncoding());
  333 + response.setContentType("application/octet-stream");
  334 + FileInputStream fis = null;
  335 + try {
  336 + fis = new FileInputStream(file);
  337 + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
  338 + IOUtils.copy(fis, response.getOutputStream());
  339 + response.flushBuffer();
  340 + } catch (Exception e) {
  341 + e.printStackTrace();
  342 + } finally {
  343 + if (fis != null) {
  344 + try {
  345 + fis.close();
  346 + if (deleteOnExit) {
  347 + file.deleteOnExit();
  348 + }
  349 + } catch (IOException e) {
  350 + e.printStackTrace();
  351 + }
  352 + }
  353 + }
  354 + }
  355 +
  356 + public static String getMd5(File file) {
  357 + return getMd5(getByte(file));
  358 + }
  359 +
  360 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/JsonUtil.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/JsonUtil.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +
  4 +import com.alibaba.fastjson.JSONException;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.fasterxml.jackson.annotation.JsonInclude;
  7 +import com.fasterxml.jackson.core.JsonGenerator;
  8 +import com.fasterxml.jackson.core.JsonProcessingException;
  9 +import com.fasterxml.jackson.core.type.TypeReference;
  10 +import com.fasterxml.jackson.databind.*;
  11 +import com.fasterxml.jackson.databind.node.ArrayNode;
  12 +import com.fasterxml.jackson.databind.node.ObjectNode;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +
  15 +import java.io.IOException;
  16 +
  17 +/**
  18 + *
  19 + * @author achims
  20 + * @date 2019/11/4
  21 + * 用于转换成json字符串以及解析成对象
  22 + */
  23 +@Slf4j
  24 +public class JsonUtil {
  25 +
  26 + private static ObjectMapper mapper = new ObjectMapper();
  27 +
  28 + static {
  29 + log.info("注册jackson-datatype-jsr310的java8时间处理模块");
  30 + mapper.findAndRegisterModules();
  31 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  32 + mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
  33 + @Override
  34 + public void serialize(Object paramT, JsonGenerator paramJsonGenerator,
  35 + SerializerProvider paramSerializerProvider) throws IOException {
  36 + //设置返回null转为 空字符串""
  37 + paramJsonGenerator.writeString("");
  38 + }
  39 + });
  40 + }
  41 +
  42 +
  43 +
  44 +
  45 + /**
  46 + * Create empty json node
  47 + *
  48 + * @return
  49 + */
  50 + public static ObjectNode createJsonNode() {
  51 + return mapper.createObjectNode();
  52 + }
  53 +
  54 + /**
  55 + * Create empty json Array
  56 + *
  57 + * @return
  58 + */
  59 + public static ArrayNode createJsonArray() {
  60 + return mapper.createArrayNode();
  61 +
  62 + }
  63 +
  64 + /**
  65 + * Convert the object to corresponding json string
  66 + *
  67 + * @param obj
  68 + * @return
  69 + */
  70 + public static String toJsonString(Object obj) {
  71 + try {
  72 + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
  73 + return mapper.writeValueAsString(obj);
  74 + } catch (JsonProcessingException e) {
  75 + return null;
  76 + }
  77 + }
  78 +
  79 + /**
  80 + * 转成格式化后的json,便于调试排错
  81 + * @param obj
  82 + * @return
  83 + */
  84 + public static String toJsonStringWithDefaultPretty(Object obj) {
  85 + try {
  86 + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
  87 + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
  88 + } catch (JsonProcessingException e) {
  89 +
  90 + return null;
  91 + }
  92 + }
  93 +
  94 + public static <T> T jsonToEntity(String json, Class<T> clazz) {
  95 + if (StringUtils.isEmpty(json)) return null;
  96 + try {
  97 + return mapper.readValue(json, clazz);
  98 + } catch (IOException e) {
  99 + e.printStackTrace();
  100 + }
  101 + return null;
  102 + }
  103 +
  104 + /**
  105 + * 借助json做中转,实体类转实体类
  106 + * @param obj 实体
  107 + * @param clazz 目标类型
  108 + * @param <T> 目标泛型
  109 + * @return 结果
  110 + */
  111 + public static <T> T entityConvert(Object obj, Class<T> clazz) {
  112 + return jsonToEntity(toJsonString(obj), clazz);
  113 + }
  114 +
  115 + /**
  116 + * 带泛型返回不告警
  117 + * @param json json字符
  118 + * @param typeReference TypeReference
  119 + * @param <R> 返回类型
  120 + * @param <T> 转换的类型
  121 + * @return 转换结果
  122 + * @author 刘迪榕
  123 + * @version Date 2022-08-26
  124 + */
  125 + public static <R, T extends R> R jsonToEntity(String json, TypeReference<T> typeReference) {
  126 + if (StringUtils.isEmpty(json)) return null;
  127 + try {
  128 + return mapper.readValue(json, typeReference);
  129 + } catch (IOException e) {
  130 + e.printStackTrace();
  131 + }
  132 + return null;
  133 + }
  134 +
  135 + public static JsonNode readStringAsJsonNode(String json) {
  136 + try {
  137 + return mapper.readValue(json, JsonNode.class);
  138 + } catch (IOException e) {
  139 + e.printStackTrace();
  140 + }
  141 + return null;
  142 + }
  143 +
  144 + public static JsonNode valueToTree(Object value) {
  145 + return mapper.valueToTree(value);
  146 + }
  147 +
  148 + public static <T> T treeToValue(JsonNode jsonNode, Class<T> clazz) {
  149 + try {
  150 + return mapper.treeToValue(jsonNode, clazz);
  151 + } catch (IOException e) {
  152 + e.printStackTrace();
  153 + }
  154 + return null;
  155 + }
  156 +
  157 + /**
  158 + * 是否爲json格式的數據
  159 + *
  160 + * @param test
  161 + * @return
  162 + */
  163 + public final static boolean isJSONValid(String test) {
  164 + try {
  165 + JSONObject.parseObject(test);
  166 + } catch (JSONException ex) {
  167 + try {
  168 + JSONObject.parseArray(test);
  169 + } catch (JSONException ex1) {
  170 + return false;
  171 + }
  172 + }
  173 + return true;
  174 + }
  175 +
  176 + public <T> T paraseJsonTOClass(String json, Class<T> cla) {
  177 + try {
  178 + return JSONObject.parseObject(json, cla);
  179 + } catch (JSONException ex) {
  180 + return null;
  181 + }
  182 + }
  183 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/LocalDateTimeUtil.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/LocalDateTimeUtil.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +import org.joda.time.DateTime;
  4 +
  5 +import java.time.LocalDateTime;
  6 +
  7 +/**
  8 + * @author: xms
  9 + * @description: TODO
  10 + * @date: 2023/1/16 16:35
  11 + * @version: 1.0
  12 + */
  13 +public class LocalDateTimeUtil {
  14 +
  15 + /**
  16 + * @param dateTime
  17 + * @return
  18 + */
  19 + public static LocalDateTime toLocalDateTime(DateTime dateTime) {
  20 + return LocalDateTime.of(dateTime.getYear(), dateTime.getMonthOfYear(),
  21 + dateTime.getDayOfMonth(), dateTime.getHourOfDay(),
  22 + dateTime.getMinuteOfHour(), dateTime.getSecondOfMinute());
  23 + }
  24 +
  25 + /**
  26 + *
  27 + * @param localDateTime
  28 + * @return
  29 + */
  30 + public static DateTime toDateTime(LocalDateTime localDateTime) {
  31 + return new DateTime().withYear(localDateTime.getYear()).withMonthOfYear(localDateTime.getMonthValue())
  32 + .withDayOfMonth(localDateTime.getDayOfMonth()).withHourOfDay(localDateTime.getHour())
  33 + .withMinuteOfHour(localDateTime.getMinute()).withSecondOfMinute(localDateTime.getSecond());
  34 + }
  35 +}
... ...
src/main/java/com/canrd/webmagic/common/utils/PageUtils.java 0 → 100644
  1 +++ a/src/main/java/com/canrd/webmagic/common/utils/PageUtils.java
  1 +package com.canrd.webmagic.common.utils;
  2 +
  3 +import com.baomidou.mybatisplus.core.metadata.IPage;
  4 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5 +import com.canrd.webmagic.domain.vo.BasePageVO;
  6 +import org.springframework.util.CollectionUtils;
  7 +
  8 +import java.io.Serializable;
  9 +import java.util.*;
  10 +
  11 +/**
  12 + * @Author: dengbin
  13 + * @Date: 2020/9/11
  14 + * 分页工具类
  15 + */
  16 +
  17 +public class PageUtils implements Serializable {
  18 + private static final long serialVersionUID = 4359709211352400087L;
  19 + private static final String PAGE_INDEX = "pageNo";
  20 + private static final String PAGE_SIZE = "pageSize";
  21 + private static final String TOTAL_ROWS = "total";
  22 + private static final String TOTAL_PAGES = "pages";
  23 + private static final String RECORDS = "records";
  24 +
  25 + private static final int DEFAULT_PAGE_INDEX = 1;
  26 + private static final int DEFAULT_PAGE_SIZE = 10;
  27 + private static final int DEFAULT_MAP_CAPACITY = 5;
  28 +
  29 + /**
  30 + * 统一分页返回对象
  31 + *
  32 + * @param list
  33 + * @return
  34 + */
  35 + public static Map<String, Object> getUnifiedPageReturn(IPage list) {
  36 + if (list == null) {
  37 + return getUnifiedEmptyPage(DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE);
  38 + }
  39 +
  40 + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY);
  41 + resultMap.put(PAGE_INDEX, list.getCurrent());
  42 + resultMap.put(PAGE_SIZE, list.getSize());
  43 + resultMap.put(RECORDS, list.getRecords());
  44 + resultMap.put(TOTAL_PAGES, list.getPages());
  45 + resultMap.put(TOTAL_ROWS, list.getTotal());
  46 +
  47 + return resultMap;
  48 + }
  49 +
  50 + /**
  51 + * 返回空分页信息给前端
  52 + * 返回空或其他字段不满足前端要求,会报错
  53 + *
  54 + * @return
  55 + */
  56 + public static Map<String, Object> getUnifiedEmptyPage(int pageIndex, int pageSize) {
  57 + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY);
  58 + resultMap.put(PAGE_INDEX, pageIndex);
  59 + resultMap.put(PAGE_SIZE, pageSize);
  60 + resultMap.put(RECORDS, new ArrayList<>());
  61 + resultMap.put(TOTAL_PAGES, 0);
  62 + resultMap.put(TOTAL_ROWS, 0);
  63 + return resultMap;
  64 + }
  65 +
  66 + public static Map<String, Object> getUnifiedEmptyPage(BasePageVO pageVO) {
  67 + return getUnifiedEmptyPage(pageVO.getCurrent(), pageVO.getSize());
  68 + }
  69 +
  70 +
  71 + /**
  72 + * 将旧的分页转换成新的分页对象
  73 + *
  74 + * @param oldPage 旧的分页对象,例如:xxDo的分页对象
  75 + * @param records 新的分页对象,例如:xxVo的分页对象
  76 + * @param <T> 新的分页对象的类型
  77 + * @return 统一的返回的分页对象
  78 + */
  79 + public static <T> Map<String, Object> transferPage(IPage<?> oldPage, List<T> records) {
  80 + Page<T> newPage = new Page<>();
  81 + newPage.setCurrent(oldPage.getCurrent());
  82 + newPage.setSize(oldPage.getSize());
  83 + newPage.setRecords(records);
  84 + newPage.setPages(oldPage.getPages());
  85 + newPage.setTotal(oldPage.getTotal());
  86 + return getUnifiedPageReturn(newPage);
  87 + }
  88 +
  89 + /**
  90 + * 统一分页返回对象
  91 + *
  92 + * @param records 分页数据
  93 + * @param pageVO 分页参数
  94 + * @return
  95 + */
  96 + public static Map<String, Object> getPageReturn(List records, BasePageVO pageVO) {
  97 + if (records == null) {
  98 + return getUnifiedEmptyPage(DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE);
  99 + }
  100 + if (CollectionUtils.isEmpty(records)) {
  101 + return getUnifiedEmptyPage(Math.toIntExact(pageVO.getCurrent()), Math.toIntExact(pageVO.getSize()));
  102 + }
  103 + Map<String, Object> resultMap = new HashMap<>(DEFAULT_MAP_CAPACITY);
  104 + resultMap.put(PAGE_INDEX, pageVO.getCurrent());
  105 + resultMap.put(PAGE_SIZE, pageVO.getSize());
  106 + resultMap.put(RECORDS, records);
  107 + resultMap.put(TOTAL_PAGES, (pageVO.getTotal() + pageVO.getSize() - 1) / pageVO.getSize());
  108 + resultMap.put(TOTAL_ROWS, pageVO.getTotal());
  109 +
  110 + return resultMap;
  111 + }
  112 +
  113 + public static <T> Page<T> getRAMPageReturn(Integer current, Integer size, List<T> records) {
  114 + if (Objects.isNull(current)) {
  115 + current = 1;
  116 + }
  117 + if (Objects.isNull(size)) {
  118 + size = 10;
  119 + }
  120 + int startIndex = (current - 1) * size;
  121 + int endIndex = Math.min(current * size, records.size());
  122 + if (startIndex > endIndex) {
  123 + startIndex = endIndex;
  124 + }
  125 + Page<T> page = new Page<>();
  126 + page.setCurrent(current);
  127 + page.setSize(size);
  128 + page.setRecords(records.subList(startIndex, endIndex));
  129 + int totalPages = size == 0 ? 0 : records.size() % size == 0 ? (records.size() / size) : (records.size() / size + 1);
  130 + page.setPages(totalPages);
  131 + page.setTotal(records.size());
  132 + return page;
  133 + }
  134 +
  135 +
  136 +}
... ...