第一版

master
YangNan 2023-12-13 08:57:15 +08:00
commit 8cb5617cd0
162 changed files with 5025 additions and 0 deletions

8
.idea/.gitignore vendored 100644
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

32
.idea/compiler.xml 100644
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="bwie-login" />
<module name="bwie-user" />
<module name="bwie-service" />
<module name="bwie-floor" />
<module name="bwie-gateway" />
<module name="bwie-auth" />
<module name="bwie-common" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="bwie-auth" options="-parameters" />
<module name="bwie-common" options="-parameters" />
<module name="bwie-floor" options="-parameters" />
<module name="bwie-gateway" options="-parameters" />
<module name="bwie-login" options="-parameters" />
<module name="bwie-module" options="-parameters" />
<module name="bwie-service" options="-parameters" />
<module name="bwie-user" options="-parameters" />
</option>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/bwie-auth/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-gateway/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-module/bwie-floor/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-module/bwie-login/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-module/bwie-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bwie-module/bwie-user/src/main/java" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,36 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

19
.idea/misc.xml 100644
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
<option name="ignoredFiles">
<set>
<option value="$PROJECT_DIR$/bwie-login/pom.xml" />
</set>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml 100644
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

46
bwie-auth/pom.xml 100644
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bwie-tenement</artifactId>
<groupId>com.bwie</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bwie-auth</artifactId>
<dependencies>
<!-- 项目公共 依赖 -->
<dependency>
<groupId>com.bwie</groupId>
<artifactId>bwie-common</artifactId>
</dependency>
<!-- SpringBoot Web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package com.bwie.auth;
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);
}
}

View File

@ -0,0 +1,53 @@
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;
/**
* RabbitAdminRabbitMQJavaRabbitMQRabbitMQ
*/
@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;
/**
* RabbitMQ
* @return
*/
@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;
}
}

View File

@ -0,0 +1,62 @@
package com.bwie.auth.controller;
import com.alibaba.fastjson.JSON;
import com.bwie.auth.service.AuhService;
import com.bwie.common.domain.Login;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.UserRequest;
import com.bwie.common.result.Result;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/auth")
@Log4j2
public class AuthController {
@Autowired
private AuhService auhService;
@Autowired
private HttpServletRequest request;
@PostMapping("/getCode/{phone}")
public Result getCode(@PathVariable String phone) {
log.info("功能描述: 发送验证码,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), phone);
Result result= auhService.getCode(phone);
log.info("功能描述: 发送验证码,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
@PostMapping("/login")
public Result login(@RequestBody UserRequest user) {
log.info("功能描述: 登录,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), user);
Result result = auhService.login(user);
log.info("功能描述: 登录 ,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
}

View File

@ -0,0 +1,14 @@
package com.bwie.auth.feign;
import com.bwie.common.domain.Login;
import com.bwie.common.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient("bwie-login")
public interface LoginFeignService {
@PostMapping("/login/findByLogin/{loginName}")
public Result<Login> findByLogin(@PathVariable String loginName);
}

View File

@ -0,0 +1,15 @@
package com.bwie.auth.feign;
import com.bwie.common.domain.User;
import com.bwie.common.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient("bwie-user")
public interface UserFeignService {
@PostMapping("/user/findByPhone/{phone}")
public Result<User> findByPhone(@PathVariable String phone);
}

View File

@ -0,0 +1,12 @@
package com.bwie.auth.service;
import com.bwie.common.domain.Login;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.UserRequest;
import com.bwie.common.result.Result;
public interface AuhService {
Result login(UserRequest user);
Result getCode(String phone);
}

View File

@ -0,0 +1,86 @@
package com.bwie.auth.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.bwie.auth.feign.UserFeignService;
import com.bwie.auth.service.AuhService;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.UserRequest;
import com.bwie.common.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@Service
public class AuhServiceImpl implements AuhService {
@Autowired
private UserFeignService userFeignService;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Override
public Result login(UserRequest user) {
Result<User> byPhone = userFeignService.findByPhone(user.getPhone());
User login = byPhone.getData();
if(null==login){
return Result.error("登录失败");
}
if (!redisTemplate.hasKey(user.getPhone())){
return Result.error("验证码已过期");
}
String code = redisTemplate.opsForValue().get(user.getPhone());
if (!code.equals(user.getCode())){
return Result.error("验证码有误");
}
redisTemplate.opsForValue().set("login", JSONObject.toJSONString(login));
return Result.success("登录成功");
}
@Override
public Result getCode(String phone) {
Result<User> byPhone = userFeignService.findByPhone(phone);
User user = byPhone.getData();
if (null==user){
return Result.error("手机号不存在");
}
String code="";
for (int i = 0; i < 4; i++) {
code+=new Random().nextInt(10);
}
redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
return Result.success(code,"发送成功");
}
}

View File

@ -0,0 +1,77 @@
package com.bwie.auth.utils;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Component
public class DLXQueue {
// routingKey
private static final String DEAD_ROUTING_KEY = "dead.routingkey";
private static final String ROUTING_KEY = "routingkey";
private static final String DEAD_EXCHANGE = "dead.exchange";
private static final String EXCHANGE = "common.exchange";
@Autowired
RabbitTemplate rabbitTemplate;
@Resource
RabbitAdmin rabbitAdmin;
/**
*
*
* @param queueName
* @param deadQueueName
* @param params
* @param expiration
*/
public void sendDLXQueue(String queueName, String deadQueueName, Object params, Integer expiration) {
/**
* ----------------------------------ttl--------------------------------------------
*/
Map<String, Object> map = new HashMap<>();
// 队列设置存活时间单位ms, 必须是整形数据。
map.put("x-message-ttl", expiration);
// 设置死信交换机
map.put("x-dead-letter-exchange", DEAD_EXCHANGE);
// 设置死信交换器路由
map.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY);
/*参数1队列名称 参数2持久化 参数3是否排他 参数4自动删除队列 参数5队列参数*/
Queue queue = new Queue(queueName, true, false, false, map);
rabbitAdmin.declareQueue(queue);
/**
* ------------------------------------------------------------------------------
*/
DirectExchange directExchange = new DirectExchange(EXCHANGE, true, false);
rabbitAdmin.declareExchange(directExchange);
/**
* ------------------------------------------------------------------------------
*/
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(ROUTING_KEY);
rabbitAdmin.declareBinding(binding);
/**
* ------------------------------------------------------------------------------
*/
DirectExchange deadExchange = new DirectExchange(DEAD_EXCHANGE, true, false);
rabbitAdmin.declareExchange(deadExchange);
Queue deadQueue = new Queue(deadQueueName, true, false, false);
rabbitAdmin.declareQueue(deadQueue);
/**
* ------------------------------------------------------------------------------
*/
// 将队列和交换机绑定
Binding deadbinding = BindingBuilder.bind(deadQueue).to(deadExchange).with(DEAD_ROUTING_KEY);
rabbitAdmin.declareBinding(deadbinding);
// 发送消息
rabbitTemplate.convertAndSend(EXCHANGE, ROUTING_KEY, params);
}
}

View File

@ -0,0 +1,79 @@
package com.bwie.auth.utils;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
*
*/
@Component
public class DelayedQueue {
// routingKey
private static final String DELAYED_ROUTING_KEY = "delayed.routingkey";
// 延迟队列交换机
private static final String DELAYED_EXCHANGE = "delayed.exchange";
@Autowired
RabbitTemplate rabbitTemplate;
@Resource
RabbitAdmin rabbitAdmin;
/**
*
*
* @param queueName
* @param params
* @param expiration
*/
public void sendDelayedQueue(String queueName, Object params, Integer expiration) {
// 先创建一个队列
Queue queue = new Queue(queueName);
rabbitAdmin.declareQueue(queue);
// 创建延迟队列交换机
CustomExchange customExchange = createCustomExchange();
rabbitAdmin.declareExchange(customExchange);
// 将队列和交换机绑定
Binding binding = BindingBuilder.bind(queue).to(customExchange).with(DELAYED_ROUTING_KEY).noargs();
rabbitAdmin.declareBinding(binding);
// 发送延迟消息
rabbitTemplate.convertAndSend(DELAYED_EXCHANGE, DELAYED_ROUTING_KEY, params, msg -> {
// 发送消息的时候 延迟时长
msg.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
msg.getMessageProperties().setDelay(expiration);
return msg;
});
}
private CustomExchange createCustomExchange() {
Map<String, Object> arguments = new HashMap<>();
/**
*
* 1.
* 2.
* 3.
* 4.
* 5.
*/
arguments.put("x-delayed-type", "direct");
return new CustomExchange(DELAYED_EXCHANGE, "x-delayed-message", true, false, arguments);
}
}

View File

@ -0,0 +1,66 @@
package com.bwie.auth.utils;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* TTL
*
*/
@Component
public class TtlQueue {
// routingKey
private static final String TTL_KEY = "ttl.routingkey";
private static final String TTL_EXCHANGE = "ttl.exchange";
@Autowired
RabbitTemplate rabbitTemplate;
@Resource
RabbitAdmin rabbitAdmin;
/**
* TTL
*
* @param queueName
* @param params
* @param expiration
*/
public void sendTtlQueue(String queueName, Object params, Integer expiration) {
/**
* ----------------------------------ttl--------------------------------------------
*/
Map<String, Object> map = new HashMap<>();
// 队列设置存活时间单位ms,必须是整形数据。
map.put("x-message-ttl", expiration);
/*参数1队列名称 参数2持久化 参数3是否排他 参数4自动删除队列 参数5队列参数*/
Queue queue = new Queue(queueName, true, false, false, map);
rabbitAdmin.declareQueue(queue);
/**
* ------------------------------------------------------------------------------
*/
DirectExchange directExchange = new DirectExchange(TTL_EXCHANGE, true, false);
rabbitAdmin.declareExchange(directExchange);
/**
* ------------------------------------------------------------------------------
*/
// 将队列和交换机绑定
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(TTL_KEY);
rabbitAdmin.declareBinding(binding);
// 发送消息
rabbitTemplate.convertAndSend(TTL_EXCHANGE, TTL_KEY, params);
}
}

View File

@ -0,0 +1,112 @@
# 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-auth
kafka:
producer:
# Kafka服务器
bootstrap-servers: 124.221.114.13:9092
# 开启事务,必须在开启了事务的方法中发送,否则报错
transaction-id-prefix: kafkaTx-
# 发生错误后消息重发的次数开启事务必须设置大于0。
retries: 3
# acks=0 生产者在成功写入消息之前不会等待任何来自服务器的响应。
# acks=1 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
# acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
# 开启事务时必须设置为all
acks: all
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
batch-size: 16384
# 生产者内存缓冲区的大小。
buffer-memory: 1024000
# 键的序列化方式
key-serializer: org.springframework.kafka.support.serializer.JsonSerializer
# 值的序列化方式建议使用Json这种序列化方式可以无需额外配置传输实体类
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
consumer:
# Kafka服务器
bootstrap-servers: 124.221.114.13:9092
group-id: firstGroup
# 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式如1S,1M,2H,5D
#auto-commit-interval: 2s
# 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
# earliest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时从头开始消费分区的记录
# latest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时消费新产生的该分区下的数据在消费者启动之后生成的记录
# none当各分区都存在已提交的offset时从提交的offset开始消费只要有一个分区不存在已提交的offset则抛出异常
auto-offset-reset: latest
# 是否自动提交偏移量默认值是true为了避免出现重复数据和数据丢失可以把它设置为false然后手动提交偏移量
enable-auto-commit: false
# 键的反序列化方式
#key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
key-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
# 值的反序列化方式建议使用Json这种序列化方式可以无需额外配置传输实体类
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
# 配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
properties:
spring:
json:
trusted:
packages: "*"
# 这个参数定义了poll方法最多可以拉取多少条消息默认值为500。如果在拉取消息的时候新消息不足500条那有多少返回多少如果超过500条每次只返回500。
# 这个默认值在有些场景下太大有些场景很难保证能够在5min内处理完500条消息
# 如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
# 然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
# 要避免出现上述问题提前评估好处理一条消息最长需要多少时间然后覆盖默认的max.poll.records参数
# 注需要开启BatchListener批量监听才会生效如果不开启BatchListener则不会出现reBalance情况
max-poll-records: 3
properties:
# 两次poll之间的最大间隔默认值为5分钟。如果超过这个间隔会触发reBalance
max:
poll:
interval:
ms: 600000
# 当broker多久没有收到consumer的心跳请求后就触发reBalance默认值是10s
session:
timeout:
ms: 10000
listener:
# 在侦听器容器中运行的线程数,一般设置为 机器数*分区数
concurrency: 4
# 自动提交关闭,需要设置手动消息确认
ack-mode: manual_immediate
# 消费监听接口监听的主题不存在时默认会报错所以设置为false忽略错误
missing-topics-fatal: false
# 两次poll之间的最大间隔默认值为5分钟。如果超过这个间隔会触发reBalance
poll-timeout: 600000
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 124.221.114.13:8848
config:
# 配置中心地址
server-addr: 124.221.114.13:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
rabbitmq:
username: root
password: zzh123
virtualHost: /
port: 5672
host: 124.221.114.13
listener:
simple:
prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
publisher-returns: true #确认消息已发送到队列(Queue)

View File

@ -0,0 +1,112 @@
# 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-auth
kafka:
producer:
# Kafka服务器
bootstrap-servers: 124.221.114.13:9092
# 开启事务,必须在开启了事务的方法中发送,否则报错
transaction-id-prefix: kafkaTx-
# 发生错误后消息重发的次数开启事务必须设置大于0。
retries: 3
# acks=0 生产者在成功写入消息之前不会等待任何来自服务器的响应。
# acks=1 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
# acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
# 开启事务时必须设置为all
acks: all
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
batch-size: 16384
# 生产者内存缓冲区的大小。
buffer-memory: 1024000
# 键的序列化方式
key-serializer: org.springframework.kafka.support.serializer.JsonSerializer
# 值的序列化方式建议使用Json这种序列化方式可以无需额外配置传输实体类
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
consumer:
# Kafka服务器
bootstrap-servers: 124.221.114.13:9092
group-id: firstGroup
# 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式如1S,1M,2H,5D
#auto-commit-interval: 2s
# 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
# earliest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时从头开始消费分区的记录
# latest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时消费新产生的该分区下的数据在消费者启动之后生成的记录
# none当各分区都存在已提交的offset时从提交的offset开始消费只要有一个分区不存在已提交的offset则抛出异常
auto-offset-reset: latest
# 是否自动提交偏移量默认值是true为了避免出现重复数据和数据丢失可以把它设置为false然后手动提交偏移量
enable-auto-commit: false
# 键的反序列化方式
#key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
key-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
# 值的反序列化方式建议使用Json这种序列化方式可以无需额外配置传输实体类
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
# 配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
properties:
spring:
json:
trusted:
packages: "*"
# 这个参数定义了poll方法最多可以拉取多少条消息默认值为500。如果在拉取消息的时候新消息不足500条那有多少返回多少如果超过500条每次只返回500。
# 这个默认值在有些场景下太大有些场景很难保证能够在5min内处理完500条消息
# 如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
# 然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
# 要避免出现上述问题提前评估好处理一条消息最长需要多少时间然后覆盖默认的max.poll.records参数
# 注需要开启BatchListener批量监听才会生效如果不开启BatchListener则不会出现reBalance情况
max-poll-records: 3
properties:
# 两次poll之间的最大间隔默认值为5分钟。如果超过这个间隔会触发reBalance
max:
poll:
interval:
ms: 600000
# 当broker多久没有收到consumer的心跳请求后就触发reBalance默认值是10s
session:
timeout:
ms: 10000
listener:
# 在侦听器容器中运行的线程数,一般设置为 机器数*分区数
concurrency: 4
# 自动提交关闭,需要设置手动消息确认
ack-mode: manual_immediate
# 消费监听接口监听的主题不存在时默认会报错所以设置为false忽略错误
missing-topics-fatal: false
# 两次poll之间的最大间隔默认值为5分钟。如果超过这个间隔会触发reBalance
poll-timeout: 600000
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 124.221.114.13:8848
config:
# 配置中心地址
server-addr: 124.221.114.13:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
rabbitmq:
username: root
password: zzh123
virtualHost: /
port: 5672
host: 124.221.114.13
listener:
simple:
prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
publisher-returns: true #确认消息已发送到队列(Queue)

126
bwie-common/pom.xml 100644
View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bwie-tenement</artifactId>
<groupId>com.bwie</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bwie-common</artifactId>
<dependencies>
<!-- bootstrap 启动器 -->
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- SpringCloud Openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Alibaba Fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
</dependency>
<!-- SpringBoot Boot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Hibernate Validator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Apache Lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
<!-- 阿里大鱼 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.1</version>
</dependency>
<!-- rabbitMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--fastDfs文件上传-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,59 @@
package com.bwie.common.config;//package com.bwie.room.config;
//
//import org.springframework.amqp.core.Binding;
//import org.springframework.amqp.core.BindingBuilder;
//import org.springframework.amqp.core.DirectExchange;
//import org.springframework.amqp.core.Queue;
//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();
// }
// /**
// * 创建队列
// */
// @Bean
// public Queue queue1(){
//
// return new Queue("phoneQUeue",true);
// }
//
// @Bean
// public Queue queue2(){
//
// return new Queue("msgQueue4",true);
// }
//
// /**
// *
// * 创建交换机
// */
// @Bean(name = "phoneExchange")
// public DirectExchange directExchange1(){
// return new DirectExchange("phoneExchange");
// }
//
// @Bean(name = "msgExchange4")
// public DirectExchange directExchange2(){
// return new DirectExchange("msgExchange4");
// }
//
// /**
// * 绑定队列和交换机
// */
//
// @Bean
// public Binding binding(){
// return BindingBuilder.bind(queue1()).to(directExchange1()).with("phoneBinding");
// }
//}

View File

@ -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 = "操作异常";
}

View File

@ -0,0 +1,34 @@
package com.bwie.common.constants;
public class JwtConstants {
/**
* ID
*/
public static final String DETAILS_USER_ID = "user_id";
/**
*
*/
public static final String DETAILS_USERNAME = "user_name";
/**
*
*/
public static final String USER_KEY = "user_key";
/**
*
*/
public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
/**
*
*/
public static final String USER_PHONE = "user_phone";
/**
* token
*/
public static final String LOGIN_TOKEN = "login_token:";
}

View File

@ -0,0 +1,15 @@
package com.bwie.common.constants;
/**
* @Project boot-month
* @Author
* @Date 2023/9/6 10:06-+
* @Description
*/
public class QueueConstants {
public static final String SEND_CODE_QUEUE = "send_code_queue";
public static final String SEND_CODE_PREVENT_REPEAT_ID = "send_code_prevent_repeat_id:";
public static final String BLOG_UPDATE_QUEUE = "blog_update_queue";
public static final String BLOG_UPDATE_PREVENT_REPEAT_ID = "blog_update_prevent_repeat_id:";
}

View File

@ -0,0 +1,18 @@
package com.bwie.common.constants;
/**
* Clazz:2103A
* Name :FYSN
* Desc :--·
* Date :2023-08-20 20:37:02
*/
public class RabbitMQOneConstants {
//发送短消息队列名称
public static final String SEND_SHORT_MESSAGE_QUEUE_NAME = "send_short_message";
//查看的日志队列名称
public static final String QUERY_LOG_QUEUE_NAME = "query_log_message";
}

View File

@ -0,0 +1,18 @@
package com.bwie.common.constants;
/**
* Clazz:2103A
* Name :FYSN
* Desc :--·
* Date :2023-08-20 20:37:02
*/
public class RabbitMQTwoConstants {
//发送消息队列名称
public static final String SEND_SMS_QUEUE = "send_sms_queue";
//添加消息队列名称日志
public static final String ADD_MESSAGE_QUEUE_NAME_LOG = "add_message_log";
}

View File

@ -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";
}

View File

@ -0,0 +1,34 @@
package com.bwie.common.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Client {
//客户编号
private Integer clientId;
//客户姓名
private String clientName;
//客户电话
private String clientTel;
//客户类型
private String clientType;
//证件类型
private String clientDocument;
//证件号
private String clientDocumentNumber;
//性别
private String clientSex;
//民族
private String clientNation;
}

View File

@ -0,0 +1,51 @@
package com.bwie.common.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Complain {
//投诉编号
private Integer complainId;
//客户编号
private Integer clientId;
//客户姓名
private String clientName;
//客户电话
private String clientTel;
//投诉类型
private String complainType;
//投诉时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date complainTime;
//投诉描述
private String complainContent;
//投诉状态
private Integer complainStarts;
//登录人编号
private Integer userId;
//登录人姓名
private String userName;
//投诉处理时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date complainOutTime;
//投诉备注
private String complainRemark;
}

View File

@ -0,0 +1,26 @@
package com.bwie.common.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Floor {
//住宅类编号
private Integer floorId;
//楼名称(楼号)
private String floorName;
//楼层数
private Integer floorCount;
//类状态
private Integer floorStart;
//建筑面积
private Integer floorArea;
}

View File

@ -0,0 +1,20 @@
package com.bwie.common.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Login {
private Integer loginId;
private String loginName;
private String loginPwd;
private Integer loginRole;
}

View File

@ -0,0 +1,43 @@
package com.bwie.common.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Repair {
//保修编号
private Integer repairId;
//客户编号
private Integer clientId;
//客户姓名
private String clientName;
//客户电话
private String clientTel;
//报修类型
private String repairType;
//报修物品
private String repairContent;
//报修问题描述
private String repairItem;
//报修状态
private Integer repairStart;
//报修时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date repairStartTime;
}

View File

@ -0,0 +1,49 @@
package com.bwie.common.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
//角色编号
private Integer roleId;
//角色名称
private String roleName;
//创建人编号
private Integer addLoginId;
//创建人姓名
private String addLoginName;
//修改人编号
private Integer upLoginId;
//修改人姓名
private String upLoginName;
//创建人时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date addLoginTime;
//修改人时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date upLoginTime;
//用户编号
private Integer userId;
//用户名称
private String userName;
}

View File

@ -0,0 +1,46 @@
package com.bwie.common.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Room {
//房间编号
private Integer roomId;
//房间号
private String roomName;
//住宅楼编号
private Integer floorId;
//楼名称(楼号)
private String floorName;
//楼层
private Integer roomFloorCount;
//建筑面积
private Integer floorArea;
//客户编号
private Integer clientId;
//客户姓名
private String clientName;
//客户电话
private String clientTel;
//证件类型
private String clientDocument;
//证件号
private String clientDocumentNumber;
}

View File

@ -0,0 +1,46 @@
package com.bwie.common.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Space {
//停车位编号
private Integer spaceId;
//车位号
private String spaceNumber;
//住户编号
private Integer clientId;
//客户姓名
private String clientName;
//客户电话
private String clientTel;
//车位类型
private String spaceType;
//购车时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date spaceStartTime;
//到期时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date spaceEndTime;
//车位状态
private Integer spaceStatus;
//房间号
private String roomName;
}

View File

@ -0,0 +1,43 @@
package com.bwie.common.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
//用户编号
private Integer userId;
//用户姓名
private String userName;
//用户邮箱
private String userEmil;
//用户电话
private String userTel;
//用户账号
private String userZh;
//用户类型
private String userType;
//用户状态
private Integer userStart;
//创建时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date userTime;
//权限
private Integer userRole;
}

View File

@ -0,0 +1,16 @@
package com.bwie.common.domain.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Count {
private Integer id;
private Integer name;
}

View File

@ -0,0 +1,15 @@
package com.bwie.common.domain.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRequest {
private String phone;
private String code;
}

View File

@ -0,0 +1,27 @@
package com.bwie.common.mq;//package com.bwie.room.mq;
//
//
//import com.bwie.common.domain.User;
//import org.springframework.amqp.rabbit.annotation.RabbitHandler;
//import org.springframework.amqp.rabbit.annotation.RabbitListener;
//import org.springframework.stereotype.Component;
//
//@Component
//@RabbitListener(queues = "phoneQUeue")
//public class Conmuser {
//
//
// @RabbitHandler
// public void phone(User user){
//
// System.out.println(user);
//
// }
//
//
//
//
//
//
//
//}

View File

@ -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<T> implements Serializable {
/**
*
*/
private long total;
/**
*
*/
private List<T> list;
public PageResult() {
}
public PageResult(long total, List<T> list) {
this.total = total;
this.list = list;
}
public static <T> PageResult<T> toPageResult(long total, List<T> list){
return new PageResult(total , list);
}
public static <T> Result<PageResult<T>> toResult(long total, List<T> list){
return Result.success(PageResult.toPageResult(total,list));
}
}

View File

@ -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<T> 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 <T> Result<T> success() {
return restResult(null, SUCCESS, Constants.SUCCESS_MSG);
}
public static <T> Result<T> success(T data) {
return restResult(data, SUCCESS, Constants.SUCCESS_MSG);
}
public static <T> Result<T> success(T data, String msg) {
return restResult(data, SUCCESS, msg);
}
public static <T> Result<T> error() {
return restResult(null, FAIL, Constants.ERROR_MSG);
}
public static <T> Result<T> error(String msg) {
return restResult(null, FAIL, msg);
}
public static <T> Result<T> error(T data) {
return restResult(data, FAIL, Constants.ERROR_MSG);
}
public static <T> Result<T> error(T data, String msg) {
return restResult(data, FAIL, msg);
}
public static <T> Result<T> error(int code, String msg) {
return restResult(null, code, msg);
}
private static <T> Result<T> restResult(T data, int code, String msg) {
Result<T> apiResult = new Result<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
}

View File

@ -0,0 +1,312 @@
package com.bwie.common.utils;
import javax.servlet.http.HttpServletRequest;
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.99ip
*/
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;
}
}

View File

@ -0,0 +1,109 @@
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
* @author DongZl
*/
public class JwtUtils {
/**
*
*/
public static String secret = JwtConstants.SECRET;
/**
*
*
* @param claims
* @return
*/
public static String createToken(Map<String, Object> 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();
}
}

View File

@ -0,0 +1,68 @@
package com.bwie.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 ListSetQueue
*
* @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<String> 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);
}
}

View File

@ -0,0 +1,88 @@
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 {
/**
* AccessKeyaccessKeySecretAPI访
*/
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 templateCode SMS_153991546
* @param sendDataMap
*/
public static String sendSms(String tel, String templateCode,Map<String,String> 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());
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bwie-tenement</artifactId>
<groupId>com.bwie</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bwie-gateway</artifactId>
<dependencies>
<!-- 公共模块 -->
<dependency>
<groupId>com.bwie</groupId>
<artifactId>bwie-common</artifactId>
</dependency>
<!-- 网关依赖 -->
<!-- SpringCloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- 引入阿里巴巴sentinel限流 依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package com.bwie.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class);
}
}

View File

@ -0,0 +1,32 @@
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;
/**
* @description:
* @author DongZl
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "ignore")
@Data
@Log4j2
public class IgnoreWhiteConfig {
/**
*
*/
private List<String> whites = new ArrayList<>();
public void setWhites(List<String> whites) {
log.info("加载网关路径白名单:{}", JSONObject.toJSONString(whites));
this.whites = whites;
}
}

