竺森洋 пре 1 година
родитељ
комит
ebb176931a
72 измењених фајлова са 6003 додато и 0 уклоњено
  1. 658 0
      pom.xml
  2. 29 0
      src/main/java/cn/com/jdkj/BobiLeisureApplication.java
  3. 9 0
      src/main/java/cn/com/jdkj/annotation/CheckSign.java
  4. 15 0
      src/main/java/cn/com/jdkj/annotation/CheckSignInject.java
  5. 32 0
      src/main/java/cn/com/jdkj/annotation/IgnoreSwaggerParameter.java
  6. 10 0
      src/main/java/cn/com/jdkj/annotation/LogIgnore.java
  7. 31 0
      src/main/java/cn/com/jdkj/annotation/LogInject.java
  8. 12 0
      src/main/java/cn/com/jdkj/annotation/OutServer.java
  9. 17 0
      src/main/java/cn/com/jdkj/annotation/Rename.java
  10. 12 0
      src/main/java/cn/com/jdkj/annotation/StarPermissionCheck.java
  11. 11 0
      src/main/java/cn/com/jdkj/annotation/TokenIgnore.java
  12. 9 0
      src/main/java/cn/com/jdkj/annotation/XingZhanServer.java
  13. 19 0
      src/main/java/cn/com/jdkj/annotation/sys/SysManageLog.java
  14. 117 0
      src/main/java/cn/com/jdkj/aspect/CheckSignAspect.java
  15. 148 0
      src/main/java/cn/com/jdkj/aspect/LogAspect.java
  16. 49 0
      src/main/java/cn/com/jdkj/aspect/LogMdcAspect.java
  17. 161 0
      src/main/java/cn/com/jdkj/config/DruidSqlLogFilter.java
  18. 60 0
      src/main/java/cn/com/jdkj/config/FrontInterceptor.java
  19. 66 0
      src/main/java/cn/com/jdkj/config/Knife4jConfiguration.java
  20. 77 0
      src/main/java/cn/com/jdkj/config/MultiDataSourceConfiguration.java
  21. 54 0
      src/main/java/cn/com/jdkj/config/MybatisConfig.java
  22. 103 0
      src/main/java/cn/com/jdkj/config/MybatisPlusConfig.java
  23. 83 0
      src/main/java/cn/com/jdkj/config/MybatisPlusMetaObjectHandler.java
  24. 124 0
      src/main/java/cn/com/jdkj/config/RedisConfiguration.java
  25. 52 0
      src/main/java/cn/com/jdkj/config/RedissonConfig.java
  26. 21 0
      src/main/java/cn/com/jdkj/config/ScheduleConfig.java
  27. 23 0
      src/main/java/cn/com/jdkj/config/SeafoodMybatisProperties.java
  28. 33 0
      src/main/java/cn/com/jdkj/config/Swagger2Config.java
  29. 68 0
      src/main/java/cn/com/jdkj/config/WebMvcConfig.java
  30. 20 0
      src/main/java/cn/com/jdkj/constant/RedisConstant.java
  31. 351 0
      src/main/java/cn/com/jdkj/constant/ReturnCode.java
  32. 7 0
      src/main/java/cn/com/jdkj/constant/TokenKey.java
  33. 49 0
      src/main/java/cn/com/jdkj/customer/controller/CustomerController.java
  34. 15 0
      src/main/java/cn/com/jdkj/customer/dto/AIBodyDto.java
  35. 13 0
      src/main/java/cn/com/jdkj/customer/dto/AIMessageDto.java
  36. 14 0
      src/main/java/cn/com/jdkj/customer/dto/LoginDto.java
  37. 14 0
      src/main/java/cn/com/jdkj/customer/dto/QuestionDto.java
  38. 14 0
      src/main/java/cn/com/jdkj/customer/dto/RegisterDto.java
  39. 27 0
      src/main/java/cn/com/jdkj/customer/entity/Customer.java
  40. 9 0
      src/main/java/cn/com/jdkj/customer/mapper/CustomerMapper.java
  41. 8 0
      src/main/java/cn/com/jdkj/customer/service/BaiduService.java
  42. 17 0
      src/main/java/cn/com/jdkj/customer/service/CustomerService.java
  43. 65 0
      src/main/java/cn/com/jdkj/customer/service/imp/BaiduServiceImpl.java
  44. 145 0
      src/main/java/cn/com/jdkj/customer/service/imp/CustomerServiceImpl.java
  45. 15 0
      src/main/java/cn/com/jdkj/customer/vo/AIResponseBodyVo.java
  46. 9 0
      src/main/java/cn/com/jdkj/customer/vo/AiMessageVo.java
  47. 12 0
      src/main/java/cn/com/jdkj/customer/vo/ChoiceVo.java
  48. 10 0
      src/main/java/cn/com/jdkj/customer/vo/UsageVo.java
  49. 37 0
      src/main/java/cn/com/jdkj/entity/ResultBean.java
  50. 15 0
      src/main/java/cn/com/jdkj/enums/AIMessageTypeEnums.java
  51. 23 0
      src/main/java/cn/com/jdkj/enums/ReturnCode.java
  52. 37 0
      src/main/java/cn/com/jdkj/exception/CustomException.java
  53. 36 0
      src/main/java/cn/com/jdkj/exception/GlobalExceptionHandler.java
  54. 56 0
      src/main/java/cn/com/jdkj/handler/JsonLongArrayTypeHandler.java
  55. 56 0
      src/main/java/cn/com/jdkj/handler/JsonStringArrayTypeHandler.java
  56. 37 0
      src/main/java/cn/com/jdkj/handler/LocalDateTimeTypeHandler.java
  57. 145 0
      src/main/java/cn/com/jdkj/interceptor/BodyReaderHttpServletRequestWrapper.java
  58. 61 0
      src/main/java/cn/com/jdkj/interceptor/FrontInterceptor.java
  59. 99 0
      src/main/java/cn/com/jdkj/util/DateUtils.java
  60. 56 0
      src/main/java/cn/com/jdkj/util/SpringUtils.java
  61. 285 0
      src/main/java/cn/com/jdkj/util/StringUtils.java
  62. 120 0
      src/main/java/cn/com/jdkj/util/WeiXinUtils.java
  63. 53 0
      src/main/resources/bootstrap-debug1.yml
  64. 273 0
      src/main/resources/bootstrap-dev.yml
  65. 312 0
      src/main/resources/bootstrap-dev1.yml
  66. 152 0
      src/main/resources/bootstrap-dev2.yml
  67. 313 0
      src/main/resources/bootstrap-devLocal.yml
  68. 320 0
      src/main/resources/bootstrap-prod.yml
  69. 34 0
      src/main/resources/bootstrap-rel.yml
  70. 320 0
      src/main/resources/bootstrap-test1.yml
  71. 207 0
      src/main/resources/bootstrap.yml
  72. 39 0
      src/main/resources/logback-spring.xml

+ 658 - 0
pom.xml

@@ -0,0 +1,658 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>cn.com.jdkj</groupId>
+    <artifactId>little-scholar</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <packaging>jar</packaging>
+    <description>小书童</description>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.6.RELEASE</version>
+        <relativePath /> <!-- lookup parent from repository -->
+    </parent>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
+        <swagger.version>3.0.0</swagger.version>
+        <knife4j.version>2.0.9</knife4j.version>
+    </properties>
+
+    <dependencies>
+        <!--<dependency>-->
+        <!--<groupId>org.mybatis.spring.boot</groupId>-->
+        <!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
+        <!--<version>1.3.1</version>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+            <version>2.2.5.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+            <version>2.2.5.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper</artifactId>
+            <version>5.3.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.30</version>
+        </dependency>
+        <!-- druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.9</version>
+        </dependency>
+        <!-- swagger2 -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.9.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.9.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.5.21</version>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+            <version>1.5.21</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>2.0.8</version>
+        </dependency>
+        <!--<dependency>-->
+        <!--<groupId>io.springfox</groupId>-->
+        <!--<artifactId>springfox-swagger2</artifactId>-->
+        <!--<version>${swagger.version}</version>-->
+        <!--</dependency>-->
+
+        <!--<dependency>-->
+        <!--<groupId>io.springfox</groupId>-->
+        <!--<artifactId>springfox-swagger-ui</artifactId>-->
+        <!--<version>${swagger.version}</version>-->
+        <!--</dependency>-->
+        <!--<dependency>-->
+        <!--<groupId>io.springfox</groupId>-->
+        <!--<artifactId>springfox-swagger2</artifactId>-->
+        <!--<version>${swagger.version}</version>-->
+        <!--</dependency>-->
+        <!--<dependency>-->
+        <!--<groupId>io.springfox</groupId>-->
+        <!--<artifactId>springfox-oas</artifactId>-->
+        <!--<version>3.0.0</version>-->
+        <!--</dependency>-->
+        <!--&lt;!&ndash;knife4j spring ui &ndash;&gt;-->
+        <!--<dependency>-->
+        <!--<groupId>com.github.xiaoymin</groupId>-->
+        <!--<artifactId>knife4j-spring-ui</artifactId>-->
+        <!--<version>${knife4j.version}</version>-->
+        <!--</dependency>-->
+        <!--&lt;!&ndash;knife4j是为Java MVC框架集成Swagger生成Api文档的增强&ndash;&gt;-->
+        <!--<dependency>-->
+        <!--<groupId>com.github.xiaoymin</groupId>-->
+        <!--<artifactId>knife4j-micro-spring-boot-starter</artifactId>-->
+        <!--<version>${knife4j.version}</version>-->
+        <!--</dependency>-->
+        <!--&lt;!&ndash;webflux 相关包&ndash;&gt;-->
+        <!--<dependency>-->
+        <!--<groupId>org.springframework</groupId>-->
+        <!--<artifactId>spring-webflux</artifactId>-->
+        <!--<scope>provided</scope>-->
+        <!--</dependency>-->
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.32</version>
+        </dependency>
+        <!-- For log4j -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.7</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- Redis -->
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+
+        <!-- EXCEL -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.17</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.17</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.0.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv</artifactId>
+            <version>0.8</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
+        <dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>1.10.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>3.10.7</version>
+            <!--			<exclusions>-->
+            <!--				<exclusion>-->
+            <!--					<groupId>org.redisson</groupId>-->
+            <!--					<artifactId>redisson-spring-data-21</artifactId>-->
+            <!--				</exclusion>-->
+            <!--			</exclusions>-->
+        </dependency>
+        <!--		<dependency>-->
+        <!--			<groupId>org.redisson</groupId>-->
+        <!--			<artifactId>redisson-spring-data-20</artifactId>-->
+        <!--			<version>3.10.7</version>-->
+        <!--		</dependency>-->
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-redis</artifactId>
+            <version>2.3.0.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!--		<dependency>-->
+        <!--			<groupId>redis.clients</groupId>-->
+        <!--			<artifactId>lettuce</artifactId>-->
+        <!--		</dependency>-->
+        <!--		<dependency>-->
+        <!--			<groupId>org.apache.commons</groupId>-->
+        <!--			<artifactId>commons-pool2</artifactId>-->
+        <!--			<version>2.0</version>-->
+        <!--		</dependency>-->
+
+        <!-- oss -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>2.8.1</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>commons-lang</artifactId>
+                    <groupId>commons-lang</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- 阿里云cos -->
+
+        <dependency>
+            <groupId>com.qcloud</groupId>
+            <artifactId>cos_api</artifactId>
+            <version>5.6.97</version>
+        </dependency>
+        <!-- 图片压缩-->
+        <dependency>
+            <groupId>net.coobird</groupId>
+            <artifactId>thumbnailator</artifactId>
+            <version>0.4.8</version>
+        </dependency>
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-s3</artifactId>
+            <version>1.11.543</version>
+        </dependency>
+        <!-- oss end -->
+        <!-- feign -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <version>2.2.0.RELEASE</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jsr305</artifactId>
+                    <groupId>com.google.code.findbugs</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>HdrHistogram</artifactId>
+                    <groupId>org.hdrhistogram</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>commons-io</artifactId>
+                    <groupId>commons-io</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- feign end -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.rocketmq</groupId>
+            <artifactId>rocketmq-client</artifactId>
+            <version>3.2.6</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>fastjson</artifactId>
+                    <groupId>com.alibaba</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.18</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.datahub</groupId>
+            <artifactId>aliyun-sdk-datahub</artifactId>
+            <version>2.13.1-public</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>slf4j-log4j12</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- sharding jdbc -->
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
+            <version>4.1.1</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>commons-collections4</artifactId>
+                    <groupId>org.apache.commons</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!--<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId>
+            </dependency> -->
+        <!--sharding jdbc end -->
+        <!-- guava -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>30.1-jre</version>
+        </dependency>
+        <!-- guava -->
+        <!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-spring-boot-starter</artifactId>
+            <version>1.30.0</version>
+        </dependency>
+        <!-- 提供Redis连接池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <!-- Sa-Token end -->
+        <!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-dao-redis-jackson</artifactId>
+            <version>1.30.0</version>
+        </dependency>
+        <!-- dynamic-datasource-spring-boot-starter -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <!-- dynamic end -->
+        <!-- sqljdbc4 -->
+        <!--<dependency>-->
+        <!--<groupId>com.microsoft.sqlserver</groupId>-->
+        <!--<artifactId>sqljdbc4</artifactId>-->
+        <!--<version>4.0</version>-->
+        <!--</dependency>-->
+        <!-- sqljdbc4 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15to18</artifactId>
+            <version>1.68</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.11</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf.tool</groupId>
+            <artifactId>xmlworker</artifactId>
+            <version>5.5.11</version>
+        </dependency>
+        <!-- 支持中文 -->
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext-asian</artifactId>
+            <version>5.2.0</version>
+        </dependency>
+        <!-- 微信支付-->
+        <!--https://gitee.com/binary/weixin-java-tools?_from=gitee_search-->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-pay</artifactId>
+            <version>4.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>4.4.0</version>
+        </dependency>
+        <!-- SSOTOKEN -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>kisso</artifactId>
+            <version>3.7.0</version>
+        </dependency>
+        <!--Groovy脚本依赖-->
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy</artifactId>
+            <version>2.5.14</version>
+        </dependency>
+
+
+        <!-- mybatis plus -->
+        <dependency>
+            <groupId>org.mybatis</groupId>
+            <artifactId>mybatis-typehandlers-jsr310</artifactId>
+            <version>1.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-core</artifactId>
+            <version>3.5.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+            <version>3.5.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.9.124.ALL</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+        <!--华为云obs-->
+        <dependency>
+            <groupId>com.huaweicloud</groupId>
+            <artifactId>esdk-obs-java-bundle</artifactId>
+            <version>3.23.9.1</version>
+        </dependency>
+        <!-- 阿里云短信 -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>alibabacloud-dysmsapi20170525</artifactId>
+            <version>2.0.24</version>
+        </dependency>
+
+        <!--ffmpeg-->
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv</artifactId>
+            <version>1.4.4</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.bytedeco</groupId>
+                    <artifactId>javacpp</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>flycapture</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libdc1394</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libfreenect</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libfreenect2</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>librealsense</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>videoinput</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>opencv</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>tesseract</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>leptonica</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>flandmark</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>artoolkitplus</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv-platform</artifactId>
+            <version>1.4.4</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.bytedeco</groupId>
+                    <artifactId>javacv</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>flycapture-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libdc1394-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libfreenect-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>libfreenect2-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>librealsense-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>videoinput-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>opencv-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>tesseract-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>leptonica-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>flandmark-platform</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.bytedeco.javacpp-presets</groupId>
+                    <artifactId>artoolkitplus-platform</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+    <repositories>
+        <repository>
+            <!--<id>clojars</id>-->
+            <!--<url>http://clojars.org/repo/</url>-->
+            <id>alimaven</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+        </repository>
+    </repositories>
+    <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>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+            </plugin>
+            <!-- mybatis generate 插件生成实体类和dao -->
+            <plugin>
+                <groupId>org.mybatis.generator</groupId>
+                <artifactId>mybatis-generator-maven-plugin</artifactId>
+                <version>1.3.5</version>
+                <configuration>
+                    <overwrite>true</overwrite>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>mysql</groupId>
+                        <artifactId>mysql-connector-java</artifactId>
+                        <version>5.1.43</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.yml</include>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                    <include>**/*.json</include>
+                    <include>**/*.p12</include>
+                    <include>**/*.pem</include>
+                </includes>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+    </build>
+</project>

+ 29 - 0
src/main/java/cn/com/jdkj/BobiLeisureApplication.java

@@ -0,0 +1,29 @@
+package cn.com.jdkj;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@EnableTransactionManagement
+@EnableDiscoveryClient
+@EnableFeignClients
+@EnableAsync
+@ServletComponentScan
+@SpringBootApplication
+@MapperScan(basePackages = {"cn.com.jdkj.customer.mapper"})
+@EnableSwagger2
+public class BobiLeisureApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(BobiLeisureApplication.class, args);
+    }
+}

+ 9 - 0
src/main/java/cn/com/jdkj/annotation/CheckSign.java

@@ -0,0 +1,9 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface CheckSign {
+}

+ 15 - 0
src/main/java/cn/com/jdkj/annotation/CheckSignInject.java

@@ -0,0 +1,15 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author duanzhibin
+ * @Description:
+ * @date 2021/1/12 13:59
+ **/
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface CheckSignInject {
+
+}

