From 73f2b24319425891d112506a9d595b04328e45e3 Mon Sep 17 00:00:00 2001 From: chentaisen <14615430+chentaisen@user.noreply.gitee.com> Date: Tue, 23 Jul 2024 21:19:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=91=A8=E8=80=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 38 +++++ .idea/$PROJECT_FILE$ | 11 ++ .idea/.gitignore | 8 + .idea/encodings.xml | 18 ++ .idea/inspectionProfiles/Project_Default.xml | 14 ++ .idea/misc.xml | 20 +++ .idea/qaplug_profiles.xml | 12 ++ .idea/vcs.xml | 6 + bwie-auth/pom.xml | 32 ++++ .../com/bwie/auth/AuthUserApplication.java | 20 +++ .../auth/config/ConfirmCallbackConfig.java | 39 +++++ .../bwie/auth/config/InitPasswordEncode.java | 15 ++ .../bwie/auth/config/RabbitAdminConfig.java | 50 ++++++ .../com/bwie/auth/config/RabbitmqConfig.java | 15 ++ .../auth/config/ReturnsCallbackConfig.java | 36 ++++ .../auth/controller/AuthUserController.java | 48 ++++++ .../bwie/auth/controlleradvice/Exception.java | 14 ++ .../bwie/auth/exception/AuthException.java | 19 +++ .../bwie/auth/feign/SysUserRemoteService.java | 20 +++ .../bwie/auth/service/AuthUserService.java | 15 ++ .../service/impl/AuthUserServiceImpl.java | 78 +++++++++ .../impl/SysUserAuthServiceFactory.java | 27 +++ bwie-auth/src/main/resources/bootstrap.yml | 44 +++++ bwie-common/pom.xml | 115 +++++++++++++ .../com/bwie/common/config/RedisConfig.java | 40 +++++ .../com/bwie/common/constants/Constants.java | 18 ++ .../bwie/common/constants/JwtConstants.java | 29 ++++ .../common/constants/RabbitMQConstants.java | 5 + .../bwie/common/constants/TokenConstants.java | 24 +++ .../common/domain/response/JwtResponse.java | 9 + .../main/java/com/bwie/common/pojo/Car.java | 19 +++ .../java/com/bwie/common/pojo/Record.java | 33 ++++ .../main/java/com/bwie/common/pojo/Type.java | 15 ++ .../main/java/com/bwie/common/pojo/User.java | 18 ++ .../com/bwie/common/result/PageResult.java | 34 ++++ .../java/com/bwie/common/result/Result.java | 76 +++++++++ .../java/com/bwie/common/utils/FastUtil.java | 50 ++++++ .../com/bwie/common/utils/GenCodeUtils.java | 86 ++++++++++ .../java/com/bwie/common/utils/JwtUtils.java | 115 +++++++++++++ .../java/com/bwie/common/utils/OssUtil.java | 154 ++++++++++++++++++ .../com/bwie/common/utils/StringUtils.java | 67 ++++++++ .../com/bwie/common/utils/TelSmsUtils.java | 92 +++++++++++ bwie-gateway/pom.xml | 40 +++++ .../com/bwie/gateway/GatewayApplication.java | 17 ++ .../gateway/config/IgnoreWhiteConfig.java | 29 ++++ .../com/bwie/gateway/filters/AuthFilter.java | 57 +++++++ .../com/bwie/gateway/utils/GatewayUtils.java | 95 +++++++++++ bwie-gateway/src/main/resources/bootstrap.yml | 29 ++++ bwie-module/bwie-list/pom.xml | 52 ++++++ .../java/com/bwie/list/CarApplication.java | 17 ++ .../bwie/list/controller/CarController.java | 71 ++++++++ .../java/com/bwie/list/mapper/CarMapper.java | 71 ++++++++ .../com/bwie/list/service/CarService.java | 43 +++++ .../list/service/impl/CarServiceImpl.java | 114 +++++++++++++ .../src/main/resources/bootstrap.yml | 29 ++++ .../src/main/resources/mapper/UserMapper.xml | 125 ++++++++++++++ bwie-module/bwie-system/pom.xml | 52 ++++++ .../com/bwie/user/SysUserApplication.java | 17 ++ .../user/controller/SysUserController.java | 35 ++++ .../com/bwie/user/mapper/SysUserMapper.java | 9 + .../com/bwie/user/service/SysUserService.java | 12 ++ .../user/service/impl/SysUserServiceImpl.java | 23 +++ .../src/main/resources/bootstrap.yml | 29 ++++ .../src/main/resources/mapper/UserMapper.xml | 12 ++ bwie-module/pom.xml | 20 +++ bwie-module/src/main/java/com/bw/Main.java | 7 + img.png | Bin 0 -> 42119 bytes pom.xml | 64 ++++++++ src/main/java/com/bw/Main.java | 7 + 屏幕截图 2024-07-23 211712.png | Bin 0 -> 58337 bytes 70 files changed, 2674 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/$PROJECT_FILE$ 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/qaplug_profiles.xml create mode 100644 .idea/vcs.xml create mode 100644 bwie-auth/pom.xml create mode 100644 bwie-auth/src/main/java/com/bwie/auth/AuthUserApplication.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/config/ConfirmCallbackConfig.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/config/InitPasswordEncode.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/config/RabbitAdminConfig.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/config/RabbitmqConfig.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/config/ReturnsCallbackConfig.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/controller/AuthUserController.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/controlleradvice/Exception.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/exception/AuthException.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/feign/SysUserRemoteService.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/service/AuthUserService.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/service/impl/AuthUserServiceImpl.java create mode 100644 bwie-auth/src/main/java/com/bwie/auth/service/impl/SysUserAuthServiceFactory.java create mode 100644 bwie-auth/src/main/resources/bootstrap.yml create mode 100644 bwie-common/pom.xml create mode 100644 bwie-common/src/main/java/com/bwie/common/config/RedisConfig.java create mode 100644 bwie-common/src/main/java/com/bwie/common/constants/Constants.java create mode 100644 bwie-common/src/main/java/com/bwie/common/constants/JwtConstants.java create mode 100644 bwie-common/src/main/java/com/bwie/common/constants/RabbitMQConstants.java create mode 100644 bwie-common/src/main/java/com/bwie/common/constants/TokenConstants.java create mode 100644 bwie-common/src/main/java/com/bwie/common/domain/response/JwtResponse.java create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/Car.java create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/Record.java create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/Type.java create mode 100644 bwie-common/src/main/java/com/bwie/common/pojo/User.java create mode 100644 bwie-common/src/main/java/com/bwie/common/result/PageResult.java create mode 100644 bwie-common/src/main/java/com/bwie/common/result/Result.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/FastUtil.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/GenCodeUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/JwtUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/OssUtil.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/StringUtils.java create mode 100644 bwie-common/src/main/java/com/bwie/common/utils/TelSmsUtils.java create mode 100644 bwie-gateway/pom.xml create mode 100644 bwie-gateway/src/main/java/com/bwie/gateway/GatewayApplication.java create mode 100644 bwie-gateway/src/main/java/com/bwie/gateway/config/IgnoreWhiteConfig.java create mode 100644 bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java create mode 100644 bwie-gateway/src/main/java/com/bwie/gateway/utils/GatewayUtils.java create mode 100644 bwie-gateway/src/main/resources/bootstrap.yml create mode 100644 bwie-module/bwie-list/pom.xml create mode 100644 bwie-module/bwie-list/src/main/java/com/bwie/list/CarApplication.java create mode 100644 bwie-module/bwie-list/src/main/java/com/bwie/list/controller/CarController.java create mode 100644 bwie-module/bwie-list/src/main/java/com/bwie/list/mapper/CarMapper.java create mode 100644 bwie-module/bwie-list/src/main/java/com/bwie/list/service/CarService.java create mode 100644 bwie-module/bwie-list/src/main/java/com/bwie/list/service/impl/CarServiceImpl.java create mode 100644 bwie-module/bwie-list/src/main/resources/bootstrap.yml create mode 100644 bwie-module/bwie-list/src/main/resources/mapper/UserMapper.xml create mode 100644 bwie-module/bwie-system/pom.xml create mode 100644 bwie-module/bwie-system/src/main/java/com/bwie/user/SysUserApplication.java create mode 100644 bwie-module/bwie-system/src/main/java/com/bwie/user/controller/SysUserController.java create mode 100644 bwie-module/bwie-system/src/main/java/com/bwie/user/mapper/SysUserMapper.java create mode 100644 bwie-module/bwie-system/src/main/java/com/bwie/user/service/SysUserService.java create mode 100644 bwie-module/bwie-system/src/main/java/com/bwie/user/service/impl/SysUserServiceImpl.java create mode 100644 bwie-module/bwie-system/src/main/resources/bootstrap.yml create mode 100644 bwie-module/bwie-system/src/main/resources/mapper/UserMapper.xml create mode 100644 bwie-module/pom.xml create mode 100644 bwie-module/src/main/java/com/bw/Main.java create mode 100644 img.png create mode 100644 pom.xml create mode 100644 src/main/java/com/bw/Main.java create mode 100644 屏幕截图 2024-07-23 211712.png 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/$PROJECT_FILE$ b/.idea/$PROJECT_FILE$ new file mode 100644 index 0000000..58b7e3e --- /dev/null +++ b/.idea/$PROJECT_FILE$ @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..1ad6455 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ 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..ee2c34b --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9e844e1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/qaplug_profiles.xml b/.idea/qaplug_profiles.xml new file mode 100644 index 0000000..9a7566c --- /dev/null +++ b/.idea/qaplug_profiles.xml @@ -0,0 +1,12 @@ + + + + + \ 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/bwie-auth/pom.xml b/bwie-auth/pom.xml new file mode 100644 index 0000000..5aa9878 --- /dev/null +++ b/bwie-auth/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + + + bwie-auth + + + + + com.bwie + bwie-common + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-amqp + + + + + diff --git a/bwie-auth/src/main/java/com/bwie/auth/AuthUserApplication.java b/bwie-auth/src/main/java/com/bwie/auth/AuthUserApplication.java new file mode 100644 index 0000000..36f7037 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/AuthUserApplication.java @@ -0,0 +1,20 @@ +package com.bwie.auth; + +import com.bwie.auth.service.AuthUserService; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @ClassName AuthUserApplication + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:01 + */ +@SpringBootApplication +@EnableFeignClients +public class AuthUserApplication { + public static void main(String[] args) { + SpringApplication.run(AuthUserApplication.class); + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/config/ConfirmCallbackConfig.java b/bwie-auth/src/main/java/com/bwie/auth/config/ConfirmCallbackConfig.java new file mode 100644 index 0000000..496c331 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/config/ConfirmCallbackConfig.java @@ -0,0 +1,39 @@ +package com.bwie.auth.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; + +@Component +public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback { + + @Autowired + private RabbitTemplate rabbitTemplate; + + /** + * 当前bean初始化的时候执行 + */ + @PostConstruct + public void init() { + this.rabbitTemplate.setConfirmCallback(this); + } + + /** + * 确认方法 + * @param correlationData correlation data for the callback. + * @param ack true for ack, false for nack + * @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/bwie-auth/src/main/java/com/bwie/auth/config/InitPasswordEncode.java b/bwie-auth/src/main/java/com/bwie/auth/config/InitPasswordEncode.java new file mode 100644 index 0000000..b369484 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/config/InitPasswordEncode.java @@ -0,0 +1,15 @@ +package com.bwie.auth.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Component; + + +@Component +public class InitPasswordEncode { + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder(){ + return new BCryptPasswordEncoder(); + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/config/RabbitAdminConfig.java b/bwie-auth/src/main/java/com/bwie/auth/config/RabbitAdminConfig.java new file mode 100644 index 0000000..2228bbb --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/config/RabbitAdminConfig.java @@ -0,0 +1,50 @@ +package com.bwie.auth.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 + */ +@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.virtual-host}") + private String virtualhost; + + @Bean + public ConnectionFactory connectionFactory() { + CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); + connectionFactory.setAddresses(host); + connectionFactory.setUsername(username); + connectionFactory.setPassword(password); + connectionFactory.setVirtualHost(virtualhost); + // 配置发送确认回调时,次配置必须配置,否则即使在RabbitTemplate配置了ConfirmCallback也不会生效 + connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED); + connectionFactory.setPublisherReturns(true); + return connectionFactory; + } + + + /** + * rabbitAdmin + * @param connectionFactory + * @return + */ + @Bean + public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { + RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); + rabbitAdmin.setAutoStartup(true); + return rabbitAdmin; + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/config/RabbitmqConfig.java b/bwie-auth/src/main/java/com/bwie/auth/config/RabbitmqConfig.java new file mode 100644 index 0000000..aa96f40 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/config/RabbitmqConfig.java @@ -0,0 +1,15 @@ +package com.bwie.auth.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 { + // 消息转换配置 + @Bean + public MessageConverter jsonMessageConverter(){ + return new Jackson2JsonMessageConverter(); + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/config/ReturnsCallbackConfig.java b/bwie-auth/src/main/java/com/bwie/auth/config/ReturnsCallbackConfig.java new file mode 100644 index 0000000..4ba234b --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/config/ReturnsCallbackConfig.java @@ -0,0 +1,36 @@ +package com.bwie.auth.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; + +@Component +public class ReturnsCallbackConfig implements RabbitTemplate.ReturnsCallback { + + @Autowired + private RabbitTemplate rabbitTemplate; + + /** + * 当前bean初始化的时候执行 + */ + @PostConstruct + public void init() { + this.rabbitTemplate.setReturnsCallback(this); + } + + /** + * 消息发送达到 queue 失败执行 + * + * @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/bwie-auth/src/main/java/com/bwie/auth/controller/AuthUserController.java b/bwie-auth/src/main/java/com/bwie/auth/controller/AuthUserController.java new file mode 100644 index 0000000..da35fa5 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/controller/AuthUserController.java @@ -0,0 +1,48 @@ +package com.bwie.auth.controller; + +import ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter; +import com.bwie.auth.service.AuthUserService; +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.web.bind.annotation.*; + +/** + * @ClassName AuthUserController + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 9:41 + */ +@RestController +@RequestMapping("/user") +public class AuthUserController { + @Autowired + private AuthUserService userService; + /** + * 登录 + * @param user + * @return + */ + @PostMapping("/login") + public Result login(@RequestBody User user) { + return userService.login(user); + } + + /** + * 加密 + */ + @GetMapping("/getPwd") + public void getPwd(){ + BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); + String encode = bCryptPasswordEncoder.encode("123"); + System.out.println(encode); + } + /** + * info + */ + @GetMapping("/info") + public Result info(){ + return userService.info(); + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/controlleradvice/Exception.java b/bwie-auth/src/main/java/com/bwie/auth/controlleradvice/Exception.java new file mode 100644 index 0000000..7eb3f9a --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/controlleradvice/Exception.java @@ -0,0 +1,14 @@ +package com.bwie.auth.controlleradvice; + +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * @ClassName Expetr + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:49 + */ +@RestControllerAdvice +public class Exception { + +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/exception/AuthException.java b/bwie-auth/src/main/java/com/bwie/auth/exception/AuthException.java new file mode 100644 index 0000000..9a86c94 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/exception/AuthException.java @@ -0,0 +1,19 @@ +//package com.bwie.auth.exception; +// +//import com.sun.xml.internal.ws.handler.HandlerException; +//import org.springframework.stereotype.Component; +//import org.springframework.web.bind.annotation.ExceptionHandler; +// +///** +// * @ClassName AuthException +// * @Description 描述 +// * @Author Chen +// * @Date 2024/7/23 10:50 +// */ +//@Component +//public class AuthException extends RuntimeException{ +// @ExceptionHandler(HandlerException.class) +// public void exception(){ +// +// } +//} diff --git a/bwie-auth/src/main/java/com/bwie/auth/feign/SysUserRemoteService.java b/bwie-auth/src/main/java/com/bwie/auth/feign/SysUserRemoteService.java new file mode 100644 index 0000000..55d7f3c --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/feign/SysUserRemoteService.java @@ -0,0 +1,20 @@ +package com.bwie.auth.feign; + +import com.bwie.auth.service.impl.SysUserAuthServiceFactory; +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * @ClassName SysUserRemoteService + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 9:32 + */ +@FeignClient(value = "bwie-system",fallbackFactory = SysUserAuthServiceFactory.class) +public interface SysUserRemoteService { + @PostMapping("user/login") + public Result login(@RequestBody String userPhone); +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/service/AuthUserService.java b/bwie-auth/src/main/java/com/bwie/auth/service/AuthUserService.java new file mode 100644 index 0000000..dbd2024 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/service/AuthUserService.java @@ -0,0 +1,15 @@ +package com.bwie.auth.service; + +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; + +public interface AuthUserService { + /** + * 登录 + * @param user + * @return + */ + Result login(User user); + + Result info(); +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/service/impl/AuthUserServiceImpl.java b/bwie-auth/src/main/java/com/bwie/auth/service/impl/AuthUserServiceImpl.java new file mode 100644 index 0000000..1bd8ac9 --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/service/impl/AuthUserServiceImpl.java @@ -0,0 +1,78 @@ +package com.bwie.auth.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.bwie.auth.feign.SysUserRemoteService; +import com.bwie.auth.service.AuthUserService; +import com.bwie.common.constants.JwtConstants; +import com.bwie.common.constants.TokenConstants; +import com.bwie.common.domain.response.JwtResponse; +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; +import com.bwie.common.utils.JwtUtils; +import com.bwie.common.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName AuthUserServiceImpl + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 9:41 + */ +@Service +public class AuthUserServiceImpl implements AuthUserService { + @Autowired + private SysUserRemoteService remoteService; + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; + @Autowired + private StringRedisTemplate redisTemplate; + @Autowired + private HttpServletRequest request; + @Override + public Result login(User user) { + if (StringUtils.isNull(user.getUserPhone())) { + return Result.error("请输入手机号"); + } + if (StringUtils.isNull(user.getUserPwd())){ + return Result.error("请输入密码"); + } + Result login = remoteService.login(user.getUserPhone()); + User data = login.getData(); + boolean matches = bCryptPasswordEncoder.matches(user.getUserPhone(),data.getUserPwd()); + if (matches) { + return Result.error("密码错误"); + } + //登录成功 生成 token + String string = UUID.randomUUID().toString(); + HashMap map = new HashMap<>(); + map.put(JwtConstants.USER_KEY, string); + String token = JwtUtils.createToken(map); + redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY + string, JSON.toJSONString(data), 15, TimeUnit.MINUTES); + JwtResponse jwtResponse = new JwtResponse(); + jwtResponse.setToken(token); + jwtResponse.setExistTime("30MIN"); + return Result.success(jwtResponse); + } + + /** + * info + * @return + */ + @Override + public Result info() { + String token = request.getHeader(TokenConstants.TOKEN); + String userKey = JwtUtils.getUserKey(token); + String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + User user = JSONObject.parseObject(s, User.class); + return Result.success(user); + } +} diff --git a/bwie-auth/src/main/java/com/bwie/auth/service/impl/SysUserAuthServiceFactory.java b/bwie-auth/src/main/java/com/bwie/auth/service/impl/SysUserAuthServiceFactory.java new file mode 100644 index 0000000..8a334ad --- /dev/null +++ b/bwie-auth/src/main/java/com/bwie/auth/service/impl/SysUserAuthServiceFactory.java @@ -0,0 +1,27 @@ +package com.bwie.auth.service.impl; + +import com.bwie.auth.feign.SysUserRemoteService; +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * @ClassName SysUserAuthServiceFactory + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:45 + */ +@Component +public class SysUserAuthServiceFactory implements FallbackFactory { + + @Override + public SysUserRemoteService create(Throwable cause) { + return new SysUserRemoteService() { + @Override + public Result login(String userPhone) { + return Result.error(cause.getMessage()); + } + }; + } +} diff --git a/bwie-auth/src/main/resources/bootstrap.yml b/bwie-auth/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..647a29a --- /dev/null +++ b/bwie-auth/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +# Tomcat +server: + port: 9004 +# Spring +spring: + rabbitmq: + host: 106.54.193.225 + port: 5672 + username: guest + password: guest + virtual-host: / + listener: + simple: + prefetch: 1 # 默认每次取出一条消息消费, 消费完成取下一条 + acknowledge-mode: manual # 设置消费端手动ack确认 + retry: + enabled: true # 是否支持重试 + publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange) + publisher-returns: true #确认消息已发送到队列(Queue) + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: bwie-auth + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 106.54.193.225:8848 + config: + # 配置中心地址 + server-addr: 106.54.193.225:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + diff --git a/bwie-common/pom.xml b/bwie-common/pom.xml new file mode 100644 index 0000000..58d8d7d --- /dev/null +++ b/bwie-common/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + + + bwie-common + + + + + 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 + + + + com.aliyun.oss + aliyun-sdk-oss + 3.12.0 + + + + + + + com.github.tobato + fastdfs-client + 1.26.5 + + + + org.springframework.boot + spring-boot-starter-amqp + + + + diff --git a/bwie-common/src/main/java/com/bwie/common/config/RedisConfig.java b/bwie-common/src/main/java/com/bwie/common/config/RedisConfig.java new file mode 100644 index 0000000..b62e4b1 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/config/RedisConfig.java @@ -0,0 +1,40 @@ +package com.bwie.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/bwie-common/src/main/java/com/bwie/common/constants/Constants.java b/bwie-common/src/main/java/com/bwie/common/constants/Constants.java new file mode 100644 index 0000000..2fdc9fe --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/constants/Constants.java @@ -0,0 +1,18 @@ +package com.bwie.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/bwie-common/src/main/java/com/bwie/common/constants/JwtConstants.java b/bwie-common/src/main/java/com/bwie/common/constants/JwtConstants.java new file mode 100644 index 0000000..03692c1 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/constants/JwtConstants.java @@ -0,0 +1,29 @@ +package com.bwie.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/bwie-common/src/main/java/com/bwie/common/constants/RabbitMQConstants.java b/bwie-common/src/main/java/com/bwie/common/constants/RabbitMQConstants.java new file mode 100644 index 0000000..1f09187 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/constants/RabbitMQConstants.java @@ -0,0 +1,5 @@ +package com.bwie.common.constants; + +public class RabbitMQConstants { + public static final String SEND_SMS_QUEUE = "send_sms_queue"; +} diff --git a/bwie-common/src/main/java/com/bwie/common/constants/TokenConstants.java b/bwie-common/src/main/java/com/bwie/common/constants/TokenConstants.java new file mode 100644 index 0000000..1871fb7 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/constants/TokenConstants.java @@ -0,0 +1,24 @@ +package com.bwie.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/bwie-common/src/main/java/com/bwie/common/domain/response/JwtResponse.java b/bwie-common/src/main/java/com/bwie/common/domain/response/JwtResponse.java new file mode 100644 index 0000000..5d888b2 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/domain/response/JwtResponse.java @@ -0,0 +1,9 @@ +package com.bwie.common.domain.response; + +import lombok.Data; + +@Data +public class JwtResponse { + private String token; + private String existTime; +} diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/Car.java b/bwie-common/src/main/java/com/bwie/common/pojo/Car.java new file mode 100644 index 0000000..826cf8e --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/Car.java @@ -0,0 +1,19 @@ +package com.bwie.common.pojo; + +import lombok.Data; + +/** + * @ClassName Car + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:55 + */ +@Data +public class Car { + private Integer carId; + private String carNumber; + private Integer typeId; + private Integer carState; + + private String typeName; +} diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/Record.java b/bwie-common/src/main/java/com/bwie/common/pojo/Record.java new file mode 100644 index 0000000..edbd322 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/Record.java @@ -0,0 +1,33 @@ +package com.bwie.common.pojo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @ClassName Record + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:55 + */ +@Data +public class Record { + private Integer recordId; + private Integer userId; + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date recordStart; + private Integer recordDuration; + private Integer recordDistance; + private Integer carId; + + private String carNumber; + private String typeName; + private String userName; + + private Integer carState; + + private String recordMoney; +} diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/Type.java b/bwie-common/src/main/java/com/bwie/common/pojo/Type.java new file mode 100644 index 0000000..d3d1f8c --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/Type.java @@ -0,0 +1,15 @@ +package com.bwie.common.pojo; + +import lombok.Data; + +/** + * @ClassName Type + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:57 + */ +@Data +public class Type { + private Integer typeId; + private String typeName; +} diff --git a/bwie-common/src/main/java/com/bwie/common/pojo/User.java b/bwie-common/src/main/java/com/bwie/common/pojo/User.java new file mode 100644 index 0000000..c39e197 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/pojo/User.java @@ -0,0 +1,18 @@ +package com.bwie.common.pojo; + +import lombok.Data; + +/** + *@ClassName User + *@Description 描述 + *@Author Chen + *@Date 2024/7/23 9:24 + */ +@Data +public class User { + private Integer userId; + private String userName; + private String userPhone; + private String userPwd; + private Integer userMoney; +} diff --git a/bwie-common/src/main/java/com/bwie/common/result/PageResult.java b/bwie-common/src/main/java/com/bwie/common/result/PageResult.java new file mode 100644 index 0000000..85ecdda --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/result/PageResult.java @@ -0,0 +1,34 @@ +package com.bwie.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/bwie-common/src/main/java/com/bwie/common/result/Result.java b/bwie-common/src/main/java/com/bwie/common/result/Result.java new file mode 100644 index 0000000..30b1e73 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/result/Result.java @@ -0,0 +1,76 @@ +package com.bwie.common.result; + +import com.bwie.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/bwie-common/src/main/java/com/bwie/common/utils/FastUtil.java b/bwie-common/src/main/java/com/bwie/common/utils/FastUtil.java new file mode 100644 index 0000000..6d92a56 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/FastUtil.java @@ -0,0 +1,50 @@ +package com.bwie.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; + + +@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/bwie-common/src/main/java/com/bwie/common/utils/GenCodeUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/GenCodeUtils.java new file mode 100644 index 0000000..2ae9ff9 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/GenCodeUtils.java @@ -0,0 +1,86 @@ +package com.bwie.common.utils; + +import java.util.Random; + +/** + * @description: 生成验证码工具类 + * @Date 2023-5-11 上午 10:09 + */ +public class GenCodeUtils { + + /** + * 数字类型 + */ + private static final String NUMBER_STR = "0123456789"; + /** + * 字母类型 + */ + private static final String LETTERS_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + /** + * 短信验证码长度 + */ + private static final Integer SMS_CODE_LENGTH = 4; + + /** + * 生成短信四位验证码 + * @return 验证码 + */ + public static String genLetterStrSms(){ + return genCode(LETTERS_STR, SMS_CODE_LENGTH); + } + + /** + * 生成短信四位验证码 + * @return 验证码 + */ + public static String genNumberCodeSms(){ + return genCode(NUMBER_STR, SMS_CODE_LENGTH); + } + + /** + * 生成验证码 + * @param codeLength 验证码长度 + * @return 验证码 + */ + public static String genLetterStr(int codeLength){ + return genCode(LETTERS_STR, codeLength); + } + + /** + * 生成验证码 + * @param codeLength 验证码长度 + * @return 验证码 + */ + public static String genNumberCode( int codeLength){ + return genCode(NUMBER_STR, codeLength); + } + + /** + * 生成验证码 + * @param str 验证码字符串 + * @param codeLength 验证码长度 + * @return 验证码 + */ + public static String genCode (String str, int codeLength){ + //将字符串转换为一个新的字符数组。 + char[] verificationCodeArray = str.toCharArray(); + Random random = new Random(); + //计数器 + int count = 0; + StringBuilder stringBuilder = new StringBuilder(); + do { + //随机生成一个随机数 + int index = random.nextInt(verificationCodeArray.length); + char c = verificationCodeArray[index]; + //限制四位不重复数字 + if (stringBuilder.indexOf(String.valueOf(c)) == -1) { + stringBuilder.append(c); + //计数器加1 + count++; + } + //当count等于4时结束,随机生成四位数的验证码 + } while (count != codeLength); + return stringBuilder.toString(); + } +} diff --git a/bwie-common/src/main/java/com/bwie/common/utils/JwtUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/JwtUtils.java new file mode 100644 index 0000000..75f3c7b --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/JwtUtils.java @@ -0,0 +1,115 @@ +package com.bwie.common.utils; + +import com.bwie.common.constants.JwtConstants; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import java.util.Map; + +/** + * @description: Jwt工具类 + */ +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/bwie-common/src/main/java/com/bwie/common/utils/OssUtil.java b/bwie-common/src/main/java/com/bwie/common/utils/OssUtil.java new file mode 100644 index 0000000..3c4de92 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/OssUtil.java @@ -0,0 +1,154 @@ +package com.bwie.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 { + + /**# LTAI5t6ytyyHWWB693bMEo53 + # CSubcq72LLVttBlo2XO1JEMEmw894z + * Endpoint 存储对象概述 阿里云主账号AccessKey,accessKeySecret拥有所有API的访问权限 访问路径前缀 存储对象概述 + */ + private static String endPoint = "oss-cn-shanghai.aliyuncs.com"; + private static String accessKeyId = "LTAI5t6ytyyHWWB693bMEo53"; + private static String accessKeySecret = "CSubcq72LLVttBlo2XO1JEMEmw894z"; + private static String accessPre = "https://oss-tai.oss-cn-shanghai.aliyuncs.com/"; + + /** + * bucket名称 + * @return + */ + private static String bucketName = "oss-tai"; + + 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/bwie-common/src/main/java/com/bwie/common/utils/StringUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/StringUtils.java new file mode 100644 index 0000000..7cf6a15 --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/StringUtils.java @@ -0,0 +1,67 @@ +package com.bwie.common.utils; + +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.List; + +/** + * @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/bwie-common/src/main/java/com/bwie/common/utils/TelSmsUtils.java b/bwie-common/src/main/java/com/bwie/common/utils/TelSmsUtils.java new file mode 100644 index 0000000..12053bd --- /dev/null +++ b/bwie-common/src/main/java/com/bwie/common/utils/TelSmsUtils.java @@ -0,0 +1,92 @@ +package com.bwie.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 = "LTAI5tHU282xbcCSKZJSuKyH"; + + private static String accessKeySecret = "mX4tPoqoI55x3ACK1Z7IFiuAMVxuQr"; + + /** + * 短信访问域名 + */ + private static String endpoint = "dysmsapi.aliyuncs.com"; + /** + * 短信签名 + */ + private static String signName = "乐优购"; + + private static String templateCode = "SMS_163851467"; + + /** + * 实例化短信对象 + */ + 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/bwie-gateway/pom.xml b/bwie-gateway/pom.xml new file mode 100644 index 0000000..430deab --- /dev/null +++ b/bwie-gateway/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + + + bwie-gateway + + + + + + com.bwie + bwie-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/bwie-gateway/src/main/java/com/bwie/gateway/GatewayApplication.java b/bwie-gateway/src/main/java/com/bwie/gateway/GatewayApplication.java new file mode 100644 index 0000000..614166b --- /dev/null +++ b/bwie-gateway/src/main/java/com/bwie/gateway/GatewayApplication.java @@ -0,0 +1,17 @@ +package com.bwie.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @ClassName GatewayApplication + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:36 + */ +@SpringBootApplication +public class GatewayApplication { + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class); + } +} diff --git a/bwie-gateway/src/main/java/com/bwie/gateway/config/IgnoreWhiteConfig.java b/bwie-gateway/src/main/java/com/bwie/gateway/config/IgnoreWhiteConfig.java new file mode 100644 index 0000000..eea0d7c --- /dev/null +++ b/bwie-gateway/src/main/java/com/bwie/gateway/config/IgnoreWhiteConfig.java @@ -0,0 +1,29 @@ +package com.bwie.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; + + +@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/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java b/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java new file mode 100644 index 0000000..5d20530 --- /dev/null +++ b/bwie-gateway/src/main/java/com/bwie/gateway/filters/AuthFilter.java @@ -0,0 +1,57 @@ +package com.bwie.gateway.filters; + +import com.bwie.gateway.config.IgnoreWhiteConfig; +import com.bwie.common.constants.TokenConstants; +import com.bwie.common.result.Result; +import com.bwie.gateway.utils.GatewayUtils; +import com.bwie.common.utils.JwtUtils; +import com.bwie.common.utils.StringUtils; +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.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +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; +import java.util.concurrent.TimeUnit; + +@Component +public class AuthFilter implements GlobalFilter, Ordered { + @Autowired + private IgnoreWhiteConfig ignoreWhiteConfig; + @Autowired + private StringRedisTemplate redisTemplate; + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + List whites = ignoreWhiteConfig.getWhites(); + ServerHttpRequest request = exchange.getRequest(); + String path = request.getURI().getPath(); + if(StringUtils.matches(path,whites)){ + return chain.filter(exchange); + } + String token = request.getHeaders().getFirst(TokenConstants.TOKEN); + try{ + JwtUtils.parseToken(token); + }catch (Exception exception){ + + return GatewayUtils.errorResponse(exchange,"token不合法"); + } + String userKey=JwtUtils.getUserKey(token); + if(!redisTemplate.hasKey(TokenConstants.LOGIN_TOKEN_KEY+userKey)){ + return GatewayUtils.errorResponse(exchange,"token过期"); + }else { + redisTemplate.expire(TokenConstants.LOGIN_TOKEN_KEY,30, TimeUnit.MINUTES); + } + return chain.filter(exchange); + } + + @Override + public int getOrder() { + return 0; + } +} diff --git a/bwie-gateway/src/main/java/com/bwie/gateway/utils/GatewayUtils.java b/bwie-gateway/src/main/java/com/bwie/gateway/utils/GatewayUtils.java new file mode 100644 index 0000000..cf24c5e --- /dev/null +++ b/bwie-gateway/src/main/java/com/bwie/gateway/utils/GatewayUtils.java @@ -0,0 +1,95 @@ +package com.bwie.gateway.utils; + +import com.alibaba.fastjson.JSONObject; +import com.bwie.common.result.Result; +import com.bwie.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; + + +@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/bwie-gateway/src/main/resources/bootstrap.yml b/bwie-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..452d98d --- /dev/null +++ b/bwie-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 18080 +# Spring +spring: + application: + # 应用名称 + name: bwie-gateway + profiles: + # 环境配置 + active: dev + main: + # 允许使用循环引用 + allow-circular-references: true + # 允许定义相同的bean对象 去覆盖原有的 + allow-bean-definition-overriding: true + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 106.54.193.225:8848 + config: + # 配置中心地址 + server-addr: 106.54.193.225:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/bwie-module/bwie-list/pom.xml b/bwie-module/bwie-list/pom.xml new file mode 100644 index 0000000..bab97bb --- /dev/null +++ b/bwie-module/bwie-list/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + ../../pom.xml + + + bwie-list + + + + + com.bwie + bwie-common + 1.0-SNAPSHOT + + + + com.alibaba + druid-spring-boot-starter + 1.2.8 + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + mysql + mysql-connector-java + + + + org.springframework.boot + spring-boot-starter-web + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.1 + + + + diff --git a/bwie-module/bwie-list/src/main/java/com/bwie/list/CarApplication.java b/bwie-module/bwie-list/src/main/java/com/bwie/list/CarApplication.java new file mode 100644 index 0000000..b291d0c --- /dev/null +++ b/bwie-module/bwie-list/src/main/java/com/bwie/list/CarApplication.java @@ -0,0 +1,17 @@ +package com.bwie.list; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @ClassName CarApplication + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 11:01 + */ +@SpringBootApplication +public class CarApplication { + public static void main(String[] args) { + SpringApplication.run(CarApplication.class); + } +} diff --git a/bwie-module/bwie-list/src/main/java/com/bwie/list/controller/CarController.java b/bwie-module/bwie-list/src/main/java/com/bwie/list/controller/CarController.java new file mode 100644 index 0000000..660916f --- /dev/null +++ b/bwie-module/bwie-list/src/main/java/com/bwie/list/controller/CarController.java @@ -0,0 +1,71 @@ +package com.bwie.list.controller; + +import com.bwie.common.pojo.Car; +import com.bwie.common.pojo.Record; +import com.bwie.common.pojo.Type; +import com.bwie.common.result.Result; +import com.bwie.list.service.CarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * @ClassName CarControlelr + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:58 + */ +@RestController +@RequestMapping("/car") +public class CarController { + @Autowired + private CarService carService; + + /** + * 自行车列表 + * + * @param car + * @return + */ + @PostMapping("/list") + public Result> list(@RequestBody Car car) { + List list = carService.list(car); + return Result.success(list); + } + + /** + * 类型下拉框 + */ + @GetMapping("/typeList") + public Result> typeList() { + List list = carService.typeList(); + return Result.success(list); + } + + /** + * 添加用车记录 + */ + @PostMapping("/recordAdd/{carId}") + public Result recordAdd(@PathVariable Integer carId) { + Integer add = carService.recordAdd(carId); + return Result.success(add); + } + + /** + * 记录自行车列表 + */ + @PostMapping("/recordList") + public Result> recordList(@RequestBody Record record) { + List list = carService.recordList(record); + return Result.success(list); + } + /** + * 结束行程 + */ + @PostMapping("/updateByReId/{carNumber}") + public Result updateByReId(@PathVariable String carNumber){ + Integer upd = carService.updateByReId(carNumber); + return Result.success(upd); + } +} diff --git a/bwie-module/bwie-list/src/main/java/com/bwie/list/mapper/CarMapper.java b/bwie-module/bwie-list/src/main/java/com/bwie/list/mapper/CarMapper.java new file mode 100644 index 0000000..1b9f207 --- /dev/null +++ b/bwie-module/bwie-list/src/main/java/com/bwie/list/mapper/CarMapper.java @@ -0,0 +1,71 @@ +package com.bwie.list.mapper; + +import com.bwie.common.pojo.Car; +import com.bwie.common.pojo.Record; +import com.bwie.common.pojo.Type; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface CarMapper { + /** + * 自行车列表 + * @param car + * @return + */ + List list(Car car); + + /** + * 类型列表 + * @return + */ + List typeList(); + +// /** +// * 查询carId数据 +// * @param carId +// * @return +// */ +// Car selectByCarId(Integer carId); + + /** + * 添加自行车记录 + * @param record1 + * @return + */ + Integer recordAdd(Record record1); + + /** + * 修改状态 + * @param carId + */ + void updateById(Integer carId); + + /** + * 自行车列表 + * @param record + * @return + */ + List recordList(Record record); + + /** + * 结束行程 + * @param carNumber + * @return + */ + Integer updateByReId(String carNumber); + + + + Record select(String carNumber); + + void updateMoney(@Param("userId") Integer userId, @Param("recordMoney") String recordMoney); + + Record selectOne(String carNumber); + + Record selectTwo(String carNumber); + + Record selectThree(String carNumber); +} diff --git a/bwie-module/bwie-list/src/main/java/com/bwie/list/service/CarService.java b/bwie-module/bwie-list/src/main/java/com/bwie/list/service/CarService.java new file mode 100644 index 0000000..87ad214 --- /dev/null +++ b/bwie-module/bwie-list/src/main/java/com/bwie/list/service/CarService.java @@ -0,0 +1,43 @@ +package com.bwie.list.service; + +import com.bwie.common.pojo.Car; +import com.bwie.common.pojo.Record; +import com.bwie.common.pojo.Type; + +import java.util.List; + +public interface CarService { + /** + * 自行车列表 + * @param car + * @return + */ + List list(Car car); + + /** + * 类型下拉框 + * @return + */ + List typeList(); + + /** + * 添加用车记录 + * @param carId + * @return + */ + Integer recordAdd(Integer carId); + + /** + * 自行车列表 + * @param record + * @return + */ + List recordList(Record record); + + /** + * 结束行程 + * @param carNumber + * @return + */ + Integer updateByReId(String carNumber); +} diff --git a/bwie-module/bwie-list/src/main/java/com/bwie/list/service/impl/CarServiceImpl.java b/bwie-module/bwie-list/src/main/java/com/bwie/list/service/impl/CarServiceImpl.java new file mode 100644 index 0000000..b5274f9 --- /dev/null +++ b/bwie-module/bwie-list/src/main/java/com/bwie/list/service/impl/CarServiceImpl.java @@ -0,0 +1,114 @@ +package com.bwie.list.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.bwie.common.constants.TokenConstants; +import com.bwie.common.pojo.Car; +import com.bwie.common.pojo.Record; +import com.bwie.common.pojo.Type; +import com.bwie.common.pojo.User; +import com.bwie.common.utils.JwtUtils; +import com.bwie.list.mapper.CarMapper; +import com.bwie.list.service.CarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * @ClassName CarServiceImpl + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:58 + */ +@Service +public class CarServiceImpl implements CarService { + @Autowired + private CarMapper carMapper; + @Autowired + private HttpServletRequest request; + @Autowired + private StringRedisTemplate redisTemplate; + + /** + * 自行车列表 + * + * @param car + * @return + */ + @Override + public List list(Car car) { + return carMapper.list(car); + } + + /** + * 类型列表 + * + * @return + */ + @Override + public List typeList() { + return carMapper.typeList(); + } + + /** + * 添加用车记录 + * + * @param carId + * @return + */ + @Override + public Integer recordAdd(Integer carId) { +// //用carId获取这条数据 +// Car car = carMapper.selectByCarId(carId); + //修改状态 + carMapper.updateById(carId); + //添加自行车记录 + Record record1 = new Record(); + String token = request.getHeader(TokenConstants.TOKEN); + String userKey = JwtUtils.getUserKey(token); + String s = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey); + User user = JSONObject.parseObject(s, User.class); + record1.setUserId(user.getUserId()); + record1.setCarId(carId); + Integer add = carMapper.recordAdd(record1); + return add; + } + + @Override + public List recordList(Record record) { + return carMapper.recordList(record); + } + + /** + * 结束行程 + * + * @param carNumber + * @return + */ + @Override + public Integer updateByReId(String carNumber) { + Integer upd = carMapper.updateByReId(carNumber); + //扣费 + if (upd > 0) { + //通过编号查 + Record record = carMapper.select(carNumber); + if (record.getTypeName().equals("入门山地车")) { +// Record recordOne = carMapper.select(carNumber); + carMapper.updateMoney(record.getUserId(), record.getRecordMoney()); + } else if (record.getTypeName().equals("入门公路车")) { + Record recordOne = carMapper.selectOne(carNumber); + carMapper.updateMoney(recordOne.getUserId(), recordOne.getRecordMoney()); + } else if (record.getTypeName().equals("专业山地车")) { + Record recordTwo = carMapper.selectTwo(carNumber); + carMapper.updateMoney(recordTwo.getUserId(), recordTwo.getRecordMoney()); + } else { + Record recordThree = carMapper.selectThree(carNumber); + carMapper.updateMoney(recordThree.getUserId(), recordThree.getRecordMoney()); + } + } + return upd; + } + +} diff --git a/bwie-module/bwie-list/src/main/resources/bootstrap.yml b/bwie-module/bwie-list/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..3484ca5 --- /dev/null +++ b/bwie-module/bwie-list/src/main/resources/bootstrap.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9002 +# Spring +spring: + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: bwie-list + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 106.54.193.225:8848 + config: + # 配置中心地址 + server-addr: 106.54.193.225:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/bwie-module/bwie-list/src/main/resources/mapper/UserMapper.xml b/bwie-module/bwie-list/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..9ad6792 --- /dev/null +++ b/bwie-module/bwie-list/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,125 @@ + + + + + INSERT INTO `week601`.`t_record` (`user_id`, `record_start`, `record_duration`, `record_distance`, + `car_id`) + VALUES (#{userId}, now(), null, null, #{carId}); + + + update t_car + set car_state = 1 + where car_id = #{carId} + + + update t_car + set car_state = 0 + where car_number = #{carNumber} + + + update t_user set user_money = user_money-#{recordMoney} where user_id = #{userId} + + + + + + + + + + + + + + + + diff --git a/bwie-module/bwie-system/pom.xml b/bwie-module/bwie-system/pom.xml new file mode 100644 index 0000000..ed9344b --- /dev/null +++ b/bwie-module/bwie-system/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + ../../pom.xml + + + bwie-system + + + + + com.bwie + bwie-common + 1.0-SNAPSHOT + + + + com.alibaba + druid-spring-boot-starter + 1.2.8 + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + mysql + mysql-connector-java + + + + org.springframework.boot + spring-boot-starter-web + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.1 + + + + diff --git a/bwie-module/bwie-system/src/main/java/com/bwie/user/SysUserApplication.java b/bwie-module/bwie-system/src/main/java/com/bwie/user/SysUserApplication.java new file mode 100644 index 0000000..e6e9dee --- /dev/null +++ b/bwie-module/bwie-system/src/main/java/com/bwie/user/SysUserApplication.java @@ -0,0 +1,17 @@ +package com.bwie.user; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @ClassName SysUserApplication + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 10:01 + */ +@SpringBootApplication +public class SysUserApplication { + public static void main(String[] args) { + SpringApplication.run(SysUserApplication.class); + } +} diff --git a/bwie-module/bwie-system/src/main/java/com/bwie/user/controller/SysUserController.java b/bwie-module/bwie-system/src/main/java/com/bwie/user/controller/SysUserController.java new file mode 100644 index 0000000..fbf2aa8 --- /dev/null +++ b/bwie-module/bwie-system/src/main/java/com/bwie/user/controller/SysUserController.java @@ -0,0 +1,35 @@ +package com.bwie.user.controller; + +import com.bwie.common.pojo.User; +import com.bwie.common.result.Result; +import com.bwie.user.service.SysUserService; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName SysUserController + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 9:19 + */ +@RestController +@RequestMapping("/user") +public class SysUserController { + @Autowired + private SysUserService userService; + + /** + * 手机号登录 + * @param userPhone + * @return + */ + @PostMapping("/login") + public Result login(@RequestBody String userPhone){ + User login = userService.login(userPhone); + return Result.success(login); + } + +} diff --git a/bwie-module/bwie-system/src/main/java/com/bwie/user/mapper/SysUserMapper.java b/bwie-module/bwie-system/src/main/java/com/bwie/user/mapper/SysUserMapper.java new file mode 100644 index 0000000..0bc5914 --- /dev/null +++ b/bwie-module/bwie-system/src/main/java/com/bwie/user/mapper/SysUserMapper.java @@ -0,0 +1,9 @@ +package com.bwie.user.mapper; + +import com.bwie.common.pojo.User; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SysUserMapper { + User login(String userPhone); +} diff --git a/bwie-module/bwie-system/src/main/java/com/bwie/user/service/SysUserService.java b/bwie-module/bwie-system/src/main/java/com/bwie/user/service/SysUserService.java new file mode 100644 index 0000000..5bd8fcc --- /dev/null +++ b/bwie-module/bwie-system/src/main/java/com/bwie/user/service/SysUserService.java @@ -0,0 +1,12 @@ +package com.bwie.user.service; + +import com.bwie.common.pojo.User; + +public interface SysUserService { + /** + * 手机号登录 + * @param userPhone + * @return + */ + User login(String userPhone); +} diff --git a/bwie-module/bwie-system/src/main/java/com/bwie/user/service/impl/SysUserServiceImpl.java b/bwie-module/bwie-system/src/main/java/com/bwie/user/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..d6f9ac0 --- /dev/null +++ b/bwie-module/bwie-system/src/main/java/com/bwie/user/service/impl/SysUserServiceImpl.java @@ -0,0 +1,23 @@ +package com.bwie.user.service.impl; + +import com.bwie.common.pojo.User; +import com.bwie.user.mapper.SysUserMapper; +import com.bwie.user.service.SysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName SysUserServiceImpl + * @Description 描述 + * @Author Chen + * @Date 2024/7/23 9:19 + */ +@Service +public class SysUserServiceImpl implements SysUserService { + @Autowired + private SysUserMapper userMapper; + @Override + public User login(String userPhone) { + return userMapper.login(userPhone); + } +} diff --git a/bwie-module/bwie-system/src/main/resources/bootstrap.yml b/bwie-module/bwie-system/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..f446f7f --- /dev/null +++ b/bwie-module/bwie-system/src/main/resources/bootstrap.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9001 +# Spring +spring: + main: + allow-circular-references: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + application: + # 应用名称 + name: bwie-system + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 106.54.193.225:8848 + config: + # 配置中心地址 + server-addr: 106.54.193.225:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/bwie-module/bwie-system/src/main/resources/mapper/UserMapper.xml b/bwie-module/bwie-system/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..d01e1d8 --- /dev/null +++ b/bwie-module/bwie-system/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/bwie-module/pom.xml b/bwie-module/pom.xml new file mode 100644 index 0000000..6ea2c29 --- /dev/null +++ b/bwie-module/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + + + bwie-module + + + 8 + 8 + UTF-8 + + + diff --git a/bwie-module/src/main/java/com/bw/Main.java b/bwie-module/src/main/java/com/bw/Main.java new file mode 100644 index 0000000..e856949 --- /dev/null +++ b/bwie-module/src/main/java/com/bw/Main.java @@ -0,0 +1,7 @@ +package com.bw; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/img.png b/img.png new file mode 100644 index 0000000000000000000000000000000000000000..eac747ff63202b72f3826f0b6960734a6721bc67 GIT binary patch literal 42119 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

`Q!mZNVw9JxBENjWMv5^Z_m-f! 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 z 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Ê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 + + 4.0.0 + + com.bwie + week601 + 1.0-SNAPSHOT + pom + + bwie-auth + bwie-module + bwie-gateway + bwie-common + bwie-module/bwie-system + bwie-module/bwie-list + + + + + + 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.bwie + bwie-common + 1.0-SNAPSHOT + + + + + + diff --git a/src/main/java/com/bw/Main.java b/src/main/java/com/bw/Main.java new file mode 100644 index 0000000..e856949 --- /dev/null +++ b/src/main/java/com/bw/Main.java @@ -0,0 +1,7 @@ +package com.bw; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/屏幕截图 2024-07-23 211712.png b/屏幕截图 2024-07-23 211712.png new file mode 100644 index 0000000000000000000000000000000000000000..35fe536e184e723e5ee1314dd2e9f9561d734329 GIT binary patch literal 58337 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