Compare commits

..

27 Commits

Author SHA1 Message Date
yang
85517dcd57 随机选题,bug 2024-10-09 14:57:56 +08:00
yang
9da0eae4c0 考试随机选题 2024-10-08 19:27:46 +08:00
yang
74a36d72a1 作业导出,考试随机选题 2024-10-08 17:40:28 +08:00
yang
516225f52e 作业导出,案例类型处理代码回退版本 2024-09-27 22:38:35 +08:00
nisen
e3c060b8d9 Merge remote-tracking branch 'yx/zcwy0913-yang-case-prod' 2024-09-27 18:00:06 +08:00
nisen
72783fb1ac Merge remote-tracking branch 'yx/zcwy0923-wjwyyk-online-prod2' 2024-09-27 17:59:32 +08:00
nisen
f5f8fcee98 Merge branch 'zcwy0912-llf' into 104-master 2024-09-27 17:47:55 +08:00
yang
003d227ba3 案例萃取,案例榜单排序,定时任务 2024-09-27 17:07:24 +08:00
yang
e6bd808a3d 作业导出,删除注释代码 2024-09-27 16:46:50 +08:00
yang
b87eb65b3e Merge branch 'refs/heads/zcwy-0724-wjw-online-prod' into zcwy0923-wjwyyk-online2
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/api/ThirdApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CoursePortalApi.java
2024-09-27 16:07:55 +08:00
yang
28af48581e 作业导出,相关bug修复与补充
作业导出,计算时长

作业导出,分数设置

作业导出,最高分、与作业完成时间

作业导出,考试

作业导出,模糊搜索

作业导出,优化导包

在线导出

作业导出,token

作业导出,bug修复
2024-09-27 16:00:32 +08:00
zhaolongfei
57e04f46c0 试题管理模板修改 2024-09-27 14:22:51 +08:00
nisen
6a04082245 Merge remote-tracking branch '104/master' into 104-master 2024-09-18 11:00:56 +08:00
nisen
81a1a88eab Merge branch 'zcwy0912-llf' into 104-master 2024-09-18 11:00:13 +08:00
nisen
1dfdc9277d Merge branch 'zcwy-0913-yang-case' 2024-09-14 13:51:27 +08:00
yang
7c840d2bfc 案例萃取,案例标签 2024-09-14 13:49:22 +08:00
nisen
48e2adad7f Merge branch 'zcwy-0913-yang-case' 2024-09-14 13:26:46 +08:00
yang
e04735ee44 案例萃取,最佳时间 2024-09-14 13:25:02 +08:00
yang
c2de2a433b 案例萃取,类型修改 2024-09-14 13:15:21 +08:00
nisen
cb0e784d5e Merge branch 'zcwy-0913-yang-case' 2024-09-14 13:04:00 +08:00
yang
e6feea6dbf 案例萃取,类型修改 2024-09-14 12:52:37 +08:00
nisen
012f987de0 案例萃取,暂时注释代码 2024-09-14 12:33:31 +08:00
yang
3cbef3e3f7 案例萃取 2024-09-14 10:48:00 +08:00
zhaolongfei
2e2edbbf57 试题管理模板修改 2024-09-13 16:02:26 +08:00
zhaolongfei
beba553faa 试题管理模板修改 2024-09-13 15:08:45 +08:00
lu
2c967cef0a 作业导出500 2024-09-10 17:10:48 +08:00
lu
45fce7927d 作业导出修改名称 2024-09-03 11:21:37 +08:00
47 changed files with 1972 additions and 714 deletions

View File

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

View File

@@ -4,13 +4,11 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.shaded.com.google.gson.*;
import com.xboe.api.vo.*; import com.xboe.api.vo.*;
import com.xboe.module.course.vo.StudyCourseVo; import com.xboe.module.course.vo.StudyCourseVo;
import com.xboe.module.course.vo.TeacherInfoVo; import com.xboe.module.course.vo.TeacherInfoVo;
import com.xboe.module.course.vo.TeacherVo; import com.xboe.module.course.vo.TeacherVo;
import com.xboe.module.dict.entity.DictDto; import com.xboe.module.dict.entity.DictDto;
import com.xboe.module.exam.entity.AloneExam;
import com.xboe.module.exam.entity.ExamTest; import com.xboe.module.exam.entity.ExamTest;
import com.xboe.school.study.entity.StudyCourse; import com.xboe.school.study.entity.StudyCourse;
import com.xboe.system.user.dao.UserDao; import com.xboe.system.user.dao.UserDao;
@@ -19,8 +17,13 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*; import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@@ -66,8 +69,8 @@ public class ThirdApi {
@Value("${manageApi.editExam}") @Value("${manageApi.editExam}")
private String editExam; private String editExam;
@Value("${coursesuilt.syncExamScoreToCourseSuite}") @Value("${userBasic.getUserBasicInfo}")
private String syncExamScoreToCourseSuite; private String getUserBasicInfo;
//获取例外人员的id //获取例外人员的id
public List<String> getUserId(){ public List<String> getUserId(){
@@ -237,21 +240,66 @@ public class ThirdApi {
} }
public void syncExamScoreToCourseSuite(AloneExam aloneExam,String token) { /**
Gson gson = new GsonBuilder() * 获取案例浏览记录
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()) */
.create(); public UserDynamicResult getAllUserdynamicListOfCaseRead(UserdynamicParam userdynamicParam, String token) {
String s = buildFormData(userdynamicParam);
String resp = Optional.ofNullable(HttpRequest
.post(userdynamicListUrl)
.header("Content-Type", "application/x-www-form-urlencoded")
.body(s)
.header("XBOE-Access-Token", token)
.execute().body()).orElseThrow(() -> new RuntimeException("token校验失败"));
String json = gson.toJson(aloneExam); DynamicBean dynamicBean = JSONUtil.toBean(resp, DynamicBean.class);
String resp = HttpRequest.post(syncExamScoreToCourseSuite) UserDynamicResult userdynamicResult = dynamicBean.getResult();
.body(json) return userdynamicResult;
.header("token", token) }
.execute()
.body();
if (StringUtils.isBlank(resp)){ private String buildFormData(UserdynamicParam param) {
return; StringBuilder builder = new StringBuilder();
try {
builder.append("pageIndex=").append(URLEncoder.encode(param.getPageIndex().toString(), "UTF-8"));
builder.append("&pageSize=").append(URLEncoder.encode(param.getPageSize().toString(), "UTF-8"));
builder.append("&contentType=").append(URLEncoder.encode(param.getContentType().toString(), "UTF-8"));
builder.append("&aid=").append(URLEncoder.encode(param.getAid().toString(), "UTF-8"));
builder.append("&eventKey=").append(URLEncoder.encode("ReadCase", "UTF-8"));
if (param.getHidden() != null) {
builder.append("&hidden=").append(URLEncoder.encode(param.getHidden(), "UTF-8"));
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} }
JSONUtil.toBean(resp, SyncExamScoreBean.class).success(); return builder.toString();
}
/**
* 虽然当前已存在接口查询用户基本信息目前仅仅包括用户名、工号、用户ID
*/
public List<UserBasicInfo> getUserBasicInfoByUserId(List<String> userIds, HttpServletRequest request) {
String token = request.getHeader("Xboe-Access-Token");
if (StringUtils.isEmpty(token)) {
token = request.getHeader("token");
}
if (StringUtils.isEmpty(token)) {
token = request.getHeader("x-access-token");
}
// 将userIds列表转换为逗号分隔的字符串
String userIdsStr = userIds.stream()
.collect(Collectors.joining(","));
String url = getUserBasicInfo +"?userIds=" + userIdsStr;
String respStr = Optional.ofNullable(HttpRequest
.get(url)
.header("token", token)
.execute().body()).orElseThrow(() -> new RuntimeException("用户中心用户数据获取失败"));
UserBasicInfoResult userBasicInfoResult = JSONUtil.parseObj(respStr).toBean(UserBasicInfoResult.class);
List<UserBasicInfo> basicInfos = userBasicInfoResult.getResult();
return basicInfos;
} }
} }

View File

@@ -1,31 +0,0 @@
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;
@Data
@Slf4j
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CheckExamBandingBean {
private boolean show;
private String version;
private int code;
private String msg;
private Object data;
private boolean success;
public CheckExamBandingBean success() {
if (this.code!=200) {
log.error("获取绑定关系失败----{}", JSONUtil.toJsonPrettyStr(this));
return null;
}
return this;
}
}

View File

@@ -1,19 +0,0 @@
package com.xboe.api.vo;
import com.alibaba.nacos.shaded.com.google.gson.JsonElement;
import com.alibaba.nacos.shaded.com.google.gson.JsonPrimitive;
import com.alibaba.nacos.shaded.com.google.gson.JsonSerializationContext;
import com.alibaba.nacos.shaded.com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class LocalDateTimeSerializer implements JsonSerializer<LocalDateTime> {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(formatter.format(src));
}
}

View File

