Commit bb6734c5 by shenjunjie

首页模块完成

parent ea21057a
......@@ -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,6 +19,7 @@ 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);
......@@ -56,5 +57,5 @@ public class Constant {
/**
* 主品牌默认竞品ID
*/
public static final String PRIMARY_CONTENDID = "0";
public static final String PRIMARY_CONTEND_ID = "0";
}
......@@ -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));
}
}
......@@ -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);
}
......@@ -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;
......@@ -87,8 +89,41 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
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
......
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);
}
......@@ -8,10 +8,8 @@ import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
......@@ -167,6 +165,7 @@ public interface MarkDataService {
/**
* 竞品库-获取搜索条件
*
* @param linkedGroupId 关联组Id
* @return 搜索条件
*/
......@@ -174,6 +173,7 @@ public interface MarkDataService {
/**
* 竞品库-获取搜索结果列表
*
* @param markSearchDTO 标注数据搜索传输类
* @return 搜索结果列表
*/
......@@ -191,10 +191,60 @@ public interface MarkDataService {
/**
* 竞品库-获取竞品对比传播分析数据
*
* @param markSearchDTO 标注数据搜索传输类
* @param hotArticleSize 热门稿件数量
* @param cache 是否启用缓存
* @return
*/
JSONObject getContendSpreadAnalyze(MarkSearchDTO markSearchDTO, int hotArticleSize, boolean cache) throws IOException;
/**
* 时间段内稿件数
*
* @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;
}
......@@ -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;
}
......
......@@ -645,19 +645,18 @@ 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;
}
/**
......
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();
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", positiveList);
result.put("negativeList", negativeList);
return result;
}
/**
* 传播趋势
*
* @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;
......@@ -40,6 +41,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;
......@@ -79,8 +81,7 @@ 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[]{"id", "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"};
@Resource(name = "projectServiceImpl")
private ProjectService projectService;
......@@ -103,6 +104,9 @@ public class MarkDataServiceImpl implements MarkDataService {
@Resource(name = "aggreeResultDaoImpl")
AggreeResultDao aggreeResultDao;
@Resource(name = "channelDao")
ChannelDao channelDao;
@Resource(name = "redisUtil")
RedisUtil redisUtil;
......@@ -359,7 +363,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;
......@@ -450,7 +454,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);
}
......@@ -613,8 +617,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);
}
......@@ -945,7 +948,7 @@ public class MarkDataServiceImpl implements MarkDataService {
// 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)));
postFilter = QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery("brandkbs_cache_maps.key.keyword", Tools.concat(projectId, linkedGroupId, Constant.PRIMARY_CONTEND_ID)));
} else {
postFilter = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
}
......@@ -1030,8 +1033,7 @@ public class MarkDataServiceImpl implements MarkDataService {
result.put("days", new Period(dto.getStartTime(), dto.getEndTime(), PeriodType.days()).getDays());
result.put("priName", project.getBrandName());
// 获取时间段主品牌在每个平台传播量占比
List<JSONObject> primaryPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, true);
List<JSONObject> primaryPlatformsProportion = 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);
......@@ -1044,8 +1046,7 @@ public class MarkDataServiceImpl implements MarkDataService {
String brandName = projectByContendId.getBrandName();
result.put("conName", brandName);
// 获取时间段竞品在每个平台传播量
List<JSONObject> contendPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), true);
List<JSONObject> contendPlatformsProportion = getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), true);
// 获取时间段竞品总传播量
long contendTotalCount = contendPlatformsProportion.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
result.put("conNorTotal", contendTotalCount);
......@@ -1055,16 +1056,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;
......@@ -1097,10 +1093,9 @@ 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);
List<JSONObject> primarySpread = 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());
......@@ -1109,8 +1104,7 @@ public class MarkDataServiceImpl implements MarkDataService {
JSONObject contendLine = new JSONObject();
contendLine.put("id", dto.getContendId());
contendLine.put("brand", brandName);
List<JSONObject> contendSpread =
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
List<JSONObject> contendSpread = getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
contendLine.put("spread", contendSpread);
resList.add(contendLine);
result.put("spread", resList);
......@@ -1130,24 +1124,20 @@ public class MarkDataServiceImpl implements MarkDataService {
long priMaxDayStartTime = Long.parseLong(primaryMax.getString("date"));
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);
List<Map.Entry<String, Integer>> priTopTitle = 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);
BaseMap priFirstArticle = 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);
List<Map.Entry<String, Integer>> priHotTitles = 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);
BaseMap priFirstArticle = 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());
......@@ -1176,25 +1166,21 @@ public class MarkDataServiceImpl implements MarkDataService {
result.put("conMaxCount", contendMax.getLongValue("count"));
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);
List<Map.Entry<String, Integer>> conTopTitle = getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), 1);
if (CollectionUtils.isNotEmpty(conTopTitle)) {
// 首发稿件
BaseMap conFirstArticle =
getFirstArticle(conMaxDayStartTime, conMaxDayEndTime, conTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
BaseMap conFirstArticle = getFirstArticle(conMaxDayStartTime, conMaxDayEndTime, conTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), 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);
List<Map.Entry<String, Integer>> conHotTitles = getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), 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());
BaseMap conFirstArticle = getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
if (null != conFirstArticle) {
jsonObject.put("title", conFirstArticle.getTitle());
jsonObject.put("url", conFirstArticle.getUrl());
......@@ -1211,6 +1197,77 @@ public class MarkDataServiceImpl implements MarkDataService {
return result;
}
@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'].keyword +'_' +doc['real_source'].keyword+'_' +doc['source'].keyword");
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;
}
/**
* 获取每日稿件数量
*
......@@ -1515,13 +1572,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());
......
......@@ -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);
}
......
......@@ -703,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());
......@@ -712,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);
......@@ -740,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 关键词数据
......
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