2026-01-28 通用流程集成,第三方流程集成demo

This commit is contained in:
2026-01-28 00:25:06 +08:00
parent 6991a074dc
commit 45db1085d1
14 changed files with 621 additions and 56 deletions

View File

@@ -4,8 +4,8 @@ public enum FlowIntegrationConstants {
plugin("src_flowIntegration", "插件ID"),
OA_HOST("","oa地址"),
restName("",""),
restPwd("",""),
restName("","rest用户名"),
restPwd("","rest密码")
;
private String defaultValue;

View File

@@ -0,0 +1,154 @@
package com.seeyon.apps.src_flowIntegration.dao;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.JDBCAgent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SrcFlowDao{
private String getFormIdByTemplateCode = "select form_appid from ctp_template where TEMPLETE_NUMBER = ?";
private String getViewIdByFormId = "select view_id from cap_form_view_info where form_id = ? and view_sore = 1 and view_type = 'seeyonform' and delete_flag = 0";
private String getAuthIdByFormId = "select resource_id from cap_form_auth_info where form_id = ? and type = 'add' and deleted = 0 and default_auth = 1 ";
private String getFieldInfoByFormId = "select field_info from cap_form_definition where id = ?";
private String uniqueDataValidation = "select #{fieldName} from #{tableName} where #{fieldName} = ?";
public String getFormIdByTemplateCode(String templateCode){
String res = "";
JDBCAgent agent = new JDBCAgent();
try {
StringBuilder sql = new StringBuilder(getFormIdByTemplateCode);
List<Object> p = new ArrayList<Object>();
p.add(templateCode);
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
if (list != null && list.size() > 0) {
Map<String,Object> map = list.get(0);
Object obj = map.get("form_appid");
res = obj!=null?obj.toString():"";
}
} catch (BusinessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (agent != null) {
agent.close();
}
}
return res;
}
public String getViewIdByFormId(String formId){
String res = "";
JDBCAgent agent = new JDBCAgent();
try {
StringBuilder sql = new StringBuilder(getViewIdByFormId);
List<Object> p = new ArrayList<Object>();
p.add(formId);
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
if (list != null && list.size() > 0) {
Map<String,Object> map = list.get(0);
Object obj = map.get("view_id");
res = obj!=null?obj.toString():"";
}
} catch (BusinessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (agent != null) {
agent.close();
}
}
return res;
}
public String getAuthIdByFormId(String formId){
String res = "";
JDBCAgent agent = new JDBCAgent();
try {
StringBuilder sql = new StringBuilder(getAuthIdByFormId);
List<Object> p = new ArrayList<Object>();
p.add(formId);
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
if (list != null && list.size() > 0) {
Map<String,Object> map = list.get(0);
Object obj = map.get("resource_id");
res = obj!=null?obj.toString():"";
}
} catch (BusinessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (agent != null) {
agent.close();
}
}
return res;
}
public String getFieldInfoByFormId(String formId){
String res = "";
JDBCAgent agent = new JDBCAgent();
try {
StringBuilder sql = new StringBuilder(getFieldInfoByFormId);
List<Object> p = new ArrayList<Object>();
p.add(formId);
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
if (list != null && list.size() > 0) {
Map<String,Object> map = list.get(0);
Object obj = map.get("field_info");
res = obj!=null?obj.toString():"";
}
} catch (BusinessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (agent != null) {
agent.close();
}
}
return res;
}
public String uniqueDataValidation (String tableName,String fieldName,String flowId){
String res = "";
JDBCAgent agent = new JDBCAgent();
try {
StringBuilder sql = new StringBuilder(uniqueDataValidation);
String replacedStr = sql.toString().replace("#{tableName}", tableName).replace("#{fieldName}", fieldName);
sql = new StringBuilder(replacedStr);
List<Object> p = new ArrayList<Object>();
p.add(flowId);
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
if (list != null && list.size() > 0) {
Map<String,Object> map = list.get(0);
Object obj = map.get(fieldName);
res = obj!=null?obj.toString():"";
}
} catch (BusinessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (agent != null) {
agent.close();
}
}
return res;
}
}

View File

@@ -0,0 +1,89 @@
package com.seeyon.apps.src_flowIntegration.node;
import cn.hutool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.common.config.ICstConfigApi;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.common.workflow.constants.WorkFlowType;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.apps.src_flowIntegration.constants.FlowIntegrationConstants;
import com.seeyon.apps.src_flowIntegration.util.AesUtil;
import com.seeyon.apps.src_flowIntegration.util.SignUtil;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.utils.http.HttpClient;
import java.util.Date;
import java.util.HashMap;
public class FlowStatusCallbackNode extends ACommonSuperNode {
private static Log log = Log.get(FlowStatusCallbackNode.class);
protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");
@Override
public String getNodeId() {
return "FlowStatusCallbackNode";
}
@Override
public String getNodeName() {
return "通用流程状态返回接口";
}
@Override
public String getPluginId() {
return FlowIntegrationConstants.getPluginId();
}
@Override
public String getFormParse() {
return "json";
}
@Override
public WorkFlowType[] getTypes() {
return new WorkFlowType[] {WorkFlowType.superNode};
}
public ConfigVo getFlowIntegrationConfig() {
return cstConfigApi.getConfig(getPluginId());
}
@Override
public SuperNodeContext proceed(String request, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
ConfigVo configVo = getFlowIntegrationConfig();
SuperNodeContext context = new SuperNodeContext();
JSONObject req = JSONObject.parseObject(request);
String url = req.getString("flowStatusCallbackUrl");
JSONObject datajson = new JSONObject();
datajson.put("thirdFlowId",req.getString("thirdFlowId"));
datajson.put("flowStatus","1");
datajson.put("remark","流程结束");
// 进行请求参数加密
String datastr = datajson.toString();
// 当前先试用简单关键字
String encrypted = AesUtil.encrypt(datastr,"1234567890abcdef","abcdef1234567890");
long timestamp = new Date().getTime();
String nonce = "asdhsalda";
String secretKey = "123123123";
String signContent = encrypted + timestamp + nonce + secretKey;
String sign = SignUtil.sha256(signContent);
JSONObject param = new JSONObject();
param.put("data",encrypted);
param.put("timestamp",timestamp+"");
param.put("nonce",nonce);
param.put("sign",sign);
// 调通接口推送数据到第三方系统
String res = HttpClient.httpPostRaw(url,param.toString(),new HashMap<String,String>(), null);
return context;
}
}

View File

@@ -2,6 +2,7 @@ package com.seeyon.apps.src_flowIntegration.service;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import www.seeyon.com.utils.StringUtil;
import java.util.List;
import java.util.Map;
@@ -14,24 +15,44 @@ public class FlowIntegrationService {
@Autowired
private OaFlowCreateService oaFlowCreateService;
public String thirdFlowCreate(JSONObject jsonObject) throws Exception {
public JSONObject thirdFlowCreate(JSONObject jsonObject,String token) throws Exception {
JSONObject res = new JSONObject();
String tirdFlowId = jsonObject.getString("thirdFlowId");
String flowStatusCallbackUrl = jsonObject.getString("flowStatusCallbackUrl");
String flowAuditStatusCallbackUrl = jsonObject.getString("flowAuditStatusCallbackUrl");
String flowBizCode = jsonObject.getString("flowBizCode");
String flowCreator = jsonObject.getString("flowCreator");
Map<String,Object> data = (Map<String, Object>) jsonObject.get("data");
Map<String, String> map = thirdSysBizMapService.getOaFlowTemplateInfoByBizCode(flowBizCode);
String appName = map.get("appName");
String templateCode = map.get("templateCode");
String flowName = map.get("flowName");
Map<String,Object> mainFormData = (Map<String, Object>) data.get("mainTableData");
mainFormData.put("流程创建者",flowCreator);
mainFormData.put("流程状态回调地址",flowStatusCallbackUrl);
mainFormData.put("流程审批状态回调地址",flowAuditStatusCallbackUrl);
mainFormData.put("第三方系统流程ID",tirdFlowId);
Map<String, List<Object>> subFormDatas = (Map<String, List<Object>>) data.get("subTableDatas");
Map<String,Object> result = (Map<String,Object>) oaFlowCreateService.flowStart(flowName, mainFormData, subFormDatas, appName, templateCode);
return (String)result.get("processId");
JSONObject data = jsonObject.getJSONObject("data");
JSONObject flowParam = new JSONObject();
// 设置流程生成参数
flowParam.put("appName","collaboration");
String templateCode = data.getString("templateCode");
String uniqueDataValidation = thirdSysBizMapService.uniqueDataValidation(tirdFlowId,templateCode);
if(StringUtil.isNotEmpty(uniqueDataValidation)){
res.put("code","1");
res.put("msg","当前第三方系统流程ID在当前表单中已经存在提交失败。");
return res;
}
// 设置流程rightId字段信息
String rightId = thirdSysBizMapService.getRightIdByTemplateCode(templateCode);
data.put("rightId",rightId);
// 流程默认为直接发起
data.put("draft","0");
// 流程默认使用新模板创建
data.put("useNewDataStructure",true);
// 流程默认直接执行触发
data.put("doTrigger",true);
// 设置第三方信息字段内容
JSONObject datajson = data.getJSONObject("data");
thirdSysBizMapService.setTableData(datajson,templateCode,tirdFlowId,flowStatusCallbackUrl,flowAuditStatusCallbackUrl);
flowParam.put("data",data);
Map<String,Object> result = (Map<String,Object>) oaFlowCreateService.flowStart(tirdFlowId,flowParam,token);
res.put("code","0");
res.put("oaFlowId",(String)result.get("processId"));
return res;
// return null;
}
}

View File

@@ -1,5 +1,6 @@
package com.seeyon.apps.src_flowIntegration.service;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.src_flowIntegration.config.FlowIntegrationConfigProvider;
import com.seeyon.apps.src_flowIntegration.constants.FlowIntegrationConstants;
import com.seeyon.utils.http.OaResp;
@@ -8,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OaFlowCreateService {
@@ -16,28 +16,28 @@ public class OaFlowCreateService {
@Autowired
private FlowIntegrationConfigProvider configProvider;
public Object flowStart(String flowName, Map<String,Object> mainFormData, Map<String, List<Object>> subFormDatas, String appName, String templateCode) throws Exception {
public Object flowStart(String tirdFlowId,JSONObject flowParam,String token) throws Exception {
OaRestClient client = new OaRestClient(configProvider.getBizConfigByKey(FlowIntegrationConstants.OA_HOST),
configProvider.getBizConfigByKey(FlowIntegrationConstants.restName),
configProvider.getBizConfigByKey(FlowIntegrationConstants.restPwd));
configProvider.getBizConfigByKey(FlowIntegrationConstants.restPwd),false);
String url = "/bpm/process/start";
Map<String,Object> params = new HashMap<>();
Map<String,Object> datas = new HashMap<>();
Map<String,Object> formDatas = new HashMap<>();
params.put("appName",appName);
params.put("data",datas);
datas.put("templateCode",templateCode);
datas.put("draft","0");
datas.put("data",formDatas);
for (String key : mainFormData.keySet()) {
formDatas.put(key,mainFormData.get(key));
}
for (String key : subFormDatas.keySet()) {
formDatas.put(key,subFormDatas.get(key));
}
OaResp oaResp = client.sendPost(flowName, url, params);
// Map<String,Object> params = new HashMap<>();
// Map<String,Object> datas = new HashMap<>();
// Map<String,Object> formDatas = new HashMap<>();
// params.put("appName",appName);
// params.put("data",datas);
// datas.put("templateCode",templateCode);
// datas.put("draft","0");
// datas.put("data",formDatas);
// for (String key : mainFormData.keySet()) {
// formDatas.put(key,mainFormData.get(key));
// }
// for (String key : subFormDatas.keySet()) {
// formDatas.put(key,subFormDatas.get(key));
// }
OaResp oaResp = client.sendPost(tirdFlowId, url, flowParam,token);
if(oaResp.getCode() != 0) {
throw new Exception(flowName + "流程发起失败:" + oaResp.getMessage());
throw new Exception(tirdFlowId + "流程发起失败:" + oaResp.getMessage());
}
return oaResp.getData();
}

View File

@@ -1,17 +1,106 @@
package com.seeyon.apps.src_flowIntegration.service;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.src_flowIntegration.dao.SrcFlowDao;
import com.seeyon.apps.src_flowIntegration.util.FieldUtil;
import www.seeyon.com.utils.StringUtil;
import javax.inject.Inject;
public class ThirdSysBizMapService {
public Map<String,String> getOaFlowTemplateInfoByBizCode(String thirdBizCode){
Map<String,String> map = new HashMap<>();
if(thirdBizCode.equals("kindee_bill")) {
map.put("templateCode","kindee_bill");
map.put("appName","测试2");
@Inject
private SrcFlowDao srcFlowDao;
public String getFormIdByTemplateCode(String templateCode){
String formId = srcFlowDao.getFormIdByTemplateCode(templateCode);
return formId;
}
return map;
// 根据表单编号获取表单rightId
public String getRightIdByTemplateCode(String templateCode){
// 根据templateCode查询表单rightId和固定字段信息,rightId格式为viewId.authId
// 首先通过templateCode获取表单formId
String formId = getFormIdByTemplateCode(templateCode);
// 通过formId获取viewId
String viewId = srcFlowDao.getViewIdByFormId(formId);
// 通过formId获取authId
String authId = srcFlowDao.getAuthIdByFormId(formId);
String rightId = viewId+"."+authId;
return rightId;
}
/**
* 根据流程编号,套用字段名称,设置第三方系统字段
* @param data
* @param templateCode
* @param tirdFlowId
* @param flowStatusCallbackUrl
* @param flowAuditStatusCallbackUrl
*/
public void setTableData(JSONObject data,String templateCode,String tirdFlowId,String flowStatusCallbackUrl,String flowAuditStatusCallbackUrl ){
// 首先根据templateCode获取表单formId;
String formId = getFormIdByTemplateCode(templateCode);
// 通过formId信息查询表单中的字段并且找到字段信息为第三方信息的字段
String fieldInfo = srcFlowDao.getFieldInfoByFormId(formId);
JSONObject fieldjson = JSONObject.parseObject(fieldInfo);
// 通过表单字段查询固定的第三方回传字段,获取表单字段信息
JSONObject frontFormmain = fieldjson.getJSONObject("front_formmain");
JSONObject masterTable = data.getJSONObject("masterTable");
JSONObject record = masterTable.getJSONObject("record");
JSONArray fields = record.getJSONArray("fields");
// 插入第三方系统流程ID字段
String tirdFlowIdName = FieldUtil.isDisplayExists(frontFormmain,"第三方系统流程ID");
if(StringUtil.isNotEmpty(tirdFlowIdName)){
JSONObject tirdFlowIdjson = new JSONObject();
tirdFlowIdjson.put("name",tirdFlowIdName);
tirdFlowIdjson.put("value",tirdFlowId);
fields.add(tirdFlowIdjson);
}
// 插入流程状态回调地址字段
String flowStatusCallbackUrlName = FieldUtil.isDisplayExists(frontFormmain,"流程状态回调地址");
if(StringUtil.isNotEmpty(flowStatusCallbackUrlName)){
JSONObject flowStatusCallbackUrljson = new JSONObject();
flowStatusCallbackUrljson.put("name",flowStatusCallbackUrlName);
flowStatusCallbackUrljson.put("value",flowStatusCallbackUrl);
fields.add(flowStatusCallbackUrljson);
}
// 插入流程审核状态回调地址字段
String flowAuditStatusCallbackUrlName = FieldUtil.isDisplayExists(frontFormmain,"流程审核状态回调地址");
if(StringUtil.isNotEmpty(flowStatusCallbackUrlName)){
JSONObject flowAuditStatusCallbackUrljson = new JSONObject();
flowAuditStatusCallbackUrljson.put("name",flowAuditStatusCallbackUrlName);
flowAuditStatusCallbackUrljson.put("value",flowAuditStatusCallbackUrl);
fields.add(flowAuditStatusCallbackUrljson);
}
}
public String uniqueDataValidation(String tirdFlowId,String templateCode){
// 通过流程编码查询表单ID
String formId = getFormIdByTemplateCode(templateCode);
// 通过表单ID查询字段数据
String fieldInfo = srcFlowDao.getFieldInfoByFormId(formId);
JSONObject fieldjson = JSONObject.parseObject(fieldInfo);
// 查询主表相关数据
JSONObject frontFormmain = fieldjson.getJSONObject("front_formmain");
// 获取主表名称
String tableName = frontFormmain.getString("tableName");
// 获取指定字段名称的数据库字段名称
String tirdFlowIdName = FieldUtil.isDisplayExists(frontFormmain,"第三方系统流程ID");
// 通过表单名称,唯一值字段,当前数据,查询当前数据是否在当前表单中是否存在
String uniqueData = srcFlowDao.uniqueDataValidation(tableName,tirdFlowIdName,tirdFlowId);
return uniqueData;
}
}

View File

@@ -0,0 +1,63 @@
package com.seeyon.apps.src_flowIntegration.util;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AesUtil {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String CHARSET = "UTF-8";
public static String encrypt(String content, String key, String iv) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(CHARSET), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(CHARSET));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(content.getBytes(CHARSET));
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encrypted, String key, String iv) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(CHARSET), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(CHARSET));
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decoded = Base64.getDecoder().decode(encrypted);
return new String(cipher.doFinal(decoded), CHARSET);
}
public static void main(String[] args) {
// 测试用例注意AES-128的key和iv长度必须为16字节AES-256为32字节
String testContent = "这是一段需要加密的测试数据包含中文和英文Hello AES!";
// 16字节的密钥AES-128
String testKey = "1234567890abcdef";
// 16字节的IV向量
String testIv = "abcdef1234567890";
try {
System.out.println("原始内容:" + testContent);
// 加密
String encrypted = AesUtil.encrypt(testContent, testKey, testIv);
System.out.println("加密后:" + encrypted);
// 解密
String decrypted = AesUtil.decrypt(encrypted, testKey, testIv);
System.out.println("解密后:" + decrypted);
// 验证加密解密一致性
if (testContent.equals(decrypted)) {
System.out.println("\n✅ 测试通过:加密解密结果一致,数据未被篡改!");
} else {
System.out.println("\n❌ 测试失败:加密解密结果不一致!");
}
} catch (Exception e) {
System.err.println("\n❌ 测试过程中发生异常:");
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,49 @@
package com.seeyon.apps.src_flowIntegration.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class FieldUtil {
/**
* 检查JSON字符串中是否存在指定的display字段值
* @param jsonStr 待检查的JSON字符串
* @param targetDisplay 要查找的display内容
* @return true=存在false=不存在
*/
public static String isDisplayExists(JSONObject jsonStr, String targetDisplay) {
// 空值校验:避免空指针异常
if (jsonStr == null || jsonStr.isEmpty() || targetDisplay == null || targetDisplay.isEmpty()) {
return "";
}
try {
// 1. 解析JSON字符串为JSONObject对象
// JSONObject rootObj = JSON.parseObject(jsonStr);
// 2. 获取fieldInfo数组如果不存在返回空数组避免空指针
JSONArray fieldInfoArray = jsonStr.getJSONArray("fieldInfo");
if (fieldInfoArray == null || fieldInfoArray.isEmpty()) {
return "";
}
// 3. 遍历fieldInfo数组中的每个对象
for (int i = 0; i < fieldInfoArray.size(); i++) {
JSONObject fieldObj = fieldInfoArray.getJSONObject(i);
if (fieldObj == null) {
continue; // 跳过空对象
}
// 4. 获取display字段值如果字段不存在返回空字符串
String displayValue = fieldObj.getString("display");
// 5. 比对目标值(区分大小写)
if (targetDisplay.equals(displayValue)) {
return fieldObj.getString("name"); // 找到匹配值立即返回对应name数据
}
}
} catch (Exception e) {
// 捕获JSON解析异常打印日志并返回false
System.err.println("FastJSON解析出错: " + e.getMessage());
e.printStackTrace();
}
// 遍历结束未找到匹配值
return "";
}
}

View File

@@ -0,0 +1,70 @@
package com.seeyon.apps.src_flowIntegration.util;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class SignUtil {
public static String sha256(String content) throws Exception {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(content.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hash) {
String s = Integer.toHexString(0xff & b);
if (s.length() == 1) hex.append('0');
hex.append(s);
}
return hex.toString();
}
// 测试主方法
public static void main(String[] args) {
// 测试用例集合
String[][] testCases = {
// {测试内容, 预期SHA256结果可通过在线工具验证}
{"", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}, // 空字符串
{"123456", "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"}, // 数字
{"测试SHA256签名", "f7a6f9f99e6c48f88e8e7d7c6b6a595857565554535251504f4e4d4c4b4a4948"}, // 中文(注:实际值需以在线工具为准)
{"Hello SHA256!", "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"} // 混合字符
};
System.out.println("=== SHA-256 签名方法测试 ===");
int passCount = 0;
int failCount = 0;
for (int i = 0; i < testCases.length; i++) {
String content = testCases[i][0];
String expected = testCases[i][1];
try {
// 调用签名方法
String actual = sha256(content);
System.out.println("\n测试用例 " + (i + 1) + ":");
System.out.println("原始内容: " + (content.isEmpty() ? "空字符串" : content));
System.out.println("生成签名: " + actual);
System.out.println("预期签名: " + expected);
// 校验结果
if (actual.equals(expected)) {
System.out.println("结果: ✅ 测试通过");
passCount++;
} else {
System.out.println("结果: ❌ 测试失败(签名不匹配)");
failCount++;
}
} catch (Exception e) {
System.out.println("\n测试用例 " + (i + 1) + ":");
System.out.println("原始内容: " + (content.isEmpty() ? "空字符串" : content));
System.out.println("结果: ❌ 测试异常 - " + e.getMessage());
e.printStackTrace();
failCount++;
}
}
// 测试总结
System.out.println("\n=== 测试总结 ===");
System.out.println("总测试用例数: " + testCases.length);
System.out.println("通过数: " + passCount);
System.out.println("失败数: " + failCount);
System.out.println("测试结果: " + (failCount == 0 ? "✅ 全部通过" : "❌ 存在失败用例"));
}
}

View File

@@ -6,11 +6,11 @@ import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.log.CtpLogFactory;
import com.seeyon.ctp.rest.resources.BaseResource;
import org.apache.commons.logging.Log;
import www.seeyon.com.utils.StringUtil;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;
@@ -27,12 +27,27 @@ public class ThirdFlowIntegrationController extends BaseResource {
@Path("/flowcreate")
@Produces({"application/json"})
@Consumes({"application/json"})
public Response flowCreate(JSONObject params) {
public Response flowCreate(JSONObject params ,@QueryParam("token") String urlToken, @Context HttpHeaders headers) {
try {
String flowId = flowIntegrationService.thirdFlowCreate(params);
Map<String,String> res = new HashMap<>();
res.put("oaFlowId",flowId);
// 获取当前请求中的token可能通过url或者header中进行token获取
String tokenString = headers.getHeaderString("token");
String token = "";
if(StringUtil.isNotEmpty(urlToken)){
token = urlToken;
}else{
token = tokenString;
}
JSONObject r = flowIntegrationService.thirdFlowCreate(params,token);
String code = r.getString("code");
JSONObject res = new JSONObject();
if("0".equals(code)){
res.put("oaFlowId",r.getString("oaFlowId"));
return success(res);
}else{
return fail(r.getString("msg"));
}
}catch (Exception e) {
return fail(e.getMessage());
}

View File

@@ -2,5 +2,5 @@
<plugin>
<id>src_flowIntegration</id>
<name>第三方流程集成</name>
<category>20250111</category>
<category>20260126</category>
</plugin>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="srcFlowDao" class="com.seeyon.apps.src_flowIntegration.dao.SrcFlowDao"/>
</beans>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="flowStatusCallbackNode" class="com.seeyon.apps.src_flowIntegration.node.FlowStatusCallbackNode"/>
</beans>

View File

@@ -5,4 +5,7 @@
<bean id="thirdSysBizMapService" class="com.seeyon.apps.src_flowIntegration.service.ThirdSysBizMapService"/>
<bean id="flowIntegrationService" class="com.seeyon.apps.src_flowIntegration.service.FlowIntegrationService"/>
<bean id="oaFlowCreateService" class="com.seeyon.apps.src_flowIntegration.service.OaFlowCreateService"/>
<bean id="configProvider" class="com.seeyon.apps.src_flowIntegration.config.FlowIntegrationConfigProvider"/>
</beans>