+ 32 - 0
src/main/java/cn/com/jdkj/annotation/IgnoreSwaggerParameter.java

@@ -0,0 +1,32 @@
+package cn.com.jdkj.annotation;
+/**
+ * @Title: IgnoreSwaggerParameter.java
+ * @Package com.birdsh.paradise.annotation
+ * @Description:
+ * Copyright: Copyright (c) 2018
+ * Website: www.panzhijie.cn
+ *
+ * @Author yangy
+ * @DateTime 2022年4月12日 下午7:47:32
+ * @version V1.0
+ */
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @ClassName: IgnoreSwaggerParameter
+ * @Description:
+ * @Author yangy
+ * @DateTime 2022年4月12日 下午7:47:32
+ */
+
+//swagger忽略的参数
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface IgnoreSwaggerParameter {
+
+}

+ 10 - 0
src/main/java/cn/com/jdkj/annotation/LogIgnore.java

@@ -0,0 +1,10 @@
+package cn.com.jdkj.annotation;
+
+/**
+ * 日志打印忽略
+ *
+ * @author chenc
+ * @date 2021年10月20日15:38:49
+ */
+public @interface LogIgnore {
+}

+ 31 - 0
src/main/java/cn/com/jdkj/annotation/LogInject.java

@@ -0,0 +1,31 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface LogInject {
+    /**
+     * 操作内容
+     * @return
+     */
+    String value() default "";
+
+    /**
+     * 操作备注
+     * @return
+     */
+    String memo() default "";
+
+    /**
+     * Button
+     * @return
+     */
+    String button() default "";
+    /**
+     * 参数类型
+     * @return
+     */
+    Class<?> paramType();
+}

+ 12 - 0
src/main/java/cn/com/jdkj/annotation/OutServer.java

@@ -0,0 +1,12 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 外部使用接口注解
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface OutServer {
+}

+ 17 - 0
src/main/java/cn/com/jdkj/annotation/Rename.java

@@ -0,0 +1,17 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 实体类字段映射注解
+ * @author zhusenyang
+ * @date 2022-9-5 17:13:22
+ */
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Rename {
+    String value();
+}

+ 12 - 0
src/main/java/cn/com/jdkj/annotation/StarPermissionCheck.java

@@ -0,0 +1,12 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface StarPermissionCheck {
+    String[] roleCodes() default {"ROLE_ADMIN"};
+
+    String[] permissions() default {} ;
+}

+ 11 - 0
src/main/java/cn/com/jdkj/annotation/TokenIgnore.java

@@ -0,0 +1,11 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface TokenIgnore {
+
+
+}

+ 9 - 0
src/main/java/cn/com/jdkj/annotation/XingZhanServer.java

@@ -0,0 +1,9 @@
+package cn.com.jdkj.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface XingZhanServer {
+}

+ 19 - 0
src/main/java/cn/com/jdkj/annotation/sys/SysManageLog.java

@@ -0,0 +1,19 @@
+package cn.com.jdkj.annotation.sys;
+
+import java.lang.annotation.*;
+
+/**
+ * 管理端接口日志记录注解 需token信息
+ * 本注解未赋值时则操作名称取用@ApiOperation注解中的信息
+ * 若二者皆为空 则默认取用方法名作为操作名称
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.TYPE})
+public @interface SysManageLog {
+    /**
+     * 操作名称
+     * @return
+     */
+    String name() default "";
+}

+ 117 - 0
src/main/java/cn/com/jdkj/aspect/CheckSignAspect.java

@@ -0,0 +1,117 @@
+package cn.com.jdkj.aspect;
+
+import cn.com.jdkj.enums.ReturnCode;
+import cn.com.jdkj.exception.CustomException;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.crypto.digest.DigestUtil;
+import com.alibaba.fastjson.JSONObject;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.*;
+
+@Aspect
+@Component
+@Slf4j
+//@RequiredArgsConstructor
+public class CheckSignAspect {
+
+//    String appid="1717726426";
+
+    String secret="089f7f8a1d6186524c2b4cdb0b4fb5e1";
+
+    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)&&@annotation(cn.com.jdkj.annotation.CheckSign))")
+    public void controlerPointCut() {
+    }
+
+    @Around("controlerPointCut()")
+    public Object accessTokenToUserInfo(ProceedingJoinPoint pjp) throws Throwable {
+        //上下文获取请求头 获取token
+        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
+        String sign = request.getHeader("sign");
+        String appid = request.getHeader("appid");
+        String t = request.getHeader("t");
+        //获取传参数据
+        Object[] args = pjp.getArgs();
+        //获取传参名
+//        MethodSignature msg = (MethodSignature) pjp.getSignature();
+        SortedMap<String, String> paramsMap = new TreeMap<>();
+        for (Object arg : args) {
+            if (arg instanceof HttpServletRequest) {
+                continue;
+            }
+            if (arg instanceof HttpServletResponse) {
+                continue;
+            }
+            Class<?> clazz = arg.getClass();
+            Field[] fields = clazz.getDeclaredFields();
+            for (Field field : fields) {
+                field.setAccessible(true);
+                Object o = field.get(arg);
+                if (Objects.nonNull(o)) {
+                    String value = formatValue(field, o);
+                    paramsMap.put(field.getName(), value);
+                }
+            }
+        }
+        paramsMap.put("appid",appid);
+        paramsMap.put("t",t);
+        String toSign = mapToSign(paramsMap)+secret;
+        log.info("toSing:{}",toSign);
+        String checkSign = DigestUtil.md5Hex(toSign);
+        boolean result = checkSign.equalsIgnoreCase(sign);
+        log.info("计算签名结果:{},传参签名:{},是否一致:{}",checkSign,sign,result);
+        if (!result){
+            throw new CustomException(ReturnCode.SIGN_ERROR);
+        }
+        return pjp.proceed(args);
+    }
+
+    String mapToSign(SortedMap<String,String> map){
+        StringBuffer sb = new StringBuffer();
+        map.entrySet().forEach(item->{
+            sb.append("&");
+            sb.append(item.getKey());
+            sb.append("=");
+            sb.append(item.getValue());
+        });
+        return sb.substring(1);
+    }
+
+    private String formatValue(Field field, Object o) {
+        String value;
+        if (o instanceof Date) {
+            DateTimeFormat annotation = field.getAnnotation(DateTimeFormat.class);
+            String pattern;
+            if (Objects.nonNull(annotation)) {
+                pattern = annotation.pattern();
+            } else {
+                pattern = DatePattern.NORM_DATETIME_PATTERN;
+            }
+            value = DateUtil.format((Date) o, pattern);
+        } else if (o instanceof LocalDateTime) {
+            value = DateUtil.format((LocalDateTime) o, DatePattern.NORM_DATETIME_PATTERN);
+        } else {
+            value = String.valueOf(o);
+        }
+        return value;
+    }
+}

+ 148 - 0
src/main/java/cn/com/jdkj/aspect/LogAspect.java

@@ -0,0 +1,148 @@
+package cn.com.jdkj.aspect;
+
+import cn.com.jdkj.util.SpringUtils;
+import cn.hutool.core.stream.StreamUtil;
+import cn.hutool.json.JSONUtil;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.InetAddress;
+import java.net.URLDecoder;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 描述
+ * 日志切面操作
+ **/
+@Aspect
+@Component
+public class LogAspect {
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    private boolean noLog = false;
+
+
+    @Pointcut("execution(* cn.com.jdkj.customer.controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
+    public void logPointCut() {
+    }
+
+    @Before("logPointCut()")
+    public void doBefore(JoinPoint joinPoint) {
+
+        String methodName = joinPoint.getSignature().getName();
+        String filterStr = "initDataBinder";
+        if (methodName.contains(filterStr)) {
+            noLog = true;
+            return;
+        }
+        // 接收到请求,记录请求内容
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        // 记录下请求内容
+        logger.info("******************** 接口调用请求 - 开始 ********************");
+        logger.info("************ 当前运行环境 {} ***************", SpringUtils.getActiveProfile());
+        logger.info("######Header信息:{}", getHeaders(request));
+        logger.info("###### 接口信息 : {} {}", request.getMethod(), request.getRequestURL().toString());
+        Object[] args = joinPoint.getArgs();
+        List<Object> logArgs = StreamUtil.of(args).filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)
+                && !(arg instanceof MultipartFile) && !(arg instanceof BindingResult))).collect(Collectors.toList());
+        logger.info("###### 参数 : " + JSONUtil.toJsonStr(logArgs));
+        logger.info("###### IP : " + request.getRemoteAddr());
+        logger.info("###### CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+                + joinPoint.getSignature().getName());
+        noLog = false;
+
+    }
+
+    public String getHeaders(HttpServletRequest request) {
+        StringBuilder builder = new StringBuilder();
+        Enumeration<String> headerNames = request.getHeaderNames();
+        while (headerNames.hasMoreElements()) {
+            String name = headerNames.nextElement();
+            String header = request.getHeader(name);
+            if (builder.length() > 0) {
+                builder.append(";");
+            }
+            builder.append(name).append(": ").append(header);
+        }
+        return builder.toString();
+    }
+
+    @AfterReturning(returning = "ret", pointcut = "!@annotation(cn.com.jdkj.annotation.LogIgnore) && logPointCut()")
+// returning的值和doAfterReturning的参数名一致
+    public void doAfterReturning(Object ret) {
+        if (noLog) {
+            noLog = false;
+            return;
+        }
+        // 处理完请求,返回内容
+        logger.info("###### 返回值 : " + ret);
+        logger.info("******************** 接口调用请求 - 结束 ********************");
+    }
+
+    @Around("logPointCut()")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+
+        Instant start = Instant.now();
+        Object ob = pjp.proceed();
+        if (!noLog) {
+            logger.info(MessageFormat.format("###### 接口调用耗时 : {0}ms", Duration.between(start, Instant.now()).toMillis()));
+        }
+        return ob;
+    }
+
+    public String getIpAddress(HttpServletRequest request) {
+        String ipAddress = request.getHeader("x-forwarded-for");
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getRemoteAddr();
+            String localIp = "127.0.0.1";
+            String localIpv6 = "0:0:0:0:0:0:0:1";
+            if (ipAddress.equals(localIp) || ipAddress.equals(localIpv6)) {
+                // 根据网卡取本机配置的IP
+                InetAddress inet;
+                try {
+                    inet = InetAddress.getLocalHost();
+                    ipAddress = inet.getHostAddress();
+                } catch (UnknownHostException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+        String ipSeparate = ",";
+        int ipLength = 15;
+        if (ipAddress != null && ipAddress.length() > ipLength) {
+            if (ipAddress.indexOf(ipSeparate) > 0) {
+                ipAddress = ipAddress.substring(0, ipAddress.indexOf(ipSeparate));
+            }
+        }
+        return ipAddress;
+    }
+
+
+
+
+}

+ 49 - 0
src/main/java/cn/com/jdkj/aspect/LogMdcAspect.java

@@ -0,0 +1,49 @@
+package cn.com.jdkj.aspect;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+/**
+ *
+ * @ClassName: LogMdcAspect
+ * @Description:
+ * @Author jyy
+ * @DateTime 2022年1月12日 下午6:02:37
+ */
+@Aspect
+@Component
+public class LogMdcAspect {
+    private static final String UNIQUE_ID = "traceId";
+
+    @Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled))")
+    public void logPointCut() {
+    }
+
+    //@Pointcut("execution(* com.birdsh.paradise.services.video.impl.TaskServiceImpl.doMsg(..))")
+    //public void logPointCut1() {
+    //}
+
+    @Around("logPointCut()")
+    public Object around(ProceedingJoinPoint point) throws Throwable {
+    	//if(StringUtils.isEmpty(MDC.get(UNIQUE_ID)))
+    		//return point.proceed();
+        MDC.put(UNIQUE_ID, UUID.randomUUID().toString().replace("-",""));
+        Object result = point.proceed();// 执行方法
+        MDC.remove(UNIQUE_ID);
+        return result;
+    }
+
+//    @Around("logPointCut1()")
+//    public Object around1(ProceedingJoinPoint point) throws Throwable {
+//        MDC.put(UNIQUE_ID, UUID.randomUUID().toString().replace("-",""));
+//        Object result = point.proceed();// 执行方法
+//        MDC.remove(UNIQUE_ID);
+//        return result;
+//    }
+}

+ 161 - 0
src/main/java/cn/com/jdkj/config/DruidSqlLogFilter.java

@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ * <p>
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.gnu.org/licenses/lgpl.html
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.com.jdkj.config;
+
+import com.alibaba.druid.DbType;
+import com.alibaba.druid.filter.FilterChain;
+import com.alibaba.druid.filter.FilterEventAdapter;
+import com.alibaba.druid.proxy.jdbc.JdbcParameter;
+import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
+import com.alibaba.druid.proxy.jdbc.StatementProxy;
+import com.alibaba.druid.sql.SQLUtils;
+import com.alibaba.druid.util.StringUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.SQLException;
+import java.time.temporal.TemporalAccessor;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 打印可执行的 sql 日志
+ *
+ * <p>
+ * 参考:https://jfinal.com/share/2204
+ * </p>
+ *
+ * @author L.cm
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class DruidSqlLogFilter extends FilterEventAdapter {
+
+	private static final SQLUtils.FormatOption FORMAT_OPTION = new SQLUtils.FormatOption(false, false);
+
+	private final SeafoodMybatisProperties properties;
+
+	@Override
+	protected void statementExecuteBefore(StatementProxy statement, String sql) {
+		statement.setLastExecuteStartNano();
+	}
+
+	@Override
+	protected void statementExecuteBatchBefore(StatementProxy statement) {
+		statement.setLastExecuteStartNano();
+	}
+
+	@Override
+	protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {
+		statement.setLastExecuteStartNano();
+	}
+
+	@Override
+	protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {
+		statement.setLastExecuteStartNano();
+	}
+
+	@Override
+	protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
+		statement.setLastExecuteTimeNano();
+	}
+
+	@Override
+	protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
+		statement.setLastExecuteTimeNano();
+	}
+
+	@Override
+	protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
+		statement.setLastExecuteTimeNano();
+	}
+
+	@Override
+	protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
+		statement.setLastExecuteTimeNano();
+	}
+
+	@Override
+	public void statement_close(FilterChain chain, StatementProxy statement) throws SQLException {
+		// 先调用父类关闭 statement
+		super.statement_close(chain, statement);
+		// 支持动态开启
+		if (!properties.isShowSql()) {
+			return;
+		}
+
+		// 是否开启调试
+		if (!log.isInfoEnabled()) {
+			return;
+		}
+
+		// 打印可执行的 sql
+		String sql = statement.getBatchSql();
+		// sql 为空直接返回
+		if (StringUtils.isEmpty(sql)) {
+			return;
+		}
+		int parametersSize = statement.getParametersSize();
+		List<Object> parameters = new ArrayList<>(parametersSize);
+		for (int i = 0; i < parametersSize; ++i) {
+			// 转换参数,处理 java8 时间
+			parameters.add(getJdbcParameter(statement.getParameter(i)));
+		}
+		String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
+		String formattedSql = SQLUtils.format(sql, DbType.of(dbType), parameters, FORMAT_OPTION);
+		printSql(formattedSql, statement);
+	}
+
+	private static Object getJdbcParameter(JdbcParameter jdbcParam) {
+		if (jdbcParam == null) {
+			return null;
+		}
+		Object value = jdbcParam.getValue();
+		// 处理 java8 时间
+		if (value instanceof TemporalAccessor) {
+			return value.toString();
+		}
+		return value;
+	}
+
+	private static void printSql(String sql, StatementProxy statement) {
+		// 打印 sql
+//		String sqlLogger = "\n\n======= Sql Logger ======================" + "\n{}"
+//				+ "\n======= Sql Execute Time: {} =======\n";
+//		log.info(sqlLogger, sql.trim(), format(statement.getLastExecuteTimeNano()));
+	}
+
+	/**
+	 * 格式化执行时间,单位为 ms 和 s,保留三位小数
+	 * @param nanos 纳秒
+	 * @return 格式化后的时间
+	 */
+	private static String format(long nanos) {
+		if (nanos < 1) {
+			return "0ms";
+		}
+		double millis = (double) nanos / (1000 * 1000);
+		// 不够 1 ms,最小单位为 ms
+		if (millis > 1000) {
+			return String.format("%.3fs", millis / 1000);
+		}
+		else {
+			return String.format("%.3fms", millis);
+		}
+	}
+
+}

+ 60 - 0
src/main/java/cn/com/jdkj/config/FrontInterceptor.java

