From 5990a4f052fe09cb30870daff17040dc69ca11f3 Mon Sep 17 00:00:00 2001 From: cuianbing <2668052199@qq.com> Date: Tue, 30 Dec 2025 11:02:57 +0800 Subject: [PATCH] init --- .idea/.gitignore | 8 + .idea/compiler.xml | 20 ++ .idea/encodings.xml | 6 + .idea/jarRepositories.xml | 25 ++ .idea/misc.xml | 12 + .idea/sonarlint.xml | 10 + .idea/vcs.xml | 4 + README.md | 10 + pom.xml | 136 ++++++++++ src/main/java/cn/wujiangbo/App.java | 21 ++ .../cn/wujiangbo/annotation/IgnoreAuth.java | 13 + .../cn/wujiangbo/annotation/RateLimit.java | 25 ++ .../config/cors/CorsFilterConfig.java | 39 +++ .../cn/wujiangbo/config/date/DateConfig.java | 78 ++++++ .../config/date/JacksonObjectMapper.java | 49 ++++ .../config/mp/MyBatiesPlusConfiguration.java | 23 ++ .../wujiangbo/config/redis/RedisConfig.java | 39 +++ .../cn/wujiangbo/config/swagger/Swagger2.java | 79 ++++++ .../cn/wujiangbo/config/web/WebConfig.java | 58 ++++ .../cn/wujiangbo/constants/ErrorCode.java | 44 +++ .../wujiangbo/constants/SystemConstants.java | 51 ++++ .../wujiangbo/controller/LoginController.java | 134 ++++++++++ .../controller/RegisterController.java | 65 +++++ .../wujiangbo/controller/TestController.java | 24 ++ .../app/AppSuggestionController.java | 139 ++++++++++ .../controller/base/BaseController.java | 99 +++++++ .../controller/system/SysUserController.java | 145 ++++++++++ .../wujiangbo/domain/app/AppSuggestion.java | 59 ++++ .../java/cn/wujiangbo/domain/app/AppUser.java | 99 +++++++ .../cn/wujiangbo/domain/base/BaseDomain.java | 22 ++ .../cn/wujiangbo/domain/system/SysUser.java | 85 ++++++ .../cn/wujiangbo/dto/AppSuggestionVO.java | 25 ++ src/main/java/cn/wujiangbo/dto/UserToken.java | 16 ++ .../exception/GlobalExceptionHandler.java | 43 +++ .../cn/wujiangbo/exception/MyException.java | 23 ++ .../interceptor/LoginInterceptor.java | 79 ++++++ .../interceptor/RateLimitInterceptor.java | 90 +++++++ .../mapper/app/AppSuggestionMapper.java | 30 +++ .../wujiangbo/mapper/app/AppUserMapper.java | 28 ++ .../mapper/system/SysUserMapper.java | 12 + .../query/app/AppSuggestionQuery.java | 9 + .../wujiangbo/query/app/AppSwiperQuery.java | 15 ++ .../cn/wujiangbo/query/app/AppUserQuery.java | 9 + .../cn/wujiangbo/query/base/BaseQuery.java | 17 ++ .../wujiangbo/query/system/SysUserQuery.java | 9 + .../java/cn/wujiangbo/result/JSONResult.java | 124 +++++++++ .../java/cn/wujiangbo/result/PageList.java | 33 +++ .../service/app/AppSuggestionService.java | 55 ++++ .../wujiangbo/service/app/AppUserService.java | 48 ++++ .../wujiangbo/service/system/FileService.java | 17 ++ .../service/system/SysUserService.java | 68 +++++ .../system/impl/FileServiceLocalImpl.java | 58 ++++ .../system/impl/FileServiceOssImpl.java | 127 +++++++++ .../java/cn/wujiangbo/util/DateUtils.java | 197 ++++++++++++++ src/main/java/cn/wujiangbo/util/IdUtils.java | 57 ++++ src/main/java/cn/wujiangbo/util/MyTools.java | 199 ++++++++++++++ .../java/cn/wujiangbo/util/RedisCache.java | 251 ++++++++++++++++++ .../java/cn/wujiangbo/vo/LoginSuccessVo.java | 16 ++ .../java/cn/wujiangbo/vo/UploadFileVo.java | 15 ++ .../java/cn/wujiangbo/vo/UserTokenVo.java | 15 ++ src/main/resources/application.yml | 70 +++++ src/main/resources/banner.txt | 0 .../mapper/app/AppSuggestionMapper.xml | 17 ++ .../cn/wujiangbo/mapper/app/AppUserMapper.xml | 14 + .../wujiangbo/mapper/system/SysUserMapper.xml | 5 + src/main/resources/logback-spring.xml | 145 ++++++++++ target/classes/application.yml | 70 +++++ target/classes/banner.txt | 0 target/classes/cn/wujiangbo/App.class | Bin 0 -> 952 bytes .../cn/wujiangbo/annotation/IgnoreAuth.class | Bin 0 -> 437 bytes .../cn/wujiangbo/annotation/RateLimit.class | Bin 0 -> 620 bytes .../config/cors/CorsFilterConfig.class | Bin 0 -> 1591 bytes .../wujiangbo/config/date/DateConfig$1.class | Bin 0 -> 1690 bytes .../wujiangbo/config/date/DateConfig$2.class | Bin 0 -> 1723 bytes .../cn/wujiangbo/config/date/DateConfig.class | Bin 0 -> 3943 bytes .../config/date/JacksonObjectMapper.class | Bin 0 -> 2659 bytes .../config/mp/MyBatiesPlusConfiguration.class | Bin 0 -> 909 bytes .../wujiangbo/config/redis/RedisConfig.class | Bin 0 -> 3373 bytes .../wujiangbo/config/swagger/Swagger2.class | Bin 0 -> 4033 bytes .../cn/wujiangbo/config/web/WebConfig.class | Bin 0 -> 3191 bytes .../cn/wujiangbo/constants/ErrorCode.class | Bin 0 -> 2996 bytes .../wujiangbo/constants/SystemConstants.class | Bin 0 -> 949 bytes .../controller/LoginController.class | Bin 0 -> 5654 bytes .../controller/RegisterController.class | Bin 0 -> 2981 bytes .../wujiangbo/controller/TestController.class | Bin 0 -> 1130 bytes .../app/AppSuggestionController.class | Bin 0 -> 6083 bytes .../controller/base/BaseController.class | Bin 0 -> 3218 bytes .../controller/system/SysUserController.class | Bin 0 -> 6001 bytes .../wujiangbo/domain/app/AppSuggestion.class | Bin 0 -> 5374 bytes .../cn/wujiangbo/domain/app/AppSwiper.class | Bin 0 -> 4843 bytes .../cn/wujiangbo/domain/app/AppUser.class | Bin 0 -> 11190 bytes .../cn/wujiangbo/domain/base/BaseDomain.class | Bin 0 -> 2262 bytes .../cn/wujiangbo/domain/system/SysUser.class | Bin 0 -> 8990 bytes .../cn/wujiangbo/dto/AppSuggestionVO.class | Bin 0 -> 526 bytes .../classes/cn/wujiangbo/dto/UserToken.class | Bin 0 -> 1976 bytes .../exception/GlobalExceptionHandler.class | Bin 0 -> 2094 bytes .../cn/wujiangbo/exception/MyException.class | Bin 0 -> 2196 bytes .../interceptor/LoginInterceptor.class | Bin 0 -> 3486 bytes .../interceptor/RateLimitInterceptor.class | Bin 0 -> 3756 bytes .../mapper/app/AppSuggestionMapper.class | Bin 0 -> 1170 bytes .../mapper/app/AppSuggestionMapper.xml | 17 ++ .../mapper/app/AppSwiperMapper.class | Bin 0 -> 819 bytes .../wujiangbo/mapper/app/AppSwiperMapper.xml | 14 + .../wujiangbo/mapper/app/AppUserMapper.class | Bin 0 -> 805 bytes .../cn/wujiangbo/mapper/app/AppUserMapper.xml | 14 + .../mapper/system/SysUserMapper.class | Bin 0 -> 317 bytes .../wujiangbo/mapper/system/SysUserMapper.xml | 5 + .../query/app/AppSuggestionQuery.class | Bin 0 -> 342 bytes .../wujiangbo/query/app/AppSwiperQuery.class | Bin 0 -> 1654 bytes .../cn/wujiangbo/query/app/AppUserQuery.class | Bin 0 -> 324 bytes .../cn/wujiangbo/query/base/BaseQuery.class | Bin 0 -> 3079 bytes .../wujiangbo/query/system/SysUserQuery.class | Bin 0 -> 330 bytes .../cn/wujiangbo/result/JSONResult.class | Bin 0 -> 5673 bytes .../cn/wujiangbo/result/PageList.class | Bin 0 -> 2609 bytes .../service/app/AppSuggestionService.class | Bin 0 -> 4420 bytes .../service/app/AppUserService.class | Bin 0 -> 4123 bytes .../service/system/FileService.class | Bin 0 -> 317 bytes .../service/system/SysUserService.class | Bin 0 -> 5265 bytes .../system/impl/FileServiceLocalImpl.class | Bin 0 -> 3502 bytes .../classes/cn/wujiangbo/util/DateUtils.class | Bin 0 -> 4624 bytes .../classes/cn/wujiangbo/util/IdUtils.class | Bin 0 -> 953 bytes .../classes/cn/wujiangbo/util/MyTools.class | Bin 0 -> 6216 bytes .../cn/wujiangbo/util/RedisCache.class | Bin 0 -> 8374 bytes .../cn/wujiangbo/vo/LoginSuccessVo.class | Bin 0 -> 3487 bytes .../cn/wujiangbo/vo/UploadFileVo.class | Bin 0 -> 2946 bytes .../classes/cn/wujiangbo/vo/UserTokenVo.class | Bin 0 -> 2745 bytes target/classes/logback-spring.xml | 145 ++++++++++ target/classes/smart-doc.json | 8 + 128 files changed, 3830 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/sonarlint.xml create mode 100644 .idea/vcs.xml create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/cn/wujiangbo/App.java create mode 100644 src/main/java/cn/wujiangbo/annotation/IgnoreAuth.java create mode 100644 src/main/java/cn/wujiangbo/annotation/RateLimit.java create mode 100644 src/main/java/cn/wujiangbo/config/cors/CorsFilterConfig.java create mode 100644 src/main/java/cn/wujiangbo/config/date/DateConfig.java create mode 100644 src/main/java/cn/wujiangbo/config/date/JacksonObjectMapper.java create mode 100644 src/main/java/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.java create mode 100644 src/main/java/cn/wujiangbo/config/redis/RedisConfig.java create mode 100644 src/main/java/cn/wujiangbo/config/swagger/Swagger2.java create mode 100644 src/main/java/cn/wujiangbo/config/web/WebConfig.java create mode 100644 src/main/java/cn/wujiangbo/constants/ErrorCode.java create mode 100644 src/main/java/cn/wujiangbo/constants/SystemConstants.java create mode 100644 src/main/java/cn/wujiangbo/controller/LoginController.java create mode 100644 src/main/java/cn/wujiangbo/controller/RegisterController.java create mode 100644 src/main/java/cn/wujiangbo/controller/TestController.java create mode 100644 src/main/java/cn/wujiangbo/controller/app/AppSuggestionController.java create mode 100644 src/main/java/cn/wujiangbo/controller/base/BaseController.java create mode 100644 src/main/java/cn/wujiangbo/controller/system/SysUserController.java create mode 100644 src/main/java/cn/wujiangbo/domain/app/AppSuggestion.java create mode 100644 src/main/java/cn/wujiangbo/domain/app/AppUser.java create mode 100644 src/main/java/cn/wujiangbo/domain/base/BaseDomain.java create mode 100644 src/main/java/cn/wujiangbo/domain/system/SysUser.java create mode 100644 src/main/java/cn/wujiangbo/dto/AppSuggestionVO.java create mode 100644 src/main/java/cn/wujiangbo/dto/UserToken.java create mode 100644 src/main/java/cn/wujiangbo/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/cn/wujiangbo/exception/MyException.java create mode 100644 src/main/java/cn/wujiangbo/interceptor/LoginInterceptor.java create mode 100644 src/main/java/cn/wujiangbo/interceptor/RateLimitInterceptor.java create mode 100644 src/main/java/cn/wujiangbo/mapper/app/AppSuggestionMapper.java create mode 100644 src/main/java/cn/wujiangbo/mapper/app/AppUserMapper.java create mode 100644 src/main/java/cn/wujiangbo/mapper/system/SysUserMapper.java create mode 100644 src/main/java/cn/wujiangbo/query/app/AppSuggestionQuery.java create mode 100644 src/main/java/cn/wujiangbo/query/app/AppSwiperQuery.java create mode 100644 src/main/java/cn/wujiangbo/query/app/AppUserQuery.java create mode 100644 src/main/java/cn/wujiangbo/query/base/BaseQuery.java create mode 100644 src/main/java/cn/wujiangbo/query/system/SysUserQuery.java create mode 100644 src/main/java/cn/wujiangbo/result/JSONResult.java create mode 100644 src/main/java/cn/wujiangbo/result/PageList.java create mode 100644 src/main/java/cn/wujiangbo/service/app/AppSuggestionService.java create mode 100644 src/main/java/cn/wujiangbo/service/app/AppUserService.java create mode 100644 src/main/java/cn/wujiangbo/service/system/FileService.java create mode 100644 src/main/java/cn/wujiangbo/service/system/SysUserService.java create mode 100644 src/main/java/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.java create mode 100644 src/main/java/cn/wujiangbo/service/system/impl/FileServiceOssImpl.java create mode 100644 src/main/java/cn/wujiangbo/util/DateUtils.java create mode 100644 src/main/java/cn/wujiangbo/util/IdUtils.java create mode 100644 src/main/java/cn/wujiangbo/util/MyTools.java create mode 100644 src/main/java/cn/wujiangbo/util/RedisCache.java create mode 100644 src/main/java/cn/wujiangbo/vo/LoginSuccessVo.java create mode 100644 src/main/java/cn/wujiangbo/vo/UploadFileVo.java create mode 100644 src/main/java/cn/wujiangbo/vo/UserTokenVo.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/banner.txt create mode 100644 src/main/resources/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml create mode 100644 src/main/resources/cn/wujiangbo/mapper/app/AppUserMapper.xml create mode 100644 src/main/resources/cn/wujiangbo/mapper/system/SysUserMapper.xml create mode 100644 src/main/resources/logback-spring.xml create mode 100644 target/classes/application.yml create mode 100644 target/classes/banner.txt create mode 100644 target/classes/cn/wujiangbo/App.class create mode 100644 target/classes/cn/wujiangbo/annotation/IgnoreAuth.class create mode 100644 target/classes/cn/wujiangbo/annotation/RateLimit.class create mode 100644 target/classes/cn/wujiangbo/config/cors/CorsFilterConfig.class create mode 100644 target/classes/cn/wujiangbo/config/date/DateConfig$1.class create mode 100644 target/classes/cn/wujiangbo/config/date/DateConfig$2.class create mode 100644 target/classes/cn/wujiangbo/config/date/DateConfig.class create mode 100644 target/classes/cn/wujiangbo/config/date/JacksonObjectMapper.class create mode 100644 target/classes/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.class create mode 100644 target/classes/cn/wujiangbo/config/redis/RedisConfig.class create mode 100644 target/classes/cn/wujiangbo/config/swagger/Swagger2.class create mode 100644 target/classes/cn/wujiangbo/config/web/WebConfig.class create mode 100644 target/classes/cn/wujiangbo/constants/ErrorCode.class create mode 100644 target/classes/cn/wujiangbo/constants/SystemConstants.class create mode 100644 target/classes/cn/wujiangbo/controller/LoginController.class create mode 100644 target/classes/cn/wujiangbo/controller/RegisterController.class create mode 100644 target/classes/cn/wujiangbo/controller/TestController.class create mode 100644 target/classes/cn/wujiangbo/controller/app/AppSuggestionController.class create mode 100644 target/classes/cn/wujiangbo/controller/base/BaseController.class create mode 100644 target/classes/cn/wujiangbo/controller/system/SysUserController.class create mode 100644 target/classes/cn/wujiangbo/domain/app/AppSuggestion.class create mode 100644 target/classes/cn/wujiangbo/domain/app/AppSwiper.class create mode 100644 target/classes/cn/wujiangbo/domain/app/AppUser.class create mode 100644 target/classes/cn/wujiangbo/domain/base/BaseDomain.class create mode 100644 target/classes/cn/wujiangbo/domain/system/SysUser.class create mode 100644 target/classes/cn/wujiangbo/dto/AppSuggestionVO.class create mode 100644 target/classes/cn/wujiangbo/dto/UserToken.class create mode 100644 target/classes/cn/wujiangbo/exception/GlobalExceptionHandler.class create mode 100644 target/classes/cn/wujiangbo/exception/MyException.class create mode 100644 target/classes/cn/wujiangbo/interceptor/LoginInterceptor.class create mode 100644 target/classes/cn/wujiangbo/interceptor/RateLimitInterceptor.class create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.class create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.class create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.xml create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppUserMapper.class create mode 100644 target/classes/cn/wujiangbo/mapper/app/AppUserMapper.xml create mode 100644 target/classes/cn/wujiangbo/mapper/system/SysUserMapper.class create mode 100644 target/classes/cn/wujiangbo/mapper/system/SysUserMapper.xml create mode 100644 target/classes/cn/wujiangbo/query/app/AppSuggestionQuery.class create mode 100644 target/classes/cn/wujiangbo/query/app/AppSwiperQuery.class create mode 100644 target/classes/cn/wujiangbo/query/app/AppUserQuery.class create mode 100644 target/classes/cn/wujiangbo/query/base/BaseQuery.class create mode 100644 target/classes/cn/wujiangbo/query/system/SysUserQuery.class create mode 100644 target/classes/cn/wujiangbo/result/JSONResult.class create mode 100644 target/classes/cn/wujiangbo/result/PageList.class create mode 100644 target/classes/cn/wujiangbo/service/app/AppSuggestionService.class create mode 100644 target/classes/cn/wujiangbo/service/app/AppUserService.class create mode 100644 target/classes/cn/wujiangbo/service/system/FileService.class create mode 100644 target/classes/cn/wujiangbo/service/system/SysUserService.class create mode 100644 target/classes/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.class create mode 100644 target/classes/cn/wujiangbo/util/DateUtils.class create mode 100644 target/classes/cn/wujiangbo/util/IdUtils.class create mode 100644 target/classes/cn/wujiangbo/util/MyTools.class create mode 100644 target/classes/cn/wujiangbo/util/RedisCache.class create mode 100644 target/classes/cn/wujiangbo/vo/LoginSuccessVo.class create mode 100644 target/classes/cn/wujiangbo/vo/UploadFileVo.class create mode 100644 target/classes/cn/wujiangbo/vo/UserTokenVo.class create mode 100644 target/classes/logback-spring.xml create mode 100644 target/classes/smart-doc.json diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..5678dc7 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..63e9001 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..6522237 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..732146c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sonarlint.xml b/.idea/sonarlint.xml new file mode 100644 index 0000000..d16ff45 --- /dev/null +++ b/.idea/sonarlint.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..d843f34 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..57471c5 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# 客户投诉处理系统的设计与实现(Customer complaint handling system) + +## 功能内容 +- [x] 用户注册页(用户名、密码)、 +- [x] 用户登录页(用户名、密码)、 +- [ ] 用户投诉页(投诉事由、具体内容、解决诉求)、 +- [ ] 用户查看投诉记录列表页(投诉事由、投诉时间、投诉状态:有效/已撤销、操作:修改/删除)、 +- [ ] 用户查看投诉详情页(结构类似于用户投诉页,带修改按钮和撤销按钮)。 + +设计程序的数据库结构,并据此在DBMS中实现用户表和投诉表。 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2397c2c --- /dev/null +++ b/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + + com.rensijin.cchs + rensijin-cchs + 1.0.0 + rensijin-cchs + 任思瑾的客户投诉处理系统 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.baomidou + mybatis-plus-boot-starter + 3.4.1 + + + + mysql + mysql-connector-java + + + + com.alibaba + druid + 1.2.1 + + + + org.springframework.boot + spring-boot-starter-aop + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + commons-io + commons-io + 2.5 + + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + org.projectlombok + lombok + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + + com.alibaba + fastjson + 1.2.50 + + + + cn.hutool + hutool-all + 5.7.16 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.3.5.RELEASE + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + + true + + true + + + + + EasyJavaTemplate + + + + \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/App.java b/src/main/java/cn/wujiangbo/App.java new file mode 100644 index 0000000..df386f2 --- /dev/null +++ b/src/main/java/cn/wujiangbo/App.java @@ -0,0 +1,21 @@ +package cn.wujiangbo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +/** + * @desc:系统启动类 + */ +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + System.out.println("**************************************"); + System.out.println("**************系统启动成功**************"); + System.out.println("**************************************"); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/annotation/IgnoreAuth.java b/src/main/java/cn/wujiangbo/annotation/IgnoreAuth.java new file mode 100644 index 0000000..c282f35 --- /dev/null +++ b/src/main/java/cn/wujiangbo/annotation/IgnoreAuth.java @@ -0,0 +1,13 @@ +package cn.wujiangbo.annotation; + +import java.lang.annotation.*; + +/** + * @Desc: 忽略Token验证 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IgnoreAuth { + +} diff --git a/src/main/java/cn/wujiangbo/annotation/RateLimit.java b/src/main/java/cn/wujiangbo/annotation/RateLimit.java new file mode 100644 index 0000000..749f5a1 --- /dev/null +++ b/src/main/java/cn/wujiangbo/annotation/RateLimit.java @@ -0,0 +1,25 @@ +package cn.wujiangbo.annotation; + +import java.lang.annotation.*; + +/** + * 用于防刷限流的注解 + * 默认是5秒内只能调用一次 + */ +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimit { + + /** 限流的key */ + String key() default "limit:"; + + /** 周期,单位是秒 */ + int cycle() default 5; + + /** 请求次数 */ + int count() default 1; + + /** 默认提示信息 */ + String msg() default "请勿重复点击"; +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/config/cors/CorsFilterConfig.java b/src/main/java/cn/wujiangbo/config/cors/CorsFilterConfig.java new file mode 100644 index 0000000..5f6e027 --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/cors/CorsFilterConfig.java @@ -0,0 +1,39 @@ +package cn.wujiangbo.config.cors; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +/** + * 跨域配置 + */ +@Configuration +public class CorsFilterConfig { + + @Bean + public CorsFilter corsFilter() { + //1.添加CORS配置信息 + CorsConfiguration config = new CorsConfiguration(); + //1) 允许的域(*表示允许所有) + config.addAllowedOriginPattern("*"); + //2) 是否发送Cookie信息 + config.setAllowCredentials(true); + //3) 允许的请求方式 + config.addAllowedMethod("OPTIONS"); + config.addAllowedMethod("HEAD"); + config.addAllowedMethod("GET"); + config.addAllowedMethod("PUT"); + config.addAllowedMethod("POST"); + config.addAllowedMethod("DELETE"); + config.addAllowedMethod("PATCH"); + // 4)允许的头信息 + config.addAllowedHeader("*"); + //2.添加映射路径,我们拦截一切请求 + UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); + configSource.registerCorsConfiguration("/**", config); + //3.返回新的CorsFilter. + return new CorsFilter(configSource); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/config/date/DateConfig.java b/src/main/java/cn/wujiangbo/config/date/DateConfig.java new file mode 100644 index 0000000..ed4ca11 --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/date/DateConfig.java @@ -0,0 +1,78 @@ +package cn.wujiangbo.config.date; + +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @description 全局时间配置类 + */ +@Configuration +public class DateConfig { + + private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + private static final String DATE_PATTERN = "yyyy-MM-dd"; + + /** + * string转localdate + */ + @Bean + public Converter localDateConverter() { + return new Converter() { + @Override + public LocalDate convert(String source) { + if (source.trim().length() == 0) + return null; + try { + return LocalDate.parse(source); + } catch (Exception e) { + return LocalDate.parse(source, DateTimeFormatter.ofPattern(DATE_PATTERN)); + } + } + }; + } + + /** + * string转localdatetime + */ + @Bean + public Converter localDateTimeConverter() { + return new Converter() { + @Override + public LocalDateTime convert(String source) { + if (source.trim().length() == 0) + return null; + // 先尝试ISO格式: 2019-07-15T16:00:00 + try { + return LocalDateTime.parse(source); + } catch (Exception e) { + return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + } + } + }; + } + + /** + * 统一配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { + JavaTimeModule module = new JavaTimeModule(); + LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer); + return builder -> { + builder.simpleDateFormat(DATE_TIME_PATTERN); + builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN))); + builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN))); + builder.modules(module); + }; + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/config/date/JacksonObjectMapper.java b/src/main/java/cn/wujiangbo/config/date/JacksonObjectMapper.java new file mode 100644 index 0000000..d8f3e83 --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/date/JacksonObjectMapper.java @@ -0,0 +1,49 @@ +package cn.wujiangbo.config.date; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 + * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] + * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] + */ +public class JacksonObjectMapper extends ObjectMapper { + + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_TIME_FORMAT_NO_SECOND = "yyyy-MM-dd HH:mm"; + public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; + + public JacksonObjectMapper() { + super(); + //收到未知属性时不报异常 + this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); + + //反序列化时,属性不存在的兼容处理 + this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + SimpleModule simpleModule = new SimpleModule() + .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) + .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); + + //注册功能模块 例如,可以添加自定义序列化器和反序列化器 + this.registerModule(simpleModule); + } +} diff --git a/src/main/java/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.java b/src/main/java/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.java new file mode 100644 index 0000000..daaf3dc --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.java @@ -0,0 +1,23 @@ +package cn.wujiangbo.config.mp; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @description: MyBatiesPlus配置类 + */ +@Configuration +@MapperScan("cn.wujiangbo.mapper") +public class MyBatiesPlusConfiguration { + + /* + * 分页插件 + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); + return paginationInterceptor; + } +} diff --git a/src/main/java/cn/wujiangbo/config/redis/RedisConfig.java b/src/main/java/cn/wujiangbo/config/redis/RedisConfig.java new file mode 100644 index 0000000..2b89b0f --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/redis/RedisConfig.java @@ -0,0 +1,39 @@ +package cn.wujiangbo.config.redis; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + *

Redis配置类

+ */ +@Configuration +public class RedisConfig { + + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { + // 设置序列化 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + // 配置redisTemplate + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(lettuceConnectionFactory); + RedisSerializer stringSerializer = new StringRedisSerializer(); + redisTemplate.setKeySerializer(stringSerializer);// key序列化 + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化 + redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化 + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化 + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/config/swagger/Swagger2.java b/src/main/java/cn/wujiangbo/config/swagger/Swagger2.java new file mode 100644 index 0000000..881aaa4 --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/swagger/Swagger2.java @@ -0,0 +1,79 @@ +package cn.wujiangbo.config.swagger; + +import io.swagger.models.auth.In; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger接口文档配置类 + */ +@Configuration +@EnableSwagger2 +public class Swagger2 { + + //默认路径:http://127.0.0.1:port/swagger-ui.html + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + // 是否启用Swagger + .enable(true) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))//扫描所有有注解的api + //.apis(RequestHandlerSelectors.any())//扫描所有 + .apis(RequestHandlerSelectors.basePackage("cn.wujiangbo.controller"))//扫描包 + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()); + } + + /** + * 安全模式,这里指定token通过头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("token", "token", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("token", authorizationScopes)); + return securityReferences; + } + + private ApiInfo apiInfo() { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:接口文档") + // 描述 + .description("描述:用户前后端联调接口文档") + // 作者信息 + .contact(new Contact("任思瑾", null, "")) + // 版本 + .version("版本号:1.0.0") + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/config/web/WebConfig.java b/src/main/java/cn/wujiangbo/config/web/WebConfig.java new file mode 100644 index 0000000..0cdc626 --- /dev/null +++ b/src/main/java/cn/wujiangbo/config/web/WebConfig.java @@ -0,0 +1,58 @@ +package cn.wujiangbo.config.web; + +import cn.wujiangbo.config.date.JacksonObjectMapper; +import cn.wujiangbo.interceptor.LoginInterceptor; +import cn.wujiangbo.interceptor.RateLimitInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; + +import javax.annotation.Resource; +import java.util.List; + +/** + * web配置 + */ +@Configuration +public class WebConfig extends WebMvcConfigurationSupport { + + @Resource + private LoginInterceptor loginInterceptor; + + @Resource + private RateLimitInterceptor rateLimitInterceptor; + + //扩展SpringMVC框架的消息转化器,例如实现返回日期时间的格式化 + @Override + protected void extendMessageConverters(List> converters) { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + //将java对象序列化为json数据,为消息转换器设置序列转换器 + converter.setObjectMapper(new JacksonObjectMapper()); + //将自己的消息转换器加入容器中 + converters.add(0, converter); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(rateLimitInterceptor); + registry.addInterceptor(loginInterceptor) + .addPathPatterns("/**") + .excludePathPatterns("/", "/static/**", "/file/download/**") + .excludePathPatterns("/login/**", "/user/info", "/test/**","/user/register"); + } + + /** + * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法 + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**") + .addResourceLocations("classpath:/resources/") + .addResourceLocations("classpath:/static/"); + super.addResourceHandlers(registry); + } + +} diff --git a/src/main/java/cn/wujiangbo/constants/ErrorCode.java b/src/main/java/cn/wujiangbo/constants/ErrorCode.java new file mode 100644 index 0000000..4fbef28 --- /dev/null +++ b/src/main/java/cn/wujiangbo/constants/ErrorCode.java @@ -0,0 +1,44 @@ +package cn.wujiangbo.constants; + +/** + * 系统错误码 + */ +public enum ErrorCode { + + SYSTEM_SUCCESS("0000", "操作成功!"), + + ERROR_CODE_1001("1001", "操作失败,请稍候再试!"), + ERROR_CODE_1002("1002", "认证状态失效,请重新登录!"), + ERROR_CODE_1003("1003", "登录账号不能为空!"), + ERROR_CODE_1004("1004", "登录密码不能为空!"), + ERROR_CODE_1005("1005", "登录账号不存在!"), + ERROR_CODE_1006("1006", "登录账号存在多个!"), + ERROR_CODE_1007("1007", "登录密码错误!"), + ERROR_CODE_1008("1008", "Token错误或失效!"), + ERROR_CODE_1009("1009", "UUID不能为空!"), + ERROR_CODE_1010("1010", "图片验证码不能为空!"), + ERROR_CODE_1011("1011", "图片验证码已过期,请点击图片刷新!"), + ERROR_CODE_1012("1012", "图片验证码错误,请重新输入!"), + + + SYSTEM_ERROR("9999", "系统开小差了,请稍后再试!"); + + //错误码 + private String code; + + //错误信息 + private String message; + + ErrorCode(String code, String message) { + this.code = code; + this.message = message; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/cn/wujiangbo/constants/SystemConstants.java b/src/main/java/cn/wujiangbo/constants/SystemConstants.java new file mode 100644 index 0000000..b9a4611 --- /dev/null +++ b/src/main/java/cn/wujiangbo/constants/SystemConstants.java @@ -0,0 +1,51 @@ +package cn.wujiangbo.constants; + +/** + * @description 系统常量类 + */ +public class SystemConstants { + + /** + * APP端保存注册短信验证码key + */ + public static final String TOKEN_PHONE_KEY_REGISTER = "app_sms_code_register:"; + + /** + * 令牌在Redis中保存时长 + */ + public static final int TOKEN_REDIS_ALIVE_TIME = 2; + + /** + * APP端保存短信验证码key + */ + public static final String TOKEN_PHONE_KEY = "app_sms_code:"; + + /** + * 登录时图片验证码存Redis的超时时间(单位:分钟) + */ + public final static int LOGIN_CAPTCHA_EXPIRATION = 2; + + /** + * 登录时图片验证码存Redis的key前缀 + */ + public static final String CAPTCHA_CODE_KEY = "captcha_code:"; + + /** + * 文件存储路径(项目跟路径下面的files文件夹) + */ + public static final String FILES_DIR = "/files/"; + + /** + * APP用户登录 redis key + */ + public static final String LOGIN_TOKEN_KEY_APP = "login_app_tokens:"; + + //登录成功之后token超时时间(单位:分钟) + public final static int LOGIN_TIME_OUT = 60; + + //新用户注册的默认登录密码 + public final static String DEFAULT_USER_LOGIN_PWD = "123456"; + + //新用户注册的默认头像 + public final static String DEFAULT_USER_AVATAR = "https://easyjava.oss-cn-chengdu.aliyuncs.com/common/0161a7079e574da287dc182bdf756abc.jpg"; +} diff --git a/src/main/java/cn/wujiangbo/controller/LoginController.java b/src/main/java/cn/wujiangbo/controller/LoginController.java new file mode 100644 index 0000000..2cdd28c --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/LoginController.java @@ -0,0 +1,134 @@ +package cn.wujiangbo.controller; + +import cn.hutool.crypto.SecureUtil; +import cn.wujiangbo.annotation.IgnoreAuth; +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.domain.system.SysUser; +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.mapper.system.SysUserMapper; +import cn.wujiangbo.result.JSONResult; +import cn.wujiangbo.util.MyTools; +import cn.wujiangbo.vo.UserTokenVo; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.wf.captcha.SpecCaptcha; +import com.wf.captcha.base.Captcha; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @desc 系统登录API + */ +@RestController +@RequestMapping("/login") +public class LoginController { + + @Resource + private SysUserMapper sysUserMapper; + + @Resource + private RedisTemplate redisTemplate; + + /** + * 登录页面获取图片验证码 + */ + @IgnoreAuth + @GetMapping("/getLoginImageCode/{uuid}") + public JSONResult getLoginImageCode(@PathVariable("uuid") String uuid) { + // 验证码内容存Redis的key值 + String verifyKey = SystemConstants.CAPTCHA_CODE_KEY + uuid; + + SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4); + //设置验证码的类型(可不设置,使用默认值) + specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER); + String code = specCaptcha.text().toLowerCase(); + + //图片验证码存Redis + redisTemplate.opsForValue().set(verifyKey, code, SystemConstants.LOGIN_CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + + return JSONResult.success(specCaptcha.toBase64()); + } + + /** + * 系统登录接口 + * + * @param user + * @return + */ + @IgnoreAuth + @PostMapping("/login") + public JSONResult login(@RequestBody SysUser user) { + //入参校验 + if (!MyTools.hasLength(user.getUsername())) { + throw new MyException(ErrorCode.ERROR_CODE_1003); + } + if (!MyTools.hasLength(user.getPassword())) { + throw new MyException(ErrorCode.ERROR_CODE_1004); + } + if (!MyTools.hasLength(user.getUuid())) { + throw new MyException(ErrorCode.ERROR_CODE_1009); + } + if (!MyTools.hasLength(user.getImageCode())) { + throw new MyException(ErrorCode.ERROR_CODE_1010); + } + + //到Redis获取验证码 + String verifyKey = SystemConstants.CAPTCHA_CODE_KEY + user.getUuid(); + String imagesCodeFromRedis = (String) redisTemplate.opsForValue().get(verifyKey); + if (!MyTools.hasLength(imagesCodeFromRedis)) { + throw new MyException(ErrorCode.ERROR_CODE_1011); + } + //开始对比图片验证码 + if (!imagesCodeFromRedis.equals(user.getImageCode())) { + throw new MyException(ErrorCode.ERROR_CODE_1012); + } + + //查看账号是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_name", user.getUsername()); + List sysUserList = sysUserMapper.selectList(queryWrapper); + if (CollectionUtils.isEmpty(sysUserList)) { + throw new MyException(ErrorCode.ERROR_CODE_1005); + } + if (sysUserList.size() > 1) { + throw new MyException(ErrorCode.ERROR_CODE_1006); + } + + //开始验证密码是否正确 + SysUser sysUser = sysUserList.get(0); + if (!sysUser.getPassword().equalsIgnoreCase(SecureUtil.md5(user.getPassword()))) { + throw new MyException(ErrorCode.ERROR_CODE_1007); + } + + //用户信息存Redis + String token = MyTools.getLoginToken(); + //用户信息存储到Redis + redisTemplate.opsForValue().set(SystemConstants.LOGIN_TOKEN_KEY_APP + token, JSONObject.toJSONString(sysUser), SystemConstants.LOGIN_TIME_OUT, TimeUnit.MINUTES); + + //返回token及相关用户信息给前端 + UserTokenVo vo = new UserTokenVo(); + vo.setToken(token); + vo.setAvatar(sysUser.getAvatar()); + vo.setUserName(sysUser.getUsername()); + vo.setRealName(sysUser.getRealName()); + return JSONResult.success(vo); + } + + /** + * 退出系统 + * + * @param token + * @return + */ + @GetMapping("/logout") + public JSONResult getUSerInfo(@RequestParam("token") String token) { + redisTemplate.delete(token); + return JSONResult.success(); + } +} diff --git a/src/main/java/cn/wujiangbo/controller/RegisterController.java b/src/main/java/cn/wujiangbo/controller/RegisterController.java new file mode 100644 index 0000000..5af70ae --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/RegisterController.java @@ -0,0 +1,65 @@ +package cn.wujiangbo.controller; + + +import cn.hutool.crypto.SecureUtil; +import cn.wujiangbo.annotation.IgnoreAuth; +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.domain.app.AppUser; +import cn.wujiangbo.domain.system.SysUser; +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.result.JSONResult; +import cn.wujiangbo.service.system.SysUserService; +import cn.wujiangbo.util.DateUtils; +import cn.wujiangbo.util.MyTools; +import cn.wujiangbo.vo.UserTokenVo; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.math.BigDecimal; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @desc 用户注册 + */ +@RestController +@RequestMapping("/user") +public class RegisterController { + + @Autowired + private SysUserService sysUserService; + + @IgnoreAuth + @PostMapping("/register") + public JSONResult login(@RequestBody SysUser user) { + if (!MyTools.hasLength(user.getUsername())) { + throw new MyException("账号不能为空!"); + } + System.out.println(user); + //查询用户名是否被注册 + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("user_name", user.getUsername()); + SysUser one = sysUserService.getOne(queryWrapper); + if (one != null) { + throw new MyException("账号已被注册,请更换!"); + } + + SysUser sysUser = new SysUser(); + BeanUtils.copyProperties(user, sysUser); + + sysUser.setPassword(SecureUtil.md5(user.getPassword())); + sysUser.setAvatar("https://20241211oss.oss-cn-beijing.aliyuncs.com/202412/NewsApp/image/3_20241211143629.png"); + //数据入库 + System.out.println(sysUser); + sysUserService.save(sysUser); + return JSONResult.successMessage(true, "注册成功,快去登录吧!"); + } +} diff --git a/src/main/java/cn/wujiangbo/controller/TestController.java b/src/main/java/cn/wujiangbo/controller/TestController.java new file mode 100644 index 0000000..e3f093e --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/TestController.java @@ -0,0 +1,24 @@ +package cn.wujiangbo.controller; + +import cn.wujiangbo.annotation.RateLimit; +import cn.wujiangbo.result.JSONResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

测试类

+ * + */ +@RestController +@RequestMapping("/test") +public class TestController { + + //cycle秒内只能访问count次 + @RateLimit(key= "testLimit:", count = 2, cycle = 2, msg = "同志,不要请求这么快,好吗") + @GetMapping("/test001") + public JSONResult test001() { + System.out.println("成功发送一条短信"); + return JSONResult.success("成功发送一条短信"); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/controller/app/AppSuggestionController.java b/src/main/java/cn/wujiangbo/controller/app/AppSuggestionController.java new file mode 100644 index 0000000..5cd8eab --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/app/AppSuggestionController.java @@ -0,0 +1,139 @@ +package cn.wujiangbo.controller.app; + +import cn.wujiangbo.domain.app.AppSuggestion; +import cn.wujiangbo.result.PageList; +import cn.wujiangbo.service.app.AppSuggestionService; +import cn.wujiangbo.query.app.AppSuggestionQuery; +import cn.wujiangbo.controller.base.BaseController; +import cn.wujiangbo.util.DateUtils; +import cn.wujiangbo.result.JSONResult; +import cn.wujiangbo.result.PageList; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import java.util.Arrays; +import java.util.List; + +/** + * 意见反馈表 API接口 + */ +@RestController +@RequestMapping("/appSuggestion") +@Api(value = "/appSuggestion", tags = {"意见反馈表 API接口"}) +public class AppSuggestionController extends BaseController{ + + @Autowired + public AppSuggestionService appSuggestionService; + + /** + * 新增数据到【意见反馈表】 + */ + @PostMapping(value="/save") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "AppSuggestion", name = "appSuggestion", value = "") + }) + @ApiOperation(value = "新增数据到【意见反馈表】", notes = "新增数据到【意见反馈表】", httpMethod = "POST") + public JSONResult save(@RequestBody AppSuggestion appSuggestion){ + appSuggestion.setCreateTime(DateUtils.getCurrentLocalDateTime()); + // 获取当前用户真实姓名,如果获取失败则使用默认值 + String currentUserName = getCurrentUserRealName(); + if (currentUserName != null && !currentUserName.trim().isEmpty()) { + appSuggestion.setCreateUserName(currentUserName); + } else { + appSuggestion.setCreateUserName("匿名用户"); // 或者根据业务需求设置其他默认值 + } + appSuggestion.setAppUserId(getCurrentUserId()); + appSuggestion.setStatus("有效"); // 默认为有效状态 + appSuggestionService.save(appSuggestion); + return JSONResult.success(true); + } + + /** + * 修改【意见反馈表】表数据 + */ + @PostMapping(value="/update") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "AppSuggestion", name = "appSuggestion", value = "") + }) + @ApiOperation(value = "修改【意见反馈表】表数据", notes = "修改【意见反馈表】表数据", httpMethod = "POST") + public JSONResult update(@RequestBody AppSuggestion appSuggestion){ + appSuggestion.setUpdateUserName(getCurrentUserRealName()); + appSuggestionService.updateById(appSuggestion); + return JSONResult.success(true); + } + + /** + * 批量删除【意见反馈表】数据 + */ + @PostMapping(value="/batchDelete") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "AppSuggestionQuery", name = "query", value = "") + }) + @ApiOperation(value = "批量删除【意见反馈表】数据", notes = "批量删除【意见反馈表】数据", httpMethod = "POST") + public JSONResult batchDelete(@RequestBody AppSuggestionQuery query){ + //批量删除数据库数据 + appSuggestionService.removeByIds(Arrays.asList(query.getIds())); + return JSONResult.success(true); + } + + /** + * 单个删除【意见反馈表】数据 + */ + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "") + }) + @ApiOperation(value = "单个删除【意见反馈表】数据", notes = "单个删除【意见反馈表】数据", httpMethod = "DELETE") + @DeleteMapping("/singleDelete/{id}") + public JSONResult batchDelete(@PathVariable("id") Long id){ + //单个删除数据库数据 + appSuggestionService.removeById(id); + return JSONResult.success(true); + } + + /** + * 根据ID查询【意见反馈表】详情数据 + */ + @GetMapping(value = "/{id}") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "") + }) + @ApiOperation(value = "根据ID查询【意见反馈表】详情数据", notes = "根据ID查询【意见反馈表】详情数据", httpMethod = "GET") + public JSONResult get(@PathVariable("id")Long id){ + return JSONResult.success(appSuggestionService.getById(id)); + } + + /** + * 查询【意见反馈表】所有数据(不分页) + */ + @GetMapping(value = "/list") + @ApiOperation(value = "查询【意见反馈表】所有数据(不分页)", notes = "查询【意见反馈表】所有数据(不分页)", httpMethod = "GET") + public JSONResult list(){ + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.orderByDesc("id"); + List list = appSuggestionService.list(queryWrapper); + return JSONResult.success(list); + } + + /** + * 查询【意见反馈表】数据(分页) + * @param query 查询对象 + * @return PageList 分页对象 + */ + @PostMapping(value = "/pagelist") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "AppSuggestionQuery", name = "query", value = "查询对象") + }) + @ApiOperation(value = "查询【意见反馈表】数据(分页)", notes = "查询【意见反馈表】数据(分页)", httpMethod = "POST") + public JSONResult pagelist(@RequestBody AppSuggestionQuery query){ + Page page = appSuggestionService.selectMySqlPage(query); + return JSONResult.success(new PageList<>(page.getTotal(), page.getRecords())); + } + + + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/controller/base/BaseController.java b/src/main/java/cn/wujiangbo/controller/base/BaseController.java new file mode 100644 index 0000000..312464e --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/base/BaseController.java @@ -0,0 +1,99 @@ +package cn.wujiangbo.controller.base; + +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.domain.app.AppUser; +import cn.wujiangbo.domain.system.SysUser; +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.service.app.AppUserService; +import cn.wujiangbo.util.MyTools; +import cn.wujiangbo.util.RedisCache; +import com.alibaba.fastjson.JSONObject; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +/** + * @des: Controller的基础类 + */ +public class BaseController { + + @Resource + private RedisCache redisCache; + + @Resource + private AppUserService appUserService; + + /** + * 获取APP用户昵称 + */ + public String getAppNickName() { + Long appUserId = getAppUserId(); + if (appUserId != null) { + AppUser one = appUserService.getById(appUserId); + if (one != null) { + return one.getNickName(); + } + } + return null; + } + + /** + * 获取APP用户ID + */ + public Long getAppUserId() { + HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); + if (request != null) { + String headerToken = request.getHeader("token"); + if (MyTools.hasLength(headerToken)) { + String userInfo = redisCache.getCacheObject(SystemConstants.LOGIN_TOKEN_KEY_APP + headerToken); + AppUser user = JSONObject.parseObject(userInfo, AppUser.class); + return user.getId(); + } else { + throw new MyException("您没有权限进行此操作!"); + } + } + return null; + } + + /** + * 获取登录人的信息 + * + * @return + */ + public SysUser getCurrentUser() { + //获取 HttpServletRequest 对象 + HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); + //从请求头中获取 token 值 + String token = request.getHeader("token"); + if (!MyTools.hasLength(token)) { + throw new MyException(ErrorCode.ERROR_CODE_1002.getMessage()); + } + String userInfoString = redisCache.getCacheObject(SystemConstants.LOGIN_TOKEN_KEY_APP + token); + if (!MyTools.hasLength(userInfoString)) { + throw new MyException(ErrorCode.ERROR_CODE_1002.getMessage()); + } + SysUser sysUser = JSONObject.parseObject(userInfoString, SysUser.class); + return sysUser; + } + + /** + * 获取登录人的用户ID + * + * @return + */ + public Long getCurrentUserId() { + return getCurrentUser().getId(); + } + + /** + * 获取登录人的真实姓名 + * + * @return + */ + public String getCurrentUserRealName() { + return getCurrentUser().getRealName(); + } +} diff --git a/src/main/java/cn/wujiangbo/controller/system/SysUserController.java b/src/main/java/cn/wujiangbo/controller/system/SysUserController.java new file mode 100644 index 0000000..2d6e77c --- /dev/null +++ b/src/main/java/cn/wujiangbo/controller/system/SysUserController.java @@ -0,0 +1,145 @@ +package cn.wujiangbo.controller.system; + +import cn.hutool.crypto.SecureUtil; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.controller.base.BaseController; +import cn.wujiangbo.domain.system.SysUser; +import cn.wujiangbo.query.system.SysUserQuery; +import cn.wujiangbo.result.JSONResult; +import cn.wujiangbo.result.PageList; +import cn.wujiangbo.service.system.SysUserService; +import cn.wujiangbo.util.DateUtils; +import cn.wujiangbo.util.MyTools; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; + +/** + * @desc 用户信息表 API接口 + */ +@RestController +@RequestMapping("/user") +@Api(value = "/user", tags = {"用户信息表 API接口"}) +public class SysUserController extends BaseController{ + + @Resource + public SysUserService sysUserService; + + /** + * 新增数据到【用户信息表】 + */ + @PostMapping(value="/save") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "SysUser", name = "sysUser", value = "") + }) + @ApiOperation(value = "新增数据到【用户信息表】", notes = "新增数据到【用户信息表】", httpMethod = "POST") + public JSONResult save(@RequestBody SysUser sysUser){ + sysUser.setCreateTime(DateUtils.getCurrentLocalDateTime()); + sysUser.setCreateUserId(getCurrentUserId()); + sysUser.setPassword(SecureUtil.md5(sysUser.getPassword()));//密码加密 + if(!MyTools.hasLength(sysUser.getAvatar())){ + sysUser.setAvatar(SystemConstants.DEFAULT_USER_AVATAR);//默认头像 + } + sysUserService.save(sysUser); + return JSONResult.success(true); + } + + /** + * 修改【用户信息表】表数据 + */ + @PostMapping(value="/update") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "SysUser", name = "sysUser", value = "") + }) + @ApiOperation(value = "修改【用户信息表】表数据", notes = "修改【用户信息表】表数据", httpMethod = "POST") + public JSONResult update(@RequestBody SysUser sysUser){ + sysUser.setUpdateTime(DateUtils.getCurrentLocalDateTime()); + sysUser.setUpdateUserId(getCurrentUserId()); + sysUserService.updateById(sysUser); + return JSONResult.success(true); + } + + /** + * 批量删除【用户信息表】数据 + */ + @PostMapping(value="/batchDelete") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "SysUserQuery", name = "query", value = "") + }) + @ApiOperation(value = "批量删除【用户信息表】数据", notes = "批量删除【用户信息表】数据", httpMethod = "POST") + public JSONResult batchDelete(@RequestBody SysUserQuery query){ + //批量删除数据库数据 + sysUserService.removeByIds(Arrays.asList(query.getIds())); + return JSONResult.success(true); + } + + /** + * 单个删除【用户信息表】数据 + */ + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "") + }) + @ApiOperation(value = "单个删除【用户信息表】数据", notes = "单个删除【用户信息表】数据", httpMethod = "DELETE") + @DeleteMapping("/singleDelete/{id}") + public JSONResult batchDelete(@PathVariable("id") Long id){ + //单个删除数据库数据 + sysUserService.removeById(id); + return JSONResult.success(true); + } + + /** + * 根据ID查询【用户信息表】详情数据 + */ + @GetMapping(value = "/{id}") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "path", dataType = "long", name = "id", value = "") + }) + @ApiOperation(value = "根据ID查询【用户信息表】详情数据", notes = "根据ID查询【用户信息表】详情数据", httpMethod = "GET") + public JSONResult get(@PathVariable("id")Long id){ + return JSONResult.success(sysUserService.getById(id)); + } + + /** + * 查询【用户信息表】所有数据(不分页) + */ + @GetMapping(value = "/list") + @ApiOperation(value = "查询【用户信息表】所有数据(不分页)", notes = "查询【用户信息表】所有数据(不分页)", httpMethod = "GET") + public JSONResult list(){ + List list = sysUserService.list(null); + return JSONResult.success(list); + } + + /** + * 查询【用户信息表】数据(分页) + * @param query 查询对象 + * @return PageList 分页对象 + */ + @PostMapping(value = "/pagelist") + @ApiImplicitParams({ + @ApiImplicitParam(paramType = "body", dataType = "SysUserQuery", name = "query", value = "查询对象") + }) + @ApiOperation(value = "查询【用户信息表】数据(分页)", notes = "查询【用户信息表】数据(分页)", httpMethod = "POST") + public JSONResult pagelist(@RequestBody SysUserQuery query){ + IPage page = sysUserService.selectMyPage(query); + return JSONResult.success(new PageList<>(page.getTotal(), page.getRecords())); + } + + + /** + * 获取用户个人信息 + * @param token + * @return + */ + @GetMapping("/info") + public JSONResult getUSerInfo(@RequestParam("token") String token){ + return sysUserService.getUSerInfo(token); + } +} diff --git a/src/main/java/cn/wujiangbo/domain/app/AppSuggestion.java b/src/main/java/cn/wujiangbo/domain/app/AppSuggestion.java new file mode 100644 index 0000000..716c85b --- /dev/null +++ b/src/main/java/cn/wujiangbo/domain/app/AppSuggestion.java @@ -0,0 +1,59 @@ +package cn.wujiangbo.domain.app; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.TableField; +import cn.wujiangbo.domain.base.BaseDomain; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 意见反馈表 + *

+ * + * @date 2025-02-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="app_suggestion 表对应的实体对象", description="意见反馈表") +public class AppSuggestion extends BaseDomain implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "提意见时间") + @TableField(value = "create_time") + private LocalDateTime createTime; + + @ApiModelProperty(value = "提意见人ID") + @TableField(value = "user_id") + private Long appUserId; + + @ApiModelProperty(value = "意见内容") + @TableField(value = "suggestion_countent") + private String suggestionCountent; + + + @ApiModelProperty(value = "投诉事由") + @TableField(value = "complaint") + private String complaint; + + @ApiModelProperty(value = "解决诉求") + @TableField(value = "demands") + private String demands; + + @ApiModelProperty(value = "投诉状态") + @TableField(value = "status") + private String status; + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/domain/app/AppUser.java b/src/main/java/cn/wujiangbo/domain/app/AppUser.java new file mode 100644 index 0000000..531e9e1 --- /dev/null +++ b/src/main/java/cn/wujiangbo/domain/app/AppUser.java @@ -0,0 +1,99 @@ +package cn.wujiangbo.domain.app; + +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.TableField; +import cn.wujiangbo.domain.base.BaseDomain; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * APP用户信息表 + *

+ */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="app_user 表对应的实体对象", description="APP用户信息表") +public class AppUser extends BaseDomain implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "更新时间") + @TableField(value = "update_time") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "登录账号") + @TableField(value = "login_name") + private String loginName; + + @ApiModelProperty(value = "登录密码") + @TableField(value = "login_pass") + private String loginPass; + + @ApiModelProperty(value = "昵称") + @TableField(value = "nick_name") + private String nickName; + + @ApiModelProperty(value = "用户头像") + @TableField(value = "user_img") + private String userImg; + + @ApiModelProperty(value = "用户性别(0:男;1:女)") + @TableField(value = "user_sex") + private Integer userSex; + + @ApiModelProperty(value = "用户手机号") + @TableField(value = "user_phone") + private String userPhone; + + @ApiModelProperty(value = "用户状态(1:正常;2:限制登录)") + @TableField(value = "user_status") + private Integer userStatus; + + @ApiModelProperty(value = "限制登录原因") + @TableField(value = "user_error") + private String userError; + + @ApiModelProperty(value = "用户个人简介") + @TableField(value = "user_brief") + private String userBrief; + + @ApiModelProperty(value = "最后一次登录时间") + @TableField(value = "last_login_time") + private LocalDateTime lastLoginTime; + + @ApiModelProperty(value = "注册时间") + @TableField(value = "register_time") + private LocalDateTime registerTime; + + @ApiModelProperty(value = "账户余额") + @TableField(value = "user_money") + private BigDecimal userMoney; + + @ApiModelProperty(value = "是否是管理员(1:是;2:否)") + @TableField(value = "admin_flag") + private Integer adminFlag; + + /*********************************************************************************** + ***********************************************************************************/ + + @ApiModelProperty(value = "新密码") + @TableField(exist = false) + private String password2; + + @ApiModelProperty(value = "短信验证码") + @TableField(exist = false) + private String smsCode; +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/domain/base/BaseDomain.java b/src/main/java/cn/wujiangbo/domain/base/BaseDomain.java new file mode 100644 index 0000000..3a99d53 --- /dev/null +++ b/src/main/java/cn/wujiangbo/domain/base/BaseDomain.java @@ -0,0 +1,22 @@ +package cn.wujiangbo.domain.base; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * @desc 基础Domain类 + */ +@Data +public class BaseDomain implements Serializable { + + @ApiModelProperty(value = "创建人名称") + @TableField(exist = false) + private String createUserName; + + @ApiModelProperty(value = "更新人名称") + @TableField(exist = false) + private String updateUserName; + +} diff --git a/src/main/java/cn/wujiangbo/domain/system/SysUser.java b/src/main/java/cn/wujiangbo/domain/system/SysUser.java new file mode 100644 index 0000000..a0b73d6 --- /dev/null +++ b/src/main/java/cn/wujiangbo/domain/system/SysUser.java @@ -0,0 +1,85 @@ +package cn.wujiangbo.domain.system; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.TableField; +import cn.wujiangbo.domain.base.BaseDomain; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 用户信息表 + *

