commit de87db8081b88dbfa539d13723c784994ce3005a
Author: RuicyWu <1063154311@qq.com>
Date: Wed Feb 11 11:21:50 2026 +0800
初始化
diff --git a/seeyon/WEB-INF/cfgHome/component/esign/pluginCfg.xml b/seeyon/WEB-INF/cfgHome/component/esign/pluginCfg.xml
new file mode 100644
index 0000000..e7b0812
--- /dev/null
+++ b/seeyon/WEB-INF/cfgHome/component/esign/pluginCfg.xml
@@ -0,0 +1,6 @@
+
+
+ esign
+ 致远E签宝集成封装
+ 20260122
+
diff --git a/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-bean.xml b/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-bean.xml
new file mode 100644
index 0000000..148f59e
--- /dev/null
+++ b/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-bean.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-controller.xml b/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-controller.xml
new file mode 100644
index 0000000..0dcbb84
--- /dev/null
+++ b/seeyon/WEB-INF/cfgHome/component/esign/spring/spring-controller.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/contractCompareBtn.css b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/contractCompareBtn.css
new file mode 100644
index 0000000..e5c4ae0
--- /dev/null
+++ b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/contractCompareBtn.css
@@ -0,0 +1,36 @@
+.customButton_class_box {
+ width: 35%;
+ line-height: 24px;
+ height:24px;
+ color: #1f85ec;
+ cursor: pointer;
+ font-family: "Microsoft YaHei"!important;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ word-break:keep-all;
+ box-sizing: border-box;
+ -webkit-box-sizing : border-box;
+ -moz-box-sizing : border-box;
+ text-align: center;
+ outline: none;
+ border: 1px solid #1f85ec;
+ background-color: #fff;
+ border-radius: 15px;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+}
+.customInputArea{
+ width: 65%;
+ height:auto;
+ color: #1f85ec;
+ font-family: "Microsoft YaHei"!important;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ word-break:keep-all;
+}
+.customButton_box_content{
+ width: 100%;
+ height: auto;
+}
diff --git a/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/img/icon16.png b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/img/icon16.png
new file mode 100644
index 0000000..e43def3
Binary files /dev/null and b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/css/img/icon16.png differ
diff --git a/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/html/contractCompare.html b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/html/contractCompare.html
new file mode 100644
index 0000000..63cd5dc
--- /dev/null
+++ b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/html/contractCompare.html
@@ -0,0 +1,104 @@
+
+
+
+
+ e签宝合同比对
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareBiz.js b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareBiz.js
new file mode 100644
index 0000000..d65faaa
--- /dev/null
+++ b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareBiz.js
@@ -0,0 +1,99 @@
+$(document).ready(async function() {
+ const apiBaseUrl = window.location.origin;
+ let currentFilePage = 1;
+ let totalFilePages = 1;
+ let searchKeyword;
+ const filePageSize = 10;
+
+ const dataList = await pageQueryTemplates();
+ renderTemplates(dataList);
+
+
+ function renderTemplates(list) {
+ const container = $('#file-list');
+ container.empty();
+ list.forEach(file => {
+ const fileItem = $(`
+
+ ${file.signTemplateName}
+
+ `);
+ container.append(fileItem);
+ });
+ filePagination()
+ }
+
+ async function pageQueryTemplates() {
+ const pageIndex = currentFilePage;
+ const response = await fetch(
+ `${apiBaseUrl}/seeyon/rest/cap4/etemplate/querypage?pageNum=${pageIndex}`, {}
+ );
+ const res = await response.json();
+ // 校验返回值
+
+ console.log(res)
+ let respData = res.data;
+ totalFilePages = Math.ceil(respData.total / filePageSize);
+ return res.data.templateList;
+ }
+
+ async function getContractCompareUrl(templateId,templateFileId) {
+ const response = await fetch(
+ `${apiBaseUrl}/seeyon/rest/cap4/etemplate/compareurl?templateId=${templateId}&templateFileId=${templateFileId}`, {}
+ );
+ const res = await response.json();
+ // 校验返回值
+ }
+
+ function filePagination() {
+ // 分页逻辑
+ const pagination = $('#file-pagination');
+ pagination.empty();
+
+ const firstBtn = $('');
+ const prevBtn = $('');
+ const nextBtn = $('');
+ const pageInfo = $(`第 ${currentFilePage} 页`);
+
+ // 判断是否禁用按钮
+ prevBtn.prop('disabled', currentFilePage === 1);
+
+ // 首页按钮点击事件
+ firstBtn.click(async () => {
+ currentFilePage = 1; // 跳转到第一页
+ await loadTemplates(); // 加载文件
+ });
+
+ // 上一页按钮点击事件
+ prevBtn.click(async () => {
+ if (currentFilePage <= 1) return; // 防止重复请求
+ currentFilePage--; // 页码减一
+ await loadTemplates(); // 加载文件
+ });
+
+ // 下一页按钮点击事件
+ nextBtn.click(async () => {
+ currentFilePage++; // 页码加一
+ await loadTemplates(); // 加载文件
+ });
+
+ // 加载文件的逻辑
+ async function loadTemplates() {
+ let tempTemplateList;
+
+ tempTemplateList = await pageQueryTemplates();
+
+ renderTemplates(tempFileList); // 渲染文件列表
+ pageInfo.text(`第 ${currentFilePage} 页`); // 更新页数信息
+ }
+
+ // 添加按钮到分页容器
+ pagination.append(firstBtn, prevBtn, pageInfo, nextBtn);
+ }
+
+ function getCookie(name) {
+ const value = `; ${document.cookie}`;
+ const parts = value.split(`; ${name}=`);
+ if (parts.length === 2) return parts.pop().split(';').shift();
+ }
+})
\ No newline at end of file
diff --git a/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareinit.js b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareinit.js
new file mode 100644
index 0000000..388ffea
--- /dev/null
+++ b/seeyon/apps_res/cap/customerCtrlResources/esignContractCompareBtnResources/js/compareinit.js
@@ -0,0 +1,207 @@
+(function(factory) {
+ var nameSpace = 'field_8899554679928334458';
+ if (!window[nameSpace]) {
+ console.log("开始实例化控件")
+ var Builder = factory();
+ window[nameSpace] = {
+ instance: {}
+ };
+ window[nameSpace].init = function(options) {
+ window[nameSpace].instance[options.privateId] = new Builder(options);
+ };
+ }
+})(function() {
+ function App(options) {
+ var self = this;
+ self.initParams(options);
+ //初始化dom
+ self.initDom();
+ //事件
+ self.events();
+ }
+
+ App.prototype = {
+ initParams: function(options) {
+ console.log("开始初始化参数")
+ var self = this;
+ self.adaptation = options.adaptation;
+ self.privateId = options.privateId;
+ self.preUrl = options.url_prefix;
+ self.adaptation.formMessage = options.formMessage;
+ self.messageObj = options.getData;
+ console.log(self.messageObj)
+ },
+ initDom: function() {
+ var self = this;
+ console.log("开始渲染dom")
+ dynamicLoading.css(self.preUrl + '/css/contractCompareBtn.css');
+ self.appendChildDom();
+ },
+ events: function() {
+ var self = this;
+ // 监听是否数据刷新
+ console.log("设置事件监听")
+ self.adaptation.ObserverEvent.listen('Event' + self.privateId, function() {
+ self.messageObj = self.adaptation.childrenGetData(self.privateId);
+ self.appendChildDom();
+ });
+ },
+ openCompareUrl: function(privateId, messageObj, adaptation) {
+ // 实际的业务代码方法
+ messageObj = adaptation.childrenGetData(privateId);
+ const targetObj = messageObj.formdata.formmains[adaptation.formMessage.tableName]
+ //backFill(ids, messageObj.id, messageObj.display, privateId,messageObj, adaptation);
+ //dialog.close()
+ console.log(targetObj)
+ if (targetObj) {
+ let contractRefId;
+ let templateRefId;
+ for (const key in targetObj) {
+ if (targetObj.hasOwnProperty(key) && !/^auxiliary/.test(key)) {
+ if (targetObj[key].display === "合同审批附件") {
+ console.log(targetObj[key])
+ contractRefId = targetObj[key].showValue;
+ console.log("合同附件refId: " + contractRefId)
+
+
+ }
+ if (targetObj[key].display === "原始合同模板文件") {
+ console.log(targetObj[key])
+ templateRefId = targetObj[key].showValue;
+ console.log("模板文件refId: " + templateRefId)
+ }
+ }
+ }
+
+ $.ajax({
+ type: "POST",
+ url: '/seeyon/rest/cap4/etemplate/compareurl?templateRefId=' +
+ templateRefId + '&contractRefId=' +
+ contractRefId,
+ data: {},
+ dataType: "json",
+ contentType: 'application/json;charset=UTF-8',
+ success: function(res) {
+ // 后台解析数据后 将数据填写到表单中
+ if (res.code == 0) {
+ window.open(res.data, "_blank");
+ } else {
+ // 报错
+ $.alert(res.message);
+ }
+ },
+ complete: function() {},
+ error: function(e) {
+ top.$.error(e.responseText);
+ }
+ });
+ }
+ },
+ appendChildDom: function() {
+ var self = this;
+ const params = new URLSearchParams(window.location.search);
+ console.log(params)
+ const openFrom = params.get('openFrom'); // 返回"2025"
+ const type = params.get('type');
+ var edit = !((openFrom != null && (openFrom == 'listPending' || openFrom == 'listDone' ||
+ openFrom == 'listSent')) || (type != null && type == 'browse'));
+ console.log(edit)
+ var domStructure = '' +
+ '' +
+ '' +
+ '
' +
+ '';
+ document.querySelector('#' + self.privateId).innerHTML = domStructure;
+ var compare = function() {
+ self.openCompareUrl(self.privateId, self.messageObj, self.adaptation)
+ }
+
+ var content = self.messageObj.formdata.content;
+ const picker = document.querySelector('.customButton_class_box' + '.' + self.privateId);
+ if (picker) {
+ document.querySelector('.customButton_class_box' + '.' + self.privateId)
+ .removeEventListener(
+ 'click', compare);
+ document.querySelector('.customButton_class_box' + '.' + self.privateId).addEventListener(
+ 'click', compare);
+ }
+ const goNewPages = document.querySelectorAll('.goToNewPage');
+ if (goNewPages.length > 0) {
+ goNewPages.forEach(element => {
+ element.addEventListener('click', function(e) {
+ window.open(e.currentTarget.dataset.href, '_blank'); //
+ });
+ });
+ }
+ //渲染隐藏权限
+ if (self.messageObj.auth === 'hide') {
+ document.querySelector('#' + self.privateId).innerHTML =
+ '***
';
+ }
+ }
+
+ };
+
+ function backFill(ids, fieldName, fieldDisplay, privateId, messageObj, adaptation) {
+ var param = new Object();
+ param.masterId = messageObj.formdata.content.contentDataId;
+ param.ids = ids;
+ param.formId = messageObj.formdata.content.contentTemplateId;
+ param.fieldName = fieldName;
+ param.fieldDisplay = fieldDisplay;
+ param.masterId = messageObj.formdata.content.contentDataId;
+ $.ajax({
+ type: "POST",
+ url: '/seeyon/rest/cap4/hywp/fileref',
+ data: JSON.stringify(param),
+ dataType: "json",
+ contentType: 'application/json;charset=UTF-8',
+ success: function(res) {
+ // 后台解析数据后 将数据填写到表单中
+ if (res.code == 0) {
+ var backfill = {};
+ backfill.tableName = adaptation.formMessage.tableName;
+ // 回填主表
+ backfill.tableCategory = 'formmain';
+ // 后台组装的data数据
+ console.log(res.data)
+ backfill.updateData = res.data;
+ adaptation.backfillFormControlData(backfill, privateId);
+ } else {
+ // 报错
+ $.alert(res.message);
+ }
+ },
+ complete: function() {},
+ error: function(e) {
+ top.$.error(e.responseText);
+ }
+ });
+ }
+ var dynamicLoading = {
+ css: function(path) {
+ if (!path || path.length === 0) {
+ throw new Error('argument "path" is required !');
+ }
+ var head = document.getElementsByTagName('head')[0];
+ var link = document.createElement('link');
+ link.href = path;
+ link.rel = 'stylesheet';
+ link.type = 'text/css';
+ head.appendChild(link);
+ },
+ js: function(path) {
+ if (!path || path.length === 0) {
+ throw new Error('argument "path" is required !');
+ }
+ var head = document.getElementsByTagName('head')[0];
+ var script = document.createElement('script');
+ script.src = path;
+ script.type = 'text/javascript';
+ head.appendChild(script);
+ }
+ }
+ return App;
+});
\ No newline at end of file
diff --git a/src/main/java/com/seeyon/apps/esign/EsignPluginApi.java b/src/main/java/com/seeyon/apps/esign/EsignPluginApi.java
new file mode 100644
index 0000000..7e6c7b3
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/EsignPluginApi.java
@@ -0,0 +1,44 @@
+package com.seeyon.apps.esign;
+
+import com.seeyon.apps.common.plugin.api.APluginInfoApi;
+import com.seeyon.apps.common.plugin.vo.ConfigVo;
+import com.seeyon.apps.esign.constants.EsignConfigConstants;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EsignPluginApi extends APluginInfoApi {
+ public EsignPluginApi() {
+ }
+
+ public String getPluginId() {
+ System.out.println(EsignConfigConstants.getPluginId());
+ return EsignConfigConstants.getPluginId();
+ }
+
+ public String getCreateUser() {
+ return "橙阳科技";
+ }
+
+ public String getDescription() {
+ return "E签宝对接封装";
+ }
+
+ public ConfigVo getDefaultConfig() {
+ ConfigVo configVo = new ConfigVo();
+ EsignConfigConstants[] var2 = EsignConfigConstants.values();
+ int var3 = var2.length;
+
+ for(int var4 = 0; var4 < var3; ++var4) {
+ EsignConfigConstants value = var2[var4];
+ if (value != EsignConfigConstants.plugin) {
+ configVo.getDevParams().put(value.name(), value.getDefaultValue());
+ configVo.getProdParams().put(value.name(), value.getDefaultValue());
+ configVo.getParamMap().put(value.name(), value.getDescription());
+ }
+ }
+
+ return configVo;
+ }
+
+}
+
diff --git a/src/main/java/com/seeyon/apps/esign/config/EsignConfigProvider.java b/src/main/java/com/seeyon/apps/esign/config/EsignConfigProvider.java
new file mode 100644
index 0000000..40b3c23
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/config/EsignConfigProvider.java
@@ -0,0 +1,22 @@
+package com.seeyon.apps.esign.config;
+
+import com.seeyon.apps.common.config.ICstConfigApi;
+import com.seeyon.apps.common.plugin.vo.ConfigVo;
+import com.seeyon.apps.esign.constants.EsignConfigConstants;
+import com.seeyon.ctp.common.AppContext;
+
+import static com.seeyon.apps.esign.constants.EsignConfigConstants.getPluginId;
+
+public class EsignConfigProvider {
+
+ protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");
+
+ public String getBizConfigByKey(EsignConfigConstants key) {
+ ConfigVo config = cstConfigApi.getConfig(getPluginId());
+ return config.getParamVal(key.name());
+ }
+
+ public static EsignConfigProvider getInstance() {
+ return (EsignConfigProvider) AppContext.getBean("esignConfigProvider");
+ }
+}
diff --git a/src/main/java/com/seeyon/apps/esign/constants/EsignApiUrl.java b/src/main/java/com/seeyon/apps/esign/constants/EsignApiUrl.java
new file mode 100644
index 0000000..5c201d8
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/constants/EsignApiUrl.java
@@ -0,0 +1,19 @@
+package com.seeyon.apps.esign.constants;
+
+public class EsignApiUrl {
+ public static final String SEAL_GRANT_URL = "/v3/seals/org-seals/internal-auth";
+ public static final String SIGN_START_URL = "/v3/sign-flow/{signFlowId}/start";
+ public static final String SIGN_BY_FILE_URL = "/v3/sign-flow/create-by-file";
+ public static final String SIGN_FLOW_QUERY = "/v3/sign-flow/{signFlowId}/detail";
+ public static final String GET_UPLOAD_FILE_URL = "/v3/files/file-upload-url";
+ public static final String CONTRACT_DOWNLOAD_URL= "/v3/sign-flow/{signFlowId}/file-download-url";
+ public static final String PERSON_AUTH_URL = "/v3/psn-auth-url";
+ public static final String SIGN_POSITION_URL = "/v3/files/{fileId}/keyword-positions";
+ public static final String QUERY_TEMPLATES_URL = "/v3/sign-templates";
+ public static final String QUERY_TEMPLATE_DETAIL_URL = "/v3/sign-templates/detail";
+ public static final String QUERY_ORGINFO = "/v3/organizations/identity-info";
+ public static final String CONTRACT_COMPARE_GETURL = "/v3/contract-compare-url";
+ public static final String TOKEN_GET_URL = "/v1/oauth2/access_token";
+ public static final String SEAL_QUERY_URL = "/v3/seals/org-own-seal-list";
+ public static final String SIGN_LINK_GET_URL ="/v3/sign-flow/{signFlowId}/sign-url";
+}
diff --git a/src/main/java/com/seeyon/apps/esign/constants/EsignConfigConstants.java b/src/main/java/com/seeyon/apps/esign/constants/EsignConfigConstants.java
new file mode 100644
index 0000000..638f621
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/constants/EsignConfigConstants.java
@@ -0,0 +1,44 @@
+package com.seeyon.apps.esign.constants;
+
+public enum EsignConfigConstants {
+ plugin("esign",""),
+ APP_ID("7438886882",""),
+ APP_SECRET("325c8cc6c2a303d6cf1fb5657a16e591",""),
+ OA_HOST("http://cd-2.frp.one:58336",""),
+ ESIGN_HOST("",""),
+ SIGN_SERVICE_PROVIDER("ESIGN",""),
+ UNITNAME("","平台方组织名称"),
+ FORMEDITLOGINNAME("","表单修改登录名"),
+ updateAccountName("表单",""),
+ getTokenUrl("/seeyon/rest/token/","调用获取TOKEN地址"),
+ nodeTokenUrl("/seeyon/rest/flow/notification/","超级节点回调URL"),
+ restName("",""),
+ restPwd("",""),
+ signAutoDate("","是否自动加盖签署日期"),
+ eSignOrgId("61f735dd368c45a191f43a6711c3c88a","e签宝平台方组织id"),
+ formLoginName("2019","表单数据录入登录名"),
+ sealInfoFormCode("","印章档案编码"),
+ aSignPositionKeyword("甲方盖章/签字","甲方签署位置关键字"),
+ bSignPositionKeyword("乙方盖章/签字","乙方签署位置关键字"),
+ lpSignPositionKeyword("法定代表人","法人签署位置关键字"),
+ ;
+
+ private String defaultValue;
+ private String description;
+
+ EsignConfigConstants(String defaultValue,String description) {
+ this.defaultValue = defaultValue;
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+ public static String getPluginId() {
+ return plugin.defaultValue;
+ }
+}
diff --git a/src/main/java/com/seeyon/apps/esign/controller/DefaultEsignCallBackController.java b/src/main/java/com/seeyon/apps/esign/controller/DefaultEsignCallBackController.java
new file mode 100644
index 0000000..35c5871
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/controller/DefaultEsignCallBackController.java
@@ -0,0 +1,89 @@
+package com.seeyon.apps.esign.controller;
+
+import cn.hutool.log.Log;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.seeyon.apps.esign.po.esignapi.EsignCallbackParams;
+import com.seeyon.apps.esign.service.EsignUploadFileService;
+import com.seeyon.apps.esign.service.EsignCallbackFlowBizService;
+import com.seeyon.ctp.common.AppContext;
+import com.seeyon.ctp.common.controller.BaseController;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.BufferedReader;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+public class DefaultEsignCallBackController extends BaseController {
+
+ private static final Log log = Log.get(DefaultEsignCallBackController.class);
+
+ private EsignUploadFileService esignUploadFileService = (EsignUploadFileService) AppContext.getBean("esignByUploadFileService");
+ private EsignCallbackFlowBizService esignCallbackFlowBizService = (EsignCallbackFlowBizService) AppContext.getBean("esignCallbackFlowBizService");
+
+
+ public void callback(HttpServletRequest request, HttpServletResponse response) {
+ try {
+ log.info("签署回调触发");
+ // 签署回调处理,改变超级节点状态
+ String formId = request.getParameter("formId");
+ String tableName = request.getParameter("tablename");
+ String updatefield = request.getParameter("updatefield");
+ String statusfield = request.getParameter("statusfield");;
+ BufferedReader reader = request.getReader();
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ String body = sb.toString();
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ EsignCallbackParams callbackParams = mapper.readValue(body, new TypeReference() {
+ });
+ String flowId = callbackParams.getSignFlowId();
+ String action = callbackParams.getAction();
+ log.info("签署回调当前流程: " + flowId);
+ if(action.equals("SIGN_FLOW_COMPLETE")) {
+ if(callbackParams.getSignFlowStatus() == 2) {
+ Object[] fileInfos = esignUploadFileService.getDownloadFileInfo(flowId);
+ esignCallbackFlowBizService.handleSuccessSignCallbackBiz(tableName,updatefield,statusfield,formId,fileInfos);
+ }else if(callbackParams.getSignFlowStatus() == 5){
+ //合同过期
+ //esignCallbackBizService.handleExpiredSignCallbackBiz(tableName,statusfield,formId);
+ }else {
+ esignCallbackFlowBizService.handleFailSignCallbackBiz(tableName,statusfield,formId,callbackParams.getResultDescription());
+ }
+ //signLinkService.del(flowId);
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }else if(action.equals("SIGN_MISSON_COMPLETE") && callbackParams.getSignResult() == 2 && callbackParams.getSignOrder() == 2){
+ //发送消息
+// MessageVo messageVo = new MessageVo();
+// messageVo.setBizId(flowId);
+// messageVo.setMessageType("SIGN");
+
+// thirdMessageService.sendMessage();
+ }
+ //下载合同
+ response.setContentType("application/json;charset=UTF-8");
+ response.setCharacterEncoding("UTF-8");
+ response.setStatus(HttpServletResponse.SC_OK);
+ try (OutputStream out = response.getOutputStream()) {
+ out.write("{\"code\":\"200\",\"msg\":\"success\"}".getBytes(StandardCharsets.UTF_8));
+ out.flush();
+ }
+ log.info("回调处理完成: " + flowId);
+ return;
+ } catch (Exception e) {
+ log.error("回调处理失败", e);
+ }
+// response.setStatus(HttpServletResponse.SC_OK);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+
+}
diff --git a/src/main/java/com/seeyon/apps/esign/fieldCtrl/ContractCompareFieldCtrl.java b/src/main/java/com/seeyon/apps/esign/fieldCtrl/ContractCompareFieldCtrl.java
new file mode 100644
index 0000000..3de3357
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/fieldCtrl/ContractCompareFieldCtrl.java
@@ -0,0 +1,61 @@
+package com.seeyon.apps.esign.fieldCtrl;
+
+import com.seeyon.cap4.form.bean.ParamDefinition;
+import com.seeyon.cap4.form.bean.fieldCtrl.FormFieldCustomCtrl;
+import com.seeyon.cap4.form.util.Enums;
+
+
+public class ContractCompareFieldCtrl extends FormFieldCustomCtrl {
+ @Override
+ public String getPCInjectionInfo() {
+ return "{path:'apps_res/cap/customCtrlResources/esignContractCompareBtnResources',jsUri:'/js/compareinit.js',initMethod:'init',nameSpace:'" + getNameSpace() + "'}";
+ }
+
+ @Override
+ public String getMBInjectionInfo() {
+ return "{path:'http://mapResource.v5.cmp/v1.0.0/',weixinpath:'invoice',jsUri:'js/location.js',initMethod:'init',nameSpace:'"+getNameSpace()+"'}";
+ }
+
+ @Override
+ public String getKey() {
+ return "8899554679928334458";
+ }
+
+ @Override
+ public boolean canUse(Enums.FormType formType) {
+ return true;
+ }
+
+ @Override
+ public String[] getDefaultVal(String s) {
+ return new String[0];
+ }
+
+ public String getNameSpace() {
+ return "field_" + this.getKey();
+ }
+
+ public String getFieldLength() {
+ return "20";
+ }
+ @Override
+ public String getText() {
+ return "e签宝合同比对按钮";
+ }
+
+ /**
+ * 控件初始化接口,此接口在控件初始化的时候,会调用,主要用于定义控件所属插件id、在表单编辑器中的图标、表单编辑器中有哪些属性可以设置。
+ * 使用举例:在接口中定义自定义控件在在表单编辑器中有哪些控件属性需要配置
+ */
+ @Override
+ public void init() {
+ //设置图标和插件ID
+ setPluginId("src_esign");
+ setIcon("cap-icon-custom-button");
+ // 自定义参数
+
+ ParamDefinition esignContractCompareBtnParam = new ParamDefinition();
+ esignContractCompareBtnParam.setParamType(Enums.ParamType.button);
+ addDefinition(esignContractCompareBtnParam);
+ }
+}
diff --git a/src/main/java/com/seeyon/apps/esign/job/SealDocSyncJob.java b/src/main/java/com/seeyon/apps/esign/job/SealDocSyncJob.java
new file mode 100644
index 0000000..922fdd5
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/job/SealDocSyncJob.java
@@ -0,0 +1,71 @@
+package com.seeyon.apps.esign.job;
+
+import com.seeyon.aicloud.common.JsonUtils;
+import com.seeyon.apps.esign.config.EsignConfigProvider;
+import com.seeyon.apps.esign.constants.EsignApiUrl;
+import com.seeyon.apps.esign.constants.EsignConfigConstants;
+import com.seeyon.apps.esign.po.esignapi.EsignApiHeader;
+import com.seeyon.apps.esign.po.esignapi.EsignBaseResp;
+import com.seeyon.apps.esign.po.seal.SealInfoVo;
+import com.seeyon.apps.esign.service.SealService;
+import com.seeyon.apps.esign.service.TokenCacheManager;
+import com.seeyon.apps.esign.utils.HttpClient;
+import com.seeyon.apps.ext.quartz.AbstractQuartzTask;
+import com.seeyon.ctp.common.AppContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+import java.util.Map;
+
+
+public class SealDocSyncJob extends AbstractQuartzTask {
+
+ private static final Log log = LogFactory.getLog(SealDocSyncJob.class);
+
+ private EsignConfigProvider configProvider = EsignConfigProvider.getInstance();
+ private TokenCacheManager tokenCacheManager = (TokenCacheManager) AppContext.getBean("tokenCacheManager");
+ private SealService sealService = (SealService) AppContext.getBean("sealService");
+
+ @Override
+ public String taskRun(String s) throws Exception {
+ log.info("开始执行印章同步任务");
+ syncSeals();
+ log.info("印章同步任务完成");
+ return "";
+ }
+
+ private void syncSeals() {
+ String orgId = configProvider.getBizConfigByKey(EsignConfigConstants.eSignOrgId);
+ String host = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST);
+ Integer pageNum = 1;
+ Integer pageSize = 20;
+ EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
+ esignApiHeader.token(tokenCacheManager.getToken());
+ EsignBaseResp esignBaseResp = null;
+ Map dataMap = null;
+ do {
+ String url = host + EsignApiUrl.SEAL_QUERY_URL + "?" + "orgId=" + orgId + "&pageNum=" + (pageNum++) + "&pageSize=" + pageSize;
+ String respStr = HttpClient.httpGet(url, esignApiHeader.convert2Headers(),"UTF-8");
+ esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
+ if(esignBaseResp.getCode() != 0) {
+ break;
+ }
+ dataMap = (Map)esignBaseResp.getData();
+ Object[] sealArray = (Object[]) dataMap.get("seals");
+ if(sealArray == null || sealArray.length == 0) {
+ break;
+ }
+ for (Object o : sealArray) {
+ SealInfoVo sealInfoVo = JsonUtils.parseObject(JsonUtils.toJSONString(o), SealInfoVo.class);
+ sealService.upsertOaSealDoc(sealInfoVo);
+ }
+ }while (true);
+
+ }
+
+ @Override
+ public String getName() {
+ return "E签宝印章信息同步任务";
+ }
+}
diff --git a/src/main/java/com/seeyon/apps/esign/msg/MessageVo.java b/src/main/java/com/seeyon/apps/esign/msg/MessageVo.java
new file mode 100644
index 0000000..1675d50
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/msg/MessageVo.java
@@ -0,0 +1,50 @@
+package com.seeyon.apps.esign.msg;
+
+public class MessageVo {
+
+ private String messageType;
+ private String messageContent;
+ private String messageTime;
+ private String messageReceiver;
+ private String bizId;
+
+ public String getMessageType() {
+ return messageType;
+ }
+
+ public void setMessageType(String messageType) {
+ this.messageType = messageType;
+ }
+
+ public String getMessageContent() {
+ return messageContent;
+ }
+
+ public void setMessageContent(String messageContent) {
+ this.messageContent = messageContent;
+ }
+
+ public String getMessageTime() {
+ return messageTime;
+ }
+
+ public void setMessageTime(String messageTime) {
+ this.messageTime = messageTime;
+ }
+
+ public String getMessageReceiver() {
+ return messageReceiver;
+ }
+
+ public void setMessageReceiver(String messageReceiver) {
+ this.messageReceiver = messageReceiver;
+ }
+
+ public String getBizId() {
+ return bizId;
+ }
+
+ public void setBizId(String bizId) {
+ this.bizId = bizId;
+ }
+}
diff --git a/src/main/java/com/seeyon/apps/esign/msg/ThirdMessageService.java b/src/main/java/com/seeyon/apps/esign/msg/ThirdMessageService.java
new file mode 100644
index 0000000..40ff08b
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/msg/ThirdMessageService.java
@@ -0,0 +1,8 @@
+package com.seeyon.apps.esign.msg;
+
+public interface ThirdMessageService {
+
+ void sendMessage(MessageVo messageVo);
+
+ void deletByBizId(String bizId);
+}
diff --git a/src/main/java/com/seeyon/apps/esign/node/EsignMultipleSignerNode.java b/src/main/java/com/seeyon/apps/esign/node/EsignMultipleSignerNode.java
new file mode 100644
index 0000000..b0ef62f
--- /dev/null
+++ b/src/main/java/com/seeyon/apps/esign/node/EsignMultipleSignerNode.java
@@ -0,0 +1,332 @@
+package com.seeyon.apps.esign.node;
+
+import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
+import com.seeyon.apps.esign.config.EsignConfigProvider;
+import com.seeyon.apps.esign.constants.EsignConfigConstants;
+import com.seeyon.apps.esign.po.param.FlowParamSource;
+import com.seeyon.apps.esign.po.signfield.NormalSignFieldConfig;
+import com.seeyon.apps.esign.po.signfield.SignField;
+import com.seeyon.apps.esign.po.signfield.SignFieldPosition;
+import com.seeyon.apps.esign.po.signer.Signer;
+import com.seeyon.apps.esign.service.ContractCreateService;
+import com.seeyon.apps.esign.service.EsignByTemplateService;
+import com.seeyon.apps.esign.service.EsignUploadFileService;
+import com.seeyon.apps.esign.service.FlowFormSignParamBuildFactory;
+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.cap4.form.bean.FormDataMasterBean;
+import com.seeyon.ctp.common.AppContext;
+import com.seeyon.ctp.common.exceptions.BusinessException;
+import com.seeyon.utils.form.FormTableExecutor;
+import com.seeyon.utils.form.FormUpdateField;
+import com.seeyon.utils.form.FormWhereCondition;
+import com.seeyon.utils.form.TableContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class EsignMultipleSignerNode extends ACommonSuperNode {
+
+ private static final Log log = LogFactory.getLog(EsignMultipleSignerNode.class);
+
+ private static final String CONTRACT_NAME_FIELD = "合同名称";
+ private static final String CONTRACT_ATTACHMENT_FIELD = "合同审批附件";
+ private static final String B_UNIT_NAME_FIELD = "乙方单位名称";
+ private EsignConfigProvider configProvider = EsignConfigProvider.getInstance();
+// private EsignUploadFileService uploadFileService = (EsignUploadFileService) AppContext.getBean("esignByUploadFileService");
+// private EsignByTemplateService templateService = (EsignByTemplateService) AppContext.getBean("esignByTemplateService");
+// private FlowFormSignParamBuildFactory flowFormSignParamBuildFactory = new FlowFormSignParamBuildFactory();
+ private ContractCreateService contractCreateService = (ContractCreateService) AppContext.getBean("contractCreateService");
+
+ @Override
+ public String getPluginId() {
+ return EsignConfigConstants.getPluginId();
+ }
+
+ @Override
+ public String getFormParse() {
+ return "";
+ }
+
+ @Override
+ public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) {
+ SuperNodeContext context = new SuperNodeContext();
+ context.setNeedSave(true);
+ log.info("进入E签宝多方签署集成超级节点");
+ try {
+// Map signParams = buildSignParams(formDataVo, formDataMasterBean, true);
+ FlowParamSource source = new FlowParamSource();
+ source.setConfigProvider(configProvider);
+ source.setFormDataVo(formDataVo);
+ source.setDoAutoSign(true);
+ source.setMasterBean(formDataMasterBean);
+ String esignFlowId = contractCreateService.startSign(source);
+ if(esignFlowId == null) {
+ return context.back("E签宝签署发起失败");
+ }
+ log.info("E签宝签署流程ID: " + esignFlowId + " , OA超级节点ID:" + formDataVo.getToken());
+ log.info("E签宝多方签署合同已发送: " + esignFlowId);
+ return context.wait("等待签署结束");
+ } catch (Exception e) {
+ log.error("E签宝签署失败", e);
+ context.setErrMsg("E签宝签署失败: " + e.getMessage());
+ return context.back("E签宝签署失败: " + e.getMessage());
+ }
+ }
+
+// private Map buildSignFlowConfig(FormDataVo formDataVo,FormDataMasterBean masterBean) throws Exception {
+// String contractName = getStringField(formDataVo, CONTRACT_NAME_FIELD);
+// if (contractName == null) throw new RuntimeException("合同名称不能为空");
+// String formId = formDataVo.getToken() +"_" + formDataVo.getId();
+// Long enumId = masterBean.getFormTable().getFieldBeanByDisplay("E签宝签署状态").getEnumId();
+// String signCallBackUrl = configProvider.getBizConfigByKey(EsignConfigConstants.OA_HOST) + "/seeyon/esigncallback.do?method=callback&formId=" + formId + "&tablename=" + masterBean.getFormTable().getTableName() + "&updatefield=" + masterBean.getFormTable().getFieldBeanByDisplay("盖章后合同附件").getColumnName() + "&statusfield=" + masterBean.getFormTable().getFieldBeanByDisplay("E签宝签署状态").getColumnName() + "_" + enumId;
+// Map config = new HashMap<>();
+// config.put("signFlowTitle", contractName);
+// config.put("autoFinish", true);
+// config.put("notifyUrl", signCallBackUrl);
+// Map noticeConfig = new HashMap<>();
+// noticeConfig.put("noticeTypes", "1");
+// config.put("noticeConfig", noticeConfig);
+// Map signConfig = new HashMap<>();
+// signConfig.put("showBatchDropSealButton", false);
+// config.put("signConfig",signConfig);
+// return config;
+// }
+
+// private List buildSigners(FormDataVo formDataVo, String fileId) throws Exception {
+// List keywords = new ArrayList<>();
+// keywords.add("甲方盖章/签字");
+// keywords.add("乙方盖章/签字");
+// List