diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/domain/DmsBillsInspectInstance.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/domain/DmsBillsInspectInstance.java index 678a5e1..c0e0e25 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/domain/DmsBillsInspectInstance.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/domain/DmsBillsInspectInstance.java @@ -107,9 +107,12 @@ public class DmsBillsInspectInstance extends TenantEntity { + @TableField(exist = false) private List dmsInspectInstanceDetailList; + @TableField(exist = false) private String planInspectCode; + @TableField(exist = false) private String inspectStatusStr; } diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteInspectInstanceServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteInspectInstanceServiceImpl.java index 21b2504..fed5a20 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteInspectInstanceServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteInspectInstanceServiceImpl.java @@ -1,44 +1,116 @@ package org.dromara.dms.dubbo; - +import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.ttl.TtlRunnable; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; +import io.seata.spring.annotation.GlobalTransactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; +import org.apache.dubbo.rpc.RpcContext; import org.dromara.common.core.constant.DmsConstants; import org.dromara.common.core.domain.R; +import org.dromara.common.core.utils.ObjectUtils; import org.dromara.dms.api.RemoteInspectInstanceService; import org.dromara.dms.domain.*; import org.dromara.dms.mapper.*; import org.dromara.dms.service.impl.DmsInspectProjectDeviceServiceImpl; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteCompleteTask; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.domain.RemoteStartProcessReturn; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.concurrent.CompletableFuture; @RequiredArgsConstructor @Service @DubboService +@Slf4j public class RemoteInspectInstanceServiceImpl implements RemoteInspectInstanceService { - private final DmsPlanInspectMapper dmsPlanInspectMapper; - private final DmsInspectRouteDetailMapper dmsInspectRouteDetailMapper; - private final DmsBillsInspectInstanceMapper dmsBillsInspectInstanceMapper; - private final DmsInspectInstanceDetailMapper dmsInspectInstanceDetailMapper; - private final DmsInspectInstanceDetailProjectMapper dmsInspectInstanceDetailProjectMapper; - private final DmsInspectProjectDeviceMapper dmsInspectProjectDeviceMapper; + @DubboReference(timeout = 10000) + private RemoteWorkflowService remoteWorkflowService; @Override - @Transactional( rollbackFor = Exception.class ) + @GlobalTransactional(rollbackFor = Exception.class) public R insertInspectInstance(String planInspectCode, String tenantId, Long userId){ + // 【重要】在主线程中先登录,确保后续所有调用都有认证上下文 + StpUtil.login(userId, "login"); + + try { + // 创建检查实例 + R rInspectInstanceId = createInspectInstance(planInspectCode, tenantId, userId); + Long inspectInstanceId = rInspectInstanceId.getData(); + String businessId = inspectInstanceId.toString(); + + if (!R.isSuccess(rInspectInstanceId)) { + return R.fail(); + } else { + // 启动工作流 + RemoteStartProcess remoteStartProcess = new RemoteStartProcess(); + remoteStartProcess.setBusinessId(businessId); + remoteStartProcess.setFlowCode(DmsConstants.DMS_BILLS_INSPECT_INSTANCE_WF_CODE); + RemoteStartProcessReturn result = remoteWorkflowService.startWorkFlow(remoteStartProcess); + + if (ObjectUtils.isEmpty(result)) { + return R.fail(); + } else { + Long taskId = result.getTaskId(); + // 【简化方案】异步处理工作流推进,避免死锁 + CompletableFuture.runAsync(TtlRunnable.get(() -> { + try { + // 【关键】在异步线程中重新登录相同用户 + StpUtil.login(userId, "login"); + + // 【执行业务】更新检查工单的工作流信息 + updateInspectWorkflow(inspectInstanceId, taskId); + + log.info("检查工单 {} 异步工作流处理完成", inspectInstanceId); + } catch (Exception e) { + log.error("检查工单 {} 异步工作流处理失败: {}", inspectInstanceId, e.getMessage(), e); + } finally { + // 【清理】清理登录状态,避免线程池复用时的状态污染 + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出时的异常 + } + // 清理RpcContext + try { + RpcContext.removeContext(); + } catch (Exception ignored) { + // 忽略清理时的异常 + } + } + })); + return R.ok(1); + } + } + } finally { + // 【主线程清理】确保主线程执行完成后清理登录状态 + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出异常 + } + } + } + + private R createInspectInstance(String planInspectCode, String tenantId, Long userId) { // 使用 replaceAll 方法将双引号替换为空字符串 String result = planInspectCode.replaceAll("\"", ""); // 根据检查计划代码查询检查计划信息 @@ -58,30 +130,22 @@ public class RemoteInspectInstanceServiceImpl implements RemoteInspectInstanceSe DmsBillsInspectInstance dmsBillsInspectInstance = new DmsBillsInspectInstance(); // 设置检查实例的相关属性 dmsBillsInspectInstance.setPlanInspectId(dmsPlanInspect.getPlanInspectId()); -// dmsBillsInspectInstance.setWfProcessId(105l); dmsBillsInspectInstance.setInspectType(dmsPlanInspect.getInspectType());//检查类型(1巡检 2点检) dmsBillsInspectInstance.setPlanBeginTime(dmsPlanInspect.getPlanTime()); dmsBillsInspectInstance.setPlanEndTime(new Date(dmsPlanInspect.getPlanTime().getTime()+dmsPlanInspect.getTimeLimit()*1000l)); dmsBillsInspectInstance.setInspectRouteId(dmsPlanInspect.getInspectRouteId()); -// dmsBillsInspectInstance.setDeviceAmount(dmsPlanInspect.getDeviceAmount());//设备数量FIXME:没有这个字段 dmsBillsInspectInstance.setPerformer(dmsPlanInspect.getPerformer());//执行人 - -// dmsBillsInspectInstance.setIsFlag("1"); dmsBillsInspectInstance.setInspectStatus(DmsConstants.DMS_BILLS_INSPECT_INSTANCE_INSPECT_STATUS_TO_INSPECT);//待巡检 dmsBillsInspectInstance.setCreateBy(userId); dmsBillsInspectInstance.setTenantId(tenantId); // 插入检查实例并返回影响的行数 int i = dmsBillsInspectInstanceMapper.insert(dmsBillsInspectInstance); -// List dmsBillsInspectInstances = dmsBillsInspectInstanceMapper.selectDmsBillsInspectInstanceList(dmsBillsInspectInstance); - - //新建点巡检工单明细 -/* DmsInspectRouteDetail queryInspectRouteDetail = new DmsInspectRouteDetail(); - queryInspectRouteDetail.setInspectRouteId(dmsBillsInspectInstance.getInspectRouteId());*/ // 查询检查路线明细 MPJLambdaWrapper lqw = JoinWrappers.lambda(DmsInspectRouteDetail.class) .eq(DmsInspectRouteDetail::getInspectRouteId, dmsBillsInspectInstance.getInspectRouteId()); List dmsInspectRouteDetails = dmsInspectRouteDetailMapper.selectList(lqw); + // 遍历检查路线明细,生成检查实例明细 for(DmsInspectRouteDetail dmsInspectRouteDetail:dmsInspectRouteDetails){ DmsInspectInstanceDetail dmsInspectInstanceDetail = new DmsInspectInstanceDetail(); @@ -91,38 +155,60 @@ public class RemoteInspectInstanceServiceImpl implements RemoteInspectInstanceSe dmsInspectInstanceDetail.setMachineId(deviceId); dmsInspectInstanceDetail.setInstanceDetailStatus("1");//(1待巡检 2巡检中 3已完成) dmsInspectInstanceDetail.setInspectStandard(dmsInspectRouteDetail.getInspectStandard()); - dmsInspectInstanceDetail.setInspectStatus("0");//FIXME:为什么设置为异常?设备状态(1正常 0异常) + dmsInspectInstanceDetail.setInspectStatus("0");//设备状态(1正常 0异常) dmsInspectInstanceDetail.setTenantId(tenantId); dmsInspectInstanceDetail.setCreateBy(userId); -// dmsInspectInstanceDetail.setCreateTime(new Date()); dmsInspectInstanceDetailMapper.insert(dmsInspectInstanceDetail); // 查询项目ID Long projectId = dmsInspectInstanceDetailMapper.selectProjectId(dmsInspectRouteDetail.getInspectStandard()); DmsInspectProjectDevice queryInspectProjectDevice = new DmsInspectProjectDevice(); - queryInspectProjectDevice.setTargetType("2");//FIXME:关联类型(1设备类型) + queryInspectProjectDevice.setTargetType("2");//关联类型 queryInspectProjectDevice.setTargetId(deviceId); MPJLambdaWrapper DmsInspectProjectDeviceLQW = JoinWrappers.lambda(DmsInspectProjectDevice.class) - .eq(DmsInspectProjectDevice::getTargetType, "2")//FIXME:关联类型(1设备类型) + .eq(DmsInspectProjectDevice::getTargetType, "2")//关联类型 .eq(DmsInspectProjectDevice::getTargetId, deviceId); List dmsInspectProjectDevices = dmsInspectProjectDeviceMapper.selectList(DmsInspectProjectDeviceLQW); - - // for(DmsInspectProjectDevice dmsInspectProjectDevice:dmsInspectProjectDevices){ DmsInspectInstanceDetailProject dmsInspectInstanceDetailProject = new DmsInspectInstanceDetailProject(); dmsInspectInstanceDetailProject.setInstanceDetailId(dmsInspectInstanceDetail.getInstanceDetailId()); dmsInspectInstanceDetailProject.setInspectProjectId(projectId); - dmsInspectInstanceDetailProject.setTenantId(tenantId); dmsInspectInstanceDetailProject.setCreateBy(userId); dmsInspectInstanceDetailProjectMapper.insert(dmsInspectInstanceDetailProject); -// } - } - // 返回成功结果和影响的行数 - return R.ok(i); + // 返回成功结果和检查实例ID + return R.ok(dmsBillsInspectInstance.getInspectInstanceId()); + } + private void updateInspectWorkflow(Long businessId, Long taskId) { + try { + // 1. 更新工作流ID + DmsBillsInspectInstance inspectInstance = dmsBillsInspectInstanceMapper.selectById(businessId); + if (inspectInstance != null) { + inspectInstance.setWfDefinitionId(taskId); + dmsBillsInspectInstanceMapper.updateById(inspectInstance); + log.info("检查工单 {} 工作流ID更新成功: {}", businessId, taskId); + } + + // 2. 推进工作流状态 + RemoteCompleteTask completeTask = new RemoteCompleteTask(); + completeTask.setTaskId(taskId); + completeTask.setMessage("检查工单启动,自动推进"); + // 设置消息类型为非null的List + List messageTypes = new ArrayList<>(); + messageTypes.add("system"); // 系统消息 + completeTask.setMessageType(messageTypes); + + // 【关键】调用工作流推进 + remoteWorkflowService.completeTask(completeTask); + log.info("检查工单 {} 工作流推进成功", businessId); + + } catch (Exception e) { + log.error("检查工单 {} 工作流更新失败: {}", businessId, e.getMessage(), e); + // 注意:这里不抛出异常,避免影响主流程 + } } } diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteLubeInstanceServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteLubeInstanceServiceImpl.java index c4867fb..c7e9c67 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteLubeInstanceServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteLubeInstanceServiceImpl.java @@ -1,34 +1,46 @@ package org.dromara.dms.dubbo; +import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.ttl.TtlRunnable; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import io.seata.spring.annotation.GlobalTransactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; +import org.apache.dubbo.rpc.RpcContext; import org.dromara.common.core.constant.DmsConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.uuid.Seq; import org.dromara.dms.domain.*; -import org.dromara.dms.domain.bo.DmsBillsLubeInstanceBo; -import org.dromara.dms.domain.bo.DmsPlanLubeBo; -import org.dromara.dms.domain.vo.DmsBillsLubeInstanceVo; +import org.dromara.dms.domain.bo.*; +import org.dromara.dms.domain.vo.*; import org.dromara.dms.domain.vo.DmsPlanLubeDetailVo; import org.dromara.dms.mapper.*; import org.dromara.dms.service.IDmsBillsLubeInstanceService; import org.dromara.dms.service.IDmsPlanInspectService; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteCompleteTask; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.domain.RemoteStartProcessReturn; import org.springframework.stereotype.Service; import org.dromara.dms.api.RemoteLubeInstanceService; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.concurrent.CompletableFuture; @RequiredArgsConstructor @Service @DubboService +@Slf4j public class RemoteLubeInstanceServiceImpl implements RemoteLubeInstanceService { + private final DmsBillsLubeInstanceMapper dmsBillsLubeInstanceMapper; private final DmsBillsLubeDetailMapper dmsBillsLubeDetailMapper; @@ -47,12 +59,75 @@ public class RemoteLubeInstanceServiceImpl implements RemoteLubeInstanceService private final DmsInspectRouteDetailMapper dmsInspectRouteDetailMapper; -// private final RemoteWorkflowService remoteWorkflowService; + @DubboReference(timeout = 10000) + private final RemoteWorkflowService remoteWorkflowService; @Override @GlobalTransactional(rollbackFor = Exception.class) public R insertLubeInstance(String planLubeCode, String tenantId, Long userId) { + // 【重要】在主线程中先登录,确保后续所有调用都有认证上下文 + StpUtil.login(userId, "login"); + + try { + R RLubeStanceId = LubeStance(planLubeCode, tenantId, userId); + Long LubeStanceId = RLubeStanceId.getData(); + String businessId = LubeStanceId.toString(); + if (!R.isSuccess(RLubeStanceId)) { + return R.fail(); + }else { + RemoteStartProcess remoteStartProcess = new RemoteStartProcess(); + remoteStartProcess.setBusinessId(businessId); + remoteStartProcess.setFlowCode(DmsConstants.DMS_BILLS_LUBE_INSTANCE_WF_CODE); + RemoteStartProcessReturn result = remoteWorkflowService.startWorkFlow(remoteStartProcess); + //TODO:赋值给工单的wfid + if(ObjectUtils.isEmpty(result)){ + return R.fail(); + }else { + Long taskId = result.getTaskId(); + // 【简化方案】直接在异步线程中重新登录相同用户,避免Token传递复杂性 + CompletableFuture.runAsync(TtlRunnable.get(() -> { + try { + // 【关键】在异步线程中重新登录相同用户 + // 这样可以确保生成有效的Token并自动设置到Sa-Token上下文中 + StpUtil.login(userId, "login"); + + // 【执行业务】更新润滑工单的工作流信息 + updateWarmFlow(LubeStanceId, taskId); + + log.info("润滑工单 {} 异步工作流处理完成", LubeStanceId); + } catch (Exception e) { + log.error("润滑工单 {} 异步工作流处理失败: {}", LubeStanceId, e.getMessage(), e); + } finally { + // 【清理】清理登录状态,避免线程池复用时的状态污染 + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出时的异常 + } + // 清理RpcContext + try { + RpcContext.removeContext(); + } catch (Exception ignored) { + // 忽略清理时的异常 + } + } + })); + return R.ok(); + } + } + } finally { + // 【主线程清理】确保主线程执行完成后清理登录状态 + // 注意:这里不影响异步线程,因为每个线程都有自己的ThreadLocal + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出异常 + } + } + } + + private R LubeStance(String planLubeCode, String tenantId, Long userId){ // 去除润滑计划编号中的双引号 // String lubeInstanceCodeS = planLubeCode.replaceAll("\"", ""); @@ -67,7 +142,6 @@ public class RemoteLubeInstanceServiceImpl implements RemoteLubeInstanceService List dmsPlanLubeDetailList = dmsPlanLubeDetailMapper.selectVoList(dmsPlanLubeDetailWrapper); dmsPlanLube.setDmsPlanLubeDetailList(dmsPlanLubeDetailList); - // 获取润滑计划详情列表 List planLubeDetails = dmsPlanLube.getDmsPlanLubeDetailList(); if (planLubeDetails == null || planLubeDetails.isEmpty()) { @@ -100,11 +174,14 @@ public class RemoteLubeInstanceServiceImpl implements RemoteLubeInstanceService dmsBillsLubeInstance.setCreateBy(userId); dmsBillsLubeInstance.setTenantId(tenantId); // 插入润滑工单实例到数据库 - int i = dmsBillsLubeInstanceMapper.insert(dmsBillsLubeInstance); + Boolean flag = dmsBillsLubeInstanceMapper.insert(dmsBillsLubeInstance) > 0; + Long LubeStanceId = dmsBillsLubeInstance.getLubeInstanceId(); + DmsPlanLubeBo dmsPlanLubeBo = MapstructUtils.convert(dmsPlanLube, DmsPlanLubeBo.class); // 批量插入润滑工单详情 List lubeDetails = dmsPlanLubeBo.getDmsPlanLubeDetailList(); List billsLubeDetails = new ArrayList<>(); + int insert = 0; for (DmsPlanLubeDetailVo planLubeDetail : lubeDetails) { DmsBillsLubeDetail dmsBillsLubeDetail = new DmsBillsLubeDetail(); dmsBillsLubeDetail.setLubeInstanceId(dmsBillsLubeInstance.getLubeInstanceId()); @@ -117,9 +194,39 @@ public class RemoteLubeInstanceServiceImpl implements RemoteLubeInstanceService dmsBillsLubeDetail.setCreateBy(userId); // dmsBillsLubeDetail.setCreateTime(new Date()); - dmsBillsLubeDetailMapper.insert(dmsBillsLubeDetail); + insert = dmsBillsLubeDetailMapper.insert(dmsBillsLubeDetail); } - return R.ok(); + return R.ok(LubeStanceId); + } + + + private void updateWarmFlow(Long businessId,Long taskId){ + try { + // 1. 更新工作流ID + DmsBillsLubeInstanceVo dmsBillsLubeInstanceVo = dmsBillsLubeInstanceService.queryById(businessId); + DmsBillsLubeInstance billsLubeInstance = MapstructUtils.convert(dmsBillsLubeInstanceVo, DmsBillsLubeInstance.class); + billsLubeInstance.setWfDefinitionId(taskId); + dmsBillsLubeInstanceMapper.updateById(billsLubeInstance); + log.info("润滑工单 {} 工作流ID更新成功: {}", businessId, taskId); + + // 2. 推进工作流状态 + RemoteCompleteTask completeTask = new RemoteCompleteTask(); + completeTask.setTaskId(taskId); + completeTask.setMessage("润滑工单启动,自动推进"); + // 设置消息类型为非null的List + List messageTypes = new ArrayList<>(); + messageTypes.add("system"); // 系统消息 + completeTask.setMessageType(messageTypes); + + // 【关键】调用工作流推进,可能会因为Token问题失败 + remoteWorkflowService.completeTask(completeTask); + log.info("润滑工单 {} 工作流推进成功", businessId); + + } catch (Exception e) { + log.error("润滑工单 {} 工作流更新失败: {}", businessId, e.getMessage(), e); + // 注意:这里不抛出异常,避免影响主流程 + // 工作流推进失败时,工单仍然创建成功,但状态为草稿 + } } } diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteMaintInstanceServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteMaintInstanceServiceImpl.java index 3f78042..ef176bf 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteMaintInstanceServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/dubbo/RemoteMaintInstanceServiceImpl.java @@ -1,11 +1,16 @@ package org.dromara.dms.dubbo; - - +import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.ttl.TtlRunnable; +import io.seata.spring.annotation.GlobalTransactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; +import org.apache.dubbo.rpc.RpcContext; import org.dromara.common.core.constant.DmsConstants; import org.dromara.common.core.domain.R; +import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.uuid.Seq; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.dms.api.RemoteMaintInstanceService; @@ -15,16 +20,22 @@ import org.dromara.dms.mapper.DmsBillsMaintDetailProjectMapper; import org.dromara.dms.mapper.DmsBillsMaintInstanceMapper; import org.dromara.dms.mapper.DmsPlanMaintMapper; import org.dromara.system.api.model.LoginUser; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteCompleteTask; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.domain.RemoteStartProcessReturn; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.concurrent.CompletableFuture; @RequiredArgsConstructor @Service @DubboService +@Slf4j public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceService { private final DmsPlanMaintMapper dmsPlanMaintMapper; @@ -32,10 +43,11 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic private final DmsBillsMaintInstanceMapper dmsBillsMaintInstanceMapper; private final DmsBillsMaintDetailMapper dmsBillsMaintDetailMapper; - + private final DmsBillsMaintDetailProjectMapper dmsBillsMaintDetailProjectMapper; - + @DubboReference(timeout = 10000) + private RemoteWorkflowService remoteWorkflowService; /** * 新增保养工单 @@ -44,8 +56,71 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic * @return 结果 */ @Override - @Transactional( rollbackFor = Exception.class ) + @GlobalTransactional(rollbackFor = Exception.class) public R insertDmsBillsMaintInstance(String planMaintCode , String tenantId, Long userId) { + // 【重要】在主线程中先登录,确保后续所有调用都有认证上下文 + StpUtil.login(userId, "login"); + + try { + // 创建保养实例 + R rMaintInstanceId = createMaintInstance(planMaintCode, tenantId, userId); + Long maintInstanceId = rMaintInstanceId.getData(); + String businessId = maintInstanceId.toString(); + + if (!R.isSuccess(rMaintInstanceId)) { + return R.fail(); + } else { + // 启动工作流 + RemoteStartProcess remoteStartProcess = new RemoteStartProcess(); + remoteStartProcess.setBusinessId(businessId); + remoteStartProcess.setFlowCode(DmsConstants.DMS_BILLS_MAINT_INSTANCE_WF_CODE); + RemoteStartProcessReturn result = remoteWorkflowService.startWorkFlow(remoteStartProcess); + + if (ObjectUtils.isEmpty(result)) { + return R.fail(); + } else { + Long taskId = result.getTaskId(); + // 【简化方案】异步处理工作流推进,避免死锁 + CompletableFuture.runAsync(TtlRunnable.get(() -> { + try { + // 【关键】在异步线程中重新登录相同用户 + StpUtil.login(userId, "login"); + + // 【执行业务】更新保养工单的工作流信息 + updateMaintWorkflow(maintInstanceId, taskId); + + log.info("保养工单 {} 异步工作流处理完成", maintInstanceId); + } catch (Exception e) { + log.error("保养工单 {} 异步工作流处理失败: {}", maintInstanceId, e.getMessage(), e); + } finally { + // 【清理】清理登录状态,避免线程池复用时的状态污染 + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出时的异常 + } + // 清理RpcContext + try { + RpcContext.removeContext(); + } catch (Exception ignored) { + // 忽略清理时的异常 + } + } + })); + return R.ok(1); + } + } + } finally { + // 【主线程清理】确保主线程执行完成后清理登录状态 + try { + StpUtil.logout(); + } catch (Exception ignored) { + // 忽略登出异常 + } + } + } + + private R createMaintInstance(String planMaintCode, String tenantId, Long userId) { String planMaintCodeS = planMaintCode.replaceAll("\"", ""); DmsPlanMaint dmsPlanMaint = dmsPlanMaintMapper.selectDmsPlanMaintJoinByPlanMaintCode(planMaintCodeS); List planMaintDetails = dmsPlanMaint.getDmsPlanMaintDetailList(); @@ -62,11 +137,8 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic dmsBillsMaintInstance.setMaintSupervisor(dmsPlanMaint.getMaintSupervisor()); dmsBillsMaintInstance.setMaintLevel(dmsPlanMaint.getMaintLevel()); - Date lubeTime = dmsPlanMaint.getMaintTime(); Long timeLimit = dmsPlanMaint.getTimeLimit(); -// dmsBillsMaintInstance.setIsFlag(1l); -// dmsBillsMaintInstance.setWfProcessId(103l); dmsBillsMaintInstance.setPlanEndTime(new Date(lubeTime.getTime() + timeLimit * 1000l)); //字段没有自动填充,只能代码手动填充 @@ -75,15 +147,10 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic int i = dmsBillsMaintInstanceMapper.insert(dmsBillsMaintInstance); -// DmsMaintInstanceActivity dmsMaintInstanceActivity = new DmsMaintInstanceActivity(); -// dmsMaintInstanceActivity.setMaintInstanceId(dmsBillsMaintInstance.getMaintInstanceId()); -// dmsMaintInstanceActivity.setProcessStepOrder(1L); -// int i1 = dmsMaintInstanceActivityMapper.insertDmsMaintInstanceActivity(dmsMaintInstanceActivity); batchInsertDmsBillsMaintDetail(dmsPlanMaint, dmsBillsMaintInstance.getMaintInstanceId(), tenantId, userId); - return R.ok(i); + return R.ok(dmsBillsMaintInstance.getMaintInstanceId()); } - @Transactional( rollbackFor = Exception.class ) public void batchInsertDmsBillsMaintDetail(DmsPlanMaint dmsPlanMaint, Long maintInstanceId, String tenantId, Long userId) { List planMaintDetails = dmsPlanMaint.getDmsPlanMaintDetailList(); @@ -94,7 +161,6 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic dmsBillsMaintDetail.setMachineId(planMaintDetail.getMachineId()); dmsBillsMaintDetail.setMaintStationId(planMaintDetail.getMaintStationId()); dmsBillsMaintDetail.setMaintStandardId(planMaintDetail.getMaintStandardId()); -// dmsBillsMaintDetail.setIsFlag(1L); dmsBillsMaintDetail.setMaintStatus(1L);//保养状态(1待保养 2保养中 3已完成) //字段没有自动填充,只能代码手动填充 @@ -111,11 +177,10 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic for (DmsBaseMaintProject project : projects) { DmsBillsMaintDetailProject billsMaintDetailProject = new DmsBillsMaintDetailProject(); billsMaintDetailProject.setBillsMaintDetailId(detail.getBillsMaintDetailId()); -// DmsBaseMaintStation station = dmsBillsMaintDetailMapper.selectMainStation(detail.getStationId()); billsMaintDetailProject.setMaintProjectId(project.getMaintProjectId()); billsMaintDetailProject.setMaintProjectName(project.getMaintProjectName()); billsMaintDetailProject.setMaintProjectDesc(project.getMaintProjectDesc()); - billsMaintDetailProject.setMaintProjectStatus("2");//保养项目状态(0待保养 1保养完成)FIXME:为什么是2?? + billsMaintDetailProject.setMaintProjectStatus("2");//保养项目状态(0待保养 1保养完成) //字段没有自动填充,只能代码手动填充 billsMaintDetailProject.setCreateBy(userId); @@ -123,8 +188,35 @@ public class RemoteMaintInstanceServiceImpl implements RemoteMaintInstanceServic dmsBillsMaintDetailProjectMapper.insert(billsMaintDetailProject); } - } + } + private void updateMaintWorkflow(Long businessId, Long taskId) { + try { + // 1. 更新工作流ID + DmsBillsMaintInstance maintInstance = dmsBillsMaintInstanceMapper.selectById(businessId); + if (maintInstance != null) { + maintInstance.setWfDefinitionId(taskId); + dmsBillsMaintInstanceMapper.updateById(maintInstance); + log.info("保养工单 {} 工作流ID更新成功: {}", businessId, taskId); + } + + // 2. 推进工作流状态 + RemoteCompleteTask completeTask = new RemoteCompleteTask(); + completeTask.setTaskId(taskId); + completeTask.setMessage("保养工单启动,自动推进"); + // 设置消息类型为非null的List + List messageTypes = new ArrayList<>(); + messageTypes.add("system"); // 系统消息 + completeTask.setMessageType(messageTypes); + + // 【关键】调用工作流推进 + remoteWorkflowService.completeTask(completeTask); + log.info("保养工单 {} 工作流推进成功", businessId); + + } catch (Exception e) { + log.error("保养工单 {} 工作流更新失败: {}", businessId, e.getMessage(), e); + // 注意:这里不抛出异常,避免影响主流程 + } } } diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanInspectServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanInspectServiceImpl.java index 5bb7b0f..2e7dac2 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanInspectServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanInspectServiceImpl.java @@ -202,11 +202,11 @@ public class DmsPlanInspectServiceImpl implements IDmsPlanInspectService { .setJobName("点巡检计划编号" + planInspectCode + "工单任务") .setExecutorInfo("stanceInspect")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planInspectCode") .setExtAttrs(planInspectCode) .setUserId(LoginHelper.getUserId().toString()) @@ -296,11 +296,11 @@ public class DmsPlanInspectServiceImpl implements IDmsPlanInspectService { .setJobName("点巡检计划编号" + planInspectCode + "工单任务") .setExecutorInfo("stanceInspect")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planInspectCode") .setExtAttrs(planInspectCode) .setUserId(LoginHelper.getUserId().toString()) diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanLubeServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanLubeServiceImpl.java index def83f9..9830c74 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanLubeServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanLubeServiceImpl.java @@ -187,11 +187,11 @@ public class DmsPlanLubeServiceImpl implements IDmsPlanLubeService { .setJobName("润滑计划编号" + planLubeCode + "工单任务") .setExecutorInfo("stanceLube")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planLubeCode") .setExtAttrs(planLubeCode) .setUserId(LoginHelper.getUserId().toString()) @@ -250,11 +250,11 @@ public class DmsPlanLubeServiceImpl implements IDmsPlanLubeService { .setJobName("润滑计划编号" + planLubeCode + "工单任务") .setExecutorInfo("stanceLube")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planLubeCode") .setExtAttrs(planLubeCode) .setUserId(LoginHelper.getUserId().toString()) @@ -273,11 +273,11 @@ public class DmsPlanLubeServiceImpl implements IDmsPlanLubeService { .setJobName("润滑计划编号" + planLubeCode + "工单任务") .setExecutorInfo("stanceLube")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planLubeCode") .setExtAttrs(planLubeCode) .setUserId(LoginHelper.getUserId().toString()) diff --git a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanMaintServiceImpl.java b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanMaintServiceImpl.java index d92ee0d..c06f471 100644 --- a/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanMaintServiceImpl.java +++ b/ruoyi-modules/hwmom-dms/src/main/java/org/dromara/dms/service/impl/DmsPlanMaintServiceImpl.java @@ -213,11 +213,11 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService { .setJobName("保养计划编号" + planMaintCode + "工单任务") .setExecutorInfo("stanceMaint")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planMaintCode") .setExtAttrs(planMaintCode) .setUserId(LoginHelper.getUserId().toString()) @@ -302,11 +302,11 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService { .setJobName("保养计划编号" + planMaintCode + "工单任务") .setExecutorInfo("stanceMaint")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planMaintCode") .setExtAttrs(planMaintCode) .setUserId(LoginHelper.getUserId().toString()) @@ -322,11 +322,11 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService { .setJobName("保养计划编号" + planMaintCode + "工单任务") .setExecutorInfo("stanceMaint")//执行器名称 .setExecutorTimeout(30)//执行超时时间 - .setBlockStrategy(JobBlockStrategyEnum.CONCURRENCY)//阻塞策略:并发 + .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行 .setMaxRetryTimes(2)//最大重试次数 .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron .setTriggerInterval(bo.getCronExpression())//间隔时长: cron表达式 - .setRetryInterval(3)//重试间隔时长 + .setRetryInterval(10)//重试间隔时长 .setArgsStr("planMaintCode") .setExtAttrs(planMaintCode) .setUserId(LoginHelper.getUserId().toString())