caozixuan 2 жил өмнө
parent
commit
e27424771c

+ 109 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/excel/ExamStudentImportDto.java

@@ -0,0 +1,109 @@
+package com.qmth.distributed.print.business.bean.dto.excel;
+
+import com.qmth.teachcloud.common.annotation.ExcelImportTempleteVaild;
+import com.qmth.teachcloud.common.annotation.ExcelNote;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @Description: 考生导入dto
+ * @Author: CaoZixuan
+ * @Date: 2022-09-02
+ */
+@ExcelImportTempleteVaild(value = true)
+public class ExamStudentImportDto implements Serializable {
+    @ExcelNote(value = "姓名")
+    @NotNull
+    private String studentName;
+
+    @ExcelNote(value = "学号")
+    @NotNull
+    private String studentCode;
+
+    @ExcelNote(value = "手机号")
+    private String phoneNumber;
+
+    @ExcelNote(value = "学院")
+    @NotNull
+    private String collegeName;
+
+    @ExcelNote(value = "专业")
+    @NotNull
+    private String majorName;
+
+    @ExcelNote(value = "班级")
+    @NotNull
+    private String clazzName;
+
+    @ExcelNote(value = "考点")
+    private String examPlace;
+
+    @ExcelNote(value = "考场")
+    @NotNull
+    private String examRoom;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getCollegeName() {
+        return collegeName;
+    }
+
+    public void setCollegeName(String collegeName) {
+        this.collegeName = collegeName;
+    }
+
+    public String getMajorName() {
+        return majorName;
+    }
+
+    public void setMajorName(String majorName) {
+        this.majorName = majorName;
+    }
+
+    public String getClazzName() {
+        return clazzName;
+    }
+
+    public void setClazzName(String clazzName) {
+        this.clazzName = clazzName;
+    }
+
+    public String getExamPlace() {
+        return examPlace;
+    }
+
+    public void setExamPlace(String examPlace) {
+        this.examPlace = examPlace;
+    }
+
+    public String getExamRoom() {
+        return examRoom;
+    }
+
+    public void setExamRoom(String examRoom) {
+        this.examRoom = examRoom;
+    }
+}

+ 46 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/examTaskStudent/ExamTaskExamStudentImportResult.java

@@ -0,0 +1,46 @@
+package com.qmth.distributed.print.business.bean.result.examTaskStudent;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description: 命题任务考生导入
+ * @Author: CaoZixuan
+ * @Date: 2022-09-02
+ */
+public class ExamTaskExamStudentImportResult implements Serializable {
+    @ApiModelProperty(value = "考点")
+    private String examPlace;
+
+    @ApiModelProperty(value = "考场")
+    private String examRoom;
+
+    @ApiModelProperty(value = "一个考场的命题任务学生数据集合")
+    private List<ExamTaskStudentObjectResult> examTaskStudentObjectResultList;
+
+    public String getExamPlace() {
+        return examPlace;
+    }
+
+    public void setExamPlace(String examPlace) {
+        this.examPlace = examPlace;
+    }
+
+    public String getExamRoom() {
+        return examRoom;
+    }
+
+    public void setExamRoom(String examRoom) {
+        this.examRoom = examRoom;
+    }
+
+    public List<ExamTaskStudentObjectResult> getExamTaskStudentObjectResultList() {
+        return examTaskStudentObjectResultList;
+    }
+
+    public void setExamTaskStudentObjectResultList(List<ExamTaskStudentObjectResult> examTaskStudentObjectResultList) {
+        this.examTaskStudentObjectResultList = examTaskStudentObjectResultList;
+    }
+}

+ 0 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/examTaskStudent/ExamTaskStudentObjectResult.java

@@ -2,7 +2,6 @@ package com.qmth.distributed.print.business.bean.result.examTaskStudent;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.qmth.distributed.print.business.enums.ExamObjectType;
 import com.qmth.distributed.print.business.enums.StudentClazzEnum;
 import io.swagger.annotations.ApiModelProperty;
 

+ 11 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java

@@ -8,6 +8,7 @@ import com.qmth.distributed.print.business.bean.dto.examObject.ExamObjectDto;
 import com.qmth.distributed.print.business.bean.params.ExamTaskApplyParam;
 import com.qmth.distributed.print.business.bean.params.ExamTaskReApplyParam;
 import com.qmth.distributed.print.business.bean.result.WorkResult;
+import com.qmth.distributed.print.business.bean.result.examTaskStudent.ExamTaskExamStudentImportResult;
 import com.qmth.distributed.print.business.bean.result.examTaskStudent.ExamTaskStudentObjectResult;
 import com.qmth.distributed.print.business.entity.ExamTask;
 import com.qmth.distributed.print.business.entity.ExamTaskApplyTemp;
@@ -213,14 +214,21 @@ public interface ExamTaskService extends IService<ExamTask> {
      * <p>
      * 1.选择教学班当考试对象 - TEACH_CLAZZ_STUDENT -> 以学生的教学班当考试对象集合,但学生信息中附带教学班和行政班数据。
      * 2.选择行政班当考试对象 - BASIC_CLAZZ_STUDENT -> 以学生的行政班当考试对象集合,且学生信息只包含行政班数据。
-     * 3.选择导入学生数据当考试对象 - IMPORT_STUDENT -> 文件必传,如果导入的考生在学生库中没有则新建,以学生的行政班当考试对象集合且学生信息只包含行政班数据。
      * </P>
      *
      * @param examObjectType 考试对象类型
      * @param basicCourseId  基础课程id
-     * @param file           导入的考生文件
      * @param requestUser    请求的用户
      * @return 命题任务考试对象查询结果
      */
-    List<ExamTaskStudentObjectResult> findExamTaskStudentObject(ExamObjectType examObjectType, Long basicCourseId, MultipartFile file, SysUser requestUser) throws Exception;
+    List<ExamTaskStudentObjectResult> findExamTaskStudentObject(ExamObjectType examObjectType, Long basicCourseId, SysUser requestUser) throws Exception;
+
+    /**
+     * 命题任务考生导入
+     *
+     * @param file        命题任务考生导入excel
+     * @param requestUser 请求用户
+     * @return 命题任务考生导入
+     */
+    List<ExamTaskExamStudentImportResult> examTaskExamStudentImport(MultipartFile file, SysUser requestUser) throws IOException, NoSuchFieldException, IllegalAccessException;
 }

+ 148 - 35
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -13,8 +13,10 @@ import com.google.gson.Gson;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.dto.approvalForm.*;
 import com.qmth.distributed.print.business.bean.dto.examObject.ExamObjectDto;
+import com.qmth.distributed.print.business.bean.dto.excel.ExamStudentImportDto;
 import com.qmth.distributed.print.business.bean.params.*;
 import com.qmth.distributed.print.business.bean.result.WorkResult;
+import com.qmth.distributed.print.business.bean.result.examTaskStudent.ExamTaskExamStudentImportResult;
 import com.qmth.distributed.print.business.bean.result.examTaskStudent.ExamTaskStudentObjectResult;
 import com.qmth.distributed.print.business.bean.result.examTaskStudent.StudentInfo;
 import com.qmth.distributed.print.business.entity.*;
@@ -27,6 +29,9 @@ import com.qmth.distributed.print.business.util.CreatePdfUtil;
 import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
 import com.qmth.teachcloud.common.bean.dto.BlurryUserDto;
 import com.qmth.teachcloud.common.bean.dto.MqDto;
+import com.qmth.teachcloud.common.bean.dto.excel.BasicStudentImportDto;
+import com.qmth.teachcloud.common.bean.dto.excel.DescribeImportDto;
+import com.qmth.teachcloud.common.bean.params.BasicStudentExtrasParam;
 import com.qmth.teachcloud.common.bean.result.BasicStudentResult;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
@@ -1861,7 +1866,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public List<ExamTaskStudentObjectResult> findExamTaskStudentObject(ExamObjectType examObjectType, Long basicCourseId, MultipartFile file, SysUser requestUser) throws Exception {
+    public List<ExamTaskStudentObjectResult> findExamTaskStudentObject(ExamObjectType examObjectType, Long basicCourseId,SysUser requestUser) throws Exception {
         Long schoolId = requestUser.getSchoolId();
         Long userId = requestUser.getId();
         List<ExamTaskStudentObjectResult> result = new ArrayList<>();
@@ -1946,42 +1951,150 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                     result.add(examTaskStudentObjectResult);
                 }
                 break;
-            case IMPORT_STUDENT:
-                // 学生导入
-                if (Objects.isNull(file)) {
-                    throw ExceptionResultEnum.ERROR.exception("缺少导入文件");
+        }
+        return result;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public List<ExamTaskExamStudentImportResult> examTaskExamStudentImport(MultipartFile file, SysUser requestUser) throws IOException, NoSuchFieldException, IllegalAccessException {
+        if (Objects.isNull(file)) {
+            throw ExceptionResultEnum.ERROR.exception("缺少导入文件");
+        }
+        // excel 读取和检验
+        List<ExamStudentImportDto> examStudentImportDtoList = new ArrayList<>();
+        List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(file.getInputStream(), Lists.newArrayList(ExamStudentImportDto.class, DescribeImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
+            List<ExcelError> excelErrorTemp = new ArrayList<>();
+            Map<String, String> checkCodeMap = new HashMap<>();
+            Map<String, String> checkPhoneMap = new HashMap<>();
+            for (int i = 0; i < finalExcelList.size(); i++) {
+                LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
+                List<Object> examStudentImportDtoDatasource = excelMap.get(i);
+                assert examStudentImportDtoDatasource != null;
+                if (examStudentImportDtoDatasource.get(0) instanceof DescribeImportDto) {
+                    continue;
                 }
-                Map<String, Object> studentImportMap = new HashMap<>();
-                studentImportMap.put("inputStream", file.getInputStream());
-                studentImportMap.put(SystemConstant.SYS_USER, requestUser);
-                taskLogicService.executeImportBasicStudentLogic(studentImportMap);
-                List<String> studentCodeList = JSONObject.parseArray(JSON.toJSONString(studentImportMap.get("studentCodeList")), String.class);
-
-                // 导入的学生信息查询
-                List<BasicStudentResult> basicStudentResultDatasource = basicStudentService.basicStudentList(schoolId, null, null, null, studentCodeList);
-                List<Long> basicClazzIdList = basicStudentResultDatasource.stream().map(BasicStudentResult::getClazzId).distinct().collect(Collectors.toList());
-                for (Long basicClazzId : basicClazzIdList) {
-                    List<BasicStudentResult> basicStudentResultList = basicStudentResultDatasource.stream()
-                            .filter(e -> basicClazzId.equals(e.getClazzId())).collect(Collectors.toList());
-                    List<StudentInfo> studentInfoList = basicStudentResultList.stream().flatMap(e -> {
-                        StudentInfo studentInfo = new StudentInfo();
-                        studentInfo.setStudentId(e.getId());
-                        studentInfo.setStudentCode(e.getStudentCode());
-                        studentInfo.setStudentName(e.getStudentName());
-                        studentInfo.setCollegeName(e.getCollegeName());
-                        studentInfo.setMajorName(e.getMajorName());
-                        studentInfo.setBasicClazzId(e.getClazzId());
-                        studentInfo.setBasicClazzName(e.getClazz());
-                        return Stream.of(studentInfo);
-                    }).collect(Collectors.toList());
-                    ExamTaskStudentObjectResult examTaskStudentObjectResult = new ExamTaskStudentObjectResult();
-                    examTaskStudentObjectResult.setClazzId(basicClazzId);
-                    examTaskStudentObjectResult.setClazzName(basicClazzService.getById(basicClazzId).getClazzName());
-                    examTaskStudentObjectResult.setStudentInfoList(studentInfoList);
-                    examTaskStudentObjectResult.setStudentClazzType(examObjectType.getStudentClazzType());
-                    result.add(examTaskStudentObjectResult);
+                for (int y = 0; y < Objects.requireNonNull(examStudentImportDtoDatasource).size(); y++) {
+                    ExamStudentImportDto examStudentImportDto = (ExamStudentImportDto) examStudentImportDtoDatasource.get(y);
+                    String studentName = examStudentImportDto.getStudentName();
+                    String studentCode = examStudentImportDto.getStudentCode();
+                    String phoneNumber = examStudentImportDto.getPhoneNumber();
+                    String clazzName = examStudentImportDto.getClazzName();
+                    String examPlace = examStudentImportDto.getExamPlace();
+                    String examRoom = examStudentImportDto.getExamRoom();
+                    examStudentImportDtoList.add(examStudentImportDto);
+
+
+                    // 检验excel中
+                    // 检验学号
+                    if (SystemConstant.strNotNull(studentCode)) {
+                        if (checkCodeMap.containsKey(studentCode)) {
+                            throw ExceptionResultEnum.ERROR.exception("导入的excel中包含在重复的【学生编号】:" + studentCode);
+                        } else {
+                            checkCodeMap.put(studentCode, studentName);
+                        }
+                    }
+                    // 如果电话有值则检验电话excel中唯一性
+                    if (SystemConstant.strNotNull(phoneNumber)) {
+                        if (checkPhoneMap.containsKey(phoneNumber)) {
+                            throw ExceptionResultEnum.ERROR.exception("导入的excel中包含在重复的【电话号码】:" + phoneNumber);
+                        } else {
+                            checkPhoneMap.put(phoneNumber, studentCode);
+                        }
+                    }
+
+                    excelErrorTemp.addAll(ExcelUtil.checkExcelField(examStudentImportDto, y, i));
+                    if (Objects.isNull(studentCode) || studentCode.length() > 30 || !studentCode.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)) {
+                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[学号]不符合输入规范"));
+                    }
+                    if (Objects.isNull(studentName) || studentName.length() > 30) {
+                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[学生名称]不符合输入规范"));
+                    }
+                    if (Objects.nonNull(phoneNumber) && !phoneNumber.matches(SystemConstant.REGULAR_EXPRESSION_OF_PHONE)) {
+                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[电话号码]不符合输入规范"));
+                    }
                 }
-                break;
+            }
+            if (excelErrorTemp.size() > 0) {
+                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(excelErrorTemp));
+            }
+            return finalExcelList;
+        });
+        // 创建基础学生信息
+        List<BasicStudentExtrasParam> basicStudentExtrasParamList = examStudentImportDtoList.stream().flatMap(e -> {
+            BasicStudentExtrasParam basicStudentExtrasParam = new BasicStudentExtrasParam();
+            basicStudentExtrasParam.setStudentName(e.getStudentName());
+            basicStudentExtrasParam.setStudentCode(e.getStudentCode());
+            basicStudentExtrasParam.setPhoneNumber(e.getPhoneNumber());
+            basicStudentExtrasParam.setCollegeName(e.getCollegeName());
+            basicStudentExtrasParam.setMajorName(e.getMajorName());
+            basicStudentExtrasParam.setClazzName(e.getClazzName());
+            return Stream.of(basicStudentExtrasParam);
+        }).collect(Collectors.toList());
+        basicStudentService.saveBasicStudentWithExtrasList(basicStudentExtrasParamList, requestUser);
+
+
+
+        // 考生信息回溯
+        List<ExamTaskExamStudentImportResult> result = new ArrayList<>();
+
+        List<String> studentCodeDatasource = examStudentImportDtoList.stream().map(ExamStudentImportDto::getStudentCode).distinct().collect(Collectors.toList());
+        List<String> examRoomDatasource = examStudentImportDtoList.stream().map(ExamStudentImportDto::getExamRoom).distinct().collect(Collectors.toList());
+        // 导入的excel创建或查询的学生集合
+        List<BasicStudentResult> basicStudentResultDatasource = basicStudentService.basicStudentList(requestUser.getSchoolId(), null, null, null, studentCodeDatasource);
+
+        for (String examRoom : examRoomDatasource) {
+            // 考点
+            List<String> examPlaceList = examStudentImportDtoList
+                    .stream()
+                    .filter(e -> examRoom.equals(e.getExamRoom()))
+                    .map(ExamStudentImportDto::getExamPlace)
+                    .distinct()
+                    .collect(Collectors.toList());
+            if (examPlaceList.size() > 1){
+                throw ExceptionResultEnum.ERROR.exception("异常:考场对应多个考点");
+            }
+            String examPlace = examPlaceList.get(0);
+
+
+            // 该考场学号集合
+            List<String> studentCodeList = examStudentImportDtoList.stream()
+                    .filter(e -> examRoom.equals(e.getExamRoom()))
+                    .map(ExamStudentImportDto::getStudentCode)
+                    .distinct()
+                    .collect(Collectors.toList());
+            List<ExamTaskStudentObjectResult> examTaskStudentObjectResultList = new ArrayList<>();
+            List<BasicStudentResult> basicStudentResultList = basicStudentResultDatasource.stream().filter(e -> studentCodeList.contains(e.getStudentCode())).collect(Collectors.toList());
+            List<Long> basicClazzIdList = basicStudentResultList.stream().map(BasicStudentResult::getClazzId).distinct().collect(Collectors.toList());
+            for (Long basicClazzId : basicClazzIdList) {
+                List<BasicStudentResult> basicStudentClazzList = basicStudentResultList.stream()
+                        .filter(e -> basicClazzId.equals(e.getClazzId())).collect(Collectors.toList());
+                List<StudentInfo> studentInfoList = basicStudentClazzList.stream().flatMap(e -> {
+                    StudentInfo studentInfo = new StudentInfo();
+                    studentInfo.setStudentId(e.getId());
+                    studentInfo.setStudentCode(e.getStudentCode());
+                    studentInfo.setStudentName(e.getStudentName());
+                    studentInfo.setCollegeName(e.getCollegeName());
+                    studentInfo.setMajorName(e.getMajorName());
+                    studentInfo.setBasicClazzId(e.getClazzId());
+                    studentInfo.setBasicClazzName(e.getClazz());
+                    return Stream.of(studentInfo);
+                }).collect(Collectors.toList());
+                ExamTaskStudentObjectResult examTaskStudentObjectResult = new ExamTaskStudentObjectResult();
+                examTaskStudentObjectResult.setClazzId(basicClazzId);
+                examTaskStudentObjectResult.setClazzName(basicClazzService.getById(basicClazzId).getClazzName());
+                examTaskStudentObjectResult.setStudentInfoList(studentInfoList);
+                examTaskStudentObjectResult.setStudentClazzType(ExamObjectType.IMPORT_STUDENT.getStudentClazzType());
+                examTaskStudentObjectResultList.add(examTaskStudentObjectResult);
+
+            }
+
+
+            ExamTaskExamStudentImportResult examTaskExamStudentImportResult = new ExamTaskExamStudentImportResult();
+            examTaskExamStudentImportResult.setExamRoom(examRoom);
+            examTaskExamStudentImportResult.setExamPlace(examPlace);
+            examTaskExamStudentImportResult.setExamTaskStudentObjectResultList(examTaskStudentObjectResultList);
+            result.add(examTaskExamStudentImportResult);
         }
         return result;
     }

+ 11 - 3
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskController.java

@@ -847,11 +847,19 @@ public class ExamTaskController {
     @RequestMapping(value = "/find_exam_task_student_object", method = RequestMethod.POST)
     @Transactional(rollbackFor = Exception.class)
     @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
-    public Result findExamTaskStudentObject(@RequestParam(required = false) MultipartFile file,
-                                            @RequestParam ExamObjectType examObjectType,
+    public Result findExamTaskStudentObject(@RequestParam ExamObjectType examObjectType,
                                             @RequestParam(required = false) String basicCourseId) throws Exception {
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
-        return ResultUtil.ok(examTaskService.findExamTaskStudentObject(examObjectType, SystemConstant.convertIdToLong(basicCourseId), file, requestUser));
+        return ResultUtil.ok(examTaskService.findExamTaskStudentObject(examObjectType, SystemConstant.convertIdToLong(basicCourseId), requestUser));
+    }
+
+    @ApiOperation(value = "入库申请-导入考生对象")
+    @RequestMapping(value = "/exam_task_exam_student_import", method = RequestMethod.POST)
+    @Transactional(rollbackFor = Exception.class)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result examTaskExamStudentImport(@RequestParam MultipartFile file) throws Exception {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(examTaskService.examTaskExamStudentImport(file, requestUser));
     }
 }
 

+ 0 - 13
distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java

@@ -193,19 +193,6 @@ public class ServiceTest {
 
     @Test
     public void testFindExamObject() throws Exception {
-        Long basicCourseId = 293036122005573632L;
-        ExamObjectType examObjectType = ExamObjectType.TEACH_CLAZZ_STUDENT;
-
-        File file = new File("E:" + File.separator + "file" + File.separator + "学生导入模板.xlsx");
-        FileInputStream input = new FileInputStream(file);
-        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
-
-        SysUser requestUser = new SysUser();
-        requestUser.setId(293030757817909248L);
-        requestUser.setSchoolId(292366699577999360L);
-
-        System.out.println(JSON.toJSONString(examTaskService.findExamTaskStudentObject(examObjectType, basicCourseId, multipartFile, requestUser)));
-        String x = "";
     }
 
 }