Commit b9117713 by 陈健智

热点库与危机库

parent eed08ef5
...@@ -28,6 +28,12 @@ public class RedisKeyPrefix { ...@@ -28,6 +28,12 @@ public class RedisKeyPrefix {
public static final String AGGREE_RESULT_CACHE = "BRANDKBS:AGGREE_CACHE:"; public static final String AGGREE_RESULT_CACHE = "BRANDKBS:AGGREE_CACHE:";
/** /**
* 热点相关缓存KEY
*/
public static final String HOT_RANKLIST = "brandkbs:hot:rankList:";
public static final String HOT_LIST = "brandkbs:hot:list:";
/**
* 项目简报报相关缓存KEY * 项目简报报相关缓存KEY
*/ */
public static final String REPORT_PC = "BRANDKBS:REPORT:PC:"; public static final String REPORT_PC = "BRANDKBS:REPORT:PC:";
......
package com.zhiwei.brandkbs2.controller.app;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.auth.UserThreadLocal;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
/**
* @ClassName AppCrisisController
* @Description 提供前台危机相关信息展示
* @author cjz
* @date 2022-07-19 10:20
*/
@RestController
@RequestMapping("/app/crisis")
@Api(tags = "前台危机展示接口",description = "提供前台危机相关信息展示")
@Auth(role = RoleEnum.CUSTOMER)
public class AppCrisisController extends BaseController {
@Value("${crisis.search.url}")
private String crisisSearchUrl;
@Value("${crisis.searchTags.url}")
private String crisisTagsUrl;
@Value("${crisis.top3.url}")
private String crisisTop3Url;
@Value("${crisis.searchCriteria.url}")
private String crisisSearchCriteriaUrl;
@Value("${crisis.list.url}")
private String crisisListUrl;
@Value("${crisis.share.url}")
private String crisisEventShareUrl;
@Autowired
private RestTemplate restTemplate;
@ApiOperation("危机库-查危机")
@GetMapping("/crisisSearch")
public ResponseResult crisisSearch(@RequestParam(value = "page",defaultValue = "1") Integer page,
@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);
}
@ApiOperation("危机库-通过标签查危机")
@GetMapping("/crisisTags")
public ResponseResult crisisTags(@RequestParam(value = "page",defaultValue = "1") Integer page,
@RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,
@RequestParam(value = "brand",required = false) String brand,
@RequestParam(value = "category",required = false) String category){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisTagsUrl, String.class, page, pageSize, brand, category);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("危机库-近期热点危机")
@GetMapping("/recentHotCrisis")
public ResponseResult recentHotCrisis(){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisTop3Url, String.class);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("危机库-危机搜索条件")
@GetMapping("/crisisSearchCriteria")
public ResponseResult crisisSearchCriteria(){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisSearchCriteriaUrl, String.class);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("危机库-危机库列表")
@GetMapping("/crisisList")
public ResponseResult crisisList(@RequestParam(value = "page",defaultValue = "1") Integer page,
@RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,
@RequestParam(value = "startTime",required = false) String startTime,
@RequestParam(value = "endTime",required = false) String endTime,
@RequestParam(value = "category",defaultValue = "不限") String category){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisListUrl, String.class, page, pageSize, startTime, endTime, category);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("危机库-获取危机事件分享id")
@GetMapping("/getCrisisEventShareId/{id}")
public ResponseResult getCrisisEventShareId(@PathVariable int id){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisEventShareUrl, String.class, id);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
}
package com.zhiwei.brandkbs2.controller.app;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.auth.UserThreadLocal;
import com.zhiwei.brandkbs2.common.RedisKeyPrefix;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.EmotionEnum;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.pojo.vo.ProjectVO;
import com.zhiwei.brandkbs2.service.MarkDataService;
import com.zhiwei.brandkbs2.service.ProjectService;
import com.zhiwei.brandkbs2.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
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 org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @ClassName AppCrisisController
* @Description 提供前台危机相关信息展示
* @author cjz
* @date 2022-07-19 16:17
*/
@RestController
@RequestMapping("/app/hot")
@Api(tags = "前台热点展示接口",description = "提供前台热点相关信息展示")
@Auth(role = RoleEnum.CUSTOMER)
public class AppHotController extends BaseController {
private static final long ONE_HOUR = 1L;
@Value("${trends.longTimeInListSearchByInner.url}")
private String trendsListUrl;
@Value("${trends.findHotSearchESDataInTimeByInner.url}")
private String trendsSearchUrl;
@Value("${trends.longTimeInListSearch.url}")
private String longTimeInListSearchUrl;
@Autowired
private RestTemplate restTemplate;
@Autowired
private RedisUtil redisUtil;
@Autowired
private ProjectService projectService;
@Autowired
private MarkDataService markDataService;
/**
* weibo 热搜
* weibo-topic 话题
* weibo-rise 预热
* zhihu 知乎
* toutiao 头条
* douyin 抖音
* bilibili-ranking B站
*/
@ApiOperation("热点库")
@GetMapping("/getHotList")
public ResponseResult getHotList(@RequestParam(value = "sortType",defaultValue = "realTime") String sortType,
@RequestParam(value = "type",defaultValue = "weibo") String type){
ResponseEntity<JSONObject> jsonObjectResponseEntity = restTemplate.getForEntity(trendsListUrl, JSONObject.class, sortType, type);
Object data = jsonObjectResponseEntity.getBody().get("data");
String redisKey = RedisKeyPrefix.HOT_LIST+type;
String result = redisUtil.get(redisKey);
//当舆论场崩溃时从缓存里获取
if(Objects.nonNull(data)){
if (Objects.isNull(result)) {
redisUtil.setExpire(redisKey, JSON.toJSONString(data), ONE_HOUR, TimeUnit.HOURS);
}
return ResponseResult.success(data);
}else{
if (Objects.nonNull(result)) {
return ResponseResult.success(result);
}
return ResponseResult.failure("响应超时");
}
}
@ApiOperation("热点库-查热点")
@GetMapping("/searchHotList")
public ResponseResult searchHotList(@RequestParam(value = "pageSize",defaultValue ="10") Integer limit,
@RequestParam(value = "page",defaultValue ="1") Integer page,
@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);
}else{
return ResponseResult.failure("响应超时");
}
}
@ApiOperation("热点库-热点榜单")
@GetMapping("/hot")
public ResponseResult hot(){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(longTimeInListSearchUrl, String.class,"weibo");
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
String redisKey = RedisKeyPrefix.HOT_RANKLIST;
String result = redisUtil.get(redisKey);
//当舆论场崩溃时从缓存里获取
if(jsonObject.getBoolean("state")){
Object data = jsonObject.get("data");
if (Objects.isNull(result)) {
redisUtil.setExpire(redisKey, JSON.toJSONString(data), ONE_HOUR, TimeUnit.HOURS);
}
return ResponseResult.success(data);
}else{
if (Objects.nonNull(result)) {
return ResponseResult.success(result);
}
return ResponseResult.failure("响应超时");
}
}
@ApiOperation("热点库-最新资讯")
@GetMapping("/latestNews")
public ResponseResult latestNews(@RequestParam(value = "pageSize",defaultValue = "5") Integer size) throws IOException {
String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
Date endDate = new Date();
Date startDate = DateUtils.addHours(endDate, -24);
List<Map.Entry<String, Integer>> markTopTitleList =
markDataService.getMarkTopTitle(startDate.getTime(), endDate.getTime(), null, projectId, linkedGroupId, size);
List<JSONObject> resultList = markTopTitleList.stream().map(map -> {
JSONObject article = null;
try {
article = markDataService.getFirstArticle(startDate.getTime(), endDate.getTime(), map.getKey(), projectId, linkedGroupId);
} catch (IOException e) {
throw new RuntimeException(e);
}
JSONObject resultJsonObject = new JSONObject();
resultJsonObject.put("title", map.getKey());
if (Objects.nonNull(article)) {
resultJsonObject.put("content", article.get("content"));
resultJsonObject.put("url", article.get("url"));
resultJsonObject.put("realSource", article.get("realSource"));
}
resultJsonObject.put("num", map.getValue());
return resultJsonObject;
}).collect(Collectors.toList());
return ResponseResult.success(resultList);
}
}
package com.zhiwei.brandkbs2.service; package com.zhiwei.brandkbs2.service;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.pojo.EventData;
import com.zhiwei.brandkbs2.pojo.MarkFlowEntity; import com.zhiwei.brandkbs2.pojo.MarkFlowEntity;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO; import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO; import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO; import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @ClassName: MarkDataService * @ClassName: MarkDataService
...@@ -112,4 +115,27 @@ public interface MarkDataService { ...@@ -112,4 +115,27 @@ public interface MarkDataService {
*/ */
List<JSONObject> getMarkHighWord(Long startTime, Long endTime); List<JSONObject> getMarkHighWord(Long startTime, Long endTime);
/**
* 获取时间段某情感数据最多的标题
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param emotion 情感倾向名称
* @param projectId 项目id
* @param linkedGroupId 关联组id
* @param size 分页大小
* @return 最热标题
*/
List<Map.Entry<String, Integer>> getMarkTopTitle(Long startTime, Long endTime, String emotion, String projectId, String linkedGroupId, int size) throws IOException;
/**
* 根据聚合标题和时间获取首发稿件
* @param startTime 开始时间
* @param endTime 结束时间
* @param aggTitle 聚合标题
* @param projectId 项目id
* @param linkedGroupId 关联组id
* @return 首发稿件
*/
JSONObject getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId) throws IOException;
} }
...@@ -104,6 +104,7 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -104,6 +104,7 @@ public class MarkDataServiceImpl implements MarkDataService {
@Override @Override
public PageVO<MarkFlowEntity> getYuqingMarkList(MarkSearchDTO markSearchDTO) { public PageVO<MarkFlowEntity> getYuqingMarkList(MarkSearchDTO markSearchDTO) {
try { try {
//设置默认的时间、页码、排序方式等
defaultMarkSearch(markSearchDTO); defaultMarkSearch(markSearchDTO);
// 搜索es数据 // 搜索es数据
Pair<SearchHits[], Map<String, Long>> hitsAndCounts = searchMarkHitsAndCount(markSearchDTO, false); Pair<SearchHits[], Map<String, Long>> hitsAndCounts = searchMarkHitsAndCount(markSearchDTO, false);
...@@ -601,6 +602,7 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -601,6 +602,7 @@ public class MarkDataServiceImpl implements MarkDataService {
helper.setSize(0); helper.setSize(0);
// TODO 本地调试不滚动查询 // TODO 本地调试不滚动查询
// List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper); // List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper);
//singletonList:只能存放一个元素,多一个或者少一个都会导致异常
List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper)); List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper));
return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null); return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null);
} }
...@@ -799,6 +801,30 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -799,6 +801,30 @@ public class MarkDataServiceImpl implements MarkDataService {
return result.entrySet().stream().filter(data -> !"分享一篇文章".equals(data.getKey())).sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).limit(size).collect(Collectors.toList()); return result.entrySet().stream().filter(data -> !"分享一篇文章".equals(data.getKey())).sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).limit(size).collect(Collectors.toList());
} }
@Override
public JSONObject getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId) throws IOException {
// 索引
String[] indexes = esClientDao.getIndexes();
// query
BoolQueryBuilder query = projectLinkedGroupQuery(projectId, linkedGroupId);
query.must(QueryBuilders.rangeQuery("time").gte(startTime).lt(endTime))
.must(QueryBuilders.termQuery("agg_title.keyword", aggTitle));
// response
SearchResponse searchResponse =
esClientDao.searchResponse(indexes, null, query, null, null, null, 0, 0, null);
//hits
SearchHits hits = searchResponse.getHits();
JSONObject resultJSONObject = new JSONObject();
hits.forEach(hit -> {
Map<String, Object> source = hit.getSourceAsMap();
resultJSONObject.put("time", source.get("time"));
resultJSONObject.put("content", source.get("content"));
resultJSONObject.put("url", source.get("url"));
resultJSONObject.put("realSource", source.get("real_source"));
});
return resultJSONObject;
}
/** /**
* 获取每日稿件倾向稿件数量信息 * 获取每日稿件倾向稿件数量信息
* *
...@@ -1008,4 +1034,5 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -1008,4 +1034,5 @@ public class MarkDataServiceImpl implements MarkDataService {
return instance; return instance;
} }
} }
\ No newline at end of file
...@@ -58,4 +58,15 @@ qbjc.interface.upload.token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjo ...@@ -58,4 +58,15 @@ qbjc.interface.upload.token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjo
qbjc.project.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/project/resource qbjc.project.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/project/resource
qbjc.event.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/aplan/event qbjc.event.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/aplan/event
qbjc.event.tag.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/tag/event?project={1} qbjc.event.tag.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/tag/event?project={1}
qbjc.platform.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/platform/resource qbjc.platform.url=https://yuqing.zhiweidata.com/qbjcbackPhoenix/interface/platform/resource
\ No newline at end of file #\u5371\u673A\u5E93\u5916\u90E8\u63A5\u53E3
crisis.search.url=https://crisis.zhiweidata.com/app/brandkbs/crisisSearch?page={1}&size={2}&keyword={3}
crisis.searchTags.url=https://crisis.zhiweidata.com/app/brandkbs/searchCrisisByTags?page={1}&size={2}&brand={3}&category={4}
crisis.top3.url=https://crisis.zhiweidata.com/app/brandkbs/event/online-top3
crisis.searchCriteria.url=https://crisis.zhiweidata.com/app/brandkbs/condition
crisis.list.url=https://crisis.zhiweidata.com/app/brandkbs/crisisList?page={1}&size={2}&startTime={3}&endTime={4}&category={5}
crisis.share.url=https://crisis.zhiweidata.com/app/brandkbs/share/{1}
#\u70ED\u70B9\u5E93\u5916\u90E8\u63A5\u53E3
trends.longTimeInListSearchByInner.url=https://trends.zhiweidata.com/hotSearchTrend/inner/longTimeInListSearchByInner?sortType={1}&type={2}
trends.findHotSearchESDataInTimeByInner.url=https://hotsearch-manage.zhiweidata.com/hotsearch/hotSearch/findHotSearchESDataInTimeByInner?limit={1}&page={2}&type={3}&word={4}
trends.longTimeInListSearch.url=https://trends.zhiweidata.com/hotSearchTrend/search/longTimeInListSearch?type={1}&sortType=realTime
\ No newline at end of file
spring.profiles.active=pro spring.profiles.active=local
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