浏览代码

add:考生字典管理

caozixuan 1 年之前
父节点
当前提交
dfea80ebba
共有 14 个文件被更改,包括 1050 次插入72 次删除
  1. 212 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/BasicExamStudentDto.java
  2. 22 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/BasicExamStudentMapper.java
  3. 35 9
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicExamStudentService.java
  4. 123 28
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamStudentServiceImpl.java
  5. 211 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/SyncBasicExamStudentImportService.java
  6. 121 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/SyncImportTaskTemplate.java
  7. 0 25
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/SyncImportTaskTemplete.java
  8. 8 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/TaskLogicService.java
  9. 130 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  10. 69 0
      distributed-print-business/src/main/resources/mapper/BasicExamStudentMapper.xml
  11. 4 4
      distributed-print/install/mysql/upgrade/3.3.1.sql
  12. 104 5
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicExamStudentController.java
  13. 9 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java
  14. 2 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/TaskTypeEnum.java

+ 212 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/BasicExamStudentDto.java

@@ -0,0 +1,212 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import com.qmth.teachcloud.common.annotation.ExcelNote;
+import com.qmth.teachcloud.common.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description: 考生字典数据导入导出dto
+ * @Author: CaoZixuan
+ * @Date: 2024-02-26
+ */
+public class BasicExamStudentDto {
+
+    @ApiModelProperty("课程名称")
+    @ExcelProperty(name = "课程名称", width = 10, index = 1)
+    @ExcelNote(value = "课程名称")
+    @NotNull
+    private String courseName;
+
+    @ApiModelProperty("课程代码")
+    @ExcelProperty(name = "课程代码", width = 10, index = 2)
+    @ExcelNote(value = "课程代码")
+    @NotNull
+    private String courseCode;
+
+    @ApiModelProperty("姓名")
+    @ExcelProperty(name = "姓名", width = 10, index = 3)
+    @ExcelNote(value = "姓名")
+    @NotNull
+    private String studentName;
+
+    @ApiModelProperty("学号")
+    @ExcelProperty(name = "学号", width = 10, index = 4)
+    @ExcelNote(value = "学号")
+    @NotNull
+    private String studentCode;
+
+    @ApiModelProperty("学院")
+    @ExcelProperty(name = "学院", width = 10, index = 5)
+    @ExcelNote(value = "学院")
+    private String college;
+
+    @ApiModelProperty("专业")
+    @ExcelProperty(name = "专业", width = 10, index = 6)
+    @ExcelNote(value = "专业")
+    private String major;
+
+    @ApiModelProperty("教学班")
+    @ExcelProperty(name = "教学班", width = 10, index = 7)
+    @ExcelNote(value = "教学班")
+    private String teachClazz;
+
+    @ApiModelProperty("试卷编号")
+    @ExcelProperty(name = "试卷编号", width = 10, index = 8)
+    @ExcelNote(value = "试卷编号")
+    private String paperNumber;
+
+    @ApiModelProperty("任课老师")
+    @ExcelProperty(name = "任课老师", width = 10, index = 9)
+    @ExcelNote(value = "任课老师")
+    private String teacherName;
+
+    @ApiModelProperty("任课老师工号")
+    @ExcelProperty(name = "任课老师工号", width = 10, index = 10)
+    @ExcelNote(value = "任课老师工号")
+    private String teacherCode;
+
+    @ApiModelProperty("考试日期")
+    @ExcelProperty(name = "考试日期", width = 10, index = 11)
+    @ExcelNote(value = "考试日期")
+    private String examDate;
+
+    @ApiModelProperty("考试时间")
+    @ExcelProperty(name = "考试时间", width = 10, index = 12)
+    @ExcelNote(value = "考试时间")
+    private String examTime;
+
+    @ApiModelProperty("考点(校区)")
+    @ExcelProperty(name = "考点(校区)", width = 10, index = 13)
+    @ExcelNote(value = "考点(校区)")
+    private String examPlace;
+
+    @ApiModelProperty("考场(考试教室)")
+    @ExcelProperty(name = "考场(考试教室)", width = 10, index = 14)
+    @ExcelNote(value = "考场(考试教室)")
+    private String examRoom;
+
+    @ApiModelProperty("异常信息")
+    private String errorMsg;
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    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 getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
+
+    public String getMajor() {
+        return major;
+    }
+
+    public void setMajor(String major) {
+        this.major = major;
+    }
+
+    public String getTeachClazz() {
+        return teachClazz;
+    }
+
+    public void setTeachClazz(String teachClazz) {
+        this.teachClazz = teachClazz;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getTeacherCode() {
+        return teacherCode;
+    }
+
+    public void setTeacherCode(String teacherCode) {
+        this.teacherCode = teacherCode;
+    }
+
+    public String getExamDate() {
+        return examDate;
+    }
+
+    public void setExamDate(String examDate) {
+        this.examDate = examDate;
+    }
+
+    public String getExamTime() {
+        return examTime;
+    }
+
+    public void setExamTime(String examTime) {
+        this.examTime = examTime;
+    }
+
+    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 String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+}

+ 22 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/BasicExamStudentMapper.java

@@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 
 
+import java.util.List;
+
 /**
 /**
  * <p>
  * <p>
  * 考生字典表 Mapper 接口
  * 考生字典表 Mapper 接口
@@ -40,4 +42,24 @@ public interface BasicExamStudentMapper extends BaseMapper<BasicExamStudent> {
             @Param("major") String major, @Param("teachClazzId") Long teachClazzId,
             @Param("major") String major, @Param("teachClazzId") Long teachClazzId,
             @Param("examStudentInfo") String examStudentInfo, @Param("dpr") DataPermissionRule dpr);
             @Param("examStudentInfo") String examStudentInfo, @Param("dpr") DataPermissionRule dpr);
 
 
+    /**
+     * 列表查询
+     *
+     * @param schoolId        学校id
+     * @param semesterId      学期id
+     * @param examId          考试id
+     * @param courseCode      课程代码
+     * @param teacher         教师
+     * @param college         学院
+     * @param major           专业
+     * @param teachClazzId    教学班id
+     * @param examStudentInfo 考生信息(姓名/学号)
+     * @param dpr             数据权限
+     * @return 查询结果
+     */
+    List<BasicExamStudentResult> findBasicExamStudentList(@Param("schoolId") Long schoolId, @Param("semesterId") Long semesterId, @Param("examId") Long examId,
+            @Param("courseCode") String courseCode, @Param("teacher") String teacher, @Param("college") String college,
+            @Param("major") String major, @Param("teachClazzId") Long teachClazzId, @Param("examStudentInfo") String examStudentInfo,
+            @Param("dpr") DataPermissionRule dpr);
+
 }
 }

+ 35 - 9
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicExamStudentService.java

@@ -6,10 +6,11 @@ import com.qmth.distributed.print.business.bean.params.BasicExamStudentParam;
 import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
 import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
 import com.qmth.distributed.print.business.entity.BasicExamStudent;
 import com.qmth.distributed.print.business.entity.BasicExamStudent;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.entity.SysUser;
