资讯精选获取分数详情以及列表返回分数和排序相关逻辑

This commit is contained in:
sunflower2014 2025-06-08 17:19:58 +08:00
parent 50aeba5a1c
commit 3778c703a6
12 changed files with 586 additions and 67 deletions

View File

@ -20,6 +20,7 @@ import com.jinrui.reference.core.model.dto.news.SaveNewsDTO;
import com.jinrui.reference.core.model.vo.PageObject; import com.jinrui.reference.core.model.vo.PageObject;
import com.jinrui.reference.core.model.vo.ResultObject; import com.jinrui.reference.core.model.vo.ResultObject;
import com.jinrui.reference.core.model.vo.news.NewsDetailVO; import com.jinrui.reference.core.model.vo.news.NewsDetailVO;
import com.jinrui.reference.core.model.vo.news.NewsScoreVO;
import com.jinrui.reference.core.model.vo.news.NewsVO; import com.jinrui.reference.core.model.vo.news.NewsVO;
import com.jinrui.reference.core.service.NewsService; import com.jinrui.reference.core.service.NewsService;
@ -192,14 +193,15 @@ public class NewsController {
@GetMapping @GetMapping
public PageObject<NewsVO> queryNews(@RequestHeader("auth-token") String token, public PageObject<NewsVO> queryNews(@RequestHeader("auth-token") String token,
@RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "minScore", required = false) Double minScore,
@RequestParam(value = "maxScore", required = false) Double maxScore,
@RequestParam(value = "column", required = false) String columnList, @RequestParam(value = "column", required = false) String columnList,
@RequestParam(value = "status", required = false) Integer status, @RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "page", required = false, defaultValue = "1") int page, @RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "size", required = false, defaultValue = "10") int size, @RequestParam(value = "size", required = false, defaultValue = "10") int size,
@RequestParam(value = "last", required = false) Integer last, @RequestParam(value = "last", required = false) Integer last,
@RequestParam(value = "current", required = false) Integer current, @RequestParam(value = "current", required = false) Integer current,
@RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy, @RequestParam(value = "orderBy", required = false, defaultValue = "id$asc") String orderBy
@RequestParam(value = "direction", required = false, defaultValue = "asc") String direction
) { ) {
if (!StringUtils.hasText(token)) { if (!StringUtils.hasText(token)) {
return PageObject.failedPage("登陆Token为空!"); return PageObject.failedPage("登陆Token为空!");
@ -218,13 +220,40 @@ public class NewsController {
} }
log.info("path: /news, method: GET, request user id: {}, keyword: {}, column: {}, status: {}, " + log.info("path: /news, method: GET, request user id: {}, keyword: {}, column: {}, status: {}, " +
"page: {}, size: {}, last: {}, current: {}, orderBy: {}, direction: {}", "page: {}, size: {}, last: {}, current: {}, orderBy: {}",
adminUser.getId(), keyword, columnList, status, page, size, last, current, orderBy, direction); adminUser.getId(), keyword, columnList, status, page, size, last, current, orderBy);
} catch (Exception e) { } catch (Exception e) {
log.error("解析登陆Token出错!", e); log.error("解析登陆Token出错!", e);
return PageObject.failedPage(500, "服务端错误,请联系系统管理员!"); return PageObject.failedPage(500, "服务端错误,请联系系统管理员!");
} }
return newsService.queryNews(keyword, columnList, status, page, size, last, current, orderBy, minScore, maxScore);
}
return newsService.queryNews(keyword, columnList, status, page, size, last, current, orderBy, direction); @GetMapping("/score")
public ResultObject<NewsScoreVO> getScore(@RequestHeader("auth-token") String token,
@RequestParam("id") Long id) {
if (!StringUtils.hasText(token)) {
return ResultObject.failed("登陆Token为空!");
}
try {
AdminUser adminUser = AdminJwtService.parseToken(token);
if (adminUser == null) {
log.warn("解析token {}拿不到AdminUser对象!", token);
return ResultObject.failed("登陆Token有误请联系系统管理员!");
}
Long adminUserId = adminUser.getId();
if (!adminUser.isActive()) {
log.warn("当前用户已被封禁! id = {}", adminUserId);
return ResultObject.failed("当前用户已被封禁!请联系系统管理员!");
}
log.info("path: /news/score, method: GET, request user id: {}, news id: {}", adminUserId, id);
return newsService.getScore(id);
} catch (Exception e) {
log.error("解析登陆Tokn出错!", e);
return ResultObject.failed(500, "服务端错误,请联系系统管理员!");
}
} }
} }

