Browse Source

初始化提交

hbjzws 1 year ago
parent
commit
d4450936b5
58 changed files with 4897 additions and 25 deletions
  1. 304 23
      pom.xml
  2. 7 0
      src/main/java/com/example/demo1/Demo1Application.java
  3. 0 1
      src/main/java/com/example/demo1/TestController.java
  4. 30 0
      src/main/java/com/example/demo1/config/MybatisPlusConfig.java
  5. 17 0
      src/main/java/com/example/demo1/config/OSSConfig.java
  6. 20 0
      src/main/java/com/example/demo1/config/ParkingConfig.java
  7. 180 0
      src/main/java/com/example/demo1/config/RedisConfig.java
  8. 73 0
      src/main/java/com/example/demo1/config/SwaggerConfig.java
  9. 79 0
      src/main/java/com/example/demo1/config/WebMvcConfig.java
  10. 21 0
      src/main/java/com/example/demo1/config/YsConfig.java
  11. 25 0
      src/main/java/com/example/demo1/dto/AccessToken.java
  12. 44 0
      src/main/java/com/example/demo1/dto/AddParkingMember.java
  13. 29 0
      src/main/java/com/example/demo1/dto/AlarmInfoPlate.java
  14. 17 0
      src/main/java/com/example/demo1/dto/CalcFeeTime.java
  15. 19 0
      src/main/java/com/example/demo1/dto/CostRecord.java
  16. 50 0
      src/main/java/com/example/demo1/dto/MessageResult.java
  17. 33 0
      src/main/java/com/example/demo1/dto/ParkingCostDTO.java
  18. 49 0
      src/main/java/com/example/demo1/dto/ParkingDetailDTO.java
  19. 23 0
      src/main/java/com/example/demo1/dto/ParkingFeeSubDTO.java
  20. 38 0
      src/main/java/com/example/demo1/dto/ParkingShopDTO.java
  21. 10 0
      src/main/java/com/example/demo1/dto/ParkingUserRelationDTO.java
  22. 28 0
      src/main/java/com/example/demo1/dto/PayDTO.java
  23. 13 0
      src/main/java/com/example/demo1/dto/PlateResponse.java
  24. 64 0
      src/main/java/com/example/demo1/dto/PlateResult.java
  25. 97 0
      src/main/java/com/example/demo1/dto/PojoUtils.java
  26. 26 0
      src/main/java/com/example/demo1/dto/ReceiveDeviceDTO.java
  27. 23 0
      src/main/java/com/example/demo1/dto/ResponseAlarmInfoPlate.java
  28. 14 0
      src/main/java/com/example/demo1/dto/Result.java
  29. 17 0
      src/main/java/com/example/demo1/dto/SerialData.java
  30. 14 0
      src/main/java/com/example/demo1/dto/TimeStamp.java
  31. 35 0
      src/main/java/com/example/demo1/dto/Timeval.java
  32. 18 0
      src/main/java/com/example/demo1/dto/TriggerImage.java
  33. 20 0
      src/main/java/com/example/demo1/dto/UserInfo.java
  34. 30 0
      src/main/java/com/example/demo1/dto/WhiteDTO.java
  35. 21 0
      src/main/java/com/example/demo1/dto/WhiteData.java
  36. 17 0
      src/main/java/com/example/demo1/dto/WhiteListOperate.java
  37. 84 0
      src/main/java/com/example/demo1/interceptor/LoginInterceptor.java
  38. 273 0
      src/main/java/com/example/demo1/utils/Base64.java
  39. 83 0
      src/main/java/com/example/demo1/utils/CRC16.java
  40. 77 0
      src/main/java/com/example/demo1/utils/DES3.java
  41. 60 0
      src/main/java/com/example/demo1/utils/DateUtil.java
  42. 52 0
      src/main/java/com/example/demo1/utils/FileUtil.java
  43. 422 0
      src/main/java/com/example/demo1/utils/HttpConnectionUtil.java
  44. 107 0
      src/main/java/com/example/demo1/utils/JwtUtil.java
  45. 377 0
      src/main/java/com/example/demo1/utils/LedTcProtocol.java
  46. 88 0
      src/main/java/com/example/demo1/utils/MapUtils.java
  47. 24 0
      src/main/java/com/example/demo1/utils/MyX509TrustManager.java
  48. 353 0
      src/main/java/com/example/demo1/utils/OSSUtil.java
  49. 34 0
      src/main/java/com/example/demo1/utils/RespThirdVO.java
  50. 47 0
      src/main/java/com/example/demo1/utils/RespVO.java
  51. 20 0
      src/main/java/com/example/demo1/utils/RespVOBuilder.java
  52. 163 0
      src/main/java/com/example/demo1/utils/SMSUtil.java
  53. 140 0
      src/main/java/com/example/demo1/utils/Sign.java
  54. 137 0
      src/main/java/com/example/demo1/utils/StringUtils.java
  55. 422 0
      src/main/java/com/example/demo1/utils/WeixinUtil.java
  56. 236 0
      src/main/java/com/example/demo1/utils/YsUtil.java
  57. 62 0
      src/main/resources/application-dev.yml
  58. 131 1
      src/main/resources/application.yml

+ 304 - 23
pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.6.3</version>
+        <version>2.2.1.RELEASE</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.example</groupId>
@@ -15,56 +15,337 @@
     <description>Demo project for Spring Boot</description>
     <properties>
         <java.version>1.8</java.version>
