Compare commits

..

31 Commits

Author SHA1 Message Date
刘武 9499d9738e fix(): 事件基础 2024-10-07 12:06:18 +08:00
刘武 87d104cf9b fix(): 事件基础修改 2024-10-06 10:39:59 +08:00
袁子龙 fe90a341ff Merge remote-tracking branch 'origin/dev.business' into dev 2024-09-30 16:48:27 +08:00
袁子龙 d99edc16d1 feat:新增企业入驻 2024-09-30 16:47:31 +08:00
袁子龙 50a655d888 feat:新增企业入驻 2024-09-30 16:46:34 +08:00
Number7 e8bc92c658 Merge remote-tracking branch 'refs/remotes/origin/dev.template' into dev 2024-09-30 16:38:01 +08:00
Number7 76440e1c98 feat():增加协议解析模块 2024-09-30 16:37:24 +08:00
袁子龙 b879a1768d feat:新增企业入驻 2024-09-30 16:36:35 +08:00
刘武 370fdd9fd5 Merge branch 'dev' of https://gitea.qinmian.online/group-four/cloud-car into dev
# Conflicts:
#	cloud-common/pom.xml
2024-09-30 16:35:35 +08:00
刘武 f46db057b5 fix(): 事件基础修改,kafka注入 2024-09-30 16:34:37 +08:00
Number7 82ec79ccaf fix():修改报文基础类型方法 2024-09-30 15:47:20 +08:00
Number7 551f5f5496 Merge remote-tracking branch 'refs/remotes/origin/dev.template' into dev
# Conflicts:
#	cloud-modules/saas/saas-server/src/main/java/com/muyu/server/service/impl/TemplateServiceImpl.java
2024-09-30 15:28:30 +08:00
Number7 8e0e492555 fix():修改报文基础类型方法 2024-09-30 15:27:28 +08:00
Number7 6545fc79ef feat():增加添加报文模版功能 2024-09-30 14:40:07 +08:00
袁子龙 78747b7d03 feat:新增企业入驻接口 2024-09-30 12:23:56 +08:00
袁子龙 d6ff8ad340 feat:新增企业入驻服务校验 2024-09-30 12:19:21 +08:00
袁子龙 8bc54f4662 feat:新增企业对象 2024-09-30 12:12:52 +08:00
袁子龙 e6639bc7f9 feat:新增长度限制 2024-09-30 11:37:41 +08:00
袁子龙 a0ddc45e67 feat:企业入驻 2024-09-30 11:31:52 +08:00
袁子龙 051fe490d6 feat:企业入驻 2024-09-30 11:31:41 +08:00
袁子龙 31df6d32db feat:企业入驻 2024-09-30 11:31:07 +08:00
袁子龙 798f509dec feat:企业登录 2024-09-30 11:17:20 +08:00
袁子龙 f93af8b4a6 Merge remote-tracking branch 'origin/dev.business' into dev
# Conflicts:
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/CarType.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/DataType.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/MessageTemplate.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/MessageTemplateType.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/SysCar.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/SysCarLog.java
#	cloud-modules/saas/saas-common/src/main/java/com/muyu/common/domain/Template.java
#	cloud-modules/saas/saas-server/src/main/java/com/muyu/server/config/MqttConfigure.java
#	cloud-modules/saas/saas-server/src/main/java/com/muyu/server/service/impl/SysCarServiceImpl.java
2024-09-30 11:00:49 +08:00
袁子龙 1272d0e0b7 refactor:修改注释 2024-09-30 10:59:09 +08:00
Number7 1f072d4ca2 fix():修改报文接口字段问题 2024-09-30 10:29:58 +08:00
刘武 cc99d65102 fix(): 事件基础修改,kafka注入 2024-09-30 09:17:02 +08:00
袁子龙 29cb1ffadb refactor:修改注释 2024-09-29 22:03:51 +08:00
袁子龙 2488248967 refactor:修改注释 2024-09-29 16:12:34 +08:00
袁子龙 dea0f07c90 refactor:修改注释 2024-09-29 16:03:17 +08:00
袁子龙 688154709d refactor:修改注释 2024-09-29 14:51:02 +08:00
袁子龙 3f9a930c95 refactor:修改yml的nacos命名空间 2024-09-29 12:28:21 +08:00
201 changed files with 3025 additions and 1559 deletions

View File

@ -57,6 +57,10 @@
<groupId>com.muyu</groupId>
<artifactId>cloud-common-api-doc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
</dependencies>

View File

@ -1,7 +1,10 @@
package com.muyu.auth.controller;
import com.muyu.auth.form.EnterpriseSettlement;
import com.muyu.auth.form.Firm;
import com.muyu.auth.form.LoginBody;
import com.muyu.auth.form.RegisterBody;
import com.muyu.auth.service.SysFirmService;
import com.muyu.auth.service.SysLoginService;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.JwtUtils;
@ -31,8 +34,16 @@ public class TokenController {
@Autowired
private SysLoginService sysLoginService;
@Autowired
private SysFirmService sysFirmService;
@PostMapping("login")
public Result<?> login (@RequestBody LoginBody form) {
//查询企业是否存在
Firm firm = sysFirmService.findFirmByName(form.getFirmName());
if (firm.getDatabaseName() == null){
return Result.error(null,"企业不存在");
}
// 用户登录
LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
// 获取登录token
@ -69,4 +80,10 @@ public class TokenController {
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
return Result.success();
}
@PostMapping("/enterprise")
public Result<?> enterprise( @RequestBody EnterpriseSettlement settlement){
sysLoginService.enterprise(settlement.getDatabaseName(),settlement.getFirmName());
return Result.success();
}
}

View File

@ -0,0 +1,23 @@
package com.muyu.auth.form;
import lombok.Data;
/**
*
* @author
* @package com.muyu.auth.form
* @name EnterpriseSettlement
* @date 2024/9/30 11:25
*/
@Data
public class EnterpriseSettlement {
/**
*
*/
private String firmName;
/**
*
*/
private String databaseName;
}

View File

@ -0,0 +1,28 @@
package com.muyu.auth.form;
import lombok.Data;
/**
*
* @author
* @package com.muyu.auth.form
* @name Enterprise
* @date 2024/9/30 10:30
*/
@Data
public class Firm {
/**
* id
*/
private Integer id;
/**
*
*/
private String firmName;
/**
*
*/
private String databaseName;
}

View File

@ -1,10 +1,14 @@
package com.muyu.auth.form;
import lombok.Data;
/**
*
*
* @author muyu
*/
@Data
public class LoginBody {
/**
*
@ -16,20 +20,11 @@ public class LoginBody {
*/
private String password;
/**
*
*/
private String firmName;
public String getUsername () {
return username;
}
public void setUsername (String username) {
this.username = username;
}
public String getPassword () {
return password;
}
public void setPassword (String password) {
this.password = password;
}
}

View File

@ -0,0 +1,57 @@
package com.muyu.auth.service;
import com.muyu.auth.form.Firm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.data.redis.core.RedisTemplate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
*
* @author
* @package com.muyu.auth.service
* @name SysFirmService
* @date 2024/9/30 11:05
*/
@Component
public class SysFirmService {
//数据库账号
static final String USER="root";
//数据库密码
static final String PASSWORD="Lw030106";
@Autowired
private RedisTemplate redisTemplate;
public Firm findFirmByName(String firmName){
Firm firm = new Firm();
try {
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
Connection connection= DriverManager.getConnection("jdbc:mysql://47.101.53.251:3306/datasource?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=false",USER,PASSWORD);
String sql="select * from `datasource` where firm_name = '"+firmName+"'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()){
firm.setId(rs.getInt("id"));
firm.setFirmName(rs.getString("firm_name"));
firm.setDatabaseName(rs.getString("database_name"));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
//数据源不为空
if (firm!=null){
redisTemplate.opsForValue().set("datasource",firm.getDatabaseName());
}
return firm;
};
}

View File

@ -1,5 +1,6 @@
package com.muyu.auth.service;
import com.muyu.auth.form.EnterpriseSettlement;
import com.muyu.common.core.constant.CacheConstants;
import com.muyu.common.core.constant.Constants;
import com.muyu.common.core.constant.SecurityConstants;
@ -12,6 +13,7 @@ import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.core.utils.ip.IpUtils;
import com.muyu.common.redis.service.RedisService;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.remote.RemoteUserService;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.domain.LoginUser;
@ -124,4 +126,29 @@ public class SysLoginService {
}
recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功");
}
/**
*
* @param databaseName
* @param fileName
*/
public void enterprise (String databaseName,String fileName) {
// 参数校验 数据库名或企业名称不能为空
if (StringUtils.isAnyBlank(databaseName, fileName)) {
throw new ServiceException("数据库名或企业名称不能为空");
}
if (databaseName.length() < UserConstants.PASSWORD_MIN_LENGTH || databaseName.length() > UserConstants.PASSWORD_MAX_LENGTH) {
throw new ServiceException("数据库名长度必须在5到20个字符之间");
}
if (fileName.length() < UserConstants.Firm_NAME_MIN_LENGTH || fileName.length() > UserConstants.Firm_NAME_MAX_LENGTH) {
throw new ServiceException("企业名称长度必须在2到20个字符之间");
}
Enterprise settlement = new Enterprise();
settlement.setDatabaseName(databaseName);
settlement.setFirmName(fileName);
remoteUserService.settlementEnterpriseInfo(settlement, SecurityConstants.INNER);
}
}

View File

@ -7,7 +7,7 @@ nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# Spring
spring:
application:

View File

@ -138,10 +138,10 @@
</dependency>
<!-- Java Specification Requests 标准库-->
<!-- <dependency>-->
<!-- <groupId>javax.annotation</groupId>-->
<!-- <artifactId>jsr250-api</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.annotation</groupId>-->
<!-- <artifactId>jsr250-api</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>javax.annotation</groupId>

View File

