From 4ba127459ff1b77df9014444fdac7636d3f091bc Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期六, 16 三月 2024 15:05:19 +0800
Subject: [PATCH] 题目导入

---
 src/main/java/com/mindskip/xzs/excel/CurrencyDataListener.java                       |  105 +++++++++++
 src/main/java/com/mindskip/xzs/excel/SelectExcel.java                                |   42 +++
 src/main/java/com/mindskip/xzs/viewmodel/admin/question/ExamQuestionVO.java          |   34 +++
 src/main/java/com/mindskip/xzs/configuration/spring/security/SecurityConfigurer.java |    8 
 src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java                 |   42 ++--
 src/main/java/com/mindskip/xzs/excel/FixedMergeCellStrategy.java                     |   45 +++++
 src/main/java/com/mindskip/xzs/vo/QuestionImportVO.java                              |   45 ++--
 src/main/java/com/mindskip/xzs/controller/admin/QuestionController.java              |  178 +++++++++++++++++++
 src/main/java/com/mindskip/xzs/vo/OptionAndValueVO.java                              |   20 ++
 9 files changed, 461 insertions(+), 58 deletions(-)

diff --git a/src/main/java/com/mindskip/xzs/configuration/spring/security/SecurityConfigurer.java b/src/main/java/com/mindskip/xzs/configuration/spring/security/SecurityConfigurer.java
index 97e109b..1cb3769 100644
--- a/src/main/java/com/mindskip/xzs/configuration/spring/security/SecurityConfigurer.java
+++ b/src/main/java/com/mindskip/xzs/configuration/spring/security/SecurityConfigurer.java
@@ -79,7 +79,13 @@
                     .and().authenticationProvider(restAuthenticationProvider)
                     .authorizeRequests()
                     .antMatchers(securityIgnoreUrls.toArray(ignores)).permitAll()
-                    .antMatchers("/api/admin/department/list", "/api/admin/video/getList","/api/admin/user/conversion","/api/admin/examPaperGrade/updates","/api/admin/question/download/question/import/temp").permitAll()
+                    .antMatchers("/api/admin/department/list",
+                            "/api/admin/video/getList",
+                            "/api/admin/user/conversion",
+                            "/api/admin/examPaperGrade/updates",
+                            "/api/admin/question/download/question/import/temp",
+                            "/api/admin/question/question/import"
+                    ).permitAll()
                     // todo 璁剧疆閮ㄩ棬绠$悊鍛樺彲浠ョ湅鐨勮姹�
                     .antMatchers("/api/admin/**").hasAnyRole(RoleEnum.ADMIN.getName(), RoleEnum.DEPT_ADMIN.getName())
                     .antMatchers("/api/student/**").hasRole(RoleEnum.STUDENT.getName())
diff --git a/src/main/java/com/mindskip/xzs/controller/admin/QuestionController.java b/src/main/java/com/mindskip/xzs/controller/admin/QuestionController.java
index 1cdabdb..cd4d574 100644
--- a/src/main/java/com/mindskip/xzs/controller/admin/QuestionController.java
+++ b/src/main/java/com/mindskip/xzs/controller/admin/QuestionController.java
@@ -1,16 +1,25 @@
 package com.mindskip.xzs.controller.admin;
 
 import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.enums.CellExtraTypeEnum;
 import com.alibaba.excel.metadata.data.HyperlinkData;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.alibaba.fastjson.JSON;
 import com.mindskip.xzs.base.BaseApiController;
 import com.mindskip.xzs.base.RestResponse;
 import com.mindskip.xzs.base.SystemCode;
+import com.mindskip.xzs.context.WebContext;
 import com.mindskip.xzs.domain.Question;
+import com.mindskip.xzs.domain.QuestionSubject;
 import com.mindskip.xzs.domain.Subject;
 import com.mindskip.xzs.domain.TextContent;
 import com.mindskip.xzs.domain.enums.QuestionSourceEnum;
+import com.mindskip.xzs.domain.enums.QuestionStatusEnum;
 import com.mindskip.xzs.domain.enums.QuestionTypeEnum;
+import com.mindskip.xzs.domain.question.QuestionItemObject;
 import com.mindskip.xzs.domain.question.QuestionObject;
+import com.mindskip.xzs.excel.CurrencyDataListener;
+import com.mindskip.xzs.excel.FixedMergeCellStrategy;
 import com.mindskip.xzs.excel.SelectExcel;
 import com.mindskip.xzs.repository.DepartmentMapper;
 import com.mindskip.xzs.repository.SubjectMapper;
