Browse Source

first commit

15810770710@163.com 3 years ago
parent
commit
7a6f89dfdf
37 changed files with 2079 additions and 0 deletions
  1. 118 0
      .mvn/wrapper/MavenWrapperDownloader.java
  2. 2 0
      .mvn/wrapper/maven-wrapper.properties
  3. 19 0
      HELP.md
  4. BIN
      logs/charge/client/2021-11/charge-2021-11-08.0.log.gz
  5. 1 0
      logs/charge/client/charge.log
  6. BIN
      logs/charge/original/2021-11/charge-2021-11-08.0.log.gz
  7. 1 0
      logs/charge/original/charge.log
  8. 0 0
      logs/error/error.log
  9. BIN
      logs/source/2021-11/source-2021-11-08.0.log.gz
  10. 38 0
      logs/source/source.log
  11. 310 0
      mvnw
  12. 182 0
      mvnw.cmd
  13. 96 0
      pom.xml
  14. 13 0
      src/main/java/com/jkcredit/location/LocationInfoApplication.java
  15. 30 0
      src/main/java/com/jkcredit/location/action/LocationAction.java
  16. 66 0
      src/main/java/com/jkcredit/location/action/TokenAction.java
  17. 48 0
      src/main/java/com/jkcredit/location/constant/CommonConstant.java
  18. 123 0
      src/main/java/com/jkcredit/location/enums/DigestALGEnum.java
  19. 21 0
      src/main/java/com/jkcredit/location/enums/UserInfoEnum.java
  20. 53 0
      src/main/java/com/jkcredit/location/filter/RequestCheckFilter.java
  21. 33 0
      src/main/java/com/jkcredit/location/handler/GlobalExceptionHandler.java
  22. 17 0
      src/main/java/com/jkcredit/location/model/CommonResponseObject.java
  23. 29 0
      src/main/java/com/jkcredit/location/model/HistoryLocationRequestObject.java
  24. 47 0
      src/main/java/com/jkcredit/location/model/HistoryLocationResponseObject.java
  25. 16 0
      src/main/java/com/jkcredit/location/model/TokenResponseObject.java
  26. 16 0
      src/main/java/com/jkcredit/location/model/UserObject.java
  27. 13 0
      src/main/java/com/jkcredit/location/service/LocationService.java
  28. 11 0
      src/main/java/com/jkcredit/location/service/TokenService.java
  29. 249 0
      src/main/java/com/jkcredit/location/service/impl/LocationServiceImpl.java
  30. 148 0
      src/main/java/com/jkcredit/location/service/impl/TokenServiceImpl.java
  31. 124 0
      src/main/java/com/jkcredit/location/util/ApiDigestUtil.java
  32. 62 0
      src/main/java/com/jkcredit/location/util/JwtTokenUtil.java
  33. 50 0
      src/main/java/com/jkcredit/location/util/RxUtil.java
  34. 11 0
      src/main/java/com/jkcredit/location/util/Test.java
  35. 15 0
      src/main/resources/application.yml
  36. 104 0
      src/main/resources/logback-spring.xml
  37. 13 0
      src/test/java/com/jkcredit/location/LocationInfoApplicationTests.java

+ 118 - 0
.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or 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.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+            + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if (mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if (mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if (!outputFile.getParentFile().exists()) {
+            if (!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}

+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

+ 19 - 0
HELP.md

@@ -0,0 +1,19 @@
+# Getting Started
+
+### Reference Documentation
+
+For further reference, please consider the following sections:
+
+* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
+* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.6/maven-plugin/reference/html/)
+* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.6/maven-plugin/reference/html/#build-image)
+* [Spring Web](https://docs.spring.io/spring-boot/docs/2.5.6/reference/htmlsingle/#boot-features-developing-web-applications)
+
+### Guides
+
+The following guides illustrate how to use some features concretely:
+
+* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
+* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
+* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
+

BIN
logs/charge/client/2021-11/charge-2021-11-08.0.log.gz


+ 1 - 0
logs/charge/client/charge.log

@@ -0,0 +1 @@
+2021-11-09 10:52:01,707 [http-nio-18000-exec-2] INFO  [CLIENT_CHARGE_LOGGER] LocationServiceImpl.java:198 - {"isCharge":true,"transationId":"5258d0ad-f0b1-4ac4-9554-8ef61eaed5a7","user":"guojiao"}

BIN
logs/charge/original/2021-11/charge-2021-11-08.0.log.gz


+ 1 - 0
logs/charge/original/charge.log

@@ -0,0 +1 @@
+2021-11-09 10:52:01,705 [http-nio-18000-exec-2] INFO  [ORIGINAL_CHARGE_LOGGER] LocationServiceImpl.java:194 - {"isCharge":true,"transationId":"5258d0ad-f0b1-4ac4-9554-8ef61eaed5a7"}

+ 0 - 0
logs/error/error.log


BIN
logs/source/2021-11/source-2021-11-08.0.log.gz


File diff suppressed because it is too large
+ 38 - 0
logs/source/source.log


+ 310 - 0
mvnw

@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  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
+  else
+    JAVACMD="`which java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 182 - 0
mvnw.cmd

@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  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,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%

+ 96 - 0
pom.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.5.6</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.jkcredit.location</groupId>
+    <artifactId>location-info</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>location-info</name>
+    <description>location-info</description>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.47</version>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <version>1.1.0.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.6</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bitbucket.b_c</groupId>
+            <artifactId>jose4j</artifactId>
+            <version>0.7.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/jkcredit/location/LocationInfoApplication.java

@@ -0,0 +1,13 @@
+package com.jkcredit.location;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class LocationInfoApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(LocationInfoApplication.class, args);
+    }
+
+}

+ 30 - 0
src/main/java/com/jkcredit/location/action/LocationAction.java

@@ -0,0 +1,30 @@
+package com.jkcredit.location.action;
+
+import com.jkcredit.location.model.CommonResponseObject;
+import com.jkcredit.location.service.LocationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@RestController
+@Slf4j
+public class LocationAction {
+    @Autowired
+    LocationService locationService;
+
+    @RequestMapping("/mrcp/gateway-ct/route/route.do")
+    public CommonResponseObject historyLocationQuery(HttpServletRequest request, @RequestBody String params) {
+        long startTime = System.currentTimeMillis();
+        CommonResponseObject responseObject = locationService.historyLocationQuery(params, request);
+        log.info("transationId:{}, costTime:{}", responseObject.getTransationId(), (System.currentTimeMillis() - startTime));
+        return responseObject;
+    }
+}

+ 66 - 0
src/main/java/com/jkcredit/location/action/TokenAction.java

@@ -0,0 +1,66 @@
+package com.jkcredit.location.action;
+
+import com.jkcredit.location.model.CommonResponseObject;
+import com.jkcredit.location.model.TokenResponseObject;
+import com.jkcredit.location.service.TokenService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@RestController
+public class TokenAction {
+    @Autowired
+    TokenService tokenService;
+
+    @RequestMapping("/tokenNotExist")
+    public CommonResponseObject tokenNotExist(HttpServletRequest request) {
+        /**
+         * {
+         *     "accessId": "",
+         *     "resultCode": 9953,
+         *     "resultBody": "token值不存在",
+         *     "transationId": "0738a2f3a4595e53"
+         * }
+         */
+        CommonResponseObject responseObject = new CommonResponseObject();
+        responseObject.setAccessId("");
+        responseObject.setResultCode(9953);
+        responseObject.setResultBody("token值不存在");
+        responseObject.setTransationId(request.getAttribute("transationId").toString());
+        return responseObject;
+    }
+
+    @RequestMapping("/tokenError")
+    public CommonResponseObject tokenError(HttpServletRequest request) {
+        CommonResponseObject responseObject = new CommonResponseObject();
+        responseObject.setAccessId("");
+        responseObject.setResultCode(9954);
+        responseObject.setResultBody("token不正确");
+        responseObject.setTransationId(request.getAttribute("transationId").toString());
+        return responseObject;
+    }
+
+    @GetMapping("/mrcp/gateway-ct/getToken.do")
+    public TokenResponseObject token(@RequestParam String appId, @RequestParam String appSecret) {
+        TokenResponseObject tokenResponseObject = new TokenResponseObject();
+        String token = tokenService.getToken(appId, appSecret);
+        if (StringUtils.isBlank(token)) {
+            tokenResponseObject.setCode(2002);
+        } else {
+            tokenResponseObject.setToken(token);
+            tokenResponseObject.setMessage("成功");
+            tokenResponseObject.setCode(2000);
+        }
+
+        return tokenResponseObject;
+    }
+}

+ 48 - 0
src/main/java/com/jkcredit/location/constant/CommonConstant.java

@@ -0,0 +1,48 @@
+package com.jkcredit.location.constant;
+
+import java.util.regex.Pattern;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public class CommonConstant {
+    public static final int JK_RETURN_CODE_INVALID_PARAMETER = 9909;
+    public static final String PARAMETER_NAME_ERROR = "参数名有误";
+    public static final String INVALID_PARAMETER = "参数错误";
+    public static final String CAR_NUMBER_PATTERN = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}" +
+            "[A-Z]{1}[警京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{0,1}[A-Z0-9]{4,6}[A-Z0-9挂学警港澳]{1}$";
+    public static final String DATE_REGEX = "^((19|20)[0-9]{2})-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$";
+    public static final String DATE_FORMAT = "yyyy-MM-dd";
+    public static final int JK_RETURN_CODE_MATCH = 1000;
+    public static final int JK_RETURN_CODE_NO_INFO = 1099;
+    public static final String RETURN_MESSAGE_60 = "库无";
+    public static final int JK_RETURN_CODE_OTHER_ERROR = 9901;
+    public static final String OTHER_ERROR = "查询错误";
+    public static final int CUSTOM_MONTH_LIMIT = 20;
+    public static final int ORIGINAL_MONTH_LIMIT = 10;
+    public static final String HISTORY_LOCATION_PRODUCT_ID = "30000116";
+    public static final String TOKEN_PRIVATE_KEY = "{\n" +
+            "    \"p\": \"vCQSH97Od_tpUL4_PFApKYEcMZOO2_4bY3qaX-8K_BC4SrClwNk_we9ZDL9PP5_xyPgDxBhv8dIk3TyGnu9oF8VLdKsXRwdqEigKqaHvFitpNFqNEmRMvcNSsvzv39Yeulanb7i4wJ3n11oXFwiQf6d6jBpEgDaTiMxf7ciLBbU\",\n" +
+            "    \"kty\": \"RSA\",\n" +
+            "    \"q\": \"ueZZy-wxnIaCKmca63zc2p45D0VnXJqBmQEmXqsXC_YSsuIrizZmO3--9R9THAzeCrfqfJkhP6oidce0FFKHfn7wYUds-58uQQjcgxxF93S5IIquaE2ycp1GRQgvqlrPJPXX1Juy6e2FOcKaWr9a4si2TMZhgXScQKz2sp4d_5s\",\n" +
+            "    \"d\": \"CyrjgswyS8WLNUXP66etGklVWu8ykqNLAsYiso4HiaZnVOviyCbTU5QaXhJ0pb2kyhnLnVNux3bkchHf5Vj7oDHkVo-tAOYM8jx89VJVHV2vDDDZGeY-_WBuiLRfddTSH5mMQ4ZadOJFIzjubdh6Kv-_bZ_-ZouDm-lF8hIpuDC_kg2w1hWmB1dXo6eCwODLoYj_SKH-6OJtBX2N8pXIDVbPeZc_i1B_2wtIgzz2G3uW5-9c6s5SLRr48FgXYbd9HsENZ43xo9mHKCixHSDMGGfa9XiMbJlrBsu7Z6rupfHjHTwaIM-TuZQpGu0I3eujdJWul7JHhlE4aBNyW0gUqQ\",\n" +
+            "    \"e\": \"AQAB\",\n" +
+            "    \"kid\": \"jiaokexinyong\",\n" +
+            "    \"qi\": \"RYq7h3bLoziCujVpU7-NcBKYIwWwNz9qct0f-HSRunUZun1neA-rA6PkxQ5azGCgaVZOVcr-KkSOFs-Zbfcdosfnvo7sWMSy7jBlBoyK8ebMQW6QUgP6Gtr_U2HMihqyeEb8Ts14gpJP6NBcyybRq_BNk2_nEKdzNKM1dVrqhSs\",\n" +
+            "    \"dp\": \"AXMhtJ8p5iDI0fd1U0im2IwHJJanfih6G40hTWXxJroWQXUVAeRqqlrmy8NZn_riiRLoLIWnryxYXmAOBYGAwtYhW7fJySFUfulSE7aMuhYBjIa6GY8uTDQKGhj63DWxLOxoA-NfgRR2aeFm1iWZv3IR7qxxJK_G-UHh51opQBU\",\n" +
+            "    \"dq\": \"rVqLfkhBc09Tbqs7RUHoyc0mNIFqA8bo939FAp7VHQhZI4sZQ_Z0myNjNT4CyHOPU7tx5ML_aFkFTYPu_8x-IY3KJ0zt6i7keS0ERRdGf53PTPNF9GoP8CWNc65QlLGd3T-MBu0yiEZAKD66pckvva-hoDKWlpvhYcZpPuOH4eU\",\n" +
+            "    \"n\": \"iJ9bf7kijJWfgeN61luAmHbhGBBR5pIF7cy-_ly2iNyi1DyUt8YOWw56J4Md4HlPpnktNpN6hftP_sXXJuTCdScp7oKhpXHGkpYcePcVoi7BoXhwh03jmI8rHHonYxPs56kE-TIg7-4g2pXYqO0HYdFhH3byBhzfC_D83MkU5nYl19OdmeXBHfcXsvR7csc_QHrmzB7Fa-ZWFPDXE4BY7_GYI43Ttc8kvdrdhyg6iAxkjrsc0B1zNtmOuAJMHzxTnSzivFd-CpNOu1Zj7fFxp8cfMoeZt3wi9Yp_qUp37iWw_4Vmr2UMnOk0bncJphwZMKOwqH3T0h8kw1raQly_lw\"\n" +
+            "}";
+    public static final String TOKEN_PUBLIC_KEY = "{\n" +
+            "    \"kty\": \"RSA\",\n" +
+            "    \"e\": \"AQAB\",\n" +
+            "    \"kid\": \"jiaokexinyong\",\n" +
+            "    \"n\": \"iJ9bf7kijJWfgeN61luAmHbhGBBR5pIF7cy-_ly2iNyi1DyUt8YOWw56J4Md4HlPpnktNpN6hftP_sXXJuTCdScp7oKhpXHGkpYcePcVoi7BoXhwh03jmI8rHHonYxPs56kE-TIg7-4g2pXYqO0HYdFhH3byBhzfC_D83MkU5nYl19OdmeXBHfcXsvR7csc_QHrmzB7Fa-ZWFPDXE4BY7_GYI43Ttc8kvdrdhyg6iAxkjrsc0B1zNtmOuAJMHzxTnSzivFd-CpNOu1Zj7fFxp8cfMoeZt3wi9Yp_qUp37iWw_4Vmr2UMnOk0bncJphwZMKOwqH3T0h8kw1raQly_lw\"\n" +
+            "}";
+    public static final String KEY_ID = "jiaokexinyong";
+    /**
+     * 月调用量redis key*/
+    public static final String MONTH_CHARGE_COUNT = "month_charge_count";
+    public static final String PRODUCT_ID = "30000116";
+}

