Browse Source

Merge branch 'develop' of http://39.106.31.193:9211/mengff/jihe-dc into develop

develop
lau572 1 year ago
parent
commit
b242713b6f
  1. 2
      ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
  2. 9
      zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java
  3. 181
      zc-business/src/main/java/com/zc/business/controller/DeviceStatus.java
  4. 153
      zc-business/src/main/java/com/zc/business/controller/StatusController.java
  5. 65
      zc-business/src/main/java/com/zc/business/domain/Device.java
  6. 205
      zc-business/src/main/java/com/zc/business/domain/Status.java
  7. 16
      zc-business/src/main/java/com/zc/business/mapper/DeviceMapper.java
  8. 21
      zc-business/src/main/java/com/zc/business/mapper/StatusMapper.java
  9. 23
      zc-business/src/main/java/com/zc/business/message/device/OfflineMessageListener.java
  10. 23
      zc-business/src/main/java/com/zc/business/service/impl/DeviceService.java
  11. 192
      zc-business/src/main/java/com/zc/business/service/impl/ExcelExportService.java
  12. 33
      zc-business/src/main/java/com/zc/business/service/impl/StatusService.java
  13. 16
      zc-business/src/main/resources/mapper/business/DeviceMapper.xml
  14. 94
      zc-business/src/main/resources/mapper/business/StatusMapper.xml

2
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java

