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);
}
}
......@@ -29,10 +29,10 @@ public interface EventDao extends BaseMongoDao<Event> {
*
* @param yqEventId 舆情事件id
* @param projectId 项目id
* @param linkedGroupId 关联项目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);
/**
......@@ -70,4 +70,28 @@ public interface EventDao extends BaseMongoDao<Event> {
*/
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);
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, getAggreeCollection(), JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
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
......@@ -62,35 +54,4 @@ 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,13 +167,15 @@ public interface MarkDataService {
/**
* 竞品库-获取搜索条件
* @param linkedGroupId 关联组Id
*
* @param contendId 竞品Id
* @return 搜索条件
*/
JSONObject getContendSearchCriteria(String linkedGroupId);
JSONObject getContendSearchCriteria(String contendId);
/**
* 竞品库-获取搜索结果列表
*
* @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,12 +459,11 @@ 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();
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;
......@@ -487,9 +487,6 @@ public class CustomEventServiceImpl implements CustomEventService {
line.put("negCount", negCount);
line.put("time", startTime);
lineList.add(line);
} catch (ParseException pe) {
log.error("时间转换错误");
}
}
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;
}
}
......@@ -27,6 +27,7 @@ import com.zhiwei.brandkbs2.pojo.EventData;
import com.zhiwei.brandkbs2.pojo.EventDisseminationTrend;
import com.zhiwei.brandkbs2.pojo.EventTopArticlesAnalysis;
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.service.EventDataService;
......@@ -43,7 +44,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
......@@ -110,6 +110,11 @@ public class EventServiceImpl implements EventService {
@Resource
private RedisUtil redisUtil;
/**
* 重要渠道集合
*/
private static final List<String> IMPORTANT_CHANNEL_LIST = new ArrayList<>(Arrays.asList("央级", "科技", "财经", "其他"));
// private static final Pattern PATTERN = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]");
@Override
......@@ -123,9 +128,9 @@ public class EventServiceImpl implements EventService {
}
@Override
public void addYqEvents(String linkedGroupId, List<YqEventDTO> yqEventList) {
public void addYqEvents(String contendId, List<YqEventDTO> yqEventList) {
String projectId = UserThreadLocal.getProjectId();
String redisKey = RedisKeyPrefix.yuqingProgressKey(linkedGroupId);
String redisKey = RedisKeyPrefix.yuqingProgressKey(contendId);
if (CollectionUtils.isEmpty(yqEventList)) {
stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(100), 1, TimeUnit.MINUTES);
}
......@@ -139,8 +144,8 @@ public class EventServiceImpl implements EventService {
//事件太多塞满队列了
ApplicationProjectListener.getThreadPool().execute(() -> {
yqEventList.forEach(yqEventDTO -> {
Event existEvent = eventDao.getEventByUniqueIds(yqEventDTO.getYqEventId(), projectId, linkedGroupId);
Event event = Event.createFromYqEventDTO(yqEventDTO, collectionName, projectId, linkedGroupId);
Event existEvent = eventDao.getEventByUniqueIds(yqEventDTO.getYqEventId(), projectId, contendId);
Event event = Event.createFromYqEventDTO(yqEventDTO, collectionName, projectId, contendId);
if (null != existEvent) {
event.setId(existEvent.getId());
event.setCTime(existEvent.getCTime());
......@@ -179,7 +184,7 @@ public class EventServiceImpl implements EventService {
}
log.info("开始导入" + resList.size() + "个事件...");
List<YqEventDTO> list = resList.stream().map(YqEventDTO::createFromUrlJson).collect(Collectors.toList());
addYqEvents(yqEventSearchVO.getLinkedGroupId(), list);
addYqEvents(yqEventSearchVO.getContendId(), list);
}
@Override
......@@ -239,14 +244,14 @@ public class EventServiceImpl implements EventService {
}
@Override
public JSONObject uploadEventDatas(String linkedGroupId, MultipartFile file) {
public JSONObject uploadEventDatas(String contendId, MultipartFile file) {
String uuid = Tools.getUUID();
String redisKey = RedisKeyPrefix.eventDataProgressKey(uuid);
stringRedisTemplate.opsForValue().set(redisKey, "0");
ApplicationProjectListener.getThreadPool().execute(() -> {
ReadExcelDTO<UploadEventDataDTO> readExcel = new ReadExcelDTO<>();
readExcel.setClazz(UploadEventDataDTO.class);
readExcel.setAnalysisEventListener(new EventDataListener(eventDao, eventDataDao, stringRedisTemplate, linkedGroupId, redisKey));
readExcel.setAnalysisEventListener(new EventDataListener(eventDao, eventDataDao, stringRedisTemplate, contendId, redisKey));
EasyExcelUtil.read(file, readExcel);
stringRedisTemplate.delete(redisKey);
});
......@@ -432,31 +437,30 @@ public class EventServiceImpl implements EventService {
}
@Override
public void addFileEvents(String linkedGroupId, String fileUrl) {
public void addFileEvents(String contendId, String fileUrl) {
//获取事件信息
ApplicationProjectListener.getThreadPool().execute(() -> {
ReadExcelDTO<UploadEventDTO> readExcelDTO = new ReadExcelDTO<>();
readExcelDTO.setClazz(UploadEventDTO.class);
EventFileListener eventFileListener = new EventFileListener(this, UserThreadLocal.getProjectId(), linkedGroupId);
EventFileListener eventFileListener = new EventFileListener(this, UserThreadLocal.getProjectId(), contendId);
readExcelDTO.setAnalysisEventListener(eventFileListener);
EasyExcelUtil.read(brandkbsFileUrl + fileUrl, readExcelDTO);
});
}
@Override
public void addFileEvent(String projectId, String linkedGroupId, UploadEventDTO eventDTO) {
public void addFileEvent(String projectId, String contendId, UploadEventDTO eventDTO) {
if (StringUtils.isEmpty(eventDTO.getTitle()) || StringUtils.isEmpty(eventDTO.getKeyword())) {
return;
}
Event event = Event.createFromUploadEventDTO(eventDTO, eventDataDao.generateCollectionName(), projectId, linkedGroupId);
Event event = Event.createFromUploadEventDTO(eventDTO, eventDataDao.generateCollectionName(), projectId, contendId);
event.setCTime(new Date().getTime());
eventDao.insertOne(event);
}
@Override
public void analysisEvents(List<String> eventIds) {
// ApplicationProjectListener.getThreadPool().execute(() -> eventIds.forEach(eventId -> {
eventIds.forEach(eventId -> {
ApplicationProjectListener.getThreadPool().execute(() -> eventIds.forEach(eventId -> {
String redisKey = null;
try {
Event event = getEventById(eventId);
......@@ -469,8 +473,7 @@ public class EventServiceImpl implements EventService {
log.error("事件id:{}更新失败", eventId, e);
redisUtil.set(redisKey, "-1");
}
});
// }));
}));
}
@Override
......@@ -520,26 +523,35 @@ public class EventServiceImpl implements EventService {
// 时间
result.put("times", getDefaultTimes());
// 传播量
result.put("articleAmount", Arrays.asList("全部", "1-100", "100-500", "1000-5000", ">5000"));
result.put("totalDisseminationVolume", getDefaultVolumes());
return result;
}
@Override
public PageVO<EventListInfoVO> getEventList(String contendId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter) {
public PageVO<EventListInfoVO> getEventList(EventSearchDTO eventSearchDTO) {
String projectId = UserThreadLocal.getProjectId();
// 查询条件
Query query = Query.query(Criteria.where("projectId").is(projectId).and("contendId").is(contendId));
if (Objects.nonNull(emotion) && !"全部".equals(emotion)) {
query.addCriteria(Criteria.where("emotion").is(emotion));
Query query = Query.query(Criteria.where("projectId").is(projectId).and("contendId").is(eventSearchDTO.getContendId()));
if (!(Objects.isNull(eventSearchDTO.getEmotions()) || eventSearchDTO.getEmotions().contains("全部"))) {
query.addCriteria(Criteria.where("emotion").in(eventSearchDTO.getEmotions()));
}
if (Objects.nonNull(eventSearchDTO.getStartTime()) && Objects.nonNull(eventSearchDTO.getEndTime())) {
query.addCriteria(Criteria.where("startTime").gte(eventSearchDTO.getStartTime()).lt(eventSearchDTO.getEndTime()));
}
if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) {
query.addCriteria(Criteria.where("startTime").gte(startTime).lt(endTime));
// 传播量
if (Objects.nonNull(eventSearchDTO.getTotalDisseminationVolumes())) {
Long[] totalDisseminationVolumes = eventSearchDTO.getTotalDisseminationVolumes();
Criteria volumeCriteria = Criteria.where("totalDisseminationVolume").gte(totalDisseminationVolumes[0]);
if (-1 != totalDisseminationVolumes[1]) {
volumeCriteria.lt(totalDisseminationVolumes[1]);
}
query.addCriteria(volumeCriteria);
}
// 总数
long total = eventDao.count(query);
// 排序
eventDao.addSort(query, sorter);
mongoUtil.start(page, pageSize, query);
eventDao.addSort(query, eventSearchDTO.getSorter().toJSONString());
mongoUtil.start(eventSearchDTO.getPage(), eventSearchDTO.getPageSize(), query);
// 数据
List<Event> eventList = eventDao.findList(query);
// vo封装
......@@ -549,14 +561,15 @@ public class EventServiceImpl implements EventService {
// vo.setFirstEventData(eventDataDao.findFirstData(event.getId(), event.getCollectionName()));
// return vo;
// }).collect(Collectors.toList());
// 保证排序
// 保证排序
Map<String, EventListInfoVO> sortMap = eventList.stream().collect(Collectors.toConcurrentMap(Event::getId, EventListInfoVO::new));
CompletableFuture.allOf(eventList.stream().map(event -> eventDataDao.findFirstDataAsync(event.getId(), event.getCollectionName()).thenApply((r) -> {
// 设置首发稿件
sortMap.get(event.getId()).setFirstEventData(r);
return null;
})).toArray(CompletableFuture[]::new)).join();
return PageVO.createPageVo(total, page, pageSize, eventList.stream().map(event -> sortMap.get(event.getId())).collect(Collectors.toList()));
return PageVO.createPageVo(total, eventSearchDTO.getPage(), eventSearchDTO.getPageSize(),
eventList.stream().map(event -> sortMap.get(event.getId())).collect(Collectors.toList()));
}
@Override
......@@ -576,31 +589,31 @@ public class EventServiceImpl implements EventService {
}
@Override
public PageVO<EventData> getEventChannelVoices(String eventId, String type, int page, int pageSize, String sorter) {
public List<JSONObject> getEventChannelVoices(String eventId, String type, int page, int pageSize, String sorter) {
Event event = getEventById(eventId);
Query query = Query.query(Criteria.where("eventId").is(eventId));
if (Objects.equals("重要渠道", type)) {
query.addCriteria(Criteria.where("sourceTag").ne(null));
}
// 排序
JSONObject sortJson = JSONObject.parseObject(sorter);
sortJson.entrySet().forEach(sortEntry -> {
String sort = String.valueOf(sortEntry.getValue()).replace("end", "");
String sortField = sortEntry.getKey();
if (Sort.Direction.ASC.name().equalsIgnoreCase(sort)) {
query.with(Sort.by(Sort.Direction.ASC, sortField));
} else {
query.with(Sort.by(Sort.Direction.DESC, sortField));
query.addCriteria(Criteria.where("mediaType").in(IMPORTANT_CHANNEL_LIST));
}
});
mongoUtil.start(page, pageSize, query);
// 总数
long total = eventDataDao.count(query, event.getCollectionName());
int start = pageSize * (page - 1);
query.limit(pageSize).skip(start);
// 排序
eventDataDao.addSort(query, sorter);
// 数据
List<EventData> eventDataList = eventDataDao.findList(query, event.getCollectionName());
PageVO<EventData> pageVo = PageVO.createPageVo(total, page, pageSize, eventDataList);
return pageVo;
// 分组排序
Map<String, List<EventData>> groupMap = new HashMap<>();
for (EventData eventData : eventDataList) {
groupMap.putIfAbsent(eventData.getMediaType(), new ArrayList<>());
groupMap.get(eventData.getMediaType()).add(eventData);
}
return groupMap.entrySet().stream().map(entry -> {
JSONObject json = new JSONObject();
json.put("type", entry.getKey());
json.put("list", entry.getValue());
return json;
}).collect(Collectors.toList());
}
@Override
......@@ -643,19 +656,40 @@ public class EventServiceImpl implements EventService {
String year = Tools.DF_YEAR.format(new Date());
int yearInt = Integer.parseInt(year);
List<Integer> years = Arrays.asList(yearInt, yearInt - 1, yearInt - 2);
List<JSONObject> collect = years.stream().map(yearInfo -> {
return years.stream().map(yearInfo -> {
JSONObject result = new JSONObject();
try {
String yearStr = String.valueOf(yearInfo);
result.put("name", yearStr);
result.put("startTime", Tools.DF_YEAR.parse(yearStr));
result.put("endTime", Tools.DF_YEAR.parse(yearStr));
result.put("startTime", Tools.DF_YEAR.parse(yearStr).getTime());
result.put("endTime", Tools.DF_YEAR.parse(yearStr).getTime());
} catch (ParseException e) {
throw new RuntimeException(e);
}
return result;
}).collect(Collectors.toList());
return collect;
}
private List<JSONObject> getDefaultVolumes() {
List<JSONObject> res = new ArrayList<>();
for (String name : Arrays.asList("全部", "1-100", "100-1000", "1000-5000", ">=5000")) {
JSONObject json = new JSONObject();
json.put("name", name);
switch (name) {
case "全部":
json.put("totalDisseminationVolumes", null);
break;
case ">=5000":
json.put("totalDisseminationVolumes", new Long[]{5000L, -1L});
break;
default:
String[] split = name.split("-");
json.put("totalDisseminationVolumes", new Long[]{Long.parseLong(split[0]), Long.parseLong(split[1])});
}
res.add(json);
}
return res;
}
/**
......@@ -763,7 +797,7 @@ public class EventServiceImpl implements EventService {
List<JSONObject> resList = new ArrayList<>(array.size());
for (int i = 0; i < array.size(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
jsonObject.put("exists", eventDao.existEventByUniqueIds(jsonObject.getString("id"), UserThreadLocal.getProjectId(), yqEventSearchVO.getLinkedGroupId()));
jsonObject.put("exists", eventDao.existEventByUniqueIds(jsonObject.getString("id"), UserThreadLocal.getProjectId(), yqEventSearchVO.getContendId()));
resList.add(jsonObject);
}
return Pair.of(result.getLongValue("total"), resList);
......
package com.zhiwei.brandkbs2.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.auth.UserThreadLocal;
import com.zhiwei.brandkbs2.common.GlobalPojo;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.dao.EventDataDao;
import com.zhiwei.brandkbs2.enmus.EmotionEnum;
import com.zhiwei.brandkbs2.exception.ExceptionCast;
import com.zhiwei.brandkbs2.listener.ApplicationProjectListener;
import com.zhiwei.brandkbs2.model.CommonCodeEnum;
import com.zhiwei.brandkbs2.pojo.BaseMap;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.service.CommonService;
import com.zhiwei.brandkbs2.service.IndexService;
import com.zhiwei.brandkbs2.service.MarkDataService;
import com.zhiwei.brandkbs2.service.ProjectService;
import com.zhiwei.brandkbs2.util.RedisUtil;
import com.zhiwei.brandkbs2.util.Tools;
import com.zhiwei.qbjc.bean.pojo.common.MessagePlatform;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
* @ClassName: IndexServiceImpl
* @Description IndexServiceImpl
* @author: sjj
* @date: 2022-08-18 15:17
*/
@Service("indexServiceImpl")
public class IndexServiceImpl implements IndexService {
@Resource
private CommonService commonService;
@Resource
private MarkDataService markDataService;
@Resource
private ProjectService projectService;
@Resource
private EventDao eventDao;
@Resource
private EventDataDao eventDataDao;
@Resource
private RedisUtil redisUtil;
@Override
public JSONObject getYuqingAmount(Long startTime, Long endTime, boolean cache) {
if (null == startTime || null == endTime) {
Long[] timeRangeMonth = commonService.getTimeRangeMonth();
startTime = timeRangeMonth[0];
endTime = timeRangeMonth[1];
}
String projectId = UserThreadLocal.getProjectId();
String contendId = "0";
String redisKey = RedisUtil.getIndexYuqingKey(projectId, startTime, endTime);
String resultStr;
// 返回缓存
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseObject(resultStr);
}
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("startTime", startTime);
jsonObject.put("endTime", endTime);
//获取时间范围内总稿件数
long rangeCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
long oldStart = startTime - (endTime - startTime);
jsonObject.put("rangeCount", rangeCount);
//获取项目总月份数
int totalMonths = new Period(markDataService.getYuqingMarkFirstTime(projectId, contendId), System.currentTimeMillis(), PeriodType.months()).getMonths();
//获取选择时间月份数
int selectMonths = new Period(startTime, endTime, PeriodType.months()).getMonths();
if (selectMonths <= 0) {
selectMonths = 1;
}
//获取总稿件数
long totalCount = markDataService.getYuqingMarkCount(null, null, EmotionEnum.ALL.getName(), projectId, contendId);
jsonObject.put("avgTotal", totalCount * selectMonths / (totalMonths + 1));
//获取上一周期时间范围内总稿件数
long lastRangeCount = markDataService.getYuqingMarkCount(oldStart, startTime, EmotionEnum.ALL.getName(), projectId, contendId);
jsonObject.put("compare", lastRangeCount == 0 ? 0d : (rangeCount - lastRangeCount) / (double) lastRangeCount);
List<Map<String, Long>> dayList = Tools.parseToDaysWithBase(startTime, endTime);
jsonObject.put("spread", this.getArticleSpreadWithBrand(projectId, Constant.PRIMARY_CONTEND_ID, dayList));
redisUtil.set(redisKey, JSON.toJSONString(jsonObject));
} catch (Exception e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("getYuqingAmount异常"), e);
}
return jsonObject;
}
@Override
public JSONObject getReputation(Long startTime, Long endTime, boolean cache) {
if (null == startTime || null == endTime) {
Long[] timeRangeMonth = commonService.getTimeRangeMonth();
startTime = timeRangeMonth[0];
endTime = timeRangeMonth[1];
}
String projectId = UserThreadLocal.getProjectId();
String redisKey = RedisUtil.getIndexReputationKey(projectId, startTime, endTime);
String resultStr;
// 返回缓存
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseObject(resultStr);
}
JSONObject jsonObject = new JSONObject();
try {
long oldStartTime = startTime - (endTime - startTime);
//获取总稿件数
long totalNormalCount = markDataService.getYuqingMarkCount(null, null, EmotionEnum.ALL.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取总正面稿件数
long totalPositiveCount = markDataService.getYuqingMarkCount
(null, null, EmotionEnum.POSITIVE.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取时间范围内总稿件数
long normalCount = markDataService.getYuqingMarkCount
(startTime, endTime, EmotionEnum.ALL.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取时间范围内总正面稿件数
long positiveCount = markDataService.getYuqingMarkCount
(startTime, endTime, EmotionEnum.POSITIVE.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取时间范围内总中性稿件数
long neutralCount = markDataService.getYuqingMarkCount
(startTime, endTime, EmotionEnum.NEUTRAL.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取时间范围内总负面稿件数
long negativeCount = markDataService.getYuqingMarkCount
(startTime, endTime, EmotionEnum.NEGATIVE.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取上个周期时间范围内总正面稿件数
long oldCount = markDataService.getYuqingMarkCount
(oldStartTime, startTime, EmotionEnum.ALL.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
//获取上个周期时间范围内总正面稿件数
long oldPositiveCount = markDataService.getYuqingMarkCount
(oldStartTime, startTime, EmotionEnum.POSITIVE.getName(), projectId, Constant.PRIMARY_CONTEND_ID);
double posPro = normalCount == 0 ? 0d : positiveCount / (double) normalCount;
double neuPro = normalCount == 0 ? 0d : neutralCount / (double) normalCount;
double negPro = normalCount == 0 ? 0d : negativeCount / (double) normalCount;
double oldPosPro = oldCount == 0 ? 0d : oldPositiveCount / (double) oldCount;
jsonObject.put("posPro", posPro);
jsonObject.put("neuPro", neuPro);
jsonObject.put("negPro", negPro);
jsonObject.put("compare", oldPosPro == 0 ? 0d : (posPro - oldPosPro) / oldPosPro);
double avgPosPro = totalNormalCount == 0 ? 0d : totalPositiveCount / (double) totalNormalCount;
jsonObject.put("avgPosPro", avgPosPro);
redisUtil.set(redisKey, JSON.toJSONString(jsonObject));
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e);
}
return jsonObject;
}
@Override
public JSONObject getEventAmount(Long startTime, Long endTime, boolean cache) {
if (null == startTime || null == endTime) {
Long[] timeRangeMonth = commonService.getTimeRangeMonth();
startTime = timeRangeMonth[0];
endTime = timeRangeMonth[1];
}
String projectId = UserThreadLocal.getProjectId();
String contendId = "0";
String redisKey = RedisUtil.getIndexEventKey(projectId, startTime, endTime);
String resultStr;
// 返回缓存
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseObject(resultStr);
}
JSONObject jsonObject = new JSONObject();
try {
int totalMonths = new Period(markDataService.getYuqingMarkFirstTime(projectId, contendId), System.currentTimeMillis(), PeriodType.months()).getMonths();
Long oldStartTime = startTime - (endTime - startTime);
int selectMonths = new Period(startTime, endTime, PeriodType.months()).getMonths();
selectMonths = 0 == selectMonths ? 1 : selectMonths;
long total = eventDao.getEventCountByProjectIdAndContendId(null, null, EmotionEnum.ALL.getName(), projectId, contendId);
long eventTotal = eventDao.getEventCountByProjectIdAndContendId
(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
long oldEventTotal = eventDao.getEventCountByProjectIdAndContendId
(oldStartTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
jsonObject.put("eventTotal", eventTotal);
jsonObject.put("avgEventTotal", total * selectMonths / (totalMonths + 1));
jsonObject.put("compare", oldEventTotal == 0 ? 0d : (eventTotal - oldEventTotal) / (double) oldEventTotal);
List<Map<String, Long>> dayList = Tools.parseToDaysWithBase(startTime, endTime);
List<JSONObject> lineList = this.getEventSpreadWithBrand(projectId, contendId, dayList);
//截取传播量最高的附近7天数据
long topTotalCount =
lineList.stream().max(Comparator.comparing(json -> json.getIntValue("totalCount"))).map(json -> json.getLongValue("totalCount")).get();
int lineSize = lineList.size();
for (int i = 0; i < lineSize; i++) {
int totalCount = lineList.get(i).getIntValue("totalCount");
if (topTotalCount == totalCount) {
if (i <= 3) {
lineList = lineList.subList(0, 7);
} else if (i >= lineSize - 3) {
lineList = lineList.subList(lineSize - 7, lineSize);
} else {
lineList = lineList.subList(i - 3, i + 4);
}
break;
}
}
jsonObject.put("spread", lineList);
redisUtil.set(redisKey, JSONObject.toJSONString(jsonObject));
} catch (Exception e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("getEventAmount异常"), e);
}
return jsonObject;
}
@Override
public List<JSONObject> getPlatformInfo(Long startTime, Long endTime, boolean cache) {
if (null == startTime || null == endTime) {
Long[] timeRangeMonth = commonService.getTimeRangeMonth();
startTime = timeRangeMonth[0];
endTime = timeRangeMonth[1];
}
String projectId = UserThreadLocal.getProjectId();
String contendId = "0";
String redisKey = RedisUtil.getIndexPlatformKey(projectId, startTime, endTime);
String resultStr;
// 返回缓存
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseArray(resultStr, JSONObject.class);
}
try {
long normalCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
List<JSONObject> platforms = getPlatformProportionWithPlatform(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId, normalCount);
redisUtil.set(redisKey, JSON.toJSONString(platforms));
return platforms;
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e);
}
return Collections.emptyList();
}
@Override
public JSONObject getSpreadingTend(Long startTime, Long endTime, boolean cache) {
boolean flag = true;
if (null == startTime || null == endTime) {
Long[] timeRangeMonth = commonService.getTimeRangeMonth();
startTime = timeRangeMonth[0];
endTime = timeRangeMonth[1];
flag = false;
}
String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = projectService.getProjectById(projectId).getBrandLinkedGroupId();
String contendId = "0";
String redisKey = RedisUtil.getIndexSpread(projectId, startTime, endTime);
String resultStr;
// 返回缓存
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseObject(resultStr, JSONObject.class);
}
JSONObject resJson = new JSONObject();
try {
Period periodYears = new Period(startTime, endTime - 1, PeriodType.years());
Period periodMonths = new Period(startTime, endTime - 1, PeriodType.months());
String type;
if (periodYears.getYears() > 1) {
type = "year";
} else if (flag && periodMonths.getMonths() >= 1) {
type = "month";
} else {
type = "day";
}
List<JSONObject> lineList = this.getLineWithType(startTime, endTime, projectId, type);
lineList.sort(Comparator.comparing(json -> json.getDate("time").getTime()));
resJson.put("type", type);
resJson.put("spreadingTend", lineList);
JSONObject summary = new JSONObject();
List<Map.Entry<String, Integer>> resList = markDataService.getMarkTopTitle(startTime, endTime, EmotionEnum.ALL.getName(), projectId, linkedGroupId, contendId, 1);
summary.put("yqSpread", this.getYqSpread(startTime, endTime, projectId, contendId, lineList, type, flag));
summary.put("pcTopArticle", this.getPcTopArticle(startTime, endTime, projectId, linkedGroupId, contendId, resList));
summary.put("topArticle", this.getMobileTopArticle(startTime, endTime, projectId, linkedGroupId, contendId, resList));
summary.put("topEvent", this.getTopEvent(startTime, endTime, projectId, contendId));
summary.put("topSource", this.getTopSource(startTime, endTime, projectId, linkedGroupId, contendId));
resJson.put("summary", summary);
redisUtil.set(redisKey, JSON.toJSONString(resJson));
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e);
}
return resJson;
}
public List<JSONObject> getPlatformProportionWithPlatform(Long startTime, Long endTime, String emotion, String projectId, String contendId, long normalCount) {
List<String> platformIds = GlobalPojo.PLATFORMS.stream().map(MessagePlatform::getId).collect(Collectors.toList());
List<JSONObject> resultList = new ArrayList<>(platformIds.size());
platformIds.forEach(platformId -> {
JSONObject result = new JSONObject();
long count;
try {
count = markDataService.getYuqingMarkCount(startTime, endTime, emotion, platformId, projectId, contendId);
} catch (IOException ignored) {
count = -1;
}
result.put("platform", platformId);
result.put("num", count);
result.put("proportion", normalCount == 0 ? 0d : count / (double) normalCount);
resultList.add(result);
});
return resultList;
}
/**
* 获取舆情传播解读
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
* @param contendId 竞品ID
* @param spreadResult 传播结果
* @return 舆情传播解读
*/
private String getYqSpread(long startTime, long endTime, String projectId, String contendId, List<JSONObject> spreadResult, String type, boolean flag) throws IOException {
//获取时间范围内总稿件数
long normalCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
//获取时间范围内总正面稿件数
long positiveCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.POSITIVE.getName(), projectId, contendId);
double reputation = normalCount == 0 ? 0d : 100 * positiveCount / (double) normalCount;
SimpleDateFormat sdf;
if ("year".equals(type)) {
type = "年";
sdf = new SimpleDateFormat("yyyy年");
} else if ("month".equals(type)) {
type = "月";
sdf = new SimpleDateFormat("M月");
} else {
type = "天";
sdf = new SimpleDateFormat("M月d日");
}
String date = spreadResult.stream().max(Comparator.comparing(json -> json.getIntValue("normalCount"))).map(json -> sdf.format(json.getDate("time"))).get();
if (!flag) {
return "近一月,传播高峰为" + date + ",全网品牌相关新闻传播总量达" + normalCount + "篇,正面内容占比为" + String.format("%.1f", reputation) + "%。";
} else {
return "近" + spreadResult.size() + type + "内,传播高峰为" + date + ",全网品牌相关新闻传播总量达" + normalCount + "篇,正面内容占比为" + String.format("%.1f", reputation) + "%。";
}
}
/**
* 获取最热文章(PC)
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param resList 首发稿件列表
* @return 最热文章
*/
private JSONObject getPcTopArticle(long startTime, long endTime, String projectId, String linkedGroupId, String contendId, List<Map.Entry<String, Integer>> resList) throws IOException {
JSONObject result = new JSONObject();
if (CollectionUtils.isNotEmpty(resList)) {
Map.Entry<String, Integer> resMap = resList.get(0);
String aggTitle = resMap.getKey();
BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId, contendId);
result.put("title", firstArticle.getTitleNullOptionalContent());
result.put("url", firstArticle.getUrl());
result.put("time", firstArticle.getTime());
result.put("source", firstArticle.getSource());
result.put("platform", firstArticle.getPlatform());
result.put("num", resMap.getValue());
}
return result;
}
/**
* 获取最热文章(mobile)
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
* @param contendId 竞品ID
* @return 最热文章
*/
private String getMobileTopArticle(long startTime, long endTime, String projectId, String linkedGroupId, String contendId, List<Map.Entry<String, Integer>> resList) throws IOException {
if (CollectionUtils.isEmpty(resList)) {
return "暂无最热文章。";
}
Map.Entry<String, Integer> resMap = resList.get(0);
String aggTitle = resMap.getKey();
BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId, contendId);
SimpleDateFormat format = new SimpleDateFormat("M月d日");
return "《" + firstArticle.getTitleNullOptionalContent() + "》一文于" + format.format(firstArticle.getTime()) + "在" + firstArticle.getSource()
+ "(" + firstArticle.getPlatform() + ")上首发,相似文章数" + resMap.getValue() + "篇。";
}
/**
* 获取最热事件
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
* @param contendId 竞品ID
* @return 最热事件
*/
private JSONObject getTopEvent(Long startTime, Long endTime, String projectId, String contendId) {
JSONObject result = new JSONObject();
List<Event> eventList = eventDao.getEventsByProjectIdAndContendId(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId, 1);
if (CollectionUtils.isNotEmpty(eventList)) {
Event event = eventList.get(0);
long articleCount = eventDataDao.getEventArticleCount(event);
result.put("id", event.getId());
result.put("title", event.getTitle());
result.put("influence", event.getInfluence());
result.put("articleCount", articleCount);
}
return result;
}
/**
* 获取高频渠道
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
* @param contendId 竞品ID
* @return 高频渠道
*/
private JSONObject getTopSource(long startTime, long endTime, String projectId, String linkedGroupId, String contendId) throws IOException {
JSONObject result = new JSONObject();
// TODO 等待线上es数据格式调整
// List<Map<String, Object>> positiveList = markDataService.getEsTopSource(startTime, endTime, projectId, linkedGroupId, contendId, EmotionEnum.POSITIVE.getName(), 3);
// List<Map<String, Object>> negativeList = markDataService.getEsTopSource(startTime, endTime, projectId, linkedGroupId, contendId, EmotionEnum.NEGATIVE.getName(), 1);
result.put("positiveList", tempTopSource());
result.put("negativeList", tempTopSource());
return result;
}
private List<Map<String, Object>> tempTopSource() {
List<Map<String, Object>> channelResultList = new ArrayList<>();
Map<String, Object> result = new HashMap<>();
result.put("id", "testId");
result.put("source", "source");
result.put("platform", "微信");
result.put("num", "1");
channelResultList.add(result);
return channelResultList;
}
/**
* 传播趋势
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
*/
private List<JSONObject> getLineWithType(Long startTime, Long endTime, String projectId, String type) {
List<Map<String, Long>> mapList;
switch (type) {
case "year": {
mapList = Tools.parseToYears(startTime, endTime);
break;
}
case "month": {
mapList = Tools.parseToMonths(startTime, endTime);
break;
}
case "day": {
mapList = Tools.parseToDays(startTime, endTime);
break;
}
default:
throw new IllegalArgumentException("lineYears-不识别的type类型:" + type);
}
return this.getLineResult(projectId, type, mapList);
}
/**
* 获取传播趋势结果
*
* @param projectId 项目ID
* @param type 传播类型
* @param dateList 时间区间集合
* @return 传播趋势结果
*/
private List<JSONObject> getLineResult(String projectId, String type, List<Map<String, Long>> dateList) {
List<JSONObject> lineList = Collections.synchronizedList(new ArrayList<>(dateList.size()));
List<List<Map<String, Long>>> partition = ListUtils.partition(dateList, 3);
List<CompletableFuture<Void>> futureList = new ArrayList<>(partition.size());
for (List<Map<String, Long>> dates : partition) {
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
lineList.addAll(this.getGroupLineResult(projectId, type, dates));
return null;
}, ApplicationProjectListener.getThreadPool());
futureList.add(future);
}
CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])).join();
return lineList;
}
/**
* 获取传播趋势分组结果
*
* @param projectId 项目ID
* @param type 趋势类型
* @param dateList 时间区间集合
* @return 传播趋势分组结果
*/
private List<JSONObject> getGroupLineResult(String projectId, String type, List<Map<String, Long>> dateList) {
List<JSONObject> lineList = new ArrayList<>(dateList.size());
for (Map<String, Long> map : dateList) {
JSONObject result = new JSONObject();
Long startTime = map.get("startTime");
Long endTime = map.get("endTime");
//统计时间段总稿件个数
long normalCount;
try {
normalCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.ALL.getName(), projectId, "0");
} catch (IOException e) {
normalCount = -1;
}
result.put("normalCount", normalCount);
result.put("time", startTime);
//统计时间段总事件数
long eventCount = eventDao.getEventCountByProjectIdAndContendId(startTime, endTime, EmotionEnum.ALL.getName(), projectId, "0");
result.put("eventCount", eventCount);
lineList.add(result);
}
return lineList;
}
/**
* 获取事件传播趋势结果
*
* @param projectId 项目ID
* @param contendId 竞品ID
* @param dateList 时间区间集合
* @return 稿件传播趋势结果
*/
private List<JSONObject> getEventSpreadWithBrand(String projectId, String contendId, List<Map<String, Long>> dateList) {
List<JSONObject> lineList = new ArrayList<>(dateList.size());
for (Map<String, Long> map : dateList) {
Long startTime = map.get("startTime");
Long endTime = map.get("endTime");
//统计时间段总事件数
long totalEventCount = eventDao.getEventCountByProjectIdAndContendId(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
long posEventCount = eventDao.getEventCountByProjectIdAndContendId(startTime, endTime, EmotionEnum.POSITIVE.getName(), projectId, contendId);
long neuEventCount = eventDao.getEventCountByProjectIdAndContendId(startTime, endTime, EmotionEnum.NEUTRAL.getName(), projectId, contendId);
long negEventCount = eventDao.getEventCountByProjectIdAndContendId(startTime, endTime, EmotionEnum.NEGATIVE.getName(), projectId, contendId);
JSONObject result = new JSONObject();
result.put("totalCount", totalEventCount);
result.put("posCount", posEventCount);
result.put("neuCount", neuEventCount);
result.put("negCount", negEventCount);
result.put("time", startTime);
lineList.add(result);
}
return lineList;
}
/**
* 获取稿件传播趋势结果
*
* @param projectId 项目ID
* @param contendId 竞品ID
* @param dateList 时间区间集合
* @return 稿件传播趋势结果
*/
private List<JSONObject> getArticleSpreadWithBrand(String projectId, String contendId, List<Map<String, Long>> dateList) throws Exception {
List<JSONObject> resList = new ArrayList<>(dateList.size());
for (Map<String, Long> map : dateList) {
JSONObject json = new JSONObject();
long startTime = map.get("startTime");
long endTime = map.get("endTime");
long normalCount = markDataService.getYuqingMarkCount(startTime, endTime, EmotionEnum.ALL.getName(), projectId, contendId);
json.put("num", normalCount);
json.put("startTime", startTime);
resList.add(json);
}
return resList;
}
}
......@@ -10,6 +10,7 @@ import com.zhiwei.brandkbs2.common.GlobalPojo;
import com.zhiwei.brandkbs2.common.RedisKeyPrefix;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.AggreeResultDao;
import com.zhiwei.brandkbs2.dao.ChannelDao;
import com.zhiwei.brandkbs2.enmus.ChannelEmotion;
import com.zhiwei.brandkbs2.enmus.EmotionEnum;
import com.zhiwei.brandkbs2.enmus.ImportantChannelEnum;
......@@ -21,6 +22,7 @@ import com.zhiwei.brandkbs2.model.CommonCodeEnum;
import com.zhiwei.brandkbs2.pojo.*;
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.CustomTagVo;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import com.zhiwei.brandkbs2.pojo.vo.ProjectVO;
......@@ -40,6 +42,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
......@@ -57,8 +60,10 @@ import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
......@@ -79,7 +84,10 @@ import java.util.stream.Collectors;
public class MarkDataServiceImpl implements MarkDataService {
private static final Logger log = LogManager.getLogger(MarkDataServiceImpl.class);
private static final String[] EVENT_FETCH_SOURCE = new String[]{"ind_full_text", "c5", "real_source", "source", "mtime", "time", "url", "mtag", "foreign", "brandkbs_mark_cache_maps"};
private static final String[] EVENT_FETCH_SOURCE = new String[]{"id", "ind_full_text", "c5", "real_source", "source", "mtime", "time", "url", "mtag", "foreign", "brandkbs_mark_cache_maps"};
@Value("${istarshine.addIStarShineKSData.url}")
private String addIStarShineKSDataUrl;
@Resource(name = "projectServiceImpl")
private ProjectService projectService;
......@@ -102,6 +110,9 @@ public class MarkDataServiceImpl implements MarkDataService {
@Resource(name = "aggreeResultDaoImpl")
AggreeResultDao aggreeResultDao;
@Resource(name = "channelDao")
ChannelDao channelDao;
@Resource(name = "redisUtil")
RedisUtil redisUtil;
......@@ -358,7 +369,7 @@ public class MarkDataServiceImpl implements MarkDataService {
}
result.put("negTopTitle", topTitle);
// 舆情库默认contendId为0
List<JSONObject> articlePlatformProportion = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, true);
List<JSONObject> articlePlatformProportion = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID, true);
result.put("platformRank", articlePlatformProportion.stream().filter(articlePlatform -> articlePlatform.getLongValue("count") > 0).sorted((o1, o2) -> o2.getLong("count").compareTo(o1.getLong("count"))).collect(Collectors.toList()));
redisUtil.setExpire(redisKey, JSON.toJSONString(result));
return result;
......@@ -449,7 +460,7 @@ public class MarkDataServiceImpl implements MarkDataService {
String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
// 舆情库默认contendId为0
res = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, cache);
res = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID, cache);
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e);
}
......@@ -612,8 +623,7 @@ public class MarkDataServiceImpl implements MarkDataService {
Map<String, Long> counts = new HashMap<>();
if (1 == dto.getPage() && CollectionUtils.isEmpty(dto.getPlatforms())) {
for (MessagePlatform platform : GlobalPojo.PLATFORMS) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter())
.must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter()).must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
Long count = esClientDao.count(esClientDao.getIndexes(), queryBuilder, null);
counts.put(platform.getName(), count);
}
......@@ -829,7 +839,8 @@ public class MarkDataServiceImpl implements MarkDataService {
@Override
public List<JSONObject> searchMarkDataByEvent(Event event) {
return searchMarkDataByTime(event.getProjectId(), event.getLinkedGroupId(), event.getContendId(), event.getStartTime(), event.getEndTime(), EVENT_FETCH_SOURCE);
String linkedGroupId = projectService.getProjectByContendId(event.getProjectId(), event.getContendId()).getBrandLinkedGroupId();
return searchMarkDataByTime(event.getProjectId(), linkedGroupId, event.getContendId(), event.getStartTime(), event.getEndTime(), EVENT_FETCH_SOURCE);
}
@Override
......@@ -849,18 +860,16 @@ public class MarkDataServiceImpl implements MarkDataService {
}
@Override
public JSONObject getContendSearchCriteria(String linkedGroupId) {
public JSONObject getContendSearchCriteria(String contendId) {
String projectId = UserThreadLocal.getProjectId();
if (null == linkedGroupId) {
linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
}
JSONObject result = new JSONObject();
// 搜索时间
result.put("times", Arrays.asList("今天", "24小时", "三天", "七天", "近30天"));
// 平台
result.put("platformList", commonService.getQbjcPlatform("id", "name"));
// 情感标签
result.put("emotionList", commonService.getEmotionTagsWithSort(projectId, linkedGroupId).stream().map(markerTag -> {
String contendLinkedGroupId = projectService.getProjectByContendId(projectId, contendId).getBrandLinkedGroupId();
result.put("emotionList", commonService.getEmotionTagsWithSort(projectId, contendLinkedGroupId).stream().map(markerTag -> {
JSONObject json = new JSONObject();
json.put("uniqueId", markerTag.getUniqueId());
json.put("name", markerTag.getName());
......@@ -869,17 +878,13 @@ public class MarkDataServiceImpl implements MarkDataService {
// 重要发声方
result.put("mediaTypeList", ImportantChannelEnum.getAllTagExceptSpec());
// 竞品品牌
Project project = projectService.getProjectById(projectId);
ProjectVO project = projectService.getProjectVOById(projectId);
List<JSONObject> contendNameList = project.getContendList().stream().map(contend -> {
JSONObject jsonObject = new JSONObject();
jsonObject.put("contendName", contend.getBrandName());
jsonObject.put("contendId", contend.getId());
return jsonObject;
}).collect(Collectors.toList());
JSONObject allContend = new JSONObject();
allContend.put("contendName", "全部");
allContend.put("contendId", "-1");
contendNameList.add(0, allContend);
result.put("contendNameList", contendNameList);
// 其他标签组(筛选器)
result.put("tagFilterList", tagFilterService.getTagFilter());
......@@ -915,9 +920,8 @@ public class MarkDataServiceImpl implements MarkDataService {
private Pair<SearchHits[], Map<String, Long>> searchContendMarkHitsAndCount(MarkSearchDTO dto, boolean aggree) throws IOException {
EsClientDao.SearchHelper helper = createContendSearchHelper(dto);
if (aggree) {
// TODO 本地调试不滚动查询
// List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper);
List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper));
List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper);
// <SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper));
return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null);
}
SearchHits searchHits = esClientDao.searchHits(helper);
......@@ -925,7 +929,8 @@ public class MarkDataServiceImpl implements MarkDataService {
Map<String, Long> counts = new HashMap<>();
if (1 == dto.getPage() && CollectionUtils.isEmpty(dto.getPlatforms())) {
for (MessagePlatform platform : GlobalPojo.PLATFORMS) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter()).must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter())
.must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
Long count = esClientDao.count(esClientDao.getIndexes(), queryBuilder, null);
counts.put(platform.getName(), count);
}
......@@ -937,17 +942,11 @@ public class MarkDataServiceImpl implements MarkDataService {
EsClientDao.SearchHelper helper = EsClientDao.createSearchHelper();
// linkedGroupId、projectId、contendId
String projectId = dto.getProjectId();
String linkedGroupId = dto.getLinkedGroupId();
String contendId = dto.getContendId();
List<String> contendIdList = projectService.getProjectById(projectId).getContendList().stream().map(AbstractBaseMongo::getId).collect(Collectors.toList());
// PostFilter 后置过滤器 time
BoolQueryBuilder postFilter;
if ("-1".equals(contendId) && CollectionUtils.isNotEmpty(contendIdList)) {
postFilter = QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery("brandkbs_cache_maps.key.keyword", Tools.concat(projectId, linkedGroupId, Constant.PRIMARY_CONTENDID)));
} else {
postFilter = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
}
//time
String contendLinkedGroupId = projectService.getProjectByContendId(projectId, dto.getContendId()).getBrandLinkedGroupId();
// PostFilter 后置过滤器
BoolQueryBuilder postFilter = projectLinkedGroupContendIdQuery(projectId, contendLinkedGroupId, contendId);
// time
postFilter.must(QueryBuilders.rangeQuery(dto.getTimeType()).gte(dto.getStartTime()).lt(dto.getEndTime()));
// platform
if (CollectionUtils.isNotEmpty(dto.getPlatforms())) {
......@@ -1029,7 +1028,7 @@ public class MarkDataServiceImpl implements MarkDataService {
result.put("priName", project.getBrandName());
// 获取时间段主品牌在每个平台传播量占比
List<JSONObject> primaryPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, true);
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID, true);
// 获取时间段主品牌总传播量
long primaryTotalCount = primaryPlatformsProportion.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
result.put("priNorTotal", primaryTotalCount);
......@@ -1038,12 +1037,12 @@ public class MarkDataServiceImpl implements MarkDataService {
result.put("priMaxPlatform", primaryMaxPlatformProportion.getString("platform"));
result.put("priMaxPlatformPro", primaryMaxPlatformProportion.getDoubleValue("proportion"));
// 竞品的名字
AbstractProject projectByContendId = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId());
String brandName = projectByContendId.getBrandName();
String brandName = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId()).getBrandName();
result.put("conName", brandName);
// 获取时间段竞品在每个平台传播量
String contendLinkedGroupId = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId()).getBrandLinkedGroupId();
List<JSONObject> contendPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), true);
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId(), true);
// 获取时间段竞品总传播量
long contendTotalCount = contendPlatformsProportion.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
result.put("conNorTotal", contendTotalCount);
......@@ -1053,16 +1052,11 @@ public class MarkDataServiceImpl implements MarkDataService {
result.put("conMaxPlatformPro", contendMaxPlatformProportion.getDoubleValue("proportion"));
result.put("compare", String.format("%.1f", primaryTotalCount * 1.0 / contendTotalCount));
List<JSONObject> platformPros = primaryPlatformsProportion.stream()
.peek(priJson -> {
JSONObject samePlatformJson = contendPlatformsProportion.stream()
.filter(conJson -> priJson.getString("platform").equals(conJson.getString("platform")))
.collect(Collectors.toList()).get(0);
List<JSONObject> platformPros = primaryPlatformsProportion.stream().peek(priJson -> {
JSONObject samePlatformJson = contendPlatformsProportion.stream().filter(conJson -> priJson.getString("platform").equals(conJson.getString("platform"))).collect(Collectors.toList()).get(0);
priJson.put("conProportion", samePlatformJson.getDoubleValue("proportion"));
priJson.put("conNum", samePlatformJson.getLongValue("count"));
})
.filter(json -> json.getDoubleValue("proportion") > 0.001 || json.getDoubleValue("conProportion") > 0.001)
.collect(Collectors.toList());
}).filter(json -> json.getDoubleValue("proportion") > 0.001 || json.getDoubleValue("conProportion") > 0.001).collect(Collectors.toList());
result.put("platformPros", platformPros);
redisUtil.setExpire(redisKey, JSON.toJSONString(result), 1, TimeUnit.DAYS);
return result;
......@@ -1075,6 +1069,7 @@ public class MarkDataServiceImpl implements MarkDataService {
// 竞品的名字
AbstractProject projectByContendId = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId());
String brandName = projectByContendId.getBrandName();
String contendLinkedGroupId = projectByContendId.getBrandLinkedGroupId();
// 缓存
SimpleDateFormat sdf = new SimpleDateFormat(Constant.DAY_PATTERN);
String startTimeStr = sdf.format(dto.getStartTime());
......@@ -1095,10 +1090,10 @@ public class MarkDataServiceImpl implements MarkDataService {
// 主品牌图谱
JSONObject primaryLine = new JSONObject();
primaryLine.put("id", Constant.PRIMARY_CONTENDID);
primaryLine.put("id", Constant.PRIMARY_CONTEND_ID);
primaryLine.put("brand", project.getBrandName());
List<JSONObject> primarySpread =
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID);
primaryLine.put("spread", primarySpread);
resList.add(primaryLine);
result.put("days", primarySpread.size());
......@@ -1108,7 +1103,7 @@ public class MarkDataServiceImpl implements MarkDataService {
contendLine.put("id", dto.getContendId());
contendLine.put("brand", brandName);
List<JSONObject> contendSpread =
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId());
contendLine.put("spread", contendSpread);
resList.add(contendLine);
result.put("spread", resList);
......@@ -1129,23 +1124,23 @@ public class MarkDataServiceImpl implements MarkDataService {
long priMaxDayEndTime = DateUtils.addDays(new Date(Long.parseLong(primaryMax.getString("date"))), 1).getTime();
// 获取时间段某情感数据最多的标题
List<Map.Entry<String, Integer>> priTopTitle =
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, 1);
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID, 1);
if (CollectionUtils.isNotEmpty(priTopTitle)) {
// 首发稿件
BaseMap priFirstArticle =
getFirstArticle(priMaxDayStartTime, priMaxDayEndTime, priTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
getFirstArticle(priMaxDayStartTime, priMaxDayEndTime, priTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID);
result.put("priTopTitle", priFirstArticle.getTitle());
result.put("priTopTitleUrl", priFirstArticle.getUrl());
}
// 获取主品牌热门媒体方向
List<Map.Entry<String, Integer>> priHotTitles =
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, hotArticleSize);
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID, hotArticleSize);
if (CollectionUtils.isNotEmpty(priHotTitles)) {
List<JSONObject> priHotArticle = priHotTitles.stream().map(map -> {
JSONObject jsonObject = new JSONObject();
try {
BaseMap priFirstArticle =
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTEND_ID);
if (null != priFirstArticle) {
jsonObject.put("title", priFirstArticle.getTitle());
jsonObject.put("url", priFirstArticle.getUrl());
......@@ -1175,24 +1170,24 @@ public class MarkDataServiceImpl implements MarkDataService {
long conMaxDayStartTime = Long.parseLong(primaryMax.getString("date"));
long conMaxDayEndTime = DateUtils.addDays(new Date(Long.parseLong(primaryMax.getString("date"))), 1).getTime();
List<Map.Entry<String, Integer>> conTopTitle =
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), 1);
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId(), 1);
if (CollectionUtils.isNotEmpty(conTopTitle)) {
// 首发稿件
BaseMap conFirstArticle =
getFirstArticle(conMaxDayStartTime, conMaxDayEndTime, conTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
getFirstArticle(conMaxDayStartTime, conMaxDayEndTime, conTopTitle.get(0).getKey(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId());
result.put("conTopTitle", conFirstArticle.getTitle());
result.put("conTopTitleUrl", conFirstArticle.getUrl());
}
// 获取竞品热门媒体方向
List<Map.Entry<String, Integer>> conHotTitles =
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), hotArticleSize);
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId(), hotArticleSize);
if (CollectionUtils.isNotEmpty(conHotTitles)) {
List<JSONObject> conHotArticle = conHotTitles.stream().map(map -> {
JSONObject jsonObject = new JSONObject();
try {
BaseMap conFirstArticle =
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), contendLinkedGroupId, dto.getContendId());
if (null != conFirstArticle) {
jsonObject.put("title", conFirstArticle.getTitle());
jsonObject.put("url", conFirstArticle.getUrl());
......@@ -1209,6 +1204,138 @@ public class MarkDataServiceImpl implements MarkDataService {
return result;
}
@Override
public Pair<String, List<ExportAppYuqingDTO>> downloadContendMarkList(MarkSearchDTO markSearchDTO) {
try {
ProjectVO project = projectService.getProjectVOById(UserThreadLocal.getProjectId());
List<ExportAppYuqingDTO> returnList = new ArrayList<>();
defaultMarkSearch(markSearchDTO);
Pair<SearchHits[], Map<String, Long>> hitsAndCounts = searchContendMarkHitsAndCount(markSearchDTO, false);
for (SearchHits searchHits : hitsAndCounts.getLeft()) {
List<ExportAppYuqingDTO> collect = Arrays.stream(searchHits.getHits()).map(SearchHit::getSourceAsMap).map(ExportAppYuqingDTO::createFromEsMap).collect(Collectors.toList());
returnList.addAll(collect);
}
return Pair.of(project.getBrandName() + "_" + markSearchDTO.getStartTime() + "_" + markSearchDTO.getEndTime(), returnList);
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es检索异常"));
}
return null;
}
@Override
public JSONObject searchWholeNetwork(SearchFilterDTO dto) {
// Project project = projectService.getProjectById(dto.getProjectId());
// if (1 == project.getWholeSearchDataSource()){
// defaultSearchFilter(dto);
// try {
// JSONObject params = IstarShineUtil.getKSSearchParam(keyword, null, dto.getStartTime(), dto.getEndTime(), platforms,
// filterForward, sortOf, dto.getPage(), dto.getPageSize(), matchFields,null,null);
//
// JSONObject taskEntity = new JSONObject();
//
// taskEntity.put("appId", "6183571e0d710000f6003a12"); //应用id,由张志伟提供给使用者
// taskEntity.put("taskType", ""); //可为null, 任务类型
// taskEntity.put("taskDescription", ""); //可为null, 任务描述
// taskEntity.put("userName", "品见"); //提交任务的人
// taskEntity.put("searchParams", params); //任务详情参数
//
// ResponseEntity<JSONObject> entity = restTemplate.postForEntity(url, taskEntity, JSONObject.class);
// JSONObject result = entity.getBody().getJSONObject("data");
// return searchWholeBackUp(result.get("id").toString());
// }
// }
return null; //TODO
}
private void defaultSearchFilter(SearchFilterDTO dto){
String projectId = UserThreadLocal.getProjectId();
dto.setProjectId(projectId);
// 平台为空时,传全部
if (dto.getPlatforms().size() == 0 ){
dto.setPlatforms(Arrays.asList("微博","微信","新闻","平媒","自媒体","论坛","视频","短视频"));
}
// 平台
dto.setPlatformsStr(StringUtils.join(dto.getPlatforms(), ",")); //平台
// sort
dto.setSortOf("ctime+" + dto.getSorter());
// matchFields
if(dto.getMatchType().equals("标题")){
dto.setMatchFields("title");
}
}
@Override
public long getYuqingMarkCount(Long startTime, Long endTime, String emotion, String projectId, String contendId) throws IOException {
return getYuqingMarkCount(startTime, endTime, emotion, null, projectId, contendId);
}
@Override
public long getYuqingMarkCount(Long startTime, Long endTime, String emotion, String platformId, String projectId, String contendId) throws IOException {
BoolQueryBuilder filter = projectLinkedGroupContendIdQuery(projectId, projectService.getProjectById(projectId).getBrandLinkedGroupId(), contendId);
if (null != startTime) {
filter.must(QueryBuilders.rangeQuery("time").gte(startTime));
}
if (null != endTime) {
filter.must(QueryBuilders.rangeQuery("time").lt(endTime));
}
if (StringUtils.isNotEmpty(emotion) && !EmotionEnum.ALL.getName().equals(emotion)) {
filter.must(QueryBuilders.termQuery("brandkbs_mark_cache_maps.name.keyword", emotion));
}
if (null != platformId) {
filter.must(QueryBuilders.termQuery("platform_id.keyword", platformId));
}
return esClientDao.count(filter);
}
@Override
public long getYuqingMarkFirstTime(String projectId, String contendId) throws IOException {
EsClientDao.SearchHelper searchHelper = EsClientDao.createSearchHelper();
BoolQueryBuilder filter = projectLinkedGroupContendIdQuery(projectId, projectService.getProjectById(projectId).getBrandLinkedGroupId(), contendId);
searchHelper.setPostFilter(filter);
searchHelper.setSort(SortBuilders.fieldSort("time").order(SortOrder.ASC));
searchHelper.setSize(1);
return Long.parseLong(esClientDao.searchResponse(searchHelper).getHits().getAt(0).getSourceAsMap().get("time") + "");
}
@Override
public List<Map<String, Object>> getEsTopSource(Long startTime, Long endTime, String projectId, String linkedGroupId, String contendId, String emotion, int size) throws IOException {
EsClientDao.SearchHelper searchHelper = EsClientDao.createSearchHelper();
// 聚合条件
Script script = new Script("doc['platform_id'].value +'_' +doc['real_source'].value+'_' +doc['source'].value");
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("agg").script(script).order(BucketOrder.count(false));
searchHelper.setAggregationBuilder(aggregationBuilder);
// query
BoolQueryBuilder query = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
query.must(QueryBuilders.rangeQuery("time").gte(startTime).lt(endTime));
if (StringUtils.isNotEmpty(emotion) && !EmotionEnum.ALL.getName().equals(emotion)) {
query.must(QueryBuilders.termQuery("brandkbs_mark_cache_maps.name.keyword", emotion));
}
// 搜索结果
SearchResponse searchResponse = esClientDao.searchResponse(searchHelper);
List<Map<String, Object>> channelResultList = new ArrayList<>();
Map<String, Aggregation> aggMap = searchResponse.getAggregations().asMap();
ParsedStringTerms teamAgg = (ParsedStringTerms) aggMap.get("agg");
List<? extends Terms.Bucket> buckets = teamAgg.getBuckets();
buckets.forEach(bucket -> {
if (channelResultList.size() < size) {
String[] keys = bucket.getKeyAsString().split("_");
String channelFid = Tools.concat(projectId, contendId, GlobalPojo.getPlatformNameById(keys[0]), keys[1], keys[2]);
Channel channel = channelDao.queryUnique(channelFid);
if (null != channel) {
Map<String, Object> result = new HashMap<>();
result.put("id", channel.getId());
result.put("source", channel.getSource());
result.put("platform", channel.getPlatform());
result.put("num", bucket.getDocCount());
channelResultList.add(result);
}
}
});
return channelResultList;
}
/**
* 获取每日稿件数量
*
......@@ -1357,7 +1484,7 @@ public class MarkDataServiceImpl implements MarkDataService {
}
private List<JSONObject> getMarkPlatformProportion(Long startTime, Long endTime, String projectId, String linkedGroupId, String contendId, boolean cache) throws IOException {
String redisKey = RedisKeyPrefix.MARK_PLATFORM_PROPORTION + Tools.concat(projectId, startTime, endTime);
String redisKey = RedisKeyPrefix.MARK_PLATFORM_PROPORTION + Tools.concat(projectId, contendId, startTime, endTime);
String resultStr;
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseArray(resultStr, JSONObject.class);
......@@ -1513,13 +1640,11 @@ public class MarkDataServiceImpl implements MarkDataService {
String title = baseMap.getTitleNullOptionalContent();
return Tools.filterSpecialCharacter(title) + baseMap.getTypeB().encode();
}));
Map<String, List<Map<String, Object>>> collect = groupMap.values().stream().map(list -> list.stream().sorted(Comparator.comparingLong(o -> Long.parseLong(o.get("time") + ""))).collect(Collectors.toList()))
.collect(Collectors.toMap(list -> list.get(0).get("id") + "", list -> list));
Map<String, List<Map<String, Object>>> collect = groupMap.values().stream().map(list -> list.stream().sorted(Comparator.comparingLong(o -> Long.parseLong(o.get("time") + ""))).collect(Collectors.toList())).collect(Collectors.toMap(list -> list.get(0).get("id") + "", list -> list));
return sortList.stream().map(id -> {
List<Map<String, Object>> maps = collect.get(id);
if (null != maps) {
return MarkFlowEntity.getFoldInstance(maps.stream().map(map -> getMarkFlowEntity(map, projectId,
linkedGroupId, contendId)).collect(Collectors.toList()));
return MarkFlowEntity.getFoldInstance(maps.stream().map(map -> getMarkFlowEntity(map, projectId, linkedGroupId, contendId)).collect(Collectors.toList()));
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
......
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,19 +843,13 @@ 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