浏览代码

签到表扫描图片上传

xiatian 1 年之前
父节点
当前提交
898e98d64c

+ 6 - 8
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailCourseService.java

@@ -1,21 +1,17 @@
 package com.qmth.distributed.print.business.service;
 
-import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.ExamDetailCourseDto;
 import com.qmth.distributed.print.business.bean.dto.ExamDetailCourseFieldsDto;
-import com.qmth.distributed.print.business.bean.dto.SyncExamTaskDto;
 import com.qmth.distributed.print.business.bean.params.SingleExamStudentAddParam;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
-import com.qmth.distributed.print.business.enums.ExamTaskSyncStatusEnum;
-import com.qmth.distributed.print.business.enums.SyncCardTypeEnum;
 import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * <p>
  * 考务数据(考场关联科目) 服务类
@@ -51,4 +47,6 @@ public interface ExamDetailCourseService extends IService<ExamDetailCourse> {
     List<ExamDetailCourseFieldsDto> listExamDetailPaperNumber(Long examDetailId);
 
     boolean addExamStudent(SingleExamStudentAddParam singleExamStudentAddParam);
+
+	List<ExamDetailCourse> listByExamDetailIds(List<Long> edIds);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java

@@ -248,4 +248,7 @@ public interface ExamDetailService extends IService<ExamDetail> {
     void resetExamDetail(Long entityId, boolean clearPaperType);
 
     List<ExamDetailCourseInitMarkDto> listPrintFinishExamDetailCourse(String printStatus, long startTime, String markStatus);
+    
+    List<ExamDetail> listByExamAndPackage(Long examId, String packageCode);
+
 }

+ 21 - 8
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java

@@ -1,13 +1,25 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.stereotype.Service;
+
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.dto.ExamDetailCourseDto;
 import com.qmth.distributed.print.business.bean.dto.ExamDetailCourseFieldsDto;
 import com.qmth.distributed.print.business.bean.examRule.CodeName;
-import com.qmth.distributed.print.business.bean.examRule.CodeNameEnable;
 import com.qmth.distributed.print.business.bean.examRule.CodeNameEnableValue;
 import com.qmth.distributed.print.business.bean.params.SingleExamStudentAddParam;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
@@ -23,13 +35,6 @@ import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.util.ServletUtil;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.lang.reflect.Field;
-import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -188,4 +193,12 @@ public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMap
         // todo 往exam_student表插入扫描数据
         return false;
     }
+
+	@Override
+	public List<ExamDetailCourse> listByExamDetailIds(List<Long> edIds) {
+		QueryWrapper<ExamDetailCourse> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ExamDetailCourse> lw = wrapper.lambda();
+        lw.in(ExamDetailCourse::getExamDetailId, edIds);
+		return this.list(wrapper);
+	}
 }

+ 112 - 34
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -1,5 +1,44 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+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.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.BadSqlGrammarException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -10,7 +49,13 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.api.exception.ApiException;
-import com.qmth.distributed.print.business.bean.dto.*;
+import com.qmth.distributed.print.business.bean.dto.ClientExamStudentDto;
+import com.qmth.distributed.print.business.bean.dto.ExamDetailCourseDto;
+import com.qmth.distributed.print.business.bean.dto.ExamDetailPdfDownloadDto;
+import com.qmth.distributed.print.business.bean.dto.ExaminationExportDto;
+import com.qmth.distributed.print.business.bean.dto.ExaminationImportDto;
+import com.qmth.distributed.print.business.bean.dto.PrintTaskDto;
+import com.qmth.distributed.print.business.bean.dto.PrintTaskTotalDto;
 import com.qmth.distributed.print.business.bean.dto.initMarkData.ExamDetailCourseInitMarkDto;
 import com.qmth.distributed.print.business.bean.examRule.CodeNameEnableValue;
 import com.qmth.distributed.print.business.bean.examRule.FieldsDto;
@@ -18,45 +63,69 @@ import com.qmth.distributed.print.business.bean.params.SerialNumberParams;
 import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
-import com.qmth.distributed.print.business.entity.*;
-import com.qmth.distributed.print.business.enums.*;
+import com.qmth.distributed.print.business.entity.BasicCardRule;
+import com.qmth.distributed.print.business.entity.BasicExamRule;
+import com.qmth.distributed.print.business.entity.ClientPrintData;
+import com.qmth.distributed.print.business.entity.ClientStatus;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.distributed.print.business.entity.ExamPrintPlan;
+import com.qmth.distributed.print.business.entity.ExamStudent;
+import com.qmth.distributed.print.business.entity.ExamTask;
+import com.qmth.distributed.print.business.entity.ExamTaskDetail;
+import com.qmth.distributed.print.business.entity.TeachClazz;
+import com.qmth.distributed.print.business.enums.CardTypeEnum;
+import com.qmth.distributed.print.business.enums.ExamDataSourceEnum;
+import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
+import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
+import com.qmth.distributed.print.business.enums.StudentClazzEnum;
+import com.qmth.distributed.print.business.enums.SyncCardTypeEnum;
 import com.qmth.distributed.print.business.mapper.ExamDetailMapper;
