xdd 2 тижнів тому
батько
коміт
61fb4aacbe

+ 1 - 1
fs-admin/src/main/java/com/fs/course/controller/FsCourseQuestionBankController.java

@@ -57,7 +57,7 @@ public class FsCourseQuestionBankController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsCourseQuestionBank fsCourseQuestionBank)
     {
-        List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankList(fsCourseQuestionBank);
+        List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankListExport(fsCourseQuestionBank);
         ExcelUtil<FsCourseQuestionBank> util = new ExcelUtil<FsCourseQuestionBank>(FsCourseQuestionBank.class);
         return util.exportExcel(list, "题库数据");
     }

+ 8 - 0
fs-service-system/src/main/java/com/fs/course/cache/FsUserCourseCategoryCacheService.java

@@ -0,0 +1,8 @@
+package com.fs.course.cache;
+
+import com.fs.course.domain.FsUserCourseCategory;
+import org.apache.ibatis.annotations.Param;
+
+public interface FsUserCourseCategoryCacheService {
+    Long selectCateIdByName(@Param("name")String name);
+}

+ 33 - 0
fs-service-system/src/main/java/com/fs/course/cache/impl/FsUserCourseCategoryCacheServiceImpl.java

@@ -0,0 +1,33 @@
+package com.fs.course.cache.impl;
+
+import com.fs.course.cache.FsUserCourseCategoryCacheService;
+import com.fs.course.domain.FsUserCourseCategory;
+import com.fs.course.mapper.FsUserCourseCategoryMapper;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class FsUserCourseCategoryCacheServiceImpl implements FsUserCourseCategoryCacheService {
+    @Autowired
+    private FsUserCourseCategoryMapper fsUserCourseCategoryMapper;
+    private static final Cache<String, Long> CATEGORY_CACHE = Caffeine.newBuilder()
+            .maximumSize(5000)
+            .expireAfterWrite(12, TimeUnit.HOURS)
+            .build();
+
+    @Override
+    public Long selectCateIdByName(String name) {
+        return CATEGORY_CACHE.get(name,e->{
+            FsUserCourseCategory fsUserCourseCategory = fsUserCourseCategoryMapper.selectFsUserCourseCategoryByName(name);
+            if(fsUserCourseCategory == null) {
+                return null;
+            }
+            return fsUserCourseCategory.getCateId();
+        });
+    }
+}

+ 11 - 5
fs-service-system/src/main/java/com/fs/course/domain/FsCourseQuestionBank.java

@@ -22,15 +22,18 @@ public class FsCourseQuestionBank extends BaseEntity
     @Excel(name = "标题")
     private String title;
 
-    @Excel(name = "问题类别")
     private Long questionType;
+    @Excel(name = "问题类别")
+    private String questionTypeStr;
 
     /** 类别1 单选 2 多选  */
-    @Excel(name = "题目类型: 单选 多选")
+
     private Long type;
+    @Excel(name = "题目类型: 单选 多选")
+    private String typeStr;
 
     /** 状态 */
-    @Excel(name = "状态")
+//    @Excel(name = "状态")
     private Long status;
 
     /** 选项 */
@@ -39,7 +42,7 @@ public class FsCourseQuestionBank extends BaseEntity
     /**
      * 多个用分隔符|
      */
-    @Excel(name = "选项")
+    @Excel(name = "选项: 多个用 | 隔开")
     private String questionOption;
 
     /** 答案 */
@@ -48,11 +51,14 @@ public class FsCourseQuestionBank extends BaseEntity
     /**
      * 答案: 多个用 | 隔开
      */
-    @Excel(name = "答案")
+    @Excel(name = "答案: 多个用 | 隔开")
     private String answerOption;
 
     private Long questionSubType;
 
+    @Excel(name = "题目子类别")
+    private String questionSubTypeStr;
+
     /** 排序 */
     @Excel(name = "序号")
     private Long sort;

+ 3 - 0
fs-service-system/src/main/java/com/fs/course/dto/FsCourseQuestionBankImportDTO.java

