Commit a4169b6d by shenjunjie

Merge branch 'feature' into 'dev'

Feature

See merge request !26
parents 40571620 aaeb0883
package com.zhiwei.brandkbs2.common;
import com.zhiwei.brandkbs2.pojo.ChannelTag;
import com.zhiwei.brandkbs2.service.SystemInfoService;
import com.zhiwei.qbjc.bean.pojo.common.MessagePlatform;
import com.zhiwei.qbjc.bean.pojo.common.Tag;
......@@ -38,6 +39,14 @@ public class GlobalPojo {
**/
public static Map<String, List<Tag>> TAGS;
public static Map<String, String> CHANNEL_TAGS;
/**
* 渠道类型(划分重要渠道)
*/
public static Map<String, Map<String, String>> MEDIA_TYPE;
@PostConstruct
public void start() {
try {
......@@ -60,12 +69,14 @@ public class GlobalPojo {
private void updatePojo(String logMsg) {
PLATFORMS = systemInfoService.getPlatforms();
TAGS = systemInfoService.getTags().stream().collect(Collectors.groupingBy(Tag::getGroupName));
log.info("{}-获取PLATFORMS-size:{},TAGS-size:{}", logMsg, PLATFORMS.size(), TAGS.size());
CHANNEL_TAGS = systemInfoService.getChannelTags().stream().collect(Collectors.toMap(ChannelTag::getChannel, ChannelTag::getTag));
MEDIA_TYPE = systemInfoService.getMediaTypes();
log.info("{}-获取PLATFORMS-size:{},TAGS-size:{},CHANNEL_TAGS:{}", logMsg, PLATFORMS.size(), TAGS.size(), CHANNEL_TAGS.size());
}
public static String getPlatformIdByName(String platformName){
public static String getPlatformIdByName(String platformName) {
for (MessagePlatform platform : PLATFORMS) {
if(platform.getName().equals(platformName)){
if (platform.getName().equals(platformName)) {
return platform.getId();
}
}
......@@ -81,4 +92,8 @@ public class GlobalPojo {
return null;
}
public static String getMediaType(String projectId, String platform, String source) {
return MEDIA_TYPE.get(projectId).get(platform + source);
}
}
......@@ -17,6 +17,24 @@ public class RedisKeyPrefix {
private static final String SEPARATOR = ":";
/**
* 首页相关缓存KEY
*/
public static final String INDEX_YUQING = "BRANDKBS:INDEX:YUQING:";
public static final String INDEX_REPUTATION = "BRANDKBS:INDEX:REPUTATION:";
public static final String INDEX_EVENT = "BRANDKBS:INDEX:EVENT:";
public static final String INDEX_PLATFORM = "BRANDKBS:INDEX:PLATFORM:";
public static final String INDEX_SPREAD = "BRANDKBS:INDEX:SPREAD:";
public static final String INDEX_COMPARE_SUMMARY_MOBILE = "BRANDKBS:INDEX:COMPARE_SUMMARY:MOBILE:";
/**
* 竞品库-获取竞品对比舆情解读数据(PC
*/
public static final String INDEX_COMPARE_SUMMARY_PC = "BRANDKBS:CONTEND:COMPARE_SUMMARY:PC:";
/**
* 竞品库-获取竞品对比传播分析数据
*/
public static final String INDEX_COMPARE_ANALYZE = "BRANDKBS:CONTEND:COMPARE_ANALYZE:";
public static final String MARK_ANALYZE_SUMMARY = "BRANDKBS:MARK:ANALYZE_SUMMARY:";
public static final String MARK_PLATFORM_PROPORTION = "BRANDKBS:MARK:PLATFORM_PROPORTION:";
public static final String MARK_SPREAD = "BRANDKBS:MARK:SPREAD:";
......@@ -60,16 +78,6 @@ public class RedisKeyPrefix {
*/
private static final String EVENT_ANALYZE_PROGRESS = "BRANDKBS:EVENT:ANALYZE:PROGRESS:";
/**
* 竞品库-获取竞品对比舆情解读数据(PC
*/
public static final String INDEX_COMPARE_SUMMARY_PC = "BRANDKBS:CONTEND:COMPARESUMMARY:PC:";
/**
* 竞品库-获取竞品对比传播分析数据
*/
public static final String INDEX_COMPARE_ANALYZE = "BRANDKBS:CONTEND:COMPAREANALYZE:";
public static String eventAnalysisProgress(String eventId, String projectId) {
return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, projectId, eventId);
}
......
......@@ -19,9 +19,11 @@ public class Constant {
public static final String HOUR_PATTERN = "yyyy-MM-dd HH";
public static final String DAY_PATTERN = "yyyy-MM-dd";
public static final String MONTH_PATTERN = "yyyy-MM";
public static final String YEAR_PATTERN = "yyyy";
public static final FastDateFormat HOUR_FORMAT = FastDateFormat.getInstance(HOUR_PATTERN);
public static final FastDateFormat DAY_FORMAT = FastDateFormat.getInstance(DAY_PATTERN);
public static final FastDateFormat SPEC_DAY_FORMAT = FastDateFormat.getInstance("yyyy/MM/dd");
public static final FastDateFormat MONTH_FORMAT = FastDateFormat.getInstance(MONTH_PATTERN);
/**
......@@ -55,5 +57,5 @@ public class Constant {
/**
* 主品牌默认竞品ID
*/
public static final String PRIMARY_CONTENDID = "0";
public static final String PRIMARY_CONTEND_ID = "0";
}
......@@ -222,9 +222,9 @@ public class EventController extends BaseController {
@ApiImplicitParams({@ApiImplicitParam(name = "list", paramType = "body", dataType = "list"), @ApiImplicitParam(name = "linkedGroupId", value = "关联项目id", paramType = "body", dataType = "string")})
@PutMapping("/upload/yq")
public ResponseResult addEventsByYq(@RequestBody JSONObject info) {
String linkedGroupId = info.getString("linkedGroupId");
String contendId = null == info.getString("contendId") ? "0" : info.getString("contendId");
List<YqEventDTO> yqEventList = info.getJSONArray("list").toJavaList(YqEventDTO.class);
eventService.addYqEvents(linkedGroupId, yqEventList);
eventService.addYqEvents(contendId, yqEventList);
behaviorService.pushBehavior(OPERATION, "批量导入舆情事件数据", request);
return ResponseResult.success();
}
......@@ -238,21 +238,22 @@ public class EventController extends BaseController {
}
@ApiOperation("文件上传事件")
@ApiImplicitParams({@ApiImplicitParam(name = "linkedGroupId", value = "关联项目组id", paramType = "form", dataType = "string"), @ApiImplicitParam(name = "fileUrl", value = "文件路径", required = true, paramType = "form", dataType = "string")})
@ApiImplicitParams({@ApiImplicitParam(name = "contendId", value = "竞品id", paramType = "form", dataType = "string"), @ApiImplicitParam(name = "fileUrl",
value = "文件路径", required = true, paramType = "form", dataType = "string")})
@PostMapping(value = "/upload/file", headers = "content-type=multipart/form-data")
@Auth(role = RoleEnum.SUPER_ADMIN)
public ResponseResult addEventsByFile(@RequestParam(value = "linkedGroupId") String linkedGroupId, @RequestParam("fileUrl") String fileUrl) {
eventService.addFileEvents(linkedGroupId, fileUrl);
public ResponseResult addEventsByFile(@RequestParam(value = "contendId",defaultValue = "0") String contendId, @RequestParam("fileUrl") String fileUrl) {
eventService.addFileEvents(contendId, fileUrl);
behaviorService.pushBehavior(OPERATION, "文件上传事件", request);
return ResponseResult.success();
}
@ApiOperation("事件数据上传")
@ApiImplicitParams({@ApiImplicitParam(name = "file", value = "上传表格", paramType = "form", dataType = "multipartFile"), @ApiImplicitParam(name =
"linkedGroupId", value = "关联项目id", paramType = "form", dataType = "string")})
"contendId", value = "竞品id", paramType = "form", dataType = "string")})
@PostMapping(value = "/data/upload", headers = "content-type=multipart/form-data")
public ResponseResult uploadEventDatas(@RequestParam("linkedGroupId") String linkedGroupId, @RequestParam("file") MultipartFile file) {
eventService.uploadEventDatas(linkedGroupId, file);
public ResponseResult uploadEventDatas(@RequestParam(value = "contendId",defaultValue = "0") String contendId, @RequestParam("file") MultipartFile file) {
eventService.uploadEventDatas(contendId, file);
behaviorService.pushBehavior(OPERATION, "事件数据上传", request);
return ResponseResult.success();
}
......
......@@ -2,14 +2,17 @@ package com.zhiwei.brandkbs2.controller.app;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.easyexcel.EasyExcelUtil;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.service.MarkDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
......@@ -34,26 +37,33 @@ public class AppContendController extends BaseController {
@ApiOperation("竞品库-竞品舆情-搜索条件")
@GetMapping("/searchCriteria")
public ResponseResult getContendSearchCriteria(@RequestParam(required = false) String linkedGroupId) {
return ResponseResult.success(markDataService.getContendSearchCriteria(linkedGroupId));
public ResponseResult getContendSearchCriteria(@RequestParam(required = false) String contendId) {
return ResponseResult.success(markDataService.getContendSearchCriteria(contendId));
}
@ApiOperation("竞品库-竞品舆情-搜索结果列表")
@GetMapping("/list")
@PostMapping("/list")
public ResponseResult getContendSearchList(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSearchList(markSearchDTO));
}
@ApiOperation("竞品库-竞品分析-舆情总结页面")
@GetMapping("/summary")
@PostMapping("/summary")
public ResponseResult getSummary(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSummary(markSearchDTO, true));
return ResponseResult.success(markDataService.getContendSummary(markSearchDTO, true)); // 测试时关闭缓存,记得打开
}
@ApiOperation("竞品库-竞品对比-传播分析页面")
@GetMapping("/spread/analyze")
@PostMapping("/spread/analyze")
public ResponseResult getSpreadAnalyze(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSpreadAnalyze(markSearchDTO, 5, true));
return ResponseResult.success(markDataService.getContendSpreadAnalyze(markSearchDTO, 5, true)); // 测试时关闭缓存,记得打开
}
@ApiOperation("竞品库-竞品舆情-舆情导出")
@PostMapping(value = "/list/export")
public ResponseResult exportContendMarkList(@RequestBody MarkSearchDTO markSearchDTO) {
Pair<String, List<ExportAppYuqingDTO>> stringListPair = markDataService.downloadContendMarkList(markSearchDTO);
EasyExcelUtil.download(stringListPair.getLeft() + "_舆情列表数据", "sheet1", ExportAppYuqingDTO.class, stringListPair.getRight(), response);
return ResponseResult.success();
}
}
......@@ -6,6 +6,7 @@ import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.pojo.dto.EventSearchDTO;
import com.zhiwei.brandkbs2.service.EventService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
......@@ -56,15 +57,9 @@ public class AppEventController extends BaseController {
}
@ApiOperation("前台事件库-品牌事件库")
@GetMapping("/list")
public ResponseResult getEventList(@RequestParam(value = "contendId", defaultValue = "0") String contendId,
@RequestParam(value = "emotion", defaultValue = "全部") String emotion,
@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime,
@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "pageSize", defaultValue = "50") int pageSize,
@RequestParam(value = "sorter", required = false) String sorter) {
return ResponseResult.success(eventService.getEventList(contendId, emotion, startTime, endTime, page, pageSize, sorter));
@PostMapping("/list")
public ResponseResult getEventList(@RequestBody EventSearchDTO eventSearchDTO) {
return ResponseResult.success(eventService.getEventList(eventSearchDTO));
}
@ApiOperation("前台事件库-事件详情-基础信息")
......
......@@ -125,14 +125,14 @@ public class AppHotController extends BaseController {
Date startDate = DateUtils.addHours(endDate, -24);
List<Map.Entry<String, Integer>> markTopTitleList =
markDataService.getMarkTopTitle(startDate.getTime(), endDate.getTime(), null, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, size);
markDataService.getMarkTopTitle(startDate.getTime(), endDate.getTime(), null, projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID, size);
List<JSONObject> resultList = markTopTitleList.stream().map(map -> {
JSONObject resultJsonObject = new JSONObject();
resultJsonObject.put("title", map.getKey());
resultJsonObject.put("num", map.getValue());
try {
BaseMap firstArticle = markDataService.getFirstArticle(startDate.getTime(), endDate.getTime(), map.getKey(), projectId, linkedGroupId, Constant.PRIMARY_CONTENDID);
BaseMap firstArticle = markDataService.getFirstArticle(startDate.getTime(), endDate.getTime(), map.getKey(), projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID);
resultJsonObject.put("content", firstArticle.getContent());
resultJsonObject.put("url", firstArticle.getUrl());
resultJsonObject.put("realSource", firstArticle.getRealSource());
......
package com.zhiwei.brandkbs2.controller.app;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.service.IndexService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
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.annotation.Resource;
/**
* @author lxj
* @version 1.0
* @description 前台首页展示接口
* @date 2019/9/11 14:38
*/
@RestController
@RequestMapping("/app/index")
@Api(tags = "前台首页展示接口", description = "提供前台首页相关信息展示")
@Auth(role = RoleEnum.CUSTOMER)
public class AppIndexController extends BaseController {
@Resource
private IndexService indexService;
@ApiOperation("首页-舆情总量")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "long")
})
@GetMapping("/yuqing-amount")
public ResponseResult getYuqingAmount(@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime) {
return ResponseResult.success(indexService.getYuqingAmount(startTime, endTime, true));
}
@ApiOperation("首页-美誉度")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "long")
})
@GetMapping("/reputation")
public ResponseResult getReputation(@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime) {
return ResponseResult.success(indexService.getReputation(startTime, endTime, true));
}
@ApiOperation("首页-事件数")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "long")
})
@GetMapping("/event-amount")
public ResponseResult getEvent(@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime) {
return ResponseResult.success(indexService.getEventAmount(startTime, endTime, true));
}
@ApiOperation("首页-平台贡献信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "long")
})
@GetMapping("/platform-info")
public ResponseResult getPlatformInfo(@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime) {
return ResponseResult.success(indexService.getPlatformInfo(startTime, endTime, true));
}
@ApiOperation("传播趋势")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "long")
})
@GetMapping("/spreadingTend")
public ResponseResult getSpreadingTend(@RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime) {
return ResponseResult.success(indexService.getSpreadingTend(startTime, endTime, true));
}
}
......@@ -49,9 +49,9 @@ public class AppSearchController {
@RequestParam(value = "type",defaultValue = "weibo") String type,
@RequestParam(value = "word") String word){
ResponseEntity<JSONObject> jsonObjectResponseEntity = restTemplate.getForEntity(trendsSearchUrl, JSONObject.class, limit, page, type, word);
JSONObject body = jsonObjectResponseEntity.getBody();
if(Objects.nonNull(body)){
return ResponseResult.success(body);
JSONObject result = jsonObjectResponseEntity.getBody();
if(Objects.nonNull(result)){
return ResponseResult.success(result);
}else{
return ResponseResult.failure("响应超时");
}
......@@ -63,8 +63,8 @@ public class AppSearchController {
@RequestParam(value = "pageSize",defaultValue = "3") Integer pageSize,
@RequestParam("keyword") String keyword){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisSearchUrl, String.class, page, pageSize, keyword);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
Object result = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(result);
}
@ApiOperation("搜索-全网事件库-查事件")
......@@ -73,7 +73,7 @@ public class AppSearchController {
@RequestParam(value = "page",defaultValue = "1") Integer page){
String name = keyword.trim();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchUrl, String.class, name, page);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject);
JSONObject result = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(result);
}
}
......@@ -27,12 +27,12 @@ public interface EventDao extends BaseMongoDao<Event> {
/**
* 根据联合id查询事件
*
* @param yqEventId 舆情事件id
* @param projectId 项目id
* @param linkedGroupId 关联项目id
* @param yqEventId 舆情事件id
* @param projectId 项目id
* @param contendId 竞品id
* @return 事件
*/
Event getEventByUniqueIds(String yqEventId, String projectId, String linkedGroupId);
Event getEventByUniqueIds(String yqEventId, String projectId, String contendId);
/**
......@@ -41,7 +41,7 @@ public interface EventDao extends BaseMongoDao<Event> {
* @param channelIndex 渠道标识
* @return 参与事件数
*/
List<String> getEventCount(ChannelIndex channelIndex);
List<String> getEvents(ChannelIndex channelIndex);
/**
......@@ -63,11 +63,35 @@ public interface EventDao extends BaseMongoDao<Event> {
/**
* 获取参与的反常事件数
*
* @param channelIndex 渠道标识
* @param eventEmotions 事件情感倾向
* @param channelIndex 渠道标识
* @param eventEmotions 事件情感倾向
* @param articleEmotion 文章情感倾向
* @return 参与的反常事件数
*/
long getEventCount(ChannelIndex channelIndex, List<String> eventEmotions, String articleEmotion);
/**
* 根据特征值获取事件数
*
* @param startTime
* @param endTime
* @param emotion
* @param projectId
* @param contendId
* @return
*/
long getEventCountByProjectIdAndContendId(Long startTime, Long endTime, String emotion, String projectId, String contendId);
/**
* 根据特征值获取事件
*
* @param startTime
* @param endTime
* @param emotion
* @param projectId
* @param contendId
* @return
*/
List<Event> getEventsByProjectIdAndContendId(Long startTime, Long endTime, String emotion, String projectId, String contendId, int limit);
}
......@@ -9,4 +9,6 @@ import com.zhiwei.brandkbs2.pojo.EventTopArticlesAnalysis;
*/
public interface EventTopArticlesAnalysisDao extends BaseMongoDao<EventTopArticlesAnalysis>{
void deleteByEventId(String eventId);
}
......@@ -3,9 +3,11 @@ package com.zhiwei.brandkbs2.dao.impl;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.enmus.EmotionEnum;
import com.zhiwei.brandkbs2.pojo.ChannelIndex;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.util.Tools;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
......@@ -34,25 +36,28 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
}
@Override
public boolean existEventByUniqueIds(String yqEventId, String projectId, String linkedGroupId) {
return null != getEventByUniqueIds(yqEventId, projectId, linkedGroupId);
public boolean existEventByUniqueIds(String yqEventId, String projectId, String contendId) {
return null != getEventByUniqueIds(yqEventId, projectId, contendId);
}
@Override
public Event getEventByUniqueIds(String yqEventId, String projectId, String linkedGroupId) {
public Event getEventByUniqueIds(String yqEventId, String projectId, String contendId) {
Query query = new Query();
query.addCriteria(Criteria.where("yqEventId").is(yqEventId).and("projectId").is(projectId).and("linkedGroupId").is(linkedGroupId));
query.addCriteria(Criteria.where("yqEventId").is(yqEventId).and("projectId").is(projectId).and("contendId").is(contendId));
return mongoTemplate.findOne(query, Event.class);
}
@Override
public List<String> getEventCount(ChannelIndex channelIndex) {
public List<String> getEvents(ChannelIndex channelIndex) {
// 添加渠道唯一标识
Criteria criteria = addChannelIndex(channelIndex);
// 分组
Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), Aggregation.group("eventId").count().as("eventCount"));
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, getAggreeCollection(), JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
List<JSONObject> mappedResults = new ArrayList<>();
for (String aggreeCollection : getAggreeCollections(3)) {
// 分组
Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), Aggregation.group("eventId").count().as("eventCount"));
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, aggreeCollection, JSONObject.class);
mappedResults.addAll(aggregate.getMappedResults());
}
return mappedResults.stream().map(json -> json.getString("_id")).collect(Collectors.toList());
}
......@@ -68,6 +73,65 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
@Override
public long getEventCount(ChannelIndex channelIndex, List<String> eventEmotions, String emotion) {
long res = 0;
Criteria criteria = Criteria.where("channelFid").is(channelIndex.getFid());
if (null != eventEmotions) {
criteria.and("eventMapper.emotion").in(eventEmotions);
}
if (null != emotion) {
criteria.and("emotion").is(emotion);
}
for (String aggreeCollection : getAggreeCollections(3)) {
Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), Aggregation.group("eventId").count().as("eventCount"));
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, aggreeCollection, JSONObject.class);
res += aggregate.getMappedResults().size();
}
return res;
}
@Override
public long getEventCountByProjectIdAndContendId(Long startTime, Long endTime, String emotion, String projectId, String contendId) {
return mongoTemplate.count(Query.query(eventCountCriteria(startTime, endTime, emotion, projectId, contendId)), COLLECTION_NAME);
}
@Override
public List<Event> getEventsByProjectIdAndContendId(Long startTime, Long endTime, String emotion, String projectId, String contendId, int limit) {
Query query = new Query();
Criteria criteria = eventCountCriteria(startTime, endTime, emotion, projectId, contendId);
query.addCriteria(criteria);
query.limit(limit);
// 按影响力排序
addSort(query, "{\"influence\":\"descend\"}");
return mongoTemplate.find(query, clazz, COLLECTION_NAME);
}
private Criteria eventCountCriteria(Long startTime, Long endTime, String emotion, String projectId, String contendId) {
Criteria criteria = Criteria.where("projectId").is(projectId);
criteria.and("contendId").is(contendId);
Criteria startTimeCriteria = criteria.and("startTime");
if (null != startTime) {
startTimeCriteria.gte(startTime);
}
if (null != endTime) {
startTimeCriteria.lt(endTime);
}
if (StringUtils.isNotEmpty(emotion) && !EmotionEnum.ALL.getName().equals(emotion)) {
criteria.and("emotion").is(emotion);
}
return criteria;
}
/**
* mongo版本不支持toString/toObjectId 表达式
* 已被getEventCount 代替
*
* @param channelIndex
* @param eventEmotions
* @param emotion
* @return
*/
@Deprecated
private long getEventCountOrigin(ChannelIndex channelIndex, List<String> eventEmotions, String emotion) {
String primaryCollection = getAggreeCollection();
Criteria criteria = Criteria.where("channelFid").is(channelIndex.getFid());
if (null != emotion) {
......@@ -75,10 +139,7 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
}
String aliasName = "events";
Criteria lookUpCriteria = Criteria.where(aliasName + ".emotion").in(eventEmotions);
List<AggregationOperation> operations = Arrays.asList(Aggregation.match(criteria),
Aggregation.lookup(COLLECTION_NAME, "eventId", "_id", aliasName),
Aggregation.match(lookUpCriteria),
Aggregation.project("events._id"));
List<AggregationOperation> operations = Arrays.asList(Aggregation.match(criteria), Aggregation.lookup(COLLECTION_NAME, "eventId", "_id", aliasName), Aggregation.match(lookUpCriteria), Aggregation.project("events._id"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(aggregation, primaryCollection, JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
......@@ -87,6 +148,7 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
/**
* 以事件为主表联合查询 应用于getEventCount,已被替代
*
* @param channelIndex
* @param eventEmotions
* @param emotion
......@@ -116,9 +178,7 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
Criteria lookUpCriteria = Criteria.where(aliasName.concat(".channelFid")).is(channelIndex.getFid());
// 分组
Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria), Aggregation.project("startTime", "_id", "emotion", "influence", "title", "endTime", "eventTag"),
// 想通过截取的方式来分组,但是会有8小时误差问题未解决,故舍弃
// .andExpression("add(new java.util.Date(8),startTime)").substring(0, nrOfChars).as("patternDate"),
Aggregation.lookup(getAggreeCollection(), "_id", "eventId", aliasName), Aggregation.match(lookUpCriteria));
Aggregation.lookup(getAggreeCollection(), "_id", "eventMapper.id", aliasName), Aggregation.match(lookUpCriteria));
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, COLLECTION_NAME, JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
for (JSONObject mappedResult : mappedResults) {
......@@ -142,10 +202,18 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
return res;
}
private String getAggreeCollection() {
private List<String> getAggreeCollections(int years) {
List<String> res = new ArrayList<>();
Calendar date = Calendar.getInstance();
int year = date.get(Calendar.YEAR);
return COLLECTION_PREFIX + "_" + year;
for (int i = 0; i < years; i++) {
res.add(COLLECTION_PREFIX + (year - i));
}
return res;
}
private String getAggreeCollection() {
return getAggreeCollections(1).get(0);
}
}
......@@ -3,6 +3,8 @@ package com.zhiwei.brandkbs2.dao.impl;
import com.zhiwei.brandkbs2.dao.EventTopArticlesAnalysisDao;
import com.zhiwei.brandkbs2.pojo.EventTopArticlesAnalysis;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
/**
......@@ -17,4 +19,9 @@ public class EventTopArticlesAnalysisDaoImpl extends BaseMongoDaoImpl<EventTopAr
public EventTopArticlesAnalysisDaoImpl() {
super(COLLECTION_NAME);
}
@Override
public void deleteByEventId(String eventId) {
mongoTemplate.remove(Query.query(Criteria.where("eventId").is(eventId)), COLLECTION_NAME);
}
}
package com.zhiwei.brandkbs2.easyexcel.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
import com.zhiwei.brandkbs2.util.Tools;
import lombok.Data;
import lombok.ToString;
import org.apache.logging.log4j.util.Strings;
import org.bson.types.ObjectId;
import java.util.Date;
import java.util.Optional;
/**
* @ClassName: UploadEventDataDTO
......@@ -61,36 +53,5 @@ public class UploadEventDataDTO {
@ExcelProperty("原创/转发(微博平台)")
private boolean isForward;
/**
* 表格解析后的数据转换为事件数据传输格式
*
* @return 事件数据传输格式
*/
public EventData createEventData(Event event) {
EventData eventData = new EventData();
eventData.setPlatform(this.getPlatform());
eventData.setRealSource(this.getRealSource());
eventData.setSource(this.getSource());
eventData.setUrl(this.getUrl());
eventData.setTime(this.getTime().getTime());
//如果标题不为空,取前64个字符作为标题,如果为空,取内容的前32位作为标题
eventData.setTitle(Strings.isNotBlank(title) ? (title.length() > 64 ? title.substring(0, 64) : title) : content.length() > 32 ? content.substring(0, 32) : content);
eventData.setAggTitle(Tools.filterSpecialCharacter(title));
eventData.setContent(content);
eventData.setTime(this.getTime().getTime());
JSONObject tagInfo = new JSONObject();
Optional.ofNullable(this.getEmotion()).ifPresent(emotion -> tagInfo.put(Constant.EMOTION_LABEL_KEY, emotion));
Optional.ofNullable(this.getBrand()).ifPresent(brand -> tagInfo.put(Constant.BRAND_LABEL_KEY, brand));
eventData.setTagInfo(tagInfo);
eventData.setEmotion(this.getEmotion());
eventData.setForward(this.isForward);
eventData.setEventId(new ObjectId(event.getId()));
eventData.setProjectId(event.getProjectId());
eventData.setLinkedGroupId(event.getLinkedGroupId());
eventData.setCTime(System.currentTimeMillis());
// TODO Type字段类型是否需要???
return eventData;
}
}
......@@ -5,10 +5,8 @@ import com.alibaba.excel.event.AnalysisEventListener;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.dao.EventDataDao;
import com.zhiwei.brandkbs2.easyexcel.dto.UploadEventDataDTO;
import com.zhiwei.brandkbs2.listener.ApplicationProjectListener;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.redis.core.StringRedisTemplate;
......@@ -27,15 +25,15 @@ public class EventDataListener extends AnalysisEventListener<UploadEventDataDTO>
private final StringRedisTemplate stringRedisTemplate;
private final String linkedGroupId;
private final String contendId;
private final String redisKey;
public EventDataListener(EventDao eventDao, EventDataDao eventDataDao, StringRedisTemplate stringRedisTemplate, String linkedGroupId,
public EventDataListener(EventDao eventDao, EventDataDao eventDataDao, StringRedisTemplate stringRedisTemplate, String contendId,
String redisKey) {
this.eventDao = eventDao;
this.eventDataDao = eventDataDao;
this.stringRedisTemplate = stringRedisTemplate;
this.linkedGroupId = linkedGroupId;
this.contendId = contendId;
this.redisKey = redisKey;
}
......@@ -43,8 +41,8 @@ public class EventDataListener extends AnalysisEventListener<UploadEventDataDTO>
public void invoke(UploadEventDataDTO eventDataDTO, AnalysisContext analysisContext) {
Event event = eventDao.findOneById(eventDataDTO.getEventId());
// 不允许上传其他关联组数据
if (event.getLinkedGroupId().equals(linkedGroupId)) {
EventData eventData = eventDataDTO.createEventData(event);
if (event.getContendId().equals(contendId)) {
EventData eventData = EventData.createFromUploadEventDataDTO(eventDataDTO, event);
eventDataDao.insertOneWithoutId(eventData);
}
int progress = analysisContext.readRowHolder().getRowIndex() * 100 / (analysisContext.readSheetHolder().getApproximateTotalRowNumber() - 1);
......
......@@ -4,7 +4,6 @@ import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.zhiwei.brandkbs2.easyexcel.dto.UploadEventDTO;
import com.zhiwei.brandkbs2.service.EventService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -29,12 +28,12 @@ public class EventFileListener extends AnalysisEventListener<UploadEventDTO> {
private final List<UploadEventDTO> datas = new ArrayList<>(BATCH_COUNT);
private final EventService eventService;
private final String projectId;
private final String linkedGroupId;
private final String contendId;
public EventFileListener(EventService eventService, String projectId, String linkedGroupId) {
public EventFileListener(EventService eventService, String projectId, String contendId) {
this.eventService = eventService;
this.projectId = projectId;
this.linkedGroupId = linkedGroupId;
this.contendId = contendId;
}
/**
......@@ -67,6 +66,6 @@ public class EventFileListener extends AnalysisEventListener<UploadEventDTO> {
* 保存更新事件信息逻辑
*/
private void addFileEvent() {
datas.forEach(eventDTO -> eventService.addFileEvent(projectId, linkedGroupId, eventDTO));
datas.forEach(eventDTO -> eventService.addFileEvent(projectId, contendId, eventDTO));
}
}
......@@ -112,7 +112,16 @@ public enum EmotionEnum {
return emotion;
}
public static int parseFromName(String name) {
public static EmotionEnum parseFromName(String name) {
for (EmotionEnum value : EmotionEnum.values()) {
if (value.getName().equals(name)) {
return value;
}
}
return UNDEFINED;
}
public static int parseFromName2State(String name) {
for (EmotionEnum value : EmotionEnum.values()) {
if (value.getName().equals(name)) {
return value.getState();
......
......@@ -92,7 +92,7 @@ public class EsQueryTools {
public static BoolQueryBuilder assembleMediaTypeQuery(List<String> mediaTypes) {
BoolQueryBuilder tagQuery = QueryBuilders.boolQuery();
mediaTypes.forEach(e -> {
tagQuery.should(QueryBuilders.termQuery("brandkbs_mark_cache_maps.channel_type.keyword", e));
tagQuery.should(QueryBuilders.termQuery("brandkbs_cache_maps.channel_type.keyword", e));
});
return tagQuery;
}
......
......@@ -2,6 +2,7 @@ package com.zhiwei.brandkbs2.pojo;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.base.category.ClassD;
import com.zhiwei.brandkbs2.util.Tools;
import lombok.Getter;
import lombok.Setter;
......@@ -69,12 +70,13 @@ public class BaseMap {
private JSONObject sourceJson;
/**
* 当标题为空时用文本截取前20个字代替
*
* @return
*/
public String getTitleNullOptionalContent() {
if (null != title) {
return title;
} else {
return incompleteContent;
}
return Tools.getTitleWithContent(title, incompleteContent, content);
}
}
......@@ -231,7 +231,7 @@ public class ChannelIndex extends AbstractBaseMongo {
// String url = baseMap.getUrl();
// String title = baseMap.getTitle();
String emotionStr = baseMap.getEmotion();
return new Article(time, mtime, id, EmotionEnum.parseFromName(emotionStr));
return new Article(time, mtime, id, EmotionEnum.parseFromName2State(emotionStr));
}
public Map<String, Object> toEsMap() {
......
......@@ -66,10 +66,10 @@ public class Event extends AbstractBaseMongo {
* 项目ID
*/
private String projectId;
/**
* 关联项目组ID
*/
private String linkedGroupId;
// /**
// * 关联项目组ID
// */
// private String linkedGroupId;
/**
* 品牌ID
*/
......@@ -103,13 +103,12 @@ public class Event extends AbstractBaseMongo {
*/
private String eventTopArticlesAnalysisDetail;
public static Event createFromYqEventDTO(YqEventDTO yqEventDTO, String collectionName, String projectId, String linkedGroupId) {
public static Event createFromYqEventDTO(YqEventDTO yqEventDTO, String collectionName, String projectId, String contendId) {
Event event = new Event();
event.setTitle(yqEventDTO.getName());
event.setStartTime(yqEventDTO.getStartTime());
boolean isEnd = "结束".equals(yqEventDTO.getSpreadStatus());
event.setEndStatus(isEnd);
event.setEndTime(isEnd ? yqEventDTO.getEndTime() : null);
event.setEndTime(yqEventDTO.getEndTime());
event.setEndStatus(Objects.nonNull(yqEventDTO.getEndTime()));
event.setKeyword(yqEventDTO.getKeyword());
event.setEmotion(yqEventDTO.getTagInfo().getString(EventTagEnum.EVENT_ATTRIBUTE.getName()));
event.setEventTag(yqEventDTO.getTagInfo());
......@@ -117,13 +116,12 @@ public class Event extends AbstractBaseMongo {
// 关联id
event.setCollectionName(collectionName);
event.setProjectId(projectId);
event.setLinkedGroupId(linkedGroupId);
event.setContendId(contendId);
return event;
}
public static Event createFromUploadEventDTO(UploadEventDTO eventDTO, String collectionName, String projectId, String linkedGroupId) {
public static Event createFromUploadEventDTO(UploadEventDTO eventDTO, String collectionName, String projectId, String contendId) {
Event event = new Event();
event.setCollectionName(collectionName);
event.setTitle(eventDTO.getTitle());
event.setStartTime(eventDTO.getStartTime().getTime());
event.setEndTime(eventDTO.getEndTime().getTime());
......@@ -134,9 +132,18 @@ public class Event extends AbstractBaseMongo {
// 关联id
event.setCollectionName(collectionName);
event.setProjectId(projectId);
event.setLinkedGroupId(linkedGroupId);
event.setContendId(contendId);
return event;
}
public void setStaticState(long totalDisseminationVolume, long totalChannelVolume, long negativeArticleVolume, JSONObject articleEmotionProportions,
JSONObject articlePlatformProportions, String eventTopArticlesAnalysisDetail) {
this.totalDisseminationVolume = totalDisseminationVolume;
this.totalChannelVolume = totalChannelVolume;
this.negativeArticleVolume = negativeArticleVolume;
this.articleEmotionProportions = articleEmotionProportions;
this.articlePlatformProportions = articlePlatformProportions;
this.eventTopArticlesAnalysisDetail = eventTopArticlesAnalysisDetail;
}
}
......@@ -2,13 +2,18 @@ package com.zhiwei.brandkbs2.pojo;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.common.GenericAttribute;
import com.zhiwei.brandkbs2.common.GlobalPojo;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.easyexcel.dto.UploadEventDataDTO;
import com.zhiwei.brandkbs2.pojo.dto.EventDataDTO;
import com.zhiwei.brandkbs2.util.Tools;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.bson.types.ObjectId;
import java.util.Map;
import java.util.Optional;
/**
* @author sjj
......@@ -27,7 +32,12 @@ public class EventData extends AbstractBaseMongo {
/**
* 事件ID
*/
private ObjectId eventId;
private String eventId;
/**
* 跟事件关联关系
*/
private EventMapper eventMapper;
/**
* 平台
*/
......@@ -95,32 +105,76 @@ public class EventData extends AbstractBaseMongo {
/**
* 渠道标签(重要渠道)
*/
private String channelTag;
private String mediaType;
public static EventData createFromEsMap(Map<String, Object> map, Event event) {
EventData data = new EventData();
JSONObject jsonMap = new JSONObject(map);
BaseMap baseMap = Tools.getBaseFromEsMap(map);
data.setEventId(new ObjectId(event.getId()));
data.setEventId(event.getId());
data.setProjectId(event.getProjectId());
data.setContendId(event.getContendId());
data.setLinkedGroupId(event.getLinkedGroupId());
data.setPlatform(baseMap.getPlatform());
data.setRealSource(baseMap.getRealSource());
data.setSource(baseMap.getSource());
data.setChannelFid(Tools.concat(data.projectId, data.contendId, data.platform, data.realSource, data.source));
data.setUrl(baseMap.getUrl());
data.setTitle(baseMap.getTitle());
data.setAggTitle(Tools.filterSpecialCharacter(baseMap.getTitle()));
data.setTitle(baseMap.getTitleNullOptionalContent());
data.setAggTitle(Tools.filterSpecialCharacter(data.getTitle()));
data.setContent(baseMap.getContent());
data.setEmotion(baseMap.getEmotion());
data.setTime(baseMap.getTime());
data.setForward(baseMap.isForward());
data.setCTime(jsonMap.getLong(GenericAttribute.ES_CTIME));
data.setCTime(System.currentTimeMillis());
data.setMediaType(GlobalPojo.getMediaType(data.getProjectId(), data.getPlatform(), data.getSource()));
// TagInfo
data.setTagInfo(Tools.change2TagInfoByMtag(jsonMap.getString(GenericAttribute.ES_MTAG)));
data.setEmotion(baseMap.getEmotion());
data.setArticleId(jsonMap.getString("id"));
// setMapper
EventMapper eventMapper = new EventMapper();
eventMapper.setId(new ObjectId(event.getId()));
eventMapper.setEmotion(event.getEmotion());
eventMapper.setStartTime(event.getStartTime());
eventMapper.setEndTime(event.getEndTime());
data.setEventMapper(eventMapper);
return data;
}
/**
* 表格解析后的数据转换为事件数据传输格式
*
* @return 事件数据传输格式
*/
public static EventData createFromUploadEventDataDTO(UploadEventDataDTO uploadEventDataDTO, Event event) {
EventData data = new EventData();
data.setEventId(event.getId());
data.setProjectId(event.getProjectId());
data.setContendId(event.getContendId());
data.setPlatform(uploadEventDataDTO.getPlatform());
data.setRealSource(uploadEventDataDTO.getRealSource());
data.setSource(uploadEventDataDTO.getSource());
data.setChannelFid(Tools.concat(data.projectId, data.contendId, data.platform, data.realSource, data.source));
data.setUrl(uploadEventDataDTO.getUrl());
data.setTitle(Tools.getTitleWithContent(uploadEventDataDTO.getTitle(), uploadEventDataDTO.getContent()));
data.setAggTitle(Tools.filterSpecialCharacter(data.getTitle()));
data.setContent(uploadEventDataDTO.getContent());
data.setTime(uploadEventDataDTO.getTime().getTime());
data.setForward(uploadEventDataDTO.isForward());
data.setCTime(System.currentTimeMillis());
data.setMediaType(GlobalPojo.getMediaType(data.getProjectId(), data.getPlatform(), data.getSource()));
// TagInfo
JSONObject tagInfo = new JSONObject();
Optional.ofNullable(uploadEventDataDTO.getEmotion()).ifPresent(emotion -> tagInfo.put(Constant.EMOTION_LABEL_KEY, emotion));
Optional.ofNullable(uploadEventDataDTO.getBrand()).ifPresent(brand -> tagInfo.put(Constant.BRAND_LABEL_KEY, brand));
data.setTagInfo(tagInfo);
data.setEmotion(uploadEventDataDTO.getEmotion());
// setMapper
EventMapper eventMapper = new EventMapper();
eventMapper.setId(new ObjectId(event.getId()));
eventMapper.setEmotion(event.getEmotion());
eventMapper.setStartTime(event.getStartTime());
eventMapper.setEndTime(event.getEndTime());
data.setEventMapper(eventMapper);
return data;
}
......@@ -128,4 +182,13 @@ public class EventData extends AbstractBaseMongo {
return Tools.convertMap(eventDataDTO, EventData.class);
}
@Data
public static class EventMapper {
ObjectId id;
String emotion;
Long startTime;
Long endTime;
}
}
......@@ -12,20 +12,20 @@ import org.springframework.data.mongodb.core.mapping.Document;
@Getter
@Setter
@Document(collection = "brandkbs_event_top_articles_analysis")
public class EventTopArticlesAnalysis extends AbstractBaseMongo{
public class EventTopArticlesAnalysis extends AbstractBaseMongo {
/**
* 聚合标题
*/
private String aggTitle;
/**
* 聚合标题
* 聚合情感
*/
private String emotion;
/**
* 聚合数
*/
private String count;
private Integer count;
/**
* 发布时间
*/
......@@ -42,4 +42,28 @@ public class EventTopArticlesAnalysis extends AbstractBaseMongo{
* 关联事件id
*/
private String eventId;
public static EventTopArticlesAnalysis createWithTimeType(String aggTitle, EventData templateData, String timePoint, Integer count, String eventId) {
EventTopArticlesAnalysis eventTopArticlesAnalysis = new EventTopArticlesAnalysis();
eventTopArticlesAnalysis.setAggTitle(aggTitle);
eventTopArticlesAnalysis.setEmotion(templateData.getEmotion());
eventTopArticlesAnalysis.setCount(count);
eventTopArticlesAnalysis.setTime(templateData.getTime());
eventTopArticlesAnalysis.setTimePoint(timePoint);
eventTopArticlesAnalysis.setType("按时间");
eventTopArticlesAnalysis.setEventId(eventId);
return eventTopArticlesAnalysis;
}
public static EventTopArticlesAnalysis createWithAmountType(String aggTitle, EventData templateData, Integer count, String eventId) {
EventTopArticlesAnalysis eventTopArticlesAnalysis = new EventTopArticlesAnalysis();
eventTopArticlesAnalysis.setAggTitle(aggTitle);
eventTopArticlesAnalysis.setEmotion(templateData.getEmotion());
eventTopArticlesAnalysis.setCount(count);
eventTopArticlesAnalysis.setTime(templateData.getTime());
eventTopArticlesAnalysis.setType("按数量");
eventTopArticlesAnalysis.setEventId(eventId);
return eventTopArticlesAnalysis;
}
}
package com.zhiwei.brandkbs2.pojo.dto;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.List;
import java.util.Map;
/**
* @ClassName: EventSearchDto
......@@ -19,18 +19,50 @@ import java.util.Map;
@ApiModel("事件信息传输类")
public class EventSearchDTO {
private Map<String, List<String>> tags;
@ApiModelProperty("搜索条件")
private String searchInfo;
private Integer page;
private Integer pageSize;
private Integer brandId;
/**
* 页码
*/
@ApiModelProperty("页码")
private Integer page = 1;
/**
* 大小
*/
@ApiModelProperty("页码大小")
private Integer pageSize = 50;
/**
* 开始时间
*/
@ApiModelProperty("开始时间")
private Long startTime;
/**
* 结束时间
*/
@ApiModelProperty("结束时间")
private Long endTime;
/**
* 品牌ID结合
*/
@ApiModelProperty(value = "品牌ID")
private String contendId= "0";
/**
* 情感倾向集合
*/
@ApiModelProperty(value = "情感倾向集合")
private List<String> emotions;
/**
* 排序字段
*/
@ApiModelProperty(value = "排序字段")
private JSONObject sorter = JSONObject.parseObject("{\"startTime\":\"descend\"}");
/**
* 搜索关键词
*/
@ApiModelProperty(value = "关键词")
private String keyword;
/**
* 传播量
*/
@ApiModelProperty(value = "传播量")
private Long[] totalDisseminationVolumes;
}
package com.zhiwei.brandkbs2.pojo.vo;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.enmus.EventTagEnum;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
import io.swagger.annotations.ApiModel;
......@@ -8,8 +9,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.stream.Collectors;
/**
* @Description: 事件库列表VO
* @Author: shentao
......@@ -89,7 +88,7 @@ public class EventListInfoVO {
this.totalDisseminationVolume = event.getTotalDisseminationVolume();
this.totalChannelVolume = event.getTotalChannelVolume();
this.emotion = event.getEmotion();
this.eventTag = event.getEventTag().values().stream().map(String::valueOf).collect(Collectors.joining("|"));
this.eventTag = null == event.getEventTag() ? null : event.getEventTag().getString(EventTagEnum.EVENT_TYPE.getName());
this.negativeArticleVolume = event.getNegativeArticleVolume();
this.articleEmotionProportions = event.getArticleEmotionProportions();
this.articlePlatformProportions = event.getArticlePlatformProportions();
......
......@@ -23,7 +23,7 @@ public class EventTopArticlesAnalysisVO {
/**
* 聚合数
*/
private String count;
private Integer count;
/**
* 发布时间
*/
......
......@@ -24,6 +24,9 @@ public class YqEventSearchVO {
@ApiModelProperty("关联项目组id")
private String linkedGroupId;
@ApiModelProperty("关联品牌id")
private String contendId = "0";
@ApiModelProperty("起始时间")
private Long startTime;
......
......@@ -5,16 +5,18 @@ import com.zhiwei.brandkbs2.easyexcel.dto.ExportEventDTO;
import com.zhiwei.brandkbs2.easyexcel.dto.ExportEventDataDTO;
import com.zhiwei.brandkbs2.easyexcel.dto.UploadEventDTO;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
import com.zhiwei.brandkbs2.pojo.EventDisseminationTrend;
import com.zhiwei.brandkbs2.pojo.dto.EventDataDTO;
import com.zhiwei.brandkbs2.pojo.dto.EventSearchDTO;
import com.zhiwei.brandkbs2.pojo.dto.YqEventDTO;
import com.zhiwei.brandkbs2.pojo.vo.*;
import com.zhiwei.brandkbs2.pojo.vo.EventListInfoVO;
import com.zhiwei.brandkbs2.pojo.vo.EventVO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import com.zhiwei.brandkbs2.pojo.vo.YqEventSearchVO;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
/**
* @ClassName: EventService
......@@ -35,10 +37,10 @@ public interface EventService {
/**
* 批量添加舆情事件数据
*
* @param linkedGroupId 关联项目ID
* @param contendId 竞品id
* @param yqEventList 舆情事件列表
*/
void addYqEvents(String linkedGroupId, List<YqEventDTO> yqEventList);
void addYqEvents(String contendId, List<YqEventDTO> yqEventList);
/**
* 批量添加舆情事件数据
......@@ -70,11 +72,11 @@ public interface EventService {
/**
* 稿件数据上传
*
* @param linkedGroupId 关联项目id
* @param contendId 竞品id
* @param file 文件
* @return 文件信息
*/
JSONObject uploadEventDatas(String linkedGroupId, MultipartFile file);
JSONObject uploadEventDatas(String contendId, MultipartFile file);
/**
* 根据票据获取文件上传进度
......@@ -166,19 +168,19 @@ public interface EventService {
/**
* 添加文件上传事件信息
*
* @param linkedGroupId 关联项目组id
* @param contendId 竞品id
* @param fileUrl 文件路径
*/
void addFileEvents(String linkedGroupId, String fileUrl);
void addFileEvents(String contendId, String fileUrl);
/**
* 添加文件上传事件信息
*
* @param projectId 项目id
* @param linkedGroupId 关联项目组id
* @param contendId 竞品id
* @param eventDTO 事件传输对象
*/
void addFileEvent(String projectId, String linkedGroupId, UploadEventDTO eventDTO);
void addFileEvent(String projectId, String contendId, UploadEventDTO eventDTO);
/**
* 批量更新事件
......@@ -222,16 +224,10 @@ public interface EventService {
/**
* 获取品牌事件列表信息
* @param contendId
* @param emotion
* @param startTime
* @param endTime
* @param page
* @param pageSize
* @param sorter
* @param eventSearchDTO 事件搜索类
* @return
*/
PageVO<EventListInfoVO> getEventList(String contendId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter);
PageVO<EventListInfoVO> getEventList(EventSearchDTO eventSearchDTO);
/**
* 事件详情-基础静态信息
......@@ -257,7 +253,7 @@ public interface EventService {
* @param sorter
* @return
*/
PageVO<EventData> getEventChannelVoices(String eventId, String type, int page, int pageSize, String sorter);
List<JSONObject> getEventChannelVoices(String eventId, String type, int page, int pageSize, String sorter);
/**
* 事件详情-热门文章分析
......
package com.zhiwei.brandkbs2.service;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
* @ClassName: IndexService
* @Description 首页服务
* @author: sjj
* @date: 2022-08-18 15:15
*/
public interface IndexService {
/**
* 获取舆情总量信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param cache 是否读取缓存
* @return 舆情总量信息
*/
JSONObject getYuqingAmount(Long startTime, Long endTime, boolean cache);
/**
* 获取品牌美誉度信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param cache 是否读取缓存
* @return 品牌美誉度信息
*/
JSONObject getReputation(Long startTime, Long endTime, boolean cache);
/**
* 获取品牌平台贡献度信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param cache 是否读取缓存
* @return 品牌平台贡献度信息
*/
JSONObject getEventAmount(Long startTime, Long endTime, boolean cache);
/**
* 获取品牌平台贡献度信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param cache 是否读取缓存
* @return 品牌平台贡献度信息
*/
List<JSONObject> getPlatformInfo(Long startTime, Long endTime, boolean cache);
/**
* 获取主品牌传播趋势
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param cache 是否优先读取缓存
* @return 主品牌传播趋势
*/
JSONObject getSpreadingTend(Long startTime, Long endTime, boolean cache);
}
......@@ -6,12 +6,12 @@ import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.MarkFlowEntity;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.pojo.dto.SearchFilterDTO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.web.bind.annotation.RequestParam;
import javax.naming.directory.SearchControls;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
......@@ -167,14 +167,16 @@ public interface MarkDataService {
/**
* 竞品库-获取搜索条件
* @param linkedGroupId 关联组Id
*
* @param contendId 竞品Id
* @return 搜索条件
*/
JSONObject getContendSearchCriteria(String linkedGroupId);
JSONObject getContendSearchCriteria(String contendId);
/**
* 竞品库-获取搜索结果列表
* @param markSearchDTO 标注数据搜索传输类
*
* @param markSearchDTO 标注数据搜索传输类
* @return 搜索结果列表
*/
......@@ -191,10 +193,74 @@ public interface MarkDataService {
/**
* 竞品库-获取竞品对比传播分析数据
*
* @param markSearchDTO 标注数据搜索传输类
* @param hotArticleSize 热门稿件数量
* @param cache 是否启用缓存
* @return
*/
JSONObject getContendSpreadAnalyze(MarkSearchDTO markSearchDTO, int hotArticleSize, boolean cache) throws IOException;
/**
* 竞品库-舆情导出
* @param markSearchDTO 标注数据搜索传输类
* @return
*/
Pair<String, List<ExportAppYuqingDTO>> downloadContendMarkList(MarkSearchDTO markSearchDTO);
/**
* 搜索-全网搜
* @param searchFilterDTO
* @return
*/
JSONObject searchWholeNetwork(SearchFilterDTO searchFilterDTO);
/**
* 时间段内稿件数
*
* @param startTime
* @param endTime
* @param emotion
* @param projectId
* @param contendId
* @return
*/
long getYuqingMarkCount(Long startTime, Long endTime, String emotion, String projectId, String contendId) throws IOException;
/**
* 时间段内稿件数
*
* @param startTime
* @param endTime
* @param emotion
* @param platformId
* @param projectId
* @param contendId
* @return
*/
long getYuqingMarkCount(Long startTime, Long endTime, String emotion, String platformId, String projectId, String contendId) throws IOException;
/**
* 项目最早稿件时间
*
* @param projectId
* @param contendId
* @return
* @throws IOException
*/
long getYuqingMarkFirstTime(String projectId, String contendId) throws IOException;
/**
* 根据情感获取时间段发布最多稿件的渠道
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param emotion 情感倾向
* @param projectId 项目ID
* @param contendId 竞品ID
* @param size 大小
* @return 发布最多稿件的渠道
*/
List<Map<String, Object>> getEsTopSource(Long startTime, Long endTime, String projectId, String linkedGroupId, String contendId, String emotion, int size) throws IOException;
}
package com.zhiwei.brandkbs2.service;
import com.zhiwei.brandkbs2.pojo.ChannelTag;
import com.zhiwei.qbjc.bean.pojo.common.MessagePlatform;
import com.zhiwei.qbjc.bean.pojo.common.Tag;
import java.util.List;
import java.util.Map;
/**
* @ClassName: SystemInfoService
......@@ -27,4 +29,13 @@ public interface SystemInfoService {
*/
List<Tag> getTags();
/**
* 获取ChannelTags
*
* @return List<ChannelTag>
*/
List<ChannelTag> getChannelTags();
Map<String, Map<String, String>> getMediaTypes();
}
......@@ -165,7 +165,7 @@ public class ChannelServiceImpl implements ChannelService {
@Override
public PageVO<JSONObject> findEventList(int page, int size, String channelId) {
Channel channel = channelDao.findOneById(channelId);
List<String> eventIds = eventDao.getEventCount(channel.getChannelIndex());
List<String> eventIds = eventDao.getEvents(channel.getChannelIndex());
Query query = Query.query(Criteria.where("_id").in(eventIds));
long total = eventDao.count(query);
mongoUtil.start(page, size, query);
......@@ -262,7 +262,7 @@ public class ChannelServiceImpl implements ChannelService {
public List<ExportAdminChannelEventDTO> findDownloadChannelEventList(String channelId) {
List<ExportAdminChannelEventDTO> resList = new ArrayList<>();
Channel channel = channelDao.findOneById(channelId);
List<String> eventIds = eventDao.getEventCount(channel.getChannelIndex());
List<String> eventIds = eventDao.getEvents(channel.getChannelIndex());
if (CollectionUtils.isEmpty(eventIds)) {
return resList;
}
......@@ -460,9 +460,8 @@ public class ChannelServiceImpl implements ChannelService {
@Override
public List<JSONObject> getCollectList(String contendId) {
String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = projectService.getProjectByContendId(projectId, contendId).getBrandLinkedGroupId();
Query query = new Query();
query.addCriteria(Criteria.where("projectId").is(projectId).and("linkedGroupId").is(linkedGroupId).and("isCollect").is(true));
query.addCriteria(Criteria.where("projectId").is(projectId).and("contendId").is(contendId).and("isCollect").is(true));
channelDao.addSort(query, "{\"collectTime\":\"descend\"}");
return channelDao.findList(query).stream().map(channel -> {
JSONObject json = new JSONObject();
......@@ -808,7 +807,7 @@ public class ChannelServiceImpl implements ChannelService {
}
channel.setEmotionIndex(index);
channel.setEmotion(emotion);
channel.setEventCount(eventDao.getEventCount(new ChannelIndex(channel)).size());
channel.setEventCount(eventDao.getEvents(new ChannelIndex(channel)).size());
}
/**
......
......@@ -59,7 +59,7 @@ public class CommonServiceImpl implements CommonService {
@Override
public List<MarkerTag> getEmotionTagsWithSort(String projectId, String linkedGroupId, TagSearch... tagSearches) {
List<MarkerTag> emotionList = getQbjcTags(linkedGroupId, TagField.GROUP_NAME.is("情感倾向"));
return emotionList.stream().filter(tag -> 0 != EmotionEnum.parseFromName(tag.getName())).sorted(Comparator.comparingInt(tag -> EmotionEnum.parseFromName(tag.getName()))).collect(Collectors.toList());
return emotionList.stream().filter(tag -> 0 != EmotionEnum.parseFromName2State(tag.getName())).sorted(Comparator.comparingInt(tag -> EmotionEnum.parseFromName2State(tag.getName()))).collect(Collectors.toList());
}
@Override
......
......@@ -99,7 +99,7 @@ public class CustomEventServiceImpl implements CustomEventService {
JSONObject result = new JSONObject();
String aggTitle = map.getKey();
try {
BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID);
BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID);
result.put("title", firstArticle.getTitle());
result.put("time", firstArticle.getTime());
result.put("url", firstArticle.getUrl());
......@@ -271,7 +271,8 @@ public class CustomEventServiceImpl implements CustomEventService {
result.put("platformPro", this.getPlatformPro(articleList));
result.put("hotKeyword", this.getHotKeyword(articleList));
FastDateFormat df = gtDay ? Constant.DAY_FORMAT : Constant.HOUR_FORMAT;
List<Map<String, String>> dateList = gtDay ? Tools.parseToDays(customEvent.getStartTime(), customEvent.getEndTime()) : Tools.parseToHours(customEvent.getStartTime(), customEvent.getEndTime());
List<Map<String, Long>> dateList = gtDay ? Tools.parseToDays(customEvent.getStartTime(), customEvent.getEndTime()) :
Tools.parseToHours(customEvent.getStartTime(), customEvent.getEndTime());
result.put("spreadType", gtDay ? "day" : "hour");
result.put("spread", this.getSpread(dateList, df, articleList));
result.put("hotArticles", this.getHotArticles(articleList));
......@@ -458,38 +459,34 @@ public class CustomEventServiceImpl implements CustomEventService {
* @param articleList 自定义事件稿件集合
* @return 自定义事件传播趋势
*/
private List<JSONObject> getSpread(List<Map<String, String>> dateList, FastDateFormat df, List<BaseMap> articleList) {
private List<JSONObject> getSpread(List<Map<String, Long>> dateList, FastDateFormat df, List<BaseMap> articleList) {
List<JSONObject> lineList = new ArrayList<>(dateList.size());
for (Map<String, String> map : dateList) {
try {
Long startTime = df.parse(map.get("startTime")).getTime();
Long endTime = df.parse(map.get("endTime")).getTime();
long count = 0;
long posCount = 0;
long neuCount = 0;
long negCount = 0;
for (BaseMap baseMap : articleList) {
if (baseMap.getTime() >= startTime && baseMap.getTime() < endTime) {
if (EmotionEnum.POSITIVE.getName().equals(baseMap.getEmotion())) {
posCount++;
} else if (EmotionEnum.NEGATIVE.getName().equals(baseMap.getEmotion())) {
negCount++;
} else {
neuCount++;
}
count++;
for (Map<String, Long> map : dateList) {
Long startTime = map.get("startTime");
Long endTime = map.get("endTime");
long count = 0;
long posCount = 0;
long neuCount = 0;
long negCount = 0;
for (BaseMap baseMap : articleList) {
if (baseMap.getTime() >= startTime && baseMap.getTime() < endTime) {
if (EmotionEnum.POSITIVE.getName().equals(baseMap.getEmotion())) {
posCount++;
} else if (EmotionEnum.NEGATIVE.getName().equals(baseMap.getEmotion())) {
negCount++;
} else {
neuCount++;
}
count++;
}
JSONObject line = new JSONObject();
line.put("count", count);
line.put("posCount", posCount);
line.put("neuCount", neuCount);
line.put("negCount", negCount);
line.put("time", startTime);
lineList.add(line);
} catch (ParseException pe) {
log.error("时间转换错误");
}
JSONObject line = new JSONObject();
line.put("count", count);
line.put("posCount", posCount);
line.put("neuCount", neuCount);
line.put("negCount", negCount);
line.put("time", startTime);
lineList.add(line);
}
return lineList;
}
......
package com.zhiwei.brandkbs2.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.dao.EventDataDao;
import com.zhiwei.brandkbs2.dao.EventTopArticlesAnalysisDao;
import com.zhiwei.brandkbs2.enmus.EmotionEnum;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
import com.zhiwei.brandkbs2.pojo.EventTopArticlesAnalysis;
import com.zhiwei.brandkbs2.service.EventDataService;
import com.zhiwei.brandkbs2.service.MarkDataService;
import com.zhiwei.brandkbs2.util.Tools;
......@@ -15,9 +20,9 @@ import org.joda.time.PeriodType;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
/**
......@@ -42,6 +47,11 @@ public class EventDataServiceImpl implements EventDataService {
@Resource(name = "eventServiceImpl")
private EventServiceImpl eventServiceImpl;
@Resource(name = "eventTopArticlesAnalysisDao")
private EventTopArticlesAnalysisDao eventTopArticlesAnalysisDao;
private static final String TOP_DETAIL_TEMPLATE = "Top媒体传播方向:全局Top8的文章中,{0}报道方向占比最高,为{1}%,{2}报道方向占比{3}%。Top报道方向中,《{4}》相似文章数最多,总文章数为{5}篇。";
@Override
public void analysisEvent(Event event) {
long startTime = event.getStartTime();
......@@ -72,13 +82,15 @@ public class EventDataServiceImpl implements EventDataService {
}
private void updateEventData(Event event, List<EventData> eventDataList) {
String keyword = event.getKeyword();
// 删除历史数据
eventDataDao.deleteByEventId(event.getId(), event.getCollectionName());
deleteEventRelated(event);
// 设置快照属性值
setEventStaticState(event, eventDataList);
List<EventData> insertList = new ArrayList<>();
String keyword = event.getKeyword();
for (EventData data : eventDataList) {
// 关键词筛选
if (Tools.containsKeyword(Arrays.asList(keyword.split(keyword.contains(",") ? "," : "\\|")), (data.getTitle() + data.getContent()).toLowerCase())) {
if (Tools.isContains(Arrays.asList(keyword.split(keyword.contains(",") ? "," : "\\|")), (data.getTitle() + data.getContent()))) {
insertList.add(data);
}
}
......@@ -87,4 +99,118 @@ public class EventDataServiceImpl implements EventDataService {
});
log.info("analysisEvent-eventId:{},更新事件数据完毕,实际更新:{}条", event.getId(), insertList.size());
}
private void deleteEventRelated(Event event) {
// 删除历史数据
eventDataDao.deleteByEventId(event.getId(), event.getCollectionName());
eventTopArticlesAnalysisDao.deleteByEventId(event.getId());
}
private void setEventStaticState(Event event, List<EventData> eventDataList) {
long totalDisseminationVolume = eventDataList.size();
Set<String> totalChannelVolumes = new HashSet<>();
Map<String, AtomicLong> platformIdCounts = new HashMap<>();
long positiveArticleVolume = 0;
long negativeArticleVolume = 0;
long neutralArticleVolume = 0;
long totalArticleVolume = 0;
for (EventData eventData : eventDataList) {
switch (EmotionEnum.parseFromName(eventData.getEmotion())) {
case POSITIVE:
positiveArticleVolume++;
totalArticleVolume++;
break;
case NEGATIVE:
negativeArticleVolume++;
totalArticleVolume++;
break;
case NEUTRAL:
neutralArticleVolume++;
totalArticleVolume++;
break;
}
totalChannelVolumes.add(eventData.getPlatform() + eventData.getRealSource() + eventData.getSource());
platformIdCounts.putIfAbsent(eventData.getPlatform(), new AtomicLong());
platformIdCounts.get(eventData.getPlatform()).incrementAndGet();
}
// 文章情感占比
JSONObject articleEmotionProportions = new JSONObject();
articleEmotionProportions.put("positive", getProportion(positiveArticleVolume, totalArticleVolume));
articleEmotionProportions.put("negative", getProportion(negativeArticleVolume, totalArticleVolume));
articleEmotionProportions.put("neutral", getProportion(neutralArticleVolume, totalArticleVolume));
// 文章平台占比
JSONObject articlePlatformProportions = new JSONObject();
platformIdCounts.forEach((platform, count) -> articlePlatformProportions.put(platform, getProportion(count.get(), totalDisseminationVolume)));
// 热门文章分析描述
String eventTopArticlesAnalysisDetail = MessageFormat.format(TOP_DETAIL_TEMPLATE, topArticlesAnalysis(eventDataList, event));
event.setStaticState(totalDisseminationVolume, totalChannelVolumes.size(), negativeArticleVolume, articleEmotionProportions,
articlePlatformProportions, eventTopArticlesAnalysisDetail);
eventDao.updateOne(event);
}
private List<String> topArticlesAnalysis(List<EventData> eventDataList, Event event) {
// 标题前8数据
List<Map.Entry<String, List<EventData>>> top8Titles =
eventDataList.stream().collect(Collectors.groupingBy(EventData::getAggTitle)).entrySet().stream()
.sorted((e1, e2) -> Integer.compare(e2.getValue().size(), e1.getValue().size())).limit(8).collect(Collectors.toList());
List<EventTopArticlesAnalysis> insertList = new ArrayList<>();
// 按时间(天级)录入
top8Titles.forEach(entry -> {
Map<String, List<EventData>> dayMap = entry.getValue().stream().collect(Collectors.groupingBy(data -> Constant.SPEC_DAY_FORMAT.format(data.getTime())));
for (Map.Entry<String, List<EventData>> dayEntry : dayMap.entrySet()) {
EventData eventData = dayEntry.getValue().stream().min(Comparator.comparingLong(EventData::getTime)).get();
EventTopArticlesAnalysis eventTopArticlesAnalysis = EventTopArticlesAnalysis.createWithTimeType(entry.getKey(), eventData, dayEntry.getKey(),
dayEntry.getValue().size(), event.getId());
insertList.add(eventTopArticlesAnalysis);
}
});
// 按数量录入
top8Titles.forEach(entry -> {
EventData eventData = entry.getValue().stream().min(Comparator.comparingLong(EventData::getTime)).get();
EventTopArticlesAnalysis eventTopArticlesAnalysis = EventTopArticlesAnalysis.createWithAmountType(entry.getKey(), eventData,
entry.getValue().size(), event.getId());
insertList.add(eventTopArticlesAnalysis);
});
eventTopArticlesAnalysisDao.insertMany(insertList);
return fillDetail(top8Titles);
}
private List<String> fillDetail(List<Map.Entry<String, List<EventData>>> top8Titles) {
List<String> details = new ArrayList<>();
Map<String, AtomicLong> emotionMap = new HashMap<>();
for (Map.Entry<String, List<EventData>> entry : top8Titles) {
for (EventData eventData : entry.getValue()) {
switch (EmotionEnum.parseFromName(eventData.getEmotion())) {
case POSITIVE:
emotionMap.putIfAbsent("正面", new AtomicLong());
emotionMap.get("正面").incrementAndGet();
break;
case NEGATIVE:
emotionMap.putIfAbsent("负面", new AtomicLong());
emotionMap.get("负面").incrementAndGet();
break;
case NEUTRAL:
emotionMap.putIfAbsent("中性", new AtomicLong());
emotionMap.get("中性").incrementAndGet();
break;
}
}
}
long sum = emotionMap.values().stream().mapToLong(AtomicLong::get).sum();
emotionMap.entrySet().stream().sorted((x, y) -> Long.compare(y.getValue().get(), x.getValue().get())).limit(2).forEach(entry -> {
details.add(entry.getKey());
details.add(String.valueOf((entry.getValue().get()) / sum));
});
details.add(top8Titles.get(0).getKey());
details.add(String.valueOf(top8Titles.get(0).getValue().size()));
return details;
}
private Double getProportion(long part, long total) {
if (0 == part || 0 == total) {
return 0.00;
}
return (double) part / total;
}
}
package com.zhiwei.brandkbs2.service.impl;
import com.zhiwei.brandkbs2.dao.ChannelTagDao;
import com.zhiwei.brandkbs2.dao.MediaTypeDao;
import com.zhiwei.brandkbs2.dao.QbjcPojoDao;
import com.zhiwei.brandkbs2.pojo.ChannelTag;
import com.zhiwei.brandkbs2.pojo.MediaType;
import com.zhiwei.brandkbs2.service.SystemInfoService;
import com.zhiwei.qbjc.bean.pojo.common.MessagePlatform;
import com.zhiwei.qbjc.bean.pojo.common.Tag;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName: SystemInfoServiceImpl
......@@ -21,6 +27,12 @@ public class SystemInfoServiceImpl implements SystemInfoService {
@Resource(name = "qbjcPojoDao")
private QbjcPojoDao qbjcPojoDao;
@Resource
private ChannelTagDao channelTagDao;
@Resource
private MediaTypeDao mediaTypeDao;
@Override
public List<MessagePlatform> getPlatforms() {
return qbjcPojoDao.findMessagePlatformAll();
......@@ -30,4 +42,20 @@ public class SystemInfoServiceImpl implements SystemInfoService {
public List<Tag> getTags() {
return qbjcPojoDao.findTagAll();
}
@Override
public List<ChannelTag> getChannelTags() {
return channelTagDao.findList(null);
}
@Override
public Map<String, Map<String, String>> getMediaTypes() {
Map<String, Map<String, String>> res = new HashMap<>();
List<MediaType> list = mediaTypeDao.findList(null);
for (MediaType mediaType : list) {
res.putIfAbsent(mediaType.getProjectId(), new HashMap<>());
res.get(mediaType.getProjectId()).put(mediaType.getPlatform() + mediaType.getChannel(), mediaType.getType());
}
return res;
}
}
......@@ -31,6 +31,26 @@ public class RedisUtil {
return RedisKeyPrefix.AGGREE_RESULT_CACHE + projectId + ":" + id;
}
public static String getIndexYuqingKey(String projectId, Long startTime, Long endTime) {
return RedisKeyPrefix.INDEX_YUQING + Tools.concat(projectId, startTime, endTime);
}
public static String getIndexReputationKey(String projectId, Long startTime, Long endTime) {
return RedisKeyPrefix.INDEX_REPUTATION + Tools.concat(projectId, startTime, endTime);
}
public static String getIndexEventKey(String projectId, Long startTime, Long endTime) {
return RedisKeyPrefix.INDEX_EVENT + Tools.concat(projectId, startTime, endTime);
}
public static String getIndexPlatformKey(String projectId, Long startTime, Long endTime) {
return RedisKeyPrefix.INDEX_PLATFORM + Tools.concat(projectId, startTime, endTime);
}
public static String getIndexSpread(String projectId, Long startTime, Long endTime) {
return RedisKeyPrefix.INDEX_SPREAD + Tools.concat(projectId, startTime, endTime);
}
public void setExpire(String key, String value, long timeout, TimeUnit unit) {
stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
}
......
......@@ -210,25 +210,26 @@ public class Tools {
}
}
/**
* 是否包含关键字
*
* @param keywordsList 关键词数据
* @param content 字符串标题+内容
* @return 是否包含关键字
*/
public static boolean containsKeyword(List<String> keywordsList, String content) {
//按空格分割必须全部命中
for (String keywords : keywordsList) {
for (String keyword : keywords.split(" ")) {
if (!content.contains(keyword.toLowerCase())) {
//一个不命中,直接返回false
return false;
}
}
}
return true;
}
// /**
// * 是否包含关键字
// *
// * @param keywordsList 关键词数据
// * @param content 字符串标题+内容
// * @return 是否包含关键字
// */
// public static boolean containsKeyword(List<String> keywordsList, String content) {
// keywordsList = keywordsList.stream().map(keywords->keywords.split(keywords.contains(",") ? "," : "\\|")).collect(Collectors.toList());
// //按空格分割必须全部命中
// for (String keywords : keywordsList) {
// for (String keyword : keywords.split(" ")) {
// if (!content.contains(keyword.toLowerCase())) {
// //一个不命中,直接返回false
// return false;
// }
// }
// }
// return true;
// }
public static <T> T convertMap(Object source, Class<T> destinationClass) throws MappingException {
return DOZER_BEAN_MAPPER.map(source, destinationClass);
......@@ -702,8 +703,7 @@ public class Tools {
* @param endTime 结束时间
* @return 按日分割的map集合
*/
public static List<Map<String, String>> parseToDays(Long startTime, Long endTime) {
FastDateFormat df = DAY_FORMAT;
public static List<Map<String, Long>> parseToDays(Long startTime, Long endTime) {
Date start = Tools.truncDate(new Date(startTime), Constant.DAY_PATTERN);
Date end = Tools.truncDate(new Date(endTime), Constant.DAY_PATTERN);
Period periodDays = new Period(start.getTime(), end.getTime(), PeriodType.days());
......@@ -711,26 +711,77 @@ public class Tools {
if (days < 0) {
return Collections.emptyList();
}
List<Map<String, String>> dayList = new ArrayList<>(days);
List<Map<String, Long>> dayList = new ArrayList<>(days);
for (int i = 0; i <= days; i++) {
Map<String, String> dayMap = new HashMap<>(4);
Map<String, Long> dayMap = new HashMap<>(4);
//开始时间
dayMap.put("startTime", df.format(DateUtils.addDays(start, i)));
dayMap.put("startTime", DateUtils.addDays(start, i).getTime());
//结束时间
dayMap.put("endTime", df.format(DateUtils.addDays(start, i + 1)));
dayMap.put("endTime", DateUtils.addDays(start, i + 1).getTime());
dayList.add(dayMap);
}
return dayList;
}
/**
* 解析时间转换成按年的集合
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 按年分割的map集合
*/
public static List<Map<String, Long>> parseToYears(Long startTime, Long endTime) {
Date start = Tools.truncDate(new Date(startTime), Constant.YEAR_PATTERN);
Date end = Tools.truncDate(new Date(endTime), Constant.YEAR_PATTERN);
Period periodYears = new Period(start.getTime(), end.getTime(), PeriodType.years());
int years = periodYears.getYears();
if (years < 0) {
return Collections.emptyList();
}
List<Map<String, Long>> yearList = new ArrayList<>(years);
for (int i = 0; i <= years; i++) {
Map<String, Long> yearMap = new HashMap<>(4);
yearMap.put("startTime", DateUtils.addYears(start, i).getTime());
yearMap.put("endTime", DateUtils.addYears(start, i + 1).getTime());
yearList.add(yearMap);
}
return yearList;
}
/**
* 解析时间转换成按月的集合
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 按月分割的map集合
*/
public static List<Map<String, Long>> parseToMonths(Long startTime, Long endTime) {
Date start = Tools.truncDate(new Date(startTime), Constant.MONTH_PATTERN);
Date end = Tools.truncDate(new Date(endTime), Constant.MONTH_PATTERN);
Period periodMonths = new Period(start.getTime(), end.getTime(), PeriodType.months());
int months = periodMonths.getMonths();
if (months < 0) {
return Collections.emptyList();
}
List<Map<String, Long>> monthList = new ArrayList<>(months);
for (int i = 0; i <= months; i++) {
Map<String, Long> monthMap = new HashMap<>(4);
monthMap.put("startTime", DateUtils.addMonths(start, i).getTime());
monthMap.put("endTime", DateUtils.addMonths(start, i + 1).getTime());
monthList.add(monthMap);
}
return monthList;
}
/**
* 解析时间转换成按小时的集合
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 按小时分割的map集合
*/
public static List<Map<String, String>> parseToHours(Long startTime, Long endTime) {
public static List<Map<String, Long>> parseToHours(Long startTime, Long endTime) {
FastDateFormat df = HOUR_FORMAT;
Date start = Tools.truncDate(new Date(startTime), Constant.HOUR_PATTERN);
Date end = Tools.truncDate(new Date(endTime), Constant.HOUR_PATTERN);
......@@ -739,19 +790,50 @@ public class Tools {
if (hours < 0) {
return Collections.emptyList();
}
List<Map<String, String>> hourList = new ArrayList<>(hours);
List<Map<String, Long>> hourList = new ArrayList<>(hours);
for (int i = 0; i <= hours; i++) {
Map<String, String> hourMap = new HashMap<>(4);
Map<String, Long> hourMap = new HashMap<>(4);
//开始时间
hourMap.put("startTime", df.format(DateUtils.addHours(start, i)));
hourMap.put("startTime", DateUtils.addHours(start, i).getTime());
//结束时间
hourMap.put("endTime", df.format(DateUtils.addHours(start, i + 1)));
hourMap.put("endTime", DateUtils.addHours(start, i + 1).getTime());
hourList.add(hourMap);
}
return hourList;
}
/**
* 解析时间转换成按月基数时间的集合
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 按月基数分割时间的集合
*/
public static List<Map<String, Long>> parseToDaysWithBase(Long startLong, Long endLong) {
Date start = Tools.truncDate(new Date(startLong), Constant.DAY_PATTERN);
Date end = Tools.truncDate(new Date(endLong - 1), Constant.DAY_PATTERN);
Period periodDays = new Period(start.getTime(), end.getTime(), PeriodType.days());
Period periodMonths = new Period(start.getTime(), end.getTime(), PeriodType.months());
int base = (periodMonths.getMonths() + 1);
int days = periodDays.getDays() / (periodMonths.getMonths() + 1);
if (days < 0) {
return Collections.emptyList();
}
List<Map<String, Long>> dayList = new ArrayList<>(days);
for (int i = 0; i <= days; i++) {
//开始时间
Long startTime = DateUtils.addDays(start, base * i).getTime();
//结束时间
Long endTime = i == days ? (DateUtils.addDays(end, 1)).getTime() : DateUtils.addDays(start, base * (i + 1)).getTime();
Map<String, Long> dayMap = new HashMap<>(4);
dayMap.put("startTime", startTime);
dayMap.put("endTime", endTime);
dayList.add(dayMap);
}
return dayList;
}
/**
* 是否包含关键字
*
* @param keywords 关键词数据
......@@ -761,20 +843,14 @@ public class Tools {
public static boolean isContains(List<String> keywords, String content) {
boolean contains = true;
content = content.toLowerCase();
for (String value : keywords) {
//按空格分割必须全部命中
String[] keys = value.split(" ");
for (String key : keys) {
if (!content.contains(key.toLowerCase())) {
//一个不命中,直接结束当前循环
contains = false;
break;
// 按空格分割必须全部命中
for (String keyword : keywords) {
for (String word : keyword.split(" ")) {
if (!content.contains(word.toLowerCase())) {
//一个不命中,直接返回false
return false;
}
}
if (contains) {
//已经满足条件,视为有效数据,结束循环
break;
}
}
return contains;
}
......@@ -803,4 +879,17 @@ public class Tools {
return res;
}
public static String getTitleWithContent(String title, String... contents) {
if (null != title) {
return title;
} else {
for (String content : contents) {
if (null != content) {
return content.substring(0, Math.min(20, content.length()));
}
}
}
return null;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment