diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/constants/FlowIntegrationConstants.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/constants/FlowIntegrationConstants.java index f231e54..ed3e77a 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/constants/FlowIntegrationConstants.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/constants/FlowIntegrationConstants.java @@ -4,8 +4,8 @@ public enum FlowIntegrationConstants { plugin("src_flowIntegration", "插件ID"), OA_HOST("","oa地址"), - restName("",""), - restPwd("",""), + restName("","rest用户名"), + restPwd("","rest密码") ; private String defaultValue; diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/dao/SrcFlowDao.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/dao/SrcFlowDao.java new file mode 100644 index 0000000..11b2b4a --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/dao/SrcFlowDao.java @@ -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 p = new ArrayList(); + p.add(templateCode); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if (list != null && list.size() > 0) { + Map 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 p = new ArrayList(); + p.add(formId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if (list != null && list.size() > 0) { + Map 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 p = new ArrayList(); + p.add(formId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if (list != null && list.size() > 0) { + Map 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 p = new ArrayList(); + p.add(formId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if (list != null && list.size() > 0) { + Map 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 p = new ArrayList(); + p.add(flowId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if (list != null && list.size() > 0) { + Map 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; + } + + + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/node/FlowStatusCallbackNode.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/node/FlowStatusCallbackNode.java new file mode 100644 index 0000000..2fb7ebe --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/node/FlowStatusCallbackNode.java @@ -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(), null); + + return context; + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/FlowIntegrationService.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/FlowIntegrationService.java index 282e175..b5e7431 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/FlowIntegrationService.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/FlowIntegrationService.java @@ -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 data = (Map) jsonObject.get("data"); - Map map = thirdSysBizMapService.getOaFlowTemplateInfoByBizCode(flowBizCode); - String appName = map.get("appName"); - String templateCode = map.get("templateCode"); - String flowName = map.get("flowName"); - Map mainFormData = (Map) data.get("mainTableData"); - mainFormData.put("流程创建者",flowCreator); - mainFormData.put("流程状态回调地址",flowStatusCallbackUrl); - mainFormData.put("流程审批状态回调地址",flowAuditStatusCallbackUrl); - mainFormData.put("第三方系统流程ID",tirdFlowId); - Map> subFormDatas = (Map>) data.get("subTableDatas"); - Map result = (Map) 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 result = (Map) oaFlowCreateService.flowStart(tirdFlowId,flowParam,token); + res.put("code","0"); + res.put("oaFlowId",(String)result.get("processId")); + return res; +// return null; } } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/OaFlowCreateService.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/OaFlowCreateService.java index f50c192..f5cf6ea 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/OaFlowCreateService.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/OaFlowCreateService.java @@ -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 mainFormData, Map> 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 params = new HashMap<>(); - Map datas = new HashMap<>(); - Map 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 params = new HashMap<>(); +// Map datas = new HashMap<>(); +// Map 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(); } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/ThirdSysBizMapService.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/ThirdSysBizMapService.java index 2c13b57..7f503cc 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/ThirdSysBizMapService.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/service/ThirdSysBizMapService.java @@ -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 getOaFlowTemplateInfoByBizCode(String thirdBizCode){ - Map 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; + } + + + + + + } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/AesUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/AesUtil.java new file mode 100644 index 0000000..34d4a8b --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/AesUtil.java @@ -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(); + } + } + + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/FieldUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/FieldUtil.java new file mode 100644 index 0000000..7cbaaf7 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/FieldUtil.java @@ -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 ""; + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/SignUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/SignUtil.java new file mode 100644 index 0000000..e2fba85 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_flowIntegration/util/SignUtil.java @@ -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 ? "✅ 全部通过" : "❌ 存在失败用例")); + } + +} \ No newline at end of file diff --git a/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/flowIntegration/ThirdFlowIntegrationController.java b/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/flowIntegration/ThirdFlowIntegrationController.java index 81ed9d3..bfeb055 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/flowIntegration/ThirdFlowIntegrationController.java +++ b/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/flowIntegration/ThirdFlowIntegrationController.java @@ -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 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()); } diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/pluginCfg.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/pluginCfg.xml index 57d19ac..00fa680 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/pluginCfg.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/pluginCfg.xml @@ -2,5 +2,5 @@ src_flowIntegration 第三方流程集成 - 20250111 + 20260126 \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-dao.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-dao.xml new file mode 100644 index 0000000..d6cf82b --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-dao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-node.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-node.xml new file mode 100644 index 0000000..c692782 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring-node.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring.xml index 6fe182f..1433809 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_flowIntegration/spring/spring.xml @@ -5,4 +5,7 @@ + + + \ No newline at end of file