diff --git a/flowable/jsonTemplate/简单串行流程.json b/flowable/jsonTemplate/简单串行流程.json new file mode 100644 index 00000000..99090197 --- /dev/null +++ b/flowable/jsonTemplate/简单串行流程.json @@ -0,0 +1,76 @@ +{ + "process": { + "id": "simplified_process_001", + "name": "简化版-串行流程:本地应用+HPC+导出报告" + }, + "flowElements": [ + { + "id": "start", + "type": "startEvent", + "name": "开始", + "outgoingFlows": ["flow1"] + }, + { + "id": "task_localApp", + "type": "userTask", + "name": "本地应用操作", + "incomingFlows": ["flow1"], + "outgoingFlows": ["flow2"] + }, + { + "id": "task_HPC", + "type": "serviceTask", + "name": "执行HPC任务", + "incomingFlows": ["flow2"], + "outgoingFlows": ["flow3"], + "extensionElements": { + "executeConfig": { + "executeType": "HPC", + "asyncCallback": true + } + } + }, + { + "id": "task_exportReport", + "type": "serviceTask", + "name": "生成报告脚本", + "incomingFlows": ["flow3"], + "outgoingFlows": ["flow4"], + "extensionElements": { + "executeConfig": { + "executeType": "exportWordScript" + } + } + }, + { + "id": "end", + "type": "endEvent", + "name": "结束", + "incomingFlows": ["flow4"] + }, + { + "id": "flow1", + "type": "sequenceFlow", + "sourceRef": "start", + "targetRef": "task_localApp" + }, + { + "id": "flow2", + "type": "sequenceFlow", + "sourceRef": "task_localApp", + "targetRef": "task_HPC" + }, + { + "id": "flow3", + "type": "sequenceFlow", + "sourceRef": "task_HPC", + "targetRef": "task_exportReport" + }, + { + "id": "flow4", + "type": "sequenceFlow", + "sourceRef": "task_exportReport", + "targetRef": "end" + } + ] +} \ No newline at end of file diff --git a/flowable/src/main/resources/flow.json b/flowable/jsonTemplate/网关串并行+人工节点+异步回调混合流程.json similarity index 100% rename from flowable/src/main/resources/flow.json rename to flowable/jsonTemplate/网关串并行+人工节点+异步回调混合流程.json diff --git a/flowable/sql/process_node_param.sql b/flowable/sql/process_node_param.sql index 8c0dc373..920ef1ff 100644 --- a/flowable/sql/process_node_param.sql +++ b/flowable/sql/process_node_param.sql @@ -1,6 +1,7 @@ CREATE TABLE `flowable`.`process_node_param` ( `id` bigint NOT NULL AUTO_INCREMENT, + `processDefinitionId` varchar(64) DEFAULT NULL COMMENT '流程定义ID', `processInstanceId` varchar(64) DEFAULT NULL COMMENT '流程实例ID', `nodeId` varchar(64) DEFAULT NULL COMMENT '节点ID', `paramJson` text COMMENT '输入参数JSON', diff --git a/flowable/src/main/java/com/sdm/flowable/controller/ProcessController.java b/flowable/src/main/java/com/sdm/flowable/controller/ProcessController.java index 3696242f..1d8c6ebd 100644 --- a/flowable/src/main/java/com/sdm/flowable/controller/ProcessController.java +++ b/flowable/src/main/java/com/sdm/flowable/controller/ProcessController.java @@ -3,15 +3,16 @@ package com.sdm.flowable.controller; import com.fasterxml.jackson.databind.ObjectMapper; import com.sdm.common.common.SdmResponse; import com.sdm.common.feign.inter.flowable.IFlowableFeignClient; -import com.sdm.flowable.delegate.UniversalDelegate; import com.sdm.flowable.delegate.handler.HpcHandler; import com.sdm.flowable.dto.ProcessDefinitionDTO; import com.sdm.flowable.dto.req.AsyncCallbackRequest; import com.sdm.flowable.dto.req.CompleteTaskReq; import com.sdm.flowable.dto.req.RetryRequest; import com.sdm.common.entity.resp.flowable.ProcessInstanceResp; +import com.sdm.flowable.dto.resp.DeployFlowableResp; import com.sdm.flowable.process.ProcessService; import com.sdm.flowable.service.IProcessNodeParamService; +import lombok.extern.slf4j.Slf4j; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.Deployment; import org.flowable.engine.runtime.ProcessInstance; @@ -23,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +@Slf4j @RestController @RequestMapping("/process") public class ProcessController implements IFlowableFeignClient { @@ -68,20 +70,13 @@ public class ProcessController implements IFlowableFeignClient { // 部署流程 @PostMapping("/deploy") - public Map deploy(@RequestBody ProcessDefinitionDTO processDTO) { - Map result = new HashMap<>(); - + public SdmResponse deploy(@RequestBody ProcessDefinitionDTO processDTO) { try { - Deployment deployment = processService.deploy(processDTO); - result.put("success", true); - result.put("deploymentId", deployment.getId()); - result.put("deploymentName", deployment.getName()); + return processService.deploy(processDTO); } catch (Exception e) { - result.put("success", false); - result.put("message", "部署失败: " + e.getMessage()); + log.error("流程部署失败: ", e); + return SdmResponse.failed("流程部署失败"); } - - return result; } /** @@ -108,28 +103,14 @@ public class ProcessController implements IFlowableFeignClient { /** * 获取部署的流程定义元数据信息 - * 1、查询所有流程定义(所有版本) - * 2、查询所有流程的"最新版本" - * 3、查询某个流程的所有版本 - * 4、查询某个流程的最新版本 - * 5、查询版本从大到小 * - * @param processDefinitionKey - * @param latest - * @param order - * @param page - * @param size + * @param processDefinitionId * @return */ @GetMapping("/listProcessDefinitionsMetaInfo") - public Map listProcessDefinitionsMetaInfo( - @RequestParam(required = false) String processDefinitionKey, - @RequestParam(defaultValue = "false") boolean latest, - @RequestParam(defaultValue = "asc") String order, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "20") int size) { + public SdmResponse listProcessDefinitionsMetaInfo(@RequestParam String processDefinitionId) { - return processService.listProcessDefinitionsMetaInfo(processDefinitionKey, latest, order, page, size); + return processService.listProcessDefinitionsMetaInfo(processDefinitionId); } /** @@ -160,11 +141,17 @@ public class ProcessController implements IFlowableFeignClient { } - // 保存节点用户输入参数(基于流程定义ID,作为参数模板) + // 保存节点用户输入参数(先基于流程定义ID,等流程启动后,保存流程实例ID,作为参数模板) @PostMapping("/saveParamsByDefinitionId") public void saveParamsByDefinitionId(@RequestParam String processDefinitionId, @RequestParam String nodeId, @RequestBody Map params) { - processNodeParamService.saveParamByDefinitionId(processDefinitionId, nodeId, params); + processNodeParamService.saveParamByProcessDefinitionId(processDefinitionId, nodeId, params); + } + + // 启动流程实例后,更新流程参数的流程实例id + @PostMapping("/updateNodeParamProcessInstanceId") + public void updateNodeParamProcessInstanceId(@RequestParam String processDefinitionId, @RequestParam String processInstanceId) { + processNodeParamService.updateNodeParamProcessInstanceId(processInstanceId, processDefinitionId); } // 启动流程实例 @@ -236,7 +223,7 @@ public class ProcessController implements IFlowableFeignClient { } /** - * 流程节点继续执行(完成人工节点/或者等待用户输入后继续手动执行的节点) + * 流程节点继续执行(完成人工节点/或者等待用户输入后继续手动执行的节点) * * @param req * @return @@ -256,11 +243,11 @@ public class ProcessController implements IFlowableFeignClient { // 发送信号唤醒流程实例中等待的节点 processService.asyncCallback(request); } - + /** * 用户点击"重试"按钮,传入目标节点ID * - * @param request 重试请求参数,包括流程实例ID、目标节点ID和新变量 + * @param request 重试请求参数,包括流程实例ID、目标节点ID和新变量 * @return 重试结果 */ @PostMapping("/retryToNode") diff --git a/flowable/src/main/java/com/sdm/flowable/dto/resp/DeployFlowableResp.java b/flowable/src/main/java/com/sdm/flowable/dto/resp/DeployFlowableResp.java new file mode 100644 index 00000000..2dd85a8b --- /dev/null +++ b/flowable/src/main/java/com/sdm/flowable/dto/resp/DeployFlowableResp.java @@ -0,0 +1,11 @@ +package com.sdm.flowable.dto.resp; + +import lombok.Data; + +@Data +public class DeployFlowableResp { + String deploymentId; + String deploymentName; + String processDefinitionId; + String processDefinitionKey; +} diff --git a/flowable/src/main/java/com/sdm/flowable/entity/ProcessNodeParam.java b/flowable/src/main/java/com/sdm/flowable/entity/ProcessNodeParam.java index 9a4af5a4..4c25d3f7 100644 --- a/flowable/src/main/java/com/sdm/flowable/entity/ProcessNodeParam.java +++ b/flowable/src/main/java/com/sdm/flowable/entity/ProcessNodeParam.java @@ -32,6 +32,10 @@ public class ProcessNodeParam implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + @ApiModelProperty(value = "流程定义ID") + @TableField("processDefinitionId") + private String processDefinitionId; + @ApiModelProperty(value = "流程实例ID") @TableField("processInstanceId") private String processInstanceId; diff --git a/flowable/src/main/java/com/sdm/flowable/process/ProcessService.java b/flowable/src/main/java/com/sdm/flowable/process/ProcessService.java index 83765898..72280ced 100644 --- a/flowable/src/main/java/com/sdm/flowable/process/ProcessService.java +++ b/flowable/src/main/java/com/sdm/flowable/process/ProcessService.java @@ -1,11 +1,13 @@ package com.sdm.flowable.process; import com.fasterxml.jackson.core.JsonProcessingException; +import com.sdm.common.common.SdmResponse; import com.sdm.flowable.constants.FlowableConfig; import com.sdm.flowable.delegate.UniversalDelegate; import com.sdm.flowable.dto.ProcessDefinitionDTO; import com.sdm.flowable.dto.req.AsyncCallbackRequest; import com.sdm.flowable.dto.req.RetryRequest; +import com.sdm.flowable.dto.resp.DeployFlowableResp; import com.sdm.flowable.enums.FlowElementTypeEnums; import com.sdm.flowable.util.Dto2BpmnConverter; import com.sdm.flowable.constants.FlowableConfig; @@ -58,7 +60,7 @@ public class ProcessService { private UniversalDelegate universalDelegate; // 部署流程(前端传入Flowable标准JSON) - public Deployment deploy(ProcessDefinitionDTO processDTO) throws Exception { + public SdmResponse deploy(ProcessDefinitionDTO processDTO) throws Exception { log.info("开始部署流程定义"); BpmnModel bpmnModel = dto2BpmnConverter.convert(processDTO); log.info("BPMN模型转换完成"); @@ -66,7 +68,7 @@ public class ProcessService { // 检查BPMN模型是否有效 if (bpmnModel.getProcesses().isEmpty()) { log.error("无效的BPMN模型:未找到任何流程定义"); - throw new RuntimeException("无效的BPMN模型:未找到任何流程定义"); + return SdmResponse.failed("无效的BPMN模型:未找到任何流程定义"); } // 验证BPMN模型 @@ -78,7 +80,7 @@ public class ProcessService { errorMsg.append("\n - ").append(error.toString()); } log.error("BPMN模型验证失败: {}", errorMsg.toString()); - throw new RuntimeException(errorMsg.toString()); + return SdmResponse.failed("BPMN模型验证失败"); } Deployment deployment = repositoryService.createDeployment() @@ -87,7 +89,20 @@ public class ProcessService { .deploy(); log.info("流程部署成功, 部署ID: {}, 部署名称: {}", deployment.getId(), deployment.getName()); - return deployment; + // 查询该部署下的流程定义(假设只部署了一个流程) + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .deploymentId(deployment.getId()) + .singleResult(); + + if (processDefinition == null) { + return SdmResponse.failed("部署成功,但未找到关联的流程定义"); + } + DeployFlowableResp resp = new DeployFlowableResp(); + resp.setDeploymentId(deployment.getId()); + resp.setDeploymentName(deployment.getName()); + resp.setProcessDefinitionId(processDefinition.getId()); + resp.setProcessDefinitionKey(processDefinition.getKey()); + return SdmResponse.success(resp); } public List> listAllDeployments() { @@ -130,69 +145,9 @@ public class ProcessService { .collect(Collectors.toList()); } - public Map listProcessDefinitionsMetaInfo( - String processDefinitionKey, - boolean latest, - String order, - int page, - int size) { - - ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery(); - - // 可选流程 key - if (processDefinitionKey != null && !processDefinitionKey.isEmpty()) { - query.processDefinitionKey(processDefinitionKey); - } - - // 是否只查最新版本 - if (latest) { - query.latestVersion(); - } - - // 排序 - if ("desc".equalsIgnoreCase(order)) { - query.orderByProcessDefinitionVersion().desc(); - } else { - query.orderByProcessDefinitionVersion().asc(); - } - - // 总记录数 - long total = query.count(); - - // 分页查询 - List list = query.listPage(page * size, size); - - // 转换成 DTO - List> data = list.stream() - .map(pd -> { - Map info = new HashMap<>(); - info.put("id", pd.getId()); - info.put("key", pd.getKey()); - info.put("name", pd.getName()); - info.put("version", pd.getVersion()); - info.put("deploymentId", pd.getDeploymentId()); - info.put("resourceName", pd.getResourceName()); - info.put("diagramResourceName", pd.getDiagramResourceName()); - info.put("suspended", pd.isSuspended()); - - // 获取部署时间 - Deployment dep = repositoryService.createDeploymentQuery() - .deploymentId(pd.getDeploymentId()) - .singleResult(); - info.put("deploymentTime", dep != null ? dep.getDeploymentTime() : null); - - return info; - }) - .collect(Collectors.toList()); - - // 返回分页信息 - Map result = new HashMap<>(); - result.put("total", total); - result.put("page", page); - result.put("size", size); - result.put("data", data); - - return result; + public SdmResponse listProcessDefinitionsMetaInfo(String processDefinitionId) { + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); + return SdmResponse.success(processDefinition); } public List> listNodesByProcessDefinitionKey( @@ -342,12 +297,12 @@ public class ProcessService { } // 获取BPMN模型用于调试和验证 - public BpmnModel getBpmnModel(ProcessDefinitionDTO processDTO) throws JsonProcessingException { + public BpmnModel getBpmnModel(ProcessDefinitionDTO processDTO) throws Exception { return dto2BpmnConverter.convert(processDTO); } // 验证并返回模型验证错误信息 - public List validateModel(ProcessDefinitionDTO processDTO) throws JsonProcessingException { + public List validateModel(ProcessDefinitionDTO processDTO) throws Exception { BpmnModel bpmnModel = dto2BpmnConverter.convert(processDTO); ProcessValidator validator = new ProcessValidatorFactory().createDefaultProcessValidator(); return validator.validate(bpmnModel); diff --git a/flowable/src/main/java/com/sdm/flowable/service/IProcessNodeParamService.java b/flowable/src/main/java/com/sdm/flowable/service/IProcessNodeParamService.java index f2949924..3fe1a370 100644 --- a/flowable/src/main/java/com/sdm/flowable/service/IProcessNodeParamService.java +++ b/flowable/src/main/java/com/sdm/flowable/service/IProcessNodeParamService.java @@ -14,6 +14,7 @@ import java.util.Map; * @since 2025-11-25 */ public interface IProcessNodeParamService extends IService { - void saveParamByDefinitionId(String processDefinitionId, String nodeId, Map params); + void saveParamByProcessDefinitionId(String processDefinitionId, String nodeId, Map params); + void updateNodeParamProcessInstanceId(String processInstanceId, String processDefinitionId); Map getParam(String procInstId, String nodeId); } \ No newline at end of file diff --git a/flowable/src/main/java/com/sdm/flowable/service/impl/ProcessNodeParamServiceImpl.java b/flowable/src/main/java/com/sdm/flowable/service/impl/ProcessNodeParamServiceImpl.java index 19e0a361..6d6d4584 100644 --- a/flowable/src/main/java/com/sdm/flowable/service/impl/ProcessNodeParamServiceImpl.java +++ b/flowable/src/main/java/com/sdm/flowable/service/impl/ProcessNodeParamServiceImpl.java @@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -34,9 +33,9 @@ public class ProcessNodeParamServiceImpl extends ServiceImpl params) { + public void saveParamByProcessDefinitionId(String processDefinitionId, String nodeId, Map params) { ProcessNodeParam param = new ProcessNodeParam(); - param.setProcessInstanceId(processInstanceId); + param.setProcessDefinitionId(processDefinitionId); param.setNodeId(nodeId); try { param.setParamJson(objectMapper.writeValueAsString(params)); @@ -44,7 +43,7 @@ public class ProcessNodeParamServiceImpl extends ServiceImpl getParam(String procInstId, String nodeId) { ProcessNodeParam param = this.lambdaQuery().eq(ProcessNodeParam::getProcessInstanceId, procInstId) diff --git a/flowable/src/main/java/com/sdm/flowable/util/Dto2BpmnConverter.java b/flowable/src/main/java/com/sdm/flowable/util/Dto2BpmnConverter.java index 8caafb3a..6c60c614 100644 --- a/flowable/src/main/java/com/sdm/flowable/util/Dto2BpmnConverter.java +++ b/flowable/src/main/java/com/sdm/flowable/util/Dto2BpmnConverter.java @@ -387,16 +387,18 @@ public class Dto2BpmnConverter { userTask.setName(nodeDto.getName()); // 绑定控制参数(和 ServiceTask 类似) - BaseExecuteConfig userTaskExecuteConfig = nodeDto.getExtensionElements().getExecuteConfig(); - // 设置异步回调节点ID - userTaskExecuteConfig.setCallbackNodeId(asyncTaskMap.getOrDefault(nodeDto.getId(), null)); - if (userTaskExecuteConfig != null) { + if (nodeDto.getExtensionElements() != null && nodeDto.getExtensionElements().getExecuteConfig() != null) { + BaseExecuteConfig userTaskExecuteConfig = nodeDto.getExtensionElements().getExecuteConfig(); + // 设置异步回调节点ID + userTaskExecuteConfig.setCallbackNodeId(asyncTaskMap.getOrDefault(nodeDto.getId(), null)); + String configJson = objectMapper.writeValueAsString(userTaskExecuteConfig); ExtensionElement extensionElement = createFlowableElement( FlowableConfig.EXECUTECONFIG, configJson); userTask.getExtensionElements() .computeIfAbsent(FlowableConfig.EXECUTECONFIG, k -> new ArrayList<>()) .add(extensionElement); + } // 设置用户任务的属性,使其可以被任何人处理 // 不设置 assignee 或 candidateUsers,这样任何人都可以处理任务 @@ -416,15 +418,17 @@ public class Dto2BpmnConverter { serviceTask.setImplementation("${universalDelegate}"); serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); - // 添加 Flowable 扩展属性 - BaseExecuteConfig serviceTaskExecuteConfig = nodeDto.getExtensionElements().getExecuteConfig(); - // 设置异步回调节点ID - serviceTaskExecuteConfig.setCallbackNodeId(asyncTaskMap.getOrDefault(nodeDto.getId(), null)); - if (serviceTaskExecuteConfig != null) { + if (nodeDto.getExtensionElements() != null && nodeDto.getExtensionElements().getExecuteConfig() != null) { + // 添加 Flowable 扩展属性 + BaseExecuteConfig serviceTaskExecuteConfig = nodeDto.getExtensionElements().getExecuteConfig(); + // 设置异步回调节点ID + serviceTaskExecuteConfig.setCallbackNodeId(asyncTaskMap.getOrDefault(nodeDto.getId(), null)); + String configJson = objectMapper.writeValueAsString(serviceTaskExecuteConfig); ExtensionElement extensionElement = createFlowableElement(FlowableConfig.EXECUTECONFIG, configJson); serviceTask.getExtensionElements().computeIfAbsent(FlowableConfig.EXECUTECONFIG, k -> new ArrayList<>()) .add(extensionElement); + } process.addFlowElement(serviceTask); diff --git a/flowable/src/main/resources/bin/log.sh b/flowable/src/main/resources/bin/log.sh new file mode 100644 index 00000000..e69de29b diff --git a/flowable/src/main/resources/bin/restart.sh b/flowable/src/main/resources/bin/restart.sh new file mode 100644 index 00000000..17bb2695 --- /dev/null +++ b/flowable/src/main/resources/bin/restart.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Spring Boot 项目重启脚本 + +# 定义基础路径(公共参数) +BASE_DIR="/home/app/flowable" + +echo "=== 开始重启项目 ===" + +# 先停止服务 +if [ -f "${BASE_DIR}/stop.sh" ]; then + "${BASE_DIR}/stop.sh" +else + echo "错误:未找到停止脚本 ${BASE_DIR}/stop.sh" + exit 1 +fi + +# 再启动服务 +if [ -f "${BASE_DIR}/start.sh" ]; then + "${BASE_DIR}/start.sh" +else + echo "错误:未找到启动脚本 ${BASE_DIR}/start.sh" + exit 1 +fi + +echo "=== 重启操作完成 ===" \ No newline at end of file diff --git a/flowable/src/main/resources/bin/start.sh b/flowable/src/main/resources/bin/start.sh new file mode 100644 index 00000000..f650b1ad --- /dev/null +++ b/flowable/src/main/resources/bin/start.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Spring Boot 项目启动脚本 +JAR_PATH="/home/app/flowable" +JAR_NAME="flowable-0.0.1-SNAPSHOT.jar" +FULL_JAR_PATH="${JAR_PATH}/${JAR_NAME}" + +# 与logback.xml保持一致的日志路径 +LOG_HOME="/home/app/flowable/logs" +LOG_FILE="${LOG_HOME}/running.log" + +# JVM参数 +JVM_OPTS="-Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_HOME}/heapdump.hprof" + +# 函数定义 +check_jar_exists() { + if [ ! -f "${FULL_JAR_PATH}" ]; then + echo "ERROR: Jar包不存在!路径:${FULL_JAR_PATH}" + exit 1 + fi +} + +get_running_pid() { + ps -ef | grep "${JAR_NAME}" | grep -v "grep" | awk '{print $2}' +} + +# 检查是否已运行 +PID=$(get_running_pid) +if [ -n "${PID}" ]; then + echo "项目已在运行中!PID: ${PID}" + exit 0 +fi + +# 检查Jar包是否存在 +check_jar_exists + +# 确保日志目录存在 +if [ ! -d "${LOG_HOME}" ]; then + mkdir -p "${LOG_HOME}" + echo "日志目录不存在,已自动创建:${LOG_HOME}" +fi + + +# 启动项目 +echo "正在启动项目..." +nohup java ${JVM_OPTS} -Dspring.profiles.active=dev -jar "${FULL_JAR_PATH}" > "${LOG_FILE}" 2>&1 & diff --git a/flowable/src/main/resources/bin/status.sh b/flowable/src/main/resources/bin/status.sh new file mode 100644 index 00000000..251f861a --- /dev/null +++ b/flowable/src/main/resources/bin/status.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Spring Boot 项目状态查询脚本 +JAR_NAME="flowable-0.0.1-SNAPSHOT.jar" +LOG_HOME="/home/app/flowable/logs" +LOG_FILE="${LOG_HOME}/running.log" + + +# 函数定义 +get_running_pid() { + ps -ef | grep "${JAR_NAME}" | grep -v "grep" | awk '{print $2}' +} + +# 查看服务状态 +PID=$(get_running_pid) +if [ -n "${PID}" ]; then + echo "项目运行中!PID: ${PID}" + echo "日志文件路径:${LOG_FILE}" +else + echo "项目未在运行中" +fi diff --git a/flowable/src/main/resources/bin/stop.sh b/flowable/src/main/resources/bin/stop.sh new file mode 100644 index 00000000..e69de29b