Browse Source

初始化提交

zsy 3 days ago
commit
992f140cc6
52 changed files with 4157 additions and 0 deletions
  1. 20 0
      .gitignore
  2. 3 0
      README.md
  3. 104 0
      build.gradle
  4. 234 0
      gradlew
  5. 89 0
      gradlew.bat
  6. 57 0
      src/main/java/com/rf/conversion/FileConversionApplication.java
  7. 46 0
      src/main/java/com/rf/conversion/base/model/BaseEntity.java
  8. 18 0
      src/main/java/com/rf/conversion/base/repository/BaseRepository.java
  9. 76 0
      src/main/java/com/rf/conversion/base/rest/BaseController.java
  10. 30 0
      src/main/java/com/rf/conversion/config/CorsConfig.java
  11. 22 0
      src/main/java/com/rf/conversion/config/Properties.java
  12. 87 0
      src/main/java/com/rf/conversion/config/RedisConfig.java
  13. 51 0
      src/main/java/com/rf/conversion/config/Swagger2Config.java
  14. 18 0
      src/main/java/com/rf/conversion/dao/dto/JpaDto.java
  15. 21 0
      src/main/java/com/rf/conversion/dao/dto/ProgressDto.java
  16. 2 0
      src/main/java/com/rf/conversion/dao/lombok.config
  17. 92 0
      src/main/java/com/rf/conversion/filter/AuthenticationInterceptor.java
  18. 62 0
      src/main/java/com/rf/conversion/filter/JWTInterceptor.java
  19. 49 0
      src/main/java/com/rf/conversion/filter/JWTInterceptorConfig.java
  20. 12 0
      src/main/java/com/rf/conversion/filter/JwtIgnore.java
  21. 67 0
      src/main/java/com/rf/conversion/security/SSLConfig.java
  22. 18 0
      src/main/java/com/rf/conversion/security/SafetyProcess.java
  23. 42 0
      src/main/java/com/rf/conversion/user/dao/model/UserConversionEntity.java
  24. 42 0
      src/main/java/com/rf/conversion/user/dao/model/UserEntity.java
  25. 19 0
      src/main/java/com/rf/conversion/user/dao/repository/UserConversionRepository.java
  26. 15 0
      src/main/java/com/rf/conversion/user/dao/repository/UserRepository.java
  27. 202 0
      src/main/java/com/rf/conversion/user/rest/UserController.java
  28. 48 0
      src/main/java/com/rf/conversion/user/rest/UserConversionController.java
  29. 17 0
      src/main/java/com/rf/conversion/user/service/UserConversionService.java
  30. 18 0
      src/main/java/com/rf/conversion/user/service/UserService.java
  31. 33 0
      src/main/java/com/rf/conversion/user/service/impl/UserConversionServiceImpl.java
  32. 36 0
      src/main/java/com/rf/conversion/user/service/impl/UserServiceImpl.java
  33. 44 0
      src/main/java/com/rf/conversion/utils/Constant.java
  34. 1376 0
      src/main/java/com/rf/conversion/utils/DateUtil.java
  35. 19 0
      src/main/java/com/rf/conversion/utils/HttpStatus.java
  36. 71 0
      src/main/java/com/rf/conversion/utils/JWTUtil.java
  37. 35 0
      src/main/java/com/rf/conversion/utils/LocalAssert.java
  38. 554 0
      src/main/java/com/rf/conversion/utils/LunarCalendarFestivalUtils.java
  39. 62 0
      src/main/java/com/rf/conversion/utils/Result.java
  40. 44 0
      src/main/java/com/rf/conversion/utils/WebContextUtil.java
  41. 53 0
      src/main/resources/config/application-prod.yml
  42. 51 0
      src/main/resources/config/application-test.yml
  43. 26 0
      src/main/resources/config/application.yml
  44. 144 0
      src/main/resources/logback.xml
  45. 28 0
      src/main/resources/proguard.conf
  46. BIN
      src/main/resources/zhjw.hnhong-duo.com.jks
  47. BIN
      userAvatar/man1.png
  48. BIN
      userAvatar/man2.png
  49. BIN
      userAvatar/man3.png
  50. BIN
      userAvatar/woman1.png
  51. BIN
      userAvatar/woman2.png
  52. BIN
      userAvatar/woman3.png

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+# ---> Java
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+/.gradle/
+/build/
+/src/main/resources/static/
+/logs/
+/gradle/
+/.idea/

+ 3 - 0
README.md

@@ -0,0 +1,3 @@
+# file_conversion
+
+review code

+ 104 - 0
build.gradle

@@ -0,0 +1,104 @@
+buildscript {
+	ext {
+		queryDslVersion = '4.2.1'
+		lombokVersion = '1.18.12'
+	}
+}
+plugins {
+	id 'org.springframework.boot' version '2.4.2'
+	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
+	id 'java'
+}
+
+group = 'com.rf'
+version = 'v1.1-'+getNewVersion()
+sourceCompatibility = '8'
+
+configurations {
+	compileOnly {
+		extendsFrom annotationProcessor
+	}
+}
+
+repositories {
+	maven {
+		url 'https://maven.aliyun.com/repository/public'
+	}
+	maven {
+		credentials {
+			username '0p07qf'
+			password 'z1XwdFEf4M'
+		}
+		url 'https://repo.rdc.aliyun.com/repository/107260-release-GqdtcU/'
+	}
+	maven {
+		credentials {
+			username '0p07qf'
+			password 'z1XwdFEf4M'
+		}
+		url 'https://repo.rdc.aliyun.com/repository/107260-snapshot-C6ziam/'
+	}
+	maven {
+		url "https://plugins.gradle.org/m2/"
+	}
+	mavenLocal()
+}
+
+dependencies {
+	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+	implementation 'org.springframework.boot:spring-boot-starter-web'
+	compileOnly 'org.projectlombok:lombok'
+	annotationProcessor 'org.projectlombok:lombok'
+	implementation 'org.springframework.boot:spring-boot-starter-validation:2.6.3'
+
+	implementation 'mysql:mysql-connector-java:8.0.21'
+
+	implementation("com.querydsl:querydsl-core:${queryDslVersion}")
+	implementation("com.querydsl:querydsl-jpa:${queryDslVersion}")
+	annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jpa",
+			"org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final",
+			"javax.annotation:javax.annotation-api:1.3.2",
+			"org.projectlombok:lombok")
+
+	compileOnly "org.projectlombok:lombok:${lombokVersion}"
+	annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+	implementation("org.projectlombok:lombok:${lombokVersion}")
+	testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.3'
+
+	implementation 'com.alibaba:fastjson:1.2.83'
+	implementation 'org.apache.poi:poi-ooxml:3.17'
+
+	implementation 'commons-lang:commons-lang:2.6'
+
+	implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
+	implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
+	implementation group: 'io.swagger', name: 'swagger-annotations', version: '1.5.22'
+	implementation group: 'io.swagger', name: 'swagger-models', version: '1.5.22'
+	implementation group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.1'
+	implementation group: 'com.github.qcloudsms', name: 'qcloudsms', version: '1.0.6'
+	implementation group: 'cn.keking.project', name: 'kk-anti-reptile', version: '1.0.0-RELEASE'
+	implementation group: 'com.belerweb', name: 'pinyin4j', version: '2.5.1'
+	implementation 'org.springframework.boot:spring-boot-starter-websocket:2.5.5'
+	implementation 'org.java-websocket:Java-WebSocket:1.5.1'
+	implementation 'com.auth0:java-jwt:3.18.2'
+	implementation group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.2.9'
+	testImplementation group: 'junit', name: 'junit', version: '4.13.2'
+	implementation 'com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.4.7'
+
+	implementation group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '2.6.8'
+
+	implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
+
+	implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.6.3'
+
+	implementation group: 'org.dom4j', name: 'dom4j', version: '2.1.1'
+
+}
+
+test {
+	useJUnitPlatform()
+}
+
+def getNewVersion(){
+	return new Date().format("yyyyMMddHHmmss",TimeZone.getTimeZone("GMT+08:00"))
+}

+ 234 - 0
gradlew

@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 89 - 0
gradlew.bat

@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 57 - 0
src/main/java/com/rf/conversion/FileConversionApplication.java

@@ -0,0 +1,57 @@
+package com.rf.conversion;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.env.Environment;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author zzf
+ */
+@EnableJpaRepositories(basePackages = {"com.rf.conversion"})
+@SpringBootApplication(scanBasePackages = {"com.rf.conversion"})
+@EnableJpaAuditing
+@EnableTransactionManagement
+@EnableScheduling
+@Slf4j
+public class FileConversionApplication {
+
+    static Logger logger = LoggerFactory.getLogger(FileConversionApplication.class);
+    @Autowired
+    static Environment environment;
+    @Value("${spring.profiles.active}")
+    static String profile;
+
+
+    public static void main(String[] args) {
+
+        SpringApplication.run(FileConversionApplication.class, args);
+
+    }
+
+
+    /**
+     * 让Spring管理JPAQueryFactory
+     *
+     * @param entityManager
+     * @return
+     */
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
+        return new JPAQueryFactory(entityManager);
+    }
+
+
+}

+ 46 - 0
src/main/java/com/rf/conversion/base/model/BaseEntity.java

@@ -0,0 +1,46 @@
+package com.rf.conversion.base.model;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hibernate.annotations.GenericGenerator;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/1/18 19:13
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@EntityListeners({AuditingEntityListener.class})
+@MappedSuperclass
+public class BaseEntity implements Serializable {
+    @Getter
+    @Id
+    @GenericGenerator(name = "jpa-uuid", strategy = "uuid")
+    @GeneratedValue(generator = "jpa-uuid")
+    @Column(name = "id", columnDefinition = "varchar(36) COMMENT '数据ID'")
+    @NotNull(groups = Update.class)
+    private String id;
+
+    @Column(name = "create_time", columnDefinition = "varchar(36) COMMENT '创建时间'")
+    private String createTime;
+
+
+    @Column(name = "update_time", columnDefinition = "varchar(36) COMMENT '更新时间'")
+    private String updateTime;
+
+
+
+    public @interface Update {
+    }
+}

+ 18 - 0
src/main/java/com/rf/conversion/base/repository/BaseRepository.java

@@ -0,0 +1,18 @@
+package com.rf.conversion.base.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import java.io.Serializable;
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/1/18 19:17
+ */
+@NoRepositoryBean
+public interface BaseRepository<T, PK extends Serializable> extends JpaRepository<T, PK>, JpaSpecificationExecutor, QuerydslPredicateExecutor<T> {
+
+}

+ 76 - 0
src/main/java/com/rf/conversion/base/rest/BaseController.java

@@ -0,0 +1,76 @@
+package com.rf.conversion.base.rest;
+
+import com.rf.conversion.utils.HttpStatus;
+import com.rf.conversion.utils.Result;
+
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/1/18 19:20
+ */
+public class BaseController {
+    protected static final String PAGE_NUM = "pageNum";
+
+    protected static final String PAGE_SIZE = "pageSize";
+
+    protected Result success() {
+        return success(null, "成功");
+    }
+
+    protected static <T> Result<T> success(T data) {
+        return success(data, "成功");
+    }
+
+    protected static <T> Result<T> success(T data, String message) {
+        if (null == data) {
+            return new Result<>(HttpStatus.SUCCESS, message);
+        }
+        return new Result<>(HttpStatus.SUCCESS, message, data);
+    }
+
+    protected static <T> Result<T> success(String code,T data, String message) {
+        if (null == data) {
+            return new Result<>(code, message);
+        }
+        return new Result<>(code, message, data);
+    }
+
+    protected Result fail() {
+        return fail(null, "失败");
+    }
+
+    protected static <T> Result<T> fail(T data) {
+        return fail(data, "失败");
+    }
+
+    protected static <T> Result<T> fail(String message) {
+        return new Result<>(HttpStatus.RUNTIME_EXCEPTION, message);
+    }
+
+    protected static <T> Result<T> fail(String code ,T data ,String message){
+        if(data == null)
+            return new Result<>(code,message);
+        else
+            return new Result<>(code,message,data);
+    }
+
+    protected static <T> Result<T> fail(T data, String message) {
+        if (null == data) {
+            return new Result<>(HttpStatus.RUNTIME_EXCEPTION, message);
+        }
+        return new Result<>(HttpStatus.RUNTIME_EXCEPTION, message, data);
+    }
+
+    protected Result failBadRequest() {
+        return failBadRequest(null, "参数异常");
+    }
+
+    protected static <T> Result<T> failBadRequest(T data) {
+        return failBadRequest(null, "参数异常");
+    }
+
+    protected static <T> Result<T> failBadRequest(T data, String message) {
+        return new Result<>(org.springframework.http.HttpStatus.BAD_REQUEST.value() + "", message, data);
+    }
+}

+ 30 - 0
src/main/java/com/rf/conversion/config/CorsConfig.java

@@ -0,0 +1,30 @@
+package com.rf.conversion.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+@Configuration
+public class CorsConfig {
+
+    private CorsConfiguration buildConfig() {
+
+        CorsConfiguration corsConfiguration = new CorsConfiguration();
+        corsConfiguration.setAllowCredentials(true);
+        corsConfiguration.addAllowedOriginPattern("*");
+        corsConfiguration.addAllowedHeader("*");
+        corsConfiguration.addAllowedMethod("*");
+        return corsConfiguration;
+
+    }
+
+    @Bean
+    public CorsFilter corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", buildConfig());
+        return new CorsFilter(source);
+    }
+
+}

+ 22 - 0
src/main/java/com/rf/conversion/config/Properties.java

@@ -0,0 +1,22 @@
+package com.rf.conversion.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author:zzf
+ * @Date:2022/7/5:18:15
+ * @Description:
+ */
+
+public class Properties {
+    private final Map<String, Duration> initCaches = new HashMap<>();
+    public Map<String ,Duration> getInitCache(){
+
+        return initCaches;
+    }
+}

