From 8d658af20877032866d17b90adfc95b8ff79e7b4 Mon Sep 17 00:00:00 2001 From: zhengshixian <2193386250@qq.com> Date: Wed, 3 Jan 2024 20:48:25 +0800 Subject: [PATCH] frist --- .gitignore | 38 +++ .idea/.gitignore | 8 + .idea/encodings.xml | 20 ++ .idea/inspectionProfiles/Project_Default.xml | 53 +++ .idea/misc.xml | 18 + .idea/vcs.xml | 6 + Boot-auth/pom.xml | 33 ++ .../src/main/java/com/bw/AuthApplication.java | 13 + .../bw/auth/controller/AuthController.java | 97 ++++++ .../java/com/bw/auth/feign/AuthFeign.java | 30 ++ .../java/com/bw/auth/service/AuthService.java | 22 ++ .../bw/auth/service/impl/AuthServiceImpl.java | 84 +++++ Boot-auth/src/main/resources/bootstrap.yml | 45 +++ Boot-common/pom.xml | 151 +++++++++ .../annotation/PreventRepeatLimited.java | 26 ++ .../annotation/PreventRepeatSubmit.java | 26 ++ .../aop/PreventRepeatLimitedAspect.java | 96 ++++++ .../common/aop/PreventRepeatSubmitAspect.java | 95 ++++++ .../java/com/bw/common/config/RedisCache.java | 271 +++++++++++++++ .../com/bw/common/config/RedisConfig.java | 40 +++ .../com/bw/common/config/RedissonConfig.java | 48 +++ .../com/bw/common/constants/Constants.java | 18 + .../com/bw/common/constants/JwtConstants.java | 29 ++ .../bw/common/constants/TokenConstants.java | 24 ++ .../main/java/com/bw/common/domain/Order.java | 83 +++++ .../main/java/com/bw/common/domain/User.java | 50 +++ .../bw/common/domain/model/InterestModel.java | 22 ++ .../bw/common/domain/model/LoansModel.java | 55 +++ .../com/bw/common/domain/model/UserModel.java | 59 ++++ .../bw/common/domain/request/LoginReq.java | 33 ++ .../bw/common/domain/request/OrderListVO.java | 57 ++++ .../common/domain/response/LoginResponse.java | 24 ++ .../bw/common/exception/ServiceException.java | 74 ++++ .../handler/GlobalExceptionHandler.java | 44 +++ .../java/com/bw/common/result/PageResult.java | 34 ++ .../java/com/bw/common/result/Result.java | 76 +++++ .../java/com/bw/common/utils/FastUtil.java | 55 +++ .../java/com/bw/common/utils/HttpPost.java | 77 +++++ .../java/com/bw/common/utils/HttpUtils.java | 310 +++++++++++++++++ .../java/com/bw/common/utils/IpUtils.java | 318 ++++++++++++++++++ .../java/com/bw/common/utils/JwtUtils.java | 109 ++++++ .../java/com/bw/common/utils/MsgUitl.java | 76 +++++ .../java/com/bw/common/utils/OssUtil.java | 153 +++++++++ .../com/bw/common/utils/SendSmsResponse.java | 51 +++ .../java/com/bw/common/utils/SmsResponse.java | 21 ++ .../java/com/bw/common/utils/StringUtils.java | 68 ++++ .../java/com/bw/common/utils/TelSmsUtils.java | 88 +++++ .../main/resources/META-INF/spring.factories | 5 + Boot-gateway/pom.xml | 44 +++ .../main/java/com/bw/GatewayApplication.java | 12 + .../bw/gateway/config/IgnoreWhiteConfig.java | 32 ++ .../com/bw/gateway/filters/AuthFiltres.java | 100 ++++++ .../com/bw/gateway/utils/GatewayUtils.java | 98 ++++++ Boot-gateway/src/main/resources/bootstrap.yml | 30 ++ Boot-module/module-Buy/pom.xml | 61 ++++ .../src/main/java/com/bw/BuyApplciation.java | 15 + .../com/bw/config/ConfirmCallbackConfig.java | 48 +++ .../java/com/bw/config/RabbitAdminConfig.java | 44 +++ .../java/com/bw/config/RabbitmqConfig.java | 15 + .../com/bw/config/ReturnsCallbackConfig.java | 40 +++ .../src/main/java/com/bw/consumer/Loans.java | 43 +++ .../java/com/bw/controller/BuyController.java | 100 ++++++ .../src/main/java/com/bw/feign/BulkFeign.java | 24 ++ .../main/java/com/bw/mapper/BuyMapper.java | 26 ++ .../main/java/com/bw/service/BuyService.java | 23 ++ .../com/bw/service/impl/BuyServiceImpl.java | 122 +++++++ .../java/com/bw/synchronization/Interest.java | 49 +++ .../src/main/resources/bootstrap.yml | 30 ++ .../src/main/resources/mapper/BuyMapper.xml | 27 ++ Boot-module/module-ES/pom.xml | 38 +++ .../src/main/java/com/bw/ESApplication.java | 14 + .../com/bw/config/initRestHighLeveClient.java | 45 +++ .../java/com/bw/controller/ESCcontroller.java | 79 +++++ .../main/java/com/bw/feign/BulkListFeign.java | 27 ++ .../main/java/com/bw/service/ESService.java | 19 ++ .../com/bw/service/impl/ESServiceImpl.java | 162 +++++++++ .../bw/synchronization/ESsynchronization.java | 27 ++ .../src/main/resources/bootstrap.yml | 34 ++ Boot-module/module-system/pom.xml | 78 +++++ .../main/java/com/bw/SystemApplication.java | 11 + .../com/bw/controller/SystemController.java | 59 ++++ .../main/java/com/bw/mapper/SystemMapper.java | 16 + .../java/com/bw/service/SystemService.java | 14 + .../bw/service/impl/SystemServiceImpl.java | 26 ++ .../src/main/resources/bootstrap.yml | 30 ++ .../main/resources/mapper/SystemMapper.xml | 15 + Boot-module/pom.xml | 26 ++ pom.xml | 70 ++++ 88 files changed, 5006 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 Boot-auth/pom.xml create mode 100644 Boot-auth/src/main/java/com/bw/AuthApplication.java create mode 100644 Boot-auth/src/main/java/com/bw/auth/controller/AuthController.java create mode 100644 Boot-auth/src/main/java/com/bw/auth/feign/AuthFeign.java create mode 100644 Boot-auth/src/main/java/com/bw/auth/service/AuthService.java create mode 100644 Boot-auth/src/main/java/com/bw/auth/service/impl/AuthServiceImpl.java create mode 100644 Boot-auth/src/main/resources/bootstrap.yml create mode 100644 Boot-common/pom.xml create mode 100644 Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatLimited.java create mode 100644 Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatSubmit.java create mode 100644 Boot-common/src/main/java/com/bw/common/aop/PreventRepeatLimitedAspect.java create mode 100644 Boot-common/src/main/java/com/bw/common/aop/PreventRepeatSubmitAspect.java create mode 100644 Boot-common/src/main/java/com/bw/common/config/RedisCache.java create mode 100644 Boot-common/src/main/java/com/bw/common/config/RedisConfig.java create mode 100644 Boot-common/src/main/java/com/bw/common/config/RedissonConfig.java create mode 100644 Boot-common/src/main/java/com/bw/common/constants/Constants.java create mode 100644 Boot-common/src/main/java/com/bw/common/constants/JwtConstants.java create mode 100644 Boot-common/src/main/java/com/bw/common/constants/TokenConstants.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/Order.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/User.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/model/InterestModel.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/model/LoansModel.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/model/UserModel.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/request/LoginReq.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/request/OrderListVO.java create mode 100644 Boot-common/src/main/java/com/bw/common/domain/response/LoginResponse.java create mode 100644 Boot-common/src/main/java/com/bw/common/exception/ServiceException.java create mode 100644 Boot-common/src/main/java/com/bw/common/exception/handler/GlobalExceptionHandler.java create mode 100644 Boot-common/src/main/java/com/bw/common/result/PageResult.java create mode 100644 Boot-common/src/main/java/com/bw/common/result/Result.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/FastUtil.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/HttpPost.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/HttpUtils.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/IpUtils.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/JwtUtils.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/MsgUitl.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/OssUtil.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/SendSmsResponse.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/SmsResponse.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/StringUtils.java create mode 100644 Boot-common/src/main/java/com/bw/common/utils/TelSmsUtils.java create mode 100644 Boot-common/src/main/resources/META-INF/spring.factories create mode 100644 Boot-gateway/pom.xml create mode 100644 Boot-gateway/src/main/java/com/bw/GatewayApplication.java create mode 100644 Boot-gateway/src/main/java/com/bw/gateway/config/IgnoreWhiteConfig.java create mode 100644 Boot-gateway/src/main/java/com/bw/gateway/filters/AuthFiltres.java create mode 100644 Boot-gateway/src/main/java/com/bw/gateway/utils/GatewayUtils.java create mode 100644 Boot-gateway/src/main/resources/bootstrap.yml create mode 100644 Boot-module/module-Buy/pom.xml create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/BuyApplciation.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/config/ConfirmCallbackConfig.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/config/RabbitAdminConfig.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/config/RabbitmqConfig.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/config/ReturnsCallbackConfig.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/consumer/Loans.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/controller/BuyController.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/feign/BulkFeign.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/mapper/BuyMapper.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/service/BuyService.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/service/impl/BuyServiceImpl.java create mode 100644 Boot-module/module-Buy/src/main/java/com/bw/synchronization/Interest.java create mode 100644 Boot-module/module-Buy/src/main/resources/bootstrap.yml create mode 100644 Boot-module/module-Buy/src/main/resources/mapper/BuyMapper.xml create mode 100644 Boot-module/module-ES/pom.xml create mode 100644 Boot-module/module-ES/src/main/java/com/bw/ESApplication.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/config/initRestHighLeveClient.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/controller/ESCcontroller.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/feign/BulkListFeign.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/service/ESService.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/service/impl/ESServiceImpl.java create mode 100644 Boot-module/module-ES/src/main/java/com/bw/synchronization/ESsynchronization.java create mode 100644 Boot-module/module-ES/src/main/resources/bootstrap.yml create mode 100644 Boot-module/module-system/pom.xml create mode 100644 Boot-module/module-system/src/main/java/com/bw/SystemApplication.java create mode 100644 Boot-module/module-system/src/main/java/com/bw/controller/SystemController.java create mode 100644 Boot-module/module-system/src/main/java/com/bw/mapper/SystemMapper.java create mode 100644 Boot-module/module-system/src/main/java/com/bw/service/SystemService.java create mode 100644 Boot-module/module-system/src/main/java/com/bw/service/impl/SystemServiceImpl.java create mode 100644 Boot-module/module-system/src/main/resources/bootstrap.yml create mode 100644 Boot-module/module-system/src/main/resources/mapper/SystemMapper.xml create mode 100644 Boot-module/pom.xml create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..9f7faf4 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..90a266d --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,53 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..101e2b4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Boot-auth/pom.xml b/Boot-auth/pom.xml new file mode 100644 index 0000000..aef5b49 --- /dev/null +++ b/Boot-auth/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + com.bw + Boot-6.YKA + 1.0-SNAPSHOT + + + Boot-auth + + + 17 + 17 + UTF-8 + + + + + + com.bw + Boot-common + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/Boot-auth/src/main/java/com/bw/AuthApplication.java b/Boot-auth/src/main/java/com/bw/AuthApplication.java new file mode 100644 index 0000000..186681d --- /dev/null +++ b/Boot-auth/src/main/java/com/bw/AuthApplication.java @@ -0,0 +1,13 @@ +package com.bw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class AuthApplication { + public static void main(String[] args) { + SpringApplication.run(AuthApplication.class,args); + } +} diff --git a/Boot-auth/src/main/java/com/bw/auth/controller/AuthController.java b/Boot-auth/src/main/java/com/bw/auth/controller/AuthController.java new file mode 100644 index 0000000..b90b625 --- /dev/null +++ b/Boot-auth/src/main/java/com/bw/auth/controller/AuthController.java @@ -0,0 +1,97 @@ +package com.bw.auth.controller; + +import com.alibaba.fastjson.JSONObject; +import com.bw.auth.service.AuthService; +import com.bw.common.domain.model.UserModel; +import com.bw.common.domain.request.LoginReq; +import com.bw.common.domain.response.LoginResponse; +import com.bw.common.result.Result; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * @ClassName AuthController + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:13 + */ +@RestController +@Log4j2 +public class AuthController { + @Autowired + private AuthService authService; + @Autowired + private HttpServletRequest request; + + + + /** + * 登录 + * @return + */ + @PostMapping("/login") + public Result login(@RequestBody LoginReq loginReq){ + log.info("方法体:{ 登录 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(loginReq)); + + Result result = authService.login(loginReq); + + log.info("方法体:{ 登录 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + /** + * 登录人信息 + * @return + */ + @PostMapping("/user/info") + public Result userInfo(){ + log.info("方法体:{ 登录人信息 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod()); + + Result result = authService.userInfo(); + + log.info("方法体:{ 登录人信息 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + /** + * 登出 + * @return + */ + @PostMapping("/user/logout") + public Result userLogout(){ + log.info("方法体:{ 登出 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod()); + + Result result = authService.userLogout(); + + log.info("方法体:{ 登出 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + + + + + + +} diff --git a/Boot-auth/src/main/java/com/bw/auth/feign/AuthFeign.java b/Boot-auth/src/main/java/com/bw/auth/feign/AuthFeign.java new file mode 100644 index 0000000..f167c90 --- /dev/null +++ b/Boot-auth/src/main/java/com/bw/auth/feign/AuthFeign.java @@ -0,0 +1,30 @@ +package com.bw.auth.feign; + +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName AuthFeign + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:15 + */ +@FeignClient("boot-system") +public interface AuthFeign { + + + /** + * 查询用户 + * @return + */ + @PostMapping("/findByUser") + public Result findByUser(@RequestParam String username); + + + + +} diff --git a/Boot-auth/src/main/java/com/bw/auth/service/AuthService.java b/Boot-auth/src/main/java/com/bw/auth/service/AuthService.java new file mode 100644 index 0000000..48a21fe --- /dev/null +++ b/Boot-auth/src/main/java/com/bw/auth/service/AuthService.java @@ -0,0 +1,22 @@ +package com.bw.auth.service; + +import com.bw.common.domain.model.UserModel; +import com.bw.common.domain.request.LoginReq; +import com.bw.common.domain.response.LoginResponse; +import com.bw.common.result.Result; + +/** + * @ClassName AuthService + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:14 + */ +public interface AuthService { + Result login(LoginReq loginReq); + + Result userInfo(); + + + Result userLogout(); + +} diff --git a/Boot-auth/src/main/java/com/bw/auth/service/impl/AuthServiceImpl.java b/Boot-auth/src/main/java/com/bw/auth/service/impl/AuthServiceImpl.java new file mode 100644 index 0000000..e1e938f --- /dev/null +++ b/Boot-auth/src/main/java/com/bw/auth/service/impl/AuthServiceImpl.java @@ -0,0 +1,84 @@ +package com.bw.auth.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.bw.auth.feign.AuthFeign; +import com.bw.auth.service.AuthService; +import com.bw.common.constants.JwtConstants; +import com.bw.common.constants.TokenConstants; +import com.bw.common.domain.model.UserModel; +import com.bw.common.domain.request.LoginReq; +import com.bw.common.domain.response.LoginResponse; +import com.bw.common.exception.ServiceException; +import com.bw.common.result.Result; +import com.bw.common.utils.JwtUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName AuthServiceImpl + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:14 + */ +@Service +public class AuthServiceImpl implements AuthService { + @Autowired + private AuthFeign authFeign; + @Autowired + private HttpServletRequest request; + @Autowired + private RedisTemplate redisTemplate; + + + @Override + public Result login(LoginReq loginReq) { + + Result byUser = authFeign.findByUser(loginReq.getUsername()); + + if (byUser.getData() == null){ + throw new ServiceException("请先注册"); + } + + UserModel userModel = byUser.getData(); + + if (!userModel.getPassword().equals(loginReq.getPassword())){ + throw new ServiceException("密码错误"); + } + + HashMap map = new HashMap<>(); + String userKey = UUID.randomUUID().toString().replaceAll("-", ""); + map.put(JwtConstants.USER_KEY, userKey); + String token = JwtUtils.createToken(map); + + redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY+userKey, + JSONObject.toJSONString(userModel),30, TimeUnit.MINUTES); + + return Result.success(new LoginResponse(token,"30"),"登录成功"); + } + + @Override + public Result userInfo() { + String token = request.getHeader(TokenConstants.TOKEN); + + String userKey = JwtUtils.getUserKey(token); + String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + UserModel userModel = JSONObject.parseObject(s, UserModel.class); + return Result.success(userModel); + + } + + @Override + public Result userLogout() { + String token = request.getHeader(TokenConstants.TOKEN); + String userKey = JwtUtils.getUserKey(token); + redisTemplate.delete(TokenConstants.LOGIN_TOKEN_KEY + userKey); + + return Result.success(1,"退出成功"); + } +} diff --git a/Boot-auth/src/main/resources/bootstrap.yml b/Boot-auth/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..a9bc846 --- /dev/null +++ b/Boot-auth/src/main/resources/bootstrap.yml @@ -0,0 +1,45 @@ +# Tomcat +server: + port: 9001 +# Spring +spring: + rabbitmq: + host: 124.222.55.145 + port: 5672 + username: guest + password: guest + virtual-host: / + listener: + simple: + prefetch: 1 #每次取出来一条消息,消费完毕之后取下一条消费 + acknowledge-mode: manual #手动确认消费 + retry: #重试 + enabled: true + #发送确认配置 开启发送确认 + publisher-confirm-type: correlated #消息发送到broker确认 + publisher-returns: true #消息发送到队列确认 + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: boot-auth + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 124.222.55.145:8848 + config: + # 配置中心地址 + server-addr: 124.222.55.145:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: aaa053d1-7e8e-4711-872f-f52e841e6453 diff --git a/Boot-common/pom.xml b/Boot-common/pom.xml new file mode 100644 index 0000000..3def200 --- /dev/null +++ b/Boot-common/pom.xml @@ -0,0 +1,151 @@ + + + 4.0.0 + + com.bw + Boot-6.YKA + 1.0-SNAPSHOT + + + Boot-common + + + 17 + 17 + UTF-8 + + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + com.alibaba + fastjson + 1.2.80 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.apache.commons + commons-lang3 + + + + org.projectlombok + lombok + + + + cn.hutool + hutool-all + 5.8.3 + + + + com.aliyun + dysmsapi20170525 + 2.0.1 + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + com.aliyun.oss + aliyun-sdk-oss + 3.12.0 + + + + org.springframework.boot + spring-boot-starter-amqp + + + + com.github.tobato + fastdfs-client + 1.26.5 + + + + javax.servlet + javax.servlet-api + + + + + org.springframework + spring-web + 5.1.11.RELEASE + + + + + org.redisson + redisson + 3.16.0 + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + diff --git a/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatLimited.java b/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatLimited.java new file mode 100644 index 0000000..0a428db --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatLimited.java @@ -0,0 +1,26 @@ +package com.bw.common.annotation; + +import java.lang.annotation.*; + +/** + * @ClassName PreventRepeatlimited + * @Description + * @Author zhengshixian + * @Date 2023/12/12 23:06 + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PreventRepeatLimited { + + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interVal() default 5; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试,限流"; +} diff --git a/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatSubmit.java b/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatSubmit.java new file mode 100644 index 0000000..ba8a6a6 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/annotation/PreventRepeatSubmit.java @@ -0,0 +1,26 @@ +package com.bw.common.annotation; + +import java.lang.annotation.*; + +/** + * @ClassName PreventRepeatSubmit + * @Description + * @Author zhengshixian + * @Date 2023/12/12 22:36 + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PreventRepeatSubmit { + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 40; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; + +} diff --git a/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatLimitedAspect.java b/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatLimitedAspect.java new file mode 100644 index 0000000..0d25f10 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatLimitedAspect.java @@ -0,0 +1,96 @@ +package com.bw.common.aop; + +import com.alibaba.fastjson.JSON; +import com.bw.common.annotation.PreventRepeatLimited; +import com.bw.common.config.RedisCache; +import com.bw.common.constants.TokenConstants; +import com.bw.common.exception.ServiceException; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName PreventRepeatSubmitAspect + * @Description + * @Author zhengshixian + * @Date 2023/12/12 22:37 + */ +@Aspect +@Component +public class PreventRepeatLimitedAspect { + private static final Logger LOG = LoggerFactory.getLogger(PreventRepeatLimitedAspect.class); + +// // 令牌自定义标识 +// @Value("${token.header}") +// private String header; + + /** + * 防重复提交流程 + * 获取到当前的 HttpServletRequest 对象,并记录请求的地址、请求方式、拦截到的类名和方法名等信息。 + * 通过 pjp.getArgs() 获取请求参数,并将参数转换成字符串,用于生成唯一标识。 + * 根据请求的地址、参数、唯一标识等信息生成缓存键 cacheRepeatKey,用于作为重复提交判断的依据。 + * 通过 pjp.getSignature().getMethod() 和 method.getAnnotation(PreventRepeatSubmit.class) 获取被拦截的方法上的 PreventRepeatSubmit 注解,进而获取注解中配置的有效期时间。 + * 使用 Redis 分布式锁来判断请求是否重复提交。调用 redisCache.setNxCacheObject() 方法,尝试向缓存中设置键值对,如果设置成功(返回值为 true),则证明没有重复提交。若设置失败(返回值为 false),则抛出 BusinessException 异常,表示重复提交。 + * 如果没有重复提交,则执行目标方法,即 pjp.proceed(),并将其返回。 + * 通过在请求接口中设置一个时间间隔,例如5秒钟,同一个用户在5秒钟内只能请求一次, + * 如果再次请求则认为是重复请求并过滤/拒绝该次请求。 + */ + + @Autowired + private RedisCache redisCache; + + + + // 定义一个切入点 + @Pointcut("@annotation(com.bw.common.annotation.PreventRepeatLimited)") + public void PreventRepeatLimited() { + + } + + @Around("PreventRepeatLimited()") + public Object checkPrs(ProceedingJoinPoint pjp) throws Throwable { + LOG.info("进入PreventRepeatLimited(限流)切面"); + //得到request对象 + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String requestURI = request.getRequestURI(); + LOG.info("防重复提交的请求地址:{} ,请求方式:{}",requestURI,request.getMethod()); + LOG.info("防重复提交拦截到的类名:{} ,方法:{}",pjp.getTarget().getClass().getSimpleName(),pjp.getSignature().getName()); + + //获取请求参数 + Object[] args = pjp.getArgs(); + String argStr = JSON.toJSONString(args); + //这里替换是为了在redis可视化工具中方便查看 + argStr=argStr.replace(":","#"); + // 唯一值(没有消息头则使用请求地址) + + String submitKey = request.getHeader(TokenConstants.TOKEN).trim(); + // 唯一标识(指定key + url +参数+token) + String cacheRepeatKey = "repeat_limited:" + requestURI+":" +argStr+":"+ submitKey; + MethodSignature ms = (MethodSignature) pjp.getSignature(); + Method method=ms.getMethod(); + PreventRepeatLimited PreventRepeatlimited=method.getAnnotation(PreventRepeatLimited.class); + int intervall = PreventRepeatlimited.interVal(); + LOG.info("获取到PreventRepeatLimited的有效期时间"+intervall+"秒"); + //redis分布式锁 + Boolean aBoolean = redisCache.setNxCacheObject(cacheRepeatKey, 1, PreventRepeatlimited.interVal(), TimeUnit.SECONDS); + //aBoolean为true则证明没有重复提交 + if(!aBoolean){ + //JSON.toJSONString(ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(),annotation.message()))); + throw new ServiceException(PreventRepeatlimited.message()); + } + return pjp.proceed(); + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatSubmitAspect.java b/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatSubmitAspect.java new file mode 100644 index 0000000..bb61466 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/aop/PreventRepeatSubmitAspect.java @@ -0,0 +1,95 @@ +package com.bw.common.aop; + +import com.alibaba.fastjson.JSON; +import com.bw.common.annotation.PreventRepeatSubmit; +import com.bw.common.config.RedisCache; +import com.bw.common.constants.TokenConstants; +import com.bw.common.exception.ServiceException; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName PreventRepeatSubmitAspect + * @Description + * @Author zhengshixian + * @Date 2023/12/12 22:37 + */ +@Aspect +@Component +public class PreventRepeatSubmitAspect { + private static final Logger LOG = LoggerFactory.getLogger(PreventRepeatSubmitAspect.class); + +// // 令牌自定义标识 +// @Value("${token.header}") +// private String header; + + /** + * 防重复提交流程 + * 获取到当前的 HttpServletRequest 对象,并记录请求的地址、请求方式、拦截到的类名和方法名等信息。 + * 通过 pjp.getArgs() 获取请求参数,并将参数转换成字符串,用于生成唯一标识。 + * 根据请求的地址、参数、唯一标识等信息生成缓存键 cacheRepeatKey,用于作为重复提交判断的依据。 + * 通过 pjp.getSignature().getMethod() 和 method.getAnnotation(PreventRepeatSubmit.class) 获取被拦截的方法上的 PreventRepeatSubmit 注解,进而获取注解中配置的有效期时间。 + * 使用 Redis 分布式锁来判断请求是否重复提交。调用 redisCache.setNxCacheObject() 方法,尝试向缓存中设置键值对,如果设置成功(返回值为 true),则证明没有重复提交。若设置失败(返回值为 false),则抛出 BusinessException 异常,表示重复提交。 + * 如果没有重复提交,则执行目标方法,即 pjp.proceed(),并将其返回。 + */ + + @Autowired + private RedisCache redisCache; + + + + // 定义一个切入点 + @Pointcut("@annotation(com.bw.common.annotation.PreventRepeatSubmit)") + public void preventRepeatSubmit() { + + } + + @Around("preventRepeatSubmit()") + public Object checkPrs(ProceedingJoinPoint pjp) throws Throwable { + LOG.info("进入preventRepeatSubmit切面"); + //得到request对象 + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String requestURI = request.getRequestURI(); + LOG.info("防重复提交的请求地址:{} ,请求方式:{}",requestURI,request.getMethod()); + LOG.info("防重复提交拦截到的类名:{} ,方法:{}",pjp.getTarget().getClass().getSimpleName(),pjp.getSignature().getName()); + + //获取请求参数 + Object[] args = pjp.getArgs(); + String argStr = JSON.toJSONString(args); + //这里替换是为了在redis可视化工具中方便查看 + argStr=argStr.replace(":","#"); + // 唯一值(没有消息头则使用请求地址) + + String submitKey = request.getHeader(TokenConstants.TOKEN).trim(); + // 唯一标识(指定key + url +参数+token) + String cacheRepeatKey = "repeat_submit:" + requestURI+":" +argStr+":"+ submitKey; + MethodSignature ms = (MethodSignature) pjp.getSignature(); + Method method=ms.getMethod(); + PreventRepeatSubmit preventRepeatSubmit=method.getAnnotation(PreventRepeatSubmit.class); + int interval = preventRepeatSubmit.interval(); + LOG.info("获取到preventRepeatSubmit的有效期时间"+interval+"秒"); + //redis分布式锁 + Boolean aBoolean = redisCache.setNxCacheObject(cacheRepeatKey, 1, preventRepeatSubmit.interval(), TimeUnit.SECONDS); + //aBoolean为true则证明没有重复提交 + if(!aBoolean){ + //JSON.toJSONString(ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(),annotation.message()))); + throw new ServiceException("请勿重复提交"); + } + return pjp.proceed(); + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/config/RedisCache.java b/Boot-common/src/main/java/com/bw/common/config/RedisCache.java new file mode 100644 index 0000000..bac0c01 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/config/RedisCache.java @@ -0,0 +1,271 @@ +package com.bw.common.config; + +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; + +/** + * @ClassName RedisCache + * @Description + * @Author zhengshixian + * @Date 2023/12/12 22:38 + */ +@Component +public class RedisCache { + @Autowired + public RedisTemplate redisTemplate; + + //添加分布式锁 + public Boolean setNxCacheObject(final String key, final T value, long lt, TimeUnit tu) + { + return redisTemplate.opsForValue().setIfAbsent(key,value,lt,tu); + } + + /** + * 缓存基本的对象,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) + { + 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 Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @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) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存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); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/config/RedisConfig.java b/Boot-common/src/main/java/com/bw/common/config/RedisConfig.java new file mode 100644 index 0000000..9bdd7fd --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/config/RedisConfig.java @@ -0,0 +1,40 @@ +package com.bw.common.config; + +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.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + 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); + + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + // key采用String的序列化方式 + template.setKeySerializer(stringRedisSerializer); + // hash的key也采用String的序列化方式 + template.setHashKeySerializer(stringRedisSerializer); + // value序列化方式采用jackson + template.setValueSerializer(jackson2JsonRedisSerializer); + // hash的value序列化方式采用jackson + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.afterPropertiesSet(); + + return template; + } +} diff --git a/Boot-common/src/main/java/com/bw/common/config/RedissonConfig.java b/Boot-common/src/main/java/com/bw/common/config/RedissonConfig.java new file mode 100644 index 0000000..2e35cfd --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/config/RedissonConfig.java @@ -0,0 +1,48 @@ +package com.bw.common.config; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; + +/** + * @BelongsProject: demo02 + * @BelongsPackage: com.bw.config + * @Author: zhupengfei + * @CreateTime: 2022-12-24 09:26 + */ + +@Configuration +public class RedissonConfig { + + @Bean// 服务停止后调用 shutdown 方法。(destroyMethod="shutdown") + public RedissonClient redisson() throws IOException { + System.out.println("配置类初始加载......"); + // 1.创建配置 + Config config = new Config(); + // 集群模式 + // config.useClusterServers().addNodeAddress("127.0.0.1:6379", "127.0.0.1:6378"); + // 2.根据 Config 创建出 RedissonClient 实例。 + config.useSingleServer().setAddress("redis://124.222.55.145:6379"); + return Redisson.create(config); + } + +// /** +// * 集群模式 +// * 备注:可以用"rediss://"来启用SSL连接 +// */ +// @Bean +// public RedissonClient redissonClusterClient() { +// Config config = new Config(); +// config.useClusterServers().setScanInterval(2000) // 集群状态扫描间隔时间,单位是毫秒 +// .addNodeAddress("redis://124.222.55.145:6379:6380") +// .addNodeAddress("redis://124.222.55.145:6379:6381"); +// RedissonClient redisson = Redisson.create(config); +// return redisson; +// } + + +} diff --git a/Boot-common/src/main/java/com/bw/common/constants/Constants.java b/Boot-common/src/main/java/com/bw/common/constants/Constants.java new file mode 100644 index 0000000..1d6ce0a --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/constants/Constants.java @@ -0,0 +1,18 @@ +package com.bw.common.constants; + +/** + * @description: 系统常量 + * @author DongZl + */ +public class Constants { + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + public static final String SUCCESS_MSG = "操作成功"; + /** + * 失败标记 + */ + public static final Integer ERROR = 500; + public static final String ERROR_MSG = "操作异常"; +} diff --git a/Boot-common/src/main/java/com/bw/common/constants/JwtConstants.java b/Boot-common/src/main/java/com/bw/common/constants/JwtConstants.java new file mode 100644 index 0000000..4d54783 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/constants/JwtConstants.java @@ -0,0 +1,29 @@ +package com.bw.common.constants; + +/** + * @author DongZl + * @description: Jwt常量 + */ +public class JwtConstants { + + /** + * 用户ID字段 + */ + public static final String DETAILS_USER_ID = "user_id"; + + /** + * 用户名字段 + */ + public static final String DETAILS_USERNAME = "username"; + + /** + * 用户标识 + */ + public static final String USER_KEY = "user_key"; + + /** + * 令牌秘钥 + */ + public final static String SECRET = "abcdefghijklmnopqrstuvwxyz"; + +} diff --git a/Boot-common/src/main/java/com/bw/common/constants/TokenConstants.java b/Boot-common/src/main/java/com/bw/common/constants/TokenConstants.java new file mode 100644 index 0000000..326e27e --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/constants/TokenConstants.java @@ -0,0 +1,24 @@ +package com.bw.common.constants; + +/** + * @author DongZl + * @description: 令牌常量 + */ +public class TokenConstants { + /** + * 缓存有效期,默认720(分钟) + */ + public final static long EXPIRATION = 720; + /** + * 缓存刷新时间,默认120(分钟) + */ + public final static long REFRESH_TIME = 120; + /** + * 权限缓存前缀 + */ + public final static String LOGIN_TOKEN_KEY = "login_tokens:"; + /** + * token标识 + */ + public static final String TOKEN = "token"; +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/Order.java b/Boot-common/src/main/java/com/bw/common/domain/Order.java new file mode 100644 index 0000000..4466d95 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/Order.java @@ -0,0 +1,83 @@ +package com.bw.common.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 贷款 + * @ClassName Order + * @Description + * @Author zhengshixian + * @Date 2024/1/3 14:25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Order { + /** + * 主键 + */ + private Integer id; + /** + * 买车时间 + */ + private Date buyTime; + /** + * 买车金额 + */ + private Double buyPrice; + /** + * 期数 + */ + private Integer number; + /** + * 最近还款时间 + */ + private Date repaymentTime; + /** + * 已还本金 + */ + private Double repaidPrice; + /** + * 利息 + */ + private Double interest; + /** + * 综合手续费 + */ + private Double handlingCharge; + /** + * 银行id + */ + private Integer bankId; + /** + * 状态 0:申请中,1:通过,2:拒绝 + */ + private Integer status; + /** + * 购买用户ID + */ + private Integer buyUserId; + /** + * 放贷人ID + */ + private Integer loanUserId; + /** + * 还款总金额 + */ + private Double totalPrice; + /** + * 每期还款金额 + */ + private Double everyissuePrice; + /** + * 银行名称 + */ + private String bankName; + + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/User.java b/Boot-common/src/main/java/com/bw/common/domain/User.java new file mode 100644 index 0000000..6f1be29 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/User.java @@ -0,0 +1,50 @@ +package com.bw.common.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 用户 + * @ClassName User + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:02 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class User { + /** + * 用户主键 + */ + private Integer id; + /** + * 用户名称 + */ + private String name; + /** + * 密码 + */ + private String password; + /** + * 角色ID + */ + private Integer roleId; + /** + * 银行ID + */ + private Integer bankId; + /** + * 手机号 + */ + private String phone; + + + + + + + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/model/InterestModel.java b/Boot-common/src/main/java/com/bw/common/domain/model/InterestModel.java new file mode 100644 index 0000000..bbef726 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/model/InterestModel.java @@ -0,0 +1,22 @@ +package com.bw.common.domain.model; + +import com.alibaba.nacos.shaded.org.checkerframework.common.value.qual.ArrayLen; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 利率模版 + * @ClassName InterestModel + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:24 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class InterestModel { + private Double price; + + private Double interest; +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/model/LoansModel.java b/Boot-common/src/main/java/com/bw/common/domain/model/LoansModel.java new file mode 100644 index 0000000..1be49c5 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/model/LoansModel.java @@ -0,0 +1,55 @@ +package com.bw.common.domain.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 贷款模板 + * @ClassName LoansModel + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:07 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoansModel { + + /** + * 买车时间 + */ + private Date buyTime; + /** + * 买车金额 + */ + private Double buyPrice; + /** + * 期数 + */ + private Integer number; + /** + * 利息 + */ + private Double interest; + /** + * 综合手续费 + */ + private Double handlingCharge; + /** + * 购买用户ID + */ + private Integer buyUserId; + /** + * 还款总金额 + */ + private Double totalPrice; + /** + * 每期还款金额 + */ + private Double everyissuePrice; + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/model/UserModel.java b/Boot-common/src/main/java/com/bw/common/domain/model/UserModel.java new file mode 100644 index 0000000..930782f --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/model/UserModel.java @@ -0,0 +1,59 @@ +package com.bw.common.domain.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 用户模板 + * + * @ClassName UserModel + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:03 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserModel { + + + /** + * 用户主键 + */ + private Integer id; + /** + * 用户名称 + */ + private String name; + /** + * 密码 + */ + private String password; + /** + * 角色ID + */ + private Integer roleId; + /** + * 银行ID + */ + private Integer bankId; + /** + * 手机号 + */ + private String phone; + + + /** + * 角色名称 + */ + private String roleName; + + + /** + * 银行名称 + */ + private String bankName; + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/request/LoginReq.java b/Boot-common/src/main/java/com/bw/common/domain/request/LoginReq.java new file mode 100644 index 0000000..af96235 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/request/LoginReq.java @@ -0,0 +1,33 @@ +package com.bw.common.domain.request; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 登录请求 + * @ClassName LoginReq + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:19 + */ +@Data +public class LoginReq { + + + /** + * 用户名称 + */ + @NotNull(message = "用户名不能为空") + private String username; + /** + * 密码 + */ + @NotNull(message = "密码不能为空") + private String password; + + + + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/request/OrderListVO.java b/Boot-common/src/main/java/com/bw/common/domain/request/OrderListVO.java new file mode 100644 index 0000000..cd58aef --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/request/OrderListVO.java @@ -0,0 +1,57 @@ +package com.bw.common.domain.request; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 列表请求 + * @ClassName OrderListVO + * @Description + * @Author zhengshixian + * @Date 2024/1/3 17:02 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OrderListVO { + + + /** + * 起始·买车金额 + */ + private Double startBuyPrice; + + + /** + * 结束·买车金额 + */ + private Double endBuyPrice; + + /** + * 起始·利息 + */ + private Double startinterest; + + + /** + * 结束·利息 + */ + private Double endinterest; + + + + + + + + + + + + + + + + +} diff --git a/Boot-common/src/main/java/com/bw/common/domain/response/LoginResponse.java b/Boot-common/src/main/java/com/bw/common/domain/response/LoginResponse.java new file mode 100644 index 0000000..7626e0d --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/domain/response/LoginResponse.java @@ -0,0 +1,24 @@ +package com.bw.common.domain.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 登录返回 + * @ClassName LoginResponse + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:39 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginResponse { + + + private String token; + private String time; + + +} diff --git a/Boot-common/src/main/java/com/bw/common/exception/ServiceException.java b/Boot-common/src/main/java/com/bw/common/exception/ServiceException.java new file mode 100644 index 0000000..27e0bcd --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.bw.common.exception; + + + +/** + * @ClassName: + * @Description: 业务异常 + * @Author: zhuwenqiang + * @Date: 2023/11/28 + */ +public class ServiceException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + + + + + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + *

+ */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() { + } + + public ServiceException(String message) { + this.message = message; + } + + public ServiceException(String message, Integer code) { + this.message = message; + this.code = code; + } + + public String getDetailMessage() { + return detailMessage; + } + + public ServiceException setDetailMessage(String detailMessage) { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() { + return message; + } + + public ServiceException setMessage(String message) { + this.message = message; + return this; + } + + public Integer getCode() { + return code; + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/exception/handler/GlobalExceptionHandler.java b/Boot-common/src/main/java/com/bw/common/exception/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..05da6f9 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/exception/handler/GlobalExceptionHandler.java @@ -0,0 +1,44 @@ +package com.bw.common.exception.handler; + + +import com.bw.common.exception.ServiceException; +import com.bw.common.result.Result; +import lombok.extern.log4j.Log4j2; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import javax.servlet.http.HttpServletRequest; + + +/** + * @ClassName: + * @Description: 全局异常处理器 + * @Author: zhuwenqiang + * @Date: 2023/11/28 + */ +@RestControllerAdvice +@Log4j2 +public class GlobalExceptionHandler { + + /** + * 处理 业务异常 + * @return + */ + @ExceptionHandler(ServiceException.class) + public Result serviceExceptionHandler(ServiceException serviceException, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',业务处理失败'{}'", requestURI, serviceException.getMessage()); + return Result.error(Result.FAIL, serviceException.getMessage()); + } + +// +// /** +// * 处理 业务异常 +// * @return +// */ +// @ExceptionHandler(Exception.class) +// public Result exceptionHandler() { +// +// return Result.error(); +// } + +} diff --git a/Boot-common/src/main/java/com/bw/common/result/PageResult.java b/Boot-common/src/main/java/com/bw/common/result/PageResult.java new file mode 100644 index 0000000..34680c9 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/result/PageResult.java @@ -0,0 +1,34 @@ +package com.bw.common.result; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author DongZl + * @description: 列表返回结果集 + */ +@Data +public class PageResult implements Serializable { + /** + * 总条数 + */ + private long total; + /** + * 结果集合 + */ + private List list; + public PageResult() { + } + public PageResult(long total, List list) { + this.total = total; + this.list = list; + } + public static PageResult toPageResult(long total, List list){ + return new PageResult(total , list); + } + public static Result> toResult(long total, List list){ + return Result.success(PageResult.toPageResult(total,list)); + } +} diff --git a/Boot-common/src/main/java/com/bw/common/result/Result.java b/Boot-common/src/main/java/com/bw/common/result/Result.java new file mode 100644 index 0000000..c3a10a7 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/result/Result.java @@ -0,0 +1,76 @@ +package com.bw.common.result; + +import com.bw.common.constants.Constants; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author DongZl + * @description: 响应信息主体 + */ +@Data +public class Result implements Serializable { + + private static final long serialVersionUID = 1L; + /** + * 成功 + */ + public static final int SUCCESS = Constants.SUCCESS; + /** + * 失败 + */ + public static final int FAIL = Constants.ERROR; + /** + * 返回状态码 + */ + private int code; + /** + * 响应信息 + */ + private String msg; + /** + * 响应数据 + */ + private T data; + + public static Result success() { + return restResult(null, SUCCESS, Constants.SUCCESS_MSG); + } + + public static Result success(T data) { + return restResult(data, SUCCESS, Constants.SUCCESS_MSG); + } + + public static Result success(T data, String msg) { + return restResult(data, SUCCESS, msg); + } + + public static Result error() { + return restResult(null, FAIL, Constants.ERROR_MSG); + } + + public static Result error(String msg) { + return restResult(null, FAIL, msg); + } + + public static Result error(T data) { + return restResult(data, FAIL, Constants.ERROR_MSG); + } + + public static Result error(T data, String msg) { + return restResult(data, FAIL, msg); + } + + public static Result error(int code, String msg) { + return restResult(null, code, msg); + } + + private static Result restResult(T data, int code, String msg) { + Result apiResult = new Result<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/FastUtil.java b/Boot-common/src/main/java/com/bw/common/utils/FastUtil.java new file mode 100644 index 0000000..3513a82 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/FastUtil.java @@ -0,0 +1,55 @@ +package com.bw.common.utils; + +import org.springframework.stereotype.Component; +import com.github.tobato.fastdfs.domain.fdfs.StorePath; +import com.github.tobato.fastdfs.service.FastFileStorageClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; + +/** + * @BelongsProject: 0107day02 + * @BelongsPackage: com.bw.config + * @Author: zhupengfei + * @CreateTime: 2023-02-01 08:52 + */ +@Component +public class FastUtil { + private static final Logger log = LoggerFactory.getLogger(FastUtil.class); + + @Resource + private FastFileStorageClient storageClient ; + + /** + * 上传文件 + */ + public String upload(MultipartFile multipartFile) throws Exception{ + String originalFilename = multipartFile.getOriginalFilename(). + substring(multipartFile.getOriginalFilename(). + lastIndexOf(".") + 1); + StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage( + multipartFile.getInputStream(), + multipartFile.getSize(),originalFilename , null); + return storePath.getFullPath() ; + } + /** + * 删除文件 + */ + public String deleteFile(String fileUrl) { + if (StringUtils.isEmpty(fileUrl)) { + log.info("fileUrl == >>文件路径为空..."); + return "文件路径不能为空"; + } + try { + StorePath storePath = StorePath.parseFromUrl(fileUrl); + storageClient.deleteFile(storePath.getGroup(), storePath.getPath()); + } catch (Exception e) { + log.error(e.getMessage()); + } + return "删除成功"; + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/HttpPost.java b/Boot-common/src/main/java/com/bw/common/utils/HttpPost.java new file mode 100644 index 0000000..bb4b892 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/HttpPost.java @@ -0,0 +1,77 @@ +package com.bw.common.utils; + + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + + +public class HttpPost { + public static void main(String[] args) { + //你的本地地址 配你的项目地址 这个是我电脑本地的地址 + String doGet = doGet("http://127.0.0.1:8081/sell/list"); + System.out.println("----------SSSS---DDS--S--"+doGet); + } + public static String doGet(String httpUrl){ + //链接 + HttpURLConnection connection=null; + + InputStream is=null; + BufferedReader br = null; + StringBuffer result=new StringBuffer(); + try { + //创建连接 + URL url=new URL(httpUrl); + connection= (HttpURLConnection) url.openConnection(); + //设置请求方式 + connection.setRequestMethod("GET"); + //设置连接超时时间 + connection.setConnectTimeout(15000); + //设置读取超时时间 + connection.setReadTimeout(15000); + + //开始连接 + connection.connect(); + //获取响应数据 + if(connection.getResponseCode()==200){ + //获取返回的数据 + is=connection.getInputStream(); + if(is!=null){ + br=new BufferedReader(new InputStreamReader(is,"UTF-8")); + String temp = null; + while ((temp=br.readLine())!=null){ + result.append(temp); + } + } + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }finally { + if(br!=null){ + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(is!=null){ + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + connection.disconnect();// 关闭远程连接 + } + return result.toString(); + } + + + +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/HttpUtils.java b/Boot-common/src/main/java/com/bw/common/utils/HttpUtils.java new file mode 100644 index 0000000..88f7da0 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/HttpUtils.java @@ -0,0 +1,310 @@ +package com.bw.common.utils; + +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class HttpUtils { + /** + * get + * + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @return + * @throws Exception + */ + public static HttpResponse doGet(String host, String path, String method, + Map headers, + Map querys) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpGet request = new HttpGet(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + return httpClient.execute(request); + } + + /** + * post form + * + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @param bodys + * @return + * @throws Exception + */ + public static HttpResponse doPost(String host, String path, String method, + Map headers, + Map querys, + Map bodys) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpPost request = new HttpPost(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + if (bodys != null) { + List nameValuePairList = new ArrayList(); + + for (String key : bodys.keySet()) { + nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key))); + } + UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); + formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); + request.setEntity(formEntity); + } + + return httpClient.execute(request); + } + + /** + * Post String + * + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @param body + * @return + * @throws Exception + */ + public static HttpResponse doPost(String host, String path, String method, + Map headers, + Map querys, + String body) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpPost request = new HttpPost(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + if (StringUtils.isNotBlank(body)) { + request.setEntity(new StringEntity(body, "utf-8")); + } + + return httpClient.execute(request); + } + + /** + * Post stream + * + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @param body + * @return + * @throws Exception + */ + public static HttpResponse doPost(String host, String path, String method, + Map headers, + Map querys, + byte[] body) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpPost request = new HttpPost(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + if (body != null) { + request.setEntity(new ByteArrayEntity(body)); + } + + return httpClient.execute(request); + } + + /** + * Put String + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @param body + * @return + * @throws Exception + */ + public static HttpResponse doPut(String host, String path, String method, + Map headers, + Map querys, + String body) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpPut request = new HttpPut(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + if (StringUtils.isNotBlank(body)) { + request.setEntity(new StringEntity(body, "utf-8")); + } + + return httpClient.execute(request); + } + + /** + * Put stream + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @param body + * @return + * @throws Exception + */ + public static HttpResponse doPut(String host, String path, String method, + Map headers, + Map querys, + byte[] body) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpPut request = new HttpPut(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + if (body != null) { + request.setEntity(new ByteArrayEntity(body)); + } + + return httpClient.execute(request); + } + + /** + * Delete + * + * @param host + * @param path + * @param method + * @param headers + * @param querys + * @return + * @throws Exception + */ + public static HttpResponse doDelete(String host, String path, String method, + Map headers, + Map querys) + throws Exception { + HttpClient httpClient = wrapClient(host); + + HttpDelete request = new HttpDelete(buildUrl(host, path, querys)); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + + return httpClient.execute(request); + } + + private static String buildUrl(String host, String path, Map querys) throws UnsupportedEncodingException { + StringBuilder sbUrl = new StringBuilder(); + sbUrl.append(host); + if (!StringUtils.isBlank(path)) { + sbUrl.append(path); + } + if (null != querys) { + StringBuilder sbQuery = new StringBuilder(); + for (Map.Entry query : querys.entrySet()) { + if (0 < sbQuery.length()) { + sbQuery.append("&"); + } + if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { + sbQuery.append(query.getValue()); + } + if (!StringUtils.isBlank(query.getKey())) { + sbQuery.append(query.getKey()); + if (!StringUtils.isBlank(query.getValue())) { + sbQuery.append("="); + sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); + } + } + } + if (0 < sbQuery.length()) { + sbUrl.append("?").append(sbQuery); + } + } + + return sbUrl.toString(); + } + + private static HttpClient wrapClient(String host) { + HttpClient httpClient = new DefaultHttpClient(); + if (host.startsWith("https://")) { + sslClient(httpClient); + } + + return httpClient; + } + + private static void sslClient(HttpClient httpClient) { + try { + SSLContext ctx = SSLContext.getInstance("TLS"); + X509TrustManager tm = new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted(X509Certificate[] xcs, String str) { + + } + public void checkServerTrusted(X509Certificate[] xcs, String str) { + + } + }; + ctx.init(null, new TrustManager[] { tm }, null); + SSLSocketFactory ssf = new SSLSocketFactory(ctx); + ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + ClientConnectionManager ccm = httpClient.getConnectionManager(); + SchemeRegistry registry = ccm.getSchemeRegistry(); + registry.register(new Scheme("https", 443, ssf)); + } catch (KeyManagementException ex) { + throw new RuntimeException(ex); + } catch (NoSuchAlgorithmException ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/IpUtils.java b/Boot-common/src/main/java/com/bw/common/utils/IpUtils.java new file mode 100644 index 0000000..abc2638 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/IpUtils.java @@ -0,0 +1,318 @@ +//package com.bw.common.utils; +// +//import javax.servlet.http.HttpServletRequest; +//import cn.hutool.http.server.HttpServerRequest; +//import org.springframework.beans.factory.annotation.Autowired; +////import sun.net.httpserver.HttpServerImpl; +// +//import java.net.InetAddress; +//import java.net.UnknownHostException; +// +///** +// * 获取IP方法 +// * +// * @author ruoyi +// */ +//public class IpUtils { +// +// +// public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; +// // 匹配 ip +// public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; +// public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; +// // 匹配网段 +// public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; +// +// /** +// * 获取客户端IP +// * +// * @param request 请求对象 +// * @return IP地址 +// */ +// public static String getIpAddr(HttpServletRequest request) { +// if (request == null) { +// return "unknown"; +// } +// String ip = request.getHeader("x-forwarded-for"); +// if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { +// ip = request.getHeader("Proxy-Client-IP"); +// } +// if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { +// ip = request.getHeader("X-Forwarded-For"); +// } +// if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { +// ip = request.getHeader("WL-Proxy-Client-IP"); +// } +// if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { +// ip = request.getHeader("X-Real-IP"); +// } +// +// if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { +// ip = request.getRemoteAddr(); +// } +// +// return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); +// } +// +// /** +// * 检查是否为内部IP地址 +// * +// * @param ip IP地址 +// * @return 结果 +// */ +// public static boolean internalIp(String ip) { +// byte[] addr = textToNumericFormatV4(ip); +// return internalIp(addr) || "127.0.0.1".equals(ip); +// } +// +// /** +// * 检查是否为内部IP地址 +// * +// * @param addr byte地址 +// * @return 结果 +// */ +// private static boolean internalIp(byte[] addr) { +// if (StringUtils.isNull(addr) || addr.length < 2) { +// return true; +// } +// final byte b0 = addr[0]; +// final byte b1 = addr[1]; +// // 10.x.x.x/8 +// final byte SECTION_1 = 0x0A; +// // 172.16.x.x/12 +// final byte SECTION_2 = (byte) 0xAC; +// final byte SECTION_3 = (byte) 0x10; +// final byte SECTION_4 = (byte) 0x1F; +// // 192.168.x.x/16 +// final byte SECTION_5 = (byte) 0xC0; +// final byte SECTION_6 = (byte) 0xA8; +// switch (b0) { +// case SECTION_1: +// return true; +// case SECTION_2: +// if (b1 >= SECTION_3 && b1 <= SECTION_4) { +// return true; +// } +// case SECTION_5: +// switch (b1) { +// case SECTION_6: +// return true; +// } +// default: +// return false; +// } +// } +// +// /** +// * 将IPv4地址转换成字节 +// * +// * @param text IPv4地址 +// * @return byte 字节 +// */ +// public static byte[] textToNumericFormatV4(String text) { +// if (text.length() == 0) { +// return null; +// } +// +// byte[] bytes = new byte[4]; +// String[] elements = text.split("\\.", -1); +// try { +// long l; +// int i; +// switch (elements.length) { +// case 1: +// l = Long.parseLong(elements[0]); +// if ((l < 0L) || (l > 4294967295L)) { +// return null; +// } +// bytes[0] = (byte) (int) (l >> 24 & 0xFF); +// bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); +// bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); +// bytes[3] = (byte) (int) (l & 0xFF); +// break; +// case 2: +// l = Integer.parseInt(elements[0]); +// if ((l < 0L) || (l > 255L)) { +// return null; +// } +// bytes[0] = (byte) (int) (l & 0xFF); +// l = Integer.parseInt(elements[1]); +// if ((l < 0L) || (l > 16777215L)) { +// return null; +// } +// bytes[1] = (byte) (int) (l >> 16 & 0xFF); +// bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); +// bytes[3] = (byte) (int) (l & 0xFF); +// break; +// case 3: +// for (i = 0; i < 2; ++i) { +// l = Integer.parseInt(elements[i]); +// if ((l < 0L) || (l > 255L)) { +// return null; +// } +// bytes[i] = (byte) (int) (l & 0xFF); +// } +// l = Integer.parseInt(elements[2]); +// if ((l < 0L) || (l > 65535L)) { +// return null; +// } +// bytes[2] = (byte) (int) (l >> 8 & 0xFF); +// bytes[3] = (byte) (int) (l & 0xFF); +// break; +// case 4: +// for (i = 0; i < 4; ++i) { +// l = Integer.parseInt(elements[i]); +// if ((l < 0L) || (l > 255L)) { +// return null; +// } +// bytes[i] = (byte) (int) (l & 0xFF); +// } +// break; +// default: +// return null; +// } +// } catch (NumberFormatException e) { +// return null; +// } +// return bytes; +// } +// +// /** +// * 获取IP地址 +// * +// * @return 本地IP地址 +// */ +// public static String getHostIp() { +// try { +// return InetAddress.getLocalHost().getHostAddress(); +// } catch (UnknownHostException e) { +// } +// return "127.0.0.1"; +// } +// +// /** +// * 获取主机名 +// * +// * @return 本地主机名 +// */ +// public static String getHostName() { +// try { +// return InetAddress.getLocalHost().getHostName(); +// } catch (UnknownHostException e) { +// } +// return "未知"; +// } +// +// /** +// * 从多级反向代理中获得第一个非unknown IP地址 +// * +// * @param ip 获得的IP地址 +// * @return 第一个非unknown IP地址 +// */ +// public static String getMultistageReverseProxyIp(String ip) { +// // 多级反向代理检测 +// if (ip != null && ip.indexOf(",") > 0) { +// final String[] ips = ip.trim().split(","); +// for (String subIp : ips) { +// if (false == isUnknown(subIp)) { +// ip = subIp; +// break; +// } +// } +// } +// return StringUtils.substring(ip, 0, 255); +// } +// +// /** +// * 检测给定字符串是否为未知,多用于检测HTTP请求相关 +// * +// * @param checkString 被检测的字符串 +// * @return 是否未知 +// */ +// public static boolean isUnknown(String checkString) { +// return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); +// } +// +// /** +// * 是否为IP +// */ +// public static boolean isIP(String ip) { +// return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); +// } +// +// /** +// * 是否为IP,或 *为间隔的通配符地址 +// */ +// public static boolean isIpWildCard(String ip) { +// return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); +// } +// +// /** +// * 检测参数是否在ip通配符里 +// */ +// public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) { +// String[] s1 = ipWildCard.split("\\."); +// String[] s2 = ip.split("\\."); +// boolean isMatchedSeg = true; +// for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) { +// if (!s1[i].equals(s2[i])) { +// isMatchedSeg = false; +// break; +// } +// } +// return isMatchedSeg; +// } +// +// /** +// * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 +// */ +// public static boolean isIPSegment(String ipSeg) { +// return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); +// } +// +// /** +// * 判断ip是否在指定网段中 +// */ +// public static boolean ipIsInNetNoCheck(String iparea, String ip) { +// int idx = iparea.indexOf('-'); +// String[] sips = iparea.substring(0, idx).split("\\."); +// String[] sipe = iparea.substring(idx + 1).split("\\."); +// String[] sipt = ip.split("\\."); +// long ips = 0L, ipe = 0L, ipt = 0L; +// for (int i = 0; i < 4; ++i) { +// ips = ips << 8 | Integer.parseInt(sips[i]); +// ipe = ipe << 8 | Integer.parseInt(sipe[i]); +// ipt = ipt << 8 | Integer.parseInt(sipt[i]); +// } +// if (ips > ipe) { +// long t = ips; +// ips = ipe; +// ipe = t; +// } +// return ips <= ipt && ipt <= ipe; +// } +// +// /** +// * 校验ip是否符合过滤串规则 +// * +// * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` +// * @param ip 校验IP地址 +// * @return boolean 结果 +// */ +// public static boolean isMatchedIp(String filter, String ip) { +// if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) { +// return false; +// } +// String[] ips = filter.split(";"); +// for (String iStr : ips) { +// if (isIP(iStr) && iStr.equals(ip)) { +// return true; +// } else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) { +// return true; +// } else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) { +// return true; +// } +// } +// return false; +// } +//} diff --git a/Boot-common/src/main/java/com/bw/common/utils/JwtUtils.java b/Boot-common/src/main/java/com/bw/common/utils/JwtUtils.java new file mode 100644 index 0000000..9faabcb --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/JwtUtils.java @@ -0,0 +1,109 @@ +package com.bw.common.utils; + +import com.bw.common.constants.JwtConstants; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import java.util.Map; + +/** + * @description: Jwt工具类 + * @author DongZl + */ +public class JwtUtils { + + /** + * 秘钥 + */ + public static String secret = JwtConstants.SECRET; + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + public static String createToken(Map claims){ + String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + public static Claims parseToken(String token){ + return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + } + /** + * 根据令牌获取用户标识 + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserKey(String token){ + Claims claims = parseToken(token); + return getValue(claims, JwtConstants.USER_KEY); + } + /** + * 根据令牌获取用户标识 + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserKey(Claims claims){ + return getValue(claims, JwtConstants.USER_KEY); + } + /** + * 根据令牌获取用户ID + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserId(String token){ + Claims claims = parseToken(token); + return getValue(claims, JwtConstants.DETAILS_USER_ID); + } + /** + * 根据身份信息获取用户ID + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserId(Claims claims){ + return getValue(claims, JwtConstants.DETAILS_USER_ID); + } + /** + * 根据令牌获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public static String getUserName(String token){ + Claims claims = parseToken(token); + return getValue(claims, JwtConstants.DETAILS_USERNAME); + } + /** + * 根据身份信息获取用户名 + * + * @param claims 身份信息 + * @return 用户名 + */ + public static String getUserName(Claims claims){ + return getValue(claims, JwtConstants.DETAILS_USERNAME); + } + /** + * 根据身份信息获取键值 + * + * @param claims 身份信息 + * @param key 键 + * @return 值 + */ + public static String getValue(Claims claims, String key){ + Object obj = claims.get(key); + return obj == null ? "" : obj.toString(); + } +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/MsgUitl.java b/Boot-common/src/main/java/com/bw/common/utils/MsgUitl.java new file mode 100644 index 0000000..15b768f --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/MsgUitl.java @@ -0,0 +1,76 @@ +package com.bw.common.utils; + +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author markguo + * @version 1.0.0 + * @ClassName MsgUitl.java + * @Description TODO + * @createTime 2022年07月22日 15:38:00 + */ +@Component +public class MsgUitl { + + public static String sendMsg(String phone,String code) { + String host = "https://gyytz.market.alicloudapi.com"; + String path = "/sms/smsSend"; + String method = "POST"; + String appcode = "b491bc5d56bb4fa59171e19aaab030bb"; + Map headers = new HashMap(); + //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105 + headers.put("Authorization", "APPCODE " + appcode); + Map querys = new HashMap(); + querys.put("mobile", phone); + querys.put("param", "code"+code); + querys.put("smsSignId", "2e65b1bb3d054466b82f0c9d125465e2"); + querys.put("templateId", "908e94ccf08b4476ba6c876d13f084ad"); + Map bodys = new HashMap(); + + String message=""; + try { + /** + * 重要提示如下: + * HttpUtils请从 + * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java + * 下载 + * + * 相应的依赖请参照 + * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml + */ + HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys); + System.out.println(response.toString()); +// 获取response的body + message = EntityUtils.toString(response.getEntity()); + System.out.println(EntityUtils.toString(response.getEntity())); + + } catch (Exception e) { + e.printStackTrace(); + } + return message; + } + + @CachePut(value="aaa", key="#mobile") + public String saveCode(String mobile,String code){ + return code; + } + + /** + * 获得验证码 + * @param mobile + * @return + */ + + @Cacheable(value="aaa", key="#mobile") + public String getCode(String mobile){ + return "1234"; + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/OssUtil.java b/Boot-common/src/main/java/com/bw/common/utils/OssUtil.java new file mode 100644 index 0000000..e64be13 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/OssUtil.java @@ -0,0 +1,153 @@ +package com.bw.common.utils; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.GetObjectRequest; +import com.aliyun.oss.model.PutObjectRequest; +import lombok.extern.log4j.Log4j2; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Oss服务调用 + */ +@Log4j2 +public class OssUtil { + + /** + * Endpoint 存储对象概述 阿里云主账号AccessKey,accessKeySecret拥有所有API的访问权限 访问路径前缀 存储对象概述 + */ + private static String endPoint = "oss-cn-shanghai.aliyuncs.com/"; + private static String accessKeyId = "LTAI5t7q5mELDW6mXhTZ7zcQ"; + private static String accessKeySecret = "xYAfqdnsSAG2zdBJtptTgYCWKhmWw9"; + private static String accessPre = "https://mall-bw.oss-cn-shanghai.aliyuncs.com/"; + + /** + * bucket名称 + * @return + */ + private static String bucketName = "mall-bw"; + + private static OSS ossClient ; + + static { + ossClient = new OSSClientBuilder().build( + endPoint, + accessKeyId, + accessKeySecret); + log.info("oss服务连接成功!"); + } + + /** + * 默认路径上传本地文件 + * @param filePath + */ + public static String uploadFile(String filePath){ + return uploadFileForBucket(bucketName,getOssFilePath(filePath) ,filePath); + } + + /** + * 默认路径上传multipartFile文件 + * @param multipartFile + */ + public static String uploadMultipartFile(MultipartFile multipartFile) { + return uploadMultipartFile(bucketName,getOssFilePath(multipartFile.getOriginalFilename()),multipartFile); + } + /** + * 上传 multipartFile 类型文件 + * @param bucketName + * @param ossPath + * @param multipartFile + */ + public static String uploadMultipartFile(String bucketName , String ossPath , MultipartFile multipartFile){ + InputStream inputStream = null; + try { + inputStream = multipartFile.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + uploadFileInputStreamForBucket(bucketName, ossPath, inputStream); + return accessPre+ossPath; + } + + /** + * 使用File上传PutObject上传文件 ** 程序默认使用次方法上传 + * @param bucketName 实例名称 + * @param ossPath oss存储路径 + * @param filePath 本地文件路径 + */ + public static String uploadFileForBucket(String bucketName , String ossPath , String filePath) { + // 创建PutObjectRequest对象。 + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossPath, new File(filePath)); + + // 上传 + ossClient.putObject(putObjectRequest); + return accessPre+ossPath; + } + + /** + * 使用文件流上传到指定的bucket实例 + * @param bucketName 实例名称 + * @param ossPath oss存储路径 + * @param filePath 本地文件路径 + */ + public static String uploadFileInputStreamForBucket(String bucketName , String ossPath , String filePath){ + + // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。 + InputStream inputStream = null; + try { + inputStream = new FileInputStream(filePath); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + // 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。 + uploadFileInputStreamForBucket(bucketName, ossPath, inputStream); + return accessPre+ossPath; + } + + public static void uploadFileInputStreamForBucket(String bucketName , String ossPath , InputStream inputStream ){ + ossClient.putObject(bucketName, ossPath, inputStream); + } + + /** + * 下载 + * @param ossFilePath + * @param filePath + */ + public static void downloadFile(String ossFilePath , String filePath ){ + downloadFileForBucket(bucketName , ossFilePath , filePath); + } + /** + * 下载 + * @param bucketName 实例名称 + * @param ossFilePath oss存储路径 + * @param filePath 本地文件路径 + */ + public static void downloadFileForBucket(String bucketName , String ossFilePath , String filePath ){ + ossClient.getObject(new GetObjectRequest(bucketName, ossFilePath), new File(filePath)); + } + + /** + * + * @return + */ + public static String getOssDefaultPath(){ + LocalDateTime now = LocalDateTime.now(); + String url = + now.getYear()+"/"+ + now.getMonth()+"/"+ + now.getDayOfMonth()+"/"+ + now.getHour()+"/"+ + now.getMinute()+"/"; + return url; + } + + public static String getOssFilePath(String filePath){ + String fileSuf = filePath.substring(filePath.indexOf(".") + 1); + return getOssDefaultPath() + UUID.randomUUID().toString() + "." + fileSuf; + } + +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/SendSmsResponse.java b/Boot-common/src/main/java/com/bw/common/utils/SendSmsResponse.java new file mode 100644 index 0000000..0057c7a --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/SendSmsResponse.java @@ -0,0 +1,51 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package com.bw.common.utils; + +import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody; +import com.aliyun.tea.NameInMap; +import com.aliyun.tea.TeaModel; +import com.aliyun.tea.Validation; +import java.util.Map; + +public class SendSmsResponse extends TeaModel { + @NameInMap("headers") + @Validation( + required = true + ) + public Map headers; + @NameInMap("body") + @Validation( + required = true + ) + public SendSmsResponseBody body; + + public SendSmsResponse() { + } + + public static SendSmsResponse build(Map map) throws Exception { + SendSmsResponse self = new SendSmsResponse(); + return (SendSmsResponse)TeaModel.build(map, self); + } + + public SendSmsResponse setHeaders(Map headers) { + this.headers = headers; + return this; + } + + public Map getHeaders() { + return this.headers; + } + + public SendSmsResponse setBody(SendSmsResponseBody body) { + this.body = body; + return this; + } + + public SendSmsResponseBody getBody() { + return this.body; + } +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/SmsResponse.java b/Boot-common/src/main/java/com/bw/common/utils/SmsResponse.java new file mode 100644 index 0000000..b9db62d --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/SmsResponse.java @@ -0,0 +1,21 @@ +package com.bw.common.utils; + +import lombok.Data; + +/** + * @author 冯凯 + * @version 1.0 + * @description: TODO + * @date 2023/8/8 16:27 + */ +@Data +public class SmsResponse { + + private String msg; + + private String smsid; + + private String code; + + private String balance; +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/StringUtils.java b/Boot-common/src/main/java/com/bw/common/utils/StringUtils.java new file mode 100644 index 0000000..26b24d4 --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/StringUtils.java @@ -0,0 +1,68 @@ +package com.bw.common.utils; + +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.List; + +/** + * @author DongZl + * @description: 字符串处理工具类 + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils { + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) { + return object == null; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) { + return isNull(coll) || coll.isEmpty(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) { + if (isEmpty(str) || isEmpty(strs)) { + return false; + } + for (String pattern : strs) { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } +} diff --git a/Boot-common/src/main/java/com/bw/common/utils/TelSmsUtils.java b/Boot-common/src/main/java/com/bw/common/utils/TelSmsUtils.java new file mode 100644 index 0000000..1fc62ca --- /dev/null +++ b/Boot-common/src/main/java/com/bw/common/utils/TelSmsUtils.java @@ -0,0 +1,88 @@ +package com.bw.common.utils; + +import com.alibaba.fastjson.JSONObject; +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.teaopenapi.models.Config; +import lombok.extern.log4j.Log4j2; + +import java.util.Map; + +/** + * 短信工具类 + */ +@Log4j2 +public class TelSmsUtils { + + /** + * 阿里云主账号AccessKey,accessKeySecret拥有所有API的访问权限 + */ + private static String accessKeyId = "LTAI5tQWdAodc1EJ1doShoW4"; + private static String accessKeySecret = "9MbfDBJ3Efqc6iN5yPFX0zq3ZErsII"; + private static String templateCode = "SMS0001"; + + /** + * 短信访问域名 + */ + private static String endpoint = "dysmsapi.aliyuncs.com"; + /** + * 短信签名 + */ + private static String signName = "登录验证"; + + /** + * 实例化短信对象 + */ + private static Client client; + + static { + log.info("初始化短信服务开始"); + long startTime = System.currentTimeMillis(); + try { + client = initClient(); + log.info("初始化短信成功:{}",signName); + } catch (Exception e) { + e.printStackTrace(); + } + log.info("初始化短信服务结束:耗时:{}MS",(System.currentTimeMillis()-startTime)); + } + /** + * 初始化短信对象 + * @return + * @throws Exception + */ + private static Client initClient() throws Exception{ + Config config = new Config() + // 您的AccessKey ID + .setAccessKeyId(accessKeyId) + // 您的AccessKey Secret + .setAccessKeySecret(accessKeySecret); + // 访问的域名 + config.endpoint = endpoint; + return new Client(config); + } + + /** + * 发送单条短信 + * @param tel + + * @param sendDataMap + */ + public static String sendSms(String tel,Map sendDataMap){ + SendSmsRequest sendSmsRequest = new SendSmsRequest() + .setPhoneNumbers(tel) + .setSignName(signName) + .setTemplateCode(templateCode) + .setTemplateParam(JSONObject.toJSONString(sendDataMap)); + SendSmsResponse sendSmsResponse = null; + try { + log.info("发送短信验证码:消息内容是:【{}】", JSONObject.toJSONString(sendDataMap)); + sendSmsResponse = client.sendSms(sendSmsRequest); + } catch (Exception e) { + log.error("短信发送异常,手机号:【{}】,短信内容:【{}】,异常信息:【{}】", tel, sendDataMap, e); + } + return JSONObject.toJSONString(sendSmsResponse.getBody()); + } + +} diff --git a/Boot-common/src/main/resources/META-INF/spring.factories b/Boot-common/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a27c599 --- /dev/null +++ b/Boot-common/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.bw.common.utils.FastUtil,\ + com.bw.common.exception.ServiceException,\ + com.bw.common.exception.handler.GlobalExceptionHandler + diff --git a/Boot-gateway/pom.xml b/Boot-gateway/pom.xml new file mode 100644 index 0000000..084f0a7 --- /dev/null +++ b/Boot-gateway/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + + com.bw + Boot-6.YKA + 1.0-SNAPSHOT + + + Boot-gateway + + + 17 + 17 + UTF-8 + + + + + + com.bw + Boot-common + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + + + + com.alibaba.csp + sentinel-spring-cloud-gateway-adapter + + + + diff --git a/Boot-gateway/src/main/java/com/bw/GatewayApplication.java b/Boot-gateway/src/main/java/com/bw/GatewayApplication.java new file mode 100644 index 0000000..9e64ee7 --- /dev/null +++ b/Boot-gateway/src/main/java/com/bw/GatewayApplication.java @@ -0,0 +1,12 @@ +package com.bw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + // 网关服务Application + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class); + } +} diff --git a/Boot-gateway/src/main/java/com/bw/gateway/config/IgnoreWhiteConfig.java b/Boot-gateway/src/main/java/com/bw/gateway/config/IgnoreWhiteConfig.java new file mode 100644 index 0000000..93ff6d2 --- /dev/null +++ b/Boot-gateway/src/main/java/com/bw/gateway/config/IgnoreWhiteConfig.java @@ -0,0 +1,32 @@ +package com.bw.gateway.config; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.extern.log4j.Log4j2; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * @description: 放行白名单配置 + * @author DongZl + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "ignore") +@Data +@Log4j2 +public class IgnoreWhiteConfig { + /** + * 放行白名单配置,网关不校验此处的白名单 + */ + private List whites = new ArrayList<>(); + + public void setWhites(List whites) { + log.info("加载网关路径白名单:{}", JSONObject.toJSONString(whites)); + this.whites = whites; + } +} diff --git a/Boot-gateway/src/main/java/com/bw/gateway/filters/AuthFiltres.java b/Boot-gateway/src/main/java/com/bw/gateway/filters/AuthFiltres.java new file mode 100644 index 0000000..3552aef --- /dev/null +++ b/Boot-gateway/src/main/java/com/bw/gateway/filters/AuthFiltres.java @@ -0,0 +1,100 @@ +package com.bw.gateway.filters; + + +import com.bw.common.constants.TokenConstants; +import com.bw.common.utils.JwtUtils; +import com.bw.common.utils.StringUtils; +import com.bw.gateway.config.IgnoreWhiteConfig; +import com.bw.gateway.utils.GatewayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.util.List; + +/** + * @ClassName AuthFiltres + * @Description + * @Author zhengshixian + * @Date 2023/10/17 22:56 + */ +@Component +public class AuthFiltres implements GlobalFilter, Ordered { + @Autowired + private IgnoreWhiteConfig ignoreWhiteConfig; + @Autowired + RedisTemplate redisTemplate; + + + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + + //获取系统白名单请求 + List whites = ignoreWhiteConfig.getWhites(); + //获取当前的请求 URI + ServerHttpRequest request = exchange.getRequest(); + + String path = request.getURI().getPath(); + //matches匹配 + boolean matches = StringUtils.matches(path, whites); + if (matches){ + //放行 + return chain.filter(exchange); + } + + //获取token + String token = request.getHeaders().getFirst(TokenConstants.TOKEN); + //token 验证非空 + if (StringUtils.isEmpty(token)){ + //不放行 提示错误信息 + return GatewayUtils.errorResponse(exchange,"token不能为空", + HttpStatus.UNAUTHORIZED); + } + + try { + // token 合法性性 + JwtUtils.parseToken(token); + } catch (Exception ex) { + return GatewayUtils.errorResponse(exchange, "token格式错误!"); + } + // token 是否过期 + // 获取 UserKey + String userKey = JwtUtils.getUserKey(token); + if (!redisTemplate.hasKey(TokenConstants.LOGIN_TOKEN_KEY + userKey)) { + return GatewayUtils.errorResponse(exchange, "token过期!"); + } + + //续期 登录 在10分钟以内自动续期 + //获取用户的登录时间 + + // String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + // User user = JSONObject.parseObject(s, User.class); + // Date time = user.getTime(); + // long between = DateUtil.between(time, new Date(), DateUnit.MINUTE); + // if (between <= 10){ + // redisTemplate.expire(TokenConstants.LOGIN_TOKEN_KEY + userKey,30, TimeUnit.MINUTES); + // } + + + + // 放行 + return chain.filter(exchange); + } + + /** + * 当存在多个filter的时候 用来执行执行的优先级 + * @return 数字 数字的值越小 执行的优先级越高 + */ + @Override + public int getOrder() { + return 0; + } +} diff --git a/Boot-gateway/src/main/java/com/bw/gateway/utils/GatewayUtils.java b/Boot-gateway/src/main/java/com/bw/gateway/utils/GatewayUtils.java new file mode 100644 index 0000000..a2ab22f --- /dev/null +++ b/Boot-gateway/src/main/java/com/bw/gateway/utils/GatewayUtils.java @@ -0,0 +1,98 @@ +package com.bw.gateway.utils; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.result.Result; +import com.bw.common.utils.StringUtils; +import lombok.extern.log4j.Log4j2; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * @author DongZl + * @description: 网关处理工具类 + */ +@Log4j2 +public class GatewayUtils { + /** + * 添加请求头参数 + * @param mutate 修改对象 + * @param key 键 + * @param value 值 + */ + public static void addHeader(ServerHttpRequest.Builder mutate, String key, Object value) { + if (StringUtils.isEmpty(key)){ + log.warn("添加请求头参数键不可以为空"); + return; + } + if (value == null) { + log.warn("添加请求头参数:[{}]值为空",key); + return; + } + String valueStr = value.toString(); + mutate.header(key, valueStr); + log.info("添加请求头参数成功 - 键:[{}] , 值:[{}]", key , value); + } + + /** + * 删除请求头参数 + * @param mutate 修改对象 + * @param key 键 + */ + public static void removeHeader(ServerHttpRequest.Builder mutate, String key) { + if (StringUtils.isEmpty(key)){ + log.warn("删除请求头参数键不可以为空"); + return; + } + mutate.headers(httpHeaders -> httpHeaders.remove(key)).build(); + log.info("删除请求头参数 - 键:[{}]",key); + } + + /** + * 错误结果响应 + * @param exchange 响应上下文 + * @param msg 响应消息 + * @return + */ + public static Mono errorResponse(ServerWebExchange exchange, String msg, HttpStatus httpStatus) { + ServerHttpResponse response = exchange.getResponse(); + //设置HTTP响应头状态 + response.setStatusCode(httpStatus); + //设置HTTP响应头文本格式 + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/json"); + //定义响应内容 + Result result = Result.error(msg); + String resultJson = JSONObject.toJSONString(result); + log.error("[鉴权异常处理]请求路径:[{}],异常信息:[{}],响应结果:[{}]", exchange.getRequest().getPath(), msg, resultJson); + DataBuffer dataBuffer = response.bufferFactory().wrap(resultJson.getBytes()); + //进行响应 + return response.writeWith(Mono.just(dataBuffer)); + } + + /** + * 错误结果响应 + * @param exchange 响应上下文 + * @param msg 响应消息 + * @return + */ + public static Mono errorResponse(ServerWebExchange exchange, String msg) { + ServerHttpResponse response = exchange.getResponse(); + //设置HTTP响应头状态 + response.setStatusCode(HttpStatus.OK); + //设置HTTP响应头文本格式 + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/json"); + //定义响应内容 + Result result = Result.error(msg); + String resultJson = JSONObject.toJSONString(result); + log.error("[鉴权异常处理]请求路径:[{}],异常信息:[{}],响应结果:[{}]", exchange.getRequest().getPath(), msg, resultJson); + DataBuffer dataBuffer = response.bufferFactory().wrap(resultJson.getBytes()); + //进行响应 + return response.writeWith(Mono.just(dataBuffer)); + } + + +} diff --git a/Boot-gateway/src/main/resources/bootstrap.yml b/Boot-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..1ab245d --- /dev/null +++ b/Boot-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,30 @@ +# Tomcat +server: + port: 18080 +# Spring +spring: + application: + # 应用名称 + name: boot-gateway + profiles: + # 环境配置 + active: dev + main: + # 允许使用循环引用 + allow-circular-references: true + # 允许定义相同的bean对象 去覆盖原有的 + allow-bean-definition-overriding: true + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 124.222.55.145:8848 + config: + # 配置中心地址 + server-addr: 124.222.55.145:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: aaa053d1-7e8e-4711-872f-f52e841e6453 diff --git a/Boot-module/module-Buy/pom.xml b/Boot-module/module-Buy/pom.xml new file mode 100644 index 0000000..7f4543f --- /dev/null +++ b/Boot-module/module-Buy/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + com.bw + Boot-module + 1.0-SNAPSHOT + + + module-Buy + + + 17 + 17 + UTF-8 + + + + + + com.bw + Boot-common + + + + org.springframework.boot + spring-boot-starter-web + + + + com.alibaba + druid-spring-boot-starter + 1.2.8 + + + + mysql + mysql-connector-java + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.1 + + + + org.springframework.boot + spring-boot-starter-amqp + + + + diff --git a/Boot-module/module-Buy/src/main/java/com/bw/BuyApplciation.java b/Boot-module/module-Buy/src/main/java/com/bw/BuyApplciation.java new file mode 100644 index 0000000..166667a --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/BuyApplciation.java @@ -0,0 +1,15 @@ +package com.bw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@EnableFeignClients +@EnableScheduling +public class BuyApplciation { + public static void main(String[] args) { + SpringApplication.run(BuyApplciation.class); + } +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/config/ConfirmCallbackConfig.java b/Boot-module/module-Buy/src/main/java/com/bw/config/ConfirmCallbackConfig.java new file mode 100644 index 0000000..5a6505c --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/config/ConfirmCallbackConfig.java @@ -0,0 +1,48 @@ +package com.bw.config; + +import org.springframework.amqp.rabbit.connection.CorrelationData; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @ClassName: + * @Description: 消息发送到 broker的确认 重写 confirm 方法 + * @Author: zhuwenqiang + * @Date: 2023/10/23 + */ +@Component +public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback { + + @Autowired + private RabbitTemplate rabbitTemplate; + + /** + * 当前类被初始化的时候执行的方法 + * + */ + @PostConstruct + public void init() { + // 设置 rabbitTemplate 的消息发送到交换机确认 + rabbitTemplate.setConfirmCallback(this); + } + + /** + * 消息发送到交换机 无论成功或者失败 都会执行 + * + * @param correlationData correlation data for the callback. + * @param ack true for ack, false for nack true 成功 false 失败 + * @param cause An optional cause, for nack, when available, otherwise null. + */ + @Override + public void confirm(CorrelationData correlationData, boolean ack, String cause) { + if (ack) { + System.out.println("消息发送到broker成功!"); + } else { + System.out.println("消息发送到broker失败,失败的原因是:" + cause); + } + } + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitAdminConfig.java b/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitAdminConfig.java new file mode 100644 index 0000000..f6f3821 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitAdminConfig.java @@ -0,0 +1,44 @@ +package com.bw.config; + +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitAdmin; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * RabbitAdmin的配置 构建 RabbitAdmin + */ +@Configuration +public class RabbitAdminConfig { + + @Value("${spring.rabbitmq.host}") + private String host; + + @Value("${spring.rabbitmq.username}") + private String username; + + @Value("${spring.rabbitmq.password}") + private String password; + + @Value("${spring.rabbitmq.virtualhost}") + private String virtualhost; + + @Bean + public ConnectionFactory connectionFactory() { + CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); + connectionFactory.setAddresses(host); + connectionFactory.setUsername(username); + connectionFactory.setPassword(password); + connectionFactory.setVirtualHost(virtualhost); + return connectionFactory; + } + + @Bean + public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { + RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); + rabbitAdmin.setAutoStartup(true); + return rabbitAdmin; + } +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitmqConfig.java b/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitmqConfig.java new file mode 100644 index 0000000..d7088fa --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/config/RabbitmqConfig.java @@ -0,0 +1,15 @@ +package com.bw.config; + +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RabbitmqConfig { + // 消息转换配置 SimpleMessageConverter String byte[] serializable + @Bean + public MessageConverter jsonMessageConverter() { + return new Jackson2JsonMessageConverter(); + } +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/config/ReturnsCallbackConfig.java b/Boot-module/module-Buy/src/main/java/com/bw/config/ReturnsCallbackConfig.java new file mode 100644 index 0000000..dd16bae --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/config/ReturnsCallbackConfig.java @@ -0,0 +1,40 @@ +package com.bw.config; + +import org.springframework.amqp.core.ReturnedMessage; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @ClassName: + * @Description: 消息发送到队列的确认 + * @Author: zhuwenqiang + * @Date: 2023/10/23 + */ +@Component +public class ReturnsCallbackConfig implements RabbitTemplate.ReturnsCallback { + + @Autowired + private RabbitTemplate rabbitTemplate; + + @PostConstruct + public void init() { + rabbitTemplate.setReturnsCallback(this); + } + + /** + * 只有发送到队列失败才会执行 + * + * @param returnedMessage the returned message and metadata. + */ + @Override + public void returnedMessage(ReturnedMessage returnedMessage) { + System.out.println("消息" + returnedMessage.getMessage().toString() + + "被交换机" + returnedMessage.getExchange() + "回退!" + + "退回原因为:" + returnedMessage.getReplyText()); + // TODO 补偿 可以再发 做日志记录 + } + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/consumer/Loans.java b/Boot-module/module-Buy/src/main/java/com/bw/consumer/Loans.java new file mode 100644 index 0000000..d7ab9f2 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/consumer/Loans.java @@ -0,0 +1,43 @@ +package com.bw.consumer; + +import com.bw.feign.BulkFeign; +import lombok.extern.log4j.Log4j2; +import org.springframework.amqp.rabbit.annotation.Queue; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + *贷款异步同步 + * @ClassName Loans + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:21 + */ +@Component +@Log4j2 +public class Loans { + + @Autowired + private BulkFeign bulkFeign; + + @RabbitListener(queuesToDeclare = {@Queue(name = "TB")}) + public void loans(){ + log.info("消费者开始同步"); + bulkFeign.bulk(); + } + + + @Scheduled(cron = " 0/10 * * * * ?") + public void a(){ + + log.info("定时器开始同步"); + + bulkFeign.bulk(); + + } + + + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/controller/BuyController.java b/Boot-module/module-Buy/src/main/java/com/bw/controller/BuyController.java new file mode 100644 index 0000000..f08e947 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/controller/BuyController.java @@ -0,0 +1,100 @@ +package com.bw.controller; + + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.domain.Order; +import com.bw.common.domain.model.LoansModel; +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; +import com.bw.service.BuyService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * @ClassName BuyController + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:00 + */ +@RestController +@Log4j2 +public class BuyController { + @Autowired + private BuyService buyService; + @Autowired + private HttpServletRequest request; + + /** + * 贷款 + * @return + */ + @PostMapping("/loans") + public Result loans(@RequestBody LoansModel model){ + log.info("方法体:{ 贷款 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(model)); + + Result result = buyService.loans(model); + + log.info("方法体:{ 贷款 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + /** + * 列表 + * @return + */ + @GetMapping("/orderList") + public Result> orderList(){ + log.info("方法体:{ 列表 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod()); + + Result> result = buyService.orderList(); + + log.info("方法体:{ 列表 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + /** + * 抢单 + * @return + */ + @PostMapping("/orderGrabbing") + public Result orderGrabbing(@RequestParam Integer id){ + log.info("方法体:{ 抢单 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod()); + + Result result = buyService.orderGrabbing(id); + + log.info("方法体:{ 抢单 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + + + + + + + + + + + + + + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/feign/BulkFeign.java b/Boot-module/module-Buy/src/main/java/com/bw/feign/BulkFeign.java new file mode 100644 index 0000000..f68dfa2 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/feign/BulkFeign.java @@ -0,0 +1,24 @@ +package com.bw.feign; + +import com.bw.common.result.Result; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * 调用ES同步接口 + * @ClassName BulkFeign + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:23 + */ +@FeignClient("boot-es") +public interface BulkFeign { + + /** + * 同步 + * @return + */ + @GetMapping("/bulk") + public Result bulk(); + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/mapper/BuyMapper.java b/Boot-module/module-Buy/src/main/java/com/bw/mapper/BuyMapper.java new file mode 100644 index 0000000..28b9dd5 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/mapper/BuyMapper.java @@ -0,0 +1,26 @@ +package com.bw.mapper; + +import com.bw.common.domain.Order; +import com.bw.common.domain.model.LoansModel; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName BuyMapper + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:03 + */ +@Mapper +public interface BuyMapper { + Integer loans(LoansModel model); + + + List orderList(); + + + void updloanUserId(@Param("id") Integer id, @Param("userId") Integer userId); + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/service/BuyService.java b/Boot-module/module-Buy/src/main/java/com/bw/service/BuyService.java new file mode 100644 index 0000000..adbfcef --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/service/BuyService.java @@ -0,0 +1,23 @@ +package com.bw.service; + +import com.bw.common.domain.Order; +import com.bw.common.domain.model.LoansModel; +import com.bw.common.result.Result; + +import java.util.List; + +/** + * @ClassName BuyService + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:02 + */ +public interface BuyService { + Result loans(LoansModel model); + + Result> orderList(); + + + Result orderGrabbing(Integer id); + +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/service/impl/BuyServiceImpl.java b/Boot-module/module-Buy/src/main/java/com/bw/service/impl/BuyServiceImpl.java new file mode 100644 index 0000000..74f2d5a --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/service/impl/BuyServiceImpl.java @@ -0,0 +1,122 @@ +package com.bw.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.constants.TokenConstants; +import com.bw.common.domain.Order; +import com.bw.common.domain.model.InterestModel; +import com.bw.common.domain.model.LoansModel; +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; +import com.bw.common.utils.JwtUtils; +import com.bw.common.utils.TelSmsUtils; +import com.bw.feign.BulkFeign; +import com.bw.mapper.BuyMapper; +import com.bw.service.BuyService; +import lombok.extern.log4j.Log4j2; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +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 javax.servlet.http.HttpServletRequest; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName BuyServiceImpl + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:02 + */ +@Service +@Log4j2 +public class BuyServiceImpl implements BuyService { + @Autowired + private BuyMapper buyMapper; + @Autowired + private HttpServletRequest request; + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private RabbitTemplate rabbitTemplate; + @Autowired + private RedissonClient redissonClient; + @Autowired + private BulkFeign bulkFeign; + + + @Override + @Transactional + public Result loans(LoansModel model) { + UserModel userModel = getUserModel(); + + //从Redis中获取利率缓存 + List list = new ArrayList<>(); + for (String l : redisTemplate.opsForList().range("l", 0, -1)) { + InterestModel interestModel = JSONObject.parseObject(l, InterestModel.class); + list.add(interestModel); + } + model.setBuyTime(new Date()); + Integer loans = buyMapper.loans(model); + //贷款成功,发送短信通知 + if (loans == 1){ + String a = "贷款提交成功,待申请中"; + TelSmsUtils.sendSms(userModel.getPhone(),new HashMap(){{ + put(a,a); + }}); + } + + rabbitTemplate.convertAndSend("TB","aa"); + + + return Result.success(1,"贷款提交成功,待申请中"); + } + + private UserModel getUserModel() { + String token = request.getHeader(TokenConstants.TOKEN); + String userKey = JwtUtils.getUserKey(token); + String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + UserModel userModel = JSONObject.parseObject(s, UserModel.class); + return userModel; + } + + @Override + public Result> orderList() { + return Result.success(buyMapper.orderList()); + } + + @Override + @Transactional + public Result orderGrabbing(Integer id) { + UserModel userModel = getUserModel(); + + + RLock lock = redissonClient.getLock("one"); + + try { + boolean b = lock.tryLock(1, 3, TimeUnit.SECONDS); + if (b){ + log.info("开始抢单"); + buyMapper.updloanUserId(id,userModel.getId()); + } + //解锁 + lock.unlock(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + bulkFeign.bulk(); + + + return Result.success(1,"成功"); + } +} diff --git a/Boot-module/module-Buy/src/main/java/com/bw/synchronization/Interest.java b/Boot-module/module-Buy/src/main/java/com/bw/synchronization/Interest.java new file mode 100644 index 0000000..413acf0 --- /dev/null +++ b/Boot-module/module-Buy/src/main/java/com/bw/synchronization/Interest.java @@ -0,0 +1,49 @@ +package com.bw.synchronization; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.domain.model.InterestModel; +import com.bw.feign.BulkFeign; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * 利率同步 + * @ClassName Interest + * @Description + * @Author zhengshixian + * @Date 2024/1/3 15:22 + */ +@Component +public class Interest implements ApplicationRunner { + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private BulkFeign bulkFeign; + + + + + @Override + public void run(ApplicationArguments args) throws Exception { + + if (!redisTemplate.hasKey("l")){ + List list = new ArrayList<>(); + list.add(new InterestModel(200000.0,0.02)); + list.add(new InterestModel(500000.0,0.06)); + list.add(new InterestModel(800000.0,0.09)); + list.add(new InterestModel(1000000.0,0.12)); + + list.forEach(interestModel -> { + redisTemplate.opsForList().rightPush("l",JSONObject.toJSONString(interestModel)); + }); + } + + + } +} diff --git a/Boot-module/module-Buy/src/main/resources/bootstrap.yml b/Boot-module/module-Buy/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..9eafd5d --- /dev/null +++ b/Boot-module/module-Buy/src/main/resources/bootstrap.yml @@ -0,0 +1,30 @@ +# Tomcat +server: + port: 9004 +# Spring +spring: + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: boot-student + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 124.222.55.145:8848 + config: + # 配置中心地址 + server-addr: 124.222.55.145:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: aaa053d1-7e8e-4711-872f-f52e841e6453 diff --git a/Boot-module/module-Buy/src/main/resources/mapper/BuyMapper.xml b/Boot-module/module-Buy/src/main/resources/mapper/BuyMapper.xml new file mode 100644 index 0000000..b8036a3 --- /dev/null +++ b/Boot-module/module-Buy/src/main/resources/mapper/BuyMapper.xml @@ -0,0 +1,27 @@ + + + + + + insert into yk_buy (buy_time,buy_price,number,interest,handling_charge, + buy_user_id,total_price,everyissue_price) + values (#{buyTime},#{buyPrice},#{number},#{interest},#{handlingCharge},#{buyUserId},#{totalPrice},#{everyissuePrice}) + + + update yk_buy + set loan_user_id = #{userId}, + status = 1 + where id = #{id} + + + diff --git a/Boot-module/module-ES/pom.xml b/Boot-module/module-ES/pom.xml new file mode 100644 index 0000000..947741d --- /dev/null +++ b/Boot-module/module-ES/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.bw + Boot-module + 1.0-SNAPSHOT + + + module-ES + + + 17 + 17 + UTF-8 + + + + + + com.bw + Boot-common + + + + org.springframework.boot + spring-boot-starter-web + + + + org.elasticsearch.client + elasticsearch-rest-high-level-client + + + + diff --git a/Boot-module/module-ES/src/main/java/com/bw/ESApplication.java b/Boot-module/module-ES/src/main/java/com/bw/ESApplication.java new file mode 100644 index 0000000..2ebb465 --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/ESApplication.java @@ -0,0 +1,14 @@ +package com.bw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class ESApplication { + public static void main(String[] args) { + SpringApplication.run(ESApplication.class); + } +} + diff --git a/Boot-module/module-ES/src/main/java/com/bw/config/initRestHighLeveClient.java b/Boot-module/module-ES/src/main/java/com/bw/config/initRestHighLeveClient.java new file mode 100644 index 0000000..22714db --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/config/initRestHighLeveClient.java @@ -0,0 +1,45 @@ +package com.bw.config; + +import lombok.Data; +import org.apache.http.HttpHost; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName initRestHighLeveClient + * @Description + * @Author zhengshixian + * @Date 2023/10/28 13:35 + */ + + +@Configuration +@Data +@ConfigurationProperties(prefix = ("es")) +public class initRestHighLeveClient { + + private String host; + + private Integer port; + + private String scheme; + + + @Bean + public RestHighLevelClient init(){ + return new RestHighLevelClient( + RestClient.builder(new HttpHost(host,port,scheme)) + ); + } + + + + + + + + +} diff --git a/Boot-module/module-ES/src/main/java/com/bw/controller/ESCcontroller.java b/Boot-module/module-ES/src/main/java/com/bw/controller/ESCcontroller.java new file mode 100644 index 0000000..c84cd82 --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/controller/ESCcontroller.java @@ -0,0 +1,79 @@ +package com.bw.controller; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.domain.Order; +import com.bw.common.domain.model.UserModel; +import com.bw.common.domain.request.OrderListVO; +import com.bw.common.result.Result; +import com.bw.service.ESService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * @ClassName ESCcontroller + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:24 + */ +@RestController +@Log4j2 +public class ESCcontroller { + @Autowired + private ESService esService; + @Autowired + private HttpServletRequest request; + + /** + * 同步 + * @return + */ + @GetMapping("/bulk") + public Result bulk(){ + log.info("方法体:{ 同步 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod()); + + Result result = esService.bulk(); + + log.info("方法体:{ 同步 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + /** + * ES列表 + * @return + */ + @PostMapping("/list") + public Result> list(@RequestBody OrderListVO vo){ + log.info("方法体:{ ES列表 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(vo)); + + Result> result = esService.list(vo); + + log.info("方法体:{ ES列表 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + + + + + + + + + + + + +} diff --git a/Boot-module/module-ES/src/main/java/com/bw/feign/BulkListFeign.java b/Boot-module/module-ES/src/main/java/com/bw/feign/BulkListFeign.java new file mode 100644 index 0000000..00c2f30 --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/feign/BulkListFeign.java @@ -0,0 +1,27 @@ +package com.bw.feign; + +import com.bw.common.domain.Order; +import com.bw.common.result.Result; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +import java.util.List; + +/** + * 调用ES同步接口 + * @ClassName BulkFeign + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:23 + */ +@FeignClient("boot-student") +public interface BulkListFeign { + + /** + * 列表 + * @return + */ + @GetMapping("/orderList") + public Result> orderList(); + +} diff --git a/Boot-module/module-ES/src/main/java/com/bw/service/ESService.java b/Boot-module/module-ES/src/main/java/com/bw/service/ESService.java new file mode 100644 index 0000000..731df73 --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/service/ESService.java @@ -0,0 +1,19 @@ +package com.bw.service; + +import com.bw.common.domain.Order; +import com.bw.common.domain.request.OrderListVO; +import com.bw.common.result.Result; + +import java.util.List; + +/** + * @ClassName ESService + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:25 + */ +public interface ESService { + Result bulk(); + + Result> list(OrderListVO vo); +} diff --git a/Boot-module/module-ES/src/main/java/com/bw/service/impl/ESServiceImpl.java b/Boot-module/module-ES/src/main/java/com/bw/service/impl/ESServiceImpl.java new file mode 100644 index 0000000..4fde7b4 --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/service/impl/ESServiceImpl.java @@ -0,0 +1,162 @@ +package com.bw.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.constants.TokenConstants; +import com.bw.common.domain.Order; +import com.bw.common.domain.model.UserModel; +import com.bw.common.domain.request.OrderListVO; +import com.bw.common.exception.ServiceException; +import com.bw.common.result.Result; +import com.bw.common.utils.JwtUtils; +import com.bw.feign.BulkListFeign; +import com.bw.service.ESService; +import lombok.extern.log4j.Log4j2; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @ClassName ESServiceImpl + * @Description + * @Author zhengshixian + * @Date 2024/1/3 16:25 + */ +@Service +@Log4j2 +public class ESServiceImpl implements ESService { + @Autowired + private BulkListFeign bulkListFeign; + private final static String INDEX_NAME = "loans"; + @Autowired + private RestHighLevelClient restHighLevelClient; + @Autowired + private HttpServletRequest request; + @Autowired + private RedisTemplate redisTemplate; + + + @Override + public Result bulk() { + Result> listResult = bulkListFeign.orderList(); + List data = listResult.getData(); + if (data.size()>0){ + + BulkRequest bulkRequest = new BulkRequest(); + + data.forEach(order -> { + bulkRequest.add( + new IndexRequest(INDEX_NAME) + .id(String.valueOf(order.getId())) + .source(JSONObject.toJSONString(order), XContentType.JSON) + ); + }); + + + try { + restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT); + } catch (IOException e) { + throw new ServiceException("同步异常:"+e); + } + } + log.info("同步结束"); + + return Result.success(1,"同步成功"); + } + + @Override + public Result> list(OrderListVO vo) { + + List list = new ArrayList<>(); + + + SearchRequest searchRequest = new SearchRequest(INDEX_NAME); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); + + + //贷款金额 + if (vo.getStartBuyPrice() != null){ + boolQuery.must(QueryBuilders.rangeQuery("buyPrice").gte(vo.getStartBuyPrice())); + } + if (vo.getEndBuyPrice() != null){ + boolQuery.must(QueryBuilders.rangeQuery("buyPrice").lte(vo.getEndBuyPrice())); + } + + //利率 + if (vo.getStartinterest() != null){ + boolQuery.must(QueryBuilders.rangeQuery("interest").gte(vo.getStartinterest())); + } + if (vo.getEndBuyPrice() != null){ + boolQuery.must(QueryBuilders.rangeQuery("interest").lte(vo.getEndinterest())); + } + + //获取当前登录人 + String token = request.getHeader(TokenConstants.TOKEN); + String userKey = JwtUtils.getUserKey(token); + String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + UserModel userModel = JSONObject.parseObject(s, UserModel.class); + + if (userModel.getId() != null){ + if (userModel.getRoleId() == 1 ){ + boolQuery.must(QueryBuilders.matchQuery("buyUserId",userModel.getId())); + } + } + + + searchSourceBuilder.query(boolQuery); + + searchRequest.source(searchSourceBuilder); + + try { + SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); + + for (SearchHit hit : search.getHits().getHits()) { + + String sourceAsString = hit.getSourceAsString(); + Order order = JSONObject.parseObject(sourceAsString, Order.class); + + if (userModel.getRoleId() == 2 ){ + + //自己放款的 + if (Objects.equals(order.getLoanUserId(), userModel.getId())){ + order.setId(Integer.valueOf(hit.getId())); + list.add(order); + } + + //可以抢单的 + if (order.getLoanUserId().equals(0)){ + order.setId(Integer.valueOf(hit.getId())); + list.add(order); + } + + }else { + order.setId(Integer.valueOf(hit.getId())); + list.add(order); + } + + } + } catch (IOException e) { + throw new ServiceException("ES列表异常:" +e); + } + + return Result.success(list); + } +} diff --git a/Boot-module/module-ES/src/main/java/com/bw/synchronization/ESsynchronization.java b/Boot-module/module-ES/src/main/java/com/bw/synchronization/ESsynchronization.java new file mode 100644 index 0000000..0db9fdc --- /dev/null +++ b/Boot-module/module-ES/src/main/java/com/bw/synchronization/ESsynchronization.java @@ -0,0 +1,27 @@ +package com.bw.synchronization; + +import com.bw.service.ESService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +/** + * @ClassName ESsynchronization + * @Description + * @Author zhengshixian + * @Date 2024/1/3 18:32 + */ +@Component +public class ESsynchronization implements ApplicationRunner { + @Autowired + private ESService esService; + + + + @Override + public void run(ApplicationArguments args) throws Exception { + //同步 + esService.bulk(); + } +} diff --git a/Boot-module/module-ES/src/main/resources/bootstrap.yml b/Boot-module/module-ES/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..92aba07 --- /dev/null +++ b/Boot-module/module-ES/src/main/resources/bootstrap.yml @@ -0,0 +1,34 @@ +# Tomcat +server: + port: 9005 +# Spring +spring: + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: boot-es + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 124.222.55.145:8848 + config: + # 配置中心地址 + server-addr: 124.222.55.145:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: aaa053d1-7e8e-4711-872f-f52e841e6453 +es: + host: 124.222.55.145 + port: 9200 + scheme: http diff --git a/Boot-module/module-system/pom.xml b/Boot-module/module-system/pom.xml new file mode 100644 index 0000000..d0a91a5 --- /dev/null +++ b/Boot-module/module-system/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + + com.bw + Boot-module + 1.0-SNAPSHOT + + + module-system + + + 17 + 17 + UTF-8 + + + + + + com.bw + Boot-common + + + + org.springframework.boot + spring-boot-starter-web + + + + com.alibaba + druid-spring-boot-starter + 1.2.8 + + + + mysql + mysql-connector-java + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.1 + + + + org.springframework.boot + spring-boot-starter-amqp + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/Boot-module/module-system/src/main/java/com/bw/SystemApplication.java b/Boot-module/module-system/src/main/java/com/bw/SystemApplication.java new file mode 100644 index 0000000..0d08314 --- /dev/null +++ b/Boot-module/module-system/src/main/java/com/bw/SystemApplication.java @@ -0,0 +1,11 @@ +package com.bw; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SystemApplication { + public static void main(String[] args) { + SpringApplication.run(SystemApplication.class); + } +} diff --git a/Boot-module/module-system/src/main/java/com/bw/controller/SystemController.java b/Boot-module/module-system/src/main/java/com/bw/controller/SystemController.java new file mode 100644 index 0000000..8134691 --- /dev/null +++ b/Boot-module/module-system/src/main/java/com/bw/controller/SystemController.java @@ -0,0 +1,59 @@ +package com.bw.controller; + +import com.alibaba.fastjson.JSONObject; +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; +import com.bw.service.SystemService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * 用户查询 + * @ClassName SystemController + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:04 + */ +@RestController +@Log4j2 +public class SystemController { + @Autowired + private SystemService systemService; + @Autowired + private HttpServletRequest request; + + + /** + * 查询用户 + * @return + */ + @PostMapping("/findByUser") + public Result findByUser(@RequestParam String username){ + log.info("方法体:{ 查询用户 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(),username); + + Result result = systemService.findByUser(username); + + log.info("方法体:{ 查询用户 },请求URI:{},请求路劲:{},请求参数:{}", + request.getRequestURI(),request.getMethod(), JSONObject.toJSONString(result)); + + return result; + } + + + + + + + + + + + + +} diff --git a/Boot-module/module-system/src/main/java/com/bw/mapper/SystemMapper.java b/Boot-module/module-system/src/main/java/com/bw/mapper/SystemMapper.java new file mode 100644 index 0000000..25a5512 --- /dev/null +++ b/Boot-module/module-system/src/main/java/com/bw/mapper/SystemMapper.java @@ -0,0 +1,16 @@ +package com.bw.mapper; + +import com.bw.common.domain.model.UserModel; +import org.apache.ibatis.annotations.Mapper; + +/** + * @ClassName SystemMapper + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:06 + */ +@Mapper +public interface SystemMapper { + UserModel findByUser(String username); + +} diff --git a/Boot-module/module-system/src/main/java/com/bw/service/SystemService.java b/Boot-module/module-system/src/main/java/com/bw/service/SystemService.java new file mode 100644 index 0000000..3f7412a --- /dev/null +++ b/Boot-module/module-system/src/main/java/com/bw/service/SystemService.java @@ -0,0 +1,14 @@ +package com.bw.service; + +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; + +/** + * @ClassName SystemService + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:05 + */ +public interface SystemService { + Result findByUser(String username); +} diff --git a/Boot-module/module-system/src/main/java/com/bw/service/impl/SystemServiceImpl.java b/Boot-module/module-system/src/main/java/com/bw/service/impl/SystemServiceImpl.java new file mode 100644 index 0000000..62907a4 --- /dev/null +++ b/Boot-module/module-system/src/main/java/com/bw/service/impl/SystemServiceImpl.java @@ -0,0 +1,26 @@ +package com.bw.service.impl; + +import com.bw.common.domain.model.UserModel; +import com.bw.common.result.Result; +import com.bw.mapper.SystemMapper; +import com.bw.service.SystemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName SystemServiceImpl + * @Description + * @Author zhengshixian + * @Date 2024/1/3 11:06 + */ +@Service +public class SystemServiceImpl implements SystemService { + @Autowired + private SystemMapper systemMapper; + + + @Override + public Result findByUser(String username) { + return Result.success(systemMapper.findByUser(username)); + } +} diff --git a/Boot-module/module-system/src/main/resources/bootstrap.yml b/Boot-module/module-system/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..f1e5222 --- /dev/null +++ b/Boot-module/module-system/src/main/resources/bootstrap.yml @@ -0,0 +1,30 @@ +# Tomcat +server: + port: 9003 +# Spring +spring: + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: boot-system + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 124.222.55.145:8848 + config: + # 配置中心地址 + server-addr: 124.222.55.145:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: aaa053d1-7e8e-4711-872f-f52e841e6453 diff --git a/Boot-module/module-system/src/main/resources/mapper/SystemMapper.xml b/Boot-module/module-system/src/main/resources/mapper/SystemMapper.xml new file mode 100644 index 0000000..c7ddbb8 --- /dev/null +++ b/Boot-module/module-system/src/main/resources/mapper/SystemMapper.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/Boot-module/pom.xml b/Boot-module/pom.xml new file mode 100644 index 0000000..0b8a88c --- /dev/null +++ b/Boot-module/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + com.bw + Boot-6.YKA + 1.0-SNAPSHOT + + + Boot-module + pom + + module-system + module-Buy + module-ES + + + + 17 + 17 + UTF-8 + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8f35d5f --- /dev/null +++ b/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.bw + Boot-6.YKA + 1.0-SNAPSHOT + pom + + Boot-common + Boot-auth + Boot-gateway + Boot-module + + + + 17 + 17 + UTF-8 + + + + + + + spring-boot-starter-parent + org.springframework.boot + 2.6.2 + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + 2021.0.0 + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2021.1 + pom + import + + + + com.alibaba.nacos + nacos-client + 2.0.4 + + + + + com.bw + Boot-common + 1.0-SNAPSHOT + + + + + + +