View File

@ -0,0 +1,86 @@
package com.bwie.gateway.filters;
import com.bwie.common.utils.JwtUtils;
import com.bwie.common.utils.StringUtils;
import com.bwie.gateway.config.IgnoreWhiteConfig;
import com.bwie.gateway.utils.GatewayUtils;
import io.jsonwebtoken.Claims;
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.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<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1..获取白名单
List<String> whites = ignoreWhiteConfig.getWhites();
//获取用户请求路径
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
System.out.println("路径>>>>>>>>>>>"+path);
//放行
if(StringUtils.matches(path,whites)){
return chain.filter(exchange);
}
//获取token
String token = request.getHeaders().getFirst("token");
if(token==null){
return GatewayUtils.errorResponse(exchange,"token必须携带");
}
Claims claims = null;
//token合法性
try {
claims = JwtUtils.parseToken(token);
} catch (Exception e) {
return GatewayUtils.errorResponse(exchange,"token不合法");
}
//判断jwt的时效性
Object userId = claims.get("user_id");
// redisTemplate.opsForValue().get()
if(!redisTemplate.hasKey("token:"+userId)){
return GatewayUtils.errorResponse(exchange,"token已过期");
}
Long expire = redisTemplate.getExpire("token:" + userId);
// if(expire<jwt原定过期时间的一半){
// redisTemplate.expire("token:"+userId, 60, TimeUnit.SECONDS);
// }
redisTemplate.expire("token:"+userId, 60, TimeUnit.SECONDS);
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}

