添加监听服务异常发送短信功能(待短信服务提供)

ds-xuancheng
luyya 2025-05-10 14:34:03 +08:00
parent f9243af818
commit fbdae27daf
13 changed files with 252 additions and 9 deletions

View File

@ -14,6 +14,7 @@
<module>stwzhj-api-resource</module>
<module>stwzhj-api-workflow</module>
<module>stwzhj-api-data2es</module>
<module>stwzhj-api-location</module>
</modules>
<artifactId>stwzhj-api</artifactId>

View File

@ -47,6 +47,12 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-api-location</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-api</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>stwzhj-api-location</artifactId>
<description>
stwzhj-api-location
</description>
<dependencies>
<!-- stwzhj Common Core-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-common-excel</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,8 @@
package org.dromara.location.api;
import java.util.List;
public interface RemoteElasticSearchService {
List<String> linstenDataStatus();
}

View File

@ -6,13 +6,13 @@
<property name="console.log.pattern"
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<!-- 控制台输出 -->
<!-- &lt;!&ndash; 控制台输出 &ndash;&gt;
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${console.log.pattern}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
</appender>-->
<include resource="logback-common.xml" />
@ -21,8 +21,66 @@
<!-- 开启 skywalking 日志收集 -->
<include resource="logback-skylog.xml" />
<!--系统操作日志-->
<root level="info">
<appender-ref ref="console" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
所以我们使用下面的策略,可以避免输出 Error 的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>ERROR</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--日志名称如果没有File 属性那么只会使用FileNamePattern的文件路径规则
如果同时有<File><FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${LOG_PATH}${LOG_FILE}</File>
<encoder>
<charset>UTF-8</charset>
<pattern>%date [%level] [%thread] %logger{60} [%file : %line] %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}info/${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>20</maxHistory> <!-- 保留180天 -->
</rollingPolicy>
</appender>
<!--error log-->
<appender name="ERRORFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>Error</level>
</filter>
<!--日志名称如果没有File 属性那么只会使用FileNamePattern的文件路径规则
如果同时有<File><FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${LOG_PATH}error.${LOG_FILE}</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy ">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${LOG_PATH}error/${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</FileNamePattern>
<!--只保留最近90天的日志-->
<maxFileSize>50MB</maxFileSize>
<maxHistory>180</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%date [%level] [%thread] %logger{60} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="ERRORFILE"/>
</root>
</configuration>

View File

@ -103,6 +103,12 @@
<groupId>org.dromara</groupId>
<artifactId>stwzhj-api-resource</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-api-location</artifactId>
</dependency>
<!--elasticsearch-->
<dependency>
<groupId>org.elasticsearch</groupId>

View File

@ -0,0 +1,23 @@
package org.dromara.location.dubbo;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.location.api.RemoteElasticSearchService;
import org.dromara.location.service.ISearchService;
import org.springframework.stereotype.Service;
import java.util.List;
@RequiredArgsConstructor
@Service
@DubboService
public class RemoteElasticSearchServiceImpl implements RemoteElasticSearchService {
private final ISearchService searchService;
@Override
public List<String> linstenDataStatus() {
return searchService.linstenDataStatus();
}
}

View File

@ -1,5 +1,7 @@
package org.dromara.location.service;
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
import java.util.List;
import java.util.Map;
@ -7,5 +9,10 @@ import java.util.Map;
public interface ISearchService {
public List<Map> searchCar(String deviceCode, String startTime, String endTime,String deviceType) ;
/*
* ES
* */
public List<String> linstenDataStatus();
}

View File

@ -2,9 +2,14 @@ package org.dromara.location.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.location.service.ISearchService;
import org.dromara.system.api.RemoteDictService;
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
import org.elasticsearch.action.search.*;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.RequestOptions;
@ -13,20 +18,22 @@ import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@ -38,6 +45,11 @@ public class SearchServiceImpl implements ISearchService {
@Autowired
private RestHighLevelClient restHighLevelClient;
@DubboReference
RemoteDictService dictService;
@Override
public List<Map> searchCar(String deviceCode, String startTime, String endTime,String deviceType) throws RuntimeException{
@ -117,8 +129,47 @@ public class SearchServiceImpl implements ISearchService {
return sourceList;
}
@Override
public List<String> linstenDataStatus() {
List<RemoteDictDataVo> list = dictService.selectDictDataByType("zd_device_type");
List<String> maps = new ArrayList<>();
for (RemoteDictDataVo dataVo : list) {
try {
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
// 匹配第二个
TermQueryBuilder termTerminalBuilder2 = QueryBuilders.termQuery("deviceType", dataVo.getDictValue());
boolBuilder.must(termTerminalBuilder2);
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//排序条件
searchSourceBuilder.sort("gpsTime", SortOrder.DESC);
searchSourceBuilder.query(boolBuilder);
searchSourceBuilder.size(1);
searchRequest.source(searchSourceBuilder);
// 执行查询,然后处理响应结果
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 根据状态和数据条数验证是否返回了数据
if (RestStatus.OK.equals(searchResponse.status()) && searchResponse.getHits().getTotalHits().value > 0) {
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits) {
// 将 JSON 转换成对象
Map sourceAsMap = hit.getSourceAsMap();
String time = sourceAsMap.get("gpsTime").toString();
if (DateUtil.between(new Date(),DateUtil.parseDateTime(time) , DateUnit.MINUTE)>=30){
maps.add(dataVo.getDictLabel());
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
return maps;
}
private List<String> findEsIndexByTime(String startTime, String endTime) {
startTime = startTime.substring(0, 10).replaceAll("-","");//yyyyMMdd

View File

@ -104,6 +104,11 @@
<artifactId>stwzhj-api-resource</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stwzhj-api-location</artifactId>
</dependency>
<dependency>
<groupId>com.github.jeffreyning</groupId>
<artifactId>mybatisplus-plus</artifactId>

View File

@ -4,14 +4,20 @@ package org.dromara.system.controller.system;
import cn.hutool.core.date.DateUtil;
import jdk.dynalink.linker.LinkerServices;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.R;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.web.core.BaseController;
import org.dromara.location.api.RemoteElasticSearchService;
import org.dromara.system.domain.DeviceRedis;
import org.dromara.system.domain.SysNotice;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.bo.SysNoticeBo;
import org.dromara.system.domain.bo.TDeviceBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@ -28,6 +34,12 @@ public class IndexStaticsController extends BaseController {
private final IDeviceRedisService redisService;
private final ISysNoticeService noticeService;
@DubboReference
RemoteElasticSearchService elasticSearchService;
/*
@ -75,6 +87,27 @@ public class IndexStaticsController extends BaseController {
return R.ok(maps);
}
/*
* ES
* */
@Scheduled(cron = "0 */30 * * * ?")
public void listen(){
List<String> strs = elasticSearchService.linstenDataStatus();
if (strs.size() >0){
List<SysNoticeVo> nlist = noticeService.selectTodayNoticeList();
if (nlist.size() <=2){
// -- todo 发送短信
SysNoticeBo noticeBo = new SysNoticeBo();
noticeBo.setNoticeTitle("手机号码");
noticeBo.setNoticeType("3");
noticeBo.setNoticeContent(strs.toString()+"数据不正常,请检查服务是否正常");
noticeBo.setCreateTime(DateUtil.date());
noticeService.insertNotice(noticeBo);
}
}
}
/*
* 线
* */

View File

@ -33,6 +33,8 @@ public interface ISysNoticeService {
*/
List<SysNoticeVo> selectNoticeList(SysNoticeBo notice);
List<SysNoticeVo> selectTodayNoticeList();
/**
*
*

View File

@ -1,5 +1,6 @@
package org.dromara.system.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -20,6 +21,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
@ -64,6 +66,14 @@ public class SysNoticeServiceImpl implements ISysNoticeService {
return baseMapper.selectVoList(lqw);
}
@Override
public List<SysNoticeVo> selectTodayNoticeList() {
LambdaQueryWrapper<SysNotice> lqw = new LambdaQueryWrapper<>();
lqw.likeRight(SysNotice::getCreateTime, DateUtil.formatDate(new Date()));
lqw.eq(SysNotice::getNoticeType,"3");
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SysNotice> buildQueryWrapper(SysNoticeBo bo) {
LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getNoticeTitle()), SysNotice::getNoticeTitle, bo.getNoticeTitle());