@ -0,0 +1,49 @@
package com.muyu.common.core.constant;
/**
* kafka
* @program: cloud-server
* @author: cuiyongxing
* @create: 2024-09-28 12:18
**/
public class KafkaConstant {
public static final String BOOTSTRAP_SERVERS = "bootstrap.servers";
public static final String RETRIES = "retries";
public static final String ACKS = "acks";
public static final String BATCH_SIZE = "batch.size";
public static final String BUFFER_MEMORY = "buffer-memory";
public static final String KEY_SERIALIZER = "key.serializer";
public static final String VALUE_SERIALIZER = "value.serializer";
public static final String ENABLE_AUTO_COMMIT = "enable.auto.commit";
public static final String AUTO_COMMIT_INTERVAL = "auto.commit.interval.ms";
public static final String AUTO_OFFSET_RESET = "auto.offset.reset";
public static final String FETCH_MAX_WAIT = "fetch.max.wait";
public static final String FETCH_MIN_SIZE = "fetch.min.size";
public static final String HEARTBEAT_INTERVAL = "heartbeat.interval";
public static final String MAX_POLL_RECORDS = "max.poll.records";
public static final String KEY_DESERIALIZER = "key.deserializer";
public static final String VALUE_DESERIALIZER = "value.deserializer";
public static final String TOPIC = "topic";
public static final String GROUP_ID = "group.id";
}

View File

@ -110,4 +110,16 @@ public class UserConstants {
public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20;
/**
*
*/
public static final int Firm_NAME_MIN_LENGTH = 2;
public static final int Firm_NAME_MAX_LENGTH = 20;
/**
*
*/
public static final int DATABASE_NAME_MIN_LENGTH = 2;
public static final int DATABASE_NAME_MAX_LENGTH = 20;
}

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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.muyu</groupId>
<artifactId>cloud-common</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>cloud-common-kafka</artifactId>
<description>
cloud-common-kafka消息队列
</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,94 @@
package com.muyu.common.kafka.config;
import com.muyu.common.core.constant.KafkaConstant;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* kafka
* @program: cloud-server
* @author: cuiyongxing
* @create: 2024-09-28 14:28
**/
@Configuration
public class KafkaConsumerConfig {
/**
* id+
*/
@Value("${spring.kafka.consumer.bootstrap-servers}")
private String bootstrapServers;
/**
*
*/
@Value("${spring.kafka.consumer.enable-auto-commit}")
private Boolean enableAutoCommit;
/**
*
*/
@Value("${spring.kafka.consumer.auto-commit-interval}")
private Integer autoCommitInterval;
/**
*
*/
@Value("${spring.kafka.consumer.auto-offset-reset}")
private String autoOffsetReset;
/**
*
*/
@Value("${spring.kafka.consumer.fetch-max-wait}")
private Integer fetchMaxWait;
/**
*
*/
@Value("${spring.kafka.consumer.fetch-min-size}")
private Integer fetchMinSize;
/**
*
*/
@Value("${spring.kafka.consumer.heartbeat-interval}")
private Integer heartbeatInterval;
/**
*
*/
@Value("${spring.kafka.consumer.max-poll-records}")
private Integer maxPollRecords;
/**
*
*/
@Value("${spring.kafka.consumer.group-id}")
private String groupId;
@Bean
public KafkaConsumer kafkaConsumer(){
Map<String,Object> configs = new HashMap<>();
configs.put(KafkaConstant.BOOTSTRAP_SERVERS, bootstrapServers);
configs.put(KafkaConstant.ENABLE_AUTO_COMMIT, enableAutoCommit);
configs.put(KafkaConstant.AUTO_COMMIT_INTERVAL, autoCommitInterval);
configs.put(KafkaConstant.AUTO_OFFSET_RESET, autoOffsetReset);
configs.put(KafkaConstant.FETCH_MAX_WAIT, fetchMaxWait);
configs.put(KafkaConstant.FETCH_MIN_SIZE, fetchMinSize);
configs.put(KafkaConstant.HEARTBEAT_INTERVAL, heartbeatInterval);
configs.put(KafkaConstant.MAX_POLL_RECORDS, maxPollRecords);
configs.put(KafkaConstant.GROUP_ID, groupId);
StringDeserializer keyDeserializer = new StringDeserializer();
StringDeserializer valueDeserializer = new StringDeserializer();
return new KafkaConsumer(configs, keyDeserializer, valueDeserializer);
}
}

View File

@ -0,0 +1,66 @@
package com.muyu.common.kafka.config;
import com.muyu.common.core.constant.KafkaConstant;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* kafka
* @program: cloud-server
* @author: cuiyongxing
* @create: 2024-09-28 12:03
**/
@Configuration
public class KafkaProducerConfig {
/**
* ip+
*/
@Value("${spring.kafka.producer.bootstrap-servers}")
private String bootstrapServers;
/**
*
*/
@Value("${spring.kafka.producer.retries}")
private Integer retries;
/**
*
*/
@Value("${spring.kafka.producer.batch-size}")
private Integer batchSize;
/**
*
*/
@Value("${spring.kafka.producer.buffer-memory}")
private Integer bufferMemory;
/**
*
*/
@Value("${spring.kafka.producer.acks}")
private String acks;
@Bean
public KafkaProducer kafkaProducer() {
Map<String, Object> configs = new HashMap<>();
configs.put(KafkaConstant.BOOTSTRAP_SERVERS, bootstrapServers);
configs.put(KafkaConstant.RETRIES, retries);
configs.put(KafkaConstant.BATCH_SIZE, batchSize);
configs.put(KafkaConstant.BUFFER_MEMORY, bufferMemory);
configs.put(KafkaConstant.ACKS, acks);
StringSerializer keySerializer = new StringSerializer();
StringSerializer valueSerializer = new StringSerializer();
KafkaProducer kafkaProducer = new KafkaProducer<>(configs, keySerializer, valueSerializer);
return kafkaProducer;
}
}

View File

@ -0,0 +1,2 @@
com.muyu.common.kafka.config.KafkaConsumerConfig
com.muyu.common.kafka.config.KafkaProducerConfig

View File

@ -17,6 +17,10 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<description>
cloud-common-rabbit 消息队列服务
</description>
<dependencies>
<!-- rabbitMq 消息队列 -->
@ -28,8 +32,10 @@
<!-- 项目公共核心 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-core</artifactId>
<artifactId>cloud-common-redis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,41 +0,0 @@
package com.muyu.common.rabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
@Configuration
public class RabbitListenerConfigurer implements org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer {
static {
System.setProperty("spring.amqp.deserialization.trust.all", "true");
}
//以下配置RabbitMQ消息服务
@Autowired
public ConnectionFactory connectionFactory;
/**
*
* @return
*/
@Bean
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message body
factory.setMessageConverter(new MappingJackson2MessageConverter());
return factory;
}
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(handlerMethodFactory());
}
}

View File

@ -0,0 +1,47 @@
package com.muyu.rabbitmq.config;
import lombok.AllArgsConstructor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @ClassName:
* @Description:
*/
@Component
@AllArgsConstructor
public class MyConfirmCallback implements RabbitTemplate.ConfirmCallback {
private RabbitTemplate rabbitTemplate;
// public MyConfirmCallback(RabbitTemplate rabbitTemplate) {
// this.rabbitTemplate = rabbitTemplate;
// // 设置 消息发送到交换机成功 的回调
// this.rabbitTemplate.setConfirmCallback(this);
// }
@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("消息发送到交换机成功~");
} else {
System.out.println("消息发送到交换机失败,失败的原因:" + cause);
}
}
}

View File

@ -0,0 +1,49 @@
package com.muyu.rabbitmq.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;
/**
* @ClassName: RabbitAdminConfig
* @Description: 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.port}")
private Integer port;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setHost(host);
cachingConnectionFactory.setPort(port);
cachingConnectionFactory.setUsername(username);
cachingConnectionFactory.setPassword(password);
return cachingConnectionFactory;
}
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}

View File

@ -0,0 +1,20 @@
package com.muyu.rabbitmq.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;
/**
* JSON json
*/
@Configuration
public class RabbitmqConfig {
// 消息转换配置
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

View File

@ -0,0 +1,37 @@
package com.muyu.rabbitmq.config;
import lombok.AllArgsConstructor;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
*
*/
@Component
@AllArgsConstructor
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
private final RabbitTemplate rabbitTemplate;
@PostConstruct // @PostContruct是spring框架的注解在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法也可以理解为在spring容器初始化的时候执
public void init() {
rabbitTemplate.setReturnsCallback(this);
}
/**
*
*
* @param returnedMessage the returned message and metadata.
*/
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
System.out.println("消息" + returnedMessage.getMessage().toString() +
"被交换机" + returnedMessage.getExchange() + "回退!"
+ "退回原因为:" + returnedMessage.getReplyText());
// 回退了所有的信息,可做补偿机制 记录发送的日志
}
}

View File

@ -0,0 +1,35 @@
package com.muyu.rabbitmq.constants;
/**
*
* @author:
* @date: 2024/7/10
* @Description: rabbitmq
* @Version 1.0.0
*/
public interface RabbitmqConstants {
//普通队列
String BASIC_QUEUE_NAME = "BASIC_QUEUE_NAME";
String lOG_QUEUE_NAME = "LOG_QUEUE_NAME";
//延迟队列
//队列名称
String DELAYED_QUEUE_NAME = "delayed_queue";
//交换机名称
String DELAYED_EXCHANGE_NAME = "DELAYED_EXCHANGE";
//交换机
String DELAYED_ROUTING_KEY = "delayed";
/**
* 线
*/
String TOP_BOTTOM_STITCHING = "top_bottom_stitching";
/**
* 线
*/
String TOP_RULE = "car.top.data";
/**
* 线
*/
String BOTTOM_RULE = "car.bottom.data";
}

View File

