|
|
@ -14,9 +14,7 @@ import com.ruoyi.common.utils.uuid.IdUtils; |
|
|
|
import com.ruoyi.system.service.ISysConfigService; |
|
|
|
import com.zc.business.controller.VideoController; |
|
|
|
import com.zc.business.domain.*; |
|
|
|
import com.zc.business.enums.UniversalEnum; |
|
|
|
import com.zc.business.enums.ValueConverter; |
|
|
|
import com.zc.business.enums.WarningSubclassEnum; |
|
|
|
import com.zc.business.enums.*; |
|
|
|
import com.zc.business.mapper.*; |
|
|
|
import com.zc.business.service.IDcEventService; |
|
|
|
import com.zc.business.service.IDcTrafficPoliceService; |
|
|
@ -41,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional; |
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
|
import java.io.IOException; |
|
|
|
import java.text.DecimalFormat; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.time.Duration; |
|
|
|
import java.time.LocalDate; |
|
|
@ -51,6 +50,8 @@ import java.time.temporal.ChronoUnit; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.ThreadLocalRandom; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
@ -1268,6 +1269,7 @@ public class DcWarningServiceImpl implements IDcWarningService { |
|
|
|
qywxUtil.sendMessageByWxUserId(wxUserIds, message); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//误报解除
|
|
|
|
@Override |
|
|
|
public Integer falseAlarmResolution(DcWarning dcWarning) { |
|
|
@ -1400,4 +1402,247 @@ public class DcWarningServiceImpl implements IDcWarningService { |
|
|
|
public List<DcNoStakeWarningTable> selectStakeWarningTable() { |
|
|
|
return dcWarningMapper.selectStakeWarningTable(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Map<String, Object> selectVideoReviewEventTypeList(DcWarning dcWarning) { |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.ONE.getNumber()); |
|
|
|
List<DcWarning> dcWarningsOne = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.TWO.getNumber()); |
|
|
|
List<DcWarning> dcWarningsTwo = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
|
|
|
|
// 使用枚举类来定义类型映射
|
|
|
|
Map<Integer, String> warningTypeMap = Arrays.stream(WarningTypeEnum.values()) |
|
|
|
.collect(Collectors.toMap(WarningTypeEnum::getCode, WarningTypeEnum::getInfo)); |
|
|
|
|
|
|
|
// 统计 dcWarningsOne 每种类型的数量
|
|
|
|
Map<Integer, Long> typeCountOne = dcWarningsOne.stream() |
|
|
|
.collect(Collectors.groupingBy(DcWarning::getWarningType, Collectors.counting())); |
|
|
|
|
|
|
|
// 统计 dcWarningsTwo 每种类型的数量
|
|
|
|
Map<Integer, Long> typeCountTwo = dcWarningsTwo.stream() |
|
|
|
.collect(Collectors.groupingBy(DcWarning::getWarningType, Collectors.counting())); |
|
|
|
|
|
|
|
// 初始化结果集
|
|
|
|
Map<String, Object> result = new LinkedHashMap<>(); |
|
|
|
DecimalFormat decimalFormat = new DecimalFormat("0"); |
|
|
|
|
|
|
|
// 遍历所有类型,计算数量和百分比
|
|
|
|
warningTypeMap.forEach((type, getWarningSource) -> { |
|
|
|
long countOne = typeCountOne.getOrDefault(type, 0L); |
|
|
|
long countTwo = typeCountTwo.getOrDefault(type, 0L); |
|
|
|
|
|
|
|
// 计算总数量
|
|
|
|
long totalCount = countOne + countTwo; |
|
|
|
// 计算百分比并格式化
|
|
|
|
double percentageOne = totalCount == 0 ? 0 : ((double) countOne / totalCount) * 100; |
|
|
|
double percentageTwo = totalCount == 0 ? 0 : ((double) countTwo / totalCount) * 100; |
|
|
|
|
|
|
|
String formattedPercentageOne = decimalFormat.format(percentageOne); |
|
|
|
String formattedPercentageTwo = decimalFormat.format(percentageTwo); |
|
|
|
|
|
|
|
// 只保留有非零数量的类型
|
|
|
|
if (countOne > 0 || countTwo > 0) { |
|
|
|
// 存储结果
|
|
|
|
Map<String, Object> typeResult = new LinkedHashMap<>(); |
|
|
|
typeResult.put("AuditFlag1_Count", countOne); |
|
|
|
typeResult.put("AuditFlag2_Count", countTwo); |
|
|
|
typeResult.put("AuditFlag1_Percentage", formattedPercentageOne+"%"); |
|
|
|
typeResult.put("AuditFlag2_Percentage", formattedPercentageTwo+"%"); |
|
|
|
|
|
|
|
result.put(getWarningSource, typeResult); |
|
|
|
} |
|
|
|
/* // 存储结果
|
|
|
|
Map<String, Object> typeResult = new LinkedHashMap<>(); |
|
|
|
typeResult.put("AuditFlag1_Count", countOne); |
|
|
|
typeResult.put("AuditFlag2_Count", countTwo); |
|
|
|
typeResult.put("AuditFlag1_Percentage", formattedPercentageOne); |
|
|
|
typeResult.put("AuditFlag2_Percentage", formattedPercentageTwo); |
|
|
|
result.put(getWarningSource, typeResult); |
|
|
|
*/ |
|
|
|
}); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
//视频复核路段
|
|
|
|
@Override |
|
|
|
public Map<String,Object> selectVideoReviewSectionDistribution(DcWarning dcWarning) { |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.ONE.getNumber()); |
|
|
|
List<DcWarning> dcWarningsOne = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
|
|
|
|
dcWarning.setAuditFlag(UniversalEnum.TWO.getNumber()); |
|
|
|
List<DcWarning> dcWarningsTwo = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
Map<String, Integer> eventOne = stakeMarkCount(dcWarningsOne); |
|
|
|
|
|
|
|
Map<String, Integer> eventTwo = stakeMarkCount(dcWarningsTwo); |
|
|
|
|
|
|
|
// 转换为百分比
|
|
|
|
Map<String, String> eventOnePercents = convertToPercentage(eventOne, eventTwo); |
|
|
|
Map<String, String> eventTwoPercents = convertToPercentage(eventTwo, eventOne); |
|
|
|
|
|
|
|
// 提取所有的 key 并排序
|
|
|
|
Set<String> allKeys = new TreeSet<>((key1, key2) -> { |
|
|
|
int start1 = extractStartKm(key1); |
|
|
|
int start2 = extractStartKm(key2); |
|
|
|
return Integer.compare(start1, start2); |
|
|
|
}); |
|
|
|
allKeys.addAll(eventOne.keySet()); |
|
|
|
allKeys.addAll(eventTwo.keySet()); |
|
|
|
|
|
|
|
// 使用 LinkedHashMap 来保持插入顺序
|
|
|
|
Map<String, Object> finalData = new LinkedHashMap<>(); |
|
|
|
|
|
|
|
for (String key : allKeys) { |
|
|
|
Map<String, Object> segmentData = new HashMap<>(); |
|
|
|
segmentData.put("AuditFlag1_Count", eventOne.getOrDefault(key, 0)); |
|
|
|
segmentData.put("AuditFlag2_Count", eventTwo.getOrDefault(key, 0)); |
|
|
|
segmentData.put("AuditFlag1_Percentage", eventOnePercents.getOrDefault(key, "0%")); |
|
|
|
segmentData.put("AuditFlag2_Percentage", eventTwoPercents.getOrDefault(key, "0%")); |
|
|
|
|
|
|
|
finalData.put(key, segmentData); |
|
|
|
} |
|
|
|
|
|
|
|
return finalData; |
|
|
|
} |
|
|
|
//视频复核事件来源
|
|
|
|
@Override |
|
|
|
public Map<String, Object> videoReviewEventSource(DcWarning dcWarning) { |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.ONE.getNumber()); |
|
|
|
List<DcWarning> dcWarningsOne = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.TWO.getNumber()); |
|
|
|
List<DcWarning> dcWarningsTwo = dcWarningMapper.selectVideoReviewEventTypeList(dcWarning); |
|
|
|
|
|
|
|
// 使用枚举类来定义类型映射
|
|
|
|
Map<Integer, String> warningTypeMap = Arrays.stream(WarningSourceEnum.values()) |
|
|
|
.collect(Collectors.toMap(WarningSourceEnum::getCode, WarningSourceEnum::getDescription)); |
|
|
|
|
|
|
|
// 统计 dcWarningsOne 每种类型的数量
|
|
|
|
Map<Integer, Long> typeCountOne = dcWarningsOne.stream() |
|
|
|
.collect(Collectors.groupingBy(DcWarning::getWarningType, Collectors.counting())); |
|
|
|
|
|
|
|
// 统计 dcWarningsTwo 每种类型的数量
|
|
|
|
Map<Integer, Long> typeCountTwo = dcWarningsTwo.stream() |
|
|
|
.collect(Collectors.groupingBy(DcWarning::getWarningType, Collectors.counting())); |
|
|
|
|
|
|
|
// 初始化结果集
|
|
|
|
Map<String, Object> result = new LinkedHashMap<>(); |
|
|
|
DecimalFormat decimalFormat = new DecimalFormat("0"); |
|
|
|
|
|
|
|
// 遍历所有类型,计算数量和百分比
|
|
|
|
warningTypeMap.forEach((type, warningType) -> { |
|
|
|
long countOne = typeCountOne.getOrDefault(type, 0L); |
|
|
|
long countTwo = typeCountTwo.getOrDefault(type, 0L); |
|
|
|
|
|
|
|
// 计算总数量
|
|
|
|
long totalCount = countOne + countTwo; |
|
|
|
// 计算百分比并格式化
|
|
|
|
double percentageOne = totalCount == 0 ? 0 : ((double) countOne / totalCount) * 100; |
|
|
|
double percentageTwo = totalCount == 0 ? 0 : ((double) countTwo / totalCount) * 100; |
|
|
|
|
|
|
|
String formattedPercentageOne = decimalFormat.format(percentageOne); |
|
|
|
String formattedPercentageTwo = decimalFormat.format(percentageTwo); |
|
|
|
|
|
|
|
// 只保留有非零数量的类型
|
|
|
|
if (countOne > 0 || countTwo > 0) { |
|
|
|
// 存储结果
|
|
|
|
Map<String, Object> typeResult = new LinkedHashMap<>(); |
|
|
|
typeResult.put("AuditFlag1_Count", countOne); |
|
|
|
typeResult.put("AuditFlag2_Count", countTwo); |
|
|
|
typeResult.put("AuditFlag1_Percentage", formattedPercentageOne+"%"); |
|
|
|
typeResult.put("AuditFlag2_Percentage", formattedPercentageTwo+"%"); |
|
|
|
|
|
|
|
result.put(warningType, typeResult); |
|
|
|
} |
|
|
|
/* // 存储结果
|
|
|
|
Map<String, Object> typeResult = new LinkedHashMap<>(); |
|
|
|
typeResult.put("AuditFlag1_Count", countOne); |
|
|
|
typeResult.put("AuditFlag2_Count", countTwo); |
|
|
|
typeResult.put("AuditFlag1_Percentage", formattedPercentageOne); |
|
|
|
typeResult.put("AuditFlag2_Percentage", formattedPercentageTwo); |
|
|
|
result.put(warningType, typeResult); |
|
|
|
*/ |
|
|
|
}); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public List<DcWarning> videoReviewEventSourceList(DcWarning dcWarning) { |
|
|
|
return dcWarningMapper.selectVideoEventList(dcWarning); |
|
|
|
} |
|
|
|
//时间分布
|
|
|
|
@Override |
|
|
|
public Map<String, Object> videoReviewEventTime(DcWarning dcWarning) { |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.ONE.getNumber()); |
|
|
|
List<DcWarning> dcWarningsOne = dcWarningMapper.selectVideoReviewEventTimeList(dcWarning); |
|
|
|
dcWarning.setAuditFlag(UniversalEnum.TWO.getNumber()); |
|
|
|
List<DcWarning> dcWarningsTwo = dcWarningMapper.selectVideoReviewEventTimeList(dcWarning); |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public Map<String, Integer> stakeMarkCount(List<DcWarning> dcWarnings){ |
|
|
|
Map<String, Integer> groupCountMap = new HashMap<>(); |
|
|
|
for (DcWarning dcWarning : dcWarnings) { |
|
|
|
|
|
|
|
String kmStr = dcWarning.getStakeMark(); |
|
|
|
if (org.apache.commons.lang3.StringUtils.isBlank(kmStr)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
String patternStr = "^K\\d+(\\+\\d+)?$"; |
|
|
|
Pattern pattern = Pattern.compile(patternStr); |
|
|
|
Matcher matcher = pattern.matcher(kmStr); |
|
|
|
if (!matcher.matches()) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
int km = Integer.parseInt(kmStr.replaceAll("^K", "").split("\\+")[0]); // 假设+后面还有其他内容,我们只取+前面的部分
|
|
|
|
// 计算分组startKm,确保是5的倍数且不大于km
|
|
|
|
int startKm = ((km / 10) * 10) + (km % 10 >= 5 ? 10 : 0); |
|
|
|
startKm = startKm - startKm % 5; // 确保startKm是5的倍数
|
|
|
|
if (startKm%5==0){ |
|
|
|
if ((startKm / 5) % 2 == 0) { |
|
|
|
startKm -= 5; |
|
|
|
} |
|
|
|
} |
|
|
|
// 计算分组endKm,找到比startKm大、最接近的、以5结尾的数
|
|
|
|
int endKm = startKm + 10; |
|
|
|
while (endKm % 5 != 0) { |
|
|
|
endKm++; |
|
|
|
} |
|
|
|
// 构造分组key
|
|
|
|
String groupKey = "K" + startKm + "-" + "K" + endKm; |
|
|
|
if (groupCountMap.get(groupKey)==null){ //事件还为存入map
|
|
|
|
groupCountMap.putIfAbsent(groupKey, UniversalEnum.ONE.getNumber());//事件类型不存在存1
|
|
|
|
}else { |
|
|
|
Integer currentSum = groupCountMap.get(groupKey); |
|
|
|
groupCountMap.put(groupKey, currentSum +1 ); |
|
|
|
} |
|
|
|
} |
|
|
|
return groupCountMap; |
|
|
|
} |
|
|
|
// 提取 "Kxx-xxx" 格式中的起始公里数
|
|
|
|
private int extractStartKm(String key) { |
|
|
|
String[] parts = key.split("-"); |
|
|
|
if (parts.length == 2 && parts[0].matches("K\\d+")) { |
|
|
|
return Integer.parseInt(parts[0].substring(1)); |
|
|
|
} |
|
|
|
throw new IllegalArgumentException("Invalid stake mark format: " + key); |
|
|
|
} |
|
|
|
public Map<String, String> convertToPercentage(Map<String, Integer> countMap1, Map<String, Integer> countMap2) { |
|
|
|
Map<String, String> percentageMap = new HashMap<>(); |
|
|
|
DecimalFormat df = new DecimalFormat("0"); |
|
|
|
|
|
|
|
for (String key : countMap1.keySet()) { |
|
|
|
int count1 = countMap1.get(key); |
|
|
|
int count2 = countMap2.getOrDefault(key, 0); |
|
|
|
int totalCount = count1 + count2; |
|
|
|
|
|
|
|
if (totalCount > 0) { |
|
|
|
double percentage = (double) count1 / totalCount * 100; |
|
|
|
percentageMap.put(key, df.format(percentage) + "%"); |
|
|
|
} else { |
|
|
|
percentageMap.put(key, "0%"); |
|
|
|
} |
|
|
|
} |
|
|
|
return percentageMap; |
|
|
|
}} |
|
|
|