添加帖子是否展示的功能(二)查询最新帖、领域贴、问答帖、index 页面显示
查询
"/recent", "/recent/hot", "/recent/good", "/recent/reply" 最新帖
IndexProcessor.java
@RequestProcessing(value = {"/recent", "/recent/hot", "/recent/good", "/recent/reply"}, method = HttpMethod.GET)
@Before({StopwatchStartAdvice.class, AnonymousViewCheck.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void showRecent(final RequestContext context) {
......
final JSONObject result = articleQueryService.getRecentArticles(sortMode, pageNum, pageSize);
......
}
ArticleQueryService.java
public JSONObject getRecentArticles(final int sortMode, final int currentPageNum, final int fetchSize) {
final JSONObject ret = new JSONObject();
Query query;
switch (sortMode) {
case 0:
/**
* create by: qiankunpingtai
* create time: 2019/5/14 9:24
* website:https://qiankunpingtai.cn
* description:
* 修改帖子的默认排序方式
* 优先级:
* 1、帖子置顶时间(articleStick)
* 2、帖子更新时间(articleUpdateTime)
* 3、帖子最新回帖时间(articleLatestCmtTime)
* 4、帖子浏览计数(articleViewCount)
*/
query = new Query().
addSort(Article.ARTICLE_STICK, SortDirection.DESCENDING).
addSort(Article.ARTICLE_UPDATE_TIME, SortDirection.DESCENDING).
addSort(Article.ARTICLE_LATEST_CMT_TIME, SortDirection.DESCENDING).
addSort(Article.ARTICLE_VIEW_CNT, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setFilter(makeRecentArticleShowingFilter());
break;
case 1:
final String id = String.valueOf(DateUtils.addMonths(new Date(), -1).getTime());
query = new Query().
addSort(Article.ARTICLE_STICK, SortDirection.DESCENDING).
addSort(Article.ARTICLE_COMMENT_CNT, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING);
final CompositeFilter compositeFilter = makeRecentArticleShowingFilter();
final List<Filter> filters = new ArrayList<>();
filters.add(new PropertyFilter(Keys.OBJECT_ID, FilterOperator.GREATER_THAN_OR_EQUAL, id));
filters.addAll(compositeFilter.getSubFilters());
query.setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters));
break;
case 2:
query = new Query().
addSort(Article.ARTICLE_STICK, SortDirection.DESCENDING).
addSort(Article.REDDIT_SCORE, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setFilter(makeRecentArticleShowingFilter());
break;
case 3:
query = new Query().
addSort(Article.ARTICLE_STICK, SortDirection.DESCENDING).
addSort(Article.ARTICLE_LATEST_CMT_TIME, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setFilter(makeRecentArticleShowingFilter());
break;
default:
query = new Query().
addSort(Article.ARTICLE_STICK, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setFilter(makeRecentArticleShowingFilter());
}
query.setPage(currentPageNum, fetchSize);
addListProjections(query);
JSONObject result = null;
try {
Stopwatchs.start("Query recent articles");
result = articleRepository.get(query);
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Gets articles failed", e);
} finally {
Stopwatchs.end();
}
final int pageCount = result.optJSONObject(Pagination.PAGINATION).optInt(Pagination.PAGINATION_PAGE_COUNT);
final JSONObject pagination = new JSONObject();
ret.put(Pagination.PAGINATION, pagination);
final int windowSize = Symphonys.ARTICLE_LIST_WIN_SIZE;
final List<Integer> pageNums = Paginator.paginate(currentPageNum, fetchSize, pageCount, windowSize);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) pageNums);
final JSONArray data = result.optJSONArray(Keys.RESULTS);
final List<JSONObject> articles = CollectionUtils.jsonArrayToList(data);
organizeArticles(articles);
//final Integer participantsCnt = Symphonys.getInt("latestArticleParticipantsCnt");
//genParticipants(articles, participantsCnt);
ret.put(Article.ARTICLES, (Object) articles);
return ret;
}
private void addListProjections(final Query query) {
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 添加帖子是否展示字段
*/
query.select(Keys.OBJECT_ID,
Article.ARTICLE_STICK,
Article.ARTICLE_CREATE_TIME,
Article.ARTICLE_UPDATE_TIME,
Article.ARTICLE_LATEST_CMT_TIME,
Article.ARTICLE_AUTHOR_ID,
Article.ARTICLE_TITLE,
Article.ARTICLE_STATUS,
Article.ARTICLE_VIEW_CNT,
Article.ARTICLE_THANK_CNT,
Article.ARTICLE_TYPE,
Article.ARTICLE_PERMALINK,
Article.ARTICLE_TAGS,
Article.ARTICLE_LATEST_CMTER_NAME,
Article.ARTICLE_COMMENT_CNT,
Article.ARTICLE_ANONYMOUS,
Article.ARTICLE_PERFECT,
Article.ARTICLE_BAD_CNT,
Article.ARTICLE_GOOD_CNT,
Article.ARTICLE_COLLECT_CNT,
Article.ARTICLE_WATCH_CNT,
Article.ARTICLE_UA,
Article.ARTICLE_CONTENT,
Article.ARTICLE_QNA_OFFER_POINT,
Article.ARTICLE_DISPLAYABLE
);
}
private CompositeFilter makeRecentArticleShowingFilter() {
final List<Filter> filters = new ArrayList<>();
filters.add(new PropertyFilter(Article.ARTICLE_STATUS, FilterOperator.NOT_EQUAL, Article.ARTICLE_STATUS_C_INVALID));
filters.add(new PropertyFilter(Article.ARTICLE_TYPE, FilterOperator.NOT_EQUAL, Article.ARTICLE_TYPE_C_DISCUSSION));
filters.add(new PropertyFilter(Article.ARTICLE_TAGS, FilterOperator.NOT_EQUAL, Tag.TAG_TITLE_C_SANDBOX));
filters.add(new PropertyFilter(Article.ARTICLE_TAGS, FilterOperator.NOT_LIKE, "B3log%"));
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 过滤不展示的帖子
*/
filters.add(new PropertyFilter(Article.ARTICLE_DISPLAYABLE, FilterOperator.NOT_EQUAL, Article.ARTICLE_DISPLAYABLE_NOT));
return new CompositeFilter(CompositeFilterOperator.AND, filters);
}
public JSONObject getDomainArticles(final String domainId, final int currentPageNum, final int pageSize) {
final JSONObject ret = new JSONObject();
ret.put(Article.ARTICLES, (Object) Collections.emptyList());
final JSONObject pagination = new JSONObject();
ret.put(Pagination.PAGINATION, pagination);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, 0);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) Collections.emptyList());
try {
final JSONArray domainTags = domainTagRepository.getByDomainId(domainId, 1, Integer.MAX_VALUE)
.optJSONArray(Keys.RESULTS);
if (domainTags.length() <= 0) {
return ret;
}
final List<String> tagIds = new ArrayList<>();
for (int i = 0; i < domainTags.length(); i++) {
tagIds.add(domainTags.optJSONObject(i).optString(Tag.TAG + "_" + Keys.OBJECT_ID));
}
Query query = new Query().setFilter(
new PropertyFilter(Tag.TAG + "_" + Keys.OBJECT_ID, FilterOperator.IN, tagIds)).
setPage(currentPageNum, pageSize).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING);
JSONObject result = tagArticleRepository.get(query);
final JSONArray tagArticles = result.optJSONArray(Keys.RESULTS);
if (tagArticles.length() <= 0) {
return ret;
}
final int pageCount = result.optJSONObject(Pagination.PAGINATION).optInt(Pagination.PAGINATION_PAGE_COUNT);
final int windowSize = Symphonys.ARTICLE_LIST_WIN_SIZE;
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) pageNums);
final Set<String> articleIds = new HashSet<>();
for (int i = 0; i < tagArticles.length(); i++) {
articleIds.add(tagArticles.optJSONObject(i).optString(Article.ARTICLE + "_" + Keys.OBJECT_ID));
}
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 过滤不展示的帖子
*/
query = new Query().setFilter(CompositeFilterOperator.and(
new PropertyFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds),
new PropertyFilter(Article.ARTICLE_STATUS, FilterOperator.NOT_EQUAL, Article.ARTICLE_STATUS_C_INVALID),
new PropertyFilter(Article.ARTICLE_DISPLAYABLE, FilterOperator.NOT_EQUAL, Article.ARTICLE_DISPLAYABLE_NOT))).
setPageCount(1).addSort(Keys.OBJECT_ID, SortDirection.DESCENDING);
final List<JSONObject> articles = CollectionUtils.jsonArrayToList(articleRepository.get(query).optJSONArray(Keys.RESULTS));
organizeArticles(articles);
final Integer participantsCnt = Symphonys.ARTICLE_LIST_PARTICIPANTS_CNT;
genParticipants(articles, participantsCnt);
ret.put(Article.ARTICLES, (Object) articles);
return ret;
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Gets domain articles error", e);
return null;
}
}
/domain/{domainURI}
领域贴
DomainProcessor.java
@RequestProcessing(value = "/domain/{domainURI}", method = HttpMethod.GET)
@Before({StopwatchStartAdvice.class, AnonymousViewCheck.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void showDomainArticles(final RequestContext context) {
......
final JSONObject result = articleQueryService.getDomainArticles(domainId, pageNum, pageSize);
......
}
public JSONObject getDomainArticles(final String domainId, final int currentPageNum, final int pageSize) {
final JSONObject ret = new JSONObject();
ret.put(Article.ARTICLES, (Object) Collections.emptyList());
final JSONObject pagination = new JSONObject();
ret.put(Pagination.PAGINATION, pagination);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, 0);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) Collections.emptyList());
try {
final JSONArray domainTags = domainTagRepository.getByDomainId(domainId, 1, Integer.MAX_VALUE)
.optJSONArray(Keys.RESULTS);
if (domainTags.length() <= 0) {
return ret;
}
final List<String> tagIds = new ArrayList<>();
for (int i = 0; i < domainTags.length(); i++) {
tagIds.add(domainTags.optJSONObject(i).optString(Tag.TAG + "_" + Keys.OBJECT_ID));
}
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 过滤不展示的帖子
* 这个地方过滤的字段在多个表中,只能使用原生sql进行处理
*
*/
StringBuffer queryCount=new StringBuffer("select count(0) ").append(" from ");
StringBuffer queryList=new StringBuffer("select symphony_article.oId ").append(" from ");
StringBuffer queryStr=new StringBuffer(articleRepository.getName()+" symphony_article, ").append(tagArticleRepository.getName()+" symphony_tag_article ");
queryStr.append(" where symphony_article.oId=symphony_tag_article.article_oId and symphony_article.articleDisplayable != ? ")
.append(" and symphony_article.").append(Article.ARTICLE_STATUS).append("!=?");
queryStr.append(" and ").append( "symphony_tag_article."+Tag.TAG + '_' + Keys.OBJECT_ID).append(" in ( ");
for(int i=0;i<tagIds.size();i++){
queryStr.append(" ").append(tagIds.get(i));
if(i<(tagIds.size()-1)){
queryStr.append(",");
}
}
queryStr.append(")");
queryStr.append(" order by ").append("symphony_tag_article."+Keys.OBJECT_ID+" ").append(" desc ");
final List<JSONObject> tagArticlesCount=articleRepository.
select(queryCount.append(queryStr.toString()).toString(),Article.ARTICLE_DISPLAYABLE_NOT,Article.ARTICLE_STATUS_C_INVALID);
queryStr.append(" limit ").append((currentPageNum-1)*pageSize).append(",")
.append(currentPageNum*pageSize);
final List<JSONObject> tagArticles=articleRepository.
select(queryList.append(queryStr.toString()).toString(),Article.ARTICLE_DISPLAYABLE_NOT,Article.ARTICLE_STATUS_C_INVALID);
if(tagArticles.size()<=0){
return ret;
}
final int windowSize = Symphonys.ARTICLE_LIST_WIN_SIZE;
final int pageCount=(int) Math.ceil((tagArticlesCount==null?0:tagArticlesCount.get(0).optInt("count(0)")) / (double) pageSize);
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) pageNums);
final Set<String> articleIds = new HashSet<>();
for (int i = 0; i < tagArticles.size(); i++) {
articleIds.add(tagArticles.get(i).optString( Keys.OBJECT_ID));
}
Query query = new Query().setFilter(new PropertyFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds)).
setPageCount(1).addSort(Keys.OBJECT_ID, SortDirection.DESCENDING);
final List<JSONObject> articles = CollectionUtils.jsonArrayToList(articleRepository.get(query).optJSONArray(Keys.RESULTS));
organizeArticles(articles);
final Integer participantsCnt = Symphonys.ARTICLE_LIST_PARTICIPANTS_CNT;
genParticipants(articles, participantsCnt);
ret.put(Article.ARTICLES, (Object) articles);
return ret;
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Gets domain articles error", e);
return null;
}
}
"/qna", "/qna/unanswered", "/qna/reward", "/qna/hot"
问答帖
IndexProcessor.java
@RequestProcessing(value = {"/qna", "/qna/unanswered", "/qna/reward", "/qna/hot"}, method = HttpMethod.GET)
@Before({StopwatchStartAdvice.class, AnonymousViewCheck.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void showQnA(final RequestContext context) {
......
final JSONObject result = articleQueryService.getQuestionArticles(sortMode, pageNum, pageSize);
......
}
ArticleQueryService.java
public JSONObject getQuestionArticles(final int sortMode, final int currentPageNum, final int fetchSize) {
final JSONObject ret = new JSONObject();
Query query;
switch (sortMode) {
case 0:
query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setPage(currentPageNum, fetchSize).
setFilter(makeQuestionArticleShowingFilter());
break;
case 1:
query = new Query().
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setPage(currentPageNum, fetchSize);
final CompositeFilter compositeFilter1 = makeQuestionArticleShowingFilter();
final List<Filter> filters1 = new ArrayList<>();
filters1.add(new PropertyFilter(Article.ARTICLE_COMMENT_CNT, FilterOperator.EQUAL, 0));
filters1.addAll(compositeFilter1.getSubFilters());
query.setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters1));
break;
case 2:
final String id = String.valueOf(DateUtils.addMonths(new Date(), -1).getTime());
query = new Query().
addSort(Article.ARTICLE_QNA_OFFER_POINT, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setPage(currentPageNum, fetchSize);
final CompositeFilter compositeFilter2 = makeQuestionArticleShowingFilter();
final List<Filter> filters2 = new ArrayList<>();
filters2.add(new PropertyFilter(Keys.OBJECT_ID, FilterOperator.GREATER_THAN_OR_EQUAL, id));
filters2.addAll(compositeFilter2.getSubFilters());
query.setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters2));
break;
case 3:
query = new Query().
addSort(Article.REDDIT_SCORE, SortDirection.DESCENDING).
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setPage(currentPageNum, fetchSize).
setFilter(makeQuestionArticleShowingFilter());
break;
default:
query = new Query().
addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
setPage(currentPageNum, fetchSize).
setFilter(makeQuestionArticleShowingFilter());
}
......
}
private CompositeFilter makeQuestionArticleShowingFilter() {
final List<Filter> filters = new ArrayList<>();
filters.add(new PropertyFilter(Article.ARTICLE_TYPE, FilterOperator.EQUAL, Article.ARTICLE_TYPE_C_QNA));
filters.add(new PropertyFilter(Article.ARTICLE_STATUS, FilterOperator.NOT_EQUAL, Article.ARTICLE_STATUS_C_INVALID));
filters.add(new PropertyFilter(Article.ARTICLE_TAGS, FilterOperator.NOT_EQUAL, Tag.TAG_TITLE_C_SANDBOX));
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 过滤不展示的帖子
*/
filters.add(new PropertyFilter(Article.ARTICLE_DISPLAYABLE, FilterOperator.NOT_EQUAL, Article.ARTICLE_DISPLAYABLE_NOT));
return new CompositeFilter(CompositeFilterOperator.AND, filters);
}
index 页面显示
"", "/"
IndexProcessor.java
@RequestProcessing(value = {"", "/"}, method = HttpMethod.GET)
@Before({StopwatchStartAdvice.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void showIndex(final RequestContext context) {
......
final List<JSONObject> recentArticles = articleQueryService.getIndexRecentArticles();
......
}
ArticleQueryService.java
public List<JSONObject> getIndexRecentArticles() {
List<JSONObject> ret;
try {
Stopwatchs.start("Query index recent articles");
try {
final int fetchSize = 18;
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 过滤不展示的帖子
*/
Query query = new Query().
setFilter(CompositeFilterOperator.and(
new PropertyFilter(Article.ARTICLE_TYPE, FilterOperator.NOT_EQUAL, Article.ARTICLE_TYPE_C_DISCUSSION),
new PropertyFilter(Article.ARTICLE_STATUS, FilterOperator.EQUAL, Article.ARTICLE_STATUS_C_VALID),
new PropertyFilter(Article.ARTICLE_DISPLAYABLE, FilterOperator.NOT_EQUAL, Article.ARTICLE_DISPLAYABLE_NOT))).
setPageCount(1).setPage(1, fetchSize).
addSort(Article.ARTICLE_LATEST_CMT_TIME, SortDirection.DESCENDING);
ret = articleRepository.getList(query);
final List<JSONObject> stickArticles = getStickArticles();
if (!stickArticles.isEmpty()) {
final Iterator<JSONObject> i = ret.iterator();
while (i.hasNext()) {
final JSONObject article = i.next();
for (final JSONObject stickArticle : stickArticles) {
if (article.optString(Keys.OBJECT_ID).equals(stickArticle.optString(Keys.OBJECT_ID))) {
i.remove();
}
}
}
ret.addAll(0, stickArticles);
final int size = ret.size() < fetchSize ? ret.size() : fetchSize;
ret = ret.subList(0, size);
}
} finally {
Stopwatchs.end();
}
organizeArticles(ret);
return ret;
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Gets index recent articles failed", e);
return Collections.emptyList();
}
}