+ */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value="sys_user 表对应的实体对象", description="用户信息表") +public class SysUser extends BaseDomain implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "用户ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "用户账号") + @TableField(value = "user_name") + private String username; + + @ApiModelProperty(value = "用户账号") + @TableField(value = "real_name") + private String realName; + + @ApiModelProperty(value = "用户邮箱") + @TableField(value = "email") + private String email; + + @ApiModelProperty(value = "手机号码") + @TableField(value = "phonenumber") + private String phonenumber; + + @ApiModelProperty(value = "头像地址") + @TableField(value = "avatar") + private String avatar; + + @ApiModelProperty(value = "密码") + @TableField(value = "password") + private String password; + + @ApiModelProperty(value = "备注") + @TableField(value = "remark") + private String remark; + + @ApiModelProperty(value = "创建时间") + @TableField(value = "create_time") + private LocalDateTime createTime; + + @ApiModelProperty(value = "创建人") + @TableField(value = "create_user_id") + private Long createUserId; + + @ApiModelProperty(value = "更新时间") + @TableField(value = "update_time") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "更新人") + @TableField(value = "update_user_id") + private Long updateUserId; + + + @ApiModelProperty(value = "UUID") + @TableField(exist = false) + private String uuid; + + @ApiModelProperty(value = "图片验证码内容") + @TableField(exist = false) + private String imageCode; + +} diff --git a/src/main/java/cn/wujiangbo/dto/AppSuggestionVO.java b/src/main/java/cn/wujiangbo/dto/AppSuggestionVO.java new file mode 100644 index 0000000..d56dc66 --- /dev/null +++ b/src/main/java/cn/wujiangbo/dto/AppSuggestionVO.java @@ -0,0 +1,25 @@ +package cn.wujiangbo.dto; + + +import java.time.LocalDateTime; + +public class AppSuggestionVO { + + private Long id; + + private LocalDateTime createTime; + + private Long userId; + + private String suggestionCountent; + + + private String complaint; + + private String demands; + + private String status; + + private String realName; +} + diff --git a/src/main/java/cn/wujiangbo/dto/UserToken.java b/src/main/java/cn/wujiangbo/dto/UserToken.java new file mode 100644 index 0000000..37d0fb3 --- /dev/null +++ b/src/main/java/cn/wujiangbo/dto/UserToken.java @@ -0,0 +1,16 @@ +package cn.wujiangbo.dto; + +import lombok.Data; + +@Data +public class UserToken { + /** + * 用户ID + */ + private Long id; + + /** + * 用户真实姓名 + */ + private String nickName; +} diff --git a/src/main/java/cn/wujiangbo/exception/GlobalExceptionHandler.java b/src/main/java/cn/wujiangbo/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..c977bd6 --- /dev/null +++ b/src/main/java/cn/wujiangbo/exception/GlobalExceptionHandler.java @@ -0,0 +1,43 @@ +package cn.wujiangbo.exception; + +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.result.JSONResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理类 + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + /** + * 自定义异常 + */ + @ExceptionHandler(MyException.class) + public JSONResult MyException(MyException e){ + log.error(e.getLocalizedMessage()); + return JSONResult.error(e.getCode(), e.getMessage()); + } + + /** + * 算术异常 + */ + @ExceptionHandler(ArithmeticException.class) + public JSONResult methodArithmeticException(ArithmeticException e){ + log.error(e.getLocalizedMessage()); + return JSONResult.error("发生算术异常,请稍后再试!"); + } + + /** + * 如果发生上面没有捕获的异常,那么统一走这个异常捕获,相当于是最大的一个范围 + */ + @ExceptionHandler(Exception.class) + public JSONResult exceptionHandler(Exception e){ + e.printStackTrace(); + log.error(e.getLocalizedMessage()); + return JSONResult.error(ErrorCode.SYSTEM_ERROR.getMessage()); + } +} diff --git a/src/main/java/cn/wujiangbo/exception/MyException.java b/src/main/java/cn/wujiangbo/exception/MyException.java new file mode 100644 index 0000000..9be8538 --- /dev/null +++ b/src/main/java/cn/wujiangbo/exception/MyException.java @@ -0,0 +1,23 @@ +package cn.wujiangbo.exception; + +import cn.wujiangbo.constants.ErrorCode; +import lombok.Data; + +/** + * 自定义异常类 + */ +@Data +public class MyException extends RuntimeException { + + private String code; + private String message; + + public MyException(String message){ + this.message = message; + } + + public MyException(ErrorCode errorCode){ + this.code = errorCode.getCode(); + this.message = errorCode.getMessage(); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/interceptor/LoginInterceptor.java b/src/main/java/cn/wujiangbo/interceptor/LoginInterceptor.java new file mode 100644 index 0000000..4a87bc0 --- /dev/null +++ b/src/main/java/cn/wujiangbo/interceptor/LoginInterceptor.java @@ -0,0 +1,79 @@ +package cn.wujiangbo.interceptor; + +import cn.wujiangbo.annotation.IgnoreAuth; +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.util.MyTools; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +/** + * 校验登录的拦截器 + */ +@Component +public class LoginInterceptor implements HandlerInterceptor { + + @Resource + private RedisTemplate redisTemplate; + + //前置拦截 + @Override + public boolean preHandle(HttpServletRequest request, + HttpServletResponse response, + Object handler) throws Exception { + // 放行静态资源请求 + if (isStaticResourceRequest(request)) { + return true; + } + + if (!(handler instanceof HandlerMethod)) { + //不是请求方法,则直接放行 + return true; + } + + IgnoreAuth annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class); + if (annotation != null) { + //用IgnoreAuth注解标识的接口,直接放行 + return true; + } + + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + String methodName = method.getName(); + System.out.println("methodName=" + methodName); + + //1、从请求头中获取token + String token = request.getHeader("token"); + if (!MyTools.hasLength(token)) { + throw new MyException(ErrorCode.ERROR_CODE_1002.getMessage()); + } + + //根据token从Redis中获取到用户信息 + String userInfo = (String) redisTemplate.opsForValue().get(SystemConstants.LOGIN_TOKEN_KEY_APP + token); + if (MyTools.hasLength(userInfo)) { + //重新设置超时时间 + redisTemplate.opsForValue().set(SystemConstants.LOGIN_TOKEN_KEY_APP + token, userInfo, SystemConstants.LOGIN_TIME_OUT, TimeUnit.MINUTES); + //放行 + return true; + } else { + //Redis中拿不到用户信息,抛异常 + throw new MyException(ErrorCode.ERROR_CODE_1002.getMessage()); + } + } + + private boolean isStaticResourceRequest(HttpServletRequest request) { + String uri = request.getRequestURI(); + // 根据你的静态资源路径配置来判断 + return uri.startsWith("/static/") || uri.startsWith("/images/") || uri.startsWith("/Resource/"); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/interceptor/RateLimitInterceptor.java b/src/main/java/cn/wujiangbo/interceptor/RateLimitInterceptor.java new file mode 100644 index 0000000..0e0aadc --- /dev/null +++ b/src/main/java/cn/wujiangbo/interceptor/RateLimitInterceptor.java @@ -0,0 +1,90 @@ +package cn.wujiangbo.interceptor; + +import cn.wujiangbo.annotation.RateLimit; +import cn.wujiangbo.exception.MyException; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.concurrent.TimeUnit; + +/** + *

防刷限流的拦截器

+ */ +@Component +public class RateLimitInterceptor implements HandlerInterceptor { + + @Resource + private RedisTemplate redisTemplate; + + @Override + public boolean preHandle( + HttpServletRequest request, + HttpServletResponse response, + Object handler) throws Exception { + // 如果请求的是方法,则需要做校验 + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + // 获取目标方法上是否有指定注解 + RateLimit rateLimit = handlerMethod.getMethodAnnotation(RateLimit.class); + if (rateLimit == null) { + //说明目标方法上没有 RateLimit 注解 + return true; + } + //代码执行到此,说明目标方法上有 RateLimit 注解,所以需要校验这个请求是不是在刷接口 + // 获取请求IP地址 192.168.12.13 + String ip = getIpAddr(request); + // 请求url路径 /test/test001 + String uri = request.getRequestURI(); + //存到redis中的key + String key = rateLimit.key() + ip + ":" + uri;//testLimit:192.168.12.13:/test/test001 + // 缓存中存在key,在限定访问周期内已经调用过当前接口 + //2秒内发了10次请求 + if (redisTemplate.hasKey(key)) { + // 访问次数自增1 + redisTemplate.opsForValue().increment(key, 1); + // 超出访问次数限制 + if (redisTemplate.opsForValue().get(key) > rateLimit.count()) { + throw new MyException(rateLimit.msg()); + } + // 未超出访问次数限制,不进行任何操作,返回true + } else { + // 第一次设置数据,过期时间为注解确定的访问周期 + redisTemplate.opsForValue().set(key, 1, rateLimit.cycle(), TimeUnit.SECONDS); + } + return true; + } + //如果请求的不是方法,直接放行 + return true; + } + + //获取请求的归属IP地址 + private String getIpAddr(HttpServletRequest request) { + String ipAddress = null; + try { + 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(); + } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > 15) { + // = 15 + if (ipAddress.indexOf(",") > 0) { + ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); + } + } + } catch (Exception e) { + ipAddress = ""; + } + return ipAddress; + } +} diff --git a/src/main/java/cn/wujiangbo/mapper/app/AppSuggestionMapper.java b/src/main/java/cn/wujiangbo/mapper/app/AppSuggestionMapper.java new file mode 100644 index 0000000..0ae1a87 --- /dev/null +++ b/src/main/java/cn/wujiangbo/mapper/app/AppSuggestionMapper.java @@ -0,0 +1,30 @@ +package cn.wujiangbo.mapper.app; + +import cn.wujiangbo.domain.app.AppSuggestion; +import cn.wujiangbo.dto.AppSuggestionVO; +import cn.wujiangbo.query.app.AppSuggestionQuery; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** +*

+* 意见反馈表 Mapper接口 +*

+*/ +public interface AppSuggestionMapper extends BaseMapper { + + //查询分页列表数据 + List selectMySqlPage(Page page, @Param("query") AppSuggestionQuery query); + + + @Select("SELECT a.*, s.real_name as realName" + + "FROM app_suggestion a " + + "LEFT JOIN sys_user s ON a.user_id = s.id " + + "ORDER BY a.id DESC") + List selectWithUserInfo(); + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/mapper/app/AppUserMapper.java b/src/main/java/cn/wujiangbo/mapper/app/AppUserMapper.java new file mode 100644 index 0000000..25f55e6 --- /dev/null +++ b/src/main/java/cn/wujiangbo/mapper/app/AppUserMapper.java @@ -0,0 +1,28 @@ +package cn.wujiangbo.mapper.app; + +import cn.wujiangbo.domain.app.AppUser; +import cn.wujiangbo.dto.AppSuggestionVO; +import cn.wujiangbo.query.app.AppSuggestionQuery; +import cn.wujiangbo.query.app.AppUserQuery; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** +*

+* APP用户信息表 Mapper接口 +*

+*/ +public interface AppUserMapper extends BaseMapper { + + //查询分页列表数据 + List selectMySqlPage(Page page, @Param("query") AppUserQuery query); + + + + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/mapper/system/SysUserMapper.java b/src/main/java/cn/wujiangbo/mapper/system/SysUserMapper.java new file mode 100644 index 0000000..86a962d --- /dev/null +++ b/src/main/java/cn/wujiangbo/mapper/system/SysUserMapper.java @@ -0,0 +1,12 @@ +package cn.wujiangbo.mapper.system; + +import cn.wujiangbo.domain.system.SysUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +*

+* 用户信息表 Mapper接口 +*

+*/ +public interface SysUserMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/query/app/AppSuggestionQuery.java b/src/main/java/cn/wujiangbo/query/app/AppSuggestionQuery.java new file mode 100644 index 0000000..b294257 --- /dev/null +++ b/src/main/java/cn/wujiangbo/query/app/AppSuggestionQuery.java @@ -0,0 +1,9 @@ +package cn.wujiangbo.query.app; + +import cn.wujiangbo.query.base.BaseQuery; + +/** + * 意见反馈表-查询对象 + */ +public class AppSuggestionQuery extends BaseQuery{ +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/query/app/AppSwiperQuery.java b/src/main/java/cn/wujiangbo/query/app/AppSwiperQuery.java new file mode 100644 index 0000000..777ba36 --- /dev/null +++ b/src/main/java/cn/wujiangbo/query/app/AppSwiperQuery.java @@ -0,0 +1,15 @@ +package cn.wujiangbo.query.app; + +import cn.wujiangbo.query.base.BaseQuery; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 轮播图表-查询对象 + */ +@Data +public class AppSwiperQuery extends BaseQuery{ + + @ApiModelProperty(value = "轮播图业务类型") + private String busType; +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/query/app/AppUserQuery.java b/src/main/java/cn/wujiangbo/query/app/AppUserQuery.java new file mode 100644 index 0000000..232ec24 --- /dev/null +++ b/src/main/java/cn/wujiangbo/query/app/AppUserQuery.java @@ -0,0 +1,9 @@ +package cn.wujiangbo.query.app; + +import cn.wujiangbo.query.base.BaseQuery; + +/** + * APP用户信息表-查询对象 + */ +public class AppUserQuery extends BaseQuery{ +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/query/base/BaseQuery.java b/src/main/java/cn/wujiangbo/query/base/BaseQuery.java new file mode 100644 index 0000000..3beef2d --- /dev/null +++ b/src/main/java/cn/wujiangbo/query/base/BaseQuery.java @@ -0,0 +1,17 @@ +package cn.wujiangbo.query.base; + +import lombok.Data; +import java.io.Serializable; + +/** + * 基础查询对象 + */ +@Data +public class BaseQuery implements Serializable { + + private Long[] ids; //批量删除时,前端传来的主键ID集合 + private String keyword;//关键字 + + private Integer current = 1; //当前页 + private Integer size = 10; //每页显示多少条 +} diff --git a/src/main/java/cn/wujiangbo/query/system/SysUserQuery.java b/src/main/java/cn/wujiangbo/query/system/SysUserQuery.java new file mode 100644 index 0000000..38f029e --- /dev/null +++ b/src/main/java/cn/wujiangbo/query/system/SysUserQuery.java @@ -0,0 +1,9 @@ +package cn.wujiangbo.query.system; + +import cn.wujiangbo.query.base.BaseQuery; + +/** + * @desc 用户信息表-查询对象 + */ +public class SysUserQuery extends BaseQuery{ +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/result/JSONResult.java b/src/main/java/cn/wujiangbo/result/JSONResult.java new file mode 100644 index 0000000..d0175d7 --- /dev/null +++ b/src/main/java/cn/wujiangbo/result/JSONResult.java @@ -0,0 +1,124 @@ +package cn.wujiangbo.result; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 统一返回结果对象 + */ +@Data +@ApiModel(value = "响应数据封装类") +public class JSONResult implements Serializable { + + @ApiModelProperty(value = "响应状态描述(true:成功;false:失败;)") + private boolean success = true; + + @ApiModelProperty(value = "响应描述") + private String message = "操作成功"; + + //成功统一返回0000,其余编码全部是错误码 + @ApiModelProperty(value = "响应状态码") + private String code = "0000"; + + //是否展示提示信息(默认不展示) + @ApiModelProperty(value = "是否展示提示信息") + private boolean showMessage = false; + + //返回的数据 + @ApiModelProperty(value = "响应数据") + private Object data; + + //创建当前实例 + public static JSONResult success(){ + return new JSONResult(); + } + + //创建当前实例 + public static JSONResult success(boolean showMessage){ + JSONResult instance = new JSONResult(); + instance.setShowMessage(showMessage); + return instance; + } + + //创建当前实例 + public static JSONResult success(Object obj){ + JSONResult instance = new JSONResult(); + instance.setData(obj); + return instance; + } + + //创建当前实例 + public static JSONResult success(Object obj, boolean showMessage){ + JSONResult instance = new JSONResult(); + instance.setData(obj); + instance.setShowMessage(showMessage); + return instance; + } + + //创建当前实例 + public static JSONResult successMessage(boolean showMessage, String message){ + JSONResult instance = new JSONResult(); + instance.setShowMessage(showMessage); + instance.setMessage(message); + return instance; + } + + //成功,但是返回不同消息代码 + public static JSONResult success(Object obj, String code){ + JSONResult instance = new JSONResult(); + instance.setSuccess(true); + instance.setCode(code); + instance.setData(obj); + return instance; + } + + public static JSONResult success(String code, String message){ + JSONResult instance = new JSONResult(); + instance.setSuccess(true); + instance.setCode(code); + instance.setMessage(message); + return instance; + } + + //创建当前实例 + public static JSONResult error(){ + JSONResult instance = new JSONResult(); + instance.setCode("9999"); + instance.setSuccess(false); + instance.setMessage("系统发生异常,请稍后再试!"); + return instance; + } + + //创建当前实例 + public static JSONResult error(String message){ + JSONResult instance = new JSONResult(); + instance.setCode("9999"); + instance.setSuccess(false); + instance.setMessage(message); + return instance; + } + + public static JSONResult error(String message, Object obj){ + JSONResult instance = new JSONResult(); + instance.setCode("9999"); + instance.setMessage(message); + instance.setSuccess(false); + instance.setData(obj); + return instance; + } + + public static boolean hasLength(String str) { + return org.springframework.util.StringUtils.hasLength(str); + } + + public static JSONResult error(String code, String message){ + JSONResult instance = new JSONResult(); + instance.setCode(hasLength(code) ? code : "9999"); + instance.setMessage(message); + instance.setSuccess(false); + return instance; + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/result/PageList.java b/src/main/java/cn/wujiangbo/result/PageList.java new file mode 100644 index 0000000..aac26b8 --- /dev/null +++ b/src/main/java/cn/wujiangbo/result/PageList.java @@ -0,0 +1,33 @@ +package cn.wujiangbo.result; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 分页对象 + */ +@Data +public class PageList { + + private long total; + private List rows = new ArrayList<>(); + + @Override + public String toString() { + return "PageList{" + + "total=" + total + + ", rows=" + rows + + '}'; + } + + //提供有参构造方法,方便测试 + public PageList(long total, List rows) { + this.total = total; + this.rows = rows; + } + //除了有参构造方法,还需要提供一个无参构造方法 + public PageList() { + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/service/app/AppSuggestionService.java b/src/main/java/cn/wujiangbo/service/app/AppSuggestionService.java new file mode 100644 index 0000000..c82c89c --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/app/AppSuggestionService.java @@ -0,0 +1,55 @@ +package cn.wujiangbo.service.app; + +import cn.wujiangbo.domain.app.AppSuggestion; +import cn.wujiangbo.dto.AppSuggestionVO; +import cn.wujiangbo.mapper.app.AppSuggestionMapper; +import cn.wujiangbo.query.app.AppSuggestionQuery; +import cn.wujiangbo.util.MyTools; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * 意见反馈表 服务实现类 + *

+ */ +@Transactional +@Service +@Slf4j +public class AppSuggestionService extends ServiceImpl{ + + @Resource + private AppSuggestionMapper appsuggestionMapper; + + //查询分页列表数据(使用QueryWrapper操作) + public Page selectMyPage(AppSuggestionQuery query) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (MyTools.hasLength(query.getKeyword())) { + wrapper.and(i -> i.like("id", query.getKeyword())); + } + //排序 + wrapper.orderByDesc("id"); + Page page = new Page<>(query.getCurrent(), query.getSize()); + return super.page(page, wrapper); + } + + //查询分页列表数据(自己写SQL) + public Page selectMySqlPage(AppSuggestionQuery query) { + Page page = new Page<>(query.getCurrent(), query.getSize()); + List list = appsuggestionMapper.selectMySqlPage(page, query); + return page.setRecords(list); + } + + + public List selectWithUserInfo(){ + return appsuggestionMapper.selectWithUserInfo(); + } + + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/service/app/AppUserService.java b/src/main/java/cn/wujiangbo/service/app/AppUserService.java new file mode 100644 index 0000000..ab6187d --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/app/AppUserService.java @@ -0,0 +1,48 @@ +package cn.wujiangbo.service.app; + +import cn.wujiangbo.domain.app.AppUser; +import cn.wujiangbo.mapper.app.AppUserMapper; +import cn.wujiangbo.query.app.AppUserQuery; +import cn.wujiangbo.util.MyTools; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * APP用户信息表 服务实现类 + *

+ */ +@Transactional +@Service +@Slf4j +public class AppUserService extends ServiceImpl{ + + @Resource + private AppUserMapper appuserMapper; + + //查询分页列表数据(使用QueryWrapper操作) + public Page selectMyPage(AppUserQuery query) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (MyTools.hasLength(query.getKeyword())) { + wrapper.and(i -> i.like("id", query.getKeyword())); + } + //排序 + wrapper.orderByDesc("id"); + Page page = new Page<>(query.getCurrent(), query.getSize()); + return super.page(page, wrapper); + } + + //查询分页列表数据(自己写SQL) + public Page selectMySqlPage(AppUserQuery query) { + Page page = new Page<>(query.getCurrent(), query.getSize()); + List list = appuserMapper.selectMySqlPage(page, query); + return page.setRecords(list); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/service/system/FileService.java b/src/main/java/cn/wujiangbo/service/system/FileService.java new file mode 100644 index 0000000..3ecd60b --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/system/FileService.java @@ -0,0 +1,17 @@ +package cn.wujiangbo.service.system; + +import cn.wujiangbo.vo.UploadFileVo; +import org.springframework.web.multipart.MultipartFile; + +/** + *

文件上传接口

+ */ +public interface FileService { + + /** + * 单个文件上传方法 + * @param multipartFile 文件 + * @param folderName 保存文件夹名称 + */ + UploadFileVo uploadFile(MultipartFile multipartFile, String folderName); +} diff --git a/src/main/java/cn/wujiangbo/service/system/SysUserService.java b/src/main/java/cn/wujiangbo/service/system/SysUserService.java new file mode 100644 index 0000000..33bfbb8 --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/system/SysUserService.java @@ -0,0 +1,68 @@ +package cn.wujiangbo.service.system; + +import cn.wujiangbo.constants.ErrorCode; +import cn.wujiangbo.constants.SystemConstants; +import cn.wujiangbo.domain.system.SysUser; +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.mapper.system.SysUserMapper; +import cn.wujiangbo.query.system.SysUserQuery; +import cn.wujiangbo.result.JSONResult; +import cn.wujiangbo.util.MyTools; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 用户信息表 服务实现类 + *

+ */ +@Service +@Slf4j +@Transactional +public class SysUserService extends ServiceImpl { + + @Resource + private RedisTemplate redisTemplate; + + //查询分页列表数据 + public IPage selectMyPage(SysUserQuery query) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (MyTools.hasLength(query.getKeyword())) { + wrapper.and(i -> i.like("user_name", query.getKeyword())); + } + //排序 + wrapper.orderByDesc("create_time").orderByDesc("id"); + IPage page = new Page<>(query.getCurrent(), query.getSize()); + return super.page(page, wrapper); + } + + //获取用户个人信息 + public JSONResult getUSerInfo(String token) { + if (StringUtils.hasLength(token)) { + Object userInfo = redisTemplate.opsForValue().get(SystemConstants.LOGIN_TOKEN_KEY_APP + token); + if (userInfo == null) { + throw new MyException(ErrorCode.ERROR_CODE_1002.getMessage()); + } + SysUser sysUser = JSONObject.parseObject(userInfo.toString(), SysUser.class); + Map map = new HashMap<>(); + map.put("name", sysUser.getUsername()); + map.put("avatar", sysUser.getAvatar()); + return JSONResult.success(map); + } else { + throw new MyException(ErrorCode.ERROR_CODE_1008.getMessage()); + } + } +} diff --git a/src/main/java/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.java b/src/main/java/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.java new file mode 100644 index 0000000..6b0b3f5 --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.java @@ -0,0 +1,58 @@ +package cn.wujiangbo.service.system.impl; + +import cn.wujiangbo.exception.MyException; +import cn.wujiangbo.service.system.FileService; +import cn.wujiangbo.util.DateUtils; +import cn.wujiangbo.vo.UploadFileVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.util.Date; + +/** + *

文件上传-保存到服务器本地磁盘

+ */ +@Service +@Slf4j +public class FileServiceLocalImpl implements FileService { + + @Value("${server.port}") + private String port; + + @Override + public UploadFileVo uploadFile(MultipartFile file, String folderName) { + if (file.isEmpty()) { + throw new MyException("上传文件不能为空!"); + } + UploadFileVo vo = new UploadFileVo(); + try { + String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1); + File path = new File(ResourceUtils.getURL("classpath:").getPath()); + if (!path.exists()) { + path = new File(""); + } + String localPath = "/UploadFiles/" + DateUtils.getCurrentYearMonth() + "/" + folderName + "/"; + File upload = new File(path.getAbsolutePath(), localPath); + if (!upload.exists()) { + upload.mkdirs(); + } + String fileName = new Date().getTime() + "." + fileExt; + File dest = new File(upload.getAbsolutePath() + "/" + fileName); + file.transferTo(dest); + //如果使用idea或者eclipse重启项目,发现之前上传的图片或者文件丢失,将下面一行代码注释打开 + FileUtils.copyFile(dest, new File("E:\\workspace\\EasyJavaTemplateMaster\\EasyJavaTemplate\\SpringBoot\\src\\main\\resources\\static\\UploadFiles" + "/" + DateUtils.getCurrentYearMonth() + "/" + folderName + "/" + fileName)); + //封装返回数据 + vo.setFileName(fileName); + vo.setFileSize(file.getSize()); + vo.setFileFullPath("http://localhost:" + port + "/static/UploadFiles/" + DateUtils.getCurrentYearMonth() + "/" + folderName + "/" + fileName); + } catch (Exception e) { + e.printStackTrace(); + throw new MyException("上传文件到本地磁盘异常:" + e.getMessage()); + } + return vo; + } +} diff --git a/src/main/java/cn/wujiangbo/service/system/impl/FileServiceOssImpl.java b/src/main/java/cn/wujiangbo/service/system/impl/FileServiceOssImpl.java new file mode 100644 index 0000000..a6b95b3 --- /dev/null +++ b/src/main/java/cn/wujiangbo/service/system/impl/FileServiceOssImpl.java @@ -0,0 +1,127 @@ +//package cn.wujiangbo.service.system.impl; +// +//import cn.wujiangbo.dto.OssDto; +//import cn.wujiangbo.exception.MyException; +//import cn.wujiangbo.service.system.FileService; +//import cn.wujiangbo.util.DateUtils; +//import cn.wujiangbo.util.MyTools; +//import cn.wujiangbo.vo.UploadFileVo; +//import com.aliyun.oss.OSS; +//import com.aliyun.oss.OSSClientBuilder; +//import com.aliyun.oss.model.PutObjectRequest; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Service; +//import org.springframework.web.multipart.MultipartFile; +//import javax.annotation.Resource; +// +///** +// *

文件上传实现类

+// */ +//@Service +//@Slf4j +//public class FileServiceOssImpl implements FileService { +// +// @Resource +// private OssDto ossDto; +// +// /** +// * 文件存储方案(1:文件本地;2:存阿里云OSS) +// */ +// @Value("${file.filescheme}") +// private String filescheme; +// +// @Value("${server.port}") +// private String port; +// +// @Value("${file.download.ip}") +// private String downloadIp; +// +// /** +// * 上传文件 +// * @param multipartFile 文件 +// * @param folderName 保存文件的路径 +// * @return UploadFileVo +// */ +// @Override +// public UploadFileVo uploadFile(MultipartFile multipartFile, String folderName) { +// System.out.println("上传文件存储方案:" + ("1".equals(filescheme) ? "本地" : "OSS")); +// if ("1".equals(filescheme)) { +// /** +// * 注意,如果是存本地的话,files下面必须直接存文件,不能有其他层级了,否则下载时无法下载或预览图片了 +// */ +// //上传文件存本地方案 +// if (multipartFile.isEmpty()) { +// throw new MyException("上传文件不能为空!"); +// } +// //获取文件名 +// String fileName = extractFilename(multipartFile); +// // 封装完整的文件路径获取方法 +// String fileUploadPath = MyTools.getFileUploadPath(fileName); +// System.out.println("上传文件磁盘保存路径=" + fileUploadPath); +// try { +// java.io.File uploadFile = new java.io.File(fileUploadPath); +// java.io.File parentFile = uploadFile.getParentFile(); +// if (!parentFile.exists()) { // 如果父级不存在,也就是说files目录不存在,那么我要创建出来 +// parentFile.mkdirs(); +// } +// multipartFile.transferTo(uploadFile); +// } catch (Exception e) { +// log.error("文件上传失败", e); +// throw new MyException("上传文件失败!"); +// } +// String filePath = "http://" + downloadIp + ":" + port + "/file/download/" + fileName; +// System.out.println("上传文件完整访问路径=" + filePath); +// UploadFileVo vo = new UploadFileVo(); +// vo.setFileName(fileName); +// vo.setFilePrefix("http://" + downloadIp + ":" + port + "/file/download/"); +// vo.setFileFullPath(filePath); +// vo.setFileSize(multipartFile.getSize()); +// return vo; +// } else { +// //上传文件存OSS方案 +// if (ossDto.getEnable()) { +// if (multipartFile.isEmpty()) { +// throw new MyException("上传文件不能为空!"); +// } +// //获取文件名 +// String fileName = extractFilename(multipartFile); +// //所有文件存储必需带上年月信息 +// fileName = DateUtils.getCurrentYearMonth() + "/" + folderName + "/" + fileName; +// OSS build = new OSSClientBuilder().build(ossDto.getEndpoint(), ossDto.getAccessKey(), ossDto.getSecretKey()); +// try { +// PutObjectRequest putObjectRequest = new PutObjectRequest(ossDto.getBucketName(), fileName, multipartFile.getInputStream()); +// //将文件推到OSS服务器 +// build.putObject(putObjectRequest); +// String imagePath = "https://" + ossDto.getBucketName() + "." + ossDto.getEndpoint() + "/" + fileName; +// UploadFileVo vo = new UploadFileVo(); +// vo.setFileName(fileName); +// vo.setFilePrefix("https://" + ossDto.getBucketName() + "." + ossDto.getEndpoint() + "/"); +// vo.setFileFullPath(imagePath); +// vo.setFileSize(multipartFile.getSize()); +// return vo; +// } catch (Exception e) { +// e.printStackTrace(); +// log.error("上传文件到阿里OSS服务器发生异常:{}", e.getMessage()); +// throw new MyException("文件上传至OSS异常!"); +// } finally { +// //关闭OSSClient +// build.shutdown(); +// } +// } +// } +// return null; +// } +// +// /** +// * 编码文件名,源文件名_当前时间戳 +// * 如:用户上传的文件名是dog.png,那么此方法返回值为:dog_20231212112323.png +// */ +// public static final String extractFilename(MultipartFile file) { +// String fileName = file.getOriginalFilename(); +// fileName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" + DateUtils.getCurrentDateString(DateUtils.YYYYMMDDHHMMSS) + "." + fileName.substring(fileName.lastIndexOf(".") + 1); +// return fileName; +// } +// +// +//} diff --git a/src/main/java/cn/wujiangbo/util/DateUtils.java b/src/main/java/cn/wujiangbo/util/DateUtils.java new file mode 100644 index 0000000..a3e24d9 --- /dev/null +++ b/src/main/java/cn/wujiangbo/util/DateUtils.java @@ -0,0 +1,197 @@ +package cn.wujiangbo.util; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 时间工具类 + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYYMM = "yyyyMM"; + + public static String MM = "MM"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + public static void main(String[] args) { + System.out.println(getCurrentDateString()); + } + + /** + * 获取当前年月 + */ + public static String getCurrentYearMonth() + { + return dateTimeNow(YYYYMM); + } + + /** + * 获取当前月份 + */ + public static String getMonth() + { + return dateTimeNow(MM); + } + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static String getYear() + { + return dateTimeNow(YYYY); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final String getCurrentDateString() + { + return parseDateToStr(YYYY_MM_DD_HH_MM_SS, new Date()); + } + + public static final String getCurrentDateString(String dateExpression) + { + return parseDateToStr(dateExpression, new Date()); + } + + public static final LocalDateTime getCurrentLocalDateTime() + { + return LocalDateTime.now(); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算两个时间差 + */ + public static String getDatePoor(Date endDate, Date nowDate) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } +} diff --git a/src/main/java/cn/wujiangbo/util/IdUtils.java b/src/main/java/cn/wujiangbo/util/IdUtils.java new file mode 100644 index 0000000..5157d97 --- /dev/null +++ b/src/main/java/cn/wujiangbo/util/IdUtils.java @@ -0,0 +1,57 @@ +package cn.wujiangbo.util; + +import cn.hutool.core.lang.UUID; +import org.apache.commons.lang3.StringUtils; + +/** + * ID生成器工具类 + */ +public class IdUtils { + + /** + * 功能说明 获取随机UUID数,去掉了 - + */ + public static String getSimpleUUID() { + return StringUtils.replace(java.util.UUID.randomUUID().toString(), "-", ""); + } + + /** + * 获取随机UUID + * + * @return 随机UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线 + * + * @return 简化的UUID,去掉了横线 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/src/main/java/cn/wujiangbo/util/MyTools.java b/src/main/java/cn/wujiangbo/util/MyTools.java new file mode 100644 index 0000000..172bfec --- /dev/null +++ b/src/main/java/cn/wujiangbo/util/MyTools.java @@ -0,0 +1,199 @@ +package cn.wujiangbo.util; + +import cn.hutool.core.codec.Base64Encoder; +import cn.hutool.crypto.SecureUtil; +import cn.wujiangbo.constants.SystemConstants; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @desc 工具类 + */ +@Slf4j +public class MyTools { + + public static void main(String[] args){ + System.out.println(SecureUtil.md5("123456")); + } + + /** + * 获取文件的完整路径 + */ + public static String getFileUploadPath(String fileFullName) { + String uploadPath = System.getProperty("user.dir"); + return uploadPath + SystemConstants.FILES_DIR + fileFullName; + } + + /** + * @Description: 获取随机用户昵称 + * 返回长度:20 + */ + public synchronized static String getNickName() { + return getRandomChar(12).toLowerCase(); + } + + /** + * @desc 判断字符串是否有长度 + */ + public static boolean hasLength(String str) { + return org.springframework.util.StringUtils.hasLength(str); + } + + /** + * @desc 获取token值 + */ + public static String getLoginToken() { + return UUID.randomUUID().toString().replace("-", ""); + } + + /** + * @Description: 将本地图片转成Base64数据 + */ + public static String ImageToBase64(String imgPath) { + byte[] data = null; + // 读取图片字节数组 + try { + InputStream in = new FileInputStream(imgPath); + data = new byte[in.available()]; + in.read(data); + in.close(); + } catch (IOException e) { + log.error("图片转Base64数据时发生异常:{}", e.getLocalizedMessage()); + } + // 对字节数组Base64编码 + Base64Encoder encoder = new Base64Encoder(); + // 返回Base64编码过的字节数组字符串 + return "data:img/jpg;base64," + encoder.encode(Objects.requireNonNull(data)); + } + + /* + * @Description: 验证密码,必须是6-18位长度,必须由数字和字母组成,并且要同时含有数字和字母,且长度要在6-18位之间 + */ + public static boolean checkPassword(String str){ + boolean checkResult = false; + if(!StringUtils.isBlank(str)){ + String regEx = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(str); + if(m.matches()){ + checkResult = true; + } + } + return checkResult; + } + + /* + * @Description: 验证字母和数字,必须是6-18位长度 + */ + public static boolean checkNumChar(String str){ + boolean checkResult = false; + if(!StringUtils.isBlank(str)){ + String regEx = "^[0-9A-Za-z]{6,18}$"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(str); + if(m.matches()){ + checkResult = true; + } + } + return checkResult; + } + + /* + * @Description: 验证手机号 + */ + public static boolean checkPhone(String phone){ + boolean checkResult = false; + if(!StringUtils.isBlank(phone)){ + if(phone.length() == 11){ + String regEx = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0, 5-9]))\\d{8}$"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(phone); + if(m.matches()){ + checkResult = true; + } + } + } + return checkResult; + } + + /* + * @Description: 验证邮箱格式 + */ + public static boolean checkEmail(String email){ + boolean checkResult = false; + if(!StringUtils.isBlank(email)){ + String regEx = "([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(email); + if(m.matches()){ + checkResult = true; + } + } + return checkResult; + } + + /** + * @Description: 获取指定位数的随机整数 + */ + public synchronized static String getRandomNum(int num) { + Random random = new Random(); + StringBuffer sb = new StringBuffer(); + for (int i = 1; i <= num; i++) { + sb.append(random.nextInt(9)); + } + return sb.toString(); + } + + /** + * @description: 获取指定串中随机指定位数的字符串 + */ + public synchronized static String getRandomChar(int num) { + //先定义取值范围 + String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + StringBuffer value = new StringBuffer(); + for (int i = 0; i < num; i++) { + value.append(chars.charAt((int)(Math.random() * chars.length()))); + } + return value.toString(); + } + + /* + * @Description: 获取当前时间字符串(yyyyMMddHHmmss) + */ + public synchronized static String getCurrentTimeStr() { + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + return dateFormat.format(date); + } + + /* + * @Description: 根据MultipartFile文件获取图片Base64数据 + */ + public static String MutipartFileToBase64(MultipartFile file) { + String base64EncoderImg = ""; + try { + Base64Encoder encoder = new Base64Encoder(); + base64EncoderImg = "data:img/jpg;base64," + encoder.encode(file.getBytes()); + } catch (Exception e) { + log.error("根据MultipartFile文件获取Base64数据,异常:{}", e); + } + return base64EncoderImg; + } + + + //随机获取指定区间的整数 + public synchronized static String getRandomDotString(int min, int max) { + Random rand = new Random(); + StringBuffer result = new StringBuffer(); + result.append(rand.nextInt(max - min + 1) + min); + return result.toString(); + } +} diff --git a/src/main/java/cn/wujiangbo/util/RedisCache.java b/src/main/java/cn/wujiangbo/util/RedisCache.java new file mode 100644 index 0000000..2af0ae6 --- /dev/null +++ b/src/main/java/cn/wujiangbo/util/RedisCache.java @@ -0,0 +1,251 @@ +package cn.wujiangbo.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * Redis 工具类 + */ +@Component +public class RedisCache +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 清空Redis所有缓存数据 + */ + public void clearAllRedisData() + { + Set keys = redisTemplate.keys("*"); + redisTemplate.delete(keys); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) + { + if(timeout == -1){ + redisTemplate.opsForValue().set(key, value); + }else{ + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + if(redisTemplate.hasKey(key)){ + return redisTemplate.delete(key); + } + return true; + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public long deleteObject(final Collection collection) + { + return redisTemplate.delete(collection); + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } + + /** + * @desc 判断Redis中是否存在指定的key + */ + public boolean exists(String key) { + return redisTemplate.hasKey(key); + } +} \ No newline at end of file diff --git a/src/main/java/cn/wujiangbo/vo/LoginSuccessVo.java b/src/main/java/cn/wujiangbo/vo/LoginSuccessVo.java new file mode 100644 index 0000000..f310cc6 --- /dev/null +++ b/src/main/java/cn/wujiangbo/vo/LoginSuccessVo.java @@ -0,0 +1,16 @@ +package cn.wujiangbo.vo; + +import cn.wujiangbo.domain.app.AppUser; +import lombok.Data; + +/** + *

登录成功后,返回前端的对象

+ */ +@Data +public class LoginSuccessVo { + private String token;//token + private String refToken;//刷新token + private Long userId;//用户ID + private Integer roleId; + private AppUser appUser;//APP用户信息 +} diff --git a/src/main/java/cn/wujiangbo/vo/UploadFileVo.java b/src/main/java/cn/wujiangbo/vo/UploadFileVo.java new file mode 100644 index 0000000..3aa1522 --- /dev/null +++ b/src/main/java/cn/wujiangbo/vo/UploadFileVo.java @@ -0,0 +1,15 @@ +package cn.wujiangbo.vo; + +import lombok.Data; + +/** + *

文件上传成功后返回前端参数

+ */ +@Data +public class UploadFileVo { + + private String fileFullPath;//文件全路径 + private String fileName;//文件名称 + private String filePrefix;//文件存储路径的前缀 + private Long fileSize;//文件大小 +} diff --git a/src/main/java/cn/wujiangbo/vo/UserTokenVo.java b/src/main/java/cn/wujiangbo/vo/UserTokenVo.java new file mode 100644 index 0000000..4ffb9f8 --- /dev/null +++ b/src/main/java/cn/wujiangbo/vo/UserTokenVo.java @@ -0,0 +1,15 @@ +package cn.wujiangbo.vo; + +import lombok.Data; + +/** + * @desc 登录成功之后,返回前端的对象 + */ +@Data +public class UserTokenVo { + + private String token; + private String userName; + private String realName; + private String avatar; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..ab30a8d --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,70 @@ +server: + #启动端口 + port: 8002 + tomcat: + #设置字符编码 + uri-encoding: UTF-8 +spring: + application: + #系统服务名 + name: EasyJavaTemplate + #MySQL数据库相关配置信息 + datasource: + url: jdbc:mysql://10.232.112.35:3306/rensijin-cchs?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root #数据库账号 + password: -w9M627JZeYo5p^3lbH0mqDa #数据库密码 + driver-class-name: com.mysql.jdbc.Driver + type: com.alibaba.druid.pool.DruidDataSource + #Redis 缓存相关参数配置 + redis: + host: 10.232.12.111 + port: 6379 #端口 + timeout: 5000 #连接超时 毫秒 + password: Redis11 #密码 + jedis: + pool: + maxActive: 30 #给定时间可以分配的最大连接数。 使用负值表示没有限制 + maxIdle: 30 #最大空闲连接数 + minIdle: 10 # 最小空间连接数 + maxWait: -1 #连接池最大等待时间 -1没有限制 + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + #单个文件上传大小限制 + max-file-size: 30MB + #单次上传文件总大小限制 + max-request-size: 100MB + +#MyBatis-Plus相关配置 +mybatis-plus: + #指定Mapper.xml路径,如果与Mapper路径相同的话,可省略 + mapper-locations: classpath:cn/wujiangbo/mapper/*Mapper.xml + configuration: + #开启驼峰大小写自动转换 + map-underscore-to-camel-case: true + #开启控制台sql输出 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +easyjava: + #版本号 + version: 2.0.5 + #系统类型标识 + systemType: 'xxx' + #用户注册默认头像地址 + userDefaultAvatarPath: https://img2.baidu.com/it/u=1016407180,2828407920&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=800 + +#OSS相关配置 +file: + #文件存储方案(1:文件本地;2:存阿里云OSS) + filescheme: 1 + download: + #文件下载用到的服务器IP地址 + ip: localhost + alicloud: + enable: true #是否开启OSS上传 + bucket-name: xxx #上传空间bucket + access-key: xxx #你的key + secret-key: xxx #你的秘钥 + endpoint: oss-cn-beijing.aliyuncs.com #上传端点 \ No newline at end of file diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml b/src/main/resources/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml new file mode 100644 index 0000000..58be687 --- /dev/null +++ b/src/main/resources/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/cn/wujiangbo/mapper/app/AppUserMapper.xml b/src/main/resources/cn/wujiangbo/mapper/app/AppUserMapper.xml new file mode 100644 index 0000000..74109aa --- /dev/null +++ b/src/main/resources/cn/wujiangbo/mapper/app/AppUserMapper.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/cn/wujiangbo/mapper/system/SysUserMapper.xml b/src/main/resources/cn/wujiangbo/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..109580b --- /dev/null +++ b/src/main/resources/cn/wujiangbo/mapper/system/SysUserMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..96d8332 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + ${FORMAT} + + + + + + + + + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log_dir}/error/%d{yyyy-MM-dd}/error-%i.log + + + ${maxHistory} + + + ${maxFileSize} + + + + + + ${FORMAT} + + + + + + + + + + + WARN + + ACCEPT + + DENY + + + ${log_dir}/warn/%d{yyyy-MM-dd}/warn-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + INFO + ACCEPT + DENY + + + ${log_dir}/info/%d{yyyy-MM-dd}/info-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + DEBUG + ACCEPT + DENY + + + ${log_dir}/debug/%d{yyyy-MM-dd}/debug-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + + + + + + + + + + + diff --git a/target/classes/application.yml b/target/classes/application.yml new file mode 100644 index 0000000..ab30a8d --- /dev/null +++ b/target/classes/application.yml @@ -0,0 +1,70 @@ +server: + #启动端口 + port: 8002 + tomcat: + #设置字符编码 + uri-encoding: UTF-8 +spring: + application: + #系统服务名 + name: EasyJavaTemplate + #MySQL数据库相关配置信息 + datasource: + url: jdbc:mysql://10.232.112.35:3306/rensijin-cchs?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root #数据库账号 + password: -w9M627JZeYo5p^3lbH0mqDa #数据库密码 + driver-class-name: com.mysql.jdbc.Driver + type: com.alibaba.druid.pool.DruidDataSource + #Redis 缓存相关参数配置 + redis: + host: 10.232.12.111 + port: 6379 #端口 + timeout: 5000 #连接超时 毫秒 + password: Redis11 #密码 + jedis: + pool: + maxActive: 30 #给定时间可以分配的最大连接数。 使用负值表示没有限制 + maxIdle: 30 #最大空闲连接数 + minIdle: 10 # 最小空间连接数 + maxWait: -1 #连接池最大等待时间 -1没有限制 + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + #单个文件上传大小限制 + max-file-size: 30MB + #单次上传文件总大小限制 + max-request-size: 100MB + +#MyBatis-Plus相关配置 +mybatis-plus: + #指定Mapper.xml路径,如果与Mapper路径相同的话,可省略 + mapper-locations: classpath:cn/wujiangbo/mapper/*Mapper.xml + configuration: + #开启驼峰大小写自动转换 + map-underscore-to-camel-case: true + #开启控制台sql输出 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +easyjava: + #版本号 + version: 2.0.5 + #系统类型标识 + systemType: 'xxx' + #用户注册默认头像地址 + userDefaultAvatarPath: https://img2.baidu.com/it/u=1016407180,2828407920&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=800 + +#OSS相关配置 +file: + #文件存储方案(1:文件本地;2:存阿里云OSS) + filescheme: 1 + download: + #文件下载用到的服务器IP地址 + ip: localhost + alicloud: + enable: true #是否开启OSS上传 + bucket-name: xxx #上传空间bucket + access-key: xxx #你的key + secret-key: xxx #你的秘钥 + endpoint: oss-cn-beijing.aliyuncs.com #上传端点 \ No newline at end of file diff --git a/target/classes/banner.txt b/target/classes/banner.txt new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/cn/wujiangbo/App.class b/target/classes/cn/wujiangbo/App.class new file mode 100644 index 0000000000000000000000000000000000000000..f4e2054eb28f65760aa082657b59e6524ec0586e GIT binary patch literal 952 zcma)4&2G~`5dOAJ>LeJFCM2c&hQE>os4v`%DnTSp0V;xm1gEvTO*h!y$XQc(1JqOB zpjU1PkN{DM2jD$I-vTjff|{Tlu;dxd-#0V+&5vK-z5}>}+XXCO(L%;X7E27J0e{7v zfJc4ju{RLDW>~r_BdIqS78}i;g&ZaMk+Yi&BxQNZxi=gZP{0WbwvCfG#n4i5-x&>K z8TGeg9*SKRzjQpMw9`$UR1rv@YpEhajT4eyqjTK39q`e}eKF0HW zJ8czh%YG7bFA!5L$Zf)I9wjVWDBGyu^vtH+HzO@V8bu|vZ}m@Kshmw}s;RZ$p_@aE zVXgIFUjb*ZYT>Mnb2!gXNjICtW3bFq=zw;wPVfGA(_Ri28P;d}9ep}HIy@NfzaQ_t z`}uZ%ymv4gXUMeGmS8A$WF#IXp(o;}<~bP39p&?&$75;ii8G^j&0`&^u~tlNIen)6<}ujk$cMm&6mTi1?InF}bVzbYfG)ySNOC&f9zoVCKL{ULwmO%}8fkU%)=3 z;W|kZ25c%bGEKl0TqP@yYq(AzrucaZ2Gq+|>nrllKB8Eze#VN?7be=+$GA0W4HRjZ l63Jz(piD@WsXleA;RfY2=+Dxfky=1Al`Y&PZAQBV{08v;?J@uW literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/annotation/IgnoreAuth.class b/target/classes/cn/wujiangbo/annotation/IgnoreAuth.class new file mode 100644 index 0000000000000000000000000000000000000000..d3b035ec71df74d5822450686d9a4c3e61a7f4da GIT binary patch literal 437 zcmaiwzfQw25XQeNw1M)cg^d9fI&>rpTc=75q7tPj1QsSIoPs0QMyXxYS7YD-cqoL! zKo}x1+?{;)`#$;Z^XvTsz$K0YvVoEq`ren4q_KSOV^bc}pl*~3B4C05| zWHyfo=gpF-$z1gbejbkqge@O!e|?~Z;3w~3*Vlocbp34a3B=gP0S>DdqlZ3@fNxO2 BfCm5o literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/annotation/RateLimit.class b/target/classes/cn/wujiangbo/annotation/RateLimit.class new file mode 100644 index 0000000000000000000000000000000000000000..2379b7190083c8756f6e417f86493684bc599b90 GIT binary patch literal 620 zcmaixJ5K^Z6ot?5TE!P2K2Qm2L7;IPE2&JtNCIL2ZLEfMB!kPYfmsZ#4Ta%f*jpMk z(cb?-)IVXoTL@c_SZp@;}PIqy`_uj$!GyPD^sD*|2qPS+?Rz+Lm7B zN|a<`IHPw+;Gsh5}ka=;% z9aAxcO!v$KhM>_mOhE~mY|&4JgRW#dmU0J1db`_Xhb@DKDiht)dwj)wa21F!TkJO+T`>AX*LO{pdl! zhh7=?(Z|r!RM{|1ovUQ%J5lu-PnQ|`gYQF^KpGmWf`359Ach!vtK4?@;}$P*!`4*2 zDh#hM3*{w@5PUk5+fApk0%c6bxQL>=8O0vA56zN<2?p;@BDN`Ein6wy$Vqrei_AVP z9?@AQouyTfQoET*CUOZ0VTSfhEEnGq$g?u${zBg2YKdDuC=6>iCV$`3H`FRGwG<(1 z)~q7;BPvSql)O>GRE#JVWIV?r!;r-*T9wk@V#$!WoRUU4k~g~10z&2U;RQqJInoTh7vtC9H_9TxD1e{wJLqtwZ{fNQ;JYT07FHs|zMIsp!pSuex+@$5L_PW{ER& zB{hSmYR3g`<se*#IfsOovu(!{>;(`z4U)H9Lftr;j9e~~7{Wo4KPhOUjRB`0Lu z;kwT-f32B-Z=FK2m0epmISlJJBmAS42yf_Jji%<9=e4RvIf)sDX*&~7DVe(xoE)(E zXIoJ(RFw@HT#*#lD@qIHx=-}a<+?=0tTQa$7Syd~KI|A&yM~5yrpZp%?gY4&T8U?j$1te;snf`wiW7 z^hW~2b&N&=4;(q^$Z1E;IP$S0Lyjc7$T^~fGQT$)coM1O**TUDX3wzvg&5i(yjr1K z69_<}>+c@==^exM#os;P54cIJxc~qF literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/date/DateConfig$1.class b/target/classes/cn/wujiangbo/config/date/DateConfig$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9886b8c68593a907ae8168a0be63c9f7cd39c0ca GIT binary patch literal 1690 zcmbVN+fvg|6kP`ju`x)jiZ@h*qAeBU{Z_<#%w zIt}u2p092wHzMGi=X=q-z+f)FV#3B@0~rfPaCDD*H3~hyE|8*a3LMSl%YCfQM<%l| zX5lza5VoQGdbA$HE}J-o(+0*ZoWWUvBXMNpHI-8iT-ne~5g6K(VT;zuC6G(&GOViC zZRNYF*iE@NuxMbS2N@T(_|8?Ekr(&}FezZZ=QUfY%+_iqvY0k-!NNu41Sb0|)`GAp zqj)$k$!aNHMk*9Y2Wu~6#7AG?PLf!+M5^w%;VVivR9e3pv1e82 zP{I0*Zcr|_FCFGrD4kMJ<9tWUp0A#@o2x2(DOVeOlZmOU$k5a4?#q-Gy1>Q#z-O-( zDb|XL)`Qv$so9eog9X8lCDgPl4Z07vf_CV}+5Zr-z(_Tc?yHL2?6SF#Y-VTc^yHY> zO@vKXy}B=>c1YyciPYVg^8a*sE`ie>WI`Jnlex6^Z_$7-B zregvV^vUqcUEGVQjPFtzM-g+xy3bht30MmT0lU14fc=QPbeWphby{6+dZzFL_BJkU oaq(xh7UAgBP0_=$!FE1~10Ld0Y#*aUo1*&yp72RGJ4MUuH|n{wi2wiq literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/date/DateConfig$2.class b/target/classes/cn/wujiangbo/config/date/DateConfig$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c12bf7e40e71fcd79c51c2da53f954bfd6827abe GIT binary patch literal 1723 zcmbVNT~iZD6g>@rF>#PFD!MKzDrz9&D6lIM#E$@CRiakK!slkvgu!G6XC|;dxxZt7 z1wP19`>?go`=cyRPX;q7rHW#z(zieEJ@?#??)?AtpML?&V%0#Oz)i=qciUU8^cw5F z?fBk?+pz00QuY#ua=gwWg8>7BCJdYsxOEJZ@o9mTW{=-q*k?VV>aDxXQ`At=;Q}z1T>gs%}H6MmK zjN_Jp+a~UyAaJ8gYr_v(GK#CEiLJ!TNCg5}f8&jeIQ0bP(kzo4r1>3%!bDxhq)tXr z;9VM|C)7>~;z*A~O1taHC4FQtW#S%e0fQ~LqXJfYD(&qjlzTA@JP?@mgN7Y$>+){| zvZZ$Y;5~afP`a@->Y-GD&DPdCI#Gqfu^Mz@jXhQN>n!?k#r4#yc57V)Z{>QEJNcN- znhadMPBt_81_<0a4*d9ZiCtV((WYO2BQ<++qp=|Pg;a}u?-i;KhJHJ6V(;B%N>U{- zREwnZzACp9Hn-CW?cAxu9!*^{!e(o3!;?`vAaXn9IMU_VYJ{Y4l-+vqj22%G_k}3;HMjM)osTeSC3&L0W>gzi}MtXyJD} zrElm9` z;u>|e!x0Q{oFVuuPag7Q4tYF^35-!E&yz=(kEx7)r!tBX7Krtjw)~ecmka_Xyh?!e zjJ$N1n%4}a4mUel{14VX?(T8%W3*-*c{Xuzh-HE4d=eWx#j{vGN0~B1^(DOEOeZ@- G$?qFMIKXlM literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/date/DateConfig.class b/target/classes/cn/wujiangbo/config/date/DateConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..3f85d9bd04829dc9b85289a53b9c9e4d1c908985 GIT binary patch literal 3943 zcmcInTXz#x6#hmTRJQH{oYqAEzmtWwy2?3V5H>ePpfMdPZeFgE^tNh|q#w<-Tp0!bt^3`hn>^E8F^-EUo*lqb!oa z^NOjj`QGHk3;F_G%UfkL>l#(tOrT#mzF%N&d+dhko1UI=OVUID`*198Tg0J`y+;A{>xgUv|B+3_{S9v^yb5Cj|Q3 zXAT;N&GN_s5X>L?|hKng=D0LKK*)P!{AQ23t^IMgt)$z286sU%Kg zSfF1TM%;aYXK_1cZ0Y;yOnYRDmSgA(3{zYP{dx;WIgFj2v&t2_7RYppnf!4QXD~|O zN>x8_%M6IXFHE`}BnFLey%pWBD5RG?SvH@#-nw3N-9VSsz>V^~>M^fsiM9}}m!gWv z%1XubrmL21nBL5mIbK@BS%K5rD1!vfVM4?CBy?O5m}zCrY7kUZGNQ<)p(nLr^PuzF&>2W@oqlE6fJ@aw_P)yqf2Wr17mS>lD#x%YPo27d0Di%lL~v*qGV$xUEAylRxP?avaM@~ zGVHB3Pa~olQ;oQFXDGSs1+`k-T3M5IPG(+T&RTI~z@{M}cPQrOn;^w*fqJ7(-=@C9 z537!9^^2Bo5riqnad{V71eA5zvc1v%zI*%IEa>$nDq9KQy zp&90N@zV}(y_Q+=uDxw+kY7`EvTXIyu^T1mGn=(x6sG0!nJe!NL)$3G*Loq221 zWL)ixwC$V~nCSu70`sFSA%6GlAiz!nV{nuB2H&!$-*p@gNorU$eGQy^M;fzklatNR zY2b^=vCcK=Kn7V-0{3tq-68WNS9Pv$6Iy`+`hF$Rg@%Bkn1H^TfCu53FY%D8 zQj_BUprN{$o%Ycz9~<|$(bBZZ-fB%jxxU$ T?i?YdaaEsWwBQH$sN(RydoHh= literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/date/JacksonObjectMapper.class b/target/classes/cn/wujiangbo/config/date/JacksonObjectMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..77201405df659df1f509066aaff0f23b1e2d9a80 GIT binary patch literal 2659 zcmbVOTUQ%Z6#foiC&U42sx3up3u2pu%TNkZ38ltd?UPl+Bd(GTWK#ex|guo83w5<~I{L zhLu!btPwv(F(%=%jQ0>=n62o_v*w}3^;+3bDu#Zb)kKV{vegc_H_YMo8;*OmV4p5L z3V8wDMjemem+=9vGK|+$`?Yk%9G@BP2R&)eMH2rwu1lDZ@gY89Sh`qVJLbopY4#JN zX`fclVmJyu_KNd0hfcAPJ_C{PF~g#V`wgSotgA{+YaG?pv?KU&Lp1&*!?i>HlqmGxblL2bLsS4wR&q~ zW3|y(wJbmGASfXuBa9h_sje#rhS}h@(s3r~h;%I(hK++AZquVK>Ys8Tb!ufLXPcT{ zqeObMQ2nPcCocUw!<|zSCk1b^8wnLe$`)kY#UjHPuU6d=GCX&?6038|iggjf46vkEMrbW`Q=+PpXtWj>9AEzKcbiurA)|3;wy#`DrNU?hNt}%vP;o#88;aoyj`_=!s{CL zV?(4Vb#We%emBpyNYN;=GIsDa!>Fm&G_e%hvxA}Fxdz&AdZ(gi>QhU_6UpdaDqo66 z^NCV2yPJ;Y83Jc-In|A(uw`@IF7SGjHs^Q`G{2ed;wKz7m#UP>mU4+$HWT;Z8-~l> z?rx7Jmm@9|!%)nqlBuzjrmLA|qpX^FUapfS;M}?br%jp!^>o*)(JT literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.class b/target/classes/cn/wujiangbo/config/mp/MyBatiesPlusConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..9812febaa6547df44ee75e686bb9d53a8596f665 GIT binary patch literal 909 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 B(uDv3 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/config/web/WebConfig.class b/target/classes/cn/wujiangbo/config/web/WebConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..70a661ee8b409ad77d8e8159fc57350993a146e7 GIT binary patch literal 3191 zcmb_fZFdtz6n>^jn>4IYQYf#=OHtD#Fo?WKY85Llg`|`QTPwb>Nv7$RWH)Db)0U6^ z3;%}ac;F~Ue}F&A<1@S4bQ>c`G9; zWyftwuj5*FbJaE5YSVF_%1u?1o^m%@%9nM=UbULiv~9;Xeao@svZ_@!>a&5o>jtuF zx6^T4Utna~vMql`Ad#C|N+B(9e~^JS-|uMT4dwdEmFpg1D`uxd7Wd5hQ+{5$%Ow@% zd1h15RJbsMl;*xqpjfx%W_R5(?Pkr{=GZWOB_sU@wRKhZHKuYi$RMG0_Zv8XF@Xb~ z^5Y8xF6PR0r!7}ak9@Y;Ex8`jki;}=mfeu?^`)t$eaK=wg+m4oV?tp6y18M>u5Yzu z+42~OgxP2aOyuUu!Ay%pBM2&w;wX-#aNNKNoD?`S$Qiu{jC2@gfkOgUq-Dh;4-o_>be$2f# zvF@67qov%KT50OFO3azQY>eqge1eQD=@_3g@IF2e7;8CA%Z{xSDExci%6*GVDddQ; zvyW9@mrELXZnMniGbrMG3KtAWTojml8!-)hV4^av3#PxuA2;3h1fJv`$1*Bp@>b)P z#w7tE)3_{N#iqtwDgtd2eUVsO5v;<aniYZ&Rn(wx2%6()KfsScETT7;E>F-FG^w%sx zPVVjk5!YRV!Gqf~TQU034_N1>3>`wG`v}!eN)9<P|SwzcJgI;!bMt zS4h4E-^2MA5I+YhU-PM_fkRl~(+C&f8$9M$65rxGBm(6vz7v$4e2LV`3yfBZFOlKE zc#d}piQ=y~n1IGiKx1a93!Fllq{lJI3)Hy)|8$5E;S&wt;|JPI)BY2fbgV|bkcFPB zbFM+ju;2%v_#471g-xt+q`mry9_pwp6!O2|$aB2AtOt`EB!9<;D~aq>^*IV7;rOHK zN;3O#b!9kvh0<%OP7kIcsW`f%KAHoE#;4H2( e4X%;S^%#+2k4TY3p6(_xgcj9@(C+1q4g3w-RJHg3 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/constants/ErrorCode.class b/target/classes/cn/wujiangbo/constants/ErrorCode.class new file mode 100644 index 0000000000000000000000000000000000000000..4e6345b7752c2842789012722385e5f3762d274d GIT binary patch literal 2996 zcma)8TUS#@6#fn*WC#a53~EKKf}%jI0&)?=S}jIv3u2AXrrO#NA_ha!CPD2Tv;tC5 zTQ3!*)wXEWwJI7fP*Ll1ANw0PBtH4pw{~^UoTvy{i)O84=X~G3%$~hx_WASQdk+DW z;i?5m3Ub{3qW$fyUYEb6DNy7N_(NfrKO8Eu2ZMoNO`zG63I!$=W~3;{a5x>??RC2x z4K+1(heN@l+Ud-zg*{V|D(q+2w{5H6wyUOogMC*?adC;@(p0DkxRrv-P%$F`S1Pzn z6+8h~Cb*d@W+mXt1^1GQISIH5!Oc}MF9Ekoa4)M^kbtWcT#ky|1YDKi7OTjc%9Rug zZmEj=1f1NLLKU_IoZOdJR4f;q8n1`kR^hNnMKMYgSn?Xz*EZOxLW_4yUm`0?QD#Aj zigHvaFuQ#LzlV0Qps=>pwa-=Lqvj~8Z))|p!_`()qRN8RDyp%DD)d~z?r(3S$opKr zc2E6o1?2@3tZRI(P^fwW;0Oo3{+8;A5rhNjf31qwuuehB8n53QUaMgCL|1Xk&4rC3 z^|w;wd_(*I>|sEj>P`x9v`3vl65`!yWTx& z=;%GeR4JK;jp2ylg{u3F0^1}nPcs%Si~`3Vp41OhvruNs8IF;06@3^^P-{eQjYdZ= z==VGH8^`tG>tpx2o;THrW6zpO^z(NrPU4if9poVmDOgfa_&@FkI*CsWOkyO^X{q)4 zJzLt_nmobnt|lKL6$#Er;q+IJII#h@%h%`%dWEC7Hv#DSq&mDUepk3XNG|ddtSiw$rCn+9gpKT8y!hhx z4aFpdI^+JJk+#O|i{DPk1%-_Y$|iUfH`$u$lV4j+P91^vpxd+2D>gCX+0Af=>XC?yR(DQU<_Ndrwv8eUS;ppue?l9V)nq@-aZ zB@Gsem?UmhDe2w>w7Fug(6fc&pT;R#*BN?RL{faL5v;h2m5)$*gPs(8ProUWOCkMg zoF#ukzl@}?uyVyVf>n>82>qlN^!o`>4K19LYdBAcS;4sup-LArlBKhqB+W!|+p_t? zc-6N24%XYUO?P0wNvPqJ!$kjcXfe4+qvd8|F+_kIvL#Cl$YjMok*giR1ZGfntG z1Ae4$4Lxq6?*;lM;UcZ?C;UvmBC8^jA}h1)Hr7v0XsL{6BxH`qQ}9bdWBX)d+f-xC zD$Z~`@~1LAph?Sk0L7UcL9)YXiooJFq)SlNqpWf;UIV;xFed>j86rB(1ZlKE!-)-dXB zAz1=jP5f={kbp%34QAfR-<5z>0`H~p9sGR>q)T9zg@4GKB%n#4nQ;$qkwBINyjlux ztf5JbL$U=#Hp;`Htyh9?3ByvzoXIvS9H p-NYS$hF)R^sPC>L3y&}pf6*K37`>VPO(QpBmrgI$;bZyA z8DIDT{7{aY7Buq8H#_;=?(P0}Z}aol_a6YT2isFH0;4Gyn}%_iATZx%pP3#o+0>nS zTkwd$#IY~^=pBL4jm=sLGy>~f>RqJrE`gMO;RizL1Qv&xha%$UjdEFo z2Lu*^u<1)03yH!{LMqHMdlifwP^ap}9UNni1+!>WZI4!6vqFa<S(}xg&N-pO;l)T zoG#L;;UtBV6HeL~*<(b87`<65(H0t2hXsg>Z%(E;jU62w;(}8Yo?9X^V0xBOAhS@% zX;`FC?^%A^km>e~W-WzSBjrWq89JUP=EZ#LfM18jI7`D49gRXO2tnTTdf(}EMl83D ztJGo{mTNd$#|oUIu%y(}zU!n?mTPo6gLa0Vj-Kgf*Gk%6pOwz0OrOS_*Xg)}hL@E9 z?s3huHR8DYjHKzCM!?Cixt7sWC`8vbVWoz1b(}}=VCA#cK#w?CZ=>VxFjF}iv4%mJ ziIRYQYu0j2-zIumtB79tsi?*IxIjaTj#jKyI5ogY&bL#7xbwY*%)H#YZf?d}O~=>ad7NLZey&|Jo>rJc_# zPXu(KTfR)-$+YUtCk9Xk}_Me;!~ zx<>mPCq?^ehfJ^2$_)BL3iAtX4b!4^>23{|m6~83NLX3Hh|x9Lp1-ffZd|V63LP)N zl?scB7M-e2?XK&%ZLC5HC$#tUZ0+f9+q$8>e`QnCd0eL0Gi9Xco1M5yiiN4LxbgV> z645RsbR@-<;-zh-=P?bFV(=avgJNxoDGYcQY#n<=MibBG?0`R|BVC670^xUbWQAWR ze@EIJv}BjEh^xb!F0`^q(4W&Wj1hvELM-Wp5r`mLSWqL9C>_;tbs42ArO;ig;~-wh zVruQrnG)rq$maF#7Bw%{@scuX&ed?8LaP+u0n*P+5bQ5n?&QvOmP-A-qDzEAc9Y3TwZ@`DOMyJ!#8&U>RPc z0?gN8TicoW{N&{%}oXAo4V^Q;s*cc<+! zY#WHfnR+U6PrkJV*(h2F?6=}=8s4tsM%+YO%GJVvyG?peLj1m+C799GY_C0?^+%cM zkv~iLn8gz7cj|c8^jJ5os>jWEkB0Z^cpu)cFng-Jhue#J_SH;RjwT(V<^wuDSVqli zQS)Je^G5`59c7|chmYao8g9|?34Bued&U^b`7A_6!X3@}j?rten^>|fE|*TOD#?g^ zO)7v$L=x2BrsH-gcXLA2cMN9OTf=U?8+YostBlcWq*NZ!F)oQai#Zr{^gd^wm8rqq z3UgD^;rj`peqV?lXQxl$(;Dv4aWC#;hm*jYDSN;iFpWK?=kN7c7Nr-2X~uHkJMx$x zGme+y(T4K9cddrchMt-l^@bfo@E%yX!>PkDRLbS^I=+A}avWnn48AML`@Hvpg7_sJ zUzR=Ba?k6AIgc=5kKsWbUlkR#R53;UnvSmvRpu;NxI1VuUHGPsZ;1{msy&vO3hBr2 z9Ub4z^H0&6@I4*h#}8PRlFS{Mj+T^3|3cWTCp0WG!_?S>A4%{1FoOz>} z-jcb;`lwfig?&zloS<6-JxC_k{6JY16g)QSVTU7s@otMN5cMu7&JG^Lq6|s=KL)QY zUbVdEF5>d5OExlN!CAe&nb=1ZM&_=XId~ke0KL^l1fH2I=wX|(Jb%5D9F@Qj_1k+b zwg^^Q(B8ToV}994;OiMl{z#ow zimV7+HIHn6;{Bf~_}Jx89{z&A@>v(Z{7r}+c@_SSe}ucPxQk}h(h&!_)6Q{RdJ|?J z#m-%~gD&X5m&AcWq7@N`3W@t7Vy2L|Ux+219EzNoci05{3fzaq-75+u4~XOnuACXe zHIwGNDAad|W?kPBi^t}@R16-&%Xd=StK+c=ysiQ*Rq?8EyyeFH9^N5B@u~^Do6YNR zo_aW>R!-nUvV2!db-bGU4EOrcG2A-2=pDj2jU@pKGa!*9gn~{Gj>=#_*N!jz&Ke-hE>X-;UQrD2W9qIfO+F*9O$dTLz9cr{NOj z#AY;O3oa%mI?#IcHuBj*SFwGOrRh4<0?D|6AvRnbR~(C zAv^(F&Bk68M@B6~R&~HrJ@C~o@2o3~jydnfe9*ycC9>+fkoPBCugvM)? z!oP^YO0M}3{!Q&Mu6hJd;wd8e2_7B)Ly2mx)X(gD6dKoBu9T|a8_Y`XaRH$kNUB&~ zQdJSlk|m2!JHMf!;YoS3w3vVMpG32ULmF6J?Z)q)^kdZB^V78N&}L$W2=4SQ*c7u0cd z90!yaAJhkDc>?cV`( z;lm&*;8WmNQHeDS8z;0$jVCoT&Ih9tLU$R~95hVB?Pc)QH;e=kK$U`^inUM~cIqad z@+J(Tk6Jutr8L9jPR4OXibpce8AsR*YvaO|J5x&uhMM|@@FOJ=*EY;}D2VmgpkSkl zr%=sMTO!tTjU?~SoVKi_!%&sboUkzCZh~QR{Yp^{;|gk)TP7~)BJCQMNpg-Z?gQ9D zA{K6apZ#*?{_NF-kMG`}z5U>)+Yj%26vQSxEg`9WjFOQmY{Rn(o>Q?M&zImvev|tI zm*o+9oAVYL79S!{UGi6GDe`v*b}HDVVmDr7*pvgLl!ie`OOB+u%!GVgLJcDd_ArEW zE5)Oll`>+M$5WZ8<{C~q={a1tY(a||Go<4Vzvu}&!%xX|)Yj5zVFytMUjU5+sz>oT zCj%t!npL!*m7zjhWY}MfaY1(x>WkK_ysAPQ+7)!D=tLJoV@XWOF4wk_Nn!J05jO}i z`^eH2!+OdgnKBV!PZ~O9O>?+}oj%F?WvN!6CUo~=pMw1=4xneb<|ndJwo|eWnxyeq zeR$Q-7Vr!eXLbRY01h(j$R}BL=H|ln8}q;YnEmw1!#h_Nex8~C_SXE>>$!vrz!$_z zcv(T8io-auETKW|fLrY!pcj|z=qd6?ESR2EbZ>vb!g8L};kr)vnh*t5ET z{|Bo?Kl<0V~wGBP+YoZHIk@N```PCq?lIYW2- zcv1b8$8Uw45cSz%&vcEH7%?0pniPGeX}Q!ts9R7-!jDhC^P28j)J(J`2Hr<0GG*8z zMq>R(tQc9fA#9jpz)MAieOe>&4Ao&v*ODWeZOC)s((fh=(zmR_pV%NsM`hBA8`K(Q znf~VtqQWd8Du;z%wm^p6rIh8fjzP_J(?Z=d99n&^SlNcj8=oaxj#B7)3|mTp%A^;; z(*KX5gRAkam&{ogaW(xyzm_h9Xk)){6IN_UlWmAvHHB*#PDPn;B5u;;p?pY?r0%j= zG$o=uYM8O&1RAm&mo%p3?*N5&QcHRSNfoyXOa((pFP^r`SO>PdxH}8s2A+t) zh$rH~5Dt1VM)4qM)ZYC&TEvt8f$_~knl|z09^TBG_ult?Z{N(9A0Ivg7{a9p0tki? zilPR!49(N}oUWO=mD9$v)7+2@wZp;^@+w0xp2*ar4)tL~qBwwPReE~Cl{`;bwns&+ zDIZAK+HFTzGA$jh=aY44WN6=6UM)RbFFk(pZE>l%y}0viGRXJ|?Z zi;sEvEO#dLtVt)alx^r{Mt6kr_YXtzo*-TEY7M`IPf|0I2nPlR8M@+smCn#H;aO7T zc}BQ`Xs=n8Ep;hui&(p>S@m*Eo6sdsiM)_R7@Xk?3=u`^A6;RnF>FE&((MW;XTebY z1@mr>p|`ZUQYx%{|F}}zezf~yY4`Qk&gO&N!qejW3EK;_U(_A&{ z++9b{^Lg8u(dKzp%L;2st59=;%Uk;FtQtPi&FQ8`bah(!M?})L=NSCDP%>Jo2hy)@ z7{ld%CZkJJF;61=pVIptRaa>BHR2SG(hF2y0Mr0#$sQ+9qm|KG)3*h->4!VXsxZ)m z6J(=%2{=h0pnVs*2}BhS`(QxhTZCf`@6Z%$*hcFciUgog)T0Ml=`FWaAT{nIou*h1 tWt>3>JuZ3?A4LLv%A9p^4(Exh{|=Z-A_ExkQ3s)_V&q?-^g3_zDwzU^~`2!?d_{o2uPoKWu%a=IRD2IB3sHm#0Zf!}4~iu`=ra+Hb*Oq&QR8u?Djsi2 zw6$rbrN^QY#+x)|XlWDGrNde%3yx|{BAJXS0Zf%~FQ!RY?3?9r+YmHf_f5?>VY8_j zjhY(Spb8&MPWd3hI4Dh)p-09;66ApwZVntd^zWnRl08=i_c9sf zs2~bIg}ShWVjuWm%!Xcsg)$z3!lh`L@eyXl=;dCc_TbTmARk|(0+X*EOdjhI)E3Ls z^HK=~G|*(JR)R9C^sesuakT3fkme&Y9>sD7gmKI$s!20C^$_Ev_|-y6;{H$xx)T_} zN~{dvF&V4yB?$|Cs=3>2#@AFkY1J2}jjg-1kX2d6=vJXRfEpRKSR>(n-`a*|CL)%y zzG>rzM*Ec7FcYDWX3|M>O1BO2$&lf8=B<%!? zUEm_dnh5X?2}``vP80LFcxV^{*vX^_#X4BeV;y=pmQXsnTUARp7w41YWmGCI*EVS=fNpw)Lb?T$34ZOk8?CcIs4Bqeg~Vc}?d zEG=r%Q3{>crqf?>l?Qs0w}h$604U`WpD{Nk;<1okA)dlF19)1-xA2UF75~363Hg*% zbIejBcDY|KmVQ>ox3P}`<)cQ8;T4)r7ih1;_F%u*0vr&{XZ_&(C~Kjt8xv8{l3R3B zr<|*zQJS)4BH__s%xF{0xadJj0n9;7ZYASuQLk(Fmk?H9PN>##&b?Jr{u4LG2 zVqwN)LQs!t8xkF@n$aw>g(&UT-=Z>ucRyEm zO(bqAd@Vu3eE*bTmnPScv++q)Pr)^l8g7@O0XDHvd%YTWxlgRutevrNgDM2G zY<}<3T9sBk8uq%pA!b@!DlRq>67o9LNP<4jQ=E=c9%S(`yHswO49_f+8!5f6BOcL1 zx@FrnIk{}KgE_V!F3>i2$7w9LH5O(%h zCXe?HoO&&JtT%b+!az^&Cwq@1pF4c}?6U)h58XM_bNl4EPxih-j#AUg4W7qJ2D)xnMlhe58Cl6k`^Zem~ zo)dRoelsh{6vIW{9+7S5mo4iidNReH!#KuOi(M@@!ks45aNy9fTm5g3!v5IWHNiE_ zYa~1}>fk!z$mCJ6Vlts3nsZ-yN)JCRVcDpcYasAcfumT)ut>A7k9zt#&70D$btQS? z8grqpHu?JL+ZRt|jlk`TXOjE&r{XYX-5QYw+_m4e=E=4|+_o#>vEh5;-FFfs>;^N_ zh9pe&SA7-^xBBh)JhoQ)sSR73R}s|mLCx>8%*|7rP0X?poS!_n*M4Ua734C#XbuX71W1F9c0-l!>>jI3&Ld@XX{v14vGA!cXVscu7YAm(k&2k{P@CXKn zafC3(V+CHq_XzR(T&n;%|G}I9?#shbUgk+01=}w*oPUhtk8g)$;s^Mld%hYkljbWX zeuP&|{1~s9oO0a6>o~y~JUNL|;^z$$Z{jo;3kXl1;faK^X%{upzKF$C!F*C5*1C-A z(u^I47uhVT$hexHqiSqsQ=OSZ~eBN8|_dIE0=0&is{@HT$p#yIE_nCt=%_M@>6 zUmXNreE0)j%qL)z2m0hR^vO7npVBcd^z$4nH0k&Kg<+sy6uv+2^L?*?-a8EROD^=a zF7zT7`q#38ew^BP!UMV}4Y~;J_*n*Yy9e|Tk^EeUQ+2#bD-jv~9f#Jy=n^s}GS>ipT30xFnnuFJ_Pci-J#3HJzA-E}M{( z&NE#?`Iv%V;Fm-`jYZ4AuW01goF`JldG?$1v)}Tb5Y=oRGhE+KrRxWR$p;P-3BOAV zJkEs$?h@D6R{eGC*~+T*B>(qb#dAK`j?nj0GY33yOVa)?afM!hN%%cJbm58;>fHGQ z?~IrPe;gVcy8va9;7=(=9|=YuWl4e@{F#Ju@E6-3b4c&6y#8A{{vYG-d`i`QjDOfw H@1Oqzn&D4I literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/controller/base/BaseController.class b/target/classes/cn/wujiangbo/controller/base/BaseController.class new file mode 100644 index 0000000000000000000000000000000000000000..950adede8f63b683e3fa9c0e89bd770ed5ec06e4 GIT binary patch literal 3218 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 PP0sPk{0m$v;+OvdTylm) literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/domain/app/AppSwiper.class b/target/classes/cn/wujiangbo/domain/app/AppSwiper.class new file mode 100644 index 0000000000000000000000000000000000000000..84d51bdbacd20d4791886da38809d312824ca5f5 GIT binary patch literal 4843 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 QH=t0wkw)HMn`Y~N4oo2ot^fc4 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/domain/base/BaseDomain.class b/target/classes/cn/wujiangbo/domain/base/BaseDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..8ce5871a34569e465c79452e35637ed89057935b GIT binary patch literal 2262 zcma)7O;a035Pc)gdj4=+v1Z=9}Qx<6pEs?a!?#hny z3vx+SPC3N)aN$6zY+Qw_Qpv@s%5TUqIDa6=IL;gG3M9e7Ra-MXJw30xU-!)Z@!!EO z048y#6(NM9P-0LK5lCzs_YJ*Zl(zKSo7-mA6NpS(CCj@e5Kawmv_L~k6s<9wK}=vU zThbp?wk_Ik+Ir3|8dgc)G+a}k<8ZyY7HH2prs0`)UDH`Hil#v4^0AwB&#_8dX$jmO zLtLV^SIW6M`&Mps#L$Ve0$SE6Eqqlm3Ig4!Iut+H^zc1t+#N#?&IxpEncjSp>#o#r z-Lb&ABq15Y1?eGTN_bb|^u_Q-4d-rCNFlrxLq7%>Qr>X$^LCDTk)fq11_jPF=Qmfe z3OUnh#YKcQye)9yn4nZ6Ju}iM6~iz_7>!Xbo28t!xEF1?wAQv%tKPYn75`70nIHwWydam2A)O zEW6|i3@_8%ePC>DnT~E8@948-D??TatBzeZ9q(aUK)r7iD#VK)e*5U~*}-222Z!H( z_xH}8z{GOaF0ym%qLs5Ndhy{V@!fKv;?`m6cVsv>EVGc4VCL7B>xJ3IAmWQhk6-+- zSBI$hC5bOvC3B@x+%%o)Y1w>s)+lTkOps`SQt|Q@lex6~8Vya~9q!4_YUsyWg*JGl zGNzZebE}5K-uFz0ZshUChGJRl#(NQTH1o8*yy*y>l_3r__6jRj-94f9jT_5lRkfE-wEoBxM(h?icG2Kdm&p`ZykN8kCQ0ux~ak8wCY?}CShhLFxg#liv z5Nq`=$B=wKC{MC_U0l6S`2!ap;v))I?_r8Mz6B>O(#IAp+~uRiahfPPXTez=c?$6} zg%D;q%5BiuHI5RF2KX4Ca2E2B;MjQhF`|3itUsJM^)O$CQx3N^AMQH!@GR!&LVA{o zhB!w?MxP*hdfYv}MG&{l$tQ1~=TyN(f{|Q59kT6pA$_(3$aoc!?_m(-Kb)iVmLDDY z397O?`Wv(#p@w%ye}$GA8`(#qx}?yxGR9#_8UGz;lFD;*>>xItRQ7ScX3;yP(xi7P zl2oNliO#2t@QD`sG6Ge!hCSKyaFSZB-WGs*jMgD#QGOp64ESV}< zkdf9mi{EK}#cG` z<`+`mJEh2tq!R3Cl2~r_ole-Kj~Wmb=Jm>8g+5i@x7(CLXvG9p8Cn>F?B~xYDOGZA zL3u@mLUM#4ArRsfjgHqLspy7UGpN}pjVhYaAOAE#rfU+4nWmoM;^$8>)Ol$imu147 dI!ArESISKJ@;>zD>r{V{Q%4thty+Zj{{cm1zUKe{ literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/domain/system/SysUser.class b/target/classes/cn/wujiangbo/domain/system/SysUser.class new file mode 100644 index 0000000000000000000000000000000000000000..9a0997f43d0df99098f5fb85cb80e9cc6892988f GIT binary patch literal 8990 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 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/dto/AppSuggestionVO.class b/target/classes/cn/wujiangbo/dto/AppSuggestionVO.class new file mode 100644 index 0000000000000000000000000000000000000000..18fbafe2b1bc016262b58f75a5f367403d738050 GIT binary patch literal 526 zcmah`Jx{|h6g;ONX-lCcl1y`wEB@X;9CL{)a06z-x zoJN3HSnhm&_s;h7$LHHSfJ+>9;GpKB-bDjVhW?yCaX;lM@yFp@M24YxEtNDk47Jm< znTr;~QKbCmVlK%QYCksGzg;dTMUsfzNUdgL21mve7W||IS|wKuohTFBh^br%hW%CD zknjT?@${}Lk+E6iB72|^FaHi6>OvWz=uY0RZPv}Br2doOzh~R`O>~h(;$GUc z!Jn~Q*m2+(F3lWh5w_8xm4h{OOJ1+^270CLSG-xVSMgTK49xx-;egyeF(YoAzk&%RAk&%$CIs5FhFKe&8&-vq@pMM3gj=dNZgd$K4 zXb1}=j?J&lQrqktl^z}*TMbtrykU22_qISNn>&a?M>K+%fjJlgR~wzuH~nLq_J>ZX z={lv)dRF&S=fvs=D0Y(ptK*1Or*l-15#|jnAR(Z4?8Zsmd~69MC+zm!u1(7rEt3W= z;|eVsW@qQCzS$O7%ubm4AS<~qr16r0WvmEjN0z(G+{tWi!qm$y%e`vgB^fhp$$&lS z`Lcmm@T$NZJ?kS(SEl?&s1#f?@ETqxs+QSnZ97fkCpo(jydkhWuGjb2>f7z6)r}#8 zkdCZCe8f@KZf;6_-ar9sL}Z?xS{))UPSzMCo~&gmGKtFIx(rde;5lSxf`w^M9dEPf zwbfxCHg&u!AaXL|O#|;qPITAtodi_B)`hCwvFiQDhitWZ*!H^TG|cva*|p_9P^xar z?g^x;|2-rXHmm11>+)pDUaxWo9G{xyww&gk+2xeDR+sVS=rHcl)HDp4qN8x8XDXnA z`5d=pbp;|4T}Fyoqo4r-L)lI^P~P>m$QOv96*J)QQ?ob%9D6KxJE&|2=n_scO|ZZtCoKP z@q=gf0l)H?O5Ebt2;?#<+;JGO!tb>6kBEHFLj_~!*i2{Mh#AiDi_Qx(oj0(_6f$$! zD~vevg`W_ajeChUvJxM+lq3-Xx2e_Ga1{SDuNAmm?MBh1z+ z6LveGDTWTDXHPf?mWvw%JpK_wr-@w&xz}W>opm24vh~O4$%i zvLKO84vUY}@0d11su7<=8gy*i2oRdNXaWC)FGIZ@eAH$4*5iAswU>WRV`BEn+a literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/exception/GlobalExceptionHandler.class b/target/classes/cn/wujiangbo/exception/GlobalExceptionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..819566512beb318a8145872b01869112f3b20323 GIT binary patch literal 2094 zcma)7T~ixX7=BJ5T@toHL!l)VD7BTOm9AQ}+F&(eXvG9*f|+r=a85R-Vd=8l+1-Hk zPA|N&e$422(;08Q60I|BbeR5t{*OrS`VXAGCrLLONQIr*-E+>q=Xsv@!+jj*rPOToGQ@*12hXDatwFy1XJ7jwh1Ywi5-SczB z4o@86R!vV^EG#eO8$*VLE`(hqWd9$B0(eda@D+yfw)bhr@YXhjXXt*|`jB9lu7CgI z?oYq&{{G9q_qOXhU)O83r#s(1*?zeD+uiyP-_^gl`(*p)r#oLsU(QQME-=h?(V0A0 z)eJ5w&{Vu8t82I|%@@Qlc$;$M6+EurT6MTift|r%1eY+Y;7t{8;WESN4)=B2ay@Q& zu9lHmli6TU3!fHNGr7+*`TTO8N~lv?mn{^tOBj#h3Q`K@RJ;o+@)LVYV}a|Q?c8CA zG|Ej@E5o^9Fy>9}x~b&;qGsrAN*l}?mRPE8l!UX&OD2h>BS3{)`xkm@IF1|XHa8I(^G94-~-IljNwCM(9_twLe>)e+pru8+KmH6% zZy02eYmqM!ganN>$(W79Px_tH)f?PP#9=F`TAY3U$ZX|Rly7HzRb8z&!MZBoD9 zpuUec9^mZ``T^PlOrsYG3?Uhi5ceg-Ny3eTB;24Z=KY*ak-5AgvA!DK`3s878w=#^ SC}}LvS_rF+Fv@Ix0z3nInJ7a5 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/exception/MyException.class b/target/classes/cn/wujiangbo/exception/MyException.class new file mode 100644 index 0000000000000000000000000000000000000000..86718297247e3bb142ea58b207847ce8515b448a GIT binary patch literal 2196 zcmah~ZBrXn6n<{9o86=fgg~IFXnCvV1)8c z0QtfPow4bR&N%v|&iEVr8Gf|Z=k9LaD5C?j_uO;OdCob{Irrv|e}4J}zzTK~h#;y# zF`yzQaOKGS(kwR2=3#NC-Sq5ZtMYZtI`M3$DG*z=o3?jbAeznX#i1jvAz|PW41xJt zv-nl}$foDMQ?$BH#p*W$0NSzDYMF z-s}kfIQYKA`^hx{;^7_YZ*jNoTTq*S0+BB~hW3MRTjF;VQGUmuAc;6HW0|`t+DnX8 ztZ|i+L>0JASry#ChkrMO|2TwC2k;$?JjO)6(81JDq!eQS6Z}pREzR%LK(ur(S{iro zUO(C$KN?>Ns$?-mu7azY{}B`4Q;0y;5%ZOXk0^7cL5L{i8$iu@XYIW6$c4^#do-59 zI%AT;i9Urv==eY}v0gDTzcD@P(qviS-o=muUHNawbKQ`Te44^;{KZvc`Sn8nJE+Q8 z;Wy~tLXDmkeuZ9L%6E|Qw-jF9TH>dqEdP#68RaR)Phl))ln!3$S}c@Qnkj5Q&`#Ee- zQc>j#{g6@&9}s_*KR){37}cOZ!<2@r{MW@ZTn@x|kKg;`SCNlh?y$(QS!diH;=124KIc@)3Hp-|D%Vo7ysE7EB+ewubyBD&3#ZVQJ6QZo>K96i zJjf{Fi7tud(agn!tpuncVNpKGnrm(YKa literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/interceptor/LoginInterceptor.class b/target/classes/cn/wujiangbo/interceptor/LoginInterceptor.class new file mode 100644 index 0000000000000000000000000000000000000000..00e36c1268722aa2def9a2949a7dea6b63996f00 GIT binary patch literal 3486 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 KtQFcjz<&YAq!u9n literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.class b/target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..f12b998401dbc0a94bdaeb427fab6285ed3c1937 GIT binary patch literal 1170 zcmbtU+invv5FLkxkQPcQx0WXh2~;kMUl1<=q+SxKXp=43QiOPjoWyJ#?XJ_cw~$}s zfe(OxLY&=*K$=#7`rx%aGoCqfIs5I$m#;+hjP6ya#OO&s5udV=mPyz%B9`N^N(H`R zdpr)ZFjUrQle7wXg_antjpT_G5$uKE8>zml&}BxVZ(`AtCe{O!iFneJPTO&mStwHV z%kPe~YU+y7b*m!0ZcT#Y=s<>w(PYaz*Ngh>RAPZdz-g!xE5;HVqCk{CuX}Te9A_$> zEaveh7uO$oMGl$Mk?^#2b!632ZfFJvGL^A%Dz%K35CN#lg)2tYK!=EzrI3BU2+|kx zNCzgCI$4BTe|3?R{yhkz`<*OtI#x&8>RzN~HP}uPFX0fI-`Q()_|AK1aNBDHyNsgg2>wAMbo>7(bh=9C&k>{Lz+`D( zHFbp6Y@9*uTFwaYn9(JyGJX&xaJ@oTaIfN4EzvTz6|AedlCIGz_SF(T;4;>lr4>B6 eLF>>?ZEn)7+y=_qxxoiwmhQ~7cWI;WwD}Viz;*Kg literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml b/target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml new file mode 100644 index 0000000..58be687 --- /dev/null +++ b/target/classes/cn/wujiangbo/mapper/app/AppSuggestionMapper.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.class b/target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..13f03df0446774971d245ba4b534e45216f2720d GIT binary patch literal 819 zcmbtS%TB{E5L}0rP~MMz0TKc(_`)p+2@af6QK-b-Nv+gXVyCeU^w&7RosU9H!!t-o zJPvEiyX*1ncpjhb?uqD-x*-LOc2mu7{8$N{C59KGEM>*9@{_V0+$fxSbuOe9qxG@4 z7Cc8UKTpOobs^0&;;AWkB21x%#`9vD2&ZhBdy7IP-!M;wl`l|?)~w8NyEh$7^1jF< zBfl4aiz08G)K(eI0h%doc`2~r6{Kd@qqs4|#LH^hoZ(`YiuU80zjrFWz+&X7`1B{MxBAm@RqNTd-xB_qbAFtDTLBZn$huJNBJ2zqwPztohsy& zvMR~t``jm58&@j|1$JUnWnd=Kk>slWPA)zgpgGincGX5F>*484>HbpQYW literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.xml b/target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.xml new file mode 100644 index 0000000..a7e2ddd --- /dev/null +++ b/target/classes/cn/wujiangbo/mapper/app/AppSwiperMapper.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/target/classes/cn/wujiangbo/mapper/app/AppUserMapper.class b/target/classes/cn/wujiangbo/mapper/app/AppUserMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..2f1be61a03b74d5388f5b18913c3a36f3c378e4a GIT binary patch literal 805 zcmbtSO-~y!5FKw5(u9wup}znL2`>1;EeMGodfKRgsNB7qVR5u;FaCh$r?m%u06z-x zvMFtHKmvLgTb{Asyf=OikH7DU=$O8AC=s-u8+jLJTA3oVvQl-;PGXg3b^XJ$8#S2@ zwFLEN>Q>1TH|6(i#(C(_h9H^SN@mJddTOJr=9voG*Jbo5IDSU_syr{D1by;c;`L}g zxhco0U_t&MeG!F!1~y(>BLP}y<7KU|p$k%r=fiYO!cAm1UsZ6vNDL3thJ6gWl&SV% z2t6YX*LFHqPE{P(c|k2;gHO8w5!9XN0-d5m?$`ftJXz;BwUyFlmE`dBeKKAHENJf{ znxHGb)Lv&L|5bcuj1A2sp?yEKt^g;MU$fNBH%j&I0%nalVQlSNRYnZtYB|vrKS09U zyzn~qy@`!3=Wn`1*TI@Ej~1T_6AJo(Xv5b6M(xl?oVz%66Y62xL~J1v+NK@sI|&vT R5z+UkCV#4*Y0%u-eF9m@0%`yN literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/mapper/app/AppUserMapper.xml b/target/classes/cn/wujiangbo/mapper/app/AppUserMapper.xml new file mode 100644 index 0000000..74109aa --- /dev/null +++ b/target/classes/cn/wujiangbo/mapper/app/AppUserMapper.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/target/classes/cn/wujiangbo/mapper/system/SysUserMapper.class b/target/classes/cn/wujiangbo/mapper/system/SysUserMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..def8c4a41ebc6cc3a5b3c5367b3fa33d62ae0816 GIT binary patch literal 317 zcmb7=v5vwp42J)}L1}M6JOvY8*oqh!ZYsK=;sM+ep;S#%B@L*rcEddY4|Tdw!~h#Z zY{|Ah`^)w3=NG^lpAkj^%d(-1uM{_@!jR^+m6lxZI;kn|-N8w_ABqt^1m+c=nd&f1 z-$fXV1#IhGsHtq{sC8XV + + + + \ No newline at end of file diff --git a/target/classes/cn/wujiangbo/query/app/AppSuggestionQuery.class b/target/classes/cn/wujiangbo/query/app/AppSuggestionQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..d479236ace5eab7e5a937a47d55a34cc668eef78 GIT binary patch literal 342 zcma)%K~KUk7>3_(Yz!v?@#2}AXkstiG$ugeX(2Hf?%ix=3ASTfHU2D4CLa6&{3zpB z!c7jg$^R@kUKVRPf#uy|B(25au5ur^O=0?1`m6oQ+tk^hJeTYofN=zA#UJ30x zZFF-_XkCt$F*=0Nkt$i1Vp5h1R}`vlv^9t7aAuzsp`U7_=I%99)sxKDoSdgNm+Pgh zwD&_8HZQs+T&Mqj;g*mrtgCYMp#8NMe?M`vl5Y}2#N4|d#FM*cp0J6%1JTtdXv;x> Xgz1lg4o;cf{XXLLjE&G^2I&6+@A*`l literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/query/app/AppSwiperQuery.class b/target/classes/cn/wujiangbo/query/app/AppSwiperQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..c8223b009f9f4f656dbc3ba117d37dcce92d22de GIT binary patch literal 1654 zcma)6O>Y}j6g|(L$xNMT>ZWxV1XDiW+1J0p97GvkhD z8s#s*2C*y>5*xY+sFlF2sHk8A62F50KLRM{c_y(Wqz1)+iXnlinrrTc+m7YdtDbo)wEaD^YPD^1nZtW>D=@U+xK40IAeqZ=o`8-M z8d3&^VF+A2#@}kS%%xUqW7lcfevF}2!}iU+mMt*4wr$T`sBL+?( zEuhyd_v)?CY6@g>eWveLx9wU`&VL|{M-808S%FmD4wesr&*t)d_D9fT7}xNOfeDG8 z?!}G(sm_+s+9{0TSp!)-M-C0E-B|Iq$d-~N$0+N_35dKzDi|nA>3ZNrZUPfGLN{=B>`kZb zRGapa>w19|IG)=U$geq`+1|D4b=x| z-OqjdjlimXRIyqyadrL1YUL_%S6MILZimf)>F(L5HoVZU+1DH?{mfv|XJwaQiY=Pp zbrT$UOE}MPH_W-j|7;s3G%k1nIljarle6Hg79K#{=OTfZIm%-og;zLA6dK@FUSf&N z{^vO8{4KP5JnVNKIoA0#yiP0WJkMED9V!&RgLZuAvB)A0Eonuf-k_fE{xKI(m|$c zq3jbT`BWX~EsX-uNbZ%GtLY=J8Ui^R%cNYnqqhz9*{jA`AU zE)Wa3ObLp7g<>HRQ|3mM3M7^O#70$#Qgc`pS)chXl^Aipn;O0;aj8BfghHUnba_Ep z>?RI&W>u!?hdo2vvnC4;4|Y$^5v5>GG= zg<^%ERtWKg8R_j4LUtWrlbGE#LdYh|KEnC;AK>}XsSYkklAJ~_ap)lb-~Q@v&g@Zh JE_ai)@-Ll%L)`!X literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/query/app/AppUserQuery.class b/target/classes/cn/wujiangbo/query/app/AppUserQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..f812ca6b73752fa546530a08d8c824c160284270 GIT binary patch literal 324 zcma)%&1%9x6h^-r6Qikr?HfobsEf|Vog&zRt00uN?kDMBM{JT#jMB&IN^s!=_)x_= z;=+ZC&cK;D-*E464}ZHofIeCQ9F%;xHFzi!+HoQ_#X`$u9;M>DQ07NOGFRe>@nV%w z9_mD|MubwQJM&Q?++V4ZStiC=_MR(qu5+K$4@GE(I#JW&D^li7MoUia!Zeo4nKat^ zIdoT_Iww4Y|L8p+1g~jfVl~mW;qB$ej|;h$Xv618?IPYhE3?WbP7ZjzE$Ej62LaPQ U0~OpbYp1)%XPu4EU^-|X0f@a!?f?J) literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/query/base/BaseQuery.class b/target/classes/cn/wujiangbo/query/base/BaseQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..bf9e03126c8906eaa45d52145ad29af5c8fc196d GIT binary patch literal 3079 zcma)8ZF3V<6n<{9o85*@o2G3bfXYjiBu$C=W;%P%J@=gFp7We@Px|NIKmQ8g9efi- z2w@G10TmH}_==?PG=UP(9x$MYG4}-fx)hMsn)cX zEJr}QZB|>>+3NzybSX3Qf<>_p{TR>?H!z5Vz}`wNzt&o@d1twvztysw^?ccESotY_ z&dDt?D=o*dYK&&+UjT;PCEzzxuPwPz>@u($uMqx* zwZ2w&76lRkv-zfD(=bY~*9`2zUID#g){ft5nN@+2bimZ(s+hSfjrSWE#p?pmC965z zj(a5Ciwep90Rw4?9kC>ELn34ij7bEI2=mNG>c$NmM4o2Um1Igo>C6jBMR5pkX?WXU zY2R&Ev(>b#`D2b_uG1^JXj!Xn3fyGUK?FaE9x5-d_YAy`54^liw+S2Glvjtc5Q+v4 zW0I6Dn~mk^`l97FP)SC3)WC;0CSb@|PIZoxy`ssKG)xO@@3xV5$5hL%E?Q0$QwZxg zA<*AxmozIrDGyE=DB)vLX0EPUHCA^#STjG?U|BXnv+##7V_+6%{7^5{Jp+LQJwpvN zgb%J`j(p|z`297hIFzY@1l-R*&n$*vfT-LNkC*|&Q}av zl||Bea9?USrEmm%fO6Xv(B_`mM!OkcaWH=SIp{yNn;xN zN~O7MvuXCv{O^M;lJkb&ro)@4a-Uvifvq`fHJ9s)bEae7w3?P9TazxGzS{J>+NGkO zH0nI6WU!w804hp!jaKsEkd^x8N9_|Upw^qqa$FfQtI^JUiMi_TzRx|DEc0&f%-eW= zox$Pzb@%g4vvOnBT=mIQ=gyaAk29VUxpAyUtIA=fckfY0Jy?CT0}-9Cx15S~!j`4# zw)a6=i^sB)EOYW622f1nV;HGbu#(yi;P zcAPm(dN}Xg>KyCo%n94WIkwe#pr zIerSt_#fDoQl4V)0gUmKvVk|+7MX%dlT0C!Ql(AgDH0D5OR1?yz$izP+!MUncA6+? z)JzoglqQ{Y-$_g9Z71a+0}KcH+AHx@FYr!@@1u&F%yb0bqQ-|3;=cpys8bh477eUY zQg9LrxJ60j56m1KN)g;89Suqv?qL_2lytOsXAUt<{|o&Z`kx`GA;dpjJi`u8>=Oe4 zx!qb-GOU3Aw)lM@ADiq}RZ=T63BJ%^v$k8Eri@=^;x}u}tr>sSsbc?&A|WCKD#we5 zl}WcUyW_=W)=nQpsah;fQNDQBYkwR?S7wQ>tgz zoA@K%?LP5g#&jENj7{ZK{E|`#QCuYTlKA~NiaV4PoW^#1MM-t3T|?wK6$+^pf^e6F;lsLYDlO8dr sDJ9N&+X*S3^W=RSm`^Ntaz@G*DR1EN)*0p%)|=bYozZ*OE&td50J?8QQ~&?~ literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/query/system/SysUserQuery.class b/target/classes/cn/wujiangbo/query/system/SysUserQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..990b8b30f879268fdfecdcb2eb71188c63b592de GIT binary patch literal 330 zcma)%v2MaJ5QhH?388@&=o_$9v;$tcwPI+cP7xAQk2JHLh8T+@K9CH zh=G9tTl(zpx9+Sv{Qd3$JfjoALoI~gLV!A1dx<$NsV&)B-I64qK?Lb=&JVZ?Q U3^dSWwvP9J&s#Ra9n(YmAG+mG761SM literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/result/JSONResult.class b/target/classes/cn/wujiangbo/result/JSONResult.class new file mode 100644 index 0000000000000000000000000000000000000000..5d82ef73afeaee13e56ac65bcc45d482ea04a0ad GIT binary patch literal 5673 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 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/service/app/AppSuggestionService.class b/target/classes/cn/wujiangbo/service/app/AppSuggestionService.class new file mode 100644 index 0000000000000000000000000000000000000000..7d24525c43d39561f5efc5150532091d7af32149 GIT binary patch literal 4420 zcmcgvX>$}+6g@8q=`b`9gCGGxz<|jlp-+e0OP*l zzFTFL|3XVExKvqww){z!<$2vbNl%iQBwtL`$beRnx`d4K);+aCaq;oB72(5|6F z$0l?NWD0KCm^R(ARdlOHxi)PEmS3@}z9DZ0((x_VF?{J=w+hm*$`#wlMUydp3v`ZH zjuo5~Xzw4$Yv^jlui$#pD7a413dqzqu2rR1GcKwBQ=VC=NG}Bq?I~=5u3@W=ZP+d_ zP;iVJ)j7*_O4Dvk!^6huN+nk6C(5ft~#;Sq(hbLxbL>V>fzf z2(wU-l|bNpf3|^Xq~+=oXJQG%i)X4%LFrlZ7DDg?j|rtfJy|P{$$ME3k$3k=~iwS?L!9jwE%9sa9d6;jqAob%2G~DOq%H z#pFORQKO4yNh-JAr=uSOk)KAZo+lj|Y-fX?#+*QwLfr>3q+wXcQ5XVuEO|0MA<$(x zLEf~hGDP2)y5IpF52_0^0wHI;%1irjOac92fldAA&ky7k`XABpC>|5&pok>?iXLkg z10iP1GBAr~U>ajek<1#W69|uCO*e1og3ZWaM8o4cPT~oH;RZa_V{rwd;VElj+W zW||;}248OqXb7mRr)y0pmfo=ApLc(jF=)|OEj>=_+dj0^Nc z`cGNG>=n9e%$aeySciESyRmE5KGyr*E=dDFAhJYMVwW-YQb8d0%USnwLX4$BCW*2WTb(+FN08_Ydn6<{1S3f;0c zFpJ%Y%A&yIYb20F&WU(lN>o*u`mx=BCODs^AXH0Qf^wWmsr+#K)?CFFtiaJ zm`Z%s)$S;7ETtQP$CfQ^gzNDY`D;0K;5Ig8`3s@zcG_lnx@h(#qp$CNf%%QtuDScy z##v?{FCZ*73?l_QZdbo;&Tt7&^_;T2?OmpL>vFiPdbLD(Di@~2bCybey{D5MZd~1u zsy>K)Sd@S(s;8Y%&}7RyZv>v{_{{UFh7Ko%Ia9AXTNph{v%iydCnkz6 zc$#glE&aZ%>&{mznMCP}8~DUZ1K}hEPaa?YW^`q1+GIZ*a~?HqJ7)zl(~S?8JrL?u zI!|kToMQF-L`N0ZyYZR8sTQ5kI-#tOIga$gaxHxgU$Ty`aKUQU)bO>y{? zgOt0C51cmaQKdipVmk_f7x>-D@x^%LGm^8HI5Rj3j+@fAA%5gX8(xkN0lj#I-+FWa zCZ;(PD4>Y;koa%1>EPPA-=ST-jm_hO3rPKf?(eZ}Xz(}e0v51mYN%)b0uD_5j=rnh zKeB-IEspoA@ircsNDmL)#_>PV_X9a~gtzY@U*G_`s8SCfK>Ki*J>e0I;J#3zbaZPh z5$}h@3?=Jg_g%s)br?a44+e{J&XLnDu0(tDi+eWr%G~RM_y_wmzO@|AHnDDTaQSOP zg)Gl5D*IimY`Tdeq6j#2$ JSNI0K{{e$HC4~S0 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/service/app/AppUserService.class b/target/classes/cn/wujiangbo/service/app/AppUserService.class new file mode 100644 index 0000000000000000000000000000000000000000..57392ba22aa471d89af66691c891e6307e026fc4 GIT binary patch literal 4123 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 HUs(4)?T|we literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.class b/target/classes/cn/wujiangbo/service/system/impl/FileServiceLocalImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8a1d35b45b705fc577c115d83c5f14fefcbf2b98 GIT binary patch literal 3502 zcmb7GZFd`25q_>MdnI`tr?Nv(ohCGOVk@b$q;ZlWheF~w;2_5#cHFv{(v@^2ud~_} zyDP_T%Zpner7ygcQc4=2P@oh7q_oIN?6iF58$W!pyGZ_oRmpx_dSE z&fJ-2o|$|9`oXn#0QBH5QPiPcK}bad8U;2_>QlOA>Q-JGN>9p+C(wArung}3f%>k* zXcNMSD2S?Pf-0cdPF{11j$!3sfYf)Q+MJ z^&H?wRm5?pKxBGj6DL;44vc_b#EdW z#l7fOuup}Cj|=SHC}}0nFtsz%wM$M$o~1u7WuD?cdnQF0+6d7A1WS4v?dgr;J{(Zc zqv9Y#7x+_Mq^y&r)8tANorv*pzlu*Vfg0ts;d*Wuy#i41NrA0vb9by{m|5vWaRl{Y zd|IG+Mb=!6<;PU?;W$~-i$!T=1-ftTu+Qxv8&%8X`w4tT!Dm$ruk%j(TGg=OddR5Af)t~kqg!rHIwQ8g9aVp;oTCa0BQKEaPmXgJAm(M{c)#w> zoTQF2A`3;6FdQWEOJ|*UeAsUx$86ghcb&|5K{u>%r%Fb5-1T(N$c!)7Dreomq=IuQ zOcVrmFr{@mazbhuyHKz#SF1W!<#IS<7iWSNv}29u0m{p9a38Q$6uFl)xzb~;Q&jp4 zg`>i)p*d_kCZi}}O2K&*)1aOfB*CXx%C-m&WlA?ol1sgHHOjn9#B0OjDxSbsmQP}< zyn99N{k@Fu*9i6r&nqT1&9pPRIbpkAGJ;t=so*IU-@rEo4z6OaE1fALBQ$p2c@me3!4A7S6jj?CF_vBMuQJjPDC{tnBkQp1$(lrOP)iUAg(%?9EqR zzOnG+jY{SHg^O(E2P$6VvWik!4NBM5^OTR5@FN8;tN1Z4QZw;eotf*I)KYdnFP#&5 z#`kQBYW6bDmsI=&Kcx~fZAxxz{U!ykQYqgq1a(-Ntd^8v$y235n#x$GGyO1#1*5uS@c*hX1q|o zbZr>SZC(n!>v@=1?aP|mn~qd+gl+#cu{gx{9$~P$v?=R;*)TonvIrccR?TW$;G~z8 zE~yKeZdu{L5_jp45bqY)|9=NWkmPK>$%3Qmrl^T-|FDpn{n{ARi`BGj9+cjMojtAd zYl~Vbr6_zPV^&{i(P97kW{MHF__Mao_i;fAY@816&C>Q}ic+iU_0l_LmR^VgKcn$Z zCO$ua9?B_IZqVF&0_nM1eqMj!7jHK~bw4~9OZgn*5nS*%K*ZVb%ybNr?>olst z2K)wZ&_99S;&)`7lNOuk@vIiP`q&tXOc=>@$E$Td-lPqiFrIkmL4wS3uSzX-8dQ#(ZB}6Y@oW0b%tuz z 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 Fe*jA<4h;YR literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/util/RedisCache.class b/target/classes/cn/wujiangbo/util/RedisCache.class new file mode 100644 index 0000000000000000000000000000000000000000..18e601a85ea2cd2e07470eef70ae2961303ac1a3 GIT binary patch literal 8374 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 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/vo/LoginSuccessVo.class b/target/classes/cn/wujiangbo/vo/LoginSuccessVo.class new file mode 100644 index 0000000000000000000000000000000000000000..e6778a85fc249c5460c675e4d4937ef1de3cb9fc GIT binary patch literal 3487 zcma)8YjYD-7=BKY&2Ew{Eh#Mo5sO57NlUa|*;3>pU^NA7p$gvErc0BOCM6e8zd7SL zj(*Wk&iDi53(n}MWkwwb{eUz60e*n~3=yAmb~o9CouM zv-mKH2%ikg`GLz&p9yPHSkMV6qyL#ek%dQ9vjRo#-<1;gUQG)lG zcpUo$601&AULqfq9vct9)x%}9pD^*H~m>OpIf~wO;Vt8S1k39g^rt6H_?A zhw&~IG=UvmU@yQD`;>{NB{oIuf)`_X{*1}wKPQmnx#zUNezH6~G7-FB;zb8hPg#xycbe zQ|6lcGXi2P|WX=fMa=1ORiG+Gr-OuhX~J?pvTfqzVy#s#Iw#ArG6uU_|@(TIJ7l> zIeaNa?`g&K1#h8XYa zHSP~JeiIiM85uB(tISq>BKH&Y@Nf^i2rt|+6*8{^7ip)l0WiSLTj7*_TcwmG(x&WJ zlyBpmuvZRjl~Pt)n=-8^-^F`jlsmRcDGRqvIjkrz!49L`wN*;l18vIPiju#(E~U85 zwU1%Go16FsTI^=-cNkwoi{8xLhA}@mv57ruOJU^nBtKSc>QAIHu{+p)1LjmFwu!8d z7_~G)My+^8lbHA&q;H@vqh;a&P|nf`%2`H6mmtFf=@}yc%3BG7@>VjFkf5XoN@S7& z(6p5zXxcI}DG4$?5G5ZJyGhrgfev-s`(xMTcD>!jGK!4R5dOdlTRws;et^TXC_Cs| zT&5JmDSUxdN*d3&O#yt${i15!4_pr+q6Au^tCRt`;WAYz0uT~DyA2lUqMr9a+gUStq z+jd$z3>ux6Ver~+MU@Kw!Ql}*S^Pr^gG8SX%p8i%s)E=vFjHbV7z4Q*(5E)>{3Url zYQ>}?6Z15NED~3hvoxh*eJCR%qxq`56<4ZwTg9qzt)?wqsaPJO#Hvi z%{YTVADQvOFR(7$!lCr+CSGEKb6nELT{$o16Rte6iBsuUU3pZ>1y`Py@@dMOINSUC R5&Xd|cqtQjUlr^J{{tT+ZW#ao literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/vo/UploadFileVo.class b/target/classes/cn/wujiangbo/vo/UploadFileVo.class new file mode 100644 index 0000000000000000000000000000000000000000..e7f705ff388466e483c735c32a3bc4fb0cc6bbcb GIT binary patch literal 2946 zcma)8-*XdH6#j0qo82UvHVqUAR7Akq^anvil!Rghi&WcEDOAB^F5^H(>kb$9JTrRuHJ6`Y$iF0`uECAV2t$jo=ymz#}BZM`Ub0}cj-%og;b zd)pJ|kb{gk6XINIcsDDbh?f||)@DCyxmAVX zu@F!fSIk`(@Q8z_a8Mz+?lmQK&6^p^g#rTR2o5=TMwnxs&~8cm5eG-{tioUr->rD} z4vwH^33<-Jn1r-HDP@a)+`)wSQvsE(Ttu33a141?RCc$@=j&^%oPx|*cwS*|Z(q-~ zD%CZwk-%|8ZJbot9~NdTEX%ZjPC0l9FS96jbJMG>DNKc%733Xmhjs;@DcUHol*vPF z0jF)8VGY`$OQ4G*6kw#m{OyRY_quB}a|`@Nq#ub^_0_^g8q(l5JN*BAvuH)n9Z zQu7vDw^zN!6?e7Dc4g-4CAYfbHY)NSIE`kxvZZiv{{JSqNNuRdF@PA3*)+!!GhE+aTo}pN2J^P-6TGW8c%X0aJQi4-)Lh^yjgE~^ z{0ysq$M$GM&@t(zNTRUFIFqxFG+!?Dr%XL5rKsDX9P}xd`ctN#lu`zzLz(d@-@@g7 zh3|S&N}0J1<*-l5UlL8JKI58XPwr2Qe+SdJH}MDTZ(v66P5cgfVRC#Md;M1$2Noy! zC>T?JBAGQFV(2cMsjRV$r`w3b1(T4&g;>@UOza^tcah4P*;oiPTCfNjE!bI0Kz0DK zvUUiRE5r%P6%yIFfD!>Ho=vnt#yw^o4Gp_KDVw^Qj_&udj4LdE7~kS5Pfvtr=S!^6 z7sWWfz}vJ8PSq{EL(8Ok9qkA(>TZ1o8Hv>E>ovptQ=6vdE#90HwBGhrEUQ`C?;!-rbesps45)M>Ih zsWX`GtG>+q;iij6Mtx2Si$t60;u&Mw7jqi2rcGkd3Sn?ARi( z-Wn~K{uZ_MgY2x?-pUnX{#LBBMa3C4(qE*DI+q~%C~o6J++e0AWpHUl*w&j^WkFFK zp(G_*2F~IH)@Yd&XfI_Fk)-+G!+uPMVZm044Tn;X8Q6V~h+`OL8_>oWJ6!=R7J_w= zz1{$9?F4u6eKr`v8u@R7)&v`pD)XQD700hVz=_NY+jvnV;F3A5?NPCd+RlkRt?dKb acqMa=_BLMYy*|S~88bnT75gb;wEi#2-~-D5 literal 0 HcmV?d00001 diff --git a/target/classes/cn/wujiangbo/vo/UserTokenVo.class b/target/classes/cn/wujiangbo/vo/UserTokenVo.class new file mode 100644 index 0000000000000000000000000000000000000000..303d6d105064bf2bf2a79063760a46336cb850fa GIT binary patch literal 2745 zcma)8U2_v<6n@@hzmja)5GW7f5o(*$q4cD!=N zD`%YHR%RS7l+iMyGmhTijK4|5=j^+iq;++e>Fj&nbDnedoadaA?Vo@D{40PXSV|*- zqz%J`2}>cj=H2#6b+2)wbYW@DUv4W{$7_vR`-DPrbZjvN2PqqA7a6z;`<5G}PdjTh z;+LAG+s)FI4Zn4{dDCw!HWkdaNDBG6UetwltJb(tkvIb`1|^8oq0_u~%NOMi7x_Th z^1XVb+~s0Olopd~d#yBadtB^AfzHcbuveP!&LfcLrBj{^kX@Y_Ll z3cE(f`p{ukLdG*L4oYClm#7=!{;Z4V#63fIDNxc9{qrtfi1e4jbVWbvVodZY;!lPd zCoth+5>rfK)!SG--CXelMrUo56!vT<=v1dxU-4P#AtW6fCWn2@jt0C=i}8qyS8!CA zSzq@XD+*KnB!p%CyV5Xx#ldSVYw}>!foTWjKoPM|#c>ugc~CRYD+fW1$*X5voD4{9 zH}!iI3|-dXT&>~HcWy0l7QCf83(e0pm%aL;*Q&`qR2uEo+J?e`x&IlW3i;aTHf>9X zqv94hwN<~p+FZHlwb+@q-(u7Zy`o;}Tht+zL!0gkYvG*s&u2I{9NuPo)o&@JCCg$s z$(cYI-Liox;!a^eTYCx(h`8(mdWuXCL369%YX9h(U1)pDH>=)y$d`HX(ron%Q=VnN zTmD9;F54L;lPdP!n=1BRVHcx#>4j#ewd|j*Nk?)*POuA$%|kMM80O?A_@iL($>pY$ zko^o!u4Hg>3wdTidSLN+inkI^#nT*r0QExvJI$w1qJZ;4E)SmXXh`&OgHb zp2h@v&Y4(eu40UHcDu71>&$(Pan5ab&c-@(sbidXZg(Dtbv}plEKX`J^Aw`3@rj>c z$1}EDBSOZ6O=*e3Ed5N*GjhDV86PtHq#>od-H?Mp$hYD{=AJa93`#d-J_tD%A9ClD zhLoA>h8zk)@&{UTsXpVGAt(1I#=nJW+?)6v&NncV_a=UWQ=J^&#O~lq;i>saKFY?_ zAIKDphuCo!?o`3p#M2RCxNH(KT(%0PV62D8-$k}y7OXx{v1}7mEIS2TKu!p<3r-(s zq?{sXq?|6K1e6XzsX{se8TXiVvTxY+rmX8~x_!ToD&|@K5bodtw3MB_$amg1crSLWO;T=k8yvsa}V$gQ}!hj9u z5q8^1@Xt|?uvd$z{}7{TtgKrF6^mIj9(Z1aM=(;!3ZsmG+3L8Wiv3b zw}F#WFeB4Q*$PZn*Tjy~Ykz!`&g)#l}DR=P?zA4M!;w4y7K`v3F01VhCmgh%m-hRS2{CU_In^Z3wov zf_wNF16^1nKl!>RSd&!QlbK&|=;{N!n15*#FH389Tok#Y + + + + + + + + + + + + + + + + + + + + + + + + ${FORMAT} + + + + + + + + + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log_dir}/error/%d{yyyy-MM-dd}/error-%i.log + + + ${maxHistory} + + + ${maxFileSize} + + + + + + ${FORMAT} + + + + + + + + + + + WARN + + ACCEPT + + DENY + + + ${log_dir}/warn/%d{yyyy-MM-dd}/warn-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + INFO + ACCEPT + DENY + + + ${log_dir}/info/%d{yyyy-MM-dd}/info-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + DEBUG + ACCEPT + DENY + + + ${log_dir}/debug/%d{yyyy-MM-dd}/debug-%i.log + ${maxHistory} + + + ${maxFileSize} + + + + ${FORMAT} + + + + + + + + + + + + + + + + + diff --git a/target/classes/smart-doc.json b/target/classes/smart-doc.json new file mode 100644 index 0000000..842c2b2 --- /dev/null +++ b/target/classes/smart-doc.json @@ -0,0 +1,8 @@ +{ + // 官网地址:https://smart-doc-group.github.io/#/?id=smart-doc + "serverUrl": "http://localhost:8002", // 服务器地址,非必须 + "isStrict": false, //是否用严格模式,严格模式强制检查注释 + "allInOne": true, // 是否将文档合并到一个文件中,一般推荐为true + "outPath": "./src/main/resources/SmartDoc", //文档的输出路径 + "projectName": "EasyJavaTemplate" //指定项目名称,用于显示在文档中 +} \ No newline at end of file