@@ -24,7 +33,10 @@
 import com.mindskip.xzs.vo.QuestionImportVO;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.DataValidationHelper;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -33,9 +45,8 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 @RestController("AdminQuestionController")
@@ -50,6 +61,8 @@
     private final DepartmentMapper departmentMapper;
 
     private final QuestionSubjectService questionSubjectService;
+
+    private static final String SPLIT = "銆�";
 
     @Autowired
     public QuestionController(QuestionService questionService, TextContentService textContentService, SubjectMapper subjectMapper, DepartmentMapper departmentMapper, QuestionSubjectService questionSubjectService) {
@@ -130,11 +143,168 @@
         return RestResponse.ok();
     }
 
+    /**
+     * 涓嬭浇棰樼洰瀵煎叆妯℃澘
+     *
+     * @param response
+     * @throws IOException
+     */
     @GetMapping("/download/question/import/temp")
     public void getImportTemp(HttpServletResponse response) throws IOException {
         String fileName = URLEncoder.encode("棰樼洰瀵煎叆妯℃澘", "UTF-8").replaceAll("\\+", "%20");
         response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
-        EasyExcel.write(response.getOutputStream(), QuestionImportVO.class).registerWriteHandler(new SelectExcel()).sheet("妯℃澘").doWrite(new ArrayList());
+
+        // 鏋勫缓妯℃澘鏍蜂緥鏁版嵁
+        List<QuestionImportVO> data = new ArrayList<>(4);
+        QuestionImportVO questionImportVO = new QuestionImportVO();
+        questionImportVO.setQuestionType("鍗曢�夐");
+        questionImportVO.setDifficult(2);
+        questionImportVO.setCorrect("B");
+        questionImportVO.setScore(2);
+        questionImportVO.setSubjectName("娴嬭瘯璇剧洰");
+        questionImportVO.setAnalyze("B鏄鐨�");
+        questionImportVO.setTitle("杩欐槸涓�閬撴祴璇曢鐩紝浣跨敤璇ユā鏉胯鍒犻櫎鎴栨浛鎹㈣繖閬撻");
+        questionImportVO.setOptionName("A");
+        questionImportVO.setOptionValue("閫夋垜");
+        data.add(questionImportVO);
+
+        QuestionImportVO questionImportVO1 = new QuestionImportVO();
+        questionImportVO1.setOptionName("B");
+        questionImportVO1.setOptionValue("閫塀");
+        data.add(questionImportVO1);
+
+        QuestionImportVO questionImportVO2 = new QuestionImportVO();
+        questionImportVO2.setOptionName("C");
+        questionImportVO2.setOptionValue("閫塁");
+        data.add(questionImportVO2);
+
+        QuestionImportVO questionImportVO3 = new QuestionImportVO();
+        questionImportVO3.setOptionName("D");
+        questionImportVO3.setOptionValue("閫塂");
+        data.add(questionImportVO3);
+
+        // 鏌ュ嚭鎵�鏈夌殑璇剧洰锛坋xcel涓嬫媺鏁版嵁锛�
+        List<Subject> subjects = subjectMapper.allSubject();
+        List<String> subjectNameList = subjects.stream().map(Subject::getName).collect(Collectors.toList());
+
+        EasyExcel.write(response.getOutputStream(), QuestionImportVO.class)
+                .sheet("妯℃澘")
+                .registerWriteHandler(new SelectExcel(subjectNameList))
+                .registerWriteHandler(new FixedMergeCellStrategy(2, 4, Arrays.asList(1, 2, 3, 6, 7, 8, 9)))
+                .doWrite(data);
+    }
+
+    /**
+     * 棰樼洰瀵煎叆
+     *
+     * easyexcel瀵煎叆涓�瀵瑰锛屾瘮濡備竴涓鐩紝鍥涗釜閫夐」銆傞偅涔堣鍙栧埌鐨勬暟鎹氨鏈夊洓鏉★紝绗竴鏉℃暟鎹槸榻愬叏鐨勩�傚悗闈笁鏉″彧鏈夐�夐」鏈夊��
+     * @param file
+     * @throws IOException
+     */
+    @PostMapping("/question/import")
+    @Transactional(rollbackFor = Exception.class)
+    public RestResponse importQuestion(@RequestPart("file") MultipartFile file) throws IOException {
+        Consumer<List<QuestionImportVO>> consumer = (data) -> {
+            // 棰樼洰鐨勮鐩俊鎭�
+            List<QuestionSubject> questionSubjectsList = new ArrayList<>(48);
+            for (int i = 0; i < data.size(); i++) {
+                // 棰樼洰瀹炰綋
+                Question question = new Question();
+                // 璇诲彇鐨勯鐩�
+                QuestionImportVO excelQuestion = data.get(i);
+
+                // 濡傛灉鏄涓�鏉″畬鏁存暟鎹紝閭d箞缁х画寰�鍚庤鍙栭�夐」鍐呭
+                if (excelQuestion.master()) {
+                    // 璇ラ鐨勯�夐」
+                    List<QuestionItemObject> options = new ArrayList<>(4);
+                    // 閫夐」鍐呭
+                    QuestionItemObject option = new QuestionItemObject();
+                    option.setPrefix(excelQuestion.getOptionName());
+                    option.setContent(excelQuestion.getOptionValue());
+                    options.add(option);
+                    int next = 1;
+                    // 缁х画寰�鍚庤閫夐」
+                    while (Boolean.TRUE) {
+                        // 鍒ゆ柇鏄惁鏄渶鍚庝竴鏉�
+                        if (next + i == data.size()) {
+                            break;
+                        }
+                        QuestionImportVO nextQuestion = data.get(next + i);
+                        if (nextQuestion.master()) {
+                            break;
+                        }
+                        QuestionItemObject nextOption = new QuestionItemObject();
+                        nextOption.setPrefix(nextQuestion.getOptionName());
+                        nextOption.setContent(nextQuestion.getOptionValue());
+                        options.add(nextOption);
+                        next++;
+                    }
+                    i += next;
+
+                    // 淇濆瓨棰樼洰鍐呭
+                    QuestionObject questionObject = new QuestionObject();
+                    questionObject.setQuestionItemObjects(options);
+                    questionObject.setAnalyze(excelQuestion.getAnalyze());
+                    questionObject.setTitleContent(excelQuestion.getTitle());
+                    questionObject.setCorrect(excelQuestion.getCorrect());
+
+                    TextContent textContent = new TextContent();
+                    textContent.setContent(JSON.toJSONString(questionObject));
+                    textContent.setCreateTime(new Date());
+                    textContentService.insert(textContent);
+
+                    // 淇濆瓨棰樼洰淇℃伅
+                    // 璁剧疆棰樺瀷
+                    question.setQuestionType(QuestionTypeEnum.get(excelQuestion.getQuestionType()));
+                    // 绛旀(澶氶�夐渶瑕佺敤,鍒嗗壊淇濆瓨瀛楃涓插埌鏁版嵁搴�)
+                    String[] corrects = excelQuestion.getCorrect().split(SPLIT);
+                    if (corrects.length > 1) {
+                        question.setCorrect(Arrays.asList(corrects).stream().collect(Collectors.joining(",")));
+                    } else {
+                        question.setCorrect(excelQuestion.getCorrect());
+                    }
+
+                    // 闅惧害
+                    question.setDifficult(excelQuestion.getDifficult());
+                    // 鍒嗘暟
+                    question.setScore(ExamUtil.scoreFromVM(String.valueOf(excelQuestion.getScore())));
+                    // 鍒涘缓浜�
+                    question.setCreateUser(1);
+                    question.setStatus(QuestionStatusEnum.OK.getCode());
+                    question.setCreateTime(new Date());
+                    question.setDeleted(Boolean.FALSE);
+                    question.setInfoTextContentId(textContent.getId());
+                    questionService.insert(question);
+
+
+                    // 鏌ュ嚭鎵�鏈夌殑璇剧洰
+                    List<Subject> subjects = subjectMapper.allSubject();
+                    List<String> subjectNames = Arrays.asList(excelQuestion.getSubjectName().split(SPLIT));
+                    List<Subject> targetSubject = subjects.stream()
+                            .filter(subject -> subjectNames.contains(subject.getName()))
+                            .collect(Collectors.toList());
+                    if (CollectionUtils.isEmpty(targetSubject)) {
+                        // todo 璁板綍杩欎釜閿欒
+                        continue;
+                    }
+                    // 鏋勫缓璇剧洰-棰樼洰淇℃伅
+                    questionSubjectsList = targetSubject.stream().map(subject -> {
+                        QuestionSubject questionSubject = new QuestionSubject();
+                        questionSubject.setQuestionId(question.getId());
+                        questionSubject.setSubjectId(subject.getId());
+                        questionSubject.setDeleted(0);
+                        return questionSubject;
+                    }).collect(Collectors.toList());
+                }
+                System.out.println(question);
+            }
+            // 鎵归噺淇濆瓨棰樼洰-璇剧洰淇℃伅
+            if (! CollectionUtils.isEmpty(questionSubjectsList)) {
+                questionSubjectService.saves(questionSubjectsList);
+            }
+        };
+        EasyExcel.read(file.getInputStream(), QuestionImportVO.class, new CurrencyDataListener(consumer)).sheet("妯℃澘").doRead();
+        return RestResponse.ok();
     }
 
     @PostMapping("/import")
diff --git a/src/main/java/com/mindskip/xzs/excel/CurrencyDataListener.java b/src/main/java/com/mindskip/xzs/excel/CurrencyDataListener.java
new file mode 100644
index 0000000..424645d
--- /dev/null
+++ b/src/main/java/com/mindskip/xzs/excel/CurrencyDataListener.java
@@ -0,0 +1,105 @@
+package com.mindskip.xzs.excel;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.read.listener.ReadListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+/**
+ * easyExcel 澶氳〃閫氱敤璇诲彇鐩戝惉鍣�
+ *
+ * @author xp
+ */
+public class CurrencyDataListener<T> implements ReadListener<T> {
+
+
+    private Consumer consumer;
+
+    /**
+     * 姣忛殧100鏉″瓨鍌ㄦ暟鎹簱锛岀劧鍚庢竻鐞唋ist 锛屾柟渚垮唴瀛樺洖鏀�
+     */
+    private static final int BATCH_COUNT = 100;
+
+    /**
+     * 缂撳瓨鐨勬暟鎹�
+     */
+    private List<T> cachedDataList = new ArrayList<>(BATCH_COUNT);
+
+    private final static Logger log = LoggerFactory.getLogger(CurrencyDataListener.class);
+
+    public CurrencyDataListener(Consumer<List<T>> consumer) {
+        this.consumer = consumer;
+    }
+
+    /**
+     * 璇诲彇鍑虹幇寮傚父澶勭悊
+     *
+     * @param e
+     * @param analysisContext
+     * @throws Exception
+     */
+    @Override
+    public void onException(Exception e, AnalysisContext analysisContext) throws Exception {
+
+    }
+
+    /**
+     * 澶勭悊琛ㄥご
+     *  @param map
+     * @param analysisContext
+     */
+    @Override
+    public void invokeHead(Map<Integer, ReadCellData<?>> map, AnalysisContext analysisContext) {
+
+    }
+
+    /**
+     * 璇诲彇鏁版嵁,姣忎竴鏉℃暟鎹В鏋愰兘浼氭潵璋冪敤
+     *
+     * @param data
+     * @param analysisContext
+     */
+    @Override
+    public void invoke(T data, AnalysisContext analysisContext) {
+        cachedDataList.add(data);
+        // 杈惧埌BATCH_COUNT浜嗭紝闇�瑕佸幓瀛樺偍涓�娆℃暟鎹簱锛岄槻姝㈡暟鎹嚑涓囨潯鏁版嵁鍦ㄥ唴瀛橈紝瀹规槗OOM
+        if (cachedDataList.size() >= BATCH_COUNT) {
+            try {
+                // 蹇呴』瑕佹崟鑾峰紓甯革紝鍚﹀垯鍒楄〃涓嶄細娓呯┖
+                saveData();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            // 瀛樺偍瀹屾垚娓呯悊 list
+            cachedDataList = new ArrayList<>(BATCH_COUNT);
+        }
+    }
+
+    /**
+     * 璇诲彇瀹屾垚
+     *
+     * @param analysisContext
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        saveData();
+        log.info("鎵�鏈夋暟鎹В鏋愬畬鎴愶紒");
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    private void saveData() {
+        log.info("{}鏉℃暟鎹紝寮�濮嬪瓨鍌ㄦ暟鎹簱锛�", cachedDataList.size());
+        consumer.accept(cachedDataList);
+        log.info("瀛樺偍鏁版嵁搴撴垚鍔燂紒");
+    }
+}
diff --git a/src/main/java/com/mindskip/xzs/excel/FixedMergeCellStrategy.java b/src/main/java/com/mindskip/xzs/excel/FixedMergeCellStrategy.java
new file mode 100644
index 0000000..3e3f68f
--- /dev/null
+++ b/src/main/java/com/mindskip/xzs/excel/FixedMergeCellStrategy.java
@@ -0,0 +1,45 @@
+package com.mindskip.xzs.excel;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.util.List;
+
+/**
+ * @author锛歺p
+ * @date锛�2024/3/16 11:20
+ */
+public class FixedMergeCellStrategy extends AbstractMergeStrategy {
+
+    /**
+     * 璧峰浣嶇疆
+     */
+    private Integer startRow;
+
+    /**
+     * 鍚堝苟澶氬皯琛�
+     */
+    private Integer mergeRowNumber;
+
+    /**
+     * 鍝簺鍒楅渶瑕佸悎骞惰
+     */
+    private List<Integer> mergeWhichColumn;
+
+    public FixedMergeCellStrategy(Integer startRow, Integer mergeRowNumber, List<Integer> mergeWhichColumn) {
+        this.startRow = startRow;
+        this.mergeRowNumber = mergeRowNumber;
+        this.mergeWhichColumn = mergeWhichColumn;
+    }
+
+    @Override
+    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+        for (Integer whichColumn : mergeWhichColumn) {
+            CellRangeAddress cellRangeAddress = new CellRangeAddress(startRow, startRow + mergeRowNumber - 1, whichColumn - 1, whichColumn - 1);
+            sheet.addMergedRegionUnsafe(cellRangeAddress);
+        }
+    }
+}
diff --git a/src/main/java/com/mindskip/xzs/excel/SelectExcel.java b/src/main/java/com/mindskip/xzs/excel/SelectExcel.java
index 4ad8e22..0c91aeb 100644
--- a/src/main/java/com/mindskip/xzs/excel/SelectExcel.java
+++ b/src/main/java/com/mindskip/xzs/excel/SelectExcel.java
@@ -22,8 +22,22 @@
  */
 public class SelectExcel implements CellWriteHandler {
 
-    private String[] questionTypeList = {"鍗曢��", "澶氶��", "鍒ゆ柇"};
-    private String[] subjectTypeList = {"a","b"};
+    /**
+     * 棰樼洰绫诲瀷
+     */
+    private String[] questionTypeList = {"鍗曢�夐", "澶氶�夐", "鍒ゆ柇棰�"};
+    /**
+     * 璇剧洰
+     */
+    private List<String> subjectNameList;
+    /**
+     * 閫夐」涓嬫媺鏁版嵁
+     */
+    private String[] optionList = {"A","B","C","D","E","F","G","H"};
+
+    public SelectExcel(List subjectNameList) {
+        this.subjectNameList = subjectNameList;
+    }
 
     @Override
     public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
@@ -34,20 +48,34 @@
         // 鑾峰彇鏁版嵁鏍¢獙helper
         DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
 
-        // 璁剧疆棰樼洰涓嬫媺鑼冨洿锛岀涓�鍒楋紝500琛屽唴
-        CellRangeAddressList questionTypeRange = new CellRangeAddressList(0, 500, 0, 0);
+        // 璁剧疆棰樼洰涓嬫媺鑼冨洿锛岀涓�鍒楋紝1500琛屽唴
+        CellRangeAddressList questionTypeRange = new CellRangeAddressList(1, 1500, 0, 0);
         // 娣诲姞棰樼洰涓嬫媺
         DataValidationConstraint questionConstraint = dataValidationHelper.createExplicitListConstraint(questionTypeList);
         DataValidation questionValidation = dataValidationHelper.createValidation(questionConstraint, questionTypeRange);
         sheet.addValidationData(questionValidation);
 
 
-        // 璁剧疆璇剧洰涓嬫媺鑼冨洿锛岀2鍒楋紝500琛屽唴
-        CellRangeAddressList subjectTypeRange = new CellRangeAddressList(0, 500, 1, 1);
+        // 璁剧疆璇剧洰涓嬫媺鑼冨洿锛岀2鍒楋紝1500琛屽唴
+        CellRangeAddressList subjectTypeRange = new CellRangeAddressList(1, 1500, 1, 1);
         // 娣诲姞璇剧洰涓嬫媺
-        DataValidationConstraint subjectConstraint = dataValidationHelper.createExplicitListConstraint(subjectTypeList);
+        DataValidationConstraint subjectConstraint = dataValidationHelper.createExplicitListConstraint(subjectNameList.toArray((new String[0])));
         DataValidation subjectValidation = dataValidationHelper.createValidation(subjectConstraint, subjectTypeRange);
         sheet.addValidationData(subjectValidation);
 
+        // 璁剧疆閫夐」涓嬫媺鑼冨洿锛岀4鍒楋紝1500琛屽唴
+        CellRangeAddressList optionRange = new CellRangeAddressList(2, 1500, 3, 3);
+        // 娣诲姞閫夐」涓嬫媺
+        DataValidationConstraint optionConstraint = dataValidationHelper.createExplicitListConstraint(optionList);
+        DataValidation optionValidation = dataValidationHelper.createValidation(optionConstraint, optionRange);
+        sheet.addValidationData(optionValidation);
+
+        // 璁剧疆閫夐」涓嬫媺鑼冨洿锛岀4鍒楋紝1500琛屽唴
+        CellRangeAddressList answerRange = new CellRangeAddressList(2, 1500, 5, 5);
+        // 娣诲姞閫夐」涓嬫媺
+        DataValidationConstraint answerConstraint = dataValidationHelper.createExplicitListConstraint(optionList);
+        DataValidation answerValidation = dataValidationHelper.createValidation(answerConstraint, answerRange);
+        sheet.addValidationData(answerValidation);
+
     }
 }