@ -0,0 +1,150 @@
package com.muyu.rabbitmq.consumer;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.common.redis.service.RedisService;
//import com.muyu.rabbitmq.util.CacheUtil;
import com.rabbitmq.client.Channel;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Date;
/**
* @ClassName: RabbitMQConsumerUtil
* @Description: rabbitmq
*/
@Component
@Log4j2
@AllArgsConstructor
public class RabbitMQConsumerUtil {
private final RedisService redisService;
// @Autowired
// private CacheUtil cacheUtil;
/**
*
* @param data
* @param message
* @param channel
*/
@RabbitListener(queuesToDeclare = @Queue(name = "basic"))
public void rabbitMQBasicConsumer(String data ,Message message , Channel channel) {
log.info("当前时间:{} RabbitMQConsumerUtil : {}", new Date(), message);
try {
// 获取到消息 开始消费
log.info("消息消费者接收到消息,消息内容:{}", JSONObject.toJSONString(data));
Long add = redisService.redisTemplate.opsForSet().add(data, message.getMessageProperties().getMessageId());
if (add != 1) {
return;
}
/**
* ---------------------------------------------------------------
*/
String carList = (String) redisService.redisTemplate.opsForValue().get("carList");
/**
* ------------------------------------------------------------------------------
*/
// 消费消息成功之后需要确认
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean multiple 是否批量确认 true 批量 确认小于等于当前投递序号的消息 false 单个确认
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info("xxx消费者接收到消息消息内容{},消费成功...", message);
} catch (Exception e) {
log.error("xxx消费者接收到消息消息内容{},消费消息异常,异常信息:{}", message, e);
// 消息回退 拒绝消费消息
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean requeue 是否回到原来的队列
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
} catch (IOException ex) {
log.error("xxx消费者接收到消息消息内容{},回退消息异常,异常信息:{}", message, ex);
}
}finally {
try {
channel.close();
} catch (Exception e) {
log.error("xxx消费者关闭Channel异常消息内容{},异常信息:{}", message, e);
}
}
}
/**
*
* @param data
* @param message
* @param channel
*/
public void carUpConsumer(String data,Message message , Channel channel) {
log.info("当前时间:{} RabbitMQConsumerUtil : {}", new Date(), message);
try {
// 获取到消息 开始消费
log.info("消息消费者接收到消息,消息内容:{}", JSONObject.toJSONString(data));
Long add = redisService.redisTemplate.opsForSet().add(data, message.getMessageProperties().getMessageId());
if (add != 1) {
return;
}
/**
* ---------------------------------------------------------------
*/
log.info("[ 根据vin拿到缓存 ] vin为 --》 {}",data);
log.info("[ 存入本地缓存 ] 数据为 --》 {}",data);
log.info("[ 存入本地缓存 ] 数据为 --》 {}",data);
/**
* ------------------------------------------------------------------------------
*/
// 消费消息成功之后需要确认
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean multiple 是否批量确认 true 批量 确认小于等于当前投递序号的消息 false 单个确认
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info("xxx消费者接收到消息消息内容{},消费成功...", message);
} catch (Exception e) {
log.error("xxx消费者接收到消息消息内容{},消费消息异常,异常信息:{}", message, e);
// 消息回退 拒绝消费消息
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean requeue 是否回到原来的队列
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
} catch (IOException ex) {
log.error("xxx消费者接收到消息消息内容{},回退消息异常,异常信息:{}", message, ex);
}
}finally {
try {
channel.close();
} catch (Exception e) {
log.error("xxx消费者关闭Channel异常消息内容{},异常信息:{}", message, e);
}
}
}
}

View File

@ -0,0 +1,174 @@
package com.muyu.rabbitmq.producer;
import com.muyu.common.core.domain.Result;
import com.muyu.rabbitmq.constants.RabbitmqConstants;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* @ClassName: RabbitMQProducer
* @Description: rabbitmq
*/
@Component
@AllArgsConstructor
@Log4j2
public class RabbitMQProducerUtil {
//redis工具类对象
//rabbit
private final RabbitTemplate rabbitTemplate;
/**
*
*
* @param param
* @return
*
*/
public void basicSendMessage(String queueName, String param) {
log.info("【简单模型mq】 : method: 【 basicSendMessage 】 - ages: 【 String : {}, Object : {}】 ---> 【 消息发送中。。。 】", RabbitmqConstants.BASIC_QUEUE_NAME, param);
// 发送简单模型消息
// 第一个参数: 绑定规则 相当于 队列名称
// 第二个参数:消息内容
rabbitTemplate.convertAndSend(queueName, param, message -> {
message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
return message;
} );
log.info("【简单模型mq】 : method: 【 basicSendMessage 】- queue: 【 {} 】 ---> 【 消息发送成功 】", RabbitmqConstants.BASIC_QUEUE_NAME);
}
// /**
// * Work queue 工作模型
// *
// * @param obj 传递的消息 (如果是对象需要序列化)
// * @return 结果集
// * 多个消费者,你一个我一个分配消费消息,有预取机制,默认公平消费,可配置 能者多劳模式(),谁完成的快,谁多做一点
// */
// public Result<?> workSendMessage(String queueName, Object obj, String msg) {
//
// log.info("【工作模型mq】 : method: 【 workSendMessage 】 - ages: 【 String : {}, Object : {}, String : {} 】 ---> 【 消息发送中。。。 】", queueName, obj, msg);
// // 发送简单模型消息
// // 第一个参数: 绑定规则 相当于 队列名称
// // 第二个参数:消息内容
// rabbitTemplate.convertAndSend(queueName, obj, message -> {
// message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
// return message;
// } );
//
// log.info("【工作模型mq】 : method: 【 workSendMessage 】- queue: 【 {} 】 ---> 【 消息发送成功 】", queueName);
//
// return Result.success("消息发送成功");
// }
//
// /**
// * Publish/Subscribe 发布订阅者模型
// * 多个消费者,多个消费者可以同时接收到消息 有交换机 类型 fanout
// *
// * @param exchange 交换机名称
// * @param obj 发送的消息Object
// * @param msg 响应的内容
// * @return 结果集
// */
// public Result<?> publishSubscribeSendMessage(String exchange, Object obj, String msg) {
//
// log.info("【订阅模型mq】 : method: 【 workSendMessage 】 - ages: 【 String : {}, Object : {}, String : {} 】 ---> 【 消息发送中。。。 】", exchange, obj, msg);
// // 发送简单模型消息
// // 第一个参数: exchange 交换机的名称
// // 第二个参数: 绑定规则 发布订阅者模型 不写 默认 "" 只要绑定就行 不需要规则
// // 第三个参数:消息内容
// rabbitTemplate.convertAndSend(exchange, "", obj, message -> {
// message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
// return message;
// } );
//
// log.info("【订阅模型mq】 : method: 【 workSendMessage 】- exchange: 【 {} 】 ---> 【 消息发送成功 】", exchange);
//
// return Result.success("消息发送成功");
// }
//
// /**
// * Routing路由模型
// * 使用的是 Direct 类型的交换机,会将接收到的消息根据 规则 路由到指定的Queue(队列),因此称为路由模式
// *
// * @param exchange 交换机名称
// * @param rule 绑定规则 一个字符串即可
// * @param obj 发送的消息Object
// * @param msg 响应的内容
// * @return 结果集
// */
// public Result<?> routingSendMessage(String exchange, String rule, Object obj, String msg) {
//
// log.info("【路由模型mq】 : method: 【 workSendMessage 】 - ages: 【 String : {}, Object : {}, String : {} 】 ---> 【 消息发送中。。。 】", exchange, obj, msg);
// // 发送简单模型消息
// // 第一个参数: 绑定规则 相当于 队列名称
// // 第二个参数:消息内容
// rabbitTemplate.convertAndSend(exchange, rule, obj, message -> {
// message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
// return message;
// } );
//
// log.info("【路由模型mq】 : method: 【 workSendMessage 】- exchange: 【 {} 】 ---> 【 消息发送成功 】", exchange);
//
// return Result.success("消息发送成功");
// }
//
//
// /**
// * Topic主题模型模型
// * 使用的是 topic 类型的交换机
// *
// * @param exchange 交换机名称
// * @param rule 绑定规则 可以绑定多个单词以 . 拼接 也可以使用 #(匹配 零个 一个 或 多个 单词) 或 *(匹配 一个 单词) 通配符例如name.msg, *.msg, age.#
// * @param obj 发送的消息Object
// * @param msg 响应的内容
// * @return 结果集
// */
// public Result<?> topicSendMessage(String exchange, String rule, Object obj) {
//
// log.info("【主题模型mq】 : method: 【 workSendMessage 】 - ages: 【 String : {}, Object : {} 】 ---> 【 消息发送中。。。 】", exchange, obj);
// // 发送简单模型消息
// // 第一个参数: 绑定规则 相当于 队列名称
// // 第二个参数:消息内容
// rabbitTemplate.convertAndSend(exchange, rule, obj, message -> {
// message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
// return message;
// } );
//
// log.info("【主题模型mq】 : method: 【 workSendMessage 】- exchange: 【 {} 】 ---> 【 消息发送成功 】", exchange);
//
// return Result.success(obj,"消息发送成功");
// }
/**
*
* @param param
* @param delayTime
* @return
*/
// public Result<?> delayedSendMessage(Long delayTime, Object param) {
// log.info("【延迟队列模型】 : method: 【 delayedSendMessage 】 消息内容:{}---> 【 消息发送中。。。 】",param);
//
// rabbitTemplate.convertAndSend(RabbitmqConstants.DELAYED_EXCHANGE_NAME, RabbitmqConstants.DELAYED_ROUTING_KEY,param, message -> {
// MessageProperties messageProperties = message.getMessageProperties();
// messageProperties.setMessageId(UUID.randomUUID().toString());
// messageProperties.setDelayLong(delayTime);
// return message;
// });
// log.info("【延迟队列模型】 : method: 【 delayedSendMessage 】 消息内容:{}---> 【 消息发送成功 】",param);
//
// return Result.success(param,"消息发送成功");
//
// }
}

View File

@ -1 +1,6 @@
com.muyu.common.rabbit.RabbitListenerConfigurer
com.muyu.rabbitmq.producer.RabbitMQProducerUtil
com.muyu.rabbitmq.consumer.RabbitMQConsumerUtil
com.muyu.rabbitmq.config.RabbitmqConfig
com.muyu.rabbitmq.config.MyConfirmCallback
com.muyu.rabbitmq.config.RabbitAdminConfig
com.muyu.rabbitmq.config.ReturnCallbackConfig

View File

