Bläddra i källkod

1.修复组织和人id类型不一致导致报错,修改树工具
2.修复站内信时间,新建与查询不能共存情况
3.修复在国产系统服务器导入模板不兼容问题
4.加入主观题客观题数量
5.修复转换中的返参

honorfire 3 månader sedan
förälder
incheckning
01a4fbd200
12 ändrade filer med 201 tillägg och 10 borttagningar
  1. 2 1
      snowy-base/snowy-common/src/main/java/vip/xiaonuo/common/util/TreeUtil.java
  2. 63 0
      snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/message/entity/DevMessageVo.java
  3. 4 1
      snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/message/service/impl/DevMessageServiceImpl.java
  4. 4 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseInfoController.java
  5. 4 3
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceRecordController.java
  6. 1 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentBurialpoint.java
  7. 5 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseInfoMapper.java
  8. 2 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseAuditRecordMapper.xml
  9. 81 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseInfoMapper.xml
  10. 1 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseStudentBurialpointMapper.xml
  11. 34 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/CourseInfoServiceImpl.java
  12. BIN
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/resources/quesImportTemplate.xlsx

+ 2 - 1
snowy-base/snowy-common/src/main/java/vip/xiaonuo/common/util/TreeUtil.java

@@ -1,6 +1,7 @@
 package vip.xiaonuo.common.util;
 
 import cn.hutool.core.util.ObjectUtil;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -28,7 +29,7 @@ public class TreeUtil {
         List<Map<String,Object>> childTreeList = getChildTree(list,parentId);
         //用所有子节点,依次再去递归查询自己的所有子节点加进来
         for (Map map:childTreeList) {
-            List<Map<String, Object>> children = getThree(list, (String) map.get("id"));
+            List<Map<String, Object>> children = getThree(list, String.valueOf(map.get("id")));
             if(children.size() != 0){
                 map.put("children",children);
             }

+ 63 - 0
snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/message/entity/DevMessageVo.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.dev.modular.message.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import vip.xiaonuo.common.pojo.CommonEntity;
+
+import java.util.Date;
+
+/**
+ * 站内信实体
+ *
+ * @author xuyuxiang
+ * @date 2022/2/23 18:27
+ **/
+@Getter
+@Setter
+@TableName("DEV_MESSAGE")
+public class DevMessageVo extends CommonEntity {
+
+    /** id */
+    @ApiModelProperty(value = "主键", position = 1)
+    private String id;
+
+    /** 租户id */
+    @ApiModelProperty(value = "租户id", position = 2)
+    private String tenantId;
+
+    /** 分类 */
+    @ApiModelProperty(value = "分类", position = 3)
+    private String category;
+
+    /** 主题 */
+    @ApiModelProperty(value = "主题", position = 4)
+    private String subject;
+
+    /** 正文 */
+    @ApiModelProperty(value = "正文", position = 5)
+    private String content;
+
+    /** 扩展信息 */
+    @ApiModelProperty(value = "扩展信息", position = 6)
+    private String extJson;
+
+    /** 创建时间 */
+    @ApiModelProperty(value = "创建时间", position = 1000)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+}

+ 4 - 1
snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/message/service/impl/DevMessageServiceImpl.java

@@ -32,6 +32,7 @@ import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.dev.modular.message.entity.DevMessage;
+import vip.xiaonuo.dev.modular.message.entity.DevMessageVo;
 import vip.xiaonuo.dev.modular.message.enums.DevMessageCategoryEnum;
 import vip.xiaonuo.dev.modular.message.mapper.DevMessageMapper;
 import vip.xiaonuo.dev.modular.message.param.DevMessageIdParam;
@@ -129,7 +130,9 @@ public class DevMessageServiceImpl extends ServiceImpl<DevMessageMapper, DevMess
                 }
                 Page<JSONObject> resultPage = new Page<>();
                 Page<DevMessage> devMessagePage = this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
-                BeanUtil.copyProperties(devMessagePage, resultPage);
+                Page<DevMessageVo> devMessageVoPage = new Page<>();
+                BeanUtil.copyProperties(devMessagePage, devMessageVoPage);
+                BeanUtil.copyProperties(devMessageVoPage, resultPage);
                 List<String> relationMessageIdList = CollStreamUtil.toList(messageRelationList, DevRelation::getObjectId);
                 List<JSONObject> jsonObjectList = devMessagePage.getRecords().stream().map(obj -> {
                     JSONObject jsonObject = JSONUtil.parseObj(obj);

+ 4 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseInfoController.java

@@ -98,6 +98,10 @@ public class CourseInfoController {
         param.put("courseType", req.getParameter("courseType"));
         param.put("beginTime", req.getParameter("beginTime"));
         param.put("endTime", req.getParameter("endTime"));
+        //是否需要课程题目数量,0否1是,默认为否
+        String needQuesCount="0";
+        if(StringUtils.isNotEmpty(req.getParameter("needQuesCount")))needQuesCount=req.getParameter("needQuesCount");
+        param.put("needQuesCount", needQuesCount);
         //排序类型,0最新,1热门
         String sortflag="0";
         if(StringUtils.isNotEmpty(req.getParameter("sortflag")))sortflag=req.getParameter("sortflag");

+ 4 - 3
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceRecordController.java

@@ -805,7 +805,7 @@ public class ResourceRecordController {
     @ApiOperation("资源管理-学员超链接-添加")
     @CommonLog("资源管理-学员超链接-添加")
     //@SaCheckPermission("/disk/coursestulink/stuLinkResourceRecordAdd")
-    @PostMapping("/disk/coursestulink/stuLinkResourceRecordAdd")
+    @PostMapping("/disk/courseauditrecord/stuLinkResourceRecordAdd")
     public CommonResult<Map<String,Object>> stuLinkResourceRecordAdd(@RequestBody @Valid CourseAuditRecordAddParam courseAuditRecordAddParam) {
         Map result=new HashMap();
         //2025.10.30学生超链接功能标识,1老师上传,2查学生上传
@@ -834,11 +834,12 @@ public class ResourceRecordController {
             if("1".equals(stulinkType))
             {
                 courseAuditRecord.setCreateUser(teacherId);
-                courseAuditRecord.setFileName(StpLoginUserUtil.getLoginUser().getId());
+                courseAuditRecord.setLinkStuId(StpLoginUserUtil.getLoginUser().getId());
             }
             //2025.6.27废弃,改用userfile表,直接有相关信息
 //            ResourceUserFile resourceUserFile =resourceUserfileService.queryEntity(userFileId);
 //            courseAuditRecord.setFileName(resourceUserFile.getFileName());
+            courseAuditRecord.setVerifyStatus("0");
             courseAuditRecord.setUserfileId(userFileId);
             courseAuditRecord.setUploadBatchNum(uploadBatchNum);
             if(StringUtils.isNotEmpty(courseAuditRecordAddParam.getKeywordValue()))courseAuditRecord.setKeywordPinyin(StringUtils.deleteWhitespace(pinyinUtils.toPinyin(courseAuditRecordAddParam.getKeywordValue(),false)));
@@ -912,7 +913,7 @@ public class ResourceRecordController {
         if("1".equals(stulinkType))
         {
             courseAuditRecord.setCreateUser(teacherId);
-            courseAuditRecord.setFileName(StpLoginUserUtil.getLoginUser().getId());
+            courseAuditRecord.setLinkStuId(StpLoginUserUtil.getLoginUser().getId());
         }
         if(StringUtils.isNotEmpty(courseAuditRecordEditParam.getKeywordValue()))courseAuditRecord.setKeywordPinyin(StringUtils.deleteWhitespace(pinyinUtils.toPinyin(courseAuditRecordEditParam.getKeywordValue(),false)));
         if(StringUtils.isEmpty(courseAuditRecordEditParam.getCollegeId()))courseAuditRecord.setCourseId("");

+ 1 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentBurialpoint.java

@@ -123,6 +123,6 @@ public class CourseStudentBurialpoint {
 
     /** 视频时长 */
     @ApiModelProperty(value = "视频时长", position = 4)
-    @TableField(select = false,insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
+    @TableField(exist = false)
     private String duration;
 }

+ 5 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseInfoMapper.java

@@ -33,6 +33,11 @@ public interface CourseInfoMapper extends BaseMapper<CourseInfo> {
      */
     Page<Map<String,Object>> queryList(@Param("param") Map param, @Param("page") Page<Object> page);
 
+    /**
+     * 课程信息-分页列表-获取课程题目数量
+     */
+    List<Map<String,Object>> getCourseQuesCountList(Map param);
+
     /**
      *  课程中心-分页列表(学生端)
      *  旧,基于课程详情中学生管理,学生和课程关联表来关联,后2025.8.1改用根据开课表关联

+ 2 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseAuditRecordMapper.xml

@@ -34,7 +34,7 @@
             IFNULL (t1.COURSE_ID,'') as courseId,
             IFNULL (t3.COURSE_NAME,'') AS courseIdName,
             CASE
-            WHEN rf.PRIVIEW_FILE_URL IS NOT null  AND rf.PRIVIEW_FILE_URL !='' THEN '1'
+            WHEN rf.PRIVIEW_FILE_URL IS NOT null  or rf.PRIVIEW_FILE_URL !='' THEN '1'
             ELSE '0'
             END AS isConvert,
             IFNULL (TRIM(t1.IS_RECOMMEND),'') AS isRecommend,
@@ -256,7 +256,7 @@
             IFNULL (CAST(t7.AVATAR AS VARCHAR),'') AS avatar,
             IFNULL (CAST(t6.DOWNLOAD_PATH AS VARCHAR),'') AS coverImagePath,
             CASE
-                WHEN rf.PRIVIEW_FILE_URL IS NOT null AND rf.PRIVIEW_FILE_URL !='' THEN '1'
+                WHEN rf.PRIVIEW_FILE_URL IS NOT null or rf.PRIVIEW_FILE_URL !='' THEN '1'
                 ELSE '0'
             END AS isConvert,
             IFNULL (TRIM(t1.IS_RECOMMEND),'') AS isRecommend,

+ 81 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseInfoMapper.xml

@@ -411,5 +411,86 @@
             AND z2.courseId = #{courseId}
         </if>
     </select>
+    <select id="getCourseQuesCountList" resultType="java.util.Map">
+        SELECT
+            ci.COURSE_ID AS courseId,
+            ci.COURSE_NAME AS courseName,
+            tt1.subjectiveQuesCount AS subjectiveQuesCount,
+            tt1.externalQuesCount AS externalQuesCount
+        FROM (
+            select ci1.*
+            from COURSE_INFO ci1
+            WHERE ci1.DELETE_FLAG ='NOT_DELETE'
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci1.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+        )ci
+        LEFT JOIN (
+            SELECT
+            --	ci.COURSE_ID AS courseId,
+            --	cc.ID AS chapterId,
+            --	cch.ID AS hourId,
+            --	tep."id" AS tepId,
+            --	quesCount.subjectiveQuesCount AS subjectiveQuesCount,
+            --	quesCount.externalQuesCount AS externalQuesCount
+            ci.COURSE_ID AS courseId,
+            IFNULL(sum(quesCount.subjectiveQuesCount),0) AS subjectiveQuesCount,
+            IFNULL(sum(quesCount.externalQuesCount),0) AS externalQuesCount
+            FROM COURSE_INFO ci
+            LEFT JOIN COURSE_CHAPTER cc ON ci.COURSE_ID =cc.COURSE_ID AND cc.DELETE_FLAG ='NOT_DELETE'
+            LEFT JOIN COURSE_CLASSHOUR cch ON cc.ID=cch.CHAPTER_ID AND cch.DELETE_FLAG ='NOT_DELETE'
+            LEFT JOIN COURSE_RELATE cr ON cr.MAIN_ID =cch.ID AND cr.FUNC_TYPE IN ('4','5') AND cr.INFO_TYPE ='0' AND cr.CHAPTERHOUR_TYPE ='1'
+            LEFT JOIN "t_exam_paper" tep ON tep."id" =cr.RELATE_ID AND tep.deleted=0
+            LEFT JOIN (
+            SELECT
+            --	tep."id" AS paperId,
+            --	tq."id" AS quesId,
+            --	tq."question_type" AS quesType
+            tep."id" AS paperId,
+            IFNULL(count(CASE WHEN tq."question_type" IN ('4','5') THEN 1 END),0) AS subjectiveQuesCount,
+            IFNULL(count(CASE WHEN tq."question_type" IN ('1','2','3') THEN 1 END),0) AS externalQuesCount
+            FROM "t_exam_paper" tep
+            LEFT JOIN(
+            WITH group_data AS (
+            SELECT
+            ep.id AS paper_id,
+            ep.name AS paper_name,
+            ttc.id AS content_id,
+            ttc.content,
+            LEVEL - 1 AS group_index,
+            JSON_VALUE(ttc.content, '$[' || (LEVEL - 1) || '].name') AS group_name,
+            JSON_QUERY(ttc.content, '$[' || (LEVEL - 1) || '].questionItems') AS question_items
+            FROM t_exam_paper ep
+            JOIN t_text_content ttc ON ep.frame_text_content_id = ttc.id
+            CONNECT BY LEVEL &lt;= JSON_LENGTH(ttc.content)
+            AND PRIOR ep.id = ep.id
+            AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
+            )
+            SELECT
+            gd.paper_id,
+            gd.paper_name,
+            gd.group_name,
+            JSON_VALUE(gd.question_items, '$[' || (item_lvl - 1) || '].id') AS question_id,
+            JSON_VALUE(gd.question_items, '$[' || (item_lvl - 1) || '].itemOrder') AS item_order
+            FROM group_data gd,
+            (SELECT LEVEL AS item_lvl FROM DUAL CONNECT BY LEVEL &lt;= 10) items
+            WHERE JSON_VALUE(gd.question_items, '$[' || (item_lvl - 1) || '].id') IS NOT NULL
+            )relate ON relate.paper_id=tep."id" AND tep.deleted=0
+            LEFT JOIN "t_question" tq ON relate.question_id=tq."id" AND tq.deleted=0
+            GROUP BY tep."id"
+            )quesCount ON quesCount.paperId=tep.Id
+            where 1=1
+            <if test="courseIdList !=null and courseIdList.size()>0">
+                and ci.COURSE_ID in
+                <foreach collection=" courseIdList" close=")" index="index" item="item" open="(" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            GROUP BY ci.COURSE_ID
+        )tt1 ON tt1.courseId =ci.COURSE_ID
+    </select>
 
 </mapper>

+ 1 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseStudentBurialpointMapper.xml

@@ -17,7 +17,7 @@
                 IFNULL(rf.DURATION,'0') AS duration
             FROM COURSE_STUDENT_BURIALPOINT csb
             LEFT JOIN COURSE_CLASSHOUR cch ON csb.HOUR_ID =cch.ID AND cch.DELETE_FLAG ='NOT_DELETE'
-            LEFT JOIN COURSE_RELATE cr ON cr.MAIN_ID =cch.ID AND cr.FUNC_TYPE ='2' AND cr.INFO_TYPE ='0' AND cr.CHAPTERHOUR_TYPE ='1'
+            LEFT JOIN COURSE_RELATE cr ON cr.MAIN_ID =cch.ID AND cr.FUNC_TYPE ='1' AND cr.INFO_TYPE ='0' AND cr.CHAPTERHOUR_TYPE ='1'
             LEFT JOIN RESOURCE_RECORD rr ON rr.ID =cr.RELATE_ID AND rr.DELETE_FLAG ='NOT_DELETE'
             LEFT JOIN RESOURCE_USERFILE ru ON rr.USERFILE_ID =ru.USER_FILE_ID AND ru.DELETE_FLAG ='NOT_DELETE'
             LEFT JOIN RESOURCE_FILE rf ON rf.FILE_ID =ru.FILE_ID

+ 34 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/CourseInfoServiceImpl.java

@@ -19,6 +19,7 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
@@ -33,8 +34,10 @@ import vip.xiaonuo.disk.mapper.CourseInfoMapper;
 import vip.xiaonuo.disk.service.CourseInfoService;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 课程信息表Service接口实现类
@@ -114,7 +117,37 @@ public class CourseInfoServiceImpl extends ServiceImpl<CourseInfoMapper, CourseI
     @Override
     public Page<Map<String,Object>> queryList(Map param)
     {
-        return courseInfoMapper.queryList(param,CommonPageRequest.defaultPage());
+        Page page=courseInfoMapper.queryList(param,CommonPageRequest.defaultPage());
+        //如果需要题目数量,为不影响效率,进行单独查询匹配
+        if(StringUtils.isNotEmpty((CharSequence) param.get("needQuesCount"))){
+            if("1".equals(param.get("needQuesCount")))
+            {
+                List<Map<String,Object>> couseInfoList=page.getRecords();
+                List<String> courseIdList=  couseInfoList.stream().map(map -> (String) map.get("courseId")).collect(Collectors.toList());
+                Map quesCountParam = new HashMap<>();
+                quesCountParam.put("courseIdList", courseIdList);
+                //获取课程题目数量,为了处理效率,采取倒叙删除
+                List<Map<String,Object>> quesCountList=courseInfoMapper.getCourseQuesCountList(quesCountParam);
+                for (Map<String,Object> couseInfo : couseInfoList) {
+                    //匹配课程题目数量
+                    for (int i = quesCountList.size() - 1; i >= 0; i--) {
+                        Map<String, Object> quesCount = quesCountList.get(i);
+                        if (quesCount == null || quesCount.get("courseId") == null) continue;
+
+                        if (couseInfo.get("courseId").equals(quesCount.get("courseId"))) {
+                            //主观题数量
+                            couseInfo.put("subjectiveQuesCount", quesCount.get("subjectiveQuesCount"));
+                            //客观题数量
+                            couseInfo.put("externalQuesCount", quesCount.get("externalQuesCount"));
+                            quesCountList.remove(i);          // 从原列表删除(安全操作)
+                        }
+                    }
+                }
+
+            }
+        }
+
+        return page;
     }
 
     @Override

BIN
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/resources/quesImportTemplate.xlsx