@@ -12,6 +12,9 @@ public class FsCourseQuestionBankImportDTO {
     @Excel(name = "问题类别")
     private String questionType;
 
+    @Excel(name = "题目子类别")
+    private String questionSubTyp;
+
     @Excel(name = "题目类型: 单选 多选")
     private String type;
 

+ 4 - 0
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseQuestionBankMapper.java

@@ -38,6 +38,8 @@ public interface FsCourseQuestionBankMapper
      */
     public int insertFsCourseQuestionBank(FsCourseQuestionBank fsCourseQuestionBank);
 
+    public int insertFsCourseQuestionBankBatch(@Param("list") List<FsCourseQuestionBank> fsCourseQuestionBank);
+
     /**
      * 修改题库
      *
@@ -73,4 +75,6 @@ public interface FsCourseQuestionBankMapper
     public List<FsCourseQuestionBank> selectFsCourseQuestionBankByIdVO(@Param("list") String[] questionBankId);
 
 
+    @Select("select cate_name from fs_user_course_category where cate_id = ${cateId} and is_del=0 limit 1")
+    String selectNameByCateId(@Param("cateId") Long cateId);
 }

+ 12 - 1
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseCategoryMapper.java

@@ -1,8 +1,11 @@
 package com.fs.course.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import com.fs.course.domain.FsUserCourseCategory;
 import com.fs.his.vo.OptionsVO;
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
@@ -76,6 +79,14 @@ public interface FsUserCourseCategoryMapper
      * @param name  名称
      * @return  FsUserCourseCategory
      */
-    @Select("select * from fs_user_course_category where cate_name = #{name} limit 1")
+    @Select("select cate_id from fs_user_course_category where cate_name = #{name} and is_del=0 limit 1")
     FsUserCourseCategory selectFsUserCourseCategoryByName(@Param("name")String name);
+
+    /**
+     * 查询所有分类
+     * @return
+     */
+    @Select("select cate_id,cate_name from fs_user_course_category where is_del=0")
+    @MapKey("cateName")
+    Map<String,FsUserCourseCategory> queryAllCategoryData();
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsCourseQuestionBankService.java

@@ -90,4 +90,8 @@ public interface IFsCourseQuestionBankService
      * @return  list
      */
     List<FsCourseQuestionBank> selectFsCourseQuestionBankByIds(List<Long> ids);
+
+    List<FsCourseQuestionBank> selectFsCourseQuestionBankListExport(FsCourseQuestionBank fsCourseQuestionBank);
+
+    String selectNameByCateId(Long cateId);
 }

+ 13 - 0
fs-service-system/src/main/java/com/fs/course/service/cache/IFsCourseQuestionBankCacheService.java

@@ -0,0 +1,13 @@
+package com.fs.course.service.cache;
+
+import com.fs.course.domain.FsUserCourseCategory;
+
+public interface IFsCourseQuestionBankCacheService {
+    /**
+     * 查询课堂分类
+     *
+     * @param cateId 课堂分类主键
+     * @return 课堂分类
+     */
+    public String selectFsUserCourseCategoryByCateId(Long cateId);
+}

+ 36 - 0
fs-service-system/src/main/java/com/fs/course/service/cache/impl/FsUserCourseQuestionBankCacheServiceImpl.java

@@ -0,0 +1,36 @@
+package com.fs.course.service.cache.impl;
+
+import com.fs.course.domain.FsCourseQuestionBank;
+import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.service.IFsCourseQuestionBankService;
+import com.fs.course.service.cache.IFsCourseQuestionBankCacheService;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class FsUserCourseQuestionBankCacheServiceImpl implements IFsCourseQuestionBankCacheService {
+
+    private static final Cache<Long, String> CATEGORY_CACHE = Caffeine.newBuilder()
+            .maximumSize(1000)
+            .expireAfterWrite(3, TimeUnit.HOURS)
+            .build();
+
+    @Autowired
+    private IFsCourseQuestionBankService fsCourseQuestionBankService;
+
+
+    @Override
+    public String selectFsUserCourseCategoryByCateId(Long cateId) {
+        return CATEGORY_CACHE.get(cateId,e->{
+            String cateName = fsCourseQuestionBankService.selectNameByCateId(cateId);
+            if(cateName == null) {
+                return "";
+            }
+            return cateName;
+        });
+    }
+}

+ 90 - 29
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java

@@ -3,16 +3,19 @@ package com.fs.course.service.impl;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.course.cache.FsUserCourseCategoryCacheService;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.*;
 import com.fs.course.dto.FsCourseQuestionBankImportDTO;
 import com.fs.course.mapper.*;
 import com.fs.course.param.FsCourseQuestionAnswerUParam;
 import com.fs.course.service.IFsCourseQuestionBankService;
+import com.fs.course.service.cache.IFsCourseQuestionBankCacheService;
 import com.fs.store.domain.FsUser;
 import com.fs.store.mapper.FsUserMapper;
 import com.fs.store.service.IFsStorePaymentService;
@@ -20,6 +23,7 @@ import com.fs.system.service.ISysConfigService;
 import com.google.gson.JsonParser;
 import com.hc.openapi.tool.fastjson.JSON;
 import jodd.util.StringUtil;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -58,6 +62,12 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
     @Autowired
     private FsUserCourseCategoryMapper courseCategoryMapper;
 
