OmrGroupServiceImpl.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. package cn.com.qmth.scancentral.service.impl;
  2. import cn.com.qmth.scancentral.dao.OmrGroupDao;
  3. import cn.com.qmth.scancentral.entity.OmrGroupEntity;
  4. import cn.com.qmth.scancentral.entity.OmrTaskEntity;
  5. import cn.com.qmth.scancentral.enums.ConditionType;
  6. import cn.com.qmth.scancentral.enums.LockType;
  7. import cn.com.qmth.scancentral.enums.Stage;
  8. import cn.com.qmth.scancentral.enums.TaskStatus;
  9. import cn.com.qmth.scancentral.model.OmrCondition;
  10. import cn.com.qmth.scancentral.service.OmrGroupService;
  11. import cn.com.qmth.scancentral.service.OmrTaskService;
  12. import cn.com.qmth.scancentral.service.StudentPaperService;
  13. import cn.com.qmth.scancentral.util.BatchSetDataUtil;
  14. import cn.com.qmth.scancentral.vo.OmrConditionVo;
  15. import cn.com.qmth.scancentral.vo.OmrGroupVo;
  16. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  17. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  18. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  19. import com.qmth.boot.core.concurrent.service.ConcurrentService;
  20. import com.qmth.boot.core.exception.ParameterException;
  21. import com.qmth.boot.core.exception.ReentrantException;
  22. import com.qmth.boot.core.exception.StatusException;
  23. import org.apache.commons.collections4.CollectionUtils;
  24. import org.slf4j.Logger;
  25. import org.slf4j.LoggerFactory;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.stereotype.Service;
  28. import org.springframework.transaction.annotation.Transactional;
  29. import java.util.ArrayList;
  30. import java.util.HashSet;
  31. import java.util.List;
  32. import java.util.Set;
  33. @Service
  34. public class OmrGroupServiceImpl extends ServiceImpl<OmrGroupDao, OmrGroupEntity> implements OmrGroupService {
  35. protected static Logger log = LoggerFactory.getLogger(OmrGroupService.class);
  36. @Autowired
  37. private ConcurrentService concurrentService;
  38. @Autowired
  39. private OmrTaskService taskService;
  40. @Autowired
  41. private StudentPaperService studentPaperService;
  42. @Transactional
  43. @Override
  44. public void deleteById(Long id) {
  45. taskService.deleteByGroupId(id);
  46. this.removeById(id);
  47. }
  48. @Transactional
  49. @Override
  50. public void resetById(Long id) {
  51. OmrGroupEntity group = this.getById(id);
  52. if (group == null) {
  53. throw new ParameterException("分组不存在");
  54. }
  55. taskService.resetByGroup(group);
  56. }
  57. @Override
  58. public void buildTaskById(Long groupId) {
  59. OmrGroupEntity group = this.getById(groupId);
  60. long start = System.currentTimeMillis();
  61. List<Long> studentIds = studentPaperService.findStudentIdByExamId(group.getExamId());
  62. long end = System.currentTimeMillis();
  63. if (CollectionUtils.isEmpty(studentIds)) {
  64. log.info("OmrGroup[" + groupId + "] get studentIds finish | time cost(s):" + ((end - start) / 1000)
  65. + " | count:0");
  66. return;
  67. }
  68. log.info("OmrGroup[" + groupId + "] get studentIds finish | time cost(s):" + ((end - start) / 1000)
  69. + " | count:" + studentIds.size());
  70. new BatchSetDataUtil<Long>() {
  71. @Override
  72. protected void setData(List<Long> dataList) {
  73. buildTaskByStudent(group, dataList);
  74. }
  75. }.setDataForBatch(studentIds, 1000);
  76. }
  77. private void buildTaskByStudent(OmrGroupEntity group, List<Long> studentIds) {
  78. if (CollectionUtils.isEmpty(studentIds)) {
  79. return;
  80. }
  81. List<OmrTaskEntity> saveList = new ArrayList<OmrTaskEntity>();
  82. for (Long studentId : studentIds) {
  83. try {
  84. concurrentService.getLock(LockType.STUDENT + "-" + studentId).lock();
  85. List<OmrTaskEntity> task = taskService.buildTask(group, studentId);
  86. if (task != null && !task.isEmpty()) {
  87. saveList.addAll(task);
  88. }
  89. } finally {
  90. concurrentService.getLock(LockType.STUDENT + "-" + studentId).unlock();
  91. }
  92. }
  93. taskService.saveBatch(saveList);
  94. this.updateTotalCount(group.getId());
  95. }
  96. @Override
  97. public List<OmrGroupVo> listByExamId(Long examId) {
  98. QueryWrapper<OmrGroupEntity> wrapper = new QueryWrapper<>();
  99. LambdaQueryWrapper<OmrGroupEntity> lw = wrapper.lambda();
  100. lw.eq(OmrGroupEntity::getExamId, examId);
  101. List<OmrGroupEntity> groups = this.list(wrapper);
  102. List<OmrGroupVo> list = new ArrayList<OmrGroupVo>();
  103. for (OmrGroupEntity group : groups) {
  104. OmrGroupVo groupVo = new OmrGroupVo();
  105. groupVo.setId(group.getId());
  106. List<OmrConditionVo> conditions = new ArrayList<OmrConditionVo>();
  107. for (OmrCondition c : group.getConditions()) {
  108. conditions.add(new OmrConditionVo(c));
  109. }
  110. groupVo.setConditions(conditions);
  111. groupVo.setStage(group.getStage());
  112. groupVo.setFixed(group.getFixed());
  113. groupVo.setBuilding(
  114. !concurrentService.getSemaphore(LockType.OMR_GROUP_BUILD + "-" + group.getId()).isAvailable());
  115. groupVo.setDeleting(
  116. !concurrentService.getSemaphore(LockType.OMR_GROUP_DELETE + "-" + group.getId()).isAvailable());
  117. groupVo.setReseting(
  118. !concurrentService.getSemaphore(LockType.OMR_GROUP_RESET + "-" + group.getId()).isAvailable());
  119. groupVo.setTotalCount(group.getTotalCount());
  120. groupVo.setFinishCount(
  121. taskService.getCountByExamAndGroupAndStatus(examId, group.getId(), TaskStatus.PROCESSED));
  122. groupVo.setUnarbitrateCount(
  123. taskService.getCountByExamAndGroupAndStatus(examId, group.getId(), TaskStatus.WAIT_ARBITRATE));
  124. groupVo.setArbitratedCount(
  125. taskService.getCountByExamAndGroupAndStatus(examId, group.getId(), TaskStatus.ARBITRATED));
  126. groupVo.setUpdateTime(group.getUpdateTime());
  127. list.add(groupVo);
  128. }
  129. return list;
  130. }
  131. @Transactional
  132. @Override
  133. public void updateStage(Long id, Long userId) {
  134. OmrGroupEntity group = this.getById(id);
  135. if (group == null) {
  136. throw new ParameterException("分组不存在");
  137. }
  138. if (!Stage.FIRST.equals(group.getStage())) {
  139. throw new StatusException("分组不在第一阶段,无法切换");
  140. }
  141. if (group.getTotalCount() == 0) {
  142. throw new StatusException("分组下没有任务,无法切换");
  143. }
  144. Integer finishCount = taskService.getCountByExamAndGroupAndStatus(group.getExamId(), id, TaskStatus.PROCESSED,
  145. TaskStatus.ARBITRATED);
  146. if (group.getTotalCount() - finishCount != 0) {
  147. throw new StatusException("识别对照任务未完成,无法切换");
  148. }
  149. group.setStage(Stage.SECOND);
  150. group.setUpdaterId(userId);
  151. group.setUpdateTime(System.currentTimeMillis());
  152. this.saveOrUpdate(group);
  153. taskService.waitingByGroupToggle(id);
  154. }
  155. @Override
  156. public OmrGroupEntity save(Long id, Long examId, List<OmrCondition> conditions, Long userId) {
  157. if (examId == null) {
  158. throw new ParameterException("examId不能为空");
  159. }
  160. if (conditions == null || conditions.isEmpty()) {
  161. throw new ParameterException("识别对照条件不能为空");
  162. }
  163. for (OmrCondition omrCondition : conditions) {
  164. if (ConditionType.FILL_SUSPECT.equals(omrCondition.getCode())) {
  165. throw new ParameterException("识别对照条件不能重复");
  166. }
  167. if (ConditionType.QUESTION_SINGLE_BLANK.equals(omrCondition.getCode())
  168. || ConditionType.QUESTION_MULTI_BLANK.equals(omrCondition.getCode())
  169. || ConditionType.SELECTIVE_EXCEED.equals(omrCondition.getCode())
  170. || ConditionType.SELECTIVE_BLANK.equals(omrCondition.getCode())) {
  171. if (omrCondition.getValue() == null) {
  172. throw new ParameterException("参数不能为空");
  173. }
  174. if (omrCondition.getValue() < 0) {
  175. throw new ParameterException("参数不能小于0");
  176. }
  177. }
  178. }
  179. checkOmrCondition(id, examId, conditions);
  180. if (id != null) {
  181. OmrGroupEntity group = this.getById(id);
  182. if (group.getFixed()) {
  183. throw new ParameterException("默认分组不能修改");
  184. }
  185. if (group.getTotalCount() != null && group.getTotalCount() > 0) {
  186. throw new ParameterException("已生成任务的分组不能修改");
  187. }
  188. if (concurrentService.getLock(LockType.OMR_GROUP + "-" + id).tryLock()) {
  189. group.setConditions(conditions);
  190. group.setUpdaterId(userId);
  191. group.setUpdateTime(System.currentTimeMillis());
  192. this.saveOrUpdate(group);
  193. concurrentService.getLock(LockType.OMR_GROUP + "-" + id).unlock();
  194. return group;
  195. } else {
  196. throw new ReentrantException("该分组数据操作繁忙,请稍后重试");
  197. }
  198. } else {
  199. OmrGroupEntity group = new OmrGroupEntity();
  200. group.setExamId(examId);
  201. group.setConditions(conditions);
  202. group.setCreateTime(System.currentTimeMillis());
  203. group.setFixed(false);
  204. group.setStage(Stage.FIRST);
  205. group.setTotalCount(0);
  206. group.setCreatorId(userId);
  207. group.setCreateTime(System.currentTimeMillis());
  208. this.save(group);
  209. return group;
  210. }
  211. }
  212. @Override
  213. public List<OmrGroupEntity> findByExamIdAndFixed(Long examId, Boolean fixed) {
  214. QueryWrapper<OmrGroupEntity> wrapper = new QueryWrapper<>();
  215. LambdaQueryWrapper<OmrGroupEntity> lw = wrapper.lambda();
  216. lw.eq(OmrGroupEntity::getExamId, examId);
  217. lw.eq(OmrGroupEntity::getFixed, fixed);
  218. return baseMapper.selectList(wrapper);
  219. }
  220. private void checkOmrCondition(Long id, Long examId, List<OmrCondition> conditions) {
  221. List<OmrGroupEntity> list = findByExamId(examId);
  222. if (CollectionUtils.isEmpty(list)) {
  223. return;
  224. }
  225. Set<String> codes = new HashSet<>();
  226. for (OmrCondition oc : conditions) {
  227. codes.add(oc.getCode().name());
  228. }
  229. for (OmrGroupEntity g : list) {
  230. for (OmrCondition oc : g.getConditions()) {
  231. if (codes.contains(oc.getCode().name()) && (id == null || g.getId().longValue() != id.longValue())) {
  232. throw new ParameterException("已存在识别对照条件");
  233. }
  234. }
  235. }
  236. }
  237. private List<OmrGroupEntity> findByExamId(Long examId) {
  238. QueryWrapper<OmrGroupEntity> wrapper = new QueryWrapper<>();
  239. LambdaQueryWrapper<OmrGroupEntity> lw = wrapper.lambda();
  240. lw.eq(OmrGroupEntity::getExamId, examId);
  241. return baseMapper.selectList(wrapper);
  242. }
  243. @Transactional
  244. @Override
  245. public void updateTotalCount(Long id) {
  246. if (id == null) {
  247. throw new ParameterException("Id不能为空");
  248. }
  249. baseMapper.updateTotalCount(id);
  250. }
  251. @Override
  252. public void addFixOmrCondition(Long userId, Long examId) {
  253. OmrGroupEntity group = new OmrGroupEntity();
  254. group.setExamId(examId);
  255. List<OmrCondition> conditions = new ArrayList<OmrCondition>();
  256. OmrCondition omrCondition = new OmrCondition();
  257. omrCondition.setCode(ConditionType.FILL_SUSPECT);
  258. conditions.add(omrCondition);
  259. group.setConditions(conditions);
  260. group.setCreateTime(System.currentTimeMillis());
  261. group.setFixed(true);
  262. group.setStage(Stage.FIRST);
  263. group.setTotalCount(0);
  264. group.setCreatorId(userId);
  265. group.setCreateTime(System.currentTimeMillis());
  266. this.save(group);
  267. }
  268. @Transactional
  269. @Override
  270. public void updateTotalCountByExamId(Long examId) {
  271. List<OmrGroupEntity> list = this.findByExamId(examId);
  272. for (OmrGroupEntity omrGroupEntity : list) {
  273. this.updateTotalCount(omrGroupEntity.getId());
  274. }
  275. }
  276. }