+ 87 - 0
src/main/java/com/rf/conversion/config/RedisConfig.java

@@ -0,0 +1,87 @@
+package com.rf.conversion.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.time.Duration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Description:Redis缓存时间、序列化、反序列化等配置
+ * @Author: zsf
+ * @Date: 2022/7/1
+ */
+@Slf4j
+public class RedisConfig extends CachingConfigurerSupport {
+    @Autowired
+    private Properties properties;
+
+    @Bean
+    public CacheManager cacheManager(RedisConnectionFactory factory) {
+        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration
+                .defaultCacheConfig()
+                .entryTtl(Duration.ofDays(30))
+                .disableCachingNullValues()
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()));
+        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
+        Set<String> cacheNames = new HashSet<>();
+        ConcurrentHashMap<String, RedisCacheConfiguration> cacheConfig = new ConcurrentHashMap<>();
+
+        properties.getInitCache().forEach((key, value) -> {
+            cacheNames.add(key);
+            cacheConfig.put(key,cacheConfiguration.entryTtl(value));
+        });
+        return RedisCacheManager.builder(redisCacheWriter)
+                .cacheDefaults(cacheConfiguration)
+                .initialCacheNames(cacheNames)
+                .withInitialCacheConfigurations(cacheConfig)
+                .build();
+    }
+
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(redisConnectionFactory);
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
+
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+
+        redisTemplate.setHashKeySerializer(stringRedisSerializer);
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+    public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
+        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+
+        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+        return jackson2JsonRedisSerializer;
+    }
+}

+ 51 - 0
src/main/java/com/rf/conversion/config/Swagger2Config.java

@@ -0,0 +1,51 @@
+package com.rf.conversion.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author lpf
+ * @description:swagger 配置
+ * @date 2022/3/14 19:25
+ */
+@Configuration
+@EnableSwagger2
+@Profile({"prod", "test"})
+public class Swagger2Config {
+
+    @Bean
+    public Docket createRestApi() {
+        ParameterBuilder tokenPar = new ParameterBuilder();
+        List<Parameter> pars = new ArrayList<>();
+        tokenPar.name("Authorization").description("token令牌,格式为Bearer Token(可从/test/token接口处获取临时测试token)").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+        pars.add(tokenPar.build());
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.rf.conversion"))
+                .paths(PathSelectors.any())
+                .build()
+                .globalOperationParameters(pars);
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("文件转换小程序")
+                .version("v1.0")
+                .build();
+    }
+}

+ 18 - 0
src/main/java/com/rf/conversion/dao/dto/JpaDto.java

@@ -0,0 +1,18 @@
+package com.rf.conversion.dao.dto;
+
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.*;
+
+/**
+ * @author lpf
+ * @description: 自定义注解类,加载dto上表示这是个JpaDto类,解决jpa原生不能返回dto的问题
+ * @date 2022/4/6 21:08
+ */
+
+@Documented
+@Component
+@Target(value = {ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface JpaDto {
+}

+ 21 - 0
src/main/java/com/rf/conversion/dao/dto/ProgressDto.java

@@ -0,0 +1,21 @@
+package com.rf.conversion.dao.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author lpf
+ * @description:
+ * @date 2022/5/5 18:02
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ProgressDto {
+
+    private long maxNum;
+
+    private long havingDoNum;
+
+}

+ 2 - 0
src/main/java/com/rf/conversion/dao/lombok.config

@@ -0,0 +1,2 @@
+config.stopbubbling=true
+lombok.equalsandhashcode.callsuper=call

+ 92 - 0
src/main/java/com/rf/conversion/filter/AuthenticationInterceptor.java

@@ -0,0 +1,92 @@
+package com.rf.conversion.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.auth0.jwt.exceptions.AlgorithmMismatchException;
+import com.auth0.jwt.exceptions.SignatureVerificationException;
+import com.auth0.jwt.exceptions.TokenExpiredException;
+import com.rf.conversion.utils.JWTUtil;
+import com.rf.conversion.utils.LocalAssert;
+import com.rf.conversion.utils.WebContextUtil;
+import io.swagger.models.HttpMethod;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * @Description:使用AuthenticationInterceptor拦截器对接口参数进行验证
+ * @Author: mimang
+ * @Date: 2024/9/6
+ */
+@Slf4j
+@Component
+public class AuthenticationInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        HashMap<String, Object> resultJson = new HashMap<>();
+        final String url = request.getRequestURI();
+        log.info("url-------------------"+url);
+        // 从http请求头中取出token
+        final String token = request.getHeader(JWTUtil.AUTH_HEADER_KEY);
+        //如果不是映射到方法,直接通过
+        if(!(handler instanceof HandlerMethod)){
+            return true;
+        }
+        //如果是方法探测,直接通过
+        if (HttpMethod.OPTIONS.equals(request.getMethod())) {
+            response.setStatus(HttpServletResponse.SC_OK);
+            return true;
+        }
+        //如果方法有JwtIgnore注解,直接通过
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        Method method=handlerMethod.getMethod();
+        if (method.isAnnotationPresent(JwtIgnore.class)) {
+            JwtIgnore jwtIgnore = method.getAnnotation(JwtIgnore.class);
+            if(jwtIgnore.value()){
+                return true;
+            }
+        }
+
+        try {
+            LocalAssert.isStringEmpty(token, "token为空,鉴权失败!");
+            //验证,并获取token内部信息
+            String userToken = JWTUtil.verifyToken(token);
+            //将token放入本地缓存
+            WebContextUtil.setUserToken(userToken);
+            return true;
+        }catch (SignatureVerificationException e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "无效签名信息");
+        } catch (AlgorithmMismatchException e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "token算法不一致");
+        }catch (TokenExpiredException e){
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "token已过期,请重新获取");
+        } catch (Exception e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "登录状态失效,请重新登录");
+        }
+        String s = JSON.toJSONString(resultJson);
+        response.setContentType("application/json;charset=UTF-8");
+        response.getWriter().println(s);
+        return false;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        //方法结束后,移除缓存的token
+        WebContextUtil.removeUserToken();
+    }
+}
+

+ 62 - 0
src/main/java/com/rf/conversion/filter/JWTInterceptor.java

@@ -0,0 +1,62 @@
+package com.rf.conversion.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.auth0.jwt.exceptions.AlgorithmMismatchException;
+import com.auth0.jwt.exceptions.SignatureVerificationException;
+import com.rf.conversion.utils.JWTUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+
+/**
+ * @author lpf
+ * @description:
+ * @date 2021/12/2821:48
+ */
+@Slf4j
+public class JWTInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        HashMap<String, Object> resultJson = new HashMap<>();
+        String uri = request.getRequestURI();
+        try {
+            String token = request.getHeader("Authorization");
+            if(StringUtils.isEmpty(token)) {
+                resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+                resultJson.put("msg", "无效签名信息");
+            }
+            String[] len = token.split(" ");
+            if (len.length >=1){
+                token = len[1];
+                JWTUtil.verify(token);
+                return true;
+            }else {
+                resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+                resultJson.put("msg", "无效签名信息");
+            }
+
+        } catch (SignatureVerificationException e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "无效签名信息");
+        } catch (AlgorithmMismatchException e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "token算法不一致");
+        } catch (Exception e) {
+            e.printStackTrace();
+            resultJson.put("code", HttpServletResponse.SC_UNAUTHORIZED);
+            resultJson.put("msg", "登录状态失效,请重新登录");
+        }
+        String s = JSON.toJSONString(resultJson);
+        response.setContentType("application/json;charset=UTF-8");
+        response.getWriter().println(s);
+        return false;
+    }
+}

+ 49 - 0
src/main/java/com/rf/conversion/filter/JWTInterceptorConfig.java

@@ -0,0 +1,49 @@
+package com.rf.conversion.filter;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author lpf
+ * @description:
+ * @date 2021/12/2822:06
+ */
+@Configuration
+public class JWTInterceptorConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        String[] swaggerExcludes = new String[]{"/swagger-ui.html", "/swagger-resources/**", "/csrf", "/webjars/**"};
+        String[] webLogin = new String[]{"/user/authCode", "/user/saveUser", "/user/webLogin", "/user/webUpdatePassword", "/user/*/checkUser"};
+        String[] systemApi = new String[]{"/user/code2openid/**","/user/show","/picture/**"};
+        registry.addInterceptor(new AuthenticationInterceptor())
+                .addPathPatterns("/**")
+                .excludePathPatterns("/", "/index**", "/error")
+                .excludePathPatterns(systemApi)
+                //.excludePathPatterns(webLogin)
+                .excludePathPatterns(swaggerExcludes)
+                .excludePathPatterns("/favicon.ico")
+                .excludePathPatterns("/druid/**")
+                .excludePathPatterns("/static/**");
+        registry.addInterceptor(new AuthenticationInterceptor())
+                .addPathPatterns("/**")
+                .excludePathPatterns("/", "/index.html", "/error")
+                .excludePathPatterns(systemApi)
+                //.excludePathPatterns(webLogin)
+                .excludePathPatterns(swaggerExcludes)
+                .excludePathPatterns("/favicon.ico")
+                .excludePathPatterns("/druid/**")
+                .excludePathPatterns("/static/**");
+
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("/static/**")
+                .addResourceLocations("classpath:/static/");
+    }
+}

+ 12 - 0
src/main/java/com/rf/conversion/filter/JwtIgnore.java

@@ -0,0 +1,12 @@
+package com.rf.conversion.filter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface JwtIgnore {
+    boolean value() default true;
+}

+ 67 - 0
src/main/java/com/rf/conversion/security/SSLConfig.java

@@ -0,0 +1,67 @@
+package com.rf.conversion.security;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.connector.Connector;
+import org.apache.tomcat.util.descriptor.web.SecurityCollection;
+import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/9/15 14:32
+ */
+//@Configuration
+@Profile({"prod", "public"})
+public class SSLConfig {
+
+    @Value("${spring.profiles.active}")
+    private String profile;
+
+    @Bean
+    public TomcatServletWebServerFactory servletContainer() {
+
+        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
+
+            @Override
+            protected void postProcessContext(Context context) {
+
+                SecurityConstraint securityConstraint = new SecurityConstraint();
+                securityConstraint.setUserConstraint("CONFIDENTIAL");
+                SecurityCollection collection = new SecurityCollection();
+                collection.addPattern("/*");
+                securityConstraint.addCollection(collection);
+                context.addConstraint(securityConstraint);
+            }
+        };
+        tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
+        return tomcat;
+    }
+
+
+    private Connector initiateHttpConnector() {
+        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
+        connector.setScheme("http");
+        connector.setSecure(false);
+        if ("prod".equals(profile)) {
+            connector.setPort(8082);
+            connector.setRedirectPort(8848);
+        } else if ("public".equals(profile)) {
+            connector.setPort(8081);
+            connector.setRedirectPort(8443);
+        } else {
+            //TODO 待定
+            connector.setPort(9528);
+            connector.setRedirectPort(8849);
+        }
+
+
+        return connector;
+    }
+
+}

+ 18 - 0
src/main/java/com/rf/conversion/security/SafetyProcess.java

@@ -0,0 +1,18 @@
+package com.rf.conversion.security;
+
+import java.lang.annotation.*;
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/7/29 11:44
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface SafetyProcess {
+    boolean decode() default false;
+
+    boolean encode() default true;
+}

+ 42 - 0
src/main/java/com/rf/conversion/user/dao/model/UserConversionEntity.java

@@ -0,0 +1,42 @@
+package com.rf.conversion.user.dao.model;
+
+import com.rf.conversion.base.model.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * @author zsy
+ * @description:用户转换记录表
+ * @date 2021/6/17 15:55
+ */
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "t_user_conversion")
+@EqualsAndHashCode(callSuper=true)
+@org.hibernate.annotations.Table(appliesTo = "t_user_conversion", comment = "用户转换记录表")
+public class UserConversionEntity extends BaseEntity {
+
+    @Column(name = "user_id", columnDefinition = "varchar(36) not null comment '用户ID'")
+    private String userId;
+
+    @Column(name = "task_id", columnDefinition = "varchar(60) not null comment '任务ID'")
+    private String taskId;
+
+    @Column(name = "type", columnDefinition = "varchar(20) not null comment '类型'")
+    private String type;
+
+    @Column(name = "upload_name", columnDefinition = "varchar(100) not null comment '上传文件名称'")
+    private String uploadName;
+
+    @Column(name = "handle_name", columnDefinition = "varchar(100) not null comment '处理后文件名称'")
+    private String handleName;
+
+}

+ 42 - 0
src/main/java/com/rf/conversion/user/dao/model/UserEntity.java

@@ -0,0 +1,42 @@
+package com.rf.conversion.user.dao.model;
+
+import com.rf.conversion.base.model.BaseEntity;
+import lombok.*;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * @author zsy
+ * @description:用户信息表
+ * @date 2021/6/17 15:55
+ */
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "t_user_info")
+@EqualsAndHashCode(callSuper=true)
+@org.hibernate.annotations.Table(appliesTo = "t_user_info", comment = "用户信息表")
+public class UserEntity extends BaseEntity {
+
+    @Column(name = "user_name", columnDefinition = "varchar(50) comment '昵称'")
+    private String userName;
+
+    @Column(name = "open_id", columnDefinition = "varchar(36) not null comment 'openId'")
+    private String openId;
+
+    @Column(name = "phone", columnDefinition = "varchar(36) comment '手机号'")
+    private String phone;
+
+    @Column(name = "gender", columnDefinition = "varchar(2) comment '性别(0-男;1-女)'")
+    private String gender;
+
+    @Column(name = "intro", columnDefinition = "varchar(100) comment '用户简介'")
+    private String intro;
+
+    @Column(name = "avatar", columnDefinition = "varchar(255) comment '头像URL'")
+    private String avatar;
+
+}

