This commit is contained in:
lims1@hunktimes.com
2023-08-01 16:02:57 +08:00
96 changed files with 4185 additions and 325 deletions

48
.gitignore vendored Normal file
View File

@@ -0,0 +1,48 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
**/.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml

32
README.md Normal file
View File

@@ -0,0 +1,32 @@
## 项目名称
> 请介绍一下你的项目吧
## 运行条件
> 列出运行该项目所必须的条件和相关依赖
* 条件一
* 条件二
* 条件三
## 运行说明
> 说明如何运行和使用你的项目,建议给出具体的步骤说明
* 操作一
* 操作二
* 操作三
## 测试说明
> 如果有测试相关内容需要说明,请填写在这里
## 技术架构
> 使用的技术框架或系统架构图等相关说明,请填写在这里
## 协作者
> 高效的协作会激发无尽的创造力,将他们的名字记录在这里吧

View File

@@ -2,6 +2,8 @@ package com.xboe.module.course.dto;
import lombok.Data;
import java.util.List;
/**
* 课程的全文检索索引
*
@@ -28,7 +30,6 @@ public class CourseFullText {
/**10无目录录播课20 有目录录播课30:面授课40学习项目*/
private Integer type;
/**多个时用到*/
private String types;
@@ -118,5 +119,11 @@ public class CourseFullText {
* 是否公开0表非公开报名1表公开报名-字段需新增,按管理端需求增加
*/
private Integer openEnroll;
/**
* keywords字段分割
*/
private List<String> keywordsList;
}

View File