@@ -0,0 +1,60 @@
+package cn.com.jdkj.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.UUID;
+
+/**
+ *
+ * @ClassName: FrontInterceptor
+ * @Description: 全局前置拦截器
+ * @Author jyy
+ * @DateTime 2022年3月29日 上午9:35:14
+ */
+public class FrontInterceptor extends HandlerInterceptorAdapter implements ApplicationContextAware {
+
+	private static final Logger log = LoggerFactory.getLogger(FrontInterceptor.class);
+
+	private static final String UNIQUE_ID = "traceId";
+	// 必须声明为static
+	private static ApplicationContext context;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+			throws Exception {
+
+    	String traceID = request.getHeader("TRACE_ID");
+		if(StringUtils.isEmpty(traceID))
+			traceID = UUID.randomUUID().toString().replace("-", "");
+		MDC.put(UNIQUE_ID, traceID);
+
+		//log.info(request.getRequestURI() + " ->> request ip:" + request.getRemoteHost() + ": " + request.getRemotePort()
+		//+ " BIRD-MAC-ADDRESS:" + request.getHeader("BIRD-MAC-ADDRESS"));
+
+		return true;
+
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		if (context == null) {
+			context = applicationContext;
+		}
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
+		MDC.remove(UNIQUE_ID);
+	}
+
+}

+ 66 - 0
src/main/java/cn/com/jdkj/config/Knife4jConfiguration.java

@@ -0,0 +1,66 @@
+package cn.com.jdkj.config;
+
+import cn.com.jdkj.annotation.OutServer;
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * @Description: swagger全新UI
+ * @Author: 竺森洋
+ */
+@EnableSwagger2
+@EnableKnife4j
+@Configuration
+public class Knife4jConfiguration {
+
+    /** 生产环境可改为 false(改为false后 swagger将不能使用)*/
+    @Value("${knife4j.enable:true}")
+    private boolean knife4jEnable;
+
+//    @Bean(value = "defaultApi")
+//    public Docket defaultApi2() {
+//        Docket docket=new Docket(DocumentationType.SWAGGER_2)
+//                .apiInfo(apiInfo())
+//                //分组名称
+//                .groupName("测试接口")
+//                .select()
+//                //这里指定Controller扫描包路径
+//                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
+//                .paths(PathSelectors.any())
+//                .build();
+//        return docket;
+//    }
+
+//    @Bean(value = "defaultApi3")
+//    public Docket defaultApi3() {
+//        Docket docket=new Docket(DocumentationType.SWAGGER_2)
+//                .apiInfo(apiInfo())
+//                //分组名称
+//                .groupName("对外接口")
+//                .select()
+//                //这里指定Controller扫描包路径
+//                .apis(RequestHandlerSelectors.withMethodAnnotation(OutServer.class))
+//                .paths(PathSelectors.any())
+//                .build();
+//        return docket;
+//    }
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("Spring Boot Knife4j or swagger-bootstrap-ui API V1.0")
+                .description("swagger-bootstrap-ui-demo RESTful APIs")
+                .version("1.0")
+                .build();
+    }
+
+}

+ 77 - 0
src/main/java/cn/com/jdkj/config/MultiDataSourceConfiguration.java

@@ -0,0 +1,77 @@
+package cn.com.jdkj.config;
+
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+import org.apache.shardingsphere.shardingjdbc.jdbc.adapter.AbstractDataSourceAdapter;
+import org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.context.annotation.*;
+
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
+import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
+
+@Configuration
+@EnableAspectJAutoProxy(exposeProxy = true)
+@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class,SpringBootConfiguration.class})
+public class MultiDataSourceConfiguration {
+
+    /**
+     * 动态数据源配置项
+     */
+    @Autowired
+    private DynamicDataSourceProperties dynamicDataSourceProperties;
+
+    @Lazy
+    @Resource
+    AbstractDataSourceAdapter shardingDataSource;
+
+    @Bean
+    public DynamicDataSourceProvider dynamicDataSourceProvider() {
+        Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();
+
+        DynamicDataSourceProvider provider = new AbstractDataSourceProvider() {
+            @Override
+            public Map<String, DataSource> loadDataSources() {
+                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
+                // 将 shardingjdbc 管理的数据源也交给动态数据源管理
+                dataSourceMap.put("incrementdb", shardingDataSource);
+                return dataSourceMap;
+            }
+        };
+        return provider;
+    }
+
+    /**
+     * 将动态数据源设置为首选的
+     * 当spring存在多个数据源时, 自动注入的是首选的对象
+     * 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了
+     *
+     * @return
+     */
+    @Primary
+    @Bean
+    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
+        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
+        dataSource.setPrimary(dynamicDataSourceProperties.getPrimary());
+        dataSource.setStrict(dynamicDataSourceProperties.getStrict());
+        dataSource.setStrategy(dynamicDataSourceProperties.getStrategy());
+        /**
+         * 动态多数据源提供者,
+         * 在DynamicRoutingDataSource需要要DynamicDataSourceProvider加载进去,
+         * 否则会导致datasource注入失败,抛出空指针异常
+         */
+        dataSource.setProvider(dynamicDataSourceProvider);
+
+        dataSource.setP6spy(dynamicDataSourceProperties.getP6spy());
+        dataSource.setSeata(dynamicDataSourceProperties.getSeata());
+        return dataSource;
+    }
+}

+ 54 - 0
src/main/java/cn/com/jdkj/config/MybatisConfig.java

@@ -0,0 +1,54 @@
+package cn.com.jdkj.config;//package com.star.leisure.config;
+//
+//import com.github.pagehelper.PageHelper;
+//import com.github.pagehelper.PageInterceptor;
+//import org.apache.ibatis.plugin.Interceptor;
+//import org.apache.ibatis.session.SqlSessionFactory;
+//import org.mybatis.spring.SqlSessionFactoryBean;
+//import org.mybatis.spring.annotation.MapperScan;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+//
+//import javax.sql.DataSource;
+//import java.util.Properties;
+//
+//@Configuration
+//@MapperScan(basePackages = {"com.star.leisure.dao"})
+//public class MybatisConfig {
+//
+//    @Autowired
+//    private DataSource dataSource;
+//
+//    @Bean
+//    public SqlSessionFactory sqlSessionFactory() throws Exception {
+//        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
+//        sqlSessionFactoryBean.setDataSource(dataSource);
+//
+//        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
+//        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
+//        configuration.setUseGeneratedKeys(true);
+//        configuration.setUseColumnLabel(true);
+//        configuration.setMapUnderscoreToCamelCase(true);
+//        sqlSessionFactoryBean.setConfiguration(configuration);
+//
+//        // 分页插件
+//        PageHelper pageHelper = new PageHelper();
+//        Properties properties = new Properties();
+//        properties.setProperty("offsetAsPageNum", "true");
+//        properties.setProperty("rowBoundsWithCount", "true");
+//        properties.setProperty("reasonable", "false");
+//        properties.setProperty("supportMethodsArguments", "true");
+//        properties.setProperty("returnPageInfo", "check");
+//        properties.setProperty("params", "pageNum=page;pageSize=rows;orderBy=orderBy");
+//        pageHelper.setProperties(properties);
+//
+//        // 添加插件
+//        PageInterceptor pageInterceptor = new PageInterceptor();
+//        pageInterceptor.setProperties(properties);
+//        sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor});
+//        return sqlSessionFactoryBean.getObject();
+//    }
+//}
+//

+ 103 - 0
src/main/java/cn/com/jdkj/config/MybatisPlusConfig.java

@@ -0,0 +1,103 @@
+package cn.com.jdkj.config;
+
+import cn.com.jdkj.config.DruidSqlLogFilter;
+import cn.com.jdkj.config.SeafoodMybatisProperties;
+import com.baomidou.mybatisplus.core.injector.ISqlInjector;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInterceptor;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+/**
+ * @ClassName
+ * @Description
+ * @Author:shenjunjun
+ * @Date 2019/1/18 15:20
+ * @Version 1.0
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableConfigurationProperties(SeafoodMybatisProperties.class)
+@MapperScan(basePackages = {"cn.com.jdkj.customer.mapper"})
+public class MybatisPlusConfig {
+
+//    @Bean
+//    public ISqlInjector sqlInjector() {
+//        return new LogicSqlInjector();
+//    }
+//    @Bean
+//    public PaginationInnerInterceptor paginationInterceptor() {
+//        return new PaginationInnerInterceptor();
+//    }
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        // 分页支持
+        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
+        paginationInnerInterceptor.setMaxLimit(-1L);
+        interceptor.addInnerInterceptor(paginationInnerInterceptor);
+        return interceptor;
+    }
+
+    @Bean
+    public PageInterceptor pageInterceptor() {
+        PageHelper pageHelper = new PageHelper();
+        Properties properties = new Properties();
+        properties.setProperty("offsetAsPageNum", "true");
+        properties.setProperty("rowBoundsWithCount", "true");
+        properties.setProperty("reasonable", "false");
+        properties.setProperty("supportMethodsArguments", "true");
+        properties.setProperty("returnPageInfo", "check");
+        properties.setProperty("params", "pageNum=page;pageSize=rows;orderBy=orderBy");
+        pageHelper.setProperties(properties);
+
+        // 添加插件
+        PageInterceptor pageInterceptor = new PageInterceptor();
+        pageInterceptor.setProperties(properties);
+        return pageInterceptor;
+    }
+    /**
+     * SQL 日志格式化
+     * @return DruidSqlLogFilter
+     */
+    @Bean
+    public DruidSqlLogFilter sqlLogFilter(SeafoodMybatisProperties properties) {
+        return new DruidSqlLogFilter(properties);
+    }
+    @Autowired
+    private DataSource dataSource;
+
+    @Autowired
+//    @Lazy
+    private MybatisPlusInterceptor mybatisPlusInterceptor;
+
+    @Autowired
+//    @Lazy
+    private PageInterceptor pageInterceptor;
+
+    @Bean
+    public SqlSessionFactory sqlSessionFactory()
+            throws Exception {
+        final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
+        sessionFactory.setDataSource(dataSource);
+        sessionFactory.setPlugins(new Interceptor[]{pageInterceptor,mybatisPlusInterceptor});
+        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
+        return sessionFactory.getObject();
+    }
+}

+ 83 - 0
src/main/java/cn/com/jdkj/config/MybatisPlusMetaObjectHandler.java

@@ -0,0 +1,83 @@
+package cn.com.jdkj.config;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.util.ClassUtils;
+
+import java.nio.charset.Charset;
+import java.time.LocalDateTime;
+
+/**
+ * MybatisPlus 自动填充配置
+ *
+ * @author L.cm
+ */
+@Slf4j
+public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
+
+	@Override
+	public void insertFill(MetaObject metaObject) {
+		log.debug("mybatis plus start insert fill ....");
+		LocalDateTime now = LocalDateTime.now();
+
+		// 审计字段自动填充
+		fillValIfNullByName("createTime", now, metaObject, false);
+		fillValIfNullByName("updateTime", now, metaObject, false);
+//		fillValIfNullByName("createBy", getUserName(), metaObject, false);
+//		fillValIfNullByName("updateBy", getUserName(), metaObject, false);
+
+		// 删除标记自动填充
+		fillValIfNullByName("delFlag", "0", metaObject, false);
+	}
+
+	@Override
+	public void updateFill(MetaObject metaObject) {
+		log.debug("mybatis plus start update fill ....");
+		fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
+//		fillValIfNullByName("updateBy", getUserName(), metaObject, true);
+	}
+
+	/**
+	 * 填充值,先判断是否有手动设置,优先手动设置的值,例如:job必须手动设置
+	 * @param fieldName 属性名
+	 * @param fieldVal 属性值
+	 * @param metaObject MetaObject
+	 * @param isCover 是否覆盖原有值,避免更新操作手动入参
+	 */
+	private static void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
+		// 0. 如果填充值为空
+		if (fieldVal == null) {
+			return;
+		}
+		// 1. 没有 get 方法
+		if (!metaObject.hasSetter(fieldName)) {
+			return;
+		}
+		// 2. 如果用户有手动设置的值
+		Object userSetValue = metaObject.getValue(fieldName);
+		String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
+		if (StrUtil.isNotBlank(setValueStr) && !isCover) {
+			return;
+		}
+		// 3. field 类型相同时设置
+		Class<?> getterType = metaObject.getGetterType(fieldName);
+		if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
+			metaObject.setValue(fieldName, fieldVal);
+		}
+	}
+
+//	/**
+//	 * 获取 spring security 当前的用户名
+//	 * @return 当前用户名
+//	 */
+//	private String getUserName() {
+//		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+//		if (Optional.ofNullable(authentication).isPresent()) {
+//			return authentication.getName();
+//		}
+//		return null;
+//	}
+
+}

+ 124 - 0
src/main/java/cn/com/jdkj/config/RedisConfiguration.java

@@ -0,0 +1,124 @@
+package cn.com.jdkj.config;
+
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.RedisPassword;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+import java.time.Duration;
+
+
+/**
+ * Created by liujinbang on 2017/4/17.
+ */
+@Configuration
+public class RedisConfiguration {
+	@Value("${spring.redis.host}")
+	private  String host;
+	@Value("${spring.redis.port}")
+	private int port;
+	@Value("${spring.redis.timeout}")
+	private int timeout;
+	@Value("${spring.redis.password}")
+	private  String password;
+	@Value("${spring.redis.database}")
+	private   int database;
+
+	@Bean
+	@Autowired
+	public   JedisPool jedisPool(@Qualifier("redis.clients.jedis") JedisPoolConfig config) {
+		return new JedisPool(config, host, port, timeout, password,database);
+		//return new JedisPool(config, host, port);
+	}
+
+
+	@Bean(name = "redis.clients.jedis")
+	public JedisPoolConfig jedisPoolConfig(@Value("${spring.redis.jedis.pool.max-active}") int maxTotal,
+										   @Value("${spring.redis.jedis.pool.max-idle}") int maxIdle,
+										   @Value("${spring.redis.jedis.pool.max-wait}") int maxWaitMillis) {
+//		Config config = new Config();
+//		config.setCodec(new JsonJacksonCodec());
+		JedisPoolConfig config = new JedisPoolConfig();
+		config.setMaxTotal(maxTotal);
+		config.setMaxIdle(maxIdle);
+		config.setMaxWaitMillis(maxWaitMillis);
+		return config;
+	}
+
+
+	@Bean
+	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
+
+		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
+		container.setConnectionFactory(connectionFactory);
+		return container;
+	}
+//
+	@Bean
+	public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
+		//  配置 Jackson2JsonRedisSerializer 序列化器,在配置 redisTemplate需要用来做k,v的序列化器
+		//此种序列化方式结果清晰、容易阅读、存储字节少、速度快,所以推荐更换
+		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
+		RedisSerializer<?> stringSerializer = new StringRedisSerializer();
+
+
+		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+		//GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
+		// 设置键(key)的序列化采用StringRedisSerializer。
+		redisTemplate.setKeySerializer(stringSerializer);
+		// 设置值(value)的序列化采用jackson的序列化。
+		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+		redisTemplate.setHashKeySerializer(stringSerializer);
+		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+		redisTemplate.setConnectionFactory(connectionFactory);
+		return redisTemplate;
+	}
+	@Bean
+	public LettuceConnectionFactory lettuceConnectionFactory() {
+		GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
+		genericObjectPoolConfig.setMaxIdle(5);
+		genericObjectPoolConfig.setMinIdle(5);
+		genericObjectPoolConfig.setMaxTotal(8);
+		genericObjectPoolConfig.setMaxWaitMillis(1000);
+		genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100);
+		RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
+		redisStandaloneConfiguration.setDatabase(database);
+		redisStandaloneConfiguration.setHostName(host);
+		redisStandaloneConfiguration.setPort(port);
+		redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
+		LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
+				.commandTimeout(Duration.ofMillis(timeout))
+				.poolConfig(genericObjectPoolConfig)
+				.build();
+
+		LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
+	//  factory.setShareNativeConnection(true);
+	//  factory.setValidateConnection(false);
+		return factory;
+	}
+//private final Decoder<Object> decoder = new Decoder<Object>() {
+//	@Override
+//	public Object decode(ByteBuf buf, State state) throws IOException {
+//		ByteBufInputStream in = new ByteBufInputStream(buf);
+//
+//		FSTObjectInput inputSteam = config.getObjectInfut(in);
+//
+//	}
+//}
+}
+

+ 52 - 0
src/main/java/cn/com/jdkj/config/RedissonConfig.java

@@ -0,0 +1,52 @@
+package cn.com.jdkj.config; /**
+ *
+ */
+
+/**
+* @version:v1.0
+* @Description:
+* @author: jzhao
+* @date: 2019年9月21日下午3:09:48
+*/
+
+
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * redisson 配置类
+ * Created on 2018/6/19
+ */
+@Configuration
+public class RedissonConfig {
+
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port:6379}")
+    private String port;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+    @Value("${spring.redis.database:0}")
+    private Integer database;
+
+
+
+    @Bean
+    public RedissonClient getRedisson(){
+
+        Config config = new Config();
+        config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password).setDatabase(database);
+        //添加主从配置
+//        config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
+
+        return Redisson.create(config);
+    }
+
+}

+ 21 - 0
src/main/java/cn/com/jdkj/config/ScheduleConfig.java

@@ -0,0 +1,21 @@
+package cn.com.jdkj.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+
+/**
+ * 多线程定时任务
+ * @author jyy
+ *
+ */
+@Configuration
+public class ScheduleConfig implements SchedulingConfigurer {
+    @Override
+    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
+    }
+}

+ 23 - 0
src/main/java/cn/com/jdkj/config/SeafoodMybatisProperties.java