View File

@ -0,0 +1,98 @@
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;
/**
* @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<Void> 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<Void> 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));
}
}

View File

@ -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: 124.221.114.13:8848
config:
# 配置中心地址
server-addr: 124.221.114.13:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -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: 124.221.114.13:8848
config:
# 配置中心地址
server-addr: 124.221.114.13:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bwie-module</artifactId>
<groupId>com.bwie</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bwie-floor</artifactId>
<dependencies>
<!-- 系统公共 依赖 -->
<dependency>
<groupId>com.bwie</groupId>
<artifactId>bwie-common</artifactId>
</dependency>
<!-- SpringBoot Web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis 依赖配置 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package com.bwie.floor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FloorApplication {
public static void main(String[] args) {
SpringApplication.run(FloorApplication.class);
}
}

View File

@ -0,0 +1,278 @@
package com.bwie.floor.controller;
import com.alibaba.fastjson.JSON;
import com.bwie.common.domain.Client;
import com.bwie.common.domain.Floor;
import com.bwie.common.domain.Room;
import com.bwie.common.domain.Space;
import com.bwie.common.domain.request.Count;
import com.bwie.common.result.Result;
import com.bwie.floor.service.FloorService;
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.text.ParseException;
import java.util.List;
@RestController
@RequestMapping("/floor")
@Log4j2
public class FloorController {
@Autowired
private HttpServletRequest request;
@Autowired
private FloorService floorService;
@PostMapping("/upSpace")
public Result upSpace(@RequestBody Space space) {
log.info("功能描述: 修改车位,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), space);
Result result= floorService.upSpace(space);
log.info("功能描述: 修改车位,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
@PostMapping("/addSpace")
public Result addSpace(@RequestBody Space space) throws ParseException {
log.info("功能描述: 添加车位,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), space);
Result result = floorService.addSpace(space);
log.info("功能描述: 添加车位,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//修改房间
@PostMapping("/upRoom")
public Result upRoom(@RequestBody Room room) {
log.info("功能描述: 修改房间,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), room);
Result result = floorService.upRoom(room);
log.info("功能描述: 修改房间,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//添加房间
@PostMapping("/addRoom")
public Result addRoom(@RequestBody Room room) {
log.info("功能描述: 添加房间,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), room);
Result result = floorService.addRoom(room);
log.info("功能描述: 添加房间,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//查询所有住户
@PostMapping("/findByclient")
public Result findByclient() {
log.info("功能描述: 查询所有住户,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Client> list = floorService.findByclient();
Result<List<Client>> success = Result.success(list);
log.info("功能描述: 查询所有住户,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
@PostMapping("/findByFloorId/{floorId}")
public Result findByFloorId(@PathVariable Integer floorId) {
log.info("功能描述: 根据Id查询,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), floorId);
List<Count> list = floorService.findByFloorId(floorId);
Result<List<Count>> success = Result.success(list);
log.info("功能描述: 根据Id查询,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
@PostMapping("/floorFindList")
public Result floorFindList() {
log.info("功能描述: 查询可用楼,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Floor> floorFindList = floorService.floorFindList();
Result<List<Floor>> success = Result.success(floorFindList);
log.info("功能描述: 查询可用楼,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
//修改住户
@PostMapping("/upFloor")
public Result upFloor(@RequestBody Client client) {
log.info("功能描述: 修改住户,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), client);
Result result = floorService.upFloor(client);
log.info("功能描述: 修改住户,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//添加住户
@PostMapping("/addclient")
public Result addclient(@RequestBody Client client) {
log.info("功能描述: 添加住户,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), client);
Result result = floorService.addclient(client);
log.info("功能描述: 添加住户,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//删除楼层
@PostMapping("/floorDel/{floorId}")
public Result floorDel(@PathVariable Integer floorId) {
log.info("功能描述: 删除楼层,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), floorId);
Result result = floorService.floorDel(floorId);
log.info("功能描述: 删除楼层,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
//添加楼层
@PostMapping("/addFloor")
public Result addFloor(@RequestBody Floor floor) {
log.info("功能描述: 发送短信验证码,请求URI: {},请求方式: {},请求参数: {}",
request.getServletPath(), request.getMethod(), floor);
Result result = floorService.addFloor(floor);
log.info("功能描述: 发送短信验证码,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(result));
return result;
}
@PostMapping("/foolList")
public Result foolList() {
log.info("功能描述: 楼列表,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Floor> list = floorService.list();
Result<List<Floor>> success = Result.success(list);
log.info("功能描述: 楼列表,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
@PostMapping("/clientList")
public Result clientList() {
log.info("功能描述: 客户列表,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Client> list = floorService.clientList();
Result<List<Client>> success = Result.success(list);
log.info("功能描述: 客户列表,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
@PostMapping("/roomList")
public Result roomList() {
log.info("功能描述: 房间列表,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Room> list = floorService.roomList();
Result<List<Room>> success = Result.success(list);
log.info("功能描述: 房间列表,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
@PostMapping("/spaceList")
public Result SpaceList() {
log.info("功能描述: 车位列表,请求URI: {},请求方式: {}",
request.getServletPath(), request.getMethod());
List<Space> list = floorService.SpaceList();
Result<List<Space>> success = Result.success(list);
log.info("功能描述: 车位列表,请求URI: {},请求方式: {},响应结果: {}",
request.getServletPath(), request.getMethod(), JSON.toJSONString(success));
return success;
}
}

View File

@ -0,0 +1,43 @@
package com.bwie.floor.mapper;
import com.bwie.common.domain.Client;
import com.bwie.common.domain.Floor;
import com.bwie.common.domain.Room;
import com.bwie.common.domain.Space;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface FloorMapper {
List<Floor> list();
List<Client> clientList();
List<Room> roomList();
List<Space> SpaceList();
Integer addFloor(Floor floor);
Integer floorDel(@Param("floorId") Integer floorId);
Integer addclient(Client client);
Integer upFloor(Client client);
List<Floor> floorFindList();
Floor findByFloorId(@Param("floorId") Integer floorId);
List<Client> findByclient();
Integer addRoom(Room room);
Integer upRoom(Room room);
Integer addSpace(Space space);
Integer upSpace(Space space);
}

View File

@ -0,0 +1,43 @@
package com.bwie.floor.service;
import com.bwie.common.domain.Client;
import com.bwie.common.domain.Floor;
import com.bwie.common.domain.Room;
import com.bwie.common.domain.Space;
import com.bwie.common.domain.request.Count;
import com.bwie.common.result.Result;
import java.text.ParseException;
import java.util.List;
public interface FloorService {
List<Floor> list();
List<Client> clientList();
List<Room> roomList();
List<Space> SpaceList();
Result addFloor(Floor floor);
Result floorDel(Integer floorId);
Result addclient(Client client);
Result upFloor(Client client);
List<Floor> floorFindList();
List<Count> findByFloorId(Integer floorId);
List<Client> findByclient();
Result addRoom(Room room);
Result upRoom(Room room);
Result addSpace(Space space) throws ParseException;
Result upSpace(Space space);
}

View File

@ -0,0 +1,218 @@
package com.bwie.floor.service.impl;
import com.bwie.common.domain.Client;
import com.bwie.common.domain.Floor;
import com.bwie.common.domain.Room;
import com.bwie.common.domain.Space;
import com.bwie.common.domain.request.Count;
import com.bwie.common.result.Result;
import com.bwie.floor.mapper.FloorMapper;
import com.bwie.floor.service.FloorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@Service
public class FloorServiceImpl implements FloorService {
@Autowired
private FloorMapper floorMapper;
@Override
public List<Floor> list() {
return floorMapper.list();
}
@Override
public List<Client> clientList() {
return floorMapper.clientList();
}
@Override
public List<Room> roomList() {
return floorMapper.roomList();
}
@Override
public List<Space> SpaceList() {
return floorMapper.SpaceList();
}
@Override
public Result addFloor(Floor floor) {
Integer addFloor= floorMapper.addFloor(floor);
if (addFloor>0){
return Result.success("添加成功");
}
return Result.error("添加失败");
}
@Override
public Result floorDel(Integer floorId) {
Integer floorDel= floorMapper.floorDel(floorId);
if (floorDel>0){
return Result.success("禁用成功");
}
return Result.error("禁用失败");
}
@Override
public Result addclient(Client client) {
Integer addclient= floorMapper.addclient(client);
if (addclient>0){
return Result.success("添加成功");
}
return Result.error("添加失败");
}
@Override
public Result upFloor(Client client) {
Integer upFloor= floorMapper.upFloor(client);
if (upFloor>0){
return Result.success("修改成功");
}
return Result.error("修改失败");
}
@Override
public List<Floor> floorFindList() {
return floorMapper.floorFindList();
}
@Override
public List<Count> findByFloorId(Integer floorId) {
Floor floor= floorMapper.findByFloorId(floorId);
Integer count = floor.getFloorCount();
ArrayList<Count> list = new ArrayList<>();
for (int i = 1; i <= count; i++) {
Count count1 = new Count(i, i);
list.add(count1);
}
return list;
}
@Override
public List<Client> findByclient() {
return floorMapper.findByclient();
}
@Override
public Result addRoom(Room room) {
Integer addRoom= floorMapper.addRoom(room);
if (addRoom>0){
return Result.success("添加成功");
}
return Result.error("添加失败");
}
@Override
public Result upRoom(Room room) {
Integer upRoom= floorMapper.upRoom(room);
if (upRoom>0){
return Result.success("修改成功");
}
return Result.error("修改失败");
}
@Override
public Result addSpace(Space space) throws ParseException {
//这行代码创建一个 Calendar 对象并将其初始化为当前日期和时间
Calendar calendar = Calendar.getInstance();
//这行代码用于将一个 Date 对象的值设置到 Calendar 对象中。具体来说,它执行了以下操作:
calendar.setTime(new Date());
//这行代码的意思是将 Calendar 对象中的日期增加 2 个月。具体来说,它执行了以下操作:
//使用 Calendar 对象的 add 方法,将日期字段中的月份增加 2 个月。
//如果当前的月份是 1 到 11 之间的任何一个月,那么它会简单地将月份加 2。
//如果当前的月份是 12即十二月那么它会将年份加 1并将月份设置为 1即一月
//举例来说,如果当前日期是 2023 年 8 月 15 日,执行了这行代码后,日期会变成 2023 年 10 月 15 日
calendar.add(Calendar.MONTH, 2);
//这行代码将 Calendar 对象中表示的日期和时间转换为一个 Date 对象。具体来说,它执行了以下操作:
//使用 Calendar 对象的 getTime 方法,将 Calendar 对象中的日期和时间转换为一个 Date 对象。
//这样做可以方便地将 Calendar 对象中表示的日期和时间转换为 Date 对象,以便在程序中进行日期和时间的操作,比如格式化输出或者进行其他的处理。
Date nextMonth = calendar.getTime();
System.out.println("One month later: " + nextMonth);
//时间格式
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//转格式
String format1 = format.format(nextMonth);
//转回时间类型
Date parse = format.parse(format1);
space.setSpaceEndTime(parse);
Integer addSpace= floorMapper.addSpace(space);
if (addSpace>0){
return Result.success("添加成功");
}
return Result.error("添加失败");
}
@Override
public Result upSpace(Space space) {
Integer upSpace = floorMapper.upSpace(space);
if (upSpace>0){
return Result.success("修改成功");
}
return Result.error("修改失败");
}
}

View File

@ -0,0 +1,55 @@
package com.bwie.floor.util;
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 "删除成功";
}
}

View File

@ -0,0 +1,41 @@
# Tomcat
server:
port: 9272
# Spring
spring:
main:
allow-circular-references: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
application:
# 应用名称
name: bwie-floor
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 124.221.114.13:8848
config:
# 配置中心地址
server-addr: 124.221.114.13:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
fdfs:
so-timeout: 1500 # socket 连接时长
connect-timeout: 600 # 连接 tracker 服务器超时时长
# 这两个是你服务器的 IP 地址,注意 23000 端口也要打开阿里云服务器记得配置安全组。tracker 要和 stroage 服务进行交流
tracker-list: 124.221.114.13:22122
web-server-url: 124.221.114.13:8888
pool:
jmx-enabled: false
# 生成缩略图
thumb-image:
height: 500
width: 500

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.bwie.floor.mapper.FloorMapper">
<insert id="addFloor">
INSERT INTO `wuye`.`floor` (`floor_name`, `floor_count`, `floor_start`, `floor_area`)
VALUES ( #{floorName}, #{floorCount}, 0, #{floorArea});
</insert>
<insert id="addclient">
INSERT INTO `wuye`.`client` ( `client_name`, `client_tel`, `client_type`, `client_document`, `client_document_number`, `client_sex`, `client_nation`)
VALUES ( #{clientName}, #{clientTel}, #{clientType}, #{clientDocument}, #{clientDocumentNumber}, #{clientSex}, #{clientNation});
</insert>
<insert id="addRoom">
INSERT INTO `wuye`.`room` ( `room_name`, `floor_id`, `client_id`, `room_floor_count`)
VALUES ( #{roomName}, #{floorId}, #{clientId}, #{roomFloorCount});
</insert>
<insert id="addSpace">
INSERT INTO `wuye`.`space` ( `space_number`, `client_id`, `space_type`, `space_start_time`, `space_end_time`, `space_status`)
VALUES ( #{spaceNumber}, #{clientId}, #{spaceType}, now(), #{spaceEndTime}, 1);
</insert>
<update id="floorDel">
UPDATE `wuye`.`floor` SET `floor_start` = 1 WHERE `floor_id` = #{floorId};
</update>
<update id="upFloor">
UPDATE `wuye`.`client` SET `client_name` = #{clientName}, `client_tel` = #{clientTel}, `client_type` = #{clientType}, `client_document` = #{clientDocument}, `client_document_number` = #{clientDocumentNumber}, `client_sex` = #{clientSex}, `client_nation` = #{clientNation} WHERE `client_id` = #{clientId};
</update>
<update id="upRoom">
UPDATE `wuye`.`room` SET `room_name` = #{roomName}, `floor_id` = #{floorId}, `client_id` = #{clientId}, `room_floor_count` = #{roomFloorCount} WHERE `room_id` = #{roomId};
</update>
<update id="upSpace">
UPDATE `wuye`.`space` SET `space_number` = #{spaceNumber}, `client_id` = #{clientId}, `space_type` = #{spaceType}, `space_start_time` = #{spaceStartTime}, `space_end_time` = #{spaceEndTime}, `space_status` = 1 WHERE `space_id` = #{spaceId};
</update>
<select id="list" resultType="com.bwie.common.domain.Floor">
select * from floor
</select>
<select id="clientList" resultType="com.bwie.common.domain.Client">
select * from client
</select>
<select id="roomList" resultType="com.bwie.common.domain.Room">
SELECT * FROM room
LEFT JOIN client on room.client_id=client.client_id
LEFT JOIN floor on room.floor_id =floor.floor_id
</select>
<select id="SpaceList" resultType="com.bwie.common.domain.Space">
SELECT * FROM space
LEFT JOIN client ON space.client_id =client.client_id
LEFT JOIN room on client.client_id =room.client_id
</select>
<select id="floorFindList" resultType="com.bwie.common.domain.Floor">
select * from floor where floor_start =0
</select>
<select id="findByFloorId" resultType="com.bwie.common.domain.Floor">
select * from floor where floor_id = #{floorId}
</select>
<select id="findByclient" resultType="com.bwie.common.domain.Client">
select * from client
</select>
</mapper>

Some files were not shown because too many files have changed in this diff Show More