andyliu 7 місяців тому
батько
коміт
90971d35e1
69 змінених файлів з 4805 додано та 3 видалено
  1. 4 0
      src/main/java/com/shkpr/service/proxycenter/ProxyCenterApplication.java
  2. 52 0
      src/main/java/com/shkpr/service/proxycenter/SpringContextUtil.java
  3. 854 0
      src/main/java/com/shkpr/service/proxycenter/commtools/BytesUtils.java
  4. 354 0
      src/main/java/com/shkpr/service/proxycenter/commtools/CommTool.java
  5. 205 0
      src/main/java/com/shkpr/service/proxycenter/commtools/HttpTool.java
  6. 497 0
      src/main/java/com/shkpr/service/proxycenter/commtools/TimeTool.java
  7. 98 0
      src/main/java/com/shkpr/service/proxycenter/commtools/UZipUtils.java
  8. 45 0
      src/main/java/com/shkpr/service/proxycenter/commtools/XMLTool.java
  9. 39 0
      src/main/java/com/shkpr/service/proxycenter/configuration/CaffeineConfiguration.java
  10. 62 0
      src/main/java/com/shkpr/service/proxycenter/configuration/GlobalParamConfiguration.java
  11. 133 0
      src/main/java/com/shkpr/service/proxycenter/configuration/OkHttpClientConfig.java
  12. 44 0
      src/main/java/com/shkpr/service/proxycenter/configuration/RestTemplateConfig.java
  13. 45 0
      src/main/java/com/shkpr/service/proxycenter/configuration/RetryTemplateConfig.java
  14. 75 0
      src/main/java/com/shkpr/service/proxycenter/configuration/ScheduleTaskConfiguration.java
  15. 53 0
      src/main/java/com/shkpr/service/proxycenter/configuration/ValidatorConfiguration.java
  16. 96 0
      src/main/java/com/shkpr/service/proxycenter/configuration/WebMvcConfiguration.java
  17. 54 0
      src/main/java/com/shkpr/service/proxycenter/configuration/WebSecurityConfiguration.java
  18. 164 0
      src/main/java/com/shkpr/service/proxycenter/constants/ApiURI.java
  19. 16 0
      src/main/java/com/shkpr/service/proxycenter/constants/AttachmentPurpose.java
  20. 8 0
      src/main/java/com/shkpr/service/proxycenter/constants/AttachmentType.java
  21. 22 0
      src/main/java/com/shkpr/service/proxycenter/constants/CommAction.java
  22. 14 0
      src/main/java/com/shkpr/service/proxycenter/constants/CommDefine.java
  23. 7 0
      src/main/java/com/shkpr/service/proxycenter/constants/CommProgress.java
  24. 10 0
      src/main/java/com/shkpr/service/proxycenter/constants/CommStatus.java
  25. 37 0
      src/main/java/com/shkpr/service/proxycenter/constants/DownLoadEventFileType.java
  26. 8 0
      src/main/java/com/shkpr/service/proxycenter/constants/FeatureLikesField.java
  27. 34 0
      src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSFeatureFieldDefine.java
  28. 19 0
      src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSLayerKindDefine.java
  29. 38 0
      src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSLayerKindPPKey.java
  30. 26 0
      src/main/java/com/shkpr/service/proxycenter/constants/GisMetadataDefine.java
  31. 16 0
      src/main/java/com/shkpr/service/proxycenter/constants/GisSelfDefineTemplate.java
  32. 16 0
      src/main/java/com/shkpr/service/proxycenter/constants/LabelType.java
  33. 80 0
      src/main/java/com/shkpr/service/proxycenter/constants/LogFlagBusiType.java
  34. 16 0
      src/main/java/com/shkpr/service/proxycenter/constants/MsgNotifyDefine.java
  35. 8 0
      src/main/java/com/shkpr/service/proxycenter/constants/OrderAttRange.java
  36. 15 0
      src/main/java/com/shkpr/service/proxycenter/constants/StorageGroupType.java
  37. 37 0
      src/main/java/com/shkpr/service/proxycenter/constants/TaskQueueDataTypeEx.java
  38. 5 0
      src/main/java/com/shkpr/service/proxycenter/constants/TileMapKindDefine.java
  39. 102 0
      src/main/java/com/shkpr/service/proxycenter/constants/UploadEventFileType.java
  40. 37 0
      src/main/java/com/shkpr/service/proxycenter/constants/UrlMethodType.java
  41. 17 0
      src/main/java/com/shkpr/service/proxycenter/constants/UserCurStateType.java
  42. 53 0
      src/main/java/com/shkpr/service/proxycenter/constants/ViewContentType.java
  43. 88 0
      src/main/java/com/shkpr/service/proxycenter/controllerfilter/GrantedAuthorityImpl.java
  44. 287 0
      src/main/java/com/shkpr/service/proxycenter/controllerfilter/TokenAuthenticationService.java
  45. 78 0
      src/main/java/com/shkpr/service/proxycenter/dto/AuthTokenData.java
  46. 34 0
      src/main/java/com/shkpr/service/proxycenter/dto/ByteDataBean.java
  47. 28 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommDelRes.java
  48. 16 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommKNMBean.java
  49. 12 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommKNMListRes.java
  50. 11 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommStrListRes.java
  51. 15 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommTotalMinMax.java
  52. 21 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommUKNewRes.java
  53. 26 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommUNBean.java
  54. 23 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommUUNNewRes.java
  55. 23 0
      src/main/java/com/shkpr/service/proxycenter/dto/CommUUTNewRes.java
  56. 15 0
      src/main/java/com/shkpr/service/proxycenter/dto/KeyDataStatus.java
  57. 19 0
      src/main/java/com/shkpr/service/proxycenter/dto/LatLngBean.java
  58. 44 0
      src/main/java/com/shkpr/service/proxycenter/dto/LoginUser.java
  59. 48 0
      src/main/java/com/shkpr/service/proxycenter/dto/LoginUserRoleType.java
  60. 19 0
      src/main/java/com/shkpr/service/proxycenter/dto/RecordRes.java
  61. 27 0
      src/main/java/com/shkpr/service/proxycenter/dto/ResDataBean.java
  62. 121 0
      src/main/java/com/shkpr/service/proxycenter/dto/ResponseCode.java
  63. 65 0
      src/main/java/com/shkpr/service/proxycenter/dto/ResponseRes.java
  64. 29 0
      src/main/java/com/shkpr/service/proxycenter/dto/TObjectRes.java
  65. 46 0
      src/main/java/com/shkpr/service/proxycenter/dto/TRecordRes.java
  66. 140 0
      src/main/java/com/shkpr/service/proxycenter/globalcache/GlobalData.java
  67. 26 0
      src/main/java/com/shkpr/service/proxycenter/interfaces/URIInterceptorIntef.java
  68. 28 0
      src/main/java/com/shkpr/service/proxycenter/interfaces/sinks/LogPrintSink.java
  69. 1 3
      src/test/java/com/shkpr/service/proxycenter/V1AlamProxyCenterApplicationTests.java

+ 4 - 0
src/main/java/com/shkpr/service/proxycenter/ProxyCenterApplication.java

@@ -1,5 +1,7 @@
 package com.shkpr.service.proxycenter;
 
+import com.global.base.log.LogPrintMgr;
+import com.shkpr.service.proxycenter.interfaces.sinks.LogPrintSink;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.retry.annotation.EnableRetry;
@@ -9,6 +11,8 @@ import org.springframework.retry.annotation.EnableRetry;
 public class ProxyCenterApplication {
 
 	public static void main(String[] args) {
+		com.shkpr.service.proxycenter.globalcache.GlobalData.getInstance().setCpuCores(Runtime.getRuntime().availableProcessors());
+		LogPrintMgr.getInstance().initResWithDisruptor(/*GlobalData.getInstance().getCpuCores()*/2, 2, new LogPrintSink());//io型线程池=CPU Core*2;计算型线程池=CPU Core
 		SpringApplication.run(ProxyCenterApplication.class, args);
 	}
 

+ 52 - 0
src/main/java/com/shkpr/service/proxycenter/SpringContextUtil.java

@@ -0,0 +1,52 @@
+package com.shkpr.service.proxycenter;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+//@Lazy(false) //true为懒加载,在第一次被引用的时候才会创建;false为Spring容器在启动时会立即创建
+//若要明确指定为懒加载,则必须使用@Lazy(true),否则bean对象默认取值lazy-init="false"即@Lazy(false)
+public class SpringContextUtil implements ApplicationContextAware {
+    //Spring应用上下文环境
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextUtil.applicationContext = applicationContext;
+    }
+
+    public static ApplicationContext getApplicationContext(){
+        return applicationContext;
+    }
+
+    public static boolean containsBean(String beanName){
+        return applicationContext.containsBean(beanName);
+    }
+
+    public static boolean isSingleton(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.isSingleton(beanName);
+    }
+
+    public static Class getType(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.getType(beanName);
+    }
+
+    public static String[] getAliases(String beanName) throws NoSuchBeanDefinitionException {
+        return applicationContext.getAliases(beanName);
+    }
+
+    public static Object getBean(String beanName) throws BeansException {
+        return applicationContext.getBean(beanName);
+    }
+
+    public static <T> T getBean(Class<T> className) throws BeansException {
+        return applicationContext.getBean(className);
+    }
+
+    public static <T> T getBean(String beanName, Class<T> className) throws BeansException{
+        return applicationContext.getBean(beanName, className);
+    }
+}

+ 854 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/BytesUtils.java

