Browse Source

事故车型分析 事故时间分析 首页终止事件过滤

develop
王兴琳 6 months ago
parent
commit
9592f9df31
  1. 2
      zc-business/src/main/java/com/zc/business/controller/DcSdhsEventController.java
  2. 2
      zc-business/src/main/java/com/zc/business/service/IDcSdhsEventService.java
  3. 200
      zc-business/src/main/java/com/zc/business/service/impl/DcSdhsEventServiceImpl.java
  4. 2
      zc-business/src/main/resources/mapper/business/DcTrafficIncidentsMapper.xml
  5. BIN
      zc-business/src/main/resources/wordTemplate/accidentTimeDayAnalysis.docx
  6. BIN
      zc-business/src/main/resources/wordTemplate/accidentTimeMonthAnalysis.docx

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

@ -83,7 +83,7 @@ public class DcSdhsEventController {
@PostMapping("/export")
@ApiOperation("导出")
public void trafficSituationReport(HttpServletResponse response,DcSdhsEventQuery dcSdhsEventQuery) throws Exception {
public void trafficSituationReport(HttpServletResponse response,@RequestBody DcSdhsEventQuery dcSdhsEventQuery) throws Exception {
try {
SimpleDateFormat df = new SimpleDateFormat(UniversalEnum.TIME_FORMAT_YEARS_MONTH_DAY.getValue());
String date = df.format(new Date());

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

@ -50,7 +50,7 @@ public interface IDcSdhsEventService
* @param dcSdhsEventQuery
* @return
*/
Map<Integer, Long> accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery);
Map<String, Long> accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery);
/**
* 事故时间

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

@ -25,12 +25,17 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.naming.NamingEnumeration;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.time.ZoneId;
import java.util.regex.Matcher;
@ -417,16 +422,103 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
* @return
*/
@Override
public Map<Integer, Long> accidentTimeAnalysis(DcSdhsEventQuery dcSdhsEventQuery) {
public Map<String, 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();
if (dcSdhsEventQuery.getType().equals("2")) {
// 将查询开始时间和结束时间转换为 LocalDateTime
LocalDateTime queryStart = dcSdhsEventQuery.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
// LocalDateTime endTime = dcSdhsEventQuery.getEndTime().toInstant().atZone(zoneId).toLocalDateTime();
// 计算当天的结束时间
LocalDateTime queryEnd = queryStart.withHour(23).withMinute(59).withSecond(59);
List<DcSdhsEvent> filteredEvents = getDcSdhsEvents(dcSdhsEventQuery, cacheList, zoneId, queryStart, queryEnd);
// 按小时分组并统计每个小时内的事件数量
Map<String, Long> hourlyCounts = filteredEvents.stream()
.collect(
Collectors.groupingBy(
event -> String.format("%02d", event.getStartTime().toInstant().atZone(zoneId).toLocalDateTime().getHour()),
Collectors.counting()
)
);
// 确保所有小时都出现在结果中
for (int hour = 0; hour <= 23; hour++) {
String hourString = String.format("%02d", hour);
hourlyCounts.merge(hourString, 0L, Long::sum);
}
return hourlyCounts;
} else if (dcSdhsEventQuery.getType().equals("1")) {
// 将查询开始时间和结束时间转换为 LocalDateTime
LocalDateTime queryStart = dcSdhsEventQuery.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
// 获取该月的最后一天
LocalDate lastDayOfMonth = queryStart.toLocalDate().with(TemporalAdjusters.lastDayOfMonth());
// 构建该月的最后一刻(23:59:59)
LocalDateTime endOfMonth = LocalDateTime.of(lastDayOfMonth, LocalTime.MAX);
List<DcSdhsEvent> filteredEvents = getDcSdhsEvents(dcSdhsEventQuery, cacheList, zoneId, queryStart, endOfMonth);
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd");
// 按天分组并统计每一天内的事件数量
Map<String, Long> dailyCounts = filteredEvents.stream()
.collect(
Collectors.groupingBy(
event -> event.getStartTime().toInstant().atZone(zoneId).toLocalDate().format(formatter),
Collectors.counting()
)
);
// 确保所有日期都出现在结果中
LocalDate queryStartLocalDate = queryStart.toLocalDate();
LocalDate queryEndLocalDate = endOfMonth.toLocalDate();
// 确保所有日期都出现在结果中
for (LocalDate date = queryStartLocalDate; date.isBefore(queryEndLocalDate.plusDays(1)); date = date.plusDays(1)) {
String dateString = date.format(formatter);
dailyCounts.merge(dateString, 0L, Long::sum);
}
return dailyCounts;
}else {
// 将查询开始时间和结束时间转换为 LocalDateTime
LocalDateTime queryStart = dcSdhsEventQuery.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
// 获取该年的最后一天
LocalDate lastDayOfYear = queryStart.toLocalDate().with(TemporalAdjusters.lastDayOfYear());
// 构建该年的最后一刻(23:59:59)
LocalDateTime endOfYear = LocalDateTime.of(lastDayOfYear, LocalTime.MAX);
List<DcSdhsEvent> filteredEvents = getDcSdhsEvents(dcSdhsEventQuery, cacheList, zoneId, queryStart, endOfYear);
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM");
// 按月分组并统计每个月内的事件数量
Map<String, Long> monthlyCounts = filteredEvents.stream()
.collect(
Collectors.groupingBy(
event -> event.getStartTime().toInstant().atZone(zoneId).toLocalDate().format(formatter),
Collectors.counting()
)
);
// 确保所有月份都出现在结果中
LocalDate queryEnd = endOfYear.toLocalDate().plusMonths(1); // 确保包含结束月份
LocalDate currentMonth = queryStart.toLocalDate();
while (currentMonth.isBefore(queryEnd)) {
String monthString = currentMonth.format(formatter);
monthlyCounts.merge(monthString, 0L, Long::sum);
currentMonth = currentMonth.plusMonths(1);
}
return monthlyCounts;
}
// 在指定时间范围内的事件
String direction = dcSdhsEventQuery.getDirection(); // 获取方向查询参数
}
/**
* // 在指定时间范围内的事件
* @param dcSdhsEventQuery
* @param cacheList
* @param zoneId
* @param queryStart
* @param queryEnd
* @return
*/
private static List<DcSdhsEvent> getDcSdhsEvents(DcSdhsEventQuery dcSdhsEventQuery, List<DcSdhsEvent> cacheList, ZoneId zoneId, LocalDateTime queryStart, LocalDateTime queryEnd) {
String direction = dcSdhsEventQuery.getDirection(); // 获取方向查询参数
List<DcSdhsEvent> filteredEvents = cacheList.stream()
.filter(event -> {
LocalDateTime eventTime = event.getStartTime().toInstant().atZone(zoneId).toLocalDateTime();
@ -442,22 +534,7 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
}
})
.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;
return filteredEvents;
}
/**
@ -468,24 +545,39 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
@Override
public void exportAccidentTimeAnalysis(XWPFDocument doc,DcSdhsEventQuery dcSdhsEventQuery) {
Map<Integer, Long> currentYearData = accidentTimeAnalysis(dcSdhsEventQuery);
Map<String, 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);
Map<String, Long> lastYearData = accidentTimeAnalysis(dcSdhsEventQuery);
String type = dcSdhsEventQuery.getType();
int rows=0;
String stingType= "";
String name= "";
if (type.equals("2")){
rows=25;
stingType="点";
name= "wordTemplate/accidentTimeAnalysis.docx";
}else if (type.equals("1")){
rows=32;
stingType="日";
name= "wordTemplate/accidentTimeDayAnalysis.docx";
}else {
rows=13;
stingType="月";
name= "wordTemplate/accidentTimeMonthAnalysis.docx";
}
// 创建表格
XWPFTable table = doc.createTable(25,3);
XWPFTable table = doc.createTable(rows,3);
CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
infoTableWidth.setType(STTblWidth.DXA);
infoTableWidth.setW(BigInteger.valueOf(UniversalEnum.NINE_THOUSAND_AND_SEVENTY_TWO.getNumber()));
@ -494,19 +586,36 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
setTableFonts(table.getRow(0).getCell(0), "时段");
setTableFonts(table.getRow(0).getCell(1), "今年同期");
setTableFonts(table.getRow(0).getCell(2), "去年同期");
// 定义一个从数字到日期字符串的映射
Map<Integer, String> indexToDateMap = new HashMap<>();
for (int i = 0; i <= 32; i++) {
String dateString = String.format("%02d", i);
indexToDateMap.put(i, dateString);
}
String dayString="";
// 填充表格数据
for (int i = 0; i < 24; i++) {
setTableFonts(table.getRow(i + 1).getCell(0), (i ) + "点");
Long currentYearValue = currentYearData.getOrDefault(i, 0L);
for (int i = 0; i < rows-1; i++) {
if (type.equals("2")){
dayString = indexToDateMap.get(i); // 获取 i 对应的日期字符串
}else {
dayString = indexToDateMap.get(i+1); // 获取 i 对应的日期字符串
}
setTableFonts(table.getRow(i + 1).getCell(0), (dayString ) + stingType);
Long currentYearValue = currentYearData.getOrDefault(dayString, 0L);
setTableFonts(table.getRow(i + 1).getCell(1), String.valueOf(currentYearValue));
Long lastYearValue = lastYearData.getOrDefault(i, 0L);
Long lastYearValue = lastYearData.getOrDefault(dayString, 0L);
setTableFonts(table.getRow(i + 1).getCell(2), String.valueOf(lastYearValue));
}
// 图表部分
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/accidentTimeAnalysis.docx");
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(name);
XWPFDocument copiedTemplate = new XWPFDocument(inputStream);
List<XWPFChart> charts = copiedTemplate.getCharts();
@ -514,8 +623,14 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
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) + "点");
for (int i = UniversalEnum.ZERO.getNumber(); i < rows-1; i++){
if (type.equals("2")){
dayString = indexToDateMap.get(i); // 获取 i 对应的日期字符串
}else {
dayString = indexToDateMap.get(i+1); // 获取 i 对应的日期字符串
}
sheet.getRow(i + 1).getCell(0).setCellValue((dayString) + stingType);
int rowIndex = i + UniversalEnum.ONE.getNumber(); // 计算行索引
Row row = sheet.getRow(rowIndex);
if (row == null) {
@ -529,9 +644,8 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
// 通常情况下,getCell 会创建新的单元格,但这里我们显式地检查以防万一
cell = row.createCell(UniversalEnum.ONE.getNumber(), CellType.NUMERIC);
}
// 设置单元格的值
sheet.getRow(i + 1).getCell(1).setCellValue(currentYearData.get(i));
sheet.getRow(i + 1).getCell(1).setCellValue(currentYearData.get(dayString));
int rowIndexTwo = i +1+ UniversalEnum.ONE.getNumber(); // 计算行索引
Row rowTwo = sheet.getRow(rowIndexTwo);
if (rowTwo == null) {
@ -545,7 +659,7 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
// 通常情况下,getCell 会创建新的单元格,但这里我们显式地检查以防万一
cell = row.createCell(UniversalEnum.TWO.getNumber(), CellType.NUMERIC);
}
sheet.getRow(i + 1).getCell(2).setCellValue(lastYearData.get(i));
sheet.getRow(i + 1).getCell(2).setCellValue(lastYearData.get(dayString));
//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++) {
@ -554,7 +668,9 @@ public class DcSdhsEventServiceImpl implements IDcSdhsEventService {
sheet.getRow(i + 1).getCell(1).setCellValue(currentYearData.get(i));
sheet.getRow(i + 1).getCell(2).setCellValue(lastYearData.get(i));
}*/
for (int i=sheet.getLastRowNum();i> currentYearData.size();i--){
sheet.removeRow(sheet.getRow(i));
}
// 更新图表
PoiUtil.wordExportChar(chart, "事故时间分析", new String[]{"今年同期", "去年同期"}, sheet);

2
zc-business/src/main/resources/mapper/business/DcTrafficIncidentsMapper.xml

@ -25,7 +25,7 @@
select t1.id,t1.stake_mark stakeMark,t1.direction,t1.lang, t2.longitude,t2.latitude
from dc_event t1 left join dc_stake_mark t2 on t1.stake_mark = t2.stake_mark and t1.direction = t2.direction
<where>
t1.event_type = #{eventType} and t1.event_state != '2'
t1.event_type = #{eventType} and t1.event_state != '2' and t1.event_state != '3'
<if test="startStakeMark != null and startStakeMark != ''">
and t2.mileage >= #{startStakeMark}
</if>

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

Binary file not shown.

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

Binary file not shown.
Loading…
Cancel
Save