From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-flowable/jnpf-flowable-entity/src/main/java/jnpf/flowable/model/flowable/FlowAbleUrl.java | 461 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 461 insertions(+), 0 deletions(-)
diff --git a/jnpf-flowable/jnpf-flowable-entity/src/main/java/jnpf/flowable/model/flowable/FlowAbleUrl.java b/jnpf-flowable/jnpf-flowable-entity/src/main/java/jnpf/flowable/model/flowable/FlowAbleUrl.java
new file mode 100644
index 0000000..86fb39c
--- /dev/null
+++ b/jnpf-flowable/jnpf-flowable-entity/src/main/java/jnpf/flowable/model/flowable/FlowAbleUrl.java
@@ -0,0 +1,461 @@
+package jnpf.flowable.model.flowable;
+
+import com.alibaba.fastjson.JSONObject;
+import jnpf.config.ConfigValueUtil;
+import jnpf.constant.MsgCode;
+import jnpf.exception.WorkFlowException;
+import jnpf.util.JsonUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UserProvider;
+import jnpf.util.text.CharsetKit;
+import jnpf.util.wxutil.HttpUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class FlowAbleUrl {
+
+
+ private final ConfigValueUtil configValueUtil;
+
+ public static final String DEPLOYMENT_ID = "?deploymentId=";
+ public static final String TASK_ID = "?taskId=";
+ public static final String TASK_KEY = "&taskKey=";
+
+ public String deployFlowAble(String flowXml, String key) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/definition/deploy";
+ FlowAbleForm flowAbleForm = new FlowAbleForm();
+ flowAbleForm.setKey(key);
+ try {
+ flowAbleForm.setBpmnXml(URLDecoder.decode(flowXml, CharsetKit.UTF_8));
+ } catch (Exception e) {
+ flowAbleForm.setBpmnXml(flowXml);
+ }
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(flowAbleForm));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF090.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ FlowAbleData data = JsonUtil.getJsonToBean(flowAbleModel.getData(), FlowAbleData.class);
+ return data.getDeploymentId();
+ }
+
+ private String getFlowAbleUrl() {
+ return configValueUtil.getFlowDomain();
+ }
+
+ /**
+ * 寮曟搸 HTTP 璋冪敤缁熶竴鍑哄彛锛氬湪鍘� HttpUtil.httpRequest 澶栬褰曞線杩旇�楁椂锛�
+ * 鏃ュ織鏍囪 [flow-engine-timing]锛屼笌寮曟搸渚� [engine-timing] 鐩稿噺鍗� HTTP 缂栨帓寮�閿�锛�
+ * 涓�"鏄惁鍐呭祵寮曟搸"鍐崇瓥绉疮鏁版嵁锛坱asks/handoff-20260609-flow-engine-perf.md锛夈��
+ * 寮傚父涓庤繑鍥炲�煎師鏍烽�忎紶锛宖inally 鍙璁℃椂涓嶆敼鍙樹换浣曡涓恒��
+ */
+ private JSONObject request(String url, String method, String body) {
+ long start = System.nanoTime();
+ JSONObject result = null;
+ try {
+ result = HttpUtil.httpRequest(url, method, body, UserProvider.getToken());
+ return result;
+ } finally {
+ long costMs = (System.nanoTime() - start) / 1_000_000;
+ log.info("[flow-engine-timing] {} {} {}ms success={}", method, endpointPattern(url), costMs, isBizSuccess(result));
+ }
+ }
+
+ /**
+ * 鍙� /api/Flow 璧峰鐨勭鐐规ā寮忥紙鍘诲煙鍚嶄笌 query锛屽苟鎶� ID 璺緞娈佃鏁翠负 {id}锛夛紝
+ * 浣挎棩蹇楀彲鎸夌鐐硅仛鍚堛�佷笖涓嶆硠闇插疄渚�/浠诲姟涓氬姟鏍囪瘑銆�
+ */
+ private String endpointPattern(String url) {
+ int i = url.indexOf("/api/Flow");
+ String path = i < 0 ? url : url.substring(i);
+ int q = path.indexOf('?');
+ if (q >= 0) {
+ path = path.substring(0, q);
+ }
+ // UUID锛堝紩鎿庝富閿洩鑺�/uuid锛変笌绾暟瀛楁缁熶竴鎴� {id}锛岄伩鍏嶉珮鍩烘暟
+ return path.replaceAll("/[0-9a-fA-F]{8}-[0-9a-fA-F-]{27,}", "/{id}")
+ .replaceAll("/\\d{6,}", "/{id}");
+ }
+
+ /** 涓氬姟鏄惁鎴愬姛锛坰uccess!=false 瑙嗕负鎴愬姛锛沶ull 鍝嶅簲璁� false锛夛紝渚涜�楁椂鏃ュ織鍖哄垎鎱笌澶辫触 */
+ private boolean isBizSuccess(JSONObject result) {
+ if (result == null) {
+ return false;
+ }
+ Object success = result.get("success");
+ return !Boolean.FALSE.equals(success);
+ }
+
+ /**
+ * 鍚姩娴佺▼瀹炰緥
+ *
+ * @param deploymentId 寮曟搸閮ㄧ讲ID
+ * @param variables 鍙橀噺
+ */
+ public String startInstance(String deploymentId, Map<String, Object> variables) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/instance/start";
+ InstanceStartFo fo = new InstanceStartFo();
+ fo.setDeploymentId(deploymentId);
+ fo.setVariables(variables);
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF091.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ FlowAbleData data = JsonUtil.getJsonToBean(flowAbleModel.getData(), FlowAbleData.class);
+ return data.getInstanceId();
+ }
+
+ /**
+ * 鑾峰彇褰撳墠浠诲姟
+ *
+ * @param instanceId 寮曟搸瀹炰緥ID
+ */
+ public List<FlowableTaskModel> getCurrentTask(String instanceId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/list/" + instanceId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF092.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), FlowableTaskModel.class);
+ }
+
+ /**
+ * 鍒犻櫎娴佺▼瀹炰緥
+ *
+ * @param instanceId 瀹炰緥ID
+ * @param deleteReason 鍒犻櫎鍘熷洜
+ */
+ public void deleteInstance(String instanceId, String deleteReason) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/instance?instanceId=" + instanceId;
+ if (StringUtil.isNotEmpty(deleteReason)) {
+ url += "&deleteReason=" + deleteReason;
+ }
+ JSONObject jsonObject = request(url, "DELETE", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel || !flowAbleModel.getSuccess()) {
+ log.error("娴佺▼瀹炰緥鍒犻櫎寮傚父: {}", flowAbleModel);
+ }
+ }
+
+ /**
+ * 鑾峰彇鍑虹嚎Key闆嗗悎
+ *
+ * @param fo 鍙傛暟绫�
+ */
+ public List<String> getOutgoingFlows(OutgoingFlowsFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/outgoing/flows";
+ if (StringUtil.isNotEmpty(fo.getTaskId())) {
+ url += TASK_ID + fo.getTaskId();
+ } else {
+ url += DEPLOYMENT_ID + fo.getDeploymentId() + TASK_KEY + fo.getTaskKey();
+ }
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF094.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 鑾峰彇绾夸箣鍚庣殑浠诲姟鑺傜偣
+ *
+ * @param deploymentId 閮ㄧ讲id
+ * @param flowKey 杩炴帴绾跨殑Key
+ */
+ public List<String> getTaskKeyAfterFlow(String deploymentId, String flowKey) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/flow/target?deploymentId=" + deploymentId + "&flowKey=" + flowKey;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF095.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 鑾峰彇涓嬩竴绾т换鍔¤妭鐐归泦鍚�
+ *
+ * @param fo 鍙傛暟绫�
+ */
+ public List<FlowableNodeModel> getNext(NextOrPrevFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/next";
+ if (StringUtil.isNotEmpty(fo.getTaskId())) {
+ url += TASK_ID + fo.getTaskId();
+ } else {
+ url += DEPLOYMENT_ID + fo.getDeploymentId() + TASK_KEY + fo.getTaskKey();
+ }
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF096.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), FlowableNodeModel.class);
+ }
+
+ /**
+ * 鑾峰彇涓婁竴绾т换鍔¤妭鐐筰d闆嗗悎
+ *
+ * @param fo 鍙傛暟绫�
+ */
+ public List<String> getPrev(NextOrPrevFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/prev";
+ if (StringUtil.isNotEmpty(fo.getTaskId())) {
+ url += TASK_ID + fo.getTaskId();
+ } else {
+ url += DEPLOYMENT_ID + fo.getDeploymentId() + TASK_KEY + fo.getTaskKey();
+ }
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF097.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 瀹屾垚娴佺▼浠诲姟
+ *
+ * @param fo 鍙傛暟绫�
+ */
+ public void complete(CompleteFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/complete";
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF098.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ }
+
+ /**
+ * 鑾峰彇娴佺▼瀹炰緥
+ *
+ * @param instanceId 瀹炰緥id
+ */
+ public FlowableInstanceModel getInstance(String instanceId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/instance/" + instanceId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF099.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToBean(flowAbleModel.getData(), FlowableInstanceModel.class);
+ }
+
+ /**
+ * 鑾峰彇鏈粡杩囩殑鑺傜偣
+ *
+ * @param instanceId 寮曟搸瀹炰緥涓婚敭
+ */
+ public List<String> getTobePass(String instanceId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/tobe/pass/" + instanceId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF100.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 鑾峰彇鑺傜偣鐨勫悗缁妭鐐�
+ *
+ * @param fo 鍙傛暟
+ */
+ public List<String> getAfter(AfterFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/after";
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF101.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 鑾峰彇鍙洖閫�鐨勮妭鐐笽D
+ *
+ * @param taskId 寮曟搸浠诲姟涓婚敭
+ */
+ public List<String> getFallbacks(String taskId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/fallbacks/" + taskId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF102.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 閫�鍥�
+ *
+ * @param fo 鍙傛暟
+ */
+ public void back(BackFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/back";
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF103.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ }
+
+ /**
+ * 鑺傜偣璺宠浆
+ *
+ * @param fo 鍙傛暟
+ */
+ public void jump(JumpFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/jump";
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF104.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ }
+
+ /**
+ * 浠诲姟瀹屾垚鐨勮ˉ鍋�
+ *
+ * @param fo 鍙傛暟
+ */
+ public List<FlowableTaskModel> compensate(CompensateFo fo) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/compensate";
+ JSONObject jsonObject = request(url, "POST", JsonUtil.getObjectToString(fo));
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error(MsgCode.WF105.get());
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), FlowableTaskModel.class);
+ }
+
+ /**
+ * 鑾峰彇鍘嗗彶鑺傜偣
+ *
+ * @param instanceId 瀹炰緥涓婚敭
+ */
+ public List<FlowableHistoricModel> getHistoric(String instanceId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/historic/" + instanceId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error("鑾峰彇鍘嗗彶鑺傜偣澶辫触");
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), FlowableHistoricModel.class);
+ }
+
+ /**
+ * 鑾峰彇鍘嗗彶缁撴潫鑺傜偣
+ *
+ * @param instanceId 瀹炰緥涓婚敭
+ */
+ public List<String> getHistoricEnd(String instanceId) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/historic/end/" + instanceId;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error("鑾峰彇鍘嗗彶缁撴潫鑺傜偣澶辫触");
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToList(flowAbleModel.getData(), String.class);
+ }
+
+ /**
+ * 鑾峰彇鍏冪礌淇℃伅
+ *
+ * @param deploymentId 閮ㄧ讲id
+ * @param key 鑺傜偣key
+ */
+ public FlowableNodeModel getElementInfo(String deploymentId, String key) throws WorkFlowException {
+ String url = getFlowAbleUrl() + "/api/Flow/task/element/info";
+ url += DEPLOYMENT_ID + deploymentId + "&key=" + key;
+ JSONObject jsonObject = request(url, "GET", null);
+ FlowAbleModel flowAbleModel = JsonUtil.getJsonToBean(jsonObject, FlowAbleModel.class);
+ if (null == flowAbleModel) {
+ log.error("鑾峰彇鍏冪礌淇℃伅澶辫触");
+ throw new WorkFlowException(MsgCode.WF142.get());
+ }
+ if (Boolean.FALSE.equals(flowAbleModel.getSuccess())) {
+ throw new WorkFlowException(flowAbleModel.getMsg());
+ }
+ return JsonUtil.getJsonToBean(flowAbleModel.getData(), FlowableNodeModel.class);
+ }
+}
--
Gitblit v1.8.0