View File

@ -193,7 +193,6 @@ public class NewsInfoController {
log.error("解析登陆Token出错!", e); log.error("解析登陆Token出错!", e);
return PageObject.failedPage(500, "服务端错误,请联系系统管理员!"); return PageObject.failedPage(500, "服务端错误,请联系系统管理员!");
} }
return newsInfoService.queryNewsInfo(title, content, stockcode, sourcename, page, size, last, current, orderBy, direction); return newsInfoService.queryNewsInfo(title, content, stockcode, sourcename, page, size, last, current, orderBy, direction);
} }

View File

@ -39,3 +39,5 @@ elasticsearch:
enable: true enable: true
username: elastic username: elastic
password: ZxE,3VM@Thk0 password: ZxE,3VM@Thk0
mybatis:
type-handlers-package:com.jinrui.reference.core.typehandler

View File

@ -92,11 +92,14 @@ public interface NewsMapper {
"news.status as status," + "news.status as status," +
"news.create_time as createTime," + "news.create_time as createTime," +
"news.publish_time as publishTime," + "news.publish_time as publishTime," +
"news.update_time as updateTime " + "news.update_time as updateTime, " +
"news.newsinfo_id as newsinfoId, " +
"news_tags.news_score as score " +
"from news " + "from news " +
"<if test=\"column != null and !column.isEmpty()\">" + "<if test=\"column != null and !column.isEmpty()\">" +
"inner join news_column_rel on news.id = news_column_rel.news_id " + "inner join news_column_rel on news.id = news_column_rel.news_id " +
"</if>" + "</if>" +
" left join news_tags on news.newsinfo_id = news_tags.newsinfo_id " +
"<where>" + "<where>" +
"<if test=\"keyword != null and !keyword.isEmpty()\">" + "<if test=\"keyword != null and !keyword.isEmpty()\">" +
"news.title like concat('%', #{keyword}, '%') " + "news.title like concat('%', #{keyword}, '%') " +
@ -104,6 +107,12 @@ public interface NewsMapper {
"<if test=\"column != null and !column.isEmpty()\">" + "<if test=\"column != null and !column.isEmpty()\">" +
"and news_column_rel.column_id in (${column}) " + "and news_column_rel.column_id in (${column}) " +
"</if>" + "</if>" +
"<if test=\"minScore != null \">" +
"and news_tags.news_score &gt;= #{minScore} " +
"</if>" +
"<if test=\"maxScore != null \">" +
"and news_tags.news_score &lt;= #{maxScore} " +
"</if>" +
"<if test=\"status != null\">" + "<if test=\"status != null\">" +
"and news.status = #{status} " + "and news.status = #{status} " +
"</if>" + "</if>" +
@ -111,18 +120,18 @@ public interface NewsMapper {
"and news.id &gt; #{last}" + "and news.id &gt; #{last}" +
"</if>" + "</if>" +
"</where>" + "</where>" +
"order by news.${orderBy} " + "<if test=\"orderBy != null\">" +
"<if test=\"'desc'.equals(direction)\">" + "order by ${orderBy} " +
"desc" +
"</if>" + "</if>" +
"limit ${limit} offset ${offset}" + "limit ${limit} offset ${offset}" +
"</script>") "</script>")
List<News> queryNews(@Param("keyword") String keyword, List<News> queryNews(@Param("keyword") String keyword,
@Param("minScore") Double minScore,
@Param("maxScore") Double maxScore,
@Param("column") String columnList, @Param("column") String columnList,
@Param("status") Integer status, @Param("status") Integer status,
@Param("last") Integer last, @Param("last") Integer last,
@Param("orderBy") String orderBy, @Param("orderBy") String orderBy,
@Param("direction") String direction,
@Param("limit") int limit, @Param("limit") int limit,
@Param("offset") int offset); @Param("offset") int offset);
@ -131,6 +140,9 @@ public interface NewsMapper {
"<if test=\"column != null and !column.isEmpty() \">" + "<if test=\"column != null and !column.isEmpty() \">" +
"inner join news_column_rel on news.id = news_column_rel.news_id " + "inner join news_column_rel on news.id = news_column_rel.news_id " +
"</if>" + "</if>" +
"<if test=\"minScore != null or maxScore != null \">" +
"left join news_tags on news.newsinfo_id = news_tags.newsinfo_id " +
"</if>" +
"<where>" + "<where>" +
"<if test=\"keyword != null and !keyword.isEmpty()\">" + "<if test=\"keyword != null and !keyword.isEmpty()\">" +
"news.title like concat('%', #{keyword}, '%') " + "news.title like concat('%', #{keyword}, '%') " +
@ -138,12 +150,27 @@ public interface NewsMapper {
"<if test=\"column != null and !column.isEmpty()\">" + "<if test=\"column != null and !column.isEmpty()\">" +
"and news_column_rel.column_id in (${column}) " + "and news_column_rel.column_id in (${column}) " +
"</if>" + "</if>" +
"<if test=\"minScore != null \">" +
"and news_tags.news_score &gt;= ${minScore} " +
"</if>" +
"<if test=\"maxScore != null \">" +
"and news_tags.news_score &lt;= ${maxScore} " +
"</if>" +
"<if test=\"status != null\">" + "<if test=\"status != null\">" +
"and news.status = #{status} " + "and news.status = #{status} " +
"</if>" + "</if>" +
"</where>) tmp" + "</where>) tmp" +
"</script>") "</script>")
int queryTotal(@Param("keyword") String keyword, int queryTotal(@Param("keyword") String keyword,
@Param("minScore") Double minScore,
@Param("maxScore") Double maxScore,
@Param("column") String columnParam, @Param("column") String columnParam,
@Param("status") Integer status); @Param("status") Integer status);
@Select("select id, title, summary, picture, content, status, " +
"create_time as createTime, " +
"publish_time as publishTime, " +
"update_time as updateTime " +
"from news where newsinfo_id = #{newsinfoId}")
News getNewsDetailByNewsInfoId(@Param("newsinfoId") String newsinfoId);
} }

