案例萃取

This commit is contained in:
yang
2024-09-06 11:04:42 +08:00
parent aa5495dbfe
commit 3f0a32de14
11 changed files with 856 additions and 74 deletions

View File

@@ -133,4 +133,24 @@ public interface CacheName {
* 字典缓存key
* */
String KEY_DICT="dict";
/**
* 季度观看量排行key
* */
String CASE_RANK_VIEWS_QUARTER="case:rank:views:quarter";
/**
* 总观看排行key
* */
String CASE_RANK_VIEWS_ALL="case:rank:views:all";
/**
* 季度点赞排行key
* */
String CASE_RANK_PRAISE_QUARTER ="case:rank:praise:quarter";
/**
* 总点赞排行key
* */
String CASE_RANK_PRAISE_ALL="case:rank:praise:all";
}

View File

@@ -0,0 +1,24 @@
package com.xboe.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import static com.xboe.constants.CacheName.*;
@AllArgsConstructor
@Getter
public enum CasesRankEnum {
QUARTER_VIEWS(1,"季度观看量排行",CASE_RANK_VIEWS_QUARTER),
ALL_VIEWS(2,"总观看排行",CASE_RANK_VIEWS_ALL),
QUARTER_PRAISES(3,"季度点赞排行",CASE_RANK_PRAISE_QUARTER),
ALL_PRAISES(4,"总点赞排行",CASE_RANK_PRAISE_ALL),
;
private Integer type;
private String name;
private String cacheKey;
}

View File