diff --git a/src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java b/src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java
index 98e5ac6..bdfb0fa 100644
--- a/src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java
+++ b/src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java
@@ -156,27 +156,27 @@
         questionEditRequestVM.setTitle(questionObject.getTitleContent());
 
         //绛旀
-//        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(question.getQuestionType());
-//        switch (questionTypeEnum) {
-//            case SingleChoice:
-//            case TrueFalse:
-//                questionEditRequestVM.setCorrect(question.getCorrect());
-//                break;
-//            case MultipleChoice:
-//                questionEditRequestVM.setCorrectArray(ExamUtil.contentToArray(question.getCorrect()));
-//                break;
-//            case GapFilling:
-//                List<String> correctContent = questionObject.getQuestionItemObjects().stream().map(d -> d.getContent()).collect(Collectors.toList());
-//                questionEditRequestVM.setCorrectArray(correctContent);
-//                break;
-//            case ShortAnswer:
-//                questionEditRequestVM.setCorrect(questionObject.getCorrect());
-//                break;
-//            default:
-//                break;
-//        }
-//        questionEditRequestVM.setScore(ExamUtil.scoreToVM(question.getScore()));
-//        questionEditRequestVM.setAnalyze(questionObject.getAnalyze());
+        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(question.getQuestionType());
+        switch (questionTypeEnum) {
+            case SingleChoice:
+            case TrueFalse:
+                questionEditRequestVM.setCorrect(question.getCorrect());
+                break;
+            case MultipleChoice:
+                questionEditRequestVM.setCorrectArray(ExamUtil.contentToArray(question.getCorrect()));
+                break;
+            case GapFilling:
+                List<String> correctContent = questionObject.getQuestionItemObjects().stream().map(d -> d.getContent()).collect(Collectors.toList());
+                questionEditRequestVM.setCorrectArray(correctContent);
+                break;
+            case ShortAnswer:
+                questionEditRequestVM.setCorrect(questionObject.getCorrect());
+                break;
+            default:
+                break;
+        }
+        questionEditRequestVM.setScore(ExamUtil.scoreToVM(question.getScore()));
+        questionEditRequestVM.setAnalyze(questionObject.getAnalyze());
 
 
         //棰樼洰椤规槧灏�
