Browse Source

事故车型分析 事故时间分析

develop
王兴琳 3 months ago
parent
commit
5fe33ab438
  1. 45
      zc-business/src/main/java/com/zc/business/controller/DcSdhsEventController.java
  2. 5
      zc-business/src/main/java/com/zc/business/domain/DcSdhsEventQuery.java
  3. 33
      zc-business/src/main/java/com/zc/business/service/IDcSdhsEventService.java
  4. 361
      zc-business/src/main/java/com/zc/business/service/impl/DcSdhsEventServiceImpl.java
  5. 4
      zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java
  6. BIN
      zc-business/src/main/resources/wordTemplate/accidentModelAnalysis.docx
  7. BIN
      zc-business/src/main/resources/wordTemplate/accidentTimeAnalysis.docx

45
zc-business/src/main/java/com/zc/business/controller/DcSdhsEventController.java

@ -4,6 +4,10 @@ import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.zc.business.domain.DcSdhsEventQuery;
import com.zc.business.enums.UniversalEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.zc.business.domain.DcSdhsEvent;
import com.zc.business.domain.DcSdhsEventQuery;
import com.zc.business.enums.UniversalEnum;
import com.zc.business.service.IDcSdhsEventService;
import com.zc.business.utils.PoiUtil;
import io.swagger.annotations.Api;
@ -16,6 +20,11 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType;
import org.apache.catalina.security.SecurityUtil;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -30,6 +39,17 @@ import java.util.Map;
import static com.zc.business.utils.PoiUtil.insertTOC;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static com.zc.business.utils.PoiUtil.*;
import static com.zc.business.utils.PoiUtil.createLineBreak;
/**
* @Description 高速云事件分析Controller
*
@ -96,8 +116,12 @@ public class DcSdhsEventController {
} else if ("2".equals(trafficIncidentType)){
} else if ("3".equals(trafficIncidentType)){
//事故车型
dcSdhsEventService.exportAccidentModelAnalysis(newDoc, dcSdhsEventQuery);
} else if ("4".equals(trafficIncidentType)){
//事故时间
dcSdhsEventService.exportAccidentTimeAnalysis(newDoc, dcSdhsEventQuery);
} else if ("5".equals(trafficIncidentType)){
//事故地市分布
@ -179,7 +203,26 @@ public class DcSdhsEventController {
return dcSdhsEventService.selectRegionAnalysis(dcSdhsEventQuery);
}
/**
* 事故时间分析
* @param dcSdhsEventQuery
* @return
*/
@GetMapping("/accidentTimeAnalysis")
@ApiOperation("事故时间分析")
public AjaxResult accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery){
return AjaxResult.success( dcSdhsEventService.accidentTimeAnalysis(dcSdhsEventQuery));
}
/**
* 事故车型分析
* @param dcSdhsEventQuery
* @return
*/
@GetMapping("/accidentModelAnalysis")
@ApiOperation("事故车型分析")
public AjaxResult accidentModelAnalysis(DcSdhsEventQuery dcSdhsEventQuery){
return AjaxResult.success( dcSdhsEventService.accidentModelAnalysis(dcSdhsEventQuery));
}
@ApiOperation("查询交通管制情况分析")
@PostMapping("/selectStationAnalysis")
public AjaxResult selectStationAnalysis(@RequestBody DcSdhsEventQuery dcSdhsEventQuery)

5
zc-business/src/main/java/com/zc/business/domain/DcSdhsEventQuery.java

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
@ -27,10 +28,14 @@ public class DcSdhsEventQuery
/** 开始时间 */
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") //接收时间类型
private Date startTime;
/** 结束时间 */
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") //接收时间类型
private Date endTime;
/** 需要导出的键 */

33
zc-business/src/main/java/com/zc/business/service/IDcSdhsEventService.java