@@ -0,0 +1,23 @@
+package cn.com.jdkj.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+/**
+ * Mybatis 配置
+ *
+ * @author seafood
+ * @date 2021/6/3
+ */
+@Data
+@RefreshScope
+@ConfigurationProperties("seafood.mybatis")
+public class SeafoodMybatisProperties {
+
+	/**
+	 * 是否打印可执行 sql
+	 */
+	private boolean showSql = true;
+
+}

+ 33 - 0
src/main/java/cn/com/jdkj/config/Swagger2Config.java

@@ -0,0 +1,33 @@
+package cn.com.jdkj.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.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+            .apiInfo(apiInfo()).select()
+            .apis(RequestHandlerSelectors.basePackage("cn.com.jdkj.customer.controller"))
+            .paths(PathSelectors.any())
+            .build();
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+            .title("小书童")
+            .description("小书童")
+            .termsOfServiceUrl("http://star.mstardance.com")
+            .version("1.0").build();
+    }
+}

+ 68 - 0
src/main/java/cn/com/jdkj/config/WebMvcConfig.java

@@ -0,0 +1,68 @@
+package cn.com.jdkj.config;
+
+import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.*;
+
+import java.util.List;
+
+@Configuration
+public class WebMvcConfig extends WebMvcConfigurationSupport {
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**").allowedOrigins("*").allowedHeaders("*")
+                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowCredentials(true).maxAge(3600);
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+
+        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
+
+        /** 配置knife4j 显示文档 */
+        registry.addResourceHandler("doc.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 注册拦截器
+        InterceptorRegistration ir = registry.addInterceptor(getFrontInterceptor());
+        // 配置拦截的路径
+        ir.addPathPatterns("/**");
+        // 配置不拦截的路径
+        // swagger
+        ir.excludePathPatterns("/webjars/**", "/swagger-resources/**", "swagger-ui.html");
+
+        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**").excludePathPatterns("/webjars/**", "/swagger-resources/**", "swagger-ui.html");
+
+    }
+
+    /**
+     * jackson替换为fastjson
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
+        FastJsonConfig config = new FastJsonConfig();
+        config.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+                SerializerFeature.DisableCircularReferenceDetect);
+        fastJsonHttpMessageConverter.setFastJsonConfig(config);
+        converters.add(fastJsonHttpMessageConverter);
+    }
+
+    @Bean
+    public FrontInterceptor getFrontInterceptor() {
+        return new FrontInterceptor();
+    }
+
+
+}

+ 20 - 0
src/main/java/cn/com/jdkj/constant/RedisConstant.java

@@ -0,0 +1,20 @@
+package cn.com.jdkj.constant;
+
+public interface RedisConstant {
+    String REDIS_CACHE_WEB_ROOT = "starsky:web:";
+    String USER_ACCESS_TOKEN = REDIS_CACHE_WEB_ROOT + "sys:user:accesstoken:";
+    String AGENT_USER_ACCESS_TOKEN = REDIS_CACHE_WEB_ROOT + "sys:agentuser:accesstoken:";
+    String PLATFORM_USER_ACCESS_TOKEN = REDIS_CACHE_WEB_ROOT + "sys:platform:user:accesstoken:";
+    String USER_ACCESS_INFO = REDIS_CACHE_WEB_ROOT + "sys:user:info:token:";
+    String PLATFORM_FLAG = REDIS_CACHE_WEB_ROOT + "platFrom:";
+    String AGENT_FLAG = REDIS_CACHE_WEB_ROOT + "agent:";
+    String TOKEN_USER_SHIP_TYPE = REDIS_CACHE_WEB_ROOT + "token:user:shiptype:";
+    String PLATFORM_FLAG_TRUE = "1";
+    Long ACCESS_TOKEN_EXPIRE = Long.valueOf(24 * 60 * 60 * 30);
+    Long PLATFORM_ACCESS_TOKEN_EXPIRE = Long.valueOf(24 * 60 * 60 * 30);
+    String PLATFORM_USER_INFO = REDIS_CACHE_WEB_ROOT + "sys:user:member:info:data:";
+    /**
+     * 第三方平台秘钥信息
+     */
+    String OPEN_PLATFORM_LIMIT = PLATFORM_FLAG + "platform:limit:";
+}

+ 351 - 0
src/main/java/cn/com/jdkj/constant/ReturnCode.java

@@ -0,0 +1,351 @@
+package cn.com.jdkj.constant;
+
+public enum ReturnCode {
+	/**
+	 *
+	 */
+    Operation_Errored(0, "操作失败!"),
+    Operation_Succeeded(1, "操作成功!"),
+    Internal_Server_Error(2, "服务器内部错误!"),
+	Parameters_Incomplete(3, "传参不全!"),
+	File_Exist_Error_Data(1, "存在错误数据"),
+
+    Params_Error(100, "请求参数错误"),
+	Parameters_Sign_Error(101, "参数签名错误"),
+    Password_Error(104, "密码错误"),
+    Account_Error(1015, "账号不存在"),
+    Account_Exist(1025, "账号已存在"),
+    ACCOUNT_FROZEN(1035, "账号冻结"),
+	OPENID_IS_EMPTY(1036,"openid为空"),
+	OPENID_NOT_BIND(1037,"openid未绑定"),
+	WX_USER_IS_NULL(1038,"微信用户不存在"),
+	Visited_too_frequently(10001, "请求太频繁,请稍后再试"),
+
+	ACCOUNT_UNUSUAL(1050, "账户异常,请联系客服"),
+
+	Package_Name_Exis(1400,"套餐名不能与已上架的钻石套餐名称相同"),
+	Package_Price_Exis(1401,"套餐金额不能与已上架的钻石套餐金额相同"),
+	Package_Not_Exis(1400,"此钻石套餐不存在"),
+	Diamond_Amount_Only_Integer(1402,"钻石数量仅支持整数"),
+	Diamond_Price_Not_Null(1403,"套餐金额不能为空"),
+	Diamond_TOO_MUCH(1404,"钻石充值超过每日上限"),
+	Diamond_ORDER_NOT_EXSIT(1405,"钻石订单不存在"),
+	Diamond_UNABLE_CANCEL(1406,"此钻石订单不支持退款"),
+	empty_tel(50001, "手机号为空"),
+	repeat_tel(50000, "手机号重复"),
+	UserInfo_noChange(50002, "用户信息无更新"),
+	Package_receive_noRight(50004, "vip等级低于礼包所需等级"),
+	Package_receive_allReady(50005, "会员礼包已领取"),
+	Vip_Package_NotConfig(50006, "会员礼包未配置"),
+	error_sign(50007, "签名错误"),
+	vip_package_status(50008, "同步vip礼包领取情况"),
+	supplier_exist(50009, "供应商名称已存在"),
+	vipAndPackageNoChange(50010, "周三会员日+海哥礼包配置未修改该"),
+	VipLevelGetError(50011, "云端校验用户VIP等级失败"),
+	apiReject(50012, "系统繁忙,请稍后再试!"),
+	empty_cid(50003, "cid为空"),
+	TOO_LONG_TEXT(50004,"文本内容过长"),
+
+	appId_Empty(20001, "appId不存在"),
+	appInfo_error(20002, "app信息校验错误"),
+	cid_error(20003, "cid不存在"),
+	error_sign_forValueAdd(20004, "签名错误"),
+	param_lose(20005, "缺少参数"),
+	server_error(20006, "服务端错误"),
+	packageName_notExist(20007, "包名不存在"),
+	password_error(20008, "密码错误"),
+	empty_param(20009, "参数为空"),
+	Code_Send_Fail(20010, "验证码发送失败"),
+	Code_Get_many(20011, "验证码获取超过限制"),
+	header_lose(20012, "缺少httpHeader参数"),
+	Code_error(20013, "验证码错误"),
+	BXT_error(20014, "繁星平台错误"),
+	user_not_exist(20015, "用户不存在"),
+	wechat_binded(20016, "微信已绑定"),
+	phone_format_error(20017, "请输入正确的手机号"),
+	passoword_error(20018, "账号或密码不正确"),
+	unbind_user_error(20019, "解绑用户错误"),
+	error_bxt_user_info(20020, "繁星用户信息错误"),
+	Error_Signature(20056, "签名不正确!"),
+	Error_pwd(20057, "两次输入密码不一致!"),
+	user_exist(20058, "账号已存在"),
+
+    Empty_Token(20051, "token为空!"),
+    Error_Token(20052, "token错误!"),
+    Overdue_Token(20053, "token过期!"),
+	user_error(20054,"用户信息不一致"),
+	user_status_error(20055,"用户已禁用"),
+
+	EXCHANGE_BOBY_TIMES_NOT_ENOUGH(20100,"剩余次数不足"),
+	EXCHANGE_FAIL(20101,"流量兑换失败"),
+	EXCHANGE_BALANCE_NOT_ENOUGH(20102,"兑换券不足"),
+	EXCHANGE_ADD_REPEAT(20102,"新增兑换券重复"),
+	EXCHANGE_ORDER_IS_EMPTY(20102,"第三方订单号不能为空"),
+	EXCHANGE_ORDER_SERVER_BUSY(20102,"服务繁忙,稍后再试"),
+	EXCHANGE_CONDITION_DISCONTENT(20103,"不满足发放条件"),
+	EXCHANGE_MAX(20104,"超出每日兑换上限"),
+	EXCHANGE_PERSON_MAX(20105,"超出个人每日兑换上限"),
+	GAMECURRENCY_DEDUCTION_FAIL(600001,"游戏币交易失败"),
+	GAMECURRENCY_NUMBER(600002,"游戏币交易数量需大于0"),
+	GAMECURRENCY_NOT_ENOUGH(600003,"游戏币余额不足"),
+	//bxt平台返回错误码
+	//token_empty(20051, "token为空"),
+
+	REWARD_RECEIVED(700001,"奖励已领取"),
+	NOT_VAILD_TASK(700002,"无效的任务"),
+	NOT_VAILD_TASK_REWARD(700003,"无效的任务奖励"),
+	NOT_LOGIN(700004,"无对应的登入记录"),
+	SETTLEMENT_DETAIL_AUDIT_EXCEPTION(85001, "结算明细审核异常"),
+	SETTLEMENT_DETAIL_AMOUNT_EXCEPTION(85002, "结算金额异常"),
+	WEEK_SETTLEMENT_NOT_EXIST(85003, "周结算单不存在"),
+	WEEK_SETTLEMENT_AUDIT_COMPLETE(85004, "周结算单已审核"),
+	WEEK_SETTLEMENT_STATUS_ERROR(85005, "周结算单状态错误"),
+	EXIST_NOT_CONFIRM_SETTLEMENT(85006, "存在未确认的结算明细"),
+	SETTLE_WITHDRAW_AMOUNT_EXCEPTION(85007, "结算用户提现金额异常"),
+	WEEK_SETTLEMENT_AUDITED_EMPTY(85008, "未查询到已审核完成的周结算单"),
+	WEEK_SETTLEMENT_EXPORT_EXCEPTION(85009, "周结算单导出异常"),
+	APPLY_WITHDRAW_BALANCE_EXCEPTION(85010, "余额不足,请重新输入提现金额"),
+	WEEK_SETTLEMENT_ALREADY_EXIST(85011, "周结算单已存在"),
+	WITHDRAW_MAX(85012, "超出本日提现最大额度"),
+
+	RETURN_PRINCIPAL_UPPER_LIMIT_MORE_TOTAL_SALES_AMOUNT(90001, "回报本金区间上限不得超过总营业额"),
+
+
+	TOO_MANY_DATA(623901,"数据超过60000条或无数据,请重新筛选"),
+	Error_Prompt(10001, "无法完成请求,提示码:10001"),
+
+	Scratch_Config_Error(86001, "刮刮卡参数错误"),
+	Scratch_Sold_Out(86002, "刮刮卡已刮完"),
+	Number_Scratch_Sold_Out(86005, "幸运数字刮刮卡已刮完"),
+	Scratch_Params_Error(86003, "刮刮卡查询参数错误"),
+	Scratch_No_Award(86004, "刮刮卡查询参数错误"),
+	WelfareConfigIdError(87001, "福利社配置id错误"),
+	WelfareAwardHasGet(87002, "福利已领取"),
+	WelfareCanNotGet(87003, "不满足领奖条件"),
+    LegendNoBalance(87003, "传奇元宝余额不足"),
+	LegendErrorParam(87003, "错误参数"),
+	LegendVotingTimeParam(87004, "活动结束时间不得早于开始时间"),
+	LegendVotingTimeBeforeNow(87004, "活动结束时间不得早于当前时间"),
+	LegendVotingTimeError(87004, "活动结束时间与其他活动时间重合"),
+	LegendVotingNoConfig(87005, "活动配置不存在"),
+	LegendVotingConfigCanNotUpdate(87006, "仅可编辑未开始的活动配置"),
+	LegendVotingConfigEroorPhone(87006, "排行榜数据存在重复手机号"),
+	LegendVotingTaskNoReward(87007, "无可领取奖励"),
+	LegendVotingNoActivities(87008, "无进行中的活动"),
+	LegendVotingConfigInUse(87009, "活动正在进行中不可操作"),
+	LegendVotingPassMaxNum(87009, "今日投票已达上限"),
+	LegendVotingNoRankFile(87010, "无排行配置文件"),
+	ExchangeMallErrorOrder(87011, "无效的订单"),
+	ExchangeMallErrorGoods(87012, "商品已下架~"),
+	ExchangeMallErrorActivities(87013, "无效的活动"),
+	ExchangeMallErrorActivitiesGoods(87013, "无效的活动商品"),
+	UserAddressNoId(87014,"请选择正确的收货地址"),
+	ExchangeMallErrorActivitiesTimeIsNull(87015, "兑换商城活动时间不能为空"),
+	ExchangeMallErrorActivitiesNameIsNull(87016, "兑换商城活动名称不能为空"),
+	ExchangeMallErrorActivitiesStatusIsNull(87017, "兑换商城活动状态不能为空"),
+	ExchangeMallErrorActivitiesIdIsNull(87018, "兑换商城活动id不能为空"),
+	ExchangeMallOrderLogisticsNoIsNull(87019, "物流单号不能为空"),
+	ExchangeMallErrorActivitiesGoodsIsNull(87020, "您还未做出任何修改操作, 不能进行更新"),
+	ExchangeMallActivitiesGoodsUpdateError(87021, "兑换商城活动商品更新失败"),
+	ExchangeMallActivitiesGoodsInsertError(87022, "兑换商城活动商品插入失败"),
+	ExchangeMallActivitiesGoodsDeleteError(87023, "兑换商城活动商品逻辑删除失败"),
+	ExchangeMallErrorActivitiesTimeFormatError(87024, "兑换商城活动时间格式错误"),
+	ExchangeMallErrorActivitiesNameIsRepeat(87025, "输入的兑换商城活动名称已存在"),
+	ExchangeMallErrorActivitiesGoodsIsExist(87026, "提交的活动商品中包含已存在该活动中的商品,请勿重复添加相同种类的商品"),
+	ExchangeMallErrorActivitiesGoodsAllPriceIsNull(87027, "兑换商城活动商品的游戏币、兑换券价格不能同时为空"),
+	ExchangeMallErrorActivitiesGoodsDelFlagIsNull(87028, "兑换商城活动商品的删除标识不能为空"),
+	ExchangeMallErrorActivitiesIsInProcess(87029, "兑换商城活动进行中,不能进行删除操作"),
+	ExchangeMallErrorActivitiesDurationLessThan30Minutes(87030, "兑换商城活动时间间隔不能小于30分钟"),
+	ExchangeMallErrorActivitiesGoodsSumLessThanThree(87031, "兑换商城活动商品数量不能小于3个"),
+	ExchangeMallErrorActivitiesGetFail(87031, "兑换商城活动获取失败"),
+	ExchangeMallErrorPayType(87024, "无效的支付类型"),
+	ExchangeMallNotPayType(87025, "此商品没有你选择的支付类型"),
+	ExchangeMallMaxTimes(87026, "超出此商品的每日最高兑换次数"),
+	ExchangeMallErrorActivitiesTimeIsEqual(87032, "兑换商城活动开始时间和结束时间不能相同"),
+	ExchangeMallErrorActivitiesCrossDayIsExist(87033, "上架状态的跨天的兑换商城活动只能存在一个"),
+	ExchangeMallErrorActivitiesTimeIntersection(87034, "输入的兑换商城活动时间不能与已有的上架状态活动的时间重叠"),
+	ExchangeMallErrorActivitiesInsertError(87035, "兑换商城活动新增失败"),
+	ExchangeMallErrorActivitiesUpdateError(87036, "兑换商城活动编辑失败"),
+	No_CouponPrice_Or_GameCurrencyPrice(88001,"游戏币、兑换券至少选择一个"),
+	Sort_Is_The_Same(88002,"存在相同排序的分类,请重新输入排序数字"),
+	No_CouponPriceFlag_Or_GameCurrencyPriceFlag(88003,"游戏币、兑换券至少选择一个"),
+	Stock_Is_Error(88004,"库存不能小于0或大于99999"),
+	MaxExchangeTimes_Is_Null(88005,"每日最高兑换次数不能为空"),
+	SerialNumber_Repeat(88006,"该序号已经存在,请重新输入"),
+	ORDER_IS_NOT_EXSIT(88006,"订单编号不存在"),
+	ORDER_IS_OVER(88006,"订单已完结"),
+
+	Book_Type_Delete_Error(88007,"该类型下有书籍存在,请先清空类型下绑定书籍再进行删除"),
+	CategoryName_Is_The_Same(88008,"存在相同的二级分类名,请重新输入"),
+	Exist_Goods(88009,"该分类下存在商品,无法删除"),
+	Exist_PutOn_Goods(88010,"该分类下存在上架中的商品,无法下架该分类"),
+	NOT_Exist_Category_Goods(88011,"该商品所属分类未上架,请先上架分类"),
+	Activity_Goods_Can_Not_Delete(88012,"该商品属于活动商品,无法删除"),
+	Activity_Goods_Can_Not_TakeOff(88013,"该商品属于活动商品,无法下架"),
+	userAddressMaxNumError(88014,"最多添加10个地址,请删除后添加"),
+    userAddressErrorUser(88015,"无法操作不存在的地址"),
+	Book_Order_Purchased(88014,"此用户已经购买此书"),
+	Book_Bookshelf_Added(88015,"已经将此书加入书架"),
+	Goods_Name_is_The_Same(88016,"存在相同的商品名称,请重新输入"),
+	Bo_Bi_Num_Is_Null(88017,"请输入波贝发放数额"),
+	Activity_is_over(88018,"活动已结束"),
+	Activity_is_error(88019,"兑换失败,请刷新页面重试"),
+	Book_Order_Error(88020,"没有足够的游戏币"),
+	exchangeNoAddress(88021,"请补充收货信息"),
+	Real_Stock_Is_Null(88022,"实物商品库存不能为空"),
+	Book_Parse_Is_Null(88023,"书籍解析错误,与系统正则不匹配"),
+	Book_no_chapter(88024,"书籍缺少章节信息,请补充后上传"),
+	Book_read_end(88025,"没有下一章了"),
+	Book_not_buy(80027,"小说未购买"),
+	Stock_not_enough(88026,"来晚了,商品已兑完~"),
+	wx_user_no_exeist(88100,"微信用户不存在"),
+	SING_ACTIVITY_START_TIME_ERROR(88027,"活动开始时间最早为当天"),
+	SING_ACTIVITY_END_TIME_ERROR(88028,"活动结束时间最早为当天"),
+	SING_ACTIVITY_NAME_REPEAT(88029,"活动名称重复,请修改活动名称"),
+	SING_ACTIVITY_URL_ERROR(88030,"活动音视频链接地址错误"),
+	Failed_To_Query_The_Total_Rank(88031,"查询总榜排名失败"),
+	Excel_Data_Is_Null(88032,"表格内数据为空"),
+	Excel_Data_Is_Over_1000(88033,"表格内数据超过1000条"),
+	Excel_Row_Content_Is_Incomplete(88034,"未填写必填数据"),
+
+	GAME_CURRENCY_PACKAGE_NOT_EXIST(88035,"k歌游戏币套餐不存在"),
+	Failed_To_Query_The_Activity(88036,"查询活动榜排名失败,数据库异常"),
+	Vote_Has_Voted(88037,"已经投过当前票了"),
+	Receive_Max_Num(88038,"得票次数已达上限"),
+	Game_Currency_Not_Enough(88039,"游戏币不足"),
+	Vote_Activity_Not_Started(88040,"投票活动未处于进行中"),
+	The_Account_Has_Been_Bound(88041,"该账号已被绑定"),
+	ERROR_CHANNEL(10000,"无效渠道"),
+	CHANNEL_DOWN(10001,"渠道已下架"),
+	ERROR_SIGN(9000,"无效的签名"),
+	INVALID_TOKEN(9001,"无效的令牌或令牌已过期"),
+	UPLOAD_ERROR(9002,"上传失败"),
+	WRONG_PASSWORD(9003,"密码错误"),
+	USERNAME_EXSIT(9004,"用户名已存在"),
+	USERNAME_NOT_EXSIT(9004,"用户名不存在"),
+	MENU_NOT_EXSIT(9005,"菜单不存在"),
+	ERROR_PASSWORD_USERNAME(9006,"账号或密码错误"),
+	ERROR_PERMISSION(9007,"权限不足"),
+	IMAGE_NOT_EXSIT(9008,"图片不存在"),
+	IMAGE_HAS_BUY(9009,"图片已购买,请勿重复购买"),
+	GAME_NOT_EXSIT(9010,"游戏不存在"),
+	PACKAGE_NOT_EXSIT(9011,"套餐不存在"),
+	PACKAGE_IS_UP(9011,"请在套餐加下后操作"),
+	COUPON_LIMIT(9012,"兑换券超出单日可获得上限"),
+
+	wechat_code_invalid(9014, "微信code无效"),
+	EDIT_SALES_NUM_TOO_SMALL(9015,"套餐销量不可减少"),
+	DAY_COUPON_SOUCRE_ERROR(9016,"此玩法每日获取兑换券超出上限"),
+	SUM_COUPON_SOUCRE_ERROR(9017,"此玩法获取兑换券超出总上限"),
+	COUPON_GET_ERROR(9018,"兑换券发放异常,稍后再试"),
+	CONFIG_NO_LEVEL(90018,"配置未指定风控等级"),
+	ERROR_DATE_STRING(90019,"错误的日期,请检查日期格式yyyy-MM-dd hh:mm:ss"),
+	END_TIME_IS_BEFORE_START_TIME(90020,"结束时间早于起始时间"),
+	NO_END_TIME(90021,"未设定结束时间"),
+	ERROR_PACKAGE(90022,"套餐不存在"),
+	USER_AUTHENTICATION(90023,"请先在迪泰APP完成实名认证"),
+	END_TIME_BEFORE_START_TIME(90024,"结束时间不可早于起始时间"),
+
+	//=============== 流量加油站 ======================
+	GAS_STATION_BATCH_EMPTY_ERROR(91001, "流量加油站暂无期次活动"),
+	GAS_STATION_AWARD_EXPIRE_ERROR(91002, "奖项超过领取时间,领取失败"),
+	GAS_STATION_ERROR_TASK_TYPE(91003,"无效的任务类型"),
+	GAS_STATION_ERROR_TASK_CONDS(91003,"无效的任务条件"),
+	GAS_STATION_ERROR_TASK_TYPE_CONDS(91003,"任务类型与任务条件不匹配"),
+	GAS_STATION_AWARD_CONFIG_ERROR(91004,"销售额区间与其他配置有冲突"),
+	GAS_STATION_AWARD_CONFIG_ERROR_AMOUNT(91004,"销售额区间最大值小于最小值"),
+
+
+	BANNER_NOT_EXIST(91005,"banner不存在"),
+	BANNER_IS_UP(91005,"请下架后操作."),
+
+	NOTICE_NOT_EXIST(91006,"公告不存在"),
+	NOTICE_IS_UP(91006,"请下架后操作"),
+
+	LV_POWER_PARAM_ERROR(92000,"此等级的权益配置低于低等级的权益配置,请认真核验"),
+	LV_IS_EXSIT(92000,"此等级已存在,不可新增"),
+	ERROR_LV(92001,"错误的等级"),
+	ERROR_CODE(92002,"无效的邀请码"),
+	ERROR_PERSON_CODE(92002,"无效的个人码"),
+	ERROR_PHONE(92002,"无效的手机号"),
+	TEAM_NOT_OUT(92003,"您已有队伍,请在退队后操作"),
+	NO_TEAM(92004,"尚无队伍"),
+	NOT_OUT_TIME(92005,"暂不可退团"),
+	GOODS_NOT_EXSIT(92006,"商品不存在"),
+	OVER_TIMES(92007,"超出兑换次数"),
+	GOODS_LV_ERROR(92008,"商品所需等级高于当前等级"),
+	BALANCE_ERROR(92009,"余额不足"),
+	TEAM_LIMIT(92010,"团队人数已满"),
+	CAN_NOT_JOIN_SELF(92011,"不可加入自己的队伍"),
+	ERROR_LINK(92012,"无效的邀请链接"),
+    LEADER_LV_TOO_LOW(92013,"团长等级过低,请联系团长升级后再加入"),
+	LEADER_HAVETO_LV_UP(92014,"团队人数已满,请联系团长升级后再加入"),
+	ERROR_TIME(92015,"时间格式错误"),
+
+	ACTIVE_HAS_OPEN(92016,"已有启用中的活动"),
+	BOT_ADD_MIN_GREATE_MAX(92017,"虚拟用户增长最小值高于最大值"),
+	BOT_NUM_MIN_GREATE_MAX(92018,"虚拟用户刷新数量最小值高于最大值"),
+	BOT_COUPON_GREATE_SUM(92019,"虚拟用户回收奖励高于总奖池"),
+	RANK_START_IN_OTHER_DETAIL(92019,"排名分布存在冲突"),
+	ACTIVE_IS_OPEN(92020,"此活动正在启用中"),
+	ACTIVE_NOT_START(92021,"活动尚未开始"),
+	ACTIVE_NOT_EXSIT(92022,"活动不存在"),
+	COUPON_RATIO_ERROR(92023,"奖励分配百分比之和必须为100%"),
+	WEIGHT_ERROR(920024,"重量输入错误或超出长度"),
+	PACAKGE_NOT_EXSIT(920025,"红包不存在"),
+	PACKAGE_HAS_GRAB(920026,"红包已领取,不可重复领取"),
+	PACKAGE_NO_BALANCE(920026,"红包已领完"),
+	PACKAGE_EXPIRE(920027,"红包已过期"),
+	USER_ID_NOT_NULL(920028,"缺少用户id"),
+	FACE_NOT_EXSIT(920029,"红包封面不存在"),
+	WX_PAY_ERROR(920030,"微信支付暂时无法使用,请使用支付宝支付"),
+	PLATFORM_PACKAGE_CONFG_ERROR(920031,"红包设置参数错误"),
+	PACKAGE_STATUS_ERROR(920032,"只能下架未开始的红包"),
+	PACKAGE_IS_DOWN(920034,"红包已被下架"),
+	PACKAGE_BATCH_NO_CREATE(920035,"红包批次尚未生成"),
+	PACKAGE_NOT_BEGIN(920036,"红包活动未开始"),
+	PACKAGE_IS_OVER(920037,"红包活动未开始"),
+	PACKAGE_CHANCE_OVER(920037,"红包机会不足"),
+	MIN_PAY_IS_TOO_BIG(920038,"最小充值额度必须小于最大充值额度"),
+	MIN_MAX_PAY_ERROR(920038,"最小/最大充值额度与其他等级冲突"),
+	LV_IS_NOT_EXSIT(920039,"等级不存在"),
+	LV_IS_USEING(920040,"等级正在使用中"),
+	AGENT_IS_NOT_EXSIT(920041,"用户不存在"),
+	HAS_AGENT_CODE(920042,"验证码发送频繁"),
+	ERROR_SMS_CODE(920043,"无效的验证码"),
+	ERROR_FUN_USER(920044,"无效的娱乐用户"),
+	USER_HAS_BIND(920045,"用户已绑定,不可重复绑定"),
+	FUN_USER_HAS_BIND(920045,"娱乐账户已绑定其他账号"),
+	FUN_USER_NOT_BIND(920055,"娱乐账户尚未激活绑定"),
+	;
+
+
+
+    ReturnCode(Integer code, String detail) {
+        this.code = code;
+        this.detail = detail;
+    }
+
+
+    public static ReturnCode getByCode(int code) {
+        for (ReturnCode tradeStatus : values()) {
+            if (tradeStatus.getCode() == code) {
+                return tradeStatus;
+            }
+        }
+        return null;
+    }
+
+	/** 返回码 */
+    private Integer code;
+    /** 返回内容详情 */
+    private String detail;
+
+	public Integer getCode() {
+		return code;
+	}
+	public String getDetail() {
+		return detail;
+	}
+
+}

+ 7 - 0
src/main/java/cn/com/jdkj/constant/TokenKey.java

@@ -0,0 +1,7 @@
+package cn.com.jdkj.constant;
+
+public interface TokenKey {
+    String USER_ID_KEY = "scholar:customer:id:";
+    String USER_KEY_ID = "scholar:customer:key:";
+    String BAIDU_TOKEN = "baidu:api:token";
+}

+ 49 - 0
src/main/java/cn/com/jdkj/customer/controller/CustomerController.java

@@ -0,0 +1,49 @@
+package cn.com.jdkj.customer.controller;
+
+import cn.com.jdkj.annotation.CheckSign;
+import cn.com.jdkj.customer.dto.LoginDto;
+import cn.com.jdkj.customer.dto.QuestionDto;
+import cn.com.jdkj.customer.dto.RegisterDto;
+import cn.com.jdkj.customer.service.CustomerService;
+import cn.com.jdkj.entity.ResultBean;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+@RequestMapping("/customer")
+@RequiredArgsConstructor
+@Slf4j
+public class CustomerController {
+
+    final CustomerService customerService;
+
+    @GetMapping("/login")
+    @ApiOperation("登入")
+    @CheckSign
+    public ResultBean login(LoginDto dto){
+        return customerService.login(dto);
+    }
+
+    @GetMapping("/register")
+    @ApiOperation("注册")
+    @CheckSign
+    public ResultBean register(RegisterDto dto){
+        return customerService.register(dto);
+    }
+    @PostMapping("/question")
+    @ApiOperation("访问问题(返回文本")
+    @CheckSign
+    public ResultBean question(@RequestBody QuestionDto dto){
+        return customerService.question(dto);
+    }
+    @GetMapping("/questionToAudio")
+    @ApiOperation("访问问题(返回音频流")
+    @CheckSign
+    public void questionToAudio(QuestionDto dto, HttpServletResponse response){
+        customerService.questionToAudio(dto, response);
+    }
+}

+ 15 - 0
src/main/java/cn/com/jdkj/customer/dto/AIBodyDto.java

@@ -0,0 +1,15 @@
+package cn.com.jdkj.customer.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AIBodyDto {
+    String model = "ERNIE-Bot-turbo";
+    List<AIMessageDto> messages;
+}

+ 13 - 0
src/main/java/cn/com/jdkj/customer/dto/AIMessageDto.java

@@ -0,0 +1,13 @@
+package cn.com.jdkj.customer.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AIMessageDto {
+    String role;
+    String content;
+}

+ 14 - 0
src/main/java/cn/com/jdkj/customer/dto/LoginDto.java

@@ -0,0 +1,14 @@
+package cn.com.jdkj.customer.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoginDto {
+    String username;
+    String password;
+}

+ 14 - 0
src/main/java/cn/com/jdkj/customer/dto/QuestionDto.java

@@ -0,0 +1,14 @@
+package cn.com.jdkj.customer.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class QuestionDto {
+    String qs;
+    String UUID;
+}

+ 14 - 0
src/main/java/cn/com/jdkj/customer/dto/RegisterDto.java

@@ -0,0 +1,14 @@
+package cn.com.jdkj.customer.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RegisterDto {
+    String username;
+    String password;
+    String code;
+}

+ 27 - 0
src/main/java/cn/com/jdkj/customer/entity/Customer.java

@@ -0,0 +1,27 @@
+package cn.com.jdkj.customer.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+
+@Data
+@TableName("t_customer")
+public class Customer extends Model<Customer> {
+
+    @TableId(type = IdType.AUTO)
+    Integer id;
+
+    String username;
+
+    String password;
+
+    Integer activeFlag;
+
+    Integer delFlag;
+
+    String nickName;
+
+    String code;
+}

+ 9 - 0
src/main/java/cn/com/jdkj/customer/mapper/CustomerMapper.java

@@ -0,0 +1,9 @@
+package cn.com.jdkj.customer.mapper;
+
+import cn.com.jdkj.customer.entity.Customer;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CustomerMapper extends BaseMapper<Customer> {
+}

+ 8 - 0
src/main/java/cn/com/jdkj/customer/service/BaiduService.java

@@ -0,0 +1,8 @@
+package cn.com.jdkj.customer.service;
+
+import java.io.InputStream;
+
+public interface BaiduService {
+
+    InputStream text2audio(String text);
+}

+ 17 - 0
src/main/java/cn/com/jdkj/customer/service/CustomerService.java

@@ -0,0 +1,17 @@
+package cn.com.jdkj.customer.service;
+
+import cn.com.jdkj.customer.dto.LoginDto;
+import cn.com.jdkj.customer.dto.QuestionDto;
+import cn.com.jdkj.customer.dto.RegisterDto;
+import cn.com.jdkj.customer.entity.Customer;
+import cn.com.jdkj.entity.ResultBean;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import javax.servlet.http.HttpServletResponse;
+
+public interface CustomerService extends IService<Customer> {
+    ResultBean login(LoginDto dto);
+    ResultBean register(RegisterDto dto);
+    ResultBean question(QuestionDto dto);
+    void questionToAudio(QuestionDto dto, HttpServletResponse response);
+}

+ 65 - 0
src/main/java/cn/com/jdkj/customer/service/imp/BaiduServiceImpl.java

@@ -0,0 +1,65 @@
+package cn.com.jdkj.customer.service.imp;
+
+import cn.com.jdkj.constant.TokenKey;
+import cn.com.jdkj.customer.service.BaiduService;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSONObject;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.stereotype.Service;
+
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class BaiduServiceImpl implements BaiduService {
+
+    final RedissonClient redisson;
+
+    @Override
+    public InputStream text2audio(String text) {
+        HttpRequest request = HttpRequest.get("http://tsn.baidu.com/text2audio");
+        String token = getToken();
+        log.info("baidu acess_token:{}",token);
+        request.form("tok",token);
+        request.form("tex",text);
+        request.form("cuid","10.0.60.37");
+        request.form("ctp","1");
+        request.form("lan","zh");
+        Long start = System.currentTimeMillis();
+        HttpResponse response = request.execute();
+        Long end = System.currentTimeMillis();
+//        log.info("response:{}",response.body());
+        log.info("转音频文本长度:{},耗时:{}ms",text.length(),end-start);
+        return response.bodyStream();
+    }
+
+    String getToken(){
+        RBucket<String> rBucket = redisson.getBucket(TokenKey.BAIDU_TOKEN);
+        if (rBucket.get()==null){
+            return getNewToken();
+        }else {
+            return rBucket.get();
+        }
+    }
+    String getNewToken(){
+        HttpRequest request = HttpRequest.get("https://aip.baidubce.com/oauth/2.0/token");
+        request.form("grant_type","client_credentials");
+        request.form("client_id","SQ8wQ4Fv44gvB3OLCZAoNY5T");
+        request.form("client_secret","U2m4OngU25sjDHH5p6y4oOGGohM2AVBF");
+        HttpResponse response = request.execute();
+        JSONObject jsonObject = JSONObject.parseObject(response.body());
+        Long expires_in = jsonObject.getLong("expires_in");
+        String token = jsonObject.getString("access_token");
+        RBucket<String> rBucket = redisson.getBucket(TokenKey.BAIDU_TOKEN);
+        rBucket.set(token,expires_in, TimeUnit.SECONDS);
+        log.info("baidu accessToken:{}",token);
+        return token;
+    }
+
+}

+ 145 - 0
src/main/java/cn/com/jdkj/customer/service/imp/CustomerServiceImpl.java

@@ -0,0 +1,145 @@
+package cn.com.jdkj.customer.service.imp;
+
+import cn.com.jdkj.config.RedissonConfig;
+import cn.com.jdkj.constant.TokenKey;
+import cn.com.jdkj.customer.dto.*;
+import cn.com.jdkj.customer.entity.Customer;
+import cn.com.jdkj.customer.mapper.CustomerMapper;
+import cn.com.jdkj.customer.service.BaiduService;
+import cn.com.jdkj.customer.service.CustomerService;
+import cn.com.jdkj.customer.vo.AIResponseBodyVo;
+import cn.com.jdkj.entity.ResultBean;
+import cn.com.jdkj.enums.AIMessageTypeEnums;
+import cn.com.jdkj.enums.ReturnCode;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StreamUtils;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {
+
+    final RedissonClient redisson;
+    final BaiduService baiduService;
+    @Override
+    public ResultBean login(LoginDto dto) {
+        Customer customer = getOne(Wrappers.<Customer>lambdaQuery().eq(Customer::getUsername,dto.getUsername()).eq(Customer::getDelFlag,0));
+        if (customer==null){
+            return ResultBean.error(ReturnCode.USER_NOT_EXSIT);
+        }
+        if (!Integer.valueOf(1).equals(customer.getActiveFlag())){
+            return ResultBean.error(ReturnCode.USER_NOT_ACTIVE);
+        }
+        if (!customer.getPassword().equals(dto.getPassword())){
+            return ResultBean.error(ReturnCode.PASSWORD_ERROR);
+        }
+        String uuid = null;
+        do{
+            uuid = UUID.randomUUID().toString().replace("-","");
+        }while (redisson.getBucket(TokenKey.USER_KEY_ID+uuid).get()!=null);
+        redisson.getBucket(TokenKey.USER_KEY_ID+uuid).set(customer.getId(),8, TimeUnit.HOURS);
+        return ResultBean.succsess(uuid);
+    }
+
+    @Override
+    public ResultBean register(RegisterDto dto) {
+        Long count = count(Wrappers.<Customer>lambdaQuery().eq(Customer::getUsername,dto.getUsername()).eq(Customer::getDelFlag,0));
+        if (count>0){
+            return ResultBean.error(ReturnCode.USERNAME_EXSIT);
+        }
+        // TODO: 2024/6/6 用户名违规
+        Customer customer = new Customer();
+        BeanUtils.copyProperties(dto,customer);
+        customer.setActiveFlag(1);
+        customer.setDelFlag(0);
+        customer.insert();
+        LoginDto loginDto = new LoginDto();
+        loginDto.setUsername(dto.getUsername());
+        loginDto.setPassword(dto.getPassword());
+        return login(loginDto);
+    }
+    boolean checkUUID(String uuid){
+        RBucket rBucket = redisson.getBucket(TokenKey.USER_KEY_ID+uuid);
+        if (rBucket.get()==null){
+            return false;
+        }
+        return true;
+    }
+    @Override
+    public ResultBean question(QuestionDto dto) {
+        //验证uuid
+        if (!checkUUID(dto.getUUID())){
+            return ResultBean.error(ReturnCode.UUID_ERROR);
+        }
+        return ResultBean.succsess(question(dto.getQs()));
+    }
+
+    String question(String text){
+        HttpRequest request = HttpRequest.post("https://book.9jodia.net/v1/chat/completions");
+        request.header("Authorization","Bearer sk-w6IHvBqZBvrHfSFg23217c734c7247C990C5F528D66a6691");
+        AIBodyDto body = new AIBodyDto();
+        AIMessageDto sys = new AIMessageDto();
+        sys.setContent("你是一个工作助手,请精简回答问题,回答字数不超过100字");
+        sys.setRole(AIMessageTypeEnums.system.getCode());
+        AIMessageDto messageDto = new AIMessageDto();
+        messageDto.setContent(text);
+        messageDto.setRole(AIMessageTypeEnums.user.getCode());
+        List<AIMessageDto> messages = ListUtil.of(sys,messageDto);
+        body.setMessages(messages);
+        request.body(JSONObject.toJSONString(body));
+        Long start = System.currentTimeMillis();
+        HttpResponse response = request.execute();
+        Long end = System.currentTimeMillis();
+        log.info("问题长度:{},耗时:{}ms",text.length(),end-start);
+//        log.info("response:{}",response);
+        AIResponseBodyVo responseBodyVo = JSONObject.parseObject(response.body()).toJavaObject(AIResponseBodyVo.class);
+        StringBuffer sb = new StringBuffer();
+        responseBodyVo.getChoices().forEach(item->{
+            sb.append(item.getMessage().getContent());
+        });
+        return sb.toString();
+    }
+
+    @Override
+    public void questionToAudio(QuestionDto dto, HttpServletResponse response) {
+        //验证uuid
+        if (!checkUUID(dto.getUUID())){
+            ResultBean.error(ReturnCode.UUID_ERROR);
+        }
+        InputStream inputStream = baiduService.text2audio(question(dto.getQs()));
+        try {
+            byte[] data = new byte[1024];
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition","attachment; filename=\""+System.currentTimeMillis()+".mp3\"");
+            response.setHeader("accept-Ranges","bytes");
+            int read = 0;
+            while ((read=inputStream.read(data))!=-1){
+                response.getOutputStream().write(data,0,read);
+            }
+            response.getOutputStream().flush();
+        }catch (Exception e){
+            log.error("copy stream error:{}",e.getMessage(),e);
+        }
+    }
+
+}