@@ -0,0 +1,854 @@
+package com.shkpr.service.proxycenter.commtools;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.List;
+/**
+ * Created by Ti on 2018/8/7.
+ */
+
+/**
+ * 字节数组转换工具类
+ */
+public class BytesUtils {
+    public static final String GBK = "GBK";
+    public static final String UTF8 = "utf-8";
+    public static final char[] ascii = "0123456789ABCDEF".toCharArray();
+    private static final char[] HEX_VOCABLE = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+    /**
+     * 将short整型数值转换为字节数组
+     *
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(short data) {
+        byte[] bytes = new byte[2];
+        bytes[0] = (byte) ((data & 0xff00) >> 8);
+        bytes[1] = (byte) (data & 0xff);
+        return bytes;
+    }
+
+    /**
+     * 将字符转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(char data) {
+        byte[] bytes = new byte[2];
+        bytes[0] = (byte) (data >> 8);
+        bytes[1] = (byte) (data);
+        return bytes;
+    }
+
+    /**
+     * 将布尔值转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(boolean data) {
+        byte[] bytes = new byte[1];
+        bytes[0] = (byte) (data ? 1 : 0);
+        return bytes;
+    }
+
+    /**
+     * 将整型数值转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(int data) {
+        byte[] bytes = new byte[4];
+        bytes[0] = (byte) ((data & 0xff000000) >> 24);
+        bytes[1] = (byte) ((data & 0xff0000) >> 16);
+        bytes[2] = (byte) ((data & 0xff00) >> 8);
+        bytes[3] = (byte) (data & 0xff);
+        return bytes;
+    }
+
+    /**
+     * 将long整型数值转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(long data) {
+        byte[] bytes = new byte[8];
+        bytes[0] = (byte) ((data >> 56) & 0xff);
+        bytes[1] = (byte) ((data >> 48) & 0xff);
+        bytes[2] = (byte) ((data >> 40) & 0xff);
+        bytes[3] = (byte) ((data >> 32) & 0xff);
+        bytes[4] = (byte) ((data >> 24) & 0xff);
+        bytes[5] = (byte) ((data >> 16) & 0xff);
+        bytes[6] = (byte) ((data >> 8) & 0xff);
+        bytes[7] = (byte) (data & 0xff);
+        return bytes;
+    }
+
+    /**
+     * 将float型数值转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(float data) {
+        int intBits = Float.floatToIntBits(data);
+        return getBytes(intBits);
+    }
+
+    /**
+     * 将double型数值转换为字节数组
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(double data) {
+        long intBits = Double.doubleToLongBits(data);
+        return getBytes(intBits);
+    }
+
+    /**
+     * 将字符串按照charsetName编码格式的字节数组
+     * @param data 字符串
+     * @param charsetName 编码格式
+     * @return
+     */
+    public static byte[] getBytes(String data, String charsetName) {
+        Charset charset = Charset.forName(charsetName);
+        return data.getBytes(charset);
+    }
+
+    /**
+     * 将字节数组第0字节转换为布尔值
+     * @param bytes
+     * @return
+     */
+    public static boolean getBoolean(byte[] bytes) {
+        return bytes[0] == 1;
+    }
+
+    /**
+     * 将字节数组的第index字节转换为布尔值
+     * @param bytes
+     * @param index
+     * @return
+     */
+    public static boolean getBoolean(byte[] bytes, int index) {
+        return bytes[index] == 1;
+    }
+
+    /**
+     * 将字节数组前2字节转换为short整型数值
+     * @param bytes
+     * @return
+     */
+    public static short getShort(byte[] bytes) {
+        return (short) ((0xff00 & (bytes[0] << 8)) | (0xff & bytes[1]));
+    }
+
+    /**
+     * 将字节数组从startIndex开始的2个字节转换为short整型数值
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static short getShort(byte[] bytes, int startIndex) {
+        return (short) ((0xff00 & (bytes[startIndex] << 8)) | (0xff & bytes[startIndex + 1]));
+    }
+
+    /**
+     * 将字节数组前2字节转换为字符
+     * @param bytes
+     * @return
+     */
+    public static char getChar(byte[] bytes) {
+        return (char) ((0xff00 & (bytes[0] << 8)) | (0xff & bytes[1]));
+    }
+
+    /**
+     * 将字节数组从startIndex开始的2个字节转换为字符
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static char getChar(byte[] bytes, int startIndex) {
+        return (char) ((0xff00 & (bytes[startIndex] << 8)) | (0xff & bytes[startIndex + 1]));
+    }
+
+    /**
+     * 将字节数组前4字节转换为整型数值
+     * @param bytes
+     * @return
+     */
+    public static int getInt(byte[] bytes) {
+        return (0xff000000 & (bytes[0] << 24) | (0xff0000 & (bytes[1] << 16))
+                | (0xff00 & (bytes[2] << 8)) | (0xff & bytes[3]));
+    }
+
+    /**
+     * 将字节数组从startIndex开始的4个字节转换为整型数值
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static int getInt(byte[] bytes, int startIndex) {
+        return (0xff000000 & (bytes[startIndex] << 24)
+                | (0xff0000 & (bytes[startIndex + 1] << 16))
+                | (0xff00 & (bytes[startIndex + 2] << 8)) | (0xff & bytes[startIndex + 3]));
+    }
+
+    /**
+     * 将字节数组前8字节转换为long整型数值
+     * @param bytes
+     * @return
+     */
+    public static long getLong(byte[] bytes) {
+        return (0xff00000000000000L & ((long) bytes[0] << 56)
+                | (0xff000000000000L & ((long) bytes[1] << 48))
+                | (0xff0000000000L & ((long) bytes[2] << 40))
+                | (0xff00000000L & ((long) bytes[3] << 32))
+                | (0xff000000L & ((long) bytes[4] << 24))
+                | (0xff0000L & ((long) bytes[5] << 16))
+                | (0xff00L & ((long) bytes[6] << 8)) | (0xffL & (long) bytes[7]));
+    }
+
+    /**
+     * 将字节数组从startIndex开始的8个字节转换为long整型数值
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static long getLong(byte[] bytes, int startIndex) {
+        return (0xff00000000000000L & ((long) bytes[startIndex] << 56)
+                | (0xff000000000000L & ((long) bytes[startIndex + 1] << 48))
+                | (0xff0000000000L & ((long) bytes[startIndex + 2] << 40))
+                | (0xff00000000L & ((long) bytes[startIndex + 3] << 32))
+                | (0xff000000L & ((long) bytes[startIndex + 4] << 24))
+                | (0xff0000L & ((long) bytes[startIndex + 5] << 16))
+                | (0xff00L & ((long) bytes[startIndex + 6] << 8)) | (0xffL & (long) bytes[startIndex + 7]));
+    }
+
+    /**
+     * 将字节数组前4字节转换为float型数值
+     * @param bytes
+     * @return
+     */
+    public static float getFloat(byte[] bytes) {
+        return Float.intBitsToFloat(getInt(bytes));
+    }
+
+    /**
+     * 将字节数组从startIndex开始的4个字节转换为float型数值
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static float getFloat(byte[] bytes, int startIndex) {
+        byte[] result = new byte[4];
+        System.arraycopy(bytes, startIndex, result, 0, 4);
+        return Float.intBitsToFloat(getInt(result));
+    }
+
+    /**
+     * 将字节数组前8字节转换为double型数值
+     * @param bytes
+     * @return
+     */
+    public static double getDouble(byte[] bytes) {
+        long l = getLong(bytes);
+        return Double.longBitsToDouble(l);
+    }
+
+    /**
+     * 将字节数组从startIndex开始的8个字节转换为double型数值
+     * @param bytes
+     * @param startIndex
+     * @return
+     */
+    public static double getDouble(byte[] bytes, int startIndex) {
+        byte[] result = new byte[8];
+        System.arraycopy(bytes, startIndex, result, 0, 8);
+        long l = getLong(result);
+        return Double.longBitsToDouble(l);
+    }
+
+    /**
+     * 将charsetName编码格式的字节数组转换为字符串
+     * @param bytes
+     * @param charsetName
+     * @return
+     */
+    public static String getString(byte[] bytes, String charsetName) {
+        return new String(bytes, Charset.forName(charsetName));
+    }
+
+    /**
+     * 将GBK编码格式的字节数组转换为字符串
+     * @param bytes
+     * @return
+     */
+    public static String getString(byte[] bytes) {
+        return getString(bytes, GBK);
+    }
+
+    /**
+     * 将字节数组转换为16进制字符串
+     * @param src
+     * @return
+     */
+    public static String bytesToHexString(byte[] src){
+        StringBuilder stringBuilder = new StringBuilder("");
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        for (int i = 0; i < src.length; i++) {
+            int v = src[i] & 0xFF;
+            String hv = Integer.toHexString(v);
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString().toUpperCase();
+    }
+
+    /**
+     * 将16进制字符串转换为字节数组
+     * @param hexString
+     * @return
+     */
+    public static byte[] hexStringToBytes(String hexString) {
+        if (hexString == null || hexString.equals("")) {
+            return null;
+        }
+        hexString = hexString.toUpperCase();
+        int length = hexString.length() / 2;
+        char[] hexChars = hexString.toCharArray();
+        byte[] d = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2;
+            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+        }
+        return d;
+    }
+
+    /**
+     * 将16进制字符转换为字节
+     * @param c
+     * @return
+     */
+    private static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+    /**
+     * 将16进制字符串转换为字节数组
+     *
+     * @param hex
+     * @return
+     */
+    /*public static byte[] hexToBytes(String hex) {
+        if (hex.length() % 2 != 0)
+            throw new IllegalArgumentException(
+                    "input string should be any multiple of 2!");
+        hex.toUpperCase();
+
+        byte[] byteBuffer = new byte[hex.length() / 2];
+
+        byte padding = 0x00;
+        boolean paddingTurning = false;
+        for (int i = 0; i < hex.length(); i++) {
+            if (paddingTurning) {
+                char c = hex.charAt(i);
+                int index = indexOf(hex, c);
+                padding = (byte) ((padding << 4) | index);
+                byteBuffer[i / 2] = padding;
+                padding = 0x00;
+                paddingTurning = false;
+            } else {
+                char c = hex.charAt(i);
+                int index = indexOf(hex, c);
+                padding = (byte) (padding | index);
+                paddingTurning = true;
+            }
+
+        }
+        return byteBuffer;
+    }
+
+    private static int indexOf(String input, char c) {
+        int index = ArrayUtils.indexOf(HEX_VOCABLE, c);
+
+        if (index < 0) {
+            throw new IllegalArgumentException("err input:" + input);
+        }
+        return index;
+
+    }*/
+
+    /**
+     * 将BCD编码的字节数组转换为字符串
+     * @param bcds
+     * @return
+     */
+    public static String bcdToString(byte[] bcds) {
+        if (bcds == null || bcds.length == 0) {
+            return null;
+        }
+        byte[] temp = new byte[2 * bcds.length];
+        for (int i = 0; i < bcds.length; i++) {
+            temp[i * 2] = (byte) ((bcds[i] >> 4) & 0x0f);
+            temp[i * 2 + 1] = (byte) (bcds[i] & 0x0f);
+        }
+        StringBuffer res = new StringBuffer();
+        for (int i = 0; i < temp.length; i++) {
+            res.append(ascii[temp[i]]);
+        }
+        return res.toString();
+    }
+
+    /**
+     * 字节转整形
+     * @param value
+     * @return
+     */
+    public static int bcdToInt(byte value){
+        return ((value>>4) * 10) + (value&0x0F);
+    }
+
+    /**
+     * 字节数组转16进制字符串
+     * @param bs
+     * @return
+     */
+    public static String bytesToHex(byte[] bs) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b : bs) {
+            int high = (b >> 4) & 0x0f;
+            int low = b & 0x0f;
+            sb.append(HEX_VOCABLE[high]);
+            sb.append(HEX_VOCABLE[low]);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 字节数组取前len个字节转16进制字符串
+     * @param bs
+     * @param len
+     * @return
+     */
+    public static String bytesToHex(byte[] bs, int len) {
+        StringBuilder sb = new StringBuilder();
+        for (int i=0; i<len; i++ ) {
+            byte b = bs[i];
+            int high = (b >> 4) & 0x0f;
+            int low = b & 0x0f;
+            sb.append(HEX_VOCABLE[high]);
+            sb.append(HEX_VOCABLE[low]);
+        }
+        return sb.toString();
+    }
+    /**
+     * 字节数组偏移offset长度之后的取len个字节转16进制字符串
+     * @param bs
+     * @param offset
+     * @param len
+     * @return
+     */
+    public static String bytesToHex(byte[] bs, int offset, int len) {
+        StringBuilder sb = new StringBuilder();
+        for (int i=0; i<len; i++ ) {
+            byte b = bs[offset + i];
+            int high = (b >> 4) & 0x0f;
+            int low = b & 0x0f;
+            sb.append(HEX_VOCABLE[high]);
+            sb.append(HEX_VOCABLE[low]);
+        }
+        return sb.toString();
+    }
+    /**
+     * 字节转16进制字符串
+     * @return
+     */
+    public static String byteToHex(byte b) {
+        StringBuilder sb = new StringBuilder();
+        int high = (b >> 4) & 0x0f;
+        int low = b & 0x0f;
+        sb.append(HEX_VOCABLE[high]);
+        sb.append(HEX_VOCABLE[low]);
+        return sb.toString();
+    }
+    /**
+     * 将字节数组取反
+     * @param src
+     * @return
+     */
+    public static String negate(byte[] src) {
+        if (src == null || src.length == 0) {
+            return null;
+        }
+        byte[] temp = new byte[2 * src.length];
+        for (int i = 0; i < src.length; i++) {
+            byte tmp = (byte) (0xFF ^ src[i]);
+            temp[i * 2] = (byte) ((tmp >> 4) & 0x0f);
+            temp[i * 2 + 1] = (byte) (tmp & 0x0f);
+        }
+        StringBuffer res = new StringBuffer();
+        for (int i = 0; i < temp.length; i++) {
+            res.append(ascii[temp[i]]);
+        }
+        return res.toString();
+    }
+
+    /**
+     * 比较字节数组是否相同
+     * @param a
+     * @param b
+     * @return
+     */
+    public static boolean compareBytes(byte[] a, byte[] b) {
+        if (a == null || a.length == 0 || b == null || b.length == 0
+                || a.length != b.length) {
+            return false;
+        }
+        if (a.length == b.length) {
+            for (int i = 0; i < a.length; i++) {
+                if (a[i] != b[i]) {
+                    return false;
+                }
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+    /**
+     * 只比对指定长度byte
+     * @param a
+     * @param b
+     * @param len
+     * @return
+     */
+    public static boolean compareBytes(byte[] a, byte[] b, int len) {
+        if (a == null || a.length == 0 || b == null || b.length == 0
+                || a.length < len || b.length < len) {
+            return false;
+        }
+        for (int i = 0; i < len; i++) {
+            if (a[i] != b[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 将字节数组转换为二进制字符串
+     * @param items
+     * @return
+     */
+    public static String bytesToBinaryString(byte[] items) {
+        if (items == null || items.length == 0) {
+            return null;
+        }
+        StringBuffer buf = new StringBuffer();
+        for (byte item : items) {
+            buf.append(byteToBinaryString(item));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * 将字节转换为二进制字符串
+     * @return
+     */
+    public static String byteToBinaryString(byte item) {
+        byte a = item;
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < 8; i++) {
+            buf.insert(0, a % 2);
+            a = (byte) (a >> 1);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * 对数组a,b进行异或运算
+     * @param a
+     * @param b
+     * @return
+     */
+    public static byte[] xor(byte[] a, byte[] b) {
+        if (a == null || a.length == 0 || b == null || b.length == 0
+                || a.length != b.length) {
+            return null;
+        }
+        byte[] result = new byte[a.length];
+        for (int i = 0; i < a.length; i++) {
+            result[i] = (byte) (a[i] ^ b[i]);
+        }
+        return result;
+    }
+
+    /**
+     * 对数组a,b进行异或运算 运算长度len
+     * @param a
+     * @param b
+     * @param len
+     * @return
+     */
+    public static byte[] xor(byte[] a, byte[] b, int len) {
+        if (a == null || a.length == 0 || b == null || b.length == 0) {
+            return null;
+        }
+        if (a.length < len || b.length < len){
+            return null;
+        }
+        byte[] result = new byte[len];
+        for (int i = 0; i < len; i++) {
+            result[i] = (byte) (a[i] ^ b[i]);
+        }
+        return result;
+    }
+    /**
+     * 将short整型数值转换为字节数组
+     * @param num
+     * @return
+     */
+    public static byte[] shortToBytes(int num) {
+        byte[] temp = new byte[2];
+        for (int i = 0; i < 2; i++) {
+            temp[i] = (byte) ((num >>> (8 - i * 8)) & 0xFF);
+        }
+        return temp;
+    }
+
+    /**
+     * 将字节数组转为整型
+     * @return
+     */
+    public static int bytesToShort(byte[] arr) {
+        int mask = 0xFF;
+        int temp = 0;
+        int result = 0;
+        for (int i = 0; i < 2; i++) {
+            result <<= 8;
+            temp = arr[i] & mask;
+            result |= temp;
+        }
+        return result;
+    }
+
+    /**
+     * 将整型数值转换为指定长度的字节数组
+     * @param num
+     * @return
+     */
+    public static byte[] intToBytes(int num) {
+        byte[] temp = new byte[4];
+        for (int i = 0; i < 4; i++) {
+            temp[i] = (byte) ((num >>> (24 - i * 8)) & 0xFF);
+        }
+        return temp;
+    }
+
+    /**
+     * 将整型数值转换为指定长度的字节数组
+     * @param src
+     * @param len
+     * @return
+     */
+    public static byte[] intToBytes(int src, int len) {
+        if (len < 1 || len > 4) {
+            return null;
+        }
+        byte[] temp = new byte[len];
+        for (int i = 0; i < len; i++) {
+            temp[len - 1 - i] = (byte) ((src >>> (8 * i)) & 0xFF);
+        }
+        return temp;
+    }
+
+    /**
+     * 将字节数组转换为整型数值
+     * @param arr
+     * @return
+     */
+    public static int bytesToInt(byte[] arr) {
+        int mask = 0xFF;
+        int temp = 0;
+        int result = 0;
+        for (int i = 0; i < 4; i++) {
+            result <<= 8;
+            temp = arr[i] & mask;
+            result |= temp;
+        }
+        return result;
+    }
+
+    /**
+     * 将long整型数值转换为字节数组
+     * @param num
+     * @return
+     */
+    public static byte[] longToBytes(long num) {
+        byte[] temp = new byte[8];
+        for (int i = 0; i < 8; i++) {
+            temp[i] = (byte) ((num >>> (56 - i * 8)) & 0xFF);
+        }
+        return temp;
+    }
+
+    /**
+     * 将字节数组转换为long整型数值
+     * @param arr
+     * @return
+     */
+    public static long bytesToLong(byte[] arr) {
+        int mask = 0xFF;
+        int temp = 0;
+        long result = 0;
+        int len = Math.min(8, arr.length);
+        for (int i = 0; i < len; i++) {
+            result <<= 8;
+            temp = arr[i] & mask;
+            result |= temp;
+        }
+        return result;
+    }
+
+    /**
+     * 功能描述:把两个字节的字节数组转化为整型数据,高位补零,例如:<br/>
+     * 有字节数组byte[] data = new byte[]{1,2};转换后int数据的字节分布如下:<br/>
+     * 00000000  00000000 00000001 00000010,函数返回258
+     * @param lenData 需要进行转换的字节数组
+     * @return  字节数组所表示整型值的大小
+     */
+    public static int bytesToIntWhereByteLengthEquals2(byte lenData[]) {
+        if(lenData.length != 2){
+            return -1;
+        }
+        byte fill[] = new byte[]{0,0};
+        byte real[] = new byte[4];
+        System.arraycopy(fill, 0, real, 0, 2);
+        System.arraycopy(lenData, 0, real, 2, 2);
+        int len = byteToInt(real);
+        return len;
+
+    }
+
+    /**
+     * 功能描述:将byte数组转化为int类型的数据
+     * @param byteVal 需要转化的字节数组
+     * @return 字节数组所表示的整型数据
+     */
+    public static int byteToInt(byte[] byteVal) {
+        int result = 0;
+        for(int i = 0;i < byteVal.length;i++) {
+            int tmpVal = (byteVal[i]<<(8*(3-i)));
+            switch(i) {
+                case 0:
+                    tmpVal = tmpVal & 0xFF000000;
+                    break;
+                case 1:
+                    tmpVal = tmpVal & 0x00FF0000;
+                    break;
+                case 2:
+                    tmpVal = tmpVal & 0x0000FF00;
+                    break;
+                case 3:
+                    tmpVal = tmpVal & 0x000000FF;
+                    break;
+            }
+
+            result = result | tmpVal;
+        }
+        return result;
+    }
+
+    public static byte CheckXORSum(byte[] bData){
+        byte sum = 0x00;
+        for (int i = 0; i < bData.length; i++) {
+            sum ^= bData[i];
+        }
+        return sum;
+    }
+    /**
+     * 从offset开始 将后续长度为len的byte字节转为int
+     * @param data
+     * @param offset
+     * @param len
+     * @return
+     */
+    public static int bytesToInt(byte[] data, int offset, int len){
+        int mask = 0xFF;
+        int temp = 0;
+        int result = 0;
+        len = Math.min(len, 4);
+        for (int i = 0; i < len; i++) {
+            result <<= 8;
+            temp = data[offset + i] & mask;
+            result |= temp;
+        }
+        return result;
+    }
+
+    /**
+     * byte字节数组中的字符串的长度
+     * @param data
+     * @return
+     */
+    public static int getBytesStringLen(byte[] data)
+    {
+        int count = 0;
+        for (byte b : data) {
+            if(b == 0x00)
+                break;
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * 对指定字符串进行异或预算
+     * @param arrays
+     * @return
+     */
+    public static String xorArrayStr(List<String> arrays){
+        if (arrays == null || arrays.size() <= 0)
+            return "";
+
+        int maxLong = -1;
+        byte []tmp[] = new byte[arrays.size()][];
+        for (int i=0,j=arrays.size()-1;i<=j;i++){
+            tmp[i] = getBytes(arrays.get(i), "UTF-8");
+            int longTmp =  tmp[i].length;
+            if (maxLong == -1 || longTmp > maxLong)
+                maxLong = longTmp;
+        }
+        byte result[] = new byte[maxLong];
+        for (int k=0;k<maxLong;k++){
+            result[k] = 0;
+            for (int i=0,j=arrays.size()-1;i<=j;i++){
+                if (tmp[i].length-1 >= k)
+                    result[k] =  (byte)(result[k] ^ tmp[i][k]);
+            }
+        }
+        return getString(result, "UTF-8");
+    }
+
+    public static byte[] getBytes(char[] chars) {
+        Charset cs = Charset.forName("UTF-8");
+        CharBuffer cb = CharBuffer.allocate(chars.length);
+        cb.put(chars);
+        cb.flip();
+        ByteBuffer bb = cs.encode(cb);
+        return bb.array();
+    }
+
+    public static char[] getChars(byte[] bytes) {
+        Charset cs = Charset.forName("UTF-8");
+        ByteBuffer bb = ByteBuffer.allocate(bytes.length);
+        bb.put(bytes).flip();
+        CharBuffer cb = cs.decode(bb);
+        return cb.array();
+    }
+}

+ 354 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/CommTool.java

@@ -0,0 +1,354 @@
+package com.shkpr.service.proxycenter.commtools;
+
+import com.global.base.component.SnowFlakeEx;
+import com.global.base.tools.*;
+import com.shkpr.service.proxycenter.constants.CommDefine;
+import org.springframework.util.StringUtils;
+
+import java.security.MessageDigest;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CommTool {
+    public static final char[] HEX_DIGITS;
+    static {
+        HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+    }
+
+    public static String getPlatformByAgent(String strClientType, String strUserAgent){
+        return getPlatformByAgent(!StringUtils.isEmpty(strClientType)?strClientType:strUserAgent);
+    }
+
+    public static String getPlatformByAgent(String strUserAgent){
+        String type = "pc";
+        if (StringUtils.isEmpty(strUserAgent))
+            return type;
+
+        String lowerAgent = strUserAgent.toLowerCase();
+        if(lowerAgent.contains("android") || lowerAgent.contains("linux")) {
+            type = "apk";
+        } else if (lowerAgent.contains("iphone") || lowerAgent.contains("ios") || lowerAgent.contains("ipad")){
+            type = "ios";
+        } else if (lowerAgent.indexOf("micromessenger") > -1){
+            type = "wx";
+        } else if (lowerAgent.indexOf("cs") > -1){
+            type = "cs";
+        } else if (lowerAgent.indexOf("windows") > -1){
+            type = "pc";
+        } else if (lowerAgent.contains("tri.")){
+            type = strUserAgent;
+        }
+        return type;
+    }
+
+    public static boolean isMobilePlatform(String platform){
+        return ("apk".equals(platform) || "ios".equals(platform) || "wx".equals(platform));
+    }
+
+    public static boolean isTheThisFormatMatch(final String strFormatFilter, String strDesData){
+        if (!StringUtils.isEmpty(strFormatFilter) && !StringUtils.isEmpty(strDesData)) {
+            //正则表达式的模式
+            Pattern p = Pattern.compile(strFormatFilter);
+            //正则表达式的匹配器
+            Matcher m = p.matcher(strDesData);
+            //进行正则匹配
+            return m.matches();
+        }
+        return false;
+    }
+
+    public static int listSize(List<? extends Object> listSrc){
+        return (listSrc==null)?0:listSrc.size();
+    }
+
+    public static int collectionSize(Collection<? extends Object> cc){
+        return (cc==null)?0:cc.size();
+    }
+
+    public static int mapSize(Map<? extends Object, ? extends Object> mapSrc){
+        return (mapSrc==null)?0:mapSrc.size();
+    }
+
+    public static int lenString(String strSrc) {
+        if (StringUtils.isEmpty(strSrc))
+            return 0;
+        return strSrc.length();
+    }
+
+    public static boolean strBetweenLen(String strSrc, int nMinLen, int nMaxLen){
+        if (strSrc == null || nMinLen > nMaxLen)
+            return false;
+        return strSrc.length() >= nMinLen && strSrc.length() <= nMaxLen;
+    }
+
+    public static String genAppApisID(){
+        return (new StringBuilder("AA")).append(SnowFlakeEx.getInstance().nextHexStrId(2)).toString();
+    }
+
+    public static String genApisCaseID(){
+        return (new StringBuilder("AC")).append(SnowFlakeEx.getInstance().nextHexStrId(2)).toString();
+    }
+
+    public static String genNotifyEventID(){
+        return (new StringBuilder("PNE")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genGisTotalTempID(){
+        return (new StringBuilder("PGT")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genElementApplyID(){
+        return (new StringBuilder("EPY")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genPublishBatchNo(){
+        return (new StringBuilder("PN")).append(SnowFlakeEx.getInstance().nextHexStrId(4)).toString();
+    }
+
+    public static String genDeviceSN(){
+        StringBuilder tmp = new StringBuilder("GSM");
+        tmp.append(TimeTool.convertUTC2DateStr(System.currentTimeMillis(), TimeTool.TIMESTAMP_FORMAT_EX2).substring(2));
+        tmp.append(EncryptionUtil.MD5Hash(UUID.randomUUID().toString()).toUpperCase().substring(10, 21));
+        return tmp.toString();
+    }
+    /**
+     * 从订单id中提取订单的创建时间,并以yyyyMMddHHmmss时间格式返回
+     * @param strOrderId
+     * @return
+     */
+    public static String getOrderTmStrFromOrderID(String strOrderId){
+        try {
+            String time = "";
+            int nStartIndex = 3; //所有工单的标识为前三个字符标识
+            time = strOrderId.substring(nStartIndex, nStartIndex+TimeTool.TIMESTAMP_FORMAT_EX2.length());
+            return time.trim();
+        }catch (Exception e){}
+        return "";
+    }
+
+    /**
+     * 从订单id中提取订单的创建时间,并以UTC时间格式(精确到毫秒)返回
+     * @param strOrderId
+     * @return
+     */
+    public static long getOrderUTCFromOrderID(String strOrderId){
+        try {
+            return new SimpleDateFormat(TimeTool.TIMESTAMP_FORMAT_EX2).parse(getOrderTmStrFromOrderID(strOrderId)).getTime();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    public static String list2QueryIn(List<? extends Object> listSrc){
+        StringBuilder str = new StringBuilder("");
+        if (listSrc != null && listSrc.size() > 0){
+            str.append("(");
+            int nStart = 0;
+            for (Object item:listSrc){
+                if (nStart++ > 0)
+                    str.append(",");
+                if (item instanceof String){
+                    str.append("'"+item+"'");
+                }else{
+                    str.append(item);
+                }
+            }
+            str.append(")");
+        }
+        return str.toString();
+    }
+
+    public static int totalCharCountsInStr(String srcStr, char chDes){
+        int nums = 0;
+        if (StringUtils.isEmpty(srcStr))
+            return nums;
+
+        char[] arr = srcStr.toCharArray();
+        for (char ch:arr){
+            if (ch == chDes)
+                nums++;
+        }
+        return nums;
+    }
+
+    public static int forceConvertToInt(Object oldObj, int defaultV){
+        if (oldObj != null){
+            if (oldObj.getClass().getSimpleName().equals("Double"))
+                return Double.valueOf((double)oldObj).intValue();
+            else if (oldObj.getClass().getSimpleName().equals("Float"))
+                return Float.valueOf((float)oldObj).intValue();
+            else
+                return CastUtil.castInt(oldObj, defaultV);
+        }
+        return defaultV;
+    }
+
+    public static String escapeInHex(final String src) {
+        StringBuilder tmp = new StringBuilder("");
+        if (StringUtils.isEmpty(src))
+            return tmp.toString();
+
+        int i;
+        char j;
+        tmp.ensureCapacity(src.length() * 6);
+        for (i = 0; i < src.length(); i++) {
+            j = src.charAt(i);
+            if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j))
+                tmp.append(j);
+            else if (j < 256) {
+                tmp.append(j);
+                /*tmp.append("%");
+                if (j < 16)
+                    tmp.append("0");
+                tmp.append(Integer.toString(j, 16));
+                */
+            } else {
+                //tmp.append("%u");
+                //tmp.append(Integer.toString(j, 16));
+                tmp.append("&#x");
+                tmp.append(Integer.toString(j, 16));
+                tmp.append(";");
+            }
+        }
+        return tmp.toString();
+    }
+
+    private static final String PHONE_MATCH_FILTER = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
+    public static String adjustMobilePhone(String phone){
+        if (!StringUtils.isEmpty(phone)
+                && phone.length() == 11
+                && isTheThisFormatMatch(PHONE_MATCH_FILTER, phone)){
+            return phone;
+        }
+        return "";
+    }
+
+    private static String exchangeMD5(String md5){
+        StringBuilder res = new StringBuilder("");
+        int len = md5.length()/2;
+        for (int i=0; i<len; i++){
+            int index = i*2;
+            res.append(Integer.toHexString((Integer.parseInt(String.valueOf(md5.charAt(index+1)), 16)<<4 | Integer.parseInt(String.valueOf(md5.charAt(index)), 16)) % 16).toUpperCase());
+        }
+        //for (int i = 0,j = md5.length()-1; i<=j; i++,j--){
+        //    res.append(Integer.toHexString(((0x0F & md5.charAt(i)) ^ (0x0F & md5.charAt(j)))).toUpperCase());
+        //}
+        return res.toString();
+    }
+
+    public static String genUserUid(String account, String extend){
+        return "UUD" + exchangeMD5(EncryptionUtil.MD5Hash(account+extend));
+    }
+
+    public static String likeMap2LikeStr(Map<String, String> mapLikes, Set<String> filterKey){
+        StringBuilder strLikes = new StringBuilder("");
+        if (mapLikes != null && mapLikes.size() > 0){
+            int nStart = 0;
+            for(Map.Entry<String, String> entry:mapLikes.entrySet()){
+                String key = entry.getKey();
+                String data = entry.getValue();
+
+                if (StringUtils.isEmpty(data) || !filterKey.contains(key))  //likes条件暂时只支持有限字段
+                    continue;
+
+                if (nStart++ > 0)
+                    strLikes.append(" or ");
+                strLikes.append(StringUtil.lower2UnLine(key)+" like '%"+data+"%' ");
+            }
+        }
+        return strLikes.toString();
+    }
+
+    //WGS84标准参考椭球中的地球长半径(单位:米)
+    private static final double EARTH_RADIUS = 6378137; //地球半径:米
+    /**
+     * 根据经纬度,计算两点间的距离
+     *
+     * @param lng1 第一个点的经度
+     * @param lat1  第一个点的纬度
+     * @param lng2 第二个点的经度
+     * @param lat2  第二个点的纬度
+     * @return 返回距离 单位:米
+     */
+    public static long getGisDistance(double lng1, double lat1, double lng2, double lat2) {
+        lat1 = Math.toRadians(lat1);
+        lat2 = Math.toRadians(lat2);
+        lng1 = Math.toRadians(lng1);
+        lng2 = Math.toRadians(lng2);
+
+        double a = lat1 - lat2;    // 纬度之差
+        double b = lng1 - lng2;     // 经度之差
+        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));// 计算两点距离的公式
+        s =  s * EARTH_RADIUS;
+        return Math.round(s * 10000) / 10000;
+    }
+
+    public static String genHashCodeForBytes(byte[] data){
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] bytes = md.digest(data);
+            StringBuilder ret = new StringBuilder(bytes.length * 2);
+
+            for(int i = 0; i < bytes.length; ++i) {
+                ret.append(HEX_DIGITS[bytes[i] >> 4 & 15]);
+                ret.append(HEX_DIGITS[bytes[i] & 15]);
+            }
+
+            return ret.toString();
+        } catch (Exception var6) {
+            var6.printStackTrace();
+            return (data != null && data.length >= 16)?BytesUtils.bytesToHex(data, 0, 16):"";
+        }
+    }
+
+    public static String genFileAttachmentId(String fileName, int type, String strExtend){
+        String time = TimeTool.convertUTC2DateStr(System.currentTimeMillis(), TimeTool.TIMESTAMP_FORMAT_EX2);
+        String fileNameHash = (StringUtils.isEmpty(fileName))? RandomUtil.getDigitalRandomStr(4):EncryptionUtil.MD5Hash(fileName).substring(0,4);
+        String extend = (StringUtils.isEmpty(strExtend))?RandomUtil.getDigitalRandomStr(4):strExtend;
+        return (new StringBuilder("FT"))
+                .append(time==null?"":time)
+                .append(String.format("%02d",type%100))
+                .append(fileNameHash==null?"":fileNameHash)
+                .append(extend==null?"":extend).toString();
+    }
+
+    public static List safeList(List<? extends Object> listSrc){
+        if (listSrc == null)
+            return new ArrayList();
+        else
+            return listSrc;
+    }
+
+    public static boolean isRootAdminID(String userId){
+        return CommDefine.ADMIN_USER_ID.equals(userId)
+                || CommDefine.INTERNAL_OPERATOR_ID.equals(userId);
+    }
+
+    //84坐标系转2000坐标系
+    public static double[] convert84To2000(double latitude, double longitude) {
+        double x = 0.0, y = 0.0, z = 0.0;
+        double a = EARTH_RADIUS;
+        double f = 1.0 / 298.257223563;
+        double b = (1 - f) * a;
+        double e = Math.sqrt((a * a - b * b) / (a * a));
+        double E = Math.atan2(z, Math.sqrt(x * x + y * y));
+        double r = Math.sqrt(x * x + y * y + z * z);
+        double latitude1 = Math.atan2(z + e * e * b * Math.pow(Math.sin(E), 3), r - a * Math.pow(e, 2) * Math.pow(Math.cos(E), 3));
+        double longitude1 = Math.atan2(y, x);
+        double N = a / Math.sqrt(1 - Math.pow(e * Math.sin(latitude1), 2));
+        double h = r / Math.cos(latitude1) - N;
+        double X = (N + h) * Math.cos(latitude1) * Math.cos(longitude1);
+        double Y = (N + h) * Math.cos(latitude1) * Math.sin(longitude1);
+        double Z = (N * (1 - Math.pow(e, 2)) + h) * Math.sin(latitude1);
+        double k = 1.0000648438897;
+        double dx = -24.9;
+        double dy = 140.8;
+        double dz = 76.3;
+        double X1 = k * (X + dx);
+        double Y1 = k * (Y + dy);
+        double Z1 = k * (Z + dz);
+        return new double[]{X1, Y1, Z1};
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 205 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/HttpTool.java


+ 497 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/TimeTool.java

@@ -0,0 +1,497 @@
+package com.shkpr.service.proxycenter.commtools;
+import org.springframework.util.StringUtils;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+public class TimeTool {
+    public static final long MS_HTTP_REQ_TIMEOUT = 120*1000;  //两分钟的毫秒数
+    public static final long MS_ONE_HALF_MIN = 90*1000;  //一分半钟的毫秒数
+    public static final long MS_ONE_MIN = 60*1000;       //一分钟的毫秒数
+    public static final long MIN_ONE_DAY = 24*60;        //一天中的分
+    public static final long SEC_ONE_DAY = 24*60*60;     //一天中的秒
+    public static final long MS_ONE_DAY = 24*60*60*1000; //一天中的毫秒
+    public static final long MS_ONE_YEAR = 365*MS_ONE_DAY;//一年中的毫秒
+    public static final long MS_ONE_HOUR = 60*60*1000;   //一小时的毫秒
+    public static final String YEAR_FORMAT = "yyyy";
+    public static final String YEAR_MONTH_FORMAT_EX = "yyyyMM";
+    public static final String YEAR_MONTH_FORMAT = "yyyy-MM";
+    public static final String YEAR_MONTH_FORMAT_SLASH = "yyyy/MM";
+    public static final String YEAR_MONTH_DAY_FORMAT = "yyyy-MM-dd";
+    public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    public static final String TIMESTAMP_FORMAT_EX = "yyyy-MM-dd HH:mm:ss.SSS";
+    public static final String TIMESTAMP_FORMAT_EX2 = "yyyyMMddHHmmss";
+    public static final long UTC_MS_START_ONLINE = 1538323200000L;//2018-10-01 00:00:00
+    public static volatile long UTC_MS_TODAY_BEGIN = 0L;
+    public static volatile long UTC_MS_TODAY_END = 0L;
+    public static volatile long UTC_MS_THIS_MONTH_BEGIN = 0L;
+    public static volatile long UTC_MS_THIS_MONTH_END = 0L;
+
+    private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);
+    private static final DateTimeFormatter TIMESTAMP_EX_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX);
+    private static final DateTimeFormatter TIMESTAMP_EX2_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX2);
+    private static final DateTimeFormatter YEAR_MONTH_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_FORMAT);
+    private static final DateTimeFormatter YEAR_MONTH_DAY_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_DAY_FORMAT);
+
+    public static void refreshUTCTimeRes(){
+        UTC_MS_TODAY_BEGIN = getTodayBeginUTC();
+        UTC_MS_TODAY_END = getTodayEndUTC();
+        UTC_MS_THIS_MONTH_BEGIN = getMonthBeginUTC(System.currentTimeMillis());
+        UTC_MS_THIS_MONTH_END = getMonthEndUTC(System.currentTimeMillis());
+    }
+
+    private static LocalDateTime strTime2LocalDateTime(String time, String format) {
+        switch (format){
+            case YEAR_MONTH_FORMAT:
+                return LocalDateTime.parse(time, YEAR_MONTH_FORMATTER);
+            case YEAR_MONTH_DAY_FORMAT:
+                return LocalDateTime.parse(time, YEAR_MONTH_DAY_FORMATTER);
+            case TIMESTAMP_FORMAT:
+                return LocalDateTime.parse(time, TIMESTAMP_FORMATTER);
+            case TIMESTAMP_FORMAT_EX:
+                return LocalDateTime.parse(time, TIMESTAMP_EX_FORMATTER);
+            case TIMESTAMP_FORMAT_EX2:
+                return LocalDateTime.parse(time, TIMESTAMP_EX2_FORMATTER);
+            default:
+                return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(format));
+        }
+    }
+
+    private static String localDateTime2StrTime(LocalDateTime localDateTime, String format) {
+        switch (format){
+            case YEAR_MONTH_FORMAT:
+                return localDateTime.format(YEAR_MONTH_FORMATTER);
+            case YEAR_MONTH_DAY_FORMAT:
+                return localDateTime.format(YEAR_MONTH_DAY_FORMATTER);
+            case TIMESTAMP_FORMAT:
+                return localDateTime.format(TIMESTAMP_FORMATTER);
+            case TIMESTAMP_FORMAT_EX:
+                return localDateTime.format(TIMESTAMP_EX_FORMATTER);
+            case TIMESTAMP_FORMAT_EX2:
+                return localDateTime.format(TIMESTAMP_EX2_FORMATTER);
+            default:
+                return localDateTime.format(DateTimeFormatter.ofPattern(format));
+        }
+    }
+
+    private static LocalDateTime utcMsTime2LocalDateTime(long lUTC) {
+        if (!isMsUTC(lUTC)){
+            lUTC = lUTC*1000;
+        }
+        Instant instant = Instant.ofEpochMilli(lUTC);
+        ZoneId zone = ZoneId.systemDefault();
+        return LocalDateTime.ofInstant(instant, zone);
+    }
+
+    private static long localDateTime2UtcMsTime(LocalDateTime localDateTime) {
+        ZoneId zone = ZoneId.systemDefault();
+        Instant instant = localDateTime.atZone(zone).toInstant();
+        return instant.toEpochMilli();
+    }
+
+    private static long strTime2UtcMsTime(String dateStr, String format){
+        return localDateTime2UtcMsTime(strTime2LocalDateTime(dateStr, format));
+    }
+
+    private static String utcMsTime2StrTime(long lUTC, String format){
+        return localDateTime2StrTime(utcMsTime2LocalDateTime(lUTC), format);
+    }
+
+    public static long convertDateStr2UTC(String dateStr){
+        try {
+            dateStr = dateStr.trim();
+            int len = dateStr.length();
+            if (len >= 23)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX);
+            else if (len >= 19)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT);
+            else if (len >= 14)
+                return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX2);
+            else if (len >= 10)//即dataStr为yyyy-MM-dd
+                return strTime2UtcMsTime(String.format("%s 00:00:00", dateStr), TIMESTAMP_FORMAT);
+            else if (len >= 7)//即dataStr为yyyy-MM
+                return strTime2UtcMsTime(String.format("%s-01 00:00:00", dateStr), TIMESTAMP_FORMAT);
+            else if (len >= 6)//即dataStr为yyyyMM
+                return strTime2UtcMsTime(String.format("%s01000000", dateStr), TIMESTAMP_FORMAT_EX2);
+            else if (len >= 4)//即dataStr为yyyy
+                return strTime2UtcMsTime(String.format("%s-01-01 00:00:00", dateStr), TIMESTAMP_FORMAT);
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 指定UTC是否为精确到毫秒的UTC时间
+     * @param lUTC
+     * @return
+     */
+    public static boolean isMsUTC(long lUTC){
+        return lUTC > 10000000000L;
+    }
+
+    public static long getCurSecUTC(){
+        return (System.currentTimeMillis()/1000)*1000;
+    }
+
+    public static long getCurMsUTC(){
+        return System.currentTimeMillis();
+    }
+
+    /**
+     *
+     * @param lUTC  UTC时间格式(单位:毫秒)
+     * @param strDateFormat 日期格式模板:如:yyyy-MM-dd HH:mm:ss
+     * @return
+     */
+    public static String convertUTC2DateStr(long lUTC, String strDateFormat){
+        try {
+            return utcMsTime2StrTime(lUTC<=0?System.currentTimeMillis():lUTC
+                    , StringUtils.isEmpty(strDateFormat)?TIMESTAMP_FORMAT:strDateFormat);
+        }catch (Exception e){}
+        return "";
+    }
+
+    /**
+     * 从当前时间算起,还有多少毫秒今天将结束
+     * @return 所剩的毫秒数
+     */
+    public static long hasMsWhenTodayEnd(){
+        long lR = UTC_MS_TODAY_END+1-System.currentTimeMillis();
+        if (lR <= 0)
+            lR = 1;
+        return lR;
+    }
+
+    /**
+     * 获取过期时间
+     * @param nSeconds 从当前时间算起,nSeconds秒后过期
+     * @return UTC时间格式(单位:毫秒)
+     */
+    public static long createExpiredTime(long nSeconds){
+        nSeconds = nSeconds<0?0:nSeconds;
+        long nowMillis = System.currentTimeMillis();
+        return nowMillis+(nSeconds*1000);
+    }
+
+    /**
+     * 获取当天的开始时间
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:00:00:00.000所对应的时间戳
+     */
+    public static long getTodayBeginUTC(){
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+        /*Calendar todayStart = Calendar.getInstance();
+        todayStart.set(Calendar.HOUR_OF_DAY, 0);
+        todayStart.set(Calendar.MINUTE, 0);
+        todayStart.set(Calendar.SECOND, 0);
+        todayStart.set(Calendar.MILLISECOND, 0);
+        return todayStart.getTime().getTime();*/
+    }
+
+    /**
+     * 获取当天距离最近的整点时刻
+     * @return UTC时间格式(单位:毫秒)
+     * @return
+     */
+    public static long getTodayLastHourUTC(){
+        return LocalDateTime.now().withMinute(0).withSecond(0).withNano(0)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+    }
+
+    /**
+     * 获取指定时间当日的起始时刻(即00:00:00.000)
+     * @param tmMS
+     * @return
+     */
+    public static long getBeginUTCOfTime(long tmMS){
+        if (!isMsUTC(tmMS)){
+            tmMS = tmMS*1000;
+        }
+        LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MIN);
+        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+    }
+
+    /**
+     * 获取指定时间当日的结束时刻(即23:59:59.999)
+     * @param tmMS
+     * @return
+     */
+    public static long getEndUTCOfTime(long tmMS){
+        if (!isMsUTC(tmMS)){
+            tmMS = tmMS*1000;
+        }
+        LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MAX);
+        return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+    }
+    /**
+     * 获取当天的结束时间
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:23:59:59.999所对应的时间戳
+     */
+    public static long getTodayEndUTC(){
+        return LocalDateTime.of(LocalDate.now(), LocalTime.MAX)
+                .atZone(ZoneId.systemDefault())
+                .toInstant()
+                .toEpochMilli();
+        /*Calendar todayStart = Calendar.getInstance();
+        todayStart.set(Calendar.HOUR_OF_DAY, 23);
+        todayStart.set(Calendar.MINUTE, 59);
+        todayStart.set(Calendar.SECOND, 59);
+        todayStart.set(Calendar.MILLISECOND, 999);
+        return todayStart.getTime().getTime();*/
+    }
+
+    /**
+     * 获取当前时间所在月份的开始时间戳
+     * @param curTime
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:xxxx-xx-01 00:00:00.000所对应的时间戳
+     */
+    public static long getMonthBeginUTC(long curTime){
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.set(Calendar.DAY_OF_MONTH, 1);
+            c.set(Calendar.HOUR_OF_DAY, 0);
+            c.set(Calendar.MINUTE, 0);
+            c.set(Calendar.SECOND,0);
+            c.set(Calendar.MILLISECOND, 0);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 获取当前时间所在月份的结束时间戳
+     * @param curTime
+     * @return UTC时间格式(单位:毫秒)
+     * 返回时间格式为:xxxx-xx-31 23:59:59.999所对应的时间戳
+     */
+    public static long getMonthEndUTC(long curTime){
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
+            c.set(Calendar.HOUR_OF_DAY, 23);
+            c.set(Calendar.MINUTE, 59);
+            c.set(Calendar.SECOND,59);
+            c.set(Calendar.MILLISECOND, 999);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份字符串列表
+     * ["2018-01", "2018-02"]
+     */
+    public static List<String> getMonthListBetween(long startTime, long endTime){
+        ArrayList<String> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(dPos.getTime()));
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(strEnd);
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份字符串列表
+     * ["201801", "201802"]
+     */
+    public static List<String> getMonthListBetweenEx(long startTime, long endTime){
+        ArrayList<String> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(dPos.getTime()));
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(strEnd);
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表UTC
+     * @param startTime 起始时间,UTC时间格式,秒或毫秒
+     * @param endTime 结束时间,UTC时间格式,秒或毫秒
+     * @return 月份UTC时间戳列表(精确到毫秒)
+     * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC]
+     */
+    public static List<Long> getMonthUTCListBetween(long startTime, long endTime){
+        ArrayList<Long> arrMonth = new ArrayList<>();
+        if (!isMsUTC(startTime))
+            startTime = startTime*1000;
+        if (!isMsUTC(endTime))
+            endTime = endTime*1000;
+        try{
+            String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime));
+            String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime));
+            Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart);
+            Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd);
+
+            Calendar dPos = Calendar.getInstance();
+            dPos.setTime(dtStart);                  //设置日期起始时间
+            while (dPos.getTime().before(dtEnd)) {
+                arrMonth.add(dPos.getTimeInMillis());
+                dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1
+            }
+            arrMonth.add(dtEnd.getTime());
+        }catch (Exception e){e.printStackTrace();}
+        return arrMonth;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份字符串列表
+     * ["2018-01", "2018-02"]
+     */
+    public static List<String> getMonthListBetween(String startTime, String endTime){
+        try {
+            //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime);
+            //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime);
+            return getMonthListBetween(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份字符串列表
+     * ["201801", "201802"]
+     */
+    public static List<String> getMonthListBetweenEx(String startTime, String endTime){
+        try {
+            //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(startTime);
+            //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(endTime);
+            return getMonthListBetweenEx(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取指定时间段内的所有月份列表UTC
+     * @param startTime 起始月份,如:2018-01-01 00:00:00
+     * @param endTime 结束月份,如:2018-02-01 00:00:00
+     * @return 月份UTC时间戳列表(精确到秒)
+     * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC]
+     */
+    public static List<Long> getMonthUTCListBetween(String startTime, String endTime){
+        try {
+            Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime);
+            Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime);
+            return getMonthUTCListBetween(d1.getTime(), d2.getTime());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * yyyyMMddhhmmss时间字符串转yyyy-MM-dd HH:mm:ss时间字符串
+     * @param strDateStr
+     * @return
+     */
+    public static String addSplitForDateStr(String strDateStr){
+        if (!StringUtils.isEmpty(strDateStr)){
+            try {
+                return localDateTime2StrTime(strTime2LocalDateTime(strDateStr, TIMESTAMP_FORMAT_EX2), TIMESTAMP_FORMAT);
+            }catch (Exception e){}
+        }
+        return "";
+    }
+
+    /**
+     * 修改指定时间的月份
+     * @param curTime
+     * @param month  > 0 在指定时间上加数个月;< 0 在指定时间上减数个月;
+     * @return
+     */
+    public static long getTimeChgMonth(long curTime, int month){
+        if (month == 0)
+            return curTime;
+        Calendar c = Calendar.getInstance();
+        if (!isMsUTC(curTime))
+            curTime = curTime*1000;
+        try {
+            c.setTime(new Date(curTime));
+            c.add(Calendar.MONTH, month);
+            return c.getTimeInMillis();
+        }catch (Exception e){}
+        return 0L;
+    }
+
+    public static String convertDateObj2DateStr(Date dateObj, String strDateFormat){
+        try {
+            int len = strDateFormat.length();
+            if (len >= 21)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT_EX).format(dateObj);
+            else if (len >= 17)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT).format(dateObj);
+            else if (len >= 12)
+                return new SimpleDateFormat(TIMESTAMP_FORMAT_EX2).format(dateObj);
+            else {
+                int splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '-');
+                if (splitCounts <= 0)
+                    splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '/');
+                if (splitCounts >= 2)
+                    return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj);
+                else if (splitCounts >= 1)
+                    return new SimpleDateFormat(YEAR_MONTH_FORMAT).format(dateObj);
+                else
+                    return new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).format(dateObj);
+            }
+        }catch (Exception e){}
+        return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj);
+    }
+}

+ 98 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/UZipUtils.java

@@ -0,0 +1,98 @@
+package com.shkpr.service.proxycenter.commtools;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class UZipUtils {
+    /**
+     * 压缩文件列表中包含中文名时,必须使用GBK编码格式
+     * @param zipFile
+     * @return
+     * @throws Exception
+     */
+    private static ZipFile getZipFile(File zipFile) throws Exception {
+        ZipFile zip = new ZipFile(zipFile, Charset.forName("UTF-8"));
+        Enumeration<?> entries = zip.entries();
+        while (entries.hasMoreElements()) {
+            try {
+                ZipEntry entry = (ZipEntry)entries.nextElement();
+            } catch (Exception e) {
+                try {
+                    zip.close();
+                }catch (Exception ee){}
+                return new ZipFile(zipFile, Charset.forName("GBK"));
+            }
+        }
+        try {
+            zip.close();
+        }catch (Exception ee){}
+        return new ZipFile(zipFile, Charset.forName("UTF-8"));
+    }
+
+    public static List<String> unZip(String zipFilePath, String desDirPath) throws RuntimeException{
+        return unZip(new File(zipFilePath), desDirPath);
+    }
+
+    public static List<String> unZip(File zipFile, String desDirPath) throws RuntimeException{
+        List<String> desFilePaths = null;
+        if (zipFile == null || !zipFile.exists())
+            throw new RuntimeException(zipFile.getPath() + "->the source file not exist");
+
+        File desDirFile = new File(desDirPath);
+        if (!desDirFile.exists())
+            desDirFile.mkdirs();
+
+        ZipFile zip = null;
+        try {
+            zip = getZipFile(zipFile);
+            Enumeration<?> entries = zip.entries();
+            desFilePaths = new ArrayList<>();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = (ZipEntry)entries.nextElement();
+                String desFilePath = (desDirPath.endsWith("/"))?
+                        (desDirPath + entry.getName()):(desDirPath + "/" + entry.getName());
+                desFilePath = desFilePath.replaceAll("\\*", "/");
+
+                if (entry.isDirectory()) {
+                    File dir = new File(desFilePath);
+                    dir.mkdirs();
+                } else {
+                    desFilePaths.add(desFilePath);
+                    File targetFile = new File(desFilePath);
+                    if (!targetFile.getParentFile().exists())
+                        targetFile.getParentFile().mkdirs();
+                    targetFile.createNewFile();
+
+                    InputStream is = zip.getInputStream(entry);
+                    FileOutputStream fos = new FileOutputStream(targetFile);
+                    int len = -1;
+                    byte []buf = new byte[1024];
+                    while ((len = is.read(buf)) != -1) {
+                        fos.write(buf, 0, len);
+                    }
+                    fos.close();
+                    is.close();
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("unzip error from UZipUtils", e);
+        } finally {
+            if (zip != null) {
+                try {
+                    zip.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return desFilePaths==null?new ArrayList<>():desFilePaths;
+    }
+}

+ 45 - 0
src/main/java/com/shkpr/service/proxycenter/commtools/XMLTool.java

@@ -0,0 +1,45 @@
+package com.shkpr.service.proxycenter.commtools;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+public class XMLTool {
+    public static String objToXml(Object obj){
+        return objToXml(obj, "UTF-8");
+    }
+
+    public static String objToXml(Object obj, String encoding) {
+        StringWriter sw = new StringWriter();
+        sw.append("<?xml version=\"1.0\" encoding=\""+encoding+"\"?>\n");
+        try {
+            JAXBContext context = JAXBContext.newInstance(obj.getClass());
+            Marshaller marshaller = context.createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);//去掉生成xml的默认报文头
+            //marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
+            marshaller.marshal(obj, sw);
+        } catch (JAXBException e) {
+            e.printStackTrace();
+        }
+        return sw.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Object xmlToObj(Class objClazz, String xmlStr) {
+        Object xmlObject = null;
+        try {
+            JAXBContext context = JAXBContext.newInstance(objClazz);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            StringReader sr = new StringReader(xmlStr);
+            xmlObject = unmarshaller.unmarshal(sr);
+        } catch (JAXBException e) {
+            e.printStackTrace();
+        }
+        return xmlObject;
+    }
+
+}

+ 39 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/CaffeineConfiguration.java

@@ -0,0 +1,39 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import com.github.benmanes.caffeine.cache.RemovalCause;
+import com.github.benmanes.caffeine.cache.RemovalListener;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableAutoConfiguration
+public class CaffeineConfiguration {
+    @Value("${local.cache.max.size.push.task:1000}")
+    private int pushTaskMaxCacheSize;   //Cache可存储的最大pushTask数量;
+
+    @Value("${local.cache.expired.push.task:1440}")
+    private int pushTaskCacheExpiredTm;//Cache存储pushTask的有效时长(单位:分钟)
+
+    /*@Bean(name = OrderCacheBase.SEQ_CACHE_MGR_NAME)
+    @Primary
+    public CacheManager cacheOrderSeqManager(){
+        CaffeineCacheManager cacheManager = new CaffeineCacheManager(OrderCacheBase.SEQ_CACHE_NAME, OrderCacheBase.SEQ_CACHE_NAME_EX);
+        cacheManager.setAllowNullValues(false);
+        cacheManager.setCaffeine(Caffeine.newBuilder()
+                .initialCapacity(orderSeqMaxCacheSize/10)
+                .maximumSize(orderSeqMaxCacheSize)
+                .expireAfterWrite(orderSeqCacheExpiredTm, TimeUnit.MINUTES)
+                .removalListener(new CustomRemovalListener())
+                .recordStats());
+        return cacheManager;
+    }*/
+
+    class CustomRemovalListener implements RemovalListener<Object, Object> {
+        @Override
+        public void onRemoval(Object key, Object value, RemovalCause cause) {
+            //System.out.format("removal listerner called with key [%s], cause [%s], evicted [%S]\n",
+            //        key, cause.toString(), cause.wasEvicted());
+        }
+    }
+}

+ 62 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/GlobalParamConfiguration.java

@@ -0,0 +1,62 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import com.global.base.thread.ThreadPoolProxy;
+import com.global.base.tools.EncryptionUtil;
+import com.global.base.tools.RandomUtil;
+
+import com.shkpr.service.proxycenter.globalcache.GlobalData;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@EnableAutoConfiguration
+public class GlobalParamConfiguration {
+    @Value("${global.http.status.200:true}")
+    private boolean mBHttpStatusAlready200;                       //Http Status是否总是返回200ok,即所有错误码只能在body当中
+
+    @Value("${global.local.cache.switch:true}")                   //是否启用本地缓存策略
+    private boolean mBUseLocalCache;
+
+    @Value("${global.enable.async.subtask.cpucores:8}")         //启动异步子任务的最小cpu核心数
+    private int mNCpuCoresForEnableAsyncSubTask = 8;
+
+    @Value("${global.internal.operator.account:TriCooperation}")
+    private String mStrInternalOperatorAccount = "";
+
+    @Value("${global.internal.operator.password:123@asd}")       //123@asd的BCypte加盐值
+    private String mStrInternalOperatorPassword = "";
+
+    @Value("${global.service.online.time:0}")                      //服务上线的时间
+    private long mTmUTCServiceOnline = 0L;
+
+    @Value("${global.internal.call.password:}")
+    private String mStrInternalCallPassword = "";
+
+    public GlobalParamConfiguration() {
+    }
+
+    @PostConstruct
+    public void init(){
+        GlobalData.getInstance().setHttpStatusAlready200(mBHttpStatusAlready200);
+        GlobalData.getInstance().setUseLocalCache(mBUseLocalCache);
+        GlobalData.getInstance().setCpuCoresForEnableAsyncSubTask(mNCpuCoresForEnableAsyncSubTask);
+        GlobalData.getInstance().setStrOperatorAccount(mStrInternalOperatorAccount);
+        GlobalData.getInstance().setStrOperatorPassword(mStrInternalOperatorPassword);
+        GlobalData.getInstance().setInternalCallPassword(EncryptionUtil.MD5Hash(StringUtils.isEmpty(mStrInternalCallPassword)? RandomUtil.getRandomStr(8):mStrInternalCallPassword));
+
+        ThreadPoolProxy.getInstance().getFixedThreadPool("COMM").execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(30000);
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+           }
+        });
+    }
+}

+ 133 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/OkHttpClientConfig.java

@@ -0,0 +1,133 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * OkHttp3特别注意:1) 所有的header不能设置null
+ *                  2) 需要显示的设置user-agent请求头
+ *                  3) 需要关闭人工的Accept-Encoding:gzip压缩解压机制,OkHttp3会默认启用自身的压缩解压机制
+ */
+@Configuration
+@EnableAutoConfiguration
+public class OkHttpClientConfig {
+    @Primary
+    @Bean(name = "RestTemplateEx")
+    public RestTemplate restTemplate(@Qualifier("OkHttpClient") OkHttpClient okHttpClient) {
+        OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(okHttpClient);
+        RestTemplate restTemplate = new RestTemplate(factory);
+        // 可以添加消息转换
+        //restTemplate.setMessageConverters(...);
+        // 可以增加拦截器
+        //restTemplate.setInterceptors(...);
+        return restTemplate;
+    }
+
+    @Primary
+    @Bean(name = "RestTemplateUTF8")//解决body无法进行UTF-8编码时的中文乱码问题,如:APPLICATION_XML默认无法指定UTF-8编码;而APPLICATION_JSON_UTF8默认就对body进行了UTF-8编码
+    public RestTemplate restTemplateUTF8(@Qualifier("OkHttpClient") OkHttpClient okHttpClient) {
+        OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(okHttpClient);
+        RestTemplate restTemplate = new RestTemplate(factory);
+        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
+        if (messageConverters != null){
+            for (int i = 0; i < messageConverters.size(); i++) {
+                HttpMessageConverter<?> httpMessageConverter = messageConverters.get(i);
+                if (httpMessageConverter.getClass().equals(StringHttpMessageConverter.class)) {
+                    messageConverters.set(i, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+                }
+            }
+        }
+        return restTemplate;
+    }
+
+    @Bean(name = "OkHttpClient")
+    public OkHttpClient okHttpClient(@Qualifier("SSLSocketFactory") SSLSocketFactory sslSocketFactory, @Qualifier("X509TrustManager") X509TrustManager x509TrustManager){
+        return new OkHttpClient.Builder()
+                .sslSocketFactory(sslSocketFactory, x509TrustManager)
+                .hostnameVerifier(new SkipHostnameVerifier())
+                .retryOnConnectionFailure(true)//当使用连接池时该参数设置true才有意义
+                .connectionPool(new okhttp3.ConnectionPool(200, 5, TimeUnit.MINUTES))
+                .connectTimeout(30, TimeUnit.SECONDS)
+                .readTimeout(30, TimeUnit.SECONDS)
+                .writeTimeout(30,TimeUnit.SECONDS)
+                .addNetworkInterceptor(new Interceptor() {//添加网络拦截器
+                    @Override
+                    public Response intercept(Chain chain) throws IOException {
+                        Request oldRequest = chain.request();
+                        //在这里可以添加或修改请求的header,比如添加User-Agent
+                        //Request newRequest = oldRequest.newBuilder()
+                        //        .header("User-Agent", "Linux")
+                        //        .build();
+                        //Response oldResponse =  chain.proceed(newRequest);
+                        //重写Response
+                        //return oldResponse.newBuilder()
+                        //        .header("Cache-Control", "max-age=60")
+                        //        .build();
+                        return chain.proceed(oldRequest);
+                    }
+                })
+                //.addInterceptor(new Interceptor() {//添加应用拦截器
+                //    @Override
+                //    public Response intercept(Chain chain) throws IOException {
+                //        return null;
+                //    }
+                //})
+                .build();
+    }
+
+    @Bean(name = "X509TrustManager")
+    public X509TrustManager x509TrustManager() {
+        return new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(X509Certificate[] x509Certificates, String s){
+            }
+            @Override
+            public void checkServerTrusted(X509Certificate[] x509Certificates, String s){
+            }
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+        };
+    }
+
+    @Bean(name = "SSLSocketFactory")
+    public SSLSocketFactory sslSocketFactory(@Qualifier("X509TrustManager") X509TrustManager x509TrustManager) {
+        try {
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(null, new TrustManager[] {x509TrustManager}, new SecureRandom());
+            return context.getSocketFactory();
+        } catch (NoSuchAlgorithmException | KeyManagementException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private static class SkipHostnameVerifier implements HostnameVerifier {
+        @Override
+        public boolean verify(String s, SSLSession sslSession) {
+            return true;
+        }
+    }
+}

+ 44 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/RestTemplateConfig.java

@@ -0,0 +1,44 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableAutoConfiguration
+public class RestTemplateConfig {
+
+    /*@Bean(name = "RestTemplateEx")
+    public RestTemplate restTemplate(@Qualifier("ClientHttpRequestFactoryEx") ClientHttpRequestFactory factory) {
+        return new RestTemplate(factory);
+    }
+
+    @Bean(name = "RestTemplateUTF8") //解决body无法进行UTF-8编码时的中文乱码问题,如:APPLICATION_XML默认无法指定UTF-8编码;而APPLICATION_JSON_UTF8默认就对body进行了UTF-8编码
+    public RestTemplate restTemplateUTF8(@Qualifier("ClientHttpRequestFactoryEx") ClientHttpRequestFactory factory) {
+        RestTemplate template = new RestTemplate(factory);
+        List<HttpMessageConverter<?>> messageConverters = template.getMessageConverters();
+        if (messageConverters != null){
+            for (int i = 0; i < messageConverters.size(); i++) {
+                HttpMessageConverter<?> httpMessageConverter = messageConverters.get(i);
+                if (httpMessageConverter.getClass().equals(StringHttpMessageConverter.class)) {
+                    messageConverters.set(i, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+                }
+            }
+        }
+        return template;
+    }
+
+    @Bean("ClientHttpRequestFactoryEx")
+    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
+        //SimpleClientHttpRequestFactory factory1 = new SimpleClientHttpRequestFactory();
+        SslClientHttpRequestFactory factory = new SslClientHttpRequestFactory();
+        factory.setReadTimeout(30000);
+        factory.setConnectTimeout(30000);
+        return factory;
+    }
+
+    @Bean
+    public ServiceMgrProxy startServiceMgrProxy(){
+        ServiceMgrProxy.getInstance().init();
+        return ServiceMgrProxy.getInstance();
+    }*/
+}

+ 45 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/RetryTemplateConfig.java

@@ -0,0 +1,45 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.retry.backoff.ExponentialBackOffPolicy;
+import org.springframework.retry.backoff.FixedBackOffPolicy;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
+
+@Configuration
+@EnableAutoConfiguration
+public class RetryTemplateConfig {
+    @Primary
+    @Bean(name = "Normal3Retry")
+    public RetryTemplate normal3Retry(){
+        RetryTemplate template = new RetryTemplate();
+        SimpleRetryPolicy policy = new SimpleRetryPolicy();//默认最大重试次数为3
+
+        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
+        backOffPolicy.setInitialInterval(200L);
+        backOffPolicy.setMaxInterval(200L);
+        backOffPolicy.setMultiplier(2.0);//第一次间隔为T1=200ms,第二次为T2=2*T1=400ms,第三次为T3=2*T2=800ms
+
+        template.setBackOffPolicy(backOffPolicy);
+        template.setRetryPolicy(policy);
+
+        return template;
+    }
+
+    @Bean(name = "FixedPeriod3Retry")
+    public RetryTemplate fixedPeriod3Retry(){
+        RetryTemplate template = new RetryTemplate();
+        SimpleRetryPolicy policy = new SimpleRetryPolicy();//默认最大重试次数为3
+
+        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
+        fixedBackOffPolicy.setBackOffPeriod(500L); //每次重试固定间隔500ms
+
+        template.setBackOffPolicy(fixedBackOffPolicy);
+        template.setRetryPolicy(policy);
+
+        return template;
+    }
+}

+ 75 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/ScheduleTaskConfiguration.java

@@ -0,0 +1,75 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import javax.annotation.PostConstruct;
+import java.lang.reflect.Method;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableScheduling
+public class ScheduleTaskConfiguration implements SchedulingConfigurer, AsyncConfigurer {
+    private String mStrClassName;
+    public ScheduleTaskConfiguration() {
+        mStrClassName = this.getClass().getSimpleName();
+    }
+
+    @Override
+    public Executor getAsyncExecutor() {
+        Executor executor = taskScheduler();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncUncaughtExceptionHandler() {
+            @Override
+            public void handleUncaughtException(Throwable ex, Method method, Object... params) {
+                LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, com.shkpr.service.proxycenter.constants.LogFlagBusiType.BUSI_INIT.toStrValue(), mStrClassName
+                        ,String.format("AsyncUncaughtException(method="+method.getName()+", msg="+ex.getMessage()+")..."));
+            }
+        };
+    }
+
+    @Override
+    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
+        TaskScheduler taskScheduler = taskScheduler();
+        scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
+    }
+
+    /** 定时任务多线程处理 */
+    @Bean(destroyMethod = "shutdown")
+    public ThreadPoolTaskScheduler taskScheduler(){
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        scheduler.setPoolSize(5);
+        scheduler.setThreadNamePrefix("Time-Task-");
+        //设置线程池中任务的等待时间,如果超过这个时间还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
+        //如:kill [PID]后,最大等待时长为5秒钟
+        scheduler.setAwaitTerminationSeconds(5);
+        //设置线程池关闭的时候等待所有任务都完成后,再继续销毁其他的Bean,这样这些异步任务的销毁就会先于数据库连接池对象的销毁
+        scheduler.setWaitForTasksToCompleteOnShutdown(true);
+        return scheduler;
+    }
+
+    @PostConstruct
+    public void init(){
+        new Timer().schedule(new TimerTask() {
+            @Override
+            public void run() {
+                com.shkpr.service.proxycenter.commtools.TimeTool.refreshUTCTimeRes();
+            }
+        }, 10000);//延时10秒执行
+    }
+}

