Compare commits

...

32 Commits

Author SHA1 Message Date
ffr 676f4fa8f3 1111 2024-04-06 11:03:16 +08:00
liuyunhu 9b0121446a Merge branch 'server_five' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five_liuyunhu 2024-04-06 10:56:16 +08:00
liuyunhu 64caa2296c 11 2024-04-06 10:56:05 +08:00
lijiayao 5184d57407 fix: 代码丢失找回 2024-04-06 10:55:51 +08:00
lijiayao ba33f9abb6 fix: 代码丢失找回 2024-04-06 10:47:14 +08:00
lijiayao a5bf87099d fix: 代码丢失找回 2024-04-06 10:28:19 +08:00
lijiayao e5761fb11f fix: 代码丢失找回 2024-04-06 10:24:27 +08:00
lijiayao d2a29b0016 fix: 代码丢失找回 2024-04-06 10:15:12 +08:00
lijiayao e8c0690352 Merge branch 'server_five_xiaoyao' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five
# Conflicts:
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/BreakdownServiceImpl.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/RealTimeDataServiceImpl.java
2024-04-06 10:10:11 +08:00
lijiayao 5c2021d6f2 Merge branch 'server_five_liuyunhu' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five
# Conflicts:
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/resources/bootstrap.yml
#	couplet-modules/couplet-business/src/main/java/com/couplet/business/server/CoupletBusinessApplication.java
#	couplet-modules/couplet-business/src/main/java/com/couplet/business/server/controller/VehicleController.java
#	couplet-modules/couplet-business/src/main/java/com/couplet/business/server/mapper/VehicleMapper.java
#	couplet-modules/couplet-business/src/main/resources/bootstrap.yml
#	couplet-modules/couplet-business/src/main/resources/mapper/business/VehicleMapper.xml
#	couplet-modules/couplet-modules-mq/pom.xml
#	couplet-modules/couplet-modules-mq/src/main/java/com/couplet/mq/CoupletMqApplatcaion.java
#	couplet-modules/couplet-modules-mq/src/main/java/com/couplet/mq/service/MqConsumer.java
2024-04-06 10:04:53 +08:00
lijiayao 8de32c8223 Merge branch 'server_five_dongxiaodong' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five
# Conflicts:
#	couplet-auth/src/main/resources/bootstrap.yml
#	couplet-gateway/src/main/resources/bootstrap.yml
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/contents/StateConstant.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/BreakdownServiceImpl.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/RealTimeDataServiceImpl.java
#	couplet-modules/couplet-modules-mq/src/main/java/com/couplet/mq/controller/MqController.java
#	couplet-modules/couplet-system/src/main/resources/bootstrap.yml
2024-04-06 10:02:18 +08:00
lijiayao abce267131 Merge branch 'server_five_fufanrui' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five 2024-04-06 09:59:54 +08:00
lijiayao 5bf55e27f3 fix: 代码丢失找回 2024-04-06 09:59:38 +08:00
dongxiaodong 1db40b4db2 修改故障类 2024-04-06 09:11:03 +08:00
dongxiaodong 1b88d35574 修改故障类 2024-04-06 09:06:07 +08:00
liuyunhu ca46bfe024 Merge branch 'server_five' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five_liuyunhu 2024-04-05 19:01:21 +08:00
liuyunhu 9419a2f0a6 11 2024-04-05 19:01:11 +08:00
dongxiaodong 9a78e4a2e2 判断异常 2024-04-05 18:39:02 +08:00
dongxiaodong 71f1bc84e2 判断异常 2024-04-05 18:01:10 +08:00
dongxiaodong 371c80d110 判断异常 2024-04-05 11:37:29 +08:00
lijiayao e5352e3778 Merge remote-tracking branch 'origin/server_five_fufanrui' into server_five_xiaoyao
# Conflicts:
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/contents/StateConstant.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/BreakdownServiceImpl.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/service/impl/RealTimeDataServiceImpl.java
2024-04-05 10:12:45 +08:00
lijiayao a49e857a78 Merge remote-tracking branch 'origin/server_five_fufanrui' into server_five_xiaoyao
# Conflicts:
#	couplet-auth/src/main/resources/bootstrap.yml
#	couplet-gateway/src/main/resources/bootstrap.yml
#	couplet-modules/couplet-system/src/main/resources/bootstrap.yml
2024-04-05 09:50:01 +08:00
lijiayao 0b9423d817 feat: 事件系统 2024-04-05 09:49:04 +08:00
dongxiaodong 976f35f212 Merge branch 'server_five_xiaoyao' into server_five_dongxiaodong
# Conflicts:
#	couplet-common/couplet-common-core/src/main/java/com/couplet/common/core/constant/ServiceNameConstants.java
#	couplet-modules/couplet-analyze/couplet-analyze-msg/pom.xml
2024-04-05 08:40:48 +08:00
dongxiaodong f81f05ae1c 判断异常 2024-04-05 08:38:19 +08:00
lijiayao 9e489bd4ec feat: 事件系统 2024-04-05 08:36:56 +08:00
lijiayao ed31af73b5 Merge remote-tracking branch 'origin/server_five_fufanrui' into server_five_xiaoyao
# Conflicts:
#	couplet-auth/src/main/resources/bootstrap.yml
#	couplet-gateway/src/main/resources/bootstrap.yml
#	couplet-modules/couplet-system/src/main/resources/bootstrap.yml
2024-04-04 15:05:23 +08:00
lijiayao 041aaa4654 feat: 事件系统 2024-04-04 15:04:25 +08:00
dongxiaodong 846073f528 删除没用的文件 2024-04-04 14:45:07 +08:00
liuyunhu 4da1d7c52e Merge branch 'server_five' of https://gitea.qinmian.online/five-groups/five-groups-couplet into server_five_liuyunhu 2024-04-04 09:43:21 +08:00
dongxiaodong eac6f6076d Merge branch 'server_five' into server_five_dongxiaodong
# Conflicts:
#	couplet-modules/couplet-analyze/couplet-analyze-msg/src/main/java/com/couplet/analyze/msg/model/ModelMessage.java
2024-04-04 09:00:38 +08:00
dongxiaodong 703997bd9b dxd解析报文 2024-04-03 10:42:30 +08:00
82 changed files with 1504 additions and 285 deletions

View File

@ -17,11 +17,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -3,12 +3,15 @@ package com.couplet.common.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.couplet.common.core.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
/**
* @author DongXiaoDong
@ -38,34 +41,28 @@ public class CoupletTroubleCode {
private String troubleCode;
/**
*
* vin
*/
@Excel(name = "故障位")
private String troublePosition;
/**
*
*/
@Excel(name = "故障值")
private String troubleValue;
@Excel(name = "vin")
private String troubleVin;
/**
*
*/
@Excel(name = "故障标签")
private String troubleTag;
private Integer troubleTag;
/**
* Id
*
*/
@Excel(name = "故障类型Id")
@NotEmpty(message = "故障类型Id不能为空")
private Integer typeId;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date troubleStartTime;
/**
* Id
*
*/
@Excel(name = "故障等级Id")
@NotEmpty(message = "故障等级Id不能为空")
private Integer gradeId;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date troubleEndTime;
}

View File

@ -19,34 +19,34 @@ import java.util.Date;
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CoupletTroubleLog {
public class CoupletTroubleFault {
/**
* Id
*/
private Integer troubleLogId;
private Integer troubleFaultId;
/**
*
*/
private String troubleLogCode;
private String troubleFaultCode;
/**
* VIN
*
*/
private String troubleLogVin;
private String troubleFaultType;
/**
*
*
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date troubleLogStartTime;
private String troubleFaultTag;
/**
*
*
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date troubleLogEndTime;
private String troubleFaultPosition;
/**
*
*/
private String troubleFaultValue;
}

View File

@ -1,15 +0,0 @@
package com.couplet.common.domain;
import lombok.Data;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/3/26 21:50
* @description
*/
@Data
public class CoupletTroubleType {
private Integer typeId;
private String typeName;
}

View File

@ -84,10 +84,11 @@ public class Fence extends BaseEntity{
private Integer alarmStatus;
@TableField(exist = false)
/**
*
*/
@TableField(exist = false)
private Integer logoId;
@TableField(exist = false)
private String logoName;

View File

@ -29,6 +29,7 @@ public class Vehicle {
* @description id
* @date
*/
@TableField(exist = false)
private Long middleId;
/*
*id

View File

@ -1,10 +0,0 @@
package com.couplet.log.annotation;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/3/28 15:39
* @description
*/
public @interface Record {
}

View File

@ -1,10 +0,0 @@
package com.couplet.log.aop;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/3/28 23:12
* @description
*/
public class AopRecord {
}

View File

@ -0,0 +1,25 @@
package com.couplet.remote;
import com.couplet.common.core.constant.ServiceNameConstants;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.remote.factory.RemoteTroubleFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(contextId = "remoteTroubleService" ,
value = ServiceNameConstants.BUSINESS_SERVICE,
fallbackFactory = RemoteTroubleFallbackFactory.class
)
public interface RemoteTroubleService {
/**
*
* @param code
* @return
*/
@PostMapping("/trouble/newFaultData")
public Result<?> newFaultData(@RequestBody CoupletTroubleCode code);
}

View File

@ -51,4 +51,7 @@ public interface RemoteVehicleService {
@GetMapping("/findByVIN/{vin}")
public Result<List<Vehicle>> findByVIN(@PathVariable("vin") String vin);
@GetMapping("onOrOutLineByVIN")
public Integer onOrOutLineByVIN(@RequestParam("params") String params);
}

View File

@ -0,0 +1,34 @@
package com.couplet.remote.factory;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.remote.RemoteTroubleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* @author fufanrui
* @version 1.0
* @description: TODO
* @date 2024/4/2 14:46
*/
@Component
public class RemoteTroubleFallbackFactory implements FallbackFactory<RemoteTroubleService> {
private static final Logger log = LoggerFactory.getLogger(RemoteTroubleFallbackFactory.class);
@Override
public RemoteTroubleService create(Throwable cause) {
return new RemoteTroubleService() {
@Override
public Result<?> newFaultData(CoupletTroubleCode code) {
return Result.error("调用失败...."+cause.getMessage());
}
};
}
}

View File

@ -50,6 +50,12 @@ public class RemoteVehicleFallbackFactory implements FallbackFactory<RemoteVehic
public Result<List<Vehicle>> findByVIN(String vin) {
return Result.error("车辆服务调用失败:" + cause.getMessage());
}
@Override
public Integer onOrOutLineByVIN(String params) {
log.error("车辆服务调用失败:" + cause.getMessage());
return null;
}
};
}
}

View File

@ -26,9 +26,10 @@ public class ServiceNameConstants {
* @param null:
* @return null
* @author
* @description couplet-business
* @description
* @date
*/
public static final String VEHICLE_SERVICE = "couplet-vehicle";
public static final String BUSINESS_SERVICE = "couplet-business";
public static final String VEHICLE_SERVICE = "vehicle-service";
}

View File

@ -0,0 +1,33 @@
package com.couplet.common.redis.configure;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
* @Author: LiJiaYao
* @Date: 2024/4/4
* @Description: redis
*/
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer listenerContainer(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
return container;
}
@Bean
KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
return new KeyExpirationEventMessageListener(listenerContainer);
}
}

View File

@ -23,5 +23,10 @@
<groupId>com.couplet</groupId>
<artifactId>couplet-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-common-business</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.couplet.common.system.remote;
import com.couplet.common.core.constant.ServiceNameConstants;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.common.system.remote.factory.RemoteCodeFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/4/4 16:00
* @description
*/
@FeignClient(contextId = "remoteCodeService",value = ServiceNameConstants.BUSINESS_SERVICE, fallbackFactory = RemoteCodeFallbackFactory.class)
public interface RemoteCodeService {
@PostMapping("trouble/insertCode")
public Result<Integer> insertCode(@RequestBody CoupletTroubleCode coupletTroubleCode);
}

View File

@ -0,0 +1,30 @@
package com.couplet.common.system.remote.factory;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.common.system.remote.RemoteCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/4/4 16:03
* @description
*/
@Slf4j
@Component
public class RemoteCodeFallbackFactory implements FallbackFactory<RemoteCodeService> {
@Override
public RemoteCodeService create(Throwable cause) {
log.error("调用日志服务异常:{}", cause.getMessage());
return new RemoteCodeService()
{
@Override
public Result<Integer> insertCode(CoupletTroubleCode coupletTroubleCode) {
return null;
}
};
}
}

View File

@ -3,3 +3,4 @@ com.couplet.common.system.remote.factory.RemoteLogFallbackFactory
com.couplet.common.system.remote.factory.RemoteFileFallbackFactory
com.couplet.common.system.remote.factory.RemoteDeptFallbackFactory
com.couplet.common.system.remote.factory.RemoteEmployeeFallbackFactory
com.couplet.common.system.remote.factory.RemoteCodeFallbackFactory

View File

