feat:学习进度导出接口添加入参校验,同时添加部门、学习时长字段获取逻辑

This commit is contained in:
miaowenbo
2025-11-24 14:18:59 +08:00
parent 8e65d0a0b0
commit c2eb338e95
2 changed files with 78 additions and 15 deletions

View File

@@ -12,6 +12,7 @@ import com.xboe.constants.CacheName;
import com.xboe.core.CurrentUser;
import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController;
import com.xboe.data.outside.IOutSideDataService;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.service.ICourseContentService;
import com.xboe.module.course.service.ICourseSectionService;
@@ -29,6 +30,10 @@ import com.xboe.school.study.service.IStudyExamService;
import com.xboe.school.study.service.IStudyService;
import com.xboe.school.study.service.IStudySignupService;
import com.xboe.school.vo.StudyTimeVo;
import com.xboe.system.organization.service.IOrganizationService;
import com.xboe.system.user.entity.User;
import com.xboe.system.user.service.IUserService;
import com.xboe.system.user.vo.UserSimpleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -92,6 +97,15 @@ public class StudyCourseApi extends ApiBaseController{
@Resource
private ICourseTagService courseTagService;
@Resource
private IOutSideDataService outsideService;
@Resource
private IUserService userService;
@Resource
private IOrganizationService organizationService;
/**
* 用于避免JPA查询后修改entity实体字段自动更新到数据库
*/
@@ -137,6 +151,11 @@ public class StudyCourseApi extends ApiBaseController{
*/
@RequestMapping(value="/export",method = {RequestMethod.GET,RequestMethod.POST})
public void export(String courseId, HttpServletResponse response) {
// 入参校验
if (StringUtils.isBlank(courseId)) {
log.error("【导出课程学习记录】课程id不能为空");
return;
}
// 定义输出流
OutputStream outputStream = null;
try {
@@ -154,6 +173,7 @@ public class StudyCourseApi extends ApiBaseController{
exportMap.put("学习进度", "学习进度");
// 2.查询课程的所有考试答卷信息拼接动态表头XXX考试成绩
// 注意:这里的考试信息每个学生每门课程只有一条,实际数据可能多次考试,因此根据考试配置中的(最高分/最新数据)获取对应列表数据即可(本次新增接口)
// TODO 这里回头要换成根据考试设置最新/最多的接口
List<StudyExam> studyExams = studyExamService.getByCourseId(courseId);
// courseExam和studyExam表都有testName字段查看现有逻辑后选择studyExam表的testName字段作为考试名称
// 因为需求没提因此查询按默认id排序
@@ -201,6 +221,42 @@ public class StudyCourseApi extends ApiBaseController{
StudyCourse studyCourse = new StudyCourse();
studyCourse.setCourseId(courseId);
List<StudyCourse> studyCourses = service.findList(studyCourse, null, null);
// 通过studyCourses中的人员id集合(去重),调用用户中心接口获取人员信息,填充部门字段
List<String> userIds = studyCourses.stream().map(StudyCourse::getAid).filter(Objects::nonNull).collect(Collectors.toList());
if (!userIds.isEmpty()) {
// 调用用户中心接口
List<UserSimpleVo> userSimpleVos = outsideService.findByIds(userIds);
if (userSimpleVos != null && !userSimpleVos.isEmpty()) {
for (UserSimpleVo userSimpleVo : userSimpleVos) {
// 填充部门字段
for (StudyCourse studyCourse1 : studyCourses) {
if (userSimpleVo.getAid().equals(studyCourse1.getAid())) {
studyCourse1.setOrgInfo(userSimpleVo.getOrgInfo());
}
}
}
} else {
log.error("【导出课程学习记录】用户信息查询失败查询boe人员表作为兜底方案");
// 和需求沟通后查询用户中心失败情况查询boe的人员表作为兜底方案如果仍然查询不到则不填充继续导出其他字段
for (String userId : userIds) {
// 用户信息也是redis获取的
User userInfo = userService.get(userId);
log.info("【导出课程学习记录】查询boe人员表用户id{}", userId);
if (userInfo != null) {
// 填充部门字段
for (StudyCourse studyCourse1 : studyCourses) {
if (Objects.equals(userId, studyCourse1.getAid())) {
log.info("【导出课程学习记录】查询boe人员表机构id{}", userInfo.getDepartId());
// 和技术沟通后确认这里机构名称是redis获取的获取不到返回null因此正常遍历没有效率和空值问题
studyCourse1.setOrgInfo(organizationService.getName(userInfo.getDepartId()));
}
}
} else {
log.error("【导出课程学习记录】用户信息查询boe人员表失败用户id{}", userId);
}
}
}
}
// 将课程学习记录与考试信息拼接为map
List<Map<String, Object>> dataList = studyCourses.stream().map(studyCourse1 -> {
Map<String, Object> map = new HashMap<>();
@@ -209,13 +265,13 @@ public class StudyCourseApi extends ApiBaseController{
map.put("姓名", studyCourse1.getAname());
map.put("工号", studyCourse1.getAid());
// 部门信息需要额外获取,暂时留空
map.put("部门", "");
map.put("部门", studyCourse1.getOrgInfo());
// 这个开始时间已经弃置了,不过先用再说(有值)
map.put("学习开始时间", studyCourse1.getStartTime());
// 结束时间为空的,说明还没学习结束(有值)
map.put("学习结束时间", studyCourse1.getFinishTime());
// 学习时长需要计算,暂时留空
map.put("学习时长(分)", "");
// 学习时长学习总时间是秒现在要求的学习时间是分钟向上取整1秒算1分钟60秒算1分钟61秒算2分钟
map.put("学习时长(分)", studyCourse1.getTotalDuration() == null ? null : (int) Math.ceil(studyCourse1.getTotalDuration() / 60.0));
// 学习状态需要转换
String statusText = "";
if (studyCourse1.getStatus() != null) {

View File

@@ -1,18 +1,16 @@
package com.xboe.school.study.entity;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.IdEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.IdEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/*
* 课程学习表,课程图片通过对应图片的api获取,这里不做存储。
@@ -83,8 +81,9 @@ public class StudyCourse extends IdEntity{
/*
* 开始学习时间,报名和学习是一体的,此字段为后续报名学习不致的情况,当前这种情况没有
* */
@Deprecated
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
// @Deprecated
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "start_time")
private LocalDateTime startTime;
@@ -105,8 +104,9 @@ public class StudyCourse extends IdEntity{
/*
* 学习总时间,秒,没有小数的情况,所以直接使用整数类型
* 这一项计算时间,在二期中已经不在使用,学习时长已经移到统计服务中,单独的课程不再记录
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
@Deprecated
// @Deprecated
@Column(name = "total_duration")
private Integer totalDuration;
@@ -142,7 +142,14 @@ public class StudyCourse extends IdEntity{
* */
@Column(name = "remark",length = 200)
private String remark;
/**
* 机构信息,多级使用/分隔
*/
@Transient
private String orgInfo;
@Transient
private String courseImage;