+ 123 - 0
src/main/java/com/jkcredit/location/enums/DigestALGEnum.java

@@ -0,0 +1,123 @@
+package com.jkcredit.location.enums;
+
+/**
+ * create by Mr.Liu
+ */
+public enum DigestALGEnum {
+
+	SHA256("SHA-256","SHA256"),
+	MD5("MD5","MD5");
+	/** 枚举值 */
+	private final String code;
+
+	/** 枚举描述 */
+	private final String message;
+
+	/**
+	 *
+	 * @param code 枚举值
+	 * @param message 枚举描述
+	 */
+	private DigestALGEnum(String code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	/**
+	 * @return Returns the code.
+	 */
+	public String getCode() {
+		return code;
+	}
+
+	/**
+	 * @return Returns the message.
+	 */
+	public String getMessage() {
+		return message;
+	}
+
+	/**
+	 * @return Returns the code.
+	 */
+	public String code() {
+		return code;
+	}
+
+	/**
+	 * @return Returns the message.
+	 */
+	public String message() {
+		return message;
+	}
+
+	/**
+	 * 通过枚举<code>code</code>获得枚举
+	 *
+	 * @param code
+	 * @return IVStatusEnum
+	 */
+	public static DigestALGEnum getByCode(String code) {
+		for (DigestALGEnum _enum : values()) {
+			if (_enum.getCode().equals(code)) {
+				return _enum;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * 获取全部枚举
+	 *
+	 * @return List<IVStatusEnum>
+	 */
+	public static java.util.List<DigestALGEnum> getAllEnum() {
+		java.util.List<DigestALGEnum> list = new java.util.ArrayList<DigestALGEnum>(
+			values().length);
+		for (DigestALGEnum _enum : values()) {
+			list.add(_enum);
+		}
+		return list;
+	}
+
+	/**
+	 * 获取全部枚举值
+	 *
+	 * @return List<String>
+	 */
+	public static java.util.List<String> getAllEnumCode() {
+		java.util.List<String> list = new java.util.ArrayList<String>(values().length);
+		for (DigestALGEnum _enum : values()) {
+			list.add(_enum.code());
+		}
+		return list;
+	}
+
+	/**
+	 * 通过code获取msg
+	 * @param code 枚举值
+	 * @return
+	 */
+	public static String getMsgByCode(String code) {
+		if (code == null) {
+			return null;
+		}
+		DigestALGEnum _enum = getByCode(code);
+		if (_enum == null) {
+			return null;
+		}
+		return _enum.getMessage();
+	}
+
+	/**
+	 * 获取枚举code
+	 * @param _enum
+	 * @return
+	 */
+	public static String getCode(DigestALGEnum _enum) {
+		if (_enum == null) {
+			return null;
+		}
+		return _enum.getCode();
+	}
+}

+ 21 - 0
src/main/java/com/jkcredit/location/enums/UserInfoEnum.java

@@ -0,0 +1,21 @@
+package com.jkcredit.location.enums;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public enum UserInfoEnum {
+    INSTANCE;
+    public static ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
+
+    public static void add(String key, String value) {
+        concurrentHashMap.put(key, value);
+    }
+
+    public static ConcurrentHashMap<String, String> getInstance() {
+        return concurrentHashMap;
+    }
+}

+ 53 - 0
src/main/java/com/jkcredit/location/filter/RequestCheckFilter.java

@@ -0,0 +1,53 @@
+package com.jkcredit.location.filter;
+
+import com.jkcredit.location.service.TokenService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.catalina.connector.RequestFacade;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.UUID;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@WebFilter(urlPatterns = "/*", filterName = "requestCheckFilter")
+@Order(value = 1)
+@Component
+@Slf4j
+public class RequestCheckFilter implements Filter {
+    @Autowired
+    TokenService tokenService;
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        String transationId = UUID.randomUUID().toString();
+        servletRequest.setAttribute("transationId", transationId);
+        if (((RequestFacade) servletRequest).getRequestURI().equals("/mrcp/gateway-ct/getToken.do")) {
+            filterChain.doFilter(servletRequest, servletResponse);
+        } else {
+            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+            String xToken = httpServletRequest.getHeader("token");
+            if (StringUtils.isBlank(xToken)) {
+                // token不存在
+                servletRequest.getRequestDispatcher("/tokenNotExist").forward(servletRequest, servletResponse);
+            } else {
+                // 验证token
+                String username = tokenService.validateToken(xToken);
+                if (StringUtils.isBlank(username)) {
+                    servletRequest.getRequestDispatcher("/tokenError").forward(servletRequest, servletResponse);
+                } else {
+                    servletRequest.setAttribute("username", username);
+                    filterChain.doFilter(servletRequest, servletResponse);
+                }
+            }
+        }
+    }
+}

+ 33 - 0
src/main/java/com/jkcredit/location/handler/GlobalExceptionHandler.java

@@ -0,0 +1,33 @@
+package com.jkcredit.location.handler;
+
+import com.jkcredit.location.constant.CommonConstant;
+import com.jkcredit.location.model.CommonResponseObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@RestControllerAdvice(annotations = RestController.class)
+@Slf4j
+public class GlobalExceptionHandler {
+    @ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public CommonResponseObject errorHandler(HttpServletRequest req, Exception ex) {
+        CommonResponseObject commonResponseObject = new CommonResponseObject();
+        commonResponseObject.setResultCode(CommonConstant.JK_RETURN_CODE_OTHER_ERROR);
+        commonResponseObject.setResultBody(CommonConstant.OTHER_ERROR);
+        commonResponseObject.setTransationId(req.getAttribute("transationId").toString());
+        if (req.getAttribute("accessId") != null) {
+            commonResponseObject.setAccessId(req.getAttribute("accessId").toString());
+        }
+        log.error("transationId:{}, exception:{}", req.getAttribute("transationId").toString(), ex.getMessage());
+        return commonResponseObject;
+    }
+}

+ 17 - 0
src/main/java/com/jkcredit/location/model/CommonResponseObject.java

@@ -0,0 +1,17 @@
+package com.jkcredit.location.model;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+@ToString
+public class CommonResponseObject {
+    private Integer resultCode;
+    private String resultBody;
+    private String accessId;
+    private String transationId;
+}

+ 29 - 0
src/main/java/com/jkcredit/location/model/HistoryLocationRequestObject.java

@@ -0,0 +1,29 @@
+package com.jkcredit.location.model;
+
+import lombok.Data;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+@ToString
+public class HistoryLocationRequestObject {
+    @NotNull(message = "参数名错误")
+    private String productId;
+    @NotNull(message = "参数名错误")
+    private String accessId;
+    @NotNull(message = "参数名错误")
+    private HistoryLocationCustomBody customBody;
+
+    @Data
+    public static class HistoryLocationCustomBody {
+        @NotNull(message = "参数名错误")
+        private String plateNum;
+        @NotNull(message = "参数名错误")
+        private String time;
+    }
+}

+ 47 - 0
src/main/java/com/jkcredit/location/model/HistoryLocationResponseObject.java

@@ -0,0 +1,47 @@
+package com.jkcredit.location.model;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.List;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+@ToString
+public class HistoryLocationResponseObject {
+    /**code*/
+    private String code;
+
+    /**响应描述*/
+    private String msg;
+
+    /**本次请求的订单号*/
+    private String orderNo;
+
+    /**返回的数据,详见每个接口说明*/
+    private HistoryLocationResponseData data;
+
+    @Data
+    public static class HistoryLocationResponseData {
+        private List<HistoryLocationResponseInfos> infos;
+    }
+    @Data
+    public static class HistoryLocationResponseInfos {
+        private String queryTime;
+        private List<HistoryLocationResponseDetails> trackDetails;
+    }
+    @Data
+    public static class HistoryLocationResponseDetails {
+        private String lat;
+        private String lon;
+        private String gtm;
+        private String spd;
+        private String mlg;
+        private String hgt;
+        private String agl;
+
+    }
+}

+ 16 - 0
src/main/java/com/jkcredit/location/model/TokenResponseObject.java

@@ -0,0 +1,16 @@
+package com.jkcredit.location.model;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+@ToString
+public class TokenResponseObject {
+    private int code;
+    private String message;
+    private String token;
+}

+ 16 - 0
src/main/java/com/jkcredit/location/model/UserObject.java

@@ -0,0 +1,16 @@
+package com.jkcredit.location.model;
+
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@ToString
+@Data
+public class UserObject {
+    private String appId;
+    private String appSecret;
+    private String username;
+}

+ 13 - 0
src/main/java/com/jkcredit/location/service/LocationService.java

@@ -0,0 +1,13 @@
+package com.jkcredit.location.service;
+
+import com.jkcredit.location.model.CommonResponseObject;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public interface LocationService {
+    CommonResponseObject historyLocationQuery(String params, HttpServletRequest request);
+}

+ 11 - 0
src/main/java/com/jkcredit/location/service/TokenService.java

@@ -0,0 +1,11 @@
+package com.jkcredit.location.service;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public interface TokenService {
+    String getToken(String appId, String appSecret);
+
+    String validateToken(String token);
+}

+ 249 - 0
src/main/java/com/jkcredit/location/service/impl/LocationServiceImpl.java

@@ -0,0 +1,249 @@
+package com.jkcredit.location.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jkcredit.location.constant.CommonConstant;
+import com.jkcredit.location.enums.DigestALGEnum;
+import com.jkcredit.location.model.CommonResponseObject;
+import com.jkcredit.location.model.HistoryLocationRequestObject;
+import com.jkcredit.location.model.HistoryLocationResponseObject;
+import com.jkcredit.location.service.LocationService;
+import com.jkcredit.location.util.ApiDigestUtil;
+import com.jkcredit.location.util.RxUtil;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Slf4j
+@Service
+public class LocationServiceImpl implements LocationService {
+    @Value("${supplier.uid}")
+    private String uid;
+    @Value("${supplier.key}")
+    private String key;
+    @Value("${supplier.vehicleTrajectoryQueryOneUrl}")
+    private String vehicleTrajectoryQueryOneUrl;
+
+    private OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
+    private static final Log CLIENT_CHARGE_LOGGER = LogFactory.getLog("CLIENT_CHARGE_LOGGER");
+    private static final Log ORIGINAL_CHARGE_LOGGER = LogFactory.getLog("ORIGINAL_CHARGE_LOGGER");
+
+    @Autowired
+    private ObjectMapper objectMapper;
+    @Autowired
+    StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public CommonResponseObject historyLocationQuery(String params, HttpServletRequest request) {
+        CommonResponseObject responseObject = new CommonResponseObject();
+        String username = request.getAttribute("username").toString();
+        String transationId = request.getAttribute("transationId").toString();
+        log.info("transationId:{};requestParams:{};user:{}", transationId, params, username);
+        responseObject.setTransationId(transationId);
+        HistoryLocationRequestObject requestObject = JSON.toJavaObject(JSON.parseObject(params),
+                HistoryLocationRequestObject.class);
+        responseObject.setAccessId(requestObject.getAccessId());
+        request.setAttribute("accessId", requestObject.getAccessId());
+        // 参数校验
+        if (!validateRequestParams(responseObject, requestObject)) {
+            return responseObject;
+        }
+        //生成签名
+        Map<String, String> map = new HashMap<>();
+        map.put("vclN", requestObject.getCustomBody().getPlateNum());
+        map.put("qryTm", requestObject.getCustomBody().getTime());
+        map.put("uid", uid);
+        String sign = ApiDigestUtil.execute(map, key, DigestALGEnum.MD5, "UTF-8");
+        map.put("sign", sign);
+        MediaType mediaType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE);
+        String jsonStr = JSON.toJSONString(map);
+        log.info("transationId:{}, requestOriginalParam:{}", transationId, jsonStr);
+        RequestBody requestBody = RequestBody.create(mediaType, jsonStr);
+        Request okRequest = new Request.Builder().post(requestBody).url(vehicleTrajectoryQueryOneUrl).build();
+        OkHttpClient client = okHttpClient.newBuilder()
+                .sslSocketFactory(RxUtil.createSSLSocketFactory(), new RxUtil.TrustAllManager())
+                .connectTimeout(1500, TimeUnit.MILLISECONDS)
+                .readTimeout(5000, TimeUnit.MILLISECONDS)
+                .writeTimeout(5000, TimeUnit.MILLISECONDS)
+                .build();
+        String responseContext = "";
+        try {
+            Long startTime = System.currentTimeMillis();
+            Response response = client.newCall(okRequest).execute();
+            responseContext = response.body().string();
+            JSONObject responseJson = JSON.parseObject(responseContext);
+            responseJson.remove("data");
+            log.info("transationId:{}, response:{}, costTime:{}", transationId, JSON.toJSONString(responseJson),
+                    (System.currentTimeMillis() - startTime));
+            response.close();
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+            log.error("transationId:{}, exception:{}", transationId, ioe.getMessage());
+        }
+
+        try {
+            HistoryLocationResponseObject historyLocationResponseObject = objectMapper.readValue(responseContext,
+                    HistoryLocationResponseObject.class);
+            if (responseObject != null) {
+                setCarHistoricalTrajectoryResponse(responseObject, historyLocationResponseObject);
+                if (responseObject.getResultCode() == CommonConstant.JK_RETURN_CODE_MATCH) {
+                    chargeHandle(requestObject, username, transationId);
+                }
+            } else {
+                responseObject.setResultCode(CommonConstant.JK_RETURN_CODE_OTHER_ERROR);
+                responseObject.setResultBody(CommonConstant.OTHER_ERROR);
+            }
+        } catch (JsonProcessingException e) {
+            log.error("transationId:{}, exception:{}", transationId, e.getMessage());
+            responseObject.setResultCode(CommonConstant.JK_RETURN_CODE_OTHER_ERROR);
+            responseObject.setResultBody(CommonConstant.OTHER_ERROR);
+
+        } catch (Exception e) {
+            log.error("transationId:{}, exception:{}", transationId, e.getMessage());
+            responseObject.setResultCode(CommonConstant.JK_RETURN_CODE_OTHER_ERROR);
+            responseObject.setResultBody(CommonConstant.OTHER_ERROR);
+        }
+        return responseObject;
+    }
+
+    public void chargeHandle(HistoryLocationRequestObject requestObject, String username, String transactionId) throws ParseException {
+        boolean isCharge = true;
+        int monthCount = CommonConstant.CUSTOM_MONTH_LIMIT;
+        SimpleDateFormat monthSdf = new SimpleDateFormat("yyyyMM");
+        SimpleDateFormat daySdf = new SimpleDateFormat("yyyyMMdd");
+        Date current = new Date();
+        // 当前月
+        String monthTime = monthSdf.format(current.getTime());
+        // 当天
+        String dayTime = daySdf.format(current.getTime());
+        // 入参中的查询日期
+        Date queryTime = DateUtils.parseDate(requestObject.getCustomBody().getTime(), CommonConstant.DATE_FORMAT);
+        String queryMonth = monthSdf.format(queryTime);
+        // 判断客户是否计费
+        // 判断 车牌号+待查询时间 在自然月内重复请求是否超过 包月标志位(相同车牌和相同时间参数,一个自然月内最多收 包月标志位 次)
+        long redisMonthCount = stringRedisTemplate.boundHashOps(CommonConstant.MONTH_CHARGE_COUNT)
+                .increment(username + "_" + requestObject.getCustomBody().getPlateNum() + "_" + queryMonth, 1);
+        if (redisMonthCount == 1) {
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(current);
+            int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+            cal.set(Calendar.DAY_OF_MONTH, lastDay);
+            cal.set(Calendar.HOUR_OF_DAY, 23);
+            cal.set(Calendar.MINUTE, 59);
+            cal.set(Calendar.SECOND, 59);
+            stringRedisTemplate.boundHashOps(CommonConstant.MONTH_CHARGE_COUNT).expireAt(cal.getTime());
+        }
+        if (monthCount != -1 && redisMonthCount > monthCount) {
+            isCharge = false;
+        }
+
+        // 判断上游是否计费
+        boolean isDataOriginCharge = true;
+        // 判断 车牌号+待查询时间 在自然天内是否重复请求(相同车牌和相同时间参数,当天查询不重复收费)
+        String redisDateKey = requestObject.getCustomBody().getPlateNum() + "_" + queryTime + "_" + dayTime;
+        if (!stringRedisTemplate.boundValueOps(redisDateKey).setIfAbsent("1")) {
+            // 当天相同参数,重复查询,上游不计费
+            isDataOriginCharge = false;
+        } else {
+            stringRedisTemplate.boundValueOps(redisDateKey).expire(1, TimeUnit.DAYS);
+
+            // 判断 车牌号+待查询时间 在自然月内重复请求是否超过10次(相同车牌和相同时间参数,一个自然月内最多收10次)
+            long dataOriginRedisMonthCount = stringRedisTemplate.boundHashOps(CommonConstant.MONTH_CHARGE_COUNT)
+                    .increment(requestObject.getCustomBody().getPlateNum() + "_" + queryMonth, 1);
+            if (dataOriginRedisMonthCount == 1) {
+                Calendar cal = Calendar.getInstance();
+                cal.setTime(current);
+                int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+                cal.set(Calendar.DAY_OF_MONTH, lastDay);
+                cal.set(Calendar.HOUR_OF_DAY, 23);
+                cal.set(Calendar.MINUTE, 59);
+                cal.set(Calendar.SECOND, 59);
+                stringRedisTemplate.boundHashOps(CommonConstant.MONTH_CHARGE_COUNT).expireAt(cal.getTime());
+            }
+            if (dataOriginRedisMonthCount > CommonConstant.ORIGINAL_MONTH_LIMIT) {
+                // 上游不计费
+                isDataOriginCharge = false;
+            }
+        }
+        // 上游是否计费标识
+        JSONObject chargeObject = new JSONObject();
+        chargeObject.put("transationId", transactionId);
+        chargeObject.put("isCharge", isDataOriginCharge);
+        ORIGINAL_CHARGE_LOGGER.info(chargeObject.toJSONString());
+
+        chargeObject.put("isCharge", isCharge);
+        chargeObject.put("user", username);
+        CLIENT_CHARGE_LOGGER.info(chargeObject.toJSONString());
+    }
+
+    private CommonResponseObject setCarHistoricalTrajectoryResponse(
+            CommonResponseObject ret, HistoryLocationResponseObject responseObject) {
+        if (responseObject != null
+                && "0000".equals(responseObject.getCode())) {
+            HistoryLocationResponseObject.HistoryLocationResponseInfos responseInfos = responseObject.getData().getInfos().get(0);
+            List<HistoryLocationResponseObject.HistoryLocationResponseDetails> responseDetails = responseInfos.getTrackDetails();
+            // 查询成功,返回结果
+            ret.setResultBody(JSONArray.toJSONString(responseDetails));
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_MATCH);
+        } else if (responseObject != null
+                && "0001".equals(responseObject.getCode())) {
+            // 查询成功,没有记录
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_NO_INFO);
+            ret.setResultBody(CommonConstant.RETURN_MESSAGE_60);
+        } else {
+            // 查询错误
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_OTHER_ERROR);
+            ret.setResultBody(CommonConstant.OTHER_ERROR);
+        }
+
+        return ret;
+    }
+
+    private boolean validateRequestParams(CommonResponseObject ret,
+                                          HistoryLocationRequestObject requestObject) {
+        Pattern pattern = Pattern.compile(CommonConstant.DATE_REGEX);
+        Pattern plateNumPattern = Pattern.compile(CommonConstant.CAR_NUMBER_PATTERN);
+        if (StringUtils.isBlank(requestObject.getAccessId())
+                || StringUtils.isBlank(requestObject.getProductId())
+                || requestObject.getCustomBody() == null) {
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_INVALID_PARAMETER);
+            ret.setResultBody(CommonConstant.INVALID_PARAMETER);
+            return false;
+        } else if (StringUtils.isBlank(requestObject.getCustomBody().getPlateNum())
+                || StringUtils.isBlank(requestObject.getCustomBody().getTime())
+                || !plateNumPattern.matcher(requestObject.getCustomBody().getPlateNum()).matches()
+                || !pattern.matcher(requestObject.getCustomBody().getTime()).matches()) {
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_INVALID_PARAMETER);
+            ret.setResultBody(CommonConstant.INVALID_PARAMETER);
+            return false;
+        } else if (!requestObject.getProductId().equals(CommonConstant.PRODUCT_ID)) {
+            ret.setResultCode(CommonConstant.JK_RETURN_CODE_INVALID_PARAMETER);
+            ret.setResultBody(CommonConstant.INVALID_PARAMETER);
+            return false;
+        } else {
+            return true;
+        }
+    }
+}