+ 53 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/ValidatorConfiguration.java

@@ -0,0 +1,53 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import com.shkpr.service.proxycenter.globalcache.GlobalData;
+import org.hibernate.validator.HibernateValidator;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import javax.validation.executable.ExecutableValidator;
+
+@Configuration
+@EnableAutoConfiguration
+public class ValidatorConfiguration {
+
+    @Bean
+    public MethodValidationPostProcessor selfMethodValidationPostProcessor() {
+        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
+        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
+                .configure()
+                .addProperty( "hibernate.validator.fail_fast", "true" )
+                .buildValidatorFactory();
+        postProcessor.setValidator(validatorFactory.getValidator()/*selfValidator()*/);//设置validator模式为快速失败返回
+        return postProcessor;
+    }
+
+    //用于校验属性或变量
+    //使用时可用@Qualifier("selfValidator")进行识别
+    @Bean
+    public Validator selfValidator(){
+        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
+                .configure()
+                .addProperty( "hibernate.validator.fail_fast", "true" )
+                .buildValidatorFactory();
+        GlobalData.getInstance().setValidForParam(validatorFactory.getValidator());
+        return GlobalData.getInstance().getValidForParam();
+    }
+
+    //用于校验函数接口
+    //使用时可用@Qualifier("selfExeValidator")进行识别
+    @Bean
+    public ExecutableValidator selfExeValidator(){
+        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
+                .configure()
+                .addProperty( "hibernate.validator.fail_fast", "true" )
+                .buildValidatorFactory();
+        GlobalData.getInstance().setValidForFun(validatorFactory.getValidator().forExecutables());
+        return GlobalData.getInstance().getValidForFun();
+    }
+}

