feat(超算专区): 优化全局搜索中项目搜索逻辑
1. 项目搜索时基于Gitlink搜索功能实现 2. 支持项目描述搜索 3. 支持项目标签搜索
This commit is contained in:
parent
e2347e6609
commit
6830387bb8
|
|
@ -211,6 +211,17 @@ public class HttpAPIService {
|
|||
return doRequest(httpDelete, headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 不带Header的get请求
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public JSONObject doGet(String url) throws Exception {
|
||||
return doGet(url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 带Header的get请求
|
||||
*
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ public class OpenController extends BaseController {
|
|||
@GetMapping("/{zoneId}/member/homePageList")
|
||||
@ApiOperation("获取首页特色专区会员列表")
|
||||
public GenericsTableDataInfo<ZoneMemberDataVo> homePageMemberList(@ApiParam(name = "zoneId", value = "专区Id", required = true) @PathVariable("zoneId") Long zoneId) {
|
||||
List<ZoneMemberDataVo> list = zoneMemberService.selectZoneMemberHomePageMemberList(zoneId,true);
|
||||
List<ZoneMemberDataVo> list = zoneMemberService.selectZoneMemberHomePageMemberList(zoneId, true);
|
||||
return getGenericsDataTable(list);
|
||||
}
|
||||
|
||||
|
|
@ -421,38 +421,15 @@ public class OpenController extends BaseController {
|
|||
private IGlobalSearchService globalSearchService;
|
||||
|
||||
/**
|
||||
* 全局搜索接口(GET方法)
|
||||
* 全局搜索接口(POST方法)
|
||||
*
|
||||
* @param keyword 搜索关键词
|
||||
* @param types 搜索类型(逗号分隔)
|
||||
* @param zoneId 专区ID
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 每页数量
|
||||
* @return 搜索结果
|
||||
*/
|
||||
@ApiOperation("全局搜索(GET)")
|
||||
@GetMapping("/global")
|
||||
public GenericsTableDataInfo<GlobalSearchResult> globalSearchGet(
|
||||
@ApiParam("搜索关键词") @RequestParam String keyword,
|
||||
@ApiParam("搜索类型(zone_project:项目, resource:资源, member:会员)") @RequestParam(required = false) String types,
|
||||
@ApiParam("专区ID") @RequestParam Long zoneId,
|
||||
@ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@ApiParam("每页数量") @RequestParam(defaultValue = "20") Integer pageSize) {
|
||||
|
||||
GlobalSearchRequest request = new GlobalSearchRequest();
|
||||
request.setKeyword(keyword);
|
||||
request.setPageNum(pageNum);
|
||||
request.setPageSize(pageSize);
|
||||
request.setZoneId(zoneId);
|
||||
|
||||
if (types != null && !types.isEmpty()) {
|
||||
request.setTypes(java.util.Arrays.asList(types.split(",")));
|
||||
}
|
||||
|
||||
logger.info("全局搜索请求(GET): keyword={}, types={}", keyword, types);
|
||||
|
||||
GlobalSearchResponse response = globalSearchService.globalSearch(request);
|
||||
|
||||
return new GenericsTableDataInfo<>(response.getResults(),response.getTotal());
|
||||
@PostMapping("/global")
|
||||
public GenericsTableDataInfo<GlobalSearchResult> globalSearchGet(@RequestBody GlobalSearchRequest globalSearchRequest) {
|
||||
logger.info("全局搜索请求(GET): keyword={}, types={}", globalSearchRequest.getKeyword(), globalSearchRequest.getTypes());
|
||||
GlobalSearchResponse response = globalSearchService.globalSearch(globalSearchRequest);
|
||||
return new GenericsTableDataInfo<>(response.getResults(), response.getTotal());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,4 +183,6 @@ public interface ZoneMemberMapper {
|
|||
@Param("zoneId") Long zoneId,
|
||||
@Param("offset") int offset,
|
||||
@Param("pageSize") int pageSize);
|
||||
|
||||
Long globalSearchCount(String keyword, Long zoneId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,11 +174,9 @@ public interface ZoneProjectMapper {
|
|||
*
|
||||
* @param keyword 搜索关键词
|
||||
* @param zoneId 专区ID(可选)
|
||||
* @param deptId 组织ID(可选)
|
||||
* @return 结果数量
|
||||
*/
|
||||
Long globalSearchCount(@Param("keyword") String keyword, @Param("zoneId") Long zoneId,
|
||||
@Param("deptId") Long deptId);
|
||||
Long globalSearchCount(@Param("keyword") String keyword, @Param("zoneId") Long zoneId);
|
||||
|
||||
/**
|
||||
* 全局搜索 - 全文索引查询(含评分)
|
||||
|
|
@ -194,4 +192,15 @@ public interface ZoneProjectMapper {
|
|||
@Param("zoneId") Long zoneId,
|
||||
@Param("offset") int offset,
|
||||
@Param("pageSize") int pageSize);
|
||||
|
||||
/**
|
||||
* 获取专区下项目项目gitlink id列表
|
||||
*
|
||||
* @param zoneId 专区id
|
||||
* @param projectTypeId 专区类型id
|
||||
* @return 项目gitlink id列表
|
||||
*/
|
||||
List<String> selectZoneProjectGitlinkIdList(@Param("zoneId") Long zoneId, @Param("projectTypeId") Long projectTypeId);
|
||||
|
||||
List<ZoneProject> selectZoneProjectListFromGitlinkProjectIdList(@Param("zoneId") Long zoneId, @Param("gitlinkProjectIdList") List<Long> gitlinkProjectIdList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package com.microservices.zone.search.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class GitlinkSearchDataVo {
|
||||
|
||||
private Long total=0L;
|
||||
|
||||
private List<GitlinkSearchVo> gitlinkSearchVoList;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package com.microservices.zone.search.dto;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.microservices.common.core.utils.StringUtils;
|
||||
import com.microservices.zone.project.domain.vo.ZoneProjectDataVo;
|
||||
import com.microservices.zone.search.utils.SearchUtils;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class GitlinkSearchVo {
|
||||
|
||||
private String id;
|
||||
|
||||
private Long instanceId;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private String userName;
|
||||
|
||||
private Long type;
|
||||
|
||||
private Long star;
|
||||
|
||||
private Long fork;
|
||||
|
||||
private Long watch;
|
||||
|
||||
private String createTime;
|
||||
|
||||
private String updateTime;
|
||||
|
||||
private List<String> topics;
|
||||
|
||||
private Long praisesCount;
|
||||
|
||||
private Long forkedCount;
|
||||
|
||||
private Long watchersCount;
|
||||
|
||||
private String url;
|
||||
|
||||
private Double score;
|
||||
|
||||
public GlobalSearchResult toGlobalSearchResult(ZoneProjectDataVo zoneProjectDataVo, String topic) {
|
||||
GlobalSearchResult globalSearchResult = new GlobalSearchResult();
|
||||
globalSearchResult.setTitle(replaceHighlightGitlinkSearch(this.title));
|
||||
globalSearchResult.setContent(replaceHighlightGitlinkSearch(this.content));
|
||||
globalSearchResult.setScore(this.score);
|
||||
globalSearchResult.setId(zoneProjectDataVo.getId());
|
||||
globalSearchResult.setType("zone_project");
|
||||
globalSearchResult.setDeptId(zoneProjectDataVo.getZoneId());
|
||||
globalSearchResult.setCreateTime(globalSearchResult.getCreateTime());
|
||||
globalSearchResult.setZoneId(zoneProjectDataVo.getZoneId());
|
||||
JSONObject extendData = zoneProjectDataVo.getProjectProperties();
|
||||
String topics = extendData.getString("topics");
|
||||
if (StringUtils.isNotEmpty(topics)) {
|
||||
extendData.put("topics", SearchUtils.highlightKeyword(topics, topic));
|
||||
}
|
||||
globalSearchResult.setExtendData(extendData);
|
||||
return globalSearchResult;
|
||||
}
|
||||
|
||||
private String replaceHighlightGitlinkSearch(String text) {
|
||||
if (StringUtils.isNotEmpty(text)) {
|
||||
text = text.replace("<span class=\"highlightByGitlinkSearch\">", "<em>").replace("</span>", "</em>");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.microservices.zone.search.dto;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.microservices.common.core.utils.StringUtils;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
|
@ -48,4 +50,23 @@ public class GlobalSearchRequest implements Serializable {
|
|||
*/
|
||||
@ApiModelProperty(value = "每页数量")
|
||||
private Integer pageSize = 20;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "额外搜索参数(项目类型:projectTypeId,topic)")
|
||||
private JSONObject extraSearchParam;
|
||||
|
||||
public String toProjectEsSearchString(String gitlinkSearchUrl, String gitlinkProjectIds, String topic) {
|
||||
String esSearchString= gitlinkSearchUrl +
|
||||
"/search" +
|
||||
"?" +
|
||||
"page=" + this.pageNum +
|
||||
"&size=" + this.pageSize +
|
||||
"&term=" + this.keyword +
|
||||
"&type=" + 1 +
|
||||
"&instanceIds=" + gitlinkProjectIds;
|
||||
if(StringUtils.isNotEmpty(topic)){
|
||||
esSearchString+="&topic=" + topic;
|
||||
}
|
||||
return esSearchString;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.microservices.zone.search.dto;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 全局搜索结果对象
|
||||
*
|
||||
* @author microservices
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("全局搜索结果对象")
|
||||
public class GlobalSearchResultDataVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "总数")
|
||||
private Long total;
|
||||
|
||||
@ApiModelProperty(value = "搜索结果")
|
||||
private List<GlobalSearchResult> globalSearchResultList;
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package com.microservices.zone.search.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.microservices.common.core.domain.R;
|
||||
import com.microservices.common.core.exception.ServiceException;
|
||||
import com.microservices.common.core.utils.StringUtils;
|
||||
import com.microservices.common.httpClient.service.HttpAPIService;
|
||||
import com.microservices.common.redis.service.RedisService;
|
||||
import com.microservices.common.security.utils.SecurityUtils;
|
||||
import com.microservices.system.api.RemoteFileService;
|
||||
|
|
@ -11,28 +13,27 @@ import com.microservices.system.api.domain.SysFileInfo;
|
|||
import com.microservices.system.api.model.LoginUser;
|
||||
import com.microservices.zone.project.domain.ZoneProject;
|
||||
import com.microservices.zone.project.domain.ZoneProjectWithScore;
|
||||
import com.microservices.zone.project.domain.vo.GitLinkProjectSearchVo;
|
||||
import com.microservices.zone.project.domain.vo.ZoneProjectDataVo;
|
||||
import com.microservices.zone.project.mapper.ZoneProjectMapper;
|
||||
import com.microservices.zone.project.service.IZoneProjectService;
|
||||
import com.microservices.zone.resource.domain.ZoneResource;
|
||||
import com.microservices.zone.resource.domain.ZoneResourceWithScore;
|
||||
import com.microservices.zone.resource.mapper.ZoneResourceMapper;
|
||||
import com.microservices.zone.member.domain.ZoneMember;
|
||||
import com.microservices.zone.member.domain.ZoneMemberWithScore;
|
||||
import com.microservices.zone.member.mapper.ZoneMemberMapper;
|
||||
import com.microservices.zone.search.dto.GlobalSearchRequest;
|
||||
import com.microservices.zone.search.dto.GlobalSearchResponse;
|
||||
import com.microservices.zone.search.dto.GlobalSearchResult;
|
||||
import com.microservices.zone.search.dto.*;
|
||||
import com.microservices.zone.search.service.IGlobalSearchService;
|
||||
import com.microservices.zone.search.utils.SearchUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
|
|
@ -62,27 +63,23 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
|
||||
@Autowired
|
||||
private IZoneProjectService projectService;
|
||||
@Autowired
|
||||
private HttpAPIService httpAPIService;
|
||||
|
||||
@Value("${http.gitLinkSearchUrl:}")
|
||||
public String gitLinkSearchUrl;
|
||||
|
||||
private static final String SEARCH_CACHE_PREFIX = "search:cache:";
|
||||
private static final long CACHE_EXPIRE_SECONDS = 300; // 5分钟
|
||||
@Autowired
|
||||
private DefaultsBindHandlerAdvisor.MappingsProvider mappingsProvider;
|
||||
|
||||
@Override
|
||||
public GlobalSearchResponse globalSearch(GlobalSearchRequest request) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// 参数校验
|
||||
if (StringUtils.isEmpty(request.getKeyword())) {
|
||||
return buildEmptyResponse(request);
|
||||
}
|
||||
|
||||
// 1. 尝试从缓存获取(仅第一页)
|
||||
if (request.getPageNum() == 1) {
|
||||
String cacheKey = buildCacheKey(request);
|
||||
GlobalSearchResponse cached = redisService.getCacheObject(SEARCH_CACHE_PREFIX + cacheKey);
|
||||
if (cached != null) {
|
||||
cached.setSearchTime(System.currentTimeMillis() - startTime);
|
||||
return cached;
|
||||
}
|
||||
if (request.getZoneId() == null) {
|
||||
throw new ServiceException("专区id不能为空");
|
||||
}
|
||||
|
||||
// 2. 并行搜索各类型
|
||||
|
|
@ -97,26 +94,32 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
if (searchTypes == null || searchTypes.isEmpty()) {
|
||||
searchTypes = Arrays.asList("zone_project", "resource", "member");
|
||||
}
|
||||
Long searchTotal = 0L;
|
||||
|
||||
// 搜索Zone项目
|
||||
if (searchTypes.contains("zone_project")) {
|
||||
List<GlobalSearchResult> zoneProjectResults = searchZoneProjects(request);
|
||||
allResults.addAll(zoneProjectResults);
|
||||
typeCounts.put("zone_project", (long) zoneProjectResults.size());
|
||||
GlobalSearchResultDataVo resultDataVo = searchZoneProjects(request);
|
||||
allResults.addAll(resultDataVo.getGlobalSearchResultList());
|
||||
typeCounts.put("zone_project", resultDataVo.getTotal());
|
||||
searchTotal += resultDataVo.getTotal();
|
||||
}
|
||||
|
||||
// 搜索Zone资源
|
||||
if (searchTypes.contains("resource")) {
|
||||
List<GlobalSearchResult> resourceResults = searchResources(request);
|
||||
allResults.addAll(resourceResults);
|
||||
typeCounts.put("resource", (long) resourceResults.size());
|
||||
Long searchResourceCount = zoneResourceMapper.globalSearchCount(request.getKeyword(), request.getZoneId());
|
||||
typeCounts.put("resource", searchResourceCount);
|
||||
searchTotal += searchResourceCount;
|
||||
}
|
||||
|
||||
// 搜索Zone会员
|
||||
if (searchTypes.contains("member")) {
|
||||
List<GlobalSearchResult> memberResults = searchZoneMembers(request);
|
||||
allResults.addAll(memberResults);
|
||||
typeCounts.put("member", (long) memberResults.size());
|
||||
Long searchMemberCount = zoneMemberMapper.globalSearchCount(request.getKeyword(), request.getZoneId());
|
||||
typeCounts.put("member", searchMemberCount);
|
||||
searchTotal += searchMemberCount;
|
||||
}
|
||||
|
||||
// 3. 按相关度评分排序
|
||||
|
|
@ -136,7 +139,7 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
|
||||
// 5. 构建响应
|
||||
GlobalSearchResponse response = new GlobalSearchResponse();
|
||||
response.setTotal((long) total);
|
||||
response.setTotal(searchTotal);
|
||||
response.setResults(pagedResults);
|
||||
response.setTypeCounts(typeCounts);
|
||||
response.setKeyword(request.getKeyword());
|
||||
|
|
@ -144,16 +147,6 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
response.setPageSize(request.getPageSize());
|
||||
response.setSearchTime(System.currentTimeMillis() - startTime);
|
||||
|
||||
// 6. 缓存结果(仅第一页)
|
||||
if (request.getPageNum() == 1) {
|
||||
String cacheKey = buildCacheKey(request);
|
||||
redisService.setCacheObject(
|
||||
SEARCH_CACHE_PREFIX + cacheKey,
|
||||
response,
|
||||
CACHE_EXPIRE_SECONDS,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// 7. 异步记录搜索日志
|
||||
recordSearchLog(request, response, loginUser);
|
||||
|
||||
|
|
@ -182,29 +175,83 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
/**
|
||||
* 搜索Zone项目
|
||||
*/
|
||||
private List<GlobalSearchResult> searchZoneProjects(GlobalSearchRequest request) {
|
||||
private GlobalSearchResultDataVo searchZoneProjects(GlobalSearchRequest request) {
|
||||
GlobalSearchResultDataVo globalSearchResultDataVo = new GlobalSearchResultDataVo();
|
||||
List<GlobalSearchResult> results = new ArrayList<>();
|
||||
Long total = 0L;
|
||||
try {
|
||||
List<ZoneProjectWithScore> projects = zoneProjectMapper.globalSearchWithScore(
|
||||
request.getKeyword(),
|
||||
request.getZoneId(),
|
||||
(request.getPageNum() - 1) * request.getPageSize(),
|
||||
request.getPageSize()
|
||||
);
|
||||
List<ZoneProject> zoneProjectList = projects.stream().map(x -> (ZoneProject) x).collect(Collectors.toList());
|
||||
List<ZoneProjectDataVo> projectDataVoList = projectService.toZoneProjectDataVoList(zoneProjectList);
|
||||
if (StringUtils.isNotEmpty(gitLinkSearchUrl)) {
|
||||
Long projectTypeId = null;
|
||||
String topic = null;
|
||||
if (request.getExtraSearchParam() != null) {
|
||||
projectTypeId = request.getExtraSearchParam().getLong("projectTypeId");
|
||||
topic = request.getExtraSearchParam().getString("topic");
|
||||
}
|
||||
List<String> gitlinkProjectIds = zoneProjectMapper.selectZoneProjectGitlinkIdList(request.getZoneId(), projectTypeId);
|
||||
|
||||
for (ZoneProjectWithScore project : projects) {
|
||||
ZoneProjectDataVo zoneProjectDataVo = projectDataVoList.stream().filter(x -> x.getId().equals(project.getId())).findFirst().orElse(null);
|
||||
GlobalSearchResult result = project.toGlobalSearchResult(zoneProjectDataVo);
|
||||
result.setTitle(highlightKeyword(result.getTitle(), request.getKeyword()));
|
||||
result.setContent(highlightKeyword(result.getContent(), request.getKeyword()));
|
||||
results.add(result);
|
||||
JSONObject searchRes = httpAPIService.doGet(request.toProjectEsSearchString(gitLinkSearchUrl, String.join(",", gitlinkProjectIds), topic));
|
||||
GitlinkSearchDataVo gitlinkSearchDataVos = gitlinkSearchResToGitlinkSearchDataVo(searchRes);
|
||||
total = gitlinkSearchDataVos.getTotal();
|
||||
if (gitlinkSearchDataVos.getTotal() > 0) {
|
||||
List<GitlinkSearchVo> gitlinkSearchVoList = gitlinkSearchDataVos.getGitlinkSearchVoList();
|
||||
List<Long> gitlinkProjectIdList = gitlinkSearchVoList.stream().map(GitlinkSearchVo::getInstanceId).collect(Collectors.toList());
|
||||
List<ZoneProject> zoneProjectList = zoneProjectMapper.selectZoneProjectListFromGitlinkProjectIdList(request.getZoneId(), gitlinkProjectIdList);
|
||||
List<ZoneProjectDataVo> projectDataVoList = projectService.toZoneProjectDataVoList(zoneProjectList);
|
||||
for (GitlinkSearchVo gitlinkSearchVo : gitlinkSearchVoList) {
|
||||
ZoneProjectDataVo zoneProjectDataVo = projectDataVoList.stream().filter(x -> x.getGitlinkProjectId().equals(gitlinkSearchVo.getInstanceId())).findFirst().orElse(null);
|
||||
if (zoneProjectDataVo != null) {
|
||||
GlobalSearchResult result = gitlinkSearchVo.toGlobalSearchResult(zoneProjectDataVo,topic);
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<ZoneProjectWithScore> projects = zoneProjectMapper.globalSearchWithScore(
|
||||
request.getKeyword(),
|
||||
request.getZoneId(),
|
||||
(request.getPageNum() - 1) * request.getPageSize(),
|
||||
request.getPageSize()
|
||||
);
|
||||
total = zoneProjectMapper.globalSearchCount(request.getKeyword(), request.getZoneId());
|
||||
List<ZoneProject> zoneProjectList = projects.stream().map(x -> (ZoneProject) x).collect(Collectors.toList());
|
||||
List<ZoneProjectDataVo> projectDataVoList = projectService.toZoneProjectDataVoList(zoneProjectList);
|
||||
|
||||
for (ZoneProjectWithScore project : projects) {
|
||||
ZoneProjectDataVo zoneProjectDataVo = projectDataVoList.stream().filter(x -> x.getId().equals(project.getId())).findFirst().orElse(null);
|
||||
GlobalSearchResult result = project.toGlobalSearchResult(zoneProjectDataVo);
|
||||
result.setTitle(SearchUtils.highlightKeyword(result.getTitle(), request.getKeyword()));
|
||||
result.setContent(SearchUtils.highlightKeyword(result.getContent(), request.getKeyword()));
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("搜索Zone项目失败: " + e.getMessage());
|
||||
}
|
||||
return results;
|
||||
globalSearchResultDataVo.setTotal(total);
|
||||
globalSearchResultDataVo.setGlobalSearchResultList(results);
|
||||
return globalSearchResultDataVo;
|
||||
}
|
||||
|
||||
private GitlinkSearchDataVo gitlinkSearchResToGitlinkSearchDataVo(JSONObject gitlinkSearchRes) {
|
||||
|
||||
GitlinkSearchDataVo gitlinkSearchDataVo = new GitlinkSearchDataVo();
|
||||
List<GitlinkSearchVo> results = new ArrayList<>();
|
||||
if (gitlinkSearchRes != null && gitlinkSearchRes.getJSONObject("data") != null) {
|
||||
JSONObject data = gitlinkSearchRes.getJSONObject("data");
|
||||
if (data.getLong("total") == null || data.getLong("total") == 0) {
|
||||
gitlinkSearchDataVo.setGitlinkSearchVoList(results);
|
||||
return gitlinkSearchDataVo;
|
||||
}
|
||||
gitlinkSearchDataVo.setTotal(data.getLong("total"));
|
||||
JSONArray rows = data.getJSONArray("rows");
|
||||
for (int i = 0; i < rows.size(); i++) {
|
||||
JSONObject row = rows.getJSONObject(i);
|
||||
results.add(row.toJavaObject(GitlinkSearchVo.class));
|
||||
}
|
||||
gitlinkSearchDataVo.setGitlinkSearchVoList(results);
|
||||
}
|
||||
|
||||
return gitlinkSearchDataVo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -224,8 +271,8 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
GlobalSearchResult result = new GlobalSearchResult();
|
||||
result.setType("resource");
|
||||
result.setId(resource.getId());
|
||||
result.setTitle(highlightKeyword(resource.getName(), request.getKeyword()));
|
||||
result.setContent(highlightKeyword(resource.getSummary(), request.getKeyword()));
|
||||
result.setTitle(SearchUtils.highlightKeyword(resource.getName(), request.getKeyword()));
|
||||
result.setContent(SearchUtils.highlightKeyword(resource.getSummary(), request.getKeyword()));
|
||||
result.setDeptId(resource.getDeptId());
|
||||
result.setZoneId(resource.getZoneId());
|
||||
result.setCreateTime(resource.getCreateTime());
|
||||
|
|
@ -256,7 +303,7 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
.map(file -> {
|
||||
JSONObject fileInfo = new JSONObject();
|
||||
fileInfo.put("fileId", file.getFileId());
|
||||
fileInfo.put("fileName", highlightKeyword(file.getFileOriginName(), request.getKeyword()));
|
||||
fileInfo.put("fileName", SearchUtils.highlightKeyword(file.getFileOriginName(), request.getKeyword()));
|
||||
fileInfo.put("fileSize", file.getFileSizeInfo());
|
||||
return fileInfo;
|
||||
})
|
||||
|
|
@ -299,7 +346,7 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
GlobalSearchResult result = new GlobalSearchResult();
|
||||
result.setType("member");
|
||||
result.setId(member.getId());
|
||||
result.setTitle(highlightKeyword(member.getName(), request.getKeyword()));
|
||||
result.setTitle(SearchUtils.highlightKeyword(member.getName(), request.getKeyword()));
|
||||
|
||||
// 构建内容:用户名 + 会员介绍
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
|
@ -312,7 +359,7 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
}
|
||||
content.append(member.getIntroduction());
|
||||
}
|
||||
result.setContent(highlightKeyword(content.toString(), request.getKeyword()));
|
||||
result.setContent(SearchUtils.highlightKeyword(content.toString(), request.getKeyword()));
|
||||
|
||||
result.setDeptId(member.getDeptId());
|
||||
result.setZoneId(member.getZoneId());
|
||||
|
|
@ -378,14 +425,4 @@ public class GlobalSearchServiceImpl implements IGlobalSearchService {
|
|||
response.setSearchTime(0L);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文本中的关键词用 <em> 标签包裹(不区分大小写)
|
||||
*/
|
||||
private String highlightKeyword(String text, String keyword) {
|
||||
if (StringUtils.isEmpty(text) || StringUtils.isEmpty(keyword)) {
|
||||
return text;
|
||||
}
|
||||
return text.replaceAll("(?i)(" + Pattern.quote(keyword) + ")", "<em>$1</em>");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package com.microservices.zone.search.utils;
|
||||
|
||||
import com.microservices.common.core.utils.StringUtils;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SearchUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 将文本中的关键词用 <em> 标签包裹(不区分大小写)
|
||||
*/
|
||||
public static String highlightKeyword(String text, String keyword) {
|
||||
if (StringUtils.isEmpty(text) || StringUtils.isEmpty(keyword)) {
|
||||
return text;
|
||||
}
|
||||
return text.replaceAll("(?i)(" + Pattern.quote(keyword) + ")", "<em>$1</em>");
|
||||
}
|
||||
}
|
||||
|
|
@ -454,4 +454,17 @@
|
|||
ORDER BY search_score DESC, zm.create_time DESC
|
||||
LIMIT #{offset}, #{pageSize}
|
||||
</select>
|
||||
<select id="globalSearchCount" resultType="java.lang.Long">
|
||||
SELECT COUNT(*)
|
||||
FROM zone_member zm
|
||||
left join sys_user u on u.user_id = zm.user_id
|
||||
WHERE zm.zone_id = #{zoneId}
|
||||
AND zm.is_audit = '1'
|
||||
AND zm.del_flag = '0'
|
||||
AND (
|
||||
MATCH(zm.name) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)
|
||||
OR zm.name LIKE CONCAT('%', #{keyword}, '%')
|
||||
OR u.user_name LIKE CONCAT('%', #{keyword}, '%')
|
||||
)
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -354,4 +354,19 @@
|
|||
AND zp.dept_id = #{deptId}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectZoneProjectGitlinkIdList" resultType="java.lang.String">
|
||||
select gitlink_project_id from zone_project
|
||||
where zone_id=#{zoneId}
|
||||
<if test="projectTypeId != null">
|
||||
AND project_type_id = #{projectTypeId}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectZoneProjectListFromGitlinkProjectIdList" resultMap="ZoneProjectWithScoreResult">
|
||||
<include refid="selectZoneProjectVo"/>
|
||||
where zone_id=#{zoneId}
|
||||
and gitlink_project_id in
|
||||
<foreach item="gitlinkProjectId" collection="gitlinkProjectIdList" open="(" separator="," close=")">
|
||||
#{gitlinkProjectId}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue