From eb684e5fede8da29ed3683a466864ba63e29e83b Mon Sep 17 00:00:00 2001 From: miaowenbo <1670593359@qq.com> Date: Mon, 15 Dec 2025 20:45:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.=E3=80=90FCJDFDXTXS-120=E3=80=91?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=AD=A6=E4=B9=A0=E8=AE=B0=E5=BD=95=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0=E5=AE=8C=E6=88=90=E6=97=B6=E9=97=B4=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=AD=A6=E4=B9=A0=E7=BB=93=E6=9D=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=BA=94=E4=B8=BA=E5=AD=A6=E7=94=9F=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E5=AD=A6=E4=B9=A0=E6=97=B6=E9=97=B4=202.?= =?UTF-8?q?=E3=80=90FCJDFDXTXS-115=E3=80=81138=E3=80=81140=E3=80=91?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=BE=E7=A8=8B=E5=90=8D=E7=A7=B0=E7=9A=84?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E7=AB=A0=E5=90=8D=E7=A7=B0+=E8=8A=82=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=EF=BC=8C=E8=AF=A6=E7=BB=86=E9=80=BB=E8=BE=91=E5=A6=82?= =?UTF-8?q?=E4=B8=8B=EF=BC=9A=E9=BB=98=E8=AE=A4=E5=8F=96sectionName-conten?= =?UTF-8?q?tName=EF=BC=8C=E5=A6=82=E6=9E=9CsectionName=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=EF=BC=8C=E5=B0=B1=E7=94=A8courseName-contentName?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/course/entity/CourseContent.java | 18 ++- .../course/service/ICourseContentService.java | 8 ++ .../course/service/ICourseSectionService.java | 13 +- .../impl/CourseContentServiceImpl.java | 8 ++ .../impl/CourseSectionServiceImpl.java | 27 ++-- .../xboe/school/study/api/StudyCourseApi.java | 21 ++-- .../school/study/entity/StudyCourseItem.java | 7 ++ .../school/study/service/IStudyService.java | 9 ++ .../study/service/impl/StudyServiceImpl.java | 116 ++++++++++++++++-- 9 files changed, 197 insertions(+), 30 deletions(-) diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/entity/CourseContent.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/entity/CourseContent.java index 3e92ee3a..6e97a95e 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/entity/CourseContent.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/entity/CourseContent.java @@ -1,16 +1,15 @@ package com.xboe.module.course.entity; +import com.xboe.core.SysConstant; +import com.xboe.core.orm.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Transient; -import com.xboe.core.SysConstant; -import com.xboe.core.orm.BaseEntity; - -import lombok.Data; -import lombok.EqualsAndHashCode; - /** * 课程内容表 * */ @@ -93,6 +92,13 @@ public class CourseContent extends BaseEntity { /**用于学习时的状态显示,非存储字段*/ @Transient private Integer status; + + /** + * 展示名称(章名+节名,如果没有章节,则为课程名+节名) + * 25.12.15新增 + */ + @Transient + private String displayName; public CourseContent() { diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseContentService.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseContentService.java index 46cfa4f1..e3b85d4d 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseContentService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseContentService.java @@ -56,6 +56,14 @@ public interface ICourseContentService{ */ List getByCourseId(String courseId); + /** + * 根据id集合得到内容 + * + * @param ids id集合 + * @return 课程内容集合 + */ + List getByIds(List ids); + /** * 根据课程id、章节id得到课程所有目录(即章节,分页),顺序按orderIndex 从小到大的顺序 * 25.11.26新增 diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseSectionService.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseSectionService.java index d3c0f402..2c02da56 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseSectionService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseSectionService.java @@ -1,9 +1,9 @@ package com.xboe.module.course.service; -import java.util.List; - import com.xboe.module.course.entity.CourseSection; +import java.util.List; + /** * 课程章节目录 * */ @@ -27,4 +27,13 @@ public interface ICourseSectionService { */ List getByCourseId(String courseId); + /** + * 根据id批量查询课程章节目录 + * + * @param ids id集合 + * @return 课程章节目录集合 + */ + List getByIds(List ids); + + } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseContentServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseContentServiceImpl.java index 08f16bb5..1dbb054f 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseContentServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseContentServiceImpl.java @@ -142,6 +142,14 @@ public class CourseContentServiceImpl implements ICourseContentService { return list; } + @Override + public List getByIds(List ids) { + if (ids == null || ids.isEmpty()) { + return new ArrayList<>(); + } + return ccDao.findList(OrderCondition.asc("sortIndex"), FieldFilters.in("id", ids), FieldFilters.eq("deleted", false)); + } + /** * 根据课程id、章节id得到课程所有目录(即章节,分页),顺序按orderIndex 从小到大的顺序 * 25.11.26新增 diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseSectionServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseSectionServiceImpl.java index 2e33b0b5..bbb409ab 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseSectionServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseSectionServiceImpl.java @@ -1,17 +1,16 @@ package com.xboe.module.course.service.impl; -import java.util.List; - -import javax.annotation.Resource; -import javax.transaction.Transactional; - -import org.springframework.stereotype.Service; - import com.xboe.common.OrderCondition; import com.xboe.core.orm.FieldFilters; import com.xboe.module.course.dao.CourseSectionDao; import com.xboe.module.course.entity.CourseSection; import com.xboe.module.course.service.ICourseSectionService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; @Service @Transactional @@ -35,6 +34,20 @@ public class CourseSectionServiceImpl implements ICourseSectionService { return courseSectionDao.findList(OrderCondition.asc("orderIndex"), FieldFilters.eq("courseId", courseId)); } + /** + * 根据id批量查询课程章节目录 + * + * @param ids id集合 + * @return 课程章节目录集合 + */ + @Override + public List getByIds(List ids) { + if (ids == null || ids.isEmpty()) { + return new ArrayList<>(); + } + return courseSectionDao.findList(OrderCondition.asc("orderIndex"), FieldFilters.in("id", ids)); + } + // @Override // public void copyCourseSection(String id) { // String sql="insert into boe_course_section(course_id,description,name," + diff --git a/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java b/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java index b4fae8c5..37390cbb 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java +++ b/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java @@ -452,7 +452,8 @@ public class StudyCourseApi extends ApiBaseController{ // 这个开始时间已经弃置了,不过先用再说(有值) map.put("学习开始时间", studyCourse1.getStartTime()); // 结束时间为空的,说明还没学习结束(有值) - map.put("学习结束时间", studyCourse1.getFinishTime()); + // 25.12.15修改,需求调整:如果结束时间为空,改为获取最后一次学习时间 + map.put("学习结束时间", studyCourse1.getFinishTime() == null ? studyCourse1.getLastTime() : studyCourse1.getFinishTime()); // 学习时长(保留两位小数): map.put("学习时长", studyCourse1.getTotalDuration() == null ? null : String.format("%.2f", studyCourse1.getTotalDuration() / 60.0)); // 学习状态需要转换 @@ -1356,11 +1357,14 @@ public class StudyCourseApi extends ApiBaseController{ courseName = studyCourses.get(0).getCourseName(); // 查询资源名称 List courseContents = contentService.getByCourseId(courseId); - String contentName = ""; + String displayName = ""; if (courseContents != null && !courseContents.isEmpty()) { + // 25.12.15新增,修改课程名称的展示逻辑,修改为章名称+节名称 + // 详细逻辑如下:默认取sectionName-contentName,如果sectionName不存在,就用courseName-contentName + studyService.setContentDisplayName(courseContents); for (CourseContent cc : courseContents) { if (contentId.equals(cc.getId())) { - contentName = cc.getContentName(); + displayName = cc.getDisplayName(); break; } } @@ -1398,7 +1402,7 @@ public class StudyCourseApi extends ApiBaseController{ } } // 将考试信息与用户信息拼接为map - String finalContentName = contentName; + String finalContentName = displayName; List> dataList = studyExams.stream().map(exam -> { Map map = new HashMap<>(); // 拼接基本信息 @@ -1494,11 +1498,14 @@ public class StudyCourseApi extends ApiBaseController{ } // 查询资源名称 List courseContents = contentService.getByCourseId(courseId); - String contentName = ""; + String displayName = ""; if (courseContents != null && !courseContents.isEmpty()) { for (CourseContent cc : courseContents) { + // 25.12.15新增,修改课程名称的展示逻辑,修改为章名称+节名称 + // 详细逻辑如下:默认取sectionName-contentName,如果sectionName不存在,就用courseName-contentName + studyService.setContentDisplayName(courseContents); if (contentId.equals(cc.getId())) { - contentName = cc.getContentName(); + displayName = cc.getDisplayName(); break; } } @@ -1536,7 +1543,7 @@ public class StudyCourseApi extends ApiBaseController{ } } // 3.将作业信息与用户信息拼接为map - String finalContentName = contentName; + String finalContentName = displayName; List> dataList = studyHomeWorks.stream().map(hw -> { Map map = new HashMap<>(); // 拼接基本信息 diff --git a/servers/boe-server-all/src/main/java/com/xboe/school/study/entity/StudyCourseItem.java b/servers/boe-server-all/src/main/java/com/xboe/school/study/entity/StudyCourseItem.java index 81853d45..ec2ed71a 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/school/study/entity/StudyCourseItem.java +++ b/servers/boe-server-all/src/main/java/com/xboe/school/study/entity/StudyCourseItem.java @@ -137,6 +137,13 @@ public class StudyCourseItem extends IdEntity { @Transient private BigDecimal progressVideo; + /** + * 展示名称(章名+节名,如果没有章节,则为课程名+节名) + * 25.12.15新增 + */ + @Transient + private String displayName; + /** * 考试记录集合 * 仅在资源学习情况分页查询-考试信息接口使用 diff --git a/servers/boe-server-all/src/main/java/com/xboe/school/study/service/IStudyService.java b/servers/boe-server-all/src/main/java/com/xboe/school/study/service/IStudyService.java index 4c8c5005..779016f7 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/school/study/service/IStudyService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/school/study/service/IStudyService.java @@ -1,6 +1,7 @@ package com.xboe.school.study.service; import com.xboe.common.PageList; +import com.xboe.module.course.entity.CourseContent; import com.xboe.school.study.dto.StudyContentDto; import com.xboe.school.study.entity.StudyCourseItem; import com.xboe.school.study.entity.StudyTime; @@ -101,6 +102,14 @@ public interface IStudyService { */ PageList findItemPage(int pageIndex, int pageSize, List ids, String contentId, String courseId, String name, Integer status); + /** + * 为courseContents列表设置展示名称(章名+节名 或 课程名+节名) + * 25.12.15新增 + * + * @param courseContents 课程内容集合 + */ + void setContentDisplayName(List courseContents); + List getList(String courseId, String contentId, String name, Integer status); void updateStudyCourseItemLastTime(String studyContentId, int lastStudyTime, LocalDateTime timestamp); diff --git a/servers/boe-server-all/src/main/java/com/xboe/school/study/service/impl/StudyServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/school/study/service/impl/StudyServiceImpl.java index 1df9291e..eb74cefc 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/school/study/service/impl/StudyServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/school/study/service/impl/StudyServiceImpl.java @@ -8,12 +8,17 @@ import com.xboe.core.orm.QueryBuilder; import com.xboe.core.orm.UpdateBuilder; import com.xboe.module.course.entity.Course; import com.xboe.module.course.entity.CourseContent; +import com.xboe.module.course.entity.CourseSection; +import com.xboe.module.course.service.ICourseContentService; +import com.xboe.module.course.service.ICourseSectionService; import com.xboe.school.study.dao.StudyCourseDao; import com.xboe.school.study.dao.StudyCourseItemDao; import com.xboe.school.study.dao.StudyTimeDao; import com.xboe.school.study.dto.StudyContentDto; +import com.xboe.school.study.entity.StudyCourse; import com.xboe.school.study.entity.StudyCourseItem; import com.xboe.school.study.entity.StudyTime; +import com.xboe.school.study.service.IStudyCourseService; import com.xboe.school.study.service.IStudyService; import com.xboe.standard.enums.BoedxContentType; import com.xboe.system.user.dao.UserDao; @@ -27,10 +32,10 @@ import javax.transaction.Transactional; import java.time.Duration; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + @Slf4j @Service public class StudyServiceImpl implements IStudyService{ @@ -46,6 +51,16 @@ public class StudyServiceImpl implements IStudyService{ @Autowired UserDao userDao; + + @Autowired + IStudyCourseService studyCourseService; + + @Autowired + ICourseContentService courseContentService; + + @Autowired + ICourseSectionService courseSectionService; + @Autowired StringRedisTemplate redisTemplate; @@ -272,7 +287,7 @@ public class StudyServiceImpl implements IStudyService{ } } // 未传输status的情况,查询所有资源学习情况数据 - String sql = "select a.id, a.course_id, a.course_name, a.aname, " + "IFNULL(b.finish_time, '0') as finish_time, IFNULL(b.progress, 0) as progress, IFNULL(b.status, 1) as status " + ",b.score,b.item_id,b.aid " + "from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "'" + (StringUtils.isBlank(name) ? "" : "and aname like '%" + name + "%'") + ") a " + "inner join " + "(select bsc.id, bsc.course_id, bsc.course_name, bsc.aname, item.id as item_id,item.finish_time, item.progress, item.status,MAX(item.score) score,item.aid " + "from boe_study_course bsc left join boe_study_course_item item on item.course_id = bsc.course_id and item.study_id = bsc.id " + "where bsc.course_id = '" + courseId + "'" + + String sql = "select a.id, a.course_id, a.course_name, a.aname, " + "IFNULL(b.finish_time, '0') as finish_time, IFNULL(b.progress, 0) as progress, IFNULL(b.status, 1) as status " + ",b.score,b.item_id,b.aid,b.content_id " + "from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "'" + (StringUtils.isBlank(name) ? "" : "and aname like '%" + name + "%'") + ") a " + "inner join " + "(select bsc.id, bsc.course_id, bsc.course_name, bsc.aname, item.id as item_id,item.finish_time, item.progress, item.status,MAX(item.score) score,item.aid,item.content_id " + "from boe_study_course bsc left join boe_study_course_item item on item.course_id = bsc.course_id and item.study_id = bsc.id " + "where bsc.course_id = '" + courseId + "'" + (StringUtils.isBlank(contentId) ? "" : "and item.content_id = '" + contentId + "'") + (StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name +"%'") + " group by bsc.id) b " + "on a.course_id = b.course_id and a.id = b.id " + @@ -306,17 +321,102 @@ public class StudyServiceImpl implements IStudyService{ sc.setScore(Float.valueOf(objs[7].toString())); } // 25.12.5新增,补全aid查询 - if (objs[8] != null) { - sc.setAid(String.valueOf(objs[8].toString())); + if (objs[9] != null) { + sc.setAid(String.valueOf(objs[9].toString())); + } + // 25.12.15新增,补全contentId查询 + if (objs[10] != null) { + sc.setContentId(String.valueOf(objs[10].toString())); } item.add(sc); } + // 25.12.15新增,修改课程名称的展示逻辑,修改为章名称+节名称 + // 详细逻辑如下:默认取sectionName-contentName,如果sectionName不存在,就用courseName-contentName + List contentIds = item.stream().map(StudyCourseItem::getContentId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + if (!contentIds.isEmpty()) { + List contentList = courseContentService.getByIds(contentIds); + if (contentList != null) { + setContentDisplayName(contentList); + // 根据contentId将展示名称映射到item + for (StudyCourseItem studyCourseItem : item) { + studyCourseItem.setDisplayName(contentList.stream().filter(content -> content.getId().equals(studyCourseItem.getContentId())).findFirst().map(CourseContent::getDisplayName).orElse(null)); + } + } + } + // 查询当前 PageList pageList = new PageList<>(item); pageList.setCount(totalCount); pageList.setPageSize(pageSize); pageList.setList(item); return pageList; - + } + + /** + * 为 CourseContent 列表设置展示名称(章名+节名 或 课程名+节名) + * 基于 25.12.15 的展示逻辑:优先使用 章名+节名,章不存在则退化为 课程名+节名 + * + * @param courseContents 节内容列表(即“节”) + */ + @Override + public void setContentDisplayName(List courseContents) { + if (courseContents == null || courseContents.isEmpty()) { + return; + } + // 1. 提取唯一 sectionId 和 courseId + Set sectionIds = new HashSet<>(); + Set courseIds = new HashSet<>(); + for (CourseContent content : courseContents) { + if (content.getCsectionId() != null) { + sectionIds.add(content.getCsectionId()); + } + if (content.getCourseId() != null) { + courseIds.add(content.getCourseId()); + } + } + // 2. 批量查询 CourseSection + Map sectionMap = new HashMap<>(); + if (!sectionIds.isEmpty()) { + List sections = courseSectionService.getByIds(new ArrayList<>(sectionIds)); + if (sections != null) { + sectionMap = sections.stream().collect(Collectors.toMap(CourseSection::getId, Function.identity(), (e1, e2) -> e1)); + } + } + // 3. 批量查询 StudyCourse + Map courseMap = new HashMap<>(); + if (!courseIds.isEmpty()) { + List courses = studyCourseService.findByIds(new ArrayList<>(courseIds)); + if (courses != null) { + courseMap = courses.stream().collect(Collectors.toMap(StudyCourse::getId, Function.identity(), (e1, e2) -> e1)); + } + } + // 4. 为每个 CourseContent 设置 displayName + for (CourseContent courseContent : courseContents) { + String sectionName = null; + String courseName = "空课程名称"; + String contentName = (courseContent.getContentName() != null) ? courseContent.getContentName() : "空内容名称"; + // 尝试获取章名 + if (courseContent.getCsectionId() != null) { + CourseSection section = sectionMap.get(courseContent.getCsectionId()); + if (section != null && section.getName() != null) { + sectionName = section.getName(); + } + } + // 设置 displayName:优先章+节,否则课程+节 + String displayName; + if (sectionName != null) { + displayName = sectionName + "-" + contentName; + } else { + // 获取课程名 + if (courseContent.getCourseId() != null) { + StudyCourse course = courseMap.get(courseContent.getCourseId()); + if (course != null && course.getCourseName() != null) { + courseName = course.getCourseName(); + } + } + displayName = courseName + "-" + contentName; + } + courseContent.setDisplayName(displayName); + } } @Override