+ 15 - 0
src/main/java/cn/com/jdkj/customer/vo/AIResponseBodyVo.java

@@ -0,0 +1,15 @@
+package cn.com.jdkj.customer.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AIResponseBodyVo {
+    String id;
+    String model;
+    String object;
+    Long created;
+    List<ChoiceVo> choices;
+    UsageVo usage;
+}

+ 9 - 0
src/main/java/cn/com/jdkj/customer/vo/AiMessageVo.java

@@ -0,0 +1,9 @@
+package cn.com.jdkj.customer.vo;
+
+import lombok.Data;
+
+@Data
+public class AiMessageVo {
+    String role;
+    String content;
+}

+ 12 - 0
src/main/java/cn/com/jdkj/customer/vo/ChoiceVo.java

@@ -0,0 +1,12 @@
+package cn.com.jdkj.customer.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ChoiceVo {
+    Integer index;
+    AiMessageVo message;
+    String finish_reason;
+}

+ 10 - 0
src/main/java/cn/com/jdkj/customer/vo/UsageVo.java

@@ -0,0 +1,10 @@
+package cn.com.jdkj.customer.vo;
+
+import lombok.Data;
+
+@Data
+public class UsageVo {
+    Integer prompt_tokens;
+    Integer completion_tokens;
+    Integer total_tokens;
+}