-        <spring-cloud.version>2021.0.0</spring-cloud.version>
+        <swagger2.version>2.7.0</swagger2.version>
+        <jwts.version>0.11.2</jwts.version>
+        <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
+        <lombok.version>1.18.12</lombok.version>
     </properties>
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter</artifactId>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>${swagger2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${swagger2.version}</version>
+        </dependency>
+        <!--整合Knife4j-->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>2.0.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+            <version>1.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.dozermapper</groupId>
+            <artifactId>dozer-core</artifactId>
+            <version>6.4.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.2.0</version>
         </dependency>
 
+        <!--jwt start-->
         <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <optional>true</optional>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-api</artifactId>
+            <version>0.11.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-impl</artifactId>
+            <version>${jwts.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-jackson</artifactId>
+            <version>${jwts.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--jwt end-->
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.10.5</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.6.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.8</version>
+        </dependency>
+
+        <!--缓存 start-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!--缓存 end-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.lazyluke</groupId>
+            <artifactId>log4jdbc-remix</artifactId>
+            <version>0.2.7</version>
+        </dependency>
+
+        <!--支付相关-->
+        <dependency>
+            <groupId>com.github.javen205</groupId>
+            <artifactId>IJPay-All</artifactId>
+            <version>2.7.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.23.21.ALL</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>bcprov-jdk15on</artifactId>
+                    <groupId>org.bouncycastle</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.4.3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.1</version>
+        </dependency>
+        <!--支付相关-->
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib</artifactId>
+            <version>2.4</version>
+            <type>jar</type>
+            <classifier>jdk15</classifier>
+        </dependency>
+        <!--jwt start-->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-api</artifactId>
+            <version>0.10.5</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-impl</artifactId>
+            <version>0.10.5</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-jackson</artifactId>
+            <version>0.10.5</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.12</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.10</version>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>2.8.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.79</version>
+        </dependency>
+        <!-- aliyun oss start -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.13.2</version>
+        </dependency>
+        <!-- aliyun oss end -->
+        <dependency>
+            <groupId>com.taobao</groupId>
+            <artifactId>taobao-sdk-java</artifactId>
+            <version>1.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.10</version>
+        </dependency>
+        <!-- 导入和导出-->
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-base</artifactId>
+            <version>4.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-web</artifactId>
+            <version>4.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-annotation</artifactId>
+            <version>4.4.0</version>
+        </dependency>
     </dependencies>
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.springframework.cloud</groupId>
-                <artifactId>spring-cloud-dependencies</artifactId>
-                <version>${spring-cloud.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
+
 
     <build>
+        <finalName>demo1</finalName>
         <plugins>
+            <!-- maven 打包时跳过测试 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
                 <configuration>
-                    <excludes>
-                        <exclude>
+                    <layout>ZIP</layout>
+                    <includes>
+                        <!-- 设置没有jar包-->
+                        <include>
+                            <groupId>nothing</groupId>
+                            <artifactId>nothing</artifactId>
+                        </include>
+                    </includes>
+                    <mainClass>com.example.demo1.Demo1Application</mainClass>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${org.mapstruct.version}</version>
+                        </path>
+                        <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
-                        </exclude>
-                    </excludes>
+                            <version>${lombok.version}</version>
+                        </path>
+                        <!-- This is needed when using Lombok 1.18.16 and above -->
+                        <path>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok-mapstruct-binding</artifactId>
+                            <version>0.2.0</version>
+                        </path>
+                    </annotationProcessorPaths>
                 </configuration>
             </plugin>
         </plugins>
     </build>
-
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </dependency>
+            </dependencies>
+            <properties>
+                <active.profile>dev</active.profile>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>test</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </dependency>
+            </dependencies>
+            <properties>
+                <active.profile>test</active.profile>
+            </properties>
+        </profile>
+        <profile>
+            <id>production</id>
+            <properties>
+                <active.profile>production</active.profile>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
 </project>

+ 7 - 0
src/main/java/com/example/demo1/Demo1Application.java

@@ -1,10 +1,17 @@
 package com.example.demo1;
 
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @SpringBootApplication
+@EnableTransactionManagement
+@EnableAsync(proxyTargetClass=true)
+@EnableScheduling
 public class Demo1Application {
 
     public static void main(String[] args) {

+ 0 - 1
src/main/java/com/example/demo1/TestController.java

@@ -1,7 +1,6 @@
 package com.example.demo1;
 
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;

+ 30 - 0
src/main/java/com/example/demo1/config/MybatisPlusConfig.java

@@ -0,0 +1,30 @@
+package com.example.demo1.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/23 0023 下午 2:54
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+    /**
+     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
+        paginationInnerInterceptor.setDbType(DbType.MYSQL);
+        paginationInnerInterceptor.setOverflow(true);
+        interceptor.addInnerInterceptor(paginationInnerInterceptor);
+        return interceptor;
+    }
+
+
+}

+ 17 - 0
src/main/java/com/example/demo1/config/OSSConfig.java

@@ -0,0 +1,17 @@
+package com.example.demo1.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "oss")
+@Data
+public class OSSConfig {
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String endpoint;
+    private String bucketName;
+    private String urlPrefix;
+    private String objectPre;
+}

+ 20 - 0
src/main/java/com/example/demo1/config/ParkingConfig.java

@@ -0,0 +1,20 @@
+package com.example.demo1.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2020-4-13 14:47
+ */
+@Component
+@ConfigurationProperties(prefix = "parking")
+@Data
+public class ParkingConfig {
+    private String userName;
+    private String ip;
+    private String interfaceUrl;
+    private String fileUrl;
+
+}

+ 180 - 0
src/main/java/com/example/demo1/config/RedisConfig.java

@@ -0,0 +1,180 @@
+package com.example.demo1.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.lang.reflect.Method;
+
+
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport {
+    public final static String WX_COMMON_ACCESS_TOKEN = "wx_common_accessToken";
+    public final static String JS_API_TICKET = "js_api_ticket";
+    public final static String PERSON_SELECT_COMPANY = "psc_";
+
+    /**
+     * 注入 RedisConnectionFactory,注意maven中要有redis.clients.jedis
+     */
+    @Autowired
+    RedisConnectionFactory redisConnectionFactory;
+
+    /**
+     * 实例化 RedisTemplate 对象
+     * @return
+     */
+    @Bean
+    public RedisTemplate<String, Object> getRedisTemplate() {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
+        return redisTemplate;
+    }
+
+    /**
+     * 设置数据存入 redis 的序列化方式
+     *
+     * @param redisTemplate
+     * @param factory
+     */
+    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setValueSerializer(valueSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashValueSerializer(valueSerializer());
+        redisTemplate.setConnectionFactory(factory);
+    }
+
+    @Bean
+    public KeyGenerator keyGenerator() {
+        return new KeyGenerator() {
+            @Override
+            public Object generate(Object target, Method method, Object... params) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(target.getClass().getName());
+                sb.append(method.getName());
+                for (Object obj : params) {
+                    sb.append(obj.toString());
+                }
+
+                return sb.toString();
+            }
+        };
+    }
+
+    /**
+     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForHash();
+    }
+
+    /**
+     * 实例化 ValueOperations 对象,可以使用 String 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForValue();
+    }
+
+    /**
+     * 实例化 ListOperations 对象,可以使用 List 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForList();
+    }
+
+    /**
+     * 实例化 SetOperations 对象,可以使用 Set 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForSet();
+    }
+
+    /**
+     * 实例化 ZSetOperations 对象,可以使用 ZSet 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForZSet();
+    }
+
+    @Bean
+    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
+        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
+        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()));
+        redisCacheConfiguration.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
+        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
+    }
+
+    /**
+     * 使用Jackson序列化器
+     * @return
+     */
+    private RedisSerializer<Object> valueSerializer() {
+        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        /**
+         * 这一句必须要,作用是序列化时将对象全类名一起保存下来
+         * 设置之后的序列化结果如下:
+         *  [
+         *   "com.dxy.cache.pojo.Dept",
+         *   {
+         *     "pid": 1,
+         *     "code": "11",
+         *     "name": "财务部1"
+         *   }
+         * ]
+         *
+         * 不设置的话,序列化结果如下,将无法反序列化
+         *
+         *  {
+         *     "pid": 1,
+         *     "code": "11",
+         *     "name": "财务部1"
+         *   }
+         */
+//                objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+        //因为上面那句代码已经被标记成作废,因此用下面这个方法代替,仅仅测试了一下,不知道是否完全正确
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+        serializer.setObjectMapper(objectMapper);
+
+        return serializer;
+    }
+}

+ 73 - 0
src/main/java/com/example/demo1/config/SwaggerConfig.java

@@ -0,0 +1,73 @@
+package com.example.demo1.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.example.demo1"))
+                .paths(PathSelectors.any())
+                .build()
+                //添加登录认证
+                .securitySchemes(securitySchemes())
+                .securityContexts(securityContexts());
+    }
+
+    private List<SecurityScheme> securitySchemes() {
+        //设置请求头信息
+        List<SecurityScheme> list = new ArrayList<>();
+        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
+        list.add(apiKey);
+
+        return list;
+    }
+
+    private List<SecurityContext> securityContexts() {
+        //设置需要登录认证的路径
+        List<SecurityContext> result = new ArrayList<>();
+        result.add(getContextByPath("/*"));
+        return result;
+    }
+
+    private SecurityContext getContextByPath(String pathRegex){
+        return SecurityContext.builder()
+                .securityReferences(defaultAuth())
+                .forPaths(PathSelectors.regex(pathRegex))
+                .build();
+    }
+
+    private List<SecurityReference> defaultAuth() {
+        List<SecurityReference> result = new ArrayList<>();
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        result.add(new SecurityReference("Authorization", authorizationScopes));
+        return result;
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("后台接口文档")
+                .description("")
+                .termsOfServiceUrl("")
+                .version("1.0")
+                .build();
+    }
+}

+ 79 - 0
src/main/java/com/example/demo1/config/WebMvcConfig.java

@@ -0,0 +1,79 @@
+package com.example.demo1.config;
+
+import com.example.demo1.interceptor.LoginInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.*;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+	@Autowired
+	private LoginInterceptor loginInterceptor;
+
+	@Override
+	public void addCorsMappings(CorsRegistry registry) {
+		registry.addMapping("/**")
+				.allowedOrigins("*")
+				.allowedHeaders("*")
+				.allowedMethods("*")
+				.allowCredentials(false)
+				.exposedHeaders("access-control-allow-headers",
+						"access-control-allow-methods",
+						"access-control-allow-origin",
+						"access-control-max-age",
+						"X-Frame-Options",
+						"token-status")
+				.maxAge(3600);
+	}
+
+	@Override
+	public void addResourceHandlers(ResourceHandlerRegistry registry) {
+		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
+
+		registry.addResourceHandler("swagger-ui.html")
+				.addResourceLocations("classpath:/META-INF/resources/");
+
+		registry.addResourceHandler("/webjars/**")
+				.addResourceLocations("classpath:/META-INF/resources/webjars/");
+	}
+
+	@Override
+	public void addViewControllers(ViewControllerRegistry registry) {
+		// registry.addViewController("/login").setViewName("login");
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(loginInterceptor)
+				.addPathPatterns("/**")
+                .excludePathPatterns("/login",
+						"/swagger-resources/**",
+                        "/webjars/**",
+                        "/swagger-ui.html",
+						"/doc.html",
+                        "/v2/**",
+                        "/mobileApi/**",
+						"/favicon.ico",
+						"/error")
+				.excludePathPatterns("/parkingRecord/receiveDeviceInfo")
+				.excludePathPatterns("/parkingRecord/plateResult")
+				.excludePathPatterns("/parkingRecord/channelPayDetail")
+				.excludePathPatterns("/parkingRecord/carPayDetail")
+				.excludePathPatterns("/parkingRecord/generateTemporaryCarNum")
+				.excludePathPatterns("/parkingRecord/temporaryCarNumInPark")
+				.excludePathPatterns("/aliPay/**")
+				.excludePathPatterns("/wxPay/**")
+				.excludePathPatterns("/parkingMember/createDiscount")
+				.excludePathPatterns("/parkingMember/getParkingInfo")
+				.excludePathPatterns("/parkingMember/addParkingMember")
+				.excludePathPatterns("/parkingMemberInfo/userGetCarMember")
+				.excludePathPatterns("/parkingMemberInfo/validQrCode")
+				.excludePathPatterns("/parkingMemberInfo/userGetCarDetail")
+				.excludePathPatterns("/parkingRecord/getTemporaryCarNum")
+				.excludePathPatterns("/parkingRecord/updateSurplusParkingNumber")
+				.excludePathPatterns("/parkingRecord/snapImage")
+				.excludePathPatterns("/parkingRecord/receiveDeviceInfo/test")
+				.excludePathPatterns("/parkingRecord/getTemporaryCarNumByOpenId")
+				;
+	}
+}

+ 21 - 0
src/main/java/com/example/demo1/config/YsConfig.java

@@ -0,0 +1,21 @@
+package com.example.demo1.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "ys")
+public class YsConfig {
+    private String freeAppKey;
+    private String freeAppSecret;
+
+    private String payAppKey;
+    private String payAppSecret;
+
+    private String tokenUrl;
+    private String liveAddressUrl;
+    private String deviceInfoUrl;
+    private String deviceCaptureUrl;
+}

+ 25 - 0
src/main/java/com/example/demo1/dto/AccessToken.java

@@ -0,0 +1,25 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+@Data
+public class AccessToken {
+
+    /**
+     * 获取到的凭证
+     */
+    private String token;
+    /**
+     * 凭证有效时间,单位:秒
+     */
+    private int expiresIn;
+    /**
+     * 用户唯一标识
+     */
+    private String openid;
+
+    /**
+     * 类型
+     */
+    private String scope;
+}

+ 44 - 0
src/main/java/com/example/demo1/dto/AddParkingMember.java

@@ -0,0 +1,44 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/2 0002 下午 4:42
+ */
+@Data
+public class AddParkingMember {
+
+    private String id;
+
+    @NotNull(message = "车牌号不能为空")
+    private String carNum;
+
+    //会员开始时间
+    @NotNull(message = "会员开始时间不能为空")
+    private Date memberStartTime;
+
+    private Date memberEndTime;
+
+    //会员时长(分钟)
+    private Integer memberMin;
+
+    //停车场代号
+    @NotNull(message = "停车场代号不能为空")
+    private String parkingUname;
+
+    private String memberName;
+
+    /**
+     * 会员类型(0:临时车,1:会员车)
+     */
+    private Integer memberType;
+
+   // @NotNull(message = "手机号不能为空")
+    private String memberPhone;
+
+    private Integer gunType;
+}

+ 29 - 0
src/main/java/com/example/demo1/dto/AlarmInfoPlate.java

@@ -0,0 +1,29 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 11:13
+ */
+@Data
+public class AlarmInfoPlate {
+
+    //默认通道号(预留)
+    private Integer channel;
+
+    //设备名称
+    private String deviceName;
+
+    //设备 ip 地址
+    private String ipaddr;
+
+    //实际数据
+    private Result result;
+
+    //设备序列号,设备唯一
+    private String serialno;
+
+
+    private String user_data;
+}

+ 17 - 0
src/main/java/com/example/demo1/dto/CalcFeeTime.java

@@ -0,0 +1,17 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2023/1/6 0006 上午 9:15
+ */
+@Data
+public class CalcFeeTime {
+
+    private Date startTime;
+
+    private Date endTime;
+}

+ 19 - 0
src/main/java/com/example/demo1/dto/CostRecord.java

@@ -0,0 +1,19 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2023/1/5 0005 下午 4:59
+ */
+@Data
+public class CostRecord {
+
+   // private List<ParkingFeeSub> feeList;
+
+    private String dayStr;
+
+    private Integer minute;
+
+    private Integer number = 1;
+}

+ 50 - 0
src/main/java/com/example/demo1/dto/MessageResult.java

@@ -0,0 +1,50 @@
+package com.example.demo1.dto;
+
+public class MessageResult<T> {
+	private boolean result = true;
+	private String message;
+	private T data;
+	private int code = 200;
+
+	public MessageResult() {
+	}
+
+	public MessageResult(boolean result, String message, T data, int code) {
+		this.result = result;
+		this.message = message;
+		this.data = data;
+		this.code = code;
+	}
+
+	public boolean isResult() {
+		return result;
+	}
+
+	public void setResult(boolean result) {
+		this.result = result;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public T getData() {
+		return data;
+	}
+
+	public void setData(T data) {
+		this.data = data;
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+}

+ 33 - 0
src/main/java/com/example/demo1/dto/ParkingCostDTO.java

@@ -0,0 +1,33 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/14 0014 上午 11:29
+ */
+@Data
+public class ParkingCostDTO {
+
+    /**
+     * 总金额
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 优惠金额
+     */
+    private BigDecimal discountAmount;
+
+    /**
+     * 应缴金额
+     */
+    private BigDecimal needAmount;
+
+    /**
+     * 每小时费用
+     */
+    private BigDecimal hourCost;
+}

+ 49 - 0
src/main/java/com/example/demo1/dto/ParkingDetailDTO.java

@@ -0,0 +1,49 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2021-3-9 9:40
+ */
+@Data
+public class ParkingDetailDTO {
+
+    private String id;
+
+    //车牌
+    private String carNumber;
+
+    //商户名称
+    private String merchantName;
+
+    //停车场名称
+    private String parkingName;
+
+    //进场时间
+    private String inParkingTime;
+
+    //停车时间
+    private String parkingTime;
+
+    private String parkingTimeStr;
+
+    //优惠金额
+    private BigDecimal discountMoney;
+
+    //总金额
+    private BigDecimal total;
+
+    //订单金额
+    private BigDecimal price;
+
+    //已支付
+    private BigDecimal payed;
+
+    //每小时费用
+    private BigDecimal hourCost;
+
+
+}

+ 23 - 0
src/main/java/com/example/demo1/dto/ParkingFeeSubDTO.java

@@ -0,0 +1,23 @@
+package com.example.demo1.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/17 0017 下午 5:29
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ParkingFeeSubDTO {
+
+    private Integer minSection;
+
+    private Integer maxSection;
+
+    private BigDecimal parkingCost;
+}

+ 38 - 0
src/main/java/com/example/demo1/dto/ParkingShopDTO.java

@@ -0,0 +1,38 @@
+package com.example.demo1.dto;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/11/1 0001 上午 9:50
+ */
+@Data
+public class ParkingShopDTO {
+
+    private Page page;
+
+    private String id;
+
+    private String merchantName;
+
+    private String companyId;
+
+    private String parkId;
+
+    private String parkName;
+
+    private String companyName;
+
+    private String userName;
+
+    private String password;
+
+    private Boolean enableCoupon;
+
+    private Boolean enableMember;
+
+    private Integer reduce;
+
+    private String memberLeaveTime;
+}

+ 10 - 0
src/main/java/com/example/demo1/dto/ParkingUserRelationDTO.java

@@ -0,0 +1,10 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+@Data
+public class ParkingUserRelationDTO {
+
+    private String regUserId;
+    private String[] parkingInfoIds;
+}

+ 28 - 0
src/main/java/com/example/demo1/dto/PayDTO.java

@@ -0,0 +1,28 @@
+package com.example.demo1.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/8/10 0010 上午 10:53
+ */
+@Data
+public class PayDTO {
+
+    @Excel(name = "车牌", height = 8, width = 13, isImportField = "true")
+    private String carNum;
+    @Excel(name = "停车场", height = 8, width = 13, isImportField = "true")
+    private String  parkingName;
+    @Excel(name = "支付时间", height = 8, width = 13, isImportField = "true")
+    private String payTimeStr;
+    @Excel(name = "应付金额", height = 8, width = 13, isImportField = "true")
+    private BigDecimal  payAmount;
+    @Excel(name = "已付金额", height = 8, width = 13, isImportField = "true")
+    private BigDecimal actualPayAmount;
+    @Excel(name = "支付方式", height = 8, width = 13, isImportField = "true")
+    private String  payNameStr;
+
+}

+ 13 - 0
src/main/java/com/example/demo1/dto/PlateResponse.java

@@ -0,0 +1,13 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 下午 4:00
+ */
+@Data
+public class PlateResponse {
+
+    private ResponseAlarmInfoPlate Response_AlarmInfoPlate;
+}

+ 64 - 0
src/main/java/com/example/demo1/dto/PlateResult.java

@@ -0,0 +1,64 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 11:23
+ */
+@Data
+public class PlateResult {
+
+    //亮度评价(预留)
+    private Integer bright;
+
+    //车身亮度(预留)
+    private Integer carBright;
+
+    //车身颜色(预留)
+    private Integer carColor;
+
+    //车牌颜色 0:未知、1:蓝色、2:黄色、3:白色、4:黑 色、5:绿色
+    private Integer colorType;
+
+    private Integer colorValue;
+
+    //识别结果可信度 1-100
+    private Integer confidence;
+
+    //车的行进方向,0:未知,1:左,2:右,3:上, 4:下
+    private Integer direction;
+
+    //识别大图片内容经过 base64 后的字符串
+    private String imageFile;
+
+    //识别车牌小图片内容经过 base64 后的字符串
+    private String imageFragmentFile;
+
+    //识别小图片内容长度,注意不是 base64 后的长度
+    private Integer imageFragmentFileLen;
+
+    //设备离线状态,0:在线,1:离线
+    private Integer isoffline;
+
+    //车牌号字符串,如“京 AAAAAA”
+    private String license;
+
+    private Integer license_ext_type;
+
+    //识别结果车牌 ID
+    private Integer plateid;
+
+    //识别结果对应帧的时间戳
+    private TimeStamp timeStamp;
+
+    //识别所用时间
+    private Integer timeUsed;
+
+    //当前结果的触发类型:1:自动触发类型、2:外部输入触 发(IO 输入)、4:软件触发(SDK)、8:虚拟线圈触发
+    private Integer triggerType;
+
+    //车牌类型 0:未知车牌:、1:蓝牌小汽车、2::黑牌小汽车、 3:单排黄牌、4:双排黄牌、 5:警车车牌、6:武警车 牌、7:个性化车牌、8:单排军车牌、9:双排军车牌、1 0:使馆车牌、11:香港进出中国大陆车牌、12:农用车牌、13:教练车牌、14:澳门进出中国大陆车牌、15:双 层武警车牌、16:武警总队车牌、17:双层武警总队车牌、 18:民航车牌、19:新能源车牌
+    private Integer type;
+
+}

+ 97 - 0
src/main/java/com/example/demo1/dto/PojoUtils.java

@@ -0,0 +1,97 @@
+package com.example.demo1.dto;
+
+import com.github.dozermapper.core.DozerBeanMapperBuilder;
+import com.github.dozermapper.core.Mapper;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class PojoUtils {
+    private static Mapper MAPPER = DozerBeanMapperBuilder.buildDefault();
+
+    public static <T> Map<String, Object> pojo2map(T t) {
+        // TODO Auto-generated method stub
+        Map<String,Object> map = new HashMap<String,Object>();
+
+        try{
+            BeanInfo beanInfo  = Introspector.getBeanInfo(t.getClass());
+            PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
+
+            for (PropertyDescriptor pd : props) {
+                if (pd.getReadMethod()!=null) {
+                    try {
+                        Object srcValue = pd.getReadMethod().invoke(t);
+                        map.put(pd.getName(), srcValue);
+                    }
+                    catch (Exception ex){
+                        log.error(ex.getMessage(),ex);
+                    }
+                }
+            }
+        }
+        catch(Exception ex){
+            ex.printStackTrace();
+        }
+
+        return map;
+    }
+
+    public static Map pageWrapper(Page page){
+        Map<String,Object> pageMap = new HashMap<>();
+
+        pageMap.put("recordsTotal",page.getTotal());
+        pageMap.put("recordsFiltered",page.getTotal());
+        pageMap.put("totalPage",page.getPages());
+        pageMap.put("pageNumber",page.getPageNum());
+        pageMap.put("pageSize",page.getPageSize());
+        pageMap.put("data", page.getResult());
+
+        return pageMap;
+    }
+
+    public static Map pageWrapper2(com.baomidou.mybatisplus.extension.plugins.pagination.Page page){
+        Map<String,Object> pageMap = new HashMap<>();
+
+        pageMap.put("recordsTotal",page.getTotal());
+        pageMap.put("recordsFiltered",page.getTotal());
+        pageMap.put("totalPage",page.getPages());
+        pageMap.put("pageNumber",page.getCurrent());
+        pageMap.put("pageSize",page.getSize());
+        pageMap.put("data", page.getRecords());
+
+        return pageMap;
+    }
+
+
+    public static <T> Page<T> convertPage(Page page, Class<T> destinationClass){
+        Page newPage = new Page();
+
+        newPage.setPageNum(page.getPageNum());
+        newPage.setPageSize(page.getPageSize());
+        newPage.setPages(page.getPages());
+        newPage.setTotal(page.getTotal());
+
+        for (Object obj: page) {
+            newPage.add(map(obj,destinationClass));
+        }
+
+        return newPage;
+    }
+
+    public static <T> T map(Object source, Class<T> destinationClass) {
+        if (source == null) {
+            return null;
+        }
+        return MAPPER.map(source, destinationClass);
+    }
+
+    public static void map(Object source, Object destination) {
+        MAPPER.map(source, destination);
+    }
+}

+ 26 - 0
src/main/java/com/example/demo1/dto/ReceiveDeviceDTO.java

@@ -0,0 +1,26 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 10:36
+ */
+@Data
+public class ReceiveDeviceDTO {
+
+    private String deviceName;
+
+    private String ipaddr;
+
+    private String port;
+
+    private String userName;
+
+    private String passWd;
+
+    private String serialno;
+
+    private String channelNum;
+
+}

+ 23 - 0
src/main/java/com/example/demo1/dto/ResponseAlarmInfoPlate.java

@@ -0,0 +1,23 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 下午 3:54
+ */
+@Data
+public class ResponseAlarmInfoPlate {
+
+    private String info;
+
+    private Integer plateid;
+
+    private String content;
+
+    private WhiteListOperate white_list_operate;
+
+    private List<SerialData> serialData;
+}

+ 14 - 0
src/main/java/com/example/demo1/dto/Result.java

@@ -0,0 +1,14 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 11:23
+ */
+@Data
+public class Result {
+
+    //车牌识别结果信息
+    private PlateResult plateResult;
+}

+ 17 - 0
src/main/java/com/example/demo1/dto/SerialData.java

@@ -0,0 +1,17 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/11 0011 上午 9:02
+ */
+@Data
+public class SerialData{
+
+    private Integer serialChannel;
+
+    private String data;
+
+    private Integer dataLen;
+}

+ 14 - 0
src/main/java/com/example/demo1/dto/TimeStamp.java

@@ -0,0 +1,14 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 11:30
+ */
+@Data
+public class TimeStamp {
+
+    //时间戳结构体类型
+    private Timeval timeval;
+}

+ 35 - 0
src/main/java/com/example/demo1/dto/Timeval.java

@@ -0,0 +1,35 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/5/31 0031 上午 11:30
+ */
+@Data
+public class Timeval {
+
+    //时间,天
+    private Integer decday;
+
+    //时间,小时
+    private Integer dechour;
+
+    //时间,分钟
+    private Integer decmin;
+
+    //时间,月
+    private Integer decmon;
+
+    //时间,秒
+    private Integer decsec;
+
+    //时间,年
+    private Integer decyear;
+
+    //从 1970 年 1 月 1 日到对应帧的秒
+    private Long sec;
+
+    //从 1970 年 1 月 1 日到对应帧的毫秒
+    private Integer usec;
+}

+ 18 - 0
src/main/java/com/example/demo1/dto/TriggerImage.java

@@ -0,0 +1,18 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2023/1/3 0003 下午 3:50
+ */
+@Data
+public class TriggerImage {
+
+
+    private String imageFile;
+
+    private Integer imageFileLen;
+
+
+}

+ 20 - 0
src/main/java/com/example/demo1/dto/UserInfo.java

@@ -0,0 +1,20 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * 微信通用接口凭证
+ *
+ * @author lt
+ * @date 2013-08-08
+ */
+@Data
+public class UserInfo {
+	private String openid;
+	private String nickname;
+	private String city;
+	private String country;
+	private String province;
+	private String headimgurl;
+
+}

+ 30 - 0
src/main/java/com/example/demo1/dto/WhiteDTO.java

@@ -0,0 +1,30 @@
+package com.example.demo1.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/8/10 0010 上午 10:53
+ */
+@Data
+public class WhiteDTO {
+
+    @Excel(name = "房号", height = 8, width = 13, isImportField = "true")
+    private String memberName;
+    @Excel(name = "车牌号码", height = 8, width = 13, isImportField = "true")
+    private String memberCarNum;
+    @Excel(name = "所属商户", height = 8, width = 13, isImportField = "true")
+    private String shopName;
+    @Excel(name = "当前状态", height = 8, width = 13, isImportField = "true")
+    private String cloudDelFlagName;
+    @Excel(name = "录入时间", height = 8, width = 13, isImportField = "true")
+    private String createTime;
+    @Excel(name = "生效时间", height = 8, width = 13, isImportField = "true")
+    private String  memberStartTime;
+    @Excel(name = "截止时间", height = 8, width = 13, isImportField = "true")
+    private String  memberEndTime;
+    @Excel(name = "存放天数", height = 8, width = 13, isImportField = "true")
+    private Integer days;
+
+}

+ 21 - 0
src/main/java/com/example/demo1/dto/WhiteData.java

@@ -0,0 +1,21 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/9 0009 下午 3:09
+ */
+@Data
+public class WhiteData {
+
+    private String plate;
+
+    private Integer enable;
+
+    private Integer need_alarm;
+
+    private String enable_time;
+
+    private String overdue_time;
+}

+ 17 - 0
src/main/java/com/example/demo1/dto/WhiteListOperate.java

@@ -0,0 +1,17 @@
+package com.example.demo1.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/9 0009 下午 3:08
+ */
+@Data
+public class WhiteListOperate {
+
+    private Integer operate_type;
+
+    private List<WhiteData> white_list_data;
+}

+ 84 - 0
src/main/java/com/example/demo1/interceptor/LoginInterceptor.java

@@ -0,0 +1,84 @@
+package com.example.demo1.interceptor;
+
+
+import com.example.demo1.dto.MessageResult;
+import com.example.demo1.utils.JwtUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLDecoder;
+
+@Slf4j
+@Component
+public class LoginInterceptor implements HandlerInterceptor {
+    @Value("${jwt.secret}")
+    private String jwtSecret;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        if (request.getMethod().equals("OPTIONS")){
+            return true;
+        }
+
+        String token = request.getHeader("Authorization");
+
+        if (StringUtils.isEmpty(token)){
+            token = (String)request.getSession().getAttribute("token");
+        }
+
+        if (StringUtils.isEmpty(token) && !StringUtils.isEmpty(request.getParameter("token"))) {
+            token = URLDecoder.decode(request.getParameter("token"),"UTF-8");
+        }
+
+        boolean result;
+
+        try {
+            Claims claims = JwtUtil.decodeTokenForClaims(jwtSecret, token);
+            String subject = (String) claims.get("subject");
+
+            if(StringUtils.isEmpty(subject)){
+                log.warn("token=" + token);
+
+                //兼容之前的token
+                subject = JwtUtil.decodeTokenForSubject(jwtSecret, token);
+                request.setAttribute("subject", subject);
+            }
+            else {
+                String roles = (String) claims.get("roles");
+                String permissions = (String) claims.get("permissions");
+
+                request.setAttribute("subject", subject);
+                request.setAttribute("roles", roles);
+                request.setAttribute("permissions", permissions);
+            }
+
+            result = true;
+        }
+        catch(Exception ex){
+            MessageResult<String> msgResult = new MessageResult<>();
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+            msgResult.setCode(415);
+
+            ObjectMapper mapper = new ObjectMapper();
+            String json = mapper.writeValueAsString(msgResult);
+
+            response.setContentType("application/json");
+            response.setCharacterEncoding("UTF-8");
+            response.setHeader("access-control-allow-origin","*");
+            response.getWriter().print(json);
+
+            result = false;
+        }
+
+        return result;
+    }
+}

+ 273 - 0
src/main/java/com/example/demo1/utils/Base64.java

@@ -0,0 +1,273 @@
+package com.example.demo1.utils;
+
+public final class Base64 {
+
+    static private final int     BASELENGTH           = 128;
+    static private final int     LOOKUPLENGTH         = 64;
+    static private final int     TWENTYFOURBITGROUP   = 24;
+    static private final int     EIGHTBIT             = 8;
+    static private final int     SIXTEENBIT           = 16;
+    static private final int     FOURBYTE             = 4;
+    static private final int     SIGN                 = -128;
+    static private final char    PAD                  = '=';
+    static private final boolean fDebug               = false;
+    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
+    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = (char) '+';
+        lookUpBase64Alphabet[63] = (char) '/';
+
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+
+        if (binaryData == null) {
+            return null;
+        }
+
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+        char encodedData[] = null;
+
+        encodedData = new char[numberQuartet * 4];
+
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
+
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+
+        if (encoded == null) {
+            return null;
+        }
+
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+
+        if (len % FOURBYTE != 0) {
+            return null;//should be divisible by four
+        }
+
+        int numberQuadruple = (len / FOURBYTE);
+
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+
+        for (; i < numberQuadruple - 1; i++) {
+
+            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
+                    || !isData((d3 = base64Data[dataIndex++]))
+                    || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }//if found "no data" just return null
+
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+
+        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;//if found "no data" just return null
+        }
+
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)//last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { //No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+        }
+
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data  the byte array of base64 data (with WS)
+     * @return      the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+}