+ 148 - 0
src/main/java/com/jkcredit/location/service/impl/TokenServiceImpl.java

@@ -0,0 +1,148 @@
+package com.jkcredit.location.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jkcredit.location.constant.CommonConstant;
+import com.jkcredit.location.enums.UserInfoEnum;
+import com.jkcredit.location.model.UserObject;
+import com.jkcredit.location.service.TokenService;
+import com.jkcredit.location.util.JwtTokenUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jose4j.json.JsonUtil;
+import org.jose4j.jwk.RsaJsonWebKey;
+import org.jose4j.lang.JoseException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Service
+@Slf4j
+public class TokenServiceImpl implements TokenService {
+
+    @Value("${userInfoPath}")
+    private String userInfoPath;
+    @Override
+    public String getToken(String appId, String appSecret) {
+        Map<String, String> claims = new HashMap<>();
+        claims.put("appId", appId);
+        claims.put("appSecret", appSecret);
+        UserObject user = getUser(appId, appSecret);
+        String token = "";
+        if (user != null) {
+            token = JwtTokenUtil.generateToken(user.getUsername(), claims);
+        }
+        return token;
+    }
+
+    @Override
+    public String validateToken(String token) {
+        PublicKey publicKey;
+        try {
+            publicKey = new RsaJsonWebKey(JsonUtil.parseJson(CommonConstant.TOKEN_PUBLIC_KEY)).getPublicKey();
+        } catch (JoseException e) {
+            log.error("tokenParseException:", e);
+            return "";
+        }
+        Claims claims = JwtTokenUtil.parseToken(token, publicKey);
+        if (claims == null) {
+            return "";
+        }
+        String appId = claims.get("appId").toString();
+        String appSecret = claims.get("appSecret").toString();
+        String username = claims.getSubject();
+        String userInfo = UserInfoEnum.getInstance().get(appId);
+        if (userInfo != null) {
+            String[] userInfoArray = userInfo.split("&");
+            if (appSecret.equals(userInfoArray[1]) && username.equals(userInfoArray[2])) {
+                return username;
+            } else {
+                return "";
+            }
+        } else {
+            return "";
+        }
+    }
+
+    private UserObject getUser(String appId, String appSecret) {
+        UserObject userObject = new UserObject();
+        ConcurrentHashMap<String, String> users = UserInfoEnum.getInstance();
+        String user = users.get(appId);
+
+        if (StringUtils.isNotBlank(user)) {
+            String[] userInfo = user.split("&");
+            // {"appId":"26da5c7e0e3f4a0087578aed2477cf74","appSecret":"666fc","username":"guojiao"}
+            if (appSecret.equals(userInfo[1])) {
+                userObject.setAppId(userInfo[0]);
+                userObject.setAppSecret(userInfo[1]);
+                userObject.setUsername(userInfo[2]);
+                return userObject;
+            } else {
+                return null;
+            }
+
+        } else {
+            String userJson = getUserFromJsonFile();
+            if (StringUtils.isNotBlank(userJson)) {
+                JSONArray userArray = JSON.parseArray(userJson);
+                for (int i = 0; i < userArray.size(); i++) {
+                    JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(userArray.get(i)));
+                    if (appId.equals(jsonObject.getString("appId"))) {
+                        String userAppId = jsonObject.getString("appId");
+                        String userAppSecret = jsonObject.getString("appSecret");
+                        String username = jsonObject.getString("username");
+
+                        StringBuffer stringBuffer = new StringBuffer();
+                        stringBuffer.append(userAppId).append("&");
+                        stringBuffer.append(userAppSecret).append("&");
+                        stringBuffer.append(username);
+                        UserInfoEnum.add(appId, stringBuffer.toString());
+
+                        userObject.setAppId(userAppId);
+                        userObject.setAppSecret(userAppSecret);
+                        userObject.setUsername(username);
+                        return userObject;
+                    }
+                }
+            } else {
+                return null;
+            }
+            return null;
+        }
+    }
+
+    private String getUserFromJsonFile() {
+        String jsonStr = "";
+        File jsonFile = new File(userInfoPath);
+        try {
+            FileReader fileReader = new FileReader(jsonFile);
+            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
+            int ch = 0;
+            StringBuffer sb = new StringBuffer();
+            while ((ch = reader.read()) != -1) {
+                sb.append((char) ch);
+            }
+            fileReader.close();
+            reader.close();
+            jsonStr = sb.toString();
+            return jsonStr;
+
+        } catch (IOException ioe) {
+            log.error("getUserFromJsonFile.IOException:", ioe);
+            return jsonStr;
+        }
+    }
+}

+ 124 - 0
src/main/java/com/jkcredit/location/util/ApiDigestUtil.java

@@ -0,0 +1,124 @@
+package com.jkcredit.location.util;
+
+import com.jkcredit.location.enums.DigestALGEnum;
+import org.apache.commons.codec.binary.Hex;
+
+import java.security.MessageDigest;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 签名工具
+ * create by Mr.Liu
+ */
+public final class ApiDigestUtil {
+
+
+	/**
+	 * 对 dataMap 的内容进行签名,并返回签名值
+	 *
+	 * @param dataMap          待签名kv
+	 * @param securityCheckKey 安全密钥
+	 * @param de               签名算法
+	 * @param encoding         签名编码名称
+	 */
+	public static String execute(Map<String, String> dataMap, String securityCheckKey, DigestALGEnum de, String encoding) {
+		if (dataMap == null) {
+			throw new RuntimeException("数据不能为空");
+		}
+		if (securityCheckKey == null || "".equals(securityCheckKey)) {
+			throw new RuntimeException("安全校验码不能为空");
+		}
+		if (de == null) {
+			throw new RuntimeException("摘要算法不能为空");
+		}
+		if (encoding == null || "".equals(encoding)) {
+			throw new RuntimeException("字符集不能为空");
+		}
+
+		String message = sort(dataMap) + securityCheckKey;
+
+		/**执行签名**/
+		byte[] toDigest;
+		try {
+			toDigest = message.getBytes(encoding);
+			MessageDigest md = MessageDigest.getInstance(de.getCode());
+			md.update(toDigest);
+			return new String (Hex.encodeHex(md.digest()));
+		} catch (Exception e) {
+			throw new RuntimeException("签名失败", e);
+		}
+	}
+
+	/**
+	 * 排序字符串
+	 * @param paramMap
+	 * @return
+	 */
+	public static String sort(Map<String, String> paramMap) {
+		/**按a~z、A~Z排序**/
+		TreeMap<String, String> treeMap = new TreeMap<String, String>(paramMap);
+
+		/**拼接签名字符串**/
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, String> entry : treeMap.entrySet()) {
+			if ("sign".equals(entry.getKey())) {
+				continue;
+			}
+			sb.append(entry.getKey()).append("=").append(defaultIfBlank(entry.getValue(), "")).append("&");
+		}
+
+		/**整理字符串**/
+		if (sb.length() > 0) {
+			sb.setLength(sb.length() - 1);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 为空默认
+	 * @param value
+	 * @param defaultValue
+	 * @return
+	 */
+	private static String defaultIfBlank(String value, String defaultValue) {
+		if (value == null || "".equals(value)) {
+			return defaultValue;
+		} else {
+			return value;
+		}
+	}
+
+	/**
+	 * 将 Map<String, String[]> -> Map<String, String>
+	 *
+	 * @param paramMap
+	 * @return 转换完成的集合
+	 */
+	public static Map<String, String> toMap(Map<String, String[]> paramMap){
+		Map<String, String> returnMap = new HashMap<String, String>();
+		if (paramMap != null) {
+			for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
+				returnMap.put(entry.getKey(), entry.getValue()[0]);
+			}
+		}
+		return returnMap;
+
+	}
+
+	/**
+	 * 清除空元素
+	 * @param paramMap
+	 */
+	private static void clearNullValue(Map<String, String> paramMap) {
+		Iterator<Map.Entry<String, String>> it = paramMap.entrySet().iterator();
+		while(it.hasNext()){
+			Map.Entry<String, String> entry = it.next();
+			if ((entry.getValue()) == null || "".equals((entry.getValue()))) {
+				it.remove();
+			}
+		}
+	}
+}