@@ -1,31 +0,0 @@
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;
@Data
@Slf4j
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SyncExamScoreBean {
private boolean show;
private String version;
private int code;
private String msg;
private Object data;
private boolean success;
public SyncExamScoreBean success() {
if (this.code!=200) {
log.error("同步考试到boe库失败----{}", JSONUtil.toJsonPrettyStr(this));
return null;
}
return this;
}
}

View File

@@ -0,0 +1,23 @@
package com.xboe.api.vo;
import lombok.Data;
@Data
public class UserBasicInfo {
/**
* 用户ID
*/
private String userId;
/**
* 用户名。
*/
private String userName;
/**
* 工号。
*/
private String workNum;
}

View File

@@ -8,31 +8,26 @@ import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Date; import java.util.Date;
import java.util.HashMap; 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 @Data
@Slf4j @Slf4j
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class GetUserIdByWorkNumResult { public class UserBasicInfoResult {
private String error; private String error;
private String message; private String message;
private String permissions; private String permissions;
private HashMap<String,String> result; private List<UserBasicInfo> result;
private int status; private int status;
private Date timestamp; private Date timestamp;
public GetUserIdByWorkNumResult success() { public UserBasicInfoResult success() {
if (this.status != 200) { if (this.status != 200) {
log.error("获取用户ID列表失败----{}", JSONUtil.toJsonPrettyStr(this)); log.error("获取用户基本信息失败----{}", JSONUtil.toJsonPrettyStr(this));
return null; return null;
} }
return this; return this;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,88 @@
package com.xboe.module.boecase.dao;
import com.xboe.core.orm.BaseDao;
import com.xboe.module.boecase.entity.CasesRank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@Repository
@Slf4j
public class CasesRankDao extends BaseDao<CasesRank> {
/**
* 获取类别榜记录,默认按上榜时间降序排列
*/
public List<CasesRank> findViewsRankRecordByCaseId(String caseId) {
String sql =
"SELECT bdmt.name,bcvr.rise_rank_time,bcvr.rank,bcvr.major_id \n" +
"FROM\n" +
" boe_cases_rank bcvr\n" +
"JOIN boe_dict_major_type bdmt \n" +
" ON bdmt.code = bcvr.major_id \n" +
"WHERE bcvr.case_id = ?1 AND bcvr.deleted=0 AND bdmt.deleted=0\n" +
"ORDER BY bcvr.rise_rank_time DESC;";
List<Object[]> list = this.sqlFindList(sql, caseId);
List<CasesRank> resultList = new ArrayList<>();
for (Object[] o : list) {
CasesRank casesRank = new CasesRank();
casesRank.setMajorName(o[0].toString());
casesRank.setRiseRankTime(((Timestamp) o[1]).toLocalDateTime());
casesRank.setRank(Integer.valueOf(o[2].toString()));
casesRank.setMajorId(o[3].toString());
resultList.add(casesRank);
}
return resultList;
}
public HashMap<String, Object> findViewTopCount(List<String> authorIdList) {
String sql=
"SELECT author_id,COUNT(1) as viewTopCount\n" +
"FROM boe_cases bc JOIN boe_cases_rank bcvr ON bcvr.case_id = bc.id\n" +
"WHERE bc.author_id IN (?1) \n" +
" AND bcvr.deleted = 0 \n" +
" AND bc.deleted = 0\n" +
"GROUP BY bc.author_id;";
List<Object[]> list = this.sqlFindList(sql, authorIdList);
HashMap<String, Object> map = new HashMap<>();
list.forEach(objects -> {
String authorId = objects[0].toString();
Integer viewTopCount = Integer.parseInt(objects[1].toString());
map.put(authorId, viewTopCount);
});
return map;
}
public List<HashMap<String, Object>> findPopularityOfMajor(Integer pageSize, LocalDateTime startTime, LocalDateTime endTime, String majorId) {
String sql =
"SELECT bcr.case_id,bcr.rank\n" +
"FROM boe_cases_rank bcr\n" +
"JOIN boe_cases bc on bcr.case_id = bc.id\n" +
"WHERE bcr.deleted=0 AND bc.deleted=0 AND bcr.rise_rank_time BETWEEN ?1 and ?2 AND major_id=?3\n" +
"ORDER BY rank\n" +
"LIMIT ?4";
List<Object[]> listFields = this.sqlFindList(sql, startTime, endTime,majorId,pageSize);
List<HashMap<String, Object>> collect = listFields.stream().map(item -> {
HashMap<String, Object> map = new HashMap<>();
map.put("caseId", item[0].toString());
map.put("rank", item[1].toString());
return map;
}).collect(Collectors.toList());
return collect;
}
}

View File

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

View File

@@ -3,6 +3,7 @@ package com.xboe.module.boecase.entity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant; import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity; import com.xboe.core.orm.BaseEntity;
import com.xboe.module.boecase.vo.CaseViewRankingItemVo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -248,16 +249,7 @@ public class Cases extends BaseEntity {
@Column(name = "case_value") @Column(name = "case_value")
private String caseValue; private String caseValue;
// 种类字段1
// 暂不上线
// @Column(name = "sys_type1")
// private String sysType1;
//种类字段2
// @Column(name = "sys_type2")
// private String sysType2;
//种类字段3
// @Column(name = "sys_type3")
// private String sysType3;
/** /**
* 最佳案例标识 * 最佳案例标识
@@ -272,6 +264,48 @@ public class Cases extends BaseEntity {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime excellentTime; private LocalDateTime excellentTime;
/**
* 最佳时间
* */
@Column(name = "excellent_reason")
private String excellentReason;
/**
* 上月浏览量
*/
@Column(name = "last_month_views")
private Integer lastMonthViews;
/**
* 上季度浏览量
*/
@Column(name = "last_quarter_views")
private Integer lastQuarterViews;
/**
* 上季度点赞量
*/
@Column(name = "last_quarter_praises")
private Integer lastQuarterPraises;
/**
* 推荐榜排序
* */
@Column(name = "recommend_rank")
private Integer recommendRank;
/**
* 推送用户名称
*/
@Column(name = "recommend_rank_push_user_name")
private String recommendRankPushUserName;
/**
* 推送时间
*/
@Column(name = "recommend_rank_push_time")
private LocalDateTime recommendRankPushTime;
/** /**
* type 种类 * type 种类
* 区分 案例/推荐案例 * 区分 案例/推荐案例
@@ -279,11 +313,6 @@ public class Cases extends BaseEntity {
@Transient @Transient
private String type; private String type;
/**
* id
*/
@Transient @Transient
private List<String> majorIds; private List<String> majorIds;
@@ -296,6 +325,15 @@ public class Cases extends BaseEntity {
@Transient @Transient
private String refId; private String refId;
@Transient
private String excellentTag;
@Transient
private List<CaseViewRankingItemVo> viewRankTags;
@Transient
private List<String> authorTags;
public String getRefId() { public String getRefId() {
return refId; return refId;
} }
@@ -380,7 +418,7 @@ public class Cases extends BaseEntity {
this.title=title; this.title=title;
} }
public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted
,String sysCreateBy,String sysCreateAid){ ,String sysCreateBy,String sysCreateAid){
this.title=title; this.title=title;
super.setId(id); super.setId(id);
this.authorId=authorId; this.authorId=authorId;
@@ -398,7 +436,6 @@ public class Cases extends BaseEntity {
this.favorites=favorites; this.favorites=favorites;
super.setDeleted(deleted); super.setDeleted(deleted);
} }
public Cases(String title) { public Cases(String title) {
this.title = title; this.title = title;
} }
@@ -415,4 +452,29 @@ public class Cases extends BaseEntity {
this.authorName = authorName; this.authorName = authorName;
this.confidentialityLevel = confidentialityLevel; this.confidentialityLevel = confidentialityLevel;
} }
public Cases(String id,String title,String summary,String coverUrl,String authorId,String authorName,LocalDateTime sysCreateTime,Integer breCommend,Integer views,Integer comments,Integer praises,Integer shares,Integer favorites,Boolean deleted
,String sysCreateBy,String sysCreateAid,String keyword1,String keyword2,String keyword3,String keyword4,String keyword5){
this.title=title;
super.setId(id);
this.authorId=authorId;
this.authorName=authorName;
super.setSysCreateTime(sysCreateTime);
super.setSysCreateAid(sysCreateAid);
super.setSysCreateBy(sysCreateBy);
this.summary=summary;
this.coverUrl=coverUrl;
this.breCommend=breCommend;
this.views=views;
this.comments=comments;
this.praises=praises;
this.shares=shares;
this.favorites=favorites;
this.keyword1=keyword1;
this.keyword2=keyword2;
this.keyword3=keyword3;
this.keyword4=keyword4;
this.keyword5=keyword5;
super.setDeleted(deleted);
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,13 +4,10 @@ import java.util.List;
import javax.annotation.Resource; import javax.annotation.Resource;
import com.xboe.common.utils.StringUtil;
import com.xboe.core.log.AutoLog;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.core.JsonResponse; import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController; import com.xboe.core.api.ApiBaseController;
@@ -77,7 +74,22 @@ public class CourseContentApi extends ApiBaseController{
} }
return success(obj); return success(obj);
} }
@GetMapping("/exam/paper-content")
@AutoLog(module = "试卷",action = "查看试卷试题",info = "查看当前试题内容")
public JsonResponse<Object> paperContent(String courseExamId){
if(StringUtil.isBlank(courseExamId)){
return badRequest("缺少必要参数");
}
try {
Object paperContentOfOnline = ccontentService.getPaperContentOfOnline(courseExamId);
return success(paperContentOfOnline);
} catch (Exception e) {
log.error("查询试卷内容json错误",e);
return error("查询失败",e.getMessage());
}
}
/** /**
* 获取评估信息 * 获取评估信息
* @param ccid * @param ccid

View File

@@ -9,7 +9,12 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; 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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.common.Pagination; import com.xboe.common.Pagination;
@@ -1159,11 +1164,5 @@ public class CourseManageApi extends ApiBaseController{
return success(courses); return success(courses);
} }
@GetMapping("/getCourseCoverUrl")
public JsonResponse<Map<String, String>> getCourseCoverUrl(@RequestParam String courseIds){
Map<String, String> courseUrlMap = courseService.getCourseCoverUrl(courseIds);
return success(courseUrlMap);
}
} }

View File

@@ -1,64 +1,50 @@
package com.xboe.module.course.api; package com.xboe.module.course.api;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.xboe.api.ThirdApi; import com.xboe.api.ThirdApi;
import com.xboe.core.orm.FieldFilters; import com.xboe.api.vo.UserBasicInfo;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.vo.TeacherVo;
import com.xboe.school.study.dao.StudyCourseDao;
import com.xboe.school.study.entity.StudyHomeWork;
import com.xboe.school.study.service.IStudyHomeWorkService;
import com.xboe.school.study.service.IStudyService;
import com.xboe.system.user.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.common.Pagination; import com.xboe.common.Pagination;
import com.xboe.common.utils.StringUtil; import com.xboe.common.utils.StringUtil;
import com.xboe.core.JsonResponse; import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController; import com.xboe.core.api.ApiBaseController;
import com.xboe.core.orm.FieldFilters;
import com.xboe.module.course.dto.CourseQueryDto; import com.xboe.module.course.dto.CourseQueryDto;
import com.xboe.module.course.dto.CourseTeacherDto; import com.xboe.module.course.dto.CourseTeacherDto;
import com.xboe.module.course.dto.RankingDto; import com.xboe.module.course.dto.RankingDto;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.service.ICourseContentService; import com.xboe.module.course.service.ICourseContentService;
import com.xboe.module.course.service.ICourseSectionService; import com.xboe.module.course.service.ICourseSectionService;
import com.xboe.module.course.service.ICourseService; import com.xboe.module.course.service.ICourseService;
import com.xboe.module.course.service.ICourseTeacherService; import com.xboe.module.course.service.ICourseTeacherService;
import com.xboe.module.course.vo.CourseStudyVo; import com.xboe.module.course.vo.CourseStudyVo;
import com.xboe.module.course.vo.TeacherVo;
import com.xboe.module.teacher.entity.Teacher; import com.xboe.module.teacher.entity.Teacher;
import com.xboe.module.teacher.service.ITeacherService; import com.xboe.module.teacher.service.ITeacherService;
import com.xboe.module.usergroup.service.IUserGroupService; import com.xboe.module.usergroup.service.IUserGroupService;
import com.xboe.school.study.dao.StudyCourseDao;
import com.xboe.school.study.entity.StudyCourse; import com.xboe.school.study.entity.StudyCourse;
import com.xboe.school.study.entity.StudyCourseItem; import com.xboe.school.study.entity.StudyCourseItem;
import com.xboe.school.study.entity.StudyHomeWork;
import com.xboe.school.study.service.IStudyCourseService; import com.xboe.school.study.service.IStudyCourseService;
import com.xboe.school.study.service.IStudyHomeWorkService;
import com.xboe.school.study.service.IStudyService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
@@ -365,13 +351,15 @@ public class CoursePortalApi extends ApiBaseController{
} }
//作业导出 //作业导出
@GetMapping("/export") @GetMapping("/export")
public JsonResponse<String> export(String courseName,String courseId,String contentId,String name,Integer status) throws IOException { public JsonResponse<String> export(String courseId,String courseName,String contentId,String name,Integer status,HttpServletRequest request) throws IOException {
Map<String, String>map=new HashMap<>(); Map<String, String>map=new HashMap<>();
List<String> userIds = studyCourseDao.findList(FieldFilters.eq("courseId", courseId)).stream().filter(Objects::nonNull).map(StudyCourse::getAid).collect(Collectors.toList()); List<String> userIds = studyCourseDao.findList(FieldFilters.eq("courseId", courseId)).stream().filter(Objects::nonNull).map(StudyCourse::getAid).collect(Collectors.toList());
if (userIds.isEmpty()){ if (userIds.isEmpty()){
return error("查询不到用户"); return error("查询不到用户");
} }
List<User>user=studyService.getUserNo(userIds);
List <UserBasicInfo> userBasicInfoList =thirdApi.getUserBasicInfoByUserId(userIds,request);
try {//筛选出的人员 try {//筛选出的人员
List<StudyCourseItem> list = studyService.getList(courseId, contentId, name, status); List<StudyCourseItem> list = studyService.getList(courseId, contentId, name, status);
if(list.isEmpty()){ if(list.isEmpty()){
@@ -383,12 +371,12 @@ public class CoursePortalApi extends ApiBaseController{
return success("暂无数据"); return success("暂无数据");
} }
studyHomeWorks.forEach(e->{ studyHomeWorks.forEach(e->{
user.forEach(u->{ userBasicInfoList.forEach(u->{
if(u.getId().equals(s.getAid())){ if(u.getUserId().equals(s.getAid())){
//取后缀 //取后缀
int dotIndex = e.getFilePath().lastIndexOf('.'); // 查找最后一个'.'的位置 int dotIndex = e.getFilePath().lastIndexOf('.'); // 查找最后一个'.'的位置
String extension = e.getFilePath().substring(dotIndex); String extension = e.getFilePath().substring(dotIndex);
map.put(u.getName()+"-"+u.getUserNo()+extension,"/home/www/elearning/upload"+e.getFilePath()); map.put(u.getUserName()+"-"+u.getWorkNum()+extension,"/home/www/elearning/upload"+e.getFilePath());
} }
}); });
}); });
@@ -404,60 +392,36 @@ public class CoursePortalApi extends ApiBaseController{
if (totalFileSize > 2L * 1024 * 1024 * 1024) { if (totalFileSize > 2L * 1024 * 1024 * 1024) {
return success("您要下载的作业过大,请分批下载或联系管理员!"); return success("您要下载的作业过大,请分批下载或联系管理员!");
} }
// 创建压缩文件
String zipFilePath = "/home/www/elearning/upload/saveZip/" + courseName+"【作业】" + ".zip";
createZipFile(map, zipFilePath);
return success(zipFilePath);
}
private static void createZipFile(Map<String, String> map, String zipFilePath) throws IOException {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// String encodedFilename = URLEncoder.encode(courseName+"【作业】.zip") File file = new File(value);
// .replace("+", "%20") // 空格替换为"%20" if (!file.exists()) {
// .replace("%2F", "/"); // 解决斜杠问题 continue;
// StringBuilder contentDispositionValue = new StringBuilder(); }
// contentDispositionValue.append("attachment; filename=\"")
// .append(encodedFilename)
// .append("\"")
// .append("; filename*=utf-8''")
// .append(encodedFilename);
//
// // 设置响应类型和Content-Disposition头
// response.setContentType("application/zip");
// 创建一个临时文件用于存储ZIP文件 byte[] buffer = new byte[1024];
File tempZipFile = new File("/home/www/elearning/upload/temp.zip"); FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(key);
zos.putNextEntry(zipEntry);
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tempZipFile))) { int length;
for (Map.Entry<String, String> e : map.entrySet()) { while ((length = fis.read(buffer)) > 0) {
File fileToZip = new File(e.getValue()); zos.write(buffer, 0, length);
// 添加 ZIP 条目
ZipEntry entry = new ZipEntry(e.getKey());
entry.setSize(fileToZip.length());
zos.putNextEntry(entry);
try (FileInputStream fis = new FileInputStream(fileToZip)) {
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
} }
zos.closeEntry(); zos.closeEntry();
fis.close();
} }
} }
// 将临时文件移动到指定位置
Path source = tempZipFile.toPath();
//生成uuid
String uuid = UUID.randomUUID().toString();
Path destination = Paths.get("/home/www/elearning/upload/saveZip/" + uuid + ".zip");
// 删除目标文件如果已存在
if (Files.exists(destination)) {
Files.delete(destination);
}
// 移动文件
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
// 返回文件路径给前端
String filePath = destination.toAbsolutePath().toString();
return success(filePath);
} }
@GetMapping("/detail-study") @GetMapping("/detail-study")
public JsonResponse<List<CourseStudyVo>> detailStudy(String courseId, String aid){ public JsonResponse<List<CourseStudyVo>> detailStudy(String courseId, String aid){

View File

@@ -85,4 +85,6 @@ public interface ICourseContentService{
void updateProcessVideo(String contentId, String courseId, Float processVideo); void updateProcessVideo(String contentId, String courseId, Float processVideo);
Object getPaperContentOfOnline(String courseExamId);
} }

View File

@@ -340,8 +340,9 @@ public interface ICourseService {
* */ * */
List<Course> mobiledelList(Integer num,CourseQueryDto courseQueryDto); List<Course> mobiledelList(Integer num,CourseQueryDto courseQueryDto);
/**
* 获取课程封面
* */
Map<String, String> getCourseCoverUrl(String courseIds);
} }

