|
@@ -1,14 +1,270 @@
|
|
package cn.com.qmth.am.service.impl;
|
|
package cn.com.qmth.am.service.impl;
|
|
|
|
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
+import java.io.FileNotFoundException;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.InputStream;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.qmth.boot.core.exception.StatusException;
|
|
|
|
+import com.qmth.boot.tools.excel.ExcelReader;
|
|
|
|
+import com.qmth.boot.tools.excel.enums.ExcelType;
|
|
|
|
+import com.qmth.boot.tools.excel.model.DataMap;
|
|
|
|
|
|
|
|
+import cn.com.qmth.am.bean.ImportResult;
|
|
|
|
+import cn.com.qmth.am.bean.StudentScoreDto;
|
|
|
|
+import cn.com.qmth.am.config.SysProperty;
|
|
import cn.com.qmth.am.dao.StudentScoreDao;
|
|
import cn.com.qmth.am.dao.StudentScoreDao;
|
|
import cn.com.qmth.am.entity.StudentScoreEntity;
|
|
import cn.com.qmth.am.entity.StudentScoreEntity;
|
|
import cn.com.qmth.am.service.StudentScoreService;
|
|
import cn.com.qmth.am.service.StudentScoreService;
|
|
|
|
|
|
@Service
|
|
@Service
|
|
public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, StudentScoreEntity> implements StudentScoreService {
|
|
public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, StudentScoreEntity> implements StudentScoreService {
|
|
|
|
+ private static final String[] EXCEL_HEADER = new String[] { "考试ID", "科目代码","考生编号", "大题号", "小题号", "评分"};
|
|
|
|
+ @Autowired
|
|
|
|
+ private SysProperty sysProperty;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void importScore() {
|
|
|
|
+ File dir = new File(sysProperty.getDataDir() + "/marking-score-import");
|
|
|
|
+ File[] fs = dir.listFiles();
|
|
|
|
+ if (fs == null || fs.length == 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ for (File file : fs) {
|
|
|
|
+ if (!file.isFile() || !file.getName().endsWith(".xlsx")) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ InputStream inputStream = null;
|
|
|
|
+ ImportResult ret = null;
|
|
|
|
+ try {
|
|
|
|
+ inputStream = new FileInputStream(file);
|
|
|
|
+ ret = disposeFile(inputStream);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ String errMsg;
|
|
|
|
+ if (e instanceof FileNotFoundException) {
|
|
|
|
+ errMsg = "未找到文件:" + file.getAbsolutePath();
|
|
|
|
+ } else {
|
|
|
|
+ errMsg = "系统错误:" + e.getMessage();
|
|
|
|
+ }
|
|
|
|
+ ret = new ImportResult(errMsg);
|
|
|
|
+ } finally {
|
|
|
|
+ if (inputStream != null) {
|
|
|
|
+ try {
|
|
|
|
+ inputStream.close();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ moveFile(dir, file, ret);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void moveFile(File dir, File file, ImportResult ret) {
|
|
|
|
+ try {
|
|
|
|
+ boolean succss = CollectionUtils.isEmpty(ret.getErrMsg());
|
|
|
|
+ if (succss) {
|
|
|
|
+ File sucDir = new File(dir.getAbsoluteFile() + "/success/");
|
|
|
|
+ if (!sucDir.exists()) {
|
|
|
|
+ sucDir.mkdir();
|
|
|
|
+ }
|
|
|
|
+ File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
|
|
|
|
+ if (targetFile.exists()) {
|
|
|
|
+ targetFile.delete();
|
|
|
|
+ }
|
|
|
|
+ FileUtils.copyFile(file, targetFile);
|
|
|
|
+ file.delete();
|
|
|
|
+ String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
|
|
|
|
+ File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
|
|
|
|
+ if (msgFile.exists()) {
|
|
|
|
+ msgFile.delete();
|
|
|
|
+ }
|
|
|
|
+ FileUtils.write(msgFile, ret.getCountInfo(), "UFT-8");
|
|
|
|
+ } else {
|
|
|
|
+ File sucDir = new File(dir.getAbsoluteFile() + "/failed/");
|
|
|
|
+ if (!sucDir.exists()) {
|
|
|
|
+ sucDir.mkdir();
|
|
|
|
+ }
|
|
|
|
+ File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
|
|
|
|
+ if (targetFile.exists()) {
|
|
|
|
+ targetFile.delete();
|
|
|
|
+ }
|
|
|
|
+ FileUtils.copyFile(file, targetFile);
|
|
|
|
+ file.delete();
|
|
|
|
+ String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
|
|
|
|
+ File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
|
|
|
|
+ if (msgFile.exists()) {
|
|
|
|
+ msgFile.delete();
|
|
|
|
+ }
|
|
|
|
+ FileUtils.writeLines(msgFile, ret.getErrMsg(), "UFT-8");
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new StatusException("文件处理出错", e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String errorMsg(int lineNum, String msg) {
|
|
|
|
+ return "第" + lineNum + "行 " + msg;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String trimAndNullIfBlank(String s) {
|
|
|
|
+ if (StringUtils.isBlank(s)) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ return s.trim();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private ImportResult disposeFile(InputStream inputStream) {
|
|
|
|
+ List<DataMap> lineList = null;
|
|
|
|
+ ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
|
|
|
|
+ try {
|
|
|
|
+ lineList = reader.getDataMapList();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new StatusException("Excel 解析失败");
|
|
|
|
+ }
|
|
|
|
+ if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
|
|
|
|
+ throw new StatusException("Excel表头错误");
|
|
|
|
+ }
|
|
|
|
+ if (CollectionUtils.isEmpty(lineList)) {
|
|
|
|
+ throw new StatusException("Excel无内容");
|
|
|
|
+ }
|
|
|
|
+ if (100001 < lineList.size()) {
|
|
|
|
+ throw new StatusException("数据行数不能超过100000");
|
|
|
|
+ }
|
|
|
|
+ List<StudentScoreDto> ss = new ArrayList<>();
|
|
|
|
+ ImportResult ret = new ImportResult();
|
|
|
|
+ List<String> failRecords = new ArrayList<>();
|
|
|
|
+ ret.setErrMsg(failRecords);
|
|
|
|
+ for (int i = 0; i < lineList.size(); i++) {
|
|
|
|
+ DataMap line = lineList.get(i);
|
|
|
|
+
|
|
|
|
+ StringBuilder msg = new StringBuilder();
|
|
|
|
+
|
|
|
|
+ StudentScoreDto imp = new StudentScoreDto();
|
|
|
|
+ String examId = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
|
|
|
|
+ if (StringUtils.isBlank(examId)) {
|
|
|
|
+ msg.append(" 考试ID不能为空");
|
|
|
|
+ } else if (examId.length() > 20) {
|
|
|
|
+ msg.append(" 考试ID不能超过20个字符");
|
|
|
|
+ } else {
|
|
|
|
+ try {
|
|
|
|
+ Long examIdVal = Long.parseLong(examId);
|
|
|
|
+ imp.setExamId(examIdVal);
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
+ msg.append(" 考试ID只能是数字");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String subjectCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
|
|
|
|
+ if (StringUtils.isBlank(subjectCode)) {
|
|
|
|
+ msg.append(" 科目代码不能为空");
|
|
|
|
+ } else if (subjectCode.length() > 100) {
|
|
|
|
+ msg.append(" 科目代码不能超过100个字符");
|
|
|
|
+ }
|
|
|
|
+ imp.setSubjectCode(subjectCode);
|
|
|
|
+
|
|
|
|
+ String studentCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
|
|
|
|
+ if (StringUtils.isBlank(studentCode)) {
|
|
|
|
+ msg.append(" 考生编号不能为空");
|
|
|
|
+ } else if (studentCode.length() > 100) {
|
|
|
|
+ msg.append(" 考生编号不能超过100个字符");
|
|
|
|
+ }
|
|
|
|
+ imp.setStudentCode(studentCode);
|
|
|
|
+
|
|
|
|
+ String mainNum = trimAndNullIfBlank(line.get(EXCEL_HEADER[3]));
|
|
|
|
+ if (StringUtils.isBlank(mainNum)) {
|
|
|
|
+ msg.append(" 大题号不能为空");
|
|
|
|
+ } else if (mainNum.length() > 10) {
|
|
|
|
+ msg.append(" 大题号不能超过10个字符");
|
|
|
|
+ } else {
|
|
|
|
+ try {
|
|
|
|
+ Integer mainNumVal = Integer.parseInt(mainNum);
|
|
|
|
+ if (mainNumVal <= 0) {
|
|
|
|
+ msg.append(" 大题号必须大于0");
|
|
|
|
+ }
|
|
|
|
+ imp.setMainNumber(mainNumVal);
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
+ msg.append(" 大题号格式错误");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String subNum = trimAndNullIfBlank(line.get(EXCEL_HEADER[4]));
|
|
|
|
+ if (StringUtils.isBlank(subNum)) {
|
|
|
|
+ msg.append(" 小题号不能为空");
|
|
|
|
+ } else if (subNum.length() > 10) {
|
|
|
|
+ msg.append(" 小题号不能超过10个字符");
|
|
|
|
+ }
|
|
|
|
+ imp.setSubNumber(subNum);
|
|
|
|
+
|
|
|
|
+ String score = trimAndNullIfBlank(line.get(EXCEL_HEADER[5]));
|
|
|
|
+ if (StringUtils.isBlank(score)) {
|
|
|
|
+ msg.append(" 评分不能为空");
|
|
|
|
+ } else if (score.length() > 10) {
|
|
|
|
+ msg.append(" 评分不能超过10个字符");
|
|
|
|
+ } else {
|
|
|
|
+ try {
|
|
|
|
+ Double scoreVal = Double.parseDouble(score);
|
|
|
|
+ imp.setMarkingScore(scoreVal);
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
+ msg.append(" 评分格式错误");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (msg.length() > 0) {
|
|
|
|
+ failRecords.add(errorMsg(i + 1, msg.toString()));
|
|
|
|
+ } else {
|
|
|
|
+ ss.add(imp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (CollectionUtils.isNotEmpty(failRecords)) {
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ updateScoreBatch(ret,ss);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ failRecords.add("系统错误:" + e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
|
|
+ private void updateScoreBatch(ImportResult ret,List<StudentScoreDto> ss) {
|
|
|
|
+ if (CollectionUtils.isEmpty(ss)) {
|
|
|
|
+ ret.setCountInfo("更新数量:0");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ int count=0;
|
|
|
|
+ for (StudentScoreDto s : ss) {
|
|
|
|
+ count=count+updateScore(s);
|
|
|
|
+ }
|
|
|
|
+ ret.setCountInfo("更新数量:"+count);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int updateScore(StudentScoreDto dto) {
|
|
|
|
+ UpdateWrapper<StudentScoreEntity> wrapper = new UpdateWrapper<>();
|
|
|
|
+ LambdaUpdateWrapper<StudentScoreEntity> lw = wrapper.lambda();
|
|
|
|
+ lw.set(StudentScoreEntity::getMarkingScore, dto.getMarkingScore());
|
|
|
|
+ lw.eq(StudentScoreEntity::getExamId, dto.getExamId());
|
|
|
|
+ lw.eq(StudentScoreEntity::getSubjectCode, dto.getSubjectCode());
|
|
|
|
+ lw.eq(StudentScoreEntity::getStudentCode, dto.getStudentCode());
|
|
|
|
+ lw.eq(StudentScoreEntity::getMainNumber, dto.getMainNumber());
|
|
|
|
+ lw.eq(StudentScoreEntity::getSubNumber, dto.getSubNumber());
|
|
|
|
+ return this.update(wrapper)?1:0;
|
|
|
|
+ }
|
|
}
|
|
}
|