diff --git a/src/main/java/com/mindskip/xzs/viewmodel/admin/question/ExamQuestionVO.java b/src/main/java/com/mindskip/xzs/viewmodel/admin/question/ExamQuestionVO.java
index 8e0b895..44d8eea 100644
--- a/src/main/java/com/mindskip/xzs/viewmodel/admin/question/ExamQuestionVO.java
+++ b/src/main/java/com/mindskip/xzs/viewmodel/admin/question/ExamQuestionVO.java
@@ -28,21 +28,43 @@
      */
     private String title;
 
+    /**
+     * 鍒嗘暟
+     */
+    private String score;
+
+    /**
+     * 瑙f瀽
+     */
+    private String analyze;
+
+    /**
+     * 闅惧害
+     */
+    private Integer difficult;
+
+    /**
+     * 澶氶�夐绛旀
+     */
+    private List<String> correctArray;
+
+    /**
+     * 鍗曢�夌瓟妗�
+     */
+    private String correct;
+
     private String sbNames;
 
     private List<QuestionSubject> questionSubjects;
 
-    //绛旀
+    /**
+     * 閫夐」
+     */
     private List<QuestionEditItemVM> items;
 
     private Integer itemOrder;
 
     private String department;
 
-
-    private String a;
-    private String b;
-    private String c;
-    private String d;
 
 }
