Merge remote-tracking branch '104/master' into 104-master

This commit is contained in:
nisen
2024-09-18 11:00:56 +08:00
20 changed files with 1358 additions and 198 deletions

View File

@@ -12,12 +12,14 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.system.ApplicationPid; import org.springframework.boot.system.ApplicationPid;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration @Configuration
@SpringBootApplication @SpringBootApplication
@EnableCaching @EnableCaching
@EnableAsync @EnableAsync
@EnableRetry @EnableRetry
@EnableScheduling
public class BoeServerAllApplication { public class BoeServerAllApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@@ -16,6 +16,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -231,5 +234,38 @@ public class ThirdApi {
} }
/**
* 获取案例浏览记录
*/
public UserDynamicResult getAllUserdynamicListOfCaseRead(UserdynamicParam userdynamicParam, String token) {
String s = buildFormData(userdynamicParam);
String resp = Optional.ofNullable(HttpRequest
.post(userdynamicListUrl)
.header("Content-Type", "application/x-www-form-urlencoded")
.body(s)
.header("XBOE-Access-Token", token)
.execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
DynamicBean dynamicBean = JSONUtil.toBean(resp, DynamicBean.class);
UserDynamicResult userdynamicResult = dynamicBean.getResult();
return userdynamicResult;
}
private String buildFormData(UserdynamicParam param) {
StringBuilder builder = new StringBuilder();
try {
builder.append("pageIndex=").append(URLEncoder.encode(param.getPageIndex().toString(), "UTF-8"));
builder.append("&pageSize=").append(URLEncoder.encode(param.getPageSize().toString(), "UTF-8"));
builder.append("&contentType=").append(URLEncoder.encode(param.getContentType().toString(), "UTF-8"));
builder.append("&aid=").append(URLEncoder.encode(param.getAid().toString(), "UTF-8"));
builder.append("&eventKey=").append(URLEncoder.encode("ReadCase", "UTF-8"));
if (param.getHidden() != null) {
builder.append("&hidden=").append(URLEncoder.encode(param.getHidden(), "UTF-8"));
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return builder.toString();
}
} }

View File

@@ -135,4 +135,24 @@ public interface CacheName {
String KEY_DICT="dict"; String KEY_DICT="dict";
String STUDY_KEY = "StudyKey:"; String STUDY_KEY = "StudyKey:";
/**
* 季度观看量排行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,26 @@
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

@@ -0,0 +1,29 @@
package com.xboe.module.boecase.api;
import com.xboe.module.boecase.service.ICasesService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class CaseScheduledTasks {
@Resource
private ICasesService casesService;
@Scheduled(cron = "0 0 1 1 * ?") // 每月的第一天的1:00执行
public void refreshViewsRankOfMajor() {
casesService.refreshViewsRankOfMajor();
}
/**
* 季初执行cron表达式设置为每个季度的第一个月的第一天的特定时间。每个季度的第一个月是1月、4月、7月和10月
*/
@Scheduled(cron = "0 0 2 1 1,4,7,10 ?")
public void refreshLastQuarterStatistics() {
casesService.refreshLastQuarterStatistics();
}
}

View File

@@ -11,18 +11,14 @@ import com.xboe.module.boecase.dao.CasesMajorTypeDao;
import com.xboe.module.boecase.dto.*; import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.CasesMajorType; import com.xboe.module.boecase.entity.CasesMajorType;
import com.xboe.module.boecase.service.ICasesRecommendPushRecordService; import com.xboe.module.boecase.service.ICasesRecommendPushRecordService;
import com.xboe.module.boecase.vo.CaseExportVo; import com.xboe.module.boecase.vo.*;
import com.xboe.module.dict.entity.DictItem; import com.xboe.module.dict.entity.DictItem;
import com.xboe.module.excel.ExportsExcelSenderUtil; import com.xboe.module.excel.ExportsExcelSenderUtil;
import com.xboe.system.user.dao.UserDao; import com.xboe.system.user.dao.UserDao;
import com.xboe.system.user.entity.User; import com.xboe.system.user.entity.User;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
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 cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
@@ -39,6 +35,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -127,25 +124,12 @@ public class CasesApi extends ApiBaseController {
@PostMapping("/queryListV2") @PostMapping("/queryListV2")
public JsonResponse<PageList<Cases>> queryCaseBreV2(@Validated @RequestBody CasePageVo req) { public JsonResponse<PageList<Cases>> queryCaseBreV2(@Validated @RequestBody CasePageVo req) {
String type = req.getType(); String type = req.getType();
PageList<Cases> subViews1;
PageList<Cases> subViews2;
PageList<Cases> views = null;
req.setUserId(getCurrent().getAccountId()); req.setUserId(getCurrent().getAccountId());
if (StringUtils.isNotEmpty(type)) { PageList<Cases> views = null;
if ("recommend".equals(type)) { if (type.equals("recommend")) {
views = casesService.queryRecommendPageCasesV2(req); views = casesService.queryRecommendPageCasesV2(req);
} else {
views = casesService.queryPageCasesV2(req);
}
} else { } else {
PageDto pageDto = new PageDto(); views = casesService.queryPageCasesV2(req);
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);
} }
if (views != null) { if (views != null) {
@@ -175,24 +159,6 @@ public class CasesApi extends ApiBaseController {
return success(views); 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") @PostMapping("/caseYears")
public JsonResponse<List<String>> caseYears() { public JsonResponse<List<String>> caseYears() {
List<String> result = casesService.getCaseYears(); List<String> result = casesService.getCaseYears();
@@ -646,7 +612,8 @@ public class CasesApi extends ApiBaseController {
if (ids.isEmpty()) { if (ids.isEmpty()) {
return badRequest("参数异常"); return badRequest("参数异常");
} }
List<Cases> cases = casesService.ids(ids); String accountId = getCurrent().getAccountId();
List<Cases> cases = casesService.ids(ids,accountId);
return success(cases); return success(cases);
} }
@@ -654,7 +621,7 @@ public class CasesApi extends ApiBaseController {
* 设置/取消优秀案例 * 设置/取消优秀案例
*/ */
@PostMapping("/excellent") @PostMapping("/excellent")
public JsonResponse<Boolean> excellent(String id, Boolean excellent) { public JsonResponse<Boolean> excellent(String id, Boolean excellent,String excellentReason) {
if (StringUtil.isBlank(id)) { if (StringUtil.isBlank(id)) {
return badRequest("参数异常"); return badRequest("参数异常");
} }
@@ -662,12 +629,145 @@ public class CasesApi extends ApiBaseController {
excellent = false;//默认设置取消 excellent = false;//默认设置取消
} }
try { try {
casesService.excellent(id, excellent); casesService.excellent(id, excellent,excellentReason);
return success(true); return success(true);
} catch (Exception e) { } catch (Exception e) {
return error("设置或者取消失败", e.getMessage()); return error("设置或者取消失败", e.getMessage());
} }
} }
/**
* 不同专业分类下排行榜刷新
* 注意定时统计任务是在本月月初执行的而上榜时间是在上个月最后一天23:59:59
*/
@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 String majorId,
@RequestParam LocalDateTime rankMonth) {
String accountId = getCurrent().getAccountId();
List<Cases> caseRankingVoList =casesService.queryPopularityOfMajor(pageSize,majorId,rankMonth,accountId);
return success(caseRankingVoList);
}
/**
* 所有上榜的的(专业ID-时间), 用于下拉框.优化可将majorName一并查询返回为List<List<Entity>> todo by anyone
*/
@GetMapping("/queryAllTimePopularityOfMajor")
public JsonResponse<Map<String, List<String>>> queryAllTimePopularityOfMajor() {
Map<String, List<String>> time = casesService.queryAllTimePopularityOfMajor();
return success(time);
}
/**
* 查询推荐案例榜单
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryRecommendRank")
public JsonResponse<List<CasesQueryRecommendRankVo>> queryRecommendRank(@RequestParam(required = false,defaultValue = "3") Integer pageSize) {
List<CasesQueryRecommendRankVo> list = casesService.queryRecommendRank(pageSize);
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);
}
/**
* 查询收藏
* @param pageIndex
* @param pageSize
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/queryFavoriteCaseOfIndex")
public JsonResponse<PageList<FavoriteCaseOfIndexVo>> queryFavoriteCaseOfIndex(@RequestParam(required = false,defaultValue = "1") Integer pageIndex,
@RequestParam(required = false,defaultValue = "5") Integer pageSize) {
String accountId = this.getCurrent().getAccountId();
PageList<FavoriteCaseOfIndexVo> casesList = casesService.queryFavoriteCaseOfIndex(pageIndex,pageSize,accountId);
return success(casesList);
}
@GetMapping("/browsingHistory")
public JsonResponse<PageList<CasesBrowsingHistoryVo>> browsingHistory(@RequestParam(required = false,defaultValue = "1") Integer pageIndex,
@RequestParam(required = false,defaultValue = "5") Integer pageSize,
HttpServletRequest request) {
String accountId = this.getCurrent().getAccountId();
PageList<CasesBrowsingHistoryVo> casesList = casesService.browsingHistory(pageIndex,pageSize,accountId,request);
return success(casesList);
}
} }

View File

@@ -1,18 +1,24 @@
package com.xboe.module.boecase.dao; package com.xboe.module.boecase.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.xboe.common.OrderCondition; import com.xboe.common.OrderCondition;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.core.orm.BaseDao; import com.xboe.core.orm.BaseDao;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.IFieldFilter; import com.xboe.core.orm.IFieldFilter;
import com.xboe.module.boecase.entity.Cases; import com.xboe.module.boecase.entity.Cases;
import com.xboe.core.orm.FieldFilters; import com.xboe.module.boecase.vo.CaseRankingVo;
import com.xboe.module.boecase.dto.CaseVo; 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 @Repository
@Slf4j
public class CasesDao extends BaseDao<Cases> { public class CasesDao extends BaseDao<Cases> {
/** /**
@@ -35,4 +41,106 @@ public class CasesDao extends BaseDao<Cases> {
public Cases getByTitle(String title) { public Cases getByTitle(String title) {
return this.getGenericDao().findOne(Cases.class, FieldFilters.eq("title", 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_quarter_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_quarter_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,bcvr.major_id \n" +
"FROM\n" +
" boe_cases_rank bcvr\n" +
"JOIN boe_dict_major_type bdmt \n" +
" ON bdmt.code = 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.setRiseRankTime(((Timestamp) o[1]).toLocalDateTime());
casesRank.setRank(Integer.valueOf(o[2].toString()));
casesRank.setMajorId(o[3].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<HashMap<String, Object>> findPopularityOfMajor(Integer pageSize, LocalDateTime startTime, LocalDateTime endTime, String majorId) {
String sql =
"SELECT bcr.case_id,bcr.rank\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);
List<HashMap<String, Object>> collect = listFields.stream().map(item -> {
HashMap<String, Object> map = new HashMap<>();
map.put("caseId", item[0].toString());
map.put("rank", item[1].toString());
return map;
}).collect(Collectors.toList());
return collect;
}
}

View File

@@ -21,50 +21,79 @@ import java.util.List;
*/ */
@Repository @Repository
public interface CasesRecordDao extends JpaRepository<Cases, String>, JpaSpecificationExecutor<Cases> { public interface CasesRecordDao extends JpaRepository<Cases, String>, JpaSpecificationExecutor<Cases> {
@Query(nativeQuery = true, value = "select c.* from ( select b.*" + @Query(nativeQuery = true, value =
" from boe_cases_recommend_push_record a left JOIN boe_cases b on a.case_id = b.id" + " SELECT c.* FROM ( " +
" where b.deleted=0 and a.push_status = 3 and a.deleted=0 and a.push_user_id= :#{#condition.userId}" + " SELECT b.*,a.sys_create_time as recommendPushTime" +
" and if(IFNULL(:#{#condition.keyWord},'')!='',b.title like CONCAT('%',:#{#condition.keyWord},'%')" + " FROM boe_cases_recommend_push_record a " +
" or b.author_name like CONCAT('%',:#{#condition.keyWord},'%')" + " LEFT JOIN boe_cases b ON a.case_id = b.id " +
" or b.keyword1 like CONCAT('%',:#{#condition.keyWord},'%')" + " WHERE b.deleted = 0 " +
" or b.keyword2 like CONCAT('%',:#{#condition.keyWord},'%')" + " AND a.push_status = 3 " +
" or b.keyword3 like CONCAT('%',:#{#condition.keyWord},'%')" + " AND a.deleted = 0 " +
" or b.keyword4 like CONCAT('%',:#{#condition.keyWord},'%')" + " AND a.push_user_id = :#{#condition.userId} " +
" or b.keyword5 like CONCAT('%',:#{#condition.keyWord},'%'),1=1)" + " AND IF(IFNULL(:#{#condition.keyWord}, '') != '', " +
" and if(:#{#condition.yearsEmpty},1=1, YEAR(b.sys_create_time) in (:#{#condition.years}))" + " b.title LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" and if(:#{#condition.caseIdsEmpty}, 1=1, b.id in (:#{#condition.caseIds}))" + " OR b.author_name LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" and ("+ " OR b.keyword1 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" if(:#{#condition.allOrgEmpty}, 1=1, 1=2)" + " OR b.keyword2 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" or if(:#{#condition.org1Empty}, 1=2, b.org_domain_parent in (:#{#condition.org1}))" + " OR b.keyword3 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" or if(:#{#condition.org2Empty}, 1=2, b.org_domain_parent2 in (:#{#condition.org2}))" + " OR b.keyword4 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" or if(:#{#condition.org3Empty}, 1=2, b.org_domain_parent3 in (:#{#condition.org3}))" + " OR b.keyword5 LIKE CONCAT('%', :#{#condition.keyWord}, '%'), " +
")" + " 1 = 1) " +
" and if(:#{#condition.isSysType1Empty} , 1=1, b.sys_type1 = :#{#condition.sysType1} )"+ " AND IF(:#{#condition.yearsEmpty}, 1 = 1, YEAR(b.sys_create_time) IN (:#{#condition.years})) " +
" and if(:#{#condition.isSysType2Empty} , 1=1, b.sys_type2 = :#{#condition.sysType2} )"+ " AND IF(:#{#condition.caseIdsEmpty}, 1 = 1, b.id IN (:#{#condition.caseIds})) " +
" and if(:#{#condition.isSysType3Empty} , 1=1, b.sys_type3 = :#{#condition.sysType3} )"+ " AND ( " +
" order by a.sys_create_time DESC, a.read_flag ASC) as c group by c.id", " IF(:#{#condition.allOrgEmpty}, 1 = 1, 1 = 2) " +
countQuery = "select count(*) FROM (select c.* from ( select b.*" + " OR IF(:#{#condition.org1Empty}, 1 = 2, b.org_domain_parent IN (:#{#condition.org1})) " +
" from boe_cases_recommend_push_record a left JOIN boe_cases b on a.case_id = b.id " + " OR IF(:#{#condition.org2Empty}, 1 = 2, b.org_domain_parent2 IN (:#{#condition.org2})) " +
" where b.deleted=0 and a.push_status = 3 and a.deleted=0 and a.push_user_id= :#{#condition.userId}" + " OR IF(:#{#condition.org3Empty}, 1 = 2, b.org_domain_parent3 IN (:#{#condition.org3})) " +
" and if(IFNULL(:#{#condition.keyWord},'')!='',b.title like CONCAT('%',:#{#condition.keyWord},'%')" + " ) " +
" or b.author_name like CONCAT('%',:#{#condition.keyWord},'%')" + " AND IF(:#{#condition.isSysType1Empty}, 1 = 1, b.sys_type1 = :#{#condition.sysType1}) " +
" or b.keyword1 like CONCAT('%',:#{#condition.keyWord},'%')" + " AND IF(:#{#condition.isSysType2Empty}, 1 = 1, b.sys_type2 = :#{#condition.sysType2}) " +
" or b.keyword2 like CONCAT('%',:#{#condition.keyWord},'%')" + " AND IF(:#{#condition.isSysType3Empty}, 1 = 1, b.sys_type3 = :#{#condition.sysType3}) " +
" or b.keyword3 like CONCAT('%',:#{#condition.keyWord},'%')" + " ) AS c GROUP BY c.id " +
" or b.keyword4 like CONCAT('%',:#{#condition.keyWord},'%')" + " ORDER BY " +
" or b.keyword5 like CONCAT('%',:#{#condition.keyWord},'%'),1=1)" + " IF(:#{#condition.orderField}='views' and :#{#condition.orderAsc}=true,c.views, null) asc," +
" and if(:#{#condition.yearsEmpty},1=1, YEAR(b.sys_create_time) in (:#{#condition.years}))" + " IF(:#{#condition.orderField}='views' and :#{#condition.orderAsc}=false,c.views, null) desc," +
" and if(:#{#condition.caseIdsEmpty}, 1=1, b.id in (:#{#condition.caseIds}))" + " IF(:#{#condition.orderField}='sysCreateTime' and :#{#condition.orderAsc}=true ,c.sys_create_time,null) asc," +
" and ("+ " IF(:#{#condition.orderField}='sysCreateTime' and :#{#condition.orderAsc}=false , c.sys_create_time,null) desc," +
" if(:#{#condition.allOrgEmpty}, 1=1, 1=2)" + " IF(:#{#condition.orderField}='recommendPushTime', c.recommendPushTime,null) desc",
" or if(:#{#condition.org1Empty}, 1=1, b.org_domain_parent in (:#{#condition.org1}))" + countQuery =
" or if(:#{#condition.org2Empty}, 1=1, b.org_domain_parent2 in (:#{#condition.org2}))" + " SELECT count(*) FROM ( " +
" or if(:#{#condition.org3Empty}, 1=1, b.org_domain_parent3 in (:#{#condition.org3}))" + " SELECT b.*,a.sys_create_time as recommendPushTime" +
")" + " FROM boe_cases_recommend_push_record a " +
" and if(:#{#condition.isSysType1Empty} , 1=1, b.sys_type1 = :#{#condition.sysType1} )"+ " LEFT JOIN boe_cases b ON a.case_id = b.id " +
" and if(:#{#condition.isSysType2Empty} , 1=1, b.sys_type2 = :#{#condition.sysType2} )"+ " WHERE b.deleted = 0 " +
" and if(:#{#condition.isSysType3Empty} , 1=1, b.sys_type3 = :#{#condition.sysType3} )"+ " AND a.push_status = 3 " +
" order by a.sys_create_time DESC, a.read_flag ASC ) as c group by c.id) as d") " AND a.deleted = 0 " +
" AND a.push_user_id = :#{#condition.userId} " +
" AND IF(IFNULL(:#{#condition.keyWord}, '') != '', " +
" b.title LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.author_name LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.keyword1 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.keyword2 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.keyword3 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.keyword4 LIKE CONCAT('%', :#{#condition.keyWord}, '%') " +
" OR b.keyword5 LIKE CONCAT('%', :#{#condition.keyWord}, '%'), " +
" 1 = 1) " +
" AND IF(:#{#condition.yearsEmpty}, 1 = 1, YEAR(b.sys_create_time) IN (:#{#condition.years})) " +
" AND IF(:#{#condition.caseIdsEmpty}, 1 = 1, b.id IN (:#{#condition.caseIds})) " +
" AND ( " +
" IF(:#{#condition.allOrgEmpty}, 1 = 1, 1 = 2) " +
" OR IF(:#{#condition.org1Empty}, 1 = 2, b.org_domain_parent IN (:#{#condition.org1})) " +
" OR IF(:#{#condition.org2Empty}, 1 = 2, b.org_domain_parent2 IN (:#{#condition.org2})) " +
" OR IF(:#{#condition.org3Empty}, 1 = 2, b.org_domain_parent3 IN (:#{#condition.org3})) " +
" ) " +
" AND IF(:#{#condition.isSysType1Empty}, 1 = 1, b.sys_type1 = :#{#condition.sysType1}) " +
" AND IF(:#{#condition.isSysType2Empty}, 1 = 1, b.sys_type2 = :#{#condition.sysType2}) " +
" AND IF(:#{#condition.isSysType3Empty}, 1 = 1, b.sys_type3 = :#{#condition.sysType3}) " +
" ) AS c GROUP BY c.id " +
" ORDER BY " +
" IF(:#{#condition.orderField}='views' and :#{#condition.orderAsc}=true,c.views, null) asc," +
" IF(:#{#condition.orderField}='views' and :#{#condition.orderAsc}=false,c.views, null) desc," +
" IF(:#{#condition.orderField}='sysCreateTime' and :#{#condition.orderAsc}=true ,c.sys_create_time,null) asc," +
" IF(:#{#condition.orderField}='sysCreateTime' and :#{#condition.orderAsc}=false , c.sys_create_time,null) desc," +
" IF(:#{#condition.orderField}='recommendPushTime', c.recommendPushTime,null) desc"
)
Page<Cases> queryList(Pageable pageable, @Param("condition") CasePageVo casePage); Page<Cases> queryList(Pageable pageable, @Param("condition") CasePageVo casePage);

View File

@@ -3,6 +3,7 @@ package com.xboe.module.boecase.entity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant; import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity; import com.xboe.core.orm.BaseEntity;
import com.xboe.module.boecase.vo.CaseViewRankingItemVo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -248,16 +249,7 @@ public class Cases extends BaseEntity {
@Column(name = "case_value") @Column(name = "case_value")
private String caseValue; 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 +264,48 @@ public class Cases extends BaseEntity {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime excellentTime; private LocalDateTime excellentTime;
/**
* 最佳时间
* */
@Column(name = "excellent_reason")
private String excellentReason;
/**
* 上月浏览量
*/
@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 种类 * type 种类
* 区分 案例/推荐案例 * 区分 案例/推荐案例
@@ -279,11 +313,6 @@ public class Cases extends BaseEntity {
@Transient @Transient
private String type; private String type;
/**
* id
*/
@Transient @Transient
private List<String> majorIds; private List<String> majorIds;
@@ -296,6 +325,15 @@ public class Cases extends BaseEntity {
@Transient @Transient
private String refId; private String refId;
@Transient
private String excellentTag;
@Transient
private List<CaseViewRankingItemVo> viewRankTags;
@Transient
private List<String> authorTags;
public String getRefId() { public String getRefId() {
return refId; return refId;
} }
@@ -380,7 +418,7 @@ public class Cases extends BaseEntity {
this.title=title; this.title=title;
} }
public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted
,String sysCreateBy,String sysCreateAid){ ,String sysCreateBy,String sysCreateAid){
this.title=title; this.title=title;
super.setId(id); super.setId(id);
this.authorId=authorId; this.authorId=authorId;
@@ -398,7 +436,6 @@ public class Cases extends BaseEntity {
this.favorites=favorites; this.favorites=favorites;
super.setDeleted(deleted); super.setDeleted(deleted);
} }
public Cases(String title) { public Cases(String title) {
this.title = title; this.title = title;
} }
@@ -415,4 +452,29 @@ public class Cases extends BaseEntity {
this.authorName = authorName; this.authorName = authorName;
this.confidentialityLevel = confidentialityLevel; this.confidentialityLevel = confidentialityLevel;
} }
public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted
,String sysCreateBy,String sysCreateAid,String keyword1,String keyword2,String keyword3,String keyword4,String keyword5){
this.title=title;
super.setId(id);
this.authorId=authorId;
this.authorName=authorName;
super.setSysCreateTime(sysCreateTime);
super.setSysCreateAid(sysCreateAid);
super.setSysCreateBy(sysCreateBy);
this.summary=summary;
this.coverUrl=coverUrl;
this.breCommend=breCommend;
this.views=views;
this.comments=comments;
this.praises=praises;
this.shares=shares;
this.favorites=favorites;
this.keyword1=keyword1;
this.keyword2=keyword2;
this.keyword3=keyword3;
this.keyword4=keyword4;
this.keyword5=keyword5;
super.setDeleted(deleted);
}
} }

View File

@@ -0,0 +1,61 @@
package com.xboe.module.boecase.entity;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
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
@NoArgsConstructor
@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 String majorId;
/**
* 排名
*/
@Column(name = "rank")
private Integer rank;
/**
* 浏览量每月增量
*/
@Column(name = "monthly_increment")
private Integer monthlyIncrement;
@Column(name = "rise_rank_time")
private LocalDateTime riseRankTime;
@Transient
private String majorName;
public CasesRank(String majorId, LocalDateTime riseRankTime) {
this.majorId = majorId;
this.riseRankTime = riseRankTime;
}
}

View File

@@ -54,8 +54,15 @@ public class CasesRecommend extends BaseEntity {
public CasesRecommend() { public CasesRecommend() {
} }
public CasesRecommend(String id, String recommendOrgName) { public CasesRecommend(String id, String recommendOrgName) {
this.setId(id); this.setId(id);
this.recommendOrgName = recommendOrgName; this.recommendOrgName = recommendOrgName;
} }
public CasesRecommend(String id, String recommendOrgName,LocalDateTime recommendTime) {
this.setId(id);
this.recommendOrgName = recommendOrgName;
this.recommendTime = recommendTime;
}
} }

View File

@@ -1,14 +1,22 @@
package com.xboe.module.boecase.service; package com.xboe.module.boecase.service;
import java.util.List;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.core.CurrentUser; import com.xboe.core.CurrentUser;
import com.xboe.module.boecase.dto.*; import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.Cases; import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.vo.CasesBrowsingHistoryVo;
import com.xboe.module.boecase.vo.CaseRankingVo;
import com.xboe.module.boecase.vo.CasesQueryRecommendRankVo;
import com.xboe.module.boecase.vo.FavoriteCaseOfIndexVo;
import com.xboe.module.dict.entity.DictItem; import com.xboe.module.dict.entity.DictItem;
import com.xboe.school.vo.CasesVo; import com.xboe.school.vo.CasesVo;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface ICasesService{ public interface ICasesService{
/** /**
* 案例分页搜索,是否被推荐 * 案例分页搜索,是否被推荐
@@ -91,7 +99,7 @@ public interface ICasesService{
/** /**
* 用于二次查询 * 用于二次查询
* */ * */
List<Cases> ids(List<String> ids); List<Cases> ids(List<String> ids, String accountId);
/** /**
*二期 首页的推荐案例 *二期 首页的推荐案例
@@ -101,7 +109,7 @@ public interface ICasesService{
/** /**
* 设置或者取消优秀案例 * 设置或者取消优秀案例
* */ * */
void excellent(String id,Boolean excellent); void excellent(String id, Boolean excellent, String excellentReason);
PageList<Cases> queryRecommendPageCasesV2(CasePageVo req); PageList<Cases> queryRecommendPageCasesV2(CasePageVo req);
@@ -110,5 +118,27 @@ public interface ICasesService{
List<String> getCaseYears(); List<String> getCaseYears();
@Transactional
void refreshViewsRankOfMajor();
void refreshLastQuarterStatistics();
List<CasesQueryRecommendRankVo> queryRecommendRank(Integer pageSize);
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, String majorId, LocalDateTime month, String accountId);
PageList<FavoriteCaseOfIndexVo> queryFavoriteCaseOfIndex(Integer pageIndex, Integer pageSize, String accountId);
PageList<CasesBrowsingHistoryVo> browsingHistory(Integer pageIndex, Integer pageSize, String accountId, HttpServletRequest request);
Map<String, List<String>> queryAllTimePopularityOfMajor();
} }

View File

@@ -2,8 +2,14 @@ package com.xboe.module.boecase.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.xboe.api.ThirdApi;
import com.xboe.api.vo.UserDynamic;
import com.xboe.api.vo.UserDynamicResult;
import com.xboe.api.vo.UserdynamicParam;
import com.xboe.common.OrderCondition; import com.xboe.common.OrderCondition;
import com.xboe.common.OrderDirection; import com.xboe.common.OrderDirection;
import com.xboe.common.PageList; import com.xboe.common.PageList;
@@ -11,29 +17,40 @@ import com.xboe.common.utils.IDGenerator;
import com.xboe.common.utils.StringUtil; import com.xboe.common.utils.StringUtil;
import com.xboe.core.CurrentUser; import com.xboe.core.CurrentUser;
import com.xboe.core.orm.*; import com.xboe.core.orm.*;
import com.xboe.enums.CasesRankEnum;
import com.xboe.module.boecase.dao.*; import com.xboe.module.boecase.dao.*;
import com.xboe.module.boecase.dto.*; import com.xboe.module.boecase.dto.*;
import com.xboe.module.boecase.entity.Cases; import com.xboe.module.boecase.entity.*;
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.service.ICasesService; import com.xboe.module.boecase.service.ICasesService;
import com.xboe.module.boecase.vo.*;
import com.xboe.module.dict.dao.SysDictionaryDao; import com.xboe.module.dict.dao.SysDictionaryDao;
import com.xboe.module.dict.entity.DictItem; import com.xboe.module.dict.entity.DictItem;
import com.xboe.module.interaction.entity.Favorites;
import com.xboe.orm.CustomFieldInFilter; import com.xboe.orm.CustomFieldInFilter;
import com.xboe.school.vo.CasesVo; import com.xboe.school.vo.CasesVo;
import com.xboe.standard.enums.BoedxResourceType;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.transaction.Transactional; import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j @Slf4j
@Service @Service
@@ -61,6 +78,15 @@ public class CasesServiceImpl implements ICasesService {
@Autowired @Autowired
private CasesRecommendDao casesRecommendDao; private CasesRecommendDao casesRecommendDao;
@Resource
private CasesRankDao casesRankDao;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private ThirdApi thirdApi;
/** /**
* 案例分页查询,用于门户的查询 * 案例分页查询,用于门户的查询
*/ */
@@ -178,12 +204,6 @@ public class CasesServiceImpl implements ICasesService {
@Override @Override
public PageList<Cases> queryPageCasesV2(CasePageVo caseVo) { public PageList<Cases> queryPageCasesV2(CasePageVo caseVo) {
String type = caseVo.getType();
if (!StrUtil.equals(type,"excellent")) {
caseVo.setOrderField("");
caseVo.setOrderAsc(null);
}
String keyword = caseVo.getKeyWord(); String keyword = caseVo.getKeyWord();
QueryBuilder query = QueryBuilder.from(Cases.class); QueryBuilder query = QueryBuilder.from(Cases.class);
PageList<Cases> page = null; PageList<Cases> page = null;
@@ -296,18 +316,16 @@ public class CasesServiceImpl implements ICasesService {
filters.add(FieldFilters.eq("excellent", caseVo.getExcellent())); filters.add(FieldFilters.eq("excellent", caseVo.getExcellent()));
} }
OrderCondition order = null; OrderCondition order = null;
if (StringUtils.isNotBlank(caseVo.getOrderField())) { if (StringUtils.isNotBlank(caseVo.getOrderField()) && caseVo.getOrderAsc() != null && ("sysCreateTime".equals(caseVo.getOrderField()) || "views".equals(caseVo.getOrderField()))) {
if (caseVo.getOrderAsc() == null || caseVo.getOrderAsc()) { if (caseVo.getOrderAsc()) {
order = OrderCondition.asc(caseVo.getOrderField()); order = OrderCondition.asc(caseVo.getOrderField());
} else { } else {
order = OrderCondition.desc(caseVo.getOrderField()); order = OrderCondition.desc(caseVo.getOrderField());
} }
} } else {
if (StrUtil.equals(type,"new")) {
order = OrderCondition.desc("sysCreateTime"); order = OrderCondition.desc("sysCreateTime");
} else if (StrUtil.equals(type,"hot")) {
order = OrderCondition.desc("views");
} }
if(Objects.nonNull(order)) { if(Objects.nonNull(order)) {
query.addOrder(order); query.addOrder(order);
} }
@@ -315,53 +333,18 @@ public class CasesServiceImpl implements ICasesService {
query.setPageIndex(caseVo.getPageIndex()); query.setPageIndex(caseVo.getPageIndex());
query.setPageSize(caseVo.getPageSize()); query.setPageSize(caseVo.getPageSize());
page = casesDao.findPage(query.builder()); page = casesDao.findPage(query.builder());
List<Cases> list = page.getList(); List<Cases> casesList = page.getList();
list.forEach(it->{ casesList.forEach(it->{
it.setBreCommend(0); it.setBreCommend(0);
}); });
if (CollUtil.isNotEmpty(list) && StrUtil.isNotBlank(caseVo.getUserId())) { casesList = caseListCommonHandle(casesList, caseVo.getUserId());
List<String> caseIds = list.stream().map(Cases::getId).collect(Collectors.toList()); page.setList(casesList);
QueryBuilder recommendCasesQuery = QueryBuilder.from(CasesRecommendPushRecord.class);
recommendCasesQuery.addField("new CasesRecommendPushRecord(id,recommendId,caseId)");
List<IFieldFilter> subFilters = new ArrayList<>();
subFilters.add(FieldFilters.eq("pushUserId", caseVo.getUserId()));
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()));
list.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);
}
});
}
}
}
return page; return page;
} }
@Override @Override
public PageList<Cases> queryRecommendPageCasesV2(CasePageVo caseVo) { public PageList<Cases> queryRecommendPageCasesV2(CasePageVo caseVo) {
@@ -408,37 +391,68 @@ public class CasesServiceImpl implements ICasesService {
caseVo.setOrg2(level2); caseVo.setOrg2(level2);
caseVo.setOrg3(level3); caseVo.setOrg3(level3);
Set<String> validOrderFields = new HashSet<>();
validOrderFields.add("sysCreateTime");
validOrderFields.add("views");
validOrderFields.add("recommendPushTime");
if (StringUtils.isBlank(caseVo.getOrderField()) || caseVo.getOrderAsc() == null || !validOrderFields.contains(caseVo.getOrderField())) {
caseVo.setOrderField("recommendPushTime");
caseVo.setOrderAsc(false);
}
Page<Cases> cases = casesRecordDao.queryList(pageRequest,caseVo); Page<Cases> cases = casesRecordDao.queryList(pageRequest,caseVo);
PageList<Cases> pageList = new PageList<>(); PageList<Cases> pageList = new PageList<>();
pageList.setCount((int) cases.getTotalElements()); pageList.setCount((int) cases.getTotalElements());
pageList.setPageSize(cases.getSize()); pageList.setPageSize(cases.getSize());
List<Cases> content = cases.getContent(); List<Cases> content = cases.getContent();
List<String> caseIds = content.stream().map(Cases::getId).collect(Collectors.toList());
String userId = caseVo.getUserId();
if (CollUtil.isNotEmpty(caseIds)) {
QueryBuilder recommendCasesQuery = QueryBuilder.from(CasesRecommendPushRecord.class);
recommendCasesQuery.addField("new CasesRecommendPushRecord(id,recommendId,caseId)");
List<IFieldFilter> subFilters = new ArrayList<>();
subFilters.add(FieldFilters.eq("pushUserId", userId));
subFilters.add(FieldFilters.in("caseId", caseIds));
subFilters.add(FieldFilters.eq("pushStatus", 3));
subFilters.add(FieldFilters.eq("deleted", Boolean.FALSE));
QueryBuilder queryBuilder = recommendCasesQuery.addFilters(subFilters) caseListCommonHandle(content, caseVo.getUserId());
pageList.setList(content);
return pageList;
}
private List<Cases> caseListCommonHandle(List<Cases> casesList, String accountId) {
if (CollUtil.isEmpty(casesList)) {
return casesList;
}
//1.推荐案例数据处理
recommendCasesDataHandle(casesList, accountId);
//2.标签处理,添加作者标签和新的案例标签
addAuthorTagAndCaseNewTag(casesList);
return casesList;
}
private void recommendCasesDataHandle(List<Cases> casesList, String accountId) {
if (StrUtil.isNotBlank(accountId)) {
List<String> caseIdList = casesList.stream().map(Cases::getId).collect(Collectors.toList());
QueryBuilder queryBuilder = QueryBuilder.from(CasesRecommendPushRecord.class)
.addField("new CasesRecommendPushRecord(id,recommendId,caseId)")
.addFilters(Arrays.asList(
FieldFilters.eq("pushUserId", accountId),
FieldFilters.in("caseId", caseIdList),
FieldFilters.eq("pushStatus", 3),
FieldFilters.eq("deleted", Boolean.FALSE)
))
.addOrder("sysCreateTime", OrderDirection.DESC) .addOrder("sysCreateTime", OrderDirection.DESC)
.addGroupBy("caseId"); .addGroupBy("caseId");
List<CasesRecommendPushRecord> pushRecords = casesRecommendPushRecordDao.findList(queryBuilder.builder()); List<CasesRecommendPushRecord> pushRecords = casesRecommendPushRecordDao.findList(queryBuilder.builder());
if (CollUtil.isNotEmpty(pushRecords)) { if (CollUtil.isNotEmpty(pushRecords)) {
List<String> rIds = pushRecords.stream().map(CasesRecommendPushRecord::getRecommendId).distinct().collect(Collectors.toList()); List<String> rIds = pushRecords.stream().map(CasesRecommendPushRecord::getRecommendId).distinct().collect(Collectors.toList());
QueryBuilder builder = QueryBuilder.from(CasesRecommend.class); QueryBuilder builder = QueryBuilder.from(CasesRecommend.class)
List<IFieldFilter> recommendFilters = new ArrayList<>(); .addField("new CasesRecommend(id,recommendOrgName,recommendTime)")
recommendFilters.add(FieldFilters.eq("deleted", Boolean.FALSE)); .addFilters(Arrays.asList(
recommendFilters.add(FieldFilters.in("id", rIds)); FieldFilters.eq("deleted", Boolean.FALSE),
builder.addFilters(recommendFilters); FieldFilters.in("id", rIds)
));
List<CasesRecommend> recommands = casesRecommendDao.findList(builder.builder()); List<CasesRecommend> recommands = casesRecommendDao.findList(builder.builder());
if (CollUtil.isNotEmpty(recommands)) { if (CollUtil.isNotEmpty(recommands)) {
Map<String, CasesRecommend> collect = recommands.stream().collect(Collectors.toMap(k -> k.getId(), item->item)); Map<String, CasesRecommend> collect = recommands.stream().collect(Collectors.toMap(k -> k.getId(), item -> item));
content.forEach(it -> { casesList.forEach(it -> {
CasesRecommendPushRecord one = CollUtil.findOne(pushRecords, (a) -> StrUtil.equals(a.getCaseId(), it.getId())); CasesRecommendPushRecord one = CollUtil.findOne(pushRecords, (a) -> StrUtil.equals(a.getCaseId(), it.getId()));
if (Objects.nonNull(one)) { if (Objects.nonNull(one)) {
CasesRecommend recommend = collect.get(one.getRecommendId()); CasesRecommend recommend = collect.get(one.getRecommendId());
@@ -446,13 +460,76 @@ public class CasesServiceImpl implements ICasesService {
it.setRefId(one.getId()); it.setRefId(one.getId());
it.setRecommendOrgName(recommend.getRecommendOrgName()); it.setRecommendOrgName(recommend.getRecommendOrgName());
it.setSysCreateTime(recommend.getRecommendTime()); it.setSysCreateTime(recommend.getRecommendTime());
} else {
it.setBreCommend(0);
} }
}); });
} }
} }
} }
pageList.setList(content); }
return pageList;
/**
* 添加案例标签、作者标签最佳案例N篇、上榜浏览量TOP榜单N次、案例标签xx分类浏览量TOP、最佳案例
*/
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<CaseViewRankingItemVo> viewRankTags = viewsRankRecords.stream().map(casesRank -> {
String pattern = casesRank.getRiseRankTime().getMonthValue() < 10 ? "yy年M月" : "yy年MM月";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
String time = casesRank.getRiseRankTime().format(formatter);
// 2023年6月 经营管理类 浏览量 TOP1
String viewRankTag = time + casesRank.getMajorName() + "类浏览量TOP" + (casesRank.getRank() + 1);
CaseViewRankingItemVo caseViewRankingItemVo = new CaseViewRankingItemVo();
caseViewRankingItemVo.setMajorId(String.valueOf(casesRank.getMajorId()));
caseViewRankingItemVo.setMajorName(casesRank.getMajorName());
caseViewRankingItemVo.setTagName(viewRankTag);
caseViewRankingItemVo.setRiseRankTime(casesRank.getRiseRankTime());
return caseViewRankingItemVo;
}).collect(Collectors.toList());
e.setViewRankTags(viewRankTags);
}
// 拼接生成年度最佳标签
if (e.getExcellent()!=null && e.getExcellent()) {
if (e.getDraftingTime()!=null){
e.setExcellentTag(e.getDraftingTime().format(DateTimeFormatter.ofPattern("yy年"))+"度最佳");
} else {
e.setExcellentTag(e.getSysCreateTime().format(DateTimeFormatter.ofPattern("yy年"))+"度最佳");
}
}
List<String> authorTags = new ArrayList<>();
if (excellentCountMap.get(e.getAuthorId())!=null){
String authorTagOfExcellent = excellentCountMap.get(e.getAuthorId()) + "篇最佳案例";
authorTags.add(authorTagOfExcellent);
}
if (viewTopCountMap.get(e.getAuthorId())!=null){
String authorTagOfView = "上榜浏览量TOP榜单" + viewTopCountMap.get(e.getAuthorId()) + "";
authorTags.add(authorTagOfView);
}
e.setAuthorTags(authorTags);
});
} }
public static void main(String[] args) { public static void main(String[] args) {
@@ -945,11 +1022,12 @@ public class CasesServiceImpl implements ICasesService {
} }
@Override @Override
public List<Cases> ids(List<String> ids) { public List<Cases> ids(List<String> ids, String accountId) {
QueryBuilder builder = QueryBuilder.from(Cases.class); QueryBuilder builder = QueryBuilder.from(Cases.class);
builder.addFilter(FieldFilters.in("id", ids)); builder.addFilter(FieldFilters.in("id", ids));
builder.addFields("new Cases(id,title,summary,coverUrl,authorId,authorName,sysCreateTime,breCommend,views,comments,praises,shares,favorites,deleted,sysCreateBy,sysCreateAid)"); builder.addFields("new Cases(id,title,summary,coverUrl,authorId,authorName,sysCreateTime,breCommend,views,comments,praises,shares,favorites,deleted,sysCreateBy,sysCreateAid,keyword1,keyword2,keyword3,keyword4,keyword5)");
List<Cases> cases = casesDao.findList(builder.builder()); List<Cases> cases = casesDao.findList(builder.builder());
cases = caseListCommonHandle(cases, accountId);
return cases; return cases;
} }
@@ -1078,15 +1156,362 @@ public class CasesServiceImpl implements ICasesService {
} }
@Override @Override
public void excellent(String id, Boolean excellent) { public void excellent(String id, Boolean excellent, String excellentReason) {
//取消时,把时间清空 //取消时,把时间清空
if (excellent) { 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 { } 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(){
log.info("开始执行每月案例浏览量相关定时任务");
// 获取上个月的第一天的00:00
// LocalDateTime firstDayOfLastMonth = LocalDateTime.now().minusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).toLocalDate().atStartOfDay();
// 获取上个月的最后一天的23:59:59,将其设置为上榜时间。注意定时统计任务是在本月月初执行的而上榜时间是在上个月最后一天23:59:59
LocalDateTime lastDayOfLastMonth = LocalDateTime.now().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().atTime(23, 59, 59); // 设置为当天的几乎结束时刻
int count = casesRankDao.sqlCount("SELECT count(1) FROM boe_cases_rank WHERE deleted=0 AND rise_rank_time = ?1" , lastDayOfLastMonth);
if (count > 0){
log.info("已生成上个月排行榜数据,本次不执行");
throw new RuntimeException("已生成上个月排行榜数据,请将上月排行榜数据删除");
}
//获取案例当月排名
// String sql =
// "SELECT bc.id,bcmt.major_id,bc.views - COALESCE(bc.last_month_views, 0) AS increment\n" +
// "FROM boe_cases bc\n" +
// "JOIN boe_cases_major_type bcmt ON bcmt.case_id = bc.id and bc.deleted=0 and file_path is not null and file_path!='' and bc.views - COALESCE(bc.last_month_views, 0)!=0";
String sql =
"SELECT bc.id,bcmt.major_id,bc.views AS increment\n" +
"FROM boe_cases bc\n" +
"JOIN boe_cases_major_type bcmt ON bcmt.case_id = bc.id and bc.deleted=0 and file_path is not null and file_path!='' and bc.views !=0 and bc.views is not null";
List<Object> caseListOfObject = casesDao.sqlFindList(sql);
// 转为casesRank
List<CasesRank> casesRankList = caseListOfObject.stream()
.map(o -> {
CasesRank casesRank = new CasesRank();
casesRank.setCaseId(Long.valueOf(Array.get(o, 0).toString()));
casesRank.setMajorId(Array.get(o, 1).toString());
casesRank.setMonthlyIncrement(Integer.parseInt(Array.get(o, 2).toString()));
casesRank.setRiseRankTime(lastDayOfLastMonth);
return casesRank;
}).collect(Collectors.toList());
// 根据专业分类进行分组
Map<String, 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);
// 重置上月观看量last_month_views
int i = casesDao.sqlUpdate("update boe_cases set last_month_views=views where deleted=0");
log.info("每月案例浏览量相关定时任务执行完成boe_cases更新数据量为条数为"+i);
log.info("每月案例浏览量相关定时任务执行完成boe_cases_rank添加数据量为条数为"+lastMonthRank.size());
} }
@Override
public void refreshLastQuarterStatistics() {
log.info("开始执行每季案例相关定时任务");
int i = casesDao.sqlUpdate("update boe_cases set last_quarter_views=views,last_quarter_praise=praise where deleted=0");
log.info("每季案例相关定时任务执行完成boe_cases更新数据量为条数为"+i);
}
@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()) {
// 格式如case:rank:praise:all3
cacheKey = enumValue.getCacheKey()+pageSize;
}
}
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, 600, TimeUnit.SECONDS);
return casesList;
}
return Collections.emptyList();
}
@Override
public List<Cases> queryPopularityOfMajor(Integer pageSize, String majorId, LocalDateTime month, String accountId) {
if (pageSize == null) {
pageSize = 10;
}
LocalDateTime startTime = month.withDayOfMonth(1);
LocalDateTime endTime = month.plusMonths(1).withDayOfMonth(1).withMinute(0);
List<HashMap<String, Object>> popularityOfMajor = casesRankDao.findPopularityOfMajor(pageSize, startTime, endTime, majorId);
List<String> caseIdList = popularityOfMajor.stream().map(map -> map.get("caseId").toString()).collect(Collectors.toList());
Map<Object, Integer> collect = popularityOfMajor.stream().collect(Collectors.toMap(map -> map.get("caseId").toString(), map -> Integer.valueOf(map.get("rank").toString())));
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());
casesList = caseListCommonHandle(casesList, accountId);
Collections.sort(casesList, new Comparator<Cases>() {
@Override
public int compare(Cases c1, Cases c2) {
Integer order1 = collect.get(c1.getId());
Integer order2 = collect.get(c2.getId());
return Integer.compare(order1, order2);
}
});
return casesList;
}
@Override
public List<CasesQueryRecommendRankVo> queryRecommendRank(Integer pageSize) {
QueryBuilder queryBuilder = QueryBuilder.from(Cases.class);
queryBuilder.setPageSize(pageSize);
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)){
// 更新排序
for (int i = 0; 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);
}
@Override
public PageList<FavoriteCaseOfIndexVo> queryFavoriteCaseOfIndex(Integer pageIndex, Integer pageSize, String accountId) {
String from = Favorites.class.getSimpleName()+" f,"+ Cases.class.getSimpleName()+" c";
QueryBuilder builder = QueryBuilder.from(from);
builder.addFields("f.id","f.sysCreateTime","c");
builder.addFilter(FieldFilters.eqField("f.objId","c.id"));
builder.addFilter(FieldFilters.eq("f.objType", BoedxResourceType.Case.value()));
builder.addFilter(FieldFilters.eq("f.sysCreateAid",accountId));
builder.addFilter(FieldFilters.eq("c.deleted", false));
builder.addOrder(OrderCondition.desc("f.sysCreateTime"));
builder.setPageIndex(pageIndex);
builder.setPageSize(pageSize);
PageList<Object[]> pageFields=null;
try {
pageFields = casesDao.findPageFields(builder.builder());
} catch (Exception e) {
log.error("收藏案例查询错误",e);
}
List<Object[]> list = pageFields.getList();
// 提取出 Cases 对象,添加标签
List<Cases> casesList = list.stream().map(o -> {
Cases cases = (Cases) o[2];
FavoriteCaseOfIndexVo favoriteCaseOfIndexVo = new FavoriteCaseOfIndexVo();
BeanUtils.copyProperties(cases, favoriteCaseOfIndexVo);
favoriteCaseOfIndexVo.setFavoriteId(o[0].toString());
favoriteCaseOfIndexVo.setFavoriteTime(LocalDateTime.parse(o[1].toString()));
return favoriteCaseOfIndexVo;
}).collect(Collectors.toList());
casesList = caseListCommonHandle(casesList, accountId);
List<FavoriteCaseOfIndexVo> collect = casesList.stream().map(cases -> (FavoriteCaseOfIndexVo) cases).collect(Collectors.toList());
PageList<FavoriteCaseOfIndexVo> favoriteCaseOfIndexVoPageList = new PageList<>();
favoriteCaseOfIndexVoPageList.setList(collect);
favoriteCaseOfIndexVoPageList.setPageSize(pageSize);
favoriteCaseOfIndexVoPageList.setCount(pageFields.getCount());
return favoriteCaseOfIndexVoPageList;
}
@Override
public PageList<CasesBrowsingHistoryVo> browsingHistory(Integer pageIndex, Integer pageSize, String accountId, HttpServletRequest request) {
UserdynamicParam userdynamicParam = new UserdynamicParam();
userdynamicParam.setPageIndex(pageIndex);
userdynamicParam.setPageSize(pageSize);
userdynamicParam.setContentType(3);
userdynamicParam.setAid(Long.valueOf(accountId));
userdynamicParam.setHidden("");
String token = request.getHeader("Xboe-Access-Token");
if (StringUtils.isEmpty(token)) {
token = request.getHeader("token");
}
// 获取案例浏览记录
UserDynamicResult userDynamicResult = thirdApi.getAllUserdynamicListOfCaseRead(userdynamicParam, token);
List<UserDynamic> allUserdynamicList = userDynamicResult.getList();
List<String> collect = allUserdynamicList.stream().map(UserDynamic::getContentId).distinct().collect(Collectors.toList());
// 查询案例信息
List<Cases> caseList = this.ids(collect, accountId);
Map<String, Cases> map = caseList.stream().collect(Collectors.toMap(Cases::getId, cases -> cases));
// 组合案例信息与浏览记录
List<CasesBrowsingHistoryVo> batchHistoryVoList = allUserdynamicList.stream().map(userDynamic -> {
CasesBrowsingHistoryVo browsingHistoryVo = new CasesBrowsingHistoryVo();
browsingHistoryVo.setBrowsingHistoryId(userDynamic.getId());
browsingHistoryVo.setContentInfo(userDynamic.getContentInfo());
browsingHistoryVo.setEventTime(userDynamic.getEventTime());
browsingHistoryVo.setContentId(userDynamic.getContentId());
if (map.containsKey(userDynamic.getContentId())){
// 重名属性如IDcopy会出现覆盖。
BeanUtils.copyProperties(map.get(userDynamic.getContentId()),browsingHistoryVo);
}
return browsingHistoryVo;
}).collect(Collectors.toList());
PageList<CasesBrowsingHistoryVo> pageList = new PageList<>();
pageList.setList(batchHistoryVoList);
pageList.setCount(userDynamicResult.getCount());
pageList.setPageSize(userDynamicResult.getPageSize());
return pageList;
}
@Override
public Map<String, List<String>> queryAllTimePopularityOfMajor() {
QueryBuilder builder = QueryBuilder.from(CasesRank.class);
builder.addField("new CasesRank(majorId,riseRankTime)");
builder.addFilter(FieldFilters.eq("deleted",false));
builder.addGroupBy("majorId");
builder.addGroupBy("riseRankTime");
List<CasesRank> list = casesRankDao.findList(builder.builder());
// 定义日期时间的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy-MM");
Map<String, List<String>> collect = list.stream().collect(Collectors.groupingBy
(CasesRank::getMajorId, Collectors.mapping(casesRank -> casesRank.getRiseRankTime().format(formatter), Collectors.toList())));
return collect;
}
} }