@ -157,7 +157,7 @@ public class Constants
/**
* 定时任务白名单配置仅允许访问的包名如其他需要可以自行添加
*/
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi","com.zc" };
/**
* 定时任务违规的字符

9
zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java

@ -136,6 +136,7 @@ public class DcDeviceController extends BaseController {
* @param deviceId 物联设备id
* @return 获取属性数据操作结果
*/
@ApiOperation("获取设备最新属性数据")
@GetMapping("/properties/latest/{deviceId}")
public AjaxResult getDeviceLatestProperties(@PathVariable @Parameter(description = "设备ID") String deviceId) throws HttpException, IOException {
@ -155,6 +156,7 @@ public class DcDeviceController extends BaseController {
* @param props 查询条件
* @return 属性列表
*/
@ApiOperation("获取设备历史属性列表")
@GetMapping("/properties/history/{deviceId}/{propertyId}")
public AjaxResult queryDeviceProperties(@PathVariable @Parameter(description = "设备ID") String deviceId,
@PathVariable @Parameter(description = "属性ID") String propertyId,
@ -178,6 +180,7 @@ public class DcDeviceController extends BaseController {
* @param propertyId 属性id
* @return 获取属性数据操作结果
*/
@ApiOperation("获取设备指定属性最新数据")
@GetMapping("/properties/latest/{deviceId}/{propertyId}")
public AjaxResult getDeviceLatestProperty(@PathVariable @Parameter(description = "设备ID") String deviceId,
@PathVariable @Parameter(description = "属性ID") String propertyId) throws HttpException, IOException {
@ -196,6 +199,7 @@ public class DcDeviceController extends BaseController {
* @param propertyId 属性
* @return 属性实时数据
*/
@ApiOperation("获取设备指定属性实时数据")
@GetMapping("/properties/realtime/{deviceId}/{propertyId}")
public AjaxResult getDeviceRealtimeProperty(
@PathVariable String deviceId,
@ -221,6 +225,7 @@ public class DcDeviceController extends BaseController {
* @param props 属性id集
* @return 属性实时数据
*/
@ApiOperation("获取设备属性实时数据")
@PostMapping("/properties/realtime/{deviceId}")
public AjaxResult getDeviceRealtimeProperties(
@PathVariable String deviceId,
@ -249,6 +254,7 @@ public class DcDeviceController extends BaseController {
* @param props 参数
* @return 设备属性操作结果
*/
@ApiOperation("设置设备属性值")
@PostMapping("/properties/setting/{deviceId}")
public AjaxResult setDeviceProperties(
@PathVariable String deviceId,
@ -274,6 +280,7 @@ public class DcDeviceController extends BaseController {
* @param props 调用参数
* @return 调用结果
*/
@ApiOperation("设备功能调用")
@PostMapping("/functions/{deviceId}/{functionId}")
public AjaxResult invokedFunction(
@PathVariable String deviceId,
@ -302,6 +309,7 @@ public class DcDeviceController extends BaseController {
* @param queryParam 查询条件
* @return 查询事件结果
*/
@ApiOperation("查询事件历史数据列表")
@GetMapping("/events/history/{deviceId}/{eventId}")
public AjaxResult queryPagerDeviceEvents(
@PathVariable @Parameter(description = "设备ID") String deviceId,
@ -327,6 +335,7 @@ public class DcDeviceController extends BaseController {
* @param id 物联设备id
* @return 更新结果
*/
@ApiOperation("获取设备物模型")
@GetMapping(value = "/metadata/{id}")
public AjaxResult getMetadata(@PathVariable String id) throws HttpException, IOException {

181
zc-business/src/main/java/com/zc/business/controller/DeviceStatus.java

@ -0,0 +1,181 @@
package com.zc.business.controller;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.zc.business.service.impl.DeviceService;
import com.zc.business.service.impl.ExcelExportService;
import com.zc.business.service.impl.StatusService;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import com.zc.business.domain.Status;
import com.zc.business.domain.Device;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@Component
@EnableScheduling
public class DeviceStatus {
@Autowired
private DeviceService deviceService;
@Autowired
private StatusService statusService;
@Autowired
private ExcelExportService excelExportService;
//每天凌晨0点到晚上23点整点测试设备状态
// @Scheduled(cron = "0 0 0-23 * * ?")
// @Scheduled(cron = "0 0 1,5,7,8,11,14,17,19,21,23")
public void deviceStatus() {
DeviceService deviceService= SpringUtils.getBean(DeviceService.class);
StatusService statusService= SpringUtils.getBean(StatusService.class);
ExecutorService executor = Executors.newFixedThreadPool(100);
List<Device> deviceList = deviceService.SelectList();
List<Future<Void>> futures = new ArrayList<>();
for (Device device : deviceList) {
Callable<Void> task = () -> {
try {
Status status = new Status();
InetAddress address = InetAddress.getByName(device.getDeviceIp());
String lostRate = getPingPacketLossRate(device.getDeviceIp());
boolean reachable = address.isReachable(5000); // Timeout: 5 seconds
status.setDeviceNo(device.getDeviceNo());
status.setDeviceName(device.getDeviceName());
status.setDeviceIp(device.getDeviceIp());
LocalDateTime localDateTime = LocalDateTime.now();
status.setTime(localDateTime);
status.setLostRate(lostRate);
if (reachable) {
status.setDeviceStatus(1);
status.setSuccessRate("100.00%");
} else {
status.setDeviceStatus(0);
status.setSuccessRate("0.00%");
}
statusService.Add(status);
} catch (IOException e) {
System.out.println("Error pinging " + device.getDeviceIp() + ": " + e.getMessage());
}
return null;
};
futures.add(executor.submit(task));
}
for (Future<Void> future : futures) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
/**
* 计算丢包率
*/
public String getPingPacketLossRate(String ipAddress) {
try {
// Execute the ping command
Process process = Runtime.getRuntime().exec("ping -c 4 " + ipAddress); // Sending 4 ICMP Echo Request packets
// Read the output of the command
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
int packetsSent = 0;
int packetsLost = 0;
while ((line = reader.readLine()) != null) {
// Check for lines containing packet loss information
if (line.contains("packets transmitted")) {
// Extract the number of packets sent and lost
String[] stats = line.split(", ");
packetsSent = Integer.parseInt(stats[0].split(" ")[0]);
packetsLost = Integer.parseInt(stats[0].split(" ")[0])-Integer.parseInt(stats[1].split(" ")[0]);
}
}
// Calculate and return the packet loss rate
if (packetsSent > 0) {
return String.format("%.2f%%", (double) packetsLost / packetsSent * 100);
} else {
return "0.00%"; // No packets sent
}
} catch (IOException e) {
e.printStackTrace();
return "-1.00%"; // Error occurred
}
}
/**
* 成功率和丢包率按小时分组
* 每天17点 23点 30分导出excel表
*/
// @Scheduled(cron = "0 30 17,23 * * ?")
public void calculateSuccessRate() {
StatusService statusService= SpringUtils.getBean(StatusService.class);
ExcelExportService excelExportService= SpringUtils.getBean(ExcelExportService.class);
LocalDateTime todayStart = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
LocalDateTime currentTime = LocalDateTime.now();
Status status = new Status();
status.setStartTime(todayStart);
status.setTime(currentTime);
List<Status> listStatus = statusService.list(status);
//根据时间分组
Map<Integer, List<Status>> map = listStatus.stream()
.collect(Collectors.groupingBy(Status -> Status.getTime().getHour()));
//根据类型分组
Map<String, List<Status>> maps = listStatus.stream().filter(iteam->iteam.getType()!=null).collect(Collectors.groupingBy(Status::getType));
String filePath=CreateNamedExcel();
excelExportService.exportDataToExcel(map,maps,filePath);
}
public String CreateNamedExcel() {
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = dateTime.format(formatter);
//修改成服务器地址
String filePath = "/Users/mengfanfeng/Downloads/excel/"+formattedDateTime+"--deviceStatus.xlsx";
try (Workbook workbook = new XSSFWorkbook()) {
FileOutputStream fileOut = new FileOutputStream(filePath);
workbook.write(fileOut);
System.out.println("Empty named Excel created successfully.");
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
}

153
zc-business/src/main/java/com/zc/business/controller/StatusController.java

@ -0,0 +1,153 @@
package com.zc.business.controller;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.zc.business.domain.Status;
import com.zc.business.service.impl.StatusService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import static com.ruoyi.common.utils.PageUtils.startPage;
@Api(tags="设备状态")
@RestController
@RequestMapping("/system/status")
public class StatusController extends BaseController {
@Autowired
private StatusService statusService;
//设备列表
@ApiOperation("设备状态列表按时间和类型")
@GetMapping ("/tablist")
public TableDataInfo getTabList(Status status)
{
startPage();
LocalDateTime todayStart = status.getStartTime().truncatedTo(ChronoUnit.DAYS);
LocalDateTime currentTime = status.getTime().truncatedTo(ChronoUnit.DAYS).plusDays(1);
status.setStartTime(todayStart);
status.setTime(currentTime);
List<Status> listStatus = statusService.list(status);
return getDataTable(listStatus);
}
//按时间划分设备柱状图
@ApiOperation("设备状态柱状图按时间和类型")
@GetMapping ("/list")
public AjaxResult getStatusList(Status status)
{
LocalDateTime todayStart = status.getStartTime().truncatedTo(ChronoUnit.DAYS);
LocalDateTime currentTime = status.getTime().truncatedTo(ChronoUnit.DAYS).plusDays(1);
status.setStartTime(todayStart);
status.setTime(currentTime);
String type=status.getType();
List<Status> listStatus = statusService.list(status);
List<Status> listStatu=listStatus.stream().filter(iteam ->iteam.getType()!=null && iteam.getType().equals(type)).collect(Collectors.toList());
//根据时间分组
Map<String, List<Status>> map = listStatu.stream()
.collect(Collectors.groupingBy(Status -> (Status.getTime().getYear()+"-"+Status.getTime().getMonthValue()+"-"+Status.getTime().getDayOfYear())));
//根据类型分组
// Map<String, List<Status>> maps = listStatu.stream().filter(iteam->iteam.getType()!=null).collect(Collectors.groupingBy(Status::getType));
//生成有序map
Map<String, List<Status>> mapTime = new TreeMap<>(map);
Map<String,String> mapSort=new TreeMap<>();
for (Map.Entry<String, List<Status>> entry : mapTime.entrySet()) {
List<Status> groupItems = entry.getValue();
long count = groupItems.stream().filter(iteam -> iteam.getDeviceStatus() == 1).count();
String onlineRate=String.format("%.2f%%", (double) count / groupItems.size() * 100);
mapSort.put(entry.getKey(),onlineRate);
}
// Map<String, List<Status>> mapStatus = new TreeMap<>(maps);
return AjaxResult.success(mapSort);
}
//按类型划分设备
@ApiOperation("设备状态列表按类型")
@GetMapping ("/type")
public AjaxResult getTypeList()
{
HashMap<String, String> itemTypeMap = new HashMap<>();
itemTypeMap.put("1", "高清网络枪型固定摄像机");
itemTypeMap.put("2", "高清网络球形摄像机");
itemTypeMap.put("3", "桥下高清网络球形摄像机");
itemTypeMap.put("4", "360°全景摄像机");
itemTypeMap.put("5", "180°全景摄像机");
itemTypeMap.put("6", "门架式可变信息标志");
itemTypeMap.put("7", "雨棚可变信息标志");
itemTypeMap.put("8", "站前悬臂式可变信息标志");
itemTypeMap.put("9", "气象检测器");
itemTypeMap.put("10", "路段语音广播系统");
itemTypeMap.put("11", "护栏碰撞预警系统");
itemTypeMap.put("12", "毫米波雷达");
itemTypeMap.put("13", "合流区预警系统");
itemTypeMap.put("14", "激光疲劳唤醒");
itemTypeMap.put("15", "一类交通量调查站");
itemTypeMap.put("16", "智能行车诱导系统");
itemTypeMap.put("17", "智能设备箱");
LocalDateTime todayStart = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
LocalDateTime currentTime = LocalDateTime.now();
Status status = new Status();
status.setStartTime(todayStart);
status.setTime(currentTime);
List<Status> listStatus = statusService.list(status);
//根据时间分组
Map<Integer, List<Status>> map = listStatus.stream()
.collect(Collectors.groupingBy(Status -> Status.getTime().getHour()));
Map<Integer, List<Status>> ipMap = new TreeMap<>(map);
Integer lastKey = Collections.max(ipMap.keySet());
List<Status> lastEntry = ipMap.get(lastKey);
Map<String, List<Status>> typeMap = lastEntry.stream().filter(iteam -> iteam.getType() != null).collect(Collectors.groupingBy(Status::getType));
Map<String,Map<String,String>> subMap=new HashMap<>();
for (Map.Entry<String, List<Status>> entrys : typeMap.entrySet()) {
Map<String, String> maps=new HashMap<>();
List<Status> groupItems = entrys.getValue();
double lostRate = groupItems.stream()
.mapToDouble(Status -> Double.parseDouble(Status.getLostRate().replace("%", ""))) // 去掉%,并转换为double
.average().getAsDouble();
double sucessRate = groupItems.stream()
.mapToDouble(Status -> Double.parseDouble(Status.getSuccessRate().replace("%", ""))) // 去掉%,并转换为double
.average().getAsDouble();
String failRate=String.format("%.2f", (100-sucessRate))+"%";
//丢包率
maps.put("lostRate",String.format("%.2f", lostRate)+"%");
//在线率
maps.put("sucessRate",String.format("%.2f", sucessRate)+"%");
//离线率
maps.put("failRate",failRate);
//总数
maps.put("sum",String.valueOf(groupItems.size()));
subMap.put(itemTypeMap.get(entrys.getKey()),maps);
}
Map<String, String> maps=new HashMap<>();
double lostRate = lastEntry.stream()
.mapToDouble(Status -> Double.parseDouble(Status.getLostRate().replace("%", ""))) // 去掉%,并转换为double
.average().getAsDouble();
double sucessRate = lastEntry.stream()
.mapToDouble(Status -> Double.parseDouble(Status.getSuccessRate().replace("%", ""))) // 去掉%,并转换为double
.average().getAsDouble();
String failRate=String.format("%.2f", (100-sucessRate))+"%";
//丢包率
maps.put("lostRate",String.format("%.2f", lostRate)+"%");
//在线率
maps.put("sucessRate",String.format("%.2f", sucessRate)+"%");
//离线率
maps.put("failRate",failRate);
//总数
maps.put("sum",String.valueOf(lastEntry.size()));
subMap.put("全部设备",maps);
return AjaxResult.success(subMap);
}
}

65
zc-business/src/main/java/com/zc/business/domain/Device.java

@ -0,0 +1,65 @@
package com.zc.business.domain;
/**
* @author mengff
* @Date 2020/03/03
*/
public class Device {
private long id;
public String getDeviceNo() {
return deviceNo;
}
public void setDeviceNo(String deviceNo) {
this.deviceNo = deviceNo;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceIp() {
return deviceIp;
}
@Override
public String toString() {
return "Device{" +
"id=" + id +
", deviceNo='" + deviceNo + '\'' +
", deviceName='" + deviceName + '\'' +
", deviceIp='" + deviceIp + '\'' +
'}';
}
public Device(long id, String deviceNo, String deviceName, String deviceIp) {
this.id = id;
this.deviceNo = deviceNo;
this.deviceName = deviceName;
this.deviceIp = deviceIp;
}
public void setDeviceIp(String deviceIp) {
this.deviceIp = deviceIp;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String deviceNo;
private String deviceName;
private String deviceIp;
private String type;
}

205
zc-business/src/main/java/com/zc/business/domain/Status.java

@ -0,0 +1,205 @@
package com.zc.business.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* @author mengff
* @Date 2024/01/04
*/
public class Status {
public String getDeviceIp() {
return deviceIp;
}
public void setDeviceIp(String deviceIp) {
this.deviceIp = deviceIp;
}
public LocalDateTime getStartTime() {
return startTime;
}
public Status(long id, String deviceNo, String deviceName, int deviceStatus, LocalDateTime time, LocalDateTime startTime, String deviceIp, String successRate, String lostRate, String direction, String production, String model, String network, String content, String type) {
this.id = id;
this.deviceNo = deviceNo;
this.deviceName = deviceName;
this.deviceStatus = deviceStatus;
this.time = time;
this.startTime = startTime;
this.deviceIp = deviceIp;
this.successRate = successRate;
this.lostRate = lostRate;
this.direction = direction;
this.production = production;
this.model = model;
this.network = network;
this.content = content;
this.type = type;
}
public void setStartTime(LocalDateTime startTime) {
this.startTime = startTime;
}
@Override
public String toString() {
return "Status{" +
"id=" + id +
", deviceNo='" + deviceNo + '\'' +
", deviceName='" + deviceName + '\'' +
", deviceStatus=" + deviceStatus +
", time=" + time +
", startTime=" + startTime +
", deviceIp='" + deviceIp + '\'' +
", successRate='" + successRate + '\'' +
", lostRate='" + lostRate + '\'' +
", direction='" + direction + '\'' +
", production='" + production + '\'' +
", model='" + model + '\'' +
", network='" + network + '\'' +
", content='" + content + '\'' +
", type='" + type + '\'' +
'}';
}
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalDateTime time) {
this.time = time;
}
public String getDeviceNo() {
return deviceNo;
}
public Status(long id, String deviceNo, String deviceName, int deviceStatus) {
this.id = id;
this.deviceNo = deviceNo;
this.deviceName = deviceName;
this.deviceStatus = deviceStatus;
}
public Status() {
}
public void setDeviceNo(String deviceNo) {
this.deviceNo = deviceNo;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public int getDeviceStatus() {
return deviceStatus;
}
public void setDeviceStatus(int deviceStatus) {
this.deviceStatus = deviceStatus;
}
private long id;
private String deviceNo;
private String deviceName;
private int deviceStatus;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss")
private LocalDateTime time;
public String getSuccessRate() {
return successRate;
}
public void setSuccessRate(String successRate) {
this.successRate = successRate;
}
public String getLostRate() {
return lostRate;
}
public void setLostRate(String lostRate) {
this.lostRate = lostRate;
}
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
private String deviceIp;
private String successRate;
private String lostRate;
private String direction;
private String production;
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public String getProduction() {
return production;
}
public void setProduction(String production) {
this.production = production;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getNetwork() {
return network;
}
public void setNetwork(String network) {
this.network = network;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
private String model;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String network;
private String content;
private String type;
}

16
zc-business/src/main/java/com/zc/business/mapper/DeviceMapper.java

@ -0,0 +1,16 @@
package com.zc.business.mapper;
import com.zc.business.domain.Device;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author mengff
* @Date 2024/01/04
*/
@Repository
public interface DeviceMapper {
List<Device> SelectList();
}

21
zc-business/src/main/java/com/zc/business/mapper/StatusMapper.java

@ -0,0 +1,21 @@
package com.zc.business.mapper;
import com.zc.business.domain.Status;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author mengff
* @Date 2024/01/04
*/
@Repository
public interface StatusMapper {
int Add(@Param("status")Status status);
List<Status> listStatus(@Param("status")Status status);
}

23
zc-business/src/main/java/com/zc/business/message/device/OfflineMessageListener.java

@ -1,14 +1,18 @@
package com.zc.business.message.device;
import com.alibaba.fastjson.JSON;
import com.zc.common.core.redis.stream.RedisStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.connection.stream.RecordId;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 离线消息监听
*/
@ -17,15 +21,30 @@ public class OfflineMessageListener implements StreamListener<String, ObjectReco
{
private static final Logger log = LoggerFactory.getLogger(OfflineMessageListener.class);
@Autowired
@Resource
private RedisStream redisStream;
@Resource
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void onMessage(ObjectRecord<String, String> message) {
String streamKay = message.getStream();
RecordId recordId = message.getId();
threadPoolTaskExecutor.execute(() -> {
List<String> list = JSON.parseArray(message.getValue(), String.class);
this.handle(list);
});
// 消费完后直接删除消息
redisStream.del(streamKay, String.valueOf(recordId));
}
/**
* 处理离线消息
*/
private void handle(List<String> msg) {
System.out.println(msg);
}
}

23
zc-business/src/main/java/com/zc/business/service/impl/DeviceService.java

@ -0,0 +1,23 @@
package com.zc.business.service.impl;
import com.zc.business.domain.Device;
import com.zc.business.mapper.DeviceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author mengff
* @Date 2024/01/04
*/
@Service
public class DeviceService {
@Autowired
DeviceMapper deviceMapper;
public List<Device> SelectList() {
return deviceMapper.SelectList();
}
}

192
zc-business/src/main/java/com/zc/business/service/impl/ExcelExportService.java

@ -0,0 +1,192 @@
package com.zc.business.service.impl;
import com.zc.business.domain.Status;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
@Service
public class ExcelExportService {
public void exportDataToExcel(Map<Integer, List<Status>> ipMap, Map<String, List<Status> >categoryMap, String filePath) {
Workbook workbook = new XSSFWorkbook();
Map<Integer, List<Status>> map = new TreeMap<>(ipMap);
Sheet sheet = workbook.createSheet("设备故障率分时统计页");
int rowNum = 0;
Row row0 = sheet.createRow(0);
row0.createCell(0).setCellValue("设备名称");
row0.createCell(1).setCellValue("设备IP");
row0.createCell(2).setCellValue("设备桩号");
row0.createCell(3).setCellValue("设备方向");
row0.createCell(4).setCellValue("设备厂家");
row0.createCell(5).setCellValue("设备型号");
row0.createCell(6).setCellValue("备注");
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 1, 1));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 2, 2));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 3, 3));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 4, 4));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 5, 5));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 6, 6));
int i=0;
boolean flag = true;
Row row1= sheet.createRow(1);
for (Map.Entry<Integer, List<Status>> entry : map.entrySet()) {
row0.createCell(2*i+7).setCellValue(entry.getKey()+"时");
sheet.addMergedRegion(new CellRangeAddress(0, 0, 2*i+7, 2*i+8));
row1.createCell(2*i+7).setCellValue("在线率");
row1.createCell(2*i+8).setCellValue("丢包率");
rowNum = 2;
List<Status> groupItems = entry.getValue();
for (Status ignored : groupItems) {
int a=rowNum++;
Row row = sheet.getRow(a); // 获取指定索引的行
if (row == null) { // 如果行不存在,则创建新行
row = sheet.createRow(a);
}
if(flag) {
row.createCell(0).setCellValue(ignored.getDeviceName());
row.createCell(1).setCellValue(ignored.getDeviceIp());
row.createCell(2).setCellValue(ignored.getDeviceNo());
row.createCell(3).setCellValue(ignored.getDirection());
row.createCell(4).setCellValue(ignored.getProduction());
row.createCell(5).setCellValue(ignored.getModel());
row.createCell(6).setCellValue(ignored.getContent());
}
row.createCell(2*i+7).setCellValue(ignored.getSuccessRate());
row.createCell(2*i+8).setCellValue(ignored.getLostRate());
}
i++;
flag = false;
}
Sheet sheets = workbook.createSheet("设备故障率汇总页");
createSheet(sheets,categoryMap);
Sheet sheet1 = workbook.createSheet("设备故障率分时汇总页");
createSheet1(sheet1,ipMap);
try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
workbook.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("excel写入成功!!!!!!");
}
public void createSheet1(Sheet sheet,Map<Integer, List<Status>> ipMap){
Map<Integer, List<Status>> map = new TreeMap<>(ipMap);
int rowNum = 0;
Row row0 = sheet.createRow(rowNum);
row0.createCell(0).setCellValue("设备分类");
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
int i=0;
boolean flag = true;
Row row1= sheet.createRow(1);
for (Map.Entry<Integer, List<Status>> entry : map.entrySet()) {
row0.createCell(3 * i + 1).setCellValue(entry.getKey() + "时");
sheet.addMergedRegion(new CellRangeAddress(0, 0, 3 * i + 1, 3 * i + 3));
row1.createCell(3 * i + 1).setCellValue("总统计数");
row1.createCell(3 * i + 2).setCellValue("在线统计数");
row1.createCell(3 * i + 3).setCellValue("在线率");
rowNum = 2;
List<Status> groupItem = entry.getValue();
Map<String, List<Status>> maps = groupItem.stream().filter(iteam -> iteam.getType() != null).collect(Collectors.groupingBy(Status::getType));
for (Map.Entry<String, List<Status>> entrys : maps.entrySet()) {
List<Status> groupItems = entrys.getValue();
long b = groupItems.stream().filter(iteam -> iteam.getDeviceStatus() == 1).count();
// for (Status ignored : groupItems) {
int a = rowNum++;
Row row = sheet.getRow(a); // 获取指定索引的行
if (row == null) { // 如果行不存在,则创建新行
row = sheet.createRow(a);
}
HashMap<String, String> itemTypeMap = new HashMap<>();
itemTypeMap.put("1", "高清网络枪型固定摄像机");
itemTypeMap.put("2", "高清网络球形摄像机");
itemTypeMap.put("3", "桥下高清网络球形摄像机");
itemTypeMap.put("4", "360°全景摄像机");
itemTypeMap.put("5", "180°全景摄像机");
itemTypeMap.put("6", "门架式可变信息标志");
itemTypeMap.put("7", "雨棚可变信息标志");
itemTypeMap.put("8", "站前悬臂式可变信息标志");
itemTypeMap.put("9", "气象检测器");
itemTypeMap.put("10", "路段语音广播系统");
itemTypeMap.put("11", "护栏碰撞预警系统");
itemTypeMap.put("12", "毫米波雷达");
itemTypeMap.put("13", "合流区预警系统");
itemTypeMap.put("14", "激光疲劳唤醒");
itemTypeMap.put("15", "一类交通量调查站");
itemTypeMap.put("16", "智能行车诱导系统");
itemTypeMap.put("17", "智能设备箱");
String type = groupItems.get(0).getType();
String description = itemTypeMap.get(type);
if (flag) {
row.createCell(0).setCellValue(description);
}
row.createCell(3 * i + 1).setCellValue(groupItems.size());
row.createCell(3 * i + 2).setCellValue(b);
row.createCell(3 * i + 3).setCellValue(String.format("%.2f%%", (double) b / groupItems.size() * 100));
}
i++;
flag = false;
// }
}
}
public void createSheet(Sheet sheet,Map<String, List<Status> >categoryMap){
int rowNum = 0;
Row row = sheet.createRow(rowNum);
row.createCell(0).setCellValue("设备分类");
row.createCell(1).setCellValue("总统计数");
row.createCell(2).setCellValue("在线统计数");
row.createCell(3).setCellValue("在线率");
rowNum = 1;
for (Map.Entry<String, List<Status>> entry : categoryMap.entrySet()) {
List<Status> groupItems = entry.getValue();
long a=groupItems.stream().filter(iteam->iteam.getDeviceStatus()==1).count();
row = sheet.createRow(rowNum++);
HashMap<String, String> itemTypeMap = new HashMap<>();
itemTypeMap.put("1", "高清网络枪型固定摄像机");
itemTypeMap.put("2", "高清网络球形摄像机");
itemTypeMap.put("3", "桥下高清网络球形摄像机");
itemTypeMap.put("4", "360°全景摄像机");
itemTypeMap.put("5", "180°全景摄像机");
itemTypeMap.put("6", "门架式可变信息标志");
itemTypeMap.put("7", "雨棚可变信息标志");
itemTypeMap.put("8", "站前悬臂式可变信息标志");
itemTypeMap.put("9", "气象检测器");
itemTypeMap.put("10", "路段语音广播系统");
itemTypeMap.put("11", "护栏碰撞预警系统");
itemTypeMap.put("12", "毫米波雷达");
itemTypeMap.put("13", "合流区预警系统");
itemTypeMap.put("14", "激光疲劳唤醒");
itemTypeMap.put("15", "一类交通量调查站");
itemTypeMap.put("16", "智能行车诱导系统");
itemTypeMap.put("17", "智能设备箱");
String type = groupItems.get(0).getType();
String description = itemTypeMap.get(type);
row.createCell(0).setCellValue(description);
row.createCell(1).setCellValue(groupItems.size());
row.createCell(2).setCellValue(a);
row.createCell(3).setCellValue(String.format("%.2f%%", (double) a / groupItems.size() * 100));
}
}
}

33
zc-business/src/main/java/com/zc/business/service/impl/StatusService.java

@ -0,0 +1,33 @@
package com.zc.business.service.impl;
import com.zc.business.domain.Status;
import com.zc.business.mapper.StatusMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author mengff
* @Date 2024/01/04
*/
@Service
public class StatusService {
@Autowired
StatusMapper statusMapper;
public String Add(Status status) {
int a = statusMapper.Add(status);
if (a == 1) {
return "添加成功";
} else {
return "添加失败";
}
}
public List<Status> list(Status status) {
List<Status> list = statusMapper.listStatus(status);
return list;
}
}

16
zc-business/src/main/resources/mapper/business/DeviceMapper.xml

@ -0,0 +1,16 @@
<?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.zc.business.mapper.DeviceMapper">
<resultMap id="BaseResultMap" type="com.zc.business.domain.Device">
<result column="id" jdbcType="BIGINT" property="id"/>
<result column="device_no" jdbcType="VARCHAR" property="deviceNo"/>
<result column="device_name" jdbcType="VARCHAR" property="deviceName"/>
<result column="device_ip" jdbcType="VARCHAR" property="deviceIp"/>
</resultMap>
<select id="SelectList" resultType="com.zc.business.domain.Device">
select * from device
</select>
</mapper>

94
zc-business/src/main/resources/mapper/business/StatusMapper.xml

@ -0,0 +1,94 @@
<?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.zc.business.mapper.StatusMapper">
<resultMap id="BaseResultMap" type="com.zc.business.domain.Status">
<result column="id" jdbcType="BIGINT" property="id"/>
<result column="device_no" jdbcType="VARCHAR" property="deviceNo"/>
<result column="device_name" jdbcType="VARCHAR" property="deviceName"/>
<result column="device_status" jdbcType="INTEGER" property="deviceStatus"/>
<result column="device_ip" jdbcType="VARCHAR" property="deviceIp"/>
<result column="success_rate" jdbcType="VARCHAR" property="successRate"/>
<result column="lost_rate" jdbcType="VARCHAR" property="lostRate"/>
<result column="direction" jdbcType="VARCHAR" property="direction"/>
<result column="production" jdbcType="VARCHAR" property="production"/>
<result column="model" jdbcType="VARCHAR" property="model"/>
<result column="network" jdbcType="VARCHAR" property="network"/>
<result column="content" jdbcType="VARCHAR" property="content"/>
<result column="type" jdbcType="VARCHAR" property="type"/>
</resultMap>
<insert id="Add" parameterType="com.zc.business.domain.Status">
INSERT INTO status
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="status.deviceNo != null">
device_no,
</if>
<if test="status.deviceName != null">
device_name,
</if>
<if test="status.deviceStatus != null">
device_status,
</if>
<if test="status.time != null">
time,
</if>
<if test="status.successRate != null">
success_rate,
</if>
<if test="status.lostRate != null">
lost_rate,
</if>
<if test="status.deviceIp != null">
device_ip,
</if>
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="status.deviceNo != null">
#{status.deviceNo,jdbcType=VARCHAR},
</if>
<if test="status.deviceName != null">
#{status.deviceName,jdbcType=VARCHAR},
</if>
<if test="status.deviceStatus != null">
#{status.deviceStatus,jdbcType=INTEGER},
</if>
<if test="status.time != null">
#{status.time,jdbcType=DATE},
</if>
<if test="status.successRate != null">
#{status.successRate,jdbcType=VARCHAR},
</if>
<if test="status.lostRate != null">
#{status.lostRate,jdbcType=VARCHAR},
</if>
<if test="status.deviceIp != null">
#{status.deviceIp,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<sql id="selectStatus">
select id, device_no, device_name, device_status, time from status
</sql>
<select id="listStatus" parameterType="com.zc.business.domain.Status" resultMap="BaseResultMap">
select s.id, s.device_no, s.device_name, s.device_status,s.time, d.device_ip,s.success_rate,s.lost_rate,d.direction,d.production,d.model,d.network,d.content,d.type
from status s
LEFT JOIN device d on s.device_ip = d.device_ip
<where>
<if test="status.time != null">
AND s.time BETWEEN #{status.startTime,jdbcType=DATE} AND #{status.time,jdbcType=DATE}
</if>
<if test="status.deviceNo != null">
AND s.device_no = #{status.deviceNo}
</if>
</where>
</select>
</mapper>
Loading…
Cancel
Save