-import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -31,7 +32,7 @@ public interface BasicExamStudentService extends IService<BasicExamStudent> {
      * @param teacher         教师
      * @param teacher         教师
      * @param college         学院
      * @param college         学院
      * @param major           专业
      * @param major           专业
-     * @param teachClazzId      教学班id
+     * @param teachClazzId    教学班id
      * @param examStudentInfo 考生信息(姓名/学号)
      * @param examStudentInfo 考生信息(姓名/学号)
      * @param pageNumber      分页页码
      * @param pageNumber      分页页码
      * @param pageSize        分页数量
      * @param pageSize        分页数量
@@ -40,6 +41,23 @@ public interface BasicExamStudentService extends IService<BasicExamStudent> {
     IPage<BasicExamStudentResult> page(SysUser requestUser, Long semesterId, Long examId, String courseCode, String teacher,
     IPage<BasicExamStudentResult> page(SysUser requestUser, Long semesterId, Long examId, String courseCode, String teacher,
             String college, String major, Long teachClazzId, String examStudentInfo, int pageNumber, int pageSize);
             String college, String major, Long teachClazzId, String examStudentInfo, int pageNumber, int pageSize);
 
 
+    /**
+     * 列表查询
+     *
+     * @param requestUser     请求人
+     * @param semesterId      学期id
+     * @param examId          考试id
+     * @param courseCode      课程代码
+     * @param teacher         教师
+     * @param college         学院
+     * @param major           专业
+     * @param teachClazzId    教学班id
+     * @param examStudentInfo 考生信息(姓名/学号)
+     * @return 查询结果
+     */
+    List<BasicExamStudentResult> list(SysUser requestUser, Long semesterId, Long examId, String courseCode, String teacher,
+            String college, String major, Long teachClazzId, String examStudentInfo);
+
     /**
     /**
      * 新增编辑
      * 新增编辑
      *
      *
@@ -47,31 +65,30 @@ public interface BasicExamStudentService extends IService<BasicExamStudent> {
      * @param requestUser           用户
      * @param requestUser           用户
      * @return id
      * @return id
      */
      */
-    Long edit(BasicExamStudentParam basicExamStudentParam, SysUser requestUser);
+    Long save(BasicExamStudentParam basicExamStudentParam, SysUser requestUser);
 
 
     /**
     /**
      * 导入
      * 导入
      *
      *
-     * @param file excel文件
+     * @param map 参数集
      */
      */
-    void importLogic(MultipartFile file);
+    void buildImportObjects(Map<String, Object> map) throws IOException, NoSuchFieldException;
 
 
     /**
     /**
      * 导出
      * 导出
      *
      *
      * @param response        response
      * @param response        response
-     * @param schoolId        学校id
      * @param semesterId      学期id
      * @param semesterId      学期id
      * @param examId          考试id
      * @param examId          考试id
      * @param courseCode      课程代码
      * @param courseCode      课程代码
      * @param teacher         教师
      * @param teacher         教师
      * @param college         学院
      * @param college         学院
      * @param major           专业
      * @param major           专业
-     * @param teachClazz      教学班
+     * @param teachClazzId    教学班id
      * @param examStudentInfo 考生信息(姓名/学号)
      * @param examStudentInfo 考生信息(姓名/学号)
      */
      */
-    void exportLogic(HttpServletResponse response, Long schoolId, Long semesterId, Long examId, String courseCode,
-            String teacher, String college, String major, String teachClazz, String examStudentInfo);
+    void exportLogic(HttpServletResponse response, Long semesterId, Long examId, String courseCode, String teacher,
+            String college, String major, Long teachClazzId, String examStudentInfo) throws Exception;
 
 
     /**
     /**
      * 批量删除
      * 批量删除
@@ -79,4 +96,13 @@ public interface BasicExamStudentService extends IService<BasicExamStudent> {
      * @param idList 要删除的考生字典id集合
      * @param idList 要删除的考生字典id集合
      */
      */
     void deleteBatch(List<Long> idList);
     void deleteBatch(List<Long> idList);
+
+    /**
+     * 构建考生字典对象
+     *
+     * @param basicExamStudentParam 考生字典参数
+     * @param requestUser           请求人
+     * @return 考生字典
+     */
+    BasicExamStudent editEntityHelp(BasicExamStudentParam basicExamStudentParam, SysUser requestUser);
 }
 }

+ 123 - 28
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamStudentServiceImpl.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import com.qmth.distributed.print.business.bean.dto.BasicExamStudentDto;
 import com.qmth.distributed.print.business.bean.params.BasicExamStudentParam;
 import com.qmth.distributed.print.business.bean.params.BasicExamStudentParam;
 import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
 import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
 import com.qmth.distributed.print.business.entity.BasicExamStudent;
 import com.qmth.distributed.print.business.entity.BasicExamStudent;
@@ -11,6 +13,7 @@ import com.qmth.distributed.print.business.entity.BasicTeachClazz;
 import com.qmth.distributed.print.business.mapper.BasicExamStudentMapper;
 import com.qmth.distributed.print.business.mapper.BasicExamStudentMapper;
 import com.qmth.distributed.print.business.service.BasicExamStudentService;
 import com.qmth.distributed.print.business.service.BasicExamStudentService;
 import com.qmth.distributed.print.business.service.BasicTeachClazzService;
 import com.qmth.distributed.print.business.service.BasicTeachClazzService;
+import com.qmth.teachcloud.common.base.BaseEntity;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.BasicCourse;
@@ -20,18 +23,23 @@ import com.qmth.teachcloud.common.service.BasicCourseService;
 import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
 import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
 import com.qmth.teachcloud.common.service.SysUserService;
 import com.qmth.teachcloud.common.service.SysUserService;
 import com.qmth.teachcloud.common.util.ConvertUtil;
 import com.qmth.teachcloud.common.util.ConvertUtil;
+import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
+import org.springframework.util.LinkedMultiValueMap;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -86,9 +94,81 @@ public class BasicExamStudentServiceImpl extends ServiceImpl<BasicExamStudentMap
         return page;
         return page;
     }
     }
 
 
+    @Override
+    public List<BasicExamStudentResult> list(SysUser requestUser, Long semesterId, Long examId, String courseCode,
+            String teacher, String college, String major, Long teachClazzId, String examStudentInfo) {
+        Long schoolId = requestUser.getSchoolId();
+
+        courseCode = SystemConstant.translateSpecificSign(courseCode);
+        teacher = SystemConstant.translateSpecificSign(teacher);
+        college = SystemConstant.translateSpecificSign(college);
+        major = SystemConstant.translateSpecificSign(major);
+        examStudentInfo = SystemConstant.translateSpecificSign(examStudentInfo);
+
+        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(),
+                ServletUtil.getRequest().getServletPath());
+        List<BasicExamStudentResult> list = this.baseMapper.findBasicExamStudentList(schoolId, semesterId, examId,
+                courseCode, teacher, college, major, teachClazzId, examStudentInfo, dpr);
+        for (BasicExamStudentResult basicExamStudentResult : list) {
+            Long examStartTime = basicExamStudentResult.getExamStartTime();
+            Long examEndTime = basicExamStudentResult.getExamEndTime();
+            if (SystemConstant.longNotNull(examStartTime) && SystemConstant.longNotNull(examEndTime)) {
+                Map<String, Object> dateMap = ConvertUtil.analyzeDateAndTime(examStartTime, examEndTime);
+                String date = String.valueOf(dateMap.get("date"));
+                String time = String.valueOf(dateMap.get("time"));
+                basicExamStudentResult.setExamDate(date);
+                basicExamStudentResult.setExamTime(time);
+            }
+        }
+        return list;
+    }
+
+    @Transactional
+    @Override
+    public Long save(BasicExamStudentParam basicExamStudentParam, SysUser requestUser) {
+        BasicExamStudent basicExamStudent = this.editEntityHelp(basicExamStudentParam, requestUser);
+        this.saveOrUpdate(basicExamStudent);
+        return basicExamStudent.getId();
+    }
+
     @Transactional
     @Transactional
     @Override
     @Override
