Appearance
指令执行前与执行后扩展开发
指令执行前与执行后方法为默认触发,无需配置。
指令执行前方法配置为 指令:INIT
,例如 SendCommit:INIT
。
指令执行后方法配置为 指令:DESTROY
,例如 FlowSend:DESTROY
。
新建项目
pom.xml 中引入 co-service-macro-sdk-x.x.x.jar
xml
<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>
<groupId>com.kanq</groupId>
<artifactId>co-service-ext</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>co_service_web_ext_demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.kanq</groupId>
<artifactId>co-service-macro-sdk</artifactId>
<version>1.x.x</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<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>
<groupId>com.kanq</groupId>
<artifactId>co-service-ext</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>co_service_web_ext_demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.kanq</groupId>
<artifactId>co-service-macro-sdk</artifactId>
<version>1.x.x</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
扩展接口实现
创建 java 类
com.kanq.FlowDemo
增加
private static byte[] sendCommitInit(byte[] macroHead, byte[][] argv);
流程发送前置处理方法增加指令注册注解
@Macro(name = "SendCommit:INIT", describe = "流程发送前置处理")
增加
private static byte[] flowSendDestroy(byte[] macroHead, byte[][] argv);
流程发送查询接收人后置处理方法增加指令注册注解
@Macro(name = "FlowSend:DESTROY", describe = "流程发送查询接收人后置处理")
注意
- 入参说明:
macroHead
请求头,参数不定,格式:form:2\r\nuser:1
argv
入参参数
- 出参说明:
- 字符串:json 格式
- 文件: 字节流
- 注解说明:
name
指令名称describe
接口描述 :::
macroHead 参数说明
addr
当前用户 IPclient
f: 函数,m:移动动busi
当前业务编号role
当前角色user
当前用户编号stat
当前流程状态tach
当前流程环节flow
当前打开流程form
当前打开表单prev
父级表单tent
指定租户编号trace
链路日志ticket
票据
- FormDemo.java
java
package com.kanq;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.kanq.sdk.config.Macro;
import com.kanq.sdk.impl.ParmImpl;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FlowDemo {
/**
* 流程发送查询接收人后置处理
* @param macroHead
* @param argv
* @return
* @throws JsonProcessingException
*/
@Macro(name = "FlowSend:DESTROY", describe = "流程发送查询接收人后置处理")
private static byte[] flowSendDestroy(byte[] macroHead, byte[][] argv) throws JsonProcessingException {
//获取parm
byte[] parm_byte = argv[1];
String parm = new String(parm_byte,StandardCharsets.UTF_8);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = null;
try {
// 读取 JSON 文件
rootNode = objectMapper.readTree(parm);
// 确保根节点是一个对象
if (rootNode.isObject()) {
// 获取 "tach" 字段,确保它是一个数组
JsonNode tachNode = rootNode.path("tach");
if (tachNode.isArray()) {
ArrayNode tachArray = (ArrayNode) tachNode;
// 遍历数组中的每个对象
for (JsonNode item : tachArray) {
// 检查是否是目标对象
if (item.isObject()) {
// 获取 "children" 字段,确保它是一个数组
JsonNode childrenNode = item.path("children");
if (childrenNode.isArray()) {
ArrayNode childrenArray = (ArrayNode) childrenNode;
// 遍历 children 数组中的每个对象
for (JsonNode child : childrenArray) {
// 检查是否是目标对象
if (child.isObject()) {
// 获取 "children" 字段,确保它是一个数组
JsonNode innerChildrenNode = child.path("children");
if (innerChildrenNode.isArray()) {
ArrayNode innerChildrenArray = (ArrayNode) innerChildrenNode;
// 遍历 innerChildren 数组中的每个对象
for (JsonNode innerChild : innerChildrenArray) {
// 替换指定 text 值
if (innerChild.isObject()
&& innerChild.has("text")
&& innerChild.get("text").asText().equals("Admin")) {
((ObjectNode) innerChild).put("text", "张晓明");
break; // 替换完成后退出循环
}
}
}
}
}
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return objectMapper.writeValueAsBytes(rootNode);
}
/**
* 流程发送前置处理
* @param macroHead
* @param argv
* @return
* @throws JsonProcessingException
*/
@Macro(name = "SendCommit:INIT", describe = "流程发送前置处理")
private static byte[] sendCommitInit(byte[] macroHead, byte[][] argv) throws JsonProcessingException, DocumentException {
ObjectMapper mapper = new ObjectMapper();
// 获取参数
byte[] parm_byte = argv[0];
String parm = new String(parm_byte,StandardCharsets.UTF_8);
// 解析XML
Document document = org.dom4j.DocumentHelper.parseText(parm);
// 获取根节点
Element root = document.getRootElement();
// 设置审批意见
root.addAttribute("msg", "扩展:同意");
// 转换为XML
parm = document.getRootElement().asXML();
// 组装格式
ArrayNode arrayNode = mapper.createArrayNode();
arrayNode.add(parm);
// 返回赋值
ParmImpl parmImpl = new ParmImpl();
parmImpl.setParameter(arrayNode);
return mapper.writeValueAsString(parmImpl).getBytes(StandardCharsets.UTF_8);
}
}
package com.kanq;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.kanq.sdk.config.Macro;
import com.kanq.sdk.impl.ParmImpl;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FlowDemo {
/**
* 流程发送查询接收人后置处理
* @param macroHead
* @param argv
* @return
* @throws JsonProcessingException
*/
@Macro(name = "FlowSend:DESTROY", describe = "流程发送查询接收人后置处理")
private static byte[] flowSendDestroy(byte[] macroHead, byte[][] argv) throws JsonProcessingException {
//获取parm
byte[] parm_byte = argv[1];
String parm = new String(parm_byte,StandardCharsets.UTF_8);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = null;
try {
// 读取 JSON 文件
rootNode = objectMapper.readTree(parm);
// 确保根节点是一个对象
if (rootNode.isObject()) {
// 获取 "tach" 字段,确保它是一个数组
JsonNode tachNode = rootNode.path("tach");
if (tachNode.isArray()) {
ArrayNode tachArray = (ArrayNode) tachNode;
// 遍历数组中的每个对象
for (JsonNode item : tachArray) {
// 检查是否是目标对象
if (item.isObject()) {
// 获取 "children" 字段,确保它是一个数组
JsonNode childrenNode = item.path("children");
if (childrenNode.isArray()) {
ArrayNode childrenArray = (ArrayNode) childrenNode;
// 遍历 children 数组中的每个对象
for (JsonNode child : childrenArray) {
// 检查是否是目标对象
if (child.isObject()) {
// 获取 "children" 字段,确保它是一个数组
JsonNode innerChildrenNode = child.path("children");
if (innerChildrenNode.isArray()) {
ArrayNode innerChildrenArray = (ArrayNode) innerChildrenNode;
// 遍历 innerChildren 数组中的每个对象
for (JsonNode innerChild : innerChildrenArray) {
// 替换指定 text 值
if (innerChild.isObject()
&& innerChild.has("text")
&& innerChild.get("text").asText().equals("Admin")) {
((ObjectNode) innerChild).put("text", "张晓明");
break; // 替换完成后退出循环
}
}
}
}
}
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return objectMapper.writeValueAsBytes(rootNode);
}
/**
* 流程发送前置处理
* @param macroHead
* @param argv
* @return
* @throws JsonProcessingException
*/
@Macro(name = "SendCommit:INIT", describe = "流程发送前置处理")
private static byte[] sendCommitInit(byte[] macroHead, byte[][] argv) throws JsonProcessingException, DocumentException {
ObjectMapper mapper = new ObjectMapper();
// 获取参数
byte[] parm_byte = argv[0];
String parm = new String(parm_byte,StandardCharsets.UTF_8);
// 解析XML
Document document = org.dom4j.DocumentHelper.parseText(parm);
// 获取根节点
Element root = document.getRootElement();
// 设置审批意见
root.addAttribute("msg", "扩展:同意");
// 转换为XML
parm = document.getRootElement().asXML();
// 组装格式
ArrayNode arrayNode = mapper.createArrayNode();
arrayNode.add(parm);
// 返回赋值
ParmImpl parmImpl = new ParmImpl();
parmImpl.setParameter(arrayNode);
return mapper.writeValueAsString(parmImpl).getBytes(StandardCharsets.UTF_8);
}
}
打包
将程序和依赖 jar 分离打包
- 程序保存
./jar/co/
目录下 - 依赖保存
./jar/lib/
目录下
xml
<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>
<groupId>com.kanq</groupId>
<artifactId>co-service-ext</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>co_service_web_ext_demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 打包不含依赖jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- 依赖包导出lib文件夹下 -->
<build>
<finalName>Ext</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.2.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!--<fork>true</fork>-->
<layout>ZIP</layout>
<includes>
<include>
<!-- 排除所有Jar -->
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- ${project.build.directory}是maven变量,内置的,表示target目录,如果不写,将在跟目录下创建/lib -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!-- excludeTransitive:是否不包含间接依赖包,比如我们依赖A,但是A又依赖了B,我们是否也要把B打进去 默认不打-->
<excludeTransitive>false</excludeTransitive>
<!-- 复制的jar文件去掉版本信息 true去掉 false 不去-->
<stripVersion>false</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<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>
<groupId>com.kanq</groupId>
<artifactId>co-service-ext</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>co_service_web_ext_demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 打包不含依赖jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- 依赖包导出lib文件夹下 -->
<build>
<finalName>Ext</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.2.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!--<fork>true</fork>-->
<layout>ZIP</layout>
<includes>
<include>
<!-- 排除所有Jar -->
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- ${project.build.directory}是maven变量,内置的,表示target目录,如果不写,将在跟目录下创建/lib -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!-- excludeTransitive:是否不包含间接依赖包,比如我们依赖A,但是A又依赖了B,我们是否也要把B打进去 默认不打-->
<excludeTransitive>false</excludeTransitive>
<!-- 复制的jar文件去掉版本信息 true去掉 false 不去-->
<stripVersion>false</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
注意
- 新接口需重启 co-service 后才能生效
启动服务
扩展开发注册成功如下:
注意
- co-service 日志级别为 调试
测试初始化 init 处理方法
流程发送前置处理扩展方法前:
流程发送前置处理扩展方法后:
测试后置 destroy 处理方法
流程发送查询接收人后置处理扩展方法前:
流程发送查询接收人后置处理扩展方法后:
本示例代码在 com.kanq.FlowDemo
类中的 flowSendDestroy
、sendCommitInit
方法