View File

@ -0,0 +1,35 @@
package com.jinrui.reference.core.mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import com.jinrui.reference.core.model.entity.NewsTags;
import com.jinrui.reference.core.typehandler.JsonArrayTypeHandler;
public interface NewsTagsMapper {
@Results({
@Result(column = "id", property = "id", id = true),
@Result(column = "abstract", property = "summary"),
@Result(column = "title", property = "title"),
@Result(column = "rewrite_content", property = "rewriteContent"),
@Result(column = "industry_label", property = "industryLabel", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "industry_confidence", property = "industryConfidence", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "industry_score", property = "industryScore", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "concept_label", property = "conceptLabel", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "concept_confidence", property = "conceptConfidence", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "concept_score", property = "conceptScore", typeHandler = JsonArrayTypeHandler.class),
@Result(column = "source", property = "source"),
@Result(column = "source_impact", property = "sourceImpact"),
@Result(column = "China_factor", property = "chinaFactor"),
@Result(column = "public_opinion_score", property = "publicOpinionScore"),
@Result(column = "news_score", property = "newsScore"),
@Result(column = "news_id", property = "newsId"),
@Result(column = "deleted", property = "deleted"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime"),
})
@Select("select * from news_tags where newsinfo_id = #{newsId}")
NewsTags getNewsTagsByNewsId(@Param("newsId") String newsId);
}

View File

@ -76,6 +76,8 @@ public class News {
*/ */
private String newsinfoId; private String newsinfoId;
private Double score;
public News() {} public News() {}
public News(SaveNewsDTO saveNewsDTO) { public News(SaveNewsDTO saveNewsDTO) {
@ -204,4 +206,12 @@ public class News {
public void setNewsinfoId(String newsinfoId) { public void setNewsinfoId(String newsinfoId) {
this.newsinfoId = newsinfoId; this.newsinfoId = newsinfoId;
} }
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
} }

View File

@ -0,0 +1,196 @@
package com.jinrui.reference.core.model.entity;
import java.util.Date;
import java.util.List;
public class NewsTags {
private Long id;
private String summary;
private String title;
private String rewriteContent;
private List<String> industryLabel;
private List<Double> industryConfidence;
private List<Double> industryScore;
private List<String> conceptLabel;
private List<Double> conceptConfidence;
private List<Double> conceptScore;
private String source;
private Integer sourceImpact;
private Double chinaFactor;
private Integer publicOpinionScore;
private Double newsScore;
private Long newsId;
private Boolean deleted;
private Date createTime;
private Date updateTime;
public List<Double> getIndustryScore() {
return industryScore;
}
public void setIndustryScore(List<Double> industryScore) {
this.industryScore = industryScore;
}
public List<String> getConceptLabel() {
return conceptLabel;
}
public void setConceptLabel(List<String> conceptLabel) {
this.conceptLabel = conceptLabel;
}
public List<Double> getConceptConfidence() {
return conceptConfidence;
}
public void setConceptConfidence(List<Double> conceptConfidence) {
this.conceptConfidence = conceptConfidence;
}
public List<Double> getConceptScore() {
return conceptScore;
}
public void setConceptScore(List<Double> conceptScore) {
this.conceptScore = conceptScore;
}
public Integer getSourceImpact() {
return sourceImpact;
}
public void setSourceImpact(Integer sourceImpact) {
this.sourceImpact = sourceImpact;
}
public Double getChinaFactor() {
return chinaFactor;
}
public void setChinaFactor(Double chinaFactor) {
this.chinaFactor = chinaFactor;
}
public Integer getPublicOpinionScore() {
return publicOpinionScore;
}
public void setPublicOpinionScore(Integer publicOpinionScore) {
this.publicOpinionScore = publicOpinionScore;
}
public Double getNewsScore() {
return newsScore;
}
public void setNewsScore(Double newsScore) {
this.newsScore = newsScore;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<String> getIndustryLabel() {
return industryLabel;
}
public void setIndustryLabel(List<String> industryLabel) {
this.industryLabel = industryLabel;
}
public List<Double> getIndustryConfidence() {
return industryConfidence;
}
public void setIndustryConfidence(List<Double> industryConfidence) {
this.industryConfidence = industryConfidence;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getRewriteContent() {
return rewriteContent;
}
public void setRewriteContent(String rewriteContent) {
this.rewriteContent = rewriteContent;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public Long getNewsId() {
return newsId;
}
public void setNewsId(Long newsId) {
this.newsId = newsId;
}
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

View File

@ -0,0 +1,134 @@
package com.jinrui.reference.core.model.vo.news;
import java.util.List;
import com.jinrui.reference.core.model.entity.NewsTags;
public class NewsScoreVO {
private Long id;
private List<String> industryLabel;
private List<Double> industryConfidence;
private List<Double> industryScore;
private List<String> conceptLabel;
private List<Double> conceptConfidence;
private List<Double> conceptScore;
private Integer sourceImpact;
private Double chinaFactor;
private Integer publicOpinionScore;
private Double newsScore;
public NewsScoreVO() {
}
public NewsScoreVO(NewsTags newsTags) {
this.id = newsTags.getId();
this.industryLabel = newsTags.getIndustryLabel();
this.industryConfidence = newsTags.getIndustryConfidence();
this.industryScore = newsTags.getIndustryScore();
this.conceptLabel = newsTags.getConceptLabel();
this.conceptConfidence = newsTags.getConceptConfidence();
this.conceptScore = newsTags.getConceptScore();
this.sourceImpact = newsTags.getSourceImpact();
this.chinaFactor = newsTags.getChinaFactor();
this.publicOpinionScore = newsTags.getPublicOpinionScore();
this.newsScore = newsTags.getNewsScore();
}
public List<Double> getIndustryScore() {
return industryScore;
}
public void setIndustryScore(List<Double> industryScore) {
this.industryScore = industryScore;
}
public List<String> getConceptLabel() {
return conceptLabel;
}
public void setConceptLabel(List<String> conceptLabel) {
this.conceptLabel = conceptLabel;
}
public List<Double> getConceptConfidence() {
return conceptConfidence;
}
public void setConceptConfidence(List<Double> conceptConfidence) {
this.conceptConfidence = conceptConfidence;
}
public List<Double> getConceptScore() {
return conceptScore;
}
public void setConceptScore(List<Double> conceptScore) {
this.conceptScore = conceptScore;
}
public Integer getSourceImpact() {
return sourceImpact;
}
public void setSourceImpact(Integer sourceImpact) {
this.sourceImpact = sourceImpact;
}
public Double getChinaFactor() {
return chinaFactor;
}
public void setChinaFactor(Double chinaFactor) {
this.chinaFactor = chinaFactor;
}
public Integer getPublicOpinionScore() {
return publicOpinionScore;
}
public void setPublicOpinionScore(Integer publicOpinionScore) {
this.publicOpinionScore = publicOpinionScore;
}
public Double getNewsScore() {
return newsScore;
}
public void setNewsScore(Double newsScore) {
this.newsScore = newsScore;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<String> getIndustryLabel() {
return industryLabel;
}
public void setIndustryLabel(List<String> industryLabel) {
this.industryLabel = industryLabel;
}
public List<Double> getIndustryConfidence() {
return industryConfidence;
}
public void setIndustryConfidence(List<Double> industryConfidence) {
this.industryConfidence = industryConfidence;
}
}

View File

@ -52,6 +52,8 @@ public class NewsVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime; private Date updateTime;
private Double score;
public NewsVO(News news) { public NewsVO(News news) {
this.id = news.getId(); this.id = news.getId();
this.title = news.getTitle(); this.title = news.getTitle();
@ -59,6 +61,7 @@ public class NewsVO {
this.createTime = news.getCreateTime(); this.createTime = news.getCreateTime();
this.publishTime = news.getPublishTime(); this.publishTime = news.getPublishTime();
this.updateTime = news.getUpdateTime(); this.updateTime = news.getUpdateTime();
this.score = news.getScore();
} }
public Long getId() { public Long getId() {
@ -112,4 +115,12 @@ public class NewsVO {
public void setUpdateTime(Date updateTime) { public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime; this.updateTime = updateTime;
} }
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
} }

View File

@ -77,7 +77,7 @@ public class NewsInfoService {
public ResultObject<Void> publish(String id, long editorId) { public ResultObject<Void> publish(String id, long editorId) {
try { try {
GetResponse<NewsInfo> newsInfoResp = elasticsearchClient.get(g -> g.index(NewsInfo.INDEX_NAME).id(String.valueOf(id)), NewsInfo.class); GetResponse<NewsInfo> newsInfoResp = elasticsearchClient.get(g -> g.index(NewsInfo.INDEX_NAME).id(id), NewsInfo.class);
if (!newsInfoResp.found()) { if (!newsInfoResp.found()) {
return ResultObject.success(); return ResultObject.success();
} }
@ -90,15 +90,14 @@ public class NewsInfoService {
newsInfo.setStatus(1); newsInfo.setStatus(1);
} }
News relateNews = newsMapper.getNewsDetail(newsInfo.getNewsId()); News relateNews = newsMapper.getNewsDetailByNewsInfoId(id);
if (relateNews == null||!Objects.equals(relateNews.getTitle(), newsInfo.getTitle())) { if (relateNews == null) {
// 插入数据到News表中 // 插入数据到News表中,默认是未发布
News relNews = newsInfo.toNews(); News relNews = newsInfo.toNews();
relNews.setStatus(1);
relNews.setEditorId(editorId); relNews.setEditorId(editorId);
newsMapper.saveNews(relNews); newsMapper.saveNews(relNews);
newsInfo.setNewsId(relNews.getId());
String industry = newsInfo.getIndustry(); String industry = newsInfo.getIndustry();
if (!ObjectUtils.isEmpty(industry)) { if (!ObjectUtils.isEmpty(industry)) {
@ -119,19 +118,12 @@ public class NewsInfoService {
} }
} }
} }
} else {
if (newsInfo.getStatus().intValue() == 2) {
newsMapper.simplePublish(newsInfo.getNewsId(), editorId);
} else {
newsMapper.simpleUnpublish(newsInfo.getNewsId());
}
} }
NewsInfo publishedNewsInfo = new NewsInfo(); NewsInfo publishedNewsInfo = new NewsInfo();
publishedNewsInfo.setStatus(newsInfo.getStatus()); publishedNewsInfo.setStatus(newsInfo.getStatus());
publishedNewsInfo.setNewsId(newsInfo.getNewsId());
elasticsearchClient.update(e -> e.index(NewsInfo.INDEX_NAME).refresh(Refresh.True).id(String.valueOf(id)).doc(publishedNewsInfo), NewsInfo.class); elasticsearchClient.update(e -> e.index(NewsInfo.INDEX_NAME).refresh(Refresh.True).id(id).doc(publishedNewsInfo), NewsInfo.class);
} catch(IOException e) { } catch(IOException e) {
log.error("全量资讯发布失败!", e); log.error("全量资讯发布失败!", e);
@ -243,21 +235,20 @@ public class NewsInfoService {
String id = saveNewsInfoDTO.getId(); String id = saveNewsInfoDTO.getId();
try { try {
GetResponse<NewsInfo> getResp = elasticsearchClient.get(e -> e.index(NewsInfo.INDEX_NAME).id(String.valueOf(id)), NewsInfo.class); GetResponse<NewsInfo> getResp = elasticsearchClient.get(e -> e.index(NewsInfo.INDEX_NAME).id(id), NewsInfo.class);
if (getResp.found()) { if (getResp.found()) {
NewsInfo newsInfo = getResp.source(); NewsInfo newsInfo = getResp.source();
newsInfo.setId(id); newsInfo.setId(id);
Long newsId = newsInfo.getNewsId(); News relateNews = newsMapper.getNewsDetailByNewsInfoId(id);
News relateNews = newsMapper.getNewsDetail(newsId);
if (relateNews == null ||!Objects.equals(newsInfo.getTitle(), relateNews.getTitle())) { if (relateNews == null) {
News news = createRelateNews(saveNewsInfoDTO); relateNews = createRelateNews(saveNewsInfoDTO);
newsId = news.getId(); NewsInfo updatedNewsInfo = toNewsInfo(relateNews.getId(), saveNewsInfoDTO);
} else {
updateRelateNews(newsId, saveNewsInfoDTO);
}
NewsInfo updatedNewsInfo = toNewsInfo(newsId, saveNewsInfoDTO);
elasticsearchClient.update(e -> e.index(NewsInfo.INDEX_NAME).id(updatedNewsInfo.getId()).doc(updatedNewsInfo).refresh(Refresh.True), NewsInfo.class); elasticsearchClient.update(e -> e.index(NewsInfo.INDEX_NAME).id(updatedNewsInfo.getId()).doc(updatedNewsInfo).refresh(Refresh.True), NewsInfo.class);
} else {
saveNewsInfoDTO.setStatus(relateNews.getStatus());
updateRelateNews(relateNews.getId(), saveNewsInfoDTO);
}
} }
} catch(IOException e) { } catch(IOException e) {
log.error("全量资讯更新异常!", e); log.error("全量资讯更新异常!", e);
@ -364,6 +355,7 @@ public class NewsInfoService {
private News createRelateNews(SaveNewsInfoDTO saveNewsInfoDTO) { private News createRelateNews(SaveNewsInfoDTO saveNewsInfoDTO) {
News news = saveNewsInfoDTO.toNews(); News news = saveNewsInfoDTO.toNews();
news.setStatus(1);
newsMapper.saveNews(news); newsMapper.saveNews(news);
// 保存标签关系 // 保存标签关系

View File

@ -1,6 +1,8 @@
package com.jinrui.reference.core.service; package com.jinrui.reference.core.service;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -10,6 +12,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -23,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.jinrui.reference.core.mapper.ColumnMapper; import com.jinrui.reference.core.mapper.ColumnMapper;
import com.jinrui.reference.core.mapper.IndustryMapper; import com.jinrui.reference.core.mapper.IndustryMapper;
import com.jinrui.reference.core.mapper.NewsMapper; import com.jinrui.reference.core.mapper.NewsMapper;
import com.jinrui.reference.core.mapper.NewsTagsMapper;
import com.jinrui.reference.core.mapper.TagMapper; import com.jinrui.reference.core.mapper.TagMapper;
import com.jinrui.reference.core.model.dto.news.SaveDraftColumn; import com.jinrui.reference.core.model.dto.news.SaveDraftColumn;
import com.jinrui.reference.core.model.dto.news.SaveDraftColumnItem; import com.jinrui.reference.core.model.dto.news.SaveDraftColumnItem;
@ -40,6 +44,7 @@ import com.jinrui.reference.core.model.entity.NewsDraft;
import com.jinrui.reference.core.model.entity.NewsIndustryRel; import com.jinrui.reference.core.model.entity.NewsIndustryRel;
import com.jinrui.reference.core.model.entity.NewsInfo; import com.jinrui.reference.core.model.entity.NewsInfo;
import com.jinrui.reference.core.model.entity.NewsTagRel; import com.jinrui.reference.core.model.entity.NewsTagRel;
import com.jinrui.reference.core.model.entity.NewsTags;
import com.jinrui.reference.core.model.entity.Tag; import com.jinrui.reference.core.model.entity.Tag;
import com.jinrui.reference.core.model.vo.PageObject; import com.jinrui.reference.core.model.vo.PageObject;
import com.jinrui.reference.core.model.vo.ResultObject; import com.jinrui.reference.core.model.vo.ResultObject;
@ -50,6 +55,7 @@ import com.jinrui.reference.core.model.vo.news.NewsDetailIndustry;
import com.jinrui.reference.core.model.vo.news.NewsDetailTag; import com.jinrui.reference.core.model.vo.news.NewsDetailTag;
import com.jinrui.reference.core.model.vo.news.NewsDetailTagItem; import com.jinrui.reference.core.model.vo.news.NewsDetailTagItem;
import com.jinrui.reference.core.model.vo.news.NewsDetailVO; import com.jinrui.reference.core.model.vo.news.NewsDetailVO;
import com.jinrui.reference.core.model.vo.news.NewsScoreVO;
import com.jinrui.reference.core.model.vo.news.NewsVO; import com.jinrui.reference.core.model.vo.news.NewsVO;
import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.ElasticsearchClient;
@ -66,19 +72,22 @@ public class NewsService {
private final TagMapper tagMapper; private final TagMapper tagMapper;
private final IndustryMapper industryMapper; private final IndustryMapper industryMapper;
private final ElasticsearchClient elasticsearchClient; private final ElasticsearchClient elasticsearchClient;
private final NewsTagsMapper newsTagsMapper;
public NewsService(NewsMapper newsMapper, public NewsService(NewsMapper newsMapper,
ColumnMapper columnMapper, ColumnMapper columnMapper,
ObjectMapper objectMapper, ObjectMapper objectMapper,
TagMapper tagMapper, TagMapper tagMapper,
IndustryMapper industryMapper, IndustryMapper industryMapper,
ElasticsearchClient elasticsearchClient) { ElasticsearchClient elasticsearchClient,
NewsTagsMapper newsTagsMapper) {
this.newsMapper = newsMapper; this.newsMapper = newsMapper;
this.columnMapper = columnMapper; this.columnMapper = columnMapper;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
this.tagMapper = tagMapper; this.tagMapper = tagMapper;
this.industryMapper = industryMapper; this.industryMapper = industryMapper;
this.elasticsearchClient = elasticsearchClient; this.elasticsearchClient = elasticsearchClient;
this.newsTagsMapper = newsTagsMapper;
} }
public ResultObject<Void> publish(long id, long editorId) { public ResultObject<Void> publish(long id, long editorId) {
@ -90,14 +99,12 @@ public class NewsService {
Integer status = news.getStatus(); Integer status = news.getStatus();
if (status == 2) { if (status == 2) {
newsMapper.simpleUnpublish(id); newsMapper.simpleUnpublish(id);
syncStatusToNewsInfo(news.getNewsinfoId(), 1);
return ResultObject.success(); return ResultObject.success();
} }
Long draftId = news.getDraftId(); Long draftId = news.getDraftId();
if (draftId == null) { if (draftId == null) {
newsMapper.simplePublish(id, editorId); newsMapper.simplePublish(id, editorId);
syncStatusToNewsInfo(news.getNewsinfoId(), 2);
return ResultObject.success(); return ResultObject.success();
} }
@ -111,16 +118,6 @@ public class NewsService {
return createPublish(editorId, saveNewsDTO); return createPublish(editorId, saveNewsDTO);
} }
private void syncStatusToNewsInfo(String newsInfoId, Integer status) {
NewsInfo publishedNewsInfo = new NewsInfo();
publishedNewsInfo.setStatus(status);
try {
elasticsearchClient.update(e -> e.index(NewsInfo.INDEX_NAME).refresh(Refresh.True).id(newsInfoId).doc(publishedNewsInfo), NewsInfo.class);
} catch(IOException e) {
log.error("资讯精选状态同步至全量资讯出错!", e);
}
}
public ResultObject<NewsDetailVO> detail(Long id) { public ResultObject<NewsDetailVO> detail(Long id) {
News news = newsMapper.getById(id); News news = newsMapper.getById(id);
if (news == null) { if (news == null) {
@ -460,7 +457,8 @@ public class NewsService {
} }
NewsInfo newsInfo = saveNewsDTO.toNewsInfo(); NewsInfo newsInfo = saveNewsDTO.toNewsInfo();
newsInfo.setStatus(2); // 状态不同步
// newsInfo.setStatus(2);
SaveDraftTag saveDraftTag = saveNewsDTO.getTag(); SaveDraftTag saveDraftTag = saveNewsDTO.getTag();
if (saveDraftTag != null && saveDraftTag.getSource() != null) { if (saveDraftTag != null && saveDraftTag.getSource() != null) {
Tag sourceTag = tagMapper.queryById(saveDraftTag.getSource()); Tag sourceTag = tagMapper.queryById(saveDraftTag.getSource());
@ -785,21 +783,24 @@ public class NewsService {
} }
public PageObject<NewsVO> queryNews(String keyword, String columnParam, Integer status, int page, int size, public PageObject<NewsVO> queryNews(String keyword, String columnParam, Integer status, int page, int size,
Integer last, Integer current, String orderBy, String direction) { Integer last, Integer current, String orderBy, Double minScore, Double maxScore) {
String orderByClause = null;
if (StringUtils.hasText(orderBy)) { if (StringUtils.hasText(orderBy)) {
switch (orderBy) { String orderByStr = orderBy;
case "publishTime": { try {
orderBy = "publish_time"; orderByStr = URLDecoder.decode(orderByStr, "UTF-8");
break; } catch(UnsupportedEncodingException e) {
} return PageObject.failedPage(400, "排序参数异常! orderBy = " + orderBy);
case "updateTime": {
orderBy = "update_time";
break;
}
case "createTime": {
orderBy = "create_time";
break;
} }
orderByStr = orderByStr.replace("publishTime", "publish_time").replace("updateTime", "update_time").replace("createTime", "create_time");
orderByClause = Stream.of(orderByStr.split(";")).map(e -> {
String[] params = e.split("\\$");
return "news." + params[0] + " " + params[1];
}).collect(Collectors.joining(","));
// 处理空值排在最后面的情况
if (orderByStr.contains("score")) {
orderByClause = orderByClause.replace("news.score", "news_tags.news_score");
orderByClause = " IF(ISNULL(news_tags.news_score), 1, 0) asc, " + orderByClause;
} }
} }
int offset = 0; int offset = 0;
@ -821,7 +822,7 @@ public class NewsService {
List<News> newsList; List<News> newsList;
try { try {
newsList = newsMapper.queryNews(keyword, columnParam, status, last, orderBy, direction, size, offset); newsList = newsMapper.queryNews(keyword, minScore, maxScore, columnParam, status, last, orderByClause, size, offset);
} catch (Exception e) { } catch (Exception e) {
log.error("搜索新闻异常!", e); log.error("搜索新闻异常!", e);
return PageObject.failedPage(500, "服务器错误,请联系系统管理员!"); return PageObject.failedPage(500, "服务器错误,请联系系统管理员!");
@ -830,7 +831,7 @@ public class NewsService {
PageObject<NewsVO> pageObject = new PageObject<>(); PageObject<NewsVO> pageObject = new PageObject<>();
if (page == 1) { if (page == 1) {
try { try {
int total = newsMapper.queryTotal(keyword, columnParam, status); int total = newsMapper.queryTotal(keyword,minScore, maxScore, columnParam, status);
pageObject.setTotal(total); pageObject.setTotal(total);
} catch (Exception e) { } catch (Exception e) {
log.error("获取新闻总数异常!", e); log.error("获取新闻总数异常!", e);
@ -898,4 +899,15 @@ public class NewsService {
} }
return pageObject; return pageObject;
} }
public ResultObject<NewsScoreVO> getScore(Long id) {
News news = newsMapper.getById(id);
String newsinfoId = news.getNewsinfoId();
NewsTags newsTags = newsTagsMapper.getNewsTagsByNewsId(newsinfoId);
if (newsTags == null) {
return ResultObject.success();
}
NewsScoreVO newsScoreVO = new NewsScoreVO(newsTags);
return ResultObject.success(newsScoreVO);
}
} }

View File

@ -0,0 +1,72 @@
package com.jinrui.reference.core.typehandler;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.util.ObjectUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonArrayTypeHandler<T> extends BaseTypeHandler<List<T>> {
protected final ObjectMapper objectMapper = new ObjectMapper();
protected final JavaType listType;
public JsonArrayTypeHandler(Class<T> clazz) {
listType = objectMapper.getTypeFactory().constructCollectionType(List.class, clazz);
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
try {
ps.setString(i, objectMapper.writeValueAsString(parameter));
} catch (JsonProcessingException | SQLException e) {
e.printStackTrace();
}
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
final String json = rs.getString(columnName);
if (ObjectUtils.isEmpty(json)) {
return Collections.emptyList();
}
// json.replaceAll("\"", "'")
return parseJson(json);
}
private List<T> parseJson(String json) {
try {
return objectMapper.readValue(json, new TypeReference<List<T>>() {});
} catch (IOException e) {
throw new RuntimeException("JSON 解析失败", e);
}
}
@Override
public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
final String json = rs.getString(columnIndex);
if (ObjectUtils.isEmpty(json)) {
return Collections.emptyList();
}
return parseJson(json);
}
@Override
public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
final String json = cs.getString(columnIndex);
if (ObjectUtils.isEmpty(json)) {
return Collections.emptyList();
}
return parseJson(json);
}
}