-    public Long edit(BasicExamStudentParam basicExamStudentParam, SysUser requestUser) {
+    public void buildImportObjects(Map<String, Object> map) throws IOException, NoSuchFieldException {
+
+    }
+
+    @Override
+    public void exportLogic(HttpServletResponse response, Long semesterId, Long examId,
+            String courseCode, String teacher, String college, String major, Long teachClazzId, String examStudentInfo)
+            throws Exception {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        List<BasicExamStudentResult> list = this.list(requestUser, semesterId, examId, courseCode, teacher, college,
+                major, teachClazzId, examStudentInfo);
+        List<BasicExamStudentDto> exportDto = list.stream().flatMap(e -> {
+            BasicExamStudentDto basicExamStudentDto = new BasicExamStudentDto();
+            BeanUtils.copyProperties(e, basicExamStudentDto);
+            return Stream.of(basicExamStudentDto);
+        }).collect(Collectors.toList());
+
+        // 生成excel文件
+        ExcelUtil.excelExport("考生字典数据", BasicExamStudentDto.class, exportDto, response);
+    }
+
+    @Transactional
+    @Override
+    public void deleteBatch(List<Long> idList) {
+        this.removeByIds(idList);
+    }
+
+    /**
+     * 构造考生新增/编辑对象
+     *
+     * @param basicExamStudentParam 考生参数
+     * @param requestUser           请求人
+     * @return 考生对象
+     */
+    @Override
+    public BasicExamStudent editEntityHelp(BasicExamStudentParam basicExamStudentParam, SysUser requestUser) {
         List<String> errorMsgList = new ArrayList<>();
         List<String> errorMsgList = new ArrayList<>();
         Long schoolId = requestUser.getSchoolId();
         Long schoolId = requestUser.getSchoolId();
         Long requestUserId = requestUser.getId();
         Long requestUserId = requestUser.getId();
@@ -136,6 +216,7 @@ public class BasicExamStudentServiceImpl extends ServiceImpl<BasicExamStudentMap
         }
         }
 
 
         // 校验2 试卷编号存在时,任课教师,考试时间,考点考场均必填;
         // 校验2 试卷编号存在时,任课教师,考试时间,考点考场均必填;
+        Long teacherId = null;
         if (SystemConstant.strNotNull(paperNumber)) {
         if (SystemConstant.strNotNull(paperNumber)) {
             String hasPaperNumberError = "存在试卷编号时: ";
             String hasPaperNumberError = "存在试卷编号时: ";
             if (!SystemConstant.strNotNull(teacherCode) || !SystemConstant.strNotNull(teacherName)) {
             if (!SystemConstant.strNotNull(teacherCode) || !SystemConstant.strNotNull(teacherName)) {
@@ -155,6 +236,7 @@ public class BasicExamStudentServiceImpl extends ServiceImpl<BasicExamStudentMap
                         sysUserService.updateById(teacher);
                         sysUserService.updateById(teacher);
                     }
                     }
                 }
                 }
+                teacherId = teacher.getId();
             }
             }
 
 
             if (!SystemConstant.longNotNull(examStartTime) || !SystemConstant.longNotNull(examEndTime)) {
             if (!SystemConstant.longNotNull(examStartTime) || !SystemConstant.longNotNull(examEndTime)) {
@@ -177,31 +259,44 @@ public class BasicExamStudentServiceImpl extends ServiceImpl<BasicExamStudentMap
                 courseCode, teachClazz);
                 courseCode, teachClazz);
 
 
         BasicExamStudent basicExamStudent = new BasicExamStudent();
         BasicExamStudent basicExamStudent = new BasicExamStudent();
+        basicExamStudent.setSchoolId(schoolId);
+        basicExamStudent.setSemesterId(semesterId);
+        basicExamStudent.setExamId(examId);
+        basicExamStudent.setCourseCode(courseCode);
+        basicExamStudent.setClazzId(basicTeachClazz.getId());
+        basicExamStudent.setStudentName(studentName);
+        basicExamStudent.setStudentCode(studentCode);
+        basicExamStudent.setCollege(college);
+        basicExamStudent.setMajor(major);
+        if (SystemConstant.strNotNull(paperNumber)) {
+            basicExamStudent.setPaperNumber(paperNumber);
+            basicExamStudent.setTeacherId(teacherId);
+            basicExamStudent.setExamStartTime(examStartTime);
+            basicExamStudent.setExamEndTime(examEndTime);
+            basicExamStudent.setExamPlace(examPlace);
+            basicExamStudent.setExamRoom(examRoom);
+        }
 
 
         if (SystemConstant.longNotNull(id)) {
         if (SystemConstant.longNotNull(id)) {
-            // 编辑
-
+            // 编辑 (学号不可更改)
+            BasicExamStudent dbBasicExamStudent = this.getById(id);
+            if (Objects.isNull(dbBasicExamStudent)) {
+                throw ExceptionResultEnum.ERROR.exception("考生不存在");
+            }
+            if (!studentCode.equals(dbBasicExamStudent.getStudentCode())) {
+                throw ExceptionResultEnum.ERROR.exception("编辑考生时,学号不可更改");
+            }
+            basicExamStudent.updateInfo(requestUserId);
+        } else {
+            // 新增 (学号在考试课程下唯一)
+            if (this.count(new QueryWrapper<BasicExamStudent>().lambda().eq(BasicExamStudent::getSchoolId, schoolId)
+                    .eq(BasicExamStudent::getExamId, examId).eq(BasicExamStudent::getCourseCode, courseCode)
+                    .eq(BasicExamStudent::getStudentCode, studentCode)) > 0) {
+                throw ExceptionResultEnum.ERROR.exception(String.format("学号[%s]重复", studentCode));
+            }
+            basicExamStudent.insertInfo(requestUserId);
         }
         }
 
 
-        return null;
-    }
-
-    @Transactional
-    @Override
-    public void importLogic(MultipartFile file) {
-
-    }
-
-    @Override
-    public void exportLogic(HttpServletResponse response, Long schoolId, Long semesterId, Long examId,
-            String courseCode, String teacher, String college, String major, String teachClazz,
-            String examStudentInfo) {
-
-    }
-
-    @Transactional
-    @Override
-    public void deleteBatch(List<Long> idList) {
-
+        return basicExamStudent;
     }
     }
 }
 }

+ 211 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/SyncBasicExamStudentImportService.java