View File

@@ -1,23 +1,17 @@
package com.xboe.module.course.service.impl; package com.xboe.module.course.service.impl;
import java.sql.PreparedStatement; import com.fasterxml.jackson.core.JsonProcessingException;
import java.sql.SQLException; import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import javax.annotation.Resource; import com.fasterxml.jackson.databind.ObjectMapper;
import javax.transaction.Transactional; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.xboe.common.OrderCondition; import com.xboe.common.OrderCondition;
import com.xboe.core.cache.IXaskCache;
import com.xboe.core.cache.XaskCacheProvider;
import com.xboe.core.orm.FieldFilters; import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.UpdateBuilder; import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.course.dao.CourseAssessDao; import com.xboe.module.course.dao.*;
import com.xboe.module.course.dao.CourseContentDao;
import com.xboe.module.course.dao.CourseExamDao;
import com.xboe.module.course.dao.CourseHomeWorkDao;
import com.xboe.module.course.dao.CourseSectionDao;
import com.xboe.module.course.dto.CourseContentDto; import com.xboe.module.course.dto.CourseContentDto;
import com.xboe.module.course.dto.SortItem; import com.xboe.module.course.dto.SortItem;
import com.xboe.module.course.entity.CourseAssess; import com.xboe.module.course.entity.CourseAssess;
@@ -25,8 +19,21 @@ import com.xboe.module.course.entity.CourseContent;
import com.xboe.module.course.entity.CourseExam; import com.xboe.module.course.entity.CourseExam;
import com.xboe.module.course.entity.CourseHomeWork; import com.xboe.module.course.entity.CourseHomeWork;
import com.xboe.module.course.service.ICourseContentService; import com.xboe.module.course.service.ICourseContentService;
import com.xboe.module.exam.dao.ExamPaperDao;
import com.xboe.module.exam.vo.TestQuestionVo;
import com.xboe.standard.enums.BoedxContentType; import com.xboe.standard.enums.BoedxContentType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service @Service
public class CourseContentServiceImpl implements ICourseContentService { public class CourseContentServiceImpl implements ICourseContentService {
@@ -44,7 +51,13 @@ public class CourseContentServiceImpl implements ICourseContentService {
@Resource @Resource
private CourseHomeWorkDao homeworkDao; private CourseHomeWorkDao homeworkDao;
@Resource
private CourseExamDao courseExamDao;
@Resource
private ExamPaperDao examPaperDao;
@Override @Override
@Transactional @Transactional
@@ -78,6 +91,9 @@ public class CourseContentServiceImpl implements ICourseContentService {
assessDao.saveOrUpdate(assess); assessDao.saveOrUpdate(assess);
} }
if(exam!=null) { if(exam!=null) {
if ((exam.getRandomMode() && !(exam.getQnum() > 0)) || (!exam.getRandomMode() && exam.getQnum() > 0)) {
throw new RuntimeException("随机选题处参数错误");
}
exam.setCourseId(cc.getCourseId()); exam.setCourseId(cc.getCourseId());
exam.setContentId(cc.getId()); exam.setContentId(cc.getId());
if(exam.getPercentScore()==null) { if(exam.getPercentScore()==null) {
@@ -188,4 +204,68 @@ public class CourseContentServiceImpl implements ICourseContentService {
return ccDao.sumDurationByCourseId(courseId); return ccDao.sumDurationByCourseId(courseId);
} }
@Override
public Object getPaperContentOfOnline(String courseExamId) {
CourseExam courseExam = courseExamDao.findOne(FieldFilters.eq("id", courseExamId));
if (courseExam == null) {
throw new RuntimeException("课程考试不存在");
}
String paperId = courseExam.getPaperId();
Integer qnum = courseExam.getQnum();
Boolean randomMode = courseExam.getRandomMode();
String paperJson = "";
ObjectMapper objectMapper = new ObjectMapper();
try {
// 判断试卷类型
if (courseExam.getPaperType() == 1 && StringUtils.isNotBlank(courseExam.getPaperContent())) {
paperJson = courseExam.getPaperContent();
JsonNode rootNode = objectMapper.readTree(paperJson);
JsonNode itemsNode = rootNode.path("items");
List<JsonNode> itemsNodes = new ArrayList<>();
itemsNode.forEach(itemsNodes::add);
if (randomMode && qnum != null && qnum > 0 && randomMode && qnum != null && qnum > 0 && itemsNodes.size() > qnum) {
Collections.shuffle(itemsNodes);
itemsNodes = itemsNodes.subList(0, qnum);
}
return itemsNodes;
} else if (courseExam.getPaperType() == 2) {
IXaskCache cache = XaskCacheProvider.getCache();
String cacheKey = "course:exam:" + courseExamId + ":" + paperId;
String cacheData = cache.getCacheObject(cacheKey);
if (StringUtils.isBlank(cacheData)) {
paperJson = (String) examPaperDao.findField("paperContent", FieldFilters.eq("id", paperId));
cache.setCacheObject(cacheKey, paperJson, 5, TimeUnit.HOURS);
} else {
paperJson = cacheData;
}
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List<TestQuestionVo> eqVoList = objectMapper.readValue(paperJson, new TypeReference<List<TestQuestionVo>>() {
});
if (randomMode && qnum != null && qnum > 0 && eqVoList.size() > qnum) {
Collections.shuffle(eqVoList);
eqVoList = eqVoList.subList(0, qnum);
}
return eqVoList;
}
} catch (JsonProcessingException e) {
log.error("JSON处理错误", e);
throw new RuntimeException(e);
}
if (StringUtils.isBlank(paperJson)) {
throw new RuntimeException("此考试无试卷内容,考试已经过期或试卷已被删除");
}
return null;
}
} }

View File

@@ -1979,16 +1979,5 @@ public class CourseServiceImpl implements ICourseService {
return courseDao.findListByHql("Select new Course(id,studys,score) from Course where id in(?1)", ids); return courseDao.findListByHql("Select new Course(id,studys,score) from Course where id in(?1)", ids);
} }
@Override
public Map<String, String> getCourseCoverUrl(String courseIds) {
List<String> courseIdList = Arrays.asList(courseIds.split(","));
List<Course> courseList = courseDao.findList(FieldFilters.in("id", courseIdList));
Map<String, String> coverUrlMap = courseList.stream()
.filter(course -> StringUtils.isNotBlank(course.getCoverImg()))
.collect(Collectors.toMap(Course::getId, Course::getCoverImg));
return coverUrlMap;
}
} }