+ 96 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/WebMvcConfiguration.java

@@ -0,0 +1,96 @@
+package com.shkpr.service.proxycenter.configuration;
+import com.shkpr.service.proxycenter.SpringContextUtil;
+import com.shkpr.service.proxycenter.interfaces.URIInterceptorIntef;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpMethod;
+import org.springframework.util.StringUtils;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.*;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 该类主要用来注册各种Controller拦截器
+ * WebSecurityConfig类中注册的过滤器JWTLoginFilter、JWTAuthenticationFilter优先于该类中注册的拦截器URIInterceptorIntef
+ * 过滤拦截顺序: JWTLoginFilter--->JWTAuthenticationFilter--->URIInterceptorIntef
+ */
+@Configuration
+@EnableWebMvc
+public class WebMvcConfiguration implements WebMvcConfigurer{
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        @SuppressWarnings("static-access")
+        Map<String, URIInterceptorIntef> mapURLInterceptorByOrder = new TreeMap<String, URIInterceptorIntef>(); //TreeMap默认按键值升序
+        Map<String, URIInterceptorIntef> mapURLInterceptor = SpringContextUtil.getApplicationContext().getBeansOfType(URIInterceptorIntef.class);  //获取URIInterceptorIntef类型的所有Component组件
+        if (!StringUtils.isEmpty(mapURLInterceptor)){
+            Iterator it = mapURLInterceptor.entrySet().iterator();
+            while (it.hasNext()){
+                Map.Entry entry = (Map.Entry)it.next();
+                URIInterceptorIntef urlInterceptor = (URIInterceptorIntef)entry.getValue();
+                if (urlInterceptor != null){
+                    mapURLInterceptorByOrder.put(String.valueOf(urlInterceptor.order()), urlInterceptor);
+                }
+            }
+        }
+
+        if (!StringUtils.isEmpty(mapURLInterceptorByOrder)){
+            Iterator it = mapURLInterceptorByOrder.entrySet().iterator();
+            while (it.hasNext()){
+                Map.Entry entry = (Map.Entry)it.next();
+                //System.out.println("WebMvcConfig::addInterceptors() key="+(String) entry.getKey());
+                URIInterceptorIntef urlInterceptor = (URIInterceptorIntef)entry.getValue();
+                if (urlInterceptor != null){
+                    String[] arrForbidUrls = urlInterceptor.forbidPathPatterns();
+                    if (arrForbidUrls == null)
+                        arrForbidUrls = new String[]{};
+                    String[] arrExcludeUrls = urlInterceptor.excludePathPatterns();
+                    if (arrExcludeUrls == null){
+                        //多个拦截器将按照链接的顺序依次匹配拦截(注:有可能多个拦截器都匹配成功,则多个拦截器依次执行)
+                        registry.addInterceptor(urlInterceptor).addPathPatterns(arrForbidUrls);
+                    }else{
+                        registry.addInterceptor(urlInterceptor).addPathPatterns(arrForbidUrls).excludePathPatterns(arrExcludeUrls);
+                    }
+                }
+            }
+        }
+        //super.addInterceptors(registry);
+    }
+
+    //解决跨域问题
+    private CorsConfiguration buildConfig() {
+        CorsConfiguration corsConfiguration = new CorsConfiguration();
+        corsConfiguration.addAllowedOrigin("*");
+        //corsConfiguration.addAllowedMethod("*");
+        corsConfiguration.addAllowedMethod(HttpMethod.POST);
+        corsConfiguration.addAllowedMethod(HttpMethod.GET);
+        corsConfiguration.addAllowedMethod(HttpMethod.PUT);
+        corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
+        corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
+        corsConfiguration.addAllowedMethod(HttpMethod.HEAD);
+        corsConfiguration.addAllowedHeader("x-requested-with,Content-Type,Authorization,user-agent,Timestamp,Sequence,Signature");
+        return corsConfiguration;
+    }
+
+    //解决跨域问题
+    @Bean
+    public CorsFilter corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", buildConfig());
+        return new CorsFilter(source);
+    }
+
+    //配置该服务的默认首页用于阿里云服务SLB的http head健康检查
+    @Override
+    public void addViewControllers(ViewControllerRegistry registry) {
+        registry.addViewController("/").setViewName("index");
+        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
+        //super.addViewControllers(registry);
+    }
+
+}