@ -15,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -86,6 +86,15 @@
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-modules-mq</artifactId>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-common-business</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -11,7 +11,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @date 2024/4/2 8:39
* @description
*/
@SpringBootApplication
@SpringBootApplication(scanBasePackages = "com.couplet")
@EnableScheduling
@EnableFeignClients(basePackages = "com.couplet.**")
public class CoupletMsgApplication {

View File

@ -0,0 +1,76 @@
package com.couplet.analyze.msg.consumer;
import com.alibaba.fastjson.JSON;
import com.couplet.common.domain.request.FenceUpdateRequest;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
/**
* @Author: LiJiaYao
* @Date: 2024/4/4
* @Description:
*/
@Log4j2
@Component
@RabbitListener(queues = "fenceQueue")
public class FenceConsumer {
@Autowired
private StringRedisTemplate redisTemplate;
@RabbitHandler
public void fenceConsumer(FenceUpdateRequest fenceUpdateRequest, Channel channel, Message message) throws IOException {
log.info("消息进入队列,传入的数据是:[{}]", fenceUpdateRequest);
String messageId = message.getMessageProperties().getMessageId();
long deliveryTag = message.getMessageProperties().getDeliveryTag();
if (!redisTemplate.hasKey("消息不丢失:" + messageId)) {
redisTemplate.opsForValue().set("消息不丢失:" + messageId, "" + deliveryTag, 1, TimeUnit.MINUTES);
}
Long add = redisTemplate.opsForSet().add("消息不重复:" + messageId, messageId);
redisTemplate.expire("消息不重复:" + messageId, 5, TimeUnit.MINUTES);
try {
if (0 < add) {
HashMap<String, Object> hashMap = new HashMap<>();
HashSet<FenceUpdateRequest> hashSet = new HashSet<>();
hashSet.add(fenceUpdateRequest);
hashMap.put(fenceUpdateRequest.getFenceId()+"",fenceUpdateRequest);
redisTemplate.opsForValue().set("fence", JSON.toJSONString(hashMap),10,TimeUnit.MINUTES);
//判断车辆是否有实时数据,如果没有则删除数据
channel.basicAck(deliveryTag, false);
} else {
log.error("消息不能重复消费:[{}]", fenceUpdateRequest);
channel.basicReject(deliveryTag, false);
}
} catch (IOException e) {
log.error("消息未进入队列,传入的信息是:【{}】", fenceUpdateRequest);
String s = redisTemplate.opsForValue().get("消息不丢失:" + messageId);
Long o = Long.valueOf(s);
if (deliveryTag == o + 2) {
log.error("消息已丢失,无法传入的信息是:【{}】", fenceUpdateRequest);
channel.basicNack(deliveryTag, false, false);
} else {
log.error("消息已丢失,已再次传入的信息是:【{}】", fenceUpdateRequest);
channel.basicNack(deliveryTag, true, false);
}
}
}
}

View File

@ -0,0 +1,92 @@
package com.couplet.analyze.msg.consumer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.analyze.msg.mapper.IncidentMapper;
import com.couplet.analyze.msg.service.impl.realTimeData.RealTimeJudge;
import com.couplet.common.domain.request.RealTimeDataRequest;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @Author: LiJiaYao
* @Date: 2024/4/4
* @Description:
*/
@Log4j2
@Component
@RabbitListener(queues = "finByVinQueueName")
public class MsgConsumer {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IncidentMapper incidentMapper;
@RabbitHandler
public void realTimeDataConsumer(RealTimeDataRequest realTimeDataRequest, Channel channel, Message message) throws IOException {
log.info("消息进入队列,传入的数据是:[{}]", realTimeDataRequest);
String messageId = message.getMessageProperties().getMessageId();
long deliveryTag = message.getMessageProperties().getDeliveryTag();
if (!redisTemplate.hasKey("消息不丢失:" + messageId)) {
redisTemplate.opsForValue().set("消息不丢失:" + messageId, "" + deliveryTag, 1, TimeUnit.MINUTES);
}
Long add = redisTemplate.opsForSet().add("消息不重复:" + messageId, messageId);
redisTemplate.expire("消息不重复:" + messageId, 5, TimeUnit.MINUTES);
try {
if (0 < add) {
JSONObject jsonObject = JSONObject.parseObject(String.valueOf(realTimeDataRequest));
String vin = jsonObject.getString("vin");
Long userId = jsonObject.getLong("userId");
RealTimeDataRequest request = new RealTimeDataRequest();
request.setVin(vin);
request.setUserId(userId);
RealTimeJudge.addRealTime(request);
//判断车辆是否有实时数据,如果没有则删除数据
if (RealTimeJudge.isJudge(realTimeDataRequest.getVin())){
log.info("开始实时数据传输:[{}]",realTimeDataRequest.getVin());
}
CoupletMsgData incident = incidentMapper.queryByIncident(realTimeDataRequest.getVin());
if (incident == null){
log.error("没有数据......");
}
redisTemplate.opsForList().rightPush("coupletMsgData", JSON.toJSONString(incident));
channel.basicAck(deliveryTag, false);
} else {
log.error("消息不能重复消费:[{}]", realTimeDataRequest);
channel.basicReject(deliveryTag, false);
}
} catch (IOException e) {
log.error("消息未进入队列,传入的信息是:【{}】", realTimeDataRequest);
String s = redisTemplate.opsForValue().get("消息不丢失:" + messageId);
Long o = Long.valueOf(s);
if (deliveryTag == o + 2) {
log.error("消息已丢失,无法传入的信息是:【{}】", realTimeDataRequest);
channel.basicNack(deliveryTag, false, false);
} else {
log.error("消息已丢失,已再次传入的信息是:【{}】", realTimeDataRequest);
channel.basicNack(deliveryTag, true, false);
}
}
}
}

View File

@ -0,0 +1,89 @@
package com.couplet.analyze.msg.contents;
import io.swagger.models.auth.In;
import org.springframework.stereotype.Component;
/**
* @Author: LiJiaYao
* @Date: 2024/4/4
* @Description:
*/
@Component
public class StateConstant {
/**
*
*/
public static final Integer VEHICLE_STATUS = 1;
/**
*
*/
public static final Integer CHARGING_STATUS = 1;
/**
*
*/
public static final Integer OPERATING_STATUS = 1;
/**
* soc
*/
public static final Integer SOC_STATUS = 1;
/**
*
*/
public static final Integer CHARGING_ENERGY_STORAGE_STATUS = 1;
/**
*
*/
public static final Integer DRIVE_MOTOR_STATUS = 1;
/**
*
*/
public static final Integer POSITION_STATUS = 1;
/**
* EAS()
*/
public static final Integer EAS_STATUS = 1;
/**
* PTC()
*/
public static final Integer PTC_STATUS = 1;
/**
* ABS()
*/
public static final Integer ABS_STATUS = 1;
/**
* MCU(/)
*/
public static final Integer MCU_STATUS = 1;
/**
*
*/
public static final Integer HEATING_STATUS = 1;
/**
*
*/
public static final Integer BATTERY_STATUS = 1;
/**
*
*/
public static final Integer BATTERY_INSULATION_STATUS = 1;
/**
* DCDC()
*/
public static final Integer DCDC_STATUS = 1;
/**
* CHG()
*/
public static final Integer CHG_STATUS = 1;
}

View File

@ -15,4 +15,11 @@ public interface IncidentMapper {
* @param coupletMsgData
*/
public void reportMapper(CoupletMsgData coupletMsgData);
/**
* vin
*/
// CoupletMsgData queryByIncident(RealTimeDataRequest realTimeDataRequest);
CoupletMsgData queryByIncident(String vin);
}

View File

@ -3,26 +3,20 @@ package com.couplet.analyze.msg.model;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.analyze.msg.service.IncidentService;
import com.couplet.common.core.utils.SpringUtils;
import com.couplet.common.core.utils.uuid.IdUtils;
import com.couplet.common.system.remote.RemoteCodeService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.*;
import static com.couplet.analyze.msg.contents.MsgContent.BROKER_URL;
import static com.couplet.analyze.msg.contents.MsgContent.CLIENT_ID;
import static io.lettuce.core.pubsub.PubSubOutput.Type.message;
/**
@ -35,13 +29,8 @@ import static io.lettuce.core.pubsub.PubSubOutput.Type.message;
@Component
public class ModelMessage {
// @Autowired
// private CoupletMsgService coupletMsgService;
// @Autowired
// public ModelMessage(CoupletMsgService coupletMsgService){
// this.coupletMsgService = coupletMsgService;
// }
@Autowired
private RabbitTemplate rabbitTemplate;
static ArrayList<String> strings = new ArrayList<>() {
{
add("breakdown");
@ -51,16 +40,19 @@ public class ModelMessage {
}
};
@Value("${mq.queueName}")
public String queueName;
@Autowired
private RemoteCodeService remoteCodeService;
//交换机
@Value("${mq.exchangeName}")
public String exchangeName;
//路由键
@Value("${mq.routingKey}")
public String routingKey;
// @Value("${mq.queueName}")
// public String queueName;
//
// //交换机
// @Value("${mq.exchangeName}")
// public String exchangeName;
//
// //路由键
// @Value("${mq.routingKey}")
// public String routingKey;
@Scheduled(cron = "0/5 * * * * ?")
public void startMsg() {
@ -87,16 +79,43 @@ public class ModelMessage {
for (CoupletMsgData msgData : coupletMsgDataList) {
log.info("解析到车辆数据:{}", msgData);
//发送日志到MQ
// // 使用CompletableFuture.runAsync()方法创建一个异步任务,该任务会在一个新的线程中执行
// CompletableFuture.runAsync(() ->{
// // 创建一个CoupletTroubleLog对象用于记录故障日志
// CoupletTroubleCode troubleCode = new CoupletTroubleCode();
// //判断状态是否为异常
// if (msgData.getVehicleStatus() !=1 || msgData.getEasStatus() !=1 || msgData.getHeatingStatus() !=1){
// String code = generateGTA();
// troubleCode.setTroubleCode(code);
// String vin = msgData.getVin();
// troubleCode.setTroubleVin(vin);
// String position = getPosition();
// troubleCode.setTroublePosition(position);
// troubleCode.setTroubleValue("00");
// String tag = getTag();
// troubleCode.setTroubleTag(tag);
// String type = getType();
// troubleCode.setTroubleType(type);
// troubleCode.setTroubleStartTime(new Date());
// // 如果车辆状态为正常状态为1则添加结束时间为当前时间
// if (msgData.getVehicleStatus() == 1){
// troubleCode.setTroubleEndTime(new Date());
// }
// }
// // 调用远程服务插入故障日志信息
// remoteCodeService.insertCode(troubleCode);
// });
// log.info("记录异常成功");
for (String string : strings) {
IncidentService incidentService = SpringUtils.getBean(string);
incidentService.incident(msgData);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// 不睡眠,他们也会主动拉取数据,不会影响其他服务
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
}
}
@ -108,12 +127,84 @@ public class ModelMessage {
});
mqttClient.subscribe("test",0);
Thread.sleep(1000*6*10);
Thread.sleep(1000*60*10);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// /**
// *
// * 拼接GTA字符串
// * @return
// */
// public static String generateGTA() {
// // 生成以GTA开头的字符串
// String codefix = "GTA";
// // 删除4位数随机数字
// String s = generateRandomNumber(4);
// //拼接
// return codefix + s;
// }
//
// /**
// * 随机生成1到10位的数字
// * @param length
// * @return
// */
// public static String generateRandomNumber(int length) {
// Random random = new Random();
// StringBuilder builder = new StringBuilder();
// for (int i = 0; i < length; i++) {
// builder.append(random.nextInt(10));
// }
// return builder.toString();
// }
//
// /**
// * 生成 190 到 209 之间的随机数
// * @param
// * @return
// */
// public static String getPosition() {
// // 生成随机数对象
// Random rand = new Random();
//
// // 生成 190 到 209 之间的随机数
// int randomNumber = rand.nextInt(20) + 190;
//
// // 将随机数转换为字符串形式
// return String.valueOf(randomNumber);
// }
//
// public static String getTag() {
// // 创建一个字符串数组存储三个状态
// String[] statuses = {"车辆状态", "EAS(汽车防盗系统)状态", "DCDC(电力交换系统)"};
//
// // 生成随机数对象
// Random rand = new Random();
//
// // 生成一个范围在 0 到 2 之间的随机整数
// int randomIndex = rand.nextInt(3);
//
// return statuses[randomIndex];
// }
//
// public static String getType() {
// // 创建一个字符串数组存储三个状态
// String[] statuses = {"电池故障", "车体故障", "车尾故障","抽轮故障"};
//
// // 生成随机数对象
// Random rand = new Random();
//
// // 生成一个范围在 0 到 2 之间的随机整数
// int randomIndex = rand.nextInt(4);
//
// return statuses[randomIndex];
// }
/**
* 16ASCII
* @param s 16

View File

@ -2,6 +2,7 @@ package com.couplet.analyze.msg.service;
import com.couplet.analyze.msg.contents.MsgContent;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.common.domain.request.RealTimeDataRequest;
/**
* @Author: LiJiaYao
@ -25,4 +26,5 @@ public interface IncidentService {
}

View File

@ -1,19 +1,47 @@
package com.couplet.analyze.msg.service.impl;
import com.alibaba.fastjson.JSON;
import com.couplet.analyze.msg.contents.StateConstant;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.analyze.msg.service.IncidentService;
import com.couplet.common.log.annotation.Log;
import lombok.extern.log4j.Log4j2;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.remote.RemoteTroubleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @Author: LiJiaYao
* @Date: 2024/4/2
* @Description:
*/
@Service("breakdown")
@Log4j2
public class BreakdownServiceImpl implements IncidentService {
public class BreakdownServiceImpl extends KeyExpirationEventMessageListener implements IncidentService {
/**
* redis
*/
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RemoteTroubleService remoteTroubleService;
private static Logger log = LoggerFactory.getLogger(BreakdownServiceImpl.class);
public BreakdownServiceImpl(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
*
*
@ -23,9 +51,41 @@ public class BreakdownServiceImpl implements IncidentService {
public void incident(CoupletMsgData coupletMsgData) {
log.info("故障事件开始.....");
long l = System.currentTimeMillis();
log.info("开始时间是:"+l);
if (StateConstant.VEHICLE_STATUS != coupletMsgData.getVehicleStatus()
|| StateConstant.CHARGING_STATUS!=coupletMsgData.getChgStatus()
|| StateConstant.OPERATING_STATUS!=coupletMsgData.getOperatingStatus()
|| StateConstant.SOC_STATUS!=coupletMsgData.getSocStatus()
|| StateConstant.CHARGING_ENERGY_STORAGE_STATUS != coupletMsgData.getChargingEnergyStorageStatus()
|| StateConstant.DRIVE_MOTOR_STATUS != coupletMsgData.getDriveMotorStatus()
|| StateConstant.POSITION_STATUS != coupletMsgData.getPositionStatus()
|| StateConstant.EAS_STATUS != coupletMsgData.getEasStatus()
|| StateConstant.PTC_STATUS != coupletMsgData.getPtcStatus()
|| StateConstant.ABS_STATUS != coupletMsgData.getAbsStatus()
|| StateConstant.MCU_STATUS != coupletMsgData.getMcuStatus()
|| StateConstant.HEATING_STATUS != coupletMsgData.getHeatingStatus()
|| StateConstant.BATTERY_STATUS != coupletMsgData.getBatteryStatus()
|| StateConstant.BATTERY_INSULATION_STATUS != coupletMsgData.getBatteryInsulationStatus()
|| StateConstant.DCDC_STATUS != coupletMsgData.getDcdcStatus()
|| StateConstant.CHG_STATUS != coupletMsgData.getChgStatus()){
//获取过期的key
String key = "breakdown";
log.debug("失效+key is:"+ key);
String value = JSON.toJSONString(coupletMsgData);
redisTemplate.opsForSet().add(key, value);
long expireTime = 30;
redisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
long timeMillis = System.currentTimeMillis();
scheduledRedis();
log.info("故障事件结束时间:"+timeMillis);
log.info("故障事件检测结束.....");
log.info("故障事件结束.....");
}
long timeMillis = System.currentTimeMillis();
log.info("故障事件结束时间:"+timeMillis);
log.info("故障事件检测结束.....");
log.info("故障事件结束.....");
}
/**
@ -35,4 +95,31 @@ public class BreakdownServiceImpl implements IncidentService {
public String getName() {
return "breakdown";
}
public void scheduledRedis() {
// Get all members of the set
Set<String> members = redisTemplate.opsForSet().members("breakdown");
if (members.size()!=0){
for (String member : members){
CoupletMsgData code = JSON.parseObject(member, CoupletMsgData.class);
Set<String> breakdownIds = redisTemplate.opsForSet().members(code.getVin());
if (breakdownIds.size()==0){
CoupletTroubleCode troubleCode = new CoupletTroubleCode();
troubleCode.setTroubleStartTime(new Date());
// 插入数据库
troubleCode.setTroubleTag(0);
troubleCode.setTroubleVin(code.getVin());
remoteTroubleService.newFaultData(troubleCode);
redisTemplate.opsForSet().add(code.getVin(), code.getVin()+":"+code);
long expireTime = 30;
redisTemplate.expire(code.getVin(), expireTime, TimeUnit.MINUTES);
}
}
}
}
}

View File

@ -3,6 +3,8 @@ package com.couplet.analyze.msg.service.impl;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.analyze.msg.service.IncidentService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
/**
@ -14,6 +16,8 @@ import org.springframework.stereotype.Service;
@Log4j2
public class ElectronicFenceServiceImpl implements IncidentService {
@Autowired
private StringRedisTemplate redisTemplate;
/**
*
@ -24,10 +28,16 @@ public class ElectronicFenceServiceImpl implements IncidentService {
public void incident(CoupletMsgData coupletMsgData) {
log.info("电子围栏事件开始.......");
if (redisTemplate.hasKey("fence")) {
log.info("电子围栏事件redis存在.......");
String s = redisTemplate.opsForValue().get("fence");
log.info("更改的电子围栏内容是:"+s);
log.info("电子围栏事件结束.......");
}
log.info("电子围栏事件结束.......");
}
/**

View File

@ -1,8 +1,12 @@
package com.couplet.analyze.msg.service.impl;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.analyze.msg.mapper.IncidentMapper;
import com.couplet.analyze.msg.service.IncidentService;
import com.couplet.analyze.msg.service.impl.realTimeData.RealTimeJudge;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
/**
@ -14,6 +18,15 @@ import org.springframework.stereotype.Service;
@Log4j2
public class RealTimeDataServiceImpl implements IncidentService {
/**
*
*/
@Autowired
private IncidentMapper incidentMapper;
@Autowired
private StringRedisTemplate redisTemplate;
/**
*
*
@ -23,6 +36,12 @@ public class RealTimeDataServiceImpl implements IncidentService {
public void incident(CoupletMsgData coupletMsgData) {
log.info("实时数据事件开始.....");
if (RealTimeJudge.isJudge(coupletMsgData.getVin())){
log.info("[{}]开始传输实时数据", coupletMsgData.getVin());
}
log.info("[{}]开始传输实时数据", coupletMsgData.getVin());
log.info("实时数据事件结束.....");
}

View File

@ -0,0 +1,19 @@
package com.couplet.analyze.msg.service.impl.breakdown;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
/**
* @Author: LiJiaYao
* @Date: 2024/4/5
* @Description:
*/
@Component
public class BreakdownEvent {
@Autowired
private StringRedisTemplate redisTemplate;
}

View File

@ -0,0 +1,45 @@
package com.couplet.analyze.msg.service.impl.realTimeData;
import com.couplet.analyze.msg.domain.CoupletMsgData;
import com.couplet.common.domain.request.RealTimeDataRequest;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @Author: LiJiaYao
* @Date: 2024/4/4
* @Description:
*/
public class RealTimeJudge {
/**
*
*/
private static final Map<String, Set<Long>> setMap = new HashMap<>();
public static boolean isJudge(String vin){
return setMap.containsKey(vin);
}
/**
*
* @param realTimeDataRequest
* @return
*/
public static boolean addRealTime(RealTimeDataRequest realTimeDataRequest){
Set<Long> userIds = setMap.get(realTimeDataRequest.getVin());
if (userIds == null){
userIds = new HashSet<>();
setMap.put(realTimeDataRequest.getVin(),userIds);
}
userIds.add(realTimeDataRequest.getUserId());
return true;
}
}

View File

@ -4,7 +4,6 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.couplet.analyze.msg.mapper.IncidentMapper">
<insert id="reportMapper">
INSERT INTO `couplet-cloud`.`couplet_msg_data`
(`vin`, `create_time`, `longitude`, `latitude`,
@ -71,5 +70,10 @@
#{brakePedal}
);
</insert>
<select id="queryByIncident" resultType="com.couplet.analyze.msg.domain.CoupletMsgData"
parameterType="com.couplet.common.domain.request.RealTimeDataRequest">
SELECT * FROM couplet_msg_data WHERE vin =#{vin}
</select>
</mapper>

View File

@ -1,5 +1,6 @@
package com.couplet.msg;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -11,18 +12,17 @@ import java.util.regex.Pattern;
*/
public class Main {
public static void main(String[] args) {
String msgString = "VIN123456789DIJE41711764104506116.664380039.531990072.00031.3760000022000022000852000000D00809.600940000589066790930000203002030000044282.55000014000080700007440003000400095000058000054000011111111111111111";
// 创建一个字符串数组存储三个状态
String[] statuses = {"电池故障", "车体故障", "车尾故障","抽轮故障"};
//使用正则表达式匹配需要的部分
String pattern = "(.{17})(.{10})(.{4})(.{2})(.{2})";
Pattern compile = Pattern.compile(pattern);
Matcher matcher = compile.matcher(msgString);
// 生成随机数对象
Random rand = new Random();
if (matcher.find()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group "+ i + ":" + matcher.group(i));
}
}
// 生成一个范围在 0 到 2 之间的随机整数
int randomIndex = rand.nextInt(4);
// 随机选择一个字符串并输出
String randomStatus = statuses[randomIndex];
System.out.println("随机输出的字符串:" + randomStatus);
}
}

View File

@ -0,0 +1,36 @@
package com.couplet.msg;
import java.util.Random;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/4/4 11:34
* @description
*/
public class Randoms {
public static void main(String[] args) {
String gtaNumber = generateGTA();
System.out.println("随机生成的GTA开头的七位数字" + gtaNumber);
}
public static String generateGTA() {
// 生成四位以"GTA"开头的字符串
String prefix = "GTA";
// 生成三位随机数字
String randomNumber = generateRandomNumber(4);
// 拼接字符串
return prefix + randomNumber;
}
public static String generateRandomNumber(int length) {
// 生成随机数
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
// 生成0到9之间的随机数字并转换为字符串
sb.append(random.nextInt(10));
}
return sb.toString();
}
}

View File

@ -87,6 +87,17 @@
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-analyze-msg</artifactId>
</dependency>
<!-- RabbitMQ依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -5,6 +5,7 @@ import com.couplet.common.security.annotation.EnableMyFeignClients;
import com.couplet.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @Author: LiJiaYao
@ -15,6 +16,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableCustomSwagger2
@EnableMyFeignClients(basePackages = ("com.couplet"))
@SpringBootApplication(scanBasePackages = {"com.couplet"})
@EnableScheduling
public class CoupletBusinessApplication {
public static void main (String[] args) {
SpringApplication.run(CoupletBusinessApplication.class, args);

View File

@ -3,14 +3,8 @@ package com.couplet.business.server.controller;
import com.couplet.business.server.service.OnLineVehicleService;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.Vehicle;
import com.couplet.common.domain.request.RealTimeDataRequest;
import com.couplet.common.security.utils.SecurityUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -28,8 +22,7 @@ public class OnLineVehicleController {
@Autowired
private OnLineVehicleService onLineVehicleService;
@Autowired
private RabbitTemplate rabbitTemplate;
@PostMapping("onlineList")
public Result<List<Vehicle>> onlineList(){
List<Vehicle> onlineList = onLineVehicleService.onlineList();
@ -37,14 +30,8 @@ public class OnLineVehicleController {
return success;
}
@PostMapping("/monitorinData")
public void monitorinData(@RequestBody RealTimeDataRequest realTimeDataRequest){
String exchangeName = "exchangeName"; // 交换机名称
String routingKey = "routingKey"; // 路由键
Long userId = SecurityUtils.getUserId();
realTimeDataRequest.setUserId(userId);
rabbitTemplate.convertAndSend(exchangeName, routingKey, realTimeDataRequest);
}
}

View File

@ -6,7 +6,6 @@ import com.couplet.common.core.domain.Result;
import com.couplet.common.core.web.controller.BaseController;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.common.domain.CoupletTroubleGrade;
import com.couplet.common.domain.CoupletTroubleType;
import com.couplet.common.domain.request.TroubleResp;
import com.couplet.common.log.annotation.Log;
import com.couplet.common.log.enums.BusinessType;
@ -37,13 +36,6 @@ public class SysTroubleController extends BaseController {
return Result.success(result);
}
/**
*
*/
@GetMapping("/troubleTypeList")
public List<CoupletTroubleType> listType() {
return troubleService.selectTroubleListByType();
}
/**
*
@ -80,4 +72,14 @@ public class SysTroubleController extends BaseController {
troubleService.removeById(troubleId);
return success();
}
/**
*
*/
@Log(title = "新增故障码",businessType = BusinessType.INSERT)
@PostMapping("/newFaultData")
public Result<?> newFaultData(@RequestBody CoupletTroubleCode code) {
troubleService.newFaultData(code);
return success();
}
}

View File

@ -174,8 +174,21 @@ public class VehicleController extends BaseController {
/*
* @Author: LiuYunHu
* @Date: 2024/4/4 11:28
* @Description: vin线
* @Param:
* @Return:
**/
@GetMapping("onOrOutLineByVIN")
public Integer onOrOutLineByVIN(@RequestParam("params") String params) {
String[] split = params.split(",");
return vehicleService.onOrOutLineByVIN(split[0], Integer.parseInt(split[1]));
}
}

View File

@ -2,14 +2,17 @@ package com.couplet.business.server.controller;
import com.couplet.business.server.service.VehicleDetectionService;
import com.couplet.common.core.domain.Result;
import com.couplet.common.domain.CoupletVehicleData;
import com.couplet.common.domain.Vehicle;
import com.couplet.common.domain.request.RealTimeDataRequest;
import com.couplet.common.security.utils.SecurityUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
* @author fufanrui
@ -23,10 +26,14 @@ import java.util.List;
public class VehicleDetectionController {
@Autowired
private VehicleDetectionService vehicleDetectionService;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private final String REDIS_LIST_KEY = "coupletMsgData";
/*
* @param :
* @return Result<List<Vehicle>>
@ -58,4 +65,9 @@ public class VehicleDetectionController {
rabbitTemplate.convertAndSend(exchangeName, routingKey, realTimeDataRequest);
}
}

View File

@ -1,7 +1,6 @@
package com.couplet.business.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.couplet.common.domain.Fence;
import com.couplet.common.domain.request.FenceConfig;
import com.couplet.common.domain.request.FenceRequest;

View File

@ -23,6 +23,13 @@ public interface SysTroubleMapper extends BaseMapper<CoupletTroubleCode> {
List<CoupletTroubleGrade> selectTroubleListByGrade();
/**
*
* @param code
*/
void newFaultData(CoupletTroubleCode code);
// int addTrouble(TroubleAddReq troubleAddReq);
// int updateTrouble(TroubleUpdReq troubleUpdReq);

View File

@ -9,5 +9,5 @@ import java.util.List;
public interface VehicleDetectionMapper {
List<Vehicle> detectionList();
List<Vehicle> findByVin(Integer vehicleId);
List<Vehicle> findByVin(String vehicleId);
}

View File

@ -22,10 +22,9 @@ public interface VehicleMapper extends BaseMapper<Vehicle> {
Integer deleteVehicle(Long middleId);
Integer addVehicle(VehicleMiddle vehicleMiddle);
List<Vehicle> vehicleAll();
Integer addVehicle(@Param("userId") Long userId, @Param("vehicleIds") List<Long> vehicleIds);
Integer onOrOutLineByVIN(@Param("vin") String vin, @Param("status") int status);
}

View File

@ -3,7 +3,6 @@ package com.couplet.business.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.couplet.common.domain.Logo;
import java.util.List;
/**

View File

@ -4,10 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.couplet.common.core.domain.PageResult;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.common.domain.CoupletTroubleGrade;
import com.couplet.common.domain.CoupletTroubleType;
import com.couplet.common.domain.request.TroubleResp;
import java.util.List;
/**
@ -19,10 +17,15 @@ import java.util.List;
public interface SysTroubleService extends IService<CoupletTroubleCode> {
PageResult<CoupletTroubleCode> selectTroubleList(TroubleResp troubleReq);
List<CoupletTroubleType> selectTroubleListByType();
List<CoupletTroubleGrade> selectTroubleListByGrade();
/**
*
* @param code
*/
void newFaultData(CoupletTroubleCode code);
// int addTrouble (TroubleAddReq troubleAddReq);
// int updateTrouble(TroubleUpdReq troubleUpdReq);

View File

@ -3,7 +3,6 @@ package com.couplet.business.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.couplet.common.domain.VehicleAndLogo;
import java.util.List;
/**

View File

@ -9,5 +9,4 @@ public interface VehicleDetectionService {
List<Vehicle> detectionList();
List<Vehicle> findByVin(Integer vehicleId);
}

View File

@ -37,4 +37,6 @@ public interface VehicleService extends IService<Vehicle> {
List<Vehicle> vehicleAll();
Integer onOrOutLineByVIN(String s, int i);
}

View File

@ -3,7 +3,6 @@ package com.couplet.business.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.couplet.common.domain.VehicleType;
import java.util.List;
/**

View File

@ -1,5 +1,6 @@
package com.couplet.business.server.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.couplet.business.server.mapper.FenceMapper;
import com.couplet.business.server.service.FenAndLogoService;
@ -8,12 +9,15 @@ import com.couplet.common.domain.Fence;
import com.couplet.common.domain.request.FenceConfig;
import com.couplet.common.domain.request.FenceRequest;
import com.couplet.common.domain.request.FenceUpdateRequest;
import com.couplet.common.security.utils.SecurityUtils;
import com.couplet.mq.remote.RemoteFenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @Author: LiJiaYao
@ -38,45 +42,66 @@ public class FenceServiceImpl extends ServiceImpl<FenceMapper, Fence> implements
*/
@Autowired
private StringRedisTemplate redisTemplate;
/**
*
*/
@Autowired
private RemoteFenceService remoteFenceService;
@Override
public List<Fence> pageQuery(FenceConfig fenceConfig) {
List<Fence> list= fenceMapper.pageQuery(fenceConfig);
List<Fence> list = fenceMapper.pageQuery(fenceConfig);
return list;
}
@Override
public void changeFenceStatus(FenceUpdateRequest fenceUpdateRequest) {
String username = SecurityUtils.getUsername();
fenceUpdateRequest.setCrateName(username);
fenceMapper.changeFence(fenceUpdateRequest);
/**
*
*/
redisTemplate.opsForValue().set("changeFenceStatus", JSON.toJSONString(fenceUpdateRequest), 10, TimeUnit.MINUTES);
remoteFenceService.fenceQueue(fenceUpdateRequest);
}
/**
* :
*
* @param request
* @param fenceRequest
*/
@Override
public void fenceInsert(HttpServletRequest request, FenceRequest fenceRequest) {
String username = SecurityUtils.getUsername();
fenceRequest.setCrateName(username);
//先添加围栏
int a= fenceMapper.insertFence(fenceRequest);
fenceMapper.insertFence(fenceRequest);
String[] logoIds = fenceRequest.getLogoIds();
String[] parts = new String[0];
for (String logoId : logoIds) {
//把前台传入的字符串分割成数组
parts = logoId.split(",");
//再添加围栏和标识中间表
fenAndLogoService.addBach(fenceRequest.getFenceId(),parts);
parts = logoId.split(",");
//再添加围栏和标识中间表
fenAndLogoService.addBach(fenceRequest.getFenceId(), parts);
}
/**
*
*/
redisTemplate.opsForValue().set("fenceInsert", JSON.toJSONString(fenceRequest), 10, TimeUnit.MINUTES);
}
@Override
public void removeByFenceId(Long fenceId) {
fenceMapper.removeByFenceId(fenceId);
/**
*
*/
redisTemplate.opsForValue().set("removeByFenceId", JSON.toJSONString(fenceId), 10, TimeUnit.MINUTES);
}
@Override

View File

@ -7,7 +7,6 @@ import com.couplet.common.system.domain.LoginUser;
import com.couplet.common.system.domain.SysDept;
import com.couplet.common.system.remote.RemoteDeptService;
import com.couplet.common.system.remote.RemoteUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@ -6,7 +6,6 @@ import com.couplet.business.server.service.SysTroubleService;
import com.couplet.common.core.domain.PageResult;
import com.couplet.common.domain.CoupletTroubleCode;
import com.couplet.common.domain.CoupletTroubleGrade;
import com.couplet.common.domain.CoupletTroubleType;
import com.couplet.common.domain.request.TroubleResp;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@ -40,16 +39,17 @@ public class SysTroubleServiceImpl extends ServiceImpl<SysTroubleMapper, Couplet
return PageResult.toPageResult(info.getTotal(),troubleList);
}
@Override
public List<CoupletTroubleType> selectTroubleListByType() {
return sysTroubleMapper.selectTroubleListByType();
}
@Override
public List<CoupletTroubleGrade> selectTroubleListByGrade() {
return sysTroubleMapper.selectTroubleListByGrade();
}
@Override
public void newFaultData(CoupletTroubleCode code) {
sysTroubleMapper.newFaultData(code);
}
/**
*
// * @param troubleAddReq

View File

@ -27,8 +27,4 @@ public class VehicleDetectionServiceImpl implements VehicleDetectionService{
return vehicleDetectionMapper.detectionList();
}
@Override
public List<Vehicle> findByVin(Integer vehicleId) {
return vehicleDetectionMapper.findByVin(vehicleId);
}
}

View File

@ -61,6 +61,8 @@ public class VehicleManageServiceImpl implements VehicleManageService {
*/
@Override
public Result addVehicle(VehicleMiddle middle) {
Long userId = SecurityUtils.getUserId();
middle.setUserId(userId);
Result<Integer> integerResult = remoteVehicleService.addVehicle(middle);
Integer resultData = integerResult.getData();
return resultData==1?Result.success():Result.error("添加失败");

View File

@ -16,7 +16,6 @@ import com.couplet.common.domain.VehicleType;
import com.couplet.common.domain.request.VehicleEditParams;
import com.couplet.common.domain.request.VehicleInsertParams;
import com.couplet.common.domain.request.VehicleListParams;
import com.couplet.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -274,8 +273,8 @@ public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> impl
@Override
public Integer addVehicle(VehicleMiddle vehicleMiddle) {
Long userId = SecurityUtils.getUserId();
return vehicleMapper.addVehicle(userId,vehicleMiddle.getVehicleIds());
return vehicleMapper.addVehicle(vehicleMiddle);
}
@Override
@ -283,6 +282,14 @@ public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> impl
return vehicleMapper.vehicleAll();
}
//通过vin修改车辆上下线的状态
@Override
public Integer onOrOutLineByVIN(String vin, int status) {
return vehicleMapper.onOrOutLineByVIN(vin, status);
}
@Override
public List<Vehicle> findByVIN(String vin) {

View File

@ -0,0 +1,62 @@
package com.couplet.business.server.time;
import com.couplet.business.server.service.VehicleService;
import com.couplet.common.domain.Vehicle;
import com.couplet.common.domain.request.VehicleListParams;
import com.couplet.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @ProjectName: five-groups-couplet
* @Author: LiuYunHu
* @CreateTime: 2024/4/4
* @Description:
*/
@Component
@Slf4j
public class Timer {
//redis
@Autowired
private RedisService redis;
//查询车辆列表
@Autowired
private VehicleService vehicleService;
//判断车辆是否下线
@Scheduled(cron = "* * * * * *")
public void outLine() {
log.info("定时器启动");
//先查询车辆列表
List<Vehicle> list = vehicleService.list(new VehicleListParams(null, null, null, null));
list.forEach(vehicle -> {
//只针对已经上线的车辆
if (redis.hasKey(vehicle.getVin())) {
//如果vin的缓存 时间还剩一秒,则判断为已经下线
if (redis.getExpire(vehicle.getVin()) <= 3) {
log.info(vehicle.getVin() + "的车辆已经下线");
//执行修改下线状态的方法
Integer i = vehicleService.onOrOutLineByVIN(vehicle.getVin(), 0);
if (0 == 1) {
log.error("下线状态修改失败");
}
log.info("下线状态修改成功");
}
}
});
}
}

View File

@ -14,6 +14,7 @@
<result property="updateTime" column="update_time" />
<result property="isDelete" column="is_delete" />
<result property="maintainerName" column="maintainer_name" />
<result property="fenceCondition" column="fence_condition" />
</resultMap>
<resultMap id="logoMap" type="com.couplet.common.domain.Logo">
<id property="logoId" column="logo_id"/>

View File

@ -14,6 +14,7 @@
<result property="updateTime" column="update_time" />
<result property="isDelete" column="is_delete" />
<result property="maintainerName" column="maintainer_name" />
<result property="fenceCondition" column="fence_condition" />
</resultMap>
<resultMap id="logoMap" type="com.couplet.common.domain.Logo">
<id property="logoId" column="logo_id"/>
@ -32,6 +33,7 @@
create_name,
maintainer_name,
alarm_status,
fence_condition,
l.logo_id,
GROUP_CONCAT(logo_name) as logoName
FROM couplet_fence_info f INNER JOIN couplet_fences_and_logo m on
@ -49,16 +51,17 @@
update_time,
create_name,
maintainer_name,
alarm_status
alarm_status,
fence_condition
FROM couplet_fence_info
</sql>
<insert id="insertFence" parameterType="com.couplet.common.domain.request.FenceRequest" keyProperty="fenceId"
useGeneratedKeys="true">
INSERT INTO `couplet-cloud`.`couplet_fence_info`
(`fence_name`, `fence_longitude_latitude`, `fence_description`, `is_delete`, `fence_state`, `create_time`,
`update_time`, `create_name`, `maintainer_name`, `alarm_status`)
`update_time`, `create_name`, `maintainer_name`, `alarm_status`,`fence_condition`)
VALUES
(#{fenceName}, null, #{fenceDescription}, 0, 0, now(), null, null, #{maintainerName}, 0)
(#{fenceName}, null, #{fenceDescription}, 0, 0, now(), null, null, #{maintainerName}, 0 ,0)
</insert>
@ -73,7 +76,8 @@
`fence_state` = #{fenceState},
`update_time` = now(),
`maintainer_name` = 'admin',
`alarm_status` = #{alarmStatus}
`alarm_status` = #{alarmStatus},
`fence_condition` = #{fenceCondition}
WHERE `fence_id` = #{fenceId}
</update>

View File

@ -12,6 +12,7 @@
<result property="troubleTag" column="trouble_tag"/>
<result property="typeId" column="type_id"/>
<result property="gradeId" column="grade_id"/>
<result property="troubleType" column="trouble_type"/>
</resultMap>
<sql id="selectTroubleVo">
@ -19,6 +20,13 @@
LEFT JOIN couplet_trouble_grade g on t.grade_id = g.grade_id
LEFT JOIN couplet_trouble_type y on t.type_id= y.type_id
</sql>
<insert id="newFaultData">
INSERT INTO `couplet-cloud`.`couplet_trouble_code`
(`trouble_vin`, `trouble_tag`,
`trouble_start_time`)
VALUES
(#{troubleVin}, #{troubleTag}, #{troubleStartTime})
</insert>
<select id="selectTroubleList" parameterType="com.couplet.business.server.mapper.SysTroubleMapper" resultMap="SysTroubleResult">
<include refid="selectTroubleVo"/>

View File

@ -41,16 +41,19 @@
</sql>
<insert id="addVehicle">
INSERT INTO `couplet-cloud`.`couplet_middle` (`user_id`, `vehicle_id`, `del_flag`) VALUES
<foreach collection="vehicleIds" item="singleVehicleId" separator=",">
(#{userId}, #{singleVehicleId}, 0)
<foreach collection="vehicleId" item="vehicleId" separator=",">
(#{userId}, #{vehicleId}, 0)
</foreach>
</insert>
<!-- <insert id="addVehicle" useGeneratedKeys="true" keyProperty="vehicleId">-->
<!-- INSERT INTO `couplet-cloud`.`couplet_middle` (`user_id`, `vehicle_id`, `del_flag`) VALUES-->
<!-- <foreach collection="vehicleId" item="vehicleId" separator=",">-->
<!-- (#{userId}, #{vehicleId}, 0)-->
<!-- </foreach>-->
<!-- </insert>-->
<update id="onOrOutLineByVIN">
UPDATE `couplet-cloud`.`couplet_vehicle`
SET `vehicle_state` = #{status}
WHERE `vin` = #{vin};
</update>
<delete id="deleteVehicle">
update couplet_middle
set del_flag = '2'

View File

@ -15,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -17,15 +17,11 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
main:
allow-bean-definition-overriding: true

View File

@ -4,8 +4,6 @@ server:
# Spring
spring:
main:
allow-bean-definition-overriding: true
application:
# 应用名称
name: couplet-job
@ -17,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -106,6 +106,15 @@
<groupId>com.couplet</groupId>
<artifactId>couplet-common-business</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.kafka</groupId>-->
<!-- <artifactId>spring-kafka</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
<build>

View File

@ -25,16 +25,22 @@ import org.springframework.context.annotation.Primary;
public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {
// 通过注入的方式获取队列名、交换机名和路由键
//队列名
@Value("${mq.queueName}")
@Value("queueName")
public String queueName;
//队列名
public static final String FENCE_QUEUE ="fenceQueue";
//交换机
@Value("${mq.exchangeName}")
@Value("exchangeName")
public String exchangeName;
public static final String FENCE_EXCHANGE="fenceExchange";
//路由键
@Value("${mq.routingKey}")
@Value("routingKey")
public String routingKey;
//路由键
public static final String FENCE_ROUTINGKEY="fenceRoutingKey";
private RabbitTemplate rabbitTemplate;
@ -61,6 +67,10 @@ public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback, RabbitTem
public Queue queue() {
return new Queue(queueName, true);
}
@Bean("fenceQueue")
public Queue queue2() {
return new Queue(FENCE_QUEUE, true);
}
/*
* @Author: LiuYunHu
@ -74,6 +84,11 @@ public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback, RabbitTem
return new DirectExchange(exchangeName);
}
@Bean("fenceExchange")
public DirectExchange directExchange2() {
return new DirectExchange(FENCE_EXCHANGE);
}
/*
* @Author: LiuYunHu
* @Date: 2024/3/29 21:27
@ -116,6 +131,11 @@ public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback, RabbitTem
return BindingBuilder.bind(queue()).to(directExchange()).with(routingKey);
}
@Bean("fenceRoutingKey")
public Binding binding2() {
return BindingBuilder.bind(queue2()).to(directExchange2()).with(FENCE_ROUTINGKEY);
}
/*
* @Author: LiuYunHu
* @Date: 2024/3/29 21:28

View File

@ -0,0 +1,54 @@
package com.couplet.mq.controller;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
/**
* @author DongXiaoDong
* @version 1.0
* @date 2024/4/5 21:38
* @description
*/
public class KafkaTest {
private static final String TOPIC_NAME = "online";
private static final String BOOTSTRAP_SERVERS = "39.103.133.136:9092";
public static void main(String[] args) {
aaa();
}
private static void aaa() {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-consumer-group");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
//创建消费者
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
try {
//订阅主题
consumer.subscribe(Collections.singletonList("online"));
//持续消费消息
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
records.forEach(record -> {
System.out.println("消费者接受到的消息值:" + record.value());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
consumer.close();
}
}
}

View File

@ -1,15 +1,20 @@
package com.couplet.mq.controller;
import com.couplet.common.core.utils.uuid.IdUtils;
import com.couplet.common.domain.request.FenceUpdateRequest;
import com.couplet.common.domain.request.RealTimeDataRequest;
import com.couplet.common.security.utils.SecurityUtils;
import com.couplet.mq.config.RabbitMQConfig;
import com.couplet.mq.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ProjectName: five-groups-couplet
@ -23,17 +28,17 @@ import org.springframework.web.bind.annotation.*;
public class MqController {
// 通过注入的方式获取队列名、交换机名和路由键
//队列名
@Value("${mq.queueName}")
public static final String queueName="queueName";
@Value("${mq.finByVinQueueName}")
public static final String finByVinQueueName="finByVinQueueName";
@Value("queueName")
public String queueName;
@Value("finByVinQueueName")
public String finByVinQueueName;
//交换机
@Value("${mq.exchangeName}")
public static final String exchangeName="exchangeName";
@Value("exchangeName")
public String exchangeName;
//路由键
@Value("${mq.routingKey}")
public static final String routingKey="routingKey";
@Value("routingKey")
public String routingKey;
@Autowired
private RabbitTemplate rabbitTemplate;
@ -57,13 +62,19 @@ public class MqController {
}
@PostMapping("findByVin/{vin}")
public void postFindByVin(@PathVariable String vin){
RealTimeDataRequest realTimeDataRequest = new RealTimeDataRequest();
@PostMapping("findByVin")
public void postFindByVin(@RequestBody RealTimeDataRequest request){
Long userId = SecurityUtils.getUserId();
realTimeDataRequest.setUserId(userId);
realTimeDataRequest.setVin(vin);
rabbitTemplate.convertAndSend(exchangeName, routingKey, realTimeDataRequest, message -> {
request.setUserId(userId);
rabbitTemplate.convertAndSend(exchangeName, routingKey, request, message -> {
message.getMessageProperties().setMessageId(IdUtils.randomUUID());
return message;
}, new CorrelationData(IdUtils.randomUUID())
);
}
@PostMapping("fenceQueue")
public void fenceQueue(@RequestBody FenceUpdateRequest fenceUpdateRequest){
rabbitTemplate.convertAndSend(RabbitMQConfig.FENCE_EXCHANGE, RabbitMQConfig.FENCE_ROUTINGKEY, fenceUpdateRequest, message -> {
message.getMessageProperties().setMessageId(IdUtils.randomUUID());
return message;
}, new CorrelationData(IdUtils.randomUUID())

View File

@ -0,0 +1,19 @@
package com.couplet.mq.remote;
import com.couplet.common.core.constant.ServiceNameConstants;
import com.couplet.common.domain.request.FenceUpdateRequest;
import com.couplet.mq.remote.factory.RemoteFenceFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(contextId = "remoteVehicleService" ,
value = ServiceNameConstants.BUSINESS_SERVICE,
fallbackFactory = RemoteFenceFallbackFactory.class
)
public interface RemoteFenceService {
@PostMapping("/mq/fenceQueue")
public void fenceQueue(@RequestBody FenceUpdateRequest fenceUpdateRequest);
}

View File

@ -0,0 +1,33 @@
package com.couplet.mq.remote.factory;
import com.couplet.common.domain.request.FenceUpdateRequest;
import com.couplet.mq.remote.RemoteFenceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import static com.couplet.common.core.domain.Result.error;
/**
* @author fufanrui
* @version 1.0
* @description: TODO
* @date 2024/4/2 14:46
*/
@Component
public class RemoteFenceFallbackFactory implements FallbackFactory<RemoteFenceService> {
private static final Logger log = LoggerFactory.getLogger(RemoteFenceFallbackFactory.class);
@Override
public RemoteFenceService create(Throwable cause) {
return new RemoteFenceService() {
@Override
public void fenceQueue(FenceUpdateRequest fenceUpdateRequest) {
error("调用失败...."+cause.getMessage());
}
};
}
}

View File

@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@SuppressWarnings("all")
@RabbitListener(queues = "${mq.queueName}")
@RabbitListener(queues = "queueName")
public class Consumer {
@Autowired
private StringRedisTemplate redis;

View File

@ -0,0 +1,164 @@
package com.couplet.mq.service;
import com.couplet.mq.domain.User;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @ProjectName: five-groups-couplet
* @Author: LiuYunHu
* @CreateTime: 2024/3/28
* @Description: MQ
*/
@Component
@Slf4j
@SuppressWarnings("all")
@RabbitListener(queues = "${mq.queueName}")
public class MqConsumer {
@Autowired
private StringRedisTemplate redis;
/* 线
//创建一个定长线程池
private final Executor executor = Executors.newFixedThreadPool(5);
@Async
@RabbitHandler
public void process(User param, Channel channel, Message message) {
executor.execute(() -> {
try {
handleMessage(param, channel, message);
} catch (IOException e) {
log.error("处理消息失败:{}", e);
}
});
}
//处理信息的方法
private void handleMessage(User param, Channel channel, Message message) throws IOException {
log.info("消费者收到消息为:{},{}" + param, message.getMessageProperties().getDeliveryTag());
long deliveryTag = message.getMessageProperties().getDeliveryTag();
String messageId = message.getMessageProperties().getMessageId();
if (!redis.hasKey("value:" + messageId)) {
redis.opsForValue().set("value:" + messageId, "" + deliveryTag, 5, TimeUnit.MINUTES);
}
// 1 添加成功新数据 0已有重复值,不允许再添加
Long add = redis.opsForSet().add("set:" + messageId, "set:" + messageId);
//过期时间
redis.expire("set:" + messageId, 5, TimeUnit.MINUTES);
try {
if (add == 1) {
//第一次 消费
System.out.println("*****************************");
System.out.println("消费者收到消息:" + param);
System.out.println("*****************************");
log.info("消费结束");
channel.basicAck(deliveryTag, false);
} else {
//重复消费
log.error("重复消费");
channel.basicReject(deliveryTag, false);
//删除缓存
redis.opsForSet().remove("set:" + messageId, "set:" + messageId);
}
} catch (Exception e) {
log.error("消息没有成功消费!");
String s = redis.opsForValue().get("value:" + messageId);
long oldTag = Long.parseLong(s);
if (deliveryTag == (oldTag + 2)) {
log.error("确实消费不了,不入队了!");
channel.basicNack(deliveryTag, false, false);
} else {
log.info("消息消费失败,重新入队");
channel.basicNack(deliveryTag, false, true);
}
}
}
**/
@RabbitHandler
public void process(User param, Channel channel, Message message) throws IOException {
log.info("消费者收到消息为:{},{}" + param, message.getMessageProperties().getDeliveryTag());
long deliveryTag = message.getMessageProperties().getDeliveryTag();
String messageId = message.getMessageProperties().getMessageId();
if (!redis.hasKey("value:" + messageId)) {
redis.opsForValue().set("value:" + messageId, "" + deliveryTag, 5, TimeUnit.MINUTES);
}
// 1 添加成功新数据 0已有重复值,不允许再添加
Long add = redis.opsForSet().add("set:" + messageId, "set:" + messageId);
//过期时间
redis.expire("set:" + messageId, 5, TimeUnit.MINUTES);
try {
if (add == 1) {
//第一次 消费
System.out.println("*****************************");
System.out.println("消费者收到消息:" + param);
System.out.println("*****************************");
log.info("消费结束");
//确认消费
channel.basicAck(deliveryTag, false);
} else {
//重复消费
log.error("重复消费");
//拒绝消费
channel.basicReject(deliveryTag, false);
//删除缓存
redis.opsForSet().remove("set:" + messageId, "set:" + messageId);
}
} catch (Exception e) {
log.error("消息没有成功消费!");
String s = redis.opsForValue().get("value:" + messageId);
long oldTag = Long.parseLong(s);
if (deliveryTag == (oldTag + 2)) {
log.error("确实消费不了,不入队了!");
//拒绝消费
channel.basicNack(deliveryTag, false, false);
} else {
log.info("消息消费失败,重新入队");
//重新入队
channel.basicNack(deliveryTag, false, true);
}
}
}
}

View File

@ -15,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 172469
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 172469
# 配置文件格式
file-extension: yml
# 共享配置
@ -27,6 +25,9 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
main:
allow-bean-definition-overriding: true
logging:
level:
com.couplet.system.mapper: DEBUG
@ -47,3 +48,5 @@ mq:
queueName: queue
exchangeName: exchange
routingKey: routingKey

View File

@ -97,6 +97,18 @@
<artifactId>couplet-common-business</artifactId>
</dependency>
<!-- Kafka依赖-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.kafka</groupId>-->
<!-- <artifactId>spring-kafka</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
<build>

View File

@ -5,6 +5,7 @@ import com.couplet.common.security.annotation.EnableMyFeignClients;
import com.couplet.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @ProjectName: Default (Template) Project
@ -17,6 +18,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication
@EnableScheduling
//@EnableFeignClients
public class OnlineApplication {
public static void main(String[] args) {

View File

@ -1,18 +1,23 @@
package com.couplet.online.utils;
import com.alibaba.fastjson2.JSON;
import com.couplet.common.domain.Vehicle;
import com.couplet.common.redis.service.RedisService;
import com.couplet.remote.RemoteVehicleService;
import com.fasterxml.jackson.databind.ser.std.StringSerializer;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/**
* @ProjectName: five-groups-couplet
@ -66,7 +71,12 @@ public class MqttMonitor {
//redis
@Autowired
private RedisService redis;
private StringRedisTemplate redis;
//Kafka生产者配置
private static final String TOPIC_NAME = "online";
private static final String BOOTSTRAP_SERVERS = "39.103.133.136:9092";
//随项目启动而执行这个方法
@ -132,33 +142,54 @@ public class MqttMonitor {
log.info("当前车辆的vin码为" + start17);
//判断缓存中是否有这个vin
if (redis.hasKey("不存在的车辆VIN" + start17)) {
// //判断缓存中是否有这个vin
// if (redis.hasKey("不存在的车辆VIN" + start17)) {
//
// //可使用RabbitMQ发送消息
// log.error("vin码为" + start17 + "的车辆不属于本系统!");
//
// } else {//如果缓存中没有存这个vin
//
//
// }
//可使用RabbitMQ发送消息
log.error("vin码为" + start17 + "的车辆不属于本系统!");
}
//调取接口通过vin查询车辆
List<Vehicle> vehicles = remoteVehicleService.findByVIN(start17).getData();
System.out.println("**************" + vehicles);
//如果不存在这个车
if (vehicles.isEmpty()) {
if (0 == vehicles.size()) {
//将不属于自己系统的车辆存入缓存,便于提前进行拒绝提示
redis.setCacheObject("不存在的车辆VIN" + start17, start17);
// redis.setCacheObject("不存在的车辆VIN" + start17, start17);
log.error("未找到vin码为" + start17 + "的车辆信息");
} else {
//如果存在这个车
Vehicle vehicle = vehicles.get(0);
System.out.println("***********" + vehicle + "***********");
//存入redis
redis.setCacheObject("存在的车辆VIN" + start17, JSON.toJSONString(vehicle));
log.info("远程调用查询到的车辆数据:" + vehicle);
//上线车辆存入redis 6秒 用于判断车辆是否下线,还要写定时器,定时查询
redis.opsForValue().set(start17, start17, 6L, TimeUnit.SECONDS);
log.info("vin码为" + start17 + "的车辆属于本系统,允许上线!");
}
//调用上线接口,修改上线状态
Integer i = remoteVehicleService.onOrOutLineByVIN(start17 + "," + 1);
//上线成功
if (0 != i) {
log.info("上线成功!");
try {
produceMessage(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Override
@ -176,4 +207,27 @@ public class MqttMonitor {
}
}
//Kafka生产者
private static void produceMessage(String message) {
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
//创建生产者
try {
//发送消息
producer.send(new ProducerRecord<>(TOPIC_NAME, message));
System.out.println("发送消息:" + message);
} catch (Exception e) {
e.printStackTrace();
} finally {
producer.close();
}
}
}

View File

@ -15,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 172469
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 172469
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -4,7 +4,6 @@ server:
# Spring
spring:
application:
# 应用名称
name: couplet-system
@ -16,11 +15,11 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
namespace: 172469
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
namespace: 172469
# 配置文件格式
file-extension: yml
# 共享配置

View File

@ -15,11 +15,9 @@ spring:
discovery:
# 服务注册地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
config:
# 配置中心地址
server-addr: 121.89.211.230:8848
namespace: 968741d4-299d-483c-8d30-ede2aff8cfd4
# 配置文件格式
file-extension: yml
# 共享配置

83
pom.xml
View File

@ -211,47 +211,47 @@
<artifactId>couplet-modules-system</artifactId>
<version>${couplet.version}</version>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-trouble</artifactId>
<version>${couplet.version}</version>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-electronic-fence-server</artifactId>
<version>${couplet.version}</version>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-electronic-fence-common</artifactId>
<version>${couplet.version}</version>
</dependency>
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-electronic-fence-remote</artifactId>
<version>${couplet.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-trouble</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-electronic-fence-server</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-electronic-fence-common</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-electronic-fence-remote</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- 企业服务 模块 公共依赖 -->
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-enterprisemanagement-common</artifactId>
<version>${couplet.version}</version>
</dependency>
<!-- &lt;!&ndash; 企业服务 模块 公共依赖 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-enterprisemanagement-common</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- 企业服务 模块 远程调用依赖 -->
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-enterprisemanagement-remote</artifactId>
<version>${couplet.version}</version>
</dependency>
<!-- &lt;!&ndash; 企业服务 模块 远程调用依赖 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-enterprisemanagement-remote</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- 车辆管理模块 -->
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-modules-vehicle</artifactId>
<version>${couplet.version}</version>
</dependency>
<!-- &lt;!&ndash; 车辆管理模块 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.couplet</groupId>-->
<!-- <artifactId>couplet-modules-vehicle</artifactId>-->
<!-- <version>${couplet.version}</version>-->
<!-- </dependency>-->
<!-- RabbitMq模块 -->
<dependency>
@ -275,6 +275,13 @@
<version>${couplet.version}</version>
</dependency>
<!--车辆解析模块-->
<dependency>
<groupId>com.couplet</groupId>
<artifactId>couplet-analyze-msg</artifactId>
<version>${couplet.version}</version>
</dependency>
</dependencies>
</dependencyManagement>