|
@@ -1,46 +1,44 @@
|
|
package com.qmth.paper.library.business.service.impl;
|
|
package com.qmth.paper.library.business.service.impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
-import com.alibaba.fastjson.JSONObject;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
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.qmth.paper.library.business.bean.result.PaperLibraryImageResult;
|
|
import com.qmth.paper.library.business.bean.result.PaperLibraryResult;
|
|
import com.qmth.paper.library.business.bean.result.PaperLibraryResult;
|
|
-import com.qmth.paper.library.business.bean.result.PaperScanTaskResult;
|
|
|
|
import com.qmth.paper.library.business.bean.result.TaskStudentResult;
|
|
import com.qmth.paper.library.business.bean.result.TaskStudentResult;
|
|
|
|
+import com.qmth.paper.library.business.bean.vo.FilePathVo;
|
|
|
|
+import com.qmth.paper.library.business.bean.vo.RecognitionResultVo;
|
|
import com.qmth.paper.library.business.entity.PaperLibrary;
|
|
import com.qmth.paper.library.business.entity.PaperLibrary;
|
|
import com.qmth.paper.library.business.entity.PaperScanTask;
|
|
import com.qmth.paper.library.business.entity.PaperScanTask;
|
|
-import com.qmth.paper.library.business.entity.PaperScanTaskDetail;
|
|
|
|
import com.qmth.paper.library.business.mapper.PaperLibraryMapper;
|
|
import com.qmth.paper.library.business.mapper.PaperLibraryMapper;
|
|
import com.qmth.paper.library.business.service.*;
|
|
import com.qmth.paper.library.business.service.*;
|
|
|
|
+import com.qmth.paper.library.common.bean.dto.syssetting.SimpleObject;
|
|
|
|
+import com.qmth.paper.library.common.contant.SysSettingConstant;
|
|
import com.qmth.paper.library.common.contant.SystemConstant;
|
|
import com.qmth.paper.library.common.contant.SystemConstant;
|
|
-import com.qmth.paper.library.common.entity.SysUser;
|
|
|
|
|
|
+import com.qmth.paper.library.common.entity.BasicSchool;
|
|
|
|
+import com.qmth.paper.library.common.entity.ExamStudent;
|
|
import com.qmth.paper.library.common.enums.ExceptionResultEnum;
|
|
import com.qmth.paper.library.common.enums.ExceptionResultEnum;
|
|
import com.qmth.paper.library.common.enums.RecognitionTypeEnum;
|
|
import com.qmth.paper.library.common.enums.RecognitionTypeEnum;
|
|
import com.qmth.paper.library.common.enums.RoleTypeEnum;
|
|
import com.qmth.paper.library.common.enums.RoleTypeEnum;
|
|
import com.qmth.paper.library.common.enums.UploadFileEnum;
|
|
import com.qmth.paper.library.common.enums.UploadFileEnum;
|
|
-import com.qmth.paper.library.common.lock.LockService;
|
|
|
|
-import com.qmth.paper.library.common.lock.LockType;
|
|
|
|
-import com.qmth.paper.library.common.service.BasicStudentService;
|
|
|
|
|
|
+import com.qmth.paper.library.common.service.BasicSchoolService;
|
|
|
|
+import com.qmth.paper.library.common.service.CommonCacheService;
|
|
import com.qmth.paper.library.common.service.SysUserService;
|
|
import com.qmth.paper.library.common.service.SysUserService;
|
|
import com.qmth.paper.library.common.util.*;
|
|
import com.qmth.paper.library.common.util.*;
|
|
-import org.apache.commons.io.FileUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONArray;
|
|
-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 javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
-import java.awt.print.Paper;
|
|
|
|
import java.io.File;
|
|
import java.io.File;
|
|
-import java.io.FileNotFoundException;
|
|
|
|
-import java.io.IOException;
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.Set;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -52,426 +50,231 @@ import java.util.Set;
|
|
public class PaperLibraryServiceImpl extends ServiceImpl<PaperLibraryMapper, PaperLibrary> implements PaperLibraryService {
|
|
public class PaperLibraryServiceImpl extends ServiceImpl<PaperLibraryMapper, PaperLibrary> implements PaperLibraryService {
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
- PaperScanTaskService paperScanTaskService;
|
|
|
|
-
|
|
|
|
- @Resource
|
|
|
|
- PaperScanTaskDetailService paperScanTaskDetailService;
|
|
|
|
-
|
|
|
|
|
|
+ private PaperScanTaskService paperScanTaskService;
|
|
@Resource
|
|
@Resource
|
|
- PaperLibraryCommonService paperLibraryCommonService;
|
|
|
|
-
|
|
|
|
|
|
+ private BasicSchoolService basicSchoolService;
|
|
@Resource
|
|
@Resource
|
|
- BusinessCacheService businessCacheService;
|
|
|
|
-
|
|
|
|
|
|
+ private ExamStudentService examStudentService;
|
|
@Resource
|
|
@Resource
|
|
- SysUserService sysUserService;
|
|
|
|
-
|
|
|
|
|
|
+ private FileUploadService fileUploadService;
|
|
@Resource
|
|
@Resource
|
|
- OcrUtil ocrUtil;
|
|
|
|
-
|
|
|
|
|
|
+ private OcrUtil ocrUtil;
|
|
@Resource
|
|
@Resource
|
|
- LockService lockService;
|
|
|
|
-
|
|
|
|
|
|
+ private FileStoreUtil fileStoreUtil;
|
|
@Resource
|
|
@Resource
|
|
- FileStoreUtil fileStoreUtil;
|
|
|
|
|
|
+ private CommonCacheService commonCacheService;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public IPage<PaperScanTaskResult> pageUnbindData(Long semesterId, Long paperArchivesId, String courseCode, String scanTaskName, Integer pageNumber, Integer pageSize) {
|
|
|
|
- return paperScanTaskService.pageUnbindData(new Page<>(pageNumber, pageSize), semesterId, paperArchivesId, courseCode, scanTaskName);
|
|
|
|
|
|
+ public int countScanStudentCount(Long paperScanTaskId) {
|
|
|
|
+ return this.baseMapper.countScanStudentCount(paperScanTaskId);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public IPage<PaperLibraryResult> pageBindData(Long semesterId, Long paperArchivesId, String courseCode, String scanTaskName, Integer pageNumber, Integer pageSize) {
|
|
|
|
- return this.baseMapper.pageBindData(new Page<>(pageNumber, pageSize), semesterId, paperArchivesId, courseCode, scanTaskName);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public int countBindData(Long paperScanTaskId) {
|
|
|
|
- return this.baseMapper.countBindData(paperScanTaskId);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public IPage<PaperLibraryResult> pageAbnormalData(Long semesterId, Long paperArchivesId, String courseCode, String scanTaskName, Integer pageNumber, Integer pageSize) {
|
|
|
|
- Set<Long> listSubOrgIds = paperLibraryCommonService.listSubOrgIds(null);
|
|
|
|
- Long userId = Long.valueOf(ServletUtil.getRequestHeaderUserId().toString());
|
|
|
|
- boolean isMatch = sysUserService.checkRoleIsAppoint(RoleTypeEnum.DATA_CHECKER, userId);
|
|
|
|
- return this.baseMapper.pageAbnormalData(new Page<>(pageNumber, pageSize), semesterId, paperArchivesId, courseCode, scanTaskName, listSubOrgIds, isMatch, userId);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Transactional
|
|
|
|
- @Override
|
|
|
|
- public boolean bind(Long paperLibraryId, Long paperScanTaskId, Long studentId) {
|
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
|
- Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
|
|
|
|
-
|
|
|
|
- PaperLibrary paperLibrary = this.getById(paperLibraryId);
|
|
|
|
- if (paperLibrary == null) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("绑定对象有误,图片已删除,请刷新数据再试");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- PaperScanTaskDetail paperScanTaskDetail = paperScanTaskDetailService.getByPaperScanTaskIdAndStudentId(paperScanTaskId, studentId);
|
|
|
|
- if (paperScanTaskDetail == null) {
|
|
|
|
- paperScanTaskDetail = new PaperScanTaskDetail();
|
|
|
|
- paperScanTaskDetail.insertInfo(sysUser.getId());
|
|
|
|
- paperScanTaskDetail.setUpdateTime(System.currentTimeMillis());
|
|
|
|
- paperScanTaskDetail.setSchoolId(schoolId);
|
|
|
|
- paperScanTaskDetail.setPaperScanTaskId(paperScanTaskId);
|
|
|
|
- paperScanTaskDetail.setStudentId(studentId);
|
|
|
|
- paperScanTaskDetail.setBindCount(1);
|
|
|
|
- paperScanTaskDetailService.save(paperScanTaskDetail);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Boolean abnormal = paperLibrary.getAbnormal();
|
|
|
|
- UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(PaperLibrary::getPaperScanTaskDetailId, paperScanTaskDetail.getId())
|
|
|
|
- .set(PaperLibrary::getAbnormal, false)
|
|
|
|
- .set(PaperLibrary::getUpdateTime, System.currentTimeMillis())
|
|
|
|
- .eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
-
|
|
|
|
- // 更新已绑定状态
|
|
|
|
- if (paperLibrary.getPaperScanTaskDetailId() != null) {
|
|
|
|
- PaperScanTaskDetail oldPaperScanTaskDetail = paperScanTaskDetailService.getById(paperLibrary.getPaperScanTaskDetailId());
|
|
|
|
- // 查询是否有绑定试卷
|
|
|
|
- int count = this.baseMapper.countByPaperScanTaskDetailId(paperLibrary.getPaperScanTaskDetailId());
|
|
|
|
- oldPaperScanTaskDetail.setBindCount(count);
|
|
|
|
- paperScanTaskDetailService.updateById(oldPaperScanTaskDetail);
|
|
|
|
|
|
+ public PaperLibraryResult listStudentPicture(Long paperScanTaskId, Long studentId) {
|
|
|
|
+ PaperLibraryResult paperLibraryResult = new PaperLibraryResult();
|
|
|
|
+ ExamStudent examStudent = examStudentService.getById(studentId);
|
|
|
|
+ if (examStudent == null) {
|
|
|
|
+ paperLibraryResult.setStudentName(examStudent.getStudentName());
|
|
|
|
+ paperLibraryResult.setStudentCode(examStudent.getStudentCode());
|
|
|
|
+ paperLibraryResult.setCourseCode(examStudent.getCourseCode());
|
|
|
|
+ paperLibraryResult.setCourseName(examStudent.getCourseName());
|
|
|
|
+ paperLibraryResult.setCollegeName(examStudent.getCollegeName());
|
|
|
|
+ paperLibraryResult.setMajorName(examStudent.getMajorName());
|
|
|
|
+ paperLibraryResult.setClassName(examStudent.getClassName());
|
|
|
|
+ paperLibraryResult.setTeacher(examStudent.getTeacher());
|
|
|
|
+ paperLibraryResult.setTeachClass(examStudent.getTeachClass());
|
|
|
|
+ paperLibraryResult.setBindCount(examStudent.getBindCount());
|
|
|
|
+ paperLibraryResult.setScore(examStudent.getScore());
|
|
}
|
|
}
|
|
- int count = this.baseMapper.countByPaperScanTaskDetailId(paperScanTaskDetail.getId());
|
|
|
|
- paperScanTaskDetail.setUpdateTime(System.currentTimeMillis());
|
|
|
|
- paperScanTaskDetail.setBindCount(count);
|
|
|
|
- paperScanTaskDetailService.updateById(paperScanTaskDetail);
|
|
|
|
-
|
|
|
|
- // 任务下所有任务绑定完,更新状态
|
|
|
|
- PaperScanTask paperScanTask = paperScanTaskService.getById(paperScanTaskId);
|
|
|
|
- int studentCount = paperScanTaskDetailService.countStudent(paperScanTaskId);
|
|
|
|
- int bindCount = this.baseMapper.countBindData(paperLibrary.getPaperScanTaskId());
|
|
|
|
- // 总扫描数
|
|
|
|
- int scanCount = paperScanTask.getScanCount();
|
|
|
|
- Double progress = scanCount == 0 ? 0D :
|
|
|
|
- new BigDecimal(bindCount * 100).divide(new BigDecimal(scanCount), BigDecimal.ROUND_DOWN, 2).doubleValue();
|
|
|
|
- UpdateWrapper<PaperScanTask> taskUpdateWrapper = new UpdateWrapper<>();
|
|
|
|
- taskUpdateWrapper.lambda().set(PaperScanTask::getStudentCount, studentCount)
|
|
|
|
- .set(PaperScanTask::getBindCount, bindCount)
|
|
|
|
- .set(PaperScanTask::getProgress, progress)
|
|
|
|
- .set(PaperScanTask::getAbnormalCount, abnormal ? paperScanTask.getAbnormalCount() - 1 : paperScanTask.getAbnormalCount())
|
|
|
|
- .eq(PaperScanTask::getId, paperLibrary.getPaperScanTaskId());
|
|
|
|
- paperScanTaskService.update(taskUpdateWrapper);
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
- public List<PaperLibraryResult> listStudentPicture(Long paperScanTaskDetailId) {
|
|
|
|
- Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
|
|
|
|
QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
- queryWrapper.lambda().eq(PaperLibrary::getSchoolId, schoolId)
|
|
|
|
- .eq(PaperLibrary::getPaperScanTaskDetailId, paperScanTaskDetailId)
|
|
|
|
|
|
+ queryWrapper.lambda().eq(PaperLibrary::getPaperScanTaskId, paperScanTaskId)
|
|
|
|
+ .eq(PaperLibrary::getStudentId, studentId)
|
|
.orderByAsc(PaperLibrary::getSequence);
|
|
.orderByAsc(PaperLibrary::getSequence);
|
|
List<PaperLibrary> paperLibraryList = this.list(queryWrapper);
|
|
List<PaperLibrary> paperLibraryList = this.list(queryWrapper);
|
|
- List<PaperLibraryResult> paperLibraryResultList = new ArrayList<>();
|
|
|
|
|
|
+
|
|
|
|
+ List<PaperLibraryImageResult> fileUrlList = new ArrayList<>();
|
|
for (PaperLibrary paperLibrary : paperLibraryList) {
|
|
for (PaperLibrary paperLibrary : paperLibraryList) {
|
|
- PaperLibraryResult paperLibraryResult = new PaperLibraryResult();
|
|
|
|
- BeanUtils.copyProperties(paperLibrary, paperLibraryResult);
|
|
|
|
- String fileUrl = paperLibrary.getPath();
|
|
|
|
- if (StringUtils.isBlank(fileUrl)) {
|
|
|
|
|
|
+ if (StringUtils.isBlank(paperLibrary.getPath())) {
|
|
throw ExceptionResultEnum.ERROR.exception("未找到图片路径");
|
|
throw ExceptionResultEnum.ERROR.exception("未找到图片路径");
|
|
}
|
|
}
|
|
- List<JSONObject> objectList = JSON.parseArray(fileUrl, JSONObject.class);
|
|
|
|
|
|
+ List<FilePathVo> objectList = JSON.parseArray(paperLibrary.getPath(), FilePathVo.class);
|
|
|
|
+ PaperLibraryImageResult paperLibraryImageResult = new PaperLibraryImageResult();
|
|
|
|
+ paperLibraryImageResult.setPaperLibraryId(paperLibrary.getId());
|
|
List<String> fileUrls = new ArrayList<>();
|
|
List<String> fileUrls = new ArrayList<>();
|
|
- for (JSONObject jsonObject : objectList) {
|
|
|
|
- fileUrls.add(paperLibraryCommonService.preViewPath(jsonObject.getString(SystemConstant.PATH), jsonObject.getString(SystemConstant.UPLOAD_TYPE), jsonObject.getString(SystemConstant.TYPE), false));
|
|
|
|
- }
|
|
|
|
- PaperScanTaskResult paperScanTaskResult = paperScanTaskService.getByPaperScanTaskId(paperLibrary.getPaperScanTaskId());
|
|
|
|
- if (paperScanTaskResult != null) {
|
|
|
|
- paperLibraryResult.setSemesterName(paperScanTaskResult.getSemesterName());
|
|
|
|
- paperLibraryResult.setPaperArchivesName(paperScanTaskResult.getArchivesName());
|
|
|
|
- paperLibraryResult.setPaperScanTaskName(paperScanTaskResult.getScanTaskName());
|
|
|
|
- paperLibraryResult.setCourseName(paperScanTaskResult.getCourseName());
|
|
|
|
-// paperLibraryResult.setTeacherName(paperScanTaskResult.getTeacherName());
|
|
|
|
-// paperLibraryResult.setTeachClazzName(paperScanTaskResult.getTeachClazzName());
|
|
|
|
|
|
+ for (FilePathVo filePathVo : objectList) {
|
|
|
|
+ fileUrls.add(fileUploadService.filePreview(filePathVo));
|
|
}
|
|
}
|
|
- paperLibraryResult.setFileUrls(fileUrls);
|
|
|
|
- paperLibraryResultList.add(paperLibraryResult);
|
|
|
|
|
|
+ paperLibraryImageResult.setFileUrls(fileUrls);
|
|
|
|
+ fileUrlList.add(paperLibraryImageResult);
|
|
}
|
|
}
|
|
- return paperLibraryResultList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<PaperLibraryResult> toAbnormalPaper(Long paperLibraryId) {
|
|
|
|
- Long userId = Long.valueOf(ServletUtil.getRequestHeaderUserId().toString());
|
|
|
|
- Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
|
|
|
|
-
|
|
|
|
- List<PaperLibraryResult> paperLibraryResultList = new ArrayList<>();
|
|
|
|
- PaperLibrary paperLibrary = this.getById(paperLibraryId);
|
|
|
|
- PaperLibraryResult paperLibraryResult = new PaperLibraryResult();
|
|
|
|
- BeanUtils.copyProperties(paperLibrary, paperLibraryResult);
|
|
|
|
- String fileUrl = paperLibrary.getPath();
|
|
|
|
- if (StringUtils.isBlank(fileUrl)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("未找到图片路径");
|
|
|
|
- }
|
|
|
|
- List<JSONObject> objectList = JSON.parseArray(fileUrl, JSONObject.class);
|
|
|
|
- List<String> fileUrls = new ArrayList<>();
|
|
|
|
- for (JSONObject jsonObject : objectList) {
|
|
|
|
- fileUrls.add(paperLibraryCommonService.preViewPath(jsonObject.getString(SystemConstant.PATH), jsonObject.getString(SystemConstant.UPLOAD_TYPE), jsonObject.getString(SystemConstant.TYPE), false));
|
|
|
|
- }
|
|
|
|
- PaperScanTaskResult paperScanTaskResult = paperScanTaskService.getByPaperScanTaskId(paperLibrary.getPaperScanTaskId());
|
|
|
|
- if (paperScanTaskResult != null) {
|
|
|
|
- paperLibraryResult.setSemesterName(paperScanTaskResult.getSemesterName());
|
|
|
|
- paperLibraryResult.setPaperArchivesName(paperScanTaskResult.getArchivesName());
|
|
|
|
- paperLibraryResult.setPaperScanTaskName(paperScanTaskResult.getScanTaskName());
|
|
|
|
- paperLibraryResult.setCourseName(paperScanTaskResult.getCourseName());
|
|
|
|
-// paperLibraryResult.setTeacherName(paperScanTaskResult.getTeacherName());
|
|
|
|
-// paperLibraryResult.setTeachClazzName(paperScanTaskResult.getTeachClazzName());
|
|
|
|
- }
|
|
|
|
- paperLibraryResult.setFileUrls(fileUrls);
|
|
|
|
- paperLibraryResultList.add(paperLibraryResult);
|
|
|
|
- return paperLibraryResultList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<PaperLibraryResult> toBindPaper(Long paperScanTaskId) {
|
|
|
|
- Long userId = Long.valueOf(ServletUtil.getRequestHeaderUserId().toString());
|
|
|
|
-
|
|
|
|
- // 查询下一个待绑定任务
|
|
|
|
- List<PaperLibrary> waitPaperLibraryList = this.baseMapper.selectBatchData(paperScanTaskId, userId);
|
|
|
|
- if (waitPaperLibraryList.isEmpty()) {
|
|
|
|
- waitPaperLibraryList = createBindData(userId, paperScanTaskId);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- List<PaperLibraryResult> paperLibraryResultList = new ArrayList<>();
|
|
|
|
- if (!waitPaperLibraryList.isEmpty()) {
|
|
|
|
- for (PaperLibrary paperLibrary : waitPaperLibraryList) {
|
|
|
|
- PaperLibraryResult paperLibraryResult = new PaperLibraryResult();
|
|
|
|
- BeanUtils.copyProperties(paperLibrary, paperLibraryResult);
|
|
|
|
- String fileUrl = paperLibrary.getPath();
|
|
|
|
- if (StringUtils.isBlank(fileUrl)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("未找到图片路径");
|
|
|
|
- }
|
|
|
|
- List<JSONObject> objectList = JSON.parseArray(fileUrl, JSONObject.class);
|
|
|
|
- List<String> fileUrls = new ArrayList<>();
|
|
|
|
- for (JSONObject jsonObject : objectList) {
|
|
|
|
- fileUrls.add(paperLibraryCommonService.preViewPath(jsonObject.getString(SystemConstant.PATH), jsonObject.getString(SystemConstant.UPLOAD_TYPE), jsonObject.getString(SystemConstant.TYPE), false));
|
|
|
|
- }
|
|
|
|
- PaperScanTaskResult paperScanTaskResult = paperScanTaskService.getByPaperScanTaskId(paperLibrary.getPaperScanTaskId());
|
|
|
|
- if (paperScanTaskResult != null) {
|
|
|
|
- paperLibraryResult.setSemesterName(paperScanTaskResult.getSemesterName());
|
|
|
|
- paperLibraryResult.setPaperArchivesName(paperScanTaskResult.getArchivesName());
|
|
|
|
- paperLibraryResult.setPaperScanTaskName(paperScanTaskResult.getScanTaskName());
|
|
|
|
- paperLibraryResult.setCourseName(paperScanTaskResult.getCourseName());
|
|
|
|
- }
|
|
|
|
- paperLibraryResult.setFileUrls(fileUrls);
|
|
|
|
- paperLibraryResultList.add(paperLibraryResult);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return paperLibraryResultList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public IPage<TaskStudentResult> listByStudentCode(String studentCode, Integer pageNumber, Integer pageSize) {
|
|
|
|
- if (StringUtils.isBlank(studentCode)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("请输入考号");
|
|
|
|
- }
|
|
|
|
- Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
|
|
|
|
- return this.baseMapper.listByStudentCode(new Page<>(pageNumber, pageSize), schoolId, studentCode);
|
|
|
|
|
|
+ paperLibraryResult.setFileUrls(fileUrlList);
|
|
|
|
+ return paperLibraryResult;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public int countScanCount(Long paperScanTaskId) {
|
|
public int countScanCount(Long paperScanTaskId) {
|
|
- Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
|
|
|
|
QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
- queryWrapper.lambda().eq(PaperLibrary::getSchoolId, schoolId)
|
|
|
|
- .eq(PaperLibrary::getPaperScanTaskId, paperScanTaskId);
|
|
|
|
|
|
+ queryWrapper.lambda().eq(PaperLibrary::getPaperScanTaskId, paperScanTaskId);
|
|
return this.count(queryWrapper);
|
|
return this.count(queryWrapper);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public IPage<TaskStudentResult> pageStudent(Long paperScanTaskId, String param, Integer pageNumber, Integer pageSize) {
|
|
|
|
- Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
|
|
|
|
|
|
+ public IPage<TaskStudentResult> pageStudent(Long examId, String courseCode, String studentCode, Integer pageNumber, Integer pageSize) {
|
|
Page<TaskStudentResult> ipage = new Page<>(pageNumber, pageSize);
|
|
Page<TaskStudentResult> ipage = new Page<>(pageNumber, pageSize);
|
|
- IPage<TaskStudentResult> taskStudentResultIPage = this.baseMapper.listByStudentCode(ipage, schoolId, param);
|
|
|
|
- for (TaskStudentResult studentResult : taskStudentResultIPage.getRecords()) {
|
|
|
|
- PaperScanTaskDetail paperScanTaskDetail = paperScanTaskDetailService.getByPaperScanTaskIdAndStudentId(paperScanTaskId, Long.valueOf(studentResult.getStudentId()));
|
|
|
|
- studentResult.setBindCount(paperScanTaskDetail == null ? 0 : paperScanTaskDetail.getBindCount());
|
|
|
|
- }
|
|
|
|
- return taskStudentResultIPage;
|
|
|
|
|
|
+ return this.baseMapper.listByStudentCode(ipage, examId, courseCode, studentCode);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public List<String> recognition(Long paperLibraryId, Integer index, Integer x, Integer y, Integer width, Integer height, Integer rotate, RecognitionTypeEnum type) {
|
|
|
|
- QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
|
|
- queryWrapper.lambda().eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
- PaperLibrary paperLibrary = this.getOne(queryWrapper);
|
|
|
|
- List<JSONObject> objectList = JSON.parseArray(paperLibrary.getPath(), JSONObject.class);
|
|
|
|
- JSONObject jsonObject = objectList.get(index);
|
|
|
|
-
|
|
|
|
- String rootPath = fileStoreUtil.buildPath(UploadFileEnum.DOWNLOAD, true);
|
|
|
|
- String cutRootPath = fileStoreUtil.buildPath(UploadFileEnum.CUT, true);
|
|
|
|
- File file;
|
|
|
|
- try {
|
|
|
|
- file = paperLibraryCommonService.downloadFile(rootPath, jsonObject.getString(SystemConstant.PATH), jsonObject.getString(SystemConstant.UPLOAD_TYPE), jsonObject.getString(SystemConstant.TYPE));
|
|
|
|
- } catch (FileNotFoundException e) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("下载图片失败:" + e.getMessage());
|
|
|
|
- }
|
|
|
|
- // 裁剪
|
|
|
|
- File outFile = new File(cutRootPath, "sub" + file.getName());
|
|
|
|
|
|
+ public RecognitionResultVo recognition(PaperScanTask paperScanTask, String studentCode, MultipartFile file, Integer x, Integer y, Integer width, Integer height, Integer rotate) {
|
|
|
|
+ RecognitionResultVo recognitionResultVo = new RecognitionResultVo();
|
|
|
|
+ BasicSchool basicSchool = basicSchoolService.getById(paperScanTask.getSchoolId());
|
|
|
|
+ String courseNameCode = String.format("%s(%s)", paperScanTask.getCourseName(), paperScanTask.getCourseCode());
|
|
|
|
+ String cutRootPath = fileStoreUtil.buildPath(UploadFileEnum.CUT, true, basicSchool.getCode(), courseNameCode);
|
|
|
|
+ // 裁剪识别区图片
|
|
|
|
+ File outFile = new File(cutRootPath, "bar-" + file.getName());
|
|
if (!outFile.exists()) {
|
|
if (!outFile.exists()) {
|
|
outFile.getParentFile().mkdirs();
|
|
outFile.getParentFile().mkdirs();
|
|
}
|
|
}
|
|
- File subFile = ImageUtil.subImg(file, x, y, width, height, outFile);
|
|
|
|
|
|
+ File subFile = ImageUtil.subImg((File) file, x, y, width, height, outFile);
|
|
if (subFile == null) {
|
|
if (subFile == null) {
|
|
- throw ExceptionResultEnum.ERROR.exception("识别区域图片生成失败");
|
|
|
|
|
|
+ return recognitionResultVo;
|
|
}
|
|
}
|
|
-
|
|
|
|
// 旋转
|
|
// 旋转
|
|
File rotateOutFile = new File(cutRootPath, "rotate" + file.getName());
|
|
File rotateOutFile = new File(cutRootPath, "rotate" + file.getName());
|
|
File rotateFile = ImageUtil.rotate(subFile, rotate, rotateOutFile);
|
|
File rotateFile = ImageUtil.rotate(subFile, rotate, rotateOutFile);
|
|
|
|
|
|
List<String> stringList = new ArrayList<>();
|
|
List<String> stringList = new ArrayList<>();
|
|
|
|
+ String wordsResult = null;
|
|
|
|
+ String result = studentCode;
|
|
try {
|
|
try {
|
|
- if (RecognitionTypeEnum.OCR.equals(type)) {
|
|
|
|
- org.json.JSONObject callHandwriting;
|
|
|
|
- if (rotateFile.exists()) {
|
|
|
|
- callHandwriting = ocrUtil.callHandwriting(rotateFile.getPath());
|
|
|
|
- } else {
|
|
|
|
- callHandwriting = ocrUtil.callHandwriting(subFile.getPath());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 未联网提示
|
|
|
|
- if (!callHandwriting.has(SystemConstant.OCR_WORDS_RESULT)) {
|
|
|
|
- // ocr错误提示
|
|
|
|
- if (callHandwriting.has(SystemConstant.OCR_ERROR_MSG)) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception(callHandwriting.getString(SystemConstant.OCR_ERROR_MSG));
|
|
|
|
|
|
+ if (StringUtils.isBlank(studentCode)) {
|
|
|
|
+ Map<String, SimpleObject> sysSetting = commonCacheService.getSysSetting(basicSchool.getId());
|
|
|
|
+ String type = sysSetting.get(SysSettingConstant.RECOGNITION_TYPE).getValue();
|
|
|
|
+ if (RecognitionTypeEnum.OCR.equals(type)) {
|
|
|
|
+ org.json.JSONObject callHandwriting;
|
|
|
|
+ if (rotateFile.exists()) {
|
|
|
|
+ callHandwriting = ocrUtil.callHandwriting(rotateFile.getPath());
|
|
} else {
|
|
} else {
|
|
- throw ExceptionResultEnum.ERROR.exception("OCR识别异常,请检查网络是否连接或者关闭OCR识别");
|
|
|
|
|
|
+ callHandwriting = ocrUtil.callHandwriting(subFile.getPath());
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- JSONArray jsonArray = callHandwriting.getJSONArray(SystemConstant.OCR_WORDS_RESULT);
|
|
|
|
- if (jsonArray.length() == 0) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("未正确识别出内容");
|
|
|
|
- } else {
|
|
|
|
- jsonArray.forEach(m -> {
|
|
|
|
- org.json.JSONObject object = (org.json.JSONObject) m;
|
|
|
|
- if (object.has(SystemConstant.OCR_WORDS)) {
|
|
|
|
- stringList.add(object.getString(SystemConstant.OCR_WORDS));
|
|
|
|
|
|
+ // 未联网提示
|
|
|
|
+ if (!callHandwriting.has(SystemConstant.OCR_WORDS_RESULT)) {
|
|
|
|
+ // ocr错误提示
|
|
|
|
+ if (callHandwriting.has(SystemConstant.OCR_ERROR_MSG)) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(callHandwriting.getString(SystemConstant.OCR_ERROR_MSG));
|
|
|
|
+ } else {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("OCR识别异常,请检查网络是否连接或者关闭OCR识别");
|
|
}
|
|
}
|
|
- });
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- // 保存识别数据
|
|
|
|
- UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(PaperLibrary::getWordsResult, jsonArray.toString())
|
|
|
|
- .set(PaperLibrary::getOcrResult, String.join(",", stringList))
|
|
|
|
- .eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
- }
|
|
|
|
- } else if (RecognitionTypeEnum.BAR_CODE.equals(type)) {
|
|
|
|
- String result;
|
|
|
|
- if (rotateFile.exists()) {
|
|
|
|
- result = BarCodeUtils.decode(rotateFile);
|
|
|
|
|
|
+ JSONArray jsonArray = callHandwriting.getJSONArray(SystemConstant.OCR_WORDS_RESULT);
|
|
|
|
+ if (jsonArray.length() == 0) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("未正确识别出内容");
|
|
|
|
+ } else {
|
|
|
|
+ jsonArray.forEach(m -> {
|
|
|
|
+ org.json.JSONObject object = (org.json.JSONObject) m;
|
|
|
|
+ if (object.has(SystemConstant.OCR_WORDS)) {
|
|
|
|
+ stringList.add(object.getString(SystemConstant.OCR_WORDS));
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ wordsResult = String.join(",", stringList);
|
|
|
|
+
|
|
|
|
+ //自动绑定,默认返回第一条
|
|
|
|
+ result = stringList.get(0);
|
|
|
|
+ }
|
|
|
|
+ } else if (RecognitionTypeEnum.BAR_CODE.equals(type)) {
|
|
|
|
+ if (rotateFile.exists()) {
|
|
|
|
+ result = BarCodeUtils.decode(rotateFile);
|
|
|
|
+ } else {
|
|
|
|
+ result = BarCodeUtils.decode(subFile);
|
|
|
|
+ }
|
|
|
|
+ wordsResult = result;
|
|
} else {
|
|
} else {
|
|
- result = BarCodeUtils.decode(subFile);
|
|
|
|
- }
|
|
|
|
- if (StringUtils.isNotBlank(result)) {
|
|
|
|
- stringList.add(result);
|
|
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("不支持的识别方式");
|
|
}
|
|
}
|
|
- // 保存识别数据
|
|
|
|
- UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(PaperLibrary::getWordsResult, result)
|
|
|
|
- .eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
- this.update(updateWrapper);
|
|
|
|
- } else {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("不支持的识别方式");
|
|
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
|
+ wordsResult = e.getMessage();
|
|
throw ExceptionResultEnum.ERROR.exception("识别异常:" + e.getMessage());
|
|
throw ExceptionResultEnum.ERROR.exception("识别异常:" + e.getMessage());
|
|
} finally {
|
|
} finally {
|
|
- try {
|
|
|
|
- FileUtils.forceDelete(file);
|
|
|
|
-// FileUtils.forceDelete(subFile);
|
|
|
|
-// FileUtils.forceDelete(rotateFile);
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
+ recognitionResultVo.setBindResult(result);
|
|
|
|
+ recognitionResultVo.setRecognizeResult(wordsResult);
|
|
|
|
+
|
|
|
|
+ if (outFile.exists()) {
|
|
|
|
+ outFile.delete();
|
|
|
|
+ }
|
|
|
|
+ if (subFile.exists()) {
|
|
|
|
+ subFile.delete();
|
|
|
|
+ }
|
|
|
|
+ if (rotateOutFile.exists()) {
|
|
|
|
+ rotateOutFile.delete();
|
|
|
|
+ }
|
|
|
|
+ if (rotateFile.exists()) {
|
|
|
|
+ rotateFile.delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return stringList;
|
|
|
|
|
|
+ return recognitionResultVo;
|
|
}
|
|
}
|
|
|
|
|
|
- @Transactional
|
|
|
|
@Override
|
|
@Override
|
|
- public Boolean abnormal(Long paperLibraryId) {
|
|
|
|
- PaperLibrary paperLibrary = this.getById(paperLibraryId);
|
|
|
|
- if (paperLibrary == null) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("绑定对象有误,图片已删除,请刷新数据再试");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Long paperScanTaskId = paperLibrary.getPaperScanTaskId();
|
|
|
|
- PaperScanTask paperScanTask = paperScanTaskService.getById(paperScanTaskId);
|
|
|
|
- UpdateWrapper<PaperScanTask> taskUpdateWrapper = new UpdateWrapper<>();
|
|
|
|
- taskUpdateWrapper.lambda().set(PaperScanTask::getAbnormalCount, paperScanTask.getAbnormalCount() + 1)
|
|
|
|
- .eq(PaperScanTask::getId, paperScanTaskId);
|
|
|
|
- paperScanTaskService.update(taskUpdateWrapper);
|
|
|
|
-
|
|
|
|
- UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(PaperLibrary::getAbnormal, true).eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
- return this.update(updateWrapper);
|
|
|
|
|
|
+ public List<Map> listMaxSequenceByPaperScanTaskId(Long paperScanTaskId) {
|
|
|
|
+ return this.baseMapper.listMaxSequenceByPaperScanTaskId(paperScanTaskId);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public Integer maxSequence(Long paperScanTaskId) {
|
|
|
|
- return this.baseMapper.maxSequence(paperScanTaskId);
|
|
|
|
|
|
+ public void removeByPaperScanTaskId(Long paperScanTaskId) {
|
|
|
|
+ QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(PaperLibrary::getPaperScanTaskId, paperScanTaskId);
|
|
|
|
+ this.remove(queryWrapper);
|
|
}
|
|
}
|
|
|
|
|
|
- private List<PaperLibrary> createBindData(Long userId, Long paperScanTaskId) {
|
|
|
|
- try {
|
|
|
|
- lockService.waitlock(LockType.BIND_PAPER_TASK, paperScanTaskId);
|
|
|
|
- PaperScanTask paperScanTask = paperScanTaskService.getById(paperScanTaskId);
|
|
|
|
- if (paperScanTask.getCheckUserId() != null && !userId.equals(paperScanTask.getCheckUserId())) {
|
|
|
|
- throw ExceptionResultEnum.ERROR.exception("该任务已被其它人绑定,请刷新数据");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- UpdateWrapper<PaperScanTask> updateWrapper = new UpdateWrapper<>();
|
|
|
|
- updateWrapper.lambda().set(PaperScanTask::getCheckUserId, userId)
|
|
|
|
- .eq(PaperScanTask::getId, paperScanTaskId);
|
|
|
|
- paperScanTaskService.update(updateWrapper);
|
|
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public boolean rebind(Long paperLibraryId, Long studentId) {
|
|
|
|
+ PaperLibrary paperLibrary = this.getById(paperLibraryId);
|
|
|
|
+ if (paperLibrary == null) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("该图片数据不存在");
|
|
|
|
+ }
|
|
|
|
+ // 自己绑定自己,直接返回
|
|
|
|
+ if (paperLibrary.getStudentId() != null && paperLibrary.getStudentId().equals(studentId)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
|
|
- List<PaperLibrary> paperLibraryList = this.baseMapper.listUnBindData(paperScanTaskId);
|
|
|
|
- if (!paperLibraryList.isEmpty()) {
|
|
|
|
- paperLibraryList.forEach(m -> {
|
|
|
|
- if (m.getPaperScanTaskDetailId() == null) {
|
|
|
|
- m.setUserId(userId);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- this.updateBatchById(paperLibraryList);
|
|
|
|
- }
|
|
|
|
- return paperLibraryList;
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- } finally {
|
|
|
|
- lockService.unlock(LockType.BIND_PAPER_TASK, paperScanTaskId);
|
|
|
|
|
|
+ // 更新绑定考生ID
|
|
|
|
+ UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
|
|
|
|
+ updateWrapper.lambda().set(PaperLibrary::getStudentId, studentId)
|
|
|
|
+ .eq(PaperLibrary::getId, paperLibraryId);
|
|
|
|
+ this.update(updateWrapper);
|
|
|
|
+ // 更新考生绑定数量
|
|
|
|
+ if (paperLibrary.getStudentId() != null) {
|
|
|
|
+ examStudentService.updateBindCount(paperLibrary.getStudentId());
|
|
}
|
|
}
|
|
- return new ArrayList<>();
|
|
|
|
|
|
+ examStudentService.updateBindCount(studentId);
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public String getPaperArchivesCode(Long schoolId) {
|
|
|
|
- return SystemConstant.PAPER_ARCHIVES_CODE_PREFIX + String.format("%05d", businessCacheService.getPaperArchivesCodeSequence(schoolId));
|
|
|
|
|
|
+ public int countByStudentId(Long studentId) {
|
|
|
|
+ QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(PaperLibrary::getStudentId, studentId);
|
|
|
|
+ return this.count(queryWrapper);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public String getScanTaskCode(Long schoolId) {
|
|
|
|
- return SystemConstant.SCAN_TASK_CODE_PREFIX + String.format("%07d", businessCacheService.getScanTaskCodeSequence(schoolId));
|
|
|
|
- }
|
|
|
|
|
|
+ public int countByExamId(Long examId) {
|
|
|
|
+ List<PaperScanTask> paperScanTaskList = paperScanTaskService.listByExamId(examId);
|
|
|
|
+ for (PaperScanTask paperScanTask : paperScanTaskList) {
|
|
|
|
+ QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ queryWrapper.lambda().eq(PaperLibrary::getPaperScanTaskId, paperScanTask.getId());
|
|
|
|
+ int count = this.count(queryWrapper);
|
|
|
|
+ if (count > 0) {
|
|
|
|
+ return count;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
|
|
- @Override
|
|
|
|
- public List<PaperLibrary> listHistory() {
|
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
|
- QueryWrapper<PaperLibrary> queryWrapper = new QueryWrapper<>();
|
|
|
|
- queryWrapper.lambda().eq(PaperLibrary::getSchoolId, sysUser.getSchoolId())
|
|
|
|
- .eq(PaperLibrary::getUserId, sysUser.getId())
|
|
|
|
- .orderByDesc(PaperLibrary::getUpdateTime)
|
|
|
|
- .last("limit 5");
|
|
|
|
- return this.list(queryWrapper);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|