+ 83 - 0
src/main/java/com/example/demo1/utils/CRC16.java

@@ -0,0 +1,83 @@
+package com.example.demo1.utils;
+
+public class CRC16 {
+    static int[] gabyCRCHi = {
+            0x03, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+            0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+            0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+            0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+            0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+            0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+            0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+            0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+            0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
+            0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
+            0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
+            0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+    };
+
+    static int[] gabyCRCLo = {
+            0x02, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
+            0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
+            0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
+            0x08, 0xC8, 0xD8, 0x28, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
+            0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
+            0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
+            0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
+            0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
+            0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
+            0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
+            0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
+            0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
+            0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
+            0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
+            0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
+            0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
+            0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
+            0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
+            0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
+            0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
+            0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
+            0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
+            0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
+            0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
+            0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
+            0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
+
+    public static byte[] Get_CRC16(byte[] data){
+        byte[] crc16 = new byte[2];
+
+        int ucCRCLo = 0xff;
+        int ucCRCHi = 0xff;
+
+        int iIndex;
+
+        for (int i = 0; i < data.length; ++i) {
+            iIndex = (ucCRCLo ^ data[i]) & 0x00ff;
+            ucCRCLo = ucCRCHi ^ gabyCRCHi[iIndex];
+            ucCRCHi = gabyCRCLo[iIndex];
+        }
+
+        ucCRCHi = ucCRCHi & 0xff;
+        ucCRCLo = ucCRCLo & 0xff;
+
+        crc16[0] = (byte)ucCRCHi;
+        crc16[1] = (byte)ucCRCLo;
+
+        return crc16;
+    }
+}

+ 77 - 0
src/main/java/com/example/demo1/utils/DES3.java

@@ -0,0 +1,77 @@
+package com.example.demo1.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.Key;
+
+public class DES3 {
+
+    public String encrypt(byte[] key, byte[] data)  throws Exception {
+
+        Key deskey = null;
+        DESedeKeySpec spec = new DESedeKeySpec(key);
+        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
+        deskey = keyfactory.generateSecret(spec);
+        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, deskey);
+        byte[] bOut = cipher.doFinal(data);
+
+        return Base64.encode(bOut);
+    }
+
+    public String encrypt(String key, String data)  throws Exception {
+        return encrypt(getKeyByte(key),data.getBytes("UTF-8"));
+    }
+
+    public String decrypt(byte[] key, byte[] data) throws Exception {
+        Key deskey = null;
+        DESedeKeySpec spec = new DESedeKeySpec(key);
+        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
+        deskey = keyfactory.generateSecret(spec);
+
+        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
+
+        cipher.init(Cipher.DECRYPT_MODE, deskey);
+
+        byte[] bOut = cipher.doFinal(data);
+
+        return new String(bOut, "UTF-8");
+    }
+
+    public String decrypt(String key, String data)  throws Exception {
+        return decrypt(getKeyByte(key), Base64.decode(data));
+    }
+
+    public byte[] getKeyByte(String key) throws UnsupportedEncodingException {
+        if (key == null) {
+            return new byte[0];
+        }
+
+        int length = key.length();
+        if (length >= 24) {
+            return key.substring(0, 24).getBytes("UTF-8");
+        } else {
+            for (int i = 0; i < (24 - length); i++) {
+                key += "0";
+            }
+
+            return key.getBytes("UTF-8");
+        }
+    }
+
+    public static void main(String[] args) {
+        DES3 des3 = new DES3();
+        String appKey = "8ZZAHLlTMeNRCP6X";
+
+        try {
+            System.out.println(des3.encrypt(appKey, "ac5c629f-068d-4b8d-8700-3c3d362337f0"));
+
+            System.out.println(des3.decrypt(appKey, "Xkb9FDXbmw8tEybl2ItjvomEK0QrL+pn6wt9yO7/vA7G9jIUiDhFLg=="));
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+}

+ 60 - 0
src/main/java/com/example/demo1/utils/DateUtil.java

@@ -0,0 +1,60 @@
+package com.example.demo1.utils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public class DateUtil {
+
+
+    public static Date parse(String dataStr){
+    	return parse(dataStr,null);
+    }
+
+	public static Date parse(String dateStr,String pattern) {
+		if(dateStr==null||dateStr.length()==0){
+			return null;
+		}
+	try{
+		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");//SimpleDateFormat非线程安全,每次使用时创建实例
+		if(pattern!=null){
+			df.applyPattern(pattern);
+		}
+		else{
+			if(dateStr.length()>10){//yyyy-MM-dd HH:mm:ss
+				df.applyPattern("yyyy-MM-dd HH:mm:ss");
+			}
+			else{
+				df.applyPattern("yyyy-MM-dd");
+			}
+		}
+
+		   return df.parse(dateStr);
+		}
+		catch(ParseException pe){
+			pe.printStackTrace();
+			return null;
+		}
+
+	}
+
+	public static String format(Date date,String pattern){
+		if(date==null){
+			return null;
+		}
+		if(pattern==null||pattern.length()==0){
+			pattern="yyyy-MM-dd";
+		}
+		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
+		df.applyPattern(pattern);
+		return df.format(date);
+	}
+
+	public static void main(String[] args) throws Exception{
+		String d="2011-09-01";
+		Date dd=DateUtil.parse(d, null);
+		System.out.println(dd.getTime());
+	}
+
+}

+ 52 - 0
src/main/java/com/example/demo1/utils/FileUtil.java

@@ -0,0 +1,52 @@
+package com.example.demo1.utils;
+
+import com.example.demo1.config.OSSConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import sun.misc.BASE64Decoder;
+
+import java.io.ByteArrayInputStream;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/1 0001 上午 11:51
+ */
+@Component
+public class FileUtil {
+
+    @Autowired
+    private OSSConfig ossConfig;
+
+
+    public  String uploadBase64(String photoName, String photoBase64Data) {
+
+        try {
+            BASE64Decoder decoder = new BASE64Decoder();
+
+            String[] arr = photoBase64Data.split(",");
+
+            byte[] imgData = decoder.decodeBuffer(arr[0]);
+
+            for (int i = 0; i < imgData.length; ++i) {
+                if (imgData[i] < 0) {// 调整异常数据
+                    imgData[i] += 256;
+                }
+            }
+
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(imgData);
+
+            if (org.apache.commons.lang3.StringUtils.isEmpty(photoName)) {
+                photoName = "1.png";
+            }
+
+            String retFileUrl = OSSUtil.upload(ossConfig, "/chargingParking", photoName, inputStream);
+            return retFileUrl;
+        } catch (Exception ex) {
+
+        }
+        return null;
+
+
+
+    }
+}

+ 422 - 0
src/main/java/com/example/demo1/utils/HttpConnectionUtil.java

@@ -0,0 +1,422 @@
+package com.example.demo1.utils;
+
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import java.io.*;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+
+public class HttpConnectionUtil {
+	private static int connectTimeoutMs = 10000;
+	private static int readTimeoutMs = 10000;
+	private static String charSet = "UTF-8";
+
+	public static String getHttpContent(String url) {
+        return getHttpContent(url, "UTF-8");
+    }
+
+    public static String getHttpContent(String url, String charSet) {
+        HttpURLConnection connection = null;
+        String content = "";
+        try {
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("GET");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+            //after JDK 1.5
+//            connection.setConnectTimeout(10000);
+//            connection.setReadTimeout(10000);
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+                return content;
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static String getHttpContentByPost(String url, String charSet,Map<String, Object> requestParamsMap) {
+        HttpURLConnection connection = null;
+        DataOutputStream out = null;
+        String content = "";
+        StringBuffer params = new StringBuffer();
+        try {
+
+        	// 组织请求参数
+            Iterator it = requestParamsMap.entrySet().iterator();
+            while (it.hasNext()) {
+				Map.Entry element = (Map.Entry) it.next();
+                params.append(element.getKey());
+                params.append("=");
+                params.append(element.getValue());
+                params.append("&");
+            }
+            if (params.length() > 0) {
+                params.deleteCharAt(params.length() - 1);
+            }
+
+            System.out.println("url>>>>>>>>>>" + url);
+            System.out.println("params>>>>>>>>>>" + params);
+
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("POST");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+         // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));
+            // 发送POST请求必须设置如下两行
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            // 获取URLConnection对象对应的输出流
+            out = new DataOutputStream(connection.getOutputStream());
+            // 发送请求参数
+            out.write(params.toString().getBytes("utf-8"));
+            out.flush();
+            out.close();
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+
+            System.out.println("response_code>>>>>" + response_code);
+
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+
+                System.out.println("content>>>>>" + content);
+                return content;
+            }
+
+
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+
+    public static String getHttpContentByPost(String url, String charSet,String params) {
+        HttpURLConnection connection = null;
+        String content = "";
+        PrintWriter printWriter = null;
+        try {
+
+            URL address_url = new URL(url);
+            connection = (HttpURLConnection) address_url.openConnection();
+            connection.setRequestMethod("POST");
+            //设置访问超时时间及读取网页流的超市时间,毫秒值
+            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
+
+         // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));
+            // 发送POST请求必须设置如下两行
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            // 获取URLConnection对象对应的输出流
+            printWriter = new PrintWriter(connection.getOutputStream());
+            // 发送请求参数
+            printWriter.write(params);
+            // flush输出流的缓冲
+            printWriter.flush();
+            //得到访问页面的返回值
+            int response_code = connection.getResponseCode();
+            if (response_code == HttpURLConnection.HTTP_OK) {
+                InputStream in = connection.getInputStream();
+//                InputStreamReader reader = new InputStreamReader(in,charSet);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
+                String line = null;
+                while ((line = reader.readLine()) != null) {
+                    content+=line;
+                }
+                return content;
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(connection !=null){
+                connection.disconnect();
+            }
+        }
+        return "";
+    }
+
+	/**
+	 * 以http post方式请求
+	 * @param url 请求地址
+	 * @param data 请求参数
+	 * @return
+	 */
+	public static String requestByPost(String url,String data){
+		return requestByPost(url,charSet,data,connectTimeoutMs,readTimeoutMs);
+	}
+
+	/**
+	 * 以http get方式请求
+	 * @param url 请求地址
+	 * @return
+	 */
+	public static String requestByGet(String url){
+		return requestByGet(url,charSet,connectTimeoutMs,readTimeoutMs);
+	}
+
+	/**
+	 * 以http post方式请求
+	 * @param url 请求地址
+	 * @param charSet 字符编码
+	 * @param data 请求参数
+	 * @param connectTimeoutMs 连接超时(毫秒)
+	 * @param readTimeoutMs 数据读取超时(毫秒)
+	 * @return
+	 */
+    public static String requestByPost(String url,String charSet,String data, int connectTimeoutMs, int readTimeoutMs){
+    	try{
+	        BasicHttpClientConnectionManager connManager;
+
+	        connManager = new BasicHttpClientConnectionManager(
+	                RegistryBuilder.<ConnectionSocketFactory>create()
+	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
+	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
+	                        .build(),
+	                null,
+	                null,
+	                null
+	        );
+
+	        HttpClient httpClient = HttpClientBuilder.create()
+					//取消HttpClient 设置超时后,若在设定的时间内没有返回数据,httpClient底层会重复请求
+					.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
+	                .setConnectionManager(connManager)
+	                .build();
+
+	        HttpPost httpPost = new HttpPost(url);
+
+	        RequestConfig requestConfig = RequestConfig.custom()
+					.setSocketTimeout(readTimeoutMs)
+					.setConnectTimeout(connectTimeoutMs)
+					.build();
+
+	        httpPost.setConfig(requestConfig);
+
+	        StringEntity postEntity = new StringEntity(data, charSet);
+	        httpPost.addHeader("Content-Type", "text/xml");
+	        httpPost.setEntity(postEntity);
+
+	        HttpResponse httpResponse = httpClient.execute(httpPost);
+	        HttpEntity httpEntity = httpResponse.getEntity();
+	        return EntityUtils.toString(httpEntity, "UTF-8");
+    	}catch(Exception e){
+    		e.printStackTrace();
+    	}
+
+    	return "";
+
+    }
+
+    /**
+	 * 以http get方式请求
+	 * @param url 请求地址
+	 * @param charSet 字符编码
+	 * @param connectTimeoutMs 连接超时(毫秒)
+	 * @param readTimeoutMs 数据读取超时(毫秒)
+	 * @return
+	 */
+    public static String requestByGet(String url,String charSet,int connectTimeoutMs, int readTimeoutMs){
+    	try{
+	        BasicHttpClientConnectionManager connManager;
+
+	        connManager = new BasicHttpClientConnectionManager(
+	                RegistryBuilder.<ConnectionSocketFactory>create()
+	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
+	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
+	                        .build(),
+	                null,
+	                null,
+	                null
+	        );
+
+	        HttpClient httpClient = HttpClientBuilder.create()
+	                .setConnectionManager(connManager)
+	                .build();
+
+	        HttpGet httpGet = new HttpGet(url);
+
+	        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
+	        httpGet.setConfig(requestConfig);
+	        httpGet.addHeader("Content-Type", "text/xml");
+
+	        HttpResponse httpResponse = httpClient.execute(httpGet);
+	        HttpEntity httpEntity = httpResponse.getEntity();
+	        return EntityUtils.toString(httpEntity, "UTF-8");
+    	}catch(Exception e){
+    		e.printStackTrace();
+    	}
+
+    	return "";
+
+    }
+
+    /**
+	 * 发起https请求并获取结果
+	 *
+	 * @param requestUrl 请求地址
+	 * @param requestMethod 请求方式(GET、POST)
+	 * @param outputStr 提交的数据
+	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
+	 */
+	public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
+		JSONObject jsonObject = null;
+		StringBuffer buffer = new StringBuffer();
+		try {
+			URL url = new URL(requestUrl);
+			HttpURLConnection httpUrlConn = (HttpURLConnection)url.openConnection();
+
+			if (requestUrl.startsWith("https")) {
+				HttpsURLConnection httpsURLConnection = (HttpsURLConnection)httpUrlConn;
+
+				// 创建SSLContext对象,并使用我们指定的信任管理器初始化
+				TrustManager[] tm = { new MyX509TrustManager() };
+				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
+				sslContext.init(null, tm, new java.security.SecureRandom());
+				// 从上述SSLContext对象中得到SSLSocketFactory对象
+				SSLSocketFactory ssf = sslContext.getSocketFactory();
+
+				httpsURLConnection.setSSLSocketFactory(ssf);
+			}
+
+			httpUrlConn.setDoOutput(true);
+			httpUrlConn.setDoInput(true);
+			httpUrlConn.setUseCaches(false);
+			httpUrlConn.setRequestMethod(requestMethod);
+
+			if ("GET".equalsIgnoreCase(requestMethod))
+				httpUrlConn.connect();
+
+			// 当有数据需要提交时
+			if (null != outputStr) {
+				OutputStream outputStream = httpUrlConn.getOutputStream();
+				// 注意编码格式,防止中文乱码
+				outputStream.write(outputStr.getBytes("UTF-8"));
+				outputStream.close();
+			}
+
+			// 将返回的输入流转换成字符串
+			InputStream inputStream = httpUrlConn.getInputStream();
+			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
+			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+
+			String str = null;
+			while ((str = bufferedReader.readLine()) != null) {
+				buffer.append(str);
+			}
+			bufferedReader.close();
+			inputStreamReader.close();
+			// 释放资源
+			inputStream.close();
+			inputStream = null;
+			httpUrlConn.disconnect();
+			jsonObject = JSONObject.fromObject(buffer.toString());
+		} catch (ConnectException ce) {
+			System.out.println("Weixin server connection timed out.");
+		} catch (Exception e) {
+			System.out.println("https request error:" +  e.getMessage());
+		}
+		return jsonObject;
+	}
+
+	public static InputStream downloadStream(String requestUrl){
+		InputStream inputStream = null;
+
+		try {
+			URL url = new URL(requestUrl);
+			HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
+
+			if (requestUrl.startsWith("https")) {
+				HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpUrlConn;
+
+				// 创建SSLContext对象,并使用我们指定的信任管理器初始化
+				TrustManager[] tm = {new MyX509TrustManager()};
+				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
+				sslContext.init(null, tm, new java.security.SecureRandom());
+				// 从上述SSLContext对象中得到SSLSocketFactory对象
+				SSLSocketFactory ssf = sslContext.getSocketFactory();
+
+				httpsURLConnection.setSSLSocketFactory(ssf);
+			}
+
+			httpUrlConn.setDoOutput(true);
+			httpUrlConn.setDoInput(true);
+			httpUrlConn.setUseCaches(false);
+			httpUrlConn.setRequestMethod("GET");
+			httpUrlConn.connect();
+
+			inputStream = httpUrlConn.getInputStream();
+		}
+		catch (Exception ex){
+			System.out.println(ex.getMessage());
+		}
+
+		return inputStream;
+	}
+
+}

+ 107 - 0
src/main/java/com/example/demo1/utils/JwtUtil.java

@@ -0,0 +1,107 @@
+package com.example.demo1.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.security.Keys;
+
+import java.security.Key;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class JwtUtil {
+    public static String createToken(String jwtSecret, String subject, Date expiration) {
+        //token有效时间天
+        byte[] privateKey = Base64.getDecoder().decode(jwtSecret);
+
+        Key key = Keys.hmacShaKeyFor(privateKey);
+
+        Map<String,Object> extraInfo = new HashMap<>();
+        extraInfo.put("subject", subject);
+
+        String token = Jwts.builder()
+//                    .setSubject(subject)
+                //设置自定义claims后,setSubject值将失效
+                .setClaims(extraInfo)
+                .signWith(key)
+                .setExpiration(expiration)
+                .compact();
+
+        return "Bearer " + token;
+    }
+
+    public static String createToken(String jwtSecret, String userId,String roles,String permissions, Date expiration) {
+        //token有效时间天
+        byte[] privateKey = Base64.getDecoder().decode(jwtSecret);
+
+        Key key = Keys.hmacShaKeyFor(privateKey);
+
+        Map<String,Object> extraInfo = new HashMap<>();
+        extraInfo.put("subject", userId);
+        extraInfo.put("roles", roles);
+        extraInfo.put("permissions", permissions);
+
+        String token = Jwts.builder()
+//                    .setSubject(subject)
+                //设置自定义claims后,setSubject值将失效
+                .setClaims(extraInfo)
+                .signWith(key)
+                .setExpiration(expiration)
+                .compact();
+
+        return "Bearer " + token;
+    }
+
+    public static Claims decodeTokenForClaims(String jwtSecret,String token) throws Exception{
+        String prefix = "Bearer ";
+
+        if (token==null || token.length() < prefix.length()){
+            throw new Exception("未传递令牌或未带前缀Bearer!");
+        }
+
+        token = token.substring(prefix.length());
+
+        byte[] privateKey = Base64.getDecoder().decode(jwtSecret);
+
+        Key key = Keys.hmacShaKeyFor(privateKey);
+
+        Claims claims = Jwts.parser()
+                .setSigningKey(key)
+                .parseClaimsJws(token)
+                .getBody();
+
+        return claims;
+    }
+
+    public static String decodeToken(String jwtSecret,String token) throws Exception{
+        Claims claims = decodeTokenForClaims(jwtSecret,token);
+
+        String subject = (String)claims.get("subject");
+
+        return subject;
+    }
+
+    public static String decodeTokenForSubject(String jwtSecret,String token) throws Exception{
+        Claims claims = decodeTokenForClaims(jwtSecret,token);
+
+        return claims.getSubject();
+    }
+
+    public static void main(String[] args) throws Exception {
+//        String jwtSecret="WJgLLiAktNj/vCNEoz6mfAmE0btwluCTk/TnJiZOIkQ=";
+//        String userId="36aeb4c5-c644-4f5a-af21-92883568b271";
+//        String roles="111";
+//        String permissions="222";
+//        Date expiration= DateTime.now().plusHours(12).toDate();
+//        String token= createToken(jwtSecret,userId,roles,permissions,expiration);
+//        System.out.println(token);
+
+        String jwtSecret="WJgLLiAktNj/vCNEoz6mfAmE0btwluCTk/TnJiZOIkQ=";
+        String token ="Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWJqZWN0IjoiMzZhZWI0YzUtYzY0NC00ZjVhLWFmMjEtOTI4ODM1NjhiMjcxIiwicGVybWlzc2lvbnMiOiIyMjIiLCJyb2xlcyI6IjExMSIsImV4cCI6MTY5MDYzOTg3OX0.fItHTSxF3RUY23BsMGqIQlisMHI9QiHJyQwpzXt6kBY";
+         String subJect=decodeToken(jwtSecret,token);
+        System.out.println(subJect);
+        //Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWJqZWN0IjoiMzZhZWI0YzUtYzY0NC00ZjVhLWFmMjEtOTI4ODM1NjhiMjcxIiwicGVybWlzc2lvbnMiOiIyMjIiLCJyb2xlcyI6IjExMSIsImV4cCI6MTY5MDQ4OTkyM30.TFRxRggZ3BoNn-D1Zxx0aflv8B4_wEF8eCyMhU0b094
+        //Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWJqZWN0IjoiMzZhZWI0YzUtYzY0NC00ZjVhLWFmMjEtOTI4ODM1NjhiMjcxIiwicGVybWlzc2lvbnMiOiIyMjIiLCJyb2xlcyI6IjExMSIsImV4cCI6MTY5MDYzOTg3OX0.fItHTSxF3RUY23BsMGqIQlisMHI9QiHJyQwpzXt6kBY
+    }
+}

+ 377 - 0
src/main/java/com/example/demo1/utils/LedTcProtocol.java

@@ -0,0 +1,377 @@
+package com.example.demo1.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class LedTcProtocol {
+
+    public static byte[] sendText(String text) throws UnsupportedEncodingException {
+        //显示文本
+        byte[] textBytes = text.getBytes("GB2312");
+
+//      System.out.println(hex2str(textBytes));
+
+        //数据包
+        //区域编号(1)+显示类型(1)+区域X坐标(2)+区域Y坐标(2)+本区域使用宽度(2)+本区域使用高度(2)+字体大小(1)+字体颜色(1)
+        //+显示特效(1)+滚动速度(1)+文本显示时长(2)+显示退出特效(1)+显示本文的字节数(2)+文本
+        byte[] area = new byte[1+1+2+2+2+2+1+1+1+1+2+1+2+textBytes.length];
+
+        //00:区域本区域编号
+        area[0] = 0x00;
+
+        //00:显示文本;01显示时间
+        area[1] = 0x00;
+
+        //0000:区域X坐标,高字节在前低字节在后;0~31
+        area[2] = 0x00;
+        area[3] = 0x00;
+
+        //0000:区域Y坐标,高字节在前低字节在后;0~63
+        area[4] = 0x00;
+        area[5] = 0x00;
+
+        //0040:本区域使用宽度;16的倍数,默认为屏幕宽度(0x40 = 64)
+        area[6] = 0x00;
+        area[7] = 0x40;
+
+        //000F:本区域使用高度;16的倍数减1,默认为屏幕宽度(0x0F = 15)
+        area[8] = 0x00;
+        area[9] = 0x0F;
+
+        //10:字体大小;16字体或32字体。0x10 = 16
+        area[10] = 0x10;
+
+        //00:字体颜色,0红色,1绿色,2黄色,3蓝色,4紫色,5青色,6白色;需硬件支持
+        area[11] = 0x00;
+
+        //00:显示特效,0立即显示,1由右向左滚动,2自动换行显示,3向上滚动进入,4分屏显示
+        area[12] = 0x01;
+
+        //00:滚动速度,只有特效为滚动时才生效,取值范围0~10;
+        area[13] = 0x00;
+
+        //001E:文本显示时长,单位:秒;高字节在前低字节在后。
+        area[14] = 0x00;
+        area[15] = 0x1E;
+
+        //00:显示退出特效,00立即退出;
+        area[16] = 0x00;
+
+        //0008:显示本文的字节数,后续数据字节数;
+        area[17] = (byte)((textBytes.length>>8) & 0xff);
+        area[18] =  (byte)(textBytes.length & 0xff);
+
+        //显示文本的字符内码
+        for (int i = 0; i < textBytes.length; i++) {
+            area[19+i] = textBytes[i];
+        }
+
+        //区域数量(1)+区域序号(1)+区域数据字节数(1)+区域数据
+        byte[] section = new byte[1+1+1+area.length];
+
+        //01 区域数量
+        section[0] = 0x01;
+
+        //00:区域序号;从0开始
+        section[1] = 0x00;
+
+        //1B:第一个区域的数据长度,本区域后续数据字节数
+        section[2] = (byte)area.length;
+
+        //区域数据
+        for (int i = 0; i < area.length; i++) {
+            section[3+i] = area[i];
+        }
+
+        //命令(1)+设备应答(1)+数据长度(2)+数据
+        byte[] dataField = new byte[1+1+2+section.length];
+
+        //0B:命令,显示屏显示文本
+        dataField[0] = (byte) 0x0B;
+
+        //00:设备无需应答;02则需要应答
+        dataField[1] = (byte) 0x00;
+
+        //后续数据长度
+        dataField[2] = (byte)(section.length >> 8);
+        dataField[3]= (byte)(section.length & 0xFF);
+
+        for (int i = 0; i < section.length; i++) {
+            dataField[4+i] = section[i];
+        }
+
+        byte[] frame = createFrame(dataField);
+
+     //   printFrame(frame);
+
+        return frame;
+    }
+
+
+    /**
+     * 发送多行文本到设备
+     * @param arr 多行文本
+     * @param displayModes 0立即显示,1由右向左滚动,2自动换行显示
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+    public static byte[] sendMultilineText(String[] arr,int[] displayModes) throws UnsupportedEncodingException {
+        List<byte[]> areaList = new ArrayList<>();
+
+        int areaTotalLen = 0;
+
+        for(int i=0;i<arr.length;i++){
+            //显示文本
+            byte[] textBytes = arr[i].getBytes("GB2312");
+
+            //数据包
+            //区域编号(1)+显示类型(1)+区域X坐标(2)+区域Y坐标(2)+本区域使用宽度(2)+本区域使用高度(2)+字体大小(1)+字体颜色(1)
+            //+显示特效(1)+滚动速度(1)+文本显示时长(2)+显示退出特效(1)+显示本文的字节数(2)+文本
+            byte[] area = new byte[1+1+2+2+2+2+1+1+1+1+2+1+2+textBytes.length];
+
+            //00:区域本区域编号
+            area[0] = (byte)i;
+
+            //00:显示文本;01显示时间
+            area[1] = 0x00;
+
+            //0000:区域X坐标,高字节在前低字节在后;0~31
+            area[2] = 0x00;
+            area[3] = 0x00;
+
+            int y = 16*i;
+
+            //0000:区域Y坐标,高字节在前低字节在后;0~63
+            area[4] = (byte)(y>>8 & 0xff);
+            area[5] = (byte)(y & 0xff);
+
+            //0040:本区域使用宽度;16的倍数,默认为屏幕宽度(0x40 = 64)
+            area[6] = 0x00;
+            area[7] = 0x40;
+
+            //000F:本区域使用高度;16的倍数减1,默认为屏幕宽度(0x0F = 15)
+            area[8] = 0x00;
+            area[9] = 0x0F;
+
+            //10:字体大小;16字体或32字体。0x10 = 16
+            area[10] = 0x10;
+
+            //00:字体颜色,0红色,1绿色,2黄色,3蓝色,4紫色,5青色,6白色;需硬件支持
+            area[11] = 0x00;
+
+            //00:显示特效,0立即显示,1由右向左滚动,2自动换行显示,3向上滚动进入,4分屏显示
+            area[12] = (byte)displayModes[i];
+
+            //00:滚动速度,只有特效为滚动时才生效,取值范围0~10;
+            area[13] = 0x00;
+
+            //001E:文本显示时长,单位:秒;高字节在前低字节在后。
+            area[14] = 0x00;
+            area[15] = 0x1E;
+
+            //00:显示退出特效,00立即退出;
+            area[16] = 0x00;
+
+            //0008:显示本文的字节数,后续数据字节数;
+            area[17] = (byte)((textBytes.length>>8) & 0xff);
+            area[18] =  (byte)(textBytes.length & 0xff);
+
+            //显示文本的字符内码
+            for (int j = 0; j < textBytes.length; j++) {
+                area[19+j] = textBytes[j];
+            }
+
+            areaList.add(area);
+            areaTotalLen += area.length;
+        }
+
+        //区域数量(1)+[区域1序号(1)+区域1数据字节数(1)+区域1数据,区域2序号+区域2数据字节数+区域2数据...]
+        byte[] section = new byte[1 + 2*areaList.size() + areaTotalLen];
+
+        //01 区域数量
+        int index = 0;
+        section[index] = (byte)areaList.size();
+        index++;
+
+        for (int i = 0; i < areaList.size(); i++) {
+            byte[] area = areaList.get(i);
+
+            //本区域的数据长度,本区域后续数据字节数
+            section[index] = (byte)((area.length>>8) & 0xff);
+            index++;
+
+            section[index] = (byte)(area.length & 0xff);
+            index++;
+
+            //区域数据
+            for (int j = 0; j < area.length; j++) {
+                section[index] =area[j];
+                index++;
+            }
+        }
+
+//        byte[] programInfo = new byte[22];
+//
+//        String hexStr = "46303154001E00000000235959201012312030123100";
+//
+//        for (int i=0;i<programInfo.length;i++){
+//            programInfo[i] = Integer.valueOf(hexStr.substring(i*2,i*2+2),16).byteValue();
+//        }
+
+        //命令(1)+设备应答(1)+数据长度(2)+数据
+        byte[] dataField = new byte[1+1+2+section.length];
+
+        //0B:命令,显示屏显示文本,0D:下载节目信息
+        dataField[0] = (byte) 0x0B;
+
+        //00:设备无需应答;02则需要应答
+        dataField[1] = (byte) 0x00;
+
+        //后续数据长度
+        dataField[2] = (byte)(section.length >> 8);
+        dataField[3]= (byte)(section.length & 0xFF);
+
+//        for (int i = 0; i < programInfo.length; i++) {
+//            dataField[4 + i] = programInfo[i];
+//        }
+
+        for (int i = 0; i < section.length; i++) {
+            dataField[4 +i] = section[i];
+        }
+
+        byte[] frame = createFrame(dataField);
+
+      //  printFrame(frame);
+
+        return frame;
+    }
+
+    private static void printFrame(byte[] frame){
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < frame.length; i++) {
+            String hex = Integer.toHexString(frame[i] & 0xff);
+
+            if (hex.length() == 1) {
+                hex = "0" + hex;
+            }
+
+            sb.append(hex.toUpperCase());
+        }
+
+     //   log.warn("下发串口数据:" + sb);
+    }
+
+    /**
+     * 创建帧数据
+     * @param dataField
+     * @return
+     */
+    private static byte[] createFrame(byte[] dataField) {
+        //协议头(3)+地址(1)+数据域(n)+CRC16(2)
+        byte[] frame = new byte[3 + 1 + dataField.length + 2];
+
+        //协议头
+        frame[0] = (byte) 0xFF;
+        frame[1] = (byte) 0xFE;
+        frame[2] = (byte) 0xA5;
+
+        //设备地址;FF为广播地址
+        frame[3] = (byte) 0xFF;
+
+        for (int i = 0; i < dataField.length; i++) {
+            frame[4 + i] = dataField[i];
+        }
+
+        //crc校验值
+        byte[] crc16 = CRC16.Get_CRC16(dataField);
+
+        //低位在前,高位在后
+        frame[frame.length - 1] = crc16[0];
+        frame[frame.length - 2] = crc16[1];
+        return frame;
+    }
+
+    public static String hex2str(byte[] bytes){
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < bytes.length; i++) {
+            String hex = Integer.toHexString(bytes[i] & 0xff);
+
+            if (hex.length()==1){
+                hex = "0" + hex;
+            }
+
+            sb.append(hex.toUpperCase());
+        }
+
+        return sb.toString();
+    }
+
+    public static byte[] sendVoice(String voiceText) throws UnsupportedEncodingException {
+        String encodeText = "";
+
+        //显示文本
+        byte[] textBytes = voiceText.getBytes("GB2312");
+
+        System.out.println(hex2str(textBytes));
+
+        //语音协议头(1)+数据长度(2)+命令码(1)+命令参数(1)+播报文本
+        byte[] voicePackage = new byte[1+2+1+1+textBytes.length];
+
+        //语音协议头
+        voicePackage[0] = (byte)0xFD;
+
+        //后续数据的字节数
+        voicePackage[1] = (byte)((textBytes.length+2) >> 8);
+        voicePackage[2]= (byte)((textBytes.length+2) & 0xFF);
+
+        //命令码 01
+        voicePackage[3] = 0x01;
+
+        //命令参数 00
+        voicePackage[4] = 0x00;
+
+        for (int i = 0; i < textBytes.length; i++) {
+            voicePackage[5+i] = textBytes[i];
+        }
+
+        //命令(1)+设备应答(1)+数据长度(2)+数据
+        byte[] dataField = new byte[1+1+2+voicePackage.length];
+
+        //24:命令,播报文本
+        dataField[0] = (byte) 0x24;
+
+        //00:设备无需应答;02则需要应答
+        dataField[1] = (byte) 0x00;
+
+        //后续数据长度
+        dataField[2] = (byte)(voicePackage.length >> 8);
+        dataField[3]= (byte)(voicePackage.length & 0xFF);
+
+        for (int i = 0; i < voicePackage.length; i++) {
+            dataField[4+i] = voicePackage[i];
+        }
+
+        //协议头(3)+地址(1)+数据域(n)+CRC16(2)
+        byte[] frame = createFrame(dataField);
+
+
+//      encodeText = hex2str(frame);
+        return frame;
+    }
+
+    public static void main(String[] args) {
+        try {
+            byte[] frame = LedTcProtocol.sendMultilineText(new String[]{"第一行内容很长","第2行信息预览","第3行信息预览","第4行信息预览"},
+                    new int[]{1,1,1,1});
+        }
+        catch (Exception ex){
+            ex.printStackTrace();
+        }
+    }
+}

+ 88 - 0
src/main/java/com/example/demo1/utils/MapUtils.java

@@ -0,0 +1,88 @@
+package com.example.demo1.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class MapUtils {
+
+	/**
+	 * 为空串的value设置为null
+	 * @param args
+	 */
+	public static void blankValToNull(Map<String,Object> args){
+		for(String key : args.keySet()){
+			if(args.get(key) instanceof String && StringUtils.isEmpty((String)args.get(key))){
+				args.put(key,null);
+			}
+		}
+	}
+
+	/**
+	 * 为空串的value设置为null,指定的keys有效
+	 * @param args
+	 */
+    public static void blankValToNull(Map<String,Object> args,String... keys){
+		for(String key : keys){
+			if(args.get(key) instanceof String && StringUtils.isEmpty((String)args.get(key))){
+				args.put(key,null);
+			}
+		}
+	}
+
+
+    /**
+     * 字符串时间value转换为Date对象值,指定的keys有效
+     * @param args
+     * @param fields
+     */
+    public static void strValToDate(Map<String,Object> args,String... keys){
+		for(String key : keys){
+			if(StringUtils.isNotEmpty((String)args.get(key))){
+				args.put(key,DateUtil.parse((String)args.get(key)));
+			}
+		}
+	}
+
+    /**
+     * 提取部分键值对作为新的Map返回,原Map去掉被提取的键值对
+     * @param <V>
+     * @param srcMap
+     * @param keys
+     * @return
+     */
+    public static <V>  Map<String,V>  trackMap(Map<String,V> srcMap,String... keys){
+		Map<String,V> rtnMap=new HashMap<String,V>(keys.length);
+		for(String key : keys){
+			rtnMap.put(key, srcMap.get(key));
+		}
+		for(String key : keys){
+			srcMap.remove(key);
+		}
+		return rtnMap;
+	}
+
+    /**
+     * 提取部分键值对作为新的Map返回
+     * @param <V>
+     * @param srcMap
+     * @param keys
+     * @return
+     */
+	public static <V> Map<String,V> clone(Map<String,V> srcMap,String... keys){
+		Map<String,V> rtnMap=new HashMap<String,V>(keys.length);
+		for(String key : keys){
+			rtnMap.put(key, srcMap.get(key));
+		}
+		return rtnMap;
+	}
+
+	public static Map<String,Object> build(Object... keyVals){
+		Map<String,Object> rtnMap=new HashMap<String,Object>(keyVals.length/2);
+		for(int i=0,len=keyVals.length;i<len;i++){
+			rtnMap.put(keyVals[i].toString(), (i+1)<len?keyVals[i+1]:null);
+			i+=1;
+		}
+		return rtnMap;
+	}
+}

+ 24 - 0
src/main/java/com/example/demo1/utils/MyX509TrustManager.java

@@ -0,0 +1,24 @@
+package com.example.demo1.utils;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * 证书信任管理器(用于https请求)
+ *
+ * @author lt
+ * @date 2013-08-08
+ */
+public class MyX509TrustManager implements X509TrustManager {
+
+	public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public X509Certificate[] getAcceptedIssuers() {
+		return null;
+	}
+}

+ 353 - 0
src/main/java/com/example/demo1/utils/OSSUtil.java

@@ -0,0 +1,353 @@
+package com.example.demo1.utils;
+
+import cn.hutool.core.codec.Base64Encoder;
+import com.aliyun.oss.HttpMethod;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.GeneratePresignedUrlRequest;
+import com.aliyun.oss.model.OSSObject;
+import com.aliyun.oss.model.PutObjectResult;
+import com.example.demo1.config.OSSConfig;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+@Slf4j
+public class OSSUtil {
+    public static String upload(OSSConfig ossConfig,
+                                String subFolder, String fileName,
+                                InputStream fileInputStream) {
+        Date now = new Date();
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(now);
+
+        String savePath = ossConfig.getObjectPre();
+
+        if (!subFolder.startsWith("/")) {
+            savePath += "/";
+        }
+
+        savePath += subFolder;
+
+        //增加一级uuid目录
+        savePath += "/" + cal.get(Calendar.YEAR)
+                 + "/" + (cal.get(Calendar.MONTH) + 1)
+                 + "/" + cal.get(Calendar.DAY_OF_MONTH)
+                 + "/" + UUID.randomUUID().toString()
+                 + "/"
+        ;
+
+        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
+
+//      int index = fileName.indexOf(".");
+//      String prefix = fileName.substring(0,index);
+//      String ext = fileName.substring(index);
+//      String newFileName = DateTime.now().toString("ddHHmmssSSS") + ext;
+//      String retFileUrl = savePath + newFileName;
+        String retFileUrl = savePath + fileName;
+  //      String retFileUrl = fileName;
+
+        // 上传文件流
+        PutObjectResult result = ossClient.putObject(ossConfig.getBucketName(), retFileUrl, fileInputStream);
+
+        // 关闭OSSClient
+        ossClient.shutdown();
+
+        return ossConfig.getUrlPrefix() + "/" + retFileUrl;
+    }
+
+    public static boolean download(String fileUrl,String filePath){
+        boolean result;
+
+        try {
+            FileOutputStream output = new FileOutputStream(filePath);
+
+            URL url = new URL(encodeFileName(fileUrl));
+            URLConnection conn = url.openConnection();
+            InputStream input = conn.getInputStream();
+
+            byte[] buffs = new byte[1024 * 10];
+
+            BufferedInputStream bis = new BufferedInputStream(input, 1024 * 10);
+
+            int read;
+            while ((read = bis.read(buffs, 0, 1024 * 10)) != -1) {
+                output.write(buffs, 0, read);
+            }
+
+            input.close();
+            output.close();
+
+            result = true;
+        } catch (Exception e) {
+            result = false;
+            log.error(e.getMessage(),e);
+        }
+
+        return result;
+    }
+    public static String  downloadToBase64(String fileUrl){
+            ByteArrayOutputStream data = new ByteArrayOutputStream();;
+        try {
+       //     FileOutputStream output = new FileOutputStream();
+       //     OutputStream outputStream =null;
+
+
+
+            URL url = new URL(encodeFileName(fileUrl));
+        //    URLConnection conn = url.openConnection();
+        //    InputStream input = conn.getInputStream();
+
+            byte[] buffs = new byte[1024 * 10];
+            //创建连接
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");
+            conn.setConnectTimeout(5000);
+            InputStream input = conn.getInputStream();
+            //将内容读到内存中
+            int len = -1;
+            while ((len =input.read(buffs))!=-1){
+                data.write(buffs,0,len);
+            }
+            input.close();
+
+
+
+        } catch (Exception e) {
+
+            log.error(e.getMessage(),e);
+        }
+
+
+        return Base64Encoder.encode(data.toByteArray());
+    }
+
+    public static boolean deleteFile(OSSConfig ossConfig,String filePath) {
+        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
+
+        String key = "";
+
+        if (filePath.startsWith(ossConfig.getUrlPrefix())) {
+            key = filePath.substring(ossConfig.getUrlPrefix().length());
+        }
+
+        if (key.startsWith("/")) {
+            key = key.substring(1);
+        }
+
+        boolean exist = ossClient.doesObjectExist(ossConfig.getBucketName(), key);
+
+        if (!exist) {
+            log.error("文件不存在,key={}", key);
+            return false;
+        }
+
+        log.info("删除文件,key={}", key);
+        ossClient.deleteObject(ossConfig.getBucketName(), key);
+
+        ossClient.shutdown();
+
+        return true;
+    }
+
+    public static void batchDownload(List<Map<String,Object>> fileList, OutputStream output){
+        try{
+            ZipOutputStream zos = new ZipOutputStream(output);
+
+            for (Map<String,Object> map : fileList) {
+                String fileUrl = (String)map.get("fileUrl");
+                String filePath = (String)map.get("filePath");
+                String fileName = (String)map.get("fileName");
+
+                try {
+                    if (StringUtils.isEmpty(fileName)) {
+                        fileName = fileUrl;
+                    }
+
+                    if (fileName.indexOf("?") != -1) {
+                        fileName = fileName.substring(0, fileName.indexOf("?"));
+                    }
+
+                    fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
+
+                    String zipFile = fileName;
+
+                    if(StringUtils.isNotEmpty(filePath)){
+                        zipFile = filePath + fileName;
+                    }
+
+                    if(StringUtils.isNotEmpty(fileUrl)) {
+                        ZipEntry zipEntry = new ZipEntry(zipFile);
+                        zos.putNextEntry(zipEntry);
+
+                        URL url = new URL(encodeFileName(fileUrl));
+
+                        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+                        // 设置连接主机超时(单位:毫秒)
+                        conn.setConnectTimeout(5000);
+                        // 设置从主机读取数据超时(单位:毫秒)
+                        conn.setReadTimeout(5000);
+
+                        if(conn.getResponseCode()==200) {
+                            InputStream inputStream = conn.getInputStream();
+
+                            byte[] buffs = new byte[1024 * 10];
+
+                            BufferedInputStream bis = new BufferedInputStream(inputStream, 1024 * 10);
+
+                            int read;
+                            while ((read = bis.read(buffs, 0, 1024 * 10)) != -1) {
+                                zos.write(buffs, 0, read);
+                            }
+
+                            bis.close();
+                        }
+                    }
+                    else if(map.containsKey("localPath")){
+                        ZipEntry zipEntry = new ZipEntry(zipFile);
+                        zos.putNextEntry(zipEntry);
+
+                        String localPath = (String)map.get("localPath");
+                        byte[] buffs = new byte[1024 * 10];
+
+                        InputStream bis = new BufferedInputStream(new FileInputStream(localPath));
+
+                        int read;
+                        while ((read = bis.read(buffs, 0, 1024 * 10)) != -1) {
+                            zos.write(buffs, 0, read);
+                        }
+
+                        bis.close();
+                    }
+                    else if(map.containsKey("fileData")){
+                        ZipEntry zipEntry = new ZipEntry(zipFile);
+                        zos.putNextEntry(zipEntry);
+
+                        byte[] data = (byte[])map.get("fileData");
+
+                        zos.write(data, 0, data.length);
+                    }
+                }
+                catch(Exception ex){
+                    log.error(ex.getMessage(),ex);
+                }
+            }
+
+            zos.close();
+        }
+        catch(Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+    }
+
+    private static String encodeFileName(String fileUrl) throws Exception{
+        String[] segements = fileUrl.split("\\?");
+
+        String[] arr = segements[0].split("/");
+
+        //文件名可能是中文,用utf-8编码
+        arr[arr.length - 1] = URLEncoder.encode(arr[arr.length - 1],"UTF-8");
+
+        String encFileUrl = Arrays.stream(arr).collect(Collectors.joining("/"));
+
+        if (segements.length>1){
+            encFileUrl += "?" + segements[1];
+        }
+
+        return encFileUrl;
+    }
+
+    public static void presignedDownload(OSSConfig ossConfig, List<Map> fileList, OutputStream output){
+        BufferedInputStream bis = null;
+
+        try{
+            ZipOutputStream zos = new ZipOutputStream(output);
+
+            OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
+
+            for (Map<String,String> map : fileList) {
+                try {
+                    String fileUrl = map.get("fileUrl");
+                    String filePath = map.get("filePath");
+
+                    Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
+
+                    if (fileUrl.startsWith(ossConfig.getUrlPrefix())) {
+                        fileUrl = fileUrl.substring(ossConfig.getUrlPrefix().length());
+                    }
+
+                    if (fileUrl.indexOf("?") != -1) {
+                        fileUrl = fileUrl.substring(0, fileUrl.indexOf("?"));
+                    }
+
+                    if (fileUrl.startsWith("/")) {
+                        fileUrl = fileUrl.substring(1);
+                    }
+
+                    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(ossConfig.getBucketName(), fileUrl, HttpMethod.GET);
+
+                    // 设置过期时间。
+                    request.setExpiration(expiration);
+
+                    //设置缩放
+                    request.setProcess("image/resize,l_1024,limit_1");
+
+                    // 生成签名URL(HTTP GET请求)。
+                    URL signedUrl = ossClient.generatePresignedUrl(request);
+
+                    // 使用签名URL发送请求。
+                    OSSObject ossObject = ossClient.getObject(signedUrl, new HashMap<>());
+
+                    if (ossObject != null) {
+                        InputStream inputStream = ossObject.getObjectContent();
+                        byte[] buffs = new byte[1024 * 10];
+                        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
+                        String zipFile = fileName;
+
+                        if (StringUtils.isNotEmpty(filePath)){
+                            zipFile = filePath + fileName;
+                        }
+
+                        ZipEntry zipEntry = new ZipEntry(zipFile);
+                        zos.putNextEntry(zipEntry);
+                        bis = new BufferedInputStream(inputStream, 1024 * 10);
+
+                        int read;
+                        while ((read = bis.read(buffs, 0, 1024 * 10)) != -1) {
+                            zos.write(buffs, 0, read);
+                        }
+
+                        ossObject.close();
+                    }
+                }
+                catch(Exception ex){
+                    log.error(ex.getMessage(),ex);
+                }
+            }
+
+            zos.close();
+            ossClient.shutdown();
+        }
+        catch(Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+        finally {
+            if(bis!=null){
+                try {
+                    bis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}

+ 34 - 0
src/main/java/com/example/demo1/utils/RespThirdVO.java

@@ -0,0 +1,34 @@
+package com.example.demo1.utils;
+
+public class RespThirdVO {
+
+	private Integer code;
+
+	private String  msg;
+
+	public RespThirdVO() {
+		this.code=0;
+	}
+	public RespThirdVO(Integer code, String  msg) {
+		this.code=code;
+		this.msg=msg;
+	}
+
+	public Integer getCode() {
+		return code;
+	}
+
+	public void setCode(Integer code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+
+}

+ 47 - 0
src/main/java/com/example/demo1/utils/RespVO.java

@@ -0,0 +1,47 @@
+package com.example.demo1.utils;
+
+public class RespVO {
+
+	private Boolean success;
+
+	private Object  data;
+
+	private String  msg;
+
+
+	public RespVO() {
+		this.success=true;
+	}
+
+	public RespVO(Boolean success,Object  data,String  msg) {
+		this.success=success;
+		this.data=data;
+		this.msg=msg;
+	}
+
+	public Boolean getSuccess() {
+		return success;
+	}
+
+	public void setSuccess(Boolean success) {
+		this.success = success;
+	}
+
+	public Object getData() {
+		return data;
+	}
+
+	public void setData(Object data) {
+		this.data = data;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+
+}

+ 20 - 0
src/main/java/com/example/demo1/utils/RespVOBuilder.java

@@ -0,0 +1,20 @@
+package com.example.demo1.utils;
+
+public class RespVOBuilder {
+
+	public static RespVO  ok() {  //默认只设置success=true
+		return new RespVO();
+	}
+
+	public static RespVO  ok(Object data) {
+		return new RespVO(true,data,null);
+	}
+
+	public static RespVO  error(String msg) {
+		return new RespVO(false,null,msg);
+	}
+
+	public static RespVO  error(String msg,Object data) {
+		return new RespVO(false,data,msg);
+	}
+}

+ 163 - 0
src/main/java/com/example/demo1/utils/SMSUtil.java

@@ -0,0 +1,163 @@
+//package com.example.demo1.utils;
+//
+//
+//import com.charging.chargingparking.dto.MessageResult;
+//import com.taobao.api.ApiException;
+//import com.taobao.api.DefaultTaobaoClient;
+//import com.taobao.api.TaobaoClient;
+//import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
+//import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
+//import net.sf.json.JSONException;
+//import net.sf.json.JSONObject;
+//
+//import java.util.Random;
+//
+//
+//public class SMSUtil {
+//
+//	public final static String REG_TEMPLATE_CODE = "SMS_49390047";
+//	public static final String NUMBERCHAR = "0123456789";
+//
+//	private final static String APP_KEY = "24698874";
+//	private final static String APP_SECRET = "5f5b21d1dc93e124aa803f95d71c00b8";
+//	private final static String APP_URL = "https://eco.taobao.com/router/rest";
+//	private final static String SIGN_NAME = "51充电联盟"; //校信达
+//	private final static String SMS_TYPE = "normal";
+//
+//	/**
+//	 *
+//	 * @param phones 手机号,多个以英文逗号","隔开
+//	 * @param smsTemplateCode 短信模版ID
+//	 * @param jsonStr 短信模板变量,传参规则{"key":"value"},key的名字须和申请模板中的变量名一致,多个变量之间以逗号隔开。示例:针对模板“验证码${code},您正在进行${product}身份验证,打死不要告诉别人哦!”,传参时需传入{"code":"1234","product":"alidayu"}
+//	 * @return
+//	 */
+//	public static MessageResult send(String phones, String smsTemplateCode, String jsonStr){
+//
+//		boolean success = true;
+//		String msg = "发送成功";
+//
+//		TaobaoClient client = new DefaultTaobaoClient(APP_URL, APP_KEY, APP_SECRET);
+//		AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
+//		req.setSmsType(SMS_TYPE);
+//		req.setSmsFreeSignName(SIGN_NAME);
+//		if(jsonStr != null){
+//			req.setSmsParamString(jsonStr);
+//		}
+//		req.setRecNum(phones);
+//		req.setSmsTemplateCode(smsTemplateCode);
+//		AlibabaAliqinFcSmsNumSendResponse rsp;
+//		try {
+//			rsp = client.execute(req);
+//
+//			JSONObject ret = JSONObject.fromObject(rsp.getBody());
+//
+//			System.out.println("ret>>>>" + ret);
+//
+//			if(ret.containsKey("error_response")){
+//				success = false;
+//				msg = ret.getJSONObject("error_response").getString("sub_msg");
+//			}else if(ret.containsKey("alibaba_aliqin_fc_sms_num_send_response")){
+//
+//				JSONObject result = ret.getJSONObject("alibaba_aliqin_fc_sms_num_send_response").getJSONObject("result");
+//
+//				if(!result.getBoolean("success")){
+//					msg = result.getString("msg");
+//				}
+//			}else{
+//				success = false;
+//				msg = ret.toString();
+//			}
+//		} catch (ApiException e) {
+//			success = false;
+//			msg = e.getErrMsg();
+//		} catch (JSONException ex) {
+//			success = false;
+//			msg = ex.getMessage();
+//		}
+//
+//		MessageResult retMessage = new MessageResult();
+//
+//		retMessage.setMessage(msg);
+//		retMessage.setResult(success);
+//
+//		return retMessage;
+//	}
+//
+//	/**
+//	 *
+//	 * @param phones 手机号,多个以英文逗号","隔开
+//	 * @param signName 签名:目前仅支持"荆鹏云平台","速乐购"两种签名
+//	 * @param smsTemplateCode 短信模版ID
+//	 * @param json 短信模板变量,传参规则{"key":"value"},key的名字须和申请模板中的变量名一致,多个变量之间以逗号隔开。示例:针对模板“验证码${code},您正在进行${product}身份验证,打死不要告诉别人哦!”,传参时需传入{"code":"1234","product":"alidayu"}
+//	 * @return
+//	 */
+//	public static MessageResult send(String phones, String signName, String smsTemplateCode, JSONObject json){
+//
+//		boolean success = true;
+//		String msg = "发送成功";
+//
+//		TaobaoClient client = new DefaultTaobaoClient(APP_URL, APP_KEY, APP_SECRET);
+//		AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
+//		req.setSmsType(SMS_TYPE);
+//		req.setSmsFreeSignName(signName);
+//		if(json != null){
+//			req.setSmsParamString(json.toString());
+//		}
+//		req.setRecNum(phones);
+//		req.setSmsTemplateCode(smsTemplateCode);
+//		AlibabaAliqinFcSmsNumSendResponse rsp;
+//		try {
+//			rsp = client.execute(req);
+//
+//			JSONObject ret = JSONObject.fromObject(rsp.getBody());
+//
+//			System.out.println("ret>>>>" + ret);
+//
+//			if(ret.containsKey("error_response")){
+//				success = false;
+//				msg = ret.getJSONObject("error_response").getString("sub_msg");
+//			}else if(ret.containsKey("alibaba_aliqin_fc_sms_num_send_response")){
+//
+//				JSONObject result = ret.getJSONObject("alibaba_aliqin_fc_sms_num_send_response").getJSONObject("result");
+//
+//				if(!result.getBoolean("success")){
+//					msg = result.getString("msg");
+//				}
+//			}else{
+//				success = false;
+//				msg = ret.toString();
+//			}
+//		} catch (ApiException e) {
+//			success = false;
+//			msg = e.getErrMsg();
+//		} catch (JSONException ex) {
+//			success = false;
+//			msg = ex.getMessage();
+//		}
+//
+//		MessageResult retMessage = new MessageResult();
+//
+//		retMessage.setMessage(msg);
+//		retMessage.setResult(success);
+//
+//		return retMessage;
+//	}
+//
+//
+//
+//	public static String generateNumberString(int length) {
+//		StringBuffer sb = new StringBuffer();
+//		Random random = new Random();
+//		for (int i = 0; i < length; i++) {
+//			sb.append(NUMBERCHAR.charAt(random.nextInt(NUMBERCHAR.length())));
+//		}
+//		return sb.toString();
+//	}
+//
+//	public static void main(String[] args) {
+//		JSONObject verifyCodeJSON = new JSONObject();
+//		verifyCodeJSON.put("code", "66666");
+//
+//		SMSUtil.send("17261745051", "SMS_49390047", verifyCodeJSON.toString());
+//	}
+//}

+ 140 - 0
src/main/java/com/example/demo1/utils/Sign.java

@@ -0,0 +1,140 @@
+package com.example.demo1.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+public class Sign {
+
+    public static Map<String, String> sign(String jsapi_ticket, String url) {
+        Map<String, String> ret = new HashMap<String, String>();
+        String nonce_str = create_nonce_str();
+        String timestamp = create_timestamp();
+        String string1;
+        String signature = "";
+
+        //注意这里参数名必须全部小写,且必须有序
+        string1 = "jsapi_ticket=" + jsapi_ticket +
+                "&noncestr=" + nonce_str +
+                "&timestamp=" + timestamp +
+                "&url=" + url;
+
+        try {
+            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
+            crypt.reset();
+            crypt.update(string1.getBytes("UTF-8"));
+            signature = byteToHex(crypt.digest());
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        ret.put("url", url);
+        ret.put("jsapi_ticket", jsapi_ticket);
+        ret.put("nonceStr", nonce_str);
+        ret.put("timestamp", timestamp);
+        ret.put("signature", signature);
+
+        return ret;
+    }
+
+    private static String byteToHex(final byte[] hash) {
+        Formatter formatter = new Formatter();
+        for (byte b : hash) {
+            formatter.format("%02x", b);
+        }
+        String result = formatter.toString();
+        formatter.close();
+        return result;
+    }
+
+    private static String create_nonce_str() {
+        return UUID.randomUUID().toString();
+    }
+
+    private static String create_timestamp() {
+        return Long.toString(System.currentTimeMillis() / 1000);
+    }
+
+
+    public static String parkSign(Map<String, Object> map, String signKey) {
+
+
+        if (map == null) {
+            return null;
+        }
+        if (map.containsKey("sign")) {
+            map.remove("sign");
+        }
+
+        List<String> keyList = new ArrayList<String>(map.keySet());
+        Collections.sort(keyList);
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < keyList.size(); i++) {
+            String key = keyList.get(i);
+            Object value = map.get(key);
+            sb.append(key + "=" + value + "&");
+        }
+        String signStr = (sb.substring(0,
+                sb.length() - 1) + signKey).toLowerCase();
+        System.out.println("before sign: " + signStr);
+        String md5Str = MD5(signStr);
+        System.out.println("after sign: " + md5Str);
+        return md5Str;
+
+
+    }
+
+    /**
+     * 生成MD5
+     */
+    public static String
+
+    MD5(String s) {
+        return MD5(s, "utf-8");
+    }
+
+    /**
+     * 生成MD5
+     */
+    public static String
+
+    MD5(String s, String charset) {
+
+        try {
+            MessageDigest messagedigest =
+                    MessageDigest.getInstance("MD5");
+            messagedigest.reset();
+            byte abyte0[] = messagedigest.digest(s.getBytes(charset));
+            return byteToString(abyte0);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    private static String
+
+    byteToString(byte abyte0[]) {
+        int i = abyte0.length;
+        char ac[] = new char[i * 2];
+        int j = 0;
+        for (int k = 0; k < i; k++) {
+            byte byte0 = abyte0[k];
+            ac[j++] = hexDigits[byte0 >>> 4 & 0xf];
+            ac[j++] = hexDigits[byte0 & 0xf];
+        }
+        return new String(ac);
+    }
+
+    private static final char hexDigits[] =
+
+            {
+                    '0', '1', '2', '3', '4', '5',
+                    '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+            };
+}

+ 137 - 0
src/main/java/com/example/demo1/utils/StringUtils.java

@@ -0,0 +1,137 @@
+package com.example.demo1.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+
+import com.example.demo1.config.OSSConfig;
+import com.example.demo1.dto.Timeval;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/1 0001 上午 10:24
+ */
+@Component
+@Slf4j
+public final class StringUtils extends StrUtil {
+
+    @Autowired
+    private OSSConfig ossConfig;
+
+
+
+    @Autowired
+    private ValueOperations<String, Object> valueOperations;
+
+
+
+    /**
+     * 获取停车数据的时间
+     *
+     * @param timeval
+     * @return
+     */
+    public static String getAlarmInfoPlateTimeStr(Timeval timeval) {
+
+        String year = Convert.toStr(timeval.getDecyear());
+        String month = setTimeStr(Convert.toStr(timeval.getDecmon()));
+        String day = setTimeStr(Convert.toStr(timeval.getDecday()));
+        String hour = setTimeStr(Convert.toStr(timeval.getDechour()));
+        String min = setTimeStr(Convert.toStr(timeval.getDecmin()));
+        String sec = setTimeStr(Convert.toStr(timeval.getDecsec()));
+
+        return StringUtils.format("{}-{}-{} {}:{}:{}", year, month, day, hour, min, sec);
+    }
+
+    /**
+     * 要求外部订单号必须唯一。
+     *
+     * @return {String}
+     */
+    public synchronized static String getOutTradeNo() {
+        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
+        Date date = new Date();
+        String key = format.format(date);
+        Integer ran = (int) ((Math.random() * 9 + 1) * 100000);
+        key = key + ran.toString();
+        //	key = key.substring(0, 24);
+        return key;
+    }
+
+
+    private static String setTimeStr(String timeStr) {
+        if (timeStr.length() == 1) {
+            timeStr = "0" + timeStr;
+        }
+        return timeStr;
+    }
+
+    public static Integer similarity(String carNum1,String carNum2){
+
+        if (carNum1.length() != carNum2.length()){
+            return 0;
+        }
+        else if (carNum1.equals(carNum2)){
+            return 1;
+        }
+        else {
+            String simi = StrUtil.similar(carNum1,carNum2,1);
+            if (carNum1.length() == 7){
+                if (simi.equals("85.7%")){
+                    return 1;
+                }else {
+                    return 0;
+                }
+            }else {
+                if (simi.equals("87.5%")){
+                    return 1;
+                }else {
+                    return 0;
+                }
+            }
+        }
+    }
+
+    public static String getParkingTimeStr(Integer time) {
+
+        long sec = 1;
+        long min = 60 * sec;
+        long day = 24 * min;
+
+        StringBuilder sb = new StringBuilder();
+
+        /*if (time == 1){
+            sb.append(String.format("%d分钟", 1));
+        }else {*/
+            if (time >= day) {
+                sb.append(String.format("%d天", time / day));
+            }
+            long remainder = time % day;
+
+            if (remainder >= min) {
+                sb.append(String.format("%d小时", remainder / min));
+            }
+
+            remainder = remainder % min;
+
+            if (remainder >= sec) {
+                sb.append(String.format("%d分钟", remainder / sec));
+            }
+      //  }
+        return sb.toString();
+    }
+
+
+}

+ 422 - 0
src/main/java/com/example/demo1/utils/WeixinUtil.java

@@ -0,0 +1,422 @@
+package com.example.demo1.utils;
+
+import cn.hutool.core.date.DateTime;
+
+import com.example.demo1.dto.AccessToken;
+import com.example.demo1.dto.UserInfo;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONException;
+import net.sf.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 公众平台通用接口工具类
+ *
+ * @author lt
+ * @date 2013-08-09
+ */
+@Component
+public class WeixinUtil {
+	private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
+
+	private static StringUtils stringUtils;
+
+	public static final String send_template = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
+
+	// 获取access_token的接口地址(GET) 限200(次/天),可以在配置文件中修改
+	//public static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
+	public static String access_token_url = "http://ykt.xiaoxinda.com/weixin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
+
+	//获取微信的code
+	public static String code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
+	public static String getCodeRequest(String appid, String url,String scope){
+        String result = null;
+        String url_encode = "";
+        try {
+			url_encode = java.net.URLEncoder.encode(url, "utf-8");
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        result  = code.replace("APPID", appid).replace("REDIRECT_URI",url_encode).replace("SCOPE", scope);
+        return result;
+    }
+
+	//通过code换取网页授权access_token
+	public static String accessTokenurl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+	public static AccessToken getAccessToken(String appid, String appsecret, String code) throws Exception {
+        AccessToken accessToken = null;
+        String formatUrl = accessTokenurl.replace("APPID", appid).replace("SECRET",appsecret).replace("CODE", code);
+        JSONObject json  = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
+		if (!json.isNullObject() && !json.isEmpty()) {
+			try {
+				accessToken = new AccessToken();
+				accessToken.setToken(json.getString("access_token"));
+				accessToken.setExpiresIn(json.getInt("expires_in"));
+				accessToken.setOpenid(json.getString("openid"));
+				accessToken.setScope(json.getString("scope"));
+			} catch (Exception e) {
+
+				// 获取token失败
+				log.error("获取token失败,返回结果result={}", json);
+				if (json.getString("errcode").equals("40163")){
+					throw new Exception("请重新扫码");
+
+				}
+
+			}
+		}
+        return accessToken;
+    }
+
+	public static String jsAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
+	public static String getJsAPI(String accessToken){
+		String formatUrl = jsAccessTokenUrl.replace("ACCESS_TOKEN", accessToken);
+        JSONObject json  = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
+
+        if (!json.isNullObject() && !json.isEmpty()) {
+			try {
+				return json.getString("ticket");
+			} catch (Exception e) {
+				// 获取token失败
+				log.error("获取jsAPI失败,返回结果result={}", json);
+			}
+		}
+
+        return null;
+	}
+
+	/**
+	 * 获取access_token
+	 *
+	 * @param appid 凭证
+	 * @param appsecret 密钥
+	 * @return
+	 */
+	public static AccessToken getAccessToken(String appid, String appsecret) {
+		AccessToken accessToken = null;
+
+		String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
+		JSONObject jsonObject =HttpConnectionUtil.httpRequest(requestUrl, "GET", null);
+		// 如果请求成功
+		if (null != jsonObject) {
+			try {
+				accessToken = new AccessToken();
+				accessToken.setToken(jsonObject.getString("access_token"));
+				accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
+				//accessToken.setOpenid(jsonObject.getString("openid"));
+			} catch (JSONException e) {
+				accessToken = null;
+				// 获取token失败
+				log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
+			}
+		}
+		return accessToken;
+	}
+
+	// 获取用户信息
+	public static String user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
+	public static String subscribe_user_info_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN ";
+
+	public static UserInfo getUserInfo(String openid, String accessToken) {
+		// 拼装url
+		String url = user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);;
+
+		JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "GET", null);
+
+		UserInfo userInfo = null;
+		 if (null != jsonObject) {
+				try {
+					userInfo = new UserInfo();
+					userInfo.setOpenid(jsonObject.getString("openid").replaceAll("\"", ""));
+
+					userInfo.setNickname(jsonObject.getString("nickname").replaceAll("\"", ""));
+					userInfo.setCity(jsonObject.getString("city").replaceAll("\"", ""));
+					userInfo.setProvince(jsonObject.getString("province").replaceAll("\"", ""));
+					userInfo.setCountry(jsonObject.getString("country").replaceAll("\"", ""));
+					userInfo.setHeadimgurl(jsonObject.getString("headimgurl").replaceAll("\"", ""));
+				} catch (JSONException e) {
+					// 获取token失败
+					log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
+				}
+			}
+		return userInfo;
+	}
+
+	public static String checkSubscribe(String openid, String accessToken) {
+		// 拼装url
+		String url = subscribe_user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);;
+
+		JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "GET", null);
+
+		String subscribe = "";
+		if (null != jsonObject) {
+			try {
+				subscribe = jsonObject.getString("subscribe").replaceAll("\"", "");
+			} catch (JSONException e) {
+				// 获取token失败
+				log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
+			}
+		}
+		return subscribe;
+	}
+
+	public static boolean checkSignature(String token,String signature, String timestamp, String nonce) {
+		String[] arr = new String[] { token, timestamp, nonce };
+
+		String content = Arrays.stream(arr)
+				.sorted(Comparator.naturalOrder())
+				.collect(Collectors.joining());
+
+		MessageDigest md = null;
+		String tmpStr = null;
+
+		try {
+			md = MessageDigest.getInstance("SHA-1");
+			// 将三个参数字符串拼接成一个字符串进行sha1加密
+			byte[] digest = md.digest(content.getBytes("UTF-8"));
+
+			StringBuffer hexstr = new StringBuffer();
+
+			String shaHex = "";
+
+			for (int i = 0; i < digest.length; i++) {
+				shaHex = Integer.toHexString(digest[i] & 0xFF);
+				if (shaHex.length() < 2) {
+					hexstr.append(0);
+				}
+				hexstr.append(shaHex);
+			}
+
+			tmpStr = hexstr.toString();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
+		return signature.equals(tmpStr);
+	}
+
+	public static cn.hutool.json.JSONObject xmlToJson(ServletInputStream inputStream) throws Exception {
+		cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject();
+
+		// 创建sax解析工厂
+		SAXParserFactory factory = SAXParserFactory.newInstance();
+		// 创建sax转换工具
+		SAXParser saxParser = factory.newSAXParser();
+
+		saxParser.parse(inputStream,new DefaultHandler(){
+			private String tagName;
+
+			@Override
+			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+				tagName = qName;
+			}
+
+			@Override
+			public void endElement(String uri, String localName, String qName) throws SAXException {
+				tagName = null;
+			}
+
+			@Override
+			public void characters(char[] ch, int start, int length) throws SAXException {
+				if(tagName!=null){
+					String content = new String(ch,start,length);
+					jsonObject.put(tagName,content);
+				}
+			}
+		});
+
+		return jsonObject;
+	}
+	public static void replyTextMessage(HttpServletResponse response, String fromUserName, String toUserName, String content){
+		StringBuilder sb = new StringBuilder();
+
+		sb.append("<xml>");
+		sb.append("<ToUserName><![CDATA[" + toUserName + "]]></ToUserName>");
+		sb.append("<FromUserName><![CDATA["+ fromUserName + "]]></FromUserName>");
+		sb.append("<CreateTime>" + DateTime.now().getTime() + "</CreateTime>");
+		sb.append("<MsgType><![CDATA[text]]></MsgType>");
+		sb.append("<Content><![CDATA[" + content + "]]></Content>");
+		sb.append("</xml>");
+
+		try {
+			response.getWriter().print(sb.toString());
+			response.getWriter().close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static void replyArticlesMessage(HttpServletResponse response, String fromUserName, String toUserName, String title,String description,String picurl,String url){
+		StringBuilder sb = new StringBuilder();
+		sb.append("<xml>");
+		sb.append("<ToUserName><![CDATA[" + toUserName + "]]></ToUserName>");
+		sb.append("<FromUserName><![CDATA["+ fromUserName + "]]></FromUserName>");
+		sb.append("<CreateTime>" + DateTime.now().getTime() + "</CreateTime>");
+		sb.append("<MsgType><![CDATA[news]]></MsgType>");
+		sb.append("<ArticleCount>" + 1 + "</ArticleCount>");
+		sb.append("<Articles>");
+		sb.append("<item>");
+		sb.append("<Title><![CDATA["+title+"]]></Title> ");
+		sb.append("<Description><![CDATA["+description+"]]></Description>");
+		sb.append("<PicUrl><![CDATA["+picurl+"]]></PicUrl>");
+		sb.append("<Url><![CDATA["+url+"]]></Url>");
+		sb.append("</item>");
+		sb.append("</Articles>");
+		sb.append("</xml>");
+
+		try {
+			response.getWriter().print(sb.toString());
+			response.getWriter().close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+
+	/**
+	 * 创建微信菜单
+	 * @param appid
+	 * @param appSecret
+	 * @return
+	 */
+	public static String createMenu(String appid,String appSecret){
+		AccessToken token = WeixinUtil.getAccessToken(appid, appSecret);
+
+		System.out.println(token.getToken());
+
+		JSONObject data = new JSONObject();
+		JSONArray buttonArray = new JSONArray();
+
+		JSONObject button1 = new JSONObject();
+		button1.put("type", "view");
+		button1.put("name", "疫情监管");
+		button1.put("url", "http://wisdomhousewechat.sudaonline.net/prevention/");
+		buttonArray.add(button1);
+
+		JSONObject button2 = new JSONObject();
+		button2.put("type","view");
+		button2.put("name","智慧物业");
+		button2.put("url","http://wisdomhousewechat.sudaonline.net/#/home/?id=1");
+		buttonArray.add(button2);
+
+		JSONObject button3 = new JSONObject();
+		button3.put("type","click");
+		button3.put("name","关于系统");
+		button3.put("key","文章");
+		buttonArray.add(button3);
+
+		data.put("button", buttonArray);
+		data.put("action_name", "QR_LIMIT_STR_SCENE");
+
+		JSONObject actionInfo = new JSONObject();
+		JSONObject scene = new JSONObject();
+
+		scene.put("scene_str", "6");
+
+		actionInfo.put("scene", scene);
+
+		data.put("action_info", actionInfo);
+		System.out.println(data.toString());
+		//创建菜单
+		String result = HttpConnectionUtil.getHttpContentByPost(" https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token.getToken(), "utf-8", data.toString());
+
+		return result;
+	}
+
+	public static String sendTemplateMessage(String appId,String appSecret,String templateId, String openId,JSONObject sendData,String urlPath) {
+		String result = "";
+
+		try {
+			AccessToken accessToken = WeixinUtil.getAccessToken(appId, appSecret);
+
+			if (accessToken == null) {
+				throw new Exception("token无法获取");
+			}
+
+			//发送模版内容
+			String sendTemplateUrl = send_template.replace("ACCESS_TOKEN", accessToken.getToken());
+
+			JSONObject sendTemplateData = new JSONObject();
+
+			sendTemplateData.put("touser", openId);
+			sendTemplateData.put("template_id", templateId);
+			sendTemplateData.put("url", urlPath);
+			sendTemplateData.put("data", sendData);
+
+			URL url = new URL(sendTemplateUrl);
+			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+			conn.setRequestMethod("POST");
+			conn.setDoOutput(true);
+			conn.setDoInput(true);
+			conn.setUseCaches(false);
+			conn.setRequestProperty("Connection", "Keep-Alive");
+			conn.setRequestProperty("Charset", "UTF-8");
+
+			// 设置文件类型:
+			conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");
+
+			// 设置接收类型否则返回415错误
+			//conn.setRequestProperty("accept","*/*")此处为暴力方法设置接受所有类型,以此来防范返回415;
+			conn.setRequestProperty("accept","application/json");
+			conn.setConnectTimeout(5000);
+			conn.setReadTimeout(5000);
+
+			String dataStr = sendTemplateData.toString();
+
+			log.warn("发送数据:" + dataStr);
+			// 往服务器里面发送数据
+			byte[] buffer = dataStr.getBytes("UTF-8");
+
+			// 设置文件长度
+			conn.setRequestProperty("Content-Length", String.valueOf(buffer.length));
+			OutputStream output = conn.getOutputStream();
+			output.write(buffer);
+			output.flush();
+			output.close();
+
+			if (conn.getResponseCode() == 200) {
+				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
+
+				StringBuilder sb = new StringBuilder();
+				String line = "";
+
+				while ((line = reader.readLine()) != null) {
+					sb.append(line);
+				}
+
+				result = sb.toString();
+
+				log.warn("接收数据:" + result);
+
+				reader.close();
+			}
+		} catch (Exception ex) {
+			log.error(ex.getMessage(),ex);
+		}
+
+		return result;
+	}
+
+
+}

+ 236 - 0
src/main/java/com/example/demo1/utils/YsUtil.java

@@ -0,0 +1,236 @@
+package com.example.demo1.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.example.demo1.config.YsConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Component
+public class YsUtil {
+    @Autowired
+    private YsConfig ysConfig;
+
+    @Autowired
+    private ValueOperations<String,Object> valueOperations;
+
+    @Autowired
+    private RedisTemplate<String,Object> redisTemplate;
+
+    public final String TOKEN_PREFIX = "ys_token_";
+
+    public void removeToken(String appKey){
+        log.warn("删除token:" + appKey);
+        redisTemplate.delete(TOKEN_PREFIX + appKey);
+    }
+
+    public String getAccessToken(String appKey,String appSecret){
+        String accessToken = (String)valueOperations.get(TOKEN_PREFIX + appKey);
+
+        if(accessToken==null) {
+            log.warn("请求萤石云token,key=" + appKey);
+
+            try {
+                HttpClient httpClient = HttpClientBuilder.create().build();
+
+                HttpPost httpPost = new HttpPost(ysConfig.getTokenUrl());
+
+                RequestConfig requestConfig = RequestConfig.custom()
+                        .setSocketTimeout(3000)
+                        .setConnectTimeout(3000)
+                        .build();
+
+                httpPost.setConfig(requestConfig);
+
+                MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();
+
+                postBuilder.addTextBody("appKey",appKey, ContentType.MULTIPART_FORM_DATA);
+                postBuilder.addTextBody("appSecret", appSecret, ContentType.MULTIPART_FORM_DATA);
+
+                httpPost.setEntity(postBuilder.build());
+
+                HttpResponse httpResponse = httpClient.execute(httpPost);
+                HttpEntity httpEntity = httpResponse.getEntity();
+
+                String responseText = EntityUtils.toString(httpEntity);
+
+                log.warn("萤石云token返回:" + responseText);
+
+                JSONObject json = JSONObject.parseObject(responseText);
+
+                if (json.getString("code").equals("200")){
+                    JSONObject data = json.getJSONObject("data");
+
+                    long expireTime = data.getLong("expireTime");
+                    accessToken = data.getString("accessToken");
+
+                    valueOperations.set(TOKEN_PREFIX + appKey, accessToken, expireTime, TimeUnit.MICROSECONDS);
+                }
+            }
+            catch (Exception ex){
+                log.error(ex.getMessage(),ex);
+            }
+        }
+
+        return accessToken;
+    }
+
+    public JSONObject getLiveAddressUrl(String appKey,String appSecret,String deviceSerial,int channelNo,Long expireTime){
+        JSONObject data = null;
+
+        try {
+            HttpClient httpClient = HttpClientBuilder.create().build();
+
+            String accessToken = getAccessToken(appKey,appSecret);
+
+            HttpPost httpPost = new HttpPost(ysConfig.getLiveAddressUrl());
+
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setSocketTimeout(3000)
+                    .setConnectTimeout(3000)
+                    .build();
+
+            httpPost.setConfig(requestConfig);
+
+            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();
+
+            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("channelNo",String.valueOf(channelNo), ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("expireTime",String.valueOf(expireTime), ContentType.MULTIPART_FORM_DATA);
+
+            httpPost.setEntity(postBuilder.build());
+
+            HttpResponse httpResponse = httpClient.execute(httpPost);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            String responseText = EntityUtils.toString(httpEntity);
+
+            log.warn(responseText);
+
+            JSONObject json = JSONObject.parseObject(responseText);
+
+            if (json.getString("code").equals("200")){
+                data = json.getJSONObject("data");
+            }
+            else{
+                removeToken(appKey);
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+
+        return data;
+    }
+
+    public JSONObject getDeviceInfo(String appKey,String appSecret,String deviceSerial){
+        JSONObject data = null;
+
+        try {
+            HttpClient httpClient = HttpClientBuilder.create().build();
+
+            HttpPost httpPost = new HttpPost(ysConfig.getDeviceInfoUrl());
+
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setSocketTimeout(3000)
+                    .setConnectTimeout(3000)
+                    .build();
+
+            httpPost.setConfig(requestConfig);
+
+            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();
+
+            String accessToken = getAccessToken(appKey,appSecret);
+
+            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);
+
+            httpPost.setEntity(postBuilder.build());
+
+            HttpResponse httpResponse = httpClient.execute(httpPost);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            String responseText = EntityUtils.toString(httpEntity);
+
+            log.warn(responseText);
+
+            JSONObject json = JSONObject.parseObject(responseText);
+
+            if (json.getString("code").equals("200")){
+                data = json.getJSONObject("data");
+            }
+            else{
+                removeToken(appKey);
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+
+        return data;
+    }
+
+    public String capturePicture(String appKey,String appSecret,String deviceSerial,int channelNo) {
+        String picUrl = "";
+
+        try {
+            HttpClient httpClient = HttpClientBuilder.create().build();
+
+            HttpPost httpPost = new HttpPost(ysConfig.getDeviceCaptureUrl());
+
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setSocketTimeout(3000)
+                    .setConnectTimeout(3000)
+                    .build();
+
+            httpPost.setConfig(requestConfig);
+
+            MultipartEntityBuilder postBuilder = MultipartEntityBuilder.create();
+
+            String accessToken = getAccessToken(appKey,appSecret);
+
+            postBuilder.addTextBody("accessToken", accessToken, ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("deviceSerial",deviceSerial, ContentType.MULTIPART_FORM_DATA);
+            postBuilder.addTextBody("channelNo",String.valueOf(channelNo), ContentType.MULTIPART_FORM_DATA);
+
+            httpPost.setEntity(postBuilder.build());
+
+            HttpResponse httpResponse = httpClient.execute(httpPost);
+            HttpEntity httpEntity = httpResponse.getEntity();
+
+            String responseText = EntityUtils.toString(httpEntity);
+
+            log.warn(responseText);
+
+            JSONObject json = JSONObject.parseObject(responseText);
+
+            if (json.getString("code").equals("200")){
+                JSONObject data = json.getJSONObject("data");
+                picUrl = data.getString("picUrl");
+            }
+            else{
+                removeToken(appKey);
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+
+        return picUrl;
+    }
+}

+ 62 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,62 @@
+spring:
+  datasource:
+    url: jdbc:log4jdbc:mysql://127.0.0.1:3306/charging_parking?autoReconnect=true&characterEncoding=utf8&serverTimezone=GMT%2B8
+    username: root
+    password: root
+  devtools:
+    add-properties: false
+    restart:
+      enabled: true
+  redis:
+    # Redis数据库索引(默认为0)
+    database: 3
+    # Redis服务器地址
+    host: 127.0.0.1
+  rabbitmq:
+    virtual-host: housekeeper-dev
+logger:
+  level: INFO
+  dir: "D:\\logs\\demo1"
+
+
+parking:
+  userName: system
+  ip: http://120.78.14.85
+  interfaceUrl : http://S.appykt.com
+  fileUrl: /data/docker/tomcat8/jp-housekeeper/file
+
+
+wx:
+  pay:
+    appId: wx907e84ad32e6e142
+    appSecret: 1d891ee3f4cc8002ff0330d1e04acf2c
+    #充电联盟工作号
+    subAppId: wx3afdb1b60188c1e5
+    subAppSecret: d8850c70659fe4ed71d3476f556eda03
+    mchId: 1509055881
+    #subMchId: 1523544111
+    #湖北荆鹏软件开发有限公司
+    subMchId: 1621835993
+    mchKey: xxd33333333333333333333333333333
+    notifyUrl: http://18891j25i6.iok.la/charging-parking/wxPay/parkingWxPayNotify
+    refundUrl: https://charging.xiaoxinda.com/charging-station-server/wxPay/wxJsapiRefundNotify
+    ip: 101.37.31.116
+    certPath: C:\Users\Administrator\Desktop\cert\xiaoxinda\apiclient_cert.p12
+    temporaryUrl: https://charging.xiaoxinda.com/charging-station-server/wxPay/wxJsapiPayTemporaryNotify
+    urlKey: F1
+
+#可用支付环境
+alipay:
+  serviceUrl: https://openapi.alipay.com/gateway.do
+  #校信达
+  appId: 2018070260539153
+  publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzMBfmTqqpt4dMcuz8DpyrEtruu/G7+Gvkd0j99QX4mzcRLx4Wg9IicOIiZGSdgzLMKIxBmk0eKiqqbuBjOsrS/XU+SvsTNlT1O/ZY0w30HEWrb/pvmo58HSY76cevWqLqW19+fUax7HG811mF4lq4YkHNAWArqByEjoFYbKHbtqS0ReXFJ9SE5TaqZSVOieiu3bYPkw5HEGmnYZMhWH3Gvt6tK2peLSM8mEMY5qp3zlGew3sq1KtcDkvO2UCuAmEkAnCDZ1zoYYt45cvcmwaHozGKHGOtOe0EAitpZyLZW3dP5/yBFfWk+MdaA1kZe5gNr8ePY5ht+Sd+DizMEINiQIDAQAB
+  privateKey: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsORLetI9grCmAToY6cpCEFeXIN5dFmqYLWaAPwnEIH/EJptA5uzSIAAIydK8+skZfOLlmIscCHdZWgSvFnLLtOEt1CMjtwQPO7Q8lFBkEaEp8QYgsgOCyHV1TBSWgLk3QHgdTP6teLKfZ2DGaCdbQyqKC+Z3NnPJjYww/J3nxb6LsSBchV+uRD9BYrv4d1341t4KE6N1QCQtMHrpRER3hLMWqzfusKpRrp/eu8g5sAG8p9twY6JMnBg+fHa5EgqBS2MlzA0v1p4DR3hc700CZ6aIoBi7AUhVTbxk8iEfUe3F20S3QTuYLni+tNXpwQDJcUgxDpOPJ2RRDCoyYf40HAgMBAAECggEAWxm5tJqYeU+4iEmBUWuGrIgUy4s0droueTSIqa12MxEKZMubu94eFI7EmsIEbUrKVNZho/hjgugbmBit+dNBBqDPsXHbL4D5Lb1SVI/ECAPO2tmjWb82nKFR23eOhqPXv24S++NjF+bRRzfITS5FNp7pxhSad8g8o3wiX0nXhHFlRbgYBmPS5jl/Y4G341iXo09/EoXG3UfEdauPQZhjpKT4MYKZDafVsIxEhEili69ZIok7R+c5TgR8i3fMhiYf+FWepv8v01kvh6knEWhz7ipuad6N0NMgyljMHw1FwhjEXpaLoqN8kJphs3vzsSuUUAtLGuQUymZWQaKtQBZvIQKBgQDjj+PaDmzCwSlBtoPKR+YgIqVkGo761hOe4QiUkit+bE6+ytiPc/gjdhgnZkVE0in3xdPCtjWt6m6q21/x44VHHhsehz38DvAL994yT77WTgYwg3GAebscRVJnq+3qJ6a5tvB+nv7MC4uCk0tfJF9PT26ZuSYf0q0gn42dktUKEQKBgQDBvsm0P96S8ybIjOhp622mRDqL3neAUC/hqNQbpl49gfaD5EIOLOvyIl022AAYA9QzXZd5OoImBuKX+g1MB+IIOyk9CM7W6K5LCpmAjB0efVFjW+UbsJK44ybfmel4dqlSn3mUZm+4fn1G93IsRcbeGwDUVUnE2wGPQNpoeFfNlwKBgDtebOmU3dcpoePdBCEgBO/ZWiD1tNvIQjIvL5fjUqmXBCxOq5UxgkluI/sTeXrtAbn8yLSB6RtIkDrPJQbsfvcA6b5bNlauZv4YWsXxfC5ZCNBbWp9UIvbLNyaI+ncehSbqjW/bd0owsOMOHpnh2WPNq2M7pLCkvDpIph+4ERChAoGAZeuj2DqxL8TR5jaaHP5IlGrYEbRaURnd1mwmCNWgReMUd5WgWiyvgpUpTCydAAUjoFHf2Vo6FR8SHLjiPdj3wzS8IOt9Q/jrl3ZgAguzVdK++fHhuItO5Aw66u3gsApcUKasIrEwnHGOHcMWQMwELdsuuISVZgV/8IhBXSvRpMkCgYBC8tjKcalhwCORlCzOLaT6eA9mPCCuST2sAgR3/4jcDh6aC8VIJu0SIL+rCbkLKtk+jhpW1mRi571E1Ic06engC6719aN/y0Hu45MVTGP9VMVd460ym/4eDXT6jQ4i56b5kMuWh+NixguKHAz+W+h4ltnPGQHpEmm54ZR/yRSbag==
+  zfbPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3gaIrAD47mfSBmye1c8GLIRF4H3sl0MhT1OHIO0FqwtDqyxpHkrpOQADQggEzgv1nO82V+ChQxHUeaQ7W987+s1cnwtm7ZVML8DxVtji1va1ahBKL62dBommOoIt4fRIO2upbnF6r3NjB/3MCTZUIE03xIqc+aUeNdRO7eAMpm6sHjBfSimFwXlyTaEsAsnTK4hkOzdvoldHry6A3375kE3msj8Z48Nko7AFedOToPfJNolap+i7qWv3VOhnWLrAZH/Jgq/uHQmx8r29BeBl9AT4EwxDN5mVVKDOYsWW1efmrhKXO3wvzInhB6qQ8L1uBCWKhw1eGHCvlCjTHxBYQIDAQAB
+  inputCharset: UTF-8
+  mchId: 2088511854331096
+  #荆鹏开发
+  appAuthToken: 202205BBb8c1351b9a09492bab4259fb45fa3X21
+  signType: RSA2
+  format: json
+  notifyUrl: http://18891j25i6.iok.la/charging-parking/aliPay/payNotify

+ 131 - 1
src/main/resources/application.yml

@@ -2,4 +2,134 @@ server:
   port: 8088
   servlet:
     context-path: /demo1
-
+jwt:
+  secret: WJgLLiAktNj/vCNEoz6mfAmE0btwluCTk/TnJiZOIkQ=
+  header: Authorization
+#萤石云摄像头
+ys:
+  freeAppKey: "4ba471c7d468491c981fa04fa3daf4ea"
+  freeAppSecret: "0a12b82dac82d901ba318b137ae307aa"
+  payAppKey: "3b888cc9bebe4ce3b073f16e8a49be27"
+  payAppSecret: "7f6f43fb42c912654c3a52b4da9c1083"
+  tokenUrl: "https://open.ys7.com/api/lapp/token/get"
+  liveAddressUrl: "https://open.ys7.com/api/lapp/live/address/limited"
+  deviceInfoUrl: "https://open.ys7.com/api/lapp/device/info"
+  deviceCaptureUrl: "https://open.ys7.com/api/lapp/device/capture"
+oss:
+  accessKeyId: LTAIXIyrXmjgOXQa
+  accessKeySecret: B0RS3zHLct8OKKIDu2HREaVx6RXgWL
+  endpoint: http://oss-cn-hangzhou.aliyuncs.com
+  bucketName: rccs
+  urlPrefix: http://oss.xiaoxinda.com
+  objectPre: charging
+spring:
+  main:
+    allow-circular-references: true
+  servlet:
+    multipart:
+      max-request-size: 20MB
+      max-file-size: 20MB
+  datasource:
+    driver-class-name: net.sf.log4jdbc.DriverSpy
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      # 连接池的配置信息
+      # 初始化大小,最小,最大
+      initial-size: 5
+      min-idle: 5
+      maxActive: 50
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+      timeBetweenEvictionRunsMillis: 60000
+      # 配置一个连接在池中最小生存的时间,单位是毫秒
+      minEvictableIdleTimeMillis: 300000
+      validationQuery: SELECT 1
+      testWhileIdle: true
+      # 获取连接时检测连接是否可用
+      testOnBorrow: true
+      testOnReturn: false
+      # 打开PSCache,并且指定每个连接上PSCache的大小(PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。)
+      poolPreparedStatements: false
+      maxPoolPreparedStatementPerConnectionSize: 20
+      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+      filters: stat,wall
+      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+      connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+      # 配置DruidStatFilter
+      web-stat-filter:
+        enabled: true
+        url-pattern: "/*"
+        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+      # 配置DruidStatViewServlet
+      stat-view-servlet:
+        enabled: true
+        url-pattern: "/druid/*"
+        # IP白名单(没有配置或者为空,则允许所有访问)
+        allow:
+        # IP黑名单 (存在共同时,deny优先于allow)
+        deny:
+        #  禁用HTML页面上的“Reset All”功能
+        reset-enable: false
+        # 登录名
+        login-username: admin
+        # 登录密码
+        login-password: jpsoft
+  devtools:
+    restart:
+      enabled: true
+  profiles:
+    active: "@active.profile@"
+  redis:
+    # Redis数据库索引(默认为0)
+    database: 4
+    # Redis服务器地址
+    host: 127.0.0.1
+    #host: 127.0.0.1
+    # Redis服务器连接端口
+    port: 6379
+    # Redis服务器连接密码(默认为空)
+    password:
+    #password: 123456
+    # 连接池最大连接数(使用负值表示没有限制)
+    pool:
+      max-active: 8
+      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-wait: -1
+      # 连接池中的最大空闲连接
+      max-idle: 8
+      # 连接池中的最小空闲连接
+      min-idle: 0
+      # 连接超时时间(毫秒)
+      timeout: 0
+  rabbitmq:
+    #    host: 119.36.146.59
+    host: 192.168.33.20
+    port: 5672
+    username: admin
+    password: admin
+    #虚拟host 可以不设置,使用server默认host
+    virtual-host: devmq
+  thymeleaf:
+    cache: false
+    mode: HTML
+    prefix: classpath:/templates/
+    suffix: .html
+    encoding: UTF-8
+    servlet:
+      content-type: text/html; charset=utf-8
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  web:
+    resources:
+      static-locations: classpath:/static/
+mybatis-plus:
+  global-config:
+    db-config:
+      # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
+      logic-delete-field: delFlag
+      # 逻辑已删除值(默认为 1)
+      logic-delete-value: 1
+      # 逻辑未删除值(默认为 0)
+      logic-not-delete-value: 0