@@ -0,0 +1,211 @@
+package com.qmth.distributed.print.business.templete.execute;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.qmth.distributed.print.business.bean.dto.BasicExamStudentDto;
+import com.qmth.distributed.print.business.entity.BasicExamStudent;
+import com.qmth.distributed.print.business.service.BasicExamStudentService;
+import com.qmth.distributed.print.business.templete.importData.SyncImportTaskTemplate;
+import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
+import com.qmth.teachcloud.common.contant.SpringContextHolder;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.TBTask;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.TaskResultEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import com.qmth.teachcloud.common.enums.UploadFileEnum;
+import com.qmth.teachcloud.common.service.FileUploadService;
+import com.qmth.teachcloud.common.service.TBTaskService;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ * @Description: 考生字典导入同步任务
+ * @Author: CaoZixuan
+ * @Date: 2024-02-26
+ */
+@Service
+public class SyncBasicExamStudentImportService extends SyncImportTaskTemplate {
+
+    private final static Logger log = LoggerFactory.getLogger(SyncBasicExamStudentImportService.class);
+
+    public static final String OBJ_TITLE = "考生字典数据";
+
+    @Resource
+    private BasicExamStudentService basicExamStudentService;
+
+    @Resource
+    private FileUploadService fileUploadService;
+
+    @Override
+    public Result importTask(Map<String, Object> map) throws Exception {
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+        InputStream inputStream = super.getUploadFileInputStream(tbTask);
+        map.put("inputStream", inputStream);
+
+        StringJoiner stringJoinerSummary = new StringJoiner("\n").add(
+                MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN),
+                        BEGIN_TITLE, OBJ_TITLE));
+        tbTask.setStatus(TaskStatusEnum.RUNNING);
+        TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
+        tbTaskService.updateById(tbTask);
+        int dataCount = 0;
+        int successCount = 0;
+        int errorCount = 0;
+        List<BasicExamStudentDto> errorDataList = new ArrayList<>();
+        boolean importResult = true;
+
+        try {
+            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
+
+            // 执行导入考务数据
+            Map<String, Object> result = taskLogicService.executeImportBasicExamStudentLogic(map);
+            dataCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.DATA_COUNT)));
+            successCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.SUCCESS_DATA_COUNT)));
+            errorCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.ERROR_DATA_COUNT)));
+
+            // 无异常数据
+            if (result.containsKey(SystemConstant.DATASOURCE)) {
+                List<BasicExamStudent> basicExamStudentList = JSON.parseArray(JSON.toJSONString(result.get(SystemConstant.DATASOURCE)), BasicExamStudent.class);
+                basicExamStudentService.saveOrUpdateBatch(basicExamStudentList);
+
+            }
+            if (result.containsKey(SystemConstant.ERROR_DATA_LIST)) {
+                // 有异常数据
+                errorDataList = JSON.parseArray(JSON.toJSONString(result.get(SystemConstant.ERROR_DATA_LIST)),
+                        BasicExamStudentDto.class);
+            }
+
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e.getMessage());
+            throw ExceptionResultEnum.ERROR.exception("导入考生字典失败");
+        } finally {//生成文件
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}",
+                    DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, dataCount,
+                    FINISH_TOTAL_SIZE, successCount, FINISH_SUCCESS_SIZE, errorCount, FINISH_ERROR_SIZE));
+            if (CollectionUtils.isNotEmpty(errorDataList)) {
+                tbTask.setResult(TaskResultEnum.ERROR);
+                try {
+                    File excelFileTemp = SystemConstant.getFileTempVar(SystemConstant.EXCEL_PREFIX);
+                    this.createLocalErrorExcel(errorDataList, excelFileTemp);
+                    String fileName = SystemConstant.getNanoId() + SystemConstant.EXCEL_PREFIX;
+                    FilePathVo filePathVo = fileUploadService.uploadFile(excelFileTemp, UploadFileEnum.FILE, fileName);
+                    tbTask.setErrorFilePath(JSON.toJSONString(filePathVo));
+                } catch (Exception e) {
+                    log.error("创建考生字典导入错误数据文件失败");
+                } finally {
+                    tbTask.setSummary("创建考生字典导入错误数据文件失败" + stringJoinerSummary);
+                }
+                importResult = false;
+            } else {
+                tbTask.setSummary(stringJoinerSummary.toString());
+                tbTask.setResult(TaskResultEnum.SUCCESS);
+            }
+            tbTask.setStatus(TaskStatusEnum.FINISH);
+            super.createTxt(tbTask);
+        }
+        return ResultUtil.ok(importResult);
+    }
+
+    private void createLocalErrorExcel(List<BasicExamStudentDto> basicExamStudentDtoList, File excelFileTemp)
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException {
+
+        List<Field> fields = Arrays.asList(BasicExamStudentDto.class.getDeclaredFields());
+        log.debug("导出Excel开始...");
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet sheet = wb.createSheet("考生字典导入");
+
+        Font defaultFont = wb.createFont();
+        defaultFont.setFontHeightInPoints((short) 12);
+        defaultFont.setFontName("宋体");
+
+        int cellCount = fields.size() + 1;
+        // 说明
+        XSSFCellStyle describeStyle = wb.createCellStyle();
+        describeStyle.setAlignment(HorizontalAlignment.LEFT);
+        Font describeFont = wb.createFont();
+        describeFont.setFontHeightInPoints((short) 12);
+        describeFont.setFontName("宋体");
+        describeFont.setColor(IndexedColors.RED.getIndex());
+        describeStyle.setFont(describeFont);
+        String describe = SystemConstant.BASIC_EXAM_STUDENT;
+        describe = describe.trim();
+        XSSFRow rowDescribe = sheet.createRow(0);
+        rowDescribe.setHeightInPoints(195); //行高设置成195px
+        for (int i = 0; i < cellCount; i++) {
+            XSSFCell cell = rowDescribe.createCell(i);
+            if (i == 0) {
+                cell.setCellValue(describe);
+                cell.setCellStyle(describeStyle);
+            }
+        }
+        CellRangeAddress region = new CellRangeAddress(0, 0, 0, cellCount - 1);
+        sheet.addMergedRegion(region);
+
+        // 表头行
+        XSSFCellStyle headerStyle = wb.createCellStyle();
+        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
+        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+        headerStyle.setFont(defaultFont);
+        XSSFRow rowHead = sheet.createRow(1);
+        for (int i = 0; i < fields.size(); i++) {
+            XSSFCell cell = rowHead.createCell(i);
+            cell.setCellValue(fields.get(i).getName());
+            cell.setCellStyle(headerStyle);
+        }
+        XSSFCell lastCell = rowHead.createCell(cellCount - 1);
+        lastCell.setCellValue("异常信息");
+        lastCell.setCellStyle(headerStyle);
+
+        // 内容行
+        XSSFCellStyle exampleStyle = wb.createCellStyle();
+        exampleStyle.setAlignment(HorizontalAlignment.LEFT);
+        exampleStyle.setFont(defaultFont);
+
+        for (int i = 0; i < basicExamStudentDtoList.size(); i++) {
+            BasicExamStudentDto basicExamStudentDto = basicExamStudentDtoList.get(i);
+            XSSFRow row = sheet.createRow(i + 2);
+            for (int j = 0; j < fields.size(); j++) {
+                XSSFCell cell = row.createCell(j);
+                Field head = fields.get(j);
+                String methodName = "get" + SystemConstant.initCap(head.getName());
+                Method getMethod = basicExamStudentDto.getClass().getDeclaredMethod(methodName);
+                String value = String.valueOf(getMethod.invoke(basicExamStudentDto));
+                cell.setCellValue(value);
+                cell.setCellStyle(exampleStyle);
+            }
+        }
+        for (int i = 0; i < cellCount; i++) {
+            sheet.autoSizeColumn(i);
+            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
+        }
+
+        FileOutputStream outputStream = new FileOutputStream(excelFileTemp);
+        wb.write(outputStream);
+        outputStream.flush();
+        outputStream.close();
+    }
+}

+ 121 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/SyncImportTaskTemplate.java

@@ -0,0 +1,121 @@
+package com.qmth.distributed.print.business.templete.importData;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.teachcloud.common.contant.SpringContextHolder;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.TBTask;
+import com.qmth.teachcloud.common.enums.TaskResultEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import com.qmth.teachcloud.common.enums.TaskTypeEnum;
+import com.qmth.teachcloud.common.enums.UploadFileEnum;
+import com.qmth.teachcloud.common.service.TBTaskService;
+import com.qmth.teachcloud.common.util.FileStoreUtil;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+
+/**
+ * @Description: 同步导入模版
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/29
+ */
+public abstract class SyncImportTaskTemplate {
+    private final static Logger log = LoggerFactory.getLogger(SyncImportTaskTemplate.class);
+    public static final String BEGIN_TITLE = "->开始准备处理导入的";
+
+    public static final String FINISH_TITLE = "数据处理结束,共处理了";
+
+    public static final String FINISH_TOTAL_SIZE = "条数据,正常";
+
+    public static final String FINISH_SUCCESS_SIZE = "条数据,异常";
+
+    public static final String FINISH_ERROR_SIZE = "条数据";
+
+    public static final String EXCEPTION_DATA = "错误信息:";
+
+    public static final String EXCEPTION_CREATE_TXT_TITLE = "->创建导出日志时发生异常!";
+
+    /**
+     * 同步导入任务
+     *
+     * @param map 参数集
+     * @return 结果
+     * @throws IOException,NoSuchFieldException 异常
+     */
+    public abstract Result importTask(Map<String, Object> map) throws Exception;
+
+    /**
+     * 获取上传的文件
+     *
+     * @param tbTask 任务
+     * @return InputStream
+     * @throws IOException 异常
+     */
+    public InputStream getUploadFileInputStream(TBTask tbTask) throws Exception {
+        FileStoreUtil fileStoreUtil = SpringContextHolder.getBean(FileStoreUtil.class);
+        JSONObject jsonObject = JSONObject.parseObject(tbTask.getImportFilePath());
+        String path = (String) jsonObject.get(SystemConstant.PATH);
+        String type = (String) jsonObject.get(SystemConstant.TYPE);
+        UploadFileEnum uploadType = Enum.valueOf(UploadFileEnum.class, (String) jsonObject.get(SystemConstant.UPLOAD_TYPE));
+        InputStream inputStream;
+        if (Objects.equals(type, SystemConstant.OSS)) {
+            inputStream = fileStoreUtil.ossDownloadIs(path, uploadType.getFssType());
+        } else {
+            inputStream = new FileInputStream(path);
+        }
+        return inputStream;
+    }
+
+    /**
+     * 创建txt文件
+     *
+     * @param tbTask 任务
+     */
+    public void createTxt(TBTask tbTask) throws IOException {
+        try {
+            JSONObject json = SystemConstant.createTxt(tbTask.getSummary());
+            tbTask.setReportFilePath(json.toJSONString());
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e.getMessage());
+            StringJoiner stringJoinerSummary = new StringJoiner("").add(tbTask.getSummary()).add("\n");
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_CREATE_TXT_TITLE, EXCEPTION_DATA, e.getMessage()));
+
+            String summary = stringJoinerSummary.toString();
+            if (summary.length() >= 65535) {
+                summary = "Data too long : " + summary.substring(0, 100) + "......" + summary.substring(summary.length() - 100);
+            }
+
+            tbTask.setSummary(summary);
+            tbTask.setResult(TaskResultEnum.ERROR);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
+            tbTask.setStatus(TaskStatusEnum.FINISH);
+            if (tbTask.getType() == TaskTypeEnum.CREATE_PDF) {
+                tbTask.setResultFilePath(tbTask.getImportFilePath());
+                tbTask.setImportFileName(null);
+                tbTask.setImportFilePath(null);
+                tbTask.setErrorMessage(null);
+            }
+            tbTaskService.updateById(tbTask);
+        }
+    }
+}

+ 0 - 25
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/SyncImportTaskTemplete.java

@@ -1,25 +0,0 @@
-package com.qmth.distributed.print.business.templete.importData;
-
-import com.qmth.teachcloud.common.util.Result;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * @Description: 同步导入模版
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2021/3/29
- */
-public interface SyncImportTaskTemplete {
-
-    /**
-     * 同步导入任务
-     *
-     * @param map
-     * @return
-     * @throws IOException,NoSuchFieldException
-     */
-    Result importTask(Map<String, Object> map) throws IOException, NoSuchFieldException;
-}

+ 8 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/TaskLogicService.java

@@ -116,4 +116,12 @@ public interface TaskLogicService {
     Map<String, Object> executeDownloadScoreLogic(Map<String, Object> map) throws Exception;
     Map<String, Object> executeDownloadScoreLogic(Map<String, Object> map) throws Exception;
 
 
     Map<String, Object> executeDownloadPaperFileBatch(Map<String, Object> map) throws Exception;
     Map<String, Object> executeDownloadPaperFileBatch(Map<String, Object> map) throws Exception;
+
+    /**
+     * 处理考生字典导入
+     * @param map 数据源
+     * @return 结果
+     * @throws Exception 异常
+     */
+    Map<String, Object> executeImportBasicExamStudentLogic(Map<String, Object> map) throws Exception;
 }
 }

+ 130 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -14,6 +14,7 @@ import com.qmth.distributed.print.business.bean.createPdf.PrintPathVo;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.examRule.CodeNameEnableValue;
 import com.qmth.distributed.print.business.bean.examRule.CodeNameEnableValue;
 import com.qmth.distributed.print.business.bean.examRule.FieldsDto;
 import com.qmth.distributed.print.business.bean.examRule.FieldsDto;
+import com.qmth.distributed.print.business.bean.params.BasicExamStudentParam;
 import com.qmth.distributed.print.business.bean.params.DownloadPaperFileParam;
 import com.qmth.distributed.print.business.bean.params.DownloadPaperFileParam;
 import com.qmth.distributed.print.business.bean.result.DictionaryResult;
 import com.qmth.distributed.print.business.bean.result.DictionaryResult;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
@@ -52,7 +53,6 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.dao.DuplicateKeyException;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.FileCopyUtils;
 import org.springframework.util.FileCopyUtils;
@@ -139,6 +139,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     ExamDetailCoursePaperTypeService examDetailCoursePaperTypeService;
     ExamDetailCoursePaperTypeService examDetailCoursePaperTypeService;
     @Resource
     @Resource
     FileUploadService fileUploadService;
     FileUploadService fileUploadService;
+    @Resource
+    BasicExamStudentService basicExamStudentService;
 
 
     /**
     /**
      * 创建pdf前置条件
      * 创建pdf前置条件
@@ -2068,6 +2070,133 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         return map;
         return map;
     }
     }
 
 
+    @Transactional
+    @Override
+    public Map<String, Object> executeImportBasicExamStudentLogic(Map<String, Object> map) throws Exception {
+
+        SysUser requestUser = (SysUser) map.get(SystemConstant.USER);
+        InputStream inputStream = (InputStream) map.get("inputStream");
+        Long semesterId = SystemConstant.convertIdToLong(String.valueOf(map.get("semesterId")));
+        Long examId = SystemConstant.convertIdToLong(String.valueOf(map.get("examId")));
+        Long schoolId = requestUser.getSchoolId();
+
+        List<BasicExamStudent> dbData = basicExamStudentService.list(new QueryWrapper<BasicExamStudent>().lambda()
+                .select(BasicExamStudent::getId, BasicExamStudent::getExamId, BasicExamStudent::getCourseCode,
+                        BasicExamStudent::getStudentCode).eq(BasicExamStudent::getSchoolId, schoolId)
+                .eq(BasicExamStudent::getSemesterId, semesterId).eq(BasicExamStudent::getExamId, examId));
+
+        // 数据库中学生学号和id对应关系
+        Map<String, Long> studentCodeIdMap = dbData.stream().collect(Collectors.toMap(
+                k -> k.getExamId() + SystemConstant.HYPHEN + k.getCourseCode() + SystemConstant.HYPHEN + k.getStudentCode(),
+                BaseEntity::getId));
+        // excel中学生学号和学生字典对象关系
+        Map<String, BasicExamStudent> studentCodeObjMap = new HashMap<>();
+        List<BasicExamStudentDto> errorDataList = new ArrayList<>();
+        AtomicInteger successInteger = new AtomicInteger(0);
+        AtomicInteger exceptionInteger = new AtomicInteger(0);
+
+        ExcelUtil.excelReader(inputStream, Lists.newArrayList(BasicExamStudentDto.class),
+                (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
+
+                    for (int i = 0; i < finalExcelList.size(); i++) {
+                        List<String> errorMsgList = new ArrayList<>();
+                        LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
+                        List<Object> basicExamStudentDtoList = excelMap.get(i);
+                        // 无数据,跳过
+                        if (CollectionUtils.isEmpty(basicExamStudentDtoList)) {
+                            continue;
+                        }
+                        for (int y = 0; y < Objects.requireNonNull(basicExamStudentDtoList).size(); y++) {
+                            // 行索引
+                            BasicExamStudentDto basicExamStudentDto = (BasicExamStudentDto) basicExamStudentDtoList.get(
+                                    y);
+                            String courseName = StringUtils.trimToNull(basicExamStudentDto.getCourseName());
+                            String courseCode = StringUtils.trimToNull(basicExamStudentDto.getCourseCode());
+                            String studentName = StringUtils.trimToNull(basicExamStudentDto.getStudentName());
+                            String studentCode = StringUtils.trimToNull(basicExamStudentDto.getStudentCode());
+                            String college = StringUtils.trimToNull(basicExamStudentDto.getCollege());
+                            String major = StringUtils.trimToNull(basicExamStudentDto.getMajor());
+                            String teachClazz = StringUtils.trimToNull(basicExamStudentDto.getTeachClazz());
+                            String paperNumber = StringUtils.trimToNull(basicExamStudentDto.getPaperNumber());
+                            String teacherName = StringUtils.trimToNull(basicExamStudentDto.getTeacherName());
+                            String teacherCode = StringUtils.trimToNull(basicExamStudentDto.getTeacherCode());
+                            String examDate = StringUtils.trimToNull(basicExamStudentDto.getExamDate());
+                            String examTime = StringUtils.trimToNull(basicExamStudentDto.getExamTime());
+                            String examPlace = StringUtils.trimToNull(basicExamStudentDto.getExamPlace());
+                            String examRoom = StringUtils.trimToNull(basicExamStudentDto.getExamRoom());
+
+                            // 本行全部列为空,跳过
+                            if (StringUtils.isAllBlank(courseName, courseCode, studentName, studentCode, college, major,
+                                    teachClazz, paperNumber, teacherName, teacherCode, examDate, examTime, examPlace,
+                                    examRoom)) {
+                                continue;
+                            }
+                            Long examStartTime = null;
+                            Long examEndTime = null;
+                            try {
+                                if (SystemConstant.strNotNull(examDate) && SystemConstant.strNotNull(examTime)) {
+                                    Map<String, Object> timeMap = ConvertUtil.analyzeStartAndEndTime(examDate, examTime);
+                                    examStartTime = SystemConstant.convertIdToLong(String.valueOf(timeMap.get("startTime")));
+                                    examEndTime = SystemConstant.convertIdToLong(String.valueOf(timeMap.get("endTime")));
+                                }
+                            } catch (Exception e) {
+                                errorMsgList.add(e.getMessage());
+                            }
+
+                            String key = examId + SystemConstant.HYPHEN + courseCode + SystemConstant.HYPHEN + studentCode;
+                            Long id = null;
+                            if (studentCodeIdMap.containsKey(key)) {
+                                id = studentCodeIdMap.get(key);
+                            }
+                            BasicExamStudentParam basicExamStudentParam = new BasicExamStudentParam();
+                            basicExamStudentParam.setId(id);
+                            basicExamStudentParam.setSemesterId(semesterId);
+                            basicExamStudentParam.setExamId(examId);
+                            basicExamStudentParam.setCourseCode(courseCode);
+                            basicExamStudentParam.setStudentName(studentName);
+                            basicExamStudentParam.setStudentCode(studentCode);
+                            basicExamStudentParam.setCollege(college);
+                            basicExamStudentParam.setMajor(major);
+                            basicExamStudentParam.setTeachClazz(teachClazz);
+                            basicExamStudentParam.setPaperNumber(paperNumber);
+                            basicExamStudentParam.setTeacherName(teacherName);
+                            basicExamStudentParam.setTeacherCode(teacherCode);
+                            basicExamStudentParam.setExamStartTime(examStartTime);
+                            basicExamStudentParam.setExamEndTime(examEndTime);
+                            basicExamStudentParam.setExamPlace(examPlace);
+                            basicExamStudentParam.setExamRoom(examRoom);
+                            try {
+                                BasicExamStudent basicExamStudent = basicExamStudentService.editEntityHelp(
+                                        basicExamStudentParam, requestUser);
+                                // 考试课程下学号重复 后面的替换前面的
+                                studentCodeObjMap.put(key, basicExamStudent);
+                            } catch (Exception e) {
+                                errorMsgList.add(e.getMessage());
+                            }
+
+                            if (CollectionUtils.isNotEmpty(errorMsgList)) {
+                                basicExamStudentDto.setErrorMsg(String.join(";", errorMsgList));
+                                exceptionInteger.getAndIncrement();
+                            } else {
+                                successInteger.getAndIncrement();
+                            }
+                            errorDataList.add(basicExamStudentDto);
+                        }
+                    }
+
+                    if (!errorDataList.isEmpty()) {
+                        map.put(SystemConstant.ERROR_DATA_LIST, errorDataList);
+                    } else {
+                        List<BasicExamStudent> basicExamStudentList = new ArrayList<>(studentCodeObjMap.values());
+                        map.put(SystemConstant.DATASOURCE, basicExamStudentList);
+                    }
+                    map.put(SystemConstant.DATA_COUNT, errorDataList.size());
+                    map.put(SystemConstant.SUCCESS_DATA_COUNT, successInteger.get());
+                    map.put(SystemConstant.ERROR_DATA_COUNT, exceptionInteger.get());
+                    return finalExcelList;
+                }, 2);
+        return map;
+    }
 
 
     /**
     /**
      * 验证机构是否存在
      * 验证机构是否存在

+ 69 - 0
distributed-print-business/src/main/resources/mapper/BasicExamStudentMapper.xml

@@ -71,4 +71,73 @@
             </if>
             </if>
         </where>
         </where>
     </select>
     </select>
+    <select id="findBasicExamStudentList"
+            resultType="com.qmth.distributed.print.business.bean.result.BasicExamStudentResult">
+        SELECT
+            bes.id,
+            bc.name AS courseName,
+            bes.course_code AS courseCode,
+            bes.student_name AS studentName,
+            bes.student_code AS studentCode,
+            bes.college,
+            bes.major,
+            tbc.clazz_name AS clazzName,
+            bes.paper_number AS paperNumber,
+            teacher.real_name AS teacherName,
+            teacher.code AS teacherCode,
+            bes.exam_start_time AS examStartTime,
+            bes.exam_end_time AS examEndTime,
+            bes.exam_place AS examPlace,
+            bes.exam_room AS examRoom
+        FROM
+            basic_exam_student bes
+                LEFT JOIN
+            basic_course bc ON bes.course_code = bc.code
+                LEFT JOIN
+            basic_teach_clazz tbc ON bes.clazz_id = tbc.id
+                LEFT JOIN
+            sys_user teacher ON bes.teacher_id = teacher.id
+                LEFT JOIN
+            sys_user su ON bes.create_id = su.id
+        <where>
+            <if test="schoolId != null and schoolId != ''">
+                AND bes.school_id = #{schoolId}
+            </if>
+            <if test="semesterId != null">
+                AND bes.semester_id = #{semesterId}
+            </if>
+            <if test="examId != null">
+                AND bes.exam_id = #{examId}
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                AND bes.course_code LIKE CONCAT('%',#{courseCode},'%')
+            </if>
+            <if test="teacher != null and teacher != ''">
+                AND (teacher.real_name LIKE CONCAT('%',#{teacher},'%') OR teacher.code LIKE CONCAT('%',#{teacher},'%'))
+            </if>
+            <if test="college != null and college != ''">
+                AND bes.college LIKE CONCAT('%',#{college},'%')
+            </if>
+            <if test="major != null and major != ''">
+                AND bes.major LIKE CONCAT('%',#{major},'%')
+            </if>
+            <if test="teachClazzId != null">
+                AND tbc.id = #{teachClazzId}
+            </if>
+            <if test="examStudentInfo != null and examStudentInfo != ''">
+                AND (bes.student_code LIKE CONCAT('%',#{examStudentInfo},'%') OR bes.student_name LIKE CONCAT('%',#{examStudentInfo},'%'))
+            </if>
+            <if test="dpr != null">
+                <if test="dpr.requestUserId != null">
+                    AND bes.create_id = #{dpr.requestUserId}
+                </if>
+                <if test="dpr.orgIdSet != null and dpr.orgIdSet != '' and dpr.orgIdSet.size > 0">
+                    AND su.org_id IN
+                    <foreach collection="dpr.orgIdSet" item="item" index="index" open="(" separator="," close=")">
+                        #{item}
+                    </foreach>
+                </if>
+            </if>
+        </where>
+    </select>
 </mapper>
 </mapper>

+ 4 - 4
distributed-print/install/mysql/upgrade/3.3.1.sql

@@ -118,7 +118,7 @@ INSERT INTO sys_privilege
 (id, name, url, `type`, parent_id, `sequence`, property, related, enable, default_auth, front_display)
 (id, name, url, `type`, parent_id, `sequence`, property, related, enable, default_auth, front_display)
 VALUES(2029, '获取试卷蓝图信息', '/api/admin/course/degree/final_score/paper_struct/query', 'URL', 2006, 1, 'AUTH', NULL, 1, 1, 1);
 VALUES(2029, '获取试卷蓝图信息', '/api/admin/course/degree/final_score/paper_struct/query', 'URL', 2006, 1, 'AUTH', NULL, 1, 1, 1);
 
 
---2024/2/18
+-- 2024/2/18
 DROP TABLE IF EXISTS `t_c_paper_struct`;
 DROP TABLE IF EXISTS `t_c_paper_struct`;
 CREATE TABLE `t_c_paper_struct` (
 CREATE TABLE `t_c_paper_struct` (
                                       `id` bigint NOT NULL COMMENT '主键',
                                       `id` bigint NOT NULL COMMENT '主键',
@@ -220,7 +220,7 @@ ALTER TABLE t_r_basic_info CHANGE credit credit varchar(50) NULL COMMENT '学分
 ALTER TABLE t_r_basic_info ADD period varchar(50) NULL COMMENT '学时';
 ALTER TABLE t_r_basic_info ADD period varchar(50) NULL COMMENT '学时';
 ALTER TABLE t_r_basic_info CHANGE period period varchar(50) NULL COMMENT '学时' AFTER credit;
 ALTER TABLE t_r_basic_info CHANGE period period varchar(50) NULL COMMENT '学时' AFTER credit;
 
 
---2014/2/26
+-- 2014/2/26
 DROP TABLE IF EXISTS `exam_task_assign_paper_type`;
 DROP TABLE IF EXISTS `exam_task_assign_paper_type`;
 CREATE TABLE `exam_task_assign_paper_type` (
 CREATE TABLE `exam_task_assign_paper_type` (
            `exam_id` bigint NOT NULL COMMENT '考试ID',
            `exam_id` bigint NOT NULL COMMENT '考试ID',
@@ -230,7 +230,7 @@ CREATE TABLE `exam_task_assign_paper_type` (
            `paper_type` varchar(45) DEFAULT NULL COMMENT '卷型',
            `paper_type` varchar(45) DEFAULT NULL COMMENT '卷型',
            `assign_mode` varchar(10) DEFAULT NULL COMMENT '分配方式:MANUAL-手动关联,AUTO-自动分配',
            `assign_mode` varchar(10) DEFAULT NULL COMMENT '分配方式:MANUAL-手动关联,AUTO-自动分配',
            PRIMARY KEY (`exam_id`,`paper_number`,`exam_start_time`,`exam_end_time`)
            PRIMARY KEY (`exam_id`,`paper_number`,`exam_start_time`,`exam_end_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
 
 
 DROP TABLE IF EXISTS `t_b_task_pdf`;
 DROP TABLE IF EXISTS `t_b_task_pdf`;
 CREATE TABLE `t_b_task_pdf` (
 CREATE TABLE `t_b_task_pdf` (
@@ -361,7 +361,7 @@ ALTER TABLE `basic_exam_student`
     ADD UNIQUE INDEX `basic_exam_student_unique` (`school_id` ASC, `exam_id` ASC, `course_code` ASC, `student_code` ASC) VISIBLE;
     ADD UNIQUE INDEX `basic_exam_student_unique` (`school_id` ASC, `exam_id` ASC, `course_code` ASC, `student_code` ASC) VISIBLE;
 ;
 ;
 
 
---2024/2/27
+-- 2024/2/27
 UPDATE sys_privilege
 UPDATE sys_privilege
 SET name='管理成绩', url='Score', `type`='LINK', parent_id=2001, `sequence`=1, property='AUTH', related='2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2029,2030', enable=1, default_auth=0, front_display=1
 SET name='管理成绩', url='Score', `type`='LINK', parent_id=2001, `sequence`=1, property='AUTH', related='2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2029,2030', enable=1, default_auth=0, front_display=1
 WHERE id=2006;
 WHERE id=2006;

+ 104 - 5
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicExamStudentController.java

@@ -1,9 +1,32 @@
 package com.qmth.distributed.print.api;
 package com.qmth.distributed.print.api;
 
 
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.distributed.print.business.bean.params.BasicExamStudentParam;
+import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
+import com.qmth.distributed.print.business.service.BasicExamStudentService;
+import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.distributed.print.business.templete.execute.SyncBasicExamStudentImportService;
+import com.qmth.teachcloud.common.annotation.OperationLogDetail;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.TaskTypeEnum;
+import com.qmth.teachcloud.common.enums.log.CustomizedOperationTypeEnum;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.common.util.ServletUtil;
+import io.swagger.annotations.*;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -13,8 +36,84 @@ import org.springframework.web.bind.annotation.RestController;
  * @author CaoZixuan
  * @author CaoZixuan
  * @since 2024-02-22
  * @since 2024-02-22
  */
  */
+@Api(tags = "专业管理controller")
 @RestController
 @RestController
-@RequestMapping("/basic-exam-student")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_BASIC + "/exam_student")
 public class BasicExamStudentController {
 public class BasicExamStudentController {
 
 
-}
+    @Resource
+    private BasicExamStudentService basicExamStudentService;
+
+    @Resource
+    private PrintCommonService printCommonService;
+
+    @Resource
+    private SyncBasicExamStudentImportService syncBasicExamStudentImportService;
+
+    @ApiOperation(value = "考生字典管理-分页查询")
+    @RequestMapping(value = "/page", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = BasicExamStudentResult.class) })
+    public Result findBasicExamStudentPage(@ApiParam(value = "学期id") @RequestParam(required = false) String semesterId,
+            @ApiParam(value = "学期id") @RequestParam(required = false) String examId,
+            @ApiParam(value = "考试id") @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "教师(工号/姓名)") @RequestParam(required = false) String teacher,
+            @ApiParam(value = "学院") @RequestParam(required = false) String college,
+            @ApiParam(value = "专业") @RequestParam(required = false) String major,
+            @ApiParam(value = "教学班ID(下拉选择)") @RequestParam(required = false) String teachClazzId,
+            @ApiParam(value = "考生信息(姓名/学号)") @RequestParam(required = false) String examStudentInfo,
+            @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+            @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(basicExamStudentService.page(requestUser, SystemConstant.convertIdToLong(semesterId),
+                SystemConstant.convertIdToLong(examId), courseCode, teacher, college, major, SystemConstant.convertIdToLong(teachClazzId),
+                examStudentInfo, pageNumber, pageSize));
+    }
+
+    @ApiOperation(value = "考生字典管理-新增/编辑")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "更新成功", response = Result.class) })
+    @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.EDIT)
+    public Result saveBasicExamStudent(@Valid @RequestBody BasicExamStudentParam basicExamStudentParam, BindingResult bindingResult) {
+        if (bindingResult.hasErrors()) {
+            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
+        }
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(basicExamStudentService.save(basicExamStudentParam, sysUser));
+    }
+
+    @ApiOperation(value = "考生字典管理-批量导入(同步)")
+    @RequestMapping(value = "/import", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Result.class) })
+    @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.IMPORT)
+    public Result basicExamStudentImportSync(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file) throws Exception {
+        Map<String, Object> map = printCommonService.saveTask(file, TaskTypeEnum.STUDENT_IMPORT);
+        return syncBasicExamStudentImportService.importTask(map);
+    }
+
+    @ApiOperation(value = "考生字典管理-导出")
+    @RequestMapping(value = "/export", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Result.class) })
+    @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.EXPORT)
+    public void export(@ApiParam(value = "学期id") @RequestParam(required = false) String semesterId,
+            @ApiParam(value = "学期id") @RequestParam(required = false) String examId,
+            @ApiParam(value = "考试id") @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "教师(工号/姓名)") @RequestParam(required = false) String teacher,
+            @ApiParam(value = "学院") @RequestParam(required = false) String college,
+            @ApiParam(value = "专业") @RequestParam(required = false) String major,
+            @ApiParam(value = "教学班ID(下拉选择)") @RequestParam(required = false) String teachClazzId,
+            @ApiParam(value = "考生信息(姓名/学号)") @RequestParam(required = false) String examStudentInfo, HttpServletResponse response) throws Exception {
+        basicExamStudentService.exportLogic(response, SystemConstant.convertIdToLong(semesterId),
+                SystemConstant.convertIdToLong(examId), courseCode, teacher, college, major, SystemConstant.convertIdToLong(teachClazzId),
+                examStudentInfo);
+    }
+
+    @ApiOperation(value = "考生字典管理-删除")
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "删除成功", response = Result.class) })
+    @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.DELETE)
+    public Result deleteBasicExamStudent(@ApiParam(value = "选择要删除的考生生id集合", required = true) @RequestParam List<String> idList) {
+        basicExamStudentService.deleteBatch(
+                idList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList()));
+        return ResultUtil.ok();
+    }
+}

+ 9 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java

@@ -305,6 +305,7 @@ public class SystemConstant {
     public static final String SYS_USER = "sysUser";
     public static final String SYS_USER = "sysUser";
 
 
     public static final String ERROR_DATA_LIST = "errorDataList";
     public static final String ERROR_DATA_LIST = "errorDataList";
+    public static final String DATASOURCE = "datasource";
     public static final String DATA_COUNT = "dataCount";
     public static final String DATA_COUNT = "dataCount";
     public static final String SUCCESS_DATA_COUNT = "successDataCount";
     public static final String SUCCESS_DATA_COUNT = "successDataCount";
     public static final String ERROR_DATA_COUNT = "errorDataCount";
     public static final String ERROR_DATA_COUNT = "errorDataCount";
@@ -440,6 +441,14 @@ public class SystemConstant {
             "11、请不要删除此行,也不要删除模板中的任何列。\n" +
             "11、请不要删除此行,也不要删除模板中的任何列。\n" +
             "12、使用前请先删除样例数据。\n";
             "12、使用前请先删除样例数据。\n";
 
 
+    public static final String BASIC_EXAM_STUDENT = "说明\n" +
+            "1、学期、考试、课程、姓名、学号、教学班均必填;\n" +
+            "2、试卷编号存在时,任课教师信息、考试时间、考点、考场均必填\n" +
+            "3、【考试日期】必填,且格式为YYYY-MM-DD。例如2023-07-09;\n" +
+            "4、【考试时间】必填,且格式为HH:mm-HH:mm。例如18:30-20:30;\n" +
+            "5、请不要删除此行,也不要删除模板中的任何列。\n" +
+            "6、使用前请先删除样例数据。\n";
+
     /**
     /**
      * 线程池配置
      * 线程池配置
      */
      */

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/TaskTypeEnum.java

@@ -12,6 +12,8 @@ import java.util.Objects;
 public enum TaskTypeEnum {
 public enum TaskTypeEnum {
     USER_IMPORT("用户导入"),
     USER_IMPORT("用户导入"),
 
 
+    BASIC_EXAM_STUDENT_IMPORT("考生字典导入"),
+
     STUDENT_IMPORT("学生导入"),
     STUDENT_IMPORT("学生导入"),
 
 
     CLAZZ_IMPORT("班级导入"),
     CLAZZ_IMPORT("班级导入"),