diff --git a/src/main/java/com/mindskip/xzs/vo/OptionAndValueVO.java b/src/main/java/com/mindskip/xzs/vo/OptionAndValueVO.java
new file mode 100644
index 0000000..3724e85
--- /dev/null
+++ b/src/main/java/com/mindskip/xzs/vo/OptionAndValueVO.java
@@ -0,0 +1,20 @@
+package com.mindskip.xzs.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * 棰樼洰閫夐」
+ *
+ * @author锛歺p
+ * @date锛�2024/3/15 22:53
+ */
+@Data
+public class OptionAndValueVO {
+
+    @ExcelProperty({"棰樼洰閫夐」", "閫夐」"})
+    private String optionName;
+
+    @ExcelProperty({"棰樼洰閫夐」", "閫夐」鍊�"})
+    private String optionValue;
+}
diff --git a/src/main/java/com/mindskip/xzs/vo/QuestionImportVO.java b/src/main/java/com/mindskip/xzs/vo/QuestionImportVO.java
index 3894850..b61ec5f 100644
--- a/src/main/java/com/mindskip/xzs/vo/QuestionImportVO.java
+++ b/src/main/java/com/mindskip/xzs/vo/QuestionImportVO.java
@@ -2,8 +2,15 @@
 
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
+import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
 import com.mindskip.xzs.viewmodel.admin.question.QuestionEditItemVM;