+ 37 - 0
src/main/java/cn/com/jdkj/entity/ResultBean.java

@@ -0,0 +1,37 @@
+package cn.com.jdkj.entity;
+
+import cn.com.jdkj.enums.ReturnCode;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultBean<T> {
+
+    @ApiModelProperty("返回码")
+    private Integer code;
+
+    @ApiModelProperty("返回信息")
+    private String message;
+
+    @ApiModelProperty("数据")
+    private T data;
+    public static <T>ResultBean succsess(){
+        return new ResultBean(ReturnCode.SUCCESS.getCode(),"",null);
+    }
+    public static <T>ResultBean succsess(T data){
+        return new ResultBean(ReturnCode.SUCCESS.getCode(),"",data);
+    }
+    public static <T>ResultBean succsess(T data,String message){
+        return new ResultBean(ReturnCode.SUCCESS.getCode(),message,data);
+    }
+    public static ResultBean error(ReturnCode code){
+        return new ResultBean(code.getCode(),code.getMessage(),null);
+    }
+    public static ResultBean error(Integer code,String message){
+        return new ResultBean(code,message,null);
+    }
+}

+ 15 - 0
src/main/java/cn/com/jdkj/enums/AIMessageTypeEnums.java

@@ -0,0 +1,15 @@
+package cn.com.jdkj.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum AIMessageTypeEnums {
+    system("system","它设定了 AI 的行为和角色,和背景,可以帮助设定对话的语境,以便 AI 更好地理解其在对话中的角色"),
+    user("user","就是我们输入的问题或请求"),
+    assistant("assistant","指的是模型自己,ChatGPT它自己的回答"),
+    ;
+    private String code;
+    private String desc;
+}

+ 23 - 0
src/main/java/cn/com/jdkj/enums/ReturnCode.java

@@ -0,0 +1,23 @@
+package cn.com.jdkj.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum ReturnCode {
+
+    SUCCESS(200,"成功"),
+    USER_NOT_ACTIVE(400,"账号登录失败,账号未激活。"),
+    PASSWORD_ERROR(301,"密码错误,或账号错误。"),
+    USER_NOT_EXSIT(302,"账号不存在请注册。"),
+    REGISTER_ERROR(400,"账号注册失败"),
+    USERNAME_EXSIT(301,"当前账号已存在。请更换用户名注册。"),
+    USERNAME_ERROR(302,"当前账号名称违规,请更换用户名注册"),
+    UUID_ERROR(301,"UUID失效"),
+    SIGN_ERROR(300,"无效签名"),
+    ;
+
+    private Integer code;
+    private String message;
+}

+ 37 - 0
src/main/java/cn/com/jdkj/exception/CustomException.java

@@ -0,0 +1,37 @@
+package cn.com.jdkj.exception;
+
+
+import cn.com.jdkj.enums.ReturnCode;
+
+/**
+ * 自定义异常类
+ *
+ * @author HuangChendi
+ */
+public class CustomException extends RuntimeException {
+
+    private static final long serialVersionUID = -4290208105450474741L;
+
+    private Integer code;
+
+    private Object data;
+
+    public CustomException(ReturnCode returnCode) {
+        super(returnCode.getMessage());
+        this.code = returnCode.getCode();
+    }
+
+    public CustomException(ReturnCode returnCode,Object obj) {
+        super(returnCode.getMessage());
+        this.code = returnCode.getCode();
+        this.data = obj;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public Object getData() {
+        return data;
+    }
+}

+ 36 - 0
src/main/java/cn/com/jdkj/exception/GlobalExceptionHandler.java

@@ -0,0 +1,36 @@
+package cn.com.jdkj.exception;
+
+import cn.com.jdkj.constant.ReturnCode;
+import cn.com.jdkj.entity.ResultBean;
+import cn.dev33.satoken.exception.NotLoginException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.support.DefaultMessageSourceResolvable;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.validation.BindException;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.multipart.support.MissingServletRequestPartException;
+
+import javax.validation.ConstraintViolationException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 全局异常捕获处理并返回信息
+ *
+ * @author HuangChendi
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @ExceptionHandler({CustomException.class})
+    public ResultBean<?> customException(CustomException e) {
+        return ResultBean.error(e.getCode(),e.getMessage());
+    }
+}

+ 56 - 0
src/main/java/cn/com/jdkj/handler/JsonLongArrayTypeHandler.java

@@ -0,0 +1,56 @@
+package cn.com.jdkj.handler;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.SneakyThrows;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Mybatis数组,符串互转
+ * <p>
+ * MappedJdbcTypes 数据库中的数据类型 MappedTypes java中的的数据类型
+ *
+ * @author xuzihui
+ * @date 2019-11-20
+ */
+@MappedTypes(value = { Long[].class })
+@MappedJdbcTypes(value = JdbcType.VARCHAR)
+public class JsonLongArrayTypeHandler extends BaseTypeHandler<Long[]> {
+
+	@Override
+	public void setNonNullParameter(PreparedStatement ps, int i, Long[] parameter, JdbcType jdbcType)
+			throws SQLException {
+		ps.setString(i, ArrayUtil.join(parameter, StrUtil.COMMA));
+	}
+
+	@Override
+	@SneakyThrows
+	public Long[] getNullableResult(ResultSet rs, String columnName) {
+		String reString = rs.getString(columnName);
+		return Convert.toLongArray(reString);
+	}
+
+	@Override
+	@SneakyThrows
+	public Long[] getNullableResult(ResultSet rs, int columnIndex) {
+		String reString = rs.getString(columnIndex);
+		return Convert.toLongArray(reString);
+	}
+
+	@Override
+	@SneakyThrows
+	public Long[] getNullableResult(CallableStatement cs, int columnIndex) {
+		String reString = cs.getString(columnIndex);
+		return Convert.toLongArray(reString);
+	}
+
+}

+ 56 - 0
src/main/java/cn/com/jdkj/handler/JsonStringArrayTypeHandler.java

@@ -0,0 +1,56 @@
+package cn.com.jdkj.handler;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.SneakyThrows;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Mybatis数组,符串互转
+ * <p>
+ * MappedJdbcTypes 数据库中的数据类型 MappedTypes java中的的数据类型
+ *
+ * @author xuzihui
+ * @date 2019-11-20
+ */
+@MappedTypes(value = { String[].class })
+@MappedJdbcTypes(value = JdbcType.VARCHAR)
+public class JsonStringArrayTypeHandler extends BaseTypeHandler<String[]> {
+
+	@Override
+	public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType)
+			throws SQLException {
+		ps.setString(i, ArrayUtil.join(parameter, StrUtil.COMMA));
+	}
+
+	@Override
+	@SneakyThrows
+	public String[] getNullableResult(ResultSet rs, String columnName) {
+		String reString = rs.getString(columnName);
+		return Convert.toStrArray(reString);
+	}
+
+	@Override
+	@SneakyThrows
+	public String[] getNullableResult(ResultSet rs, int columnIndex) {
+		String reString = rs.getString(columnIndex);
+		return Convert.toStrArray(reString);
+	}
+
+	@Override
+	@SneakyThrows
+	public String[] getNullableResult(CallableStatement cs, int columnIndex) {
+		String reString = cs.getString(columnIndex);
+		return Convert.toStrArray(reString);
+	}
+
+}

+ 37 - 0
src/main/java/cn/com/jdkj/handler/LocalDateTimeTypeHandler.java

@@ -0,0 +1,37 @@
+package cn.com.jdkj.handler;
+
+
+import org.apache.ibatis.type.JdbcType;
+import org.springframework.stereotype.Component;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.LocalDateTime;
+
+@Component
+public class LocalDateTimeTypeHandler extends org.apache.ibatis.type.LocalDateTimeTypeHandler {
+
+    public LocalDateTimeTypeHandler(){}
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException {
+        ps.setObject(i, parameter);
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return (LocalDateTime)rs.getObject(columnName, LocalDateTime.class);
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return (LocalDateTime)rs.getObject(columnIndex, LocalDateTime.class);
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return (LocalDateTime)cs.getObject(columnIndex, LocalDateTime.class);
+    }
+}

+ 145 - 0
src/main/java/cn/com/jdkj/interceptor/BodyReaderHttpServletRequestWrapper.java