@ -40,7 +40,7 @@ import java.util.Map;
public class ManyDataSource implements ApplicationRunner{
private List<EntInfo> dataSourceInfoList(){
RemoteSaaSService remoteSaaSService = SpringUtils.getBean(RemoteSaaSService.class);
Result<List<Datasource>> tableDataInfoResult = remoteSaaSService.findDatabaseList();
Result<List<Datasource>> tableDataInfoResult = remoteSaaSService.findDatabaseList();
if (tableDataInfoResult==null){
throw new SaaSException("saas远调数据源错误");
}

View File

@ -1,23 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.muyu</groupId>
<artifactId>cloud-common</artifactId>
<version>3.6.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.bwie</groupId>
<artifactId>cloud-common-swagger</artifactId>
<description>
cloud-common-swagger swagger2文档聚合
cloud-common-swagger系统接口
</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -1,10 +1,21 @@
package com.muyu.common.swagger.annotation;
import com.muyu.common.swagger.config.SwaggerAutoConfiguration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author
* @packagecom.muyu.common.swagger.annotation
* @nameEnableCustomSwagger2
* @date2024/9/29 10:01
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({SwaggerAutoConfiguration.class})
public @interface EnableCustomSwagger2 {
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import java.util.stream.Collectors;
/**
* springboot 2.6.x
* @author
* @packagecom.muyu.common.swagger.config
* @nameSwaggerBeanPostProcessor

View File

@ -300,4 +300,3 @@ public class SwaggerProperties {
}
}
}

View File

@ -0,0 +1,42 @@
package com.muyu.common.system.domain;
import com.muyu.common.core.annotation.Excel;
import com.muyu.common.core.annotation.Excel.ColumnType;
import com.muyu.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
*
* @author
* @package com.muyu.common.system.domain
* @name Enterprise
* @date 2024/9/30 12:05
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Enterprise extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* Id
*/
@Excel(name = "企业序号",cellType = ColumnType.NUMERIC, prompt = "企业编号")
private Integer id;
/**
*
*/
@Excel(name = "企业名称")
private String firmName;
/**
*
*/
@Excel(name = "数据库名称")
private String databaseName;
}

View File

@ -4,6 +4,7 @@ import com.muyu.common.core.constant.SecurityConstants;
import com.muyu.common.core.constant.ServiceNameConstants;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.web.page.TableDataInfo;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.domain.SysFirmUser;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.remote.factory.RemoteUserFallbackFactory;
@ -44,4 +45,13 @@ public interface RemoteUserService {
@GetMapping("/user/companyList")
Result<List<SysUser>> companyList();
/**
*
* @param enterprise
* @param source
* @return
*/
@PostMapping("/user/settlement")
Result<Boolean>settlementEnterpriseInfo(@RequestBody Enterprise enterprise, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -2,6 +2,7 @@ package com.muyu.common.system.remote.factory;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.web.page.TableDataInfo;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.domain.SysFirmUser;
import com.muyu.common.system.remote.RemoteUserService;
import com.muyu.common.system.domain.SysUser;
@ -41,6 +42,11 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
return Result.error("获取企业列表失败:" + throwable.getMessage());
}
@Override
public Result<Boolean> settlementEnterpriseInfo(Enterprise enterprise, String source) {
return Result.error("入驻企业失败");
}
};
}
}

View File

@ -23,6 +23,7 @@
<module>cloud-common-saas</module>
<module>cloud-common-swagger</module>
<module>cloud-common-cache</module>
<module>cloud-common-kafka</module>
</modules>
<artifactId>cloud-common</artifactId>

View File

@ -7,7 +7,7 @@ nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# Spring
spring:

View File

@ -54,13 +54,6 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
@ -110,11 +103,23 @@
<artifactId>node-commons</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-kafka</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-rabbit</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>saas-cache</artifactId>
<version>3.6.3</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,26 @@
package com.muyu.event.basic;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.context.ApplicationEvent;
/**
*
* @author
* @packagecom.muyu.event.Basic
* @nameEventCustom
* @date2024/9/29 21:17
*/
public class EventCustom extends ApplicationEvent {
private JSONObject data;
public EventCustom(Object source,JSONObject data) {
super(source);
this.data=data;
}
public JSONObject getData(){
return data;
}
}

View File

@ -0,0 +1,17 @@
package com.muyu.event.basic;
import org.springframework.context.ApplicationListener;
/**
*
* @author
* @packagecom.muyu.event.basic
* @nameEventListener
* @date2024/9/29 21:21
*/
public interface EventListener extends ApplicationListener<EventCustom> {
void onEvent(EventCustom event);
}

View File

@ -0,0 +1,31 @@
package com.muyu.event.basic;
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
/**
*
* @author
* @packagecom.muyu.event.basic
* @nameEventPublisher
* @date2024/9/29 22:01
*/
@Component
public class EventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher=applicationEventPublisher;
}
public void publishEvent(JSONObject jsonObject){
EventCustom event = new EventCustom(this, jsonObject);
publisher.publishEvent(event);
}
}

View File

@ -1,25 +0,0 @@
package com.muyu.event.basics;
/**
* @author
* @package
* @nameEventHandler
* @date2024/9/29
*/
public class EventHandler {
private static final ThreadLocal<EventQueueConfig> EVENT_THREAD = new ThreadLocal<>();
public static void set(final EventQueueConfig handler) {
EVENT_THREAD.set(handler);
}
public static EventQueueConfig get() {
return EVENT_THREAD.get();
}
public static void remove(){
EVENT_THREAD.remove();
}
}

View File

@ -1,25 +0,0 @@
package com.muyu.event.basics;
public abstract class EventProcessBasics {
/**
*
*/
protected EventProcessBasics nextEvent;
/**
*
* @param nextHandler
*/
public void setNextHandler(EventProcessBasics nextHandler) {
this.nextEvent = nextHandler;
}
/**
*
* @param eventKey key
*/
public abstract void handleEvent(String eventKey);
}

View File

@ -1,35 +0,0 @@
package com.muyu.event.basics;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @author
* @package
* @nameEventQueueConfig
* @date2024/9/29
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EventQueueConfig {
private LinkedBlockingDeque<EventProcessBasics> taskNodeQueue = new LinkedBlockingDeque<>();
public void addEvent(EventProcessBasics obj){
this.taskNodeQueue.add(obj);
}
public boolean hashEventNext(){
return !taskNodeQueue.isEmpty();
}
private EventProcessBasics nextTaskNode(){
return taskNodeQueue.poll();
}
}

View File

@ -1,28 +0,0 @@
package com.muyu.event.basics;
import com.muyu.event.domian.EventActuate;
import org.springframework.context.ApplicationEvent;
import java.util.List;
/**
* @author
* @package
* @nameStartEvent
* @date2024/9/29
*/
public class StartEvent extends ApplicationEvent {
private EventActuate eventActuate;
public StartEvent(EventActuate source) {
super(source);
this.eventActuate = source;
}
public EventActuate getEventActuate() {
return eventActuate;
}
}

View File

@ -0,0 +1,23 @@
package com.muyu.event.config;
import com.muyu.event.listener.AddDatabaseListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author
* @packagecom.muyu.event.config
* @nameEventConfig
* @date2024/9/29 21:13
*/
@Configuration
public class EventConfig {
@Bean
public AddDatabaseListener addDatabaseListener() {
return new AddDatabaseListener();
}
}

View File

@ -66,9 +66,7 @@ public class IoTDBConfig {
measurements.add("car_vin");
measurements.add("information");
session.insertRecord(TABLENAME,System.currentTimeMillis(),measurements,list);
//关闭连接
session.close();
} catch (IoTDBConnectionException e) {

View File

@ -1,129 +0,0 @@
package com.muyu.event.config;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.support.serializer.JsonDeserializer;
import java.util.HashMap;
import java.util.Map;
/**
* @author
* @date 2022/10/31 18:05
* kafkaymlyml
*/
@SpringBootConfiguration
public class KafkaConsumerConfig {
/**
* Kafka
*/
@Value("${spring.kafka.consumer.bootstrap-servers}")
private String bootstrapServers;
/**
*
*/
@Value("${spring.kafka.consumer.group-id}")
private String groupId;
/**
*
*/
@Value("${spring.kafka.consumer.enable-auto-commit}")
private boolean enableAutoCommit;
/**
* Kafka
*/
@Value("${spring.kafka.properties.session.timeout.ms}")
private String sessionTimeout;
/**
* poll5reBalance
*/
@Value("${spring.kafka.properties.max.poll.interval.ms}")
private String maxPollIntervalTime;
@Value("${spring.kafka.consumer.max-poll-records}")
private String maxPollRecords;
@Value("${spring.kafka.consumer.auto-offset-reset}")
private String autoOffsetReset;
@Value("${spring.kafka.listener.concurrency}")
private Integer concurrency;
@Value("${spring.kafka.listener.missing-topics-fatal}")
private boolean missingTopicsFatal;
@Value("${spring.kafka.listener.poll-timeout}")
private long pollTimeout;
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> propsMap = new HashMap<>(16);
propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
//是否自动提交偏移量默认值是true为了避免出现重复数据和数据丢失可以把它设置为false然后手动提交偏移量
propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
//自动提交的时间间隔,自动提交开启时生效
propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "2000");
//该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
//earliest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时从头开始消费分区的记录
//latest当各分区下有已提交的offset时从提交的offset开始消费无提交的offset时消费新产生的该分区下的数据在消费者启动之后生成的记录
//none当各分区都存在已提交的offset时从提交的offset开始消费只要有一个分区不存在已提交的offset则抛出异常
propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
//两次poll之间的最大间隔默认值为5分钟。如果超过这个间隔会触发reBalance
propsMap.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalTime);
//这个参数定义了poll方法最多可以拉取多少条消息默认值为500。如果在拉取消息的时候新消息不足500条那有多少返回多少如果超过500条每次只返回500。
//这个默认值在有些场景下太大有些场景很难保证能够在5min内处理完500条消息
//如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
//然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
//要避免出现上述问题提前评估好处理一条消息最长需要多少时间然后覆盖默认的max.poll.records参数
//注需要开启BatchListener批量监听才会生效如果不开启BatchListener则不会出现reBalance情况
propsMap.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
//当broker多久没有收到consumer的心跳请求后就触发reBalance默认值是10s
propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
//序列化建议使用Json这种序列化方式可以无需额外配置传输实体类
propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
return propsMap;
}
@Bean
public ConsumerFactory<Object, Object> consumerFactory() {
// 配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
try (JsonDeserializer<Object> deserializer = new JsonDeserializer<>()) {
deserializer.trustedPackages("*");
return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new JsonDeserializer<>(), deserializer);
}
}
/**
* kafka Kafka
* @return
*/
@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Object, Object>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
//在侦听器容器中运行的线程数,一般设置为 机器数*分区数
factory.setConcurrency(concurrency);
// 消费监听接口监听的主题不存在时默认会报错所以设置为false忽略错误
factory.setMissingTopicsFatal(missingTopicsFatal);
// 自动提交关闭,需要设置手动消息确认
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
factory.getContainerProperties().setPollTimeout(pollTimeout);
// 设置为批量监听需要用List接收
// factory.setBatchListener(true);
return factory;
}
}

View File