View File

@@ -0,0 +1,17 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
@Data
public class CaseRankingVo {
/**
* 案例id
*/
private String caseId;
/**
* 案例标题
*/
private String caseTitle;
}

View File

@@ -0,0 +1,29 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CaseViewRankingItemVo {
/**
* 分类id
*/
private String majorId;
/**
* 分类名称
*/
private String majorName;
/**
* 上榜时间目前默认为一月中的最后一天的23:59:59
*/
private LocalDateTime riseRankTime;
/**
* 标签名称
*/
private String tagName;
}

View File

@@ -0,0 +1,31 @@
package com.xboe.module.boecase.vo;
import com.xboe.module.boecase.entity.Cases;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CasesBrowsingHistoryVo extends Cases{
/**
* 浏览记录id
* */
private String browsingHistoryId;
/**
* 案例标题
* */
private String contentInfo;
/**
* 事件时间查看案例时有定时接口触发名为sendeventTime为该时间
* */
private LocalDateTime eventTime;
/**
* 案例ID
* */
private String contentId;
}

View File

@@ -0,0 +1,37 @@
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;
}

View File

@@ -0,0 +1,23 @@
package com.xboe.module.boecase.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.module.boecase.entity.Cases;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class FavoriteCaseOfIndexVo extends Cases{
/**
* 收藏id
*/
private String favoriteId;
/**
* 收藏时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime favoriteTime;
}

View File

@@ -12,6 +12,7 @@ public class FavoriteCaseDto {
private String id; private String id;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime time; private LocalDateTime time;
/** /**