@ -1,11 +1,17 @@
package com.zc.business.service;
import com.ruoyi.common.core.domain.AjaxResult;
import com.zc.business.domain.DcSdhsEvent;
import com.zc.business.domain.DcSdhsEventQuery;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import com.zc.business.domain.DcSdhsEventQuery;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
/**
@ -25,6 +31,33 @@ public interface IDcSdhsEventService
void exportRegionAnalysis(XWPFDocument doc, DcSdhsEventQuery dcSdhsEventQuery);
/**
* 事故车型
* @param newDoc
* @param dcSdhsEventQuery
*/
void exportAccidentModelAnalysis(XWPFDocument newDoc,DcSdhsEventQuery dcSdhsEventQuery);
/**
* 事故车型分析
* @param dcSdhsEventQuery
* @return
*/
Map<String, Map<String, Integer>> accidentModelAnalysis(DcSdhsEventQuery dcSdhsEventQuery);
/**
* 事故时间分析
* @param dcSdhsEventQuery
* @return
*/
Map<Integer, Long> accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery);
/**
* 事故时间
* @param newDoc
* @param dcSdhsEventQuery
*/
void exportAccidentTimeAnalysis(XWPFDocument newDoc,DcSdhsEventQuery dcSdhsEventQuery);
AjaxResult selectStationAnalysis(DcSdhsEventQuery dcSdhsEventQuery);
void exportStationAnalysis(XWPFDocument doc, DcSdhsEventQuery dcSdhsEventQuery);

361
zc-business/src/main/java/com/zc/business/service/impl/DcSdhsEventServiceImpl.java