@@ -0,0 +1,145 @@
+package cn.com.jdkj.interceptor;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.*;
+
+/**
+ * 保存过滤器里面的流
+ * @author yangy
+ *
+ */
+@Slf4j
+public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
+
+    private final byte[] body;
+
+    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
+        super(request);
+        String sessionStream = getBodyString(request);
+        body = sessionStream.getBytes(Charset.forName("UTF-8"));
+    }
+
+    /**
+     * 获取请求Body
+     */
+    public String getBodyString(final ServletRequest request) {
+        StringBuilder sb = new StringBuilder();
+        try (
+            InputStream inputStream = cloneInputStream(request.getInputStream());
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))
+        ) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                sb.append(line);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Description: 复制输入流</br>
+     */
+    public InputStream cloneInputStream(ServletInputStream inputStream) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        try {
+            while ((len = inputStream.read(buffer)) > -1) {
+                byteArrayOutputStream.write(buffer, 0, len);
+            }
+            byteArrayOutputStream.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+    }
+
+    @Override
+    public BufferedReader getReader() {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+
+            @Override
+            public int read() {
+                return bais.read();
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+			@Override
+			public void setReadListener(ReadListener listener) {
+				// TODO Auto-generated method stub
+				log.info("setReadListener--设置读监听器");
+			}
+        };
+    }
+
+
+    private Map<String, String> headerMap = new HashMap<String, String>();
+
+    /**
+     * add a header with given name and value
+     *
+     * @param name
+     * @param value
+     */
+    public void addHeader(String name, String value) {
+        headerMap.put(name, value);
+    }
+
+    @Override
+    public String getHeader(String name) {
+        String headerValue = super.getHeader(name);
+        if (headerMap.containsKey(name)) {
+            headerValue = headerMap.get(name);
+        }
+        return headerValue;
+    }
+
+    /**
+     * get the Header names
+     */
+    @Override
+    public Enumeration<String> getHeaderNames() {
+        List<String> names = Collections.list(super.getHeaderNames());
+        for (String name : headerMap.keySet()) {
+            names.add(name);
+        }
+        return Collections.enumeration(names);
+    }
+
+    @Override
+    public Enumeration<String> getHeaders(String name) {
+        List<String> values = Collections.list(super.getHeaders(name));
+        if (headerMap.containsKey(name)) {
+            values.add(headerMap.get(name));
+        }
+        return Collections.enumeration(values);
+    }
+
+
+}

+ 61 - 0
src/main/java/cn/com/jdkj/interceptor/FrontInterceptor.java

@@ -0,0 +1,61 @@
+package cn.com.jdkj.interceptor;
+
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+/**
+ *
+ * @ClassName: FrontInterceptor
+ * @Description: 全局前置拦截器
+ * @Author jyy
+ * @DateTime 2022年3月29日 上午9:35:14
+ */
+public class FrontInterceptor extends HandlerInterceptorAdapter implements ApplicationContextAware {
+
+	private static final Logger log = LoggerFactory.getLogger(FrontInterceptor.class);
+
+	private static final String UNIQUE_ID = "traceId";
+	// 必须声明为static
+	private static ApplicationContext context;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+			throws Exception {
+
+    	String traceID = request.getHeader("TRACE_ID");
+		if(StringUtils.isEmpty(traceID))
+			traceID = UUID.randomUUID().toString().replace("-", "");
+		MDC.put(UNIQUE_ID, traceID);
+
+		//log.info(request.getRequestURI() + " ->> request ip:" + request.getRemoteHost() + ": " + request.getRemotePort()
+		//+ " BIRD-MAC-ADDRESS:" + request.getHeader("BIRD-MAC-ADDRESS"));
+
+		return true;
+
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		if (context == null) {
+			context = applicationContext;
+		}
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
+		MDC.remove(UNIQUE_ID);
+	}
+
+}

+ 99 - 0
src/main/java/cn/com/jdkj/util/DateUtils.java

@@ -0,0 +1,99 @@
+package cn.com.jdkj.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class DateUtils {
+	public final static String formatYYMMDD = "yyyy-MM-dd";
+
+	public final static String formatYYMMDD2 = "yyyyMMdd";
+
+	public final static String formatYYMM = "yyyy-MM";
+
+	public final static String formatYM = "yyyyMM";
+
+	public final static String formatHHmm = "HH:mm";
+
+	public final static String formatHHmmss = "HH:mm:ss";
+
+	public final static String formatYYMMDDHHmmss = "yyyy-MM-dd HH:mm:ss";
+
+	public final static String formatYYYYMMDDHHmmss = "yyyyMMddHHmmss";
+
+	public final static String formatYYMMDDHHmmssSSS = "yyyyMMddHHmmssSSS";
+
+	public final static String formatYMForTable = "yyyy_MM";
+
+	public final static String formatYMDDForTable = "yyyy_MM_dd";
+
+	// 获取某一天的零点
+	public static Date getDateZero(Date date) {
+		if(date == null){
+			return date;
+		}
+		Calendar calendar = Calendar.getInstance(); // 得到日历
+		calendar.setTime(date);// 把当前时间赋给日历
+		// 将小时至0
+		calendar.set(Calendar.HOUR_OF_DAY, 0);
+		// 将分钟至0
+		calendar.set(Calendar.MINUTE, 0);
+		// 将秒至0
+		calendar.set(Calendar.SECOND, 0);
+		// 将毫秒至0
+		calendar.set(Calendar.MILLISECOND, 0);
+		return calendar.getTime();
+	}
+
+	// 获取某一天的二十三点五十九分五十九秒
+	public static Date getDateTwentyFour(Date date) {
+		if(date == null){
+			return date;
+		}
+		Calendar calendar = Calendar.getInstance(); // 得到日历
+		calendar.setTime(date);// 把当前时间赋给日历
+		// 将小时至23
+		calendar.set(Calendar.HOUR_OF_DAY, 23);
+		// 将分钟至59
+		calendar.set(Calendar.MINUTE, 59);
+		// 将秒至59
+		calendar.set(Calendar.SECOND, 59);
+		// 将毫秒至0
+		calendar.set(Calendar.MILLISECOND, 0);
+		return calendar.getTime();
+	}
+
+
+
+	/**
+	 * @Title: formatDate @Description: 转换时间格式 @param @param date @param @param
+	 * format @param @return 参数说明 @return String 返回类型 @throws
+	 */
+	public static String formatDate(Date date, String format) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	public static Date StringToDate(String dateStr) throws ParseException {
+		if(dateStr ==null){
+			return null;
+		}
+		SimpleDateFormat sf = new SimpleDateFormat(formatYYMMDD);
+			//使用SimpleDateFormat的parse()方法生成Date
+			Date date = sf.parse(dateStr);
+			//打印Date
+			System.out.println(date);
+			return date;
+	}
+
+	public static Date strToDate(String str, String format) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		try {
+			return sdf.parse(str);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}

+ 56 - 0
src/main/java/cn/com/jdkj/util/SpringUtils.java

@@ -0,0 +1,56 @@
+package cn.com.jdkj.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.LocaleResolver;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Locale;
+
+@Component
+public class SpringUtils implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        if (SpringUtils.applicationContext == null) {
+            SpringUtils.applicationContext = applicationContext;
+        }
+    }
+
+    public static <T> T getBean(Class<T> tClass){
+        return applicationContext.getBean(tClass);
+    }
+
+    public static <T> T getBean(String name, Class<T> type) {
+        return applicationContext.getBean(name, type);
+    }
+
+    public static HttpServletRequest getCurrentReq() {
+        ServletRequestAttributes requestAttrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (requestAttrs == null) {
+            return null;
+        }
+        return requestAttrs.getRequest();
+    }
+
+    public static String getMessage(String code, Object... args) {
+        LocaleResolver localeResolver = getBean(LocaleResolver.class);
+        Locale locale = localeResolver.resolveLocale(getCurrentReq());
+        return applicationContext.getMessage(code, args, locale);
+    }
+
+    /**
+     * 获取当前环境
+     */
+    public static String getActiveProfile() {
+        return applicationContext.getEnvironment().getActiveProfiles()[0];
+    }
+
+}
+

+ 285 - 0
src/main/java/cn/com/jdkj/util/StringUtils.java

