提交 3bf36b9c 作者: chenshiqiang

commit 3.24

上级 9cb29731
...@@ -85,6 +85,10 @@ ...@@ -85,6 +85,10 @@
<groupId>commons-codec</groupId> <groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
</exclusion> </exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
...@@ -149,8 +153,40 @@ ...@@ -149,8 +153,40 @@
<artifactId>mammoth</artifactId> <artifactId>mammoth</artifactId>
<version>1.5.0</version> <version>1.5.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.8.7</version>
</dependency>
<!--stream kafka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.1.5</version>
</dependency>
<!-- mini文件存储服务 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.2</version>
</dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies> </dependencies>
...@@ -161,19 +197,25 @@ ...@@ -161,19 +197,25 @@
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
</plugins> </plugins>
<resources> <resources>
<resource> <resource>
<directory>${project.basedir}/lib</directory> <directory>${project.basedir}/lib</directory>
<targetPath>BOOT-INF/lib/</targetPath> <targetPath>BOOT-INF/lib/</targetPath>
<includes> <includes>
<include>**/*.jar</include> <include>**/*.jar</include>
</includes> </includes>
</resource> </resource>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
</resources> <resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build> </build>
<repositories> <repositories>
<repository> <repository>
...@@ -188,4 +230,5 @@ ...@@ -188,4 +230,5 @@
</releases> </releases>
</repository> </repository>
</repositories> </repositories>
</project> </project>
package com.zzsn.event; package com.zzsn.event;
import com.zzsn.event.config.TaskExecutor; import com.zzsn.event.config.TaskExecutor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
......
...@@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit; ...@@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit;
@Component @Component
public class TaskExecutor implements CommandLineRunner { public class TaskExecutor implements CommandLineRunner {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
private final Integer PERIOD=1; private final Integer PERIOD=10000;
@Autowired @Autowired
private IEventService eventService; private IEventService eventService;
......
...@@ -7,6 +7,44 @@ public class Constants { ...@@ -7,6 +7,44 @@ public class Constants {
//redis缓存 key常量 //redis缓存 key常量
public static final String FINANCE = "SAVE_ES:"; public static final String FINANCE = "SAVE_ES:";
public static final String RESEARCH = "RESEARCH:"; public static final String RESEARCH = "RESEARCH:";
//事件专题-redis缓存key前缀
public static final String SUBJECT_ANALYSIS_PRE = "SUBJECT_ANALYSIS::";
//传播路径
public static final String PROPAGATION_KEY = "PROPAGATION_PATH::";
/**
* 关键词数据入缓存 key前缀
*/
public static final String KEY_WORDS_TO_REDIS_PREFIX = "KEY_WORDS_TO_REDIS::";
public static String[] FETCH_FIELDS_STATISTIC = {"id", "subjectId","title","origin", "publishDate", "sourceAddress", "masterEntryId","infoSourceType"};
public static String[] FETCH_FIELDS_DATA = {"id", "subjectId", "title", "content", "publishDate", "origin", "sourceAddress", "masterEntryId","infoSourceType"};
//es 专题库索引
public static final String SUBJECT_INDEX = "subjectdatabase";
//es 采集库索引
public static final String COLLECT_INDEX = "basedata";
//专题事件脉络展示 伪事件脉络 的资讯数量阈值
public static final int FAKE_NUM = 6;
//kafka 发送分析命令 主题
public static final String EVENT_ANALYSIS_TOPIC = "event-analysis";
//kafka 发送 事件脉络所需信息 主题
public static final String EVENT_CONTEXT_SEND_TOPIC = "event_context_send_topic";
//kafka 发送 伪事件脉络所需信息 主题
public static final String FAKE_EVENT_CONTEXT_SEND_TOPIC = "fake_event_context_send_data";
//统计分析
public static final String TW_STATISTIC_ANALYSIS_KEY = "TW_STATISTIC_ANALYSIS::";
//统计分析
public static final String STATISTIC_ANALYSIS_KEY = "STATISTIC_ANALYSIS::";
//kafka 接收 观点分析结果 主题
public static final String VIEWPOINT_RECEIVE_TOPIC = "event_viewpoint_result_data";
//kafka 接收 事件脉络结果 主题
public static final String EVENT_CONTEXT_RECEIVE_TOPIC = "event_topic_result_data";
//kafka 接收 伪事件脉络结果 主题
public static final String FAKE_EVENT_CONTEXT_RECEIVE_TOPIC = "fake_event_context-result_data";
//重复数索引ku
public final static String ES_REPEAT_OLD = "repeathold";
//旧同步数据时索引 //旧同步数据时索引
public final static String ES_DATA_NEW_INDEX = "newclbdatabase"; public final static String ES_DATA_NEW_INDEX = "newclbdatabase";
......
package com.zzsn.event.consumer;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.Event;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.service.EsService;
import com.zzsn.event.service.IEventService;
import com.zzsn.event.service.SubjectAnalysisService;
import com.zzsn.event.vo.SubjectDataVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
/**
* @author lkg
* 监听消费kafka消息
* 消费topic中消息(注意:如果监听的topic不存在则会自动创建)
* @date 2022/7/15
*/
@Slf4j
@Component
public class KafkaConsumer {
@Autowired
private EsService esService;
@Autowired
private SubjectAnalysisService subjectAnalysisService;
@Autowired
private IEventService eventService;
/**
* 获取-观点分析-分析结果数据,并入库
*
* @param record 接受的kafka数据
*/
@KafkaListener(topics = {Constants.VIEWPOINT_RECEIVE_TOPIC})
public void viewPointAnalysis(ConsumerRecord<String, String> record) {
String value = record.value();
if (StringUtils.isNotEmpty(value)) {
String subjectId = null;
try {
List<SubjectAnalysis> subjectAnalyses = JSON.parseArray(value, SubjectAnalysis.class);
subjectAnalyses.forEach(e -> {
SubjectDataVo subjectDataVo = esService.queryInfo(e.getDataId());
Integer repeatNum = e.getRepeatNum();
if (repeatNum == 0) {
String repeatId = subjectDataVo.getRepeatId();
if (StringUtils.isNotEmpty(repeatId)) {
repeatNum = esService.getRepeatNum(repeatId);
}
}
if (repeatNum == 0) {
e.setRepeatNum(1);
} else {
e.setRepeatNum(repeatNum);
}
e.setTitle(removeNonBmpUniCodes(e.getTitle()));
});
Integer category = subjectAnalyses.get(0).getCategory();
subjectId = subjectAnalyses.get(0).getSubjectId();
Date analysisDate = subjectAnalyses.get(0).getAnalysisDate();
LambdaQueryWrapper<SubjectAnalysis> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(SubjectAnalysis::getSubjectId, subjectId).eq(SubjectAnalysis::getCategory, category);
subjectAnalysisService.remove(queryWrapper);
subjectAnalysisService.saveBatch(subjectAnalyses);
//更新专题最近一次观点分析的时间
Event subject = new Event();
subject.setId(subjectId);
subject.setAnalysisTime(analysisDate);
eventService.updateById(subject);
} catch (Exception e) {
e.printStackTrace();
}
log.info("id为-{}-的专题,此次-观点分析-数据更新完成", subjectId);
}
}
/**
* 获取-事件脉络-分析结果数据,并入库
*
* @param record 接受的kafka数据
*/
@KafkaListener(topics = {Constants.EVENT_CONTEXT_RECEIVE_TOPIC})
public void eventContext(ConsumerRecord<String, String> record) {
String value = record.value();
if (StringUtils.isNotEmpty(value)) {
try {
List<SubjectAnalysis> subjectAnalyses = JSON.parseArray(value, SubjectAnalysis.class);
subjectAnalyses.forEach(e -> {
if (exist(e)) {
e.setTitle(removeNonBmpUniCodes(e.getTitle()));
subjectAnalysisService.save(e);
}
});
log.info("id为-{}-的专题,此次-事件脉络-数据更新完成", subjectAnalyses.get(0).getSubjectId());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 获取-伪事件脉络-分析结果数据,并入库
*
* @param record 接受的kafka数据
*/
@KafkaListener(topics = {Constants.FAKE_EVENT_CONTEXT_RECEIVE_TOPIC})
public void eventContext_fake(ConsumerRecord<String, String> record) {
String value = record.value();
if (StringUtils.isNotEmpty(value)) {
String subjectId = null;
Integer category = 3;
try {
List<SubjectAnalysis> subjectAnalyses = JSON.parseArray(value, SubjectAnalysis.class);
subjectId = subjectAnalyses.get(0).getSubjectId();
subjectAnalyses.forEach(e -> {
e.setCategory(category);
e.setTitle(removeNonBmpUniCodes(e.getTitle()));
});
LambdaQueryWrapper<SubjectAnalysis> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(SubjectAnalysis::getSubjectId,subjectId).eq(SubjectAnalysis::getCategory,category);
int count = subjectAnalysisService.count(queryWrapper);
if (count>0) {
subjectAnalysisService.remove(queryWrapper);
}
subjectAnalysisService.saveBatch(subjectAnalyses);
} catch (Exception e) {
e.printStackTrace();
}
log.info("id为-{}-的专题,此次-伪事件脉络-数据更新完成", subjectId);
}
}
private boolean exist(SubjectAnalysis subjectAnalyse){
LambdaQueryWrapper<SubjectAnalysis> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(SubjectAnalysis::getCategory,2).eq(SubjectAnalysis::getDataId,subjectAnalyse.getDataId())
.eq(SubjectAnalysis::getSubjectId,subjectAnalyse.getSubjectId());
SubjectAnalysis one = subjectAnalysisService.getOne(queryWrapper);
return one == null;
}
//去除特殊的字符,例如表情符
private String removeNonBmpUniCodes(String str) {
return StringUtils.isEmpty(str) ? null : str.replaceAll("[^\\u0000-\\uFFFF]", "");
}
}
package com.zzsn.event.controller;
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.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzsn.event.entity.LabelEntity;
import com.zzsn.event.entity.Report;
import com.zzsn.event.service.EsStatisticsService;
import com.zzsn.event.service.LabelEntityService;
import com.zzsn.event.service.ReportService;
import com.zzsn.event.util.CalculateUtil;
import com.zzsn.event.util.MinioUtil;
import com.zzsn.event.util.RestUtil;
import com.zzsn.event.vo.CountVO;
import com.zzsn.event.vo.MediaVO;
import com.zzsn.event.vo.Result;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
/**
* 舆情分析
*
* @author lkg
* @date 2024/1/24
*/
@RestController
@RequestMapping("/public/opinion/analysis")
public class EventAnalysisController {
@Autowired
private EsStatisticsService esStatisticsService;
@Autowired
private LabelEntityService labelEntityService;
@Autowired
private ReportService reportService;
@Value("${subject.analysis-url:}")
private String analysisUrl;
/**
* 下载报告
*
* @param subjectId 专题id
* @author lkg
* @date 2024/2/1
*/
@GetMapping("/download")
public void download(@RequestParam String subjectId,HttpServletResponse response){
try {
LambdaQueryWrapper<Report> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.select(Report::getReportName, Report::getFilePath)
.eq(Report::getSubjectId,subjectId);
Report one = reportService.getOne(queryWrapper);
String filePath = one.getFilePath();
if (StringUtils.isNotEmpty(filePath)) {
int index = filePath.indexOf("/");
String bucketName = filePath.substring(0, index);
String filename = filePath.substring(index);
InputStream inputStream = MinioUtil.getMinioFile(bucketName, filename);
byte[] bytes = IOUtils.toByteArray(inputStream);
String fileName = one.getReportName() + ".docx";
fileName = URLEncoder.encode(fileName, "UTF-8").replace("+", " ");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.setContentLength(bytes.length);
OutputStream out = response.getOutputStream();
out.write(bytes);
out.flush();
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 总体分析
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @author lkg
* @date 2024/1/24
*/
@GetMapping("/total")
public Result<?> totalAndMax(@RequestParam String subjectId, @RequestParam String startTime, @RequestParam String endTime) {
Map<String, Object> map = esStatisticsService.totalAndMax(subjectId, null, null);
long hours = DateUtil.between(DateUtil.parseDateTime(startTime), DateUtil.parseDateTime(endTime), DateUnit.HOUR);
map.put("duration",hours);
Object count = map.get("totalCount");
String divide = CalculateUtil.divide(String.valueOf(count), String.valueOf(hours), 2);
map.put("spread", divide);
String mainReport = esStatisticsService.mainReport(subjectId);
map.put("mainReport",mainReport);
return Result.OK(map);
}
/**
* 情感判断分析
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-按小时;2-按天
* @author lkg
* @date 2024/1/25
*/
@GetMapping("/orientation")
public Result<?> orientation(@RequestParam String subjectId, @RequestParam String startTime,
@RequestParam String endTime, @RequestParam Integer type) {
List<CountVO> list = new ArrayList<>();
String labelTypeId = "1631119596744265729";
List<LabelEntity> labelEntities = labelEntityService.listByType(labelTypeId);
AtomicLong total = new AtomicLong();
labelEntities.forEach(e -> {
CompletableFuture<CountVO> async = CompletableFuture.supplyAsync(() -> {
CountVO countVO = esStatisticsService.orientation(subjectId, e.getId(), startTime, endTime, type);
total.addAndGet(countVO.getValue());
supply(countVO, startTime,endTime,type);
return countVO;
});
try {
CountVO countVO = async.get();
list.add(countVO);
} catch (Exception ex) {
ex.printStackTrace();
}
});
for (CountVO countVO : list) {
long value = countVO.getValue();
long totalCount = total.get();
String divide = CalculateUtil.divide(String.valueOf(value), String.valueOf(totalCount));
String percentage = "0%";
if (StringUtils.isNotEmpty(divide)) {
percentage = CalculateUtil.percentage(Double.parseDouble(divide),false);
}
countVO.setPercentage(percentage);
}
return Result.OK(list);
}
/**
* 影响力分析
*
* @param subjectId 专题id
* @author lkg
* @date 2024/1/25
*/
@GetMapping("/influence")
public Result<?> influence(@RequestParam String subjectId){
List<CountVO> list = esStatisticsService.influence(subjectId, null, null);
return Result.OK(list);
}
/**
* 来源分析
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-按小时;2-按天
* @author lkg
* @date 2024/1/25
*/
@GetMapping("/source")
public Result<?> source(@RequestParam String subjectId,@RequestParam String startTime,
@RequestParam String endTime, @RequestParam Integer type){
List<CountVO> list = esStatisticsService.source(subjectId, startTime, endTime, type);
for (CountVO countVO : list) {
supply(countVO, startTime,endTime,type);
}
return Result.OK(list);
}
/**
* 平台活跃度占比
*
* @param subjectId 专题id
* @author lkg
* @date 2024/1/25
*/
@GetMapping("/origin")
public Result<?> origin(@RequestParam String subjectId){
List<CountVO> list = esStatisticsService.origin(subjectId, null, null);
return Result.OK(list);
}
//补充缺失的时间
private void supply(CountVO countVO, String startTime,String endTime,Integer type) {
List<CountVO> list = new ArrayList<>();
List<CountVO> children = countVO.getChildren();
Map<String, CountVO> map = children.stream().collect(Collectors.toMap(CountVO::getName, item -> item, (k1, k2) -> k2));
DateTime startDate = DateUtil.parseDateTime(startTime);
DateTime endDate = DateUtil.parseDateTime(endTime);
List<DateTime> rangeToList = new ArrayList<>();
String format = null;
if (type == 1) {
rangeToList = DateUtil.rangeToList(startDate, endDate, DateField.HOUR_OF_DAY);
format = "yyyy-MM-dd HH";
} else if (type == 2) {
rangeToList = DateUtil.rangeToList(startDate, endDate, DateField.DAY_OF_YEAR);
format = "yyyy-MM-dd";
}
for (DateTime dateTime : rangeToList) {
String date = DateUtil.format(dateTime,format);
if (map.containsKey(date)) {
list.add(countVO);
} else {
CountVO vo = new CountVO();
vo.setName(date);
vo.setValue(0L);
list.add(vo);
}
}
countVO.setChildren(list);
}
}
package com.zzsn.event.controller; package com.zzsn.event.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
...@@ -14,8 +15,11 @@ import org.springframework.web.bind.annotation.*; ...@@ -14,8 +15,11 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 事件分类 * 事件分类
* @Author: jeecg-boot * @Author: jeecg-boot
* @Date: 2024-03-14 * @Date: 2024-03-14
...@@ -49,7 +53,41 @@ public class EventCategoryController { ...@@ -49,7 +53,41 @@ public class EventCategoryController {
IPage<EventCategory> pageList = eventCategoryService.page(page, queryWrapper); IPage<EventCategory> pageList = eventCategoryService.page(page, queryWrapper);
return Result.OK(pageList); return Result.OK(pageList);
} }
/**
* 通过父级id查询列表
*
* @return
*/
@ApiOperation(value="通过父级id查询列表", notes="通过父级id查询列表")
@GetMapping(value = "/getByParentId")
public Result<?> getByParentId(String pid) {
return Result.OK(eventCategoryService.list(new LambdaQueryWrapper<EventCategory>().eq(EventCategory::getPid,pid)));
}
/**
* 获取树状数据
*
* @return
*/
@ApiOperation(value="获取树状数据", notes="获取树状数据")
@GetMapping(value = "/treeData")
public Result<?> treeData() {
Map<String, List<EventCategory>> collect = eventCategoryService.list().stream().collect(Collectors.groupingBy(EventCategory::getPid));
EventCategory parent = EventCategory.builder().id("0").typeName("所有").hasChild(1).build();
buildData(parent,collect);
return Result.OK(parent);
}
private void buildData(EventCategory parent, Map<String, List<EventCategory>> collect) {
if(parent.getHasChild()==1){
parent.setChildren(collect.get(parent.getId()));
collect.remove(parent.getId());
for (EventCategory child : parent.getChildren()) {
buildData(child,collect);
}
}
}
/** /**
* 添加 * 添加
* *
......
package com.zzsn.event.controller; package com.zzsn.event.controller;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.Event; import com.zzsn.event.entity.Event;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.producer.ProduceInfo;
import com.zzsn.event.service.AnalysisService;
import com.zzsn.event.service.IEventService; import com.zzsn.event.service.IEventService;
import com.zzsn.event.util.ObjectUtil; import com.zzsn.event.util.ObjectUtil;
import com.zzsn.event.util.RedisUtil;
import com.zzsn.event.util.RestUtil; import com.zzsn.event.util.RestUtil;
import com.zzsn.event.vo.InfoSourceVo; import com.zzsn.event.vo.*;
import com.zzsn.event.vo.Result; import com.zzsn.event.xxljob.service.IXxlJobInfoService;
import com.zzsn.event.vo.SubjectKeywordsMap;
import com.zzsn.event.vo.SubjectPage;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; import java.util.*;
/** /**
* 事件 * 事件
* @Author: jeecg-boot * @Author: jeecg-boot
* @Date: 2024-03-14 * @Date: 2024-03-14
...@@ -36,8 +37,17 @@ import java.util.Arrays; ...@@ -36,8 +37,17 @@ import java.util.Arrays;
public class EventController { public class EventController {
@Autowired @Autowired
private IEventService eventService; private IEventService eventService;
@Value(("${enterprise-service.url:}")) @Value(("${serviceProject.url:}"))
private String ENTERPRISE_URL; private String SERVICE_PROJECT_URL;
@Autowired
private RedisUtil redisUtil;
@Autowired
private AnalysisService analysisService;
@Autowired
private IXxlJobInfoService iXxlJobInfoService;
@Autowired
private ProduceInfo produceInfo;
/** /**
* 分页列表查询 * 分页列表查询
...@@ -54,9 +64,8 @@ public class EventController { ...@@ -54,9 +64,8 @@ public class EventController {
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) { HttpServletRequest req) {
QueryWrapper<Event> queryWrapper = new QueryWrapper<>();
Page<Event> page = new Page<Event>(pageNo, pageSize); IPage<Event> pageList = eventService.pageList(event, pageNo,pageSize);
IPage<Event> pageList = eventService.page(page, queryWrapper);
return Result.OK(pageList); return Result.OK(pageList);
} }
...@@ -68,21 +77,42 @@ public class EventController { ...@@ -68,21 +77,42 @@ public class EventController {
*/ */
@ApiOperation(value="事件-添加", notes="事件-添加") @ApiOperation(value="事件-添加", notes="事件-添加")
@PostMapping(value = "/add") @PostMapping(value = "/add")
public Result<?> add(@RequestBody Event event) { public Result<?> add(@RequestBody AddEventParam eventParam) {
eventService.save(event); eventParam.setCreateTime(new Date());
eventParam.setUpdateTime(new Date());
Event event = eventService.saveMain(eventParam);
//插入xxlJob
iXxlJobInfoService.subjectInsert(event);
return Result.OK("添加成功!"); return Result.OK("添加成功!");
} }
/** /**
* 编辑 * 编辑
* *
* @param event * @param addEventParam
* @return * @return
*/ */
@ApiOperation(value="事件-编辑", notes="事件-编辑") @ApiOperation(value="事件-编辑", notes="事件-编辑")
@PutMapping(value = "/edit") @PutMapping(value = "/edit")
public Result<?> edit(@RequestBody Event event) { public Result<?> edit(@RequestBody AddEventParam addEventParam) {
eventService.updateById(event); Event byId = eventService.getById(addEventParam.getId());
addEventParam.setUpdateTime(new Date());
eventService.updateMain(addEventParam);
//更新xxljob
List<String> subjectCodes = new ArrayList<>();
if(null!=addEventParam.getEventCode()){
subjectCodes.add(addEventParam.getEventCode());
iXxlJobInfoService.keyWordsUpdate(subjectCodes, String.valueOf(addEventParam.getStatus()));
}else {
return Result.error("eventCode 必传!");
}
//判断是否提取热词
eventService.extractHotWords(addEventParam);
if (!Objects.equals(byId.getStatus(), addEventParam.getStatus()) && addEventParam.getStatus() == 1){
produceInfo.sendSubjectMsg(addEventParam.getEventCode());
}
return Result.OK("编辑成功!"); return Result.OK("编辑成功!");
} }
...@@ -133,7 +163,7 @@ public class EventController { ...@@ -133,7 +163,7 @@ public class EventController {
public Object infoSourceBind(@RequestBody SubjectPage subjectPage) { public Object infoSourceBind(@RequestBody SubjectPage subjectPage) {
try { try {
JSONObject params = ObjectUtil.objectToJSONObject(subjectPage);; JSONObject params = ObjectUtil.objectToJSONObject(subjectPage);;
String url = ENTERPRISE_URL + "enterpriseData/getYearReportList"; String url = SERVICE_PROJECT_URL + "enterpriseData/getYearReportList";
return RestUtil.post(url, null, params); return RestUtil.post(url, null, params);
} catch (Exception e) { } catch (Exception e) {
return null; return null;
...@@ -149,7 +179,7 @@ public class EventController { ...@@ -149,7 +179,7 @@ public class EventController {
@RequestParam(name="groupId") String groupId, @RequestParam(name="groupId") String groupId,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) { @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
String url = ENTERPRISE_URL + "event/infoSource/bindList"; String url = SERVICE_PROJECT_URL + "event/infoSource/bindList";
JSONObject params = ObjectUtil.objectToJSONObject(infoSourceVo); JSONObject params = ObjectUtil.objectToJSONObject(infoSourceVo);
params.put("ynBind",ynBind); params.put("ynBind",ynBind);
params.put("groupId",groupId); params.put("groupId",groupId);
...@@ -164,7 +194,7 @@ public class EventController { ...@@ -164,7 +194,7 @@ public class EventController {
@GetMapping("/keywordsType/rootListNoPage") @GetMapping("/keywordsType/rootListNoPage")
public Object keywordsList(@RequestParam(name = "contain", defaultValue = "false") Boolean contain, public Object keywordsList(@RequestParam(name = "contain", defaultValue = "false") Boolean contain,
@RequestParam(name = "subjectId", defaultValue = "0") String subjectId) { @RequestParam(name = "subjectId", defaultValue = "0") String subjectId) {
String url = ENTERPRISE_URL + "event/keywordsType/rootListNoPage"; String url = SERVICE_PROJECT_URL + "event/keywordsType/rootListNoPage";
JSONObject params = new JSONObject(); JSONObject params = new JSONObject();
params.put("contain",contain); params.put("contain",contain);
params.put("subjectId",subjectId); params.put("subjectId",subjectId);
...@@ -177,7 +207,7 @@ public class EventController { ...@@ -177,7 +207,7 @@ public class EventController {
public Object keyWordsBind(@RequestBody SubjectPage subjectPage) { public Object keyWordsBind(@RequestBody SubjectPage subjectPage) {
try { try {
JSONObject params = ObjectUtil.objectToJSONObject(subjectPage);; JSONObject params = ObjectUtil.objectToJSONObject(subjectPage);;
String url = ENTERPRISE_URL + "event/keyWordsBind"; String url = SERVICE_PROJECT_URL + "event/keyWordsBind";
return RestUtil.post(url, null, params); return RestUtil.post(url, null, params);
} catch (Exception e) { } catch (Exception e) {
return null; return null;
...@@ -190,10 +220,57 @@ public class EventController { ...@@ -190,10 +220,57 @@ public class EventController {
public Object keyWordsEdit(@RequestBody SubjectKeywordsMap subjectKeywordsMap) { public Object keyWordsEdit(@RequestBody SubjectKeywordsMap subjectKeywordsMap) {
try { try {
JSONObject params = ObjectUtil.objectToJSONObject(subjectKeywordsMap);; JSONObject params = ObjectUtil.objectToJSONObject(subjectKeywordsMap);;
String url = ENTERPRISE_URL + "event/keyWords/edit"; String url = SERVICE_PROJECT_URL + "event/keyWords/edit";
return RestUtil.post(url, null, params); return RestUtil.post(url, null, params);
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
/**
* 标签查询
*/
@PostMapping("/label/treeList")
public Object labelTreeList(@RequestBody SubjectKeywordsMap subjectKeywordsMap) {
try {
JSONObject params = ObjectUtil.objectToJSONObject(subjectKeywordsMap);;
String url = SERVICE_PROJECT_URL + "event/label/treeList";
return RestUtil.post(url, null, params);
} catch (Exception e) {
return null;
}
}
/**
* 传播路径
*
* @param eventId 事件id
*/
@GetMapping("/propagationPath")
public Result propagationPath(@RequestParam String eventId) {
String key = Constants.SUBJECT_ANALYSIS_PRE + Constants.PROPAGATION_KEY + eventId;
PropagationPathVo pathVo = (PropagationPathVo) redisUtil.get(key);
if (ObjectUtils.isEmpty(pathVo)) {
pathVo = analysisService.propagationPath(eventId);
}
return Result.OK(pathVo);
}
/**
* 事件脉络
*
* @param subjectId 专题id
* @param fakeNum 专题事件脉络展示 伪事件脉络 的资讯数量阈值
* @return com.zzsn.subjectAnalysis.common.Result
*/
@GetMapping("/eventContext")
public Result eventContext(@RequestParam String subjectId,
@RequestParam(value = "fakeNum", required = false) Integer fakeNum) {
if (fakeNum == null) {
fakeNum = Constants.FAKE_NUM;
}
List<SubjectAnalysis> cacheList = analysisService.eventContext(subjectId, fakeNum);
return Result.OK(cacheList);
}
} }
package com.zzsn.event.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: 通用多字段基类
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class BaseEntity extends BaseEntityId {
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
}
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author zs
* @Description: 通用id
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class BaseEntityId implements Serializable {
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
}
...@@ -43,7 +43,7 @@ public class Event { ...@@ -43,7 +43,7 @@ public class Event {
/**事件类型*/ /**事件类型*/
@Excel(name = "事件类型", width = 15) @Excel(name = "事件类型", width = 15)
@ApiModelProperty(value = "事件类型") @ApiModelProperty(value = "事件类型")
private Integer eventType; private String eventType;
/**开始时间*/ /**开始时间*/
@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") @Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
...@@ -60,10 +60,12 @@ public class Event { ...@@ -60,10 +60,12 @@ public class Event {
@Excel(name = "事件地域", width = 15) @Excel(name = "事件地域", width = 15)
@ApiModelProperty(value = "事件地域") @ApiModelProperty(value = "事件地域")
private String eventArea; private String eventArea;
private String eventAreaId;
/**标签*/ /**标签*/
@Excel(name = "标签", width = 15) @Excel(name = "标签", width = 15)
@ApiModelProperty(value = "标签") @ApiModelProperty(value = "标签")
private String eventLabel; private String eventLabel;
private String eventLabelIds;
/**关键词*/ /**关键词*/
@Excel(name = "关键词", width = 15) @Excel(name = "关键词", width = 15)
@ApiModelProperty(value = "关键词") @ApiModelProperty(value = "关键词")
...@@ -97,4 +99,24 @@ public class Event { ...@@ -97,4 +99,24 @@ public class Event {
@ApiModelProperty(value = "修改人id") @ApiModelProperty(value = "修改人id")
private String updateBy; private String updateBy;
private Integer status=1; private Integer status=1;
/**
* 分析事件脉络-最新资讯的时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date analysisTime;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date eventTime;
@TableField(exist = false)
private String typeName;
private String eventCode;
private String cron;
/**事件专题增量分析规则*/
@ApiModelProperty(value = "事件专题增量分析规则")
private Integer increAnaRule;
/**事件专题总量分析规则*/
@ApiModelProperty(value = "事件专题总量分析规则")
private Integer totalAnaRule;
/**事件专题时间间隔分析规则(天)*/
@ApiModelProperty(value = "事件专题时间间隔分析规则(天)")
private Integer timeAnaRule;
} }
...@@ -2,14 +2,15 @@ package com.zzsn.event.entity; ...@@ -2,14 +2,15 @@ package com.zzsn.event.entity;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.*;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
...@@ -26,12 +27,14 @@ import org.jeecgframework.poi.excel.annotation.Excel; ...@@ -26,12 +27,14 @@ import org.jeecgframework.poi.excel.annotation.Excel;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value="event_category对象", description="事件分类") @ApiModel(value="event_category对象", description="事件分类")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EventCategory { public class EventCategory {
/**id*/ /**id*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
private Integer id; private String id;
/**事件分类名称*/ /**事件分类名称*/
@Excel(name = "事件分类名称", width = 15) @Excel(name = "事件分类名称", width = 15)
@ApiModelProperty(value = "事件分类名称") @ApiModelProperty(value = "事件分类名称")
...@@ -43,7 +46,7 @@ public class EventCategory { ...@@ -43,7 +46,7 @@ public class EventCategory {
/**是否有子节点0,没有 1,有*/ /**是否有子节点0,没有 1,有*/
@Excel(name = "是否有子节点0,没有 1,有", width = 15) @Excel(name = "是否有子节点0,没有 1,有", width = 15)
@ApiModelProperty(value = "是否有子节点0,没有 1,有") @ApiModelProperty(value = "是否有子节点0,没有 1,有")
private String hasChild; private Integer hasChild;
/**状态*/ /**状态*/
@Excel(name = "状态", width = 15) @Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态") @ApiModelProperty(value = "状态")
...@@ -80,4 +83,6 @@ public class EventCategory { ...@@ -80,4 +83,6 @@ public class EventCategory {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间") @ApiModelProperty(value = "更新时间")
private Date updateTime; private Date updateTime;
@TableField(exist = false)
private List<EventCategory> children;
} }
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Description: 标签相关的实体
* @Author: jeecg-boot
* @Date: 2022-11-30
* @Version: V1.0
*/
@Data
@TableName("label_entity")
@ApiModel(value="label_entity对象", description="标签相关的实体")
public class LabelEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
/**名称*/
@Excel(name = "名称", width = 15)
@ApiModelProperty(value = "名称")
private String name;
/**近义词*/
@Excel(name = "近义词", width = 15)
@ApiModelProperty(value = "近义词")
private String synonym;
/**说明*/
@Excel(name = "说明", width = 15)
@ApiModelProperty(value = "说明")
private String explanation;
/**层级*/
@Excel(name = "层级", width = 15)
@ApiModelProperty(value = "层级")
private Integer level;
/**一级主键id*/
@Excel(name = "一级主键id", width = 15)
@ApiModelProperty(value = "一级主键id")
private String topId;
/**所有id*/
@Excel(name = "所有id", width = 15)
@ApiModelProperty(value = "所有id")
private String pathIds;
/**状态*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态")
private Integer status;
/**排序*/
@Excel(name = "排序", width = 15)
@ApiModelProperty(value = "排序")
private Integer sort;
/**父级节点*/
@Excel(name = "父级节点", width = 15)
@ApiModelProperty(value = "父级节点")
private String pid;
/**是否有子节点*/
@Excel(name = "是否有子节点", width = 15, dicCode = "yn")
@ApiModelProperty(value = "是否有子节点")
private String hasChild;
@TableField(exist = false)
private String labelTypeId;
}
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zzsn.event.vo.ReportExtendVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 报告表
*
* @author lkg
* @date 2023/3/16
*/
@Data
@TableName("clb_report")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "clb_report", description = "报告表")
public class Report implements Serializable {
/**
* 主键id
*/
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 报告名称
*/
@ApiModelProperty(value = "报告名称")
@TableField("report_name")
private String reportName;
/**
* 报告刊期
*/
@ApiModelProperty(value = "报告刊期")
@TableField("report_issue")
private String reportIssue;
/**
* 报告内容
*/
@ApiModelProperty(value = "报告内容")
@TableField("content")
private String content;
/**
* 开始时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "开始时间")
@TableField("start_time")
private Date startTime;
/**
* 结束时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "结束时间")
@TableField("end_time")
private Date endTime;
/**
* 文件地址
*/
@ApiModelProperty(value = "文件地址")
@TableField("file_path")
private String filePath;
/**
* 预览地址
*/
@ApiModelProperty(value = "预览地址")
@TableField("preview")
private String preview;
/**
* 模板id
*/
@ApiModelProperty(value = "模板id")
@TableField("template_id")
private String templateId;
/**
* 报告类型id
*/
@ApiModelProperty(value = "报告类型id")
@TableField("type_id")
private String typeId;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
@TableField("description")
private String description;
/**
* 专题id
*/
@ApiModelProperty(value = "专题id")
@TableField("subject_id")
private String subjectId;
/**
* 项目id
*/
@ApiModelProperty(value = "项目id")
@TableField("project_id")
private String projectId;
/**
* 项目下的栏目id
*/
@ApiModelProperty(value = "项目下的栏目id")
@TableField("column_id")
private String columnId;
/**
* 发布状态(0-不发布;1-发布)
*/
@ApiModelProperty(value = "发布状态(0-不发布;1-发布)")
@TableField("publish")
private Integer publish;
/**
* 生成方式(1-自动;2-手动)
*/
@ApiModelProperty(value = "生成方式(1-自动;2-手动)")
@TableField("create_way")
private Integer createWay;
/**
* 报告状态(0-禁用;1-正常)
*/
@ApiModelProperty(value = "报告状态(0-禁用;1-正常)")
@TableField("status")
private Integer status;
/**
* 报告任务id
*/
@ApiModelProperty(value = "报告任务id")
@TableField("task_id")
private String taskId;
/**
* 任务执行时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "任务执行时间")
@TableField("task_execution_time")
private Date taskExecutionTime;
/**
* 是否删除(0-否;1-是)
*/
@ApiModelProperty(value = "是否删除(0-否;1-是)")
@TableField("delete_status")
private Integer deleteStatus;
/**
* 创建人
*/
@ApiModelProperty(value = "创建人")
@TableField("create_by")
private String createBy;
/**
* 创建时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
@TableField("create_time")
private Date createTime;
/**报告所属栏目信息*/
@TableField(exist = false)
private List<ReportExtendVo> reportExtendVoList;
}
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @author : wp
* @title : Subject
* @description: 专题
* @date : Created in 2022/7/7 10:04
* @modified By:
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "subject",autoResultMap = true)
public class Subject implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String subjectCode;
/**
* 专题名称
*/
private String subjectName;
/**
* 专题图片名称
*/
private String picturePolicy;
/**
* 启用时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date timeEnable;
/**
* 停用时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date timeDisable;
/**
* 专题增量分析规则
*/
private Integer increAnaRule;
/**
* 专题总量分析规则
*/
private Integer totalAnaRule;
/**
* 专题时间间隔分析规则
*/
private Integer timeAnaRule;
/**
* 专题最近一次分析时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date analysisTime;
/**
* 分析事件脉络-最新资讯的时间
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date eventTime;
/**
* 外事办映射id
*/
private Integer wsbMapId;
/**
* 创建人
*/
private String createBy;
/**
* 创建日期
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新日期
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 所属部门
*/
private String sysOrgCode;
/**
* 所属客户
*/
private String customerId;
private Integer status;
/**
* 专题类别(1:通用专题 2:事件专题)
*/
public Integer subjectType;
}
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @author lkg
* @description: 专题分析表
* @date 2022/7/14 17:10
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "subject_analysis",autoResultMap = true)
public class SubjectAnalysis implements Serializable {
/*主键id*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/*专题id*/
private String subjectId;
/*资讯id*/
private String dataId;
/*标题*/
private String title;
/*来源*/
private String origin;
/*发布时间*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date publishDate;
/*链接*/
private String sourceAddress;
/*重复数*/
private Integer repeatNum;
/*观点分析下的类型(1-新闻;2-论坛;3-微博)*/
private Integer type;
/*分类(1-观点分析;2-事件脉络;3-伪事件脉络)*/
//伪事件脉络 即当事件脉络资讯数量少于约定数量,通过python算法生成临时的资讯数量大于/等于约定数量的事件脉络。
private Integer category;
/*分析时间*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date analysisDate;
}
package com.zzsn.event.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
/**
* @Description: 专题与搜索引擎关联表
* @Author: jeecg-boot
* @Date: 2022-06-21
* @Version: V1.0
*/
@Data
@TableName("subject_search_engines_map")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="subject_search_engines_map对象", description="专题与搜索引擎关联表")
public class SubjectSearchEnginesMap implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**专题id*/
@Excel(name = "专题id", width = 15)
@ApiModelProperty(value = "专题id")
private String subjectId;
/**搜索引擎id*/
@Excel(name = "搜索引擎id", width = 15)
@ApiModelProperty(value = "搜索引擎id")
private String searchEngineId;
}
package com.zzsn.event.enums;
/**
* @author zhang ya nuo
* @Description 编码前缀枚举
* @since 2021/6/8
*/
public enum CodePrefixEnum {
INFO_SOURCE_DEFAULT("IN","信息源编码默认前缀"),
SUBJECT_DEFAULT("SJ", "专题编码默认前缀"),
PROJECT_DEFAULT("PJ", "项目编码默认前缀"),
CUSTOMER_DEFAULT("CS", "客户编码默认前缀"),
SPECIAL_INFO_SOURCE_DEFAULT("PY","信息源编码默认前缀"),
INFO_SOURCE_GROUP_DEFAULT("ING","信息源组编码默认前缀"),
KEY_WORDS_DEFAULT("KW", "关键词默认前缀"),
SOCIAL_CREDIT_CODE_DEFAULT("ZZSN", "统一社会信用代码前缀"),
QCC_ENTERPRISE_ID_DEFAULT("QCC", "老企业库ID"),
COLUMN_CODE_DEFAULT("COL", "栏目编码默认前缀"),
LABEL_CODE_DEFAULT("LABEL", "标签编码默认前缀");
// 前缀
private String value;
// 描述信息
private String des;
CodePrefixEnum(String value, String des) {
this.value = value;
this.des = des;
}
public String getValue() {
return value;
}
public String getDes() {
return des;
}
}
package com.zzsn.event.enums;
/**
* 影响力字段枚举
*
* @author lkg
* @date 2024/1/24
*/
public enum InfluenceEnum {
LIKE("likeNum", "点赞数"),
COMMENT("commentNum", "评论数"),
COLLECT("collectNum", "收藏数"),
SHARE("shareNum", "分享数");
/**值*/
private final String field;
/**描述*/
private final String description;
public String getField() {
return field;
}
public String getDescription() {
return description;
}
InfluenceEnum(String field, String description) {
this.field = field;
this.description = description;
}
}
package com.zzsn.event.enums;
/**
* @author zhang ya nuo
* @Description 信息源状态枚举
* @since 2021/6/9
*/
public enum InfoSourceStatusEnum {
ENABLE("1","启用"),
DISABLE("0","禁用");
private String value;
private String des;
InfoSourceStatusEnum(String value, String des) {
this.value = value;
this.des = des;
}
public String getvalue() {
return value;
}
public String getDes() {
return des;
}
}
package com.zzsn.event.enums;
import lombok.Getter;
/**
* 货币计量单位枚举
*
* @author lkg
* @date 2023/8/25
*/
@Getter
public enum SourceEnum {
OTHER("0", "其他"),
WEBSITE("1", "网站"),
WEIBO("2", "微博"),
WECHAT("3", "微信公众号"),
DOUYIN("4", "抖音"),
TIEBA("5", "贴吧");
/**值*/
private final String value;
/**描述*/
private final String description;
SourceEnum(String value, String description) {
this.value = value;
this.description = description;
}
public static String getDescription(String value){
String description = null;
SourceEnum[] values = SourceEnum.values();
for (SourceEnum sourceEnum : values) {
if (sourceEnum.value.equals(value)) {
description = sourceEnum.description;
break;
}
}
return description;
}
}
package com.zzsn.event.enums;
/**
* @author zhang ya nuo
* @Description xxljobinfo status 枚举
* @since 2021/6/9
*/
public enum XxljobInfoStatusEnum {
RUNNING(1,"运行"),
STOP(0,"停止");
private Integer value;
private String des;
XxljobInfoStatusEnum(int value, String des) {
this.value = value;
this.des = des;
}
public Integer getvalue() {
return value;
}
public String getDes() {
return des;
}
}
...@@ -2,8 +2,12 @@ package com.zzsn.event.mapper; ...@@ -2,8 +2,12 @@ package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.Event; import com.zzsn.event.entity.Event;
import com.zzsn.event.vo.SubjectKafkaVo;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
/** /**
* @Description: 事件 * @Description: 事件
* @Author: jeecg-boot * @Author: jeecg-boot
...@@ -13,4 +17,11 @@ import org.apache.ibatis.annotations.Mapper; ...@@ -13,4 +17,11 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface EventMapper extends BaseMapper<Event> { public interface EventMapper extends BaseMapper<Event> {
List<SubjectKafkaVo> eventSubjectList(int i);
List<Event> pageList(Event event, Integer offset, Integer pageSize);
Integer totalCount(Event event);
List<SubjectKafkaVo> prosessList(Date disableDate);
} }
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.vo.KeyWordsPage;
import com.zzsn.event.xxljob.entity.KeyWords;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description: 关键词管理
* @Author: jeecg-boot
* @Date: 2021-11-26
* @Version: V1.0
*/
@Mapper
public interface KeyWordsMapper extends BaseMapper<KeyWords> {
List<KeyWordsPage> selectKeyWordsListById(@Param("subjectId") String subjectId);
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.LabelEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author lenovo
* @description 针对表【label_entity】的数据库操作Mapper
* @createDate 2023-08-28 15:02:50
* @Entity com.zzsn.clb.scheduletask.entity.LabelEntity
*/
@Mapper
public interface LabelEntityMapper extends BaseMapper<LabelEntity> {
/**
* 根据分类获取标签列表
*
* @param labelTypeId 标签分类id
* @author lkg
* @date 2024/1/22
*/
List<LabelEntity> listByType(@Param("labelTypeId") String labelTypeId);
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.Report;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 报告表
*
* @author lkg
* @date 2023/3/16
*/
@Mapper
public interface ReportMapper extends BaseMapper<Report> {
// /**
// * 报告表-分页列表
// *
// * @param typeId 报告分类id
// * @param offset 偏移量
// * @param pageSize 返回条数
// * @author lkg
// * @date 2023/3/24
// */
// List<ReportVO> pageList(@Param("typeId") String typeId, @Param("offset") Integer offset, @Param("pageSize") Integer pageSize);
//
// /**
// * 报告表-总数量
// *
// * @param typeId 报告分类id
// * @author lkg
// * @date 2023/3/24
// */
// Integer count(@Param("typeId") String typeId);
//
//
// /**
// * 报告表-分页列表(客户)
// *
// * @param typeIds 报告分类id集合
// * @param projectIds 项目id集合
// * @param reportName 报告名称
// * @param startTime 开始时间
// * @param endTime 结束时间
// * @param offset 偏移量
// * @param pageSize 返回条数
// * @author lkg
// * @date 2023/3/24
// */
// List<UserReportVO> userPageList(@Param("typeIds") List<String> typeIds, @Param("projectIds") List<String> projectIds,
// @Param("reportName") String reportName,
// @Param("startTime") String startTime, @Param("endTime") String endTime,
// @Param("offset") Integer offset, @Param("pageSize") Integer pageSize);
//
// /**
// * 报告表-总数量(客户)
// *
// * @param typeIds 报告分类id集合
// * @param projectIds 项目id集合
// * @param reportName 报告名称
// * @param startTime 开始时间
// * @param endTime 结束时间
// * @author lkg
// * @date 2023/3/24
// */
// Integer total(@Param("typeIds") List<String> typeIds, @Param("projectIds") List<String> projectIds,
// @Param("reportName") String reportName,
// @Param("startTime") String startTime, @Param("endTime") String endTime);
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.SubjectAnalysis;
import org.apache.ibatis.annotations.Mapper;
/**
* @author lkg
* @description:
* @date 2022/7/14 17:17
*/
@Mapper
public interface SubjectAnalysisMapper extends BaseMapper<SubjectAnalysis> {
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.vo.SubjectKeywordsMap;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description: 专题关键词关联表
* @Author: jeecg-boot
* @Date: 2021-12-09
* @Version: V1.0
*/
@Mapper
public interface SubjectKeywordsMapMapper extends BaseMapper<SubjectKeywordsMap> {
KeyWordsDTO selectMinByKeyWordsId(@Param("keyWordsId") String keyWordsId);
int selectCountByKeyWordsId(@Param("keyWordsId") String keyWordsId);
KeyWordsDTO selectMaxByKeyWordsId(@Param("keyWordsId") String keyWordsId);
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.Subject;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* @author : wp
* @title : subjectMapper
* @description:专题mapper接口
* @date : Created in 2022/7/7 10:25
* @modified By:
*/
@Mapper
public interface SubjectMapper extends BaseMapper<Subject> {
// /**
// * 获取用户授权得事件专题列表
// *
// * @param userId: 用户id
// * @param subjectType: 专题类别(1:通用专题 2:事件专题)
// * @param title: 专题标题
// * @author lkg
// * @date 2023/2/22
// */
// List<Subject> searchSubjectList(@Param("userId") String userId, @Param("subjectType") Integer subjectType, @Param("title") String title);
//
// /**
// * 获取进行中(未结束)的事件专题列表
// *
// * @param subjectType 专题类别(1:通用专题 2:事件专题)
// * @param endDate 结束时间
// * @return java.util.List<com.zzsn.subjectAnalysis.vo.SubjectKafkaVo>
// * @author lkg
// */
// List<SubjectKafkaVo> progressList(@Param("subjectType") Integer subjectType, @Param("endDate") Date endDate);
//
// /**
// * 获取所有的事件专题列表
// *
// * @param subjectType 专题类别(1:通用专题 2:事件专题)
// * @return java.util.List<com.zzsn.subjectAnalysis.vo.SubjectKafkaVo>
// * @author lkg
// */
// List<SubjectKafkaVo> eventSubjectList(@Param("subjectType") Integer subjectType);
//
// /**
// * 获取最大外事办映射id
// *
// * @return java.lang.Integer
// * @author lkg
// */
// Integer getMaxWsbMapId();
}
package com.zzsn.event.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.entity.SubjectSearchEnginesMap;
import com.zzsn.event.vo.SearchEnginesVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description: 专题与搜索引擎关联表
* @Author: jeecg-boot
* @Date: 2022-06-21
* @Version: V1.0
*/
@Mapper
public interface SubjectSearchEnginesMapMapper extends BaseMapper<SubjectSearchEnginesMap> {
void deleteBySubjectId(@Param("subjectId") String subjectId);
List<SearchEnginesVo> bindSearchEngineList(@Param("searchEnginesVo") SearchEnginesVo searchEnginesVo);
List<String> querySearchList(@Param("subjectId") String subjectId);
}
...@@ -2,4 +2,44 @@ ...@@ -2,4 +2,44 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.EventMapper"> <mapper namespace="com.zzsn.event.mapper.EventMapper">
<select id="eventSubjectList" resultType="com.zzsn.event.vo.SubjectKafkaVo">
select s.id,s.event_name as subject_name,s.start_time as time_enable,s.end_time as time_disable,s.incre_ana_rule,
s.total_ana_rule,s.time_ana_rule,s.analysis_time,s.event_time
from event s
</select>
<select id="pageList" resultType="com.zzsn.event.entity.Event">
select t2.type_name,t1.* from event t1
left join event_category t2 on t1.event_type =t2.id
where 1=1
<if test="event.eventName!=null and event.eventName != ''">
and t1.event_name like CONCAT('%',#{event.eventName},'%')
</if>
<if test="event.eventType!=null and event.eventType != ''">
and dt1.event_type = #{event.eventType}
</if>
limit #{offset}, #{pageSize}
</select>
<select id="totalCount" resultType="java.lang.Integer">
select count(1) from event t1
left join event_category t2 on t1.event_type =t2.id
where 1=1
<if test="event.eventName!=null and event.eventName != ''">
and t1.event_name like CONCAT('%',#{event.eventName},'%')
</if>
<if test="event.eventType!=null and event.eventType != ''">
and dt1.event_type = #{event.eventType}
</if>
</select>
<select id="prosessList" resultType="com.zzsn.event.vo.SubjectKafkaVo">
select s.id,s.event_name as subject_name,s.start_time as time_enable,s.end_time as time_disable,s.incre_ana_rule,
s.total_ana_rule,s.time_ana_rule,s.analysis_time,s.event_time
from event s
where 1=1
<if test="endDate != null">
and (s.end_time is null or s.end_time <![CDATA[ >= ]]> #{endDate})
</if>
</select>
</mapper> </mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.KeyWordsMapper">
<select id="selectKeyWordsListById" resultType="com.zzsn.event.vo.KeyWordsPage">
SELECT b.*, d.type_name as keyWordTypeNames, a.type as type, a.id as subjectKeyWordId FROM subject_keywords_map a
INNER JOIN key_words b ON a.keywords_id = b.id
LEFT JOIN keywords_type_map c ON b.id = c.keywords_id
LEFT JOIN keywords_type d ON d.id = c.type_id
where a.subject_id = #{subjectId}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.LabelEntityMapper">
<resultMap id="BaseResultMap" type="com.zzsn.event.entity.LabelEntity">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="synonym" column="synonym" jdbcType="VARCHAR"/>
<result property="explanation" column="explanation" jdbcType="VARCHAR"/>
<result property="level" column="level" jdbcType="INTEGER"/>
<result property="topId" column="top_id" jdbcType="VARCHAR"/>
<result property="pathIds" column="path_ids" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="INTEGER"/>
<result property="sort" column="sort" jdbcType="INTEGER"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="sysOrgCode" column="sys_org_code" jdbcType="VARCHAR"/>
<result property="pid" column="pid" jdbcType="VARCHAR"/>
<result property="hasChild" column="has_child" jdbcType="VARCHAR"/>
</resultMap>
<select id="listByType" resultType="com.zzsn.event.entity.LabelEntity">
SELECT e.id, e.name
FROM label_entity e
inner join sys_base_label_type_map m on e.id = m.relation_id
where m.label_id = #{labelTypeId}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.SubjectAnalysisMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.SubjectKeywordsMapMapper">
<delete id="deleteBySubjectId" >
delete from subject_keywords_map
WHERE subject_id = #{subjectId}
</delete>
<delete id="deleteBySubjectIds" >
delete from subject_keywords_map
WHERE subject_id in
<foreach collection="subjectIds" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
<delete id="deleteByKeyWordsIds" >
delete from subject_keywords_map
WHERE subject_id = #{subjectId}
and keywords_id in
<foreach collection="keyWordsIds" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
<select id="selectByKeyWordsId" resultType="com.zzsn.event.vo.KeyWordsDTO">
SELECT b.words_code, GROUP_CONCAT(a.subject_id SEPARATOR ',') as subjectId FROM subject_keywords_map a
left join key_words b on a.keywords_id = b.id
WHERE a.keywords_id = #{keyWordsId}
</select>
<select id="selectMinByKeyWordsId" resultType="com.zzsn.event.vo.KeyWordsDTO">
SELECT b.words_code, min(time_enable) as startTime FROM subject_keywords_map a
LEFT JOIN key_words b ON a.keywords_id = b.id
LEFT JOIN subject c ON a.subject_id = c.id
WHERE a.keywords_id = #{keyWordsId}
</select>
<select id="selectCountByKeyWordsId" resultType="int">
SELECT count(1) from subject_keywords_map a
LEFT JOIN subject b ON a.subject_id = b.id
WHERE a.keywords_id = #{keyWordsId} and time_disable is null
</select>
<select id="selectMaxByKeyWordsId" resultType="com.zzsn.event.vo.KeyWordsDTO">
SELECT b.words_code, max(time_disable) as endTime from subject_keywords_map a
LEFT JOIN key_words b ON a.keywords_id = b.id
LEFT JOIN subject c ON a.subject_id = c.id
WHERE a.keywords_id = #{keyWordsId}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.SubjectMapper">
<!-- <select id="searchSubjectList" resultType="com.zzsn.subjectAnalysis.entity.Subject">-->
<!-- select s.id,s.subject_name,s.time_enable,s.time_disable,s.picture_policy,s.wsb_map_id from subject s-->
<!-- <if test="userId !=null and userId != ''">-->
<!-- inner join sys_user_data_permission dp on s.id = dp.permission_id-->
<!-- </if>-->
<!-- where s.subject_type = #{subjectType}-->
<!-- <if test="title !=null and title != ''">-->
<!-- and s.subject_name like concat('%',#{title},'%')-->
<!-- </if>-->
<!-- <if test="userId !=null and userId != ''">-->
<!-- and dp.user_id = #{userId}-->
<!-- </if>-->
<!-- order by s.create_time desc-->
<!-- </select>-->
<!-- <select id="progressList" resultType="com.zzsn.subjectAnalysis.vo.SubjectKafkaVo">-->
<!-- select s.id,s.subject_name,s.time_enable,s.time_disable,s.incre_ana_rule,-->
<!-- s.total_ana_rule,s.time_ana_rule,s.analysis_time,s.event_time-->
<!-- from subject s-->
<!-- where s.subject_type = #{subjectType}-->
<!-- <if test="endDate != null">-->
<!-- and (s.time_disable is null or s.time_disable <![CDATA[ >= ]]> #{endDate})-->
<!-- </if>-->
<!-- </select>-->
<!-- <select id="eventSubjectList" resultType="com.zzsn.subjectAnalysis.vo.SubjectKafkaVo">-->
<!-- &lt;!&ndash;select a.*,w.key_word from (-->
<!-- select s.id,s.subject_name,s.time_enable,s.time_disable,s.incre_ana_rule,-->
<!-- s.total_ana_rule,s.time_ana_rule,s.analysis_time,s.event_time-->
<!-- from subject s-->
<!-- where s.subject_type = #{subjectType}-->
<!-- ) a-->
<!-- INNER JOIN subject_keywords_map k ON a.id=k.subject_id-->
<!-- INNER JOIN key_words w ON k.keywords_id=w.id&ndash;&gt;-->
<!-- select s.id,s.subject_name,s.time_enable,s.time_disable,s.incre_ana_rule,-->
<!-- s.total_ana_rule,s.time_ana_rule,s.analysis_time,s.event_time-->
<!-- from subject s-->
<!-- where s.subject_type = #{subjectType}-->
<!-- </select>-->
<!-- <select id="getMaxWsbMapId" resultType="Integer">-->
<!-- select max(wsb_map_id) from subject-->
<!-- </select>-->
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.mapper.SubjectSearchEnginesMapMapper">
<select id="bindSearchEngineList" resultType="com.zzsn.event.vo.SearchEnginesVo">
SELECT b.subject_id as subjectId, a.* FROM search_engines a
LEFT JOIN subject_search_engines_map b ON a.id = b.search_engine_id and b.subject_id = #{searchEnginesVo.subjectId}
where 1 = 1
<if test="searchEnginesVo.type!=null">
and a.type = #{searchEnginesVo.type}
</if>
</select>
<delete id="deleteBySubjectId" >
delete from subject_search_engines_map
WHERE subject_id = #{subjectId}
</delete>
<select id="querySearchList" resultType="String">
SELECT a.dictionary_code FROM search_engines a
INNER JOIN subject_search_engines_map b ON a.id = b.search_engine_id and b.subject_id = #{subjectId}
</select>
</mapper>
package com.zzsn.event.producer;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import javax.sound.midi.Receiver;
/**
* @author zs
* @Description 信息通道
* @since 2021/6/10
*/
public interface IInfosourceSource {
/**
* 专题通道
*/
@Output
MessageChannel subjectModel();
/**
* 关键词通道
*
* @return org.springframework.messaging.MessageChannel
*/
@Output
MessageChannel keyWordsCrawl();
}
package com.zzsn.event.producer;
import com.alibaba.fastjson.JSON;
import com.zzsn.event.vo.KeyWordsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Slf4j
@EnableBinding(IInfosourceSource.class)
public class ProduceInfo {
@Autowired
private IInfosourceSource source;
/*
* 专题拉取数据
* @param info 专题编码
* */
public void sendSubjectMsg(String subjectCode) {
Message<String> message = MessageBuilder.withPayload(subjectCode).build();
source.subjectModel().send(message);
log.info("专题投递到kafka成功,topic:subjectModel, subjectCode=[{}]", subjectCode);
}
/**
* 关键词执行
* @param keyWordsDTO 关键词信息源
*/
public void sendKeyWordsInfoSourceMsg(KeyWordsDTO keyWordsDTO) {
try{
String msg = JSON.toJSONString(keyWordsDTO);
Message<String> message = MessageBuilder.withPayload(msg).build();
source.keyWordsCrawl().send(message);
}catch (Exception e){
log.error("关键词:"+ keyWordsDTO.getWordsCode() + "推送kafka失败");
}
}
}
package com.zzsn.event.service;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.vo.PropagationPathVo;
import com.zzsn.event.vo.StatisticAnalysisVo;
import com.zzsn.event.vo.ViewPointAnalysisVo;
import java.util.List;
import java.util.Map;
/**
* @author lkg
* @description: 专题分析
* @date 2022/7/20 11:25
*/
public interface AnalysisService {
// /**
// * 观点分析
// * @param subjectId 专题id
// * @return java.util.Map<java.lang.String,java.util.List<com.zzsn.subjectAnalysis.vo.ViewPointAnalysisVo>>
// */
// Map<String, List<ViewPointAnalysisVo>> viewPointAnalysis(String subjectId);
//
/**
* 事件脉络
* @param subjectId 专题id
* @param fakeNum 专题事件脉络展示 伪事件脉络 的资讯数量阈值
* @return java.util.List<com.zzsn.subjectAnalysis.entity.SubjectAnalysis>
*/
List<SubjectAnalysis> eventContext(String subjectId, int fakeNum);
/**
* 传播路径
* @param subjectId 专题id
* @return com.zzsn.subjectAnalysis.vo.PropagationPathVo
*/
PropagationPathVo propagationPath(String subjectId);
// /**
// * 统计分析-所有
// * @param subjectId 专题id
// * @return java.util.Map<java.lang.String,java.lang.Object>
// */
// Map<String, Object> statisticAnalysis(String subjectId);
//
// /**
// * 统计分析-按时间范围
// * @param subjectId 专题id
// * @param startTime 开始时间
// * @param endTime 结束时间
// */
// List<StatisticAnalysisVo> statisticAnalysis(String subjectId, String startTime, String endTime);
}
package com.zzsn.event.service;
import com.zzsn.event.vo.SpecialInformationParam;
import org.elasticsearch.search.builder.SearchSourceBuilder;
/**
* @Description: 门户自定义模型配置
* @Author: jeecg-boot
* @Date: 2023-11-21
* @Version: V1.0
*/
public interface EsDataSearchService {
/**
* 组装es查询条件
*
* @param param 查询参数
* @author lkg
* @date 2024/1/29
*/
SearchSourceBuilder packageSearQuery(SpecialInformationParam param);
}
package com.zzsn.event.service;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.util.EsDateUtil;
import com.zzsn.event.vo.SubjectDataVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author lkg
* @description: es查询
* @date 2022/7/7 9:57
*/
@Slf4j
@Service
public class EsService {
@Autowired
private RestHighLevelClient client;
/**
* 获取专题下的资讯
*
* @param subjectId 专题id
* @param startDate 开始时间
* @param endDate 结束时间
* @param flag 0-主条目;null表示所有
* @param fetchFields 抓取的字段
* @param sort 1-升序;2-降序
* @param pageNo 当前页
* @param pageSize 每页返回条数
*/
public List<SubjectDataVo> getDataBySubjectId(String subjectId, String startDate, String endDate, String flag, String[] fetchFields, Integer sort, Integer pageNo, Integer pageSize) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//按时间排序
if (sort == 1) {
searchSourceBuilder.sort("publishDate", SortOrder.ASC);
} else if (sort == 2) {
searchSourceBuilder.sort("publishDate", SortOrder.DESC);
}
//设置需要获取的字段
// String[] fetchFields = {"id", "subjectId", "title", "content", "publishDate", "origin", "sourceAddress", "masterEntryId","infoSourceType"};
searchSourceBuilder.fetchSource(fetchFields, null);
//设置返回条数
if (pageNo != null) {
searchSourceBuilder.from((pageNo - 1) * pageSize);
}
if (pageSize == null) {
pageSize = 50000;
}
searchSourceBuilder.size(pageSize);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.matchQuery("subjectId", subjectId));
if (StringUtils.isNotBlank(startDate) || StringUtils.isNotBlank(endDate)) {
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishDate");
if (StringUtils.isNotBlank(startDate)) {
rangeQueryBuilder.gte(EsDateUtil.esFieldDateFormat(startDate));
}
if (StringUtils.isNotBlank(endDate)) {
rangeQueryBuilder.lte(EsDateUtil.esFieldDateFormat(endDate));
}
boolQuery.filter(rangeQueryBuilder);
}
//只查询主条目且未删除
if (StringUtils.isNotEmpty(flag)) {
boolQuery.mustNot(QueryBuilders.matchQuery("flag", flag));
//未删除
boolQuery.mustNot(QueryBuilders.matchQuery("deleteFlag", "1"));
}
return formatData(getEsResult(searchSourceBuilder, boolQuery, subjectId));
}
/**
* 获取专题下的资讯数量
*
* @param subjectId 专题id
* @param startDate 开始时间
* @param endDate 结束时间
* @param flag 0-主条目;null表示所有
*/
public Integer count(String subjectId, String startDate, String endDate, String flag) {
long count = 0L;
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.matchQuery("subjectId", subjectId));
if (StringUtils.isNotBlank(startDate) || StringUtils.isNotBlank(endDate)) {
if (StringUtils.isNotBlank(startDate)) {
boolQuery.filter(QueryBuilders.rangeQuery("publishDate").gte(EsDateUtil.esFieldDateFormat(startDate)));
}
if (StringUtils.isNotBlank(endDate)) {
boolQuery.filter(QueryBuilders.rangeQuery("publishDate").lte(EsDateUtil.esFieldDateFormat(endDate)));
}
}
//只查询主条目且未删除
if (StringUtils.isNotEmpty(flag)) {
boolQuery.mustNot(QueryBuilders.matchQuery("flag", flag));
//未删除
boolQuery.mustNot(QueryBuilders.matchQuery("deleteFlag", "1"));
}
SearchHits searchHits = getEsResult(searchSourceBuilder, boolQuery, subjectId);
if (searchHits != null) {
count = searchHits.getTotalHits().value;
}
return (int) count;
}
/**
* 根据查询条件分页获取资讯
*
* @param subjectId 专题id
* @param title 标题
* @param keyword 关键词
* @param startDate 开始时间
* @param endDate 结束时间
* @param pageNo 当前页
* @param pageSize 页面大小
* @author lkg
*/
public IPage<SubjectDataVo> pageList(String subjectId, String title, String keyword, String startDate, String endDate, Integer pageNo, Integer pageSize) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置分页参数
searchSourceBuilder.size(pageSize);
searchSourceBuilder.from((pageNo - 1) * pageSize);
//按时间倒序
searchSourceBuilder.sort("publishDate", SortOrder.DESC);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//某专题下的信息
boolQuery.must(QueryBuilders.matchPhraseQuery("subjectId", subjectId));
//过滤掉重复数据-flag!=0 表示主条目
boolQuery.mustNot(QueryBuilders.matchQuery("flag", "0"));
//未删除
boolQuery.mustNot(QueryBuilders.matchQuery("deleteFlag", "1"));
//标题搜索
if (StringUtils.isNotEmpty(title)) {
boolQuery.must(QueryBuilders.matchQuery("title", title));
}
/*//标题必须匹配命中关键词
if (StringUtils.isNotEmpty(keyword)) {
boolQuery.must(QueryBuilders.matchQuery("title", keyword));
}*/
//时间过滤
if (StringUtils.isNotEmpty(startDate) || StringUtils.isNotEmpty(endDate)) {
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishDate");
if (StringUtils.isNotBlank(startDate)) {
rangeQueryBuilder.gte(EsDateUtil.esFieldDateFormat(startDate));
}
if (StringUtils.isNotBlank(endDate)) {
rangeQueryBuilder.lte(EsDateUtil.esFieldDateFormat(endDate));
}
boolQuery.filter(rangeQueryBuilder);
}
SearchHits searchHits = getEsResult(searchSourceBuilder, boolQuery, subjectId);
IPage<SubjectDataVo> page = new Page<>();
if (searchHits != null) {
page.setCurrent(pageNo);
page.setSize(pageSize);
page.setTotal(searchHits.getTotalHits().value);
page.setRecords(formatData(searchHits));
}
return page;
}
/**
* 根据id获取该条信息的所有重复数据
*
* @param id 信息id
* @param subjectId 专题id
*/
public List<SubjectDataVo> dataById(String subjectId, String id) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置需要获取的字段
String[] fetchFields = {"id", "subjectId", "title", "publishDate", "origin", "sourceAddress", "masterEntryId", "infoSourceType"};
searchSourceBuilder.fetchSource(fetchFields, null);
//设置返回条数
searchSourceBuilder.size(10000);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("subjectId", subjectId));
boolQuery.must(QueryBuilders.termQuery("masterEntryId", id));
boolQuery.mustNot(QueryBuilders.termQuery("id", id));
return formatData(getEsResult(searchSourceBuilder, boolQuery, subjectId));
}
public SubjectDataVo queryInfo(String id) {
SubjectDataVo subjectDataVo = new SubjectDataVo();
try {
SearchRequest searchRequest = new SearchRequest(Constants.SUBJECT_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(1);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("id",id));
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse;
try {
searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
if (hits.getTotalHits().value > 0) {
SearchHit hit = hits.getAt(0);
String sourceAsString = hit.getSourceAsString();
subjectDataVo = JSON.parseObject(sourceAsString, SubjectDataVo.class);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
log.info("获取资讯-{}-详情,查询es库失败", id);
e.printStackTrace();
}
return subjectDataVo;
}
public int getRepeatNum(String id) {
int num = 0;
SearchRequest searchRequest = new SearchRequest(Constants.COLLECT_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//默认最大数量是10000,设置为true后,显示准确数量
searchSourceBuilder.trackTotalHits(true);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("repeatId", id));
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse;
try {
searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
num = (int) searchResponse.getHits().getTotalHits().value;
} catch (Exception e) {
log.info("获取资讯-{}-重复数,查询es库失败", id);
e.printStackTrace();
}
return num;
}
//格式化数据
private List<SubjectDataVo> formatData(SearchHits searchHits) {
List<SubjectDataVo> list = new ArrayList<>();
if (searchHits != null) {
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
SubjectDataVo subjectDataVo = JSON.parseObject(sourceAsString, SubjectDataVo.class);
subjectDataVo.setPublishDate(EsDateUtil.esFieldDateMapping(subjectDataVo.getPublishDate()));
subjectDataVo.setCreateDate(EsDateUtil.esFieldDateMapping(subjectDataVo.getCreateDate()));
list.add(subjectDataVo);
}
}
return list;
}
//获取es查询结果
private SearchHits getEsResult(SearchSourceBuilder searchSourceBuilder, BoolQueryBuilder boolQuery, String subjectId) {
SearchRequest searchRequest = new SearchRequest(Constants.SUBJECT_INDEX);
//默认最大数量是10000,设置为true后,显示准确数量
searchSourceBuilder.trackTotalHits(true);
//未删除
// boolQuery.must(QueryBuilders.matchQuery("deleteFlag",0));
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse;
try {
searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
return searchResponse.getHits();
} catch (Exception e) {
log.info("获取专题-{}-下资讯,查询es库失败", subjectId);
e.printStackTrace();
}
return null;
}
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzsn.event.vo.CountVO;
import com.zzsn.event.vo.MediaVO;
import com.zzsn.event.vo.NegativeDataVO;
import java.util.List;
import java.util.Map;
/**
* es统计查询
*
* @author lkg
* @date 2024/1/24
*/
public interface EsStatisticsService {
/**
* 总体信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-按小时;2-按天
* @author lkg
* @date 2024/1/25
*/
CountVO total(String startTime, String endTime, Integer type);
/**
* 总体分析,获取总量和波峰值
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @author lkg
* @date 2024/1/25
*/
Map<String, Object> totalAndMax(String subjectId, String startTime, String endTime);
/**
* 时间段内最新或最早的资讯
*
* @param subjectId 专题id
* @param labelId 标签id
* @param type 1-正序;2-倒序
* @param startTime 开始时间
* @param endTime 结束时间
* @author lkg
* @date 2024/1/25
*/
Map<String, Object> findOne(String subjectId, String labelId, int type, String startTime, String endTime);
/**
* 情感判断分析
*
* @param subjectId 专题id
* @param labelId 情感标签id
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-按小时;2-按天
* @author lkg
* @date 2024/1/25
*/
CountVO orientation(String subjectId, String labelId, String startTime, String endTime, Integer type);
/**
* 影响力分析
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @author lkg
* @date 2024/1/25
*/
List<CountVO> influence(String subjectId, String startTime, String endTime);
// /**
// * 媒体分布
// *
// * @param subjectId 专题id
// * @param startTime 开始时间
// * @param endTime 结束时间
// * @author lkg
// * @date 2024/1/24
// */
// List<MediaVO> media(String subjectId, String startTime, String endTime);
/**
* 来源分析
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-按小时;2-按天
* @author lkg
* @date 2024/1/23
*/
List<CountVO> source(String subjectId, String startTime, String endTime, Integer type);
/**
* 平台活跃度--前十
*
* @param subjectId 专题id
* @param startTime 开始时间
* @param endTime 结束时间
* @author lkg
* @date 2024/1/24
*/
List<CountVO> origin(String subjectId, String startTime, String endTime);
// /**
// * 地域分析
// *
// * @param subjectId 专题id
// * @param startTime 开始时间
// * @param endTime 结束时间
// * @author lkg
// * @date 2024/1/25
// */
// List<CountVO> region(String subjectId, String startTime, String endTime);
/**
* 专题下的主流报道
*
* @param subjectId 专题id
* @author lkg
* @date 2024/1/29
*/
String mainReport(String subjectId);
/**
* 某标签下资讯分页列表
*
* @param labelId 标签id
* @param startTime 开始时间
* @param endTime 结束时间
* @param pageNo 当前页
* @param pageSize 返回条数
* @author lkg
* @date 2024/2/29
*/
Page<NegativeDataVO> labelPageList(String labelId, String startTime, String endTime, Integer pageNo, Integer pageSize);
}
package com.zzsn.event.service; package com.zzsn.event.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zzsn.event.entity.Event; import com.zzsn.event.entity.Event;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.vo.AddEventParam;
import com.zzsn.event.vo.KeyWordsPage;
import com.zzsn.event.vo.SubjectKafkaVo;
import java.util.Date;
import java.util.List;
/** /**
* @Description: 事件 * @Description: 事件
...@@ -14,4 +21,20 @@ public interface IEventService extends IService<Event> { ...@@ -14,4 +21,20 @@ public interface IEventService extends IService<Event> {
* 计算热度 * 计算热度
*/ */
void compute(); void compute();
List<SubjectKafkaVo> progressList(Date disableDate);
List<SubjectKafkaVo> eventSubjectList();
IPage<Event> pageList(Event event, Integer pageNo, Integer pageSize);
void extractHotWords(AddEventParam event);
Event saveMain(AddEventParam addEventParam);
void updateMain(AddEventParam addEventParam);
/**
* 获取专题绑定的关键词组列表
*/
List<KeyWordsPage> bindKeyWordsList(String id);
} }
package com.zzsn.event.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.vo.KeyWordsPage;
import com.zzsn.event.xxljob.entity.KeyWords;
import java.util.List;
/**
* @Description: 关键词管理
* @Author: jeecg-boot
* @Date: 2021-11-26
* @Version: V1.0
*/
public interface IKeyWordsService extends IService<KeyWords> {
/**
* 获取专题绑定的信息源列表
*/
List<KeyWordsPage> bindKeyWordsList(String subjectId);
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.vo.SubjectKeywordsMap;
import java.util.List;
/**
* @Description: 专题关键词关联表
* @Author: jeecg-boot
* @Date: 2021-12-09
* @Version: V1.0
*/
public interface ISubjectKeywordsMapService extends IService<SubjectKeywordsMap> {
/**
* 查询这个词组绑定的专题的最小时间
* @param keyWordsId
* @return
*/
KeyWordsDTO selectMinByKeyWordsId(String keyWordsId);
/**
* 查询这个词组绑定的专题时间为空的个数
* @param keyWordsId
* @return
*/
int selectCountByKeyWordsId(String keyWordsId);
/**
* 查询这个词组绑定的专题结束的最大时间
* @param keyWordsId
* @return
*/
KeyWordsDTO selectMaxByKeyWordsId(String keyWordsId);
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.SubjectSearchEnginesMap;
import com.zzsn.event.vo.SearchEnginesVo;
import java.util.List;
/**
* @Description: 专题与搜索引擎关联表
* @Author: jeecg-boot
* @Date: 2022-06-21
* @Version: V1.0
*/
public interface ISubjectSearchEnginesMapService extends IService<SubjectSearchEnginesMap> {
void deleteBySubjectId(String subjectId);
List<SearchEnginesVo> bindSearchEngineList(SearchEnginesVo searchEnginesVo);
/**
* 根据专题id查询出专题绑定的搜索引擎编码
* @param subjectId
* @return
*/
List<String> querySearchList(String subjectId);
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.Subject;
import java.util.Date;
import java.util.List;
/**
* @author : wp
* @title : ISubjectService
* @description: 专题接口
* @date : Created in 2022/7/7 10:21
* @modified By:
*/
public interface ISubjectService extends IService<Subject> {
// /**
// * 获取用户授权得事件专题列表
// *
// * @param userId: 用户id
// * @param title: 专题标题
// * @author lkg
// * @date 2023/2/22
// */
// List<Subject> searchSubjectList(String userId, String title);
//
// IPage<SubjectDataVo> queryInfoListBySid(SubjectVo subjectInfo, Integer pageNo, Integer pageSize) throws Exception;
//
// /**
// * 获取进行中(未结束)的事件专题列表
// *
// * @param endDate 结束时间
// * @return java.util.List<com.zzsn.subjectAnalysis.vo.SubjectKafkaVo>
// * @author lkg
// */
// List<SubjectKafkaVo> progressList(Date endDate);
//
// /**
// * 获取所有的事件专题列表
// *
// * @return java.util.List<com.zzsn.subjectAnalysis.vo.SubjectKafkaVo>
// * @author lkg
// */
// List<SubjectKafkaVo> eventSubjectList();
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.LabelEntity;
import java.util.List;
/**
* @author lkg
* @date 2023/3/2
*/
public interface LabelEntityService extends IService<LabelEntity> {
/**
* 根据分类获取标签列表
*
* @param labelTypeId 标签分类id
* @author lkg
* @date 2024/1/22
*/
List<LabelEntity> listByType(String labelTypeId);
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.Report;
/**
* 报告表
*
* @author lkg
* @date 2023/3/16
*/
public interface ReportService extends IService<Report> {
//
// /**
// * 报告分页列表
// *
// * @param typeId 分类id
// * @param pageNo 当前页
// * @param pageSize 返回条数
// * @author lkg
// * @date 2024/1/31
// */
// IPage<ReportVO> pageList(String typeId, Integer pageNo, Integer pageSize);
//
//
// /**
// * 报告表-分页列表(客户)
// *
// * @param typeId 报告分类id
// * @param projectId 项目id集合
// * @param reportName 报告名称
// * @param startTime 开始时间
// * @param endTime 结束时间
// * @param pageNo 当前页
// * @param pageSize 返回条数
// * @author lkg
// * @date 2023/3/24
// */
// IPage<UserReportVO> userPageList(String typeId, String projectId, String reportName, String startTime, String endTime, Integer pageNo, Integer pageSize);
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.SubjectAnalysis;
/**
* @author lkg
* @description:
* @date 2022/7/14 17:17
*/
public interface SubjectAnalysisService extends IService<SubjectAnalysis> {
}
package com.zzsn.event.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.SubjectSearchEnginesMap;
import com.zzsn.event.mapper.SubjectSearchEnginesMapMapper;
import com.zzsn.event.vo.SearchEnginesVo;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description: 专题与搜索引擎关联表
* @Author: jeecg-boot
* @Date: 2022-06-21
* @Version: V1.0
*/
@Service
public class SubjectSearchEnginesMapServiceImpl extends ServiceImpl<SubjectSearchEnginesMapMapper, SubjectSearchEnginesMap> implements ISubjectSearchEnginesMapService {
@Override
public void deleteBySubjectId(String subjectId){
baseMapper.deleteBySubjectId(subjectId);
}
@Override
public List<SearchEnginesVo> bindSearchEngineList(SearchEnginesVo searchEnginesVo){
return baseMapper.bindSearchEngineList(searchEnginesVo);
}
@Override
public List<String> querySearchList(String subjectId){
return baseMapper.querySearchList(subjectId);
}
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.Event;
import com.zzsn.event.entity.Subject;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.service.*;
import com.zzsn.event.util.DateUtil;
import com.zzsn.event.vo.PropagationPathVo;
import com.zzsn.event.vo.SubjectDataVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author lkg
* @description:
* @date 2022/7/20 11:32
*/
@Service
public class AnalysisServiceImpl implements AnalysisService {
@Autowired
private SubjectAnalysisService subjectAnalysisService;
@Autowired
private IEventService eventService;
@Autowired
private EsService esService;
//
// @Override
// public Map<String, List<ViewPointAnalysisVo>> viewPointAnalysis(String subjectId) {
// Map<String, List<ViewPointAnalysisVo>> map = new HashMap<>();
// List<SubjectAnalysis> viewPointList = getList(subjectId, 1);
// if (CollectionUtils.isNotEmpty(viewPointList)) {
// Map<Integer, List<SubjectAnalysis>> collect = viewPointList.stream().collect(Collectors.groupingBy(SubjectAnalysis::getType));
// collect.forEach((type, value) -> {
// List<ViewPointAnalysisVo> list = new ArrayList<>();
// String name = ViewPointEnum.getNameByType(type);
// //求和
// int sum = value.stream().mapToInt(SubjectAnalysis::getRepeatNum).sum();
// value.forEach(e -> {
// ViewPointAnalysisVo vo = new ViewPointAnalysisVo();
// BeanUtils.copyProperties(e, vo);
// //计算百分比
// String divide = CalculateUtil.divide(String.valueOf(e.getRepeatNum()), String.valueOf(sum));
// if (StringUtils.isNotEmpty(divide)) {
// String percentage = CalculateUtil.percentage(Double.parseDouble(divide));
// vo.setPercentage(percentage);
// }
// list.add(vo);
// });
// map.put(name, list);
// });
// }
// return map;
// }
//
/*
* 优先级:事件脉络 > 伪事件脉络 > 资讯
* 1.若事件脉络资讯数量少于展示伪事件脉络的阈值(6),若有伪事件脉络就展示,若无则根据发布时间倒序后,默认取前15条资讯为事件脉络。
* 2.若事件脉络资讯数量少于展示伪事件脉络的阈值(6)但不为空;
* 2.1 若有伪事件脉络就展示,若无则展示事件脉络;
* 2.2 若有伪事件脉络就展示,若无则根据发布时间倒序后,默认取前15条资讯为事件脉络。
* 3.若事件脉络资讯数量大于/等于展示伪事件脉络的阈值(6),则直接展示
*
* 此种情况一般是专题资讯少或者刚建立的专题的事件专题,才会触发。
*/
@Override
public List<SubjectAnalysis> eventContext(String subjectId, int fakeNum) {
//专题下的事件脉络
List<SubjectAnalysis> list = getList(subjectId, 2);
if (list.size() < fakeNum) {
//专题下的伪事件脉络
List<SubjectAnalysis> fakeList = getList(subjectId, 3);
if (CollectionUtils.isEmpty(fakeList)) {
if (CollectionUtils.isEmpty(list)) {
List<SubjectAnalysis> finalList = new ArrayList<>();
List<SubjectDataVo> dataList = esService.getDataBySubjectId(subjectId, null, null, "0", Constants.FETCH_FIELDS_STATISTIC, 1, 1, 15);
dataList.forEach(e -> {
SubjectAnalysis subjectAnalysis = new SubjectAnalysis();
BeanUtils.copyProperties(e, subjectAnalysis);
subjectAnalysis.setPublishDate(DateUtil.stringToDate(e.getPublishDate(), "yyyy-MM-dd HH:mm:ss"));
List<SubjectDataVo> subjectDataVoList = esService.dataById(subjectId, e.getId());
subjectAnalysis.setRepeatNum(subjectDataVoList.size());
finalList.add(subjectAnalysis);
});
list = finalList;
}
} else {
list = fakeList;
}
}
return list;
}
@Override
public PropagationPathVo propagationPath(String subjectId) {
Event event = eventService.getById(subjectId);
String subjectName = event.getEventName();
List<PropagationPathVo> children = new ArrayList<>();
//获取专题数据
List<SubjectDataVo> specialDataList = getSubjectData(event, "0", Constants.FETCH_FIELDS_STATISTIC,1);
if (CollectionUtils.isNotEmpty(specialDataList)) {
//最早发布的时间
String publishDate = specialDataList.get(0).getPublishDate();
String earlyTime;
if (publishDate.length() > 10) {
earlyTime = DateUtil.formatStr(publishDate, "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
} else {
earlyTime = publishDate;
}
//获取最早发布的信息,若过多,取前一个
List<SubjectDataVo> earlyList = specialDataList.stream()
.filter(subjectDataVo -> {
String date = subjectDataVo.getPublishDate();
if (date.length() > 10) {
date = DateUtil.formatStr(date, "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
}
return earlyTime.equals(date);
})
.collect(Collectors.toList());
if (earlyList.size() > 1) {
earlyList = earlyList.subList(0, 1);
}
Map<SubjectDataVo, List<SubjectDataVo>> map = new HashMap<>();
//获取跟最早发布的信息的重复信息
earlyList.forEach(e -> {
List<SubjectDataVo> subjectDataVoList = esService.dataById(subjectId, e.getId());
if (CollectionUtils.isNotEmpty(subjectDataVoList)) {
map.put(e, subjectDataVoList);
}
});
//若最早发布的信息没有重复数据,则随机补充10个重复数最多的信息来源
// 本不该有的逻辑,奈何数据采集、处理 不给力
if (map.isEmpty()) {
for (SubjectDataVo subjectDataVo : earlyList) {
PropagationPathVo vo = new PropagationPathVo();
String topOrigin = subjectDataVo.getOrigin();
vo.setName(topOrigin);
//
vo.setChildren(pathByRepeat(topOrigin, event));
children.add(vo);
}
} else {//正常逻辑
Map<SubjectDataVo, LinkedHashMap<String, List<SubjectDataVo>>> dataMap = new HashMap<>();
for (Map.Entry<SubjectDataVo, List<SubjectDataVo>> entry : map.entrySet()) {
SubjectDataVo information = entry.getKey();
List<SubjectDataVo> value = entry.getValue();
//按来源分组
Map<String, List<SubjectDataVo>> originMap = value.stream().filter(e -> StringUtils.isNotEmpty(e.getOrigin()))
.collect(Collectors.groupingBy(SubjectDataVo::getOrigin));
//按统一来源信息数量 倒序 并截取前10
LinkedHashMap<String, List<SubjectDataVo>> orderMap = new LinkedHashMap<>();
originMap.entrySet().stream()
.sorted((o1, o2) -> o2.getValue().size() - o1.getValue().size()).limit(10)
.collect(Collectors.toList()).forEach(info -> orderMap.put(info.getKey(), info.getValue()));
dataMap.put(information, orderMap);
}
children = getPath(dataMap);
}
}
PropagationPathVo pathVo = null;
if (CollectionUtils.isNotEmpty(children)) {
pathVo = new PropagationPathVo();
pathVo.setName(subjectName);
pathVo.setChildren(children);
}
return pathVo;
}
//
// @Override
// public Map<String, Object> statisticAnalysis(String subjectId) {
// Map<String, Object> map = new HashMap<>();
// Subject subject = subjectService.getById(subjectId);
// //获取专题数据
// List<SubjectDataVo> specialDataList = getSubjectData(subject, "0", Constant.FETCH_FIELDS_STATISTIC,2);
// if (CollectionUtils.isNotEmpty(specialDataList)) {
// /*
// * 按信息源类型分组--infoSourceType
// * 因数据处理部分,未给信息源进行分类,故先按来源(origin)进行分组
// */
// Map<String, List<SubjectDataVo>> originMap = specialDataList.stream().filter(e -> StringUtils.isNotEmpty(e.getInfoSourceType()))
// .collect(Collectors.groupingBy(SubjectDataVo::getInfoSourceType));
// //获取信息分散在的日期
// Set<String> timeList = specialDataList.stream().collect(Collectors.groupingBy(e -> e.getPublishDate().substring(0, 10))).keySet();
// List<CountVo> countVoList = new ArrayList<>();
// Map<String, List<CountVo>> countMap = new HashMap<>();
// originMap.forEach((key, value) -> {
// //统计占比-饼状图
// CountVo countVo = new CountVo();
// String typeName = InfoSourceTypeEnum.getNameByCode(key);
// countVo.setName(typeName);
// countVo.setValue(value.size());
// countVoList.add(countVo);
// //数量统计-折线图
// List<CountVo> countVos = statisticCount(typeName, value, timeList);
// countMap.put(typeName, countVos);
// });
// if (CollectionUtils.isNotEmpty(countVoList)) {
// map.put("ratio", countVoList);
// map.put("count", countMap);
// }
// }
// return map;
// }
//
// @Override
// public List<StatisticAnalysisVo> statisticAnalysis(String subjectId, String startTime, String endTime) {
// List<SubjectDataVo> dataList = esService.getDataBySubjectId(subjectId, startTime, endTime, "0", Constant.FETCH_FIELDS_STATISTIC, 2, null, null);
// List<StatisticAnalysisVo> resultList = new ArrayList<>();
// if (CollectionUtils.isNotEmpty(dataList)) {
// /*
// * 按信息源类型分组--infoSourceType
// * 因数据处理部分,未给信息源进行分类,故先按来源(origin)进行分组
// */
// Map<String, List<SubjectDataVo>> originMap = dataList.stream().filter(e -> StringUtils.isNotEmpty(e.getInfoSourceType()))
// .collect(Collectors.groupingBy(SubjectDataVo::getInfoSourceType));
// //获取信息分散在的日期
// Set<String> timeList = dataList.stream().collect(Collectors.groupingBy(e -> e.getPublishDate().substring(0, 10))).keySet();
// originMap.forEach((key, value) -> {
// StatisticAnalysisVo statisticAnalysisVo = new StatisticAnalysisVo();
// statisticAnalysisVo.setName(InfoSourceTypeEnum.getNameByCode(key));
// statisticAnalysisVo.setNum(value.size());
// List<StatisticAnalysisVo> keyList = new ArrayList<>();
// //有数据的日期集合
// List<String> dateList = new ArrayList<>();
// value.stream().collect(Collectors.groupingBy(e -> e.getPublishDate().substring(0, 10))).forEach((time, data) -> {
// dateList.add(time);
// StatisticAnalysisVo vo = new StatisticAnalysisVo();
// vo.setKey(time);
// vo.setNum(data.size());
// vo.setName(DateUtil.formatStr(time, "yyyy-MM-dd", "yyyy-MM-dd 00:00:00"));
// keyList.add(vo);
// });
// //补充没有信息的日期 数据量为0
// List<String> list = new ArrayList<>(timeList);
// list.removeAll(dateList);
// list.forEach(time -> {
// StatisticAnalysisVo analysisVo = new StatisticAnalysisVo();
// analysisVo.setName(DateUtil.formatStr(time, "yyyy-MM-dd", "yyyy-MM-dd 00:00:00"));
// analysisVo.setKey(time);
// analysisVo.setNum(0);
// keyList.add(analysisVo);
// });
// List<StatisticAnalysisVo> collect = keyList.stream().sorted(Comparator.comparing(StatisticAnalysisVo::getKey)).collect(Collectors.toList());
// statisticAnalysisVo.setList(collect);
// resultList.add(statisticAnalysisVo);
// });
// }
// return resultList;
// }
//
private List<SubjectAnalysis> getList(String subjectId, Integer category) {
LambdaQueryWrapper<SubjectAnalysis> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(SubjectAnalysis::getSubjectId, subjectId).eq(SubjectAnalysis::getCategory, category).orderByAsc(SubjectAnalysis::getPublishDate);
return subjectAnalysisService.list(queryWrapper);
}
private List<SubjectDataVo> getSubjectData(Event event, String flag, String[] fetchFields, Integer sort) {
String startDate = null;
String endDate = null;
if (event.getStartTime() != null) {
startDate = DateUtil.dateToString(event.getStartTime(), "yyyy-MM-dd HH:mm:ss");
}
if (event.getEndTime() != null) {
endDate = DateUtil.dateToString(event.getEndTime(), "yyyy-MM-dd HH:mm:ss");
}
return esService.getDataBySubjectId(event.getId(), startDate, endDate, flag, fetchFields, sort, null, null);
}
private List<PropagationPathVo> getPath(Map<SubjectDataVo, LinkedHashMap<String, List<SubjectDataVo>>> dataMap) {
List<PropagationPathVo> list = new ArrayList<>();
for (Map.Entry<SubjectDataVo, LinkedHashMap<String, List<SubjectDataVo>>> entry : dataMap.entrySet()) {
PropagationPathVo pathVo = new PropagationPathVo();
SubjectDataVo information = entry.getKey();
pathVo.setName(information.getOrigin());
List<PropagationPathVo> children = new ArrayList<>();
Map<String, List<SubjectDataVo>> value = entry.getValue();
for (Map.Entry<String, List<SubjectDataVo>> entry1 : value.entrySet()) {
PropagationPathVo pathVo1 = new PropagationPathVo();
pathVo1.setName(entry1.getKey());
children.add(pathVo1);
}
pathVo.setChildren(children);
list.add(pathVo);
}
return list;
}
//
// private List<CountVo> statisticCount(String origin, List<SubjectDataVo> list, Set<String> timeList) {
// List<CountVo> countVoList = new ArrayList<>();
// List<String> dateList = new ArrayList<>();
// list.stream().collect(Collectors.groupingBy(e -> e.getPublishDate().substring(0, 10))).forEach((key, value) -> {
// dateList.add(key);
// CountVo countVo = new CountVo();
// countVo.setName(origin);
// countVo.setDate(key);
// countVo.setValue(value.size());
// countVoList.add(countVo);
// });
// //补充没有信息的 时间 数据量为0
// List<String> allTimeList = new ArrayList<>(timeList);
// allTimeList.removeAll(dateList);
// allTimeList.forEach(time -> {
// CountVo countVo = new CountVo();
// countVo.setName(origin);
// countVo.setDate(time);
// countVo.setValue(0);
// countVoList.add(countVo);
// });
// return countVoList;
// }
private List<PropagationPathVo> pathByRepeat(String topOrigin, Event event) {
List<PropagationPathVo> childrenList = new ArrayList<>();
TreeSet<String> topIdList = new TreeSet<>();
List<SubjectDataVo> specialDataList = getSubjectData(event, null, Constants.FETCH_FIELDS_STATISTIC,2);
Map<String, List<SubjectDataVo>> map = specialDataList.stream().filter(this::filterCondition)
.collect(Collectors.groupingBy(SubjectDataVo::getMasterEntryId));
map.entrySet().stream().sorted(((o1, o2) -> o2.getValue().size() - o1.getValue().size())).limit(10)
.collect(Collectors.toList()).forEach(info -> topIdList.add(info.getKey()));
if (CollectionUtils.isNotEmpty(topIdList)) {
TreeSet<String> originSet = new TreeSet<>();
for (String id : topIdList) {
SubjectDataVo subjectDataVo = esService.queryInfo(id);
String origin = subjectDataVo.getOrigin();
if (StringUtils.isNotEmpty(origin)) {
originSet.add(origin);
}
}
for (String origin : originSet) {
if (!origin.equals(topOrigin)) {
PropagationPathVo propagationPathVo = new PropagationPathVo();
propagationPathVo.setName(origin);
childrenList.add(propagationPathVo);
}
}
}
return childrenList;
}
private boolean filterCondition(SubjectDataVo subjectDataVo) {
boolean flag = false;
String masterEntryId = subjectDataVo.getMasterEntryId();
String origin = subjectDataVo.getOrigin();
if (StringUtils.isNotEmpty(masterEntryId) && StringUtils.isNotEmpty(origin)) {
flag = true;
}
return flag;
}
}
package com.zzsn.event.service.impl;
import cn.hutool.core.net.URLDecoder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.zzsn.event.service.EsDataSearchService;
import com.zzsn.event.util.EsDateUtil;
import com.zzsn.event.vo.SpecialInformationParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Description: 配置关联表
* @Author: jeecg-boot
* @Date: 2023-11-20
* @Version: V1.0
*/
@Slf4j
@Service
public class EsDataSearchServiceServiceImpl implements EsDataSearchService {
@Override
public SearchSourceBuilder packageSearQuery(SpecialInformationParam param) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置分页参数
searchSourceBuilder.size(param.getPageSize());
searchSourceBuilder.from((param.getPageNo() - 1) * param.getPageSize());
if (StringUtils.isNotEmpty(param.getSearchKey())) {
//包含检索关键词的时候按照相关度排序
param.setColumn("score");
}
if (param.getColumn().equals("score")) {
if (param.getOrder().equals("asc")) {
searchSourceBuilder.sort("_score", SortOrder.ASC);
searchSourceBuilder.sort("publishDate", SortOrder.ASC);
} else {
searchSourceBuilder.sort("_score", SortOrder.DESC);
searchSourceBuilder.sort("publishDate", SortOrder.DESC);
}
} else if (param.getColumn().equals("common")) {
if (param.getOrder().equals("asc")) {
searchSourceBuilder.sort("publishDate", SortOrder.ASC);
//第二排序依据为标题倒序
searchSourceBuilder.sort("title.keyword", SortOrder.ASC);
} else {
searchSourceBuilder.sort("publishDate", SortOrder.DESC);
//第二排序依据为标题倒序
searchSourceBuilder.sort("title.keyword", SortOrder.DESC);
}
} else if (param.getColumn().equals("topNum")) {
searchSourceBuilder.sort("topNum", SortOrder.DESC);
} else {
if (param.getOrder().equals("asc")) {
searchSourceBuilder.sort(param.getColumn(), SortOrder.ASC);
} else {
searchSourceBuilder.sort(param.getColumn(), SortOrder.DESC);
}
}
//默认最大数量是10000,设置为true后,显示准确数量
searchSourceBuilder.trackTotalHits(true);
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//指定分类标签
if (StringUtils.isNotEmpty(param.getLabelMarks())) {
String[] labelMarks = param.getLabelMarks().split(",");
BoolQueryBuilder boolQuery1 = QueryBuilders.boolQuery();
for (String labelMark : labelMarks) {
boolQuery1.should(QueryBuilders.matchPhraseQuery("labels.labelMark", labelMark));
}
NestedQueryBuilder nestedQueryBuilder = QueryBuilders
.nestedQuery("labels", boolQuery1, ScoreMode.None);
boolQuery.must(nestedQueryBuilder);
}
//封装条件中id为需要排除的数据id
if (StringUtils.isNotEmpty(param.getId())) {
boolQuery.mustNot(QueryBuilders.termQuery("id", param.getId()));
}
//检索关键词,与数据库配置关键词检索逻辑一致
if (StringUtils.isNotEmpty(param.getSearchKey())) {
BoolQueryBuilder builder4 = QueryBuilders.boolQuery();
for (String keyword : param.getSearchKey().split(" |\\+|,|,|;|;")) {
if (StringUtils.isEmpty(keyword)) {
continue;
}
BoolQueryBuilder builder3 = QueryBuilders.boolQuery();
builder3.should(QueryBuilders.matchQuery("title", keyword).boost(50.0f));
builder3.should(QueryBuilders.matchQuery("summary", keyword).boost(2.0f));
builder3.should(QueryBuilders.matchQuery("content", keyword).boost(1.0f));
if (keyword.startsWith("-")) {
builder4.mustNot(builder3);
} else {
builder4.must(builder3);
}
}
boolQuery.must(builder4);
}
//标签id
if (StringUtils.isNotEmpty(param.getSearchLabelIds())) {
BoolQueryBuilder builder1 = QueryBuilders.boolQuery();
for (String ids : param.getSearchLabelIds().split(";")) {
builder1.must(QueryBuilders.nestedQuery("labels", QueryBuilders.termsQuery("labels.relationId", ids.split(",")), ScoreMode.None));
}
boolQuery.must(builder1);
}
//排除的标签id
if (StringUtils.isNotEmpty(param.getExcludeLabelIds())) {
NestedQueryBuilder nestedQueryBuilder = QueryBuilders
.nestedQuery("labels", QueryBuilders.termsQuery("labels.relationId", param.getExcludeLabelIds().split(",")), ScoreMode.None);
boolQuery.mustNot(nestedQueryBuilder);
}
//专题id
if (StringUtils.isNotEmpty(param.getSubjectId())) {
boolQuery.must(QueryBuilders.termsQuery("subjectId", param.getSubjectId().split(",")));
}
if (StringUtils.isNotEmpty(param.getTitle())) {
boolQuery.must(QueryBuilders.matchPhraseQuery("title", param.getTitle()));
}
if (StringUtils.isNotEmpty(param.getSummary())) {
boolQuery.must(QueryBuilders.matchPhraseQuery("summary", param.getTitle()));
}
if (StringUtils.isNotEmpty(param.getContent())) {
boolQuery.must(QueryBuilders.matchPhraseQuery("content", param.getContent()));
}
if (StringUtils.isNotEmpty(param.getOrigin())) {
boolQuery.must(QueryBuilders.matchPhraseQuery("origin", param.getOrigin()));
}
if (StringUtils.isNotEmpty(param.getSourceAddress())) {
boolQuery.must(QueryBuilders.termQuery("sourceAddress.keyword", param.getSourceAddress()));
}
//数据状态
if (StringUtils.isNotEmpty(param.getFindStatus()) && !"ALL".equalsIgnoreCase(param.getFindStatus())) {
String[] findStatus = param.getFindStatus().split(",");
boolQuery.must(QueryBuilders.termsQuery("checkStatus", findStatus));
}
//发布状态
if (StringUtils.isNotEmpty(param.getFindPublishStatus()) && !"ALL".equalsIgnoreCase(param.getFindPublishStatus())) {
List<String> findPublishStatus = new ArrayList<>(Arrays.asList(param.getFindPublishStatus().split(",")));
if (findPublishStatus.contains("0")) {
//publishStatus为null的也属于待发布数据
BoolQueryBuilder builder2 = QueryBuilders.boolQuery();
builder2.should(QueryBuilders.termsQuery("publishStatus", findPublishStatus));
builder2.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("publishStatus")));
boolQuery.must(builder2);
} else {
boolQuery.must(QueryBuilders.termsQuery("publishStatus", findPublishStatus));
}
}
if (StringUtils.isNotEmpty(param.getInfoSourceNatureId())) {
boolQuery.must(QueryBuilders.termsQuery("infoSourceNatureId", param.getInfoSourceNatureId().split(",")));
}
//数据类型
if (StringUtils.isNotEmpty(param.getDataType())) {
List<String> dataTypes = new ArrayList<>(Arrays.asList(param.getDataType().split(",")));
if (dataTypes.contains("yqjc")) {
//包含舆情监测时,舆情预警、竞争情报、口碑监测均不生效
dataTypes.remove("yqyj");
dataTypes.remove("jzqb");
dataTypes.remove("kbjc");
}
BoolQueryBuilder builder11 = QueryBuilders.boolQuery();
for (String dataType : dataTypes) {
builder11.should(QueryBuilders.termQuery("dataType.keyword", dataType));
}
boolQuery.must(builder11);
}
//未删除状态查询
boolQuery.mustNot(QueryBuilders.matchQuery("deleteFlag", "1"));
//情报时间过滤筛选
if (StringUtils.isNotBlank(param.getStartTime())) {
boolQuery.filter(QueryBuilders.rangeQuery("publishDate").gte(EsDateUtil.esFieldDateFormat(param.getStartTime())));
}
if (StringUtils.isNotBlank(param.getEndTime())) {
boolQuery.filter(QueryBuilders.rangeQuery("publishDate").lte(EsDateUtil.esFieldDateFormat(param.getEndTime())));
}
//本系统发布时间过滤筛选
if (StringUtils.isNotBlank(param.getPublishStartTime())) {
boolQuery.filter(QueryBuilders.rangeQuery("updateDate").gte(EsDateUtil.esFieldDateFormat(param.getPublishStartTime())));
}
if (StringUtils.isNotBlank(param.getPublishEndTime())) {
boolQuery.filter(QueryBuilders.rangeQuery("updateDate").lte(EsDateUtil.esFieldDateFormat(param.getPublishEndTime())));
}
//高级查询数据处理
if (StringUtils.isNotEmpty(param.getSuperQueryParams())) {
try {
BoolQueryBuilder superBuilder = QueryBuilders.boolQuery();
String params = URLDecoder.decode(param.getSuperQueryParams(), Charsets.UTF_8);
JSONArray array = JSON.parseArray(params);
for (int i = 0; i < array.size(); i++) {
JSONObject item = array.getJSONObject(i);
BoolQueryBuilder builder2 = QueryBuilders.boolQuery();
String type = item.getString("type");
String rule = item.getString("rule");
String field = item.getString("field");
String val = item.getString("val");
if ("date".equals(type)) {
//日期类型处理
if ("eq".equals(rule)) {
builder2.must(QueryBuilders.rangeQuery(field).from(val + "T00:00:00").to(val + "T23:59:59"));
}
if ("ne".equals(rule)) {
builder2.mustNot(QueryBuilders.rangeQuery(field).from(val + "T00:00:00").to(val + "T23:59:59"));
} else if ("gt".equals(rule)) {
builder2.must(QueryBuilders.rangeQuery(field).from((val + "T23:59:59")));
} else if ("ge".equals(rule)) {
builder2.must(QueryBuilders.rangeQuery(field).from((val + "T00:00:00")));
} else if ("lt".equals(rule)) {
builder2.must(QueryBuilders.rangeQuery(field).to((val + "T00:00:00")));
} else if ("le".equals(rule)) {
builder2.must(QueryBuilders.rangeQuery(field).to((val + "T23:59:59")));
}
} else if ("list".equals(type)) {
//列表(数组)类查询
if ("eq".equals(rule)) {
builder2.must(QueryBuilders.termQuery(field + ".keyword", val));
} else if ("ne".equals(rule)) {
builder2.mustNot(QueryBuilders.termQuery(field + ".keyword", val));
} else if ("in".equals(rule)) {
builder2.must(QueryBuilders.termsQuery(field + ".keyword", val.split(" |\\+|,|,|;|;")));
} else if ("not_in".equals(rule)) {
builder2.mustNot(QueryBuilders.termsQuery(field + ".keyword", val.split(" |\\+|,|,|;|;")));
}
} else if ("string".equals(type)) {
//文本类查询
if ("eq".equals(rule)) {
builder2.must(QueryBuilders.termQuery(field + ".keyword", val));
} else if ("ne".equals(rule)) {
builder2.mustNot(QueryBuilders.termQuery(field + ".keyword", val));
} else if ("in".equals(rule)) {
builder2.must(QueryBuilders.termsQuery(field + ".keyword", val.split(" |\\+|,|,|;|;")));
} else if ("not_in".equals(rule)) {
builder2.mustNot(QueryBuilders.termsQuery(field + ".keyword", val.split(" |\\+|,|,|;|;")));
} else if ("like".equals(rule)) {
builder2.must(QueryBuilders.matchPhraseQuery(field, val));
} else if ("not_like".equals(rule)) {
builder2.mustNot(QueryBuilders.matchPhraseQuery(field, val));
}
}
if ("or".equals(param.getSuperQueryMatchType())) {
superBuilder.should(builder2);
} else {
superBuilder.must(builder2);
}
}
boolQuery.must(superBuilder);
} catch (Exception e) {
log.error("高级查询条件封装失败,e:{},params:{}", e.getMessage(), param.getSuperQueryParams());
}
}
if (param.getHasImg() != null && param.getHasImg() == 1) {
//包含 img 并且包含 src 的认为包含
boolQuery.must(QueryBuilders.matchPhraseQuery("contentWithTag", "img"));
boolQuery.must(QueryBuilders.matchPhraseQuery("contentWithTag", "src"));
}
searchSourceBuilder.query(boolQuery);
String[] include = null;
String[] exclude = null;
if (null!=param.sourceInclude) {
include = param.sourceInclude.split(",");
}
//设置排除字段
if (null!=param.sourceExclude) {
exclude = param.sourceExclude.split(",");
}
//查询指定字段
searchSourceBuilder.fetchSource(include, exclude);
return searchSourceBuilder;
}
}
package com.zzsn.event.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.LabelEntity;
import com.zzsn.event.enums.InfluenceEnum;
import com.zzsn.event.enums.SourceEnum;
import com.zzsn.event.service.EsDataSearchService;
import com.zzsn.event.service.EsStatisticsService;
import com.zzsn.event.service.LabelEntityService;
import com.zzsn.event.util.CalculateUtil;
import com.zzsn.event.vo.CountVO;
import com.zzsn.event.vo.NegativeDataVO;
import com.zzsn.event.vo.SpecialInformationParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.ParsedDateHistogram;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 舆情信息统计 es查询工具类
*
* @author lkg
* @date 2024/1/19
*/
@Service
public class EsStatisticsServiceImpl implements EsStatisticsService {
@Resource
private RestHighLevelClient client;
@Autowired
private LabelEntityService labelEntityService;
@Autowired
private EsDataSearchService dataSearchService;
@Override
public CountVO total(String startTime, String endTime, Integer type) {
CountVO countVO = new CountVO();
countVO.setName("舆情信息");
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(null, null, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
DateHistogramAggregationBuilder aggregation = AggregationBuilders.dateHistogram("group_day")
.field("publishDate");
if (type == 1) {
aggregation.calendarInterval(DateHistogramInterval.HOUR).format("yyyy-MM-dd HH");
} else if (type == 2) {
aggregation.calendarInterval(DateHistogramInterval.DAY).format("yyyy-MM-dd");
}
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long value = response.getHits().getTotalHits().value;
countVO.setValue(value);
List<CountVO> list = new ArrayList<>();
Aggregations aggregations = response.getAggregations();
ParsedDateHistogram groupHour = aggregations.get("group_day");
List<? extends Histogram.Bucket> buckets = groupHour.getBuckets();
if (CollectionUtils.isNotEmpty(buckets)) {
for (Histogram.Bucket bucket : buckets) {
CountVO vo = new CountVO();
vo.setName(bucket.getKeyAsString());
vo.setValue(bucket.getDocCount());
list.add(vo);
}
}
countVO.setChildren(list);
} catch (Exception e) {
e.printStackTrace();
}
return countVO;
}
@Override
public Map<String, Object> totalAndMax(String subjectId, String startTime, String endTime) {
Map<String, Object> map = new HashMap<>();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
DateHistogramAggregationBuilder aggregation = AggregationBuilders.dateHistogram("group_hour")
.field("publishDate")
.calendarInterval(DateHistogramInterval.HOUR)
.format("yyyy-MM-dd HH")
.order(BucketOrder.count(false));
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long value = response.getHits().getTotalHits().value;
map.put("totalCount", value);
Aggregations aggregations = response.getAggregations();
ParsedDateHistogram groupHour = aggregations.get("group_hour");
List<? extends Histogram.Bucket> buckets = groupHour.getBuckets();
if (CollectionUtils.isNotEmpty(buckets)) {
Histogram.Bucket bucket = buckets.get(0);
long count = bucket.getDocCount();
map.put("max", count);
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
@Override
public Map<String, Object> findOne(String subjectId, String labelId, int type, String startTime, String endTime) {
Map<String, Object> map = new HashMap<>();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, labelId, startTime, endTime, type);
searchSourceBuilder.size(1);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
if (hits.length > 0) {
SearchHit hit = hits[0];
map = hit.getSourceAsMap();
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
@Override
public CountVO orientation(String subjectId, String labelId, String startTime, String endTime, Integer type) {
CountVO countVO = new CountVO();
LabelEntity labelEntity = labelEntityService.getById(labelId);
countVO.setName(labelEntity.getName());
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, labelId, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
DateHistogramAggregationBuilder aggregation = AggregationBuilders.dateHistogram("group_day")
.field("publishDate");
if (type == 1) {
aggregation.calendarInterval(DateHistogramInterval.HOUR).format("yyyy-MM-dd HH");
} else if (type == 2) {
aggregation.calendarInterval(DateHistogramInterval.DAY).format("yyyy-MM-dd");
}
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long value = response.getHits().getTotalHits().value;
countVO.setValue(value);
List<CountVO> list = new ArrayList<>();
Aggregations aggregations = response.getAggregations();
ParsedDateHistogram groupHour = aggregations.get("group_day");
List<? extends Histogram.Bucket> buckets = groupHour.getBuckets();
if (CollectionUtils.isNotEmpty(buckets)) {
for (Histogram.Bucket bucket : buckets) {
CountVO vo = new CountVO();
vo.setName(bucket.getKeyAsString());
vo.setValue(bucket.getDocCount());
list.add(vo);
}
}
countVO.setChildren(list);
} catch (Exception e) {
e.printStackTrace();
}
return countVO;
}
@Override
public List<CountVO> source(String subjectId, String startTime, String endTime, Integer type) {
List<CountVO> list = new ArrayList<>();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
DateHistogramAggregationBuilder dateAgg = AggregationBuilders.dateHistogram("group_day").field("publishDate");
if (type == 1) {
dateAgg.calendarInterval(DateHistogramInterval.HOUR).format("yyyy-MM-dd HH");
} else if (type == 2) {
dateAgg.calendarInterval(DateHistogramInterval.DAY).format("yyyy-MM-dd");
}
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_source")
.field("infoSourceTypeId.keyword")
.size(SourceEnum.values().length)
.subAggregation(dateAgg);
searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long value = response.getHits().getTotalHits().value;
Aggregations aggregations = response.getAggregations();
Terms groupSource = aggregations.get("group_source");
List<? extends Terms.Bucket> sourceBuckets = groupSource.getBuckets();
for (Terms.Bucket source : sourceBuckets) {
CountVO countVO = new CountVO();
String keyAsString = source.getKeyAsString();
countVO.setName(SourceEnum.getDescription(keyAsString));
long count = source.getDocCount();
countVO.setValue(count);
String percentage = getPercentage(count, value);
countVO.setPercentage(percentage);
List<CountVO> children = new ArrayList<>();
Aggregations sourceAggregations = source.getAggregations();
ParsedDateHistogram groupDay = sourceAggregations.get("group_day");
List<? extends Histogram.Bucket> dayBuckets = groupDay.getBuckets();
for (Histogram.Bucket day : dayBuckets) {
CountVO vo = new CountVO();
vo.setName(day.getKeyAsString());
vo.setValue(day.getDocCount());
children.add(vo);
}
countVO.setChildren(children);
list.add(countVO);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
// @Override
// public List<CountVO> region(String subjectId, String startTime, String endTime) {
// List<SysBaseDomesticRegion> regionList = provinceList();
// List<CountVO> list = new ArrayList<>();
// SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
// SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null, user);
// searchSourceBuilder.size(0);
// searchSourceBuilder.trackTotalHits(true);
// NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("labels", "labels")
// .subAggregation(AggregationBuilders.terms("group_type")
// .field("labels.labelMark.keyword")
// .subAggregation(AggregationBuilders.terms("group_code")
// .field("labels.relationId")
// .order(BucketOrder.count(false))
// .size(regionList.size())));
// searchSourceBuilder.aggregation(nestedAggregationBuilder);
// searchRequest.source(searchSourceBuilder);
// try {
// SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// //获取分组桶
// Aggregations aggregations = searchResponse.getAggregations();
// ParsedNested labels = aggregations.get("labels");
// Aggregations labelsAggregations = labels.getAggregations();
// //获取按企业信用代码分组集合
// Terms groupType = labelsAggregations.get("group_type");
// List<? extends Terms.Bucket> typeBuckets = groupType.getBuckets();
// Map<String, Long> regionMap = new HashMap<>();
// for (Terms.Bucket type : typeBuckets) {
// String key = type.getKeyAsString();
// if ("region_out".equals(key)) {
// Aggregations codeAggregations = type.getAggregations();
// Terms groupCode = codeAggregations.get("group_code");
// List<? extends Terms.Bucket> codeBuckets = groupCode.getBuckets();
// for (Terms.Bucket code : codeBuckets) {
// regionMap.put(code.getKeyAsString(), code.getDocCount());
// }
// break;
// }
// }
// for (SysBaseDomesticRegion region : regionList) {
// CountVO countVO = new CountVO();
// String id = region.getId();
// String name = region.getName();
// countVO.setName(name);
// if (regionMap.containsKey(id)) {
// Long count = regionMap.get(id);
// countVO.setValue(count);
// } else {
// countVO.setValue(0L);
// }
// list.add(countVO);
// }
// list.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));
// for (int i = 0; i < list.size(); i++) {
// CountVO countVO = list.get(i);
// countVO.setOrder(i + 1);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// return list;
// }
@Override
public List<CountVO> influence(String subjectId, String startTime, String endTime) {
List<CountVO> list = new ArrayList<>();
InfluenceEnum[] influenceEnums = InfluenceEnum.values();
for (InfluenceEnum influenceEnum : influenceEnums) {
String field = influenceEnum.getField();
String description = influenceEnum.getDescription();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("sum_count").field(field);
searchSourceBuilder.aggregation(sumAggregationBuilder);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
Sum sumCount = aggregations.get("sum_count");
double value = sumCount.getValue();
CountVO countVO = new CountVO();
countVO.setName(description);
countVO.setValue((long) value);
list.add(countVO);
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
//
// @Override
// public List<MediaVO> media(String subjectId, String startTime, String endTime) {
// List<MediaVO> list = new ArrayList<>();
// SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
// SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null, user);
// searchSourceBuilder.size(0);
// searchSourceBuilder.trackTotalHits(true);
// TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_nature")
// .field("infoSourceNatureId.keyword")
// .subAggregation(AggregationBuilders.terms("group_sid")
// .field("sid.keyword")
// .order(BucketOrder.count(false))
// .size(3))
// .subAggregation(AggregationBuilders.cardinality("sid_count").field("sid.keyword"));
// searchSourceBuilder.aggregation(aggregationBuilder);
// searchRequest.source(searchSourceBuilder);
// try {
// SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// long totalCount = response.getHits().getTotalHits().value;
// Aggregations aggregations = response.getAggregations();
// Terms groupNature = aggregations.get("group_nature");
// List<? extends Terms.Bucket> natureBuckets = groupNature.getBuckets();
// for (Terms.Bucket nature : natureBuckets) {
// MediaVO vo = new MediaVO();
// String natureName = infoSourceService.getNatureName(nature.getKeyAsString());
// vo.setName(natureName);
// long count = nature.getDocCount();
// vo.setValue(count);
// String percentage = getPercentage(count, totalCount);
// vo.setPercentage(percentage);
// List<String> hotList = new ArrayList<>();
// Aggregations natureAggregations = nature.getAggregations();
// Terms groupSid = natureAggregations.get("group_sid");
// List<? extends Terms.Bucket> sidBuckets = groupSid.getBuckets();
// for (Terms.Bucket sid : sidBuckets) {
// String key = sid.getKeyAsString();
// hotList.add(key);
// }
// List<String> nameList = infoSourceService.infoNameList(hotList);
// vo.setHotList(nameList);
// Cardinality sidCount = natureAggregations.get("sid_count");
// long value = sidCount.getValue();
// vo.setMediaNum(value);
// list.add(vo);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// return list;
// }
@Override
public List<CountVO> origin(String subjectId, String startTime, String endTime) {
List<CountVO> list = new ArrayList<>();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(subjectId, null, startTime, endTime, null);
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_origin")
.field("origin.keyword")
.order(BucketOrder.count(false))
.size(10);
searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long value = response.getHits().getTotalHits().value;
Aggregations aggregations = response.getAggregations();
Terms groupSource = aggregations.get("group_origin");
List<? extends Terms.Bucket> buckets = groupSource.getBuckets();
if (CollectionUtils.isNotEmpty(buckets)) {
for (int i = 0; i < buckets.size(); i++) {
Terms.Bucket bucket = buckets.get(i);
CountVO vo = new CountVO();
vo.setOrder(i + 1);
vo.setName(bucket.getKeyAsString());
long count = bucket.getDocCount();
vo.setValue(count);
String percentage = getPercentage(count, value);
vo.setPercentage(percentage);
list.add(vo);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
@Override
public String mainReport(String subjectId) {
String title = null;
String mark = getMark(subjectId);
SearchRequest searchRequest = new SearchRequest(Constants.ES_REPEAT_OLD);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("subjectId", subjectId));
if (StringUtils.isNotEmpty(mark)) {
boolQuery.must(QueryBuilders.termQuery("repeatMark", mark));
}
boolQuery.must(QueryBuilders.termQuery("saveType", 1));
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
SearchHit hit = hits[0];
title = hit.getSourceAsMap().get("title").toString();
} catch (Exception e) {
e.printStackTrace();
}
return title;
}
@Override
public Page<NegativeDataVO> labelPageList(String labelId, String startTime, String endTime, Integer pageNo, Integer pageSize) {
Page<NegativeDataVO> page = new Page<>();
SearchRequest searchRequest = new SearchRequest(Constants.ES_DATA_FOR_SUBJECT);
SearchSourceBuilder searchSourceBuilder = formatSourceBuilder(null, labelId, startTime, endTime, null);
int offset = (pageNo - 1) * pageSize;
searchSourceBuilder.from(offset);
searchSourceBuilder.size(pageSize);
searchSourceBuilder.trackTotalHits(true);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
long count = response.getHits().getTotalHits().value;
SearchHit[] hits = response.getHits().getHits();
List<NegativeDataVO> list = new ArrayList<>();
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
NegativeDataVO negativeDataVO = JSON.parseObject(sourceAsString, NegativeDataVO.class);
list.add(negativeDataVO);
}
page = new Page<>(pageNo, pageSize, count);
page.setRecords(list);
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
private String getMark(String subjectId) {
String mark = null;
SearchRequest searchRequest = new SearchRequest(Constants.ES_REPEAT_OLD);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("subjectId", subjectId));
searchSourceBuilder.size(0);
searchSourceBuilder.trackTotalHits(true);
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_mark")
.field("repeatMark")
.order(BucketOrder.count(false))
.size(1);
searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
Terms groupSource = aggregations.get("group_mark");
List<? extends Terms.Bucket> buckets = groupSource.getBuckets();
if (CollectionUtils.isNotEmpty(buckets)) {
Terms.Bucket bucket = buckets.get(0);
mark = bucket.getKeyAsString();
}
} catch (Exception e) {
e.printStackTrace();
}
return mark;
}
/**
* 构造查询条件
*
* @param subjectId 专题id
* @param relationId 关联id(可以是标签id,企业信用代码等)
* @param startTime 开始时间
* @param endTime 结束时间
* @param type 1-正序;2-倒序
* @author lkg
* @date 2024/1/23
*/
private SearchSourceBuilder formatSourceBuilder(String subjectId, String relationId, String startTime, String endTime, Integer type) {
SpecialInformationParam param = new SpecialInformationParam();
if (StringUtils.isNotEmpty(subjectId)) {
param.setSubjectId(subjectId);
} else {
param.setDataType("yqjc");
}
if (StringUtils.isNotEmpty(relationId)) {
param.setSearchLabelIds(relationId);
}
if (StringUtils.isNotBlank(startTime)) {
param.setStartTime(startTime);
}
if (StringUtils.isNotBlank(endTime)) {
param.setEndTime(endTime);
}
param.setColumn("publishDate");
if (type != null) {
if (type == 1) {
param.setOrder("asc");
} else if (type == 2){
param.setOrder("desc");
}
} else {
param.setOrder("desc");
}
return dataSearchService.packageSearQuery(param);
}
// /**
// * 获取一级地域信息
// *
// * @author lkg
// * @date 2024/1/24
// */
// private List<SysBaseDomesticRegion> provinceList() {
// LambdaQueryWrapper<SysBaseDomesticRegion> queryWrapper = Wrappers.lambdaQuery();
// queryWrapper.select(SysBaseDomesticRegion::getId, SysBaseDomesticRegion::getName, SysBaseDomesticRegion::getLevel);
// queryWrapper.eq(SysBaseDomesticRegion::getLevel, 1);
// return domesticRegionService.list(queryWrapper);
// }
/**
* 获取占比
*
* @param count 数量
* @param totalCount 总数量
* @author lkg
* @date 2024/1/25
*/
private String getPercentage(long count, long totalCount) {
String divide = CalculateUtil.divide(String.valueOf(count), String.valueOf(totalCount));
String percentage = "0%";
if (StringUtils.isNotEmpty(divide)) {
percentage = CalculateUtil.percentage(Double.parseDouble(divide), false);
}
return percentage;
}
}
package com.zzsn.event.service.impl; package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.Event; import com.zzsn.event.entity.Event;
import com.zzsn.event.enums.CodePrefixEnum;
import com.zzsn.event.mapper.EventMapper; import com.zzsn.event.mapper.EventMapper;
import com.zzsn.event.producer.ProduceInfo;
import com.zzsn.event.service.IEventService; import com.zzsn.event.service.IEventService;
import com.zzsn.event.service.IKeyWordsService;
import com.zzsn.event.service.ISubjectKeywordsMapService;
import com.zzsn.event.service.ISubjectSearchEnginesMapService;
import com.zzsn.event.util.CodeGenerateUtil;
import com.zzsn.event.util.CronUtil;
import com.zzsn.event.util.HttpUtil;
import com.zzsn.event.util.RedisUtil;
import com.zzsn.event.vo.AddEventParam;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.vo.KeyWordsPage;
import com.zzsn.event.vo.SubjectKafkaVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.StringUtils;
import java.util.List; import java.util.*;
/** /**
* @Description: 事件 * @Description: 事件
* @Author: jeecg-boot * @Author: jeecg-boot
* @Date: 2024-03-14 * @Date: 2024-03-14
* @Version: V1.0 * @Version: V1.0
*/ */
@Service @Service
public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements IEventService { public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements IEventService {
@Value("${hotWords.extractUrl}")
private String extractHotWordsUrl;
@Autowired
private CodeGenerateUtil codeGenerateUtil;
@Autowired
private IKeyWordsService iKeyWordsService;
@Autowired
private ISubjectSearchEnginesMapService iSubjectSearchEnginesMapService;
@Autowired
private ISubjectKeywordsMapService iSubjectKeywordsMapService;
@Autowired
private ProduceInfo produceInfo;
@Autowired
private RedisUtil redisUtil;
@Override @Override
public void compute() { public void compute() {
//get the events need to compute //get the events need to compute
List<Event> list = this.list(new LambdaQueryWrapper<Event>().eq(Event::getStatus, 1)); List<Event> list = this.list(new LambdaQueryWrapper<Event>().eq(Event::getStatus, 1));
for (Event event : list) { for (Event event : list) {
// latest week data // latest week data
...@@ -31,4 +67,113 @@ public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements ...@@ -31,4 +67,113 @@ public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements
// data before a year // data before a year
} }
} }
@Override
public List<SubjectKafkaVo> progressList(Date disableDate) {
return this.baseMapper.prosessList(disableDate);
}
@Override
public List<SubjectKafkaVo> eventSubjectList() {
return this.baseMapper.eventSubjectList(2);
}
@Override
public IPage<Event> pageList(Event event, Integer pageNo, Integer pageSize) {
Integer offset = (pageNo - 1) * pageSize;
if (pageNo == 0) {
offset = 0;
}
List<Event> pageList = baseMapper.pageList(event, offset, pageSize);
//获取总条数
Integer count = baseMapper.totalCount(event);
IPage<Event> pageData = new Page<>(pageNo, pageSize, count);
pageData.setRecords(pageList);
return null;
}
@Override
public void extractHotWords(AddEventParam event) {
if (!StringUtils.isEmpty(event.getExtractHotWords()) && "1".equals(event.getExtractHotWords())) {
Map<String, String> param = new HashMap<>();
param.put("status", "0,1,2,3");
param.put("timeFiled", "ALL");
param.put("subjectId", event.getId());
HttpUtil.doGet(extractHotWordsUrl, param, "utf-8");
}
}
@Override
public Event saveMain(AddEventParam addEventParam) {
String cron = null;
Event event = new Event();
//事件专题的默认分析规则参数-必填
BeanUtils.copyProperties(addEventParam, event);
event.setIncreAnaRule(20);
event.setTotalAnaRule(50);
event.setTimeAnaRule(5);
String subjectCode = codeGenerateUtil.geneCodeNo(CodePrefixEnum.SUBJECT_DEFAULT.getValue());
event.setEventCode(subjectCode);
cron = CronUtil.getRandomCron();
event.setCron(cron);
baseMapper.insert(event);
return event;
}
@Override
public void updateMain(AddEventParam addEventParam) {
Event subject = new Event();
BeanUtils.copyProperties(addEventParam, subject);
//先记录老的信息状态
Event oldSubject = baseMapper.selectById(subject.getId());
baseMapper.updateById(subject);
//判断开始时间和结束时间是否发生变动
if ((StringUtils.isEmpty(addEventParam.getStartTime()) && StringUtils.isEmpty(oldSubject.getStartTime())) ||
(!StringUtils.isEmpty(addEventParam.getStartTime()) && !StringUtils.isEmpty(oldSubject.getStartTime())
&& oldSubject.getStartTime().compareTo(addEventParam.getStartTime()) == 0)) {
} else {
//查询出该专题绑定的关键词组
List<KeyWordsPage> keyWordsPages = bindKeyWordsList(subject.getId());
List<String> keyWordIds = new ArrayList<>();
for (KeyWordsPage keyWordsPage : keyWordsPages) {
keyWordIds.add(keyWordsPage.getId());
}
//更新redis中关键词时间
updateRedisKeyWordsDate(addEventParam.getId(), keyWordIds);
}
}
@Override
public List<KeyWordsPage> bindKeyWordsList(String subjectId) {
return iKeyWordsService.bindKeyWordsList(subjectId);
}
//更新专题绑定的关键词组的缓存信息
private void updateRedisKeyWordsDate(String subjectId, List<String> keyWordsIds) {
for (String keyWordsId : keyWordsIds) {
KeyWordsDTO keyWordsDTO = iSubjectKeywordsMapService.selectMinByKeyWordsId(keyWordsId);
KeyWordsDTO redisKeyWordsDTO = (KeyWordsDTO) redisUtil.get(Constants.KEY_WORDS_TO_REDIS_PREFIX + keyWordsDTO.getWordsCode());
int count = iSubjectKeywordsMapService.selectCountByKeyWordsId(keyWordsId);
KeyWordsDTO keyWordsDTO1;
if (count <= 0) {
keyWordsDTO1 = iSubjectKeywordsMapService.selectMaxByKeyWordsId(keyWordsId);
redisKeyWordsDTO.setStartTime(keyWordsDTO.getStartTime());
redisKeyWordsDTO.setEndTime(keyWordsDTO1.getEndTime());
} else {
if (redisKeyWordsDTO == null) {
redisKeyWordsDTO = keyWordsDTO;
} else {
redisKeyWordsDTO.setEndTime(null);
redisKeyWordsDTO.setStartTime(keyWordsDTO.getStartTime());
}
}
//查询出该专题绑定了哪些搜索引擎
List<String> stringList = iSubjectSearchEnginesMapService.querySearchList(subjectId);
redisKeyWordsDTO.setSearchEngines(stringList);
redisUtil.set(Constants.KEY_WORDS_TO_REDIS_PREFIX + redisKeyWordsDTO.getWordsCode(), redisKeyWordsDTO);
//立即执行一次
produceInfo.sendKeyWordsInfoSourceMsg(redisKeyWordsDTO);
}
}
} }
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.mapper.KeyWordsMapper;
import com.zzsn.event.service.IKeyWordsService;
import com.zzsn.event.vo.KeyWordsPage;
import com.zzsn.event.xxljob.entity.KeyWords;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description: 关键词管理
* @Author: jeecg-boot
* @Date: 2021-11-26
* @Version: V1.0
*/
@Service
public class KeyWordsServiceImpl extends ServiceImpl<KeyWordsMapper, KeyWords> implements IKeyWordsService {
@Override
public List<KeyWordsPage> bindKeyWordsList(String subjectId) {
return baseMapper.selectKeyWordsListById(subjectId);
}
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.LabelEntity;
import com.zzsn.event.mapper.LabelEntityMapper;
import com.zzsn.event.service.LabelEntityService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author lkg
* @date 2023/3/2
*/
@Service
public class LabelEntityServiceImpl extends ServiceImpl<LabelEntityMapper, LabelEntity> implements LabelEntityService {
@Override
public List<LabelEntity> listByType(String labelTypeId) {
return baseMapper.listByType(labelTypeId);
}
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.Report;
import com.zzsn.event.mapper.ReportMapper;
import com.zzsn.event.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 报告表
*
* @author lkg
* @date 2023/3/23
*/
@Service
@Slf4j
public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements ReportService {
// @Autowired
// private ReportBusinessTypeService reportBusinessTypeService;
// @Autowired
// private IProjectService projectService;
// @Autowired
// private ISubjectService subjectService;
//
// @Override
// public IPage<ReportVO> pageList(String typeId, Integer pageNo, Integer pageSize) {
// int offset = (pageNo - 1) * pageSize;
// List<ReportVO> pageList = baseMapper.pageList(typeId, offset, pageSize);
// Integer count = baseMapper.count(typeId);
// Page<ReportVO> page = new Page<>(pageNo, pageSize, count);
// page.setRecords(pageList);
// return page;
// }
//
// @Override
// public IPage<UserReportVO> userPageList(String typeId, String projectId, String reportName, String startTime, String endTime, Integer pageNo, Integer pageSize) {
// int offset = (pageNo - 1) * pageSize;
// List<String> typeIds = new ArrayList<>();
// List<String> projectIds = new ArrayList<>();
// if (StringUtils.isEmpty(projectId) && StringUtils.isEmpty(typeId)) {
// //获取当前登录用户
// LoginUser currentUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// Integer category = currentUser.getCategory();
// if (!category.equals(CommonConstant.SUPER_USER)) {
// String userId = null;
// String customerId = null;
// if (category.equals(CommonConstant.ADMIN_USER)) {
// customerId = currentUser.getRelTenantIds();
// } else if (category.equals(CommonConstant.COMMON_USER)) {
// userId = currentUser.getId();
// }
// List<ProjectVO> projectVOS = projectService.permissionList(customerId, userId);
// projectVOS.forEach(e->projectIds.add(e.getId()));
// }
// } else {
// if (StringUtils.isNotEmpty(typeId)) {
// typeIds = reportBusinessTypeService.getBelowList(typeId);
// }
// if (StringUtils.isNotEmpty(projectId)) {
// projectIds.add(projectId);
// }
// }
// List<UserReportVO> pageList = baseMapper.userPageList(typeIds, projectIds,reportName, startTime, endTime, offset, pageSize);
// for (UserReportVO reportVO : pageList) {
// String subjectId = reportVO.getSubjectId();
// String subjectName = getSubject(subjectId);
// reportVO.setSubjectName(subjectName);
// }
// Integer count = baseMapper.total(typeIds, projectIds,reportName, startTime, endTime);
// Page<UserReportVO> page = new Page<>(pageNo, pageSize, count);
// page.setRecords(pageList);
// return page;
// }
// private String getSubject(String subjectId) {
// String subjectName = null;
// if (StringUtils.isNotEmpty(subjectId)) {
// StringBuilder stringBuilder = new StringBuilder();
// String[] split = subjectId.split(",");
// LambdaQueryWrapper<Subject> query = Wrappers.lambdaQuery();
// query.in(Subject::getId, Arrays.asList(split));
// List<Subject> list = subjectService.list(query);
// list.forEach(e -> stringBuilder.append(",").append(e.getSubjectName()));
// subjectName = stringBuilder.length() == 0 ? null : stringBuilder.substring(1);
// }
// return subjectName;
// }
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.mapper.SubjectAnalysisMapper;
import com.zzsn.event.service.SubjectAnalysisService;
import org.springframework.stereotype.Service;
/**
* @author lkg
* @description:
* @date 2022/7/14 17:17
*/
@Service
public class SubjectAnalysisServiceImpl extends ServiceImpl<SubjectAnalysisMapper, SubjectAnalysis> implements SubjectAnalysisService {
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.mapper.SubjectKeywordsMapMapper;
import com.zzsn.event.service.ISubjectKeywordsMapService;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.vo.SubjectKeywordsMap;
import org.springframework.stereotype.Service;
/**
* @Description: 专题关键词关联表
* @Author: jeecg-boot
* @Date: 2021-12-09
* @Version: V1.0
*/
@Service
public class SubjectKeywordsMapServiceImpl extends ServiceImpl<SubjectKeywordsMapMapper, SubjectKeywordsMap> implements ISubjectKeywordsMapService {
@Override
public KeyWordsDTO selectMinByKeyWordsId(String keyWordsId){
return baseMapper.selectMinByKeyWordsId(keyWordsId);
}
@Override
public int selectCountByKeyWordsId(String keyWordsId){
return baseMapper.selectCountByKeyWordsId(keyWordsId);
}
@Override
public KeyWordsDTO selectMaxByKeyWordsId(String keyWordsId){
return baseMapper.selectMaxByKeyWordsId(keyWordsId);
}
}
package com.zzsn.event.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.Subject;
import com.zzsn.event.mapper.SubjectMapper;
import com.zzsn.event.service.ISubjectService;
import org.springframework.stereotype.Service;
/**
* @author : wp
* @title : subjectServiceImpl
* @description: 专题实现类
* @date : Created in 2022/7/7 10:23
* @modified By:
*/
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements ISubjectService {
// @Autowired
// private IKeyWordsService keyWordsService;
// @Autowired
// private EsService esService;
//
// @Override
// public List<Subject> searchSubjectList(String userId, String title) {
// return baseMapper.searchSubjectList(userId, 2,title);
// }
//
// public IPage<SubjectDataVo> queryInfoListBySid(SubjectVo subjectInfo, Integer pageNo, Integer pageSize) {
// IPage<SubjectDataVo> pageData;
// String keyWords = keyWordsService.getBySubjectId(subjectInfo.getId());
// if (StringUtils.isNotEmpty(keyWords)) {
// String keywords = keyWords.replaceAll("\\(","").replaceAll("\\)","")
// .replaceAll("\\+",";").replaceAll("\\|",";");
// pageData = esService.pageList(subjectInfo.getId(), subjectInfo.getTitle(), keywords, subjectInfo.getStartTime(), subjectInfo.getEndTime(), pageNo, pageSize);
// List<SubjectDataVo> records = pageData.getRecords();
// for (SubjectDataVo dataVo :records) {
// String title = dataVo.getTitle();
// String[] keyWordArr = keywords.split(";");
// for (String keyWord :keyWordArr) {
// if (title.contains(keyWord)) {
// title = title.replaceAll(keyWord,"<font style=\"color:red;\">"+keyWord+"</font>");
// }
// }
// dataVo.setTitle(title);
// }
// } else {
// pageData = esService.pageList(subjectInfo.getId(), subjectInfo.getTitle(), null, subjectInfo.getStartTime(), subjectInfo.getEndTime(), pageNo, pageSize);
// }
// return pageData;
// }
//
// @Override
// public List<SubjectKafkaVo> progressList(Date endDate) {
// return baseMapper.progressList(2,endDate);
// }
//
// @Override
// public List<SubjectKafkaVo> eventSubjectList() {
// return baseMapper.eventSubjectList(2);
// }
}
package com.zzsn.event.task;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzsn.event.constant.Constants;
import com.zzsn.event.entity.Event;
import com.zzsn.event.entity.SubjectAnalysis;
import com.zzsn.event.service.AnalysisService;
import com.zzsn.event.service.EsService;
import com.zzsn.event.service.IEventService;
import com.zzsn.event.service.SubjectAnalysisService;
import com.zzsn.event.util.DateUtil;
import com.zzsn.event.util.EsDateUtil;
import com.zzsn.event.util.RedisUtil;
import com.zzsn.event.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* @author lkg
* @description: 专题分析定时任务
* @date 2022/7/8 11:58
*/
@Slf4j
@Component
@EnableScheduling
public class AnalysisTask {
@Autowired
private IEventService eventService;
@Autowired
private EsService esService;
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private RedisUtil redisUtil;
@Autowired
private AnalysisService analysisService;
@Autowired
private SubjectAnalysisService subjectAnalysisService;
private static final String queryString = "{\"bool\":{\"must\":[{\"match\":{\"subjectId\":\"subject_id\"}}],\"must_not\":[{\"match\":{\"flag\":\"0\"}},{\"match\":{\"deleteFlag\":\"1\"}}]}}";
private static final String beforeQueryString = "{\"bool\":{\"filter\":[{\"range\":{\"publishDate\":{\"gte\":\"start_time\",\"lte\":\"end_time\"}}}],\"must\":[{\"match\":{\"subjectId\":\"subject_id\"}}],\"must_not\":[{\"match\":{\"flag\":\"0\"}},{\"match\":{\"deleteFlag\":\"1\"}}]}}";
private static final String repeatNumQueryString = "{\"bool\":{\"must\":[{\"match\":{\"subjectId\":\"subject_id\"}},{\"match\":{\"masterEntryId\":\"data_id\"}}],\"must_not\":[{\"match\":{\"id\":\"data_id\"}}]}}";
/**
* 每天凌晨0点执行一次
* 按天发送kafka 获取进行中(未结束)的事件专题列表
*/
@Scheduled(cron = "0 0 0 * * ?")
// @Scheduled(cron = "0 * * * * ?")
public void subjectList() {
List<SubjectKafkaVo> data = new ArrayList<>();
Date today = new Date();
Date disableDate = DateUtil.addDate(today, -1);
String startTime = EsDateUtil.esFieldDateFormat(DateUtil.dateToString(disableDate, "yyyy-MM-dd 00:00:00"));
String endTime = EsDateUtil.esFieldDateFormat(DateUtil.dateToString(disableDate, "yyyy-MM-dd 23:59:59"));
log.info("subjectList");
List<SubjectKafkaVo> subjects = eventService.progressList(disableDate);
subjects.forEach(e -> {
String subjectId = e.getId();
Integer increCount = esService.count(subjectId, startTime, endTime, "0");
Integer totalCount = esService.count(subjectId, null, null, "0");
Date analysisTime = e.getAnalysisTime();
if (analysisTime == null) {
analysisTime = e.getTimeEnable();
}
Integer betweenTwoDate = DateUtil.betweenTwoDate(analysisTime, today);
if (increCount.compareTo(e.getIncreAnaRule()) > 0
|| totalCount.compareTo(e.getTotalAnaRule()) > 0
|| betweenTwoDate.compareTo(e.getTimeAnaRule()) > 0) {
e.setIndexName(Constants.SUBJECT_INDEX);
String query = queryString.replace("subject_id", subjectId);
e.setQuery(query);
String beforeQuery = beforeQueryString.replace("subject_id", subjectId).replace("start_time", startTime).replace("end_time", endTime);
e.setBeforeQuery(beforeQuery);
String repeatNumQuery = repeatNumQueryString.replace("subject_id", subjectId);
e.setRepeatNumQuery(repeatNumQuery);
e.setAnalysisTime(today);
data.add(e);
}
});
if (CollectionUtils.isNotEmpty(data)) {
kafkaTemplate.send(Constants.EVENT_ANALYSIS_TOPIC, JSON.toJSONString(data));
}
log.info("进行中(未结束)的事件专题列表数据{}发送成功!",data);
}
/**
* 每天凌晨0点5分执行一次
* 按天发送 事件脉络 所需信息到kafka对应的topic
* 保证信息采集的及时性,审核人员审核的及时性
*/
@Scheduled(cron = "0 5 0 * * ?")
// @Scheduled(cron = "0 * * * * ?")
public void eventContext() {
Date today = new Date();
Date disableDate = DateUtil.addDate(today, -1);
List<SubjectKafkaVo> subjects = eventService.progressList(disableDate);
for (SubjectKafkaVo subjectKafkaVo : subjects) {
String subjectId = subjectKafkaVo.getId();
Date eventTime = subjectKafkaVo.getEventTime();
String startDate;
if (eventTime != null) {
startDate = DateUtil.dateToString(eventTime, "yyyy-MM-dd HH:mm:ss");
} else {
startDate = DateUtil.dateToString(subjectKafkaVo.getTimeEnable(), "yyyy-MM-dd 00:00:00");
}
String endDate = DateUtil.dateToString(disableDate, "yyyy-MM-dd 23:59:59");
List<SubjectDataVo> perDateList = esService.getDataBySubjectId(subjectId, startDate, endDate, "0", Constants.FETCH_FIELDS_DATA, 2, null, null);
if (perDateList.size()> 30) {
String keyWord = subjectKafkaVo.getKeyWord();
List<KafkaDataVo> list = new ArrayList<>();
format(subjectId, list, perDateList);
//分批发送
splitSend(Constants.EVENT_CONTEXT_SEND_TOPIC, subjectId, list, keyWord);
//更新专题 分析事件脉络-最新资讯时间
Event subject = new Event();
subject.setId(subjectId);
subject.setAnalysisTime(DateUtil.stringToDate(perDateList.get(0).getPublishDate(), "yyyy-MM-dd HH:mm:ss"));
eventService.updateById(subject);
log.info("id为-{}-的专题,此次事件脉络({}~{})数据-共{}条,发送成功!", subjectId, startDate.substring(0, 10), endDate.substring(0, 10), list.size());
}
}
}
/**
* 每天凌晨0点20分执行一次
* 发送 伪事件脉络 所需信息到kafka对应的topic
*/
@Scheduled(cron = "0 20 0 * * ?")
// @Scheduled(cron = "0 * * * * ?")
public void eventContext_fake() {
Date today = new Date();
Date disableDate = DateUtil.addDate(today, -1);
List<SubjectKafkaVo> fakeEventIdList = new ArrayList<>();
List<SubjectKafkaVo> subjectList = eventService.progressList(disableDate);
subjectList.forEach(e -> {
LambdaQueryWrapper<SubjectAnalysis> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(SubjectAnalysis::getSubjectId, e.getId()).eq(SubjectAnalysis::getCategory, 2);
int count = subjectAnalysisService.count(queryWrapper);
if (count < Constants.FAKE_NUM) {
fakeEventIdList.add(e);
}
});
for (SubjectKafkaVo subjectKafkaVo : fakeEventIdList) {
List<KafkaDataVo> kafkaDataVoList = new ArrayList<>();
String subjectId = subjectKafkaVo.getId();
String keyWord = subjectKafkaVo.getKeyWord();
List<SubjectDataVo> dataList = esService.getDataBySubjectId(subjectId, null, null, "0", Constants.FETCH_FIELDS_DATA, 2, null, null);
format(subjectId, kafkaDataVoList, dataList);
splitSend(Constants.FAKE_EVENT_CONTEXT_SEND_TOPIC, subjectId, kafkaDataVoList, keyWord);
}
}
private void format(String subjectId, List<KafkaDataVo> kafkaDataVoList, List<SubjectDataVo> dataList) {
dataList.forEach(e -> {
KafkaDataVo kafkaDataVo = new KafkaDataVo();
BeanUtils.copyProperties(e, kafkaDataVo);
List<SubjectDataVo> subjectDataVoList = esService.dataById(subjectId, e.getId());
kafkaDataVo.setRepeatNum(subjectDataVoList.size());
kafkaDataVoList.add(kafkaDataVo);
});
}
//防止数据量太大,超过kafka的最大值,所以分批发送,一次20条数据
private void splitSend(String topic, String subjectId, List<KafkaDataVo> list, String keyWord) {
List<List<KafkaDataVo>> partition = ListUtils.partition(list, 20);
partition.forEach(e -> {
Map<String, Object> map = new HashMap<>();
map.put("keyword", keyWord);
map.put("data", e);
kafkaTemplate.send(topic, subjectId, JSON.toJSONString(map, JSONWriter.Feature.WriteMapNullValue));
});
}
/**
* 定时生成传播路径
* 每天凌晨0点10分执行一次
*/
// @Scheduled(cron = "0 0 0 * * ?")
@Scheduled(cron = "0 * * * * ?")
public void propagationPath() {
Date today = new Date();
Date deadlineDate = DateUtil.addDate(today, -1);
List<SubjectKafkaVo> subjects = eventService.eventSubjectList();
for (SubjectKafkaVo subject : subjects) {
String subjectId = subject.getId();
String key = Constants.SUBJECT_ANALYSIS_PRE + Constants.PROPAGATION_KEY + subjectId;
Date timeDisable = subject.getTimeDisable();
//已经结束的事件专题,永久缓存
if (timeDisable != null && deadlineDate.compareTo(timeDisable) > 0) {
Object cacheObject = redisUtil.get(key);
if (cacheObject == null) {
PropagationPathVo pathVo = analysisService.propagationPath(subjectId);
if (ObjectUtils.isNotEmpty(pathVo)) {
redisUtil.set(key, pathVo);
}
}
} else {//已经结束的事件专题,缓存有效期一天
PropagationPathVo pathVo = analysisService.propagationPath(subjectId);
if (ObjectUtils.isNotEmpty(pathVo)) {
redisUtil.set(key, pathVo, 3600 * 24);
}
}
log.info("专题id为-{}-的专题-传播路径数据-缓存成功!", subjectId);
}
}
//
// /**
// * 定时生成统计分析数据-最近两周(按最新时间)
// * 每天凌晨1点执行一次
// */
// @Scheduled(cron = "0 0 1 * * ?")
// public void tw_statisticAnalysis() {
// Date today = new Date();
// Date deadlineDate = DateUtil.addDate(today, -1);
// List<SubjectKafkaVo> subjects = eventService.eventSubjectList();
// for (SubjectKafkaVo subject : subjects) {
// String subjectId = subject.getId();
// List<SubjectDataVo> dataVoList = esService.getDataBySubjectId(subjectId, null, null, "0", Constant.FETCH_FIELDS_STATISTIC, 2, null, null);
// if (CollectionUtils.isNotEmpty(dataVoList)) {
// String key = Constants.SUBJECT_ANALYSIS_PRE + Constants.TW_STATISTIC_ANALYSIS_KEY + subjectId;
// Date timeDisable = subject.getTimeDisable();
// String latelyTime = EsDateUtil.esFieldDateMapping(dataVoList.get(0).getPublishDate());
// String twoWeekBeforeTime = DateUtil.getDayBeforeOrAfter(latelyTime, -14);
// //已经结束的事件专题,永久缓存
// if (timeDisable != null && deadlineDate.compareTo(timeDisable) > 0) {
// Object cacheObject = redisUtil.get(key);
// if (cacheObject == null) {
// List<StatisticAnalysisVo> statisticAnalysisVos = analysisService.statisticAnalysis(subjectId, twoWeekBeforeTime, latelyTime);
// if (CollectionUtils.isNotEmpty(statisticAnalysisVos)) {
// redisUtil.set(key, statisticAnalysisVos);
// }
// }
// } else { //已经结束的事件专题,缓存有效期一天
// List<StatisticAnalysisVo> statisticAnalysisVos = analysisService.statisticAnalysis(subjectId, twoWeekBeforeTime, latelyTime);
// if (CollectionUtils.isNotEmpty(statisticAnalysisVos)) {
// redisUtil.set(key, statisticAnalysisVos,3600*24);
// }
// }
// log.info("专题id为-{}-的专题-统计分析数据-最近两周-分析成功!", subjectId);
// }
// }
// }
}
package com.zzsn.event.util;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.OptionalDouble;
import java.util.stream.Stream;
/**
* @author lkg
* @description: 指标值计算
* @date 2023/6/19
*/
public class CalculateUtil {
private static final List<String> list = Arrays.asList("-","--");
/**
* 加法
* @param param1 参数1
* @param param2 参数2
* @return java.lang.String
*/
public static String add(String param1,String param2){
String data = null;
if (!list.contains(param1) && !list.contains(param2)){
if (StringUtils.isEmpty(param1)) {
param1 = "0";
}
if (StringUtils.isEmpty(param2)) {
param2 = "0";
}
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal bd2 = new BigDecimal(param2);
BigDecimal add = bd1.add(bd2);
if (add.compareTo(BigDecimal.ZERO) != 0) {
data = add.toString();
}
}
return data;
}
/**
* 减法
* @param param1 参数1
* @param param2 参数2
* @return java.lang.String
*/
public static String subtract(String param1,String param2){
String data = null;
if (!list.contains(param1) && !list.contains(param2) ){
if (StringUtils.isEmpty(param1)) {
param1 = "0";
}
if (StringUtils.isEmpty(param2)) {
param2 = "0";
}
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal bd2 = new BigDecimal(Objects.requireNonNull(param2));
BigDecimal subtract = bd1.subtract(bd2);
if (subtract.compareTo(BigDecimal.ZERO) != 0) {
data = subtract.toString();
}
}
return data;
}
/**
* 乘法
* @param param1 参数1
* @param param2 参数2
* @return java.lang.String
*/
public static String multiply(String param1,String param2){
if(StringUtils.isNotEmpty(param1)&& StringUtils.isNotEmpty(param2)){
if (!list.contains(param1) && !list.contains(param2) ){
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal bd2 = new BigDecimal(param2);
BigDecimal multiply = bd1.multiply(bd2);
return multiply.setScale(2,RoundingMode.HALF_UP).toString();
}
}
return null;
}
/**
* 除法-固定精度(默认保留小数点后四位)
* @param param1 参数1
* @param param2 参数2
* @return java.lang.String
*/
public static String divide(String param1,String param2){
if(StringUtils.isNotEmpty(param1)&& StringUtils.isNotEmpty(param2)){
if (!list.contains(param1) && !list.contains(param2) ){
BigDecimal bd2 = new BigDecimal(param2);
if (bd2.compareTo(BigDecimal.ZERO)==0){
return null;
}else {
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal divide = bd1.divide(bd2,4, RoundingMode.HALF_UP);
return divide.toString();
}
}
}
return null;
}
/**
* 除法-控制精度
* @param param1 参数1
* @param param2 参数2
* @param num 精确到小数点后几位
* @return java.lang.String
*/
public static String divide(String param1,String param2,int num){
if(StringUtils.isNotEmpty(param1)&& StringUtils.isNotEmpty(param2)){
if (!list.contains(param1) && !list.contains(param2) ){
BigDecimal bd2 = new BigDecimal(param2);
if (bd2.compareTo(BigDecimal.ZERO)==0){
return null;
}else {
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal divide = bd1.divide(bd2,num, RoundingMode.HALF_UP);
return divide.toString();
}
}
}
return null;
}
/**
* 转换百分比
* @param param 参数1
* @return java.lang.String
*/
public static String percentage(Double param){
if(param!=null){
DecimalFormat decimalFormat = new DecimalFormat("0.00%");
return decimalFormat.format(param);
}
return null;
}
/**
* 转换百分比
*
* @param param 参数
* @param flag 转换后是否要小数
* @return java.lang.String
*/
public static String percentage(Double param, Boolean flag) {
if (param != null) {
String pattern = "0%";
if (flag) {
pattern = "0.00%";
}
DecimalFormat decimalFormat = new DecimalFormat(pattern);
return decimalFormat.format(param);
}
return null;
}
/**
* 平均数
* @param param1 参数1
* @param param2 参数2
* @return java.lang.String
*/
public static String average(String param1,String param2){
if(StringUtils.isNotEmpty(param1)&& StringUtils.isNotEmpty(param2)){
if (!list.contains(param1) && !list.contains(param2) ){
BigDecimal bd1 = new BigDecimal(param1);
BigDecimal bd2 = new BigDecimal(param2);
OptionalDouble average = Stream.of(bd1, bd2).mapToDouble(BigDecimal::doubleValue).average();
if (average.isPresent()){
return String.valueOf(average.getAsDouble());
}
}
}
return null;
}
/**
* 绝对值
* @param param1 参数1
* @return java.lang.String
*/
public static String abs(String param1){
if(StringUtils.isNotEmpty(param1)){
if (!list.contains(param1) ){
BigDecimal bd1 = new BigDecimal(param1);
return bd1.abs().toString();
}
}
return null;
}
}
package com.zzsn.event.util;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CommonUtils {
/**
* 判断文件名是否带盘符,重新处理
* @param fileName
* @return
*/
public static String getFileName(String fileName){
//判断是否带有盘符信息
// Check for Unix-style path
int unixSep = fileName.lastIndexOf('/');
// Check for Windows-style path
int winSep = fileName.lastIndexOf('\\');
// Cut off at latest possible point
int pos = (winSep > unixSep ? winSep : unixSep);
if (pos != -1) {
// Any sort of path separator found...
fileName = fileName.substring(pos + 1);
}
//替换上传文件名字的特殊字符
fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
//替换上传文件名字中的空格
fileName=fileName.replaceAll("\\s","");
return fileName;
}
}
\ No newline at end of file
package com.zzsn.event.util;
import com.cronutils.builder.CronBuilder;
import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.field.expression.FieldExpressionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.Random;
/**
* @author lkg
* @description: cron表达式工具类
* @date 2021/6/19 10:13
*/
@Slf4j
public class CronUtil {
private static final SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
/**
* 根据时间间隔生成cron表达式--暂只支持 秒、分、时
* @param duration 时间间隔(单位:秒)
* @return java.lang.String
*/
public static String geneCronByPeriod(Integer duration){
String cron;
int hours = (duration % (86400)) / 3600;
int minutes = ((duration % (86400)) % 3600) / 60;
if (hours == 0){
if (minutes == 0){
cron = cronSecond(duration);
}else {
cron = cronMinute(minutes);
}
}else {
cron = cronHour(hours);
}
return cron;
}
//按秒
private static String cronSecond(int seconds){
Cron cron = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(FieldExpressionFactory.always())
.withDoW(FieldExpressionFactory.questionMark())
.withMonth(FieldExpressionFactory.always())
.withDoM(FieldExpressionFactory.always())
.withHour(FieldExpressionFactory.always())
.withMinute(FieldExpressionFactory.always())
.withSecond(FieldExpressionFactory.every(seconds))
.instance();
return cron.asString();
}
//按分钟
private static String cronMinute(int minutes){
Cron cron = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(FieldExpressionFactory.always())
.withDoW(FieldExpressionFactory.questionMark())
.withMonth(FieldExpressionFactory.always())
.withDoM(FieldExpressionFactory.always())
.withHour(FieldExpressionFactory.always())
.withMinute(FieldExpressionFactory.every(minutes))
.withSecond(FieldExpressionFactory.on(0))
.instance();
return cron.asString();
}
//按小时
private static String cronHour(int hours){
Cron cron = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(FieldExpressionFactory.always())
.withDoW(FieldExpressionFactory.questionMark())
.withMonth(FieldExpressionFactory.always())
.withDoM(FieldExpressionFactory.always())
.withHour(FieldExpressionFactory.every(hours))
.withMinute(FieldExpressionFactory.on(0))
.withSecond(FieldExpressionFactory.on(0))
.instance();
return cron.asString();
}
//当前时间转换为cron表达式
/***
* 功能描述:日期转换cron表达式
* @param date
* @return
*/
private static String formatDateByPattern(Date date) {
String formatTimeStr = null;
if (Objects.nonNull(date)) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
/***
* convert Date to cron, eg "0 07 10 15 1 ? 2016"
* @param date : 时间点
* @return
*/
public static String getCron(Date date, int space) {
String cron = formatDateByPattern(date);
//将生成的cron最后一个参数年转化为通配符
String[] cronArray = cron.split(" ");
cronArray[6] = "*";
String result = "";
if(!StringUtils.isEmpty(space)){
cronArray[2] = "0/" + space;
}
for(int i = 0; i < 3; i++){
result += cronArray[i] + " ";
}
cron = result + "* * ?";
// for (String s : cronArray) {
// result += s + " ";
// }
// cron = cronExpressionPlusDuration(result, (int)space*60*60);
return cron;
}
/**
* <p>对cron表达式进行修改,根据传入的时间生成一个新的cron表达式</>
* 两个表达式之间的间隔为duration
*
* @param cron
* @param duration 单位为秒
* @return
*/
private static String cronExpressionPlusDuration(String cron, int duration) {
String[] cronArray = cron.split(" ");
int days = duration / 86400;
int hours = (duration % (86400)) / 3600;
int minutes = ((duration % (86400)) % 3600) / 60;
cronArray[2] = String.valueOf(Integer.valueOf(cronArray[2]) + hours);
cronArray[1] = String.valueOf(Integer.valueOf(cronArray[1]) + minutes);
/* 对小时和分钟进行合法性校验*/
if (Integer.valueOf(cronArray[1]) >= 60 || Integer.valueOf(cronArray[2]) >= 24) {
int extraMinutes = Integer.valueOf(cronArray[1]) % 60;
int extraHours = (Integer.valueOf(cronArray[2])+ Integer.valueOf(cronArray[1]) / 60)%24;
cronArray[2] = String.valueOf(extraHours);
cronArray[1] = String.valueOf(extraMinutes);
}
/* 持续时间一天以内*/
if (duration < 86400 && "*".equals(cronArray[3]) && "*".equals(cronArray[4]) && "?".equals(cronArray[5])) {
} else if (duration > 86400 && duration < 86400 * 7) {
cronArray[5] = String.valueOf((Integer.valueOf(cronArray[5]) + days) % 7 + 1);
} else if (duration > 86400 * 7 && duration < 86400 * 32) {
if("L".equals(cronArray[3])){
cronArray[3]=String.valueOf(days);
}else {
cronArray[3] = String.valueOf(((Integer.valueOf(cronArray[3]) + days) % 31) + 1);
}
}
String result = "";
for (String s : cronArray) {
result += s + " ";
}
return result;
}
/**
* 随机生成一个corn表达式
*/
public static String getRandomCron() {
int min = 2;
int max = 12;
String cron = formatDateByPattern(new Date());
//将生成的cron最后一个参数年转化为通配符
String[] cronArray = cron.split(" ");
Random random = new Random();
int s = random.nextInt(max) % (max - min + 1) + min;
int second = random.nextInt(58) % (57) + 2;
int second1 = random.nextInt(58) % (57) + 2;
String corn = second + " " + second1 + " " + "0/" + String.valueOf(s) + " " + "* * ?";
return corn;
}
/**
* 根据设置方式生成cron
* @param unit (1分;2小时;3日;4月)
* @param space
* @return
*/
public static String generateCron(String unit, Integer space) {
String cron = formatDateByPattern(new Date());
//将生成的cron最后一个参数年转化为通配符
String[] cronArray = cron.split(" ");
if("1".equals(unit)) {
cron = cronArray[0] + " " + "1/" + space + " * * * ?";
}else if("2".equals(unit)){
cron = cronArray[0] + " " + cronArray[1] + " " + "1/" + space + " * * ?";
}else if("3".equals(unit)){
cron = cronArray[0] + " " + cronArray[1] + " " + cronArray[2] + " " + "1/" + space + " * ?";
}else if("4".equals(unit)){
cron = cronArray[0] + " " + cronArray[1] + " " + cronArray[2] + " 1 " + "1/" + space + " ?";
}
return cron;
}
}
package com.zzsn.event.util; package com.zzsn.event.util;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class DateUtil { public class DateUtil {
static SimpleDateFormat format; private static SimpleDateFormat format;
public static String dateToString(Date date) {
format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(date);
}
public static String getStringDate(Date date){
String format = "yyyy-MM-dd";
return DateUtil.format(date, format);
}
public static String format(Date d, String format)
{
if (d == null)
return "";
SimpleDateFormat myFormatter = new SimpleDateFormat(format);
myFormatter.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
return myFormatter.format(d);
}
/** /**
* 获取每天的开始时间 00:00:00:00 * Date转String
* *
* @param date * @param date 时间日期
* @return * @param formatStr 格式
* @return java.lang.String
*/ */
public static Date getStartTime(Date date) { public static String dateToString(Date date, String formatStr) {
Calendar dateStart = Calendar.getInstance(); format = new SimpleDateFormat(formatStr);
dateStart.setTime(date); return format.format(date);
dateStart.set(Calendar.HOUR_OF_DAY, 0);
dateStart.set(Calendar.MINUTE, 0);
dateStart.set(Calendar.SECOND, 0);
return dateStart.getTime();
} }
/** /**
* 获取每天的结束时间 23:59:59:999 * String转Date
* *
* @param date * @param dateStr 时间字符串
* @return * @param formatStr 格式
* @return java.lang.String
*/ */
public static Date getEndTime(Date date) { public static Date stringToDate(String dateStr, String formatStr) {
Calendar dateEnd = Calendar.getInstance(); format = new SimpleDateFormat(formatStr);
dateEnd.setTime(date); Date parse = null;
dateEnd.set(Calendar.HOUR_OF_DAY, 23); try {
dateEnd.set(Calendar.MINUTE, 59); parse = format.parse(dateStr);
dateEnd.set(Calendar.SECOND, 59); } catch (Exception e) {
return dateEnd.getTime(); e.printStackTrace();
}
return parse;
} }
/** /**
* 获取当前年份 * 增加天数
* @return *
* @param d 目标时间
* @param day 天数
* @return java.util.Date
*/ */
public static String getSysYear() { public static Date addDate(Date d, int day) {
Calendar date = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
return String.valueOf(date.get(Calendar.YEAR)); cal.setTime(d);
cal.add(Calendar.DATE, day);
return cal.getTime();
} }
/** /**
* 获取当前时间所在日 * 格式化时间字符串
*
* @param dateStr 时间字符串
* @param format1 字符串转时间格式
* @param format2 时间转字符串格式
* @return java.lang.String
* @author lkg
*/ */
public static Integer getDay(String dateStr) { public static String formatStr(String dateStr, String format1, String format2) {
Calendar instance = Calendar.getInstance(); return dateToString(stringToDate(dateStr, format1), format2);
Date date = stringToDate(dateStr, "yyyy-MM-dd");
instance.setTime(date);
return instance.get(Calendar.DAY_OF_MONTH);
} }
/** /**
* 获取前一小时的时间 * 两个时间相差的天数
* @param date 时间 *
* @param startDate 开始时间
* @param endDate 结束时间
* @return java.lang.Integer
* @author lkg
*/ */
public static Date beforeOneHour(Date date){ public static Integer betweenTwoDate(String startDate, String endDate) {
Calendar instance = Calendar.getInstance(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
instance.setTime(date); LocalDate start = LocalDate.parse(startDate, formatter);
instance.add(Calendar.HOUR_OF_DAY,-1); LocalDate end = LocalDate.parse(endDate, formatter);
return instance.getTime(); long between = ChronoUnit.DAYS.between(start, end);
} return (int) between;
public static Date stringToDate(String date,String formatStr) {
Date parse = null;
format = new SimpleDateFormat(formatStr);
try {
parse = format.parse(date);
} catch (Exception e) {
e.printStackTrace();
}
return parse;
}
public static List<String> betweenDate(String startDate,String endDate) {
List<String> dateList = new ArrayList<>();
String formatStr = "yyyy-MM-dd";
try {
Date dayOne = stringToDate(startDate, formatStr);
Date dayTwo = stringToDate(endDate, formatStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(dayOne);
dateList.add(startDate);
while (dayTwo.after(calendar.getTime())) {
calendar.add(Calendar.DAY_OF_MONTH,1);
dateList.add(format(calendar.getTime(),formatStr));
}
} catch (Exception e) {
e.printStackTrace();
}
return dateList;
} }
/** /**
* 获取天前凌晨时间 * 两个时间相差的天数
* @param number 几天前 *
* @param startDate 开始时间
* @param endDate 结束时间
* @return java.lang.Integer
* @author lkg
*/ */
public static Date getSomeDayBegin(int number) { public static Integer betweenTwoDate(Date startDate, Date endDate) {
String pattern = "yyyy-MM-dd";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDate start = LocalDate.parse(dateToString(startDate, pattern), formatter);
LocalDate end = LocalDate.parse(dateToString(endDate, pattern), formatter);
long between = ChronoUnit.DAYS.between(start, end);
return Math.abs((int) between);
}
// 获取当前的日期和时间 public static String getDayBeforeOrAfter(String dateStr, int num){
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(stringToDate(dateStr,"yyyy-MM-dd"));
// 将当前的日期和时间减去一天 calendar.add(Calendar.DATE,num);
calendar.add(Calendar.DAY_OF_MONTH, -number); return dateToString(calendar.getTime(),"yyyy-MM-dd 00:00:00");
// 将时间部分设置为凌晨时间
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 获取昨天凌晨时间
return new Date(String.valueOf(calendar.getTime()));
} }
} }
package com.zzsn.event.util;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* 类描述:时间操作定义类
*
* @Author: 张代浩
* @Date:2012-12-8 12:15:03
* @Version 1.0
*/
public class DateUtils extends PropertyEditorSupport {
public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
public static ThreadLocal<SimpleDateFormat> yyyyMMdd = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public static ThreadLocal<SimpleDateFormat> date_sdf_wz = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy年MM月dd日");
}
};
public static ThreadLocal<SimpleDateFormat> time_sdf = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm");
}
};
public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyyMMddHHmmss");
}
};
public static ThreadLocal<SimpleDateFormat> short_time_sdf = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("HH:mm");
}
};
public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
// 以毫秒表示的时间
private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
private static final long HOUR_IN_MILLIS = 3600 * 1000;
private static final long MINUTE_IN_MILLIS = 60 * 1000;
private static final long SECOND_IN_MILLIS = 1000;
// 指定模式的时间格式
private static SimpleDateFormat getSDFormat(String pattern) {
return new SimpleDateFormat(pattern);
}
/**
* 当前日历,这里用中国时间表示
*
* @return 以当地时区表示的系统当前日历
*/
public static Calendar getCalendar() {
return Calendar.getInstance();
}
/**
* 指定毫秒数表示的日历
*
* @param millis 毫秒数
* @return 指定毫秒数表示的日历
*/
public static Calendar getCalendar(long millis) {
Calendar cal = Calendar.getInstance();
// --------------------cal.setTimeInMillis(millis);
cal.setTime(new Date(millis));
return cal;
}
// ////////////////////////////////////////////////////////////////////////////
// getDate
// 各种方式获取的Date
// ////////////////////////////////////////////////////////////////////////////
/**
* 当前日期
*
* @return 系统当前时间
*/
public static Date getDate() {
return new Date();
}
/**
* 指定毫秒数表示的日期
*
* @param millis 毫秒数
* @return 指定毫秒数表示的日期
*/
public static Date getDate(long millis) {
return new Date(millis);
}
/**
* 时间戳转换为字符串
*
* @param time
* @return
*/
public static String timestamptoStr(Timestamp time) {
Date date = null;
if (null != time) {
date = new Date(time.getTime());
}
return date2Str(date_sdf.get());
}
/**
* 字符串转换时间戳
*
* @param str
* @return
*/
public static Timestamp str2Timestamp(String str) {
Date date = str2Date(str, date_sdf.get());
return new Timestamp(date.getTime());
}
/**
* 字符串转换成日期
*
* @param str
* @param sdf
* @return
*/
public static Date str2Date(String str, SimpleDateFormat sdf) {
if (null == str || "".equals(str)) {
return null;
}
Date date = null;
try {
date = sdf.parse(str);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 日期转换为字符串
*
* @param date_sdf 日期格式
* @return 字符串
*/
public static String date2Str(SimpleDateFormat date_sdf) {
Date date = getDate();
if (null == date) {
return null;
}
return date_sdf.format(date);
}
/**
* 格式化时间
*
* @param date
* @param format
* @return
*/
public static String dateformat(String date, String format) {
SimpleDateFormat sformat = new SimpleDateFormat(format);
Date _date = null;
try {
_date = sformat.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sformat.format(_date);
}
/**
* 日期转换为字符串
*
* @param date 日期
* @param date_sdf 日期格式
* @return 字符串
*/
public static String date2Str(Date date, SimpleDateFormat date_sdf) {
if (null == date) {
return null;
}
return date_sdf.format(date);
}
/**
* 日期转换为字符串
*
* @param format 日期格式
* @return 字符串
*/
public static String getDate(String format) {
Date date = new Date();
if (null == date) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 指定毫秒数的时间戳
*
* @param millis 毫秒数
* @return 指定毫秒数的时间戳
*/
public static Timestamp getTimestamp(long millis) {
return new Timestamp(millis);
}
/**
* 以字符形式表示的时间戳
*
* @param time 毫秒数
* @return 以字符形式表示的时间戳
*/
public static Timestamp getTimestamp(String time) {
return new Timestamp(Long.parseLong(time));
}
/**
* 系统当前的时间戳
*
* @return 系统当前的时间戳
*/
public static Timestamp getTimestamp() {
return new Timestamp(System.currentTimeMillis());
}
/**
* 当前时间,格式 yyyy-MM-dd HH:mm:ss
*
* @return 当前时间的标准形式字符串
*/
public static String now() {
return datetimeFormat.get().format(getCalendar().getTime());
}
/**
* 指定日期的时间戳
*
* @param date 指定日期
* @return 指定日期的时间戳
*/
public static Timestamp getTimestamp(Date date) {
return new Timestamp(date.getTime());
}
/**
* 指定日历的时间戳
*
* @param cal 指定日历
* @return 指定日历的时间戳
*/
public static Timestamp getCalendarTimestamp(Calendar cal) {
// ---------------------return new Timestamp(cal.getTimeInMillis());
return new Timestamp(cal.getTime().getTime());
}
public static Timestamp gettimestamp() {
Date dt = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowTime = df.format(dt);
Timestamp buydate = Timestamp.valueOf(nowTime);
return buydate;
}
// ////////////////////////////////////////////////////////////////////////////
// getMillis
// 各种方式获取的Millis
// ////////////////////////////////////////////////////////////////////////////
/**
* 系统时间的毫秒数
*
* @return 系统时间的毫秒数
*/
public static long getMillis() {
return System.currentTimeMillis();
}
/**
* 指定日历的毫秒数
*
* @param cal 指定日历
* @return 指定日历的毫秒数
*/
public static long getMillis(Calendar cal) {
// --------------------return cal.getTimeInMillis();
return cal.getTime().getTime();
}
/**
* 指定日期的毫秒数
*
* @param date 指定日期
* @return 指定日期的毫秒数
*/
public static long getMillis(Date date) {
return date.getTime();
}
/**
* 指定时间戳的毫秒数
*
* @param ts 指定时间戳
* @return 指定时间戳的毫秒数
*/
public static long getMillis(Timestamp ts) {
return ts.getTime();
}
// ////////////////////////////////////////////////////////////////////////////
// formatDate
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:年-月-日
*
* @return 默认日期按“年-月-日“格式显示
*/
public static String formatDate() {
return date_sdf.get().format(getCalendar().getTime());
}
/**
* 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
*
* @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
*/
public static String formatDateTime() {
return datetimeFormat.get().format(getCalendar().getTime());
}
/**
* 获取时间字符串
*/
public static String getDataString(SimpleDateFormat formatstr) {
return formatstr.format(getCalendar().getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日
*
* @param cal 指定的日期
* @return 指定日期按“年-月-日“格式显示
*/
public static String formatDate(Calendar cal) {
return date_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日
*
* @param date 指定的日期
* @return 指定日期按“年-月-日“格式显示
*/
public static String formatDate(Date date) {
return date_sdf.get().format(date);
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“年-月-日“格式显示
*/
public static String formatDate(long millis) {
return date_sdf.get().format(new Date(millis));
}
/**
* 默认日期按指定格式显示
*
* @param pattern 指定的格式
* @return 默认日期按指定格式显示
*/
public static String formatDate(String pattern) {
return getSDFormat(pattern).format(getCalendar().getTime());
}
/**
* 指定日期按指定格式显示
*
* @param cal 指定的日期
* @param pattern 指定的格式
* @return 指定日期按指定格式显示
*/
public static String formatDate(Calendar cal, String pattern) {
return getSDFormat(pattern).format(cal.getTime());
}
/**
* 指定日期按指定格式显示
*
* @param date 指定的日期
* @param pattern 指定的格式
* @return 指定日期按指定格式显示
*/
public static String formatDate(Date date, String pattern) {
return getSDFormat(pattern).format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// formatTime
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:年-月-日 时:分
*
* @return 默认日期按“年-月-日 时:分“格式显示
*/
public static String formatTime() {
return time_sdf.get().format(getCalendar().getTime());
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(long millis) {
return time_sdf.get().format(new Date(millis));
}
/**
* 指定日期的默认显示,具体格式:年-月-日 时:分
*
* @param cal 指定的日期
* @return 指定日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(Calendar cal) {
return time_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:年-月-日 时:分
*
* @param date 指定的日期
* @return 指定日期按“年-月-日 时:分“格式显示
*/
public static String formatTime(Date date) {
return time_sdf.get().format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// formatShortTime
// 将日期按照一定的格式转化为字符串
// ////////////////////////////////////////////////////////////////////////////
/**
* 默认方式表示的系统当前日期,具体格式:时:分
*
* @return 默认日期按“时:分“格式显示
*/
public static String formatShortTime() {
return short_time_sdf.get().format(getCalendar().getTime());
}
/**
* 指定毫秒数表示日期的默认显示,具体格式:时:分
*
* @param millis 指定的毫秒数
* @return 指定毫秒数表示日期按“时:分“格式显示
*/
public static String formatShortTime(long millis) {
return short_time_sdf.get().format(new Date(millis));
}
/**
* 指定日期的默认显示,具体格式:时:分
*
* @param cal 指定的日期
* @return 指定日期按“时:分“格式显示
*/
public static String formatShortTime(Calendar cal) {
return short_time_sdf.get().format(cal.getTime());
}
/**
* 指定日期的默认显示,具体格式:时:分
*
* @param date 指定的日期
* @return 指定日期按“时:分“格式显示
*/
public static String formatShortTime(Date date) {
return short_time_sdf.get().format(date);
}
// ////////////////////////////////////////////////////////////////////////////
// parseDate
// parseCalendar
// parseTimestamp
// 将字符串按照一定的格式转化为日期或时间
// ////////////////////////////////////////////////////////////////////////////
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的日期
* @throws ParseException
*/
public static Date parseDate(String src, String pattern) {
Date parse = null;
try {
parse = getSDFormat(pattern).parse(src);
} catch (Exception e) {
e.printStackTrace();
}
return parse;
}
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的日期
* @throws ParseException
*/
public static Calendar parseCalendar(String src, String pattern) {
Date date = parseDate(src, pattern);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
public static String formatAddDate(String src, String pattern, int amount) {
Calendar cal;
cal = parseCalendar(src, pattern);
cal.add(Calendar.DATE, amount);
return formatDate(cal);
}
/**
* 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
*
* @param src 将要转换的原始字符窜
* @param pattern 转换的匹配格式
* @return 如果转换成功则返回转换后的时间戳
* @throws ParseException
*/
public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
Date date = parseDate(src, pattern);
return new Timestamp(date.getTime());
}
// ////////////////////////////////////////////////////////////////////////////
// dateDiff
// 计算两个日期之间的差值
// ////////////////////////////////////////////////////////////////////////////
/**
* 计算两个时间之间的差值,根据标志的不同而不同
*
* @param flag 计算标志,表示按照年/月/日/时/分/秒等计算
* @param calSrc 减数
* @param calDes 被减数
* @return 两个日期之间的差值
*/
public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
long millisDiff = getMillis(calSrc) - getMillis(calDes);
if (flag == 'y') {
return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
}
if (flag == 'd') {
return (int) (millisDiff / DAY_IN_MILLIS);
}
if (flag == 'h') {
return (int) (millisDiff / HOUR_IN_MILLIS);
}
if (flag == 'm') {
return (int) (millisDiff / MINUTE_IN_MILLIS);
}
if (flag == 's') {
return (int) (millisDiff / SECOND_IN_MILLIS);
}
return 0;
}
/**
* String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
* HH:mm:ss“ * @param text String类型的时间值
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
try {
if (text.indexOf(":") == -1 && text.length() == 10) {
setValue(DateUtils.date_sdf.get().parse(text));
} else if (text.indexOf(":") > 0 && text.length() == 19) {
setValue(DateUtils.datetimeFormat.get().parse(text));
} else {
throw new IllegalArgumentException("Could not parse date, date format is error ");
}
} catch (ParseException ex) {
IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
iae.initCause(ex);
throw iae;
}
} else {
setValue(null);
}
}
public static int getYear() {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(getDate());
return calendar.get(Calendar.YEAR);
}
// 获得本周一0点时间
public static Date getTimesWeekMorning() {
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return cal.getTime();
}
// 获得本周日24点时间
public static Date getTimesWeekNight() {
Calendar cal = Calendar.getInstance();
cal.setTime(getTimesWeekMorning());
cal.add(Calendar.DAY_OF_WEEK, 7);
return cal.getTime();
}
// 获得本月第一天0点时间
public static Date getTimesMonthMorning() {
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
return cal.getTime();
}
// 获得本月最后一天24点时间
public static Date getTimesMonthNight() {
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, 24);
return cal.getTime();
}
public static Date getHalfYearStartTime() {
Calendar c = Calendar.getInstance();
int currentMonth = c.get(Calendar.MONTH) + 1;
Date now = null;
try {
if (currentMonth <= 6) {
c.set(Calendar.MONTH, 0);
} else if (currentMonth <= 12) {
c.set(Calendar.MONTH, 6);
}
c.set(Calendar.DATE, 1);
now = c.getTime();
} catch (Exception e) {
e.printStackTrace();
}
return now;
}
public static Date getHalfYearEndTime() {
Calendar c = Calendar.getInstance();
int currentMonth = c.get(Calendar.MONTH) + 1;
Date now = null;
try {
if (currentMonth <= 6) {
c.set(Calendar.MONTH, 5);
c.set(Calendar.DATE, 30);
} else if (currentMonth <= 12) {
c.set(Calendar.MONTH, 11);
c.set(Calendar.DATE, 31);
}
now = c.getTime();
} catch (Exception e) {
e.printStackTrace();
}
return now;
}
// 获得本年第一天的时间
public static Date getCurrentYearStart() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DATE, 1);
return cal.getTime();
}
// 获得本年最后一天的时间
public static Date getCurrentYearEnd() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 11);
cal.set(Calendar.DATE, 31);
return cal.getTime();
}
}
package com.zzsn.event.util;
import cn.hutool.core.lang.Snowflake;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.Date;
/**
* minio文件上传工具类
*/
@Slf4j
public class MinioUtil {
private static String minioUrl;
private static String visitUrl;
private static String minioName;
private static String minioPass;
private static String bucketName;
public static void setMinioUrl(String minioUrl) {
MinioUtil.minioUrl = minioUrl;
}
public static void setMinioName(String minioName) {
MinioUtil.minioName = minioName;
}
public static void setMinioPass(String minioPass) {
MinioUtil.minioPass = minioPass;
}
public static void setBucketName(String bucketName) {
MinioUtil.bucketName = bucketName;
}
public static String getMinioUrl() {
return minioUrl;
}
public static String getBucketName() {
return bucketName;
}
public static String getVisitUrl() {
return visitUrl;
}
public static void setVisitUrl(String visitUrl) {
MinioUtil.visitUrl = visitUrl;
}
private static MinioClient minioClient = null;
/**
* 上传文件
* @param file
* @return
*/
public static String upload(MultipartFile file, String bizPath, String customBucket) {
String file_url = "";
//update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
bizPath=StrAttackFilter.filter(bizPath);
//update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
String newBucket = bucketName;
if(oConvertUtils.isNotEmpty(customBucket)){
newBucket = customBucket;
}
try {
initMinio(minioUrl, minioName,minioPass);
// 检查存储桶是否已经存在
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
log.info("create a new bucket.");
}
InputStream stream = file.getInputStream();
// 获取文件名
String orgName = file.getOriginalFilename();
if("".equals(orgName)){
orgName=file.getName();
}
orgName = CommonUtils.getFileName(orgName);
String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
// 使用putObject上传一个本地文件到存储桶中。
if(objectName.startsWith("/")){
objectName = objectName.substring(1);
}
PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
.bucket(newBucket)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
file_url = visitUrl+newBucket+"/"+objectName;
}catch (Exception e){
log.error(e.getMessage(), e);
}
return file_url;
}
/**
* 文件上传
* @param file
* @param bizPath
* @return
*/
public static String upload(MultipartFile file, String bizPath) {
return upload(file,bizPath,null);
}
/**
* 获取文件流
* @param bucketName
* @param objectName
* @return
*/
public static InputStream getMinioFile(String bucketName,String objectName){
InputStream inputStream = null;
try {
initMinio(minioUrl, minioName, minioPass);
GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
inputStream = minioClient.getObject(objectArgs);
} catch (Exception e) {
log.info("文件获取失败" + e.getMessage());
}
return inputStream;
}
/**
* 删除文件
* @param bucketName
* @param objectName
* @throws Exception
*/
public static void removeObject(String bucketName, String objectName) {
try {
initMinio(minioUrl, minioName,minioPass);
RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
minioClient.removeObject(objectArgs);
}catch (Exception e){
log.info("文件删除失败" + e.getMessage());
}
}
/**
* 获取文件外链
* @param bucketName
* @param objectName
* @param expires
* @return
*/
public static String getObjectURL(String bucketName, String objectName, Integer expires) {
initMinio(minioUrl, minioName,minioPass);
try{
GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
.bucket(bucketName)
.expiry(expires).build();
String url = minioClient.getPresignedObjectUrl(objectArgs);
return URLDecoder.decode(url,"UTF-8");
}catch (Exception e){
log.info("文件路径获取失败" + e.getMessage());
}
return null;
}
/**
* 初始化客户端
* @param minioUrl
* @param minioName
* @param minioPass
* @return
*/
private static MinioClient initMinio(String minioUrl, String minioName,String minioPass) {
if (minioClient == null) {
try {
minioClient = MinioClient.builder()
.endpoint(minioUrl)
.credentials(minioName, minioPass)
.build();
} catch (Exception e) {
e.printStackTrace();
}
}
return minioClient;
}
/**
* 上传文件到minio
* @param stream
* @param relativePath
* @return
*/
public static String upload(InputStream stream,String relativePath) throws Exception {
initMinio(minioUrl, minioName,minioPass);
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
log.info("create a new bucket.");
}
PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath)
.bucket(bucketName)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
return visitUrl+bucketName+"/"+relativePath;
}
/**
* 上传文件
*
* @param file 文件
* @param contentType 类型,如果pdf文件或者图片,需要预览功能的话,必填.示例:pdf application/pdf;图片 image/png;image/jpeg
* @param bizPath 文件夹名称
* @param customBucket 自定义桶的名称
* @author lkg
* @date 2023/5/22
*/
public static String upload(MultipartFile file, String contentType, String bizPath, String customBucket) {
String fileUrl = null;
try {
if (StringUtils.isEmpty(bizPath)) {
bizPath = "report";
} else {
//过滤上传文件夹名特殊字符,防止攻击
bizPath = StrAttackFilter.filter(bizPath);
}
InputStream stream = file.getInputStream();
// 获取文件名
String orgName = file.getOriginalFilename();
if (StringUtils.isEmpty(orgName)) {
orgName = file.getName();
}
String objectName = bizPath + "/" + orgName;
// 使用putObject上传一个本地文件到存储桶中。
if (objectName.startsWith("/")) {
objectName = objectName.substring(1);
}
fileUrl = uploadByStream(stream,contentType, customBucket,objectName);
} catch (Exception e) {
e.printStackTrace();
}
return fileUrl;
}
/**
* 通过文件流上传文件
*
* @param stream 文件流
* @param contentType 类型,如果pdf文件或者图片,需要预览功能的话,必填.示例:pdf application/pdf;图片 image/png;image/jpeg
* @param customBucket 自定义桶名称
* @param relativePath 文件路径
* @author lkg
* @date 2023/5/22
*/
public static String uploadByStream(InputStream stream, String contentType, String customBucket, String relativePath) throws Exception {
initMinio(minioUrl, minioName, minioPass);
if (StringUtils.isEmpty(customBucket)) {
customBucket = bucketName;
}
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(customBucket).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(customBucket).build());
}
if (StringUtils.isEmpty(contentType)) {
contentType = "application/octet-stream";
}
int index = relativePath.lastIndexOf(".");
relativePath = relativePath.substring(0,index) + "_" + System.currentTimeMillis() + relativePath.substring(index);
if (relativePath.startsWith("/")) {
relativePath = relativePath.substring(1);
}
PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath)
.bucket(customBucket)
.contentType(contentType)
.stream(stream, stream.available(), -1).build();
minioClient.putObject(objectArgs);
stream.close();
return customBucket + "/" + relativePath;
}
/**
* 通过字节上传文件
*
* @param bytes 字节
* @param contentType 类型,如果pdf文件或者图片,需要预览功能的话,必填.示例:pdf application/pdf;图片 image/png;image/jpeg
* @param customBucket 自定义桶名称
* @param relativePath 文件路径
* @author lkg
* @date 2023/5/22
*/
public static String uploadByByte(byte[] bytes, String contentType, String customBucket, String relativePath) throws Exception {
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
return uploadByStream(stream, contentType, customBucket, relativePath);
}
/**
* 根据文件名生成文件存储路径(yyyy/yyyyMMdd/id)
* @param fileName
* @return
*/
public static String getRelativePath(String fileName) {
if(fileName == null || StringUtils.isEmpty(fileName) ){
return null;
}
String suffix = fileName;
if(fileName.lastIndexOf(".") > -1){
suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
}
String date = DateUtils.formatDate(new Date()).replaceAll("-", "");
return date.substring(0,4)+"/"+date+"/"+ new Snowflake(1L,1L).nextIdStr()+"."+suffix;
}
}
package com.zzsn.event.util; package com.zzsn.event.util;
import com.zzsn.event.vo.PropagationPathVo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
...@@ -592,4 +590,6 @@ public class RedisUtil { ...@@ -592,4 +590,6 @@ public class RedisUtil {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
package com.zzsn.event.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* 文件上传字符串过滤特殊字符
*/
public class StrAttackFilter {
public static String filter(String str) throws PatternSyntaxException {
// 清除掉所有特殊字符
String regEx = "[`_《》~!@#$%^&*()+=|{}':;',\\[\\].<>?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
// public static void main(String[] args) {
// String filter = filter("@#jeecg/《》【bo】¥%……&*(o))))!@t<>,.,/?'\'~~`");
// System.out.println(filter);
// }
}
package com.zzsn.event.vo;
import com.zzsn.event.entity.Event;
import lombok.Data;
@Data
public class AddEventParam extends Event {
private String corn;
//0 do not 1 do 1
private Integer extractHotWords;
// time unit minute
private Integer period;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.List;
/**
* 统计信息封装
*
* @author lkg
* @date 2023/6/20
*/
@Data
public class CountVO {
/**排序*/
private Integer order;
/**名称*/
private String name;
/**数量*/
private Long value;
/**声量/占比*/
private String percentage;
/**按时间分组的子集*/
private List<CountVO> children;
/**预警类型*/
private Integer warningType;
}
package com.zzsn.event.vo;
import lombok.Data;
/**
* @author lkg
* @description: 发送kafka数据封装
* @date 2022/7/20
*/
@Data
public class KafkaDataVo {
/*信息id*/
private String id;
/*标题*/
private String title;
/*内容*/
private String content;
/*来源*/
private String origin;
/*发布时间*/
private String publishDate;
/*链接*/
private String sourceAddress;
/*重复数*/
private Integer repeatNum;
/*专题id*/
private String subjectId;
/*来源分类*/
private String type;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class KeyWordsDTO {
/**主键*/
private String id;
/**词组编码*/
private String wordsCode;
/**词组名称*/
private String wordsName;
/**关键词*/
private String keyWord;
/**排除词*/
private String exclusionWord;
/**状态*/
private String status;
/**数据库查询数据时承接*/
private String subjectId;
/**所属专题*/
private List<String> subjectIds;
private Date startTime;
private Date endTime;
//需要启动的信息采集器
private List<String> searchEngines;
//采集的要求(1:标题 2:正文 3:全文)
private String crawlerType;
}
package com.zzsn.event.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
@Data
public class KeyWordsPage {
private String id;
/**词组编码*/
@Excel(name = "词组编码", width = 15)
@ApiModelProperty(value = "词组编码")
private String wordsCode;
/**词组名称*/
@Excel(name = "词组名称", width = 15)
@ApiModelProperty(value = "词组名称")
private String wordsName;
/**词组类别id*/
@Excel(name = "词组类别id", width = 15)
@ApiModelProperty(value = "词组类别id")
private String keyWordsTypeId;
private String keyWordTypeNames;
/**关键词*/
@Excel(name = "关键词", width = 15)
@ApiModelProperty(value = "关键词")
private String keyWord;
/**排除词*/
@Excel(name = "排除词", width = 15)
@ApiModelProperty(value = "排除词")
private String exclusionWord;
/**状态*/
@Excel(name = "状态", width = 15, dicCode = "use_status")
@ApiModelProperty(value = "状态")
private String status;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**今日采集数*/
private Integer numToday;
/**累计采集数*/
private Integer numTotal;
/**今日调度次数*/
private Integer numDispatcherToday;
/**累计调度次数*/
private Integer numDispatcherTotal;
/**成功调度次数*/
private Integer numDispatcherSuccess;
/**失败调度次数*/
private Integer numDispatcherFailed;
/**昨日采集数*/
private Integer numYesterday;
/**最近一次调度时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date latestDispatcherTime;
/**最近一次采集时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date latestCollectionTime;
/**说明 1信息源 2 关键词*/
private String remark;
/**专题绑定关键词时,关键词的采集方式( 1:标题 2:正文 3:全文)*/
private String type;
/**专题绑定的关键词映射表主键id*/
private String subjectKeyWordId;
private String typeId;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.List;
/**
* 媒体分布统计
*
* @author lkg
* @date 2023/6/20
*/
@Data
public class MediaVO {
//媒体性质
private String name;
//数据量
private Long value;
//占比
private String percentage;
//媒体数量
private Long mediaNum;
//热门媒体
private List<String> hotList;
}
package com.zzsn.event.vo;
import lombok.Data;
/**
* 负面信息
*
* @author lkg
* @date 2024/2/29
*/
@Data
public class NegativeDataVO {
private String id;
private String title;
private String origin;
private String publishDate;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author lkg
* @description: 传播路径响应数据封装
* @date 2022/7/8 11:23
*/
@Data
public class PropagationPathVo implements Serializable {
private String name;
private List<PropagationPathVo> children;
}
package com.zzsn.event.vo;
import lombok.Data;
/**
* 报告所属栏目信息封装
*
* @author lkg
* @date 2023/9/21
*/
@Data
public class ReportExtendVo {
private String projectId;
private String columnId;
}
package com.zzsn.event.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
@Data
public class SearchEnginesVo {
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**搜索引擎名称*/
@Excel(name = "搜索引擎名称", width = 15)
@ApiModelProperty(value = "搜索引擎名称")
private String name;
/**字典码*/
@Excel(name = "字典码", width = 15)
@ApiModelProperty(value = "字典码")
private String dictionaryCode;
/**引擎地址*/
@Excel(name = "引擎地址", width = 15)
@ApiModelProperty(value = "引擎地址")
private String searchUrl;
/**类别*/
@Excel(name = "类别", width = 15, dicCode = "searchEngineType")
@ApiModelProperty(value = "类别")
private Integer type;
/**使用状态*/
@Excel(name = "使用状态", width = 15, dicCode = "use_status")
@ApiModelProperty(value = "使用状态")
private Integer status;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**专题id*/
private String subjectId;
/**专题是否配置*/
private String yn;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.List;
@Data
public class SpecialInformation {
//的索引名
private String dbIndex;
//说明:...Raw 表示原文,即原语言
//作者
private String author;
private String authorRaw;
//正文
private String content;
private String contentRaw;
//带标签正文
private String contentWithTag;
private String contentWithTagRaw;
//入库时间
private String createDate;
//信息id
private String id;
//信息来源id(信息源或者关键词)
private String sid;
//信息源分类id
private String infoSourceNatureId;
//语言
private String lang;
private String langRaw;
//来源(信息来源)
private String origin;
private String originRaw;
//发布时间
private String publishDate;
//原始时间(网页上,没有解析之前的时间)
private String originalTime;
//发布地址
private String sourceAddress;
//摘要
private String summary;
private String summaryRaw;
//关键词
private String keyWords;
//标题
private String title;
private String titleRaw;
//采集来源(如通用、定制、微信公众号等)
private String source;
//附加字段
private String type;
//视频下载链接
private String downLoadUrl;
//视频链接(原链接 网页版)
private String videoUrl;
//视频链接(原链接 手机版)
private String videoPhoneUrl;
//视频时长
private Long videoTime;
//视频第一帧图片
private String videoImg;
//自定义标签
private List<String> customLabel;
private Double score;
//专题库类型(0: 其它 1:政策;2:领导讲话;3:专家观点;4:企业案例)
private Integer classificationType;
//置顶排位(默认为0)
private Integer topNum;
//删除标记(1:删除;0:保留)
private Integer deleteFlag;
private String subjectId;
//审核操作(0:未审核 1:审核通过 2:审核未通过 3:暂定 默认值为0)
private Integer checkStatus;
//阅读数
private Long readNum = 0L;
//是否收藏
private boolean ynCollect = false;
//重复id
private String repeatId;
//(1:主条目 0:非主条目)
private String flag;
//关联的主条目id
private String masterEntryId;
//原始id(去重服务生成的id,因为一条信息可以属于多个专题,原始id会发生改变,所以存储一个原始id,找寻对应关系)
private String originalId;
//快照地址
private String screenShotImg;
//资讯更新时间
private String updateDate;
//信息类别(1:报刊 2:博客 3:客户端 4:论坛 5:视频 6:外媒 7:网站 8:微博 9:微信 10:新闻 11:政务 12:其它)
private String infoSourceType;
//舆情监测:yqjc、舆情预警:yqyj、舆情分析:yqfx、舆情报告:yqbg、竞争情报:jzqb、口碑监测:kbjc
private String dataType;
//资讯关联的附件id
private List<String> attachmentIds;
//数据入专题库时间
private String processDate;
//点赞数字
private Integer likesNum = 0;
//法规号
private String contentNo;
//用户id
private String userId;
//封面附件id
private String coverEnclosureId;
//封面图url地址
private String coverImgUrl;
//发布状态 checkStatus=1时生效(0/null:待发布 1:已发布 2:已下架 默认值为null)
private Integer publishStatus;
//关联附件id
private List<String> enclosureIds;
private String imgDisposeStatus;
/**公开方式 0会员 1公开*/
private Integer publishMethod=0;
/**栏目id*/
private List<String> columnIds;
/**抖音微博作品点赞数*/
private Integer likeNum;
/**抖音微博贴吧作品评论数*/
private Integer commentNum;
/**抖音收藏数*/
private Integer collectNum;
/**抖音微博 分享数*/
private Integer shareNum;
/**作品、帖子唯一标识*/
private String articleId;
/**作品、帖子唯一标识*/
private String index;
/**信息源类别id*/
private String infoSourceTypeId;
/**资讯是否包含图片,1:资讯包含图片 0:资讯不包含图片*/
private String isIncludeImg;
//关键词
private List<String> keyWordsList;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class SpecialInformationParam extends SpecialInformation{
//的索引名
private String dbIndex;
//查询es时需要包含的字段 多个使用,分隔
public String sourceInclude;
//查询es时需要排除的字段 多个使用,分隔
public String sourceExclude;
//舆情推送检索:yqts 舆情预警检索:yqyj
private String searchType;
//检索关键词
private String searchKey;
//分类标签id,多个使用逗号分隔
private String searchLabelIds;
//不查询的分类id,多个使用逗号分隔
private String excludeLabelIds;
//分类标签,多个使用逗号分隔
private String labelMarks;
//状态(多个使用逗号分隔)
private String findStatus;
//发布状态(多个使用逗号分隔)
private String findPublishStatus;
//情报开始时间
private String startTime;
//情报结束时间
private String endTime;
//发布开始时间
private String publishStartTime;
//发布结束时间
private String publishEndTime;
//页码
private Integer pageNo = 1;
//每页数据条数
private Integer pageSize = 10;
//排序规则
private String column = "common";
//排序方式
private String order = "desc";
//高级查询-规则
private String superQueryMatchType;
//高级查询-条件(url转码后的json)
private String superQueryParams;
//是否包含图片
private Integer hasImg;
//栏目id
private String channelId;
//栏目组id
private String channelGroupId;
//取置顶第一条数据的封面图
private Integer hasBanner;
/**舆情推送业务参数:begin*/
//前端传参,关注项id
private String attentionIds;
private String resourceCatalogId;
private String orientation;
//检索条件 用于关注栏目配置 key为栏目id,value为关注类型,0:全部 1:正面 2:中性 3:负面
private Map<String,String> attentionMap;
/**舆情推送业务参数:end*/
/**舆情预警业务参数:begin*/
/**
* 预警类型 2系统预警 3自定义预警
*/
private Integer warningType;
/**
* 信息区域
*/
private Map<String,String> articleAreaMap;
/**
* 互动数
*/
private Map<String,Integer> interactionNumberMap;
/**
* 粉丝数
*/
private Map<String,Integer> fansNumberMap;
/**
* 阅读数
*/
private Map<String,Integer> readNumberMap;
/**
* 相似文章个数
*/
private Map<String,Integer> similarNumberMap;
//检索条件 用于舆情预警配置 key为栏目id,value为舆情预警类型,0:全部 1:正面 2:中性 3:负面
private Map<String,String> pushTypeMap;
/**资讯是否包含图片,1:资讯包含图片 0:资讯不包含图片*/
private Map<String,String> isIncludeImgMap;
/**
* 精准筛选(1 开启 0 关闭)
*/
private Map<String,Integer> accurateFilterMap;
private Map<String,String> infoSourceTypeIdsMap;
/**舆情预警业务参数:end*/
/**抖音微博作品点赞数*/
private Integer likeNum;
/**抖音微博贴吧作品评论数*/
private Integer commentNum;
/**抖音收藏数*/
private Integer collectNum;
/**抖音微博 分享数*/
private Integer shareNum;
/**作品、帖子唯一标识*/
private String articleId;
/**信息源类别id*/
private String infoSourceTypeId;
/**信息源性质id*/
private String infoSourceNatureId;
/**资讯是否包含图片,1:资讯包含图片 0:资讯不包含图片*/
private String isIncludeImg;
//关键词
private List<String> keyWordsList;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.List;
/**
* @author lkg
* @description: 旧专题响应数据封装类-统计分析数据
* @date 2022/7/29 14:59
*/
@Data
public class StatisticAnalysisVo {
private String name;
private String key;
private Integer num;
List<StatisticAnalysisVo> list;
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author lkg
* @description:
* @date 2022/7/19 15:10
*/
@Data
public class SubjectDataVo {
private String id;
//关联专题id
private String subjectId;
//标题
private String title;
//摘要
private String summary;
//正文
private String content;
//带标签正文
private String contentWithTag;
//来源(信息来源)
private String origin;
//发布地址
private String sourceAddress;
//发布时间
private String publishDate;
//入库时间
private String createDate;
//(flag!=0:主条目 flag=0:非主条目)
private String flag;
//关联的主条目id
private String masterEntryId;
//原始id(去重服务生成的id,因为一条信息可以属于多个专题,原始id会发生改变,所以存储一个原始id,找寻对应关系)
private String originalId;
//关键词
private String keyWords;
//信息源类型(1:报刊 2:博客 3:客户端 4:论坛 5:视频 6:外媒 7:网站 8:微博 9:微信 10:新闻 11:政务 12:其它)
private String infoSourceType;
//重复id
private String repeatId;
public List<String> toList(){
List<String> list = new ArrayList<>();
list.add(id);
list.add(title);
list.add(summary);
list.add(content);
list.add(publishDate);
list.add(origin);
list.add(sourceAddress);
return list;
}
}
package com.zzsn.event.vo;
import lombok.Data;
import java.util.Date;
/**
* @author lkg
* @description: 专题列表信息封装-通过kafka发送给python
* @date 2022/7/21
*/
@Data
public class SubjectKafkaVo {
/*专题id*/
private String id;
/*专题名称*/
private String subjectName;
/*专题开始时间*/
private Date timeEnable;
/*专题结束*/
private Date timeDisable;
/*专题增量分析规则*/
private Integer increAnaRule;
/*专题总量分析规则*/
private Integer totalAnaRule;
/*专题时间间隔分析规则*/
private Integer timeAnaRule;
/*专题最近一次分析时间*/
private Date analysisTime;
/*分析事件脉络-最新资讯的时间*/
private Date eventTime;
/*关键词*/
private String keyWord;
/*es索引名*/
private String indexName;
/*es查询语句-查询所有*/
private String query;
/*es查询语句-查询前一天的数据*/
private String beforeQuery;
/*es查询语句-查询重复数据*/
private String repeatNumQuery;
}
package com.zzsn.event.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author lkg
* @description: 观点分析响应数据封装
* @date 2022/7/8 11:35
*/
@Data
public class ViewPointAnalysisVo {
//资讯id
private String dataId;
//标题
private String title;
//来源
private String origin;
//发布时间
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date publishDate;
//链接
private String sourceAddress;
/*重复数*/
private Integer repeatNum;
//占比
private String percentage;
//观点分析下的类型(1-新闻;2-论坛;3-微博)
private Integer type;
}
package com.zzsn.event.xxljob.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 信息源表
* @Author: jeecg-boot
* @Date: 2021-10-15
* @Version: V1.0
*/
@ApiModel(value="info_source对象", description="信息源表")
@Data
@TableName("info_source")
public class InfoSource implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**信息源编码*/
@ApiModelProperty(value = "信息源编码")
private String infoSourceCode;
/**信息源名称*/
@ApiModelProperty(value = "信息源名称")
private String webSiteName;
/**栏目名称*/
@ApiModelProperty(value = "栏目名称")
private String siteName;
/**栏目地址*/
@ApiModelProperty(value = "栏目地址")
private String siteUri;
/**网站重要级别*/
@ApiModelProperty(value = "网站重要级别")
private String siteLevel;
/**国家*/
@ApiModelProperty(value = "国家")
private String country;
/**是否境外*/
@ApiModelProperty(value = "是否境外")
private String ynOther;
/**地区*/
@ApiModelProperty(value = "地区")
private String area;
/**是否需要登录*/
@ApiModelProperty(value = "是否需要登录")
private Integer ynLogin;
/**语种*/
@ApiModelProperty(value = "语种")
private String language;
/**是否公共*/
@ApiModelProperty(value = "是否公共")
private String ynPublic;
/**是否需要翻墙*/
@ApiModelProperty(value = "是否需要翻墙")
private Integer ynAbroad;
/**是否需要代理*/
@ApiModelProperty(value = "是否需要代理")
private Integer ynAgent;
/**动态爬取*/
@ApiModelProperty(value = "动态爬取")
private Integer ynBrowser;
/**调度时间间隔*/
@ApiModelProperty(value = "调度时间间隔")
private String period;
/**调度周期(cron自动生成)*/
@ApiModelProperty(value = "调度周期(cron自动生成)")
private String cron;
/**调度周期说明*/
@ApiModelProperty(value = "调度周期说明")
private String remarkCron;
/**信息源状态*/
@ApiModelProperty(value = "信息源状态")
private Integer status;
/**网站可信度*/
@ApiModelProperty(value = "网站可信度")
private Integer siteReliability;
/**信息源综合评分*/
@ApiModelProperty(value = "信息源综合评分")
private Integer score;
/**爬取深度*/
@ApiModelProperty(value = "爬取深度")
private Integer crawlDepth;
/**爬取方式*/
@ApiModelProperty(value = "爬取方式")
private Integer crawlType;
/**历史数据URL*/
@ApiModelProperty(value = "历史数据URL")
private String hisUriExp;
/**历史数据开始时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "历史数据开始时间")
private Date hisDateStarttime;
/**历史数据结束时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "历史数据结束时间")
private Date hisDateEndtime;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
}
package com.zzsn.event.xxljob.entity;
import lombok.Data;
@Data
public class KeyWords {
/**主键*/
private String id;
/**词组编码*/
private String wordsCode;
/**词组名称*/
private String wordsName;
/**关键词*/
private String keyWord;
/**排除词*/
private String exclusionWord;
/**状态*/
private Integer status;
/**创建人*/
private String createBy;
/**创建日期*/
private java.util.Date createTime;
/**更新人*/
private String updateBy;
/**更新日期*/
private java.util.Date updateTime;
/**所属部门*/
private String sysOrgCode;
}
package com.zzsn.event.xxljob.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 定制化信息源管理表
* @Author: jeecg-boot
* @Date: 2021-11-10
* @Version: V1.0
*/
@Data
@TableName("special_info_source")
@ApiModel(value="special_info_source对象", description="定制化信息源管理表")
public class SpecialInfoSource implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**信息源编码*/
@ApiModelProperty(value = "信息源编码")
private String infoCode;
/**爬虫名称*/
@ApiModelProperty(value = "爬虫名称")
private String carwlname;
/**爬取类别*/
@ApiModelProperty(value = "爬取类别")
private String type;
/**关键词*/
@ApiModelProperty(value = "关键词")
private String keyWords;
/**调度周期*/
@ApiModelProperty(value = "调度周期")
private String cron;
/**调度时间间隔*/
@ApiModelProperty(value = "调度时间间隔")
private String period;
/**调度周期说明*/
@ApiModelProperty(value = "调度周期说明")
private String remarkCron;
/**页数*/
@ApiModelProperty(value = "页数")
private String pagenum;
/**信息源状态*/
@ApiModelProperty(value = "信息源状态")
private String status;
/**开始时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "开始时间")
private Date startTime;
/**结束时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "结束时间")
private Date endTime;
/**技术说明*/
@ApiModelProperty(value = "技术说明")
private String explanation;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
}
package com.zzsn.event.xxljob.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @Description: xxl_job_group
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@Data
@TableName("xxl_job_group")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "xxl_job_group对象", description = "xxl_job_group")
public class XxlJobGroup implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.AUTO)
@ApiModelProperty(value = "id")
private Long id;
/**
* 执行器AppName
*/
@ApiModelProperty(value = "执行器AppName")
private String appName;
/**
* 执行器名称
*/
@ApiModelProperty(value = "执行器名称")
private String title;
/**
* 执行器地址类型:0=自动注册、1=手动录入
*/
@ApiModelProperty(value = "执行器地址类型:0=自动注册、1=手动录入")
private Integer addressType;
/**
* 执行器地址列表,多地址逗号分隔
*/
@ApiModelProperty(value = "执行器地址列表,多地址逗号分隔")
private String addressList;
}
package com.zzsn.event.xxljob.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: xxl_job_info
* @Author: zhang ya nuo
* @Date: 2021-06-09
* @Version: V1.0
*/
@Data
@TableName("xxl_job_info")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "xxl_job_info对象", description = "xxl_job_info")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class XxlJobInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.AUTO)
@ApiModelProperty(value = "id")
private Long id;
/**
* 执行器主键ID
*/
@ApiModelProperty(value = "执行器主键ID")
private Long jobGroup;
/**
* 任务执行CRON
*/
@ApiModelProperty(value = "任务执行CRON")
private String jobCron;
/**
* jobDesc
*/
@ApiModelProperty(value = "jobDesc")
private String jobDesc;
/**
* addTime
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "addTime")
private Date addTime;
/**
* updateTime
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "updateTime")
private Date updateTime;
/**
* 作者
*/
@ApiModelProperty(value = "作者")
private String author;
/**
* 报警邮件
*/
@ApiModelProperty(value = "报警邮件")
private String alarmEmail;
/**
* 执行器路由策略
*/
@ApiModelProperty(value = "执行器路由策略")
private String executorRouteStrategy;
/**
* 执行器任务handler
*/
@ApiModelProperty(value = "执行器任务handler")
private String executorHandler;
/**
* 执行器任务参数
*/
@ApiModelProperty(value = "执行器任务参数")
private String executorParam;
/**
* 阻塞处理策略
*/
@ApiModelProperty(value = "阻塞处理策略")
private String executorBlockStrategy;
/**
* 任务执行超时时间,单位秒
*/
@ApiModelProperty(value = "任务执行超时时间,单位秒")
private Integer executorTimeout;
/**
* 失败重试次数
*/
@ApiModelProperty(value = "失败重试次数")
private Integer executorFailRetryCount;
/**
* GLUE类型
*/
@ApiModelProperty(value = "GLUE类型")
private String glueType;
/**
* GLUE源代码
*/
@ApiModelProperty(value = "GLUE源代码")
private String glueSource;
/**
* GLUE备注
*/
@ApiModelProperty(value = "GLUE备注")
private String glueRemark;
/**
* GLUE更新时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ApiModelProperty(value = "GLUE更新时间")
private Date glueUpdatetime;
/**
* 子任务ID,多个逗号分隔
*/
@ApiModelProperty(value = "子任务ID,多个逗号分隔")
private String childJobid;
/**
* 调度状态:0-停止,1-运行
*/
@ApiModelProperty(value = "调度状态:0-停止,1-运行")
private Integer triggerStatus;
/**
* 上次调度时间
*/
@ApiModelProperty(value = "上次调度时间")
private Long triggerLastTime;
/**
* 下次调度时间
*/
@ApiModelProperty(value = "下次调度时间")
private Long triggerNextTime;
/**
* 关联的信息源编码
*/
@ApiModelProperty(value = "关联的信息源编码")
private String infoSourceCode;
}
package com.zzsn.event.xxljob.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: xxl_job_log
* @Author: chenshiqiang
* @Date: 2023-06-21
* @Version: V1.0
*/
@Data
@TableName("xxl_job_log")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "xxl_job_log对象", description = "xxl_job_log")
public class XxlJobLog implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
// job info
private int jobGroup;
private int jobId;
// execute info
private String executorAddress;
private String executorHandler;
private String executorParam;
private String executorShardingParam;
private int executorFailRetryCount;
// trigger info
private Date triggerTime;
private int triggerCode;
private String triggerMsg;
// handle info
private Date handleTime;
private int handleCode;
private String handleMsg;
// alarm info
private int alarmStatus;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getJobGroup() {
return jobGroup;
}
public void setJobGroup(int jobGroup) {
this.jobGroup = jobGroup;
}
public int getJobId() {
return jobId;
}
public void setJobId(int jobId) {
this.jobId = jobId;
}
public String getExecutorAddress() {
return executorAddress;
}
public void setExecutorAddress(String executorAddress) {
this.executorAddress = executorAddress;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public String getExecutorShardingParam() {
return executorShardingParam;
}
public void setExecutorShardingParam(String executorShardingParam) {
this.executorShardingParam = executorShardingParam;
}
public int getExecutorFailRetryCount() {
return executorFailRetryCount;
}
public void setExecutorFailRetryCount(int executorFailRetryCount) {
this.executorFailRetryCount = executorFailRetryCount;
}
public Date getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(Date triggerTime) {
this.triggerTime = triggerTime;
}
public int getTriggerCode() {
return triggerCode;
}
public void setTriggerCode(int triggerCode) {
this.triggerCode = triggerCode;
}
public String getTriggerMsg() {
return triggerMsg;
}
public void setTriggerMsg(String triggerMsg) {
this.triggerMsg = triggerMsg;
}
public Date getHandleTime() {
return handleTime;
}
public void setHandleTime(Date handleTime) {
this.handleTime = handleTime;
}
public int getHandleCode() {
return handleCode;
}
public void setHandleCode(int handleCode) {
this.handleCode = handleCode;
}
public String getHandleMsg() {
return handleMsg;
}
public void setHandleMsg(String handleMsg) {
this.handleMsg = handleMsg;
}
public int getAlarmStatus() {
return alarmStatus;
}
public void setAlarmStatus(int alarmStatus) {
this.alarmStatus = alarmStatus;
}
}
package com.zzsn.event.xxljob.mapper;//package com.zzsn.clb.serviceproject.xxljob.mapper;
//
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.zzsn.clb.serviceproject.xxljob.entity.KeyWords;
//
///**
// * @Description: 关键词管理
// * @Author: jeecg-boot
// * @Date: 2021-11-26
// * @Version: V1.0
// */
//public interface KeyWordsMapper extends BaseMapper<KeyWords> {
//
//}
package com.zzsn.event.xxljob.mapper;//package com.zzsn.clb.serviceproject.xxljob.mapper;
//
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.zzsn.clb.serviceproject.xxljob.entity.SpecialInfoSource;
//
///**
// * @Description: 定制化信息源管理表
// * @Author: jeecg-boot
// * @Date: 2021-11-10
// * @Version: V1.0
// */
//public interface SpecialInfoSourceMapper extends BaseMapper<SpecialInfoSource> {
//
//}
package com.zzsn.event.xxljob.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.xxljob.entity.XxlJobGroup;
import org.apache.ibatis.annotations.Mapper;
/**
* @Description: xxl_job_group
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@DS("multi-datasource1")
@Mapper
public interface XxlJobGroupMapper extends BaseMapper<XxlJobGroup> {
}
package com.zzsn.event.xxljob.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zzsn.event.xxljob.entity.XxlJobInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description: xxl_job_info
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@DS("multi-datasource1")
@Mapper
public interface XxlJobInfoMapper extends BaseMapper<XxlJobInfo> {
void updateInfo(@Param("keyWordsCodes") List<String> keyWordsCodes, @Param("status") String status);
void updateCron(@Param("code") String code, @Param("cron") String cron);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.xxljob.mapper.XxlJobGroupMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzsn.event.xxljob.mapper.XxlJobInfoMapper">
<update id="updateInfo" >
UPDATE xxl_job_info
SET trigger_status = #{status}
where 1 = 1
<if test="keyWordsCodes!=null and keyWordsCodes.size()>0">
and info_source_code in
<foreach collection="keyWordsCodes" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
</update>
<update id="updateCron" >
UPDATE xxl_job_info
SET job_cron = #{cron}
where info_source_code = #{code}
</update>
</mapper>
package com.zzsn.event.xxljob.service;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.xxljob.entity.XxlJobGroup;
/**
* @Description: xxl_job_group
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@DS("multi-datasource1")
public interface IXxlJobGroupService extends IService<XxlJobGroup> {
}
package com.zzsn.event.xxljob.service;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zzsn.event.entity.Event;
import com.zzsn.event.vo.AddEventParam;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.xxljob.entity.XxlJobInfo;
import java.util.List;
/**
* @Description: xxl_job_info
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@DS("multi-datasource1")
public interface IXxlJobInfoService extends IService<XxlJobInfo> {
/**关键词增加任务*/
void keyWordsInsert(KeyWordsDTO keyWordsDTO);
/**关键词删除任务*/
void keyWordsUpdate(List<String> keyWordsCodes, String status);
/**cron更新*/
void cronUpdate(String code, String cron);
/**关键词更改任务*/
void keyWordsDelete(KeyWordsDTO keyWordsDTO);
/**专题新增任务*/
void subjectInsert(Event event);
/**专题删除任务*/
void subjectUpdate(List<String> subjectCodes, String status);
/**专题更改任务*/
void subjectDelete(Event event);
void deleteByInfosourceCode(String infosourceCode);
}
package com.zzsn.event.xxljob.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.xxljob.entity.XxlJobGroup;
import com.zzsn.event.xxljob.mapper.XxlJobGroupMapper;
import com.zzsn.event.xxljob.service.IXxlJobGroupService;
import org.springframework.stereotype.Service;
/**
* @Description: xxl_job_group
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@Service
@DS("multi-datasource1")
public class XxlJobGroupServiceImpl extends ServiceImpl<XxlJobGroupMapper, XxlJobGroup> implements IXxlJobGroupService {
}
package com.zzsn.event.xxljob.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.event.entity.Event;
import com.zzsn.event.enums.InfoSourceStatusEnum;
import com.zzsn.event.enums.XxljobInfoStatusEnum;
import com.zzsn.event.util.CronUtil;
import com.zzsn.event.vo.AddEventParam;
import com.zzsn.event.vo.KeyWordsDTO;
import com.zzsn.event.xxljob.entity.XxlJobGroup;
import com.zzsn.event.xxljob.entity.XxlJobInfo;
import com.zzsn.event.xxljob.mapper.XxlJobInfoMapper;
import com.zzsn.event.xxljob.service.IXxlJobGroupService;
import com.zzsn.event.xxljob.service.IXxlJobInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Description: xxl_job_info
* @Author: jeecg-boot
* @Date: 2021-06-09
* @Version: V1.0
*/
@Slf4j
@Service
@DS("multi-datasource1")
public class XxlJobInfoServiceImpl extends ServiceImpl<XxlJobInfoMapper, XxlJobInfo> implements IXxlJobInfoService {
@Autowired
IXxlJobInfoService xxlJobInfoService;
@Autowired
IXxlJobGroupService xxlJobGroupService;
//信息源执行器
private static final String infosourceExecutorAppname = "infosource-executor";
private static final String infosourceHandlerName = "infoSourceHandler";
private static final String alarmEmail = null;
//python信息执行器
private static final String pythonInfosourceExecutorAppname = "python-infosource-executor";
private static final String pythonInfosourceHandlerName = "pythonInfoSourceHandler";
private static final String pythonAlarmEmail = null;
//关键词执行器
private static final String keyWordsExecutorAppname = "key-words-executor";
private static final String keyWordsHandlerName = "keyWordsHandler";
private static final String keyWordsAlarmEmail = null;
//专题执行器
private static final String subjectExecutorAppname = "subject-executor";
private static final String subjectHandlerName = "subjectHandler";
private static final String subjectAlarmEmail = null;
/**
* 关键词增加任务
*/
@Override
public void keyWordsInsert(KeyWordsDTO keyWordsDTO) {
deleteByInfosourceCode(keyWordsDTO.getWordsCode());
QueryWrapper<XxlJobGroup> xxlJobGroupQueryWrapper = new QueryWrapper<>();
xxlJobGroupQueryWrapper.eq("app_name", keyWordsExecutorAppname);
xxlJobGroupQueryWrapper.last("limit 1");
XxlJobGroup xxlJobGroup = xxlJobGroupService.getOne(xxlJobGroupQueryWrapper);
XxlJobInfo xxlJobInfo = new XxlJobInfo();
if (ObjectUtils.isEmpty(xxlJobGroup)) {
log.error("信息源执行器没有找到, 执行器名称=[{}]", keyWordsExecutorAppname);
// 默认执行器
xxlJobInfo.setJobGroup(-1L);
} else {
// 执行器
xxlJobInfo.setJobGroup(xxlJobGroup.getId());
}
//获取随机时间的间隔
String cron = CronUtil.getRandomCron();
xxlJobInfo.setJobCron(cron);
// 任务描述
xxlJobInfo.setJobDesc("任务名称为:" + keyWordsDTO.getWordsName() + ";关键词编码为:" + keyWordsDTO.getWordsCode());
xxlJobInfo.setAddTime(new Date());
xxlJobInfo.setUpdateTime(new Date());
xxlJobInfo.setAuthor("task-infosource-task-modify");
// 需要在yaml做配置
xxlJobInfo.setAlarmEmail("");
// 路由策略: 第一个
xxlJobInfo.setExecutorRouteStrategy("FIRST");
// JobHandler
xxlJobInfo.setExecutorHandler(keyWordsHandlerName);
// 任务参数
xxlJobInfo.setExecutorParam(keyWordsDTO.getWordsCode());
// 阻塞处理策略: 单机串行
xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
// 运行模式
xxlJobInfo.setGlueType("BEAN");
// 任务超时时间
xxlJobInfo.setExecutorTimeout(0);
// 失败重试次数
xxlJobInfo.setExecutorFailRetryCount(0);
xxlJobInfo.setGlueUpdatetime(new Date());
if (keyWordsDTO.getStatus().equals(InfoSourceStatusEnum.ENABLE.getvalue())) {
xxlJobInfo.setTriggerStatus(XxljobInfoStatusEnum.RUNNING.getvalue());
} else {
xxlJobInfo.setTriggerStatus(XxljobInfoStatusEnum.STOP.getvalue());
}
// 关联的信息源编码
xxlJobInfo.setInfoSourceCode(keyWordsDTO.getWordsCode());
xxlJobInfoService.save(xxlJobInfo);
}
/**
* 关键词删除任务
*/
@Override
public void keyWordsUpdate(List<String> keyWordsCodes, String status) {
if (StringUtils.isEmpty(status)) {
status = "0";
}
baseMapper.updateInfo(keyWordsCodes, status);
log.info("修改xxljob任务成功, keyWordsCode=[{}]", keyWordsCodes.toString());
}
@Override
public void cronUpdate(String code, String cron) {
baseMapper.updateCron(code, cron);
}
/**
* 关键词更改任务
*/
@Override
public void keyWordsDelete(KeyWordsDTO keyWordsDTO) {
deleteByInfosourceCode(keyWordsDTO.getWordsCode());
}
/**
* 关键词增加任务
*/
@Override
public void subjectInsert(Event event) {
deleteByInfosourceCode(event.getEventCode());
QueryWrapper<XxlJobGroup> xxlJobGroupQueryWrapper = new QueryWrapper<>();
xxlJobGroupQueryWrapper.eq("app_name", subjectExecutorAppname);
xxlJobGroupQueryWrapper.last("limit 1");
XxlJobGroup xxlJobGroup = xxlJobGroupService.getOne(xxlJobGroupQueryWrapper);
XxlJobInfo xxlJobInfo = new XxlJobInfo();
if (ObjectUtils.isEmpty(xxlJobGroup)) {
log.error("信息源执行器没有找到, 执行器名称=[{}]", subjectExecutorAppname);
// 默认执行器
xxlJobInfo.setJobGroup(-1L);
} else {
// 执行器
xxlJobInfo.setJobGroup(xxlJobGroup.getId());
}
xxlJobInfo.setJobCron(event.getCron());
// 任务描述
xxlJobInfo.setJobDesc("任务名称为:" + event.getEventName() + ";专题编码为:" + event.getEventCode());
xxlJobInfo.setAddTime(new Date());
xxlJobInfo.setUpdateTime(new Date());
xxlJobInfo.setAuthor("admin");
// 需要在yaml做配置
xxlJobInfo.setAlarmEmail("");
// 路由策略: 第一个
xxlJobInfo.setExecutorRouteStrategy("FIRST");
// JobHandler
xxlJobInfo.setExecutorHandler(subjectHandlerName);
// 任务参数
xxlJobInfo.setExecutorParam(event.getEventCode());
// 阻塞处理策略: 单机串行
xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
// 运行模式
xxlJobInfo.setGlueType("BEAN");
// 任务超时时间
xxlJobInfo.setExecutorTimeout(0);
// 失败重试次数
xxlJobInfo.setExecutorFailRetryCount(0);
xxlJobInfo.setGlueUpdatetime(new Date());
if (event.getStatus() != null && event.getStatus() == 1) {
xxlJobInfo.setTriggerStatus(XxljobInfoStatusEnum.RUNNING.getvalue());
} else {
xxlJobInfo.setTriggerStatus(XxljobInfoStatusEnum.STOP.getvalue());
}
// 关联的信息源编码
xxlJobInfo.setInfoSourceCode(event.getEventCode());
xxlJobInfoService.save(xxlJobInfo);
}
/**
* 关键词删除任务
*/
@Override
public void subjectUpdate(List<String> subjectCodes, String status) {
if (StringUtils.isEmpty(status)) {
status = "0";
}
baseMapper.updateInfo(subjectCodes, status);
log.info("修改xxljob任务成功, keyWordsCode=[{}]", subjectCodes.toString());
}
/**
* 关键词更改任务
*/
@Override
public void subjectDelete(Event event) {
deleteByInfosourceCode(event.getEventCode());
}
@Override
public void deleteByInfosourceCode(String infosourceCode) {
// 这里必须判空,否则会误删很多task
if (!ObjectUtils.isEmpty(infosourceCode)) {
QueryWrapper<XxlJobInfo> xxlJobInfoQueryWrapper = new QueryWrapper<>();
xxlJobInfoQueryWrapper.eq("info_source_code", infosourceCode);
xxlJobInfoService.remove(xxlJobInfoQueryWrapper);
}
}
}
server: server:
port: 9088 port: 1688
spring: spring:
servlet: servlet:
...@@ -7,9 +7,50 @@ spring: ...@@ -7,9 +7,50 @@ spring:
max-request-size: 1024MB max-request-size: 1024MB
max-file-size: 100MB max-file-size: 100MB
datasource: datasource:
url: jdbc:mysql://114.116.44.11:3306/clb_project?useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true druid:
username: ciglobal stat-view-servlet:
password: qwer@9988&zzsn enabled: true
loginUsername: admin
loginPassword: 123456
allow:
web-stat-filter:
enabled: true
dynamic:
druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 10
maxActive: 100
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 600000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://114.116.44.11:3306/clb_project?useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true
username: ciglobal
password: qwer@9988&zzsn
# 多数据源配置
multi-datasource1:
url: jdbc:mysql://114.116.44.11:3306/clb_xxl_job?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: ciglobal
password: qwer@9988&zzsn
driver-class-name: com.mysql.cj.jdbc.Driver
elasticsearch: elasticsearch:
rest: rest:
uris: ["114.116.90.53:9200"] uris: ["114.116.90.53:9200"]
...@@ -34,11 +75,42 @@ spring: ...@@ -34,11 +75,42 @@ spring:
shutdown-timeout: 100ms shutdown-timeout: 100ms
port: 6380 port: 6380
password: clbzzsn password: clbzzsn
kafka:
bootstrap-servers: 114.115.159.144:9092
producer: # 生产者
retries: 3 # 设置大于0的值,则客户端会将发送失败的记录重新发送
batch-size: 16384
buffer-memory: 335544324
acks: 1
# 指定消息key和消息体的编解码方式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# listener:
# ack-mode: manual_immediate
consumer:
#用于标识此使用者所属的使用者组的唯一字符串
group-id: subject-analysis-group
#当Kafka中没有初始偏移量或者服务器上不再存在当前偏移量时该怎么办,默认值为latest,表示自动将偏移重置为最新的偏移量
#可选的值为latest, earliest, none
auto-offset-reset: latest
#消费者的偏移量将在后台定期提交,默认值为true
enable-auto-commit: true
#如果'enable-auto-commit'为true,则消费者偏移自动提交给Kafka的频率(以毫秒为单位),默认值为5000。
auto-commit-interval: 100
#密钥的反序列化器类,实现类实现了接口org.apache.kafka.common.serialization.Deserializer
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
#值的反序列化器类,实现类实现了接口org.apache.kafka.common.serialization.Deserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
thymeleaf: thymeleaf:
prefix: classpath:/templates prefix: classpath:/templates
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:com/zzsn/event/mapper/xml/*.xml,classpath*:com/zzsn/event/xxljob/mapper/xml/*.xml
configuration: configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
serviceProject:
url: https://clb.ciglobal.cn/clb-api/
#热词抽取地址
hotWords:
extractUrl: http://114.116.99.6:8055/task/dispose/extractKeyword
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论