2026-01-28 通用流程集成,第三方流程集成demo
This commit is contained in:
@@ -4,8 +4,8 @@ public enum FlowIntegrationConstants {
|
||||
|
||||
plugin("src_flowIntegration", "插件ID"),
|
||||
OA_HOST("","oa地址"),
|
||||
restName("",""),
|
||||
restPwd("",""),
|
||||
restName("","rest用户名"),
|
||||
restPwd("","rest密码")
|
||||
;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
return map;
|
||||
@Inject
|
||||
private SrcFlowDao srcFlowDao;
|
||||
|
||||
public String getFormIdByTemplateCode(String templateCode){
|
||||
String formId = srcFlowDao.getFormIdByTemplateCode(templateCode);
|
||||
return formId;
|
||||
}
|
||||
|
||||
|
||||
// 根据表单编号获取表单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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 ? "✅ 全部通过" : "❌ 存在失败用例"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
return success(res);
|
||||
// 获取当前请求中的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());
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
<plugin>
|
||||
<id>src_flowIntegration</id>
|
||||
<name>第三方流程集成</name>
|
||||
<category>20250111</category>
|
||||
<category>20260126</category>
|
||||
</plugin>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user