View File

@@ -14,11 +14,15 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.xboe.module.exam.entity.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*; 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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
@@ -37,6 +41,9 @@ import com.xboe.core.cache.IXaskCache;
import com.xboe.core.cache.XaskCacheProvider; import com.xboe.core.cache.XaskCacheProvider;
import com.xboe.core.exception.XaskException; import com.xboe.core.exception.XaskException;
import com.xboe.module.exam.dto.AloneExamExportDto; import com.xboe.module.exam.dto.AloneExamExportDto;
import com.xboe.module.exam.entity.AloneExam;
import com.xboe.module.exam.entity.AloneExamAnswer;
import com.xboe.module.exam.entity.ExamTest;
import com.xboe.module.exam.service.IAloneExamService; import com.xboe.module.exam.service.IAloneExamService;
import com.xboe.module.exam.service.IExamPaperService; import com.xboe.module.exam.service.IExamPaperService;
import com.xboe.module.exam.service.IExamTestService; import com.xboe.module.exam.service.IExamTestService;
@@ -546,7 +553,6 @@ public class AloneExamApi extends ApiBaseController {
//转化成百分数 //转化成百分数
//answer.setScore(this.calculateScore(detail)); //answer.setScore(this.calculateScore(detail));
service.submit(answer,scoreType); service.submit(answer,scoreType);
service.syncExamScoreToCourseSuite(answer, request);
return success(map); return success(map);
} catch (Exception e) { } catch (Exception e) {
log.error("提交答卷错误", e); log.error("提交答卷错误", e);

View File

@@ -166,118 +166,253 @@ public class ExamQuestionApi extends ApiBaseController {
return badRequest("请上传正确的试题文件"); return badRequest("请上传正确的试题文件");
} }
//获取表头 //获取表头
Row row = sheetAt.getRow(2); Row row ;
//从第二行开始获取数据 //从第二行开始获取数据
List<ExamQuestion> examQuestions1 = new ArrayList<>(); List<ExamQuestion> examQuestions1 = new ArrayList<>();
QuestionDto questionDto = new QuestionDto(); QuestionDto questionDto = new QuestionDto();
if(sheetAt.getRow(1).getCell(0).getStringCellValue().equals("标题(*)") && !sheetAt.getRow(1).getCell(0).getStringCellValue().equals("")){
row = sheetAt.getRow(1);
for (int i = 2;i<sheetAt.getPhysicalNumberOfRows();i++) {
//获取每一行
for (int i=3;i<sheetAt.getPhysicalNumberOfRows();i++) { Row row1 = sheetAt.getRow(i);
//获取每一行 if(row1==null || row1.getCell(0)==null){
break;
Row row1 = sheetAt.getRow(i); }
if(row1==null || row1.getCell(0)==null){ if(StringUtil.isBlank(row1.getCell(0).getStringCellValue())){
break; break;
} }
if(StringUtil.isBlank(row1.getCell(0).getStringCellValue())){ ExamQuestion examQuestion = new ExamQuestion();
break; examQuestion.setTitle(row1.getCell(0).getStringCellValue());
} if(row1.getCell(1).getStringCellValue().equals("单选题")){
ExamQuestion examQuestion = new ExamQuestion(); examQuestion.setType(1);
examQuestion.setTitle(row1.getCell(0).getStringCellValue()); }
if(row1.getCell(1).getStringCellValue().equals("选题")){ if(row1.getCell(1).getStringCellValue().equals("选题")){
examQuestion.setType(1); examQuestion.setType(2);
} }
if(row1.getCell(1).getStringCellValue().equals("多选题")){ if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setType(2); examQuestion.setDifficulty(2f);
} }else if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setKnowledge(row1.getCell(2).getStringCellValue()); examQuestion.setDifficulty(3f);
if(row1.getCell(3).getStringCellValue().equals("")){ } else if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setDifficulty(2f); examQuestion.setDifficulty(1f);
} }else if(row1.getCell(2).getStringCellValue().equals("")){
if(row1.getCell(3).getStringCellValue().equals("")){ examQuestion.setDifficulty(null);
examQuestion.setDifficulty(3f); }
} Cell cell = row1.getCell(3);
if(row1.getCell(3).getStringCellValue().equals("")){ cell.setCellType(CellType.STRING);
examQuestion.setDifficulty(1f);
}
Cell cell = row1.getCell(4);
cell.setCellType(CellType.STRING);
// examQuestion.setDefaultScore(Float.valueOf(cell.getStringCellValue())); // examQuestion.setDefaultScore(Float.valueOf(cell.getStringCellValue()));
//单选 //单选
if (!cell.getStringCellValue().contains(",")){ if (!cell.getStringCellValue().contains(",")){
examQuestion.setAnswer(row1.getCell(6).getStringCellValue()); examQuestion.setAnswer(row1.getCell(5).getStringCellValue());
examQuestion.setDefaultScore(Float.valueOf(row1.getCell(4).getStringCellValue())); if (row1.getCell(3).getStringCellValue().isEmpty()){
Cell cell1 = row1.getCell(5, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); examQuestion.setDefaultScore(null);
cell1.setCellType(CellType.STRING); }else {
examQuestion.setAnalysis(cell1.getStringCellValue()); examQuestion.setDefaultScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
}
Cell cell1 = row1.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell1.setCellType(CellType.STRING);
examQuestion.setAnalysis(cell1.getStringCellValue());
List<ExamOption> examOptions = new ArrayList<>(); List<ExamOption> examOptions = new ArrayList<>();
for (int j=7;j<=13;j++) { for (int j=6;j<=12;j++) {
if(row1.getCell(j)!=null) { if(row1.getCell(j)!=null) {
ExamOption examOption = new ExamOption(); ExamOption examOption = new ExamOption();
// 截取表头 // 截取表头
String substring = row.getCell(j).getStringCellValue().substring(3, 4); String substring = row.getCell(j).getStringCellValue().substring(3, 4);
if (row1.getCell(6).getStringCellValue().contains(substring)) { if (row1.getCell(5).getStringCellValue().contains(substring)) {
examOption.setIsAnswer(true); examOption.setIsAnswer(true);
examOption.setScore(Float.valueOf(row1.getCell(4).getStringCellValue())); if (row1.getCell(3).getStringCellValue().isEmpty()){
} else { examOption.setScore(null);
examOption.setIsAnswer(false); }else {
} examOption.setScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
if (examOption.getIsAnswer()) { }
examOption.setScore(Float.valueOf(row1.getCell(4).getStringCellValue())); } else {
} examOption.setIsAnswer(false);
}
if (examOption.getIsAnswer()) {
if (row1.getCell(3).getStringCellValue().isEmpty()){
examOption.setScore(null);
}else {
examOption.setScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
}
}
examOption.setOptions(row.getCell(j).getStringCellValue()); examOption.setOptions(row.getCell(j).getStringCellValue());
Cell cell2 = row1.getCell(j); Cell cell2 = row1.getCell(j);
cell2.setCellType(CellType.STRING); cell2.setCellType(CellType.STRING);
examOption.setContent(cell2.getStringCellValue()); examOption.setContent(cell2.getStringCellValue());
if (examOption != null && StringUtil.isNotBlank(examOption.getContent())) { if (examOption != null && StringUtil.isNotBlank(examOption.getContent())) {
examOptions.add(examOption); examOptions.add(examOption);
}
} }
} }
}
examQuestion.setOptionList(examOptions); examQuestion.setOptionList(examOptions);
examQuestions1.add(examQuestion); examQuestions1.add(examQuestion);
} }
//多选 多选的默认分存的是最大分 //多选 多选的默认分存的是最大分
else{ else{
String stringCellValue = row1.getCell(4).getStringCellValue(); String stringCellValue = row1.getCell(4).getStringCellValue();
String[] strings = stringCellValue.split(","); String[] strings = stringCellValue.split(",");
// String[] strings = new String[stringCellValue.length()]; // String[] strings = new String[stringCellValue.length()];
String max=strings[0]; String max=strings[0];
for (int j=0;j<strings.length;j++) { for (int j=0;j<strings.length;j++) {
if(Float.valueOf(max)<Float.valueOf(strings[j])){ if(Float.valueOf(max)<Float.valueOf(strings[j])){
max=strings[j]; max=strings[j];
}
}
examQuestion.setDefaultScore(Float.valueOf(max));
Cell cell1 = row1.getCell(5, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell1.setCellType(CellType.STRING);
examQuestion.setAnalysis(cell1.getStringCellValue());
examQuestion.setAnswer(row1.getCell(6).getStringCellValue());
List<ExamOption> examOptions = new ArrayList<>();
//A
for (int j=7;j<=13;j++){
if(row1.getCell(j)!=null && StringUtil.isNotBlank(row1.getCell(j).getStringCellValue())){
ExamOption examOption=new ExamOption();
examOption.setOptions(row.getCell(j).getStringCellValue());
examOption.setContent(row1.getCell(j).getStringCellValue());
examOption.setIsAnswer(true);
examOption.setScore(Float.valueOf(strings[j-7]));
if(examOption!=null && StringUtil.isNotBlank(examOption.getContent())){
examOptions.add(examOption);
} }
} }
examQuestion.setDefaultScore(Float.valueOf(max));
Cell cell1 = row1.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell1.setCellType(CellType.STRING);
examQuestion.setAnalysis(cell1.getStringCellValue());
examQuestion.setAnswer(row1.getCell(5).getStringCellValue());
List<ExamOption> examOptions = new ArrayList<>();
//A
for (int j=6;j<=12;j++){
if(row1.getCell(j)!=null && StringUtil.isNotBlank(row1.getCell(j).getStringCellValue())){
ExamOption examOption=new ExamOption();
examOption.setOptions(row.getCell(j).getStringCellValue());
examOption.setContent(row1.getCell(j).getStringCellValue());
examOption.setIsAnswer(true);
examOption.setScore(Float.valueOf(strings[j-6]));
if(examOption!=null && StringUtil.isNotBlank(examOption.getContent())){
examOptions.add(examOption);
}
}
}
examQuestion.setOptionList(examOptions);
examQuestions1.add(examQuestion);
}
}
}else {
row = sheetAt.getRow(2);
for (int i = 3;i<sheetAt.getPhysicalNumberOfRows();i++) {
//获取每一行
Row row1 = sheetAt.getRow(i);
if(row1==null || row1.getCell(0)==null){
break;
}
if(StringUtil.isBlank(row1.getCell(0).getStringCellValue())){
break;
}
ExamQuestion examQuestion = new ExamQuestion();
examQuestion.setTitle(row1.getCell(0).getStringCellValue());
if(row1.getCell(1).getStringCellValue().equals("单选题")){
examQuestion.setType(1);
}
if(row1.getCell(1).getStringCellValue().equals("多选题")){
examQuestion.setType(2);
}
if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setDifficulty(2f);
}else if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setDifficulty(3f);
} else if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setDifficulty(1f);
}else if(row1.getCell(2).getStringCellValue().equals("")){
examQuestion.setDifficulty(null);
}
Cell cell = row1.getCell(3);
cell.setCellType(CellType.STRING);
// examQuestion.setDefaultScore(Float.valueOf(cell.getStringCellValue()));
//单选
if (!cell.getStringCellValue().contains(",")){
examQuestion.setAnswer(row1.getCell(5).getStringCellValue());
if (row1.getCell(3).getStringCellValue().isEmpty()){
examQuestion.setDefaultScore(null);
}else {
examQuestion.setDefaultScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
}
Cell cell1 = row1.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell1.setCellType(CellType.STRING);
examQuestion.setAnalysis(cell1.getStringCellValue());
List<ExamOption> examOptions = new ArrayList<>();
for (int j=6;j<=12;j++) {
if(row1.getCell(j)!=null) {
ExamOption examOption = new ExamOption();
// 截取表头
String substring = row.getCell(j).getStringCellValue().substring(3, 4);
if (row1.getCell(5).getStringCellValue().contains(substring)) {
examOption.setIsAnswer(true);
if (row1.getCell(3).getStringCellValue().isEmpty()){
examOption.setScore(null);
}else {
examOption.setScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
}
} else {
examOption.setIsAnswer(false);
}
if (examOption.getIsAnswer()) {
if (row1.getCell(3).getStringCellValue().isEmpty()){
examOption.setScore(null);
}else {
examOption.setScore(Float.valueOf(row1.getCell(3).getStringCellValue()));
}
}
examOption.setOptions(row.getCell(j).getStringCellValue());
Cell cell2 = row1.getCell(j);
cell2.setCellType(CellType.STRING);
examOption.setContent(cell2.getStringCellValue());
if (examOption != null && StringUtil.isNotBlank(examOption.getContent())) {
examOptions.add(examOption);
}
}
}
examQuestion.setOptionList(examOptions);
examQuestions1.add(examQuestion);
}
//多选 多选的默认分存的是最大分
else{
String stringCellValue = row1.getCell(4).getStringCellValue();
String[] strings = stringCellValue.split(",");
// String[] strings = new String[stringCellValue.length()];
String max=strings[0];
for (int j=0;j<strings.length;j++) {
if(Float.valueOf(max)<Float.valueOf(strings[j])){
max=strings[j];
}
}
examQuestion.setDefaultScore(Float.valueOf(max));
Cell cell1 = row1.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell1.setCellType(CellType.STRING);
examQuestion.setAnalysis(cell1.getStringCellValue());
examQuestion.setAnswer(row1.getCell(5).getStringCellValue());
List<ExamOption> examOptions = new ArrayList<>();
//A
for (int j=6;j<=13;j++){
if(row1.getCell(j)!=null && StringUtil.isNotBlank(row1.getCell(j).getStringCellValue())){
ExamOption examOption=new ExamOption();
examOption.setOptions(row.getCell(j).getStringCellValue());
examOption.setContent(row1.getCell(j).getStringCellValue());
examOption.setIsAnswer(true);
examOption.setScore(Float.valueOf(strings[j-6]));
if(examOption!=null && StringUtil.isNotBlank(examOption.getContent())){
examOptions.add(examOption);
}
}
}
examQuestion.setOptionList(examOptions);
examQuestions1.add(examQuestion);
} }
examQuestion.setOptionList(examOptions);
examQuestions1.add(examQuestion);
} }
} }
//判断题 只存在试题表中 //判断题 只存在试题表中
@@ -300,27 +435,30 @@ public class ExamQuestionApi extends ApiBaseController {
ExamQuestion examQuestion1 = new ExamQuestion(); ExamQuestion examQuestion1 = new ExamQuestion();
examQuestion1.setTitle(row2.getCell(0).getStringCellValue()); examQuestion1.setTitle(row2.getCell(0).getStringCellValue());
examQuestion1.setType(3); examQuestion1.setType(3);
examQuestion1.setKnowledge(row2.getCell(1).getStringCellValue()); System.out.println("1+++++++"+row2.getCell(1));
if(row2.getCell(2).getStringCellValue().equals("")){ if(row2.getCell(1).getStringCellValue().equals("")){
examQuestion1.setDifficulty(2f); examQuestion1.setDifficulty(2f);
} }else if(row2.getCell(1).getStringCellValue().equals("")){
if(row2.getCell(2).getStringCellValue().equals("")){
examQuestion1.setDifficulty(3f); examQuestion1.setDifficulty(3f);
} } else if(row2.getCell(1).getStringCellValue().equals("")){
if(row2.getCell(2).getStringCellValue().equals("")){
examQuestion1.setDifficulty(1f); examQuestion1.setDifficulty(1f);
}else if(row2.getCell(1).getStringCellValue().equals("")){
examQuestion1.setDifficulty(null);
} }
Cell cell1 = row2.getCell(3); Cell cell1 = row2.getCell(2);
cell1.setCellType(CellType.STRING); cell1.setCellType(CellType.STRING);
examQuestion1.setDefaultScore(Float.valueOf(cell1.getStringCellValue())); if (row2.getCell(2).getStringCellValue().isEmpty()){
examQuestion1.setDefaultScore(null);
if(row2.getCell(4)!=null) { }else {
examQuestion1.setAnalysis(row2.getCell(4).getStringCellValue()); examQuestion1.setDefaultScore(Float.valueOf(row2.getCell(2).getStringCellValue()));
}
if(row2.getCell(3)!=null) {
examQuestion1.setAnalysis(row2.getCell(3).getStringCellValue());
}else { }else {
examQuestion1.setAnalysis(""); examQuestion1.setAnalysis("");
} }
String cvalue=row2.getCell(5).getStringCellValue(); String cvalue=row2.getCell(4).getStringCellValue();
examQuestion1.setAnswer(cvalue.equals("正确")? "true":"false"); examQuestion1.setAnswer(cvalue.equals("正确")? "true":"false");
if(examQuestion1!=null){ if(examQuestion1!=null){
examQuestions2.add(examQuestion1); examQuestions2.add(examQuestion1);

View File

@@ -3,12 +3,14 @@ package com.xboe.module.exam.api;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import cn.hutool.core.collection.CollectionUtil;
import com.xboe.api.ThirdApi; import com.xboe.api.ThirdApi;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.ConstraintViolationException;
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.PageList;
import com.xboe.common.Pagination; import com.xboe.common.Pagination;
@@ -21,8 +23,6 @@ import com.xboe.module.exam.service.IExamTestService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.List;
/** /**
* 考试 * 考试
* */ * */
@@ -33,10 +33,8 @@ public class ExamTestApi extends ApiBaseController {
@Resource @Resource
private IExamTestService examTestService; private IExamTestService examTestService;
@Resource @Resource
private ThirdApi thirdApi; ThirdApi thirdApi;
/** /**
*查询考试,分页,搜索,资源归属,状态 *查询考试,分页,搜索,资源归属,状态
**/ **/
@@ -185,21 +183,4 @@ public class ExamTestApi extends ApiBaseController {
return error("上下级失败",e.getMessage()); return error("上下级失败",e.getMessage());
} }
} }
/**
* 引用关系移除
* */
@PostMapping("/removeRel")
public JsonResponse<Boolean> removeRel(@RequestParam List<String> ids){
if(CollectionUtil.isEmpty(ids)){
return badRequest("参数异常");
}
try {
examTestService.removeRel(ids);
return success(true);
} catch (Exception e) {
log.error("引用关系移除异常",e);
return error("引用关系移除异常",e.getMessage());
}
}
} }