@ -15,26 +15,30 @@ import com.zc.business.utils.PoiUtil;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.time.ZoneId;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.zc.business.utils.PoiUtil.*;
import static com.zc.business.utils.PoiUtil.addDescription;
/**
@ -223,6 +227,353 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
return AjaxResult.success("导入成功");
}*/
/**
* 事故车型分析 导出
* @param doc
* @param dcSdhsEventQuery
*/
@Override
public void exportAccidentModelAnalysis(XWPFDocument doc,DcSdhsEventQuery dcSdhsEventQuery) {
// 初始化一个空的结果映射
Map<String, Map<String, Integer>> result = accidentModelAnalysis(dcSdhsEventQuery);
// 计算最大车辆类型数量
int maxVehicleTypes = 5;
// 创建一个具有最大车辆类型数量的列的表格
XWPFTable table = doc.createTable(result.size() + 1, maxVehicleTypes );
// 提取所有不同的车辆类型作为列标题
Set<String> vehicleTypes = new HashSet<>();
vehicleTypes.add("货车");
vehicleTypes.add("小型车");
vehicleTypes.add("客车");
vehicleTypes.add("罐车");
// 设置表头
XWPFTableRow headerRow = table.getRow(0);
setTableFonts(headerRow.getCell(0), ""); // 第一列是事件类型
int colIdx = 1;
for (String vehicleType : vehicleTypes) {
table.getRow(0).getCell(colIdx++).setText(vehicleType);
}
// 填充表格内容
int rowIdx = 1;
for (Map.Entry<String, Map<String, Integer>> entry : result.entrySet()) {
XWPFTableRow row = table.getRow(rowIdx++);
setTableFonts(row.getCell(0), entry.getKey()); // 事件类型
int cellIdx = 1;
for (String vehicleType : vehicleTypes) {
Integer count = entry.getValue().get(vehicleType);
XWPFTableCell cell = row.getCell(cellIdx++);
XWPFRun run = cell.getParagraphs().get(0).createRun();
run.setText(String.valueOf(count != null ?count : 0)); // 如果该事件没有这种车辆类型,则设为0
}
}
// 创建柱状图
try {
// 复制Word模板
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/accidentModelAnalysis.docx");
XWPFDocument copiedTemplate = new XWPFDocument(inputStream);
// 获取word中所有图表对象
List<XWPFChart> charts = copiedTemplate.getCharts();
XWPFChart chart = charts.get(0);
XSSFWorkbook workbook = chart.getWorkbook();
XSSFSheet sheet = workbook.getSheetAt(0);
// 系列信息
String[] singleBarSeriesNames = vehicleTypes.toArray(new String[0]);
// 填充表格内容
int rowId = 1; // 开始填充数据的行号
for (Map.Entry<String, Map<String, Integer>> entry : result.entrySet()) {
XSSFRow row = sheet.getRow(rowId);
if (row == null) {
row = sheet.createRow(rowId); // 如果行不存在,则创建新行
}
// 获取当前行的第一个单元格
Cell cell1 = row.getCell(0);
// 如果单元格为 null,则创建一个新的单元格
if (cell1 == null) {
cell1 = row.createCell(0);
}
// 设置单元格的值
cell1.setCellValue(entry.getKey());
row.getCell(0).setCellValue(entry.getKey()); // 设置事件类型
int cellIdx = 1;
for (String vehicleType : vehicleTypes) {
Integer count = entry.getValue().get(vehicleType);
XSSFCell cell = row.getCell(cellIdx); // 获取或创建单元格
if (cell == null) {
cell = row.createCell(cellIdx); // 如果单元格不存在,则创建新单元格
}
cell.setCellValue(count != null ? count : 0); // 设置单元格值
cellIdx++;
}
rowId++; // 移动到下一行
}
for (int i=sheet.getLastRowNum();i> result.size();i--){
sheet.removeRow(sheet.getRow(i));
}
// 创建柱状图
PoiUtil.wordExportChar(chart, "事故车型分析", singleBarSeriesNames, sheet);
// 追加到同一个Word文档中
mergeChart(chart, doc);
// 关闭复制的模板文档
copiedTemplate.close();
} catch (Exception e) {
e.printStackTrace();
}
// 换行
createLineBreak(doc);
}
/**
* 事故车型分析 查询
* @param dcSdhsEventQuery
* @return
*/
@Override
public Map<String, Map<String, Integer>>accidentModelAnalysis(DcSdhsEventQuery dcSdhsEventQuery) {
List<DcSdhsEvent> cacheList = redisCache.getCacheList(RedisKeyConstants.SDHS_EVENT);
// 将查询开始时间和结束时间转换为 LocalDateTime
ZoneId zoneId = ZoneId.systemDefault(); // 获取系统默认时区
LocalDateTime queryStart = dcSdhsEventQuery.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
LocalDateTime queryEnd = dcSdhsEventQuery.getEndTime().toInstant().atZone(zoneId).toLocalDateTime();
// 在指定时间范围内的事件
String direction = dcSdhsEventQuery.getDirection(); // 获取方向查询参数
List<DcSdhsEvent> filteredEvents = cacheList.stream()
.filter(event -> {
LocalDateTime eventTime = event.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
boolean timeCondition =
(eventTime.isAfter(queryStart) || eventTime.isEqual(queryStart)) &&
(eventTime.isBefore(queryEnd) || eventTime.isEqual(queryEnd));
// 如果 direction 不为空,则添加方向过滤条件
if (direction != null && !direction.isEmpty()) {
return timeCondition && direction.equals(event.getDirection());
} else {
return timeCondition;
}
})
.collect(Collectors.toList());
// 初始化一个空的结果映射
Map<String, Map<String, Integer>> result = new HashMap<>();
for (DcSdhsEvent event : filteredEvents) {
String eventType = event.getEventType();
if ("交通事故".equals(eventType)) {
String eventSubclass = event.getEventSubclass();
String carNums = event.getCarNum();
// 分割字符串,得到每种类型的车辆数量
List<String> carNumList = Arrays.asList(carNums.split(","));
// 如果结果映射中还没有这个事件子类,就初始化一个新的映射
if (!result.containsKey(eventSubclass)) {
result.put(eventSubclass, new HashMap<>());
}
// 统计每种类型的车辆数量
Map<String, Integer> carNumCount = result.get(eventSubclass);
for (String carNum : carNumList) {
// 检查字符串格式是否正确
int index = carNum.indexOf("辆");
if (index > 0) { // 确保 "辆" 的索引大于 0,表示字符串中包含 "辆" 且前面有字符
// 提取车辆类型和数量
String carType = carNum.substring(0, index-1); // 车辆类型
int carCount = Integer.parseInt(carNum.substring(index - 1, index)); // 数量
// 在映射中累加数量
carNumCount.merge(carType, carCount, Integer::sum);
}
}
}
}
return result;
}
/**
* 事故时间分析查询
* @param dcSdhsEventQuery
* @return
*/
@Override
public Map<Integer, Long> accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery) {
List<DcSdhsEvent> cacheList = redisCache.getCacheList(RedisKeyConstants.SDHS_EVENT);
// 将查询开始时间和结束时间转换为 LocalDateTime
ZoneId zoneId = ZoneId.systemDefault(); // 获取系统默认时区
LocalDateTime queryStart = dcSdhsEventQuery.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
LocalDateTime queryEnd = dcSdhsEventQuery.getEndTime().toInstant().atZone(zoneId).toLocalDateTime();
// 在指定时间范围内的事件
String direction = dcSdhsEventQuery.getDirection(); // 获取方向查询参数
List<DcSdhsEvent> filteredEvents = cacheList.stream()
.filter(event -> {
LocalDateTime eventTime = event.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
boolean timeCondition =
(eventTime.isAfter(queryStart) || eventTime.isEqual(queryStart)) &&
(eventTime.isBefore(queryEnd) || eventTime.isEqual(queryEnd));
// 如果 direction 不为空,则添加方向过滤条件
if (direction != null && !direction.isEmpty()) {
return timeCondition && direction.equals(event.getDirection());
} else {
return timeCondition;
}
})
.collect(Collectors.toList());
// 按小时分组并统计每个小时内的事件数量
Map<Integer, Long> hourlyCounts = filteredEvents.stream()
.collect(
Collectors.groupingBy(
event -> event.getStartTime().toInstant().atZone(zoneId).toLocalDateTime().getHour(),
Collectors.counting()
)
);
// 小时都出现在结果中,如果不存在设为 0
for (int hour = 0; hour <= 23; hour++) {
hourlyCounts.merge(hour, 0L, Long::sum);
}
return hourlyCounts;
}
/**
* 事故时间分析导出
* @param doc
* @param dcSdhsEventQuery
*/
@Override
public void exportAccidentTimeAnalysis(XWPFDocument doc,DcSdhsEventQuery dcSdhsEventQuery) {
Map<Integer, Long> currentYearData = accidentTimeAnalysis(dcSdhsEventQuery);
// 获取一年前的日期
Date startTime = dcSdhsEventQuery.getStartTime();
Date endTime = dcSdhsEventQuery.getEndTime();
// 使用 Calendar 计算一年前的时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTime); // 设置当前时间为 startTime
calendar.add(Calendar.YEAR, -1); // 减去一年
Date oneYearAgoStart = calendar.getTime(); // 一年前的开始时间
calendar.setTime(endTime); // 设置当前时间为 endTime
calendar.add(Calendar.YEAR, -1); // 减去一年
Date oneYearAgoEnd = calendar.getTime(); // 一年前的结束时间
dcSdhsEventQuery.setStartTime(oneYearAgoStart);
dcSdhsEventQuery.setEndTime(oneYearAgoEnd);
Map<Integer, Long> lastYearData = accidentTimeAnalysis(dcSdhsEventQuery);
// 创建表格
XWPFTable table = doc.createTable(25,3);
CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
infoTableWidth.setType(STTblWidth.DXA);
infoTableWidth.setW(BigInteger.valueOf(UniversalEnum.NINE_THOUSAND_AND_SEVENTY_TWO.getNumber()));
// 表头
setTableFonts(table.getRow(0).getCell(0), "时段");
setTableFonts(table.getRow(0).getCell(1), "今年同期");
setTableFonts(table.getRow(0).getCell(2), "去年同期");
// 填充表格数据
for (int i = 0; i < 24; i++) {
setTableFonts(table.getRow(i + 1).getCell(0), (i ) + "点");
Long currentYearValue = currentYearData.getOrDefault(i, 0L);
setTableFonts(table.getRow(i + 1).getCell(1), String.valueOf(currentYearValue));
Long lastYearValue = lastYearData.getOrDefault(i, 0L);
setTableFonts(table.getRow(i + 1).getCell(2), String.valueOf(lastYearValue));
}
// 图表部分
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/accidentTimeAnalysis.docx");
XWPFDocument copiedTemplate = new XWPFDocument(inputStream);
List<XWPFChart> charts = copiedTemplate.getCharts();
XWPFChart chart = charts.get(0);
XSSFWorkbook workbook = chart.getWorkbook();
XSSFSheet sheet = workbook.getSheetAt(UniversalEnum.ZERO.getNumber());
// 更新图表数据
for (int i = UniversalEnum.ZERO.getNumber(); i < 24; i++){
sheet.getRow(i + 1).getCell(0).setCellValue((i) + "点");
int rowIndex = i + UniversalEnum.ONE.getNumber(); // 计算行索引
Row row = sheet.getRow(rowIndex);
if (row == null) {
// 如果行不存在,则创建新行
row = sheet.createRow(rowIndex);
}
// 现在可以安全地访问或创建单元格了
Cell cell = row.getCell(UniversalEnum.ONE.getNumber());
if (cell == null) {
// 通常情况下,getCell 会创建新的单元格,但这里我们显式地检查以防万一
cell = row.createCell(UniversalEnum.ONE.getNumber(), CellType.NUMERIC);
}
// 设置单元格的值
sheet.getRow(i + 1).getCell(1).setCellValue(currentYearData.get(i));
int rowIndexTwo = i +1+ UniversalEnum.ONE.getNumber(); // 计算行索引
Row rowTwo = sheet.getRow(rowIndexTwo);
if (rowTwo == null) {
// 如果行不存在,则创建新行
rowTwo = sheet.createRow(rowIndexTwo);
}
// 现在可以安全地访问或创建单元格了
Cell cellTwo = row.getCell(UniversalEnum.TWO.getNumber());
if (cellTwo == null) {
// 通常情况下,getCell 会创建新的单元格,但这里我们显式地检查以防万一
cell = row.createCell(UniversalEnum.TWO.getNumber(), CellType.NUMERIC);
}
sheet.getRow(i + 1).getCell(2).setCellValue(lastYearData.get(i));
//sheet.getRow(i+UniversalEnum.ONE.getNumber()).getCell(UniversalEnum.ONE.getNumber()).setCellValue(Long.parseLong(entries.get(i).getValue().toString()));
}
/* for (int i = 0; i < 24; i++) {
sheet.getRow(i + 1).getCell(0).setCellValue((i) + "点");
sheet.getRow(i + 1).getCell(1).setCellValue(currentYearData.get(i));
sheet.getRow(i + 1).getCell(2).setCellValue(lastYearData.get(i));
}*/
// 更新图表
PoiUtil.wordExportChar(chart, "事故时间分析", new String[]{"今年同期", "去年同期"}, sheet);
// 合并图表到Word文档
mergeChart(chart, doc);
// 关闭模板文档
copiedTemplate.close();
} catch (Exception e){
e.printStackTrace();
}
//换行
createLineBreak(doc);
}
/**
* @Description 提取文字中的数字
*

4
zc-business/src/main/java/com/zc/business/service/impl/DcWarningServiceImpl.java

@ -308,9 +308,9 @@ public class DcWarningServiceImpl implements IDcWarningService {
}
contentMap.put("event", dcWarning);
if (dcWarning.getWarningSource()==UniversalEnum.FIVE.getNumber()){
WebSocketService.broadcast(WebSocketEvent.EVENT, contentMap); //推送事件消息 0是交通事件
WebSocketService.broadcast(UniversalEnum.TWO.getValue(), contentMap); //推送事件消息 2是扫码报警
}else {
WebSocketService.broadcast(WebSocketEvent.WARNING, contentMap); //推送事件消息 0不是感知事件
WebSocketService.broadcast(WebSocketEvent.WARNING, contentMap); //推送事件消息 1感知事件
}
dcEventService.getCountNum();

BIN
zc-business/src/main/resources/wordTemplate/accidentModelAnalysis.docx

Binary file not shown.

BIN
zc-business/src/main/resources/wordTemplate/accidentTimeAnalysis.docx

Binary file not shown.
Loading…
Cancel
Save