@@ -0,0 +1,285 @@
+package cn.com.jdkj.util;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Pattern;
+
+/**
+ * 字符串相关工具类
+ *
+ * @author HuangChendi
+ */
+public abstract class StringUtils extends org.springframework.util.StringUtils {
+
+    public static String generateCode() {
+        String result = "";
+        Random random = new Random();
+        for (int i = 0; i < 20; i++) {
+            result += random.nextInt(10);
+        }
+        return result;
+    }
+
+    public static String generateCode(int length) {
+        String result = "";
+        Random random = new Random();
+        for (int i = 0; i < length; i++) {
+            result += random.nextInt(10);
+        }
+        return result;
+    }
+
+    /**
+     * 处理逗号分隔的字符串
+     *
+     * @param str
+     * @return
+     */
+    public static String dealString(String str) {
+        String res = "";
+        if (!isEmpty(str)) {
+            String[] ids = str.split(",");
+            for (String id : ids) {
+                if (!isEmpty(id))
+                    res = res.length() == 0 ? id : res + "," + id;
+            }
+        }
+        return res;
+    }
+
+    /**
+     * 处理逗号分隔的字符串
+     *
+     * @param str
+     * @return
+     */
+    public static List<Integer> splitString(String str) {
+        List<Integer> res = new ArrayList<>();
+        if (!isEmpty(str)) {
+            String[] ids = str.split(",");
+            for (String id : ids) {
+                id = id.replaceAll(" ", "");
+                if (!StringUtils.isEmpty(id)) {
+                    res.add(Integer.valueOf(id));
+                }
+            }
+        }
+        return res;
+    }
+
+    /**
+     * 处理逗号分隔的字符串
+     *
+     * @param str
+     * @return
+     */
+    public static String dealString(List<?> ids) {
+        String res = "";
+        for (Object id : ids) {
+            if (!StringUtils.isEmpty(id))
+                res = res.length() == 0 ? id + "" : res + "," + id;
+        }
+        return res;
+    }
+
+    public static String dealString(Object[] ids) {
+        String res = "";
+        for (Object id : ids) {
+            if (!StringUtils.isEmpty(id))
+                res = res.length() == 0 ? id + "" : res + "," + id;
+        }
+        return res;
+    }
+
+    /**
+     * 判断是否为整数
+     *
+     * @param str 传入的字符串
+     * @return 是整数返回true, 否则返回false
+     */
+    public static boolean isInteger(String str) {
+        Pattern pattern = Pattern.compile("^[\\d]*$");
+        return pattern.matcher(str).matches();
+    }
+
+    /**
+     * @param @param  number
+     * @param @return 设定文件
+     * @return Object    返回类型
+     * @throws
+     * @Description: 判断数字是否是整数
+     */
+    public static Boolean getNumber(Float number) {
+        if (number.intValue() - number.floatValue() == 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * 判断传入参数,如果是Null或者空值,返回false,不为空返回true
+     *
+     * @param checkAll True:所有的为空才返回,False:只要有一个为空返回
+     * @param strings
+     * @return
+     */
+    public static Boolean checkNull(Boolean checkAll, Object... objects) {
+        Boolean ret = true;
+        if (objects == null) return false;
+        for (Object s : objects) {
+            if (null == s || ("").equals(s.toString().trim())) {
+                if (!checkAll)
+                    return false;
+                else {
+                    ret = false;
+                }
+            }
+        }
+        return ret;
+    }
+
+    public static int getMax(String[] arr) {
+        int max = Integer.valueOf(arr[0]);
+        for (int x = 1; x < arr.length; x++) {
+            if (Integer.valueOf(arr[x]) > max)
+                max = Integer.valueOf(arr[x]);
+        }
+        return max;
+    }
+
+    public static int getMin(String[] arr) {
+        int min = Integer.valueOf(arr[0]);
+        for (int x = 1; x < arr.length; x++) {
+            if (Integer.valueOf(arr[x]) < min)
+                min = Integer.valueOf(arr[x]);
+        }
+        return min;
+    }
+
+    /**
+     * 生成规则序号
+     *
+     * @param equipmentType 设备类型
+     * @param equipmentNo   最新设备编号
+     * @return
+     */
+    public static String getNewEquipmentNo(String equipmentNo) {
+        String newEquipmentNo = "001";
+        if (equipmentNo != null && !equipmentNo.isEmpty()) {
+            int newEquipment = Integer.parseInt(equipmentNo) + 1;
+            newEquipmentNo = String.format("%03d", newEquipment);
+        }
+        return newEquipmentNo;
+    }
+
+    /**
+     * 截取字符串的最后几位
+     *
+     * @param len 截取的长度
+     * @param str 被截取的字符串
+     * @return
+     */
+    public static String getSubString(int len, String str) {
+        String substring = str.substring(str.length() - len, str.length());
+        return substring;
+    }
+
+    /**
+     * @param @param  v1
+     * @param @param  v2
+     * @param @return 参数说明
+     * @return int    返回类型
+     * @throws
+     * @Title: compareVersion
+     * @Description: TODO(字符串版本号比较大小)
+     */
+    public static int compareVersion(String v1, String v2) {
+        if (v1.equals(v2)) {
+            return 0;
+        }
+        String[] version1Array = v1.split("[._]");
+        String[] version2Array = v2.split("[._]");
+        int index = 0;
+        int minLen = Math.min(version1Array.length, version2Array.length);
+        long diff = 0;
+
+        while (index < minLen
+                && (diff = Long.parseLong(version1Array[index])
+                - Long.parseLong(version2Array[index])) == 0) {
+            index++;
+        }
+        if (diff == 0) {
+            for (int i = index; i < version1Array.length; i++) {
+                if (Long.parseLong(version1Array[i]) > 0) {
+                    return 1;
+                }
+            }
+
+            for (int i = index; i < version2Array.length; i++) {
+                if (Long.parseLong(version2Array[i]) > 0) {
+                    return -1;
+                }
+            }
+            return 0;
+        } else {
+            return diff > 0 ? 1 : -1;
+        }
+
+    }
+
+
+
+    // 拼接字符串
+    public static String concatenatedString(String... str) {
+        StringBuilder sb = new StringBuilder();
+        for (String s : str) {
+            if (null != s && !s.isEmpty()) {
+                sb.append(s);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static boolean isNotEmpty(String macAddr) {
+        return !isEmpty(macAddr);
+    }
+
+    public static String buildOrderNumber() {
+        String orderNum = new SimpleDateFormat("yyyyMMdd").format(new Date()) + StringUtils.generateCode();
+        return orderNum;
+    }
+
+    public static String getOrderNum() {
+        String orderNum = new SimpleDateFormat("yyyyMMdd").format(new Date()) + StringUtils.generateCode();
+        return orderNum;
+    }
+
+
+    public static String encryptToMD5(String str) {
+        return DigestUtils.md5Hex(str);
+    }
+
+    //静态变量存储最大值
+    private static final AtomicInteger ATOMIC_NUM = new AtomicInteger(0);
+
+    /**
+     * @return int
+     * 注:此方法并没有使用synchronized进行同步,因为共享的编号自增操作是原子操作,线程安全的
+     * @Author javaloveiphone
+     * @Description :获取最新分组编号
+     */
+    public static String getNewAutoNum() {
+        //线程安全的原子操作,所以此方法无需同步
+        int newNum = ATOMIC_NUM.incrementAndGet();
+        //数字长度为5位,长度不够数字前面补0
+        return String.format("%05d", newNum);
+    }
+}

+ 120 - 0
src/main/java/cn/com/jdkj/util/WeiXinUtils.java

@@ -0,0 +1,120 @@
+package cn.com.jdkj.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+
+public class WeiXinUtils {
+
+	private  final Logger log = LoggerFactory.getLogger(getClass());
+
+
+	/**
+	 * 编写Get请求的方法。但没有参数传递的时候,可以使用Get请求
+	 *
+	 * @param url
+	 *            需要请求的URL
+	 * @return 将请求URL后返回的数据,转为JSON格式,并return
+	 */
+	public static JSONObject doGetStr(String url) throws ClientProtocolException, IOException {
+//		DefaultHttpClient client = new DefaultHttpClient();// 获取DefaultHttpClient请求
+		CloseableHttpClient client =  HttpClients.createDefault();
+		HttpGet httpGet = new HttpGet(url);// HttpGet将使用Get方式发送请求URL
+		JSONObject jsonObject = null;
+		HttpResponse response = client.execute(httpGet);// 使用HttpResponse接收client执行httpGet的结果
+		HttpEntity entity = response.getEntity();// 从response中获取结果,类型为HttpEntity
+		if (entity != null) {
+			String result = EntityUtils.toString(entity, "UTF-8");// HttpEntity转为字符串类型
+			// jsonObject = JSONObject.fromObject(result);//字符串类型转为JSON类型
+			jsonObject = JSON.parseObject(result);
+		}
+		return jsonObject;
+	}
+
+	/**
+	 * 编写Post请求的方法。当我们需要参数传递的时候,可以使用Post请求
+	 *
+	 * @param url
+	 *            需要请求的URL
+	 * @param outStr
+	 *            需要传递的参数
+	 * @return 将请求URL后返回的数据,转为JSON格式,并return
+	 */
+	public static JSONObject doPostStr(String url, String outStr) throws ClientProtocolException, IOException {
+//		DefaultHttpClient client = new DefaultHttpClient();// 获取DefaultHttpClient请求
+//		HttpClient client = new DefaultHttpClient();
+		CloseableHttpClient client =  HttpClients.createDefault();
+		HttpPost httpost = new HttpPost(url);// HttpPost将使用Post方式发送请求URL
+		JSONObject jsonObject = null;
+		httpost.setEntity(new StringEntity(outStr, "UTF-8"));// 使用setEntity方法,将我们传进来的参数放入请求中
+		HttpResponse response = client.execute(httpost);// 使用HttpResponse接收client执行httpost的结果
+		String result = EntityUtils.toString(response.getEntity(), "UTF-8");// HttpEntity转为字符串类型
+		// jsonObject = JSONObject.fromObject(result);//字符串类型转为JSON类型
+		jsonObject = JSON.parseObject(result);
+		return jsonObject;
+	}
+
+
+
+
+
+
+	/**
+	 * 数据流输出
+	 *
+	 * @param outputStream
+	 * @param text
+	 * @return
+	 */
+	public static boolean outputStreamWrite(OutputStream outputStream, String text) {
+		try {
+			outputStream.write(text.getBytes("utf-8"));
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return false;
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+
+	/*
+	/**
+	 * 回复微信服务器"文本消息"
+	 *
+	 * @param response
+	 * @param returnvaleue
+	 */
+	public static void output(HttpServletResponse response, String returnvaleue) {
+		try {
+			PrintWriter pw = response.getWriter();
+			pw.write(returnvaleue);
+			pw.flush();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+
+}

+ 53 - 0
src/main/resources/bootstrap-debug1.yml

@@ -0,0 +1,53 @@
+spring:
+  application:
+    name: little-scholar
+  redis:
+    host: 162.14.78.61
+    port: 3306
+    password: ditai_debug
+    database: 0
+    connection-pool-size: 64
+    connection-minimum-idle-size: 10
+  redisson:
+    address: redis://162.14.78.61:3306
+    password: ditai_debug
+    database: 0
+  http:
+    encoding:
+      force-response: true
+  cloud:
+    nacos:
+      config:
+        #group: dev
+        namespace: 9fafe3a0-a48f-4dcb-a027-ecc3bc95c6f1
+        server-addr: 172.16.62.251:8848
+        file-extension: yaml
+        prefix: ${spring.application.name}
+        enabled: true # 是否开启
+        refresh-enabled: true # 是否开启自动刷新
+      discovery:
+        #group: dev
+        namespace: 9fafe3a0-a48f-4dcb-a027-ecc3bc95c6f1
+        server-addr: 172.16.62.251:8848
+  profiles:
+    active: debug1
+  servlet:
+    multipart:
+      max-file-size: 30MB  #单个数据大小
+      max-request-size: 35MB #总数据大小
+settlement:
+  save-path: /mydata/appuser/runtime/leisure/settlement
+  company: "浙江波星通卫星通信有限公司"
+  invoice-type: "增值税专⽤发票"
+  taxpayer-id: "91330903MA28K3BX5N"
+  bank: "浦发银行宁波奉化支行 94190078801700000285"
+  tel: "浙江省宁波市奉化区岳林街道秀水路168号 0574-88689916"
+  taxable-services: "可选择“⼴告费”“⼴告发布费”“微信⼴告费”“微信推⼴费”“服务费”等相关类⽬"
+
+weixin:
+  gzh:
+    appid: wxf0b4d0aedc317ab4
+    appsecret: ce2030c79af87b116f1118aa346cebf4
+
+stardance:
+  url: http://debugstar.mstardance.com/starmini/

Разлика између датотеке није приказан због своје велике величине
+ 273 - 0
src/main/resources/bootstrap-dev.yml


Разлика између датотеке није приказан због своје велике величине
+ 312 - 0
src/main/resources/bootstrap-dev1.yml


+ 152 - 0
src/main/resources/bootstrap-dev2.yml

@@ -0,0 +1,152 @@
+spring:
+  application:
+    name: little-scholar
+  http:
+    encoding:
+      force-response: true
+  cloud:
+    nacos:
+      config:
+        enabled: false
+      discovery:
+        enabled: false
+  profiles:
+    active: dev1
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 150MB
+
+  datasource:
+    # 动态数据源配置
+    dynamic:
+      # 指定默认数据源名称
+      primary: incrementdb
+
+    # 分表配置
+  shardingsphere:
+    datasource:
+      names: incrementdb
+      incrementdb:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        url: jdbc:mysql://101.132.243.1:3306/incrementdb_test1?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&useAffectedRows=true&serverTimezone=Asia/Shanghai
+        username: increment
+        password: increment6200
+        druid:
+          initial-size: 5
+          min-idle: 5
+          max-active: 20
+          max-wait: 60000
+          timeBetweenEvictionRunsMillis: 60000
+          minEvictableIdleTimeMillis: 300000
+          validationQuery: SELECT 1 FROM DUAL
+          testWhileIdle: true
+          testOnBorrow: false
+          testOnReturn: false
+          poolPreparedStatements: true
+          maxPoolPreparedStatementPerConnectionSize: 20
+          filter:
+            stat:
+              slow-sql-millis: 5000
+              merge-sql: true
+
+    props:
+      sql.show: false
+  redis:
+    database: 6
+    host: 47.100.78.149
+    port: 6379
+    password: seafood,.*#1206
+    timeout: 5000
+    lettuce:
+      pool:
+        # 连接池最大连接数
+        max-active: 200
+        # 连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+        # 连接池中的最大空闲连接
+        max-idle: 10
+        # 连接池中的最小空闲连接
+        min-idle: 0
+
+singleServerConfig:
+  address: "redis://47.100.78.149:6379"
+  password: seafood,.*#1206
+  clientName: null
+  database: 7 #选择使用哪个数据库0~15
+  idleConnectionTimeout: 10000
+  pingTimeout: 1000
+  connectTimeout: 10000
+  timeout: 3000
+  retryAttempts: 3
+  retryInterval: 1500
+  reconnectionTimeout: 3000
+  failedAttempts: 3
+  subscriptionsPerConnection: 5
+  subscriptionConnectionMinimumIdleSize: 1
+  subscriptionConnectionPoolSize: 50
+  connectionMinimumIdleSize: 32
+  connectionPoolSize: 64
+  dnsMonitoringInterval: 5000
+  #dnsMonitoring: false
+
+threads: 0
+nettyThreads: 0
+codec:
+  class: "org.redisson.codec.JsonJacksonCodec"
+transportMode: "NIO"
+wx:
+  pay:
+    appId: wx1fa5b9f727905c88
+    mchId: 1534620861
+    #mchKey: ce2030c79af87b116f1118aa346cebf4
+    mchkey: 202cb962ac59075b964b07152d234b70
+    #subAppId: #服务商模式下的子商户公众账号ID
+    #subMchId: #服务商模式下的子商户号
+    # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    keyPath: classpath:cert/apiclient_cert.p12
+    notifyUrl: http://debug1.boxingtong.net:5222/increase/Diamond/notify
+  mp:
+    appId: wx1fa5b9f727905c88
+    secret: d81bef312229d28755fe8e59e851068a
+    token:
+    aesKey:
+
+app:
+  diamond:
+    url: http://47.100.2.204/v2/app/center/BxtUserRecharge
+    app_id: 75732768099341125371
+    app_secret: j3wfx4khkx773t8lv3q4gncrkkey37nx
+  agent:
+    legend:
+      host: http://47.101.152.150:9999/admin/legendGame/getRechargeAmount
+      secret: 123543refdghtrytrfghuytr
+  bobo:
+    host: http://106.14.146.163:8088
+    secret: bT1b67G96zIERl9Q%w10vYItSmx$Kzl^
+  shacheng:
+    host: http://121.36.195.133:8081
+    secret: bT1b67G96zIERl9Q%w10vYItSmx$Kzl^
+
+
+
+
+weixin:
+  gzh:
+    appid: wx1fa5b9f727905c88
+    appsecret: d81bef312229d28755fe8e59e851068a
+
+xingHuo:
+  game:
+    url: http://debugstar.mashangyl.com
+
+
+gouwan:
+  game:
+    menggui:
+      url: http://cdn.gamejiang.com/games/boxgames/53-tangping2-3/h5-game/index.html
+
+
+stardance:
+  url: http://debugstar.mstardance.com/starmini/

Разлика између датотеке није приказан због своје велике величине
+ 313 - 0
src/main/resources/bootstrap-devLocal.yml


Разлика између датотеке није приказан због своје велике величине
+ 320 - 0
src/main/resources/bootstrap-prod.yml


+ 34 - 0
src/main/resources/bootstrap-rel.yml

@@ -0,0 +1,34 @@
+spring:
+  application:
+    name: little-scholar
+  http:
+    encoding:
+      force-response: true
+  cloud:
+    nacos:
+      config:
+        #group: dev
+        namespace: a8e77fd0-e5f4-4ffa-9814-7cb3a438a097
+        server-addr: 172.16.48.10:8848
+        file-extension: yaml
+        prefix: ${spring.application.name}
+        enabled: true # 是否开启
+        refresh-enabled: true # 是否开启自动刷新
+      discovery:
+        #group: dev
+        namespace: a8e77fd0-e5f4-4ffa-9814-7cb3a438a097
+        server-addr: 172.16.48.10:8848
+  profiles:
+    active: rel
+  servlet:
+    multipart:
+      max-file-size: 30MB  #单个数据大小
+      max-request-size: 35MB #总数据大小
+
+weixin:
+  gzh:
+    appid: wxf0b4d0aedc317ab4
+    appsecret: ce2030c79af87b116f1118aa346cebf4
+
+stardance:
+  url: http://debugstar.mstardance.com/starmini/

Разлика између датотеке није приказан због своје велике величине
+ 320 - 0
src/main/resources/bootstrap-test1.yml


+ 207 - 0
src/main/resources/bootstrap.yml

@@ -0,0 +1,207 @@
+spring:
+  application:
+    name: little-scholar
+  profiles:
+    active: ${env:dev}
+  servlet:
+    multipart:
+      max-file-size: 100MB  #单个数据大小
+      max-request-size: 150MB #总数据大小
+  main:
+    allow-bean-definition-overriding: true
+  redis:
+    jedis:
+      pool:
+        max-active: 8
+        max-wait: 10000
+        max-idle: 10
+        min-idle: 0
+    timeout: 500
+server:
+  port: 6140
+  servlet:
+    context-path: /
+  tomcat:
+    max-threads: 500
+    uri-encoding: UTF-8
+    basedir: /mydata/appuser/logs/fisher/little-scholar
+    connection-timeout: 600000
+#mybatis
+mybatis-plus:
+  mapper-locations: classpath*:mapper/*.xml
+  configuration:
+    jdbc-type-for-null: 'null'
+    call-setters-on-nulls: true
+    useGeneratedKeys: true
+    defaultExecutorType: reuse
+  type-handlers-package:  cn.com.jdkj.handler
+  global-config:
+    capitalMode: true
+    banner: false
+    db-config:
+      id-type: auto
+      select-strategy: not_empty
+      insert-strategy: not_empty
+      update-strategy: not_null
+      table-underline: true
+      # 逻辑未删除将删除标志字段deleted置为0
+      logic-not-delete-value: 0
+      # 逻辑已删除将删除标志字段deleted置为1
+      logic-delete-value: 1
+    configuration:
+      call-setters-on-nulls: true
+mybatis:
+  configuration:
+    # 开启mybatis的驼峰映射
+    map-underscore-to-camel-case: true
+    use-generated-keys: true
+  mapper-locations:
+    classpath*:mapper/*.xml
+
+logging:
+  level:
+    com.star.security: INFO
+    com.alibaba.nacos.client.naming: error
+  config: classpath:logback-spring.xml
+  path: /mydata/appuser/logs/fisher/little-scholar/${server.port}
+
+
+feign:
+  client:
+    config:
+      default:
+        connectTimeout: 60000
+        readTimeout: 60000
+  httpclient:
+    disable-ssl-validation: true
+  hystrix:
+    command:
+      default:
+        execution:
+          timeout:
+            enabled: true
+          isolation:
+            thread:
+              timeoutInMilliseconds: 60000
+  #ribbon的超时时间
+  ribbon:
+    ReadTimeout: 60000
+    ConnectTimeout: 60000
+upload:
+  tempdir: /mydata/appuser/runtime/temp
+
+oss:
+  accessKey:
+    id: LTAI5t7gkTehVrtFMTmz53YL
+    secret: E8X16aZe2LRRWPJXvkl6pIgPZY0J0s
+  endpoint: oss-cn-shanghai-internal.aliyuncs.com
+  publicpoint: oss-cn-shanghai-internal.aliyuncs.com
+  bucketname: bird-fisher
+  endpointR: oss-cn-shanghai.aliyuncs.com
+  publicpointR: oss-cn-shanghai.aliyuncs.com
+sms:
+  accessKey:
+    id: LTAI5tAWkZfwdGZvsodCbS27
+    secret: 4RxR2jL0RtG3y0iu1uijafddMZRIfP
+  endpoint:
+# 本地文件系统
+file:
+  bucketName: starplay
+  oss:
+    enable: true
+    path-style-access: false
+    endpoint: oss-cn-beijing.aliyuncs.com
+    appId: LTAI5tAWkZfwdGZvsodCbS27
+    region: cn-beijing
+    customDomain: https://starplay.oss-cn-beijing.aliyuncs.com
+    access-key: LTAI5tAWkZfwdGZvsodCbS27
+    secret-key: 4RxR2jL0RtG3y0iu1uijafddMZRIfP
+  local:
+    enable: false
+    basePath: /data/file
+tencent:
+  cos:
+    #存储服务域名
+    qcloudDomain: https://starplay.oss-cn-beijing.aliyuncs.com
+    #存储文件前缀
+    qcloudPrefix:
+    qcloudAppId: 1313828448
+    qcloudSecretId: LTAI5tAWkZfwdGZvsodCbS27
+    qcloudSecretKey: 4RxR2jL0RtG3y0iu1uijafddMZRIfP
+    #存储桶名称
+    qcloudBucketName: starplay
+    #区域名格式为ap-xxx  eg: ap-nanjing  与存储服务域名cos后字段相同
+    qcloudRegion: cn-beijing
+
+chuanglan:
+  account: YZM7620245
+  password: ykcrlms3fUae9a
+  smsUrl: http://smssh1.253.com/msg/send/json
+
+weixin:
+  gzh:
+    appid: wx1fa5b9f727905c88
+    appsecret: 202cb962ac59075b964b07152d234b70
+  agent:
+    appid: wx6bf179cc7f0bd36d
+    appsecret: bf7150bf25499a1810c064f24511a566
+# Sa-Token配置
+sa-token:
+    # token名称 (同时也是cookie名称)
+    token-name: accessToken
+    # token有效期,单位s 默认30天, -1代表永不过期
+    timeout: 2592000
+    # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
+    activity-timeout: -1
+    # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
+    is-concurrent: false
+    # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
+    is-share: false
+    # token风格
+    token-style: random-128
+    # 是否输出操作日志
+    is-log: false
+
+
+
+pagehelper:
+  helperDialect: mysql
+  reasonable: false
+  supportMethodsArguments: true
+  params: count=countSql
+
+#华为云obs
+huawei:
+  obs:
+    endPoint: obs.cn-east-3.myhuaweicloud.com
+    accessKey: WEEWURHSLJXLVCBVGIBO
+    secretKey: wTFwvsDg3AofDt3hbDwAEQpEoLR1cbrcOB0f1fI1
+    buketname: obs-fanxing
+    url: https://obs-fanxing.obs.cn-east-3.myhuaweicloud.com/
+    accessId:
+
+
+
+
+
+
+## swagger 全局配置
+#knife4j:
+#  enable: true
+#swagger:
+#  enabled: true
+#  title: seafood Swagger API
+#  license: Powered By star
+#  licenseUrl: https://pig4cloud.com/
+#  terms-of-service-url: https://pig4cloud.com/
+#  contact:
+#    email: wangiegie@gmail.com
+#    url: https://pig4cloud.com/about.html
+#  authorization:
+#    name: oauth2
+#    auth-regex: ^.*$
+#    authorization-scope-list:
+#    - scope: server
+#      description: server all
+#    token-url-list:
+#    - http://${GATEWAY_HOST:seafood-gateway}:${GATEWAY_PORT:9999}/auth/oauth/token

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

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" DEBUG="false">
+	<contextName>logback-spring</contextName>
+    <springProperty scope="context" name="LOG_PATH" source="logging.path"/>
+
+	<!--输出到控制台 -->·
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%-5p] [%file:%line] - %m%n</pattern>
+		</encoder>
+	</appender>
+
+	<!--输出到文件 -->
+	<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%-5p] [%file:%line] - %m%n</pattern>
+        </encoder>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>${LOG_PATH}/info-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+			<maxFileSize>500MB</maxFileSize>
+		    <totalSizeCap>5GB</totalSizeCap>
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+	</appender>
+
+	<root level="INFO">
+		<appender-ref ref="console" />
+		<appender-ref ref="file" />
+	</root>
+	<logger name="com.ibatis" level="DEBUG"/>
+    <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG"/>
+    <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/>
+    <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG"/>
+    <logger name="java.sql.Connection" level="DEBUG"/>
+    <logger name="java.sql.Statement" level="DEBUG"/>
+    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
+    <logger name="cn.com.jdkj.customer.mapper" level="DEBUG"/>
+	<logger name="cn.com.jdkj.customer.service" level="DEBUG"/>
+</configuration>