@@ -3,11 +3,9 @@ package com.xboe.module.elasticsearc;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@@ -33,10 +31,7 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
@@ -410,6 +405,8 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
BoolQueryBuilder keywordQuery = QueryBuilders.boolQuery();
keywordQuery.should(QueryBuilders.wildcardQuery("name", "*"+words+"*").boost(9f));
keywordQuery.should(QueryBuilders.wildcardQuery("teacher", "*"+words+"*").boost(7f));
keywordQuery.should(QueryBuilders.queryStringQuery("*" + words + "*").field("keywords"));
keywordQuery.should(QueryBuilders.queryStringQuery(words).field("keywords"));
//keywordQuery.should(QueryBuilders.queryStringQuery(words).field("name", 9f));//用此方法无法查询出有转义符的处理
//keywordQuery.should(QueryBuilders.queryStringQuery(words).field("teacher", 8f));
@@ -426,8 +423,8 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
//// //其它是教师,教师也是 like查询 它只是2位权重
//// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("teacher", 5f));
//// //关键词查询
//// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("keywords", 3f));
////
// boolQuery.should(QueryBuilders.queryStringQuery(params.getKeywords()).field("keywords", 10f));
////
//// //boolQuery.should(QueryBuilders.fuzzyQuery("keywords",params.getKeywords()).boost(3f));
//// //分词查询权重是1默念
//// boolQuery.should(QueryBuilders.multiMatchQuery(params.getKeywords(),"summary"));
@@ -613,7 +610,7 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
}
//排序
if(StringUtils.isBlank(paras.getKeywords())) {
if(StringUtils.isBlank(paras.getKeywords()) && paras.getOrderType()!=3) {
sourceBuilder.sort("isTop",SortOrder.DESC);
//sourceBuilder.sort("topTime",SortOrder.DESC);
}
@@ -623,6 +620,9 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
}else if(paras.getOrderType()==2) {
sourceBuilder.sort("studies",SortOrder.DESC);
}
}else if (paras.getOrderType()==3){
sourceBuilder.sort("score",SortOrder.DESC);
}
}
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
@@ -637,10 +637,10 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
HighlightBuilder.Field nameHighlight=new HighlightBuilder.Field("name");
HighlightBuilder.Field summaryHighlight=new HighlightBuilder.Field("summary");
HighlightBuilder.Field teacherHighlight=new HighlightBuilder.Field("teacher");
HighlightBuilder.Field keywordsHighlight=new HighlightBuilder.Field("keywords");
// HighlightBuilder.Field keywordsHighlight=new HighlightBuilder.Field("keywords");
highlightBuilder.field(nameHighlight);
highlightBuilder.field(teacherHighlight);
highlightBuilder.field(keywordsHighlight);
// highlightBuilder.field(keywordsHighlight);
highlightBuilder.field(summaryHighlight);
@@ -663,7 +663,7 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
HighlightField name = highlightFields.get("name");
HighlightField summary = highlightFields.get("summary");
HighlightField teacher = highlightFields.get("teacher");
HighlightField keywords = highlightFields.get("keywords");
// HighlightField keywords = highlightFields.get("keywords");
String sourceAsString = hit.getSourceAsString();
try {
CourseFullText cft =mapper.readValue(sourceAsString, CourseFullText.class);
@@ -695,15 +695,15 @@ public class CourseElasticsearchImpl implements ICourseFullTextSearch{
}
cft.setTeacher(fmtStr.toString());
}
if(keywords!= null){
/*if(keywords!= null){
Text[] fragments = keywords.fragments();
StringBuffer fmtStr = new StringBuffer("");
for (Text fragment : fragments) {
fmtStr.append(fragment);
}
cft.setKeywords(fmtStr.toString());
}
}*/
list.add(cft);
}catch(Exception ee) {
log.error("转化json到对应失败");

View File

@@ -20,6 +20,7 @@
<module>boe-module-es</module>
<module>boe-module-idconfig</module>
<module>boe-module-savelog</module>
<module>boe-module-scorm</module>
</modules>
<dependencyManagement>
<dependencies>

View File

@@ -17,7 +17,7 @@
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
<nacos-client.version>2.2.0</nacos-client.version>
<nacos-client.version>2.2.0</nacos-client.version>
</properties>
<dependencies>
<!-- 引入Cloud -->
@@ -38,6 +38,11 @@
<version>${nacos-client.version}</version>
</dependency>
<!-- end -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<dependency>
<groupId>com.xboe</groupId>
<artifactId>xboe-api</artifactId>
@@ -68,13 +73,13 @@
<artifactId>xboe-module-idconfig</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.xboe</groupId>
<artifactId>xboe-module-es</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>jave</artifactId>
@@ -82,7 +87,7 @@
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/libs/jave-1.0.2.jar</systemPath>
</dependency>
<dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.3</version>
@@ -282,6 +287,12 @@
<profileActive>test</profileActive>
</properties>
</profile>
<profile>
<id>test135</id>
<properties>
<profileActive>test135</profileActive>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>

View File

@@ -4,7 +4,7 @@ import java.io.File;
import java.io.IOException;
import javax.annotation.PostConstruct;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.system.ApplicationPid;
@@ -14,6 +14,7 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@SpringBootApplication
@EnableCaching
@EnableAsync
public class BoeServerAllApplication {
public static void main(String[] args) {

View File

@@ -0,0 +1,86 @@
package com.xboe.api;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.xboe.api.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;
@Service
@Slf4j
public class ThirdApi {
public static final ForkJoinPool REQUEST_TASK = new ForkJoinPool(100);
@Value("${orgTree.orgChildTreeList}")
private String orgChildTreeListUrl;
@Value("${audience.usersByAudienceList}")
private String usersByAudienceList;
@Value("${userBasic.searchUserList}")
private String searchUserListUrl;
public List<UserInfoList> getAllUserList(UserListParam userListParam, String token) {
log.info("获取用户");
String resp = Optional.ofNullable(HttpRequest.post(searchUserListUrl).body(JSONUtil.toJsonStr(userListParam)).header("token", token).execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
log.info("获取用户返回值 {}",resp);
return Opt.ofBlankAble(resp).map(t -> JSONUtil.toBean(resp, UserInfoListRootBean.class).success())
.map(UserInfoListRootBean::getResult)
.map(result -> Opt.ofEmptyAble(result.getUserInfoList()).peek(t -> nextPage(userListParam, token, t, result)).orElse(ListUtil.toList()))
.orElse(ListUtil.toList());
}
private void getAllUserList(UserListParam userListParam, String token, List<UserInfoList> userInfoLists) {
log.info("获取用户2");
String resp = Optional.ofNullable(HttpRequest.post(searchUserListUrl).body(JSONUtil.toJsonStr(userListParam)).header("token", token).execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
log.info("获取用户返回值 {}",resp);
Opt.ofBlankAble(resp).map(t -> JSONUtil.toBean(t, UserInfoListRootBean.class).success()).map(UserInfoListRootBean::getResult).map(UserInfoListRootBean.ResultData::getUserInfoList).stream().flatMap(Collection::stream).forEach(userInfoLists::add);
}
private void nextPage(UserListParam userListParam, String token, List<UserInfoList> userInfoLists, UserInfoListRootBean.ResultData t) {
log.info("获取用户--" + userListParam.getPage());
if (t.getTotalPage() > userListParam.getPage()) {
REQUEST_TASK.submit(() -> IntStream.range(userListParam.getPage(), t.getTotalPage()).parallel().forEach(i -> getAllUserList(userListParam.withPage(i + 1), token, userInfoLists))).join();
}
}
public List<OrgRootBean.ResultData> getOrgChildTree(String id, String token) {
log.info("getOrgChildTree");
String resp = Optional.ofNullable(HttpRequest.post(orgChildTreeListUrl).header("token", token).body(JSONUtil.toJsonStr(TreeSearchVo.builder().orgId(id).build())).execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
return Opt.ofNullable(JSONUtil.toBean(resp, OrgRootBean.class).success()).map(OrgRootBean::getResult).orElse(ListUtil.empty());
}
public List<AuditList> getAllAudienceList(AuditListParam userListParam, String token) {
String resp = Optional.ofNullable(HttpRequest.post(usersByAudienceList).body(JSONUtil.toJsonStr(userListParam)).header("token", token).execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
return Opt.ofBlankAble(resp).map(t -> JSONUtil.toBean(resp, AuditRootBean.class).success())
.map(AuditRootBean::getResult)
.map(result -> Opt.ofEmptyAble(result.getList()).peek(t -> nextPage(userListParam, t, result, token)).orElse(ListUtil.toList()))
.orElse(ListUtil.toList());
}
private void nextPage(AuditListParam userListParam, List<AuditList> t, Result result, String token) {
if (result.getTotalPage() > userListParam.getPage()) {
REQUEST_TASK.submit(() -> IntStream.range(userListParam.getPage(), result.getTotalPage()).parallel().forEach(i -> getAllAudienceList(userListParam.withPage(i + 1), t, token))).join();
}
}
private void getAllAudienceList(AuditListParam userListParam, List<AuditList> list, String token) {
String resp = Optional.ofNullable(HttpRequest.post(usersByAudienceList).body(JSONUtil.toJsonStr(userListParam)).header("token", token).execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
Opt.ofBlankAble(resp).map(t -> JSONUtil.toBean(t, AuditRootBean.class).success()).map(AuditRootBean::getResult).map(Result::getList).stream().flatMap(Collection::stream).forEach(list::add);
}
}

View File

@@ -0,0 +1,24 @@
package com.xboe.api.vo; /**
* Copyright 2022 bejson.com
*/
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Auto-generated: 2022-12-10 14:3:18
*
* @author bejson.com (i@bejson.com)
* @website http://www.bejson.com/java2pojo/
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AuditList {
private long audienceId;
private long userId;
private long id;
}

View File

@@ -0,0 +1,14 @@
package com.xboe.api.vo;
import lombok.*;
@Data
@Builder
@With
@NoArgsConstructor
@AllArgsConstructor
public class AuditListParam implements Cloneable {
private String audienceId;
private Integer page;
private Integer pageSize;
}

View File

@@ -0,0 +1,41 @@
package com.xboe.api.vo; /**
* Copyright 2022 bejson.com
*/
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* Auto-generated: 2022-12-10 14:3:18
*
* @author bejson.com (i@bejson.com)
* @website http://www.bejson.com/java2pojo/
*/
@Data
@Slf4j
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AuditRootBean {
private String error;
private String message;
private String permissions;
private Result result;
private int status;
private Date timestamp;
public AuditRootBean success() {
if (this.status != 200) {
log.error("获取受众列表失败----{}", JSONUtil.toJsonPrettyStr(this));
return null;
}
return this;
}
}

View File

@@ -0,0 +1,63 @@
package com.xboe.api.vo;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
@Data
@Slf4j
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgRootBean {
private String error;
private String message;
private String permissions;
private List<ResultData> result;
private int status;
private Date timestamp;
public OrgRootBean success() {
if (this.status != 200) {
log.error("获取组织列表失败----{}", JSONUtil.toJsonPrettyStr(this));
return null;
}
return this;
}
@Data
public static class ResultData {
private String id;
private String parentId;
private String oldKid;
private String oldParentId;
private String name;
private String code;
private String namePath;
private int level;
private int status;
private String description;
private boolean isMakeOrg;
private boolean isServiceSite;
private String managerId;
private String hrbpId;
private Date createTime;
private String createBy;
private String oldOrgId;
private String oldOrgParentId;
private String companyId;
private String sassId;
private String orgRepository;
private String orgFactory;
private String directChildList;
private List<Result> treeChildList;
}
}

View File

@@ -0,0 +1,27 @@
package com.xboe.api.vo; /**
* Copyright 2022 bejson.com
*/
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Auto-generated: 2022-12-10 14:3:18
*
* @author bejson.com (i@bejson.com)
* @website http://www.bejson.com/java2pojo/
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private int totalElement;
private int totalPage;
private List<AuditList> list;
}

View File

@@ -0,0 +1,15 @@
package com.xboe.api.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TreeSearchVo {
private String keyword;
private String orgId;
}

View File

@@ -0,0 +1,40 @@
package com.xboe.api.vo;
import lombok.Data;
@Data
public class UserInfoList {
private long id;
private String bandCode;
private String bandDesc;
private Boolean deleted;
private Long departId;
private String description;
private String domainId;
private String departName;
private String duty;
private int employeeStatus;
private String companyId;
private String orgName;
private Integer gender;
private String jobName;
private String kid;
private int learningDuration;
private String mobile;
private String realName;
private String oldDepartId;
private String orgNamePath;
private String orgTreeType;
private String payrollPlaceId;
private String payrollPlaceName;
private long personId;
private String positionMgrLevel;
private String rank;
private long sassId;
private int status;
private String telephoneNo;
private String userNo;
private String email;
private String avatar;
}

View File

@@ -0,0 +1,37 @@
package com.xboe.api.vo;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
@Data
@Slf4j
public class UserInfoListRootBean {
private String error;
private String message;
private String permissions;
private ResultData result;
private int status;
private Date timestamp;
public UserInfoListRootBean success() {
if (this.status != 200) {
log.error("获取学员列表失败----{}", JSONUtil.toJsonPrettyStr(this));
return null;
}
return this;
}
@Data
public static class ResultData {
private int totalElement;
private int totalPage;
private List<UserInfoList> userInfoList;
}
}

View File

@@ -0,0 +1,19 @@
package com.xboe.api.vo;
import lombok.*;
@Data
@Builder
@With
@NoArgsConstructor
@AllArgsConstructor
public class UserListParam {
private String id;
private String departId;
private String userNo;
private String realName;
@Builder.Default
private int page = 1;
@Builder.Default
private int pageSize = 10;
}

View File

@@ -0,0 +1,35 @@
package com.xboe.data.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author : civism
* @version 1.0
* @date 2023/6/23 17:32
*/
@Data
public class ImportData {
private String importId;
private List<String> caseIdList;
private List<CasesTitle> caseTitleList;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class CasesTitle {
private String caseId;
private String caseTitle;
}
}

View File

@@ -0,0 +1,40 @@
package com.xboe.enums;
/**
* @author : civism
* @version 1.0
* @date 2023/6/17 16:13
*/
public enum CasesPushStatusEnum {
/**
* 推送状态1未推送2推送中3已推送4推送失败5已撤回
*/
WAIT_PUSH(1,"未推送"),
PUSH_ING(2,"推送中"),
PUSH_SUCCESS(3,"已推送"),
PUSH_FAIL(4,"推送失败"),
PUSH_REVOKE(5,"已撤回"),
;
CasesPushStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
private Integer status;
private String desc;
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,35 @@
package com.xboe.enums;
/**
* @author : civism
* @version 1.0
* @date 2023/6/17 16:22
*/
public enum CasesRecommendLaunchTypeEnum {
/**
* 发起类型 1 正常选择 2 文件导入
*/
COMMON(1, "正常选择"),
IMPORT(2, "文件导入"),
;
private Integer launchType;
private String desc;
CasesRecommendLaunchTypeEnum(Integer launchType, String desc) {
this.launchType = launchType;
this.desc = desc;
}
public Integer getLaunchType() {
return launchType;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,22 @@
package com.xboe.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* excellent 最佳案例
* recommend 推荐
*/
@AllArgsConstructor
@Getter
public enum CasesSearchTypeEnum {
excellent("excellent","最佳案例"),
recommend("recommend","推荐"),
;
private String type;
private String name;
}

View File

@@ -6,7 +6,6 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import com.xboe.core.orm.FieldFilters;
import com.xboe.module.boecase.dao.CasesMajorTypeDao;
@@ -16,13 +15,14 @@ import com.xboe.module.boecase.vo.CaseExportVo;
import com.xboe.module.dict.entity.DictItem;
import com.xboe.module.excel.ExportsExcelSenderUtil;
import org.apache.commons.lang3.StringUtils;
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 cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.xboe.common.PageList;
import com.xboe.common.Pagination;
import com.xboe.common.utils.StringUtil;
@@ -35,9 +35,16 @@ import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.service.ICasesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
/**
* 案例
*
*/
@Slf4j
@RestController
@@ -111,6 +118,43 @@ public class CasesApi extends ApiBaseController {
}
return success(views);
}
@PostMapping("/queryListV2")
public JsonResponse<PageList<Cases>> queryCaseBreV2(@Validated @RequestBody CasePageVo req){
String type = req.getType();
PageList<Cases> views;
req.setUserId(getCurrent().getAccountId());
if (type.equals("recommend")) {
log.info("queryListV2 recommend userId:{}", getCurrent().getAccountId());
views = casesService.queryRecommendPageCasesV2(req);
} else {
views = casesService.queryPageCasesV2(req);
}
if(views!=null){
List<Cases> cases = views.getList();
if(CollUtil.isNotEmpty(cases)){
for (Cases c: cases) {
StringBuffer stringBuffer = new StringBuffer();
List<CasesMajorType> caseId = casesMajorTypeDao.findList(FieldFilters.eq("caseId", c.getId()));
if(caseId!=null && !caseId.isEmpty()){
for (CasesMajorType cm:caseId) {
stringBuffer.append(cm.getMajorId());
stringBuffer.append(",");
}
}
if(stringBuffer.length()>0){
stringBuffer.deleteCharAt(stringBuffer.length()-1);
c.setMajorType(stringBuffer.toString());
}
}
}
}
return success(views);
}
/**
* 案例分页搜索 是否置顶
* */
@@ -139,6 +183,84 @@ public class CasesApi extends ApiBaseController {
return success(casesPageList);
}
/**
* 导出案例数据
* */
@PostMapping("/exportCase")
public void exportCase(Pagination pager, CaseVo caseVo,HttpServletResponse response){
OutputStream OutputStream=null;
try {
OutputStream = response.getOutputStream();
LinkedHashMap<String,String> map = new LinkedHashMap<>();
map.put("标题","title");
map.put("密级","confidentialityLevel");
map.put("浏览量","views");
map.put("推荐量","recommends");
map.put("引用量","cites");
map.put("点赞量","praises");
map.put("评论量","comments");
map.put("分享量","shares");
map.put("收藏量","favorites");
map.put("导出时间","exportDate");
map.put("作者","authorName");
List<Cases> list = casesService.exportCase(caseVo);
List<CaseExportVo> exportVos = new ArrayList<>();
LocalDateTime now = LocalDateTime.now();
for (Cases c:list){
CaseExportVo caseExportVo = new CaseExportVo();
caseExportVo.setTitle(c.getTitle());
caseExportVo.setConfidentialityLevel(c.getConfidentialityLevel());
caseExportVo.setViews(c.getViews());
caseExportVo.setRecommends(c.getRecommends1());
caseExportVo.setCites(c.getCites());
caseExportVo.setPraises(c.getPraises());
caseExportVo.setComments(c.getComments());
caseExportVo.setShares(c.getShares());
caseExportVo.setFavorites(c.getFavorites());
caseExportVo.setExportDate(now);
caseExportVo.setAuthorName(c.getAuthorName());
exportVos.add(caseExportVo);
}
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=cases.xls");
ExportsExcelSenderUtil.export(map,exportVos, OutputStream,"yyyy-MM-dd HH:mm:ss");
}catch (Exception e){
log.error("导出失败",e.getMessage());
}
}
/**
* 导出案例标题数据
* */
@PostMapping("/exportCaseTitle")
public void exportCaseTitle(CaseVo caseVo,HttpServletResponse response){
OutputStream outputStream;
try {
outputStream = response.getOutputStream();
LinkedHashMap<String,String> map = new LinkedHashMap<>();
map.put("标题","title");
List<Cases> list = casesService.managerCaseTitleList(caseVo);
List<CaseExportVo> exportVos = new ArrayList<>();
LocalDateTime now = LocalDateTime.now();
for (Cases c:list){
CaseExportVo caseExportVo = new CaseExportVo();
caseExportVo.setTitle(c.getTitle());
exportVos.add(caseExportVo);
}
response.setContentType("application/octet-stream");
String current = LocalDateTimeUtil.format(now,"yyyyMMddHHmmss");
response.setHeader("Content-disposition", "attachment;filename=cases-title-"+current+".xls");
ExportsExcelSenderUtil.export(map,exportVos, outputStream,"yyyy-MM-dd HH:mm:ss");
}catch (Exception e){
log.error("导出失败",e.getMessage());
}
}
/**
* 导出我的案例
* */

View File

@@ -0,0 +1,291 @@
package com.xboe.module.boecase.api;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xboe.common.PageList;
import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController;
import com.xboe.data.dto.ImportData;
import com.xboe.enums.CasesRecommendLaunchTypeEnum;
import com.xboe.module.boecase.dto.CasesRecommendPushRecordExportVo;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImport;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.module.boecase.service.ICasesBrowseService;
import com.xboe.module.boecase.service.ICasesRecommendLaunchImportService;
import com.xboe.module.boecase.service.ICasesRecommendPushRecordService;
import com.xboe.module.boecase.service.ICasesRecommendService;
import com.xboe.module.boecase.vo.BrowseDurationVo;
import com.xboe.module.boecase.vo.CasesRecommendLaunchVo;
import com.xboe.module.boecase.vo.CasesRecommendPushVo;
import com.xboe.module.boecase.vo.CasesRecommendVo;
import com.xboe.module.excel.ExportsExcelSenderUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 案例推荐表
*/
@Slf4j
@RestController
@RequestMapping(value = "xboe/m/boe/cases/recommend")
public class CasesRecommendApi extends ApiBaseController {
@Resource
private ICasesRecommendService iCasesRecommendService;
@Resource
private ICasesRecommendLaunchImportService iCasesRecommendLaunchImportService;
@Resource
private ICasesRecommendPushRecordService iCasesRecommendPushRecordService;
@Resource
private ICasesBrowseService casesBrowseService;
/**
* 用于后台管理分页
*
* @param casesRecommendVo
* @return
*/
@PostMapping("/page")
public JsonResponse<PageList<CasesRecommend>> page(@RequestBody CasesRecommendVo casesRecommendVo) {
PageList<CasesRecommend> page = iCasesRecommendService.page(casesRecommendVo.getPageIndex(), casesRecommendVo.getPageSize(), casesRecommendVo);
// 组装查看率
page.getList().forEach(it -> {
List<CasesRecommendPushRecord> recordList = iCasesRecommendPushRecordService.findAllByRecommendId(it.getId());
if (CollectionUtil.isNotEmpty(recordList)) {
List<CasesRecommendPushRecord> collect = recordList.stream().filter(casesRecommendPushRecord -> casesRecommendPushRecord.getReadFlag().equals(1)).collect(Collectors.toList());
// 查看率:查看率=案例查看人数(各案例查看人数之合)/(当条推荐记录包含的案例 × 用户数)
it.setViewRate(String.valueOf(collect.size() * 100 / recordList.size()).concat("%"));
}
});
return success(page);
}
@GetMapping("/delete")
public JsonResponse<Boolean> delete(String id) {
if (StringUtils.isBlank(id)) {
return badRequest("缺少必要参数");
}
try {
iCasesRecommendService.delete(id);
return success(true);
} catch (Exception e) {
log.error("删除失败", e);
return error("删除失败", e.getMessage());
}
}
/**
* 获取导入纪录
*
* @return
* @throws Exception
*/
@GetMapping("/import-info")
public JsonResponse<CasesRecommendLaunchImport> excelImport(String importId) {
CasesRecommendLaunchImport byId = iCasesRecommendLaunchImportService.getByImportId(importId);
return success(byId);
}
/**
* 导入
*
* @param file
* @return
* @throws Exception
*/
@PostMapping("/import")
public JsonResponse<ImportData> excelImport(@RequestParam("file") MultipartFile file) throws Exception {
ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
List<List<Object>> read = reader.read();
ImportData importData = iCasesRecommendLaunchImportService.importData(read);
return success(importData);
}
/**
* 下载错误数据
*
* @return
* @throws Exception
*/
@PostMapping("/download-template")
public void downloadTemplate(HttpServletResponse response) throws Exception {
// 通过工具类创建writer默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
writer.writeHeadRow(ListUtil.toList("标题"));
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=failData.xls");
ServletOutputStream out = response.getOutputStream();
writer.flush(out, true);
writer.close();
IoUtil.close(out);
}
/**
* 下载错误数据
*
* @return
* @throws Exception
*/
@GetMapping("/download")
public void download(String importId, HttpServletResponse response) throws Exception {
List<String> dataList = iCasesRecommendLaunchImportService.downFailData(importId);
// 通过工具类创建writer默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
writer.writeHeadRow(ListUtil.toList("标题"));
if (CollectionUtil.isNotEmpty(dataList)) {
writer.write(dataList);
}
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=failData.xls");
ServletOutputStream out = response.getOutputStream();
writer.flush(out, true);
writer.close();
IoUtil.close(out);
}
@GetMapping("/startRead")
public JsonResponse<Boolean> startRead(String caseRecommendId) {
return success(iCasesRecommendPushRecordService.startRead(caseRecommendId));
}
// @GetMapping("/endRead")
// public JsonResponse<Boolean> endRead(String caseRecommendId) {
// return success(iCasesRecommendPushRecordService.startRead(caseRecommendId));
// }
/**
* 发起推送
*
* @param casesRecommendLaunch
* @return
*/
@PostMapping("/launch")
public JsonResponse<Boolean> launch(@RequestBody CasesRecommendLaunchVo casesRecommendLaunch, HttpServletRequest request) {
if (!CasesRecommendLaunchTypeEnum.COMMON.getLaunchType().equals(casesRecommendLaunch.getLaunchType()) && !CasesRecommendLaunchTypeEnum.IMPORT.getLaunchType().equals(casesRecommendLaunch.getLaunchType())) {
throw new RuntimeException("参数错误");
}
if (CasesRecommendLaunchTypeEnum.COMMON.getLaunchType().equals(casesRecommendLaunch.getLaunchType()) && CollectionUtil.isEmpty(casesRecommendLaunch.getCasesIdList())) {
throw new RuntimeException("推送案例id不能为空");
} else if (CasesRecommendLaunchTypeEnum.IMPORT.getLaunchType().equals(casesRecommendLaunch.getLaunchType()) && StrUtil.isEmpty(casesRecommendLaunch.getImportId())) {
throw new RuntimeException("导入id不能为空");
}
String token = request.getHeader("Xboe-Access-Token");
if (StringUtils.isEmpty(token)) {
token = request.getHeader("token");
}
return success(iCasesRecommendPushRecordService.launchPush(casesRecommendLaunch, getCurrent(), token));
}
/**
* 信息下载
*
* @return
* @throws Exception
*/
@PostMapping("/info_download")
public void infoDownload(@RequestBody CasesRecommendVo vo, HttpServletResponse response) {
if (StringUtils.isEmpty(vo.getCasesRecommendId())) {
throw new RuntimeException("缺少必要参数");
}
try (OutputStream outputStream = response.getOutputStream()) {
// 用个List<Map>装表格的所有内容
// 拼接上列明。我这里用的最土的方法,很不优雅别学我
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("案例名称", "caseTitle");
map.put("推送用户", "pushUserName");
map.put("所属组织", "recommendOrgName");
map.put("推送时间", "pushTime");
map.put("是否查看", "readFlag");
map.put("首次查看时间", "readStartTime");
map.put("总查看时间", "totalReadTime");
CasesRecommend casesRecommend = iCasesRecommendService.findById(vo.getCasesRecommendId());
// 拿取表格里需要的数据
List<CasesRecommendPushRecord> recordList = iCasesRecommendPushRecordService.findAllByRecommendId(vo.getCasesRecommendId());
List<CasesRecommendPushRecordExportVo> exportVos = new ArrayList<>();
if (CollectionUtil.isNotEmpty(recordList)) {
exportVos = recordList.stream().map(record -> {
CasesRecommendPushRecordExportVo exportVo = new CasesRecommendPushRecordExportVo();
exportVo.setCaseTitle(record.getCaseTitle());
exportVo.setPushUserName(record.getPushUserName());
exportVo.setRecommendOrgName(casesRecommend.getRecommendOrgName());
exportVo.setPushTime(DateUtil.formatDateTime(record.getPushTime()));
exportVo.setReadFlag(record.getReadFlag() == 1 ? "" : "");
exportVo.setReadStartTime(DateUtil.formatDateTime(record.getReadStartTime()));
Long browseDuration = casesBrowseService.getBrowseDuration(record.getCaseId(), getCurrent().getAccountId());
exportVo.setTotalReadTime(browseDuration.toString());
return exportVo;
}).collect(Collectors.toList());
}
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=casesRecommend.xls");
ExportsExcelSenderUtil.export(map, exportVos, outputStream, "yyyy-MM-dd HH:mm:ss");
} catch (Exception e) {
e.printStackTrace();
log.error("导出失败", e.getMessage());
}
}
/**
* 重新推送或撤回
*
* @param casesRecommendPushVo
* @return
*/
@PostMapping("/rePushOrWithdraw")
public JsonResponse<Boolean> rePushOrWithdraw(@RequestBody CasesRecommendPushVo casesRecommendPushVo) {
if (StringUtils.isEmpty(casesRecommendPushVo.getCasesRecommendId())) {
throw new RuntimeException("缺少必要参数");
}
iCasesRecommendService.rePushOrWithdraw(casesRecommendPushVo, getCurrent().getAccountId());
return success(true);
}
@PostMapping("/recordBrowseDuration")
public JsonResponse<Boolean> recordBrowseDuration(@RequestBody BrowseDurationVo browseDuration) {
casesBrowseService.recordBrowseDuration(browseDuration.getCaseId(), getCurrent().getAccountId(), browseDuration.getBrowseDuration());
return success(true);
}
}

View File

@@ -29,26 +29,28 @@ public class RecommendApi extends ApiBaseController {
@Resource
private IRecommendService recommendService;
/**
* 推荐
* */
*/
@PostMapping("/save")
@AutoLog(module = "案例推荐",action = "推荐案例",info = "推荐案例")
public JsonResponse<Boolean> save(String id, AcceptVo acceptVo){
if(StringUtil.isBlank(id)){
@AutoLog(module = "案例推荐", action = "推荐案例", info = "推荐案例")
public JsonResponse<Boolean> save(String id, AcceptVo acceptVo) {
if (StringUtil.isBlank(id)) {
return badRequest("缺少案例id");
}
try {
recommendService.save(id,acceptVo);
recommendService.save(id, acceptVo);
return success(true);
} catch (Exception e) {
log.error("推荐失败",e);
return error("推荐失败",e.getMessage());
log.error("推荐失败", e);
return error("推荐失败", e.getMessage());
}
}
/**
* 推荐列表
* */
*/
@GetMapping("/query")
public JsonResponse<List<Recommend>> selectRecommend(){
List<Recommend> recommends = recommendService.selectRecommend();

View File

@@ -0,0 +1,14 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesBrowse;
import org.springframework.stereotype.Repository;
/**
* @author : civism
* @version 1.0
* @date 2023/7/4 16:32
*/
@Repository
public class CasesBrowseDao extends BaseDao<CasesBrowse> {
}

View File

@@ -9,24 +9,30 @@ import com.xboe.common.PageList;
import com.xboe.core.orm.BaseDao;
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;
@Repository
public class CasesDao extends BaseDao<Cases> {
/**
* 案例列表分页
* */
public PageList<Cases> queryPageCases(int pageIndex, int pageSize, String keyWord,OrderCondition order, List<IFieldFilter> filters){
*/
public PageList<Cases> queryPageCases(int pageIndex, int pageSize, String keyWord, OrderCondition order, List<IFieldFilter> filters) {
PageList<Cases> page = this.getGenericDao().findPage(pageIndex, pageSize, getEntityClass(), filters, order);
return page;
}
/**
* 案例列表置顶分页*
* */
public PageList<Cases> queryPageIsTop(int pageIndex,int pageSize,String keyWord,OrderCondition order,List<IFieldFilter> filters){
*/
public PageList<Cases> queryPageIsTop(int pageIndex, int pageSize, String keyWord, OrderCondition order, List<IFieldFilter> filters) {
PageList<Cases> page = this.getGenericDao().findPage(pageIndex, pageSize, getEntityClass(), filters, order);
return page;
}
public Cases getByTitle(String title) {
return this.getGenericDao().findOne(Cases.class, FieldFilters.eq("title", title));
}
}

View File

@@ -0,0 +1,16 @@
package com.xboe.module.boecase.dao;
import com.xboe.module.boecase.entity.CasesMajorType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CasesMajorTypeRepoDao extends JpaRepository<CasesMajorType, String>, JpaSpecificationExecutor<CasesMajorType> {
@Query(nativeQuery = true, value = "select * from boe_cases_major_type as c where major_id in (:marjorIds) group by c.case_id")
List<CasesMajorType> findCasesBy(List<String> marjorIds);
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRecommend;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendDao extends BaseDao<CasesRecommend> {
}

View File

@@ -0,0 +1,9 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImport;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendLaunchImportDao extends BaseDao<CasesRecommendLaunchImport> {
}

View File

@@ -0,0 +1,9 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImportData;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendLaunchImportDataDao extends BaseDao<CasesRecommendLaunchImportData> {
}

View File

@@ -0,0 +1,9 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendPushRecordDao extends BaseDao<CasesRecommendPushRecord> {
}

View File

@@ -0,0 +1,78 @@
package com.xboe.module.boecase.dao;
import com.xboe.module.boecase.dto.CasePageVo;
import com.xboe.module.boecase.dto.CaseVo;
import com.xboe.module.boecase.entity.Cases;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import javax.persistence.SqlResultSetMapping;
import java.util.List;
/**
* @author : civism
* @version 1.0
* @date 2023/6/20 18:55
*/
@Repository
public interface CasesRecordDao extends JpaRepository<Cases, String>, JpaSpecificationExecutor<Cases> {
@Query(nativeQuery = true, value = "select c.* from ( select b.*" +
" from boe_cases_recommend_push_record a INNER JOIN boe_cases b on a.case_id = b.id" +
" where b.deleted=0 and a.push_status = 3 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(IFNULL(:#{#condition.majorType},'') !='',b.major_type = :#{#condition.majorType},1=1) " +
" and if(:#{#condition.org1Empty}, 1=1, b.org_domain_parent in (:#{#condition.org1}))" +
" and if(:#{#condition.org2Empty}, 1=1, b.org_domain_parent2 in (:#{#condition.org2}))" +
" and if(:#{#condition.org3Empty}, 1=1, b.org_domain_parent3 in (:#{#condition.org3}))" +
" order by a.sys_create_time DESC, a.read_flag ASC) as c group by c.id",
countQuery = "select count(*) FROM (select c.* from ( select b.*" +
" from boe_cases_recommend_push_record a INNER JOIN boe_cases b on a.case_id = b.id " +
" where b.deleted=0 and a.push_status = 3 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(IFNULL(:#{#condition.majorType},'') !='' ,b.major_type = :#{#condition.majorType},1=1) " +
" and if(:#{#condition.org1Empty}, 1=1, b.org_domain_parent in (:#{#condition.org1}))" +
" and if(:#{#condition.org2Empty}, 1=1, b.org_domain_parent2 in (:#{#condition.org2}))" +
" and if(:#{#condition.org3Empty}, 1=1, b.org_domain_parent3 in (:#{#condition.org3}))" +
" order by a.sys_create_time DESC, a.read_flag ASC ) as c group by c.id) as d")
Page<Cases> queryList(Pageable pageable, @Param("condition") CasePageVo casePage);
// @Query(nativeQuery = true, value = "SELECT bc.*, COUNT(bcrpr.case_id) AS recommends1 FROM boe_cases bc LEFT JOIN boe_cases_recommend_push_record bcrpr ON bc.id = bcrpr.case_id" +
// " where bc.deleted = 0" +
// " and if(IFNULL(:#{#caseVo.keyWord},'')!='',bc.title like CONCAT('%',:#{#caseVo.keyWord},'%'),1=1)" +
// " and if(IFNULL(:#{#caseVo.authorName},'')!='',bc.author_name like CONCAT('%',:#{#caseVo.authorName},'%'),1=1)" +
// " and if(IFNULL(:#{#caseVo.orgDomain},'') !='' ,bc.org_domain_parent = :#{#caseVo.orgDomain},1=1) " +
// " and if(IFNULL(:#{#caseVo.excellent},'') !='' ,bc.excellent = :#{#caseVo.excellent},1=1) " +
// " and if(IFNULL(:#{#caseVo.isTop},'') !='' ,bc.is_top = :#{#caseVo.isTop},1=1) " +
// " GROUP BY bc.id ORDER BY bc.sys_create_time desc")
// List<Cases> exportCase(@Param("caseVo")CaseVo caseVo);
@Query("SELECT new Cases(bc.title, bc.authorName, bc.comments, bc.views, bc.praises, bc.shares, bc.favorites, COUNT(bcrpr.caseId), bc.cites, bc.confidentialityLevel) FROM Cases bc LEFT JOIN CasesRecommendPushRecord bcrpr ON bc.id = bcrpr.caseId" +
" where bc.deleted = false" +
" and (:keyWord IS NULL or bc.title LIKE %:keyWord%)" +
" and (:authorName IS NULL or bc.authorName LIKE %:authorName%)" +
" and (:orgDomain IS NULL or bc.orgDomainParent = :orgDomain)" +
" and (:excellent IS NULL or bc.excellent = :excellent)" +
" and (:isTop IS NULL or bc.isTop = :isTop)" +
" GROUP BY bc.id ORDER BY bc.sysCreateTime desc")
List<Cases> exportCase(String keyWord, String authorName,String orgDomain,Boolean excellent,Boolean isTop);
}

View File

@@ -0,0 +1,108 @@
package com.xboe.module.boecase.dto;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.xboe.module.scorm.rte.model.datatype.Int;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
@Data
public class CasePageVo extends PageDto {
private String keyWord;
private Boolean breCommend;
private String orderField;
private Boolean orderAsc;
private List<OrgDomainDto> orgDomainDtos;//后台查询一级
/**
* 专业分类
*/
private String majorType;
/**
* 置顶
*/
private Boolean isTop;
private String caseType;
/**
* 最佳案例
*/
private Boolean excellent;
private String authorName;
private List<Object> years;
/**
* 已经返回给前端的案例需要过滤掉
*/
private List<Long> notInIds;
/**
* excellent 最佳
* hot 最热
* new 最新
* recommend 推荐
*/
private String type;
/**
* 人员id
*/
private String userId;
/**
* 推荐id
*/
private Long refId;
public boolean isYearsEmpty() {
return CollUtil.isEmpty(this.years);
}
public List<String> getOrg1() {
if (CollectionUtils.isNotEmpty(this.orgDomainDtos)) {
return orgDomainDtos.stream().map(OrgDomainDto::getParent).filter(StrUtil::isNotBlank).collect(Collectors.toList());
}
return null;
}
public boolean isOrg1Empty() {
return CollUtil.isEmpty(this.getOrg1());
}
public boolean isOrg2Empty() {
return CollUtil.isEmpty(this.getOrg2());
}
public boolean isOrg3Empty() {
return CollUtil.isEmpty(this.getOrg3());
}
public List<String> getOrg2() {
if (CollectionUtils.isNotEmpty(this.orgDomainDtos)) {
return orgDomainDtos.stream().flatMap(it->it.getChildren().stream()).map(OrgDomainDto::getParent).filter(StrUtil::isNotBlank).collect(Collectors.toList());
}
return null;
}
public List<String> getOrg3() {
if (CollectionUtils.isNotEmpty(this.orgDomainDtos)) {
return orgDomainDtos.stream().flatMap(it->it.getChildren().stream().flatMap(i->i.getChildren().stream())).map(OrgDomainDto::getParent).filter(StrUtil::isNotBlank).collect(Collectors.toList());
}
return null;
}
}

View File

@@ -28,4 +28,5 @@ public class CaseVo {
private String authorName;
}

View File

@@ -16,4 +16,6 @@ public class CasesFiledVo {
private String authorId;
private String authorName;
private Boolean excellent;
}

View File

@@ -0,0 +1,33 @@
package com.xboe.module.boecase.dto;
import lombok.Data;
import javax.persistence.Column;
import java.util.Date;
@Data
public class CasesRecommendPushRecordExportVo {
/**
* 案例标题
*/
private String caseTitle;
/**
* 推送用户名称
*/
private String pushUserName;
/**推荐组织名称*/
private String recommendOrgName;
private String pushTime;
private String readFlag;
/**
* 首次查看时间
*/
private String readStartTime;
private String totalReadTime;
}

View File

@@ -0,0 +1,18 @@
package com.xboe.module.boecase.dto;
import lombok.Data;
import java.util.List;
@Data
public class OrgDomainDto {
/**
* 组织领域1级
*/
private String parent;
/**
* 组织领域子级
*/
private List<OrgDomainDto> children;
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.boecase.dto;
import lombok.Data;
@Data
public class PageDto {
private Integer pageIndex = 1;
private Integer pageSize = 10;
}

View File

@@ -82,20 +82,32 @@ public class Cases extends BaseEntity {
@Column(name = "status",length = 1)
private Integer status;
// 浏览量
@Column(name = "views", nullable = false)
private Integer views;
// 评论量
@Column(name = "comments", nullable = false)
private Integer comments;
// 点赞量
@Column(name = "praises", nullable = false)
private Integer praises;
// 分享量
@Column(name = "shares", nullable = false)
private Integer shares;
// 收藏量
@Column(name = "favorites", nullable = false)
private Integer favorites;
// 推荐量
private Long recommends1;
// 引用量
@Column(name = "cites", nullable = false)
private Integer cites;
/**摘要,对应数据对接中的caseSummary字段*/
@Column(name = "summary", nullable = true, columnDefinition = "text")
@@ -232,6 +244,9 @@ public class Cases extends BaseEntity {
private String caseValue;
/**
* 最佳案例标识
*/
@Column(name = "excellent")
private Boolean excellent;
@@ -245,6 +260,47 @@ public class Cases extends BaseEntity {
@Transient
private List<String> majorIds;
/**
* 推荐组织
*/
@Transient
private String recommendOrgName;
@Transient
private String refId;
public String getRefId() {
return refId;
}
public void setRefId(String refId) {
this.refId = refId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getRecommends1() {
return recommends1;
}
@Transient
public void setRecommends1(Long recommends1) {
this.recommends1 = recommends1;
}
public Cases() {
@@ -313,4 +369,21 @@ public class Cases extends BaseEntity {
this.favorites=favorites;
super.setDeleted(deleted);
}
public Cases(String title) {
this.title = title;
}
public Cases(String title,String authorName, int comments, int views, int praises, int shares, int favorites, Long recommends1, int cites, String confidentialityLevel) {
this.title = title;
this.views = views;
this.praises = praises;
this.shares = shares;
this.favorites = favorites;
this.recommends1 = recommends1;
this.cites = cites;
this.comments = comments;
this.authorName = authorName;
this.confidentialityLevel = confidentialityLevel;
}
}

View File

@@ -0,0 +1,37 @@
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;
/**
* 案例推荐发起导入
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_browse")
public class CasesBrowse extends BaseEntity {
/**
* 案例id
*/
@Column(name = "case_id")
private String caseId;
/**
* 用户id
*/
private String userId;
/**
* 浏览时长
*/
private Long browseDuration;
}

View File

@@ -0,0 +1,61 @@
package com.xboe.module.boecase.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
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 java.time.LocalDateTime;
/**
* 案例推荐表
* */
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE+"cases_recommend")
public class CasesRecommend extends BaseEntity {
private static final long serialVersionUID = 1L;
/**推荐人ID*/
@Column(name = "recommend_id",nullable = false,length = 100)
private String recommendId;
/**推荐人*/
@Column(name = "recommend_by", length = 255)
private String recommendBy;
/**推荐时间*/
@Column(name = "recommend_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime recommendTime;
/**案例数*/
@Column(name = "case_count",length = 11)
private Integer caseCount;
/**用户数*/
@Column(name = "user_count",length = 11)
private Integer userCount;
/**推送进度*/
@Column(name = "push_progress", length = 255)
private Integer pushProgress;
/**查看率*/
@Column(name = "view_rate", length = 255)
private String viewRate;
/**推荐组织名称*/
@Column(name = "recommend_org_name", length = 255)
private String recommendOrgName;
public CasesRecommend() {
}
public CasesRecommend(String id, String recommendOrgName) {
this.setId(id);
this.recommendOrgName = recommendOrgName;
}
}

View File

@@ -0,0 +1,48 @@
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;
/**
* 案例推荐发起导入
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_recommend_launch_import")
public class CasesRecommendLaunchImport extends BaseEntity {
/**
* 总条数
*/
@Column(name = "total_num",length = 20)
private Integer totalNum;
/**
* 成功条数
*/
@Column(name = "success_num",length = 20)
private Integer successNum;
/**
* 失败条数
*/
@Column(name = "fail_num",length = 20)
private Integer failNum;
/**
* 上传状态1进行中2成功3失败
*/
@Column(name = "process_status",length = 20)
private Integer processStatus;
@Column(name = "import_id")
private String importId;
}

View File

@@ -0,0 +1,45 @@
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;
/**
* 案例推荐发起导入
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_recommend_launch_import_data")
public class CasesRecommendLaunchImportData extends BaseEntity {
/**
* 导入id
*/
@Column(name = "import_id", length = 20)
private String importId;
/**
* 导入类容第一例标题
*/
@Column(name = "case_title")
private String caseTitle;
/**
* 导入类容匹配的案例id
*/
@Column(name = "case_id")
private String caseId;
/**
* 状态1成功2失败
*/
@Column(name = "status")
private Integer status;
}

View File

@@ -0,0 +1,102 @@
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 java.util.Date;
/**
* 案例推荐发起导入
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_recommend_push_record")
public class CasesRecommendPushRecord extends BaseEntity {
/**
* 推送id
*/
@Column(name = "recommend_id")
private String recommendId;
/**
* 案例id
*/
@Column(name = "case_id")
private String caseId;
/**
* 案例标题
*/
@Column(name = "case_title")
private String caseTitle;
/**
* 推送用户id
*/
@Column(name = "push_user_id")
private String pushUserId;
/**
* 推送用户名称
*/
@Column(name = "push_user_name")
private String pushUserName;
/**
* 推送状态1未推送2推送中3已推送4推送失败5已撤回
*/
@Column(name = "push_status")
private Integer pushStatus;
/**
* 推送时间
*/
@Column(name = "push_time")
private Date pushTime;
/**
* 查看标识
*/
@Column(name = "read_flag")
private Integer readFlag;
/**
* 首次查看时间
*/
@Column(name = "read_start_time")
private Date readStartTime;
// /**
// * 最后查看时间
// */
// @Column(name = "read_end_time")
// private Date readEndTime;
/**
* 备注
*/
@Column(name = "remark")
private String remark;
public CasesRecommendPushRecord() {
}
public CasesRecommendPushRecord(String id,String recommendId,String caseId) {
this.setId(id);
this.recommendId = recommendId;
this.caseId = caseId;
}
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.boecase.service;
public interface ICasesBrowseService {
boolean recordBrowseDuration(String caseId, String userId, Long browseDuration);
Long getBrowseDuration(String caseId, String userId);
}

View File

@@ -0,0 +1,7 @@
package com.xboe.module.boecase.service;
public interface ICasesRecommendLaunchImportDataService {
}

View File

@@ -0,0 +1,36 @@
package com.xboe.module.boecase.service;
import com.xboe.data.dto.ImportData;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImport;
import java.util.List;
public interface ICasesRecommendLaunchImportService {
/**
* 导入数据
*
* @param dataList
* @return
*/
ImportData importData(List<List<Object>> dataList);
/**
* 下载失败的数据
*
* @param importId
* @return
*/
List<String> downFailData(String importId);
/**
* 获取导入结果信息
*
* @param id
* @return
*/
CasesRecommendLaunchImport getByImportId(String importId);
}

View File

@@ -0,0 +1,54 @@
package com.xboe.module.boecase.service;
import com.xboe.core.CurrentUser;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.module.boecase.vo.CasesRecommendLaunchVo;
import java.util.List;
public interface ICasesRecommendPushRecordService {
/**
* 案例推送
*
* @param
* @return
*/
boolean launchPush(CasesRecommendLaunchVo casesRecommendLaunch, CurrentUser currentUser, String token);
/**
* 根据案例推荐ID查询案例推送列表信息
*
* @param recommendId
* @return
*/
List<CasesRecommendPushRecord> findAllByRecommendId(String recommendId);
List<CasesRecommendPushRecord> findReadByRecommendId(String recommendId);
/**
* 重新推送或撤回
*
* @param isWithdraw 是否撤回
* @param casesRecommend 案例推荐
*/
void rePushOrWithdraw(boolean isWithdraw, CasesRecommend casesRecommend);
/**
* 开始读
*
* @param caseRecommendId
* @return
*/
boolean startRead(String caseRecommendId);
// /**
// * 结束读
// * @param caseRecommendId
// * @return
// */
// boolean endRead(String caseRecommendId);
}

View File

@@ -0,0 +1,37 @@
package com.xboe.module.boecase.service;
import com.xboe.common.PageList;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.vo.CasesRecommendPushVo;
import com.xboe.module.boecase.vo.CasesRecommendVo;
public interface ICasesRecommendService {
/**
* 分页并查询案例推荐列表
* @param pageIndex
* @param pageSize
* @param casesRecommendVo
* @return
*/
PageList<CasesRecommend> page(int pageIndex, int pageSize, CasesRecommendVo casesRecommendVo);
/**
* 删除
* @param id
*/
void delete(String id);
/**
* 根据ID查询
* @param id
* @return
*/
CasesRecommend findById(String id);
/**
* 撤回或者重新推送
* @param casesRecommendPushVo
*/
void rePushOrWithdraw(CasesRecommendPushVo casesRecommendPushVo,String userId);
}

View File

@@ -3,6 +3,7 @@ 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.dict.entity.DictItem;
@@ -14,11 +15,17 @@ public interface ICasesService{
* */
PageList<Cases> queryPageCases(int pageIndex, int pageSize, CaseVo caseVo);
PageList<Cases> queryPageCasesV2(CasePageVo caseVo);
/**
* 案例管理列表搜索
* */
PageList<Cases> managerList(int pageIndex,int pageSize,CaseVo caseVo);
List<Cases> exportCase(CaseVo caseVo);
List<Cases> managerCaseTitleList(CaseVo caseVo);
/**
* 案例分页
* */
@@ -97,5 +104,9 @@ public interface ICasesService{
void excellent(String id,Boolean excellent);
PageList<Cases> queryRecommendPageCasesV2(CasePageVo req);
List<CasesVo> caseIndexV2(CurrentUser current);
}

View File

@@ -0,0 +1,172 @@
package com.xboe.module.boecase.service.impl;
import com.xboe.api.ThirdApi;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.enums.CasesPushStatusEnum;
import com.xboe.module.boecase.dao.CasesRecommendDao;
import com.xboe.module.boecase.dao.CasesRecommendPushRecordDao;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.system.user.dao.MessageDao;
import com.xboe.system.user.entity.Message;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @author : civism
* @version 1.0
* @date 2023/7/4 18:54
*/
@Service
@Slf4j
public class AsyncSendCasesRecommendService {
@Resource
private CasesRecommendDao casesRecommendDao;
@Resource
private CasesRecommendPushRecordDao casesRecommendPushRecordDao;
@Resource
private ThirdApi thirdApi;
@Value("${xboe.old.base.url}")
private String domain;
@Resource
private MessageDao messageDao;
@Async
@Transactional(rollbackFor = Exception.class)
public void sendCasesRecommend(CasesRecommend casesRecommend) throws Exception {
TimeUnit.SECONDS.sleep(10);
log.info("异步推送任务开始了 {}", casesRecommend.getId());
List<CasesRecommendPushRecord> casesRecommendPushRecords = casesRecommendPushRecordDao.findList(FieldFilters.eq("pushStatus", CasesPushStatusEnum.WAIT_PUSH.getStatus()), FieldFilters.eq("recommendId", casesRecommend.getId()));
if (CollectionUtils.isEmpty(casesRecommendPushRecords)) {
log.info("未发现需要推送的内容 {}", casesRecommend.getId());
//修改为推送完成 --- 无数据 无需推送
updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
return;
}
//修改为推送中
updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_ING.getStatus());
List<String> caseIds = casesRecommendPushRecords.stream().map(CasesRecommendPushRecord::getCaseId).distinct().collect(Collectors.toList());
if (caseIds.size() > 1) {
sendMixCaseRecommend(casesRecommendPushRecords);
} else {
sendSingleCaseRecommend(casesRecommendPushRecords);
}
//修改为推送完成 --- 无数据 无需推送
updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
log.info("异步推送任务结束了 {}", casesRecommend.getId());
}
/**
* 修改轧辊天
*
* @param id
* @param pushProgress
* @return
*/
private boolean updateProcessStatus(String id, Integer pushProgress) {
return casesRecommendDao.updateMultiFieldById(id, UpdateBuilder.create("pushProgress", pushProgress)) > 0;
}
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
private void sendMixCaseRecommend(List<CasesRecommendPushRecord> casesRecommendPushRecords) {
Map<String, List<CasesRecommendPushRecord>> caseMap = casesRecommendPushRecords.stream().collect(Collectors.groupingBy(CasesRecommendPushRecord::getPushUserId));
Map<String, String> userMap = casesRecommendPushRecords.stream().filter(distinctByKey(CasesRecommendPushRecord::getPushUserId)).collect(Collectors.toMap(CasesRecommendPushRecord::getPushUserId, CasesRecommendPushRecord::getPushUserName));
for (String userId : caseMap.keySet()) {
List<CasesRecommendPushRecord> pushRecords = caseMap.get(userId);
try {
Message message = new Message();
message.setMsgType(1);
message.setAcceptId(userId);
message.setAcceptName(userMap.get(userId));
message.setContent("案例推荐-《" + pushRecords.get(0).getCaseTitle() + "》等" + pushRecords.size() + "个案例");
message.setIsRead(false);
message.setMsgTime(LocalDateTime.now());
message.setRefId(pushRecords.get(0).getRecommendId());
message.setBatchId(pushRecords.get(0).getRecommendId());
message.setRefType("99");
message.setSendName(pushRecords.get(0).getSysCreateBy());
message.setSendType(1);
message.setTitle("案例推荐");
message.setSendAid(pushRecords.get(0).getSysCreateAid());
message.setSource(1);
// message.setPageUrl(domain + "/pc/case/detail?id=" + casesRecommendPushRecord.getCaseId());
// message.setPageParams(casesRecommendPushRecord.getCaseId());
message.setPageType(3);
messageDao.save(message);
updatePushStatus(casesRecommendPushRecords, CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
} catch (Exception e) {
log.error("推荐案例失败", e);
updatePushStatus(casesRecommendPushRecords, CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
}
}
}
private void updatePushStatus(List<CasesRecommendPushRecord> pushRecords, Integer pushStatus) {
for (CasesRecommendPushRecord pushRecord : pushRecords) {
casesRecommendPushRecordDao.updateMultiFieldById(pushRecord.getId(), UpdateBuilder.create("pushStatus", pushStatus), UpdateBuilder.create("pushTime", new Date()));
}
}
private void sendSingleCaseRecommend(List<CasesRecommendPushRecord> casesRecommendPushRecords) {
for (CasesRecommendPushRecord casesRecommendPushRecord : casesRecommendPushRecords) {
Integer pushStatus;
try {
Message message = new Message();
message.setMsgType(1);
message.setAcceptId(casesRecommendPushRecord.getPushUserId());
message.setAcceptName(casesRecommendPushRecord.getPushUserName());
message.setContent("案例推荐-《" + casesRecommendPushRecord.getCaseTitle() + "");
message.setIsRead(false);
message.setMsgTime(LocalDateTime.now());
message.setRefId(casesRecommendPushRecord.getId());
message.setBatchId(casesRecommendPushRecord.getRecommendId());
message.setRefType("99");
message.setSendName(casesRecommendPushRecord.getSysCreateBy());
message.setSendType(1);
message.setTitle("案例推荐");
message.setSendAid(casesRecommendPushRecord.getSysCreateAid());
message.setSource(1);
message.setPageUrl(domain + "/pc/case/detail?id=" + casesRecommendPushRecord.getCaseId());
message.setPageParams(casesRecommendPushRecord.getCaseId());
message.setPageType(3);
messageDao.save(message);
pushStatus = CasesPushStatusEnum.PUSH_SUCCESS.getStatus();
} catch (Exception e) {
log.error("推荐案例失败", e);
pushStatus = CasesPushStatusEnum.PUSH_FAIL.getStatus();
}
casesRecommendPushRecordDao.updateMultiFieldById(casesRecommendPushRecord.getId(), UpdateBuilder.create("pushStatus", pushStatus), UpdateBuilder.create("pushTime", new Date()));
}
}
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.boecase.service.impl;
import com.xboe.module.boecase.service.ICasesRecommendLaunchImportDataService;
import org.springframework.stereotype.Service;
@Service
public class CasesRecommendLaunchImportDataServiceImpl implements ICasesRecommendLaunchImportDataService {
}

View File

@@ -0,0 +1,104 @@
package com.xboe.module.boecase.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.xboe.core.orm.FieldFilters;
import com.xboe.data.dto.ImportData;
import com.xboe.module.boecase.dao.CasesDao;
import com.xboe.module.boecase.dao.CasesRecommendLaunchImportDao;
import com.xboe.module.boecase.dao.CasesRecommendLaunchImportDataDao;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImport;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImportData;
import com.xboe.module.boecase.service.ICasesRecommendLaunchImportService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Transactional
public class CasesRecommendLaunchImportServiceImpl implements ICasesRecommendLaunchImportService {
@Resource
private CasesRecommendLaunchImportDao casesRecommendLaunchImportDao;
@Resource
private CasesRecommendLaunchImportDataDao casesRecommendLaunchImportDataDao;
@Resource
private CasesDao casesDao;
@Override
public ImportData importData(List<List<Object>> dataList) {
if (CollectionUtil.isEmpty(dataList) || dataList.size() < 1) {
throw new RuntimeException("导入数据为空");
}
String title = dataList.get(0).get(0).toString();
if (!"标题".equals(title.trim())) {
throw new RuntimeException("导入模版错误");
}
int totalNum = dataList.size() - 1;
int successNum = 0;
int failNum = 0;
String importId = IdUtil.getSnowflakeNextId() + "";
ImportData importData = new ImportData();
importData.setImportId(importId);
List<String> caseIds = new ArrayList<>();
List<ImportData.CasesTitle> caseTitleList = new ArrayList<>();
for (int i = 1; i < dataList.size(); i++) {
String caseTitle = dataList.get(i).get(0).toString();
CasesRecommendLaunchImportData casesRecommendLaunchImportData = new CasesRecommendLaunchImportData();
casesRecommendLaunchImportData.setImportId(importId);
casesRecommendLaunchImportData.setCaseTitle(caseTitle);
Cases cases = casesDao.getByTitle(caseTitle);
if (cases == null) {
failNum++;
casesRecommendLaunchImportData.setStatus(2);
} else {
if (caseTitleList.size() < 10) {
caseTitleList.add(new ImportData.CasesTitle(cases.getId(), cases.getTitle()));
}
caseIds.add(cases.getId());
casesRecommendLaunchImportData.setStatus(1);
casesRecommendLaunchImportData.setCaseTitle(caseTitle);
successNum++;
}
casesRecommendLaunchImportDataDao.save(casesRecommendLaunchImportData);
}
importData.setCaseTitleList(caseTitleList);
importData.setCaseIdList(caseIds);
CasesRecommendLaunchImport casesRecommendLaunchImport = new CasesRecommendLaunchImport();
casesRecommendLaunchImport.setFailNum(failNum);
casesRecommendLaunchImport.setImportId(importId);
casesRecommendLaunchImport.setSuccessNum(successNum);
casesRecommendLaunchImport.setTotalNum(totalNum);
casesRecommendLaunchImport.setProcessStatus(1);
casesRecommendLaunchImportDao.save(casesRecommendLaunchImport);
return importData;
}
@Override
public List<String> downFailData(String importId) {
List<CasesRecommendLaunchImportData> dataList = casesRecommendLaunchImportDataDao.findList(FieldFilters.eq("importId", importId)
, FieldFilters.eq("status", 2));
if (CollectionUtil.isEmpty(dataList)) {
return null;
}
return dataList.stream().map(CasesRecommendLaunchImportData::getCaseTitle).collect(Collectors.toList());
}
@Override
public CasesRecommendLaunchImport getByImportId(String importId) {
return casesRecommendLaunchImportDao.findOne(FieldFilters.eq("importId", importId));
}
}

View File

@@ -0,0 +1,229 @@
package com.xboe.module.boecase.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.xboe.api.ThirdApi;
import com.xboe.api.vo.*;
import com.xboe.core.CurrentUser;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.data.outside.IOutSideDataService;
import com.xboe.enums.CasesPushStatusEnum;
import com.xboe.module.boecase.dao.CasesDao;
import com.xboe.module.boecase.dao.CasesRecommendDao;
import com.xboe.module.boecase.dao.CasesRecommendLaunchImportDataDao;
import com.xboe.module.boecase.dao.CasesRecommendPushRecordDao;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.entity.CasesRecommendLaunchImportData;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.module.boecase.service.ICasesRecommendPushRecordService;
import com.xboe.module.boecase.vo.CasesRecommendLaunchVo;
import com.xboe.system.user.dao.UserDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Transactional
@Slf4j
public class CasesRecommendPushRecordServiceImpl implements ICasesRecommendPushRecordService {
@Resource
private UserDao userDao;
@Resource
private IOutSideDataService outSideDataService;
@Resource
private CasesDao casesDao;
@Resource
private CasesRecommendDao casesRecommendDao;
@Resource
private CasesRecommendLaunchImportDataDao casesRecommendLaunchImportDataDao;
@Resource
private CasesRecommendPushRecordDao casesRecommendPushRecordDao;
@Resource
private ThirdApi thirdApi;
@Value("${xboe.old.base.url}")
private String domain;
@Resource
private AsyncSendCasesRecommendService asyncSendCasesRecommendService;
@Override
public boolean launchPush(CasesRecommendLaunchVo casesRecommendLaunch, CurrentUser currentUser, String token) {
long t1 = System.currentTimeMillis();
List<String> caseIds = new ArrayList<>();
if (casesRecommendLaunch.getLaunchType() == 1) {
caseIds.addAll(casesRecommendLaunch.getCasesIdList());
} else {
List<CasesRecommendLaunchImportData> importDataList = casesRecommendLaunchImportDataDao.findList(FieldFilters.eq("import_id", casesRecommendLaunch.getImportId()));
List<String> caseIdList = importDataList.stream().filter(casesRecommendLaunchImportData -> casesRecommendLaunchImportData.getStatus() == 1).map(CasesRecommendLaunchImportData::getCaseId).collect(Collectors.toList());
caseIds.addAll(caseIdList);
}
Set<String> userIds = new HashSet<>();
if (CollectionUtil.isNotEmpty(casesRecommendLaunch.getPushUserIdList())) {
userIds.addAll(casesRecommendLaunch.getPushUserIdList());
}
// 组织
if (CollectionUtil.isNotEmpty(casesRecommendLaunch.getDeptIds())) {
long tt = System.currentTimeMillis();
for (String orgId : casesRecommendLaunch.getDeptIds()) {
UserListParam build = UserListParam.builder().departId(orgId).pageSize(100).build();
List<UserInfoList> allUserList = thirdApi.getAllUserList(build, token);
if (CollectionUtil.isNotEmpty(allUserList)) {
for (UserInfoList userInfo : allUserList) {
userIds.add(String.valueOf(userInfo.getId()));
}
}
}
log.info("用户查询耗时 {}秒", (System.currentTimeMillis() - tt) / 1000);
}
// 受众关联
if (CollectionUtil.isNotEmpty(casesRecommendLaunch.getGroupIds())) {
long t2 = System.currentTimeMillis();
for (String groupId : casesRecommendLaunch.getGroupIds()) {
List<AuditList> allAudienceList = thirdApi.getAllAudienceList(AuditListParam.builder().audienceId(groupId).pageSize(100).page(1).build(), token);
if (CollectionUtil.isNotEmpty(allAudienceList)) {
allAudienceList.forEach(auditList -> userIds.add(String.valueOf(auditList.getUserId())));
}
}
log.info("耗时受众查询 {}", (System.currentTimeMillis() - t2) / 1000);
}
if (CollectionUtil.isEmpty(userIds)) {
throw new RuntimeException("推荐人不能为空");
}
log.info("查询用户总共消耗时长为 {}秒", (System.currentTimeMillis() - t1) / 1000);
CasesRecommend casesRecommend = new CasesRecommend();
casesRecommend.setRecommendId(currentUser.getAccountId());
casesRecommend.setRecommendBy(currentUser.getName());
casesRecommend.setRecommendTime(LocalDateTime.now());
casesRecommend.setCaseCount(caseIds.size());
casesRecommend.setUserCount(userIds.size());
casesRecommend.setRecommendOrgName(casesRecommendLaunch.getRecommendOrgName());
casesRecommend.setPushProgress(CasesPushStatusEnum.WAIT_PUSH.getStatus());
casesRecommendDao.save(casesRecommend);
log.info("案例推送对象 {}", JSONUtil.toJsonStr(casesRecommend));
List<CasesRecommendPushRecord> pushRecords = new ArrayList<>();
for (String caseId : caseIds) {
Cases cases = casesDao.get(caseId);
Map<String, Object> userMap = userDao.findMap("id", "name", FieldFilters.in("id", userIds));
for (String userId : userIds) {
CasesRecommendPushRecord casesRecommendPushRecord = new CasesRecommendPushRecord();
casesRecommendPushRecord.setRecommendId(casesRecommend.getId());
casesRecommendPushRecord.setCaseId(caseId);
casesRecommendPushRecord.setCaseTitle(cases.getTitle());
casesRecommendPushRecord.setPushUserId(userId);
casesRecommendPushRecord.setPushUserName(userMap.get(userId) != null ? userMap.get(userId).toString() : null);
casesRecommendPushRecord.setPushStatus(CasesPushStatusEnum.WAIT_PUSH.getStatus());
//默认未查看
casesRecommendPushRecord.setReadFlag(0);
pushRecords.add(casesRecommendPushRecord);
}
}
if (CollectionUtil.isNotEmpty(pushRecords)) {
log.info("本次推送纪录条数 {}", pushRecords.size());
casesRecommendPushRecordDao.saveList(pushRecords);
}
try {
log.info("发送推送案例消息 {}", JSONUtil.toJsonStr(casesRecommend));
//发送推送案例消息
asyncSendCasesRecommendService.sendCasesRecommend(casesRecommend);
log.info("执行完成耗时 {} 秒 ", (System.currentTimeMillis() - t1) / 1000);
} catch (Exception e) {
log.error("推送失败", e);
}
return true;
}
@Override
public List<CasesRecommendPushRecord> findAllByRecommendId(String recommendId) {
return casesRecommendPushRecordDao.findList(FieldFilters.eq("recommendId", recommendId));
}
@Override
public List<CasesRecommendPushRecord> findReadByRecommendId(String recommendId) {
return casesRecommendPushRecordDao.findList(FieldFilters.eq("recommendId", recommendId), FieldFilters.eq("readFlag", 1));
}
@Override
public void rePushOrWithdraw(boolean isWithdraw, CasesRecommend casesRecommend) {
if (ObjectUtil.isEmpty(casesRecommend)) {
throw new RuntimeException("缺少必要参数");
}
if (isWithdraw) {
List<CasesRecommendPushRecord> recordList = findAllByRecommendId(casesRecommend.getId());
if (CollectionUtil.isNotEmpty(recordList)) {
List<String> pushIds = recordList.stream().map(CasesRecommendPushRecord::getId).collect(Collectors.toList());
casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
.addUpdateField("pushStatus", CasesPushStatusEnum.PUSH_REVOKE.getStatus())
.addUpdateField("readFlag", 0)
.addFilter(FieldFilters.in("id", pushIds))
.builder());
}
} else {
try {
casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
.addUpdateField("pushStatus", CasesPushStatusEnum.WAIT_PUSH.getStatus())
.addFilter(FieldFilters.eq("recommendId", casesRecommend.getId()))
.builder());
casesRecommendDao.update(UpdateBuilder.from(CasesRecommend.class)
.addUpdateField("pushProgress", CasesPushStatusEnum.WAIT_PUSH.getStatus())
.addFilter(FieldFilters.eq("id", casesRecommend.getId()))
.builder());
//发送推送案例消息
asyncSendCasesRecommendService.sendCasesRecommend(casesRecommend);
} catch (Exception e) {
log.error("推送失败", e);
casesRecommendDao.update(UpdateBuilder.from(CasesRecommend.class)
.addUpdateField("pushProgress", CasesPushStatusEnum.PUSH_FAIL.getStatus())
.addFilter(FieldFilters.eq("id", casesRecommend.getId()))
.builder());
}
}
}
@Override
public boolean startRead(String caseRecommendId) {
return casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
.addUpdateField("readFlag", 1)
.addUpdateField("readStartTime", new Date())
.addFilter(FieldFilters.eq("id", caseRecommendId))
.addFilter(FieldFilters.eq("readFlag", 0))
.builder()) > 0;
}
// @Override
// public boolean endRead(String caseRecommendId) {
// CasesRecommendPushRecord casesRecommendPushRecord = casesRecommendPushRecordDao.get(caseRecommendId);
// if (casesRecommendPushRecord.getReadEndTime() != null) {
// return true;
// }
// return casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
// .addUpdateField("readEndTime", new Date())
// .addFilter(FieldFilters.eq("id", caseRecommendId))
// .builder()) > 0;
// }
}

View File

@@ -0,0 +1,99 @@
package com.xboe.module.boecase.service.impl;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.LikeMatchMode;
import com.xboe.core.orm.QueryBuilder;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.enums.CasesPushStatusEnum;
import com.xboe.module.boecase.dao.CasesRecommendDao;
import com.xboe.module.boecase.dao.CasesRecommendPushRecordDao;
import com.xboe.module.boecase.entity.CasesRecommend;
import com.xboe.module.boecase.service.ICasesRecommendPushRecordService;
import com.xboe.module.boecase.service.ICasesRecommendService;
import com.xboe.module.boecase.vo.CasesRecommendPushVo;
import com.xboe.module.boecase.vo.CasesRecommendVo;
import com.xboe.system.user.dao.MessageDao;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
@Service
@Transactional
public class CasesRecommendServiceImpl implements ICasesRecommendService {
@Resource
private CasesRecommendDao casesRecommendDao;
@Resource
private MessageDao messageDao;
@Resource
private CasesRecommendPushRecordDao casesRecommendPushRecordDao;
@Resource
private ICasesRecommendPushRecordService iCasesRecommendPushRecordService;
@Override
public PageList<CasesRecommend> page(int pageIndex, int pageSize, CasesRecommendVo casesRecommendVo) {
QueryBuilder query = QueryBuilder.from(CasesRecommend.class);
query.addFilter(FieldFilters.eq("deleted", false));
if (StringUtils.isNotBlank(casesRecommendVo.getRecommendName())) {
query.addFilter(FieldFilters.like("recommend_by", LikeMatchMode.ANYWHERE, casesRecommendVo.getRecommendName()));
}
if (!CollectionUtils.isEmpty(casesRecommendVo.getRecommendTimeList())) {
query.addFilter(FieldFilters.ge("recommend_time", casesRecommendVo.getRecommendTimeList().get(0)));
query.addFilter(FieldFilters.le("recommend_time", casesRecommendVo.getRecommendTimeList().get(1)));
}
query.addOrder(OrderCondition.desc("sys_create_time"));
query.setPageIndex(pageIndex);
query.setPageSize(pageSize);
PageList<CasesRecommend> page = casesRecommendDao.findPage(query.builder());
return page;
}
@Override
public void delete(String id) {
casesRecommendDao.setDeleted(id);
casesRecommendPushRecordDao.deleteByFilter(FieldFilters.eq("recommendId", id));
}
@Override
public CasesRecommend findById(String id) {
return casesRecommendDao.get(id);
}
@Override
public void rePushOrWithdraw(CasesRecommendPushVo casesRecommendPushVo, String userId) {
// 查询
CasesRecommend db = casesRecommendDao.get(casesRecommendPushVo.getCasesRecommendId());
if (CasesPushStatusEnum.PUSH_SUCCESS.getStatus().equals(db.getPushProgress())
|| CasesPushStatusEnum.WAIT_PUSH.getStatus().equals(db.getPushProgress())
|| CasesPushStatusEnum.PUSH_ING.getStatus().equals(db.getPushProgress())
) {
// 当为推送成功时为
iCasesRecommendPushRecordService.rePushOrWithdraw(true, db);
casesRecommendDao.update(UpdateBuilder.from(CasesRecommend.class)
.addUpdateField("pushProgress", CasesPushStatusEnum.PUSH_REVOKE.getStatus())
.addFilter(FieldFilters.eq("id", db.getId()))
.builder());
messageDao.deleteByFilter(FieldFilters.eq("acceptId", userId), FieldFilters.eq("refType", "99"),
FieldFilters.eq("batchId", casesRecommendPushVo.getCasesRecommendId()));
} else if (CasesPushStatusEnum.PUSH_FAIL.getStatus().equals(db.getPushProgress())
|| CasesPushStatusEnum.PUSH_REVOKE.getStatus().equals(db.getPushProgress())) {
// 推送失败或者已撤回时
iCasesRecommendPushRecordService.rePushOrWithdraw(false, db);
}
}
}

View File

@@ -0,0 +1,53 @@
package com.xboe.module.boecase.service.impl;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.boecase.dao.CasesBrowseDao;
import com.xboe.module.boecase.entity.CasesBrowse;
import com.xboe.module.boecase.service.ICasesBrowseService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* @author : civism
* @version 1.0
* @date 2023/7/4 16:31
*/
@Service
@Transactional
public class ICasesBrowseServiceImpl implements ICasesBrowseService {
@Resource
private CasesBrowseDao casesBrowseDao;
@Override
public boolean recordBrowseDuration(String caseId, String userId, Long browseDuration) {
CasesBrowse one = casesBrowseDao.findOne(FieldFilters.eq("caseId", caseId), FieldFilters.eq("userId", userId));
if (one == null) {
CasesBrowse save = new CasesBrowse();
save.setUserId(userId);
save.setCaseId(caseId);
save.setBrowseDuration(browseDuration);
casesBrowseDao.save(save);
return true;
} else {
return casesBrowseDao.update(UpdateBuilder.from(CasesBrowse.class)
.addUpdateField("browseDuration", one.getBrowseDuration() + browseDuration)
.addFilter(FieldFilters.eq("id", one.getId()))
.builder()) > 0;
}
}
@Override
public Long getBrowseDuration(String caseId, String userId) {
CasesBrowse one = casesBrowseDao.findOne(FieldFilters.eq("caseId", caseId), FieldFilters.eq("userId", userId));
if (one == null) {
return 0L;
}
return one.getBrowseDuration();
}
}

View File

@@ -0,0 +1,16 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
/**
* @author : civism
* @version 1.0
* @date 2023/7/4 16:34
*/
@Data
public class BrowseDurationVo {
private String caseId;
private Long browseDuration;
}

View File

@@ -8,21 +8,32 @@ import java.time.LocalDateTime;
@Data
public class CaseExportVo {
private Integer views;
private Long recommends;
private Integer cites;
private Integer praises;
private Integer comments;
private Integer shares;
private Integer favorites;
private LocalDateTime exportDate;
private String authorName;
private String title;
private String status;
private LocalDateTime endTime;
private String caseScope;
private Integer views;
private LocalDateTime endTime;
private Integer praises;
private Integer shares;
private Integer favorites;
private String confidentialityLevel;
}

View File

@@ -0,0 +1,51 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
import java.util.List;
/**
* @author : civism
* @version 1.0
* @date 2023/6/17 09:46
*/
@Data
public class CasesRecommendLaunchVo {
/**
* 发起类型 1 正常选择 2 文件导入
*/
private Integer launchType;
/**
* 如果launchType为2 必须传递 其他情况不用传递
*/
private String importId;
/**
* 推送的文章标题id launchType 为1必须传递 其他情况不用传递
*/
private List<String> casesIdList;
/**
* 推送的用户id
*/
private List<String> pushUserIdList;
/**
* 组织列表
*/
private List<String> deptIds;
/**
* 受众列表
*/
private List<String> groupIds;
/**
* 推荐机构
*/
private String recommendOrgName;
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.boecase.vo;
import lombok.Data;
@Data
public class CasesRecommendPushVo {
/** 案例推荐id */
private String casesRecommendId;
}

View File

@@ -0,0 +1,20 @@
package com.xboe.module.boecase.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.common.Pagination;
import lombok.Data;
import java.util.List;
@Data
public class CasesRecommendVo extends Pagination {
private String casesRecommendId;
/** 推荐人姓名 */
private String recommendName;
/** 推荐时间区间 */
private List<String> recommendTimeList;
}

View File

@@ -1,6 +1,7 @@
package com.xboe.module.course.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@@ -221,9 +222,11 @@ public class CourseFullTextApi extends ApiBaseController{
paras.setOpenCourse(dto.getOpenCourse());
if(StringUtils.isNotBlank(dto.getOrderField())) {
if(dto.getOrderField().equals("studys")) {
paras.setOrderType(2);
paras.setOrderType(2);//最热
}else if (dto.getOrderField().equals("publishTime")){
paras.setOrderType(1);//最新
}else {
paras.setOrderType(1);
paras.setOrderType(3);//好评
}
}
@@ -262,7 +265,19 @@ public class CourseFullTextApi extends ApiBaseController{
c.setTeacher(ct.getTeacherName());
}
}
if (StringUtils.isNotBlank(c.getKeywords()) ){
String[] keywords = c.getKeywords().split(",");
if (keywords.length == 1){
keywords = c.getKeywords().split(" ");
}
if (keywords.length > 0){
List<String> keywordsList = Arrays.asList(keywords);
c.setKeywordsList(keywordsList);
}
}
}
return success(coursePageList);
}catch(Exception e) {

View File

@@ -7,6 +7,8 @@ import java.util.Map;
import javax.annotation.Resource;
import com.xboe.core.JsonResponseStatus;
import com.xboe.module.usergroup.entity.UserGroupItem;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -250,25 +252,27 @@ public class CoursePortalApi extends ApiBaseController{
if(preview==null) {
preview=true;
}
boolean pass = false;
if(!preview) {
if (!courseCrowdList.isEmpty()) {
// boolean pass = false;
// for (CourseCrowd c : courseCrowdList) {
// //同一个受众,同一个只会有一条记录,所以这里就直接查询了
// List<UserGroupItem> hasItem = userGroupService.findByGroupIdAndAid(c.getGroupId(),aid);
// if (hasItem != null && !hasItem.isEmpty()) {
// pass = true;
// break;
// }
// }
for (CourseCrowd c : courseCrowdList) {
//同一个受众,同一个只会有一条记录,所以这里就直接查询了
List<UserGroupItem> hasItem = userGroupService.findByGroupIdAndAid(c.getGroupId(),aid);
if (hasItem != null && !hasItem.isEmpty()) {
pass = true;
break;
}
}
// if (!pass) {
// //return badRequest("您无学习此课程的权限,请与管理员联系");
// return wrap(JsonResponseStatus.NO_CONTENT, "您无学习此课程的权限,请与管理员联系",rs);
// }
}
}
List<CourseContent> cclist=contentService.getByCourseId(id);
List<CourseSection> sectionlist=sectionService.getByCourseId(id);
List<CourseTeacher> teachers=courseService.findTeachersByCourseId(id);
@@ -282,8 +286,8 @@ public class CoursePortalApi extends ApiBaseController{
}
}
rs.put("isCrowd",pass);
rs.put("contents",cclist);
rs.put("sections",sectionlist);
rs.put("teachers",teachers);

View File

@@ -18,7 +18,6 @@ import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

View File

@@ -11,8 +11,6 @@ import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import javafx.util.Builder;
import org.apache.lucene.util.QueryBuilder;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;

View File

@@ -0,0 +1,26 @@
package com.xboe.orm;
import com.xboe.common.beans.KeyValue;
import com.xboe.core.orm.impl.FieldInFilter;
import java.util.Collection;
public class CustomFieldInFilter extends FieldInFilter {
private String param;
public CustomFieldInFilter(String name,String param, Collection<Object> values) {
super(name, values);
this.param = param;
}
@Override
public String getNamed(String name, int order) {
return super.getNamed(param, order);
}
@Override
public String getNamed(String pre, String name, int order) {
return super.getNamed(pre, param, order);
}
}

View File

@@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import com.xboe.core.CurrentUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -27,6 +27,8 @@ import com.xboe.module.qa.service.IQuestionService;
import com.xboe.school.vo.CasesVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import com.xboe.common.PageList;
/**
* 门户首页接口
@@ -69,6 +71,19 @@ public class PortalIndexApi extends ApiBaseController{
}
@RequestMapping(value="/casesV2",method = {RequestMethod.GET})
public JsonResponse<List<CasesVo>> caseList() {
try {
CurrentUser current = this.getCurrent();
List<CasesVo> casesVos = casesService.caseIndexV2(current);
return success(casesVos);
}catch(Exception e) {
log.error("查询案例数据错误",e);
return error("查询案例数据错误",e.getMessage());
}
}
/**
* 文章排行榜
* */

View File

@@ -6,6 +6,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.xboe.module.usergroup.entity.UserGroupItem;
import com.xboe.module.usergroup.service.IUserGroupService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -77,6 +79,9 @@ public class StudyCourseApi extends ApiBaseController{
@Autowired
IStudySignupService signupService;
@Autowired
private IUserGroupService userGroupService;
/**
* 用于查询课程的学习记录
@@ -153,6 +158,19 @@ public class StudyCourseApi extends ApiBaseController{
if(crowd!=null && crowd) {
rs.put("crowds",courseCrowdList);
}
boolean pass = false;
if (!courseCrowdList.isEmpty()) {
for (CourseCrowd c : courseCrowdList) {
//同一个受众,同一个只会有一条记录,所以这里就直接查询了
List<UserGroupItem> hasItem = userGroupService.findByGroupIdAndAid(c.getGroupId(),aid);
if (hasItem != null && !hasItem.isEmpty()) {
pass = true;
break;
}
}
}
List<CourseContent> cclist=contentService.getByCourseId(cid);
List<CourseSection> sectionlist=sectionService.getByCourseId(cid);
List<CourseTeacher> teachers=courseService.findTeachersByCourseId(cid);
@@ -165,8 +183,8 @@ public class StudyCourseApi extends ApiBaseController{
}
}
rs.put("isCrowd",pass);
rs.put("contents",cclist);
rs.put("sections",sectionlist);
rs.put("teachers",teachers);

View File

@@ -3,16 +3,8 @@ package com.xboe.system.user.api;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
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 com.xboe.common.PageList;
import com.xboe.common.Pagination;
import com.xboe.common.utils.IDGenerator;
@@ -24,8 +16,9 @@ import com.xboe.system.user.entity.Message;
import com.xboe.system.user.service.IMessageService;
import com.xboe.system.user.service.MessageSender;
import com.xboe.system.user.vo.BatchMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@@ -227,6 +220,23 @@ public class MessageApi extends ApiBaseController {
}
@GetMapping("/clearMessageNotCase")
public JsonResponse<Integer> clearMessageNotCase(){
String aid=getCurrent().getAccountId();
if(StringUtils.isBlank(aid)) {
return badRequest("获取用户信息异常");
}
try {
Integer type = service.clearMessageNotCase(aid);
return success(type);
} catch (Exception e) {
log.error("清空消息错误",e);
return error("清空消息失败",e.getMessage());
}
}
/**
* 移动端
* 消息页面,按用户分组返回 暂时不用

View File

@@ -1,15 +1,12 @@
package com.xboe.system.user.entity;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.IdEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -120,4 +117,10 @@ public class Message extends IdEntity {
@Column(name = "is_read")
private Boolean isRead;
/**
* 批次号
*/
@Column(name = "batch_id")
private String batchId;
}

View File

@@ -61,7 +61,14 @@ public interface IMessageService {
* @return
*/
void cleanByAcceptId(String aid);
/**
* 清楚消息排除推荐消息
* @param aid
* @return
*/
Integer clearMessageNotCase(String aid);
/**
* 批量设置已读
* */

View File

@@ -1,16 +1,15 @@
package com.xboe.system.user.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import cn.hutool.core.util.StrUtil;
import javax.annotation.Resource;
import com.xboe.core.orm.IFieldFilter;
import com.xboe.common.OrderCondition;
import com.xboe.core.orm.FilterCheckValue;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xboe.module.boecase.dao.CasesRecommendPushRecordDao;
import com.xboe.module.boecase.entity.CasesRecommendPushRecord;
import com.xboe.common.PageList;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.QueryBuilder;
@@ -19,6 +18,8 @@ import com.xboe.system.user.dao.MessageDao;
import com.xboe.system.user.entity.Message;
import com.xboe.system.user.service.IMessageService;
import com.xboe.system.user.vo.BatchMessage;
import org.apache.commons.collections4.CollectionUtils;
import java.util.stream.Collectors;
/**
* 消息
@@ -29,15 +30,18 @@ public class MessageServiceImpl implements IMessageService {
@Resource
private MessageDao dao;
@Resource
private CasesRecommendPushRecordDao casesRecommendPushRecordDao;
@Override
public PageList<Message> query(int pageIndex, int pageSize, String aid, Boolean isRead) {
QueryBuilder builder = QueryBuilder.from(Message.class);
builder.addOrder(OrderCondition.desc("id"));
builder.setPageIndex(pageIndex);
builder.setPageSize(pageSize);
builder.addFilter(FieldFilters.eq("acceptId",aid));
if(isRead!=null){
builder.addFilter(FieldFilters.eq("isRead",isRead));
builder.addFilter(FieldFilters.eq("acceptId", aid));
if (isRead != null) {
builder.addFilter(FieldFilters.eq("isRead", isRead));
}
PageList<Message> list = dao.findPage(builder.builder());
return list;
@@ -49,12 +53,12 @@ public class MessageServiceImpl implements IMessageService {
builder.addOrder(OrderCondition.desc("id"));
builder.setPageIndex(pageIndex);
builder.setPageSize(pageSize);
builder.addFilter(FieldFilters.eq("acceptId",aid));
builder.addFilter(FieldFilters.ne("refType","3"));
builder.addFilter(FieldFilters.ne("refType","6"));
builder.addFilter(FieldFilters.eq("acceptId", aid));
builder.addFilter(FieldFilters.ne("refType", "3"));
builder.addFilter(FieldFilters.ne("refType", "6"));
// builder.addFilter(FieldFilters.ne("refType","3", FilterCheckValue.NONE));
if(isRead!=null){
builder.addFilter(FieldFilters.eq("isRead",isRead));
if (isRead != null) {
builder.addFilter(FieldFilters.eq("isRead", isRead));
}
PageList<Message> list = dao.findPage(builder.builder());
return list;
@@ -63,15 +67,15 @@ public class MessageServiceImpl implements IMessageService {
@Override
@Transactional
public void delete(List<String> ids) {
dao.deleteByFilter(FieldFilters.in("id",ids));
dao.deleteByFilter(FieldFilters.in("id", ids));
}
@Override
@Transactional
public Message detail(String id) {
Message message = dao.get(id);
if(!message.getIsRead()){
dao.updateFieldById(id,"isRead",true);
if (!message.getIsRead()) {
dao.updateFieldById(id, "isRead", true);
}
return message;
}
@@ -85,8 +89,8 @@ public class MessageServiceImpl implements IMessageService {
@Override
public Integer isRead(String aid) {
QueryBuilder builder = QueryBuilder.from(Message.class);
builder.addFilter(FieldFilters.eq("isRead",false));
builder.addFilter(FieldFilters.eq("acceptId",aid));
builder.addFilter(FieldFilters.eq("isRead", false));
builder.addFilter(FieldFilters.eq("acceptId", aid));
PageList<Message> page = dao.findPage(builder.builder());
return page.getCount();
}
@@ -94,63 +98,122 @@ public class MessageServiceImpl implements IMessageService {
@Override
@Transactional
public void updateIsRead(List<String> ids) {
if (CollectionUtils.isEmpty(ids)) {
return;
}
dao.update(UpdateBuilder.from(Message.class)
.addUpdateField("isRead",true)
.addFilter(FieldFilters.in("id",ids))
.addUpdateField("isRead", true)
.addFilter(FieldFilters.in("id", ids))
.builder());
markCommendCaseStartRead(null, ids);
}
@Override
public Map<String, Object> messGroup(String aid) {
Map<String, Object> map = new HashMap<>();
QueryBuilder builder = QueryBuilder.from(Message.class);
builder.addFilter(FieldFilters.eq("acceptId",aid));
builder.addFilter(FieldFilters.eq("acceptId", aid));
builder.addGroupBy("acceptId");
List<Message> list = dao.findList(builder.builder());
map.put("mess",list);
map.put("mess", list);
//在查出未读消息数
String sql="select count(1) from boe_message where is_read=false and acceptId=?1";
String sql = "select count(1) from boe_message where is_read=false and acceptId=?1";
int count = dao.sqlCount(sql, aid);
map.put("count",count);
map.put("count", count);
return map;
}
@Override
@Transactional
public void remove(String aid) {
dao.deleteByFilter(FieldFilters.eq("acceptId",aid));
dao.deleteByFilter(FieldFilters.eq("acceptId", aid));
}
@Override
public List<Message> userMess(String aid) {
QueryBuilder builder = QueryBuilder.from(Message.class);
builder.addFilter(FieldFilters.eq("acceptId",aid));
builder.addFilter(FieldFilters.eq("acceptId", aid));
builder.addGroupBy("acceptId");
builder.addOrder(OrderCondition.desc("msgTime"));
List<Message> list = dao.findList(builder.builder());
return list;
}
@Override
@Transactional
public void setReadByAcceptId(String aid) {
dao.update("Update "+Message.class.getSimpleName()+" set isRead=?1 where acceptId=?2 and isRead=?3", true,aid,false);
}
@Override
@Transactional
public void setReadByAcceptId(String aid) {
dao.update("Update " + Message.class.getSimpleName() + " set isRead=?1 where acceptId=?2 and isRead=?3", true, aid, false);
markCommendCaseStartRead(aid, null);
}
private void markCommendCaseStartRead(String aid, List<String> ids) {
List<IFieldFilter> fieldFilters = new ArrayList<>();
if (StrUtil.isNotBlank(aid)) {
fieldFilters.add(FieldFilters.eq("acceptId", aid));
}
if (CollectionUtils.isNotEmpty(ids)) {
fieldFilters.add(FieldFilters.in("id", ids));
}
fieldFilters.add(FieldFilters.eq("refType", "99"));
List<Message> caseList = dao.findList(fieldFilters.toArray(new IFieldFilter[0]));
if (CollectionUtils.isEmpty(caseList)) {
return;
}
//单条推送
List<Message> singleList = caseList.stream().filter(message -> StrUtil.isNotBlank(message.getRefId()) && !message.getRefId().equals(message.getBatchId()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(singleList)) {
List<String> commendRecordIds = singleList.stream().map(Message::getRefId).collect(Collectors.toList());
casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
.addUpdateField("readStartTime", new Date())
// .addUpdateField("readEndTime", new Date())
.addFilter(FieldFilters.in("id", commendRecordIds))
.builder());
}
List<Message> mixList = caseList.stream().filter(message -> StrUtil.isNotBlank(message.getRefId()) && message.getRefId().equals(message.getBatchId())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(mixList)) {
List<String> commendIds = mixList.stream().map(Message::getRefId).collect(Collectors.toList());
casesRecommendPushRecordDao.update(UpdateBuilder.from(CasesRecommendPushRecord.class)
.addUpdateField("readStartTime", new Date())
// .addUpdateField("readEndTime", new Date())
.addFilter(FieldFilters.in("recommendId", commendIds))
.builder());
}
}
@Override
@Transactional
public Integer clearMessageNotCase(String aid) {
List<Message> caseList = dao.findList(FieldFilters.eq("acceptId", aid), FieldFilters.eq("refType", "99"));
List<Message> notCaseList = dao.findList(FieldFilters.eq("acceptId", aid), FieldFilters.ne("refType", "99"));
dao.deleteByFilter(FieldFilters.eq("acceptId", aid), FieldFilters.ne("refType", "99"));
if (CollectionUtils.isNotEmpty(caseList) && CollectionUtils.isEmpty(notCaseList)) {
return 1;
} else if (CollectionUtils.isEmpty(caseList) && CollectionUtils.isNotEmpty(notCaseList)) {
return 2;
}
return 3;
}
@Override
@Transactional
public void cleanByAcceptId(String aid) {
dao.deleteByField("acceptId", aid);
}
@Override
@Transactional
public void batchSave(List<Message> list) {
// for(Message msg : list) {
//
// }
dao.saveList(list);
}
dao.saveList(list);
}
}

View File

@@ -3,6 +3,9 @@ spring.redis.database=4
spring.redis.host=127.0.0.1
spring.redis.password=ENC(zA5LNV8xw3yEx6LMwdGGBGgNsOaD3Cg+)
spring.redis.port=6379
#spring.redis.host=124.70.92.162
#spring.redis.password=qwert!W577
#spring.redis.port=6379
# cloud nacos config
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
@@ -15,6 +18,9 @@ spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boeu_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=ENC(lAoFOYuc8CAypPtigTNLYg==)
#spring.datasource.url=jdbc:mysql://124.70.92.162:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
#spring.datasource.username=boe_base
#spring.datasource.password=k3DbtrcCkKAcFYzd
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
@@ -45,6 +51,7 @@ xboe.externalinterface.url.system=http://localhost:9091
## 新增加的教师的内部调用接口
xboe.old.base.url=https://u-pre.boe.com
#xboe.old.base.url=https://pretest.zcwytd.com
# 用户中心的接口配置
xboe.server.userbasic.url=https://u-pre.boe.com/userbasic
@@ -62,11 +69,14 @@ xboe.elasticsearch.server.ip=127.0.0.1
xboe.elasticsearch.server.port=9200
xboe.elasticsearch.server.user=
xboe.elasticsearch.server.password=
#xboe.elasticsearch.server.user=elastic
#xboe.elasticsearch.server.password=Boe@es123
# 默认搜索的索引
xboe.elasticsearch.index.name=new_resource_list
## 邮件的配置
xboe.email.url=https://u-pre.boe.com/api/b1/email/send
#xboe.email.url=https://pretest.zcwytd.com/api/b1/email/send
xboe.email.from=boeu_learning@boe.com.cn
xboe.email.user=
xboe.email.security=

View File

@@ -3,6 +3,10 @@ spring.redis.database=1
spring.redis.host=10.251.160.38
spring.redis.password=qwert!W577
spring.redis.port=6379
#spring.redis.database=3
#spring.redis.host=10.251.129.122
#spring.redis.password=qwert!W588
#spring.redis.port=6379
# cloud nacos config
spring.cloud.nacos.discovery.server-addr=10.251.181.11:8848

View File

@@ -75,4 +75,4 @@ xboe.elasticsearch.server.password=
xboe.email.url=https://u.boe.com/api/b1/email/send
xboe.email.from=boeu_learning@boe.com.cn
xboe.email.user=
xboe.email.security=
xboe.email.security=

View File

@@ -0,0 +1,69 @@
## redis
spring.redis.database=2
spring.redis.host=10.251.160.38
spring.redis.password=qwert!W577
spring.redis.port=6379
## datasource config
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driverClassName=com.mysql.jdbc.Driver
# spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.251.160.40:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=admin
spring.datasource.password=boeRds01
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
# 设置logback.xml位置
logging.config=classpath:log/logback-test.xml
server.tomcat.accept-count=1000
# 最大可被连接数默认10000
server.tomcat.max-connections=10000
# 最大工作线程数默认200,
server.tomcat.threads.max=500
# 最小工作线程数初始化分配线程数默认10
server.tomcat.threads.min-spare=100
# 定制KeepAliveTimeout设置30秒内没有请求则服务器自动断开keepalive连接
server.tomcat.keep-alive-timeout=3000
## 当客户端发送超过10000个请求则自动断开keepalive连接
server.tomcat.max-keep-alive-requests=10000
## xboe config
xboe.api.cross_filter=true
## 上传存储的路径配置
xboe.upload.file.temp_path=/tmp
xboe.upload.file.save_path=/home/www/elearning/upload
xboe.upload.file.http_path=http://10.251.160.135/upload
## 外部接口调用地址 旧系统机构及用户数据接口
xboe.externalinterface.url.system=http://127.0.0.1:9091
## 新增加的教师的内部调用接口
xboe.old.base.url=https://10.251.160.135
## 用户统计接口的api地址
xboe.stat.base.url=http://127.0.0.1:9080
xboe.server.userbasic.url=https://10.251.160.135/userbasic
#加密盐
#jasypt.encryptor.password=jasypt
jasypt.encryptor.algorithm=PBEWithMD5AndDES
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
# elasticsearch config
xboe.elasticsearch.server.ip=10.251.129.25
xboe.elasticsearch.server.port=9200
xboe.elasticsearch.server.user=elastic
xboe.elasticsearch.server.password=Boe@es123
## 邮件的配置
xboe.email.url=https://10.251.160.135/api/b1/email/send
xboe.email.from=boeu_learning@boe.com.cn
xboe.email.user=
xboe.email.security=

View File

@@ -2,15 +2,10 @@ spring.profiles.active=@profileActive@
spring.application.name=boe-server-all
server.port=9090
server.servlet.session.timeout=30m
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.tomcat.uri-encoding=UTF-8
ok.http.connect-timeout=30
ok.http.read-timeout=30
ok.http.write-timeout=30
@@ -18,7 +13,6 @@ ok.http.write-timeout=30
ok.http.max-idle-connections=200
# 连接空闲时间最多为 300 秒
ok.http.keep-alive-duration=300
#spring.jackson.locale=
#spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
# spring.jackson.default-property-inclusion=NON_NULL
@@ -26,7 +20,6 @@ spring.jackson.time-zone=GMT+8
spring.servlet.multipart.max-file-size=1024MB
spring.servlet.multipart.max-request-size=1024MB
## 静态文件目录默认是在static下面以后独立到nginx下面配置
spring.mvc.static-path-pattern=/cdn/**
@@ -40,6 +33,8 @@ spring.redis.lettuce.shutdown-timeout=100ms
# 上传的临时目录,部署到服务器必须指定
# spring.servlet.multipart.location=
# 上传的临时目录,部署到服务器必须指定
# spring.servlet.multipart.location=
# jpa config
spring.jpa.database = MYSQL
spring.jpa.show-sql = false
@@ -56,8 +51,13 @@ spring.jpa.properties.hibernate.current_session_context_class=org.springframewor
# 设置logback.xml位置
logging.config=classpath:log/logback-@profileActive@.xml
# 用于分布式id生成不重复的处理 配置0-31 的数值
# config.id.generator.server.num=1
# config.id.generator.datacenter.num=1
boe.domain=https://pretest.zcwytd.com
orgTree.orgTreeList=${boe.domain}/userbasic/org/list
# ????id????????????
orgTree.orgChildTreeList=${boe.domain}/userbasic/org/childOrgs
userBasic.searchUserList=${boe.domain}/userbasic/user/list
audience.usersByAudienceList=${boe.domain}/userbasic/audience/memberList

View File

@@ -12,7 +12,5 @@ class BoeServerAllApplicationTests {
// System.out.println(IDGenerator.generate());
// }
}
}

View File

@@ -0,0 +1,28 @@
package com.xboe.module.boecase.dao;
import com.xboe.module.boecase.entity.CasesMajorType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@ActiveProfiles("dev")
class CasesMajorTypeRepoDaoTest {
@Autowired
private CasesMajorTypeRepoDao casesMajorTypeRepoDao;
// @Test
void findCasesBy() {
ArrayList<String> params = new ArrayList<>();
params.add("27737267694995149");
List<CasesMajorType> majorTypes = casesMajorTypeRepoDao.findCasesBy(params);
System.out.println(majorTypes);
}
}

View File

@@ -0,0 +1,36 @@
package com.xboe.module.boecase.dao;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.module.boecase.dto.CasePageVo;
import com.xboe.module.boecase.entity.Cases;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@ActiveProfiles("dev")
class CasesRecordDaoTest {
@Autowired
private CasesRecordDao casesRecordDao;
// @Test
void queryList() throws JsonProcessingException {
PageRequest of = PageRequest.of(0, 10);
String jsonStr = "{\"pageIndex\":1,\"pageSize\":10,\"orderField\":\"excellent\",\"majorType\":\"\",\"orgDomainDtos\":[],\"orderAsc\":false,\"excellent\":true,\"breCommend\":true,\"caseType\":\"\",\"authorName\":\"\",\"notInIds\":[],\"type\":\"recommend\",\"userId\":\"\",\"parent\":\"\",\"children\":[],\"name\":\"\",\"years\":[2023,2022,2020,2021]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
CasePageVo pageVo = mapper.readValue(jsonStr, CasePageVo.class);
pageVo.setUserId("965341999643234304");
Page<Cases> cases = casesRecordDao.queryList(of, pageVo);
System.out.println(cases);
}
}

View File

@@ -0,0 +1,60 @@
package com.xboe.module.boecase.service.impl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.common.PageList;
import com.xboe.core.CurrentUser;
import com.xboe.module.boecase.dto.CasePageVo;
import com.xboe.module.boecase.entity.Cases;
import com.xboe.module.boecase.service.ICasesService;
import com.xboe.school.vo.CasesVo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
// @SpringBootTest
// @ActiveProfiles("dev")
class CasesServiceImplTest {
@Autowired
private ICasesService casesService;
// @Test
void queryPageCasesV2() throws JsonProcessingException {
String jsonStr = "{\"pageIndex\":1,\"pageSize\":10,\"orderField\":\"excellent\",\"majorType\":\"\",\"orgDomainDtos\":[],\"orderAsc\":false,\"excellent\":true,\"breCommend\":true,\"caseType\":\"\",\"authorName\":\"\",\"notInIds\":[],\"type\":\"recommend\",\"userId\":\"\",\"parent\":\"\",\"children\":[],\"name\":\"\",\"years\":[2023,2022,2020,2021]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
CasePageVo pageVo = mapper.readValue(jsonStr, CasePageVo.class);
pageVo.setUserId("965342027497607168");
PageList<Cases> casesV2 = casesService.queryPageCasesV2(pageVo);
System.out.println(casesV2);
}
// @Test
void queryRecommendPageCasesV2() throws JsonProcessingException {
String jsonStr = "{\"pageIndex\":1,\"pageSize\":5,\"majorType\":\"\",\"orderAsc\":false,\"excellent\":false,\"orgDomainDtos\":[],\"caseType\":\"\",\"authorName\":\"\",\"notInIds\":[],\"type\":\"recommend\",\"userId\":\"\",\"parent\":\"\",\"children\":[],\"name\":\"\",\"years\":[2023]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
CasePageVo pageVo = mapper.readValue(jsonStr, CasePageVo.class);
pageVo.setUserId("965342027497607168");
PageList<Cases> casesV2 = casesService.queryRecommendPageCasesV2(pageVo);
System.out.println(casesV2);
}
// @Test
void queryCaseV2() {
CurrentUser currentUser = new CurrentUser();
currentUser.setAccountId("965342027497607168");
List<CasesVo> list = casesService.caseIndexV2(currentUser);
System.out.println(list);
}
}

View File

@@ -1,12 +1,14 @@
# redis
spring.redis.database=2
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.password=ENC(zA5LNV8xw3yEx6LMwdGGBGgNsOaD3Cg+)
spring.redis.port=6379
# datasource config
# basic数据库
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

View File

@@ -0,0 +1,40 @@
package com.xboe.constants;
/**
* @author : civism
* @version 1.0
* @date 2023/6/17 16:13
*/
public enum CasesPushStatusEnum {
/**
* 推送状态1未推送2推送中3已推送4推送失败5已撤回
*/
WAIT_PUSH(1,"未推送"),
PUSH_ING(2,"推送中"),
PUSH_SUCCESS(3,"已推送"),
PUSH_FAIL(4,"推送失败"),
PUSH_REVOKE(5,"已撤回"),
;
CasesPushStatusEnum(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
private Integer status;
private String desc;
public Integer getStatus() {
return status;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,10 @@
package com.xboe.module.cases.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.cases.entity.CasesRecommend;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendDao extends BaseDao<CasesRecommend> {
}

View File

@@ -0,0 +1,9 @@
package com.xboe.module.cases.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.cases.entity.CasesRecommendPushRecord;
import org.springframework.stereotype.Repository;
@Repository
public class CasesRecommendPushRecordDao extends BaseDao<CasesRecommendPushRecord> {
}

View File

@@ -0,0 +1,69 @@
package com.xboe.module.cases.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
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 java.time.LocalDateTime;
/**
* 案例推荐表
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_recommend")
public class CasesRecommend extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 推荐人ID
*/
@Column(name = "recommend_id", length = 100)
private String recommendId;
/**
* 推荐人
*/
@Column(name = "recommend_by", length = 255)
private String recommendBy;
/**
* 推荐时间
*/
@Column(name = "recommend_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime recommendTime;
/**
* 案例数
*/
@Column(name = "case_count", length = 11)
private Integer caseCount;
/**
* 用户数
*/
@Column(name = "user_count", length = 11)
private Integer userCount;
/**
* 推送进度
*/
@Column(name = "push_progress")
private Integer pushProgress;
/**
* 查看率
*/
@Column(name = "view_rate", length = 255)
private String viewRate;
/**
* 推荐组织名称
*/
@Column(name = "recommend_org_name", length = 255)
private String recommendOrgName;
}

View File

@@ -0,0 +1,95 @@
package com.xboe.module.cases.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 java.util.Date;
/**
* 案例推荐发起导入
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SysConstant.TABLE_PRE + "cases_recommend_push_record")
public class CasesRecommendPushRecord extends BaseEntity {
/**
* 推送id
*/
@Column(name = "recommend_id")
private String recommendId;
/**
* 案例id
*/
@Column(name = "case_id")
private String caseId;
/**
* 案例标题
*/
@Column(name = "case_title")
private String caseTitle;
/**
* 推送用户id
*/
@Column(name = "push_user_id")
private String pushUserId;
/**
* 推送用户名称
*/
@Column(name = "push_user_name")
private String pushUserName;
/**
* 推送状态1未推送2推送中3已推送4推送失败5已撤回
*/
@Column(name = "push_status")
private Integer pushStatus;
/**
* 推送时间
*/
@Column(name = "push_time")
private Date pushTime;
/**
* 查看标识
*/
@Column(name = "read_flag")
private Integer readFlag;
/**
* 首次查看时间
*/
@Column(name = "read_start_time")
private Date readStartTime;
/**
* 最后查看时间
*/
@Column(name = "read_end_time")
private Date readEndTime;
/**
* 备注
*/
@Column(name = "remark")
private String remark;
}

View File

@@ -0,0 +1,24 @@
package com.xboe.module.cases.service;
import com.xboe.module.cases.entity.CasesRecommendPushRecord;
import java.util.List;
public interface ICasesRecommendPushRecordService {
/**
* 查询推送纪录通过推送状态
*
* @param pushStatusList
* @return
*/
List<CasesRecommendPushRecord> queryPushRecordByPushStatus(List<Integer> pushStatusList);
/**
* 修改
* @param pushStatus
* @return
*/
boolean updatePushRecordStatus(String id,Integer pushStatus);
}

View File

@@ -0,0 +1,25 @@
package com.xboe.module.cases.service;
import com.xboe.module.cases.entity.CasesRecommend;
import java.util.List;
public interface ICasesRecommendService {
/**
* 通过推送状态查询
*
* @param pushProgress
* @return
*/
List<CasesRecommend> queryByPushProgress(Integer pushProgress);
/**
* 修改
*
* @param casesRecommend
* @return
*/
public boolean updateProcessStatus(String id, Integer pushProgress);
}

View File

@@ -0,0 +1,34 @@
package com.xboe.module.cases.service.impl;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.cases.dao.CasesRecommendPushRecordDao;
import com.xboe.module.cases.entity.CasesRecommendPushRecord;
import com.xboe.module.cases.service.ICasesRecommendPushRecordService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
@Transactional
public class CasesRecommendPushRecordServiceImpl implements ICasesRecommendPushRecordService {
@Resource
private CasesRecommendPushRecordDao casesRecommendPushRecordDao;
@Override
public List<CasesRecommendPushRecord> queryPushRecordByPushStatus(List<Integer> pushStatusList) {
return casesRecommendPushRecordDao.getGenericDao().findList(CasesRecommendPushRecord.class, FieldFilters.in("push_status", pushStatusList));
}
@Override
public boolean updatePushRecordStatus(String id, Integer pushStatus) {
return casesRecommendPushRecordDao.updateMultiFieldById(id, UpdateBuilder.create("pushStatus", pushStatus), UpdateBuilder.create("pushTime", new Date())) > 0;
}
}

View File

@@ -0,0 +1,31 @@
package com.xboe.module.cases.service.impl;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.cases.dao.CasesRecommendDao;
import com.xboe.module.cases.entity.CasesRecommend;
import com.xboe.module.cases.service.ICasesRecommendService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Service
@Transactional
public class CasesRecommendServiceImpl implements ICasesRecommendService {
@Resource
private CasesRecommendDao casesRecommendDao;
@Override
public List<CasesRecommend> queryByPushProgress(Integer pushProgress) {
return casesRecommendDao.getGenericDao().findList(CasesRecommend.class, FieldFilters.eq("pushProgress", pushProgress));
}
@Override
public boolean updateProcessStatus(String id, Integer pushProgress) {
return casesRecommendDao.updateMultiFieldById(id, UpdateBuilder.create("pushProgress", pushProgress)) > 0;
}
}

View File

@@ -0,0 +1,82 @@
package com.xboe.stat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.core.SysConstant;
import com.xboe.core.api.TokenProxy;
import com.xboe.core.event.IEventDataSender;
import com.xboe.core.utils.OkHttpUtil;
import com.xboe.standard.BaseConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* 事件数据发送实现,如果是云环境,只需要修改此类的实现就可以了
* @author seastar
*
*/
@Slf4j
@Component
public class EventDataSender implements IEventDataSender{
@Autowired
private OkHttpUtil okHttpUtil;
@Autowired
private HttpServletRequest request;
@Override
public void send(String title, String eventKey, String content, String objId, String objType, String objInfo,
String aid, String aname,String parameters) {
String statBaseUrl=SysConstant.getConfigValue("xboe.stat.base.url");
if(StringUtils.isBlank(statBaseUrl)) {
log.error("发送事件失败:未配置【xboe.stat.base.url】的值");
return;
}
String urlPre="/xboe/m/stat/event/send";
//案例同步不需要token
if(eventKey.equals("SyncCase")) {
urlPre ="/inner/stat/event/send";
}
final String url = statBaseUrl + urlPre;
Map<String, String> params = new HashMap<>();
params.put("title", title);
params.put("source", "all");
params.put("content", content);
params.put("objId", objId);
params.put("key", eventKey);
params.put("objType", objType);
params.put("objInfo", objInfo);
params.put("aid", aid);
params.put("aname", aname);
params.put("parameters",parameters);
String token = TokenProxy.getToken(request);
//最后采用异常发送,不影响当前进程
new Thread(()->{
try {
ObjectMapper mapper=new ObjectMapper();
String json =mapper.writeValueAsString(params);
//String[] headers=new String[] {"token",token};
String[] headers=new String[] {BaseConstant.HTTP_ACCESS_TOKEN,token};
String responseStr = okHttpUtil.doPostJson(url, json,headers);
if(responseStr.indexOf("\"status\":200")==-1) {
log.error("发送事件失败:"+responseStr);
log.info("【发送的token】"+headers[0]+" "+headers[1]);
}
}catch(Exception e) {
log.error("发送事件错误",e);
}
}).start();
}
}

View File

@@ -0,0 +1,88 @@
package com.xboe.task;
import com.xboe.constants.CasesPushStatusEnum;
import com.xboe.core.event.IEventDataSender;
import com.xboe.module.cases.entity.CasesRecommend;
import com.xboe.module.cases.entity.CasesRecommendPushRecord;
import com.xboe.module.cases.service.ICasesRecommendPushRecordService;
import com.xboe.module.cases.service.ICasesRecommendService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author : civism
* @version 1.0
* @date 2023/6/18 10:50
*/
@EnableScheduling
@Component("com.xboe.casetask.CasesRecommendPushSchedule")
@Slf4j
public class CasesRecommendPushSchedule {
@Resource
private ICasesRecommendService casesRecommendService;
@Resource
private ICasesRecommendPushRecordService casesRecommendPushRecordService;
@Autowired(required = false)
private IEventDataSender eventDataSender;
/**
* 每分钟执行一次
*/
// @Scheduled(cron = "0 */1 * * * ?")
public void execute() {
log.info("启动案例推荐定时任务");
List<CasesRecommend> casesRecommends = casesRecommendService.queryByPushProgress(CasesPushStatusEnum.WAIT_PUSH.getStatus());
if (CollectionUtils.isEmpty(casesRecommends)) {
log.warn("没有推送纪录,无需推送");
return;
}
for (CasesRecommend casesRecommend : casesRecommends) {
List<Integer> pushStatusList = new ArrayList<>();
pushStatusList.add(CasesPushStatusEnum.WAIT_PUSH.getStatus());
pushStatusList.add(CasesPushStatusEnum.WAIT_PUSH.getStatus());
List<CasesRecommendPushRecord> casesRecommendPushRecords = casesRecommendPushRecordService.queryPushRecordByPushStatus(pushStatusList);
if (CollectionUtils.isEmpty(casesRecommendPushRecords)) {
//修改为推送完成 --- 无数据 无需推送
casesRecommendService.updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
continue;
}
//修改为推送中
casesRecommendService.updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_ING.getStatus());
for (CasesRecommendPushRecord casesRecommendPushRecord : casesRecommendPushRecords) {
Integer pushStatus;
try {
eventDataSender.send("案例推荐", "recommendCases", "案例推荐【" + casesRecommendPushRecord.getCaseTitle() + "",
casesRecommendPushRecord.getCaseId(), "99", casesRecommendPushRecord.getCaseTitle(),
casesRecommendPushRecord.getSysCreateAid(), casesRecommendPushRecord.getSysCreateBy(), "");
pushStatus = CasesPushStatusEnum.PUSH_SUCCESS.getStatus();
} catch (Exception e) {
log.error("推荐案例失败", e);
pushStatus = CasesPushStatusEnum.PUSH_FAIL.getStatus();
}
casesRecommendPushRecordService.updatePushRecordStatus(casesRecommendPushRecord.getId(), pushStatus);
}
//修改为推送完成 --- 无数据 无需推送
casesRecommendService.updateProcessStatus(casesRecommend.getId(), CasesPushStatusEnum.PUSH_SUCCESS.getStatus());
log.info("启动案例推荐定时任务----结束");
}
}
}

View File

@@ -13,6 +13,7 @@ spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.10:3306/boe_base1?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=ENC(lAoFOYuc8CAypPtigTNLYg==)
#spring.jpa.hibernate.ddl-auto=none
# logging.level.org.hibernate.SQL=DEBUG
# logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
@@ -33,6 +34,7 @@ xboe.upload.file.http_path=http://localhost:9090/cdn/upload
## 外部接口调用地址 旧系统机构及用户数据接口
xboe.externalinterface.url.system=http://localhost:9091
xboe.stat.base.url=http://127.0.0.1:9080
#加密盐
#jasypt.encryptor.password=jasypt

View File

@@ -1,6 +1,7 @@
# datasource config
# basic数据库
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true