+ 62 - 0
src/main/java/com/jkcredit/location/util/JwtTokenUtil.java

@@ -0,0 +1,62 @@
+package com.jkcredit.location.util;
+
+import com.jkcredit.location.constant.CommonConstant;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import lombok.extern.slf4j.Slf4j;
+import org.jose4j.json.JsonUtil;
+import org.jose4j.jwk.RsaJsonWebKey;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jws.JsonWebSignature;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.NumericDate;
+import org.jose4j.lang.JoseException;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.Map;
+
+@Slf4j
+public class JwtTokenUtil {
+    public static String generateToken(String subject, Map<String, String> user) {
+        JwtClaims claims = new JwtClaims();
+        claims.setGeneratedJwtId();
+        claims.setIssuedAtToNow();
+        //过期时间一定要设置,并且小于7天
+        NumericDate date = NumericDate.now();
+        date.addSeconds(30*60);
+        claims.setExpirationTime(date);
+        claims.setSubject(subject);
+        //添加自定义参数,所有值请都使用String类型
+        claims.setClaim("appId", user.get("appId"));
+        claims.setClaim("appSecret", user.get("appSecret"));
+
+        JsonWebSignature jws = new JsonWebSignature();
+        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
+        //必须设置
+        jws.setKeyIdHeaderValue(CommonConstant.KEY_ID);
+        jws.setPayload(claims.toJson());
+        String jwtResult = "";
+        try {
+            PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(CommonConstant.TOKEN_PRIVATE_KEY)).getPrivateKey();
+            jws.setKey(privateKey);
+            jwtResult = jws.getCompactSerialization();
+        } catch (JoseException e) {
+            e.printStackTrace();
+            log.error("generateToken.JoseException:", e);
+        }
+        return jwtResult;
+    }
+
+    public static Claims parseToken(String token, PublicKey salt) {
+        try {
+            Claims claims = Jwts.parser()
+                    .setSigningKey(salt)
+                    .parseClaimsJws(token).getBody();
+            return claims;
+        } catch (Exception e) {
+            log.error("parseToken.Exception:", e);
+        }
+        return null;
+    }
+}

