CREATE TABLE `ai_event_payload` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`send_time` datetime DEFAULT NULL COMMENT '事件从接收者发出时间',
`ability` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件类别',
`event_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件唯一标识同一事件若上报多次,则上报事件的eventId相同',
`src_index` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件源编号',
`src_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件源类型',
`event_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件类型',
`happen_time` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件发生时间',
`stop_time` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '事件结束时间',
`src_name` varchar(100) DEFAULT NULL COMMENT '事件源名称',
`location_name` varchar(100) DEFAULT NULL COMMENT '位置名称',
`handle_status` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '处理状态,0-未处理,1-已处理',
`event_level` bigint DEFAULT NULL COMMENT '事件等级,1-低,2-中,3-高',
`remark` varchar(100) DEFAULT NULL COMMENT '事件处理意见',
`first_remind_time` varchar(100) DEFAULT NULL COMMENT '首次提醒时间',
`last_remind_time` varchar(100) DEFAULT NULL COMMENT '上次提醒时间',
`remind_count` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '提醒次数',
`two_remind_time` varchar(100) DEFAULT NULL COMMENT '第二次发送首次发送时间',
`pic_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片的相对地址',
`svr_index_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'd0ddf839-ac25-41ab-a908-cc75a4d5d5bc' COMMENT '图片存储服务器唯一标识',
PRIMARY KEY (`id`),
UNIQUE KEY `ai_event_payload_unique` (`event_id`)
) ENGINE=InnoDB AUTO_INCREMENT=707 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;数据表,如果其中的send_time,ability,src_index,src_type_happen_time,stop_time,src_name,location_name,handle_status,event_level,remark,pic_uri,svr_index_code都相同的话就不进行添加和通知
现在的逻辑是:
package com.gcvcloud.interfaceservice.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gcvcloud.interfaceservice.domain.query.*;
import com.gcvcloud.interfaceservice.mapper.HaiKangMapper;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Service
@Slf4j
public class HaiKangService {
@Autowired
private HaiKangMapper haiKangMapper;
@Autowired
private WeComService weComService;
@Value("${haikang.url}")
private String url;
@Value("${haikang.appKeyEvent}")
private String appKey;
@Value("${haikang.appSecretEvent}")
private String appSecret;
private static final String ARTEMIS_PATH = "/artemis";
@Transactional
public void processWarnings(EventPayloads eventPayloads) throws Exception {
EventParams params = eventPayloads.getParams();
for (EventData eventData : params.getEvents()) {
EventPayload eventPayload = getEventPayload(eventPayloads, eventData, params);
synchronized (eventPayload.getEventId().intern()) {
processSingleEvent(eventPayload, eventData);
}
}
}
//事件处理
private void processSingleEvent(EventPayload eventPayload, EventData eventData) throws Exception {
ArtemisConfig artemisConfig = new ArtemisConfig(url, appKey, appSecret);
String searchDataApi = ARTEMIS_PATH + "/api/els/v1/events/search";
Map<String, String> path = new HashMap<String, String>(2) {
{
put("https://", searchDataApi);
}
};
SearchRequest searchRequest = new SearchRequest();
searchRequest.setHandleStatus(0);
searchRequest.setStartTime(eventData.getHappenTime());
searchRequest.setEndTime(eventData.getStopTime());
searchRequest.setPageSize(20);
searchRequest.setPageNo(1);
String body = JSON.toJSONString(searchRequest);
try {
java.util.concurrent.TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("延时执行被中断: {}", e.getMessage());
}
String artemis = ArtemisHttpUtil.doPostStringArtemis(artemisConfig, path, body, null, null, "application/json");
JSONObject responseJson = JSON.parseObject(artemis);
JSONObject dataObj = responseJson.getJSONObject("data");
if (dataObj == null) {
log.info("当前时间未查询到数据");
return;
}
JSONArray listArray = dataObj.getJSONArray("list");
if (listArray.isEmpty()) {
log.info("当前时间未查询到数据");
return;
}
for (Object object : listArray) {
JSONObject jsonObject = (JSONObject) object;
// 处理resName等数据
JSONArray eventLogSrcList = jsonObject.getJSONArray("eventLogSrcList");
if (eventLogSrcList != null && !eventLogSrcList.isEmpty()) {
JSONObject firstSrc = eventLogSrcList.getJSONObject(0);
if (firstSrc != null) {
String resName = firstSrc.getString("resName");
eventPayload.setLocationName(resName);
}
}
Integer handleStatus = jsonObject.getInteger("handleStatus");
eventPayload.setHandleStatus(handleStatus);
Integer eventLevel = jsonObject.getInteger("eventLevel");
eventPayload.setEventLevel(eventLevel);
String remark = jsonObject.getString("remark");
eventPayload.setRemark(remark);
String eventLevelValue = jsonObject.getString("eventLevelValue");
eventPayload.setAbility(eventLevelValue);
List<EventPayload> existing = haiKangMapper.selectEventPayload(eventPayload.getEventId());
String timeEventpaylods = haiKangMapper.timeEventpaylods(eventPayload.getEventId());
String firstTime = haiKangMapper.firstTime(eventPayload.getEventId());
if (existing.isEmpty()) {
eventPayload.setRemindCount(1);
eventPayload.setFirstRemindTime(getCurrentTimeString());
eventPayload.setLastRemindTime(getCurrentTimeString());
try {
if (eventPayload.getPicUri() == null){
return;
}else {
haiKangMapper.insertEventPayload(eventPayload);
log.info("插入成功");
weChatMediaUploader(eventPayload); // 只有新插入才发送提醒
}
} catch (Exception e) {
// 可能是并发插入导致的唯一约束冲突,忽略或记录日志
log.info("事件 {} 插入时发生冲突,可能已被其他线程处理", eventPayload.getEventId());
return;
}
} else if (calculateTimeDifference(firstTime) >= 900000 && existing.get(0).getRemindCount() >= 3 && existing.get(0).getRemindCount() < 6 ) {
eventPayload.setRemindCount(4);
eventPayload.setTwoRemindTime(getCurrentTimeString());
eventPayload.setLastRemindTime(getCurrentTimeString());
eventPayload.setHandleStatus(handleStatus);
haiKangMapper.updateEventPayload(eventPayload);
weChatMediaUploader(eventPayload); // 更新后发送提醒
log.info("更新成功");
} else if (calculateTimeDifference(timeEventpaylods) >= 900000 && existing.get(0).getRemindCount() >= 6 && existing.get(0).getRemindCount() < 9) {
eventPayload.setRemindCount(7);
eventPayload.setLastRemindTime(getCurrentTimeString());
eventPayload.setHandleStatus(handleStatus);
haiKangMapper.updateEventPayload(eventPayload);
weChatMediaUploader(eventPayload); // 更新后发送提醒
log.info("更新成功");
}
}
}
//发送企业微信通知
private void sendReminder(EventPayload eventPayload) {
String mobile = null;
//如果是晚上7点到早上7点执行下方逻辑
if (isNightTime(eventPayload.getSendTime())){
if (eventPayload.getRemindCount()<3){
mobile = haiKangMapper.selectPhoneEventNight();
}else if (eventPayload.getRemindCount()<=6) {
mobile = haiKangMapper.selectPhoneEventNightTwo();
}else if (eventPayload.getRemindCount()<=9) {
return;
}
}
if (eventPayload.getRemindCount()<=3){
mobile = haiKangMapper.selectPhoneEvent();
}else if (eventPayload.getRemindCount()<=6){
mobile = haiKangMapper.selectPhoneEventTwo();
}else if (eventPayload.getRemindCount()<=9){
mobile = haiKangMapper.selectPhoneEventThree();
}
if (mobile == null) {
log.warn("跳过发送预警通知:手机号为空,预警事件类别:{}", eventPayload.getAbility());
return;
}
String formattedSendTime = convertIsoToStandardFormat(eventPayload.getHappenTime());
String content = String.format(
"<font color=\"warning\">**预警事件提醒**</font> \n"+
"预警事件发生时间:<font color=\"warning\">%s</font>\n"+
">预警事件级别:<font color=\"warning\">%s</font>\n" +
">预警事件名称:<font color=\"warning\">%s</font>\n" +
">预警时间地点:<font color=\"warning\">%s</font>\n",
formattedSendTime,
eventPayload.getAbility(),
eventPayload.getSrcName(),
eventPayload.getLocationName()
);
String userId = weComService.getUserid(mobile);
String imageUrl = eventPayload.getPicUri();
if (userId != null && !userId.trim().isEmpty()) {
if (weComService.sendMarkdownMessage(userId, content)) {
log.info("已发送预警事件给 {}", userId);
}else {
log.warn("未找到用户ID,跳过发送预警事件通知:手机号 {},事件类别:{}",
mobile, eventPayload.getAbility());
}
}
if (imageUrl != null) {
if (weComService.sendImageMessage(imageUrl, userId)) {
log.info("已发送图片给 {}", userId);
}
}
}
@Scheduled(fixedRate =1000)
public void checkAndSendReminders() throws Exception {
List<EventPayload> warnings = haiKangMapper.selectUnwarnedRecords();
SearchRequest searchRequest = new SearchRequest();
for (EventPayload warning : warnings) {
ArtemisConfig artemisConfig = new ArtemisConfig(url, appKey, appSecret);
String searchDataApi = ARTEMIS_PATH + "/api/els/v1/events/search";
Map<String, String> path = new HashMap<String, String>(2) {
{
put("https://", searchDataApi);
}
};
searchRequest.setStartTime(warning.getHappenTime());
searchRequest.setEndTime(warning.getStopTime());
searchRequest.setPageSize(20);
searchRequest.setPageNo(1);
String body = JSON.toJSONString(searchRequest);
String artemis = ArtemisHttpUtil.doPostStringArtemis(artemisConfig, path, body, null, null, "application/json");
JSONObject responseJson = JSON.parseObject(artemis);
JSONObject dataObj = responseJson.getJSONObject("data");
if (dataObj == null) {
log.info("当前时间未查询到数据");
} else {
JSONArray listArray = dataObj.getJSONArray("list");
if (listArray.isEmpty()) {
log.info("当前时间未查询到数据");
} else {
for (Object object : listArray) {
JSONObject jsonObject = (JSONObject) object;
if (jsonObject.getInteger("handleStatus") == 1) {
haiKangMapper.updateEventStatus(warning.getEventId());
log.info("事件已处理,不再提醒!事件id为{}", warning.getEventId());
return;
}
}
}
}
List<EventPayload> pendingEvents = haiKangMapper.selectPendingReminders();
for (EventPayload event : pendingEvents) {
try {
// 发送提醒
event.setRemindCount(event.getRemindCount() + 1);
event.setLastRemindTime(getCurrentTimeString());
// 更新数据库
haiKangMapper.updateEventPayload(event);
sendReminder(event);
log.info("已发送第 {} 次提醒: {}", event.getRemindCount(), event.getEventId());
} catch (Exception e) {
log.error("处理提醒失败: {}", e.getMessage(), e);
}
}
String firstTime = haiKangMapper.firstTime(warning.getEventId());
String twoEventTime = haiKangMapper.twoTime(warning.getEventId());
if (calculateTimeDifference(firstTime) >= 900000 ) {
List<EventPayload> pendingEventTwo = haiKangMapper.selectPendingRemindertwo(warning.getEventId());
for (EventPayload event : pendingEventTwo) {
if (event.getRemindCount() == 3){
twoEventTime = getCurrentTimeString();
event.setRemindCount(event.getRemindCount() + 1);
event.setLastRemindTime(getCurrentTimeString());
event.setTwoRemindTime(twoEventTime);
// 更新数据库
haiKangMapper.updateEventPayload(event);
weChatMediaUploader(event);
}else{
try {
// 发送提醒
event.setRemindCount(event.getRemindCount() + 1);
event.setLastRemindTime(getCurrentTimeString());
event.setTwoRemindTime(twoEventTime);
// 更新数据库
haiKangMapper.updateEventPayload(event);
sendReminder(event);
log.info("已发送第 {} 次提醒: {}", event.getRemindCount(), event.getEventId());
} catch (Exception e) {
log.error("处理提醒失败: {}", e.getMessage(), e);
}
}
}
}
if (!isNightTime(warning.getSendTime())) {
String twoTime = haiKangMapper.twoTime(warning.getEventId());
if (calculateTimeDifference(twoTime) >= 900000) {
List<EventPayload> pendingEventTwo = haiKangMapper.selectPendingRemindertree(warning.getEventId());
for (EventPayload event : pendingEventTwo) {
// 发送提醒
if (event.getRemindCount() == 6){
event.setRemindCount(event.getRemindCount() + 1);
event.setLastRemindTime(getCurrentTimeString());
// 更新数据库
haiKangMapper.updateEventPayload(event);
weChatMediaUploader(event);
}else {
try {
event.setRemindCount(event.getRemindCount() + 1);
event.setLastRemindTime(getCurrentTimeString());
// 更新数据库
haiKangMapper.updateEventPayload(event);
sendReminder(event);
log.info("已发送第 {} 次提醒: {}", event.getRemindCount(), event.getEventId());
} catch (Exception e) {
log.error("处理提醒失败: {}", e.getMessage(), e);
}
}
}
}
}
}
}
// 获取 EventPayload 对象
private static EventPayload getEventPayload(EventPayloads eventPayloads, EventData eventPayloades, EventParams params) {
EventPayload eventPayload = new EventPayload();
eventPayload.setAbility(params.getAbility());
eventPayload.setSrcIndex(eventPayloades.getSrcIndex());
eventPayload.setSrcType(eventPayloades.getSrcType());
eventPayload.setHappenTime(eventPayloades.getHappenTime());
eventPayload.setEventId(eventPayloades.getEventId());
eventPayload.setSrcName(eventPayloades.getSrcName());
eventPayload.setEventType(eventPayloades.getEventType());
eventPayload.setMethod(eventPayloads.getMethod());
eventPayload.setSendTime(params.getSendTime());
eventPayload.setStopTime(eventPayloades.getStopTime());
List<LinkageResult> linkageResult = eventPayloades.getLinkageResult();
// 解析 content 字段提取 picUrls 和 svrIndexCode
if (linkageResult != null && !linkageResult.isEmpty()) {
for (LinkageResult result : linkageResult) {
String content = result.getContent();
if (content != null && !content.isEmpty()) {
try {
// 解析 JSON 数组字符串
JSONArray contentArray = JSON.parseArray(content);
if (contentArray != null && !contentArray.isEmpty()) {
// 获取第一个元素(根据您的数据示例)
JSONObject contentObj = contentArray.getJSONObject(0);
if (contentObj != null) {
// 提取 svrIndexCode
String svrIndexCode = contentObj.getString("svrIndexCode");
eventPayload.setSvrIndexCode(svrIndexCode);
// 提取 picUrls
JSONArray picUrlsArray = contentObj.getJSONArray("picUrls");
if (picUrlsArray != null && !picUrlsArray.isEmpty()) {
// 获取第一个图片 URL
String picUrl = picUrlsArray.getString(0);
eventPayload.setPicUri(picUrl);
}
}
}
} catch (Exception e) {
log.error("解析 content 字段失败: {}", e.getMessage(), e);
}
}
}
}
return eventPayload;
}
// 计算时间差
public static long calculateTimeDifference(String timeString1) {
if (timeString1 == null){
return 0;
}
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date1 = sdf.parse(timeString1);
String formattedDate = sdf.format(new Date());
Date date2 = sdf.parse(formattedDate);
return date2.getTime() - date1.getTime();
} catch (Exception e) {
log.error("时间计算错误: {}", e.getMessage());
return 0;
}
}
//获取当前时间字符串
public static String getCurrentTimeString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
return sdf.format(new Date());
}
//图片上传
public void weChatMediaUploader(EventPayload eventPayload) throws Exception {
PictureRequest pictureRequest = new PictureRequest();
String imageUrl = eventPayload.getPicUri();
if (imageUrl == null){
return;
}
ArtemisConfig artemisConfig = new ArtemisConfig(url, appKey, appSecret);
String pictureDataApi = ARTEMIS_PATH +"/api/video/v1/events/picture";
Map<String,String> path = new HashMap<String,String>(2){
{
put("https://",pictureDataApi);
}
};
pictureRequest.setSvrIndexCode(eventPayload.getSvrIndexCode());
pictureRequest.setPicUri(imageUrl);
pictureRequest.setNetProtocol("http");
String body=JSON.toJSONString(pictureRequest);
String result =ArtemisHttpUtil.doPostStringArtemis(artemisConfig,path,body,null,null,"application/json");
JSONObject responseJson = JSON.parseObject(result);
JSONObject dataObj = responseJson.getJSONObject("data");
if (dataObj!=null){
imageUrl = dataObj.getString("picUrl");
eventPayload.setPicUri(imageUrl);
}else {
return;
}
sendReminder(eventPayload);
}
/**
* 根据事件发生时间判断是否为夜间时段
* @param eventTime 事件发生时间,格式为 "yyyy-MM-dd HH:mm:ss.SSS"
* @return true表示夜间(19:00-7:00),false表示白天(7:00-19:00)
*/
private boolean isNightTime(String eventTime) {
try {
if (eventTime == null || eventTime.isEmpty()) {
return false;
}
LocalDateTime dateTime;
// 处理ISO 8601格式
if (eventTime.contains("T")) {
// 标准化ISO格式时间字符串
String normalizedTime = eventTime;
// 移除时区信息
if (normalizedTime.contains("+")) {
normalizedTime = normalizedTime.substring(0, normalizedTime.indexOf("+"));
} else if (normalizedTime.endsWith("Z")) {
normalizedTime = normalizedTime.substring(0, normalizedTime.length() - 1);
}
DateTimeFormatter isoFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]");
dateTime = LocalDateTime.parse(normalizedTime, isoFormatter);
} else {
// 处理标准格式
DateTimeFormatter formatter = eventTime.contains(".") ?
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS") :
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
dateTime = LocalDateTime.parse(eventTime, formatter);
}
int hour = dateTime.getHour();
return hour >= 19 || hour < 7;
} catch (Exception e) {
log.error("解析事件时间失败,时间字符串: {}, 错误: {}", eventTime, e.getMessage());
return false;
}
}
/**
* 将ISO 8601格式的时间转换为标准格式
* @param isoTime ISO 8601格式的时间字符串
* @return 标准格式的时间字符串
*/
private String convertIsoToStandardFormat(String isoTime) {
if (isoTime == null || isoTime.isEmpty()) {
return getCurrentTimeString(); // 返回当前时间作为默认值
}
try {
LocalDateTime dateTime;
// 处理ISO 8601格式
if (isoTime.contains("T")) {
// 标准化ISO格式时间字符串
String normalizedTime = isoTime;
// 移除时区信息
if (normalizedTime.contains("+")) {
normalizedTime = normalizedTime.substring(0, normalizedTime.indexOf("+"));
} else if (normalizedTime.endsWith("Z")) {
normalizedTime = normalizedTime.substring(0, normalizedTime.length() - 1);
}
DateTimeFormatter isoFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]");
dateTime = LocalDateTime.parse(normalizedTime, isoFormatter);
} else {
// 如果已经是标准格式,直接解析
DateTimeFormatter formatter = isoTime.contains(".") ?
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS") :
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
dateTime = LocalDateTime.parse(isoTime, formatter);
}
// 转换为 yyyy-MM-dd HH:mm:ss 格式
return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} catch (Exception e) {
log.error("时间格式转换失败,使用原始时间: {}, 错误: {}", isoTime, e.getMessage());
return isoTime; // 转换失败时返回原始时间
}
}
}
最新发布