package com.jeecms.front.controller; import com.jeecms.channel.domain.Channel; import com.jeecms.channel.service.ChannelService; import com.jeecms.common.base.controller.BaseController; import com.jeecms.common.exception.GlobalException; import com.jeecms.common.jsonfilter.annotation.MoreSerializeField; import com.jeecms.common.jsonfilter.annotation.SerializeField; import com.jeecms.content.constants.ContentConstant; import com.jeecms.content.constants.ContentConstant.ReleaseTimeStage; import com.jeecms.content.constants.ContentConstant.SearchKeyCondition; import com.jeecms.content.constants.ContentConstant.SearchPosition; import com.jeecms.content.domain.Content; import com.jeecms.content.domain.ContentAttr; import com.jeecms.content.domain.ContentAttrRes; import com.jeecms.content.domain.vo.ContentChannelCountVo; import com.jeecms.content.domain.vo.ContentFrontVo; import com.jeecms.content.domain.vo.ContentLuceneSummaryVo; import com.jeecms.content.service.ContentFrontService; import com.jeecms.content.service.ContentLuceneService; import com.jeecms.resource.domain.ResourcesSpaceData; import com.jeecms.system.domain.CmsSite; import com.jeecms.system.domain.ContentSource; import com.jeecms.util.SystemContextUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import static com.jeecms.common.constants.WebConstants.ARRAY_SPT; /** * 内容检索 * * @author: tom * @date: 2019年5月28日 下午3:37:05 */ @RestController @RequestMapping("/content") public class ContentSearchController extends BaseController<Content, Integer> { private Logger logger = LoggerFactory.getLogger(ContentSearchController.class); /** * 内容检索 * * @param keyword 关键词 * @param searchPos 索引位置 title 标题、txt 正文、 titleAndTxt 标题或者正文 * @param keyCondition 关键词条件 any 包含以下任意一个关键词 all 包含以下全部关键词 notInclude 不包含以下关键词 * @param siteId 站点ID * @param channelIds 栏目ID * @param typeIds 类型Id * @param tagIds tagId * @param timeStage 发布时间阶段 oneDay 一天内、oneWeek 一周内、oneMonth 一月内、oneYear * 一年内、timeRage 指定时间范围段、 * @param releaseTimeBegin 发布时间开始 * @param releaseTimeEnd 发布时间结束 * @param issueOrg 发文字号的机关代号 * @param issueYear 发文字号的年份 * @param issueNum 发文字号的顺序号 * @param isTop 是否置顶 * @param releaseApp 是否支持app通道 * @param releaseMiniprogram 是否支持小程序通道 * @param oderBy 排序 28 发布时间升序 27 发布时间降序 没有值则相关度排序 * @param pageable 分页 * @throws IOException IOException * @throws GlobalException GlobalException * @Title: searchPage * @return: Page */ @MoreSerializeField({ @SerializeField(clazz = Content.class, includes = { "id", "title", "description", "channel", "site", "releaseTime", "url", "urlWhole", "views", "comments", "downs", "ups", "downloads", "source", "contentFrontVo","docResource" }), @SerializeField(clazz = ContentFrontVo.class, includes = { "modelId", "videoJson", "imageJson", "multiImageUploads" }), @SerializeField(clazz = ContentAttr.class, includes = { "resourcesSpaceData", "contentAttrRes" }), @SerializeField(clazz = ContentAttrRes.class, includes = { "resourcesSpaceData" }), @SerializeField(clazz = ResourcesSpaceData.class, includes = { "resourceType", "dimensions", "url", "resourceDate", "suffix", "duration"}), @SerializeField(clazz = CmsSite.class, includes = { "id", "name" }), @SerializeField(clazz = Channel.class, includes = { "id", "name" }), @SerializeField(clazz = ContentSource.class, includes = { "sourceLink", "sourceName", "isOpenTarget" }), }) @RequestMapping(value = "/search") public Page<Content> searchPage(String keyword, SearchPosition searchPos, SearchKeyCondition keyCondition, Integer siteId, String channelIds, String typeIds, String tagIds, ReleaseTimeStage timeStage, Date releaseTimeBegin, Date releaseTimeEnd, Integer issueOrg, Integer issueYear, String issueNum, Boolean isTop, Boolean releaseApp, Boolean releaseMiniprogram, Integer oderBy, Pageable pageable, HttpServletRequest request) throws IOException, GlobalException { if (oderBy == null) { oderBy = ContentConstant.ORDER_TYPE_RELATE; } if (searchPos == null) { searchPos = SearchPosition.titleAndTxt; } if (keyCondition == null) { keyCondition = SearchKeyCondition.any; } if (siteId == null) { siteId = SystemContextUtils.getSiteId(request); } Boolean releasePc = null; if (SystemContextUtils.isPc()) { releasePc = true; } Boolean releaseWap = null; if (SystemContextUtils.isMobile()) { releaseWap = true; } long begin = System.currentTimeMillis(); List<Channel> channels = channelService.findList(siteId, true); List<Channel> excludeChannels = channels.stream() .filter(c -> Boolean.FALSE.equals(c.getIsOpenIndex())).collect(Collectors.toList()); List<Integer> excludeChannelIds = Channel.fetchIds(excludeChannels); Page<Content> page = luceneService.searchPage(keyword, searchPos, keyCondition, siteId, Arrays.asList(getIntArray(channelIds)), excludeChannelIds, Arrays.asList(getIntArray(typeIds)), Arrays.asList(getIntArray(tagIds)), timeStage, releaseTimeBegin, releaseTimeEnd, issueOrg, issueYear, issueNum, isTop, releasePc, releaseWap, releaseApp, releaseMiniprogram, oderBy, pageable); for (Content content : page) { ContentFrontVo contentFrontVo = contentFrontService.initPartVo(content); content.setContentFrontVo(contentFrontVo); } long end = System.currentTimeMillis(); logger.info("search times=" + (end - begin)); return page; } @SerializeField(clazz = Channel.class, includes = {"id", "name"}) @RequestMapping(value = "/searchSummary") public ContentLuceneSummaryVo searchSummary(String keyword, SearchPosition searchPos, SearchKeyCondition keyCondition, Integer siteId, @RequestParam(value = "channelIds") List<Integer> channelIds, @RequestParam(value = "typeIds") List<Integer> typeIds, @RequestParam(value = "tagIds") List<Integer> tagIds, ReleaseTimeStage timeStage, Date releaseTimeBegin, Date releaseTimeEnd, Integer issueOrg, Integer issueYear, String issueNum, Boolean isTop, Boolean releaseApp, Boolean releaseMiniprogram, Pageable pageable, HttpServletRequest request) throws IOException, GlobalException { if (searchPos == null) { searchPos = SearchPosition.titleAndTxt; } if (keyCondition == null) { keyCondition = SearchKeyCondition.any; } if (siteId == null) { siteId = SystemContextUtils.getSiteId(request); } Boolean releasePc = null; if (SystemContextUtils.isPc()) { releasePc = true; } Boolean releaseWap = null; if (SystemContextUtils.isMobile()) { releaseWap = true; } long begin = System.currentTimeMillis(); List<Channel> channels = channelService.findList(siteId, true); List<Channel> excludeChannels = channels.stream() .filter(channel -> Boolean.FALSE.equals(channel.getIsOpenIndex())) .collect(Collectors.toList()); List<Integer> excludeChannelIds = Channel.fetchIds(excludeChannels); List<ContentChannelCountVo> channelCounts = luceneService.searchSummary(keyword, searchPos, keyCondition, siteId, channelIds, excludeChannelIds, typeIds, tagIds, timeStage, releaseTimeBegin, releaseTimeEnd, issueOrg, issueYear, issueNum, isTop, releasePc, releaseWap, releaseApp, releaseMiniprogram); long end = System.currentTimeMillis(); logger.info("search times=" + (end - begin)); ContentLuceneSummaryVo vo = new ContentLuceneSummaryVo(channelCounts); return vo; } private Integer[] getIntArray(String str) { if (StringUtils.isBlank(str)) { return new Integer[0]; } String[] arr = StringUtils.split(str, ARRAY_SPT); Integer[] ids = new Integer[arr.length]; int i = 0; for (String s : arr) { ids[i++] = Integer.valueOf(s); } return ids; } @Autowired private ContentLuceneService luceneService; @Autowired private ChannelService channelService; @Autowired private ContentFrontService contentFrontService; }