+ 54 - 0
src/main/java/com/shkpr/service/proxycenter/configuration/WebSecurityConfiguration.java

@@ -0,0 +1,54 @@
+package com.shkpr.service.proxycenter.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+/**
+ * 该类主要用来做权限控制的配置、以及注册各种过滤器
+ * 执行顺序
+ * (1) 注册验证组件 - configure(AuthenticationManagerBuilder auth)方法中注册自定义验证组件
+ * (2) 设置验证规则 - configure(HttpSecurity http)方法中设置了各种路由访问规则
+ * (3) 初始化过滤组件 - JWTLoginFilter 和 JWTAuthenticationFilter 类会初始化
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)                     //@PreAuthorize对权限的注解需要设置prePostEnabled = true
+public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
+    @Value("${global.test.pressure:false}")
+    private boolean mBForPressureTest;
+
+    @Value("${global.ops.lan.ip:127.0.0.1}")
+    private String mStrOpsServerLanIP;
+
+    // 设置 HTTP 验证规则
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        String[] arrOpsServerLanIPs = mStrOpsServerLanIP.split(";");
+        String strAccessFilterForOps = "hasIpAddress('127.0.0.1')";
+        for (String strTmp:arrOpsServerLanIPs){
+            strAccessFilterForOps += " or hasIpAddress('"+ strTmp +"')";
+        }
+
+        http.csrf().disable()                                          // 关闭csrf验证
+                .authorizeRequests()                                   // 对请求进行认证
+                .antMatchers("/**").permitAll()
+                .anyRequest().authenticated();                                                                                          //所有其他请求需要身份认证;
+                /*.addFilterBefore(new ServerStatusMonitorFilter(ThirdApiURI.URI_HGAS_MONITOR_XXX, authenticationManager()),
+                        UsernamePasswordAuthenticationFilter.class);*/
+
+    }
+
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        /*web.ignoring()
+                .antMatchers("/error")
+                .antMatchers("/static")
+                .antMatchers("/static/**");                                                               // 所有/static下的静态资源请求时都忽略访问规则
+        */
+    }
+}

+ 164 - 0
src/main/java/com/shkpr/service/proxycenter/constants/ApiURI.java

@@ -0,0 +1,164 @@
+package com.shkpr.service.proxycenter.constants;
+public class ApiURI {
+    public static final String HEADER_X_SOURCE_IP = "X-Source-IP";
+    public static final String HEADER_BIZ_TYPE = "Biz-Type";
+    public static final String HEADER_CLIENT_TYPE = "Client-Type";
+    public static final String HEADER_USER_AGENT = "user-agent";
+    public static final String HEADER_AUTH_VERIFY = "Auth-Verify";
+    public static final String HEADER_SIGN_KEY = "tri_coorperation_tech_task";
+    public static final String HEADER_TIMESTAMP = "Timestamp";
+    public static final String HEADER_SEQUENCE = "Sequence";
+    public static final String HEADER_SIGNATURE = "Signature";
+    public static final String HEADER_AUTHORIZATION = "Authorization";
+    public static final String EXCEPTION_FORMAT = "{%s:%s}:%s"; //{(ios/apk/pc):url}:error reason
+    public static final String WORKSPACE = "Workspace";
+
+    public static final String URI_XXX_NEW_INFO = "new-info";//新增
+    public static final String URI_XXX_INFO = "info";   //精确查找
+    public static final String URI_XXX_ADD = "add";
+    public static final String URI_XXX_LISTS = "lists"; //分页查询
+    public static final String URI_XXX_RESET = "reset"; //更新(插入或更新)
+    public static final String URI_XXX_IDS = "ids";     //查询id列表
+    public static final String URI_XXX_SK = "sk";       //以key搜索查询
+    public static final String URI_XXX_SS = "ss";       //模糊搜索查询
+    public static final String URI_XXX_DEL = "del";     //删除
+    public static final String URI_XXX_TURN = "turn";   //转派
+    public static final String URI_XXX_TOTALS = "totals";   //数据统计
+    public static final String URI_XXX_ACCEPT = "accept";   //接收
+    public static final String URI_XXX_CHECK = "check";     //检测
+    public static final String URI_XXX_EXTENDS = "extends";//扩展数据
+    public static final String URI_XXX_ZONE_REGIONS_LISTS = "zone-regions-lists";
+    public static final String URI_XXX_STATUS_GROUP_TOTALS = "status-group-totals";   //状态分组数据统计
+    public static final String URI_XXX_ADD_NOTE = "add-note"; //追加批注
+    public static final String URI_XXX_LINE_TO_LINE = "line-to-line";//线到线
+    public static final String URI_XXX_LINE_TO_LINE_XWS = "line-to-line-xws";//多空间线到线
+    public static final String URI_XXX_LINE_TO_POINT = "line-to-point";//线到点
+    public static final String URI_XXX_LINE_TO_POINT_XWS = "line-to-point-xws";//多空间线到点
+    public static final String URI_XXX_UPLOAD = "upload";
+    public static final String URI_XXX_DOWNLOAD = "download";
+    public static final String URI_XXX_RESET_PWD = "pwd-reset";
+    public static final String URI_XXX_CHG_PWD = "pwd-chg";
+    public static final String URI_XXX_NEAR_BY = "near-by";
+    public static final String URI_XXX_NEAR_BY_XWS = "near-by-xws";//多空间附近搜索
+    public static final String URI_XXX_TYPE = "type";
+    public static final String URI_XXX_DRAW_LEN = "draw-length";
+    public static final String URI_XXX_DRAW_LEN_XWS = "draw-length-xws";//多空间长度统计
+    public static final String URI_XXX_DRAW_LEN_BY_TYPE = "draw-length-by-type";
+    public static final String URI_XXX_IMAGES = "images";
+    public static final String URI_XXX_ATT_LINK= "att-link";
+    public static final String URI_XXX_BIND = "bind";
+    public static final String URI_XXX_UNBIND = "unbind";
+    public static final String URI_XXX_APPEND_TO_BIND = "append-to-bind";
+    public static final String URI_XXX_DEL_TO_UNBIND = "del-to-unbind";
+    public static final String URI_XXX_LABEL= "label";
+    public static final String URI_XXX_SK_XWS = "sk-xws";
+    public static final String URI_XXX_LISTS_XWS = "lists-xws";
+    public static final String URI_XXX_NOTIFY = "notify";
+    public static final String URI_XXX_NUMBER = "number";
+    public static final String URI_XXX_RFIND = "rfind";
+    public static final String URI_XXX_VERIFY = "verify";
+    public static final String URI_XXX_PRE_VERIFY = "pre-verify";
+    public static final String URI_XXX_PREPARE = "prepare";
+    public static final String URI_XXX_COMMIT = "commit";
+    public static final String URI_XXX_PROPERTY_DEF = "property-def";
+    public static final String URI_XXX_TYPE_LISTS = "type-lists";
+    public static final String URI_XXX_STATUS_LISTS = "status-lists";
+    public static final String URI_XXX_WS_LISTS = "ws-lists";
+    public static final String URI_XXX_PROPERTY_LISTS = "property-lists";
+    public static final String URI_XXX_DO = "do";
+    public static final String URI_XXX_UNDO = "undo";
+    public static final String URI_XXX_RECORDS = "records";
+    public static final String URI_XXX_APPLY = "apply";
+    public static final String URI_XXX_PROGRESS = "progress";
+    public static final String URI_XXX_ALL_WITH_CHILD = "all-with-child";
+    public static final String URI_XXX_FAST_COPY = "fast-copy";
+    public static final String URI_XXX_MIX_DOWNLOAD = "mix-download";
+    public static final String URI_XXX_MIX_LISTS = "mix-lists";
+    public static final String URI_XXX_WS = "ws";
+    public static final String URI_XXX_ORG = "org";
+
+    public static final String URI_LOGIN = "/gis-ae/login";
+    public static final String URI_LOROUT = "/gis-ae/logout";
+    public static final String URI_LOGIN_NO_PASS = "/gis-ae/loginNoPass";
+    public static final String URI_ACCESS_TOKEN_CHECK = "/gis-ae/apply/access-token-check";
+    public static final String URI_FILE_BUSI_XXX = "/files/**";
+    public static final String URI_IMAGE_SHOW_XXX = "/imageShow/**";
+
+    public static final String URI_ALL_BUSI_XXX = "/gis-ae/**";
+
+    public static final String URI_USERS_H = "/gis-ae/users";
+    public static final String URI_USERS_XXX = URI_USERS_H+"/**";
+
+    public static final String URI_MAINT_H = "/gis-ae/maintenance";
+    public static final String URI_MAINT_XXX = URI_MAINT_H+"/**";
+
+    public static final String URI_LINKED_PATH_H = "/gis-ae/linked-path"; //连通性路径搜索
+    public static final String URI_LINKED_PATH_XXX = URI_LINKED_PATH_H+"/**";
+
+    public static final String URI_NNS_PATH_H = "/gis-ae/nns-path";       //最近邻路径搜索
+    public static final String URI_NNS_PATH_XXX = URI_NNS_PATH_H+"/**";
+
+    public static final String URI_CUSTOMERS_H = "/gis-ae/customer";
+    public static final String URI_CUSTOMERS_XXX = URI_CUSTOMERS_H+"/**";
+
+    public static final String URI_FEATURES_H = "/gis-ae/features";
+    public static final String URI_FEATURES_TOTALS_H = URI_FEATURES_H+"/totals";
+    public static final String URI_FEATURES_XXX = URI_FEATURES_H+"/**";
+    public static final String URI_FEATURES_UPLOAD_H = URI_FEATURES_H+"/upload";
+    public static final String URI_FEATURES_IMAGES_H = URI_FEATURES_H+"/images";
+    public static final String URI_FEATURES_LABEL_H = URI_FEATURES_H+"/label";
+    public static final String URI_FEATURES_LAYER_TEMPLATE_H = URI_FEATURES_H+"/layer-template";
+
+    public static final String URI_PIPELINE_H = "/gis-ae/pipeline";
+    public static final String URI_PIPELINE_TOTALS_H = URI_PIPELINE_H+"/totals";
+    public static final String URI_PIPELINE_XXX = URI_PIPELINE_H+"/**";
+
+    public static final String URI_COMMON_H = "/gis-ae/common";
+    public static final String URI_COMMON_XXX = URI_COMMON_H+"/**";
+
+    public static final String URI_FILES_H = "/gis-ae/files";
+    public static final String URI_FILES_XXX = URI_FILES_H+"/**";
+
+    public static final String URI_PUBLISH_H = "/gis-ae/publish";
+    public static final String URI_PUBLISH_XXX = URI_PUBLISH_H+"/**";
+
+    public static final String URI_TDT_MAP_REQ_H = "/gis-ae/tdt-map";
+    public static final String URI_TDT_MAP_REQ_XXX = URI_TDT_MAP_REQ_H+"/**";
+
+    public static final String URI_EXTEND_POWER_H = "/gis-ae/extend-power";
+    public static final String URI_EXTEND_POWER_XXX = URI_EXTEND_POWER_H+"/**";
+    public static final String URI_EXTEND_POWER_DIRECT_TABLE_H = URI_EXTEND_POWER_H+"/direct-table";
+
+    public static final String URI_TOTAL_TEMPLATE_H = "/gis-ae/total-template";
+    public static final String URI_TOTAL_TEMPLATE_XXX = URI_TOTAL_TEMPLATE_H + "/**";
+
+    public static final String URI_ANALY_STATS_REPORT_H = "/gis-ae/analy/stats-report";
+    public static final String URI_ANALY_STATS_REPORT_XXX = URI_ANALY_STATS_REPORT_H + "/**";
+
+    public static final String URI_INTERNAL_H = "/gis-ae/internal";
+    public static final String URI_INTERNAL_XXX = URI_INTERNAL_H+"/**";
+
+    public static final String URI_ELEMENT_CHANGE_H = "/gis-ae/element-change";
+    public static final String URI_ELEMENT_CHANGE_XXX = URI_ELEMENT_CHANGE_H + "/**";
+    public static final String URI_ELEMENT_CHANGE_APPLY_H = "/gis-ae/element-change/apply";
+    public static final String URI_ELEMENT_CHANGE_HANDLE_H = "/gis-ae/element-change/handle";
+
+    public static final String URI_METADATA_H = "/gis-ae/metadata";
+    public static final String URI_METADATA_XXX = URI_METADATA_H+"/**";
+    public static final String URI_METADATA_LAYER_TT_H = URI_METADATA_H+"/layer-define";
+    public static final String URI_METADATA_PROPERTY_TT_H = URI_METADATA_H+"/property-define";
+
+    public static final String URI_HGAS_MONITOR_XXX = "/hgas-monitor/**";
+    public static final String URI_HGAS_MONITOR_HEALTH = "/hgas-monitor/health"; //应用程序的健康指标信息
+    public static final String URI_HGAS_MONITOR_INFO = "/hgas-monitor/info";     //应用程序的自定义基本信息
+    public static final String URI_HGAS_MONITOR_ENV = "/hgas-monitor/env";       //应用程序的环境变量
+    public static final String URI_HGAS_MONITOR_METRICS ="/hgas-monitor/metrics";//应用程序的重要度量指标信息
+    public static final String URI_HGAS_MONITOR_DUMP ="/hgas-monitor/dump";       //应用程序的运行中的线程栈信息
+    public static final String URI_HGAS_MONITOR_TRACE ="/hgas-monitor/trace";     //应用程序的基本HTTP跟踪信息
+
+    public static final String URI_INTERNAL_PROPERTY_XXX = "/internal/prop/**";
+    public static final String URI_INTERNAL_PROPERTY_QUERY = "/internal/prop/query";
+    public static final String URI_INTERNAL_PROPERTY_SET = "/internal/prop/set";
+
+    public static final String URI_INTERNAL_OPS_XXX = "/ops/**";
+}

+ 16 - 0
src/main/java/com/shkpr/service/proxycenter/constants/AttachmentPurpose.java

@@ -0,0 +1,16 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface AttachmentPurpose {
+    String GUIDE = "guide";
+    String PROPERTY = "property";
+    String OTHER = "other";
+
+    List<String> ALL_PURPOSE = new ArrayList<String>(){{
+        add(GUIDE);
+        add(PROPERTY);
+        add(OTHER);
+    }};
+}

+ 8 - 0
src/main/java/com/shkpr/service/proxycenter/constants/AttachmentType.java

@@ -0,0 +1,8 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface AttachmentType {
+    int UN_KNOWN = -1;
+    int IMAGE = 1;
+    int VIDEO = 2;
+    int OTHER = 3;
+}

+ 22 - 0
src/main/java/com/shkpr/service/proxycenter/constants/CommAction.java

@@ -0,0 +1,22 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public interface CommAction {
+    String ADD = "add";
+    String DELETE = "delete";
+    String UPDATE = "update";
+    String PREPARE = "prepare";//预处理
+    String COMMIT = "commit";//处理提交
+    String CHECK = "check";//预审
+
+    Map<String,String> PROMOTE = new HashMap<String,String>(){{
+        put(ADD, "新增");
+        put(DELETE, "删除");
+        put(UPDATE, "修改");
+        put(PREPARE, "预处理");
+        put(COMMIT, "处理提交");
+        put(CHECK, "预审");
+    }};
+}

+ 14 - 0
src/main/java/com/shkpr/service/proxycenter/constants/CommDefine.java

@@ -0,0 +1,14 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface CommDefine {
+    String REQ_OUTER = "Outer";//外来请求者
+    String REQ_INNER = "Inner";
+    String INTERNAL_OPERATOR_ID = "FFFFFFFF";
+    String INTERNAL_OPERATOR_ROLE = "SelfOperator";
+    String INTERNAL_OPERATOR_ROLE_ID = "FFFFFFFF";
+    String ADMIN_USER_ID = "0";
+    String ADMIN_ROLE_ID = "0";
+    String ADMIN_ACCOUNT = "admin";
+    String INVALID_STR_ID = "-1";
+    String SUPER_USER_ID = "UUDA12395CB8B325F16";
+}

+ 7 - 0
src/main/java/com/shkpr/service/proxycenter/constants/CommProgress.java

@@ -0,0 +1,7 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface CommProgress {
+    int INIT = 0;
+    int HALF = 50;
+    int DONE = 100;
+}

+ 10 - 0
src/main/java/com/shkpr/service/proxycenter/constants/CommStatus.java

@@ -0,0 +1,10 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface CommStatus {
+    int UNKNOWN = -1;//未知
+    int READY = 0;//准备就绪(待预审)
+    int PROGRESS = 1;//处理中(预审通过处理中)
+    int SUCCESS = 2;//处理成功
+    int FAILED = 4;//处理失败
+    int OTHER = 255;//其他或取消
+}

+ 37 - 0
src/main/java/com/shkpr/service/proxycenter/constants/DownLoadEventFileType.java

@@ -0,0 +1,37 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class DownLoadEventFileType {
+    public static final List<String> CUSTOMER_COLUMN_HEADER = new ArrayList<>();
+    public static final HashMap<String, String> CUSTOMER_COLUMN = new HashMap<>();
+
+    static {
+        CUSTOMER_COLUMN_HEADER.add("user_code");
+        CUSTOMER_COLUMN_HEADER.add("user_name");
+        CUSTOMER_COLUMN_HEADER.add("address");
+        CUSTOMER_COLUMN_HEADER.add("caliber");
+        CUSTOMER_COLUMN_HEADER.add("phone");
+        CUSTOMER_COLUMN_HEADER.add("meter_no");
+        CUSTOMER_COLUMN_HEADER.add("meter_use");
+        CUSTOMER_COLUMN_HEADER.add("use_nature");
+        CUSTOMER_COLUMN_HEADER.add("press_level");
+        CUSTOMER_COLUMN_HEADER.add("status_code");
+        CUSTOMER_COLUMN_HEADER.add("status_name");
+
+        CUSTOMER_COLUMN.put("user_code","用户编号");
+        CUSTOMER_COLUMN.put("user_name","用户名称");
+        CUSTOMER_COLUMN.put("address","用户地址");
+        CUSTOMER_COLUMN.put("caliber","口径(DN)");
+        CUSTOMER_COLUMN.put("phone","联系电话");
+        CUSTOMER_COLUMN.put("meter_no","水表表号");
+        CUSTOMER_COLUMN.put("meter_use","水表用途");
+        CUSTOMER_COLUMN.put("use_nature","用水性质");
+        CUSTOMER_COLUMN.put("press_level","加压级别");
+        CUSTOMER_COLUMN.put("status_code","状态标识");
+        CUSTOMER_COLUMN.put("status_name","状态");
+    }
+
+}

+ 8 - 0
src/main/java/com/shkpr/service/proxycenter/constants/FeatureLikesField.java

@@ -0,0 +1,8 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface FeatureLikesField {
+    String TYPE = "type";
+    String SN = "sn";
+    String NAME = "name";
+    String WELL_NO = "wellNo";
+}

+ 34 - 0
src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSFeatureFieldDefine.java

@@ -0,0 +1,34 @@
+package com.shkpr.service.proxycenter.constants;
+
+import org.springframework.util.StringUtils;
+
+public class GeoWFSFeatureFieldDefine {
+    public static class Property{
+        public static String SN = "编码";
+        public static String Label = "电子标签";
+        public static volatile String Address = "所在道路名";
+        public static volatile String DrawLen = "图纸长度";
+        public static volatile String DN = "口径dn";
+        public static String QCode = "二维码";
+
+        public static void initTotalLineDNDefine(String dnDefine){
+            if (!StringUtils.isEmpty(dnDefine))
+                DN = dnDefine;
+        }
+
+        public static void initTotalLineLenDefine(String lenDefine){
+            if (!StringUtils.isEmpty(lenDefine))
+                DrawLen = lenDefine;
+        }
+
+        public static void initAddressDefine(String addressDefine){
+            if (!StringUtils.isEmpty(addressDefine))
+                Address = addressDefine;
+        }
+    }
+
+    public static class Geometry{
+        public static String Gis = "coordinates";
+        public static String Type = "type";
+    }
+}

+ 19 - 0
src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSLayerKindDefine.java

@@ -0,0 +1,19 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface GeoWFSLayerKindDefine {
+    String LINE = "line"; //线图层
+    String POINT = "point";//点图层
+    String FACE = "face";//面图层
+
+    String MIX_LINE_LAYER = "mix_line"; //混合线图层
+    String MIX_POINT_LAYER = "mix_point";//混合点图层
+
+    List<String> ORIGIN_KIND = new ArrayList<String>(){{
+        add(LINE);
+        add(POINT);
+        add(FACE);
+    }};
+}

+ 38 - 0
src/main/java/com/shkpr/service/proxycenter/constants/GeoWFSLayerKindPPKey.java

@@ -0,0 +1,38 @@
+package com.shkpr.service.proxycenter.constants;
+
+import org.springframework.util.StringUtils;
+
+public class GeoWFSLayerKindPPKey {
+    public static class BASE{
+        public static String TYPE = "类型";
+        public static String OBJ_ID_1 = "objectid_1";
+        public static String OBJ_ID = "objectid";
+        public static String CODE = "编码";
+        public static String WELL_NO = "井编号";
+        public static String NAME = "名称";
+    }
+
+    public static final class LINE extends BASE{
+        public static volatile String UP_NODE = "上游节点";
+        public static volatile String DOWN_NODE = "下游节点";
+        public static volatile String PIPE_LEN = "管长";//在模型中,主要用于表示线的权重;必要时可为图纸长度或勘测长度
+
+        public static void initUpDownNodeDefine(String upNode, String downNode){
+            if (!StringUtils.isEmpty(upNode))
+                UP_NODE = upNode;
+            if (!StringUtils.isEmpty(downNode))
+                DOWN_NODE = downNode;
+        }
+
+        public static void initPipeLenDefine(String pipeLen){
+            if (!StringUtils.isEmpty(pipeLen))
+                PIPE_LEN = pipeLen;
+        }
+    }
+
+    public static final class POINT extends BASE{
+    }
+
+    public static final class FACE extends BASE{
+    }
+}

+ 26 - 0
src/main/java/com/shkpr/service/proxycenter/constants/GisMetadataDefine.java

@@ -0,0 +1,26 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface GisMetadataDefine {
+    interface WATER_NATURE{
+        String SUPPLY = "supply";
+        String DRAIN = "drain";
+        List<String> DEFINES = new ArrayList<String>(){{
+            add(SUPPLY);
+            add(DRAIN);
+        }};
+    }
+
+    interface TYPE_KINE{
+        String POINT = "point";
+        String LINE = "line";
+        String FACE = "face";
+        List<String> DEFINES = new ArrayList<String>(){{
+            add(POINT);
+            add(LINE);
+            add(FACE);
+        }};
+    }
+}

+ 16 - 0
src/main/java/com/shkpr/service/proxycenter/constants/GisSelfDefineTemplate.java

@@ -0,0 +1,16 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface GisSelfDefineTemplate {
+    String TOTAL = "total"; //统计模板
+    String DISPLAY = "display";//展示模板
+    String QUERY = "query";//查询模板
+
+    List<String> ALL_TYPE = new ArrayList<String>(){{
+        add(TOTAL);
+        add(DISPLAY);
+        add(QUERY);
+    }};
+}

+ 16 - 0
src/main/java/com/shkpr/service/proxycenter/constants/LabelType.java

@@ -0,0 +1,16 @@
+package com.shkpr.service.proxycenter.constants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface LabelType {
+    String NFC = "nfc";
+    String QCODE = "qcode";
+    String OTHER = "other";
+
+    List<String> ALL_TYPE = new ArrayList<String>(){{
+        add(NFC);
+        add(QCODE);
+        add(OTHER);
+    }};
+}

+ 80 - 0
src/main/java/com/shkpr/service/proxycenter/constants/LogFlagBusiType.java

@@ -0,0 +1,80 @@
+package com.shkpr.service.proxycenter.constants;
+
+public enum  LogFlagBusiType {
+    BUSI_INIT(0,"Init Busi"),
+    BUSI_CONN(1,"Conn Busi"),
+    BUSI_AUTH(2, "Auth Busi"),
+    BUSI_SUB(3, "Subscribe Busi"),
+    BUSI_NOTIFY(4, "Notify Busi"),
+    BUSI_CMD(5,"Command Busi"),
+    BUSI_USER(6,"User Busi"),
+    BUSI_DEV(7,"Dev Busi"),
+    BUSI_APP_APIS(8, "App Apis"),
+    BUSI_USER_APIS_CASE(9,"User Apis Case"),
+    BUSI_ROLE_POWER(10,"Role Power Info"),
+    BUSI_PARTITION(11,"Partition Info"),
+    BUSI_MAINT_RECORDS(12,"Maintenance Records"),
+    BUSI_CALL_BASE_AS(13, "Call Base As Busi"),
+    BUSI_CALL_GEO_SERVER(14, "Call GeoServer As Busi"),
+    BUSI_LINKED_PATH(15, "Linked Path Busi"),
+    BUSI_NNS_PATH(16, "NNS Path Busi"),
+    BUSI_WFS_FEATURE(17, "WFS Feature Busi"),
+    BUSI_CUSTOMER(18, "Customer Busi"),
+    BUSI_FILES(19, "Files Busi"),
+    BUSI_FEATURES(20, "Features Busi"),
+    BUSI_FEATURES_TOTALS(21, "Features Totals Busi"),
+    BUSI_CALL_TDT_MAP_SERVER(22, "Call TDTMap Server As Busi"),
+    BUSI_TDT_MAP_BUSI(23, "TDTMap Busi"),
+    BUSI_COMMON(24, "Common Busi"),
+    BUSI_EXTEND_DIRECT_TABLE(25,"Extend Power Direct Table"),
+    BUSI_CALL_TASK_AS(26, "Call Task As Busi"),
+    BUSI_PIPELINE(27, "PipeLine Busi"),
+    BUSI_GIS_TOTAL_TEMPLATE(28, "Gis Super Template Busi"),
+    BUSI_GIS_ELEMENT_ACTION(29, "Gis Element Action Busi"),
+    BUSI_FEATURES_LAYER_TEMPLATE(30, "Features Layer Template Biz"),
+    BUSI_GEO_PUBLISH(31, "Geo Publish Biz"),
+    BUSI_GIS_METADATA_LAYER_TT(32, "Gis Metadata Layer Template"),
+    BUSI_GIS_METADATA_PROPERTY_TT(33, "Gis Metadata Property Template"),
+    BUSI_NO_JWT_BIZ(34, "No JWT Biz"),
+    BUSI_GIS_ANALY_STATS_REPORT(35, "Gis Analy Stats Report Biz"),
+
+    BUSI_INTERNAL(99,"Internal Busi"),
+
+    BUSI_DB_USER(100,"DB User Busi"),
+    BUSI_DB_DEV(101,"DB Dev Busi"),
+    BUSI_DB_DEV_TYPE(102, "DB Dev Type Busi"),
+    BUSI_DB_APP_APIS(103,"DB App Apis"),
+    BUSI_DB_USER_APIS_CASE(104,"DB User Apis Case"),
+    BUSI_DB_ROLE_POWER(105,"DB Role Power Info"),
+    BUSI_DB_PARTITION(106,"DB Partition Info"),
+    BUSI_DB_MT_RECORD(107,"DB Maintenance Records"),
+    BUSI_DB_ROLE_INFO(108,"DB Role Info"),
+    BUSI_DB_MEDIA_INFO(109,"DB Media Info"),
+    BUSI_DB_CUSTOMER_DEVICE_LINK(110,"DB Customer Device Link"),
+    BUSI_DB_TILE_MAP_INFO(111,"DB Tile Map Info"),
+    BUSI_DB_FILE_ATTACHMENT(112,"DB File Attachment Info"),
+    BUSI_DB_DEVICE_ATTACHMENT_LINK(113,"DB Device Attachment Link"),
+    BUSI_DB_DIRECT_READ_TABLE_INFO(114,"DB Direct Read Table Info"),
+    BUSI_DB_DEVICE_LABEL_INFO(115,"DB Device Label Info"),
+    BUSI_DB_GIS_TOTAL_TEMPLATE(116,"DB Gis Super Template"),
+    BUSI_DB_ELEMENT_CHANGE_APPLY(117,"DB Element Change Apply"),
+    BUSI_DB_PIPE_LAYER_TYPE_KIND_LINK(118,"DB Pipe Layer Type Kind Link"),
+    BUSI_DB_GIS_DYNAMIC_BIZ(119,"DB Gis Dynamic Biz"),
+    BUSI_DB_GIS_PUBLISH_APPLY(120,"DB Gis Publish Apply"),
+    BUSI_DB_GIS_METADATA_LAYER(121,"DB Gis Metadata Layer Template"),
+    BUSI_DB_GIS_METADATA_PROPERTY(122,"DB Gis Metadata Property Template"),
+    BUSI_DB_GIS_LAYER_DAILY_ANALYSIS(124,"DB Gis Layer Daily Analysis"),
+
+    BUSI_ALL(999,"ALL Busi"),
+    BUSI_REDIS(1000,"Redis Busi");
+
+    private LogFlagBusiType(int index, String name){
+        this.name = name;
+        this.index = index;
+    }
+    private String name;
+    private int index;
+    public int toIntValue(){return index;}
+    public String toStrValue() {return name;}
+}
+

+ 16 - 0
src/main/java/com/shkpr/service/proxycenter/constants/MsgNotifyDefine.java

@@ -0,0 +1,16 @@
+package com.shkpr.service.proxycenter.constants;
+
+public class MsgNotifyDefine {
+    public interface Topic{
+        String GIS_FEATURE = "gisFeature";
+        String GIS_LAYER = "gisLayer";
+        String GIS_WS = "gisWS";
+    }
+    public interface Tag{
+        String LABEL = "label";
+        String QCODE = "qcode";
+        String CHANGE = "change";
+        String RELOAD = "reload";
+        String ANALYZE = "analyze";
+    }
+}

+ 8 - 0
src/main/java/com/shkpr/service/proxycenter/constants/OrderAttRange.java

@@ -0,0 +1,8 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface OrderAttRange {
+    int UN_KNOWN = -1;
+    int ORIGINAL = 1;      //原始附件
+    int BEFORE_HANDLE = 2; //处理前附件
+    int AFTER_HANDLE = 3;  //处理后附件
+}

+ 15 - 0
src/main/java/com/shkpr/service/proxycenter/constants/StorageGroupType.java

@@ -0,0 +1,15 @@
+package com.shkpr.service.proxycenter.constants;
+
+public enum StorageGroupType {
+    BIZ(1,"gis-element"),
+    MAP(2,"maps");
+
+    private StorageGroupType(int index, String name){
+        this.name = name;
+        this.index = index;
+    }
+    private String name;
+    private int index;
+    public int toIntValue(){return index;}
+    public String toStrValue() {return name;}
+}

+ 37 - 0
src/main/java/com/shkpr/service/proxycenter/constants/TaskQueueDataTypeEx.java

@@ -0,0 +1,37 @@
+package com.shkpr.service.proxycenter.constants;
+
+import com.global.base.taskqueue.TaskQueueDataType;
+
+public class TaskQueueDataTypeEx extends TaskQueueDataType {
+    public static final int ASYNC_TASK_BEGIN = 1000;
+    public static final int ASYNC_PUSH_TASK = ASYNC_TASK_BEGIN+1;
+    public static final int ASYNC_PUSH_TASK_RW_DB = ASYNC_PUSH_TASK+1;
+    public static final int ASYNC_PARSE_EVENT_FILE = ASYNC_PUSH_TASK_RW_DB+1;
+    public static final int ASYNC_NOTIFY_PWD_RESET = ASYNC_PARSE_EVENT_FILE+1;
+    public static final int ASYNC_REFRESH_GEO_WFS_FEATURE_TYPE = ASYNC_NOTIFY_PWD_RESET+1;
+    public static final int ASYNC_FLUSH_TILE_MAP_TO_FASTDFS = ASYNC_REFRESH_GEO_WFS_FEATURE_TYPE+1;
+    public static final int ASYNC_BATCH_SYNC_TILE_MAP_FROM_REMOTE = ASYNC_FLUSH_TILE_MAP_TO_FASTDFS+1;
+    public static final int ASYNC_REFRESH_GEO_WFS_FEATURE_DATA = ASYNC_BATCH_SYNC_TILE_MAP_FROM_REMOTE+1;
+    public static final int ASYNC_RELOAD_GEO_WORKSPACE = ASYNC_REFRESH_GEO_WFS_FEATURE_DATA+1;
+    public static final int ASYNC_TASK_END = 1100;
+
+    public static final int DELAY_TASK_BEGIN = 2000;
+    public static final int DELAY_PUSH_TASK = DELAY_TASK_BEGIN+1;
+    public static final int DELAY_BATCH_SYNC_TILE_MAP_FROM_REMOTE = DELAY_PUSH_TASK+1;
+    public static final int DELAY_BATCH_SYNC_DEV_LABEL_TO_GEO_SERVER = DELAY_BATCH_SYNC_TILE_MAP_FROM_REMOTE+1;
+    public static final int DELAY_CHECK_GEO_PUBLISH_STEP = DELAY_BATCH_SYNC_DEV_LABEL_TO_GEO_SERVER+1;
+    public static final int DELAY_HANDLE_LAYER_CHANGED = DELAY_CHECK_GEO_PUBLISH_STEP+1;
+    public static final int DELAY_HANDLE_WS_CHANGED = DELAY_HANDLE_LAYER_CHANGED+1;
+    public static final int DELAY_RELOAD_GEO_WORKSPACE = DELAY_HANDLE_WS_CHANGED+1;
+    public static final int DELAY_REDO_LAYER_DAILY = DELAY_RELOAD_GEO_WORKSPACE+1;
+    public static final int DELAY_TASK_END = 2010;
+
+    public static final int NOTIFY_MSG_BEGIN = 2020;
+    public static final int NOTIFY_MSG_TO_TASK_SERVICE = NOTIFY_MSG_BEGIN+1;
+    public static final int NOTIFY_MSG_FROM_OTHER_SERVICE  = NOTIFY_MSG_TO_TASK_SERVICE+1;
+    public static final int NOTIFY_MSG_END = 2030;
+
+    public static final int SINGLE_TASK_BEGIN = 2040;
+    public static final int SINGLE_PUBLISH_LAYER = SINGLE_TASK_BEGIN+1;
+    public static final int SINGLE_TASK_END = 2050;
+}

+ 5 - 0
src/main/java/com/shkpr/service/proxycenter/constants/TileMapKindDefine.java

@@ -0,0 +1,5 @@
+package com.shkpr.service.proxycenter.constants;
+
+public interface TileMapKindDefine {
+    String TDT = "tdt"; //天地图瓦片类型
+}

+ 102 - 0
src/main/java/com/shkpr/service/proxycenter/constants/UploadEventFileType.java