@@ -12,17 +12,15 @@ import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.CasesMajorType;
import com.xboe.module.boecase.service.ICasesRecommendPushRecordService;
import com.xboe.module.boecase.vo.CaseExportVo;
import com.xboe.module.boecase.vo.CaseRankingVo;
import com.xboe.module.boecase.vo.CasesQueryRecommendRankVo;
import com.xboe.module.dict.entity.DictItem;
import com.xboe.module.excel.ExportsExcelSenderUtil;
import com.xboe.system.user.dao.UserDao;
import com.xboe.system.user.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
@@ -127,25 +125,12 @@ public class CasesApi extends ApiBaseController {
@PostMapping("/queryListV2")
public JsonResponse<PageList<Cases>> queryCaseBreV2(@Validated @RequestBody CasePageVo req) {
String type = req.getType();
PageList<Cases> subViews1;
PageList<Cases> subViews2;
PageList<Cases> views = null;
req.setUserId(getCurrent().getAccountId());
if (StringUtils.isNotEmpty(type)) {
if ("recommend".equals(type)) {
views = casesService.queryRecommendPageCasesV2(req);
} else {
views = casesService.queryPageCasesV2(req);
}
PageList<Cases> views = null;
if (type.equals("recommend")) {
views = casesService.queryRecommendPageCasesV2(req);
} else {
PageDto pageDto = new PageDto();
pageDto.setPageIndex(req.getPageIndex());
pageDto.setPageSize(req.getPageSize());
req.setPageSize(1000000);
req.setPageIndex(1);
subViews1 = casesService.queryRecommendPageCasesV2(req);
subViews2 = casesService.queryPageCasesV2(req);
views = merge(subViews1, subViews2, pageDto);
views = casesService.queryPageCasesV2(req);
}
if (views != null) {
@@ -175,24 +160,6 @@ public class CasesApi extends ApiBaseController {
return success(views);
}
public static PageList<Cases> merge(PageList<Cases> pageList1, PageList<Cases> pageList2, PageDto pageDto) {
List<Cases> mergedCaseList = new ArrayList<>();
mergedCaseList.addAll(pageList1.getList());
mergedCaseList.addAll(pageList2.getList());
List<Cases> pageCaseList = mergedCaseList.stream()
.skip((long) (pageDto.getPageIndex() - 1) * pageDto.getPageSize())
.limit(pageDto.getPageSize())
.collect(Collectors.toList());
int totalCount = pageList1.getCount() + pageList2.getCount();
int pageSize = pageDto.getPageSize();
PageList<Cases> mergePageList = new PageList<>();
mergePageList.setList(pageCaseList);
mergePageList.setCount(totalCount);
mergePageList.setPageSize(pageSize);
return mergePageList;
}
@PostMapping("/caseYears")
public JsonResponse<List<String>> caseYears() {
List<String> result = casesService.getCaseYears();
@@ -654,7 +621,7 @@ public class CasesApi extends ApiBaseController {
* 设置/取消优秀案例
*/
@PostMapping("/excellent")
public JsonResponse<Boolean> excellent(String id, Boolean excellent) {
public JsonResponse<Boolean> excellent(String id, Boolean excellent,String excellentReason) {
if (StringUtil.isBlank(id)) {
return badRequest("参数异常");
}
@@ -662,12 +629,108 @@ public class CasesApi extends ApiBaseController {
excellent = false;//默认设置取消
}
try {
casesService.excellent(id, excellent);
casesService.excellent(id, excellent,excellentReason);
return success(true);
} catch (Exception e) {
return error("设置或者取消失败", e.getMessage());
}
}
/**
* 不同专业分类下排行榜刷新
*/
@PostMapping("/refreshViewsRankOfMajor")
public JsonResponse<Boolean> refreshViewsRankOfMajor() {
casesService.refreshViewsRankOfMajor();
return success(true);
}
@PostMapping("/refreshLastQuarterStatistics")
public JsonResponse<Boolean> refreshLastQuarterStatistics() {
casesService.refreshLastQuarterStatistics();
return success(true);
}
/**
* 热度榜(当前季度、总榜) 按观看量排行
* @param pageSize
* @param rankType 1当前季度2总榜
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryPopularity")
public JsonResponse<List<CaseRankingVo>> queryPopularity(@RequestParam(required = false) Integer pageSize,@RequestParam Integer rankType) {
List<CaseRankingVo> caseRankingVoList =casesService.queryRank(pageSize,rankType);
return success(caseRankingVoList);
}
/**
* 好评榜 (当前季度、总榜) 按点赞量排行
* @param pageSize
* @param rankType
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryHighOpinion")
public JsonResponse<List<CaseRankingVo>> queryHighOpinion(@RequestParam(required = false) Integer pageSize,@RequestParam Integer rankType) {
List<CaseRankingVo> caseRankingVoList =casesService.queryRank(pageSize,rankType);
return success(caseRankingVoList);
}
/**
* 不同专业月热度榜 按观看量排行
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryPopularityOfMajor")
public JsonResponse<List<Cases>> queryPopularityOfMajor(@RequestParam(required = false) Integer pageSize,
@RequestParam Long majorId,
@RequestParam LocalDateTime rankMonth) {
List<Cases> caseRankingVoList =casesService.queryPopularityOfMajor(pageSize,majorId,rankMonth);
return success(caseRankingVoList);
}
/**
* 查询推荐案例榜单
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryRecommendRank")
public JsonResponse<List<CasesQueryRecommendRankVo>> queryRecommendRank() {
List<CasesQueryRecommendRankVo> list = casesService.queryRecommendRank();
return success(list);
}
/**
* 案例上榜
*/
@SuppressWarnings("unchecked")
@PostMapping("/riseIntoRank")
public JsonResponse<Boolean> riseIntoRank(@RequestParam Long caseId) {
casesService.riseIntoRank(caseId,getCurrent());
return success(true);
}
/**
* 案例下榜
*/
@SuppressWarnings("unchecked")
@PostMapping("/cancelRiseIntoRank")
public JsonResponse<Boolean> cancelRiseIntoRank(@RequestParam Long caseId) {
casesService.cancelRiseIntoRank(caseId);
return success(true);
}
/**
* 推荐案例调整排名
*/
@SuppressWarnings("unchecked")
@PostMapping("/adjustRank")
public JsonResponse<Boolean> adjustRank(@RequestParam List<Long> caseIds) {
casesService.adjustRank(caseIds);
return success(true);
}
}

View File

@@ -1,18 +1,24 @@
package com.xboe.module.boecase.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.core.orm.BaseDao;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.IFieldFilter;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.core.orm.FieldFilters;
import com.xboe.module.boecase.dto.CaseVo;
import com.xboe.module.boecase.vo.CaseRankingVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import static com.xboe.enums.CasesRankEnum.*;
@Repository
@Slf4j
public class CasesDao extends BaseDao<Cases> {
/**
@@ -35,4 +41,106 @@ public class CasesDao extends BaseDao<Cases> {
public Cases getByTitle(String title) {
return this.getGenericDao().findOne(Cases.class, FieldFilters.eq("title", title));
}
public HashMap<String, Object> findExcellentCount(List<String> authorIdList) {
String sql =
"SELECT author_id,COUNT(1) AS excellentCount\n" +
"FROM boe_cases \n" +
"WHERE excellent = 1 AND author_id IN (?1) AND deleted=0 \n" +
"GROUP BY author_id";
List<Object[]> list = this.sqlFindList(sql, authorIdList);
HashMap<String, Object> map = new HashMap<>();
list.forEach(objects -> {
String authorId = objects[0].toString();
int excellentCount = Integer.parseInt(objects[1].toString());
map.put(authorId, excellentCount);
});
return map;
}
private List<CaseRankingVo> handleCaseRank(List<Object[]> listFields) {
List<CaseRankingVo> list = new ArrayList<>();
for (Object[] o : listFields) {
CaseRankingVo dto = new CaseRankingVo();
dto.setCaseId(String.valueOf(o[0]));
dto.setCaseTitle((String) o[1]);
list.add(dto);
}
return list;
}
public List<CaseRankingVo> findPopularityOfAll(Integer pageSize) {
String sql =
"SELECT id,title\n" +
"FROM boe_cases \n" +
"WHERE deleted=0\n" +
"ORDER BY views DESC,sys_create_time DESC\n" +
"LIMIT ?1";
List<Object[]> listFields = this.sqlFindList(sql, pageSize);
List<CaseRankingVo> caseRankingVoList = handleCaseRank(listFields);
return caseRankingVoList;
}
public List<CaseRankingVo> findPopularityOfQuarter(Integer pageSize) {
String sql =
"SELECT id,title\n" +
"FROM boe_cases \n" +
"WHERE deleted=0\n" +
"ORDER BY (views-last_month_views) DESC,sys_create_time DESC \n" +
"LIMIT ?1";
List<Object[]> listFields = this.sqlFindList(sql, pageSize);
List<CaseRankingVo> caseRankingVoList = handleCaseRank(listFields);
return caseRankingVoList;
}
public List<CaseRankingVo> findHighOpinionOfAll(Integer pageSize) {
String sql =
"SELECT id,title\n" +
"FROM boe_cases \n" +
"WHERE deleted=0\n" +
"ORDER BY praises DESC,sys_create_time DESC \n" +
"LIMIT ?1";
List<Object[]> listFields = this.sqlFindList(sql, pageSize);
List<CaseRankingVo> caseRankingVoList = handleCaseRank(listFields);
return caseRankingVoList;
}
public List<CaseRankingVo> findHighOpinionOfQuarter(Integer pageSize) {
String sql =
"SELECT id,title\n" +
"FROM boe_cases \n" +
"WHERE deleted=0\n" +
"ORDER BY (praises-last_month_praises) DESC,sys_create_time DESC \n" +
"LIMIT ?1";
List<Object[]> listFields = this.sqlFindList(sql, pageSize);
List<CaseRankingVo> caseRankingVoList = handleCaseRank(listFields);
return caseRankingVoList;
}
public List<CaseRankingVo> findRank(Integer pageSize, Integer rankType) {
List<CaseRankingVo> popularityOfQuarter = Collections.emptyList();
if (rankType == QUARTER_VIEWS.getType()){
popularityOfQuarter = findPopularityOfQuarter(pageSize);
}
if (rankType == ALL_VIEWS.getType()){
popularityOfQuarter = findPopularityOfAll(pageSize);
}
if (rankType == QUARTER_PRAISES.getType()){
popularityOfQuarter = findHighOpinionOfQuarter(pageSize);
}
if (rankType == ALL_PRAISES.getType()){
popularityOfQuarter = findHighOpinionOfAll(pageSize);
}
return popularityOfQuarter;
}
}

View File

@@ -0,0 +1,87 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@Repository
@Slf4j
public class CasesRankDao extends BaseDao<CasesRank> {
public List<CasesRank> findViewsRankRecordByCaseId(String caseId) {
String sql =
"SELECT bdmt.name,bcvr.rise_rank_time,bcvr.rank \n" +
"FROM\n" +
" boe_cases_rank bcvr\n" +
"JOIN boe_dict_major_type bdmt \n" +
" ON CAST(bdmt.code AS SIGNED) = bcvr.major_id \n" +
"WHERE bcvr.case_id = ?1 AND bcvr.deleted=0 AND bdmt.deleted=0\n" +
"ORDER BY bcvr.sys_update_time DESC \n" +
"LIMIT 2;";
List<Object[]> list = this.sqlFindList(sql, caseId);
List<CasesRank> resultList = new ArrayList<>();
for (Object[] o : list) {
CasesRank casesRank = new CasesRank();
casesRank.setMajorName(o[0].toString());
casesRank.setSysCreateTime(((Timestamp) o[1]).toLocalDateTime());
casesRank.setRank(Integer.valueOf(o[2].toString()));
resultList.add(casesRank);
}
return resultList;
}
public HashMap<String, Object> findViewTopCount(List<String> authorIdList) {
String sql=
"SELECT author_id,COUNT(1) as viewTopCount\n" +
"FROM boe_cases bc JOIN boe_cases_rank bcvr ON bcvr.case_id = bc.id\n" +
"WHERE bc.author_id IN (?1) \n" +
" AND bcvr.deleted = 0 \n" +
" AND bc.deleted = 0\n" +
"GROUP BY bc.author_id;";
List<Object[]> list = this.sqlFindList(sql, authorIdList);
HashMap<String, Object> map = new HashMap<>();
list.forEach(objects -> {
String authorId = objects[0].toString();
Integer viewTopCount = Integer.parseInt(objects[1].toString());
map.put(authorId, viewTopCount);
});
return map;
}
public List<String> findPopularityOfMajor(Integer pageSize, LocalDateTime startTime, LocalDateTime endTime, Long majorId) {
String sql =
"SELECT bcr.case_id\n" +
"FROM boe_cases_rank bcr\n" +
"JOIN boe_cases bc on bcr.case_id = bc.id\n" +
"WHERE bcr.deleted=0 AND bc.deleted=0 AND bcr.rise_rank_time BETWEEN ?1 and ?2 AND major_id=?3\n" +
"ORDER BY rank\n" +
"LIMIT ?4";
List<Object> listFields = this.sqlFindList(sql, startTime, endTime,majorId,pageSize);
System.out.println(listFields.get(0).getClass());
List<String> collect = listFields.stream().map(item -> {
return item.toString();
}).collect(Collectors.toList());
return collect;
}
}

View File

@@ -248,16 +248,7 @@ public class Cases extends BaseEntity {
@Column(name = "case_value")
private String caseValue;
// 种类字段1
// 暂不上线
// @Column(name = "sys_type1")
// private String sysType1;
//种类字段2
// @Column(name = "sys_type2")
// private String sysType2;
//种类字段3
// @Column(name = "sys_type3")
// private String sysType3;
/**
* 最佳案例标识
@@ -272,6 +263,42 @@ public class Cases extends BaseEntity {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime excellentTime;
/**
* 上月浏览量
*/
@Column(name = "last_month_views")
private Integer lastMonthViews;
/**
* 上季度浏览量
*/
@Column(name = "last_quarter_views")
private Integer lastQuarterViews;
/**
* 上季度点赞量
*/
@Column(name = "last_quarter_praises")
private Integer lastQuarterPraises;
/**
* 推荐榜排序
* */
@Column(name = "recommend_rank")
private Integer recommendRank;
/**
* 推送用户名称
*/
@Column(name = "recommend_rank_push_user_name")
private String recommendRankPushUserName;
/**
* 推送时间
*/
@Column(name = "recommend_rank_push_time")
private LocalDateTime recommendRankPushTime;
/**
* type 种类
* 区分 案例/推荐案例
@@ -279,11 +306,6 @@ public class Cases extends BaseEntity {
@Transient
private String type;
/**
* id
*/
@Transient
private List<String> majorIds;
@@ -296,6 +318,15 @@ public class Cases extends BaseEntity {
@Transient
private String refId;
@Transient
private String excellentTag;
@Transient
private List<String> viewRankTags;
@Transient
private List<String> authorTags;
public String getRefId() {
return refId;
}

View File

@@ -0,0 +1,63 @@
package com.xboe.module.boecase.entity;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.time.LocalDateTime;
/**
* 案例推荐表
* @TableName boe_cases_rank
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE+"cases_rank")
public class CasesRank extends BaseEntity {
/**
* 案例ID
*/
@Column(name = "case_id")
private Long caseId;
/**
* 专业ID
*/
@Column(name = "major_id")
private Long majorId;
/**
* 排名
*/
@Column(name = "rank")
private Integer rank;
/**
* 浏览量每月增量
*/
@Column(name = "monthly_increment")
private Integer monthlyIncrement;
/**
* 排行类型
*/
@Column(name = "rank_type")
private Integer rankType;
@Column(name = "rise_rank_time")
private LocalDateTime riseRankTime;
@Transient
private String majorName;
}

View File

@@ -1,14 +1,18 @@
package com.xboe.module.boecase.service;
import java.util.List;
import com.xboe.common.PageList;
import com.xboe.core.CurrentUser;
import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.vo.CaseRankingVo;
import com.xboe.module.boecase.vo.CasesQueryRecommendRankVo;
import com.xboe.module.dict.entity.DictItem;
import com.xboe.school.vo.CasesVo;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.List;
public interface ICasesService{
/**
* 案例分页搜索,是否被推荐
@@ -101,7 +105,7 @@ public interface ICasesService{
/**
* 设置或者取消优秀案例
* */
void excellent(String id,Boolean excellent);
void excellent(String id, Boolean excellent, String excellentReason);
PageList<Cases> queryRecommendPageCasesV2(CasePageVo req);
@@ -110,5 +114,22 @@ public interface ICasesService{
List<String> getCaseYears();
@Transactional
void refreshViewsRankOfMajor();
void refreshLastQuarterStatistics();
List<CasesQueryRecommendRankVo> queryRecommendRank();
void riseIntoRank(Long caseId, CurrentUser currentUser);
void cancelRiseIntoRank(Long caseId);
void adjustRank(List<Long> caseIdList);
List<CaseRankingVo> queryRank(Integer pageSize, Integer rankType);
List<Cases> queryPopularityOfMajor(Integer pageSize, Long majorId, LocalDateTime month);
}

View File

@@ -2,8 +2,10 @@ package com.xboe.module.boecase.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.xboe.common.OrderCondition;
import com.xboe.common.OrderDirection;
import com.xboe.common.PageList;
@@ -11,29 +13,36 @@ import com.xboe.common.utils.IDGenerator;
import com.xboe.common.utils.StringUtil;
import com.xboe.core.CurrentUser;
import com.xboe.core.orm.*;
import com.xboe.enums.CasesRankEnum;
import com.xboe.module.boecase.dao.*;
import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.entity.CasesMajorType;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.module.boecase.entity.*;
import com.xboe.module.boecase.service.ICasesService;
import com.xboe.module.boecase.vo.CaseRankingVo;
import com.xboe.module.boecase.vo.CasesQueryRecommendRankVo;
import com.xboe.module.dict.dao.SysDictionaryDao;
import com.xboe.module.dict.entity.DictItem;
import com.xboe.orm.CustomFieldInFilter;
import com.xboe.school.vo.CasesVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j
@Service
@@ -61,6 +70,12 @@ public class CasesServiceImpl implements ICasesService {
@Autowired
private CasesRecommendDao casesRecommendDao;
@Resource
private CasesRankDao casesRankDao;
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 案例分页查询,用于门户的查询
*/
@@ -357,11 +372,63 @@ public class CasesServiceImpl implements ICasesService {
}
}
addAuthorTagAndCaseNewTag(list);
}
return page;
}
private void addAuthorTagAndCaseNewTag(List<Cases> caseList) {
if (CollUtil.isEmpty(caseList)) {
return;
}
List<String> authorIdList = caseList.stream().map(Cases::getAuthorId).distinct().collect(Collectors.toList());
HashMap<String, Object> excellentCountMap = casesDao.findExcellentCount(authorIdList);
HashMap<String, Object> viewTopCountMap = casesRankDao.findViewTopCount(authorIdList);
caseList.forEach(e -> {
// 获取最新的两个浏览量上榜记录
List<CasesRank> viewsRankRecords = casesRankDao.findViewsRankRecordByCaseId(e.getId());
if (CollUtil.isNotEmpty(viewsRankRecords)) {
// 拼接生成浏览量排行榜的标签
List<String> viewRankTags = viewsRankRecords.stream().map(casesRank -> {
String pattern = casesRank.getSysCreateTime().getMonthValue() < 10 ? "yyyy年M月" : "yyyy年MM月";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
String time = casesRank.getSysCreateTime().format(formatter);
// 2023年6月 经营管理类 浏览量 TOP1
String viewRankTag = time + casesRank.getMajorName() + "类浏览量TOP" + (casesRank.getRank() + 1);
return viewRankTag;
}).collect(Collectors.toList());
e.setViewRankTags(viewRankTags);
}
// 拼接生成年度最佳标签
if (e.getExcellent()!=null && e.getExcellent()) {
e.setExcellentTag(e.getExcellentTime().format(DateTimeFormatter.ofPattern("yyyy年"))+"度最佳");
}
List<String> authorTags = new ArrayList<>();
if (viewTopCountMap.get(e.getAuthorId())!=null){
String authorTagOfView = "上榜浏览量TOP榜单" + viewTopCountMap.get(e.getAuthorId()) + "";
authorTags.add(authorTagOfView);
}
if (excellentCountMap.get(e.getAuthorId())!=null){
String authorTagOfExcellent = "最佳案例" + excellentCountMap.get(e.getAuthorId()) + "";
authorTags.add(authorTagOfExcellent);
}
e.setAuthorTags(authorTags);
});
}
@Override
public PageList<Cases> queryRecommendPageCasesV2(CasePageVo caseVo) {
@@ -451,6 +518,7 @@ public class CasesServiceImpl implements ICasesService {
}
}
}
addAuthorTagAndCaseNewTag(content);
pageList.setList(content);
return pageList;
}
@@ -1078,15 +1146,266 @@ public class CasesServiceImpl implements ICasesService {
}
@Override
public void excellent(String id, Boolean excellent) {
public void excellent(String id, Boolean excellent, String excellentReason) {
//取消时,把时间清空
if (excellent) {
casesDao.updateMultiFieldById(id, UpdateBuilder.create("excellent", excellent), UpdateBuilder.create("excellentTime", LocalDateTime.now()));
casesDao.updateMultiFieldById(id, UpdateBuilder.create("excellent", excellent), UpdateBuilder.create("excellentTime", LocalDateTime.now()), UpdateBuilder.create("excellentReason", excellentReason));
} else {
casesDao.updateMultiFieldById(id, UpdateBuilder.create("excellent", excellent), UpdateBuilder.create("excellentTime", null));
casesDao.updateMultiFieldById(id, UpdateBuilder.create("excellent", excellent), UpdateBuilder.create("excellentTime", null), UpdateBuilder.create("excellentReason", null));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refreshViewsRankOfMajor(){
LocalDateTime riseRankTime = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).minusDays(1).toLocalDate().atTime(23, 59, 59); // 上月最后一天的结束时间
int count = casesRankDao.sqlCount("SELECT count(1) FROM boe_cases_rank WHERE deleted=0 AND rise_rank_time = ?1", riseRankTime);
if (count > 0){
return;
}
//获取案例当月排名
String sql =
"SELECT bc.id,bcmt.major_id,bc.views - COALESCE(bc.last_month_views, 0) AS increment,bc.case_owner\n" +
"FROM boe_cases bc\n" +
"JOIN boe_cases_major_type bcmt ON bcmt.case_id = bc.id and bc.deleted=0";
List<Object> caseListOfObject = casesDao.sqlFindList(sql);
// 转为casesRank
List<CasesRank> casesRankList = caseListOfObject.stream()
.filter(o -> Array.get(o, 3)!=null && StringUtils.isNotBlank(Array.get(o, 3).toString()))
.map(o -> {
CasesRank casesRank = new CasesRank();
casesRank.setCaseId(Long.valueOf(Array.get(o, 0).toString()));
casesRank.setMajorId(Long.valueOf(Array.get(o, 1).toString()));
casesRank.setMonthlyIncrement(Integer.parseInt(Array.get(o, 2).toString()));
casesRank.setRiseRankTime(riseRankTime);
return casesRank;
}).collect(Collectors.toList());
// 根据专业分类进行分组
Map<Long, List<CasesRank>> casesRankMap = casesRankList.stream().collect(Collectors.groupingBy(CasesRank::getMajorId));
// 生成当前月不同分类的最新的浏览量排名
ArrayList<CasesRank> lastMonthRank = new ArrayList<>();
casesRankMap.forEach((majorId, caseList) -> {
List<CasesRank> sortedCaseList = caseList.stream()
.sorted(Comparator.comparingInt(CasesRank::getMonthlyIncrement).reversed()).limit(10)
.collect(Collectors.toList());
IntStream.range(0, sortedCaseList.size())
.forEach(i -> sortedCaseList.get(i).setRank(i));
lastMonthRank.addAll(sortedCaseList);
});
casesRankDao.saveList(lastMonthRank);
casesDao.sqlUpdate("update boe_cases set last_month_views=views where deleted=0");
}
@Override
public void refreshLastQuarterStatistics() {
casesDao.sqlUpdate("update boe_cases set last_quarter_views=views where deleted=0");
casesDao.sqlUpdate("update boe_cases set last_quarter_praise=praise where deleted=0");
}
@Override
public List<CaseRankingVo> queryRank(Integer pageSize, Integer rankType) {
if (pageSize == null) {
pageSize = 3;
}
String cacheKey = "";
// 获取缓存key
for (CasesRankEnum enumValue : CasesRankEnum.values()) {
if (rankType == enumValue.getType()) {
cacheKey = enumValue.getCacheKey();
}
}
List<String> caseListOfJson = stringRedisTemplate.opsForList().range(cacheKey, 0, -1);
if (CollectionUtil.isNotEmpty(caseListOfJson)) {
// 缓存中存在数据
List<CaseRankingVo> casesList = caseListOfJson.stream().map(item -> JSONUtil.toBean(item, CaseRankingVo.class)).collect(Collectors.toList());
return casesList;
}
List<CaseRankingVo> casesList = casesDao.findRank(pageSize,rankType);
if (CollectionUtil.isNotEmpty(casesList)) {
// 缓存不存在数据,数据库中不存在数据,重建缓存
List<String> serializedCases = casesList.stream().map(item -> JSONUtil.toJsonStr(item)).collect(Collectors.toList());
stringRedisTemplate.opsForList().rightPushAll(cacheKey, serializedCases);
stringRedisTemplate.expire(cacheKey, 10000, TimeUnit.SECONDS);
return casesList;
}
return Collections.emptyList();
}
@Override
public List<Cases> queryPopularityOfMajor(Integer pageSize, Long majorId, LocalDateTime month) {
if (pageSize == null) {
pageSize = 10;
}
LocalDateTime startTime = month.withDayOfMonth(1);
LocalDateTime endTime = month.plusMonths(1).minusDays(1);
List<String> caseIdList = casesRankDao.findPopularityOfMajor(pageSize, startTime, endTime,majorId);
QueryBuilder query = QueryBuilder.from(Cases.class);
query.addFilter(FieldFilters.in("id",caseIdList));
query.addFilter(FieldFilters.eq("deleted",false));
List<Cases> casesList = casesDao.findList(query.builder());
if (CollUtil.isNotEmpty(casesList)) {
List<String> caseIds = casesList.stream().map(Cases::getId).collect(Collectors.toList());
QueryBuilder recommendCasesQuery = QueryBuilder.from(CasesRecommendPushRecord.class);
recommendCasesQuery.addField("new CasesRecommendPushRecord(id,recommendId,caseId)");
List<IFieldFilter> subFilters = new ArrayList<>();
subFilters.add(FieldFilters.in("caseId", caseIds));
subFilters.add(FieldFilters.eq("pushStatus", 3));
subFilters.add(FieldFilters.eq("deleted", Boolean.FALSE));
QueryBuilder queryBuilder = recommendCasesQuery.addFilters(subFilters)
.addOrder("sysCreateTime", OrderDirection.DESC)
.addGroupBy("caseId");
List<CasesRecommendPushRecord> pushRecords = casesRecommendPushRecordDao.findList(queryBuilder.builder());
if (CollUtil.isNotEmpty(pushRecords)) {
List<String> rIds = pushRecords.stream().map(CasesRecommendPushRecord::getRecommendId).distinct().collect(Collectors.toList());
QueryBuilder builder = QueryBuilder.from(CasesRecommend.class);
builder.addField("new CasesRecommend(id,recommendOrgName)");
List<IFieldFilter> recommendFilters = new ArrayList<>();
recommendFilters.add(FieldFilters.eq("deleted", Boolean.FALSE));
recommendFilters.add(FieldFilters.in("id", rIds));
builder.addFilters(recommendFilters);
List<CasesRecommend> recommands = casesRecommendDao.findList(builder.builder());
if (CollUtil.isNotEmpty(recommands)) {
Map<String, String> collect = recommands.stream().collect(Collectors.toMap(k -> k.getId(), v -> v.getRecommendOrgName()));
casesList.forEach(it -> {
CasesRecommendPushRecord one = CollUtil.findOne(pushRecords, (a) -> StrUtil.equals(a.getCaseId(), it.getId()));
if (Objects.nonNull(one)) {
String recommendOrgName = collect.get(one.getRecommendId());
it.setBreCommend(1);
it.setRecommendOrgName(recommendOrgName);
} else {
it.setBreCommend(0);
}
});
}
}
addAuthorTagAndCaseNewTag(casesList);
}
return casesList;
}
@Override
public List<CasesQueryRecommendRankVo> queryRecommendRank() {
QueryBuilder queryBuilder = QueryBuilder.from(Cases.class);
queryBuilder.setPageSize(10);
queryBuilder.addFilter(FieldFilters.eq("deleted",false));
queryBuilder.addFilter(FieldFilters.isNotNull("recommend_rank"));
queryBuilder.addOrder(OrderCondition.asc("recommend_rank"));
List<Cases> recommendRank = casesDao.findList(queryBuilder.builder());
List<CasesQueryRecommendRankVo> collect = recommendRank.stream().map(e -> {
CasesQueryRecommendRankVo casesQueryRecommendRankVo = new CasesQueryRecommendRankVo();
casesQueryRecommendRankVo.setCaseId(e.getId());
casesQueryRecommendRankVo.setCaseTitle(e.getTitle());
casesQueryRecommendRankVo.setCaseAuthor(e.getAuthorName());
casesQueryRecommendRankVo.setRecommendRankPushUserName(e.getRecommendRankPushUserName());
casesQueryRecommendRankVo.setRecommendRankPusTime(e.getRecommendRankPushTime());
return casesQueryRecommendRankVo;
}).collect(Collectors.toList());
return collect;
}
@Override
public void riseIntoRank(Long caseId, CurrentUser currentUser) {
Cases caseOfNewRise = casesDao.findOne(FieldFilters.eq("id", String.valueOf(caseId)),FieldFilters.isNull("recommend_rank"),FieldFilters.eq("deleted",false));
if (caseOfNewRise == null) {
log.error("案例不存在或已经在榜,不可上榜", caseId);
return;
}
int count = casesDao.sqlCount("select count(1) from boe_cases where deleted=0 and recommend_rank is not null order by recommend_rank asc limit 10");
if (count == 10){
log.error("已满10条无法添加");
throw new RuntimeException("已满10条无法添加");
}
caseOfNewRise.setRecommendRank(count);
caseOfNewRise.setRecommendRankPushUserName(currentUser.getLoginName());
caseOfNewRise.setRecommendRankPushTime(LocalDateTime.now());
casesDao.update(caseOfNewRise);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelRiseIntoRank(Long caseId) {
Cases caseOfCancelRise = casesDao.findOne(FieldFilters.eq("id", String.valueOf(caseId)),FieldFilters.isNotNull("recommend_rank"),FieldFilters.eq("deleted",false));
if (caseOfCancelRise == null) {
log.error("案例不存在或已经在榜,不可下榜", caseId);
return;
}
QueryBuilder queryBuilder = QueryBuilder.from(Cases.class);
queryBuilder.setPageSize(10);
queryBuilder.addFilter(FieldFilters.eq("deleted",false));
queryBuilder.addOrder(OrderCondition.asc("recommend_rank"));
queryBuilder.addFilter(FieldFilters.gt("recommend_rank",caseOfCancelRise.getRecommendRank()));
List<Cases> recommendRank = casesDao.findList(queryBuilder.builder());
if (CollectionUtils.isEmpty(recommendRank)){
return;
}
// 更新排序
for (int i = caseOfCancelRise.getRecommendRank(); i < recommendRank.size(); i++){
Integer currentSort = recommendRank.get(i).getRecommendRank();
recommendRank.get(i).setRecommendRank(currentSort - 1);
casesDao.update(recommendRank.get(i));
}
// 取消排序
caseOfCancelRise.setRecommendRank(null);
caseOfCancelRise.setRecommendRankPushTime(null);
caseOfCancelRise.setRecommendRankPushUserName(null);
casesDao.update(caseOfCancelRise);
}
@Override
public void adjustRank(List<Long> caseIdList) {
QueryBuilder queryBuilder = QueryBuilder.from(Cases.class);
queryBuilder.setPageSize(10);
queryBuilder.addFilter(FieldFilters.eq("deleted",false));
queryBuilder.addFilter(FieldFilters.isNotNull("recommend_rank"));
queryBuilder.addOrder(OrderCondition.asc("recommend_rank"));
List<Cases> recommendRank = casesDao.findList(queryBuilder.builder());
// 遍历排序后的案例列表,并根据 caseIdList 设置或重置 recommendRank
recommendRank.forEach(caseItem -> {
int index = caseIdList.indexOf(Long.valueOf(caseItem.getId()));
// 如果 ID 存在于 caseIdList 中,则设置推荐等级为该 ID 的索引位置,否则设置为 null
if (index != -1) {
caseItem.setRecommendRank(index);
} else {
caseItem.setRecommendRank(null);
caseItem.setRecommendRankPushTime(null);
caseItem.setRecommendRankPushUserName(null);
}
});
// 保存对案例排序的更改
recommendRank.forEach(casesDao::update);
}
}

View File

@@ -0,0 +1,12 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
@Data
public class CaseRankingVo {
private String caseId;
private String caseTitle;
}

View File

@@ -0,0 +1,34 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CasesQueryRecommendRankVo {
/**
* 案例id
*/
private String caseId;
/**
* 案例标题
*/
private String caseTitle;
private String caseAuthor;
/**
* 推送用户名称
*/
private String recommendRankPushUserName;
/**
* 推送时间
*/
private LocalDateTime recommendRankPusTime;
}