-import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.business.service.BasicCardRuleService;
+import com.qmth.distributed.print.business.service.BasicExamRuleService;
+import com.qmth.distributed.print.business.service.BasicPrintConfigService;
+import com.qmth.distributed.print.business.service.ClientPrintDataService;
+import com.qmth.distributed.print.business.service.ClientStatusService;
+import com.qmth.distributed.print.business.service.ExamDetailCoursePaperTypeService;
+import com.qmth.distributed.print.business.service.ExamDetailCourseService;
+import com.qmth.distributed.print.business.service.ExamDetailService;
+import com.qmth.distributed.print.business.service.ExamPrintPlanService;
+import com.qmth.distributed.print.business.service.ExamStudentService;
+import com.qmth.distributed.print.business.service.ExamTaskDetailService;
+import com.qmth.distributed.print.business.service.ExamTaskService;
+import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.distributed.print.business.service.TeachClazzService;
 import com.qmth.distributed.print.business.templete.execute.AsyncExaminationImportTemplateService;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.dto.MqDto;
 import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
 import com.qmth.teachcloud.common.contant.SystemConstant;
-import com.qmth.teachcloud.common.entity.*;
-import com.qmth.teachcloud.common.enums.*;
-import com.qmth.teachcloud.common.service.*;
-import com.qmth.teachcloud.common.util.*;
-import org.apache.commons.lang3.StringUtils;
-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.beans.BeanUtils;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.jdbc.BadSqlGrammarException;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.annotation.Resource;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import com.qmth.teachcloud.common.entity.BasicAttachment;
+import com.qmth.teachcloud.common.entity.BasicClazz;
+import com.qmth.teachcloud.common.entity.BasicPrintConfig;
+import com.qmth.teachcloud.common.entity.SysOrg;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.entity.TBTask;
+import com.qmth.teachcloud.common.enums.CardCreateMethodEnum;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.MqTagEnum;
+import com.qmth.teachcloud.common.enums.OrgTypeEnum;
+import com.qmth.teachcloud.common.enums.PdfTypeEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import com.qmth.teachcloud.common.enums.TaskTypeEnum;
+import com.qmth.teachcloud.common.service.BasicAttachmentService;
+import com.qmth.teachcloud.common.service.BasicClazzService;
+import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
+import com.qmth.teachcloud.common.service.CommonCacheService;
+import com.qmth.teachcloud.common.service.SysOrgService;
+import com.qmth.teachcloud.common.service.SysUserService;
+import com.qmth.teachcloud.common.service.TBTaskService;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
+import com.qmth.teachcloud.common.util.ConvertUtil;
+import com.qmth.teachcloud.common.util.JdbcErrorUtil;
+import com.qmth.teachcloud.common.util.RedisUtil;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.common.util.ServletUtil;
 
 /**
  * <p>
@@ -1279,4 +1348,13 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         }
         return new ArrayList<>(clazzNameSet);
     }
+
+	@Override
+	public List<ExamDetail> listByExamAndPackage(Long examId, String packageCode) {
+		QueryWrapper<ExamDetail> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ExamDetail> lw = wrapper.lambda();
+        lw.eq(ExamDetail::getExamId, examId);
+        lw.eq(ExamDetail::getPackageCode, packageCode);
+		return this.list(wrapper);
+	}
 }

+ 48 - 9
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanPackageController.java

@@ -1,16 +1,30 @@
 package com.qmth.distributed.print.api.mark;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import com.alibaba.fastjson.JSONArray;
 import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.distributed.print.business.service.ExamDetailCourseService;
+import com.qmth.distributed.print.business.service.ExamDetailService;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.SysConfig;
 import com.qmth.teachcloud.common.service.CommonCacheService;
+import com.qmth.teachcloud.mark.bean.scananswer.SheetUploadVo;
+import com.qmth.teachcloud.mark.service.ScanPackageService;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -28,14 +42,39 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/package")
 public class ScanPackageController {
 	@Autowired
-    private CommonCacheService commonCacheService;
+	private CommonCacheService commonCacheService;
+	@Autowired
+	private ScanPackageService scanPackageService;
+	@Autowired
+	private ExamDetailService examDetailService;
+	@Autowired
+	private ExamDetailCourseService examDetailCourseService;
+
+	@ApiOperation(value = "签到表条码识别坐标获取")
+	@RequestMapping(value = "position/get", method = RequestMethod.POST)
+	public JSONArray positionGet() {
+		SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.PACKAGE_BARCODE_POSITION);
+		String value = sysConfig.getConfigValue();
+		JSONArray ja = JSONArray.parseArray(value);
+		return ja;
+	}
 
-    @ApiOperation(value = "签到表条码识别坐标获取")
-    @RequestMapping(value = "position/get", method = RequestMethod.POST)
-    public JSONArray positionGet() {
-    	SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.PACKAGE_BARCODE_POSITION);
-    	String value = sysConfig.getConfigValue();
-    	JSONArray ja=JSONArray.parseArray(value);
-    	return ja;
-    }
+	@ApiOperation(value = "签到表扫描图片上传")
+	@RequestMapping(value = "image/upload", method = RequestMethod.POST)
+	public SheetUploadVo imageUpload(@RequestParam Long examId, @RequestParam String packageCode,
+			@RequestParam Integer packageNo, @RequestParam MultipartFile file, @RequestParam String md5) {
+		List<ExamDetail> eds=examDetailService.listByExamAndPackage(examId, packageCode);
+		if(CollectionUtils.isEmpty(eds)) {
+			throw new ParameterException("未找到考试详情信息");
+		}
+		List<Long> edIds=eds.stream().map(e->e.getId()).collect(Collectors.toList());
+		List<ExamDetailCourse> edcs=examDetailCourseService.listByExamDetailIds(edIds);
+		if(CollectionUtils.isEmpty(edcs)) {
+			throw new ParameterException("未找到考场关联科目信息");
+		}
+		List<String> list=edcs.stream().map(e->e.getCoursePaperId()).collect(Collectors.toList());
+		Set<String> coursePaperIds=new HashSet<>();
+		coursePaperIds.addAll(list);
+		return scanPackageService.imageUpload(examId,coursePaperIds, packageCode, packageNo,file, md5);
+	}
 }

+ 3 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanPackage.java

@@ -1,12 +1,12 @@
 package com.qmth.teachcloud.mark.entity;
 
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
 import java.io.Serializable;
 
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 

+ 5 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/FileService.java

@@ -17,4 +17,9 @@ public interface FileService {
 
 	String getSheetUri(Long examId, String coursePaperId, String studentCode, Integer paperNumber, Integer pageIndex);
 
+	String getPackageUri(Long examId, String coursePaperId, String packageCode, Integer packageNo);
+
+	String uploadPackage(InputStream in, String md5, Long examId, String coursePaperId, String packageCode,
+			Integer packageNo);
+
 }

+ 6 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPackageService.java

@@ -1,9 +1,13 @@
 package com.qmth.teachcloud.mark.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.teachcloud.mark.bean.scananswer.SheetUploadVo;
 import com.qmth.teachcloud.mark.entity.ScanPackage;
 
 import java.util.List;
+import java.util.Set;
+
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -18,4 +22,6 @@ public interface ScanPackageService extends IService<ScanPackage> {
 	int getCount(Long examId);
 
     List<ScanPackage> listByExamIdAndCoursePaperIdAndPackageCode(Long examId, String coursePaperId, String packageCode);
+
+	SheetUploadVo imageUpload(Long examId,Set<String> coursePaperIds, String packageCode, Integer packageNo, MultipartFile file, String md5);
 }

+ 26 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/FileServiceImpl.java

@@ -92,4 +92,30 @@ public class FileServiceImpl implements FileService {
     public String getSheetUri(Long examId, String coursePaperId, String studentCode, Integer paperNumber, Integer pageIndex) {
         return UploadFileEnum.SHEET.getPath(UploadFileEnum.SHEET.getTitle(), examId, coursePaperId, studentCode, paperNumber, pageIndex, FormatType.JPG.name().toLowerCase());
     }
+
+	@Override
+	public String uploadPackage(InputStream in, String md5, Long examId,String coursePaperId, String packageCode,
+			Integer packageNo) {
+		String path = getPackageUri(examId,coursePaperId, packageCode, packageNo);
+        try {
+            path = fileStoreUtils.uploadFile(in, md5, UploadFileEnum.SHEET, path);
+            return fileStoreUtils.filePreview(path);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new StatusException("文件上传出错:" + path, e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+	}
+	
+    @Override
+    public String getPackageUri(Long examId, String coursePaperId,String packageCode, Integer packageNo) {
+        return UploadFileEnum.PACKAGE.getPath(UploadFileEnum.PACKAGE.getTitle(), examId, coursePaperId, packageCode, packageNo, FormatType.JPG.name().toLowerCase());
+    }
 }

+ 73 - 20
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPackageServiceImpl.java

@@ -3,13 +3,20 @@ package com.qmth.teachcloud.mark.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.mark.bean.scananswer.SheetUploadVo;
 import com.qmth.teachcloud.mark.entity.ScanPackage;
 import com.qmth.teachcloud.mark.mapper.ScanPackageMapper;
+import com.qmth.teachcloud.mark.service.FileService;
 import com.qmth.teachcloud.mark.service.ScanPackageService;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
+import java.util.Set;
 
 /**
  * <p>
@@ -21,27 +28,73 @@ import java.util.List;
  */
 @Service
 public class ScanPackageServiceImpl extends ServiceImpl<ScanPackageMapper, ScanPackage> implements ScanPackageService {
+	@Autowired
+	private FileService fileService;
 
-    @Override
-    public int getCount(Long examId) {
-        QueryWrapper<ScanPackage> wrapper = new QueryWrapper<>();
-        LambdaQueryWrapper<ScanPackage> lw = wrapper.lambda();
-        lw.eq(ScanPackage::getExamId, examId);
-        return baseMapper.selectCount(wrapper);
-    }
+	@Override
+	public int getCount(Long examId) {
+		QueryWrapper<ScanPackage> wrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanPackage> lw = wrapper.lambda();
+		lw.eq(ScanPackage::getExamId, examId);
+		return baseMapper.selectCount(wrapper);
+	}
 
-    @Override
-    public List<ScanPackage> listByExamIdAndCoursePaperIdAndPackageCode(Long examId, String coursePaperId, String packageCode) {
-        QueryWrapper<ScanPackage> queryWrapper = new QueryWrapper<>();
-        LambdaQueryWrapper<ScanPackage> lambdaQueryWrapper = queryWrapper.lambda();
-        lambdaQueryWrapper.eq(ScanPackage::getExamId, examId)
-                .eq(ScanPackage::getCoursePaperId, coursePaperId);
-        if (StringUtils.isNotBlank(packageCode)) {
-            lambdaQueryWrapper.eq(ScanPackage::getPackageCode, packageCode)
-                    .orderByAsc(ScanPackage::getPackageCode);
-        }
-        lambdaQueryWrapper.orderByAsc(ScanPackage::getPackageNo);
-        return this.list(queryWrapper);
-    }
+	@Override
+	public List<ScanPackage> listByExamIdAndCoursePaperIdAndPackageCode(Long examId, String coursePaperId,
+			String packageCode) {
+		QueryWrapper<ScanPackage> queryWrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanPackage> lambdaQueryWrapper = queryWrapper.lambda();
+		lambdaQueryWrapper.eq(ScanPackage::getExamId, examId).eq(ScanPackage::getCoursePaperId, coursePaperId);
+		if (StringUtils.isNotBlank(packageCode)) {
+			lambdaQueryWrapper.eq(ScanPackage::getPackageCode, packageCode).orderByAsc(ScanPackage::getPackageCode);
+		}
+		lambdaQueryWrapper.orderByAsc(ScanPackage::getPackageNo);
+		return this.list(queryWrapper);
+	}
 
+	@Transactional
+	@Override
+	public SheetUploadVo imageUpload(Long examId, Set<String> coursePaperIds, String packageCode, Integer packageNo,
+			MultipartFile file, String md5) {
+		SheetUploadVo vo = null;
+		for (String coursePaperId : coursePaperIds) {
+			try {
+				String path = fileService.uploadPackage(file.getInputStream(), md5, examId, coursePaperId, packageCode,
+						packageNo);
+				if (vo == null) {
+					vo = SheetUploadVo.create(path);
+				}
+				ScanPackage sp = getByExamIdAndCoursePaperIdAndPackageCodeAndPackageNo(examId, coursePaperId,
+						packageCode, packageNo);
+				if(sp==null) {
+					sp=new ScanPackage();
+					sp.setExamId(examId);
+					sp.setCoursePaperId(coursePaperId);
+					sp.setPackageCode(packageCode);
+					sp.setPackageNo(packageNo);
+					sp.setAssigned(false);
+				}
+				sp.setMd5(md5);
+				sp.setPath(path);
+				this.saveOrUpdate(sp);
+			} catch (Exception e) {
+				log.error("原图上传失败,examId=" + examId + ", coursePaperId=" + coursePaperId + ",packageCode=" + packageCode
+						+ ", packageNo=" + packageNo, e);
+				throw new ParameterException("扫描图上传失败", e);
+			}
+		}
+		return vo;
+	}
+
+	private ScanPackage getByExamIdAndCoursePaperIdAndPackageCodeAndPackageNo(Long examId, String coursePaperId,
+			String packageCode, Integer packageNo) {
+		QueryWrapper<ScanPackage> wrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanPackage> lw = wrapper.lambda();
+		lw.eq(ScanPackage::getExamId, examId);
+		lw.eq(ScanPackage::getCoursePaperId, coursePaperId);
+		lw.eq(ScanPackage::getPackageCode, packageCode);
+		lw.eq(ScanPackage::getPackageNo, packageNo);
+		wrapper.last("LIMIT 1");
+		return this.getOne(wrapper);
+	}
 }