|
@@ -1,8 +1,13 @@
|
|
|
package cn.com.qmth.am.service.impl;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.Comparator;
|
|
|
import java.util.HashSet;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
@@ -16,15 +21,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
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.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
import com.qmth.boot.core.exception.StatusException;
|
|
|
import com.qmth.boot.core.retrofit.exception.RetrofitResponseError;
|
|
|
-import com.qmth.boot.core.solar.model.OrgInfo;
|
|
|
-import com.qmth.boot.core.solar.service.SolarService;
|
|
|
import com.qmth.boot.tools.models.ByteArray;
|
|
|
|
|
|
import cn.com.qmth.am.bean.AiMarkingDto;
|
|
@@ -53,10 +58,10 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
private static final Logger log = LoggerFactory.getLogger(StudentScoreService.class);
|
|
|
|
|
|
@Autowired
|
|
|
- private SysProperty sysProperty;
|
|
|
+ private ConcurrentService concurrentService;
|
|
|
|
|
|
@Autowired
|
|
|
- private SolarService solarService;
|
|
|
+ private SysProperty sysProperty;
|
|
|
|
|
|
@Autowired
|
|
|
private DsMarkingService dsMarkingService;
|
|
@@ -122,24 +127,25 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
|
|
|
@Transactional
|
|
|
@Override
|
|
|
- public void createSlice(StudentScoreEntity score, QuestionEntity q, Map<Integer, AnswerImageDto> answerImages) {
|
|
|
+ public void createSlice(StudentScoreEntity score, QuestionEntity q) {
|
|
|
StudentScoreImageDto dto = new StudentScoreImageDto();
|
|
|
dto.setStudentScoreId(score.getId());
|
|
|
- getSlice(score, q, answerImages, dto);
|
|
|
- // saveSliceImage(score, dto.getImage());
|
|
|
+ getSlice(score, q, dto);
|
|
|
ocr(dto);
|
|
|
+ saveSliceImage(q, score, dto.getImage());
|
|
|
}
|
|
|
|
|
|
- private void getSlice(StudentScoreEntity score, QuestionEntity q, Map<Integer, AnswerImageDto> answerImages,
|
|
|
- StudentScoreImageDto dto) {
|
|
|
+ private void getSlice(StudentScoreEntity score, QuestionEntity q, StudentScoreImageDto dto) {
|
|
|
List<byte[]> ret = new ArrayList<>();
|
|
|
String suff = null;
|
|
|
+ Map<Integer, AnswerImageDto> answerImages = new LinkedHashMap<>();
|
|
|
for (ImageSlice s : q.getImageSlice()) {
|
|
|
AnswerImageDto sheet = getSheet(score, q, s.getI(), answerImages);
|
|
|
suff = sheet.getSuff();
|
|
|
ret.add(ImageUtil.cutImage(sheet.getImage(), sheet.getSuff(), s.getX().intValue(), s.getY().intValue(),
|
|
|
s.getW().intValue(), s.getH().intValue()));
|
|
|
}
|
|
|
+ saveSheetImage(q, score, answerImages);
|
|
|
dto.setSuff(suff);
|
|
|
if (ret.size() > 1) {
|
|
|
dto.setImage(ImageUtil.joinImages(ret, suff));
|
|
@@ -161,7 +167,6 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
String tem = url.split("\\?")[0];
|
|
|
String suff = tem.substring(tem.lastIndexOf(".") + 1).toLowerCase();
|
|
|
ret.setImage(ByteArray.fromUrl(url).value());
|
|
|
- // saveSheetImage(score,pageIndex, ret.getImage());
|
|
|
ret.setPageIndex(pageIndex);
|
|
|
ret.setSuff(suff);
|
|
|
answerImages.put(pageIndex, ret);
|
|
@@ -170,57 +175,75 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
throw new RuntimeException(e);
|
|
|
}
|
|
|
}
|
|
|
- // private void saveSheetImage(StudentScoreEntity s,Integer page,byte[] bs)
|
|
|
- // {
|
|
|
- // File dir=new File(sysProperty.getDataDir()+"/"+"sheet");
|
|
|
- // if(!dir.exists()) {
|
|
|
- // dir.mkdir();
|
|
|
- // }
|
|
|
- // File image=new
|
|
|
- // File(dir.getAbsolutePath()+"/"+s.getStudentCode()+"-"+page+".jpg");
|
|
|
- // if(image.exists()) {
|
|
|
- // image.delete();
|
|
|
- // }
|
|
|
- // FileOutputStream out=null;
|
|
|
- // try {
|
|
|
- // out = new FileOutputStream(image);
|
|
|
- // out.write(bs, 0, bs.length);
|
|
|
- // out.flush();
|
|
|
- // } catch (Exception e) {
|
|
|
- // }finally {
|
|
|
- // if(out!=null) {
|
|
|
- // try {
|
|
|
- // out.close();
|
|
|
- // } catch (IOException e) {
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // private void saveSliceImage(StudentScoreEntity s,byte[] bs) {
|
|
|
- // File dir=new File(sysProperty.getDataDir()+"/"+"slice");
|
|
|
- // if(!dir.exists()) {
|
|
|
- // dir.mkdir();
|
|
|
- // }
|
|
|
- // File image=new
|
|
|
- // File(dir.getAbsolutePath()+"/"+s.getStudentCode()+"-"+s.getMainNumber()+"-"+s.getSubNumber()+".jpg");
|
|
|
- // if(image.exists()) {
|
|
|
- // image.delete();
|
|
|
- // }
|
|
|
- // FileOutputStream out=null;
|
|
|
- // try {
|
|
|
- // out = new FileOutputStream(image);
|
|
|
- // out.write(bs, 0, bs.length);
|
|
|
- // out.flush();
|
|
|
- // } catch (Exception e) {
|
|
|
- // }finally {
|
|
|
- // if(out!=null) {
|
|
|
- // try {
|
|
|
- // out.close();
|
|
|
- // } catch (IOException e) {
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
+
|
|
|
+ private void saveSheetImage(QuestionEntity q, StudentScoreEntity s, Map<Integer, AnswerImageDto> answerImages) {
|
|
|
+ List<String> ss = new ArrayList<>();
|
|
|
+ for (AnswerImageDto ims : answerImages.values()) {
|
|
|
+ String path = "sheet/" + q.getExamId() + "/" + q.getSubjectCode() + "/" + q.getMainNumber() + "/"
|
|
|
+ + q.getSubNumber() + "/" + s.getExamNumber() + "-" + ims.getPageIndex() + ".jpg";
|
|
|
+ ss.add(path);
|
|
|
+ File image = new File(sysProperty.getDataDir() + "/" + path);
|
|
|
+ if (image.exists()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ boolean lock = concurrentService.getReadWriteLock(path).writeLock().tryLock();
|
|
|
+ if (lock) {
|
|
|
+ FileOutputStream out = null;
|
|
|
+ try {
|
|
|
+ if (image.exists()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ byte[] bs = Arrays.copyOf(ims.getImage(), ims.getImage().length);
|
|
|
+ out = new FileOutputStream(image);
|
|
|
+ out.write(bs, 0, bs.length);
|
|
|
+ out.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ } finally {
|
|
|
+ concurrentService.getReadWriteLock(path).writeLock().unlock();
|
|
|
+ if (out != null) {
|
|
|
+ try {
|
|
|
+ out.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.baseMapper.saveSheetPath(s.getId(), JSONArray.toJSONString(ss));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveSliceImage(QuestionEntity q, StudentScoreEntity s, byte[] imageByte) {
|
|
|
+ String path = "slice/" + q.getExamId() + "/" + q.getSubjectCode() + "/" + q.getMainNumber() + "/"
|
|
|
+ + q.getSubNumber() + "/" + s.getExamNumber() + ".jpg";
|
|
|
+ updateSlice(s.getId(), path);
|
|
|
+ File image = new File(sysProperty.getDataDir() + "/" + path);
|
|
|
+ if (image.exists()) {
|
|
|
+ image.delete();
|
|
|
+ }
|
|
|
+ FileOutputStream out = null;
|
|
|
+ try {
|
|
|
+ byte[] bs = Arrays.copyOf(imageByte, imageByte.length);
|
|
|
+ out = new FileOutputStream(image);
|
|
|
+ out.write(bs, 0, bs.length);
|
|
|
+ out.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ } finally {
|
|
|
+ if (out != null) {
|
|
|
+ try {
|
|
|
+ out.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateSlice(Long id, String path) {
|
|
|
+ UpdateWrapper<StudentScoreEntity> wrapper = new UpdateWrapper<>();
|
|
|
+ LambdaUpdateWrapper<StudentScoreEntity> lw = wrapper.lambda();
|
|
|
+ lw.set(StudentScoreEntity::getSlice, path);
|
|
|
+ lw.eq(StudentScoreEntity::getId, id);
|
|
|
+ this.update(wrapper);
|
|
|
+ }
|
|
|
|
|
|
private String getImageUrl(StudentScoreEntity score, QuestionEntity q, Integer pageIndex) {
|
|
|
return getImageUrlFromMarkingCloud(score, q, pageIndex);
|
|
@@ -279,8 +302,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
@Override
|
|
|
public void ocr(StudentScoreImageDto dto) {
|
|
|
try {
|
|
|
- OrgInfo org = solarService.getOrgList().get(0);
|
|
|
- String ret = ocrDispose(dto, org);
|
|
|
+ String ret = ocrDispose(dto);
|
|
|
if (ret != null) {
|
|
|
updateAnswer(dto.getStudentScoreId(), ret);
|
|
|
} else {
|
|
@@ -301,7 +323,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
this.update(wrapper);
|
|
|
}
|
|
|
|
|
|
- private String ocrDispose(StudentScoreImageDto dto, OrgInfo org) {
|
|
|
+ private String ocrDispose(StudentScoreImageDto dto) {
|
|
|
try {
|
|
|
String base64 = FileUtil.byteToBase64(dto.getImage(), dto.getSuff());
|
|
|
String ret = dsMarkingService.ocr(base64);
|
|
@@ -318,7 +340,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
} catch (InterruptedException e1) {
|
|
|
}
|
|
|
dto.setRetry(dto.getRetry() + 1);
|
|
|
- return ocrDispose(dto, org);
|
|
|
+ return ocrDispose(dto);
|
|
|
} else {
|
|
|
throw new StatusException("重试次数过多");
|
|
|
}
|
|
@@ -369,7 +391,6 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
AiMarkingDto dto = new AiMarkingDto();
|
|
|
dto.setScoreInfo(score);
|
|
|
try {
|
|
|
- OrgInfo org = solarService.getOrgList().get(0);
|
|
|
QuestionEntity q = questionService.getById(score.getQuestionId());
|
|
|
if (q == null) {
|
|
|
throw new StatusException("未找到试题信息");
|
|
@@ -377,6 +398,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
if (CollectionUtils.isEmpty(q.getAnswer())) {
|
|
|
return;
|
|
|
}
|
|
|
+ dto.setQuestion(q);
|
|
|
AutoScoreEnRequest req = new AutoScoreEnRequest();
|
|
|
req.setQuestionBody(q.getContent());
|
|
|
req.setStandardAnswer(q.getAnswer());
|
|
@@ -385,7 +407,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
req.setTotalScore(q.getFullScore());
|
|
|
req.setIntervalScore(0.1);
|
|
|
req.setQuestionTitle(q.getTitle());
|
|
|
- AutoScoreResult ret = aiMarkingDispose(dto, org, req);
|
|
|
+ AutoScoreResult ret = aiMarkingDispose(dto, req);
|
|
|
if (ret != null) {
|
|
|
updateScore(score.getId(), ret.getTotalScore());
|
|
|
} else {
|
|
@@ -396,9 +418,9 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private AutoScoreResult aiMarkingDispose(AiMarkingDto dto, OrgInfo org, AutoScoreEnRequest req) {
|
|
|
+ private AutoScoreResult aiMarkingDispose(AiMarkingDto dto, AutoScoreEnRequest req) {
|
|
|
try {
|
|
|
- return dsMarkingService.autoScore(req);
|
|
|
+ return dsMarkingService.autoScore(req, dto.getQuestion());
|
|
|
} catch (Exception e) {
|
|
|
log.error("aiScore异常", e);
|
|
|
if (e instanceof RetrofitResponseError) {
|
|
@@ -410,7 +432,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
|
|
|
} catch (InterruptedException e1) {
|
|
|
}
|
|
|
dto.setRetry(dto.getRetry() + 1);
|
|
|
- return aiMarkingDispose(dto, org, req);
|
|
|
+ return aiMarkingDispose(dto, req);
|
|
|
} else {
|
|
|
throw new StatusException("重试次数过多");
|
|
|
}
|