View File

@@ -65,7 +65,6 @@ public class AloneExam extends IdBaseEntity {
private String ucode; private String ucode;
/**关联类型*/ /**关联类型*/
/**关联类型 新增关联类型14代表成长路径图*/
@Column(name = "ref_type", length = 30) @Column(name = "ref_type", length = 30)
private String refType; private String refType;

View File

@@ -178,14 +178,4 @@ public class ExamTest extends BaseEntity {
@Transient @Transient
private String paperName; private String paperName;
/** 关联类型1、项目 2、学习路径图 3、面授课 14、成长路径图 */
@Column(name = "ref_type")
private Integer refType;
@Column(name = "ref_id")
private String refId;
@Column(name = "ref_status")
private Integer refStatus;
} }

View File

@@ -10,7 +10,6 @@ import com.xboe.module.exam.dto.TestUserQuery;
import com.xboe.module.exam.entity.AloneExam; import com.xboe.module.exam.entity.AloneExam;
import com.xboe.module.exam.entity.AloneExamAnswer; import com.xboe.module.exam.entity.AloneExamAnswer;
import com.xboe.module.exam.vo.AloneExamQuery; import com.xboe.module.exam.vo.AloneExamQuery;
import javax.servlet.http.HttpServletRequest;
/** /**
* 独立考试的处理。此信息无删除操作更新也只是更新answerJson字段 * 独立考试的处理。此信息无删除操作更新也只是更新answerJson字段
@@ -93,18 +92,10 @@ public interface IAloneExamService {
/** /**
* 提交考试 * 提交考试
*
* @param aea * @param aea
*/ */
void submit(AloneExamAnswer aea, Integer scoreType); void submit(AloneExamAnswer aea,Integer scoreType);
/**
* 同步考试成绩
* @param aea
* @param request
*/
void syncExamScoreToCourseSuite(AloneExamAnswer aea, HttpServletRequest request);
/** /**
* 更新答案 * 更新答案
* @param id * @param id

View File

@@ -3,8 +3,6 @@ package com.xboe.module.exam.service;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.module.exam.entity.ExamTest; import com.xboe.module.exam.entity.ExamTest;
import java.util.List;
public interface IExamTestService { public interface IExamTestService {
/** /**
* 分页查,状态,搜索,资源归属 * 分页查,状态,搜索,资源归属
@@ -53,5 +51,4 @@ public interface IExamTestService {
* */ * */
void enabled(String id,Boolean enabled); void enabled(String id,Boolean enabled);
void removeRel(List<String> ids);
} }