@@ -0,0 +1,102 @@
+package com.shkpr.service.proxycenter.constants;
+
+import com.shkpr.service.proxycenter.commtools.BytesUtils;
+import com.shkpr.service.proxycenter.commtools.CommTool;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class UploadEventFileType {
+    public static final HashMap<String, String> FILES_TYPE = new HashMap<>();
+    public static final HashMap<String, String> CUSTOMER_REQUIRED = new HashMap<>();
+    public static final HashMap<String, String> CUSTOMER_OPTIONAL = new HashMap<>();
+    static {
+        // images
+        FILES_TYPE.put("jpg","FFD8FF");
+        FILES_TYPE.put("png","89504E47");
+        FILES_TYPE.put("gif","47494638");
+        FILES_TYPE.put("tif","49492A00");
+        FILES_TYPE.put("bmp","424D");
+
+        FILES_TYPE.put("xml","3C3F786D6C");
+        FILES_TYPE.put("html","68746D6C3E");
+        //FILES_TYPE.put("doc","D0CF11E0");
+        FILES_TYPE.put("xls","D0CF11E0");//excel2003版本文件
+        //FILES_TYPE.put("docx","504B0304");
+        FILES_TYPE.put("xlsx","504B0304");//excel2007以上版本文件
+
+        CUSTOMER_REQUIRED.put("用户编号","user_code");
+        /*CUSTOMER_OPTIONAL.put("用户名称","user_name");
+        CUSTOMER_OPTIONAL.put("用户地址","address");
+        CUSTOMER_OPTIONAL.put("口径(DN)","caliber");
+        CUSTOMER_OPTIONAL.put("联系电话","phone");
+        CUSTOMER_OPTIONAL.put("水表表号","meter_no");
+        CUSTOMER_OPTIONAL.put("水表用途","meter_use");
+        CUSTOMER_OPTIONAL.put("用水性质","use_nature");
+        CUSTOMER_OPTIONAL.put("加压级别","press_level");*/
+    }
+
+
+    public static final int CUSTOMER_EVENT = 0;
+
+    public static String getFileTypeFromStream(InputStream stream){
+        if (stream == null)
+            return "";
+
+        try {
+            byte[] b = new byte[4];
+            stream.read(b, 0, b.length);
+            return BytesUtils.bytesToHexString(b);
+        }catch (Exception e){}
+        finally {
+            if (stream != null){
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return "";
+    }
+
+    public static boolean isSupportFileType(String typeHex, int eventType){
+        switch (eventType){
+            case CUSTOMER_EVENT:{
+                return FILES_TYPE.get("xls").startsWith(typeHex) || FILES_TYPE.get("xlsx").startsWith(typeHex);
+            }
+        }
+        return false;
+    }
+
+    public static String getFileExtByFileType(String typeHex){
+        if (!StringUtils.isEmpty(typeHex)){
+            for (Map.Entry<String, String> entry:FILES_TYPE.entrySet()){
+                String ext = entry.getKey();
+                String type = entry.getValue();
+                if (type.startsWith(typeHex))
+                    return ext;
+            }
+        }
+        return "";
+    }
+
+    public static String getImageFileType(String typeHex){
+        if (CommTool.lenString(typeHex) > 0){
+            if (typeHex.startsWith(FILES_TYPE.get("jpg")))
+                return "jpg";
+            else if (FILES_TYPE.get("png").startsWith(typeHex))
+                return "png";
+            else if (FILES_TYPE.get("gif").startsWith(typeHex))
+                return "gif";
+            return "jpeg";
+        }
+        return "";
+    }
+
+    public static boolean isSupportImageFile(String typeHex){
+        return !StringUtils.isEmpty(getImageFileType(typeHex));
+    }
+}

+ 37 - 0
src/main/java/com/shkpr/service/proxycenter/constants/UrlMethodType.java

@@ -0,0 +1,37 @@
+package com.shkpr.service.proxycenter.constants;
+
+import org.springframework.web.bind.annotation.RequestMethod;
+
+public enum UrlMethodType {
+    GET("GET", RequestMethod.GET),
+    HEAD("HEAD", RequestMethod.HEAD),
+    POST("POST", RequestMethod.POST),
+    PUT("PUT", RequestMethod.PUT),
+    PATCH("PATCH", RequestMethod.PATCH),
+    DELETE("DELETE", RequestMethod.DELETE),
+    OPTIONS("OPTIONS", RequestMethod.OPTIONS);
+
+    UrlMethodType(String name, RequestMethod method) {
+        this.name = name;
+        this.method = method;
+    };
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public RequestMethod getMethod() {
+        return method;
+    }
+
+    public void setMethod(RequestMethod method) {
+        this.method = method;
+    }
+
+    private String name;
+    private RequestMethod method;
+}

+ 17 - 0
src/main/java/com/shkpr/service/proxycenter/constants/UserCurStateType.java

@@ -0,0 +1,17 @@
+package com.shkpr.service.proxycenter.constants;
+
+public enum UserCurStateType {
+    STATE_REGISTER(0,"Registering"),
+    STATE_ENABLE(1,"Enable"),
+    STATE_DISABLE(2,"Disable"),
+    STATE_LOGOUT(3,"Logout");
+    private String name;
+    private int index;
+
+    private UserCurStateType(int index,String name) {
+        this.name = name;
+        this.index = index;
+    }
+    public int toIntValue(){return index;}
+    public String toStrValue() {return name;}
+}

+ 53 - 0
src/main/java/com/shkpr/service/proxycenter/constants/ViewContentType.java

@@ -0,0 +1,53 @@
+package com.shkpr.service.proxycenter.constants;
+
+import org.apache.commons.lang3.StringUtils;
+
+public enum ViewContentType {
+    DEFAULT("default","application/octet-stream"),
+    JPG("jpg", "image/jpeg"),
+    TIFF("tiff", "image/tiff"),
+    GIF("gif", "image/gif"),
+    JFIF("jfif", "image/jpeg"),
+    PNG("png", "image/png"),
+    TIF("tif", "image/tiff"),
+    ICO("ico", "image/x-icon"),
+    JPEG("jpeg", "image/jpeg"),
+    WBMP("wbmp", "image/vnd.wap.wbmp"),
+    FAX("fax", "image/fax"),
+    NET("net", "image/pnetvue"),
+    JPE("jpe", "image/jpeg"),
+    RP("rp", "image/vnd.rn-realpix");
+
+    private String prefix;
+    private String type;
+
+    public static String getContentType(String prefix){
+        if(StringUtils.isEmpty(prefix))
+            return DEFAULT.getType();
+
+        int tmpIndex = prefix.lastIndexOf(".");
+        if (tmpIndex < 0)
+            return DEFAULT.getType();
+
+        prefix = prefix.substring(tmpIndex+1);
+        for (ViewContentType value:ViewContentType.values()) {
+            if (value.getPrefix().equalsIgnoreCase(prefix)){
+                return value.getType();
+            }
+        }
+        return DEFAULT.getType();
+    }
+
+    ViewContentType(String prefix, String type) {
+        this.prefix = prefix;
+        this.type = type;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public String getType() {
+        return type;
+    }
+}

+ 88 - 0
src/main/java/com/shkpr/service/proxycenter/controllerfilter/GrantedAuthorityImpl.java

@@ -0,0 +1,88 @@
+package com.shkpr.service.proxycenter.controllerfilter;
+
+import com.shkpr.service.proxycenter.dto.LoginUserRoleType;
+import org.springframework.security.core.GrantedAuthority;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GrantedAuthorityImpl implements GrantedAuthority{
+    private static volatile List<GrantedAuthorityImpl> msArrRootAdmin = null;
+    private static volatile List<GrantedAuthorityImpl> msArrAdmin = null;
+    private static volatile List<GrantedAuthorityImpl> msArrNormalUser = null;
+    private static volatile List<GrantedAuthorityImpl> msArrTempUser = null;
+
+    private String authority;
+    public GrantedAuthorityImpl(String authority) {
+        this.authority = authority;
+    }
+    public void setAuthority(String authority) {
+        this.authority = authority;
+    }
+    @Override
+    public String getAuthority() {
+        return this.authority;
+    }
+
+    public static List<GrantedAuthorityImpl> generateAuthority(LoginUserRoleType emType){
+        switch (emType){
+            case ROOT_ADMIN:{
+                if (msArrRootAdmin == null){
+                    synchronized(GrantedAuthorityImpl.class){
+                        if (msArrRootAdmin == null){
+                            msArrRootAdmin = new ArrayList<GrantedAuthorityImpl>();
+                            msArrRootAdmin.add(new GrantedAuthorityImpl(emType.toStrValue()));
+                        }
+                    }
+                }
+            }
+            return msArrRootAdmin;
+            case TEMP_USER:{
+                if (msArrTempUser == null){
+                    synchronized(GrantedAuthorityImpl.class){
+                        if (msArrTempUser == null){
+                            msArrTempUser = new ArrayList<GrantedAuthorityImpl>();
+                            msArrTempUser.add(new GrantedAuthorityImpl(emType.toStrValue()));
+                        }
+                    }
+                }
+            }
+            return msArrTempUser;
+            case NORMAL_USER:{
+                if (msArrNormalUser == null){
+                    synchronized(GrantedAuthorityImpl.class){
+                        if (msArrNormalUser == null){
+                            msArrNormalUser = new ArrayList<GrantedAuthorityImpl>();
+                            msArrNormalUser.add(new GrantedAuthorityImpl(emType.toStrValue()));
+                        }
+                    }
+                }
+            }
+            return msArrNormalUser;
+            case ADMIN:{
+                if (msArrAdmin == null){
+                    synchronized(GrantedAuthorityImpl.class){
+                        if (msArrAdmin == null){
+                            msArrAdmin = new ArrayList<GrantedAuthorityImpl>();
+                            msArrAdmin.add(new GrantedAuthorityImpl(emType.toStrValue()));
+                        }
+                    }
+                }
+            }
+            return msArrAdmin;
+            default:
+                break;
+        }
+        return null;
+    }
+
+    public static LoginUserRoleType getRoleTypeByAuthority(List<GrantedAuthorityImpl> authorityList){
+        if (authorityList == msArrRootAdmin)
+            return LoginUserRoleType.ROOT_ADMIN;
+        else if (authorityList == msArrAdmin)
+            return LoginUserRoleType.ADMIN;
+        else if (authorityList == msArrNormalUser)
+            return LoginUserRoleType.NORMAL_USER;
+        else
+            return LoginUserRoleType.TEMP_USER;
+    }
+}

+ 287 - 0
src/main/java/com/shkpr/service/proxycenter/controllerfilter/TokenAuthenticationService.java

@@ -0,0 +1,287 @@
+package com.shkpr.service.proxycenter.controllerfilter;
+
+import com.shkpr.service.proxycenter.dto.AuthTokenData;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.Map;
+
+public class TokenAuthenticationService {
+    public static final int MIN_EXPIRATIONTIME = 7*60*24;                              // 默认Token过期时间为7天(单位:分钟)
+    public static final long MS_EXPIRATIONTIME = MIN_EXPIRATIONTIME*60*1000;         // 默认Token过期时间为7天(单位:毫秒)
+    public static final String SECRET = "TRICP_ALAM_DMA";                              // JWT密码
+    public static final String HEADER_STRING = "Authorization";                       // 存放Token的Header Key
+    public static final String HEADER_CONTENT_TYPE = "application/json;charset=UTF-8";
+    public static final String HEADER_SHORT_CONTENT_TYPE = "application/json";
+    public static final String SIGNATURE_KEY = "tri_coorperation_tech";              //签名秘钥
+    public static final String HEADER_SEQUENCE = "Sequence";
+    public static final String HEADER_USERID = "UUID";
+    public static final String HEADER_ROLEID = "RLID";
+
+    //该方法使用HS256算法生成signKey
+    /*private static Key getKeyInstance() {
+        //We will sign our JavaWebToken with our ApiKey secret
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
+        return new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
+    }*/
+
+    /**
+     * 从数据声明中生成令牌
+     * @param claims
+     * @return
+     */
+    private static AuthTokenData generateToken(Map<String, Object> claims){
+        return generateToken(claims, MIN_EXPIRATIONTIME);
+    }
+
+    /**
+     * 从数据声明中生成令牌
+     * @param expired Token过期时间(单位:分钟)
+     * @return
+     */
+    private static AuthTokenData generateToken(Map<String, Object> claims, int expired){
+        String strFlagKey = "";
+        String strAccount = "";
+        String roleId = "";
+        try {
+            strFlagKey = (String)claims.get("flagkey");
+        } catch (Exception e){}
+        try {
+            strAccount = (String)claims.get("account");
+        } catch (Exception e){}
+        try {
+            roleId = (String)claims.get("roleid");
+        } catch (Exception e){}
+        return generateToken(strFlagKey, strAccount, roleId, expired);
+    }
+
+    /**
+     * @param strFlagKey
+     * @param expired Token过期时间(单位:分钟)
+     * @return
+     */
+    public static AuthTokenData generateToken(String strFlagKey, String strAccount, String roleId, int expired){
+        /*Map<String, Object> claims = new HashMap<>(16);
+        //claims.put("sub", strUsername);
+        claims.put("flagkey", strFlagKey);
+        claims.put("account", strAccount);
+        claims.put("roleid", roleId);
+        return generateToken(claims, expired);*/
+        long nowMillis = System.currentTimeMillis();
+        Date dateExpired  = null;
+        String strToken = null;
+        try {
+            strToken = Jwts.builder()
+                    .setHeaderParam("typ", "JWT")
+                    .setHeaderParam("alg", "HS256")
+                    //.setAudience("APP")
+                    //.setIssuer("SERVICE")
+                    //.setId(UUID.randomUUID().toString())
+                    .setIssuedAt(new Date(nowMillis))                                         //设置Token的签发时间
+                    .setExpiration(dateExpired = new Date(nowMillis + expired*60*1000))       //设置Token有效期
+                    .signWith(SignatureAlgorithm.HS256, SECRET.getBytes("UTF-8"))          //签名设置
+                    .claim("flagkey", strFlagKey)
+                    .claim("account", strAccount)
+                    .claim("roleid", roleId)
+                    .compact();
+        } catch (Exception e){
+            strToken = null;
+            e.printStackTrace();
+        }
+
+        return  StringUtils.isEmpty(strToken) ? null:new AuthTokenData(strToken
+                , dateExpired!=null ? dateExpired.getTime():System.currentTimeMillis()
+                , nowMillis
+                , strFlagKey);
+    }
+
+    /**
+     * 从令牌中获取数据声明
+     * 使用该接口需要同时捕获ExpiredJwtException和Exception异常并处理
+     * @param token 令牌
+     * @return 数据声明
+     */
+    private static Claims getClaimsFromToken(String token) throws ExpiredJwtException, Exception{
+        Claims claims = null;
+        try {
+            claims = Jwts.parser().setSigningKey(SECRET.getBytes("UTF-8")).parseClaimsJws(token).getBody();
+        }catch (ExpiredJwtException e){
+            claims = null;
+            throw e;
+        }catch (Exception e) {
+            claims = null;
+            throw e;
+        }
+        return claims;
+    }
+
+    /**
+     * 从令牌中获取FlagKey
+     * @param token
+     * @return
+     * @throws ExpiredJwtException
+     * @throws Exception
+     */
+    public static String getFlagKeyFromToken(String token) throws ExpiredJwtException, Exception{
+        String strKey = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null)
+                strKey = (String)claims.get("flagkey");
+        }catch (ExpiredJwtException e){
+            strKey = null;
+            throw e;
+        }catch (Exception e) {
+            strKey = null;
+            throw e;
+        }
+        return strKey;
+    }
+
+    public static AuthTokenData getAuthDataFromToken(String token) throws ExpiredJwtException, Exception{
+        AuthTokenData data = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                String strKey = (String)claims.get("flagkey");
+                String strRoleId = (String)claims.get("roleid");
+                data = new AuthTokenData(token, claims.getExpiration().getTime(), claims.getIssuedAt().getTime(), strKey, strRoleId);
+            }
+        }catch (ExpiredJwtException e){
+            data = null;
+            throw e;
+        }catch (Exception e) {
+            data = null;
+            throw e;
+        }
+        return data;
+    }
+
+    /**
+     * 从令牌中获取用户ID
+     *
+     * @param token 令牌
+     * @return 用户ID
+     */
+    public static String getUserIDFromToken(String token) throws ExpiredJwtException, Exception{
+        String strKey = null;
+        try {
+            strKey = getFlagKeyFromToken(token);
+        }catch (Exception e) {
+            strKey = null;
+            throw e;
+        }
+        int nIndex = (strKey != null) ? strKey.indexOf(":"):-1;
+        if (nIndex >= 0)
+            strKey = strKey.substring(nIndex+1);
+        return strKey;
+    }
+
+    /**
+     * 从令牌中获取权限角色
+     * @param token
+     * @return
+     */
+    /*public static String getStrAuthorityFromToken(String token) throws ExpiredJwtException, Exception{
+        String strAuthority = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null)
+                strAuthority = (String)claims.get("authorities");
+        } catch (ExpiredJwtException e){
+            strAuthority = null;
+            throw e;
+        } catch (Exception e) {
+            strAuthority = null;
+            throw e;
+        }
+        return strAuthority;
+    }*/
+
+    /**
+     * 判断令牌是否过期
+     *
+     * @param token 令牌
+     * @return 是否过期
+     */
+    public static Boolean isTokenExpired(String token){
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                Date expiration = claims.getExpiration();
+                return expiration.before(new Date());
+            }
+        } catch (ExpiredJwtException e){
+            return true;
+        } catch (Exception e) {
+            return true;
+        }
+        return true;
+    }
+
+    /**
+     * 判断令牌是否过期
+     *
+     * @return 是否过期
+     */
+    public static Boolean isTokenExpired(long lExpired){
+        return lExpired <= new Date().getTime();
+    }
+
+    /**
+     * 刷新令牌
+     * @param token 原令牌
+     * @param nExpired Token过期时间(单位:分钟)
+     * @return
+     */
+    public static AuthTokenData refreshToken(String token, int nExpired) throws ExpiredJwtException, Exception{
+        AuthTokenData tokenData = null;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            if (claims != null){
+                tokenData = generateToken(claims, nExpired);
+            }
+        } catch (ExpiredJwtException e){
+            tokenData = null;
+            throw e;
+        } catch (Exception e) {
+            tokenData = null;
+            throw e;
+        }
+        return tokenData;
+    }
+
+    /**
+     * 验证令牌
+     *
+     * @param token 令牌
+     * @return 是否有效
+     */
+    public static Boolean validateToken(String token) {
+        return !isTokenExpired(token);
+    }
+
+    /**
+     * Token 中的userid是否为给定的userid
+     * @param strAuthToken
+     * @param strUserId
+     * @return
+     */
+    public static boolean isTheSelfUser(String strAuthToken, String strUserId){
+        if (StringUtils.isEmpty(strUserId))
+            return false;
+
+        String strFlagKey = null;
+        try {
+            strFlagKey = TokenAuthenticationService.getFlagKeyFromToken(strAuthToken);
+        }catch (Exception e){
+            return false;
+        }
+        return strUserId.equals(strFlagKey);
+    }
+}

+ 78 - 0
src/main/java/com/shkpr/service/proxycenter/dto/AuthTokenData.java

@@ -0,0 +1,78 @@
+package com.shkpr.service.proxycenter.dto;
+import com.global.base.tools.FastJsonUtil;
+import java.util.HashMap;
+
+public class AuthTokenData {
+    private String mStrToken = "";     //Token字符串
+    private long mLExpired = 0L;      //Token过期时间,单位:毫秒
+    private long mLIssue = 0L;        //Token签发时间,单位:毫秒
+    private String mStrFlagKey = "";  //用户id
+    private String roleid = "";
+
+    public AuthTokenData() {
+    }
+
+    public AuthTokenData(String mStrToken, long mLExpired, String mStrFlagKey) {
+        this.mStrToken = mStrToken;
+        this.mLExpired = mLExpired;
+        this.mStrFlagKey = mStrFlagKey;
+    }
+
+    public AuthTokenData(String mStrToken, long mLExpired, long mLIssue, String mStrFlagKey) {
+        this.mStrToken = mStrToken;
+        this.mLExpired = mLExpired;
+        this.mLIssue = mLIssue;
+        this.mStrFlagKey = mStrFlagKey;
+    }
+
+    public AuthTokenData(String mStrToken, long mLExpired, long mLIssue, String mStrFlagKey, String roleid) {
+        this.mStrToken = mStrToken;
+        this.mLExpired = mLExpired;
+        this.mLIssue = mLIssue;
+        this.mStrFlagKey = mStrFlagKey;
+        this.roleid = roleid;
+    }
+
+    public long getIssueAt() {
+        return mLIssue;
+    }
+
+    public void setIssueAt(long mLIssue) {
+        this.mLIssue = mLIssue;
+    }
+
+    public String getStrToken() {
+        return mStrToken;
+    }
+
+    public void setStrToken(String mStrToken) {
+        this.mStrToken = mStrToken;
+    }
+
+    public long getExpired() {
+        return mLExpired;
+    }
+
+    public void setExpired(long mLExpired) {
+        this.mLExpired = mLExpired;
+    }
+
+    public String getStrFlagKey() {
+        return mStrFlagKey;
+    }
+
+    public void setStrFlagKey(String mStrFlagKey) {
+        this.mStrFlagKey = mStrFlagKey;
+    }
+
+    public String getRoleid() { return roleid; }
+
+    public void setRoleid(String roleid) { this.roleid = roleid; }
+
+    public String toTokenJsonStr(){
+        HashMap<String, Object> mapObj = new HashMap<>(16);
+        mapObj.put("token", mStrToken);
+        mapObj.put("expired", mLExpired);
+        return FastJsonUtil.toJSON(mapObj);
+    }
+}

+ 34 - 0
src/main/java/com/shkpr/service/proxycenter/dto/ByteDataBean.java

@@ -0,0 +1,34 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Arrays;
+
+@Getter
+@Setter
+public class ByteDataBean {
+    private byte[] data = null;
+    private int len = 0; //data中数据的长度
+    private String suffix = "";
+
+    public ByteDataBean() {
+    }
+
+    public ByteDataBean(byte[] src, String suffix) {
+        initData(src, suffix);
+    }
+
+    public void initData(byte[] src, String suffix){
+        len = (src != null)?src.length:0;
+        if (len > 0)
+            data = Arrays.copyOf(src, len);
+        this.suffix = suffix;
+    }
+
+    public void recycleRes(){
+        data = null;
+        len = 0;
+        suffix = "";
+    }
+}

+ 28 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommDelRes.java

@@ -0,0 +1,28 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class CommDelRes<T> {
+    private String code = "1";
+    private T id = null;
+
+    public CommDelRes(String code, T id) {
+        this.code = code;
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public T getId() {
+        return id;
+    }
+
+    public void setId(T id) {
+        this.id = id;
+    }
+}
+

+ 16 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommKNMBean.java

@@ -0,0 +1,16 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommKNMBean {
+    private String key = "";
+    private String name = "";
+    private int ordering = 0;
+    private String feature = "";
+
+    public CommKNMBean() {
+    }
+}

+ 12 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommKNMListRes.java

@@ -0,0 +1,12 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class CommKNMListRes extends TRecordRes<CommKNMBean>{
+    public CommKNMListRes() {
+        super();
+    }
+
+    public CommKNMListRes(int code) {
+        super(code);
+    }
+}
+

+ 11 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommStrListRes.java

@@ -0,0 +1,11 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class CommStrListRes extends ResDataBean<String>{
+    public CommStrListRes() {
+        super();
+    }
+
+    public CommStrListRes(int code) {
+        super(code);
+    }
+}

+ 15 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommTotalMinMax.java

@@ -0,0 +1,15 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommTotalMinMax {
+    protected int total = 0;
+    protected long minIndex = 0L;//最小重试索引位置
+    protected long maxIndex = 0L;//最大重试索引位置
+
+    public CommTotalMinMax() {
+    }
+}

+ 21 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommUKNewRes.java

@@ -0,0 +1,21 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommUKNewRes {
+    private String code = "0";               //0:表成功,其他:表失败
+    private String uid = "";
+    private String key = "";
+
+    public CommUKNewRes() {
+    }
+
+    public CommUKNewRes(String code, String uid, String key) {
+        this.code = code;
+        this.uid = uid;
+        this.key = key;
+    }
+}

+ 26 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommUNBean.java

@@ -0,0 +1,26 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommUNBean {
+    protected String uid = "";
+    protected String name = "";
+
+    public CommUNBean() {
+    }
+
+    public CommUNBean(String uid, String name) {
+        this.uid = uid;
+        this.name = name;
+    }
+
+    public CommUNBean(CommUNBean oOld) {
+        if (oOld != null) {
+            this.uid = oOld.getUid();
+            this.name = oOld.getName();
+        }
+    }
+}

+ 23 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommUUNNewRes.java

@@ -0,0 +1,23 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommUUNNewRes {
+    private String code = "0";               //0:表成功,其他:表失败
+    private String uid = "";
+    private String url = "";
+    private String name = "";
+
+    public CommUUNNewRes() {
+    }
+
+    public CommUUNNewRes(String code, String uid, String url, String name) {
+        this.code = code;
+        this.uid = uid;
+        this.url = url;
+        this.name = name;
+    }
+}

+ 23 - 0
src/main/java/com/shkpr/service/proxycenter/dto/CommUUTNewRes.java

@@ -0,0 +1,23 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommUUTNewRes {
+    private String code = "0";               //0:表成功,其他:表失败
+    private String uid = "";
+    private String userId = "";
+    private String title = "";
+
+    public CommUUTNewRes() {
+    }
+
+    public CommUUTNewRes(String code, String uid, String userId, String title) {
+        this.code = code;
+        this.uid = uid;
+        this.userId = userId;
+        this.title = title;
+    }
+}

+ 15 - 0
src/main/java/com/shkpr/service/proxycenter/dto/KeyDataStatus.java

@@ -0,0 +1,15 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class KeyDataStatus{
+    private String key = "";
+    private String data = "";
+    private int status = 0;
+
+    public KeyDataStatus() {
+    }
+}

+ 19 - 0
src/main/java/com/shkpr/service/proxycenter/dto/LatLngBean.java

@@ -0,0 +1,19 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class LatLngBean {
+    public double lat = 0.0; //对应Y
+    public double lng = 0.0; //对应X
+
+    public LatLngBean() {
+    }
+
+    public LatLngBean(double latitude, double longitude) {
+        this.lat = latitude;
+        this.lng = longitude;
+    }
+}

+ 44 - 0
src/main/java/com/shkpr/service/proxycenter/dto/LoginUser.java

@@ -0,0 +1,44 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class LoginUser {
+    protected String userid;
+    protected String account;
+    protected String password;
+
+    public LoginUser(){}
+
+    public LoginUser(String userid, String account, String password) {
+        this.userid = userid;
+        this.account = account;
+        this.password = password;
+    }
+
+    public String getUserid() {
+        return userid;
+    }
+
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getAccount() { return account; }
+
+    public void setAccount(String account) { this.account = account; }
+
+    @Override
+    public String toString() {
+        return "LoginUser{" +
+                "userid='" + userid + '\'' +
+                ", account='" + account + '\'' +
+                ", password='" + password + '\'' +
+                '}';
+    }
+}

+ 48 - 0
src/main/java/com/shkpr/service/proxycenter/dto/LoginUserRoleType.java

@@ -0,0 +1,48 @@
+package com.shkpr.service.proxycenter.dto;
+
+import com.shkpr.service.proxycenter.constants.CommDefine;
+
+public enum LoginUserRoleType {
+    ROOT_ADMIN(1,"ROOT_ADMIN"), //root管理员在系统发布时内置且密码不能更改,且不能删、改自己,不能增加同类型的用户
+    ADMIN(2,"ADMIN"),
+    NORMAL_USER(3,"NORMAL_USER"),
+    TEMP_USER(4, "TEMP_USER");
+
+    private LoginUserRoleType(int index, String name) {
+        this.name = name;
+        this.index = index;
+    }
+    private String name;
+    private int index;
+    public int toIntValue(){return index;}
+    public String toStrValue() {return name;}
+
+    @Override
+    public String toString() {
+        return "LoginUserRoleType{" +
+                "name='" + name + '\'' +
+                ", index=" + index +
+                '}';
+    }
+
+    public static LoginUserRoleType valueFromInt(int nRole){
+        switch (nRole){
+            case 1:
+                return ROOT_ADMIN;
+            case 2:
+                return ADMIN;
+            case 3:
+                return NORMAL_USER;
+            case 4:
+                return TEMP_USER;
+            default:
+                break;
+        }
+        return TEMP_USER;
+    }
+
+    public static boolean isRootAdmin(String roleId){
+        return CommDefine.ADMIN_ROLE_ID.equals(roleId)
+                || CommDefine.INTERNAL_OPERATOR_ROLE_ID.equals(roleId);
+    }
+}

+ 19 - 0
src/main/java/com/shkpr/service/proxycenter/dto/RecordRes.java

@@ -0,0 +1,19 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class RecordRes {
+    protected int code = 1;              //0:表示操作成功;1:表示操作失败
+    protected int total = 0;            //指定条件内总共有多少条记录
+
+    public RecordRes() {
+    }
+
+    public RecordRes(int code, int total) {
+        this.code = code;
+        this.total = total;
+    }
+}

+ 27 - 0
src/main/java/com/shkpr/service/proxycenter/dto/ResDataBean.java

@@ -0,0 +1,27 @@
+package com.shkpr.service.proxycenter.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+
+@Getter
+@Setter
+public class ResDataBean<T> {
+    protected int code = 0;              //0:表示操作成功;1:表示操作失败
+    protected int total = 0;
+    protected ArrayList<T> data = null;
+
+    public ResDataBean() {
+    }
+
+    public ResDataBean(int code) {
+        this.code = code;
+    }
+
+    public void clearData(){
+        if (data != null)
+            data.clear();
+        data = null;
+    }
+}

+ 121 - 0
src/main/java/com/shkpr/service/proxycenter/dto/ResponseCode.java

@@ -0,0 +1,121 @@
+package com.shkpr.service.proxycenter.dto;
+
+/**
+ * RESULT_开头的为响应体中的结果码rescode
+ * STATUS_开头的为HTTP Status响应码
+ */
+public enum ResponseCode {
+    RESULT_NORMAL(0, "Normal result."),
+    RESULT_BAD(1, "Bad result,see the message/data for reason."),
+
+    STATUS_SUCCESS(200, "Success"),
+    STATUS_BAD_REQUEST(600, "Bad Request,see the message/data for reason."),
+    STATUS_ACCESS_DENY(603, "Access denied."),
+    STATUS_NOT_FOUND_URI(604, "No mapping found for HTTP request with URI."),
+    STATUS_METHOD_NOT_ALLOWED(605, "Method Not Allowed."),
+    STATUS_HTTP_TYPE_NOT_ACCEPTABLE(606, "Http media type not acceptable."),
+    STATUS_HTTP_TYPE_NOT_SUPPORTED(615, "Http media type not supported."),
+    STATUS_INTERNAL_SERVER_ERROR(700, "Internal Server Error."),
+    STATUS_SERVER_RUN_ERROR(1000,"The server is abnormal."),
+    STATUS_NULL_POINT_EXCEPTION(1001, "Empty param or param is null."),
+    STATUS_ERROR_DATA_TYPE(1002, "The data type is wrong."),
+    STATUS_IO_EXCEPTION(1003, "IO exception."),
+    STATUS_NO_SUCH_METHOD(1004, "No such method."),
+    STATUS_INDEX_OUT_OF_BOUNDS(1005, "Index out of bounds."),
+    STATUS_ERROR_JSON_FORMAT(1006, "Error JSON data format."),
+    STATUS_NOT_POST_REQUEST(1007, "Not post request."),
+    STATUS_NOT_DELETE_REQUEST(1008, "Not delete request."),
+    STATUS_ERROR_PARAM_FORMAT(1009, "Error parameter format."),
+    STATUS_INVALID_CONTENT_TYPE(1010, "Error Content-Type."),
+    STATUS_NOT_MATCHED_URI(1011, "No mapping found for HTTP request with URI."),
+    STATUS_ERROR_REQUEST_METHOD(1012, "Error request method."),
+    STATUS_NO_USER_ACCOUNT(1013, "No such user or has not login."),
+    STATUS_SERVER_NET_DISCONN_OR_BUSY(1014, "The network of server is down or busy. Please try again later."),
+    STATUS_MAX_CONCURRENT_REQUEST_COUNT(1015, "Exceeded the maximum number of concurrent requests. Please try again later."),
+    STATUS_INVALID_HEADER(1016, "Invalid headers, please check the headers of request."),
+
+    STATUS_EMPTY_TOKEN(2000,"Empty token."),
+    STATUS_INVALID_TOKEN(2001, "Invalidate Token, please re-login."),
+    STATUS_EXPIRED_TOKEN(2002, "Expired Token, please re-login."),
+    STATUS_NOT_LOGGED_IN(2003, "Not logged in."),
+    STATUS_DENY_OPERATE_USER(2004, "No permission to operate."),
+    STATUS_TOO_OLD_TOKEN(2005, "The token is too old, please use your new token."),
+    STATUS_INVALID_OLD_PWD(2006, "The original password is wrong."),
+    STATUS_INVALID_KEY(2007, "Invalidate Key"),
+    STATUS_INVALID_NAME(2008, "Invalidate Name"),
+
+    RESULT_ERROR_SIGN(3000, "Illegal signature"),
+    RESULT_REPEAT_SEQUENCE(3001, "Repeat the request, please check the request sequence number."),
+    RESULT_REQUEST_TIMEOUT(3002, "Request timed out."),
+    RESULT_REQUEST_TOO_BUSY(3003, "Request too busy, please try again later."),
+    RESULT_REPEAT_RECORDS(3004, "Repeat the records, please check the request."),
+    RESULT_REFERENCE_RECORDS(3005, "Reference the records, please check the request."),
+    RESULT_REFERENCE_NOT_EXIST(3006, "Reference the not exist, please check the request."),
+    RESULT_INVALID_MULTI_TYPE_BIND(3007, "Multi type binding, please check the request."),
+    RESULT_ILLEGAL_LOGIN(3998, "Illegal login."),
+    RESULT_ACCOUNT_LOCKED(3999, "Account has been locked, please try again later."),
+
+    RESULT_INVALID_ORDER(4000, "The order number is inconsistent."),//错误或不合法的工单号
+    RESULT_DUPLICATE_ORDER(4001,"The order is already exists."), //指定工单已存在
+    RESULT_ORDER_ACCEPTED(4002, "The order is already accepted."),//指定工单已被接收
+    RESULT_ORDER_DEALED(4003, "The order is already deal."),//指定工单已被处理
+    RESULT_ORDER_ODD_STATUS(4004, "The order status is incorrect.No permission to operation."),//指定工单状态错误,暂无权限做次操作
+    RESULT_ORDER_OWN_CHANGED(4005, "The owner of order is changed.No permission to operation."),//指定工单归属已变更,暂无限操作
+
+    RESULT_USER_ALREADY_REG(8000, "This phone is already registered."),
+    RESULT_DENY_FOR_SAME_PASS(8001, "Two passwords cannot be the same."),
+    RESULT_REFRESH_TOKEN_FAILED(8002, "Refresh token failed, please login again."),
+    RESULT_TOKEN_INVALID_SIGN(8003, "Refresh token failed, invalid signature"),
+    RESULT_INVALID_USER_INFO(8004, "User information verification failed."),
+    RESULT_EXISTS_USER_NAME(8005, "Username already exists."),
+    RESULT_USER_NOT_REG(8006, "This phone is not registered."),
+    RESULT_INNER_JS_SERVER_AUTH_FAILED(8007, "Inner js service verify failed."),
+
+    RESULT_SERVER_NET_DISCONN_OR_BUSY(9000, "The network of server is down or busy. Please try again later."),
+
+    RESULT_INVALID_PUSH_TASK(9100, "The push task is inconsistent."),
+    RESULT_PUSH_TASK_CLOSE(9101, "The push task will be closed."),
+    RESULT_PUSH_TASK_RETRY(9102, "The push task will be next push in the queue."),
+    RESULT_PUSH_FAILED_ERROR_RECEIVER(9103, "Push task failed because of error receiver."),
+    RESULT_PUSH_FAILED_ERROR_OTHERS(9104, "Push task failed because of other errors."),
+    RESULT_PUSH_FAILED_NO_WAY(9105, "Push task failed because of no support the push way."),
+
+    RESULT_FILE_INVALID_TYPE(10000, "Illegal file type."),
+    RESULT_FILE_RW_FILED(10001, "File read/write error."),
+    RESULT_FILE_SIZE_EXCEED(10002, "File size limit exceeded."),
+    RESULT_FILE_PARSE_FAILED(10003, "File parse failed."),
+    RESULT_FILE_EMPTY_ROWS(10004, "File is empty rows."),
+
+    RESULT_NOT_SUPPORT_GEO_WFS_TYPE(20000, "The operation for this geo wfs type is not supported."),
+    RESULT_NOT_SUPPORT_GEO_WFS_WS(20001, "The operation for this geo wfs workspace is not supported."),
+    RESULT_GEO_WFS_TYPE_EMPTY_DATA(20002, "The empty data for this geo wfs type."),
+    RESULT_LABEL_ALREADY_USED(20003, "The Label is already in use."),
+    RESULT_REQ_TO_GEO_SERVER_FAILED(20004, "The request to GeoServer Failed."),
+    RESULT_GEO_WFS_ELEMENT_IS_NOT_EXIST(20005, "The geo wfs element is not exist."),
+
+    RESULT_FAST_DFS_UPLOAD_FAILED(30000, "Upload File To FastDfs Failed."),
+
+    BUSINESS_SYNC_FUN_FAILED(65529,"The Synch operation failed."),
+    BUSINESS_DB_REQ_FAILED(65530,"The DB operation failed."),
+    BUSINESS_API_ABOLISH(65531,"The Api has been abolished."),
+    BUSINESS_BUSY(65532,"Business is busy, please try again."),
+    SERVICE_OFFLINE(65533, "Service offline, please turn off offline mode"),
+    STATUS_UNKNOWN(65534,"Unknown reason,see the message/data for reason."),
+    RESULT_UNKNOWN(65535,"Unknown reason,see the message/data for reason.");
+
+    private String name;
+    private int index;
+    private ResponseCode(int indexC, String strN){
+        index = indexC;
+        name = strN;
+    }
+
+    public int toInt() {return index;}
+    public String toStrCode() {return String.valueOf(index);}
+    public String toStrMsg() {return name;}
+
+    @Override
+    public String toString() {
+        return "StatusCode: " + index + " Message: " + name;
+    }
+}

+ 65 - 0
src/main/java/com/shkpr/service/proxycenter/dto/ResponseRes.java

@@ -0,0 +1,65 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class ResponseRes<T> {
+    private long timestamp;
+    private String rescode;
+    private String resmsg;//message;
+    private T resdata;//data;
+
+    public ResponseRes() {
+    }
+
+    public ResponseRes(String rescode) {
+        this.rescode = rescode;
+    }
+
+    public ResponseRes(long timestamp, String rescode, String resmsg, T resdata) {
+        this.timestamp = timestamp;
+        this.rescode = rescode;
+        this.resmsg = resmsg;
+        this.resdata = resdata;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getRescode() {
+        return rescode;
+    }
+
+    public void setRescode(String rescode) {
+        this.rescode = rescode;
+    }
+
+    public String getResmsg() {
+        return resmsg;
+    }
+
+    public void setResmsg(String resmsg) {
+        this.resmsg = resmsg;
+    }
+
+    public T getResdata() {
+        return resdata;
+    }
+
+    public void setResdata(T resdata) {
+        this.resdata = resdata;
+    }
+
+    @Override
+    public String toString() {
+        return "ResponseRes{" +
+                "timestamp=" + timestamp +
+                ", rescode='" + rescode + '\'' +
+                ", resmsg='" + resmsg + '\'' +
+                ", resdata=" + resdata +
+                '}';
+    }
+}
+

+ 29 - 0
src/main/java/com/shkpr/service/proxycenter/dto/TObjectRes.java

@@ -0,0 +1,29 @@
+package com.shkpr.service.proxycenter.dto;
+
+public class TObjectRes<T> {
+    protected int code = 0;              //0:表示操作成功;1:表示操作失败
+    protected T data = null;
+
+    public TObjectRes() {
+    }
+
+    public TObjectRes(int code) {
+        this.code = code;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 46 - 0
src/main/java/com/shkpr/service/proxycenter/dto/TRecordRes.java

@@ -0,0 +1,46 @@
+package com.shkpr.service.proxycenter.dto;
+
+import com.global.base.tools.FastJsonUtil;
+import com.shkpr.service.proxycenter.commtools.CommTool;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Getter
+@Setter
+public class TRecordRes<T> {
+    protected String msg = "";
+    protected int code = 0;              //0:表示操作成功;1:表示操作失败
+    protected int total = 0;            //指定条件内总共有多少条记录
+    protected List<T> data = null;
+
+    public TRecordRes() {
+    }
+
+    public void clearData(){
+        if (data != null)
+            data.clear();
+        data = null;
+    }
+
+    public TRecordRes(int code) {
+        this.code = code;
+    }
+
+    public void checkRes(){
+        if (data == null)
+            data = new ArrayList<>();
+        total = CommTool.listSize(data);
+    }
+
+    public String genJsonData(){
+        Map<String, Object> mapData = new HashMap<>();
+        mapData.put("total", total);
+        mapData.put("data", data);
+        return FastJsonUtil.toJSON(mapData);
+    }
+}

+ 140 - 0
src/main/java/com/shkpr/service/proxycenter/globalcache/GlobalData.java

@@ -0,0 +1,140 @@
+package com.shkpr.service.proxycenter.globalcache;
+
+import javax.validation.Validator;
+import javax.validation.ConstraintViolation;
+import javax.validation.executable.ExecutableValidator;
+import java.util.*;
+
+public class GlobalData {
+    public final static String ORIGIN_KEY = "Y^c3b5d3z1";    //原始口令:阳春布德泽
+    private boolean mBHttpStatusAlready200 = true;          //HttpStatus返回码是不是总是返回200ok
+    private boolean  mBTokenIsUnique = false;
+    private boolean  mBSvrTestMode = false;
+
+    private Validator mValidForParam = null;
+    private ExecutableValidator mValidForFun = null;
+    private volatile boolean mBUseLocalCache = true;         //是否启用本地缓存
+    private String mStrServerId = "";                          //本服务的ID
+    private int mNOwnerMachineIndex = 0;                      //本服务所在的部署机器的索引编号
+    private int mNOwnerServiceIndex = 0;                      //本服务在部署机器上的服务索引编号
+    private int mNCpuCoresForEnableAsyncSubTask = 8;//启动异步子任务的最小cpu核心数
+    private volatile boolean mBSwitchTraceLog = true;//是否开启基于TraceId的日志记录
+
+    private String mStrOperatorAccount = "";
+    private String mStrOperatorPassword = "";
+
+    private long mTmUTCServiceOnline = 1580486400000L;        //服务上线的时间,默认为2020-02-01 00:00:00
+    private String mStrInternalCallPassword = "";            //本机的内部通信可信任口令
+    private static volatile GlobalData msInstance = null;
+    public static GlobalData getInstance(){
+        if (msInstance == null){
+            synchronized (GlobalData.class){
+                if (msInstance == null)
+                    msInstance = new GlobalData();
+            }
+        }
+        return msInstance;
+    }
+
+    private GlobalData() {
+    }
+
+    public void setCpuCoresForEnableAsyncSubTask(int nCpuCores){
+        this.mNCpuCoresForEnableAsyncSubTask = nCpuCores;
+    }
+
+    public boolean isEnableAsyncSubTask(){
+        //cpu核心数>=指定配置时才启用异步子任务(注:过多线程并发可增加线程间的切换开销,导致单个请求执行时间拉长)
+        return mNCpuCores >= mNCpuCoresForEnableAsyncSubTask;
+    }
+
+    private int mNCpuCores = 1;
+    public int getCpuCores() {
+        return mNCpuCores;
+    }
+
+    public void setCpuCores(int mNCpuCores) {
+        this.mNCpuCores = mNCpuCores;
+    }
+
+    public <T> boolean checkObjectByValidator(T object, Class<?>... classForObject){
+        if (mValidForParam != null){
+            Set<ConstraintViolation<T>> constraintViolations = mValidForParam.validate(object, classForObject);
+            if (!(constraintViolations == null || constraintViolations.size() <= 0))
+                return false;
+        }
+        return true;
+    }
+
+    public Validator getValidForParam() {
+        return mValidForParam;
+    }
+
+    public void setValidForParam(Validator mValidForParam) {
+        this.mValidForParam = mValidForParam;
+    }
+
+    public ExecutableValidator getValidForFun() {
+        return mValidForFun;
+    }
+
+    public void setValidForFun(ExecutableValidator mValidForFun) {
+        this.mValidForFun = mValidForFun;
+    }
+
+    public boolean isTokenMustUnique() {
+        return mBTokenIsUnique;
+    }
+
+    public void setTokenMustUnique(boolean mBTokenIsUnique) {
+        this.mBTokenIsUnique = mBTokenIsUnique;
+    }
+
+    public boolean isSvrTestMode() {
+        return mBSvrTestMode;
+    }
+
+    public void setSvrTestMode(boolean mBSvrTestMode) {
+        this.mBSvrTestMode = mBSvrTestMode;
+    }
+
+    public boolean isHttpStatusAlready200() {
+        return mBHttpStatusAlready200;
+    }
+
+    public void setHttpStatusAlready200(boolean mBHttpStatusAlready200) {
+        this.mBHttpStatusAlready200 = mBHttpStatusAlready200;
+    }
+
+    public boolean isUseLocalCache() { return mBUseLocalCache; }
+
+    public void setUseLocalCache(boolean mBUseLocalCache) { this.mBUseLocalCache = mBUseLocalCache; }
+
+    public String getServerId() { return mStrServerId; }
+
+    public void setServerId(String mStrServerId) { this.mStrServerId = mStrServerId; }
+
+    public int getNOwnerMachineIndex() { return mNOwnerMachineIndex; }
+
+    public void setNOwnerMachineIndex(int mNOwnerMachineIndex) { this.mNOwnerMachineIndex = mNOwnerMachineIndex; }
+
+    public int getNOwnerServiceIndex() { return mNOwnerServiceIndex; }
+
+    public void setNOwnerServiceIndex(int mNOwnerServiceIndex) { this.mNOwnerServiceIndex = mNOwnerServiceIndex; }
+
+    public boolean isSwitchTraceLog() { return mBSwitchTraceLog; }
+
+    public void setSwitchTraceLog(boolean mBSwitchTraceLog) { this.mBSwitchTraceLog = mBSwitchTraceLog; }
+
+    public String getStrOperatorAccount() { return mStrOperatorAccount; }
+
+    public void setStrOperatorAccount(String mStrOperatorAccount) { this.mStrOperatorAccount = mStrOperatorAccount; }
+
+    public String getStrOperatorPassword() { return mStrOperatorPassword; }
+
+    public void setStrOperatorPassword(String mStrOperatorPassword) { this.mStrOperatorPassword = mStrOperatorPassword; }
+
+    public String getInternalCallPassword() { return mStrInternalCallPassword; }
+
+    public void setInternalCallPassword(String mStrInternalCallPassword) { this.mStrInternalCallPassword = mStrInternalCallPassword; }
+}

+ 26 - 0
src/main/java/com/shkpr/service/proxycenter/interfaces/URIInterceptorIntef.java

@@ -0,0 +1,26 @@
+package com.shkpr.service.proxycenter.interfaces;
+
+import org.springframework.web.servlet.HandlerInterceptor;
+
+/**
+ * URL拦截器接口,实现该接口并在实现类上添加注解@Component,将会自动注入spring拦截器
+ */
+public interface URIInterceptorIntef extends HandlerInterceptor {
+    /**
+     * 需拦截的地址
+     * @return
+     */
+    public String [] forbidPathPatterns();
+
+    /**
+     * 排除拦截的地址
+     * @return
+     */
+    public String [] excludePathPatterns();
+
+    /**
+     * 值越小优先级越高,值越大优先级越低;优先级越高越先得到执行
+     * @return
+     */
+    public int order();
+}

+ 28 - 0
src/main/java/com/shkpr/service/proxycenter/interfaces/sinks/LogPrintSink.java

@@ -0,0 +1,28 @@
+package com.shkpr.service.proxycenter.interfaces.sinks;
+
+import com.global.base.log.ILogPrintSink;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogPrintSink implements ILogPrintSink {
+    private final Logger mLogger = LoggerFactory.getLogger(this.getClass());
+    public LogPrintSink() {
+    }
+
+    @Override
+    public void printLogMsg(int nLevel, String strMsg) {
+        switch (nLevel){
+            case 0:{
+                mLogger.info(strMsg);
+            }break;
+            case 1:{
+                mLogger.warn(strMsg);
+            }break;
+            case 2:{
+                mLogger.error(strMsg);
+            }break;
+            default:
+                break;
+        }
+    }
+}

+ 1 - 3
src/test/java/com/shkpr/service/proxycenter/V1AlamProxyCenterApplicationTests.java

@@ -1,12 +1,10 @@
 package com.shkpr.service.proxycenter;
 
-import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
 @SpringBootTest
-class V1AlamProxyCenterApplicationTests {
+class AlamProxyCenterApplicationTests {
 
-	@Test
 	void contextLoads() {
 	}