package jnpf.flowable.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import jnpf.base.entity.VisualdevEntity; import jnpf.base.service.SuperServiceImpl; import jnpf.constant.MsgCode; import jnpf.exception.WorkFlowException; import jnpf.flowable.entity.TemplateEntity; import jnpf.flowable.entity.TemplateJsonEntity; import jnpf.flowable.entity.TemplateNodeEntity; import jnpf.flowable.enums.NodeEnum; import jnpf.flowable.enums.TemplateStatueEnum; import jnpf.flowable.job.QuartzJobUtil; import jnpf.flowable.job.TimeTriggerJob; import jnpf.flowable.job.TriggerJobUtil; import jnpf.flowable.mapper.TemplateJsonMapper; import jnpf.flowable.model.flowable.FlowAbleUrl; import jnpf.flowable.model.template.FlowConfigModel; import jnpf.flowable.model.templatejson.TemplateJsonInfoVO; import jnpf.flowable.model.templatenode.TemplateNodeUpFrom; import jnpf.flowable.model.templatenode.nodejson.NodeModel; import jnpf.flowable.model.trigger.TimeTriggerModel; import jnpf.flowable.service.TemplateJsonService; import jnpf.flowable.service.TemplateNodeService; import jnpf.flowable.service.TemplateService; import jnpf.flowable.util.ServiceUtil; import jnpf.util.*; import org.quartz.JobDataMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; @Service public class TemplateJsonServiceImpl extends SuperServiceImpl implements TemplateJsonService { @Autowired private FlowAbleUrl flowAbleUrl; @Autowired private TemplateService templateService; @Autowired private TemplateNodeService templateNodeService; @Autowired private ServiceUtil serviceUtil; @Autowired private RedisUtil redisUtil; @Override public List getListByTemplateIds(List id) { List list = new ArrayList<>(); if (!id.isEmpty()) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().in(TemplateJsonEntity::getTemplateId, id); list.addAll(this.list(queryWrapper)); } return list; } @Override public List getList(String templateId) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(TemplateJsonEntity::getTemplateId, templateId); List list = this.list(queryWrapper); List resList = new ArrayList<>(); if (CollectionUtil.isNotEmpty(list)) { // 启用中 List enableList = list.stream().filter(e -> ObjectUtil.equals(e.getState(), 1)) .sorted(Comparator.comparing(TemplateJsonEntity::getCreatorTime).reversed()).collect(Collectors.toList()); // 已归档 List historicList = list.stream().filter(e -> ObjectUtil.equals(e.getState(), 2)) .sorted(Comparator.comparing(TemplateJsonEntity::getCreatorTime).reversed()).collect(Collectors.toList()); // 设计中 List designList = list.stream().filter(e -> ObjectUtil.equals(e.getState(), 0)) .sorted(Comparator.comparing(TemplateJsonEntity::getCreatorTime).reversed()).collect(Collectors.toList()); resList.addAll(enableList); resList.addAll(historicList); resList.addAll(designList); } return resList; } @Override public List getListOfEnable() { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(TemplateJsonEntity::getState, 1); return this.list(queryWrapper); } @Override public TemplateJsonEntity getInfo(String id) throws WorkFlowException { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(TemplateJsonEntity::getId, id); TemplateJsonEntity jsonEntity = this.getOne(queryWrapper); if (jsonEntity == null) { throw new WorkFlowException(MsgCode.FA001.get()); } return jsonEntity; } @Override public boolean update(String id, TemplateJsonEntity entity) { entity.setId(id); return this.updateById(entity); } @DSTransactional @Override public void save(TemplateNodeUpFrom from) throws WorkFlowException { String templateJsonId = from.getFlowId(); String id = from.getId(); String flowXml = from.getFlowXml(); Map> flowNodes = from.getFlowNodes(); TemplateJsonEntity jsonEntity = getInfo(templateJsonId); jsonEntity.setFlowXml(flowXml); TemplateEntity entity = templateService.getInfo(id); String flowConfig = from.getFlowConfig(); entity.setFlowConfig(flowConfig); FlowConfigModel config = JsonUtil.getJsonToBean(flowConfig, FlowConfigModel.class); config = config == null ? new FlowConfigModel() : config; entity.setVisibleType(config.getVisibleType()); //发布流程 if (Objects.equals(from.getType(), 1)) { if (StringUtil.isEmpty(jsonEntity.getFlowableId())) { String deploymentId = flowAbleUrl.deployFlowAble(flowXml, templateJsonId); jsonEntity.setFlowableId(deploymentId); } //改流程版本 if (StringUtil.isNotEmpty(id)) { TemplateJsonEntity info = getList(id).stream().filter(t -> Objects.equals(t.getState(), 1)).findFirst().orElse(null); int state = jsonEntity.getState(); if (info != null) { // 变更归档状态,排序码 //info.setSortCode(0L); info.setState(2); this.update(info.getId(), info); } jsonEntity.setState(1); //jsonEntity.setSortCode(1L); entity.setFlowId(templateJsonId); entity.setFlowableId(jsonEntity.getFlowableId()); entity.setVersion(jsonEntity.getVersion()); entity.setEnabledMark(1); entity.setStatus(TemplateStatueEnum.up.getCode()); // 归档状态的仅启用 if (Objects.equals(2, state)) { templateService.update(entity.getId(), entity); this.update(jsonEntity.getId(), jsonEntity); // this.timeTrigger(jsonEntity.getId()); return; } } } templateService.update(entity.getId(), entity); TemplateNodeEntity timeTriggerNode = null; if (ObjectUtil.isNotEmpty(flowNodes)) { List list = templateNodeService.getList(jsonEntity.getId()); List deleteList = list.stream().map(TemplateNodeEntity::getId).collect(Collectors.toList()); templateNodeService.delete(deleteList); // 开始节点的表单 String startFormId = null; for (String key : flowNodes.keySet()) { NodeModel startNode = JsonUtil.getJsonToBean(flowNodes.get(key), NodeModel.class); if (ObjectUtil.equals(startNode.getType(), NodeEnum.start.getType())) { startFormId = startNode.getFormId(); break; } } String formId = null; for (String key : flowNodes.keySet()) { NodeModel nodeModel = JsonUtil.getJsonToBean(flowNodes.get(key), NodeModel.class); if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.global.getType())) { formId = nodeModel.getFormId(); } TemplateNodeEntity nodeEntity = list.stream().filter(t -> ObjectUtil.equals(t.getNodeCode(), key)).findFirst().orElse(new TemplateNodeEntity()); nodeEntity.setId(StringUtil.isNotEmpty(nodeEntity.getId()) ? nodeEntity.getId() : RandomUtil.uuId()); nodeEntity.setFlowId(jsonEntity.getId()); nodeEntity.setNodeCode(key); nodeEntity.setNodeJson(JsonUtil.getObjectToString(flowNodes.get(key))); nodeEntity.setNodeType(nodeModel.getType()); if (StringUtil.isNotEmpty(nodeModel.getFormId())) { nodeEntity.setFormId(nodeModel.getFormId()); } else { nodeEntity.setFormId(startFormId); } // 触发节点:定时、webhook 将flowId设置到formId字段 通知将msgId设置到formId if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.timeTrigger.getType())) { nodeEntity.setFormId(nodeEntity.getFlowId()); if (Objects.equals(from.getType(), 1)) { timeTriggerNode = nodeEntity; } } else if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.webhookTrigger.getType())) { nodeEntity.setFormId(nodeEntity.getFlowId()); } else if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.noticeTrigger.getType())) { nodeEntity.setFormId(nodeModel.getNoticeId()); } templateNodeService.setIgnoreLogicDelete().removeById(nodeEntity.getId()); templateNodeService.setIgnoreLogicDelete().saveOrUpdate(nodeEntity); templateNodeService.clearIgnoreLogicDelete(); } // 保存表单关联 if (null != formId) { List formIds = new ArrayList<>(); formIds.add(formId); } } this.update(jsonEntity.getId(), jsonEntity); if (null != timeTriggerNode) { this.timeTrigger(timeTriggerNode); } } public void timeTrigger(String flowId) { List list = templateNodeService.getList(flowId); List timeTriggerList = list.stream() .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.timeTrigger.getType())).collect(Collectors.toList()); if (CollectionUtil.isNotEmpty(timeTriggerList)) { for (TemplateNodeEntity nodeEntity : timeTriggerList) { this.timeTrigger(nodeEntity); } } } public void timeTrigger(TemplateNodeEntity nodeEntity) { NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class); String id = RandomUtil.uuId(); TimeTriggerModel model = new TimeTriggerModel(); model.setId(id); model.setFlowId(nodeEntity.getFlowId()); model.setUserInfo(UserProvider.getUser()); model.setCron(nodeModel.getCron()); model.setEndLimit(nodeModel.getEndLimit()); model.setEndTimeType(nodeModel.getEndTimeType()); String start = nodeModel.getStartTime(); String end = nodeModel.getEndTime(); Date startTime = ObjectUtil.isNotEmpty(start) ? new Date(Long.parseLong(start)) : new Date(); Date endTime = ObjectUtil.equals(nodeModel.getEndTimeType(), 2) ? new Date(Long.parseLong(end)) : null; model.setStartTime(startTime.getTime()); model.setEndTime(endTime != null ? endTime.getTime() : null); JobDataMap jobDataMap = new JobDataMap(); jobDataMap.putAll(JsonUtil.entityToMap(model)); redisUtil.removeHash(TriggerJobUtil.TRIGGER_MODEL, model.getId()); boolean isAdd = endTime == null || endTime.getTime() > System.currentTimeMillis(); if (isAdd) { QuartzJobUtil.addJob(id, nodeModel.getCron(), TimeTriggerJob.class, jobDataMap, startTime, endTime); } } @DSTransactional @Override public void create(TemplateNodeUpFrom from) { Map> flowNodes = from.getFlowNodes(); String flowXml = from.getFlowXml(); String templateJsonId = from.getFlowId(); String id = from.getId(); List jsonList = getList(id); int version = jsonList.stream().map(TemplateJsonEntity::getVersion).mapToInt(Integer::parseInt).max().orElse(0) + 1; TemplateJsonEntity entity = new TemplateJsonEntity(); entity.setId(StringUtil.isNotEmpty(templateJsonId) ? templateJsonId : RandomUtil.uuId()); entity.setTemplateId(id); entity.setFlowXml(flowXml); NodeModel startNode = JsonUtil.getJsonToList(new ArrayList<>(flowNodes.values()), NodeModel.class).stream().filter(t -> NodeEnum.start.getType().equals(t.getType())).findFirst().orElse(null); entity.setVersion(String.valueOf(version)); entity.setState(0); entity.setSortCode(0L); String formId = null != startNode ? startNode.getFormId() : null; for (String key : flowNodes.keySet()) { NodeModel nodeModel = JsonUtil.getJsonToBean(flowNodes.get(key), NodeModel.class); TemplateNodeEntity nodeEntity = new TemplateNodeEntity(); nodeEntity.setId(StringUtil.isNotEmpty(nodeEntity.getId()) ? nodeEntity.getId() : RandomUtil.uuId()); nodeEntity.setFlowId(entity.getId()); nodeEntity.setNodeCode(key); nodeEntity.setNodeJson(JsonUtil.getObjectToString(flowNodes.get(key))); nodeEntity.setNodeType(nodeModel.getType()); nodeEntity.setFormId(StringUtil.isBlank(nodeModel.getFormId()) ? formId : nodeModel.getFormId()); templateNodeService.setIgnoreLogicDelete().removeById(nodeEntity.getId()); templateNodeService.setIgnoreLogicDelete().saveOrUpdate(nodeEntity); templateNodeService.clearIgnoreLogicDelete(); } this.setIgnoreLogicDelete().removeById(entity.getId()); this.setIgnoreLogicDelete().saveOrUpdate(entity); this.clearIgnoreLogicDelete(); } @Override public void delete(TemplateJsonEntity entity) { if (entity != null) { this.removeById(entity.getId()); } } @Override public void delete(List idList) { if (idList.size() > 0) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().in(TemplateJsonEntity::getId, idList); this.remove(queryWrapper); templateNodeService.delete(idList); } } @Override public void copy(TemplateJsonEntity entity, String flowId) { List list = templateNodeService.getList(entity.getId()); Map> flowNodes = new HashMap<>(); for (TemplateNodeEntity nodeEntity : list) { Map map = JsonUtil.stringToMap(nodeEntity.getNodeJson()); if (ObjectUtil.equals(nodeEntity.getNodeType(), NodeEnum.webhookTrigger.getType())) { map.put("webhookUrl", ""); } flowNodes.put(nodeEntity.getNodeCode(), map); } TemplateNodeUpFrom from = new TemplateNodeUpFrom(); from.setId(entity.getTemplateId()); from.setFlowXml(entity.getFlowXml()); from.setFlowNodes(flowNodes); from.setFlowId(flowId); create(from); } @Override public TemplateJsonInfoVO getInfoVo(String id) throws WorkFlowException { TemplateJsonEntity jsonEntity = this.getInfo(id); TemplateEntity entity = templateService.getInfo(jsonEntity.getTemplateId()); TemplateJsonInfoVO vo = JsonUtil.getJsonToBean(entity, TemplateJsonInfoVO.class); vo.setFlowXml(jsonEntity.getFlowXml()); List templateNodeList = templateNodeService.getList(jsonEntity.getId()); Map> flowNodes = new HashMap<>(); for (TemplateNodeEntity nodeEntity : templateNodeList) { flowNodes.put(nodeEntity.getNodeCode(), JsonUtil.stringToMap(nodeEntity.getNodeJson())); } vo.setFlowableId(jsonEntity.getFlowableId()); vo.setFlowNodes(flowNodes); vo.setFlowId(jsonEntity.getId()); return vo; } @Override public VisualdevEntity getFormInfo(String id) throws WorkFlowException { TemplateEntity template = templateService.getInfo(id); String flowId = template.getFlowId(); TemplateJsonEntity jsonEntity = this.getInfo(flowId); List templateNodeList = templateNodeService.getList(jsonEntity.getId()); TemplateNodeEntity global = templateNodeList.stream().filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.global.getType())).findFirst().orElse(null); if (null != global) { return serviceUtil.getFormInfo(global.getFormId()); } return null; } }