+import io.swagger.models.auth.In;
 import lombok.Data;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.springframework.util.StringUtils;
+
 import java.util.List;
 
 /**
@@ -12,12 +19,13 @@
  */
 @Data
 @ColumnWidth(20)
+@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)//鍐呭鏍峰紡
 public class QuestionImportVO {
 
     @ExcelProperty("棰樼洰绫诲瀷")
-    private Integer questionType;
+    private String questionType;
 
-    @ExcelProperty("璇剧洰")
+    @ExcelProperty("璇剧洰(澶氫釜鐢ㄣ�侀殧寮�)")
     private String subjectName;
 
     @ColumnWidth(80)
@@ -25,36 +33,35 @@
     private String title;
 
     // 閫夐」鍐呭
-    @ColumnWidth(60)
-    @ExcelProperty("閫夐」鍜岀瓟妗�")
-    private List<QuestionEditItemVM> items;
+    @ExcelProperty({"棰樼洰閫夐」", "閫夐」"})
+    private String optionName;
+
+    @ExcelProperty({"棰樼洰閫夐」", "閫夐」鍊�"})
+    private String optionValue;
+
+    @ExcelProperty("绛旀(澶氫釜鐢ㄣ�侀殧寮�)")
+    private String correct;
 
     // 瑙f瀽
     @ColumnWidth(30)
     @ExcelProperty("瑙f瀽")
     private String analyze;
 
-    @ExcelProperty("绛旀")
-    private String correct;
 
     // 棰樼洰鍒嗘暟
     @ExcelProperty("棰樼洰鍒嗘暟")
-    private String score;
+    private Integer score;
 
     // 棰樼洰闅惧害
     @ExcelProperty("棰樼洰闅惧害")
     private Integer difficult;
 
-    @ExcelProperty("閫夐」A")
-    private String a;
-
-    @ExcelProperty("閫夐」B")
-    private String b;
-
-    @ExcelProperty("閫夐」C")
-    private String c;
-
-    @ExcelProperty("閫夐」D")
-    private String d;
+    /**
+     * 杩斿洖璇ユ潯鏁版嵁鏄笉鏄锛屽洜涓鸿繕鏈夐�夐」銆傞�夐」鐨勮繖浜涘�兼槸绌虹殑
+     * @return
+     */
+    public boolean master() {
+        return StringUtils.hasText(questionType) && StringUtils.hasText(subjectName) && StringUtils.hasText(title);
+    }
 
 }

--
Gitblit v1.8.0