+ 19 - 0
src/main/java/com/rf/conversion/user/dao/repository/UserConversionRepository.java

@@ -0,0 +1,19 @@
+package com.rf.conversion.user.dao.repository;
+
+import com.rf.conversion.base.repository.BaseRepository;
+import com.rf.conversion.user.dao.model.UserConversionEntity;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.jpa.repository.Query;
+
+/**
+ * @Description: 用户转换文件相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+public interface UserConversionRepository extends BaseRepository<UserConversionEntity, String> {
+
+    @Query(value = "select * from t_user_conversion where user_id = ?1 ORDER BY create_time desc ",
+            countQuery = "select * from t_user_conversion where user_id = ?1 ", nativeQuery = true)
+    Page<UserConversionEntity> findUserConversionList(String userId, PageRequest of);
+}

+ 15 - 0
src/main/java/com/rf/conversion/user/dao/repository/UserRepository.java

@@ -0,0 +1,15 @@
+package com.rf.conversion.user.dao.repository;
+
+import com.rf.conversion.base.repository.BaseRepository;
+import com.rf.conversion.user.dao.model.UserEntity;
+
+/**
+ * @Description: 用户注册登录等相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+public interface UserRepository extends BaseRepository<UserEntity, String> {
+
+    UserEntity findByOpenId(String openId);
+
+}

+ 202 - 0
src/main/java/com/rf/conversion/user/rest/UserController.java

@@ -0,0 +1,202 @@
+package com.rf.conversion.user.rest;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import com.rf.conversion.base.rest.BaseController;
+import com.rf.conversion.security.SafetyProcess;
+import com.rf.conversion.user.dao.model.UserEntity;
+import com.rf.conversion.user.service.UserService;
+import com.rf.conversion.utils.Constant;
+import com.rf.conversion.utils.DateUtil;
+import com.rf.conversion.utils.JWTUtil;
+import com.rf.conversion.utils.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Random;
+
+/**
+ * @Description: 用户注册登录等相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+@RestController
+@RequestMapping("/user")
+@Api(tags = "用户注册登录等相关接口")
+@Slf4j
+public class UserController extends BaseController {
+
+    @Autowired
+    private UserService userService;
+
+    @GetMapping("/code2openid/{code}")
+    @ApiOperation(value = "code 换 opernid",notes = "code:临时code,获取openid")
+    @SafetyProcess
+    public Result<JSONObject> code2openid(@PathVariable String code) throws Exception {
+        String openId;
+        HttpResponse response = getToken(code);
+        int statusCode = response.getStatusLine().getStatusCode();//响应状态码
+        String body = EntityUtils.toString(response.getEntity());
+        Gson gson = new Gson();
+        HashMap resultBody = gson.fromJson(body, HashMap.class);
+        if(statusCode == 200 || statusCode == 204){
+            openId = (String) resultBody.get("openid");
+            if (openId == null){
+                log.error("错误码:{}",resultBody.get("errcode"));
+                log.error("错误消息:{}",resultBody.get("errmsg"));
+                return fail(String.valueOf(resultBody.get("errmsg")));
+            }
+        }else{
+            log.error("获取openid失败:错误码 "+resultBody.get("errcode")+"  "+resultBody.get("errmsg"));
+            log.error("错误码:{}",resultBody.get("errcode"));
+            log.error("错误消息:{}",resultBody.get("errmsg"));
+            return fail();
+        }
+        JSONObject resultJson = new JSONObject();
+        //静默注册登录
+        UserEntity userEntity = this.userService.findByOpenId(openId);
+        if(userEntity != null){
+            resultJson.put("improve",false);
+        }else{
+            //注册
+            userEntity = new UserEntity();
+            userEntity.setCreateTime(DateUtil.getNowTime());
+            userEntity.setUpdateTime(DateUtil.getNowTime());
+            userEntity.setUserName("微信用户");
+            userEntity.setOpenId(openId);
+            userEntity.setPhone("-");
+            userEntity.setGender("0");
+            Random rand = new Random();
+            int number = rand.nextInt(3) + 1;
+            if (userEntity.getGender().equals("1")){
+                userEntity.setAvatar("./userAvatar/man"+number+".png");
+            }else {
+                userEntity.setAvatar("./userAvatar/woman"+number+".png");
+            }
+            userEntity = this.userService.save(userEntity);
+            resultJson.put("improve",true);
+        }
+
+        resultJson.put("token", JWTUtil.getTokenByUserInfo(userEntity));
+        resultJson.put("user",userEntity);
+        resultJson.put("openId",openId);
+        log.info("响应消息:"+resultJson.toJSONString());
+        return success(resultJson);
+    }
+
+    public HttpResponse getToken(String code) throws IOException {
+        String url = Constant.ASPI_URL +
+                "?appid=" + Constant.ASPI_APPID +
+                "&secret=" + Constant.ASPI_SECRET +
+                "&js_code=" + code +
+                "&grant_type=authorization_code";
+        log.info("code2openid URL :"+url);
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpGet httpGet = new HttpGet(url);
+        httpGet.setHeader("Accept", "application/json");
+        return httpClient.execute(httpGet);
+    }
+
+    /**
+     * 修改用户信息
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "修改用户信息接口",notes = "id:用户id,userName:昵称,phone:手机号,gender:性别(0-男;1-女),avatar:头像图片路径,intro:用户简介")
+    @PostMapping("/updateUser")
+    public Result updateAvatar(@RequestBody String json){
+            UserEntity userEntity = JSONObject.parseObject(json, UserEntity.class);
+            UserEntity user = this.userService.findById(userEntity.getId());
+            if (user == null) {
+                return fail(null, "用户不存在");
+            }
+            userEntity.setUpdateTime(DateUtil.getNowTime());
+            userEntity.setOpenId(user.getOpenId());
+            this.userService.save(userEntity);
+            return success(userEntity);
+    }
+
+    /**
+     * 上传图片
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "上传图片",notes = "avatar:图片文件,userId:用户id,type:图片类型(1-用户头像;2-用户上传文件;3-转换后文件)")
+    @PostMapping("/uploadPictures")
+    public Result uploadPictures(String userId, String type, MultipartFile avatar){
+        if (avatar == null) {
+            return fail("头像为空");
+        } else {
+            UserEntity userEntity = userService.findById(userId);
+            System.out.println("11:"+userEntity);
+            if (userEntity == null) {
+                return fail(null, "用户不存在");
+            }
+            String fileName = "";
+            String FILEDIR = "";
+            if (type.equals("1")) {
+                FILEDIR = "./userAvatar/";
+            }else if (type.equals("2")) {
+                String date = DateUtil.getDateStr(new Date(), DateUtil.ACCURACY_PATTERN_MONTH);
+                FILEDIR = "./userUpload/" + date + "/";
+            }else {
+                String date = DateUtil.getDateStr(new Date(), DateUtil.ACCURACY_PATTERN_MONTH);
+                FILEDIR = "./userHandle/" + date + "/";
+            }
+            String avatarUrl = "";
+            if (!avatar.isEmpty()) {
+                fileName = userEntity.getOpenId() + "-=-" + System.currentTimeMillis() + "-=-" + avatar.getOriginalFilename();
+                try {
+                    File temp = new File(FILEDIR);
+                    if (!temp.exists()) {
+                        temp.mkdirs();
+                    }
+                    File fileLocal = new File(FILEDIR, fileName);
+                    FileUtils.copyInputStreamToFile(avatar.getInputStream(), fileLocal);
+                    avatarUrl = FILEDIR + fileName;
+                    return success(avatarUrl);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return fail("文件上传失败");
+                }
+            } else {
+                return fail("图片为空");
+            }
+        }
+    }
+
+    @GetMapping(value = "/show",produces = MediaType.IMAGE_JPEG_VALUE )
+    @ResponseBody
+    @ApiOperation(value = "图片展示",notes = "filePath:相对路径")
+    public byte[] showPhoto(String filePath) throws Exception {
+        try{
+            File file = new File(filePath);
+            if(file.exists()){
+                FileInputStream inputStream = new FileInputStream(file);
+                byte [] bytes = new byte[inputStream.available()];
+                inputStream.read(bytes,0,inputStream.available());
+                return bytes;
+            }
+            return null;
+        }catch(Exception e){
+            throw new Exception("未找到图片");
+        }
+    }
+
+}

+ 48 - 0
src/main/java/com/rf/conversion/user/rest/UserConversionController.java

@@ -0,0 +1,48 @@
+package com.rf.conversion.user.rest;
+
+import com.alibaba.fastjson.JSONObject;
+import com.rf.conversion.base.rest.BaseController;
+import com.rf.conversion.user.dao.model.UserConversionEntity;
+import com.rf.conversion.user.service.UserConversionService;
+import com.rf.conversion.utils.DateUtil;
+import com.rf.conversion.utils.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * @Description: 用户转换文件相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+@RestController
+@RequestMapping("/userConversion")
+@Api(tags = "用户转换文件相关接口")
+@Slf4j
+public class UserConversionController extends BaseController {
+
+    @Autowired
+    private UserConversionService userConversionService;
+
+    @PostMapping("/saveConversion")
+    @ApiOperation(value = "保存转换文件记录", notes = "参数:json对象;userId:用户ID;taskId:任务ID;type:类型;uploadName:上传文件名称;handleName:处理后文件名称")
+    public Result saveConversion(@RequestBody String json) {
+        UserConversionEntity userConversionEntity = JSONObject.parseObject(json, UserConversionEntity.class);
+        userConversionEntity.setCreateTime(DateUtil.getNowTime());
+        userConversionEntity.setUpdateTime(DateUtil.getNowTime());
+        userConversionEntity = this.userConversionService.save(userConversionEntity);
+        return success(userConversionEntity);
+    }
+
+    @GetMapping("/findUserConversionList")
+    @ApiOperation(value = "转换文件记录列表查询", notes = "参数包括:beginNum:页码,pageSize:每页条数,userId:用户ID")
+    public Result findUserConversionList(String userId, int beginNum, int pageSize) {
+        Page<UserConversionEntity> userConversionEntities = this.userConversionService.findUserConversionList(userId, beginNum, pageSize);
+        return success(userConversionEntities);
+    }
+
+}

+ 17 - 0
src/main/java/com/rf/conversion/user/service/UserConversionService.java

@@ -0,0 +1,17 @@
+package com.rf.conversion.user.service;
+
+
+import com.rf.conversion.user.dao.model.UserConversionEntity;
+import org.springframework.data.domain.Page;
+
+/**
+ * @Description: 用户转换文件相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+public interface UserConversionService {
+    UserConversionEntity save(UserConversionEntity userConversionEntity);
+
+    Page<UserConversionEntity> findUserConversionList(String userId, int beginNum, int pageSize);
+
+}

+ 18 - 0
src/main/java/com/rf/conversion/user/service/UserService.java

@@ -0,0 +1,18 @@
+package com.rf.conversion.user.service;
+
+import com.rf.conversion.user.dao.model.UserEntity;
+
+/**
+ * @Description: 用户注册登录等相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+public interface UserService {
+
+    UserEntity save(UserEntity userEntity);
+
+    UserEntity findById(String id);
+
+    UserEntity findByOpenId(String openId);
+
+}

+ 33 - 0
src/main/java/com/rf/conversion/user/service/impl/UserConversionServiceImpl.java

@@ -0,0 +1,33 @@
+package com.rf.conversion.user.service.impl;
+
+import com.rf.conversion.user.dao.model.UserConversionEntity;
+import com.rf.conversion.user.dao.repository.UserConversionRepository;
+import com.rf.conversion.user.service.UserConversionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * @Description: 用户转换文件相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+@Service
+public class UserConversionServiceImpl implements UserConversionService {
+
+    @Autowired
+    private UserConversionRepository userConversionRepository;
+
+    @Override
+    public UserConversionEntity save(UserConversionEntity userConversionEntity) {
+        return this.userConversionRepository.save(userConversionEntity);
+    }
+
+    @Override
+    public Page<UserConversionEntity> findUserConversionList(String userId, int beginNum, int pageSize) {
+        return this.userConversionRepository.findUserConversionList(userId, PageRequest.of(beginNum - 1, pageSize));
+    }
+
+}

+ 36 - 0
src/main/java/com/rf/conversion/user/service/impl/UserServiceImpl.java

@@ -0,0 +1,36 @@
+package com.rf.conversion.user.service.impl;
+
+import com.rf.conversion.user.dao.model.UserEntity;
+import com.rf.conversion.user.dao.repository.UserRepository;
+import com.rf.conversion.user.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * @Description: 用户注册登录等相关接口
+ * @Author: zsy
+ * @Date: 2024/12/4
+ */
+@Service
+public class UserServiceImpl implements UserService {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Override
+    public UserEntity save(UserEntity userEntity) {
+        return this.userRepository.save(userEntity);
+    }
+
+    @Override
+    public UserEntity findById(String id) {
+        return this.userRepository.findById(id).orElse(null);
+    }
+
+    @Override
+    public UserEntity findByOpenId(String openId) {
+        return this.userRepository.findByOpenId(openId);
+    }
+
+}

+ 44 - 0
src/main/java/com/rf/conversion/utils/Constant.java

@@ -0,0 +1,44 @@
+package com.rf.conversion.utils;
+
+/**
+ * @author zzf
+ * @description:静态类
+ * @date 2021/1/19 16:45
+ */
+public class Constant {
+
+
+    public static final String SYSTEM_VERSION ="1.0";
+
+
+
+    public static final String DEFAULT_VALUE_ZERO ="0";
+
+    public static String MAGIC_NUM_0 = "0";
+    public static String MAGIC_NUM_1 = "1";
+    public static String MAGIC_NUM_2 = "2";
+    public static String MAGIC_NUM_3 = "3";
+    public static String MAGIC_NUM_4 = "4";
+
+    public static final String DATE_TRANS_FLAG_START = "start";
+    public static final String DATE_TRANS_FLAG_END = "end";
+
+
+    public static final String DEFAULT_PASSWORD = "123456";
+
+    public static final String ASPI_URL = "https://api.weixin.qq.com/sns/jscode2session";
+    //小程序ID
+    public static final String ASPI_APPID = "wx26e15275d9899400";
+    //小程序秘钥
+    public static final String ASPI_SECRET = "168d743d4a58442f252654acdec6b383";
+
+
+
+
+
+
+
+
+
+
+}

