石墨消解仪后端服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
6.7 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. package com.iflytop.gd.app.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  4. import com.iflytop.gd.app.core.CraftsContext;
  5. import com.iflytop.gd.app.mapper.CraftsMapper;
  6. import com.iflytop.gd.app.model.entity.Crafts;
  7. import com.iflytop.gd.app.model.entity.Ores;
  8. import com.iflytop.gd.app.model.vo.CraftStatusVO;
  9. import com.iflytop.gd.app.model.vo.SetCraftsVO;
  10. import com.iflytop.gd.common.enums.automaton.CraftEvents;
  11. import com.iflytop.gd.common.enums.automaton.CraftStates;
  12. import com.iflytop.gd.common.exception.AppException;
  13. import com.iflytop.gd.common.result.ResultCode;
  14. import jakarta.annotation.PostConstruct;
  15. import lombok.RequiredArgsConstructor;
  16. import org.springframework.statemachine.config.StateMachineFactory;
  17. import org.springframework.stereotype.Service;
  18. import java.util.Arrays;
  19. import java.util.List;
  20. import java.util.concurrent.ConcurrentHashMap;
  21. import java.util.concurrent.ExecutorService;
  22. import java.util.concurrent.Executors;
  23. import java.util.concurrent.Future;
  24. import java.util.stream.Collectors;
  25. /**
  26. * 工艺执行管理服务
  27. */
  28. @Service
  29. @RequiredArgsConstructor
  30. public class CraftsService extends ServiceImpl<CraftsMapper, Crafts> {
  31. private final StateMachineFactory<CraftStates, CraftEvents> stateMachineFactory;
  32. private final WebSocketService webSocketService;
  33. private final CraftsStepService craftsStepService;
  34. private final OresService oresService;
  35. private final ConcurrentHashMap<String, CraftsContext> contextMap = new ConcurrentHashMap<>();
  36. private final ConcurrentHashMap<String, Future<?>> futureMap = new ConcurrentHashMap<>();
  37. private ExecutorService executor;
  38. @PostConstruct
  39. public void init() {
  40. this.executor = Executors.newCachedThreadPool();
  41. }
  42. /**
  43. * 配置工艺
  44. */
  45. public synchronized SetCraftsVO setCraft(Long craftId, String heatId) {
  46. // 校验已有上下文状态,仅允许在 READY、STOPPED 或 FINISHED 状态下重置
  47. CraftsContext existing = contextMap.get(heatId);
  48. if (existing != null) {
  49. CraftStates state = existing.getSm().getState().getId();
  50. if (state == CraftStates.RUNNING || state == CraftStates.PAUSED) {
  51. throw new AppException(ResultCode.CRAFT_RUNNING);
  52. }
  53. clearCraftContext(heatId);
  54. }
  55. Crafts craft = this.getById(craftId);
  56. Ores ores = oresService.getById(craft.getOresId());
  57. CraftsContext ctx = new CraftsContext(
  58. heatId,
  59. ores,
  60. craft,
  61. stateMachineFactory,
  62. webSocketService,
  63. craftsStepService
  64. );
  65. contextMap.put(heatId, ctx);
  66. SetCraftsVO setCraftsVO = new SetCraftsVO();
  67. setCraftsVO.setHeatId(heatId);
  68. setCraftsVO.setCraftsName(craft.getName());
  69. setCraftsVO.setCraftsId(craft.getId());
  70. setCraftsVO.setOresName(ores.getName());
  71. setCraftsVO.setOresId(ores.getId());
  72. return setCraftsVO;
  73. }
  74. /**
  75. * 启动执行工艺需先调用 setCraft
  76. */
  77. public synchronized void startCrafts(String heatId) {
  78. CraftsContext ctx = contextMap.get(heatId);
  79. if (ctx == null) {
  80. throw new AppException(ResultCode.CRAFT_CONTEXT_NULL);
  81. }
  82. if (futureMap.containsKey(heatId)) {
  83. throw new AppException(ResultCode.CRAFT_RUNNING);
  84. }
  85. Future<?> future = executor.submit(ctx);
  86. futureMap.put(heatId, future);
  87. }
  88. /**
  89. * 暂停执行工艺
  90. */
  91. public synchronized void pauseCrafts(String heatId) {
  92. CraftsContext ctx = contextMap.get(heatId);
  93. if (ctx == null) {
  94. throw new AppException(ResultCode.CRAFT_CONTEXT_NULL);
  95. }
  96. ctx.pause();
  97. }
  98. /**
  99. * 恢复执行工艺
  100. */
  101. public synchronized void resumeCrafts(String heatId) {
  102. CraftsContext ctx = contextMap.get(heatId);
  103. if (ctx == null) {
  104. throw new AppException(ResultCode.CRAFT_CONTEXT_NULL);
  105. }
  106. ctx.resume();
  107. }
  108. /**
  109. * 停止执行工艺不清除上下文
  110. */
  111. public synchronized void stopCrafts(String heatId) {
  112. CraftsContext ctx = contextMap.get(heatId);
  113. Future<?> future = futureMap.remove(heatId);
  114. if (ctx == null || future == null) {
  115. throw new AppException(ResultCode.CRAFT_CONTEXT_NULL);
  116. }
  117. ctx.stop();
  118. future.cancel(true);
  119. }
  120. /**
  121. * 清理指定 heatId 的执行上下文和 Future
  122. */
  123. public synchronized void clearCraftContext(String heatId) {
  124. contextMap.remove(heatId);
  125. Future<?> future = futureMap.remove(heatId);
  126. if (future != null) future.cancel(true);
  127. }
  128. /**
  129. * 查询指定 heatId 的执行状态
  130. */
  131. public CraftStatusVO getStatus(String heatId) {
  132. CraftsContext ctx = contextMap.get(heatId);
  133. if (ctx == null) {
  134. return null;
  135. }
  136. CraftStatusVO vo = new CraftStatusVO();
  137. vo.setHeatId(heatId);
  138. vo.setOresId(ctx.getOres().getId());
  139. vo.setOresName(ctx.getOres().getName());
  140. vo.setCraftsId(ctx.getCraft().getId());
  141. vo.setCraftsName(ctx.getCraft().getName());
  142. vo.setState(ctx.getSm().getState().getId());
  143. vo.setCurrentIndex(ctx.getCurrentIndex());
  144. vo.setSteps(ctx.getCraftsStepList());
  145. return vo;
  146. }
  147. /**
  148. * 查询所有正在执行的工艺状态
  149. */
  150. public List<CraftStatusVO> getAllStatuses() {
  151. return contextMap.entrySet().stream().map(entry -> {
  152. String heatIdKey = entry.getKey();
  153. CraftsContext ctx = entry.getValue();
  154. CraftStatusVO vo = new CraftStatusVO();
  155. vo.setHeatId(heatIdKey);
  156. vo.setOresId(ctx.getOres().getId());
  157. vo.setOresName(ctx.getOres().getName());
  158. vo.setCraftsId(ctx.getCraft().getId());
  159. vo.setCraftsName(ctx.getCraft().getName());
  160. vo.setState(ctx.getSm().getState().getId());
  161. vo.setCurrentIndex(ctx.getCurrentIndex());
  162. vo.setSteps(ctx.getCraftsStepList());
  163. return vo;
  164. }).collect(Collectors.toList());
  165. }
  166. public List<Crafts> selectAllByOresId(Long oresId) {
  167. return this.baseMapper.selectAllByOresId(oresId);
  168. }
  169. public Crafts findByName(String name) {
  170. return this.getOne(new LambdaQueryWrapper<>(new Crafts()).eq(Crafts::getName, name));
  171. }
  172. public boolean deleteCrafts(String idsStr) {
  173. List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).collect(Collectors.toList());
  174. return this.removeByIds(ids);
  175. }
  176. }