xiSpeak-flow模块
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<artifactId>jeecg-boot-module</artifactId>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<version>${jeecgProjectVersion}</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>jeecg-module-flow</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-boot-base-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-system-local-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-boot-module-bpm-flowable</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-system-biz</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.jeecg;
|
||||||
|
|
||||||
|
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
|
||||||
|
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
|
||||||
|
// 查看 IntelliJ IDEA 建议如何修正。
|
||||||
|
System.out.printf("Hello and welcome!");
|
||||||
|
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
//TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
|
||||||
|
// 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
|
||||||
|
System.out.println("i = " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package org.jeecg.xispeak;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "flow-biz")
|
||||||
|
public class XiSpeakConfig {
|
||||||
|
/**
|
||||||
|
* 对应 yml 中的 xi-speak 节点
|
||||||
|
* Spring 会自动将中划线命名映射为驼峰命名
|
||||||
|
*/
|
||||||
|
private XiSpeakProperties xiSpeak;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class XiSpeakProperties {
|
||||||
|
/** 对应 bg-dept-id */
|
||||||
|
private String bgDeptId;
|
||||||
|
/** 对应 ld-role-id */
|
||||||
|
private String ldRoleId;
|
||||||
|
/** 对应 need-sdw-approve-code */
|
||||||
|
private String needSdwApproveCode;
|
||||||
|
/** 对应 json-data-key */
|
||||||
|
private String jsonDataKey;
|
||||||
|
/** 对应 impl-dept-key */
|
||||||
|
private String implDeptKey;
|
||||||
|
/** 对应impl-dept-collection-used*/
|
||||||
|
private String implDeptCollectionUsedKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package org.jeecg.xispeak;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.shiro.util.StringUtils;
|
||||||
|
import org.flowable.engine.RuntimeService;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component("xiSpeakFlow")
|
||||||
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
|
public class XiSpeakFlow {
|
||||||
|
|
||||||
|
private final XiSpeakConfig xiSpeakConfig;
|
||||||
|
private final ISysBaseAPI iSysBaseAPI;
|
||||||
|
private final RuntimeService runtimeService;
|
||||||
|
|
||||||
|
public List<String> getBgDeptLdUserIdList() {
|
||||||
|
// 1. 安全获取配置,防止 NPE
|
||||||
|
XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak();
|
||||||
|
if (props == null || !StringUtils.hasText(props.getBgDeptId())) {
|
||||||
|
log.error("流程配置缺失: [flow-biz.xi-speak.bg-dept-id] 未在 YAML 中定义");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用接口获取数据
|
||||||
|
log.info("正在查询部门: {} 下的角色: {} 的用户列表", props.getBgDeptId(), props.getLdRoleId());
|
||||||
|
List<String> userList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(
|
||||||
|
props.getBgDeptId(),
|
||||||
|
props.getLdRoleId()
|
||||||
|
);
|
||||||
|
log.info("查询到的用户为: {}", userList);
|
||||||
|
return userList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getNeedSdwApproval(Object jsonData) {
|
||||||
|
XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak();
|
||||||
|
if (jsonData == null || org.apache.commons.lang.StringUtils.isBlank(props.getNeedSdwApproveCode())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String codeName = props.getNeedSdwApproveCode();
|
||||||
|
if (org.apache.commons.lang.StringUtils.isBlank(codeName)) return 0;
|
||||||
|
try {
|
||||||
|
JSONObject data;
|
||||||
|
if (jsonData instanceof JSONObject) {
|
||||||
|
data = (JSONObject) jsonData;
|
||||||
|
} else if (jsonData instanceof String) {
|
||||||
|
if (org.apache.commons.lang.StringUtils.isBlank((String) jsonData)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data = JSONObject.parseObject((String) jsonData);
|
||||||
|
} else {
|
||||||
|
data = JSONObject.parseObject(JSONObject.toJSONString(jsonData));
|
||||||
|
}
|
||||||
|
log.info("needSdwApproval结果为{}", data.getInteger(codeName));
|
||||||
|
return data == null ? 0 : data.getInteger(codeName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("getJsondata parse failed, codeName={}, jsonData={}", codeName, jsonData, e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getImplDeptLdsList(String deptId) {
|
||||||
|
return iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, xiSpeakConfig.getXiSpeak().getLdRoleId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getListSize(String jsonData){
|
||||||
|
if (org.apache.commons.lang3.StringUtils.isEmpty(jsonData)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Math.toIntExact(Arrays.stream(jsonData.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(org.apache.commons.lang3.StringUtils::isNotEmpty)
|
||||||
|
.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
// List<String> getImplDeptWorker(String JG_LOCAL_PROCESS_ID,String deptId){
|
||||||
|
// runtimeService.get
|
||||||
|
// }
|
||||||
|
|
||||||
|
public Integer getImplDeptNums(String jsonData) {
|
||||||
|
String codeName = xiSpeakConfig.getXiSpeak().getImplDeptKey();
|
||||||
|
if (jsonData == null || org.apache.commons.lang.StringUtils.isEmpty(codeName)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 统一转成 JSONObject
|
||||||
|
JSONObject json;
|
||||||
|
json = JSON.parseObject((String) jsonData);
|
||||||
|
|
||||||
|
if (json == null || !json.containsKey(codeName)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取原始对象进行兼容性处理
|
||||||
|
Object value = json.get(codeName);
|
||||||
|
if (value == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> resultList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
// 情况 A: 本身就是集合/JSON数组
|
||||||
|
resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class));
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
// 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3"
|
||||||
|
String str = (String) value;
|
||||||
|
if (org.apache.commons.lang.StringUtils.isNotEmpty(str)) {
|
||||||
|
// 使用 split 拆分,并过滤掉空格和空字符串
|
||||||
|
String[] split = str.split(",");
|
||||||
|
for (String s : split) {
|
||||||
|
if (org.apache.commons.lang.StringUtils.isNotEmpty(s.trim())) {
|
||||||
|
resultList.add(s.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
package org.jeecg.modules.extbpm.listener.execution;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.flowable.engine.RuntimeService;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.delegate.ExecutionListener;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
|
||||||
|
import org.jeecg.xispeak.XiSpeakConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component("AfterSDWApproveHqListener")
|
||||||
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
|
public class AfterSDWApproveHqListener implements ExecutionListener {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final FlowNodeExpression flowNodeExpression;
|
||||||
|
@Autowired
|
||||||
|
private RuntimeService runtimeService;
|
||||||
|
|
||||||
|
private final XiSpeakConfig xiSpeakConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(DelegateExecution execution) {
|
||||||
|
|
||||||
|
XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak();
|
||||||
|
//RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class);
|
||||||
|
String mainProcessId = (String)execution.getProcessInstanceId();
|
||||||
|
String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL);
|
||||||
|
|
||||||
|
// 打印主流程里所有的变量名,看看有没有 json_data
|
||||||
|
Map<String, Object> variables = runtimeService.getVariables(execution.getRootProcessInstanceId());
|
||||||
|
log.info("主流程中的所有变量名: " + variables.keySet());
|
||||||
|
|
||||||
|
// 打印当前执行流的所有变量名
|
||||||
|
log.info("当前执行流的所有变量名: " + execution.getVariables().keySet());
|
||||||
|
|
||||||
|
String bizTitle = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_BIZ_TITLE);
|
||||||
|
|
||||||
|
if(org.apache.commons.lang.StringUtil.isEmpty(url)) {
|
||||||
|
url = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL);
|
||||||
|
String mobileUrl = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE);
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL, url);
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE, mobileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取主流程中的 json_data 对象(可能是 String 或 JSONObject)
|
||||||
|
Object jsonDataObj = (String)runtimeService.getVariable(mainProcessId,props.getJsonDataKey());
|
||||||
|
|
||||||
|
if (oConvertUtils.isNotEmpty(jsonDataObj)) {
|
||||||
|
String json_data = jsonDataObj.toString();
|
||||||
|
try {
|
||||||
|
// 2. 调用表达式解析工具获取特定字段的字符串内容
|
||||||
|
String jsonStr = flowNodeExpression.getJsondatastring(json_data, props.getImplDeptKey());
|
||||||
|
|
||||||
|
// 3. 只有当字段存在且内容不为空时,才进行解析
|
||||||
|
if (oConvertUtils.isNotEmpty(jsonStr)) {
|
||||||
|
List<String> deptIds = Arrays.stream(jsonStr.split(","))
|
||||||
|
.map(String::trim) // 去掉可能存在的空格
|
||||||
|
.filter(s -> !s.isEmpty()) // 过滤掉空字符串
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (deptIds != null && !deptIds.isEmpty()) {
|
||||||
|
// 4. 将提取出的 List 存入子流程变量(供多实例 Collection 使用)
|
||||||
|
execution.setVariable( props.getImplDeptKey(), deptIds);
|
||||||
|
log.info("子流程变量 deptIdList 注入成功: " + deptIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解析 JSON 字段 pending_depts_id 失败: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取主表数据id
|
||||||
|
String businessKey = (String)runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DATA_ID);
|
||||||
|
//获取主表的设计表单数据ID
|
||||||
|
String BPM_DES_DATA_ID = oConvertUtils.getString(runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DES_DATA_ID));
|
||||||
|
|
||||||
|
//获取主表表名
|
||||||
|
String tableName = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_KEY);
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_FORM_KEY, tableName);
|
||||||
|
|
||||||
|
//--update--begin------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题---------
|
||||||
|
//log.info("----------传入子流程的数据ID--------------: "+execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||||
|
if(oConvertUtils.isNotEmpty(execution.getVariable(WorkFlowGlobals.DATA_ID))){
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||||
|
//如果是设计器表单,则还需要设置设计表单数据ID
|
||||||
|
if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//未传入id值,则获取主表数据id给子流程【online表单需要】
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, businessKey);
|
||||||
|
//如果是设计器表单,则还需要设置设计表单数据ID
|
||||||
|
if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){
|
||||||
|
execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, BPM_DES_DATA_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--update--end------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题---------
|
||||||
|
|
||||||
|
//子流程实例set业务号和主流程保持一致
|
||||||
|
runtimeService.updateBusinessKey(execution.getProcessInstanceId(), businessKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
flow-biz:
|
||||||
|
xi-speak:
|
||||||
|
bg-dept-id: "2044677604785229826"
|
||||||
|
ld-role-id: "2044680793306591234"
|
||||||
|
need-sdw-approve-code: "needSdwApproval"
|
||||||
|
json-data-key: "json_data"
|
||||||
|
impl-dept-key: "implDept"
|
||||||
|
impl-dept-collection-used-key: "impl_dept_id"
|
||||||
Reference in New Issue
Block a user