+ 1376 - 0
src/main/java/com/rf/conversion/utils/DateUtil.java

@@ -0,0 +1,1376 @@
+package com.rf.conversion.utils;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+public class DateUtil {
+    /**
+     * 默认的日期格式组合,用来将字符串转化为日期用
+     */
+    public static final String[] DATE_PARSE_PATTERNS = {"yyyy/MM/dd",
+            "yyyy-MM-dd", "yyyy年MM月dd日"};
+    /**
+     * 获取当前系统时间格式
+     */
+    public static final String DEFAULT_DATE = "yyyy-MM-dd HH:mm:ss";
+    /**
+     * 特殊日期格式
+     */
+    public static final String DEFAULT_DATE_T = "yyyy-MM-dd:HH:mm";
+
+    /**
+     * 特殊日期格式2
+     */
+    public static final String DEFAULT_DATE_T2 = "yyyy-MM-dd HH:mm";
+    /**
+     * 默认的时间格式
+     */
+    public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss";
+
+    /**
+     * 默认的日期格式
+     */
+    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
+
+    /**
+     * 获取当前系统时间格式
+     * 用于生成文件名
+     */
+    public static final String DEFAULT_FILE_DATE = "yyyyMMddHHmmss";
+
+
+    /**
+     * 日期代码,周日
+     */
+    public static final int SUNDAY = 1;
+
+    /**
+     * 日期代码,周一
+     */
+    public static final int MONDAY = 2;
+
+    /**
+     * 日期代码,周二
+     */
+    public static final int TUESDAY = 3;
+
+    /**
+     * 日期代码,周三
+     */
+    public static final int WEDNESDAY = 4;
+
+    /**
+     * 日期代码,周四
+     */
+    public static final int THURSDAY = 5;
+
+    /**
+     * 日期代码,周五
+     */
+    public static final int FRIDAY = 6;
+
+    /**
+     * 日期代码,周六
+     */
+    public static final int SATURDAY = 7;
+
+    /**
+     * 日期精度,秒
+     */
+    public static final int ACCURACY_SECOND = 1;
+
+    /**
+     * 日期精度,分
+     */
+    public static final int ACCURACY_MINUTE = 2;
+
+    /**
+     * 日期精度,小时
+     */
+    public static final int ACCURACY_HOUR = 3;
+
+    /**
+     * 日期精度,天
+     */
+    public static final int ACCURACY_DAY = 4;
+
+    /**
+     * 日期精度,月
+     */
+    public static final int ACCURACY_MONTH = 5;
+
+    /**
+     * 日期精度,年
+     */
+    public static final int ACCURACY_YEAR = 6;
+
+    /**
+     * 比较用日期格式,精度为年
+     */
+    public static final String ACCURACY_PATTERN_YEAR = "yyyy";
+
+    /**
+     * 比较用日期格式,精度为月
+     */
+    public static final String ACCURACY_PATTERN_MONTH = "yyyyMM";
+
+    /**
+     * 比较用日期格式,精度为日
+     */
+    public static final String ACCURACY_PATTERN_DAY = "yyyyMMdd";
+
+    /**
+     * 比较用日期格式,精度为时
+     */
+    public static final String ACCURACY_PATTERN_HOUR = "yyyyMMddHH";
+
+    /**
+     * 比较用日期格式,精度为分
+     */
+    public static final String ACCURACY_PATTERN_MINUTE = "yyyyMMddHHmm";
+
+    /**
+     * 比较用日期格式,精度为秒
+     */
+    public static final String ACCURACY_PATTERN_SECOND = "yyyyMMddHHmmss";
+
+    /**
+     * 单一属性格式,时
+     */
+    public static final String SINGLE_YEAR = "yyyy";
+
+    /**
+     * 单一属性格式,时
+     */
+    public static final String SINGLE_MONTH = "M";
+
+    /**
+     * 单一属性格式,时
+     */
+    public static final String SINGLE_DAY = "d";
+
+    /**
+     * 单一属性格式,时
+     */
+    public static final String SINGLE_HOUR = "H";
+
+    /**
+     * 单一属性格式,分
+     */
+    public static final String SINGLE_MINUTE = "m";
+
+    /**
+     * 单一属性格式,秒
+     */
+    public static final String SINGLE_SECOND = "s";
+
+    /**
+     *
+     */
+    public static final long MILLISECONDS_PER_SECOND = 1000;
+
+    /**
+     *
+     */
+    public static final long MILLISECONDS_PER_MINUTE = 1000 * 60;
+
+    /**
+     *
+     */
+    public static final long MILLISECONDS_PER_HOUR = 1000 * 60 * 60;
+
+    /**
+     *
+     */
+    public static final long MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24;
+
+    /**
+     * 将给定的日期字符串,按照预定的日期格式,转化为Date型数据
+     *
+     * @param dateStr 日期字符字符串
+     * @return 日期型结果
+     */
+    public static Date parseDate(String dateStr) {
+        Date date = null;
+        try {
+            date = org.apache.commons.lang.time.DateUtils.parseDate(dateStr,
+                    DATE_PARSE_PATTERNS);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return date;
+    }
+
+    /**
+     * 根据指定格式转化String型日期到Date型
+     *
+     * @param dateStr      String型日期
+     * @param parsePattern 指定的格式
+     * @return Date型日期
+     */
+    public static Date parseDate(String dateStr, String parsePattern) {
+        Date date = null;
+        try {
+            date = org.apache.commons.lang.time.DateUtils.parseDate(dateStr,
+                    new String[]{parsePattern.toString()});
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return date;
+    }
+
+    /**
+     * 返回系统当前时间(Date型)
+     *
+     * @return 系统当前时间
+     */
+    public static Date getCurrentDate() {
+        return new Date();
+    }
+
+    /**
+     * 日期计算,日加减
+     *
+     * @param date   初始日期
+     * @param amount 天数增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addDays(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addDays(date, amount);
+    }
+
+    /**
+     * 日期计算,周加减
+     *
+     * @param date   初始日期
+     * @param amount 周数增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addWeeks(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addWeeks(date, amount);
+    }
+
+    /**
+     * 日期计算,月加减
+     *
+     * @param date   初始日期
+     * @param amount 月数增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addMonths(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addMonths(date, amount);
+    }
+
+    /**
+     * 日期计算,年加减
+     *
+     * @param date   初始日期
+     * @param amount 年数增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addYears(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addYears(date, amount);
+    }
+
+    /**
+     * 日期计算,小时加减
+     *
+     * @param date   初始日期
+     * @param amount 小时增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addHours(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addHours(date, amount);
+    }
+
+    /**
+     * 日期计算,分钟加减
+     *
+     * @param date   初始日期
+     * @param amount 分钟增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addMinutes(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addMinutes(date, amount);
+    }
+
+    /**
+     * 日期计算,秒加减
+     *
+     * @param date   初始日期
+     * @param amount 秒增量(负数为减)
+     * @return 计算后的日期
+     */
+    public static Date addSeconds(Date date, int amount) {
+        return org.apache.commons.lang.time.DateUtils.addSeconds(date, amount);
+    }
+
+    /**
+     * 根据指定格式,返回日期时间字符串
+     *
+     * @param date    日期变量
+     * @param pattern 日期格式
+     * @return 日期时间字符串
+     */
+    public static String getDateStr(Date date, String pattern) {
+        DateFormat df = new SimpleDateFormat(pattern);
+        return df.format(date);
+    }
+
+    /**
+     * 输出时间String(默认格式)
+     *
+     * @param date 日期
+     * @return 默认格式化的日期
+     */
+    public static String getTimeStr(Date date) {
+        return getDateStr(date, DEFAULT_TIME_PATTERN);
+    }
+
+    /**
+     * 取指定日期所在月的第一天的日期
+     *
+     * @param date 指定的日期
+     * @return 指定日期所在月的第一天
+     */
+    public static Date getFirstDayOfMonth(Date date) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.DATE, 1);
+        return cal.getTime();
+    }
+
+    /**
+     * 取指定日期所在月的最后一天的日期
+     *
+     * @param date 指定的日期
+     * @return 指定日期所在月的最后一天
+     */
+    public static Date getLastDayOfMonth(Date date) {
+        Date nextMonth = addMonths(date, 1);
+        Date firstDayOfNextMonth = getFirstDayOfMonth(nextMonth);
+        return addDays(firstDayOfNextMonth, -1);
+    }
+
+    /**
+     * 取指定日期所在年的第一天的日期
+     *
+     * @param date 指定的日期
+     * @return 指定日期所在年的第一天
+     */
+    public static Date getFirstDayOfYear(Date date) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.DATE, 1);
+        cal.set(Calendar.MONTH, 0);
+        return cal.getTime();
+    }
+
+    /**
+     * 取指定日期所在年的最后一天的日期
+     *
+     * @param date 指定的日期
+     * @return 指定日期所在月的最后一天
+     */
+    public static Date getLastDayOfYear(Date date) {
+        Date nextMonth = addYears(date, 1);
+        Date firstDayOfNextYear = getFirstDayOfYear(nextMonth);
+        return addDays(firstDayOfNextYear, -1);
+    }
+
+    /**
+     * 取指定日期所在周的指定天的日期
+     *
+     * @param date     指定的日期
+     * @param day      指定的天(星期几)
+     * @param firstDay 一星期的起始天
+     * @return 指定周星期日的日期
+     */
+    public static Date getDayInWeek(Date date, int day, int firstDay) {
+        Calendar cal = getCalendar(date);
+        cal.setFirstDayOfWeek(firstDay);
+        cal.set(Calendar.DAY_OF_WEEK, day);
+        return cal.getTime();
+    }
+
+    /**
+     * 根据Date型的日期,取Calendar型的日期
+     *
+     * @param date Date型的日期
+     * @return Calendar型的日期
+     */
+    public static Calendar getCalendar(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        return cal;
+    }
+
+    /**
+     * 日期比较(精确到天),date1晚于date2
+     *
+     * @param date1 日期1
+     * @param date2 日期2
+     * @return date1晚于date2,返回true,否则返回false
+     */
+    public static boolean later(Date date1, Date date2) {
+        boolean result = false;
+        if (1 == compare(date1, date2, ACCURACY_DAY)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 日期比较(精确到天),date1早于date2
+     *
+     * @param date1 日期1
+     * @param date2 日期2
+     * @return date1早于date2,返回true,否则返回false
+     */
+    public static boolean earlier(Date date1, Date date2) {
+        boolean result = false;
+        if (-1 == compare(date1, date2, ACCURACY_DAY)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 日期比较(精确到天),date1等于date2
+     *
+     * @param date1 日期1
+     * @param date2 日期2
+     * @return date1等于date2,返回true,否则返回false
+     */
+    public static boolean equal(Date date1, Date date2) {
+        boolean result = false;
+        if (0 == compare(date1, date2, ACCURACY_DAY)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 根据指定规则比较日期,date1晚于date2
+     *
+     * @param date1    日期1
+     * @param date2    日期2
+     * @param accuracy 日期精度
+     * @return date1晚于date2,返回true,否则返回false
+     */
+    public static boolean later(Date date1, Date date2, int accuracy) {
+        boolean result = false;
+        if (1 == compare(date1, date2, accuracy)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 根据指定规则比较日期,date1早于date2
+     *
+     * @param date1    日期1
+     * @param date2    日期2
+     * @param accuracy 日期精度
+     * @return date1早于date2,返回true,否则返回false
+     */
+    public static boolean earlier(Date date1, Date date2, int accuracy) {
+        boolean result = false;
+        if (-1 == compare(date1, date2, accuracy)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 根据指定规则比较日期,date1等于date2
+     *
+     * @param date1    日期1
+     * @param date2    日期2
+     * @param accuracy 日期精度
+     * @return date1等于date2,返回true,否则返回false
+     */
+    public static boolean equal(Date date1, Date date2, int accuracy) {
+        boolean result = false;
+        if (0 == compare(date1, date2, accuracy)) {
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * 根据指定规则,比较日期
+     *
+     * @param date1    日期1
+     * @param date2    日期2
+     * @param accuracy 日期精度
+     * @return int型,date1晚,返回1;date1早,返回-1;相等,返回0
+     */
+    public static int compare(Date date1, Date date2, int accuracy) {
+        String pattern = DEFAULT_DATE_PATTERN;
+        switch (accuracy) {
+            case ACCURACY_YEAR:
+                pattern = ACCURACY_PATTERN_YEAR;
+                break;
+            case ACCURACY_MONTH:
+                pattern = ACCURACY_PATTERN_MONTH;
+                break;
+            case ACCURACY_DAY:
+                pattern = ACCURACY_PATTERN_DAY;
+                break;
+            case ACCURACY_HOUR:
+                pattern = ACCURACY_PATTERN_HOUR;
+                break;
+            case ACCURACY_MINUTE:
+                pattern = ACCURACY_PATTERN_MINUTE;
+                break;
+            case ACCURACY_SECOND:
+                pattern = ACCURACY_PATTERN_SECOND;
+                break;
+            default:
+                break;
+        }
+        Date formatedDate1 = transDateFormat(date1, pattern);
+        Date formatedDate2 = transDateFormat(date2, pattern);
+        return formatedDate1.compareTo(formatedDate2);
+    }
+
+    /**
+     * 根据指定规则,比较日期
+     *
+     * @param date1    日期1
+     * @param date2    日期2
+     * @param accuracy 日期精度
+     * @return int型,date1晚,返回1;date1早,返回-1;相等,返回0
+     * @throws ParseException
+     */
+    public static int compare(String date1, String date2, int accuracy) throws ParseException {
+        String pattern = DEFAULT_DATE_PATTERN;
+        switch (accuracy) {
+            case ACCURACY_YEAR:
+                pattern = ACCURACY_PATTERN_YEAR;
+                break;
+            case ACCURACY_MONTH:
+                pattern = ACCURACY_PATTERN_MONTH;
+                break;
+            case ACCURACY_DAY:
+                pattern = ACCURACY_PATTERN_DAY;
+                break;
+            case ACCURACY_HOUR:
+                pattern = ACCURACY_PATTERN_HOUR;
+                break;
+            case ACCURACY_MINUTE:
+                pattern = ACCURACY_PATTERN_MINUTE;
+                break;
+            case ACCURACY_SECOND:
+                pattern = ACCURACY_PATTERN_SECOND;
+                break;
+            default:
+                break;
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE);
+        Date formatedDate1 = transDateFormat(sdf.parse(date1), pattern);
+        Date formatedDate2 = transDateFormat(sdf.parse(date2), pattern);
+        return formatedDate1.compareTo(formatedDate2);
+    }
+
+    /**
+     * 根据指定规则,转化日期,如只取年、取年月等
+     *
+     * @param date    待转化日期
+     * @param pattern 日期格式
+     * @return 转化后的日期
+     */
+    public static Date transDateFormat(Date date, String pattern) {
+        String dateStr = getDateStr(date, pattern);
+        return parseDate(dateStr, pattern);
+    }
+
+    /**
+     * 返回时定时间的年
+     *
+     * @param date 日期
+     * @return String型的年
+     */
+    public static String getYear(Date date) {
+        return getDateStr(date, SINGLE_YEAR);
+    }
+
+    /**
+     * 返回时定时间的月
+     *
+     * @param date 日期
+     * @return String型的月
+     */
+    public static String getMonth(Date date) {
+        return getDateStr(date, SINGLE_MONTH);
+    }
+
+    /**
+     * 返回时定时间的日
+     *
+     * @param date 日期
+     * @return String型的日
+     */
+    public static String getDay(Date date) {
+        return getDateStr(date, SINGLE_DAY);
+    }
+
+    /**
+     * 返回时定时间的小时
+     *
+     * @param date 日期
+     * @return String型的小时
+     */
+    public static String getHour(Date date) {
+        return getDateStr(date, SINGLE_HOUR);
+    }
+
+    /**
+     * 返回时定时间的分
+     *
+     * @param date 日期
+     * @return String型的分
+     */
+    public static String getMinute(Date date) {
+        return getDateStr(date, SINGLE_MINUTE);
+    }
+
+    /**
+     * 返回时定时间的秒
+     *
+     * @param date 日期
+     * @return String型的秒
+     */
+    public static String getSecond(Date date) {
+        return getDateStr(date, SINGLE_SECOND);
+    }
+
+    /**
+     * 将时间日期变量的年份变为指定年, 如果日期不存在,则向后一天,如20102月
+     *
+     * @param date   日期时间变量
+     * @param amount 指定年
+     * @return 修改后的日期变量
+     */
+    public static Date setYear(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.YEAR, amount);
+        return cal.getTime();
+    }
+
+    /**
+     * 将时间日期变量的月份变为指定月
+     *
+     * @param date   日期时间变量
+     * @param amount 指定月
+     * @return 修改后的日期变量
+     */
+    public static Date setMonth(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.MONTH, amount - 1);
+        return cal.getTime();
+    }
+
+    /**
+     * 将时间日期变量的年份变为指定日
+     *
+     * @param date   日期时间变量
+     * @param amount 指定日
+     * @return 修改后的日期变量
+     */
+    public static Date setDay(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.DAY_OF_MONTH, amount);
+        return cal.getTime();
+    }
+
+    /**
+     * 将时间日期变量的小时变为指定时
+     *
+     * @param date   日期时间变量
+     * @param amount 指定时
+     * @return 修改后的日期变量
+     */
+    public static Date setHour(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.HOUR_OF_DAY, amount);
+        return cal.getTime();
+    }
+
+    /**
+     * 将时间日期变量的分钟变为指定分
+     *
+     * @param date   日期时间变量
+     * @param amount 指定分
+     * @return 修改后的日期变量
+     */
+    public static Date setMinute(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.MINUTE, amount);
+        return cal.getTime();
+    }
+
+    /**
+     * 将时间日期变量的秒变为指定秒
+     *
+     * @param date   日期时间变量
+     * @param amount 指定秒
+     * @return 修改后的日期变量
+     */
+    public static Date setSecond(Date date, int amount) {
+        Calendar cal = getCalendar(date);
+        cal.set(Calendar.SECOND, amount);
+        return cal.getTime();
+    }
+
+    /**
+     * 根据制定单位,计算两个日期之间的天数差
+     *
+     * @param a 时间点1
+     * @param b 时间点2
+     * @return 时间差
+     */
+    public static int getDateDistance(Date a, Date b) {
+        return getDateDistance(a, b, ACCURACY_DAY);
+    }
+
+    /**
+     * 根据制定单位,计算两个日期之间的差
+     *
+     * @param a    时间点1
+     * @param b    时间点2
+     * @param unit 时间单位
+     * @return 时间差
+     */
+    public static int getDateDistance(Date a, Date b, int unit) {
+        int result = 0;
+        if (null != a && null != b) {
+            String pattern = null;
+            switch (unit) {
+                case ACCURACY_HOUR: // '\003'
+                    pattern = "yyyyMMddHH";
+                    break;
+                case ACCURACY_MINUTE: // '\002'
+                    pattern = "yyyyMMddHHmm";
+                    break;
+                case ACCURACY_SECOND: // '\001'
+                    pattern = "yyyyMMddHHmmss";
+                    break;
+                default:
+                    pattern = "yyyyMMdd";
+            }
+            Date startDate = transDateFormat(1 != a.compareTo(b) ? a : b,
+                    pattern);
+            Date endDate = transDateFormat(1 != a.compareTo(b) ? b : a, pattern);
+            if (1 <= unit && 4 >= unit) {
+                result = getDistanceByUnit(startDate, endDate, unit);
+                return result;
+            }
+            GregorianCalendar startCalendar = new GregorianCalendar();
+            startCalendar.setTime(startDate);
+            int startYears = startCalendar.get(Calendar.YEAR);
+            int startMonths = startCalendar.get(Calendar.MONTH);
+            int startDays = startCalendar.get(Calendar.DAY_OF_MONTH);
+
+            GregorianCalendar endCalendar = new GregorianCalendar();
+            endCalendar.setTime(endDate);
+            int endYears = endCalendar.get(Calendar.YEAR);
+            int endMonths = endCalendar.get(Calendar.MONTH);
+            int endDays = endCalendar.get(Calendar.DAY_OF_MONTH);
+
+            int yearBetween = endYears - startYears;
+            int monthBetween = endMonths - startMonths;
+            if (endDays < startDays
+                    && endDays != endCalendar.getActualMaximum(Calendar.DATE)) {
+                monthBetween--;
+            }
+            if (ACCURACY_YEAR == unit) {
+                if (monthBetween < 0) {
+                    yearBetween--;
+                }
+                result = yearBetween;
+            }
+            if (ACCURACY_MONTH == unit) {
+                result = (yearBetween * 12 + monthBetween);
+            }
+        }
+        return result;
+
+    }
+
+    /**
+     * 内部方法,计算时间点的差距
+     *
+     * @param startDate 起始时间
+     * @param endDate   终止时间
+     * @param unit      时间单位
+     * @return 时间差
+     */
+    public static int getDistanceByUnit(Date startDate, Date endDate, int unit) {
+        int result = 0;
+        long millisecondPerUnit = MILLISECONDS_PER_DAY;
+        switch (unit) {
+            case ACCURACY_HOUR:
+                millisecondPerUnit = MILLISECONDS_PER_HOUR;
+                break;
+            case ACCURACY_MINUTE:
+                millisecondPerUnit = MILLISECONDS_PER_MINUTE;
+                break;
+            case ACCURACY_SECOND:
+                millisecondPerUnit = MILLISECONDS_PER_SECOND;
+                break;
+            default:
+                break;
+        }
+        long start = startDate.getTime();
+        long end = endDate.getTime();
+        long distance = end - start;
+        result = Integer.valueOf((distance / millisecondPerUnit) + "");
+        return result;
+    }
+
+    /**
+     * 内部方法,计算时间点的差距toLong
+     *
+     * @param startDate 起始时间
+     * @param endDate   终止时间
+     * @param unit      时间单位
+     * @return 时间差
+     */
+    public static long getDistanceByUnit_toLong(Date startDate, Date endDate, int unit) {
+        long result = 0;
+        long millisecondPerUnit = MILLISECONDS_PER_DAY;
+        switch (unit) {
+            case ACCURACY_HOUR:
+                millisecondPerUnit = MILLISECONDS_PER_HOUR;
+                break;
+            case ACCURACY_MINUTE:
+                millisecondPerUnit = MILLISECONDS_PER_MINUTE;
+                break;
+            case ACCURACY_SECOND:
+                millisecondPerUnit = MILLISECONDS_PER_SECOND;
+                break;
+            default:
+                break;
+        }
+        long start = startDate.getTime();
+        long end = endDate.getTime();
+        long distance = end - start;
+        result = distance / millisecondPerUnit;
+        return result;
+    }
+
+
+    /**
+     * 返回指定日期是当年的第几周
+     *
+     * @param date 指定日期
+     * @return 周数(从1开始)
+     */
+    public static int getWeekOfYear(Date date) {
+        return getCalendar(date).get(Calendar.WEEK_OF_YEAR);
+    }
+
+    /**
+     * 获取指定日期是星期几
+     *
+     * @param date 指定日期
+     * @return 星期日--1; 星期一--2; 星期二--3; 星期三--4; 星期四--5; 星期五--6; 星期六--7;
+     */
+    public static int getWeekOfDate(Date date) {
+        return getCalendar(date).get(Calendar.DAY_OF_WEEK);
+    }
+
+    /**
+     * 判断指定年份日期的年份是否为闰年
+     *
+     * @param date 日期
+     * @return 闰年ture,非闰年false
+     */
+    public static boolean isLeapYear(Date date) {
+        int year = getCalendar(date).get(Calendar.YEAR);
+        return isLeapYear(year);
+    }
+
+    /**
+     * 判断指定年份日期的年份是否为闰年
+     *
+     * @param year 年份数字
+     * @return 闰年ture,非闰年false
+     */
+    public static boolean isLeapYear(int year) {
+        if ((year % 400) == 0) {
+            return true;
+        } else if ((year % 4) == 0) {
+            if ((year % 100) == 0) {
+                return false;
+            } else {
+                return true;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 按照strFormat格式输出当前时间
+     *
+     * @param strFormat 格式
+     * @return 指定格式的当前系统日期
+     */
+    public static String getCurrentDate(String strFormat) {
+        return getDateStr(getCurrentDate(), strFormat);
+    }
+
+    /**
+     * 校验日期数据(校验输入值是否为指定的日期格式)
+     *
+     * @param strDate   要校验的日期
+     * @param strFormat 日期格式
+     * @return true/false (符合/不符合)
+     */
+    public static boolean checkDate(String strDate, String strFormat) {
+        Date date = null;
+        if ((strDate != null) && (strDate.trim().length() != 0)) {
+            DateFormat myDateFmt = new SimpleDateFormat(strFormat);
+            try {
+                date = myDateFmt.parse(strDate);
+
+                if (!strDate.equals(myDateFmt.format(date))) {
+                    date = null;
+                    return false;
+                }
+            } catch (ParseException e) {
+                date = null;
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @param
+     * @return 格式为"yyyy-MM-dd HH:mm:ss"的时间
+     * @throws
+     * @Description:获取当期系统日期以特定格式显示
+     * @author baolf
+     * @date 2016-7-25
+     */
+    public static String getNowTime() {
+        Date now = new Date();
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_DATE);
+        String date = sd.format(now);
+        return date;
+    }
+
+    /**
+     * @param
+     * @return 格式为"yyyy-MM-dd HH:mm:ss"的时间
+     * @throws
+     * @Description:获取当期系统两小时后时间 以特定格式显示
+     * @author wwq
+     * @date 2018-08-13
+     */
+    public static String get2HoursLater() {
+        Date twoHours = new Date(System.currentTimeMillis() + 120 * 60 * 1000);
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_DATE);
+        String date = sd.format(twoHours);
+        return date;
+    }
+
+    /**
+     * @param
+     * @return 格式为"yyyy-MM-dd"的时间
+     * @throws
+     * @Description:获取当期系统日期以特定格式显示
+     * @author
+     * @date 2016-7-25
+     */
+    public static String getNowTime1() {
+        Date now = new Date();
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
+        String date = sd.format(now);
+        return date;
+    }
+
+    /**
+     * 自定义时间格式
+     *
+     * @param strFormat
+     * @return
+     */
+    public static String getNowTime(String strFormat) {
+        Date now = new Date();
+        SimpleDateFormat sd = new SimpleDateFormat(strFormat);
+        String date = sd.format(now);
+        return date;
+    }
+
+    /**
+     * 时间串,没有分割符
+     * 用于自动生成文件名用
+     *
+     * @return
+     */
+    public static synchronized String getFileNameNowTime() {
+        Date now = new Date();
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_FILE_DATE);
+        String date = sd.format(now);
+        return date;
+    }
+
+    /**
+     * 获得几位随机数(正数)
+     *
+     * @param num
+     * @return
+     */
+    public static String getRandom(int num) {
+        StringBuffer format = new StringBuffer("0.0");
+        for (int ii = 2; ii <= num; ii++) {
+            format.append("0");
+        }
+        DecimalFormat df = new DecimalFormat(format.toString());
+        return df.format(Math.random()).replace("0.", "");
+
+    }
+
+    public static String getReleaseBatch() {
+        Date now = new Date();
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
+        String date = sd.format(now);
+        date = date.replace("-", "");
+        return date;
+    }
+
+    //	public static void main(String[] args) {
+//	}
+    public static String getBeforeNowTime() {
+        long time = 1 * 60 * 1000 + 10000;//1分钟
+        Date now = new Date(new Date().getTime() - time);
+        SimpleDateFormat sd = new SimpleDateFormat(DEFAULT_DATE);
+        String date = sd.format(now);
+        return date;
+    }
+
+    /**
+     * 获取秒数  (1970-01-01 08:00:00)
+     *
+     * @param :
+     * @throws :
+     * @Description :
+     * @author :
+     */
+    public static int getDateInt(String date) {
+        return getDistanceByUnit(
+                parseDate("1970-01-01 08:00:00", DEFAULT_DATE),
+                parseDate(date, DEFAULT_DATE), 1);
+    }
+
+    /**
+     * 判断字符串是否不为空 空返回false 非空返回true
+     *
+     * @param sourceStr
+     * @return
+     */
+    public static boolean isNotEmpty(String sourceStr) {
+
+        if (sourceStr == null) {
+            return false;
+        }
+        if (sourceStr.trim().length() > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 统计两个时间的时间差
+     * 相差几秒几毫秒
+     */
+    public static String getDistanceTime(String str1, String str2) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
+        Date one;
+        Date two;
+        long day = 0;//天数差
+        long hour = 0;//小时数差
+        long min = 0;//分钟数差
+        long second = 0;//秒数差
+        long diff = 0;//毫秒差
+        String result = null;
+        try {
+            final Calendar c = Calendar.getInstance();
+            c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
+            one = df.parse(str1);
+            c.setTime(one);
+            two = df.parse(str2);
+            long time1 = one.getTime();
+            long time2 = two.getTime();
+            diff = time2 - time1;
+            day = diff / (24 * 60 * 60 * 1000);
+            hour = (diff / (60 * 60 * 1000) - day * 24);
+            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
+            second = diff / 1000;
+            //System.out.println("day="+day+" hour="+hour+" min="+min+" ss="+second%60+" SSS="+diff%1000);
+            result = second % 60 + "秒" + diff % 1000 + "毫秒";
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return String.valueOf(diff);
+    }
+
+    /**
+     * 获取两个日期相差的月数
+     */
+    public static int getMonthDiff(Date d1, Date d2) {
+        Calendar c1 = Calendar.getInstance();
+        Calendar c2 = Calendar.getInstance();
+        c1.setTime(d1);
+        c2.setTime(d2);
+        int year1 = c1.get(Calendar.YEAR);
+        int year2 = c2.get(Calendar.YEAR);
+        int month1 = c1.get(Calendar.MONTH);
+        int month2 = c2.get(Calendar.MONTH);
+        int day1 = c1.get(Calendar.DAY_OF_MONTH);
+        int day2 = c2.get(Calendar.DAY_OF_MONTH);
+        // 获取年的差值
+        int yearInterval = year1 - year2;
+        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
+        if (month1 < month2 || month1 == month2 && day1 < day2) {
+            yearInterval--;
+        }
+        // 获取月数差值
+        int monthInterval = (month1 + 12) - month2;
+        if (day1 < day2) {
+            monthInterval--;
+        }
+        monthInterval %= 12;
+        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
+        return monthsDiff;
+    }
+
+    public static void main(String[] args) throws ParseException {
+
+        int monthDiff = getMonthDiff(new Date(), new SimpleDateFormat("yyyy-MM-dd").parse("1991-05-16"));
+        System.out.println(monthDiff);
+        System.out.println(monthDiff / 12);
+
+    }
+
+    /*
+     * 将yyyyMMddHHmmss格式的数据装换成yyyy-MM-dd:HH:mm格式的数据
+     * */
+    public static String formatDate(String dateStr) throws NullPointerException {
+        //
+        StringBuffer dateBuffer = new StringBuffer();
+        return dateBuffer.append(dateStr.substring(0, 4)).append("-").append(dateStr.substring(4, 6)).append("-").append(dateStr.substring(6, 8))
+                .append(" ").append(dateStr.substring(8, 10)).append(":").append(dateStr.substring(10, 12)).append(":").append(dateStr.substring(12, 14)).toString();
+    }
+
+    /**
+     * 获取今天的开始时间,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getTodayBeginTime() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+
+        // 获取当天的开始时间(00:00:00)
+        LocalDateTime startOfDay = today.atStartOfDay();
+        ZonedDateTime zonedStartOfDay = startOfDay.atZone(ZoneId.systemDefault());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String formattedStartOfDay = zonedStartOfDay.format(formatter);
+        System.out.println("当天的开始时间: " + formattedStartOfDay);
+        return formattedStartOfDay;
+    }
+
+    /**
+     * 获取当天的结束时间,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getTodayEndTime() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+        LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
+        ZonedDateTime zonedEndOfDay = endOfDay.atZone(ZoneId.systemDefault());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String formattedEndOfDay = zonedEndOfDay.format(formatter);
+        System.out.println("当天的结束时间: " + formattedEndOfDay);
+        return formattedEndOfDay;
+    }
+
+    /**
+     * 获得当前月第一天的时间起点,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getMonthBeginTime() {
+        LocalDate today = LocalDate.now();
+        // 获取当前年份和月份
+        YearMonth currentYearMonth = YearMonth.from(today);
+        // 获取当前月份的第一天
+        LocalDate firstDayOfMonth = currentYearMonth.atDay(1);
+        LocalDateTime startOfDay = firstDayOfMonth.atStartOfDay();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        return startOfDay.format(formatter);
+    }
+
+
+    /**
+     * 获得当前月最后一天的时间终点,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getMonthEndTime() {
+        LocalDate today = LocalDate.now();
+        // 获取当前年份和月份
+        YearMonth currentYearMonth = YearMonth.from(today);
+        // 获取当前月份的最后一天
+        LocalDate lastDayOfMonth = currentYearMonth.atEndOfMonth();
+        LocalDateTime endOfDay = lastDayOfMonth.atTime(LocalTime.of(23, 59, 59));
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        return endOfDay.format(formatter);
+    }
+
+    /**
+     * 获取当前季度的开始时间,并格式化为yyyy-MM-dd HH:mm:ss
+     */
+    public static String getQuarterBeginTime() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+
+        // 获取当前日期所在的季度
+        int quarter = (today.getMonthValue() - 1) / 3 + 1;
+        // 获取当前季度的第一天
+        LocalDate firstDayOfQuarter = getFirstDayOfQuarter(today, quarter);
+        // 设置时间为00:00:00
+        LocalDateTime startOfQuarter = firstDayOfQuarter.atStartOfDay();
+        // 定义日期时间格式器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        // 格式化日期时间
+        return startOfQuarter.format(formatter);
+    }
+
+    /**
+     * 获取当前季度的结束时间,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getQuarterEndTime() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+
+        // 获取当前日期所在的季度
+        int quarter = (today.getMonthValue() - 1) / 3 + 1;
+
+        // 获取当前季度的最后一天
+        LocalDate lastDayOfQuarter = getLastDayOfQuarter(today, quarter);
+
+        // 设置时间为 23:59:59
+        LocalDateTime endOfQuarter = lastDayOfQuarter.atTime(LocalTime.of(23, 59, 59));
+
+        // 定义日期时间格式器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 格式化日期时间
+        return endOfQuarter.format(formatter);
+    }
+
+    /**
+     * 获取当前日期所在年份的开始时间,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getYearBeginTime() {
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+
+        // 获取当前年份的第一天
+        LocalDate firstDayOfYear = LocalDate.of(today.getYear(), 1, 1);
+
+        // 设置时间为00:00:00
+        LocalDateTime startOfYear = firstDayOfYear.atStartOfDay();
+
+        // 定义日期时间格式器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 格式化日期时间
+        return startOfYear.format(formatter);
+    }
+
+    /**
+     * 获取当前日期所在年份的结束时间,并格式化为yyyy-MM-dd HH:mm:ss
+     *
+     * @return
+     */
+    public static String getYearEndTime() {
+        //获取当前日期
+        LocalDate today = LocalDate.now();
+
+        //获取当前年份的最后一天
+        LocalDate endDayOfYear = LocalDate.of(today.getYear(), 12, 31);
+
+        // 设置时间为23:59:59
+        LocalDateTime endOfYear = endDayOfYear.atTime(LocalTime.of(23, 59, 59));
+
+        // 定义日期时间格式器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 格式化日期时间
+        return endOfYear.format(formatter);
+    }
+
+
+    private static LocalDate getFirstDayOfQuarter(LocalDate date, int quarter) {
+        Month firstMonthOfQuarter;
+        switch (quarter) {
+            case 1:
+                firstMonthOfQuarter = Month.JANUARY;
+                break;
+            case 2:
+                firstMonthOfQuarter = Month.APRIL;
+                break;
+            case 3:
+                firstMonthOfQuarter = Month.JULY;
+                break;
+            case 4:
+                firstMonthOfQuarter = Month.OCTOBER;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid quarter: " + quarter);
+        }
+        return LocalDate.of(date.getYear(), firstMonthOfQuarter, 1);
+    }
+
+    private static LocalDate getLastDayOfQuarter(LocalDate date, int quarter) {
+        Month lastMonthOfQuarter;
+        switch (quarter) {
+            case 1:
+                lastMonthOfQuarter = Month.MARCH;
+                break;
+            case 2:
+                lastMonthOfQuarter = Month.JUNE;
+                break;
+            case 3:
+                lastMonthOfQuarter = Month.SEPTEMBER;
+                break;
+            case 4:
+                lastMonthOfQuarter = Month.DECEMBER;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid quarter: " + quarter);
+        }
+        return LocalDate.of(date.getYear(), lastMonthOfQuarter, lastMonthOfQuarter.maxLength());
+    }
+
+
+}

+ 19 - 0
src/main/java/com/rf/conversion/utils/HttpStatus.java

@@ -0,0 +1,19 @@
+package com.rf.conversion.utils;
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/1/18 19:37
+ */
+public interface HttpStatus {
+    String SUCCESS = "200";
+    String SUCCESS_PUB = "201";
+
+    String RUNTIME_EXCEPTION = "2001";
+
+    String SERVER_EXCEPTION = "500100";
+
+    String PARAMETER_ISNULL = "500101";
+
+    String USER_NOT_FOUND = "6001";
+}

+ 71 - 0
src/main/java/com/rf/conversion/utils/JWTUtil.java

@@ -0,0 +1,71 @@
+package com.rf.conversion.utils;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTCreator;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.auth0.jwt.exceptions.TokenExpiredException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.rf.conversion.user.dao.model.UserEntity;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author lpf
+ * @description:
+ * @date 2021/12/2820:18
+ */
+public class JWTUtil {
+
+    private static final String SING = "xVWGEYTPF1hjnFt$HDZ0f^iet^^q@hZv";
+
+    public static final String AUTH_HEADER_KEY = "Authorization";
+
+    //token前缀
+    public static final String TOKEN_PREFIX = "Bearer ";
+
+    public static String getToken(Map<String, String> map) {
+
+        Calendar instance = Calendar.getInstance();
+        instance.add(Calendar.MONTH, 5);
+        JWTCreator.Builder builder = JWT.create();
+        map.forEach(builder::withClaim);
+        String token = builder.withExpiresAt(instance.getTime())
+                .sign(Algorithm.HMAC256(SING));
+        return token;
+    }
+
+    public static String getTokenByUserInfo(UserEntity userEntity){
+        HashMap<String, String> payload = new HashMap<>();
+        payload.put("phone", userEntity.getPhone());
+        payload.put("userId", userEntity.getId());
+        payload.put("userName", userEntity.getUserName());
+        payload.put("openId", userEntity.getOpenId());
+        return  getToken(payload);
+    }
+
+    /**
+     * 验证token
+     * @param token
+     */
+    public static String verifyToken(String token) throws Exception {
+        try {
+            return JWT.require(Algorithm.HMAC256(SING))
+                    .build()
+                    .verify(token.replace(TOKEN_PREFIX, ""))
+                    .getSubject();
+        } catch (TokenExpiredException e){
+            throw new Exception("token已失效,请重新登录",e);
+        } catch (JWTVerificationException e) {
+            throw new Exception("token验证失败!",e);
+        }
+    }
+
+
+    public static DecodedJWT verify(String token) {
+        return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
+    }
+
+}

+ 35 - 0
src/main/java/com/rf/conversion/utils/LocalAssert.java

@@ -0,0 +1,35 @@
+package com.rf.conversion.utils;
+
+import com.alibaba.druid.util.StringUtils;
+
+import java.util.Collection;
+
+/**
+ * @Description:断言工具类
+ * @Author: mimang
+ * @Date: 2024/9/6
+ */
+public abstract  class LocalAssert {
+    public static void isTrue(boolean expression, String message) throws RuntimeException {
+        if (!expression) {
+            throw new RuntimeException(message);
+        }
+    }
+    public static void isStringEmpty(String param, String message) throws RuntimeException{
+        if(StringUtils.isEmpty(param)) {
+            throw new RuntimeException(message);
+        }
+    }
+
+    public static void isObjectEmpty(Object object, String message) throws RuntimeException {
+        if (object == null) {
+            throw new RuntimeException(message);
+        }
+    }
+
+    public static void isCollectionEmpty(Collection coll, String message) throws RuntimeException {
+        if (coll == null || (coll.size() == 0)) {
+            throw new RuntimeException(message);
+        }
+    }
+}

+ 554 - 0
src/main/java/com/rf/conversion/utils/LunarCalendarFestivalUtils.java

@@ -0,0 +1,554 @@
+package com.rf.conversion.utils;
+
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * 获取输入公历日期的生肖、天干地支、农历年、农历月、农历日、公历节日、农历节日、24节气等数据
+ */
+public class LunarCalendarFestivalUtils {
+
+    //生肖年
+    private String animal;
+    //干支年
+    private String ganZhiYear;
+    //农历年
+    private String lunarYear;
+    //农历月
+    private String lunarMonth;
+    //农历日
+    private String lunarDay;
+    //公历节日
+    private String solarFestival;
+    //农历节日
+    private String lunarFestival;
+    //节气
+    private String lunarTerm;
+
+    /**
+     * 获取查询日期的年份生肖
+     */
+    public String getAnimal() {
+        return animal;
+    }
+
+    /**
+     * 获取查询日期年份的天干地支
+     */
+    public String getGanZhiYear() {
+        return ganZhiYear;
+    }
+
+    /**
+     * 获取查询日期的农历年份
+     */
+    public String getLunarYear() {
+        return lunarYear;
+    }
+
+    /**
+     * 获取查询日期的农历月份
+     */
+    public String getLunarMonth() {
+        return lunarMonth;
+    }
+
+    /**
+     * 获取查询日期的农历日
+     */
+    public String getLunarDay() {
+        return lunarDay;
+    }
+
+    /**
+     * 获取查询日期的公历节日(不是节日返回空)
+     */
+    public String getSolarFestival() {
+        return solarFestival;
+    }
+
+    /**
+     * 获取查询日期的农历节日(不是节日返回空)
+     */
+    public String getLunarFestival() {
+        return lunarFestival;
+    }
+
+    /**
+     * 获取查询日期的节气数据(不是节气返回空)
+     */
+    public String getLunarTerm() {
+        return lunarTerm;
+    }
+
+
+    // 位数从右往左
+    // 1-4:表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
+    // 5-16:为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
+    // 注意:从1月到12月对应的是第16位到第5位。
+    // 17-20:表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
+    // 举例:
+    // 1980年的数据是:0x095b0
+    // 二进制:0000 1001 0101 1011 0000
+    // 表示1980年没有闰月,从1月到12月的天数依次为:30、29、29、30、29、30、29、30、30、29、30、30。
+    // 1982年的数据是:0x0a974
+    // 0000 1010 0 1001 0111 0100
+    // 表示1982年的4月为闰月,即有第二个4月,且是闰小月。
+    // 从1月到13月的天数依次为:30、29、30、29、29(闰月)、30、29、29、30、29、30、30、30。
+    private static final long[] lunarInfo = new long[]{
+            0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909
+            0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
+            0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
+            0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
+            0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
+            0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
+            0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
+            0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
+            0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
+            0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
+            0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
+            0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
+            0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
+            0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
+            0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,
+            0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
+            0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
+            0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
+            0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
+            0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
+            0x0d520 //2100
+    };
+    //公历天数
+    private static final int[] solarMonths = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+    //生肖
+    private static final String[] animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
+    //天干
+    private static final String[] tianGan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
+    //地支
+    private static final String[] diZhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
+    //农历年
+    private static final String[] lunarYears = new String[]{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
+    //农历月份
+    private static final String[] lunarMonths = new String[]{"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"};
+    //农历数字
+    private static final String[] lunarNumber = new String[]{"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
+    private static final String[] chineseTen = new String[]{"初", "十", "廿", "三"};
+
+    //二十四节气
+    private static final String[] solarTerms = new String[]{"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨",
+            "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"};
+    //二十四节气日期偏移度
+    private static final double D = 0.2422;
+    //定义一个二维数组,第一维数组存储的是20世纪的节气C值,第二维数组存储的是21世纪的节气C值,0到23个,依次代表小寒、大寒、立春、雨水...冬至节气的C值
+    private static final double[][] CENTURY_ARRAY = {
+            {6.11, 20.84, 4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86, 6.5, 22.2, 7.928, 23.65, 8.35, 23.95, 8.44, 23.822, 9.098, 24.218, 8.218, 23.08, 7.9, 22.6},
+            {5.4055, 20.12, 3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37, 7.108, 22.83, 7.5, 23.13, 7.646, 23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94}
+    };
+    //特殊年份节气日期偏移
+    private static final Map<Integer, Integer[]> INCREASE_OFFSETMAP = new HashMap<>();//+1偏移
+    private static final Map<Integer, Integer[]> DECREASE_OFFSETMAP = new HashMap<>();//-1偏移
+
+    static {
+        INCREASE_OFFSETMAP.put(0, new Integer[]{1982});//小寒
+        DECREASE_OFFSETMAP.put(0, new Integer[]{2019});//小寒
+        INCREASE_OFFSETMAP.put(1, new Integer[]{2000, 2082});//大寒
+        DECREASE_OFFSETMAP.put(3, new Integer[]{2026});//雨水
+        INCREASE_OFFSETMAP.put(5, new Integer[]{2084});//春分
+        INCREASE_OFFSETMAP.put(8, new Integer[]{1911});//立夏
+        INCREASE_OFFSETMAP.put(9, new Integer[]{2008});//小满
+        INCREASE_OFFSETMAP.put(10, new Integer[]{1902});//芒种
+        INCREASE_OFFSETMAP.put(11, new Integer[]{1928});//夏至
+        INCREASE_OFFSETMAP.put(12, new Integer[]{1925, 2016});//小暑
+        INCREASE_OFFSETMAP.put(13, new Integer[]{1922});//大暑
+        INCREASE_OFFSETMAP.put(14, new Integer[]{2002});//立秋
+        INCREASE_OFFSETMAP.put(16, new Integer[]{1927});//白露
+        INCREASE_OFFSETMAP.put(17, new Integer[]{1942});//秋分
+        INCREASE_OFFSETMAP.put(19, new Integer[]{2089});//霜降
+        INCREASE_OFFSETMAP.put(20, new Integer[]{2089});//立冬
+        INCREASE_OFFSETMAP.put(21, new Integer[]{1978});//小雪
+        INCREASE_OFFSETMAP.put(22, new Integer[]{1954});//大雪
+        DECREASE_OFFSETMAP.put(23, new Integer[]{1918, 2021});//冬至
+    }
+
+    //农历节日
+    private static final String[] lunarHoliday = new String[]{"0101 春节", "0115 元宵节", "0202 龙抬头", "0303 上巳节", "0505 端午节", "0707 七夕节", "0715 中元节",
+            "0815 中秋节", "0909 重阳节", "1001 寒衣节", "1015 下元节", "1208 腊八节", "1223 北小年", "1224 南小年"};
+    //公历节日
+    private static final String[] solarHoliday = new String[]{
+            "0101 元旦", "0110 中国人民警察节", "0214 情人节", "0305 学雷锋纪念日", "0308 妇女节", "0312 植树节", "0315 消费者权益日",
+            "0422 地球日", "0423 读书日", "0501 劳动节", "0504 青年节", "0512 护士节", "0518 博物馆日", "0601 儿童节", "0605 环保日",
+            "0701 建党节", "0707 七七事变纪念日", "0801 建军节", "0819 中国医师节", "0903 抗日战争胜利纪念日", "0910 教师节", "0918 九一八事变纪念日", "0930 烈士纪念日",
+            "1001 国庆节", "1024 联合国日", "1108 记者节", "1204 宪法日", "1213 国家公祭日", "1220 澳门回归纪念日", "1224 平安夜", "1225 圣诞节"
+    };
+
+    //格式化日期
+    private final SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
+    private final SimpleDateFormat solarDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
+
+    /**
+     * 返回农历y年的总天数
+     */
+    private int lunarYearDays(int y) {
+        int i, sum = 348;
+        for (i = 0x8000; i > 0x8; i >>= 1) {
+            sum += ((lunarInfo[y - 1900] & i) != 0 ? 1 : 0);
+        }
+        return (sum + leapDays(y));
+    }
+
+    /**
+     * 返回农历y年m月的总天数
+     */
+    private int monthDays(int y, int m) {
+        return ((lunarInfo[y - 1900] & (0x10000 >> m)) != 0 ? 30 : 29);
+    }
+
+    /**
+     * 返回农历y年闰月的天数
+     */
+    private int leapDays(int y) {
+        if (leapMonth(y) != 0) {
+            return ((lunarInfo[y - 1900] & 0x10000) != 0 ? 30 : 29);
+        } else
+            return 0;
+    }
+
+    /**
+     * 判断y年的农历中那个月是闰月,不是闰月返回0
+     */
+    private int leapMonth(int y) {
+        return (int) (lunarInfo[y - 1900] & 0xf);
+    }
+
+    /**
+     * 获取农历年
+     */
+    private String getLunarYearString(String year) {
+        int y1 = Integer.parseInt(year.charAt(0) + "");
+        int y2 = Integer.parseInt(year.charAt(1) + "");
+        int y3 = Integer.parseInt(year.charAt(2) + "");
+        int y4 = Integer.parseInt(year.charAt(3) + "");
+        return lunarYears[y1] + lunarYears[y2] + lunarYears[y3] + lunarYears[y4];
+    }
+
+    /**
+     * 获取农历日
+     */
+    private String getLunarDayString(int day) {
+        if (day > 30)
+            return "";
+
+        int n = day % 10 == 0 ? 9 : day % 10 - 1;
+        if (day == 10) {
+            return "初十";
+        } else if (day == 20) {
+            return "二十";
+        } else {
+            return chineseTen[day / 10] + lunarNumber[n];
+        }
+    }
+
+    /**
+     * 特例,特殊的年份的节气偏移量,由于公式并不完善,所以算出的个别节气的第几天数并不准确,在此返回其偏移量
+     *
+     * @param year 年份
+     * @param n    节气编号
+     * @return 返回其偏移量
+     */
+    private int specialYearOffset(int year, int n) {
+        int offset = 0;
+        offset += getOffset(DECREASE_OFFSETMAP, year, n, -1);
+        offset += getOffset(INCREASE_OFFSETMAP, year, n, 1);
+        return offset;
+    }
+
+    /**
+     * 节气偏移量计算
+     */
+    private int getOffset(Map<Integer, Integer[]> map, int year, int n, int offset) {
+        int off = 0;
+        Integer[] years = map.get(n);
+        if (null != years) {
+            for (int i : years) {
+                if (i == year) {
+                    off = offset;
+                    break;
+                }
+            }
+        }
+        return off;
+    }
+
+    /**
+     * 获取某年的第n个节气为几日(从0小寒起算)
+     */
+    private int sTerm(int year, int n) {
+        int centuryIndex;
+        if (year >= 1901 && year < 2000) {//20世纪
+            centuryIndex = 0;
+        } else if (year == 2000) {//20或21世纪
+            if (n < 4) {
+                centuryIndex = 0;
+            } else {
+                centuryIndex = 1;
+            }
+        } else if (year >= 2001 && year < 2100) {//21世纪
+            centuryIndex = 1;
+        } else {
+            // throw new RuntimeException("不支持此年份:" + year + ",目前只支持1901年到2100年的时间范围");
+            return -1;
+        }
+        double centuryValue = CENTURY_ARRAY[centuryIndex][n];//节气的世纪值,每个节气的每个世纪值都不同
+
+        int Y = year % 100;//步骤1,取年份的后两位数
+        int L = Y / 4;//步骤2,闰年数
+        if (n < 4) {
+            //L:L=Y/4,小寒、大寒、立春、雨水的L=(Y-1)/4
+            L = (Y - 1) / 4;
+        }
+        int dateNum = (int) (Y * D + centuryValue) - L;//步骤3,计算通式寿星公式=[Y*D+C]-L
+        dateNum += specialYearOffset(year, n);//步骤4,加上特殊的年份的节气偏移量
+        return dateNum;
+    }
+
+    /**
+     * 母亲节和父亲节
+     */
+    private String getMotherOrFatherDay(int year, int month, int day) {
+        if (month != 5 && month != 6) return null;
+        if ((month == 5 && (day < 8 || day > 14)) || (month == 6 && (day < 15 || day > 21))) return null;
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(year, month - 1, 1);
+        int weekDate = calendar.get(Calendar.DAY_OF_WEEK);
+        weekDate = (weekDate == 1) ? 7 : weekDate - 1;
+        switch (month) {
+            case 5:
+                if (day == 15 - weekDate) {
+                    return "母亲节";
+                }
+                break;
+            case 6:
+                if (day == 22 - weekDate) {
+                    return "父亲节";
+                }
+                break;
+        }
+        return null;
+    }
+
+    /**
+     * 感恩节
+     */
+    private String thanksgiving(int year, int month, int day) {
+        if (month != 11) return null;
+        if ((month == 11 && (day < 19 || day > 28))) return null;
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(year, month - 1, 1);
+        int weekDate = calendar.get(Calendar.DAY_OF_WEEK);
+        weekDate = (weekDate == 1) ? 7 : weekDate - 1;
+        switch (month) {
+            case 11:
+                if (day == 29 - weekDate + 4) {
+                    return "感恩节";
+                }
+                break;
+        }
+        return null;
+    }
+
+    /**
+     * 输入公历日期初始化当前日期的生肖、天干地支、农历年、农历月、农历日、公历节日、农历节日、24节气
+     * 输入日期的格式为(YYYY-MM-DD)
+     */
+    public void initLunarCalendarInfo(String currentDate) {
+        //基准日期
+        Date baseDate = null;
+        //当前日期
+        Date nowDay = null;
+        try {
+            baseDate = chineseDateFormat.parse("1900年1月31日");//春节
+            nowDay = solarDateFormat.parse(currentDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        // 获取当前日期与1900年1月31日相差的天数
+        int offset = (int) ((nowDay.getTime() - baseDate.getTime()) / 86400000L);
+
+        //用offset减去每农历年的天数,计算当天是农历第几天,iYear最终结果是农历的年份
+        int iYear;
+        int daysOfYear = 0;
+        for (iYear = 1900; iYear < 10000 && offset > 0; iYear++) {
+            daysOfYear = lunarYearDays(iYear);
+            offset -= daysOfYear;
+        }
+        if (offset < 0) {
+            offset += daysOfYear;
+            iYear--;
+        }
+        //设置生肖
+        this.animal = animals[(iYear - 4) % 12];
+        //设置天干地支
+        int num = iYear - 1900 + 36;
+        this.ganZhiYear = (tianGan[num % 10] + diZhi[num % 12]);
+        //设置农历年份
+        this.lunarYear = getLunarYearString(iYear + "");
+
+        boolean leap = false;
+        int leapMonth = leapMonth(iYear); // 闰哪个月,1-12
+        // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
+        int iMonth;
+        int daysOfMonth = 0;
+        for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
+            // 闰月
+            if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
+                --iMonth;
+                leap = true;
+                daysOfMonth = leapDays(iYear);
+            } else {
+                daysOfMonth = monthDays(iYear, iMonth);
+            }
+
+            offset -= daysOfMonth;
+            // 解除闰月
+            if (leap && iMonth == (leapMonth + 1)) {
+                leap = false;
+            }
+        }
+        // offset为0时,并且刚才计算的月份是闰月,要校正
+        if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
+            if (leap) {
+                leap = false;
+            } else {
+                leap = true;
+                --iMonth;
+            }
+        }
+        // offset小于0时,也要校正
+        if (offset < 0) {
+            offset += daysOfMonth;
+            --iMonth;
+        }
+        // 设置对应的农历月份
+        this.lunarMonth = lunarMonths[iMonth - 1];
+        if (leap) {
+            this.lunarMonth = "闰" + this.lunarMonth;
+        }
+
+        //设置农历日
+        int iDay = offset + 1;
+        this.lunarDay = getLunarDayString(iDay);
+
+        String[] splitDate = currentDate.split("-");
+        // 公历年月日
+        int year = Integer.parseInt(splitDate[0]);
+        int month = Integer.parseInt(splitDate[1]);
+        int day = Integer.parseInt(splitDate[2]);
+        //设置节气
+        if (day == sTerm(year, (month - 1) * 2)) {
+            this.lunarTerm = solarTerms[(month - 1) * 2];
+        } else if (day == sTerm(year, (month - 1) * 2 + 1)) {
+            this.lunarTerm = solarTerms[(month - 1) * 2 + 1];
+        } else {
+            this.lunarTerm = "";
+        }
+
+        //设置公历节日
+        String solarFestival = "";
+        for (int i = 0; i < solarHoliday.length; i++) {
+            // 返回公历节假日名称
+            String sd = solarHoliday[i].split(" ")[0]; // 节假日的日期
+            String sdv = solarHoliday[i].split(" ")[1]; // 节假日的名称
+            String currentSM = month + "";
+            if (month < 10) {
+                currentSM = "0" + month;
+            }
+            String currentSD = day + "";
+            if (day < 10) {
+                currentSD = "0" + day;
+            }
+            String currentSMD = currentSM + currentSD;
+            if (sd.trim().equals(currentSMD.trim())) {
+                solarFestival = sdv;
+                break;
+            }
+        }
+        //判断节日是否是父亲节或母亲节
+        String motherOrFatherDay = getMotherOrFatherDay(year, month, day);
+        if (motherOrFatherDay != null) {
+            solarFestival = motherOrFatherDay;
+        }
+        //判断节日是否是感恩节
+        String thanksgiving = thanksgiving(year, month, day);
+        if (thanksgiving != null) {
+            solarFestival = thanksgiving;
+        }
+        this.solarFestival = solarFestival;
+
+        //设置农历节日
+        String lunarFestival = "";
+        for (int i = 0; i < lunarHoliday.length; i++) {
+            //农历闰月节日
+            if (leap) {
+                break;
+            }
+            // 返回农历节假日名称
+            String ld = lunarHoliday[i].split(" ")[0]; // 节假日的日期
+            String ldv = lunarHoliday[i].split(" ")[1]; // 节假日的名称
+            String currentLM = iMonth + "";
+            if (iMonth < 10) {
+                currentLM = "0" + iMonth;
+            }
+            String currentLD = iDay + "";
+            if (iDay < 10) {
+                currentLD = "0" + iDay;
+            }
+            String currentLMD = currentLM + currentLD;
+            if (ld.trim().equals(currentLMD.trim())) {
+                lunarFestival = ldv;
+                break;
+            }
+            if ("12".equals(currentLM) && iDay == daysOfMonth) { // 除夕夜需要特殊处理
+                lunarFestival = "除夕";
+                break;
+            }
+        }
+        if ("清明".equals(this.lunarTerm)) {
+            lunarFestival = "清明节";
+        }
+        this.lunarFestival = lunarFestival;
+    }
+
+    public static void main(String[] args) {
+        LunarCalendarFestivalUtils festival = new LunarCalendarFestivalUtils();
+        festival.initLunarCalendarInfo(String.valueOf(LocalDate.now()));
+        System.out.println("农历:" + festival.lunarYear + "年 " + festival.lunarMonth + "月" + festival.lunarDay + "日");
+        System.out.println(festival.ganZhiYear + "【" + festival.animal + "】年");
+        System.out.println("节气:" + festival.lunarTerm);
+        System.out.println("农历节日:" + festival.lunarFestival);
+        System.out.println("公历节日:" + festival.solarFestival);
+    }
+
+    public static JSONObject isSpecialDate() {
+        LunarCalendarFestivalUtils festival = new LunarCalendarFestivalUtils();
+        festival.initLunarCalendarInfo(String.valueOf(LocalDate.now()));
+        JSONObject jsonObject = new JSONObject();
+        if (festival.lunarTerm != null && !"".equals(festival.lunarTerm)) {
+            jsonObject.put("lunarTerm", festival.lunarTerm);
+        }
+        if (festival.lunarFestival != null && !"".equals(festival.lunarFestival)) {
+            jsonObject.put("lunarFestival", festival.lunarFestival);
+        }
+        if (festival.solarFestival != null && !"".equals(festival.solarFestival)) {
+            jsonObject.put("solarFestival", festival.solarFestival);
+        }
+        return jsonObject;
+    }
+
+}

+ 62 - 0
src/main/java/com/rf/conversion/utils/Result.java

@@ -0,0 +1,62 @@
+package com.rf.conversion.utils;
+
+/**
+ * @author zzf
+ * @description:
+ * @date 2021/1/18 19:27
+ */
+
+public class Result<T> {
+    /**
+     * 状态码
+     */
+    private String code;
+
+    /**
+     * 信息
+     */
+    private String msg;
+
+    /**
+     * 返回数据
+     */
+    private T data;
+
+    public Result(String code, String msg, T data) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public Result() {
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public Result(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 44 - 0
src/main/java/com/rf/conversion/utils/WebContextUtil.java

@@ -0,0 +1,44 @@
+package com.rf.conversion.utils;
+
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * @Description:线程缓存工具类
+ * @Author: mimang
+ * @Date: 2024/9/6
+ */
+public class WebContextUtil {
+    //本地线程缓存token
+    private static ThreadLocal<String> local = new ThreadLocal<>();
+
+    /**
+     * 设置token信息
+     * @param content
+     */
+    public static void setUserToken(String content){
+        removeUserToken();
+        local.set(content);
+    }
+
+    /**
+     * 获取token信息
+     * @return
+     */
+    /*public static UserEntity getUserToken(){
+        if(local.get() != null){
+            UserEntity userToken = JSONObject.parseObject(local.get() , UserEntity.class);
+            return userToken;
+        }
+        return null;
+    }*/
+
+    /**
+     * 移除token信息
+     * @return
+     */
+    public static void removeUserToken(){
+        if(local.get() != null){
+            local.remove();
+        }
+    }
+}

+ 53 - 0
src/main/resources/config/application-prod.yml

@@ -0,0 +1,53 @@
+server:
+  port: 8446
+  address: 0.0.0.0
+  ssl:
+    key-store: classpath:zhjw.hnhong-duo.com.jks
+    key-store-password: l8k3j6ngoqzd0
+    key-store-type: JKS
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: jdbc:mysql://82.157.34.244:3306/file_conversion?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
+      username: root
+      password: Mysql@.2020
+      initial-size: 5
+      min-idle: 5
+      max-active: 20
+      max-wait: 30000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select '1' from dual
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      pool-prepared-statements: true
+      max-open-prepared-statements: 20
+      max-pool-prepared-statement-per-connection-size: 20
+      filters: stat,wall
+      filter:
+        stat:
+          enabled: true
+          db-type: mysql
+          log-slow-sql: true
+          slow-sql-millis: 2000
+      stat-view-servlet:
+        url-pattern: /druid/*
+        reset-enable: false
+        login-username: testAdmin
+        login-password: asdcjiafh^&912834
+        enabled: true
+        allow:
+      web-stat-filter:
+        url-pattern: /*
+        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+        enabled: true
+        session-stat-enable: true
+#swagger 显示隐藏配置
+swagger:
+  show: true
+
+
+

+ 51 - 0
src/main/resources/config/application-test.yml

@@ -0,0 +1,51 @@
+server:
+  port: 8060
+  address: 0.0.0.0
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: jdbc:mysql://82.157.34.244:3306/file_conversion?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
+      username: root
+      password: Mysql@.2020
+      initial-size: 5
+      min-idle: 5
+      max-active: 20
+      max-wait: 30000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select '1' from dual
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      pool-prepared-statements: true
+      max-open-prepared-statements: 20
+      max-pool-prepared-statement-per-connection-size: 20
+      filters: stat,wall
+      filter:
+        stat:
+          enabled: true
+          db-type: mysql
+          log-slow-sql: true
+          slow-sql-millis: 2000
+      stat-view-servlet:
+        url-pattern: /druid/*
+        reset-enable: false
+        login-username: testAdmin
+        login-password: asdcjiafh^&912834
+        enabled: true
+        allow:
+      web-stat-filter:
+        url-pattern: /*
+        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+        enabled: true
+        session-stat-enable: true
+#swagger 显示隐藏配置
+swagger:
+  show: true
+
+
+
+
+

+ 26 - 0
src/main/resources/config/application.yml

@@ -0,0 +1,26 @@
+spring:
+  profiles:
+    active: prod
+
+  jpa:
+    hibernate:
+      ddl-auto: update
+    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+    show-sql: false
+    open-in-view: false
+  servlet:
+    multipart:
+      enabled: true
+      file-size-threshold: 2KB
+      max-request-size: 1000MB
+      max-file-size: 1000MB
+logging:
+  level:
+    org.springframework.security:
+      - debug
+      - info
+    org.springframework.web: error
+    org.hibernate.SQL: debug
+    org.hibernate.engine.QueryParameters: debug
+    org.hibernate.engine.query.HQLQueryPlan: debug
+    org.hibernate.type.descriptor.sql.BasicBinder: trace

+ 144 - 0
src/main/resources/logback.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <property name="LOG_HOME" value="./logs/%d{yyyy-MM-dd}"/>
+    <property name="LOG_NAME" value="fileConversion"/>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) |  %msg %n</pattern>
+        </layout>
+    </appender>
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+    <appender name="POSITION_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-position-sync.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <appender name="EVENT_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-event-sync.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <appender name="TRACK_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-track-sync.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <appender name="FILE_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-file-sync.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <appender name="RESTART_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-restart.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <appender name="REDIS_LOG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${LOG_NAME}-redis.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>10GB</totalSizeCap>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} | %msg%n</pattern> 
+        </encoder>
+    </appender>
+
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="FILE"/>
+    </root>
+    <logger name="com.patrol.mobile.controller" level="info" additivity="false">
+        <appender-ref ref="CONSOLE"/>
+    </logger>
+
+    <logger name="POSITION_LOG" level="info" additivity="false">
+        <appender-ref ref="POSITION_LOG_APPENDER"/>
+    </logger>
+    <logger name="EVENT_LOG" level="info" additivity="false">
+        <appender-ref ref="EVENT_LOG_APPENDER"/>
+    </logger>
+    <logger name="TRACK_LOG" level="info" additivity="false">
+        <appender-ref ref="TRACK_LOG_APPENDER"/>
+    </logger>
+    <logger name="FILE_LOG" level="info" additivity="false">
+        <appender-ref ref="FILE_LOG_APPENDER"/>
+    </logger>
+    <logger name="RESTART_LOG" level="info" additivity="false">
+        <appender-ref ref="RESTART_LOG_APPENDER"/>
+    </logger>
+    <logger name="REDIS_LOG" level="info" additivity="false">
+        <appender-ref ref="REDIS_LOG_APPENDER"/>
+    </logger>
+</configuration>

+ 28 - 0
src/main/resources/proguard.conf

@@ -0,0 +1,28 @@
+-ignorewarnings
+-keepdirectories
+
+-keep interface com.your_package.** { *; }
+-keep class com.your_package.main{ *; }
+-keep class com.your_package.model.** { *; }
+
+-keepparameternames
+-keepclassmembers @org.springframework.** class * {
+    *;
+}
+
+-keepclassmembers @org.springframework.** interface * {
+    *;
+}
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep @org.springframework.** class *
+-keepclassmembers @javax.** class * { *; }
+
+-dontwarn org.springframework.**
+-dontwarn javax.**
+-dontwarn org.yaml.snakeyaml.**
+-dontwarn okhttp3.**

BIN
src/main/resources/zhjw.hnhong-duo.com.jks


BIN
userAvatar/man1.png


BIN
userAvatar/man2.png


BIN
userAvatar/man3.png


BIN
userAvatar/woman1.png


BIN
userAvatar/woman2.png


BIN
userAvatar/woman3.png