+ 50 - 0
src/main/java/com/jkcredit/location/util/RxUtil.java

@@ -0,0 +1,50 @@
+package com.jkcredit.location.util;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.net.ssl.*;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+@Slf4j
+public class RxUtil {
+
+    public static SSLSocketFactory createSSLSocketFactory() {
+        SSLSocketFactory sSLSocketFactory = null;
+        try {
+            SSLContext sc = SSLContext.getInstance("TLS");
+            sc.init(null, new TrustManager[]{new TrustAllManager()},
+                    new SecureRandom());
+            sSLSocketFactory = sc.getSocketFactory();
+        } catch (Exception ignored) {
+            log.error("createSSLSocketFactory.Exception:", ignored);
+        }
+        return sSLSocketFactory;
+    }
+
+    public static class TrustAllManager implements X509TrustManager {
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+                throws CertificateException {
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+                throws CertificateException {
+        }
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+    }
+
+    public static class TrustAllHostnameVerifier implements HostnameVerifier {
+        @Override
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+}

+ 11 - 0
src/main/java/com/jkcredit/location/util/Test.java

@@ -0,0 +1,11 @@
+package com.jkcredit.location.util;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public class Test {
+    public static void main(String[] args) {
+        System.out.println(System.currentTimeMillis());
+    }
+}

+ 15 - 0
src/main/resources/application.yml

@@ -0,0 +1,15 @@
+spring:
+  application:
+    name: invoice-hub
+  redis:
+    host: 127.0.0.1
+    port: 6379
+    password: jiaokedata
+server:
+
+  port: 18000
+supplier:
+  uid: jiaoke
+  key: ecb35b9550704b848a243af1f0b2c740
+  vehicleTrajectoryQueryOneUrl: https://openapi.huoyancredit.com/yunwei/openapi/vehicleTrajectoryQueryOne
+userInfoPath: /usr/local/app/track/location/user.json

+ 104 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false">
+    <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
+    <property name="log.path" value="logs"/>
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex"
+                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx"
+                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+    <!-- Console log output -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log file error output -->
+    <appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/error/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/error/%d{yyyy-MM,aux}/error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>ERROR</level>
+        </filter>
+    </appender>
+
+
+    <!-- Log file debug output -->
+    <appender name="sourceLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/source/source.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/source/%d{yyyy-MM,aux}/source-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log file debug output -->
+    <appender name="clientChargeLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/charge/client/charge.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/charge/client/%d{yyyy-MM,aux}/charge-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="originalChargeLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/charge/original/charge.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/charge/original/%d{yyyy-MM,aux}/charge-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
+    <root level="INFO">
+        <appender-ref ref="console"/>
+        <appender-ref ref="sourceLog"/>
+        <appender-ref ref="errorLog"/>
+    </root>
+    <logger name="CLIENT_CHARGE_LOGGER" additivity="false">
+        <level value="INFO" />
+        <appender-ref ref="clientChargeLog" />
+    </logger>
+    <logger name="ORIGINAL_CHARGE_LOGGER" additivity="false">
+        <level value="INFO" />
+        <appender-ref ref="originalChargeLog" />
+    </logger>
+</configuration>

+ 13 - 0
src/test/java/com/jkcredit/location/LocationInfoApplicationTests.java

@@ -0,0 +1,13 @@
+package com.jkcredit.location;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class LocationInfoApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}