Răsfoiți Sursa

1、课程和编程更改主题、类型是同步修改进度数据
2、course课程列表支持类型节点查询
3、前端主题下课程根据排序查询

liyanbo 4 luni în urmă
părinte
comite
a55cfa91e9

+ 1 - 1
byzs-blockly/src/main/java/cn/iocoder/byzs/module/blockly/controller/admin/blockly/BlocklyController.java

@@ -67,7 +67,7 @@ public class BlocklyController {
     @DeleteMapping("/delete-list")
     @Parameter(name = "ids", description = "编号", required = true)
     @Operation(summary = "批量删除课程")
-                @PreAuthorize("@ss.hasPermission('blockly:blockly:delete')")
+    @PreAuthorize("@ss.hasPermission('blockly:blockly:delete')")
     public CommonResult<Boolean> deleteBlocklyList(@RequestParam("ids") List<Long> ids) {
         blocklyService.deleteBlocklyListByIds(ids);
         return success(true);

+ 65 - 0
byzs-blockly/src/main/java/cn/iocoder/byzs/module/blockly/dal/dataobject/blocklyProgress/BlocklyProgressDO.java

@@ -0,0 +1,65 @@
+package cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyProgress;
+
+import cn.iocoder.byzs.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+/**
+ * 评估报告-课程开课率 DO
+ *
+ * @author lyb
+ */
+@TableName("blockly_report_progress")
+@KeySequence("blockly_report_progress_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class BlocklyProgressDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long brpId;
+    /**
+     * 用户id
+     */
+    private Long brpUserId;
+    /**
+     * 主题id
+     */
+    @NonNull
+    private Long brpZtId;
+    /**
+     * 课程类型id
+     */
+    @NonNull
+    private Long brpCtId;
+    /**
+     * 课程id
+     */
+    @NonNull
+    private Long brpCourseId;
+    /**
+     * 课程配置id
+     */
+    private Long brpCourseConfigId;
+    /**
+     * 进度分类
+     */
+    @NonNull
+    private String brpType;
+    /**
+     * 进度(课程开课率、课程互动率、ai问答次数)
+     */
+    private Double brpProgress;
+
+
+}

+ 15 - 0
byzs-blockly/src/main/java/cn/iocoder/byzs/module/blockly/dal/mysql/blocklyProgress/BlocklyProgressMapper.java

@@ -0,0 +1,15 @@
+package cn.iocoder.byzs.module.blockly.dal.mysql.blocklyProgress;
+
+import cn.iocoder.byzs.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyProgress.BlocklyProgressDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 课程-类型 Mapper
+ *
+ * @author lyb
+ */
+@Mapper
+public interface BlocklyProgressMapper extends BaseMapperX<BlocklyProgressDO> {
+
+}

+ 22 - 3
byzs-blockly/src/main/java/cn/iocoder/byzs/module/blockly/service/blockly/BlocklyServiceImpl.java

@@ -5,11 +5,16 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.byzs.framework.common.pojo.PageResult;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.byzs.module.blockly.controller.admin.blockly.vo.BlocklyPageReqVO;
 import cn.iocoder.byzs.module.blockly.controller.admin.blockly.vo.BlocklyRespVO;
 import cn.iocoder.byzs.module.blockly.controller.admin.blockly.vo.BlocklySaveReqVO;
 import cn.iocoder.byzs.module.blockly.dal.dataobject.blockly.BlocklyDO;
+import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyProgress.BlocklyProgressDO;
+import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyType.BlocklyTypeDO;
 import cn.iocoder.byzs.module.blockly.dal.mysql.blockly.BlocklyMapper;
+import cn.iocoder.byzs.module.blockly.dal.mysql.blocklyProgress.BlocklyProgressMapper;
+import cn.iocoder.byzs.module.blockly.dal.mysql.blocklyType.BlocklyTypeMapper;
 import cn.iocoder.byzs.module.infra.dal.dataobject.file.FileDO;
 import cn.iocoder.byzs.module.infra.framework.file.core.client.FileClient;
 import cn.iocoder.byzs.module.infra.service.file.FileConfigService;
@@ -37,9 +42,13 @@ public class BlocklyServiceImpl implements BlocklyService {
     @Resource
     private BlocklyMapper blocklyMapper;
     @Resource
+    private BlocklyTypeMapper blocklyTypeMapper;
+    @Resource
     private FileServiceImpl fileService;
     @Resource
     private FileConfigService fileConfigService;
+    @Resource
+    private BlocklyProgressMapper blocklyProgressMapper;
 
     @Override
     public Long createBlockly(BlocklySaveReqVO createReqVO) {
@@ -57,11 +66,19 @@ public class BlocklyServiceImpl implements BlocklyService {
     @Override
     public void updateBlockly(BlocklySaveReqVO updateReqVO) {
         // 校验存在
-        validateBlocklyExists(updateReqVO.getId());
+        BlocklyDO blocklyDO = validateBlocklyExists(updateReqVO.getId());
         // 更新
         BlocklyDO updateObj = BeanUtils.toBean(updateReqVO, BlocklyDO.class);
         blocklyMapper.updateById(updateObj);
 
+        //同步进度表中的课程类型
+        if (!blocklyDO.getBcType().equals(updateObj.getBcType())) {
+            BlocklyTypeDO blocklyTypeDO = blocklyTypeMapper.selectById(updateObj.getBcType());
+            // 使用条件更新,将brpCtId等于旧课程类型ID的记录更新为新课程类型ID
+            blocklyProgressMapper.update(new BlocklyProgressDO().setBrpCtId(updateObj.getBcType()).setBrpZtId(blocklyTypeDO.getCtParentId()),
+                                         new LambdaQueryWrapperX<BlocklyProgressDO>().eq(BlocklyProgressDO::getBrpCtId, blocklyDO.getBcType()));
+        }
+
         if (updateObj.getBcContentType().equals("video")) {
             getSelf().asymcVideoFfmpeg(updateObj);
         }
@@ -122,10 +139,12 @@ public class BlocklyServiceImpl implements BlocklyService {
         }
     }
 
-    private void validateBlocklyExists(Long id) {
-        if (blocklyMapper.selectById(id) == null) {
+    private BlocklyDO validateBlocklyExists(Long id) {
+        BlocklyDO blocklyDO = blocklyMapper.selectById(id);
+        if (blocklyDO == null) {
             throw exception(BLOCKLY_NOT_EXISTS);
         }
+        return blocklyDO;
     }
 
     @Override

+ 18 - 3
byzs-blockly/src/main/java/cn/iocoder/byzs/module/blockly/service/blocklyType/BlocklyTypeServiceImpl.java

@@ -1,9 +1,12 @@
 package cn.iocoder.byzs.module.blockly.service.blocklyType;
 
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.byzs.module.blockly.controller.admin.blocklyType.vo.BlocklyTypeListReqVO;
 import cn.iocoder.byzs.module.blockly.controller.admin.blocklyType.vo.BlocklyTypeSaveReqVO;
+import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyProgress.BlocklyProgressDO;
 import cn.iocoder.byzs.module.blockly.dal.dataobject.blocklyType.BlocklyTypeDO;
+import cn.iocoder.byzs.module.blockly.dal.mysql.blocklyProgress.BlocklyProgressMapper;
 import cn.iocoder.byzs.module.blockly.dal.mysql.blocklyType.BlocklyTypeMapper;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
@@ -26,6 +29,8 @@ public class BlocklyTypeServiceImpl implements BlocklyTypeService {
 
     @Resource
     private BlocklyTypeMapper blocklyTypeMapper;
+    @Resource
+    private BlocklyProgressMapper blocklyProgressMapper;
 
     @Override
     public Long createBlocklyType(BlocklyTypeSaveReqVO createReqVO) {
@@ -44,7 +49,7 @@ public class BlocklyTypeServiceImpl implements BlocklyTypeService {
     @Override
     public void updateBlocklyType(BlocklyTypeSaveReqVO updateReqVO) {
         // 校验存在
-        validateBlocklyTypeExists(updateReqVO.getId());
+        BlocklyTypeDO blocklyTypeDO = validateBlocklyTypeExists(updateReqVO.getId());
         // 校验课程类型父级id的有效性
         validateParentBlocklyType(updateReqVO.getId(), updateReqVO.getCtParentId());
         // 校验课程类型名称的唯一性
@@ -53,6 +58,14 @@ public class BlocklyTypeServiceImpl implements BlocklyTypeService {
         // 更新
         BlocklyTypeDO updateObj = BeanUtils.toBean(updateReqVO, BlocklyTypeDO.class);
         blocklyTypeMapper.updateById(updateObj);
+
+        // 如果修改了类型,同步更新进度数据
+        if (!blocklyTypeDO.getCtTypeNode().equals("0") && !Objects.equals(updateObj.getCtParentId(), blocklyTypeDO.getCtParentId())) {
+
+            // 使用条件更新,将brpCtId等于旧课程类型ID的记录更新为新课程类型ID
+            blocklyProgressMapper.update(new BlocklyProgressDO().setBrpZtId(updateObj.getCtParentId()),
+                    new LambdaQueryWrapperX<BlocklyProgressDO>().eq(BlocklyProgressDO::getBrpZtId, blocklyTypeDO.getCtParentId()));
+        }
     }
 
     @Override
@@ -68,10 +81,12 @@ public class BlocklyTypeServiceImpl implements BlocklyTypeService {
     }
 
 
-    private void validateBlocklyTypeExists(Long id) {
-        if (blocklyTypeMapper.selectById(id) == null) {
+    private BlocklyTypeDO validateBlocklyTypeExists(Long id) {
+        BlocklyTypeDO blocklyTypeDO = blocklyTypeMapper.selectById(id);
+        if (blocklyTypeDO == null) {
             throw exception(BLOCKLY_TYPE_NOT_EXISTS);
         }
+        return blocklyTypeDO;
     }
 
     private void validateParentBlocklyType(Long id, Long ctParentId) {

+ 3 - 0
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/controller/admin/course/vo/CoursePageReqVO.java

@@ -66,4 +66,7 @@ public class CoursePageReqVO extends PageParam {
     @Schema(description = "课程状态")
     private String courseStatus;
 
+    @Schema(description = "课程类型节点")
+    private String ctTypeNode;
+
 }

+ 65 - 0
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/dal/dataobject/reportprogress/CourseReportProgressDO.java

@@ -0,0 +1,65 @@
+package cn.iocoder.byzs.module.bjdx.dal.dataobject.reportprogress;
+
+import cn.iocoder.byzs.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+/**
+ * 评估报告-课程开课率 DO
+ *
+ * @author lyb
+ */
+@TableName("bjdx_report_progress")
+@KeySequence("bjdx_report_progress_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class CourseReportProgressDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long brpId;
+    /**
+     * 用户id
+     */
+    private Long brpUserId;
+    /**
+     * 年级id
+     */
+    @NonNull
+    private Long brpNjId;
+    /**
+     * 课程类型id
+     */
+    @NonNull
+    private Long brpCtId;
+    /**
+     * 课程id
+     */
+    @NonNull
+    private Long brpCourseId;
+    /**
+     * 课程配置id
+     */
+    private Long brpCourseConfigId;
+    /**
+     * 进度分类
+     */
+    @NonNull
+    private String brpType;
+    /**
+     * 进度(课程开课率、课程互动率、ai问答次数)
+     */
+    private Double brpProgress;
+
+
+}

+ 23 - 3
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/service/course/CourseServiceImpl.java

@@ -5,11 +5,16 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.byzs.framework.common.pojo.PageResult;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CoursePageReqVO;
 import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseRespVO;
 import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseSaveReqVO;
 import cn.iocoder.byzs.module.bjdx.dal.dataobject.course.CourseDO;
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.coursetype.CourseTypeDO;
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.reportprogress.CourseReportProgressDO;
 import cn.iocoder.byzs.module.bjdx.dal.mysql.course.CourseMapper;
+import cn.iocoder.byzs.module.bjdx.dal.mysql.coursetype.CourseTypeMapper;
+import cn.iocoder.byzs.module.bjdx.service.reportprogress.CourseReportProgressMapper;
 import cn.iocoder.byzs.module.infra.dal.dataobject.file.FileDO;
 import cn.iocoder.byzs.module.infra.framework.file.core.client.FileClient;
 import cn.iocoder.byzs.module.infra.service.file.FileConfigService;
@@ -20,6 +25,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -40,6 +46,10 @@ public class CourseServiceImpl implements CourseService {
     private FileServiceImpl fileService;
     @Resource
     private FileConfigService fileConfigService;
+    @Resource
+    private CourseTypeMapper courseTypeMapper;
+    @Resource
+    private CourseReportProgressMapper courseReportProgressMapper;
 
     @Override
     public Long createCourse(CourseSaveReqVO createReqVO) {
@@ -57,11 +67,19 @@ public class CourseServiceImpl implements CourseService {
     @Override
     public void updateCourse(CourseSaveReqVO updateReqVO) {
         // 校验存在
-        validateCourseExists(updateReqVO.getId());
+        CourseDO courseDO = validateCourseExists(updateReqVO.getId());
+
         // 更新
         CourseDO updateObj = BeanUtils.toBean(updateReqVO, CourseDO.class);
         courseMapper.updateById(updateObj);
 
+        //同步进度表中的课程类型
+        if (!Objects.equals(courseDO.getCourseType(), updateObj.getCourseType())) {
+            CourseTypeDO courseTypeDO = courseTypeMapper.selectById(updateObj.getCourseType());
+            courseReportProgressMapper.update(new CourseReportProgressDO().setBrpCtId(updateObj.getCourseType()).setBrpNjId(courseTypeDO.getCtParentId()),
+                    new LambdaQueryWrapperX<CourseReportProgressDO>().eq(CourseReportProgressDO::getBrpCtId, courseDO.getCourseType()));
+        }
+
         if (updateObj.getCourseContentType().equals("video")) {
             getSelf().asymcVideoFfmpeg(updateObj);
         }
@@ -122,10 +140,12 @@ public class CourseServiceImpl implements CourseService {
         }
     }
 
-    private void validateCourseExists(Long id) {
-        if (courseMapper.selectById(id) == null) {
+    private CourseDO validateCourseExists(Long id) {
+        CourseDO course = courseMapper.selectById(id);
+        if (course == null) {
             throw exception(COURSE_NOT_EXISTS);
         }
+        return course;
     }
 
     @Override

+ 20 - 3
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/service/coursetype/CourseTypeServiceImpl.java

@@ -3,12 +3,15 @@ package cn.iocoder.byzs.module.bjdx.service.coursetype;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeListReqVO;
 import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeSaveReqVO;
 import cn.iocoder.byzs.module.bjdx.dal.dataobject.course.CourseDO;
 import cn.iocoder.byzs.module.bjdx.dal.dataobject.coursetype.CourseTypeDO;
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.reportprogress.CourseReportProgressDO;
 import cn.iocoder.byzs.module.bjdx.dal.mysql.course.CourseMapper;
 import cn.iocoder.byzs.module.bjdx.dal.mysql.coursetype.CourseTypeMapper;
+import cn.iocoder.byzs.module.bjdx.service.reportprogress.CourseReportProgressMapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
@@ -35,6 +38,9 @@ public class CourseTypeServiceImpl implements CourseTypeService {
     @Resource
     private CourseMapper courseMapper;
 
+    @Resource
+    private CourseReportProgressMapper courseReportProgressMapper;
+
     @Override
     public Long createCourseType(CourseTypeSaveReqVO createReqVO) {
         // 校验课程类型父级id的有效性
@@ -72,7 +78,7 @@ public class CourseTypeServiceImpl implements CourseTypeService {
     @Override
     public void updateCourseType(CourseTypeSaveReqVO updateReqVO) {
         // 校验存在
-        validateCourseTypeExists(updateReqVO.getId());
+        CourseTypeDO courseTypeDO = validateCourseTypeExists(updateReqVO.getId());
         // 校验课程类型父级id的有效性
         validateParentCourseType(updateReqVO.getId(), updateReqVO.getCtParentId());
         // 校验课程类型名称的唯一性
@@ -81,6 +87,15 @@ public class CourseTypeServiceImpl implements CourseTypeService {
         // 更新
         CourseTypeDO updateObj = BeanUtils.toBean(updateReqVO, CourseTypeDO.class);
         courseTypeMapper.updateById(updateObj);
+
+        // 如果修改了类型,同步更新进度数据
+        if (!courseTypeDO.getCtTypeNode().equals("0") && !Objects.equals(updateObj.getCtParentId(), courseTypeDO.getCtParentId())) {
+
+            // 使用条件更新,将brpCtId等于旧课程类型ID的记录更新为新课程类型ID
+            courseReportProgressMapper.update(new CourseReportProgressDO().setBrpNjId(updateObj.getCtParentId()),
+                    new LambdaQueryWrapperX<CourseReportProgressDO>().eq(CourseReportProgressDO::getBrpNjId, courseTypeDO.getCtParentId()));
+        }
+        
     }
 
     @Override
@@ -96,10 +111,12 @@ public class CourseTypeServiceImpl implements CourseTypeService {
     }
 
 
-    private void validateCourseTypeExists(Long id) {
-        if (courseTypeMapper.selectById(id) == null) {
+    private CourseTypeDO validateCourseTypeExists(Long id) {
+        CourseTypeDO courseTypeDO = courseTypeMapper.selectById(id);
+        if (courseTypeDO == null) {
             throw exception(COURSE_TYPE_NOT_EXISTS);
         }
+        return courseTypeDO;
     }
 
     private void validateParentCourseType(Long id, Long ctParentId) {

+ 15 - 0
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/service/reportprogress/CourseReportProgressMapper.java

@@ -0,0 +1,15 @@
+package cn.iocoder.byzs.module.bjdx.service.reportprogress;
+
+import cn.iocoder.byzs.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.reportprogress.CourseReportProgressDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 评估报告-课程开课率
+ *
+ * @author lyb
+ */
+@Mapper
+public interface CourseReportProgressMapper extends BaseMapperX<CourseReportProgressDO> {
+
+}

+ 3 - 0
byzs-course/src/main/resources/mapper/course/CourseMapper.xml

@@ -28,6 +28,9 @@
             <if test="courseIsInspect!= null and courseIsInspect!= ''">
                 AND c.course_is_inspect = #{courseIsInspect}
             </if>
+            <if test="ctTypeNode!= null and ctTypeNode!= ''">
+                AND ct.ct_type_node = #{ctTypeNode}
+            </if>
         </where>
         ORDER BY ct.ct_type_sort, c.course_order
     </sql>

+ 3 - 1
byzs-web/src/main/resources/mapper/blockly/WebBlocklyMapper.xml

@@ -19,6 +19,8 @@
             bct.deleted = 0 AND bc.deleted = 0 AND bc.bc_status = 0 AND
             bct.ct_parent_id = #{ctParentId}
         GROUP BY
-            id, ctType, ctParentId, ctTypeImage, ctTypeSort;
+            id, ctType, ctParentId, ctTypeImage, ctTypeSort
+        ORDER BY
+            ctTypeSort;
     </select>
 </mapper>