@ -1,127 +0,0 @@
package com.muyu.event.config;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.transaction.KafkaTransactionManager;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@Configuration
public class KafkaProviderConfig {
/**
* kafka
*/
@Value("${spring.kafka.producer.bootstrap-servers}")
private String bootstrapServers;
/**
* Kafka
*/
@Value("${spring.kafka.producer.transaction-id-prefix}")
private String transactionIdPrefix;
/**
*
*/
@Value("${spring.kafka.producer.acks}")
private String acks;
/**
*
*/
@Value("${spring.kafka.producer.retries}")
private String retries;
/**
*
*/
@Value("${spring.kafka.producer.batch-size}")
private String batchSize;
/**
*
*/
@Value("${spring.kafka.producer.buffer-memory}")
private String bufferMemory;
/**
*
*/
@Value("${spring.kafka.producer.key-serializer}")
private String keySerializer;
/**
*
*/
@Value("${spring.kafka.producer.value-serializer}")
private String valueSerializer;
/**
* map
* @return
*/
@Bean
public Map<String, Object> producerConfigs() {
Map<String, Object> props = new HashMap<>(16);
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
//acks=0 生产者在成功写入消息之前不会等待任何来自服务器的响应。
//acks=1 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
//acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
//开启事务必须设为all
props.put(ProducerConfig.ACKS_CONFIG, acks);
//发生错误后消息重发的次数开启事务必须大于0
props.put(ProducerConfig.RETRIES_CONFIG, retries);
//当多个消息发送到相同分区时,生产者会将消息打包到一起,以减少请求交互. 而不是一条条发送
//批次的大小可以通过batch.size 参数设置.默认是16KB
//较小的批次大小有可能降低吞吐量批次大小为0则完全禁用批处理
//比如说kafka里的消息5秒钟Batch才凑满了16KB才能发送出去。那这些消息的延迟就是5秒钟
//实测batchSize这个参数没有用
props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
//有的时刻消息比较少,过了很久,比如5min也没有凑够16KB,这样延时就很大,所以需要一个参数. 再设置一个时间,到了这个时间,
//即使数据没达到16KB,也将这个批次发送出去
props.put(ProducerConfig.LINGER_MS_CONFIG, "5000");
//生产者内存缓冲区的大小
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
//反序列化,和生产者的序列化方式对应
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, keySerializer);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, valueSerializer);
return props;
}
/**
*
* @return
*/
@Bean
public ProducerFactory<Object, Object> producerFactory() {
DefaultKafkaProducerFactory<Object, Object> factory = new DefaultKafkaProducerFactory<>(producerConfigs());
//开启事务,会导致 LINGER_MS_CONFIG 配置失效
factory.setTransactionIdPrefix(transactionIdPrefix);
return factory;
}
/**
* Kafka
* @param producerFactory
* @return
*/
@Bean
public KafkaTransactionManager<Object, Object> kafkaTransactionManager(ProducerFactory<Object, Object> producerFactory) {
return new KafkaTransactionManager<>(producerFactory);
}
/**
* KafkaTemplate
* @return
*/
@Bean
public KafkaTemplate<Object, Object> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}

View File

@ -1,65 +0,0 @@
package com.muyu.event.config;
import jakarta.annotation.Nullable;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.ProducerListener;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class KafkaSendResultHandler implements ProducerListener<Object,Object> {
@Autowired
private KafkaTemplate<Object,Object> kafkaTemplate;
/**
* bean
*/
@PostConstruct
public void init(){
this.kafkaTemplate.setProducerListener(this);
}
/**
* Kafka
* @param producerRecord
* @param recordMetadata
*/
@Override
public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata){
System.out.println("信息发送成功:"+ producerRecord.toString());
}
/**
* Kafka
* @param producerRecord the failed record
* @param recordMetadata The metadata for the record that was sent (i.e. the partition
* and offset). If an error occurred, metadata will contain only valid topic and maybe
* the partition. If the partition is not provided in the ProducerRecord and an error
* occurs before partition is assigned, then the partition will be set to
* RecordMetadata.UNKNOWN_PARTITION.
* @param exception the exception thrown
*/
@Override
public void onError(ProducerRecord producerRecord, @Nullable RecordMetadata recordMetadata,
Exception exception){
System.out.println("消息发送失败: "+ producerRecord.toString());
}
}

View File

@ -1,34 +0,0 @@
package com.muyu.event.config;
import lombok.NonNull;
import org.apache.kafka.clients.consumer.Consumer;
import org.springframework.kafka.listener.KafkaListenerErrorHandler;
import org.springframework.kafka.listener.ListenerExecutionFailedException;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
@Component
public class MyKafkaListenerErrorHandler implements KafkaListenerErrorHandler {
@Override
@NonNull
public Object handleError(@NonNull Message<?> message,
ListenerExecutionFailedException exception) {
return new Object();
}
@Override
@NonNull
public Object handleError(@NonNull Message<?> message,
@NonNull ListenerExecutionFailedException exception,
Consumer<?, ?> consumer) {
System.out.println("消息详情:"+ message);
System.out.println("异常信息:"+ exception);
System.out.println("消费者详情:" +consumer.groupMetadata());
System.out.println("监听主题:"+ consumer.listTopics());
return KafkaListenerErrorHandler.super.handleError(message, exception, consumer);
}
}

View File

@ -1,15 +0,0 @@
package com.muyu.event.constant;
/**
*
* @author
* @packagecom.muyu.event.constant
* @nameEventConstant
* @date2024/9/28 19:25
*/
public interface EventConstant {
String STORAGE_EVENT = "storageEvent";
}

View File

@ -1,31 +0,0 @@
package com.muyu.event.consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
/**
* kafka
* @author
* @packagecom.muyu.event.consumer
* @nameKafkaConsumer
* @date2024/9/28 23:34
*/
public class KafkaConsumer {
@KafkaListener(topics = "data")
public void dataKafkaConsumer(ConsumerRecord<Object,Object> consumerRecord, Acknowledgment acknowledgment){
Object key = consumerRecord.key();
Object value = consumerRecord.value();
//事件调用
//消息确认消费
acknowledgment.acknowledge();
}
}

View File

@ -0,0 +1,52 @@
package com.muyu.event.consumer;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.event.basic.EventPublisher;
import lombok.extern.log4j.Log4j2;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import static org.bouncycastle.asn1.x500.style.RFC4519Style.l;
/**
* kafka
* @author
* @packagecom.muyu.event.consumer
* @nameKafkaConsumer
* @date2024/9/28 23:34
*/
@Component
@Log4j2
public class MessageConsumer implements ApplicationRunner {
@Autowired
public KafkaConsumer consumer;
@Autowired
private EventPublisher eventPublisher;
private final String topic="four_car";
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> list = Collections.singletonList(topic);
consumer.subscribe(list);
while (true){
ConsumerRecords<String,String> consumerRecords = consumer.poll(Duration.ofMillis(100));
consumerRecords.forEach(record -> {
String value = record.value();
JSONObject jsonObject = JSONObject.parseObject(value);
log.info("value:{}",value);
eventPublisher.publishEvent(jsonObject);
});
}
}
}

View File

@ -0,0 +1,92 @@
package com.muyu.event.consumer;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.cache.ElectronicFenceGroupCacheService;
import com.muyu.cache.SysCarCacheService;
import com.muyu.common.domain.database.ElectronicFenceGroup;
import com.muyu.common.domain.resp.SysCarVo;
import com.muyu.common.redis.service.RedisService;
import com.muyu.rabbitmq.consumer.RabbitMQConsumerUtil;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Date;
import java.util.List;
/**
* rabbitmq
* @author
* @packagecom.muyu.event.consumer
* @nameMqConsumer
* @date2024/10/2 14:17
*/
@Component
@Log4j2
public class MqConsumer {
@Autowired
private RedisService redisService;
@Autowired
private SysCarCacheService sysCarCacheService;
@Autowired
private ElectronicFenceGroupCacheService electronicFenceGroupCacheService;
@RabbitListener(queuesToDeclare = @Queue(name = "basic"))
public void rabbitMQBasicConsumer(String data , Message message , Channel channel) {
log.info("当前时间:{} RabbitMQConsumerUtil : {}", new Date(), message);
try {
// 获取到消息 开始消费
log.info("消息消费者接收到消息,消息内容:{}", JSONObject.toJSONString(data));
Long add = redisService.redisTemplate.opsForSet().add(data, message.getMessageProperties().getMessageId());
if (add != 1) {
return;
}
/**
* ---------------------------------------------------------------
*/
List<SysCarVo> carList = sysCarCacheService.get("carList");
ElectronicFenceGroup fenceGroupList = electronicFenceGroupCacheService.get("electronicFenceGroupList");
/**
* ------------------------------------------------------------------------------
*/
// 消费消息成功之后需要确认
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean multiple 是否批量确认 true 批量 确认小于等于当前投递序号的消息 false 单个确认
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info("xxx消费者接收到消息消息内容{},消费成功...", message);
} catch (Exception e) {
log.error("xxx消费者接收到消息消息内容{},消费消息异常,异常信息:{}", message, e);
// 消息回退 拒绝消费消息
// long deliveryTag 消息投递序号 自增的数字 在整个队列中唯一 拿到这个序号就相当于拿到这条消息
// boolean requeue 是否回到原来的队列
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
} catch (IOException ex) {
log.error("xxx消费者接收到消息消息内容{},回退消息异常,异常信息:{}", message, ex);
}
}finally {
try {
channel.close();
} catch (Exception e) {
log.error("xxx消费者关闭Channel异常消息内容{},异常信息:{}", message, e);
}
}
}
}

View File

@ -0,0 +1,23 @@
package com.muyu.event.consumer;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
/**
* 线
* @author
* @packagecom.muyu.event.consumer
* @nameOnlineConsumer
* @date2024/9/30 11:40
*/
@Component
@Log4j2
public class OnlineConsumer {
}

View File

@ -0,0 +1,21 @@
package com.muyu.event.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
* @author
* @packagecom.muyu.event.controller
* @nameDataController
* @date2024/9/29 20:16
*/
@RestController
@RequestMapping("data")
public class DataController {
}

View File

@ -19,13 +19,12 @@ import java.util.List;
* @nameItodbController
* @date2024/9/28 19:17
*/
@RestController()
@RestController
public class IoTDBController {
@Autowired
private IoTDBService tdbService;
/**
*
* @return list
@ -47,7 +46,6 @@ public class IoTDBController {
return Result.success(carInformation);
};
/**
*
* @param addCarInformation
@ -59,16 +57,4 @@ public class IoTDBController {
return Result.success("添加成功");
};
}

View File

@ -0,0 +1,68 @@
package com.muyu.event.controller;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.rabbitmq.producer.RabbitMQProducerUtil;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
*
* @author
* @packagecom.muyu.event.controller
* @nameTestController
* @date2024/9/29 20:58
*/
@RestController("test")
public class TestController {
@Resource
private KafkaProducer kafkaProducer;
@Resource
private RabbitMQProducerUtil rabbitMQProducerUtil;
private static final String topic="four_car";
@GetMapping("sendKafka")
public String sendKafka(){
String message="发送一条信息";
JSONObject jsonObject = new JSONObject();
jsonObject.put("cj","hh");
ProducerRecord<String, String> producerRecord = new ProducerRecord<String, String>(topic,jsonObject.toString());
kafkaProducer.send(producerRecord);
return "success";
}
@GetMapping("sendMq")
public String sendMq(){
String message="发送一条信息-mq";
rabbitMQProducerUtil.basicSendMessage("basic",message);
return "success-mq";
};
}

View File

@ -13,7 +13,13 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
*
* @author
* @packagecom.muyu.event.domain
* @nameEvent
* @date2024/9/28 23:10
*/
@Data
@AllArgsConstructor
@NoArgsConstructor

View File

@ -1,28 +0,0 @@
package com.muyu.event.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
* @Author
* @Data 2024/9/29
*/
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class EventActuate {
/**
* json
*/
private String jsonData;
/**
* key
*/
private List<String> eventKeys;
}

View File

@ -1,25 +0,0 @@
package com.muyu.event.eventDispose;
import com.muyu.event.basics.StartEvent;
import com.muyu.event.domian.EventActuate;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* @author
* @package
* @nameAutoStartupEventListener
* @date2024/9/29
*/
@Component
public class AutoStartupEventListener implements ApplicationListener<StartEvent> {
@Override
public void onApplicationEvent(StartEvent event) {
EventActuate eventActuate = event.getEventActuate();
}
}

View File

@ -1,37 +0,0 @@
package com.muyu.event.eventDispose;
import com.muyu.event.basics.EventProcessBasics;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;
/**
* @author
* @package
* @nameStorageEvent
* @date2024/9/29
*/
@EqualsAndHashCode(callSuper = true)
@Log4j2
@Data
@AllArgsConstructor
public class StorageEvent extends EventProcessBasics {
/**
*
*/
private String eventName;
@Override
public void handleEvent(String eventKey) {
if (eventKey.equals(eventName)){
log.info("开始执行 [{}] 事件", eventKey);
}else if (nextEvent != null){
nextEvent.handleEvent(eventKey);
}else {
log.info("处理结束,最后处理的事件为 [{}]", eventKey);
}
}
}

View File

@ -0,0 +1,38 @@
package com.muyu.event.listener;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.event.basic.EventCustom;
import com.muyu.event.basic.EventListener;
import java.util.ArrayList;
import java.util.List;
/**
*
* @program: cloud-server
* @author: cuiyongxing
* @create: 2024-09-29 17:34
**/
public class AddDatabaseListener implements EventListener {
@Override
public void onEvent(EventCustom event) {
JSONObject jsonObject = event.getData();
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
jsonObject.forEach((key, value) -> {
keys.add(key);
values.add((String) value);
});
}
@Override
public void onApplicationEvent(EventCustom event) {
onEvent(event);
}
}

View File

@ -0,0 +1,19 @@
package com.muyu.event.service;
/**
* @author
* @packagecom.muyu.event.service.impl
* @nameDataService
* @date2024/9/29 20:23
*/
public interface DataService {
void warnData(String data);
}

View File

@ -0,0 +1,10 @@
package com.muyu.event.service;
/**
* @author
* @packagecom.muyu.event.service
* @nameTestService
* @date2024/9/29 20:59
*/
public interface TestService {
}

View File

@ -0,0 +1,26 @@
package com.muyu.event.service.impl;
import com.muyu.event.service.DataService;
import org.springframework.stereotype.Service;
/**
* @author
* @packagecom.muyu.event.service.impl
* @nameDataServiceImpl
* @date2024/9/29 20:24
*/
@Service
public class DataServiceImpl implements DataService {
@Override
public void warnData(String data) {
}
}

View File

@ -0,0 +1,20 @@
package com.muyu.event.service.impl;
import com.muyu.event.service.TestService;
import org.springframework.stereotype.Service;
/**
* @author
* @packagecom.muyu.event.service.impl
* @nameTestServiceImpl
* @date2024/9/29 21:00
*/
@Service
public class TestServiceImpl implements TestService {
}

View File

@ -0,0 +1,37 @@
package com.muyu.event.util;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.stereotype.Component;
/**
*
*
* @program: cloud-server
* @author:
* @create: 2024-09-30 10:08
**/
@Component
public class CacheUtil<T> {
private final Cache<String, T> cache;
public CacheUtil() {
this.cache = Caffeine.newBuilder()
.maximumSize(500L)
.build();
}
public T get(String key) {
return cache.getIfPresent(key);
}
public void put(String key, T value) {
cache.put(key, value);
}
public void remove(String key) {
cache.invalidate(key);
}
}

View File

@ -1,14 +1,16 @@
# Tomcat
server:
port: 10009
# nacos线上地址
nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# SPRING_AMQP_DESERIALIZATION_TRUST_ALL=true spring.amqp.deserialization.trust.all
# Spring
spring:
amqp:
deserialization:
trust:
@ -51,9 +53,8 @@ nacos:
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# xxl-job 配置文件
- application-xxl-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# rabbit 配置文件
- application-rabbit-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
logging:
level:
com.muyu.fence.mapper: DEBUG
com.muyu.system.mapper: DEBUG

View File

@ -7,7 +7,7 @@ nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# Spring
spring:

View File

@ -9,7 +9,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
*
*
*
* @author ruoyi
*/

View File

@ -40,7 +40,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
*
*
*
* @author ruoyi
*/

View File

@ -7,7 +7,7 @@ nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# SPRING_AMQP_DESERIALIZATION_TRUST_ALL=true spring.amqp.deserialization.trust.all
# Spring
spring:

View File

@ -10,10 +10,7 @@ import com.muyu.common.log.enums.BusinessType;
import com.muyu.common.security.annotation.InnerAuth;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.SysDept;
import com.muyu.common.system.domain.SysRole;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.domain.LoginUser;
import com.muyu.common.system.domain.*;
import com.muyu.system.domain.resp.AuthRoleResp;
import com.muyu.system.domain.resp.UserDetailInfoResp;
import com.muyu.system.domain.resp.UserInfoResp;
@ -136,6 +133,15 @@ public class SysUserController extends BaseController {
return Result.success(userService.registerUser(sysUser));
}
/**
*
*/
@InnerAuth
@PostMapping("/enterprise")
public Result<Boolean> enterprise (@RequestBody Enterprise enterprise){
return Result.success(userService.enterprise(enterprise));
}
/**
*
*

View File

@ -1,6 +1,7 @@
package com.muyu.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.domain.SysUser;
import org.apache.ibatis.annotations.Param;
@ -66,6 +67,8 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
*/
int insertUser(SysUser user);
int enterprise(Enterprise enterprise);
/**
*
*
@ -142,4 +145,6 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
List<SysUser> selectCompanyList();
}

View File

@ -7,7 +7,7 @@ import com.muyu.system.domain.vo.TreeSelect;
import java.util.List;
/**
*
*
*
* @author muyu
*/

View File

@ -1,6 +1,7 @@
package com.muyu.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.domain.SysUser;
import java.util.List;
@ -133,6 +134,7 @@ public interface SysUserService extends IService<SysUser> {
*/
boolean registerUser(SysUser user);
boolean enterprise(Enterprise enterprise);
/**
*
*
@ -228,4 +230,5 @@ public interface SysUserService extends IService<SysUser> {
List<SysUser> selectCompanyList();
}

View File

@ -8,6 +8,7 @@ import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.core.utils.bean.BeanValidators;
import com.muyu.common.datascope.annotation.DataScope;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.Enterprise;
import com.muyu.common.system.domain.SysRole;
import com.muyu.common.system.domain.SysUser;
import com.muyu.system.domain.SysPost;
@ -257,6 +258,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return userMapper.insertUser(user) > 0;
}
@Override
public boolean enterprise(Enterprise enterprise){
return userMapper.enterprise(enterprise) > 0;
}
/**
*
*

View File

@ -7,7 +7,7 @@ nacos:
addr: 47.101.53.251:8848
user-name: nacos
password: nacos
namespace: four
namespace: yzl
# SPRING_AMQP_DESERIALIZATION_TRUST_ALL=true spring.amqp.deserialization.trust.all
# Spring
spring:

View File

@ -221,6 +221,9 @@
sysdate()
)
</insert>
<insert id="enterprise">
INSERT INTO `datasource`.`datasource` (`id`, `firm_name`, `database_name`) VALUES (NULL, #{firmName}, #{databaseName});
</insert>
<update id="updateUser" parameterType="com.muyu.common.system.domain.SysUser">
update sys_user

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.muyu</groupId>
<artifactId>cloud-modules</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>cloud-modules-template</artifactId>
<description>
cloud-modules-template 协议解析模块
</description>
<dependencies>
<!-- 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>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- MuYu Common DataSource -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-datasource</artifactId>
</dependency>
<!-- MuYu Common DataScope -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-datascope</artifactId>
</dependency>
<!-- MuYu Common Log -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-log</artifactId>
</dependency>
<!-- 接口模块 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-api-doc</artifactId>
</dependency>
<!-- XllJob定时任务 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-xxl</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,27 @@
package com.muyu.template;
import com.muyu.common.security.annotation.EnableCustomConfig;
import com.muyu.common.security.annotation.EnableMyFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author liuxinyue
* @Packagecom.muyu.template
* @nameCloudTemplateApplication
* @Date2024/9/30 10:36
*/
@EnableCustomConfig
//@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication
public class CloudTemplateApplication {
public static void main(String[] args) {
SpringApplication.run(CloudTemplateApplication.class, args);
}
}

View File

@ -0,0 +1,10 @@
package com.muyu.template.service;
/**
* @author liuxinyue
* @Packagecom.muyu.template.service
* @nameTemplateService
* @Date2024/9/30 10:57
*/
public interface TemplateService {
}

View File

@ -0,0 +1,19 @@
package com.muyu.template.service.impl;
import com.muyu.template.service.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author liuxinyue
* @Packagecom.muyu.template.service.impl
* @nameTemplateServiceImpl
* @Date2024/9/30 10:57
*/
@Service
public class TemplateServiceImpl implements TemplateService {
}

View File

@ -0,0 +1,2 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/cloud-saas"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.muyu" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/cloud-saas"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<property name="log.sky.pattern" value="%d{HH:mm:ss.SSS} %yellow([%tid]) [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.sky.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 使用gRpc将日志发送到skywalking服务端 -->
<appender name="GRPC_LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${log.sky.pattern}</Pattern>
</layout>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.muyu" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="GRPC_LOG"/>
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/cloud-saas"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<property name="log.sky.pattern" value="%d{HH:mm:ss.SSS} %yellow([%tid]) [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.sky.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 使用gRpc将日志发送到skywalking服务端 -->
<appender name="GRPC_LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${log.sky.pattern}</Pattern>
</layout>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.muyu" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="GRPC_LOG"/>
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,9 @@
<?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.muyu.server.mapper.CarTypeMapper">
</mapper>

View File

@ -0,0 +1,67 @@
<?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">
<!--
1.在mybats的开发中namespace有特殊的意思一定要是对应接口的全限定名
通过namespace可以简历mapper.xml和接口之间的关系(名字不重要,位置不重要)
-->
<mapper namespace="com.muyu.server.mapper.EnterpriseDao">
<!--查询企业信息-->
<select id="selectEnterprise" resultType="HashMap" parameterType="Map">
select *
from tb_enterprise
<where>
<if test="enterpriseName != null">
and enterprise_name like concat('%',#{enterpriseName},'%')
</if>
</where>
limit #{start},#{length}
</select>
<!--查询企业记录总数-->
<select id="selectEnterpriseCount" resultType="Long">
select count(enterprise_id)
from tb_enterprise
</select>
<!--新增企业信息-->
<insert id="insert" parameterType="com.muyu.server.mapper.EnterpriseDao">
insert into tb_enterprise
set enterprise_name = #{enterpriseName},
enterprise_car_count = #{enterpriseCarCount},
enterprise_fence_count = #{enterpriseFenceCount}
</insert>
<!--根据编号查询企业信息-->
<select id="searchById" resultType="java.util.HashMap">
select enterprise_id,enterprise_name,enterprise_car_count,enterprise_fence_count
from tb_enterprise
where enterprise_id = #{enterpriseId}
</select>
<!--修改企业信息-->
<update id="updateEnterprise" parameterType="com.muyu.common.domain.Enterprise">
update tb_enterprise
set enterprise_name = #{enterpriseName},
enterprise_car_count = #{enterpriseCarCount},
enterprise_fence_count = #{enterpriseFenceCount}
where enterprise_id = #{enterpriseId} and enterprise_id != 0
</update>
<!--删除企业信息-->
<delete id="deleteByIds">
delete from tb_enterprise
where enterprise_id in
<foreach collection="ids" open="(" separator="," close=")" item="one">
#{one}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,83 @@
<?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.muyu.server.mapper.SysCarMapper">
<insert id="addSysCar">
INSERT INTO `four`.`sys_car`
( `car_vin`, `car_type_id`, `state`, `car_motor_manufacturer`, `car_motor_model`,
`car_battery_manufacturer`, `car_battery_model`, `strategy_id`,`group_id`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`,)
VALUES (#{carVin}, #{carTypeId}, '1', #{carMotorManufacturer}, #{carMotorModel},
#{carBatteryManufacturer}, #{carBatteryModel}, #{strategyId},#{groupId},#{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{remark})
</insert>
<update id="updSysCarById">
UPDATE `four`.`sys_car`
SET `car_vin` = #{carVin},
`car_type_id` = #{carTypeId},
`state` = #{state},
`car_motor_manufacturer` = #{carMotorManufacturer},
`car_motor_model` = #{carMotorModel},
`car_battery_manufacturer` = #{carBatteryManufacturer},
`car_battery_model` = #{carBatteryModel},
`strategy_id` = #{strategyId},
`group_id`=#{groupId}
`create_by` = #{createBy},
`create_time` = #{createTime},
`update_by` = #{updateBy},
`update_time` = #{updateTime},
`remark` = #{remark} WHERE `id` = #{id}
</update>
<select id="selectSysCarVoList" resultType="com.muyu.common.domain.resp.SysCarVo">
SELECT * ,car_type.type_name,warn_strategy.strategy_name,electronic_fence_group.group_name
FROM `sys_car`
LEFT JOIN car_type ON sys_car.car_type_id=car_type.id
LEFT JOIN warn_strategy ON sys_car.strategy_id=warn_strategy.id
LEFT JOIN electronic_fence_group ON sys_car.group_id=electronic_fence_group.id
<where>
<if test="carVin!=null and carVin!=''">
sys_car.car_vin=#{carVin}
</if>
<if test="state!=null and state!=''">
and sys_car.state=#{state}
</if>
<if test="carMotorManufacturer!=null and carMotorManufacturer!=''">
and sys_car.car_motor_manufacturer=#{carMotorManufacturer}
</if>
<if test="carBatteryManufacturer!=null and carBatteryManufacturer!=''">
and sys_car.car_battery_manufacturer=#{carBatteryManufacturer}
</if>
<if test="carMotorModel!=null and carMotorModel!=''">
and sys_car.car_motor_model=#{carMotorModel}
</if>
<if test="carBatteryModel!=null and carBatteryModel!=''">
and sys_car.car_battery_model=#{carBatteryModel}
</if>
</where>
</select>
<select id="selectSysCarVoById" resultType="com.muyu.common.domain.resp.SysCarVo">
SELECT * ,car_type.type_name,warn_strategy.strategy_name,electronic_fence_group.group_name
FROM `sys_car`
LEFT JOIN car_type ON sys_car.car_type_id=car_type.id
LEFT JOIN warn_strategy ON sys_car.strategy_id=warn_strategy.id
LEFT JOIN electronic_fence_group ON sys_car.group_id=electronic_fence_group.id
where sys_car.id=#{id}
</select>
<select id="findFenceByCarVin" resultType="com.muyu.common.domain.resp.SysCarFaultLogVo">
SELECT
sys_car_fault_log.*,
sys_car_fault.*
FROM
sys_car_fault_log
LEFT JOIN sys_car_fault ON sys_car_fault_log.sys_car_fault_id = sys_car_fault.id
WHERE
sys_car_fault_log.vin = #{carVin};
</select>
<select id="findCarByVin" resultType="com.muyu.common.domain.SysCar">
select * from sys_car where car_vin=#{carVin}
</select>
<select id="selectByCarVin" resultType="com.muyu.common.domain.SysCar">
select * from sys_car where car_cin=#{carVin}
</select>
</mapper>

View File

@ -0,0 +1,10 @@
<?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.muyu.server.mapper.TemplateNeedMapper">
<select id="selectByTemplateId" resultType="com.muyu.common.domain.MessageTemplateType">
SELECT * FROM `message_template_type` WHERE template_id=#{templateId}
</select>
</mapper>

View File

@ -0,0 +1,31 @@
<?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.muyu.server.mapper.WarnLogsMapper">
<insert id="addWarnLog">
INSERT INTO warn_logs VALUES
<foreach collection="list" item="warnLogs" index="index" separator=",">
(#{warnLogs.id})
</foreach>
</insert>
<select id="selectWarnLogsList" resultType="com.muyu.common.domain.resp.WarnLogsResp">
SELECT
*,
warn_rule.rule_name
FROM
warn_logs
LEFT JOIN warn_rule
ON warn_logs.warn_rule_id = warn_rule.id
</select>
<select id="selectWarnLogs" resultType="com.muyu.common.domain.resp.WarnLogsResp">
SELECT
*,
warn_rule.rule_name
FROM
warn_logs
LEFT JOIN warn_rule
ON warn_logs.warn_rule_id = warn_rule.id
where warn_rule.id=#{id}
</select>
</mapper>

View File

@ -0,0 +1,23 @@
<?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.muyu.server.mapper.WarnRuleMapper">
<select id="selectListByStrategyId" resultType="com.muyu.common.domain.resp.WarnRuleResp">
SELECT * ,warn_strategy.strategy_name,
message_template_type.message_field
FROM `warn_rule`
LEFT JOIN warn_strategy ON warn_rule.strategy_id=warn_strategy.id
LEFT JOIN message_template_type ON warn_rule.msg_type_id=message_template_type.message_template_type_id
WHERE warn_rule.strategy_id=#{strategyId}
</select>
<select id="selectWarnRuleRespList" resultType="com.muyu.common.domain.resp.WarnRuleResp">
SELECT * ,warn_strategy.strategy_name,
message_template_type.message_field
FROM `warn_rule`
LEFT JOIN warn_strategy ON warn_rule.strategy_id=warn_strategy.id
LEFT JOIN message_template_type ON warn_rule.msg_type_id=message_template_type.message_template_type_id
</select>
</mapper>

View File

@ -0,0 +1,35 @@
<?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.muyu.server.mapper.WarnStrategyMapper">
<select id="selectWarnStrategyList" resultType="com.muyu.common.domain.resp.WarnStrategyResp">
SELECT *,
car_type.type_name,
t_template.template_name
FROM `warn_strategy`
LEFT JOIN car_type ON warn_strategy.car_type_id=car_type.id
LEFT JOIN t_template ON warn_strategy.template_id=t_template.template_id
<where>
<if test="carTypeId!=null and carTypeId!=''">
car_type.id=#{carTypeId}
</if>
<if test="strategyName!=null and strategyName!=''">
and warn_strategy.strategy_name=#{strategyName}
</if>
<if test="templateId!=null and templateId!=''">
and t_template.template_id=#{templateId}
</if>
</where>
</select>
<select id="selectListByCarType" resultType="com.muyu.common.domain.resp.WarnStrategyResp">
SELECT *,
car_type.type_name,
t_template.template_name
FROM `warn_strategy`
LEFT JOIN car_type ON warn_strategy.car_type_id=car_type.id
LEFT JOIN t_template ON warn_strategy.template_id=t_template.template_id
where warn_strategy.car_type_id=#{carTypeId}
</select>
</mapper>

View File

@ -131,18 +131,7 @@
<version>4.2.0</version><!-- 请根据实际情况使用最新的版本 -->
</dependency>
<dependency>
<groupId>com.muyu.server</groupId>
<artifactId>saas-server</artifactId>
<version>3.6.3</version>
</dependency>
<!-- Forest HTTP Client -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.36</version>
</dependency>
</dependencies>
<build>

View File

@ -6,7 +6,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableMyFeignClients
public class VehicleGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(VehicleGatewayApplication.class,args);

View File

@ -1,16 +1,15 @@
package com.muyu.vehicle;
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.muyu.common.redis.service.RedisService;
import com.muyu.vehicle.config.SelectInstance;
import com.muyu.vehicle.domain.InstanceInfo;
import com.muyu.vehicle.utils.CreateClient;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.muyu.vehicle.service.OpenInstance;
import com.muyu.vehicle.service.SelectInstance;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
@ -20,113 +19,155 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@Log4j2
/**
*
*/
public class ManageInstance implements ApplicationRunner {
@Autowired
private RedisService redisService;
/**
* ID
*/
public static final String IMAGE_ID = "m-uf6ffgkry85fwu4znr6s";
/**
* ACCESS_KEY_ID
*/
public static final String ALIBABA_CLOUD_ACCESS_KEY_ID="LTAI5tGabdxedjfCh2uXHNrw";
/**
*
*/
public static final String INSTANCE_TYPE = "ecs.e-c1m1.large";
/**
* ID
*/
public static final String SECURITY_GROUP_ID = "sg-uf6glo8c4k17szhxu7sk";
/**
*ID
*/
public static final String V_SWITCH_ID = "vsw-uf6xy4rbt9ggcz93t6oib";
/**
*ACCESS_KEY_SECRET
*/
public static final String ACCESS_KEY_SECRET="NHb7wHVpesLW6Axc0bFBs6ThhuNR10";
/**
*
*/
public static final String INSTANCE_CHARGE_TY = "PostPaid";
/**
* ID
*/
public static final String IMAGE_ID="m-uf6agr9i6g27gj23om34";
public static List<String> generateInstance() throws Exception {
// 创建阿里云ECS客户端
// 创建ECS客户端对象用于后续调用ECS相关API
Client client = CreateClient.createClient();
// 配置系统盘参数
RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk =
new RunInstancesRequest.RunInstancesRequestSystemDisk()
.setSize("40")
.setCategory("cloud_essd");
/**
*
*/
public static final String INSTANCE_TYPE="ecs.e-c1m1.large";
// 创建创建实例请求对象并设置参数
/**
* ID
*/
public static final String SECURITY_GROUP_ID="sg-uf6glo8c4k17szhxu7sk";
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
.setRegionId("cn-shanghai") // 设置地域ID
.setImageId(IMAGE_ID) // 设置镜像ID
.setInstanceType(INSTANCE_TYPE) // 设置实例类型
.setSecurityGroupId(SECURITY_GROUP_ID) // 设置安全组ID
.setVSwitchId(V_SWITCH_ID) // 设置虚拟交换机ID
.setInstanceName("cloud-MQTT") // 设置实例名称
.setInstanceChargeType(INSTANCE_CHARGE_TY) // 设置实例付费类型为后付费按量付费
.setSystemDisk(systemDisk) // 设置系统盘配置
.setHostName("root") // 设置主机名
.setPassword("2112A-four") // 设置实例密码
.setAmount(2) // 设置创建实例的数量
.setInternetChargeType("PayByTraffic")
.setInternetMaxBandwidthOut(1);
/**
*ID
*/
public static final String V_SWITCH_ID="vsw-uf6xy4rbt9ggcz93t6oib";
//创建运行时选择对象
RuntimeOptions runTime =
new RuntimeOptions();
// 尝试执行创建实例请求
try {
ArrayList<String> list = new ArrayList<>();
// 复制代码运行请自行打印 API 的返回值
RunInstancesResponse runInstancesResponse = client.runInstancesWithOptions(runInstancesRequest, runTime);
RunInstancesResponseBody body = runInstancesResponse.getBody();
for (String instance : body.getInstanceIdSets().getInstanceIdSet()) {
list.add(instance);
}
log.info("ESC创建成功,实例ID为:" + list);
return list;
} catch (TeaException error) {
// 错误 message
log.info(error.getMessage());
// 诊断地址
log.info(error.getData().get("Recommend"));
Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
log.info("实例创建失败:" + error.getMessage());
}
return null;
}
/**
*
*/
public static final String INSTANCE_CHARGE_TY="PostPaid";
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> list = generateInstance();
log.info("创建实例成功");
log.info("正在加载实例");
Thread.sleep(30000);
List<InstanceInfo> instanceInfos = SelectInstance.selectInstance(list);
log.info("实例信息加载成功");
for (InstanceInfo instanceInfo : instanceInfos) {
redisService.getCacheObject(instanceInfo.getInstanceId());
} log.info("实例信息:{}",instanceInfos);
}
/**
* 使AK&SKClient
* @return Client
* @throws Exception
*/
public static Client createClient() throws Exception {
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
Config config = new Config()
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId(ALIBABA_CLOUD_ACCESS_KEY_ID)
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
.setAccessKeySecret(ACCESS_KEY_SECRET);
// Endpoint 请参考 https://api.aliyun.com/product/Ecs
config.endpoint = "ecs-cn-hangzhou.aliyuncs.com";
return new com.aliyun.ecs20140526.Client(config);
}
public static void generateInstance() throws Exception {
// 创建阿里云ECS客户端
Client client = ManageInstance.createClient();
// 配置系统盘参数
RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk=
new RunInstancesRequest.RunInstancesRequestSystemDisk()
.setSize("40")
.setCategory("cloud_essd");
// 创建创建实例请求对象并设置参数
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
.setRegionId("cn-shanghai") // 设置地域ID
.setImageId(IMAGE_ID) // 设置镜像ID
.setInstanceType(INSTANCE_TYPE) // 设置实例类型
.setSecurityGroupId(SECURITY_GROUP_ID) // 设置安全组ID
.setVSwitchId(V_SWITCH_ID) // 设置虚拟交换机ID
.setInstanceName("cloud-MQTT") // 设置实例名称
.setInstanceChargeType(INSTANCE_CHARGE_TY) // 设置实例付费类型为后付费按量付费
.setSystemDisk(systemDisk) // 设置系统盘配置
.setHostName("root") // 设置主机名
.setPassword("2112A-four") // 设置实例密码
.setAmount(2) // 设置创建实例的数量
.setInternetChargeType("PayByTraffic")
.setInternetMaxBandwidthOut(1);
//创建运行时选择对象
RuntimeOptions runTime=
new RuntimeOptions();
// 尝试执行创建实例请求
try {
ArrayList<String> list = new ArrayList<>();
// 复制代码运行请自行打印 API 的返回值
RunInstancesResponse runInstancesResponse = client.runInstancesWithOptions(runInstancesRequest, runTime);
RunInstancesResponseBody body = runInstancesResponse.getBody();
for (String instance : body.getInstanceIdSets().getInstanceIdSet()) {
list.add(instance);
}
log.info("ESC创建成功,实例ID为:" + list);
} catch (TeaException error) {
// 错误 message
log.info(error.getMessage());
// 诊断地址
log.info(error.getData().get("Recommend"));
Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
log.info("实例创建失败:"+error.getMessage());
}
}
private static List<InstanceInfo> selectInstance() throws Exception {
Client client = ManageInstance.createClient();
ArrayList<InstanceInfo> instanceInfos = new ArrayList<>();// 实例基础信息
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
.setRegionId("cn-shanghai")
.setInternetChargeType("PayByTraffic")
.setInstanceChargeType("PostPaid")
.setInstanceName("cloud-MQTT") // 设置实例名称
;
// 创建运行时选项对象
RuntimeOptions runtime = new RuntimeOptions();
//实例ID Instances.Instance.InstanceId
//实例IP Instances.Instance.PublicIpAddress.IpAddress
//状态 Instances.Instance.Status
DescribeInstancesResponse resp =client.describeInstancesWithOptions(describeInstancesRequest, runtime);
DescribeInstancesResponseBody body = resp.getBody();
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.getInstances().getInstance()){
InstanceInfo instanceInfo = new InstanceInfo();
instanceInfo.setInstanceId(instance.getInstanceId());
instanceInfo.setIpAddress(String.valueOf(instance.getPublicIpAddress().getIpAddress()));
instanceInfo.setStatus(instance.getStatus());
instanceInfos.add(instanceInfo);
}
log.info("实例信息为:"+Common.toJSONString(instanceInfos));
return instanceInfos;
}
@Override
public void run(ApplicationArguments args) throws Exception {
generateInstance();
selectInstance();
}
}

View File

@ -1,29 +0,0 @@
package com.muyu.vehicle.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//超时设置
factory.setReadTimeout(5000);//ms
factory.setConnectTimeout(15000);//ms
return factory;
}
}

View File

@ -1,53 +0,0 @@
package com.muyu.vehicle.config;
import com.alibaba.fastjson.JSON;
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.DescribeInstancesRequest;
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.muyu.vehicle.domain.InstanceInfo;
import com.muyu.vehicle.utils.CreateClient;
import lombok.extern.log4j.Log4j2;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
@Log4j2
public class SelectInstance {
public static List<InstanceInfo> selectInstance(List<String> instanceIds) throws Exception {
// 创建ECS客户端对象用于后续调用ECS相关API
Client client = CreateClient.createClient();
ArrayList<InstanceInfo> instanceInfos = new ArrayList<>();// 实例基础信息
com.aliyun.ecs20140526.models.DescribeInstancesRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeInstancesRequest()
.setInstanceIds(JSON.toJSONString(instanceIds))
.setRegionId("cn-shanghai");
// 创建运行时选项对象
RuntimeOptions runtime = new RuntimeOptions();
//实例ID Instances.Instance.InstanceId
//实例IP Instances.Instance.PublicIpAddress.IpAddress
//状态 Instances.Instance.Status
DescribeInstancesResponse resp = client.describeInstancesWithOptions(describeInstancesRequest, runtime);
DescribeInstancesResponseBody body = resp.getBody();
ArrayList<InstanceInfo> exampleInformations = new ArrayList<>();
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.getInstances().getInstance()){
InstanceInfo instanceInfo = new InstanceInfo();
instanceInfo.setInstanceId(instance.getInstanceId());
log.info("实例ID:{}",instanceInfo.getInstanceId());
instanceInfo.setStatus(instance.getStatus());
log.info("实例状态:{}",instanceInfo.getStatus());
instanceInfo.setIpAddress(String.valueOf(instance.getPublicIpAddress().getIpAddress()));
log.info("实例IP:{}",instanceInfo.getIpAddress());
exampleInformations.add(instanceInfo);
}
log.info("实例信息:{}",instanceInfos);
return instanceInfos;
}
}

View File

@ -1,19 +0,0 @@
package com.muyu.vehicle.controller;
import com.muyu.common.core.domain.Result;
import com.muyu.vehicle.domain.req.VehicleConnectionReq;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.*;
@RestController
@Log4j2
public class CarInstanceController {
@PostMapping("/receiveMsg/connect")
public Result receiveMsg(@RequestBody VehicleConnectionReq vehicleConnectionReq){
log.info("=======>"+vehicleConnectionReq);
return Result.success();
}
}

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