资讯精选列表页增加行业分页和概念标签搜索

This commit is contained in:
sunflower2014 2025-06-17 08:01:25 +08:00
parent 09b47574d6
commit 8ec45e21fe
10 changed files with 197 additions and 28 deletions

View File

@ -1,5 +1,7 @@
package com.jinrui.reference.admin.controller; package com.jinrui.reference.admin.controller;
import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -16,7 +18,8 @@ import com.jinrui.reference.admin.service.AdminJwtService;
import com.jinrui.reference.core.model.dto.news.SaveIndustryDTO; import com.jinrui.reference.core.model.dto.news.SaveIndustryDTO;
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.tag.IndustryVO; import com.jinrui.reference.core.model.vo.industry.IndustryHierarchyVO;
import com.jinrui.reference.core.model.vo.industry.IndustryVO;
import com.jinrui.reference.core.service.IndustryService; import com.jinrui.reference.core.service.IndustryService;
/** /**
@ -99,6 +102,22 @@ public class IndustryController {
return industryService.update(saveIndustryDTO.getId(), saveIndustryDTO.getPrimaryName(), saveIndustryDTO.getSecondaryName()); return industryService.update(saveIndustryDTO.getId(), saveIndustryDTO.getPrimaryName(), saveIndustryDTO.getSecondaryName());
} }
@GetMapping("/hierarchy")
public ResultObject<List<IndustryHierarchyVO>> getHierarchy(@RequestHeader("auth-token") String token) {
AdminUser adminUser = AdminJwtService.parseToken(token);
if (adminUser == null) {
log.warn("解析token {}拿不到AdminUser对象!", token);
return ResultObject.failed("登陆Token有误请联系系统管理员!");
}
if (!adminUser.isActive()) {
log.warn("当前用户已被封禁! id = {}", adminUser.getId());
return ResultObject.failed("当前用户已被封禁!请联系系统管理员!");
}
return industryService.getHierarchy();
}
/** /**
* 行业分类搜索接口 * 行业分类搜索接口
* *

View File

@ -193,6 +193,8 @@ 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 = "tag", required = false) String tag,
@RequestParam(value = "industry", required = false) String industry,
@RequestParam(value = "minScore", required = false) Double minScore, @RequestParam(value = "minScore", required = false) Double minScore,
@RequestParam(value = "maxScore", required = false) Double maxScore, @RequestParam(value = "maxScore", required = false) Double maxScore,
@RequestParam(value = "column", required = false) String columnList, @RequestParam(value = "column", required = false) String columnList,
@ -220,13 +222,13 @@ 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: {}", "page: {}, size: {}, last: {}, current: {}, orderBy: {}, tag: {}, industry: {}",
adminUser.getId(), keyword, columnList, status, page, size, last, current, orderBy); adminUser.getId(), keyword, columnList, status, page, size, last, current, orderBy, tag, industry);
} 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, minScore, maxScore, tag, industry);
} }
@GetMapping("/score") @GetMapping("/score")

View File

@ -19,21 +19,22 @@ spring:
datasource: datasource:
type: com.zaxxer.hikari.HikariDataSource type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://10.127.2.207:3306/reference?autoReconnect=true&useUnicode=true&useSSL=false&allowMultiQueries=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai # url: jdbc:mysql://192.168.0.142:3306/reference?autoReconnect=true&useUnicode=true&useSSL=false&allowMultiQueries=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: financial_prod # username: financial_prod
password: mmTFncqmDal5HLRGY0BV # password: mmTFncqmDal5HLRGY0BV
# url: jdbc:mysql://121.37.185.246:3306/reference?autoReconnect=true&useUnicode=true&useSSL=false&allowMultiQueries=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai url: jdbc:mysql://121.37.185.246:3306/reference?autoReconnect=true&useUnicode=true&useSSL=false&allowMultiQueries=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
# username: root username: root
# password: Xgf_8000 password: Xgf_8000
redis: redis:
host: 10.127.2.209 # host: 192.168.0.172
# port: 6379
# password: Xgf_redis
host: 123.60.153.169
port: 6379 port: 6379
password: dMrt4kmwiW6LDJXy password: Xgf_redis
#host: 123.60.153.169
#port: 6379
#password: Xgf_redis
elasticsearch: elasticsearch:
scheme: http scheme: http
# 111.13.176.3
host: 10.127.2.194 host: 10.127.2.194
port: 9200 port: 9200
enable: true enable: true
@ -42,4 +43,4 @@ elasticsearch:
mybatis: mybatis:
type-handlers-package:com.jinrui.reference.core.typehandler type-handlers-package:com.jinrui.reference.core.typehandler
api: api:
key: WBysu6N1z26AbA12l key: WBysu6N1z26AbA12l

View File

@ -0,0 +1 @@
alter table tag add level tinyint after name;

View File

@ -100,6 +100,18 @@ 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=\"tags != null and !tags.isEmpty()\">" +
" inner join news_tag_rel on news.id = news_tag_rel.news_id and tag_id in " +
"<foreach collection=\"tags\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</if>" +
"<if test=\"industries != null and !industries.isEmpty()\">" +
" inner join news_industry_rel on news.id = news_industry_rel.news_id and industry_id in " +
"<foreach collection=\"industries\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</if>" +
" left join news_tags on news.newsinfo_id = news_tags.newsinfo_id " + " 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()\">" +
@ -134,13 +146,27 @@ public interface NewsMapper {
@Param("last") Integer last, @Param("last") Integer last,
@Param("orderBy") String orderBy, @Param("orderBy") String orderBy,
@Param("limit") int limit, @Param("limit") int limit,
@Param("offset") int offset); @Param("offset") int offset,
@Param("tags") List<Long> tags,
@Param("industries") List<Long> industries);
@Select("<script>" + @Select("<script>" +
"select count(*) from (select distinct news.* from news " + "select count(*) from (select distinct 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>" +
"<if test=\"tags != null and !tags.isEmpty()\">" +
" inner join news_tag_rel on news.id = news_tag_rel.news_id and tag_id in " +
"<foreach collection=\"tags\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</if>" +
"<if test=\"industries != null and !industries.isEmpty()\">" +
" inner join news_industry_rel on news.id = news_industry_rel.news_id and industry_id in " +
"<foreach collection=\"industries\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</if>" +
"<if test=\"minScore != null or maxScore != null \">" + "<if test=\"minScore != null or maxScore != null \">" +
"left join news_tags on news.newsinfo_id = news_tags.newsinfo_id " + "left join news_tags on news.newsinfo_id = news_tags.newsinfo_id " +
"</if>" + "</if>" +
@ -166,7 +192,9 @@ public interface NewsMapper {
@Param("minScore") Double minScore, @Param("minScore") Double minScore,
@Param("maxScore") Double maxScore, @Param("maxScore") Double maxScore,
@Param("column") String columnParam, @Param("column") String columnParam,
@Param("status") Integer status); @Param("status") Integer status,
@Param("tags") List<Long> tags,
@Param("industries") List<Long> industries);
@Select("select id, title, summary, picture, content, status, " + @Select("select id, title, summary, picture, content, status, " +
"create_time as createTime, " + "create_time as createTime, " +

View File

@ -0,0 +1,60 @@
package com.jinrui.reference.core.model.vo.industry;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jinrui.reference.core.model.entity.Industry;
import com.jinrui.reference.core.model.entity.Tag;
/**
* 行业分类
*/
@SuppressWarnings("unused")
public class IndustryHierarchyVO {
/**
* 行业分类ID
*/
private Long id;
/**
* 行业名称
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<IndustryHierarchyVO> getChildren() {
return children;
}
public void setChildren(List<IndustryHierarchyVO> children) {
this.children = children;
}
/**
* 二级行业
*/
private List<IndustryHierarchyVO> children;
public IndustryHierarchyVO(Industry industry) {
this.id = industry.getId();
this.name = industry.getDisplayName();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@ -1,4 +1,4 @@
package com.jinrui.reference.core.model.vo.tag; package com.jinrui.reference.core.model.vo.industry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -41,9 +41,8 @@ public class IndustryVO {
*/ */
@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;
public IndustryVO(Industry industry) {
public IndustryVO(Industry industry) {
this.id = industry.getId(); this.id = industry.getId();
this.parentId = industry.getParentId(); this.parentId = industry.getParentId();
this.primaryName = industry.getPrimaryName(); this.primaryName = industry.getPrimaryName();
@ -99,5 +98,4 @@ public class IndustryVO {
public void setUpdateTime(Date updateTime) { public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime; this.updateTime = updateTime;
} }
} }

View File

@ -16,7 +16,8 @@ import com.jinrui.reference.core.mapper.IndustryMapper;
import com.jinrui.reference.core.model.entity.Industry; import com.jinrui.reference.core.model.entity.Industry;
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.tag.IndustryVO; import com.jinrui.reference.core.model.vo.industry.IndustryHierarchyVO;
import com.jinrui.reference.core.model.vo.industry.IndustryVO;
@Service @Service
public class IndustryService { public class IndustryService {
@ -151,5 +152,21 @@ public class IndustryService {
} }
return resultPage; return resultPage;
} }
public ResultObject<List<IndustryHierarchyVO>> getHierarchy() {
List<IndustryHierarchyVO> resultList = new ArrayList<>();
try {
List<Industry> industrys = industryMapper.queryIndustry(0L, null, "id", "asc");
resultList = industrys.stream().map(IndustryHierarchyVO::new).collect(Collectors.toList());
for (IndustryHierarchyVO industryHierarchyVO: resultList) {
List<Industry> childIndustrys = industryMapper.queryIndustry(industryHierarchyVO.getId(), null, "id", "asc");
industryHierarchyVO.setChildren(childIndustrys.stream().map(IndustryHierarchyVO::new).collect(Collectors.toList()));
}
} catch (Exception e) {
log.error("搜索行业分类出错!", e);
return ResultObject.failed("服务端错误,请联系系统管理员!");
}
return ResultObject.success(resultList);
}
} }

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -22,8 +23,9 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
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;
@ -767,7 +769,8 @@ 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, Double minScore, Double maxScore) { Integer last, Integer current, String orderBy, Double minScore, Double maxScore,
String tag, String industry) {
String orderByClause = null; String orderByClause = null;
if (StringUtils.hasText(orderBy)) { if (StringUtils.hasText(orderBy)) {
String orderByStr = orderBy; String orderByStr = orderBy;
@ -803,10 +806,23 @@ public class NewsService {
} }
} }
} }
List<Long> tags = this.getMatchTags(tag);
List<Long> industries = null;
if (!ObjectUtils.isEmpty(industry)) {
try {
String industryStr = URLDecoder.decode(industry, "UTF-8");
ObjectMapper objectMapper = new ObjectMapper();
industries = objectMapper.readValue(industryStr, new TypeReference<List<Long>>() {});
} catch (UnsupportedEncodingException|JsonProcessingException e) {
log.error("资讯精选列表页面的行业分类参数异常!", e);
return PageObject.failedPage(500, "服务器错误,请联系系统管理员!");
}
}
List<News> newsList; List<News> newsList;
try { try {
newsList = newsMapper.queryNews(keyword, minScore, maxScore, columnParam, status, last, orderByClause, size, offset); newsList = newsMapper.queryNews(keyword, minScore, maxScore, columnParam, status, last, orderByClause, size, offset, tags, industries);
} catch (Exception e) { } catch (Exception e) {
log.error("搜索新闻异常!", e); log.error("搜索新闻异常!", e);
return PageObject.failedPage(500, "服务器错误,请联系系统管理员!"); return PageObject.failedPage(500, "服务器错误,请联系系统管理员!");
@ -815,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,minScore, maxScore, columnParam, status); int total = newsMapper.queryTotal(keyword,minScore, maxScore, columnParam, status, tags, industries);
pageObject.setTotal(total); pageObject.setTotal(total);
} catch (Exception e) { } catch (Exception e) {
log.error("获取新闻总数异常!", e); log.error("获取新闻总数异常!", e);
@ -894,4 +910,31 @@ public class NewsService {
NewsScoreVO newsScoreVO = new NewsScoreVO(newsTags); NewsScoreVO newsScoreVO = new NewsScoreVO(newsTags);
return ResultObject.success(newsScoreVO); return ResultObject.success(newsScoreVO);
} }
private List<Long> getMatchTags(String tagParam) {
if (ObjectUtils.isEmpty(tagParam)) {
return Collections.emptyList();
}
String[] tags = StringUtils.trimWhitespace(tagParam).split("\\s+");
List<Tag> levelOneTags = tagMapper.queryTag(6L, null, null, "create_time", null);
List<Long> result = new ArrayList<>();
for (Tag tag: levelOneTags) {
long levelOneMatchs = Stream.of(tags).filter(x -> tag.getName().contains(x)).count();
if (levelOneMatchs > 0) {
result.add(tag.getId());
}
List<Tag> childTags = tagMapper.queryTag(tag.getId(), null, null, "create_time", null);
if (levelOneMatchs > 0) {
result.addAll(childTags.stream().map(Tag::getId).collect(Collectors.toList()));
} else {
List<Long> matchedTags = childTags.stream().filter(e -> {
long count = Stream.of(tags).filter(x -> e.getName().contains(x)).count();
return count > 0;
}).map(e -> e.getId()).collect(Collectors.toList());
result.addAll(matchedTags);
}
}
return result;
}
} }