+    @Autowired
+    private IFsCourseQuestionBankCacheService fsCourseQuestionBankCacheService;
+
+    @Autowired
+    private FsUserCourseCategoryCacheService fsUserCourseCategoryCacheService;
+
     /**
      * 查询题库
      *
@@ -80,31 +90,6 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
     public List<FsCourseQuestionBank> selectFsCourseQuestionBankList(FsCourseQuestionBank fsCourseQuestionBank)
     {
         List<FsCourseQuestionBank> fsCourseQuestionBanks = fsCourseQuestionBankMapper.selectFsCourseQuestionBankList(fsCourseQuestionBank);
-        for (FsCourseQuestionBank courseQuestionBank : fsCourseQuestionBanks) {
-
-            if(StringUtil.isNotBlank(courseQuestionBank.getQuestion())) {
-                // 问题列表多个 以分隔符 | 结尾
-                JSONArray questionArr = com.alibaba.fastjson.JSON.parseArray(courseQuestionBank.getQuestion());
-                List<String> questionOpt = new ArrayList<>();
-                for(int i=0;i<questionArr.size();i++){
-                    JSONObject jsonObject = questionArr.getJSONObject(i);
-                    String name = jsonObject.getString("name");
-                    questionOpt.add(name);
-                }
-                courseQuestionBank.setQuestionOption(String.join("|",questionOpt));
-            }
-
-            if(StringUtil.isNotBlank(courseQuestionBank.getAnswer())) {
-                // 如果是json数组
-                if(JsonParser.parseString(courseQuestionBank.getAnswer()).isJsonArray()) {
-                    String answerOpt = String.join("|", JSONUtil.parseArray(courseQuestionBank.getAnswer()).toList(String.class));
-                    courseQuestionBank.setAnswerOption(answerOpt);
-                } else {
-                    courseQuestionBank.setAnswerOption(courseQuestionBank.getAnswer());
-                }
-            }
-        }
-
         return fsCourseQuestionBanks;
     }
 
@@ -386,11 +371,17 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
         StringBuilder importErrorMsg = new StringBuilder();
         StringBuilder importMsg = new StringBuilder();
 
+        List<FsCourseQuestionBank> importData = new ArrayList<>();
+
+        Map<String,FsUserCourseCategory> categoryData = courseCategoryMapper.queryAllCategoryData();
+
         for (FsCourseQuestionBankImportDTO importDTO : list) {
             try {
                 String title = importDTO.getTitle();
                 String type = importDTO.getType();
                 String questionType = importDTO.getQuestionType();
+                String questionSubTyp = importDTO.getQuestionSubTyp();
+
                 String question = importDTO.getQuestion();
                 String answer = importDTO.getAnswer();
 
@@ -449,10 +440,17 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
                 }
 
                 // 分类
+                FsUserCourseCategory fsUserCourseCategory = categoryData.get(questionType);
                 Long questionTypeId = null;
-                FsUserCourseCategory category = courseCategoryMapper.selectFsUserCourseCategoryByName(questionType);
-                if (Objects.nonNull(category)) {
-                    questionTypeId = category.getCateId();
+                if(fsUserCourseCategory != null) {
+                    questionTypeId = fsUserCourseCategory.getCateId();
+                }
+
+                // 题目子分类
+                fsUserCourseCategory = categoryData.get(questionSubTyp);
+                Long questionSubTypeId = null;
+                if(fsUserCourseCategory != null) {
+                    questionSubTypeId = fsUserCourseCategory.getCateId();
                 }
 
                 FsCourseQuestionBank questionBank = new FsCourseQuestionBank();
@@ -465,7 +463,10 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
                 questionBank.setAnswer(answers.length > 1 ? JSON.toJSONString(answers) : answer);
                 questionBank.setCreateTime(new Date());
                 questionBank.setCreateBy(nickName);
-                fsCourseQuestionBankMapper.insertFsCourseQuestionBank(questionBank);
+                questionBank.setQuestionSubType(questionSubTypeId);
+
+                importData.add(questionBank);
+
 
                 importSuccessMsg.append("<br/>").append(successNum).append("、题目 ").append(title).append(" 导入成功");
                 successNum++;
@@ -476,6 +477,10 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
             }
         }
 
+        if(CollectionUtils.isNotEmpty(importData)) {
+            fsCourseQuestionBankMapper.insertFsCourseQuestionBankBatch(importData);
+        }
+
         // 在所有导入处理完成后,构建最终的导入结果消息
         importMsg.insert(0, "导入完成!成功" + successNum + " 条,失败" + failureNum + "条。");
         importMsg.append(importErrorMsg);
@@ -493,6 +498,62 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
         return fsCourseQuestionBankMapper.selectFsCourseQuestionBankByIds(ids);
     }
 
+    @Override
+    public List<FsCourseQuestionBank> selectFsCourseQuestionBankListExport(FsCourseQuestionBank fsCourseQuestionBank) {
+        List<FsCourseQuestionBank> fsCourseQuestionBanks = this.selectFsCourseQuestionBankList(fsCourseQuestionBank);
+
+        for (FsCourseQuestionBank courseQuestionBank : fsCourseQuestionBanks) {
+
+            if(StringUtil.isNotBlank(courseQuestionBank.getQuestion())) {
+                // 问题列表多个 以分隔符 | 结尾
+                JSONArray questionArr = com.alibaba.fastjson.JSON.parseArray(courseQuestionBank.getQuestion());
+                List<String> questionOpt = new ArrayList<>();
+                for(int i=0;i<questionArr.size();i++){
+                    JSONObject jsonObject = questionArr.getJSONObject(i);
+                    String name = jsonObject.getString("name");
+                    questionOpt.add(name);
+                }
+                courseQuestionBank.setQuestionOption(String.join("|",questionOpt));
+            }
+
+            if(StringUtil.isNotBlank(courseQuestionBank.getAnswer())) {
+                // 如果是json数组
+                if(JsonParser.parseString(courseQuestionBank.getAnswer()).isJsonArray()) {
+                    String answerOpt = String.join("|", JSONUtil.parseArray(courseQuestionBank.getAnswer()).toList(String.class));
+                    courseQuestionBank.setAnswerOption(answerOpt);
+                } else {
+                    courseQuestionBank.setAnswerOption(courseQuestionBank.getAnswer());
+                }
+            }
+
+            // 问题类别
+            if(ObjectUtils.isNotNull(courseQuestionBank.getQuestionType())) {
+                String questionType = fsCourseQuestionBankCacheService.selectFsUserCourseCategoryByCateId(courseQuestionBank.getQuestionType());
+
+                courseQuestionBank.setQuestionTypeStr(questionType);
+            }
+
+            // 题目类型
+            if(ObjectUtils.isNotNull(courseQuestionBank.getType())) {
+                String type = courseQuestionBank.getType() == 1 ? "单选" : "多选";
+                courseQuestionBank.setTypeStr(type);
+            }
+
+            // 题目子类别
+            if(ObjectUtils.isNotNull(courseQuestionBank.getQuestionSubType())) {
+                String questionType = fsCourseQuestionBankCacheService.selectFsUserCourseCategoryByCateId(courseQuestionBank.getQuestionSubType());
+                courseQuestionBank.setQuestionSubTypeStr(questionType);
+            }
+
+        }
+        return fsCourseQuestionBanks;
+    }
+
+    @Override
+    public String selectNameByCateId(Long cateId) {
+        return fsCourseQuestionBankMapper.selectNameByCateId(cateId);
+    }
+
 
     public static String[] convertStringToArray(String inputString) {
         String cleanString = inputString.replaceAll("[\\[\\]\"\\s]", "");

+ 29 - 0
fs-service-system/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml

@@ -69,6 +69,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="questionSubType != null">#{questionSubType},</if>
          </trim>
     </insert>
+    <insert id="insertFsCourseQuestionBankBatch">
+        <foreach collection="list" separator=";" item="item">
+            insert into fs_course_question_bank
+            <trim prefix="(" suffix=")" suffixOverrides=",">
+                <if test="item.title != null">title,</if>
+                <if test="item.sort != null">sort,</if>
+                <if test="item.type != null">type,</if>
+                <if test="item.status != null">status,</if>
+                <if test="item.question != null">question,</if>
+                <if test="item.createTime != null">create_time,</if>
+                <if test="item.answer != null">answer,</if>
+                <if test="item.createBy != null">create_by,</if>
+                <if test="item.questionType != null">question_type,</if>
+                <if test="item.questionSubType != null">question_sub_type,</if>
+            </trim>
+            <trim prefix="values (" suffix=")" suffixOverrides=",">
+                <if test="item.title != null">#{item.title},</if>
+                <if test="item.sort != null">#{item.sort},</if>
+                <if test="item.type != null">#{item.type},</if>
+                <if test="item.status != null">#{item.status},</if>
+                <if test="item.question != null">#{item.question},</if>
+                <if test="item.createTime != null">#{item.createTime},</if>
+                <if test="item.answer != null">#{item.answer},</if>
+                <if test="item.createBy != null">#{item.createBy},</if>
+                <if test="item.questionType != null">#{item.questionType},</if>
+                <if test="item.questionSubType != null">#{item.questionSubType},</if>
+            </trim>
+        </foreach>
+    </insert>
 
     <update id="updateFsCourseQuestionBank" parameterType="FsCourseQuestionBank">
         update fs_course_question_bank