View File

@@ -1,6 +1,17 @@
package com.xboe.module.exam.service.impl; package com.xboe.module.exam.service.impl;
import com.xboe.api.ThirdApi; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xboe.common.OrderCondition; import com.xboe.common.OrderCondition;
import com.xboe.common.PageList; import com.xboe.common.PageList;
import com.xboe.common.utils.StringUtil; import com.xboe.common.utils.StringUtil;
@@ -9,7 +20,6 @@ import com.xboe.core.orm.QueryBuilder;
import com.xboe.core.orm.UpdateBuilder; import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.exam.dao.AloneExamAnswerDao; import com.xboe.module.exam.dao.AloneExamAnswerDao;
import com.xboe.module.exam.dao.AloneExamDao; import com.xboe.module.exam.dao.AloneExamDao;
import com.xboe.module.exam.dao.ExamTestDao;
import com.xboe.module.exam.dto.TestUserAnswerDto; import com.xboe.module.exam.dto.TestUserAnswerDto;
import com.xboe.module.exam.dto.TestUserDto; import com.xboe.module.exam.dto.TestUserDto;
import com.xboe.module.exam.dto.TestUserQuery; import com.xboe.module.exam.dto.TestUserQuery;
@@ -18,47 +28,23 @@ import com.xboe.module.exam.entity.AloneExamAnswer;
import com.xboe.module.exam.entity.ExamTest; import com.xboe.module.exam.entity.ExamTest;
import com.xboe.module.exam.service.IAloneExamService; import com.xboe.module.exam.service.IAloneExamService;
import com.xboe.module.exam.vo.AloneExamQuery; import com.xboe.module.exam.vo.AloneExamQuery;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@Service @Service
public class AloneExamServiceImpl implements IAloneExamService{ public class AloneExamServiceImpl implements IAloneExamService{
private static final Logger log = LoggerFactory.getLogger(AloneExamServiceImpl.class);
@Resource @Resource
AloneExamAnswerDao dao; AloneExamAnswerDao dao;
@Resource @Resource
AloneExamDao aeDao; AloneExamDao aeDao;
@Autowired
private ThirdApi thirdApi;
@Override @Override
@Transactional @Transactional
public void save(AloneExamAnswer aea){ public void save(AloneExamAnswer aea){
dao.save(aea); dao.save(aea);
AloneExam ae=aeDao.findOne(FieldFilters.eq("aid", aea.getAid()),FieldFilters.eq("testId", aea.getTestId()));
int currentTimes = ae.getTimes() != null ? ae.getTimes() : 0;
//更新状态 //更新状态
aeDao.update(UpdateBuilder.from(AloneExam.class) aeDao.update(UpdateBuilder.from(AloneExam.class)
.addUpdateField("status", AloneExam.STATUS_NORMAL) .addUpdateField("status", AloneExam.STATUS_NORMAL)
.addUpdateField("times", currentTimes+1)
.addFilter(FieldFilters.eq("aid", aea.getAid())) .addFilter(FieldFilters.eq("aid", aea.getAid()))
.addFilter(FieldFilters.eq("testId", aea.getTestId())) .addFilter(FieldFilters.eq("testId", aea.getTestId()))
.addFilter(FieldFilters.eq("status",AloneExam.STATUS_NONE)) .addFilter(FieldFilters.eq("status",AloneExam.STATUS_NONE))
@@ -67,8 +53,8 @@ public class AloneExamServiceImpl implements IAloneExamService{
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional
public void submit(AloneExamAnswer aea, Integer scoreType){ public void submit(AloneExamAnswer aea,Integer scoreType){
//dao.update(aea); //dao.update(aea);
aea.setStatus(AloneExamAnswer.STATUS_FINISH); aea.setStatus(AloneExamAnswer.STATUS_FINISH);
LocalDateTime now=LocalDateTime.now(); LocalDateTime now=LocalDateTime.now();
@@ -116,27 +102,6 @@ public class AloneExamServiceImpl implements IAloneExamService{
// } // }
} }
} }
@Override
public void syncExamScoreToCourseSuite(AloneExamAnswer aea, HttpServletRequest request) {
String token = request.getHeader("Xboe-Access-Token");
if (StringUtils.isEmpty(token)) {
token = request.getHeader("token");
}
String finalToken = token;
CompletableFuture.supplyAsync(() -> {
AloneExam aloneExam = aeDao.findOne(FieldFilters.eq("aid", aea.getAid()), FieldFilters.eq("testId", aea.getTestId()));
if (aloneExam.getRefType().equals("14")){
thirdApi.syncExamScoreToCourseSuite(aloneExam, finalToken);
}
return "完成结果";
}).exceptionally(ex -> {
log.error("异步操作中发生错误: " + ex.getMessage(), ex);
return "发生错误";
}).thenAccept(result -> {
log.info("同步考试成绩到课程项目完成:" + result);
});
}
@Override @Override
@Transactional @Transactional

View File

@@ -122,10 +122,4 @@ public class ExamTestServiceImpl implements IExamTestService {
} }
return null; return null;
} }
@Override
public void removeRel(List<String> ids) {
String idsStr = String.join(",", ids);
examTestDao.sqlUpdate("update boe_exam_test set ref_status=0 where id in (?1)",idsStr);
}
} }

View File

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

View File

@@ -117,7 +117,7 @@ public class StudyExam extends IdEntity {
/* /*
* 开始时间 * 开始时间
* */ * */
@JsonFormat(pattern = "yyyy--MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "start_time") @Column(name = "start_time")
private LocalDateTime startTime; private LocalDateTime startTime;
/* /*

View File

@@ -99,5 +99,4 @@ public interface IStudyService {
List<StudyCourseItem> getList(String courseId, String contentId, String name, Integer status); List<StudyCourseItem> getList(String courseId, String contentId, String name, Integer status);
List<User> getUserNo(List<String> userIds);
} }

View File

@@ -1,24 +1,9 @@
package com.xboe.school.study.service.impl; package com.xboe.school.study.service.impl;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import com.xboe.api.ThirdApi;
import com.xboe.core.orm.QueryBuilder;
import com.xboe.school.study.entity.StudyCourse;
import com.xboe.system.user.entity.Message;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.xboe.common.OrderCondition; import com.xboe.common.OrderCondition;
import com.xboe.core.orm.FieldFilters; import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.QueryBuilder;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.course.dao.CourseContentDao; import com.xboe.module.course.dao.CourseContentDao;
import com.xboe.module.course.dao.CourseExamDao; import com.xboe.module.course.dao.CourseExamDao;
import com.xboe.module.course.entity.CourseExam; import com.xboe.module.course.entity.CourseExam;
@@ -28,6 +13,17 @@ import com.xboe.school.study.dao.StudyExamDao;
import com.xboe.school.study.entity.StudyCourseItem; import com.xboe.school.study.entity.StudyCourseItem;
import com.xboe.school.study.entity.StudyExam; import com.xboe.school.study.entity.StudyExam;
import com.xboe.school.study.service.IStudyExamService; import com.xboe.school.study.service.IStudyExamService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@@ -73,29 +69,31 @@ public class StudyExamServiceImpl implements IStudyExamService{
exam.setPassLine(0); exam.setPassLine(0);
} }
int prog=exam.getScore().intValue()>=exam.getPassLine()?100:exam.getScore().intValue();
//完成处理,判断是否已存在 //完成处理,判断是否已存在
Object obj=scItemDao.findField("id", FieldFilters.eq("studyId", exam.getStudyId()), FieldFilters.eq("contentId", exam.getContentId())); Object obj=scItemDao.findField("id", FieldFilters.eq("studyId", exam.getStudyId()), FieldFilters.eq("contentId", exam.getContentId()));
//获取本次考试提交,学习状态与学习进度
int status=exam.getScore()>=exam.getPassLine()?StudyCourseItem.STATUS_FINISH:StudyCourseItem.STATUS_STUDYING; int status=exam.getScore()>=exam.getPassLine()?StudyCourseItem.STATUS_FINISH:StudyCourseItem.STATUS_STUDYING;
int progress = exam.getScore().intValue() >= exam.getPassLine() ? 100 : 0;
//计算时长
LocalDateTime ldt=LocalDateTime.now();
if(obj==null) { if(obj==null) {
StudyCourseItem sci=new StudyCourseItem(); StudyCourseItem sci=new StudyCourseItem();
LocalDateTime ldt=LocalDateTime.now();
sci.setStudyId(exam.getStudyId()); sci.setStudyId(exam.getStudyId());
sci.setContentId(exam.getContentId()); sci.setContentId(exam.getContentId());
sci.setContentName("考试"); sci.setContentName("考试");
sci.setCourseId(exam.getCourseId()); sci.setCourseId(exam.getCourseId());
//sci.setCsectionId(homework.getCsectionId()); //sci.setCsectionId(homework.getCsectionId());
sci.setProgress(prog);//直接设置为学习完成 sci.setProgress(progress);//直接设置为学习完成
sci.setStatus(status);//状态直接更新为已完成 sci.setStatus(status);//状态直接更新为已完成
sci.setStartTime(ldt); sci.setStartTime(exam.getStartTime());
sci.setAid(exam.getStudentId()); sci.setAid(exam.getStudentId());
sci.setAname(exam.getStudentName()); sci.setAname(exam.getStudentName());
sci.setFinishTime(LocalDateTime.now()); sci.setFinishTime(ldt);
sci.setLastStudyTime(0);//此项用户记录视频内容当前学习的时间点 sci.setLastStudyTime(0);//此项用户记录视频内容当前学习的时间点
sci.setLastTime(ldt); sci.setLastTime(ldt);
if(cexam.getScoringType()==CourseExam.SCORINGTYPE_LAST) { sci.setScore(exam.getScore());
sci.setScore(exam.getScore()); sci.setStudyDuration(exam.getTestDuration());
}
scItemDao.save(sci); scItemDao.save(sci);
exam.setStudyItemId(sci.getId()); exam.setStudyItemId(sci.getId());
dao.save(exam); dao.save(exam);
@@ -108,35 +106,34 @@ public class StudyExamServiceImpl implements IStudyExamService{
}else { }else {
exam.setStudyItemId(obj.toString());//此项就是学习条目的id exam.setStudyItemId(obj.toString());//此项就是学习条目的id
Float maxScore = (Float) dao.findField("max(score)", FieldFilters.eq("contentId", exam.getContentId()), FieldFilters.eq("courseId", exam.getCourseId()), FieldFilters.eq("studyId", exam.getStudyId()));
dao.save(exam); dao.save(exam);
if(cexam.getScoringType()==CourseExam.SCORINGTYPE_LAST){ //最新考试分值
scItemDao.updateFieldById(exam.getStudyItemId(), "score",exam.getScore()); if (cexam.getScoringType() == CourseExam.SCORINGTYPE_LAST) {
scItemDao.updateFieldById(exam.getStudyItemId(), "progress",prog); scItemDao.updateMultiFieldById(exam.getStudyItemId(),
if(exam.getScore()>=exam.getPassLine()){ UpdateBuilder.create("startTime", exam.getStartTime()),
scItemDao.updateFieldById(exam.getStudyId(), "progress",100); UpdateBuilder.create("finishTime", ldt),
scItemDao.updateFieldById(exam.getStudyId(), "finish_time",LocalDateTime.now()); UpdateBuilder.create("score", exam.getScore()),
scItemDao.updateFieldById(exam.getStudyId(), "status",StudyCourseItem.STATUS_FINISH); UpdateBuilder.create("progress", progress),
scItemDao.updateFieldById(exam.getStudyId(), "score",exam.getScore()); UpdateBuilder.create("status", status),
//scDao.updateFieldById(exam.getStudyId(), "last_score",100.0f); UpdateBuilder.create("studyDuration", exam.getTestDuration())
);
}
//最高分
if (cexam.getScoringType() == CourseExam.SCORINGTYPE_MAX) {
if (exam.getScore() > maxScore) {
scItemDao.updateMultiFieldById(exam.getStudyItemId(),
UpdateBuilder.create("startTime", exam.getStartTime()),
UpdateBuilder.create("finishTime", LocalDateTime.now()),
UpdateBuilder.create("score", exam.getScore()),
UpdateBuilder.create("progress", progress),
UpdateBuilder.create("status", status)
);
} }
} }
} }
//1最高一次,用于最高一次的计算
if(cexam.getScoringType()==CourseExam.SCORINGTYPE_MAX) {
Float f=(Float)dao.findField("max(score)", FieldFilters.eq("contentId", exam.getContentId()), FieldFilters.eq("courseId", exam.getCourseId()), FieldFilters.eq("studyId", exam.getStudyId()));
scItemDao.updateFieldById(exam.getStudyItemId(), "score", f);
scItemDao.updateFieldById(exam.getStudyItemId(), "status", f>=exam.getPassLine()?StudyCourseItem.STATUS_FINISH:StudyCourseItem.STATUS_STUDYING);
scItemDao.updateFieldById(exam.getStudyItemId(), "progress",f>=exam.getPassLine()?100:f.intValue());
if(f>=exam.getPassLine()){
scItemDao.updateFieldById(exam.getStudyId(), "progress",100);
scItemDao.updateFieldById(exam.getStudyId(), "finish_time",LocalDateTime.now());
scItemDao.updateFieldById(exam.getStudyId(), "status",StudyCourseItem.STATUS_FINISH);
scItemDao.updateFieldById(exam.getStudyId(), "score",exam.getScore());
//scDao.updateFieldById(exam.getStudyId(), "last_score",100.0f);
}
}
int totalContent = courseContentDao.getCount(exam.getCourseId()); int totalContent = courseContentDao.getCount(exam.getCourseId());
scDao.finishCheck(exam.getStudyId(),exam.getCourseId(),totalContent,token); scDao.finishCheck(exam.getStudyId(),exam.getCourseId(),totalContent,token);
scDao.updateFieldById(exam.getStudyId(), "last_score",exam.getScore()); scDao.updateFieldById(exam.getStudyId(), "last_score",exam.getScore());

View File

@@ -64,6 +64,7 @@ public class StudyHomeWorkServiceImpl implements IStudyHomeWorkService{
int totalContent=courseContentDao.count(FieldFilters.eq("courseId", homework.getCourseId()),FieldFilters.eq("deleted",false)); int totalContent=courseContentDao.count(FieldFilters.eq("courseId", homework.getCourseId()),FieldFilters.eq("deleted",false));
scDao.finishCheck(homework.getStudyId(),homework.getCourseId(),totalContent,token); scDao.finishCheck(homework.getStudyId(),homework.getCourseId(),totalContent,token);
}else { }else {
scItemDao.updateFieldById(obj.toString(), "finishTime", LocalDateTime.now());
//只是保留一条作业记录,不再保存多条记录了 //只是保留一条作业记录,不再保存多条记录了
//dao.save(homework); //dao.save(homework);
//设置id。然后进行悠 //设置id。然后进行悠

View File

@@ -294,16 +294,11 @@ public class StudyServiceImpl implements IStudyService{
} }
if(StringUtils.isNotBlank(name)) { if(StringUtils.isNotBlank(name)) {
query.addFilter(FieldFilters.eq("aname", name)); query.addFilter(FieldFilters.like("aname", name));
} }
return scItemDao.findList(query.builder()); return scItemDao.findList(query.builder());
} }
@Override
public List<User> getUserNo(List<String> userIds) {
return userDao.findList(FieldFilters.in("id", userIds));
}
@Override @Override
@Transactional @Transactional
public void updateProcess(String studyContentId,String studyId, String courseId,Integer total, Integer progress,String token) { public void updateProcess(String studyContentId,String studyId, String courseId,Integer total, Integer progress,String token) {

View File

@@ -73,6 +73,6 @@ infrasApi.dict=${boe.domain}/infrasApi/dict/list
manageApi.stu.offcourse=${boe.domain}/manageApi/stu/offcourse/getOffCourseId manageApi.stu.offcourse=${boe.domain}/manageApi/stu/offcourse/getOffCourseId
manageApi.editExam=${boe.domain}/manageApi/admin/project/editExam manageApi.editExam=${boe.domain}/manageApi/admin/project/editExam
#获取离职教师id #获取离职教师id
userBasic.getTeacherIds=${boe.domain}/userbasic/user/getTeacherInfocoursesuilt.getStudyStatus=${boe.domain}/manageApi/stu/project/completeStatus userBasic.getTeacherIds=${boe.domain}/userbasic/user/getTeacherInfo
coursesuilt.checkBanding=${boe.domain}/manageApi/stu/task/exam/checkBanding coursesuilt.getStudyStatus=${boe.domain}/manageApi/stu/project/completeStatus
coursesuilt.syncExamScoreToCourseSuite=${boe.domain}/manageApi/stu/task/exam/syncExamScoreToCourseSuite userBasic.getUserBasicInfo=${boe.domain}/userbasic/user/getUserBasicInfo