国通领域e签宝集成开发完成

This commit is contained in:
2025-08-02 19:26:06 +08:00
parent e8bdf024e9
commit d0743ebc66
79 changed files with 6996 additions and 0 deletions

17
esign/pom.xml Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.seeyon.apps</groupId>
<artifactId>esign</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -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 GtlyEsignPluginApi extends APluginInfoApi {
public GtlyEsignPluginApi() {
}
public String getPluginId() {
System.out.println(EsignConfigConstants.getPluginId());
return EsignConfigConstants.getPluginId();
}
public String getCreateUser() {
return "橙阳科技";
}
public String getDescription() {
return "长数鸿翼网盘集成";
}
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;
}
}

View File

@@ -0,0 +1,20 @@
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 org.springframework.stereotype.Component;
import static com.seeyon.apps.esign.constants.EsignConfigConstants.getPluginId;
@Component
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());
}
}

View File

@@ -0,0 +1,17 @@
package com.seeyon.apps.esign.constants;
public class EsignApiUrl {
public static final String QUERY_SEAL_URL = "/v3/seals/org-own-seal-list";
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 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";
}

View File

@@ -0,0 +1,37 @@
package com.seeyon.apps.esign.constants;
public enum EsignConfigConstants {
plugin("src_esign",""),
APP_ID("7438886882",""),
APP_SECRET("325c8cc6c2a303d6cf1fb5657a16e591",""),
OA_HOST("",""),
ESIGN_HOST("",""),
SIGN_SERVICE_PROVIDER("ESIGN",""),
UNITNAME("","平台方组织名称"),
FORMEDITLOGINNAME("","表单修改登录名"),
updateAccountName("表单",""),
getTokenUrl("/seeyon/rest/token/","调用获取TOKEN地址"),
nodeTokenUrl("/seeyon/rest/flow/notification/","超级节点回调URL"),
restName("",""),
restPwd("",""),
;
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;
}
}

View File

@@ -0,0 +1,86 @@
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.EsignCallbackParams;
import com.seeyon.apps.esign.service.EsignByUploadFileService;
import com.seeyon.apps.esign.service.EsignCallbackBizService;
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;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EsignCallBackController extends BaseController {
private static final Log log = Log.get(EsignCallBackController.class);
private EsignByUploadFileService esignByUploadFileService = (EsignByUploadFileService) AppContext.getBean("esignByUploadFileService");
private EsignCallbackBizService esignCallbackBizService = (EsignCallbackBizService) AppContext.getBean("esignCallbackBizService");
private ConcurrentHashMap<String,String> callbackMap = new ConcurrentHashMap<>();
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<EsignCallbackParams>() {
});
String flowId = callbackParams.getSignFlowId();
String action = callbackParams.getAction();
if(!action.equals("SIGN_MISSON_COMPLETE")) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
if(callbackMap.contains(flowId)) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}else {
callbackMap.put(flowId, "1");
}
if(callbackParams.getSignResult() == 2) {
Map<String, Object> fileInfo = esignByUploadFileService.getDownloadFileInfo(flowId);
esignCallbackBizService.handleSuccessSignCallbackBiz(tableName,updatefield,statusfield,formId,(String)fileInfo.get("downloadUrl"),(String)fileInfo.get("fileName"));
}else {
esignCallbackBizService.handleFailSignCallbackBiz(tableName,statusfield,formId,callbackParams.getResultDescription());
}
//下载合同
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("回调处理完成");
callbackMap.remove(flowId);
return;
} catch (Exception e) {
log.error("回调处理失败", e);
}
response.setStatus(HttpServletResponse.SC_OK);
// response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}

View File

@@ -0,0 +1,10 @@
package com.seeyon.apps.esign.core;
public interface SignApiClient {
public String signByFile();
public String signByTemplate();
public String downloadContract();
}

View File

@@ -0,0 +1,21 @@
package com.seeyon.apps.esign.core;
import com.seeyon.apps.esign.config.EsignConfigProvider;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.service.EsignApiClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SignApiClientFactory {
@Autowired
private EsignConfigProvider configProvider;
public SignApiClient getSignApiClient() {
if(configProvider.getBizConfigByKey(EsignConfigConstants.SIGN_SERVICE_PROVIDER).equals("ESIGN")) {
return new EsignApiClient();
}
return null;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.core;
public abstract class SignParams {
private String appKey;
private String appSecret;
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
}

View File

@@ -0,0 +1,64 @@
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;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
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);
}
}

View File

@@ -0,0 +1,19 @@
package com.seeyon.apps.esign.form;
public enum ClauseFactor {
EQ, //相等
GT, //大于
GE, //大于等于
LT, //小于
LE, //小于等于
NULL, //空
NOT_NULL, //非空
LIKE, //模糊
AND,
OR
;
public boolean isNullType() {
return this == NULL || this == NOT_NULL;
}
}

View File

@@ -0,0 +1,108 @@
package com.seeyon.apps.esign.form;
import com.seeyon.cap4.form.api.FormApi4Cap4;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.bean.FormTableBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumBean;
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem;
import com.seeyon.ctp.util.JDBCAgent;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class EnumMapUtils {
public static String getMasterTableEnumItemValue(String formNo,String fieldDisplay, String targetValue) {
if(targetValue == null || "null".equals(targetValue) || "".equals(targetValue)){
return "";
}
try {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
FormFieldBean beanByDisplay = masterTableBean.getFieldBeanByDisplay(fieldDisplay);
if(beanByDisplay == null || beanByDisplay.getEnumId() == 0l) {
return "";
}
return getEnumItemValueByEnumId(targetValue, beanByDisplay.getEnumId());
} catch (Exception e) {
return "";
}
}
public static String getEnumItemValue(String rootPCode, String groupValue, String targetValue) {
if(targetValue == null || "null".equals(targetValue) || "".equals(targetValue)){
return "";
}
String queryIdSql = "SELECT ce.ID FROM ctp_enum ce inner join ctp_enum cei on ce.`PARENT_ID` = cei.ID where CEI.`PROGRAM_CODE` = ? and ce.`ENUMNAME` = ?";
Long enumId = null;
JDBCAgent agent = new JDBCAgent();
try {
agent.execute(queryIdSql, Arrays.asList(rootPCode,groupValue));
List<Map<String, Object>> list = (List<Map<String, Object>>) agent.resultSetToList();
if(list == null || list.size() == 0) {
return "";
}
Map map = list.get(0);
enumId = (Long)map.get("ID");
} catch (Exception e) {
return "";
}finally {
agent.close();
}
EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");
CtpEnumBean ctpEnumBean = enumManagerNew.getEnum(enumId);
if(ctpEnumBean == null) {
return "";
}
List<CtpEnumItem> ctpEnumItems = ctpEnumBean.getItems();
if(ctpEnumBean.getItems() == null) {
return "";
}
for (CtpEnumItem enumItem : ctpEnumItems) {
if(enumItem.getShowvalue().equals(targetValue)) {
return enumItem.getId() + "";
}
}
return "";
}
public static String getEnumItemValueByEnumId(String showValue,long enumId) {
EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");
CtpEnumBean ctpEnumBean = enumManagerNew.getEnum(enumId);
if(ctpEnumBean == null) {
return "";
}
List<CtpEnumItem> ctpEnumItems = ctpEnumBean.getItems();
if(ctpEnumBean.getItems() == null) {
return "";
}
for (CtpEnumItem enumItem : ctpEnumItems) {
if(enumItem.getShowvalue().equals(showValue)) {
return enumItem.getId() + "";
}
}
return "";
}
public static String getEnumShowValue(Object enumItemId) throws BusinessException {
if(enumItemId == null) {
return "";
}
Long temp = enumItemId instanceof Long ? (Long)enumItemId : (enumItemId instanceof String ? Long.parseLong((String)enumItemId) : null);
if(temp == null) {
return "";
}
EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");
CtpEnumItem ctpEnumItem = enumManagerNew.getCtpEnumItem(temp);
if(ctpEnumItem == null) {
return "";
}
return ctpEnumItem.getShowvalue();
}
}

View File

@@ -0,0 +1,32 @@
package com.seeyon.apps.esign.form;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FormColumn {
private String id;
private List<FormFieldVo> vos;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<FormFieldVo> getVos() {
return vos;
}
public void setVos(List<FormFieldVo> vos) {
this.vos = vos;
}
public Map<String,Object> getFieldsMap() {
Map<String,Object> map = new HashMap<>();
vos.forEach(vo -> map.put(vo.getDisplayName(),vo.getValue()));
return map;
}
}

View File

@@ -0,0 +1,630 @@
package com.seeyon.apps.esign.form;
import com.seeyon.cap4.form.api.FormApi4Cap4;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.bean.FormTableBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.JDBCAgent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
public class FormDataOperator {
private static final Log log = LogFactory.getLog(FormDataOperator.class);
public void updateMasterForm(String formNo, List<FormUpdateField> updateFieldVos, List<FormWhereCondition> conditionVos) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
if (updateFieldVos == null) {
throw new IllegalArgumentException("要修改的字段为空");
}
for (FormUpdateField fieldVo : updateFieldVos) {
FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(fieldVo.getDisplay());
if (bean == null) {
continue;
}
if(bean.getInputType().equals("image") || bean.getInputType().equals("attachment")){}
fieldVo.fieldName(bean.getColumnName());
}
List<FormUpdateField> updateFields = updateFieldVos.stream().filter(u -> u.getFieldName() != null).collect(Collectors.toList());
for (FormWhereCondition conditionVo : conditionVos) {
FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
if (bean == null) {
if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) {
conditionVo.setFieldName(conditionVo.getDisplay());
}
continue;
}
conditionVo.setFieldName(bean.getColumnName());
}
List<FormWhereCondition> conditions = conditionVos.stream().filter(c -> c.getFieldName() != null).collect(Collectors.toList());
Map<String, Object> map = generateSql(updateFields, masterTableBean.getTableName(), conditions);
JDBCAgent agent = new JDBCAgent();
try {
agent.execute((String) map.get("sql"), (List<Object>) map.get("params"));
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
agent.close();
}
}
public void updateMasterForm(List<FormUpdateField> updateFields,String tableName, List<FormWhereCondition> conditionVos) throws BusinessException {
if (updateFields == null) {
throw new IllegalArgumentException("要修改的字段为空");
}
List<FormWhereCondition> conditions = conditionVos.stream().filter(c -> c.getFieldName() != null).collect(Collectors.toList());
Map<String, Object> map = generateSql(updateFields, tableName, conditions);
JDBCAgent agent = new JDBCAgent();
try {
agent.execute((String) map.get("sql"), (List<Object>) map.get("params"));
log.info("sql: " + map.get("sql") + " 更新表单执行成功");
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
agent.close();
}
}
public FormColumn queryOneRowFormData(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<String> queryColumns = new ArrayList<>();
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
String tableName = masterTableBean.getTableName();
Map<String, FormFieldBean> fieldMap4Display = masterTableBean.getFieldMap4Display();
Map<String, FormFieldBean> fieldMap4Name = masterTableBean.getFieldMap4Name();
if (queryColumnVos != null) {
for (String queryColumnVo : queryColumnVos) {
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(queryColumnVo);
if (fieldBeanByDisplay == null) {
continue;
}
queryColumns.add(fieldBeanByDisplay.getColumnName());
}
}
for (FormWhereCondition conditionVo : conditionVos) {
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
if (fieldBeanByDisplay == null) {
if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) {
conditionVo.setFieldName(conditionVo.getDisplay());
}
continue;
}
conditionVo.setFieldName(fieldBeanByDisplay.getColumnName());
}
Map<String, Object> generateSql = generateSql(queryColumns, conditionVos, tableName);
String sql = (String) generateSql.get("sql");
List<Object> params = (List<Object>) generateSql.get("params");
JDBCAgent jdbcAgent = new JDBCAgent();
List<FormColumn> columns = new ArrayList<>();
try {
jdbcAgent.execute(sql, params);
List list = jdbcAgent.resultSetToList();
for (Object o : list) {
FormColumn column = new FormColumn();
Map<String, Object> columnMap = (Map<String, Object>) o;
List<FormFieldVo> vos = new ArrayList<>();
for (String key : columnMap.keySet()) {
FormFieldVo fieldVo = new FormFieldVo();
if (fieldMap4Name.containsKey(key)) {
FormFieldBean fieldBean = fieldMap4Name.get(key);
fieldVo.setDisplayName(fieldBean.getDisplay());
fieldVo.setValue(columnMap.get(key));
vos.add(fieldVo);
}
}
column.setVos(vos);
if (columnMap.get("id") != null) {
column.setId(columnMap.get("id") + "");
}
columns.add(column);
}
return columns.get(0);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
jdbcAgent.close();
}
return null;
}
public List<FormColumn> queryFormDataCondition(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<String> queryColumns = new ArrayList<>();
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
String tableName = masterTableBean.getTableName();
Map<String, FormFieldBean> fieldMap4Display = masterTableBean.getFieldMap4Display();
Map<String, FormFieldBean> fieldMap4Name = masterTableBean.getFieldMap4Name();
if (queryColumnVos != null) {
for (String queryColumnVo : queryColumnVos) {
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(queryColumnVo);
if (fieldBeanByDisplay == null) {
continue;
}
queryColumns.add(fieldBeanByDisplay.getColumnName());
}
}
for (FormWhereCondition conditionVo : conditionVos) {
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
if (fieldBeanByDisplay == null) {
if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) {
conditionVo.setFieldName(conditionVo.getDisplay());
}
continue;
}
conditionVo.setFieldName(fieldBeanByDisplay.getColumnName());
}
Map<String, Object> generateSql = generateSql(queryColumns, conditionVos, tableName);
String sql = (String) generateSql.get("sql");
List<Object> params = (List<Object>) generateSql.get("params");
JDBCAgent jdbcAgent = new JDBCAgent();
List<FormColumn> columns = new ArrayList<>();
try {
jdbcAgent.execute(sql, params);
List list = jdbcAgent.resultSetToList();
for (Object o : list) {
FormColumn column = new FormColumn();
Map<String, Object> columnMap = (Map<String, Object>) o;
List<FormFieldVo> vos = new ArrayList<>();
for (String key : columnMap.keySet()) {
FormFieldVo fieldVo = new FormFieldVo();
if (fieldMap4Name.containsKey(key)) {
FormFieldBean fieldBean = fieldMap4Name.get(key);
fieldVo.setDisplayName(fieldBean.getDisplay());
fieldVo.setValue(columnMap.get(key));
vos.add(fieldVo);
}
}
column.setVos(vos);
if (columnMap.get("id") != null) {
column.setId(columnMap.get("id") + "");
}
columns.add(column);
}
return columns;
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
jdbcAgent.close();
}
return null;
}
public boolean queryExist(List<FormWhereCondition> conditionVos,String tableName) throws BusinessException {
String sql = "select 1 from " + tableName + " where 1=1 " + " AND " + conditionVos.get(0).getFieldName() + " =? " + " AND " + conditionVos.get(1).getFieldName() + " is not null;";
JDBCAgent jdbcAgent = new JDBCAgent();
List<Object> params = new ArrayList<>();
params.add(conditionVos.get(0).getValue());
try {
jdbcAgent.execute(sql, params);
List list = jdbcAgent.resultSetToList();
return list.size() > 0;
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
jdbcAgent.close();
}
return false;
}
private Map<String, Object> generateSql(List<String> queryColumn, List<FormWhereCondition> conditions, String tableName) {
if (tableName == null) {
throw new IllegalArgumentException("tableName cannot be null or empty");
}
StringBuilder sqlBuilder = new StringBuilder("SELECT ");
if (queryColumn == null || queryColumn.isEmpty()) {
sqlBuilder.append("*");
}
for (int i = 0; i < queryColumn.size(); i++) {
sqlBuilder.append(queryColumn.get(i));
if (queryColumn.size() > 1 && i >= 0 && i < queryColumn.size() - 1) {
sqlBuilder.append(",");
}
}
if (queryColumn.size() > 0) {
sqlBuilder.append(",`ID`");
}
sqlBuilder.append(" from " + tableName);
List<Object> params = new ArrayList<>();
sqlBuilder.append(buildWhereClause(conditions,params));
Map<String, Object> result = new HashMap<>();
result.put("sql", sqlBuilder.toString());
result.put("params", params);
return result;
}
private Map<String, Object> generateSql(List<FormUpdateField> fieldValues, String tableName,List<FormWhereCondition> conditions) {
if (fieldValues == null || fieldValues.isEmpty()) {
throw new IllegalArgumentException("Field values cannot be null or empty");
}
if (tableName == null || tableName.trim().isEmpty()) {
throw new IllegalArgumentException("Table name cannot be null or empty");
}
StringBuilder sqlBuilder = new StringBuilder("UPDATE ").append(tableName).append(" SET ");
List<Object> params = new ArrayList<>();
// Build the SET clause
int fieldCount = 0;
for (FormUpdateField updateField : fieldValues) {
if (updateField.getValue() == null || "".equals(updateField.getValue()) || "null".equals(updateField.getValue())) {
continue;
}
if (fieldCount > 0) {
sqlBuilder.append(", ");
}
if (updateField.getValue() instanceof String && ((String) updateField.getValue()).startsWith("DATE>")) {
String oldValue = (String) updateField.getValue();
sqlBuilder.append(updateField.getFieldName()).append(" = TO_DATE( ?, 'YYYY-MM-DD')");
updateField.setValue(oldValue.substring(oldValue.indexOf(">") + 1));
} else {
sqlBuilder.append(updateField.getFieldName()).append(" = ?");
}
params.add(updateField.getValue());
fieldCount++;
}
String whereClauseStr = buildWhereClause(conditions,params);
// Append the WHERE clause
sqlBuilder.append(whereClauseStr);
// Create result map
Map<String, Object> result = new HashMap<>();
result.put("sql", sqlBuilder.toString());
result.put("params", params);
return result;
}
public Map<String,List<Object>> getMainFormTableAttachments(String formNo,Map<String,Object> sourceMap) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
Map<String,List<Object>> attachmentTempMap = new HashMap<>();
Set<String> removeKey = new HashSet<>();
for (String key : sourceMap.keySet()) {
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(key);
if(fieldBeanByDisplay == null ){
continue;
}
if(fieldBeanByDisplay.getInputType().equals("image") ||
fieldBeanByDisplay.getInputType().equals("attachment")) {
attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List<Object>)sourceMap.get(key));
removeKey.add(key);
}
}
for (String key : removeKey) {
sourceMap.remove(key);
}
return attachmentTempMap;
}
public Map<String,List<Object>> getSubFormTableAttachments(String formNo,Map<String,Object> sourceMap) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<FormTableBean> subTableBean = cap4FormBean.getSubTableBean();
Map<String,List<Object>> attachmentTempMap = new HashMap<>();
String tableName = null;
for (String key : sourceMap.keySet()) {
tableName = key;
}
String finalTableName = tableName;
FormTableBean tableBean = subTableBean.stream().filter(s->s.getTableName().equals(finalTableName)).collect(Collectors.toList()).get(0);
List<Map<String,Object>> tableData = (List<Map<String,Object>>)sourceMap.get(tableName);
Set<String> removeKey = new HashSet<>();
for (Map<String, Object> rowData : tableData) {
for (String key : rowData.keySet()) {
FormFieldBean fieldBeanByDisplay = tableBean.getFieldBeanByDisplay(key);
if(fieldBeanByDisplay == null ){
continue;
}
if(fieldBeanByDisplay.getInputType().equals("image") ||
fieldBeanByDisplay.getInputType().equals("attachment")) {
attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List<Object>)sourceMap.get(key));
removeKey.add(key);
}
}
for (String key : removeKey) {
rowData.remove(key);
}
removeKey.clear();
}
return attachmentTempMap;
}
public void addSubTableRecord(String subTableName,List<Object> data,String formNo,String formId) {
JDBCAgent agent = new JDBCAgent();
try {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<FormTableBean> tableBean = cap4FormBean.getSubTableBean();
for (FormTableBean bean : tableBean) {
if(!bean.getTableName().equals(subTableName)) {
continue;
}
for (Object column : data) {
Map<String,Object> map = (Map<String,Object>) column;
Map<String,Object> tempMap = new HashMap<>();
for (String key : map.keySet()) {
FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key);
if(fieldBeanByDisplay == null) {
continue;
}
tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key));
}
tempMap.put("formmain_id",formId);
tempMap.put("sort",1);
tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits()));
Map<String, Object> insertSql = generateInsertSql(tempMap, subTableName);
agent.execute((String)insertSql.get("sql"),(List<Object>)insertSql.get("params"));
}
}
} catch (Exception e) {
} finally {
agent.close();
}
}
public void rebuildSubTableRecord(String subTableName,List<Object> data,String formNo,String formId) {
String deleteSql = "delete from " + subTableName + " where formmain_id = ? ";
JDBCAgent agent = new JDBCAgent();
try {
agent.execute(deleteSql, Arrays.asList(formId));
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<FormTableBean> tableBean = cap4FormBean.getSubTableBean();
for (FormTableBean bean : tableBean) {
if(!bean.getTableName().equals(subTableName)) {
continue;
}
for (Object column : data) {
Map<String,Object> map = (Map<String,Object>) column;
Map<String,Object> tempMap = new HashMap<>();
for (String key : map.keySet()) {
FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key);
if(fieldBeanByDisplay == null) {
continue;
}
tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key));
}
tempMap.put("formmain_id",formId);
tempMap.put("sort",1);
tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits()));
Map<String, Object> insertSql = generateInsertSql(tempMap, subTableName);
agent.execute((String)insertSql.get("sql"),(List<Object>)insertSql.get("params"));
}
}
} catch (Exception e) {
} finally {
agent.close();
}
}
public void handleEnumDeptEtc(Map<String,Object> map,String formNo) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
for (String key : map.keySet()) {
FormFieldBean fieldBean = masterTableBean.getFieldBeanByDisplay(key);
if(fieldBean == null) {
continue;
}
switch (fieldBean.getInputType()) {
case "select": if(fieldBean.getEnumId() != 0l) {
String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)map.get(key),fieldBean.getEnumId());
map.put(key,enumItemId);
} break;
case "image":break;
case "attachment": break;
case "account": break;
case "department": break;
case "radio": break;
case "member":break;
case "checkbox":
case "date":
case "text":break;
default: break;
}
}
}
public void handleSubTableEnumDeptEtc(Map<String,Object> map,String formNo) throws BusinessException {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
List<FormTableBean> subTableBean = cap4FormBean.getSubTableBean();
for (FormTableBean tableBean : subTableBean) {
String tableName = null;
for (String key : map.keySet()) {
tableName = key;
}
if(!tableBean.getTableName().equals(tableName)) {
continue;
}
List<Map<String,Object>> subDatas = (List<Map<String, Object>>) map.get(tableName);
for (Map<String, Object> subData : subDatas) {
for (String key : subData.keySet()) {
FormFieldBean fieldBean = tableBean.getFieldBeanByDisplay(key);
if(fieldBean == null) {
continue;
}
switch (fieldBean.getInputType()) {
case "select": if(fieldBean.getEnumId() != 0l) {
String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)subData.get(key),fieldBean.getEnumId());
subData.put(key,enumItemId);
} break;
case "image":break;
case "attachment": break;
case "account": break;
case "department": break;
case "radio": break;
case "member":break;
case "checkbox":
case "date":
case "text":break;
default: break;
}
}
}
}
}
public boolean isMasterTableFile(String displayName,String formNo) {
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
try {
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(displayName);
return fieldBeanByDisplay.getInputType().equals("image") || fieldBeanByDisplay.getInputType().equals("attachment");
} catch (BusinessException e) {
}
return false;
}
private Map<String, Object> generateInsertSql(Map<String, Object> data, String tableName) {
if (tableName == null || tableName.isEmpty()) {
throw new IllegalArgumentException("tableName cannot be null or empty");
}
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("data cannot be null or empty");
}
StringBuilder sqlBuilder = new StringBuilder("INSERT INTO " + tableName + " (");
List<Object> params = new ArrayList<>();
// 拼接字段名
StringBuilder columns = new StringBuilder();
// 拼接字段值
StringBuilder values = new StringBuilder();
for (Map.Entry<String, Object> entry : data.entrySet()) {
// 拼接字段名
if (columns.length() > 0) {
columns.append(", ");
}
columns.append(entry.getKey());
// 拼接值,使用占位符 ?
if (values.length() > 0) {
values.append(", ");
}
values.append("?");
// 将值加入 params 列表
params.add(entry.getValue());
}
// 完善 SQL 语句
sqlBuilder.append(columns).append(") VALUES (").append(values).append(");");
Map<String, Object> result = new HashMap<>();
result.put("sql", sqlBuilder.toString());
result.put("params", params);
return result;
}
/**
* 动态生成 WHERE 子句
* @param conditions 条件集合
* @param params 参数列表(引用传递)
* @return 拼接后的 WHERE 子句(包含 WHERE 关键字)
*/
private String buildWhereClause(List<FormWhereCondition> conditions, List<Object> params) {
if (conditions == null || conditions.isEmpty()) {
return "";
}
StringBuilder whereClause = new StringBuilder(" WHERE ");
int conditionIndex = 0;
for (FormWhereCondition condition : conditions) {
// 处理括号起始
if (condition.isStartWithBracket()) {
whereClause.append("(");
}
// 字段名校验
String fieldName = condition.getFieldName();
ClauseFactor factor = condition.getClauseFactor();
String operator = parseOperator(factor);
// 构建条件表达式
String conditionExpr;
if (factor.isNullType()) {
// 处理 NULL/NOT NULL 条件(无需参数)
conditionExpr = String.format("%s %s", fieldName, operator);
} else {
// 处理普通条件(带占位符)
conditionExpr = String.format("%s %s ?", fieldName, operator);
// 处理函数模板(如 TO_DATE
if (condition.getIndex() != null) {
conditionExpr = conditionExpr.replace("?", condition.getIndex());
}
// 添加参数值
params.add(condition.getValue());
}
whereClause.append(conditionExpr);
// 处理括号闭合
if (condition.isEndWithBracket()) {
whereClause.append(")");
}
// 添加连接符AND/OR
if (conditionIndex < conditions.size() - 1) {
whereClause.append(" ").append(condition.getConcatFactor()).append(" ");
}
conditionIndex++;
}
return whereClause.toString();
}
/**
* 校验字段名合法性(防止 SQL 注入)
*/
private String validateFieldName(String fieldName) {
if (!fieldName.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
throw new IllegalArgumentException("非法字段名: " + fieldName);
}
return fieldName;
}
/**
* 解析运算符映射eq -> =, lt -> < 等)
*/
private String parseOperator(ClauseFactor factor) {
if(factor == null) {
return "=";
}
switch (factor) {
case EQ: return "=";
case GT: return ">";
case GE: return ">=";
case LT: return "<";
case LE: return "<=";
case LIKE: return "LIKE";
case NULL: return "IS NULL"; // 空值判断
case NOT_NULL: return "IS NOT NULL"; // 非空判断
default: throw new UnsupportedOperationException("不支持的运算符: " + factor);
}
}
}

View File

@@ -0,0 +1,64 @@
package com.seeyon.apps.esign.form;
import com.seeyon.v3x.services.form.bean.RecordExport;
import com.seeyon.v3x.services.form.bean.SubordinateFormExport;
import com.seeyon.v3x.services.form.bean.ValueExport;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
//创建无流程表单数据处理工具类
public class FormExportUtil {
/**
* 设置主表信息
* @param map 设置主表字段。Map<主表显示名称,主表数据>
* @return
*/
public static List<ValueExport> setFormValue(Map<String, String> map){
// 创建返回值对象
List<ValueExport> valueExports = new ArrayList<ValueExport>();
ValueExport valueExport ;
// 获取参数信息(显示名称)
Set<String> keys = map.keySet();
if(keys.size()>0) {
// 对控件赋值
for (String key : keys) {
valueExport = new ValueExport();
valueExport.setDisplayName(key);
valueExport.setValue("null".equals(map.get(key)) ? "" : map.get(key));
valueExports.add(valueExport);
}
}
return valueExports;
}
/**
* 设置从表信息
* @param map 设置主表字段。List<Map<显示名称,数据值>>
*/
public static List<SubordinateFormExport> setSubordinateFormValue(Map<String, String> map){
List<SubordinateFormExport> subordinateFormExports = new ArrayList<SubordinateFormExport>();
SubordinateFormExport subordinateFormExport = new SubordinateFormExport();
List<Map<String,String>> lists = new ArrayList<>();
lists.add(map);
List<RecordExport> recordExports = new ArrayList<RecordExport>();
List<ValueExport> valueExports;
RecordExport recordExport;
for(int i = 0 ; i < lists.size() ; i++) {
recordExport = new RecordExport();
valueExports = setFormValue(lists.get(i));
recordExport.setRecord(valueExports);
recordExports.add(recordExport);
}
subordinateFormExport.setValues(recordExports);
subordinateFormExports.add(subordinateFormExport);
return subordinateFormExports;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.form;
public class FormFieldVo {
private String displayName;
private Object value;
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}

View File

@@ -0,0 +1,57 @@
package com.seeyon.apps.esign.form;
public class FormUpdateField {
private String display;
private String fieldName;
private Object value;
public FormUpdateField(Object value) {
this.value = value;
}
public FormUpdateField() {
}
public static FormUpdateField build() {
return new FormUpdateField();
}
public FormUpdateField display(String display) {
this.display = display;
return this;
}
public FormUpdateField value(String value) {
this.value = value;
return this;
}
public FormUpdateField fieldName(String fieldName) {
this.fieldName = fieldName;
return this;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}

View File

@@ -0,0 +1,127 @@
package com.seeyon.apps.esign.form;
public class FormWhereCondition {
private String display;
private String fieldName; //字段名
private Object value; //值
private ClauseFactor clauseFactor = ClauseFactor.EQ; //条件因子 eq lt gt not_null null
private ClauseFactor concatFactor = ClauseFactor.AND; //拼接因子
private boolean startWithBracket = false; //是否以括号开头生成子条件
private boolean endWithBracket = false; //是否以括号结尾结束子条件
private String index;
public FormWhereCondition() {
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public static FormWhereCondition build() {
return new FormWhereCondition();
}
public FormWhereCondition fieldName(String fieldName) {
this.fieldName = fieldName;
return this;
}
public FormWhereCondition display(String display) {
this.display = display;
return this;
}
public FormWhereCondition value(Object value) {
this.value = value;
return this;
}
public FormWhereCondition clauseFactor(ClauseFactor clauseFactor) {
this.clauseFactor = clauseFactor;
return this;
}
public FormWhereCondition index(String index) {
this.index = index;
return this;
}
public FormWhereCondition startWithBracket(boolean startWithBracket) {
this.startWithBracket = startWithBracket;
return this;
}
public FormWhereCondition endWithBracket(boolean endWithBracket) {
this.endWithBracket = endWithBracket;
return this;
}
public FormWhereCondition concatFactor(ClauseFactor concatFactor) {
this.concatFactor = concatFactor;
return this;
}
public FormWhereCondition(Object value, ClauseFactor clauseFactor) {
this.value = value;
this.clauseFactor = clauseFactor;
}
public boolean isStartWithBracket() {
return startWithBracket;
}
public void setStartWithBracket(boolean startWithBracket) {
this.startWithBracket = startWithBracket;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public ClauseFactor getClauseFactor() {
return clauseFactor;
}
public void setClauseFactor(ClauseFactor clauseFactor) {
this.clauseFactor = clauseFactor;
}
public ClauseFactor getConcatFactor() {
return concatFactor;
}
public void setConcatFactor(ClauseFactor concatFactor) {
this.concatFactor = concatFactor;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public boolean isEndWithBracket() {
return endWithBracket;
}
public void setEndWithBracket(boolean endWithBracket) {
this.endWithBracket = endWithBracket;
}
}

View File

@@ -0,0 +1,154 @@
package com.seeyon.apps.esign.form;
public class QueryWhereCondition {
private String display;
private String fieldName; //字段名
private Object value; //值
private ClauseFactor clauseFactor = ClauseFactor.EQ; //条件因子 eq lt gt not_null null
private ClauseFactor concatFactor = ClauseFactor.AND; //拼接因子
private boolean startWithBracket = false; //是否以括号开头生成子条件
private boolean endWithBracket = false; //是否以括号结尾结束子条件
private String index;
private Integer limit = null;
private Integer offset = null;
public QueryWhereCondition() {
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public static QueryWhereCondition build() {
return new QueryWhereCondition();
}
public QueryWhereCondition fieldName(String fieldName) {
this.fieldName = fieldName;
return this;
}
public QueryWhereCondition display(String display) {
this.display = display;
return this;
}
public QueryWhereCondition value(Object value) {
this.value = value;
return this;
}
public QueryWhereCondition clauseFactor(ClauseFactor clauseFactor) {
this.clauseFactor = clauseFactor;
return this;
}
public QueryWhereCondition index(String index) {
this.index = index;
return this;
}
public QueryWhereCondition limit(Integer limit) {
this.limit = limit;
return this;
}
public QueryWhereCondition offset(Integer offset) {
this.offset = offset;
return this;
}
public QueryWhereCondition startWithBracket(boolean startWithBracket) {
this.startWithBracket = startWithBracket;
return this;
}
public QueryWhereCondition endWithBracket(boolean endWithBracket) {
this.endWithBracket = endWithBracket;
return this;
}
public QueryWhereCondition concatFactor(ClauseFactor concatFactor) {
this.concatFactor = concatFactor;
return this;
}
public QueryWhereCondition(Object value, ClauseFactor clauseFactor) {
this.value = value;
this.clauseFactor = clauseFactor;
}
public boolean isStartWithBracket() {
return startWithBracket;
}
public void setStartWithBracket(boolean startWithBracket) {
this.startWithBracket = startWithBracket;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public ClauseFactor getClauseFactor() {
return clauseFactor;
}
public void setClauseFactor(ClauseFactor clauseFactor) {
this.clauseFactor = clauseFactor;
}
public ClauseFactor getConcatFactor() {
return concatFactor;
}
public void setConcatFactor(ClauseFactor concatFactor) {
this.concatFactor = concatFactor;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public boolean isEndWithBracket() {
return endWithBracket;
}
public void setEndWithBracket(boolean endWithBracket) {
this.endWithBracket = endWithBracket;
}
public Integer getLimit() {
return limit;
}
public void setLimit(Integer limit) {
this.limit = limit;
}
public Integer getOffset() {
return offset;
}
public void setOffset(Integer offset) {
this.offset = offset;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class AuthExcludeInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String uri = request.getRequestURI();
if(uri.contains("/public/")) {
return true; // 放行公共接口
}
return super.preHandle(request, response, handler);
}
}

View File

@@ -0,0 +1,296 @@
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.form.FormDataOperator;
import com.seeyon.apps.esign.form.FormUpdateField;
import com.seeyon.apps.esign.form.FormWhereCondition;
import com.seeyon.apps.esign.po.*;
import com.seeyon.apps.esign.service.EsignByTemplateService;
import com.seeyon.apps.esign.service.EsignByUploadFileService;
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.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class EsignNode extends ACommonSuperNode {
private static final Log log = LogFactory.getLog(EsignNode.class);
private static final String CONTRACT_NAME_FIELD = "合同名称";
private static final String CONTRACT_ATTACHMENT_FIELD = "合同审批附件";
private static final String B_UNIT_NAME_FIELD = "乙方单位名称";
private static CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");
@Autowired
private EsignConfigProvider configProvider;
@Autowired
private EsignByUploadFileService uploadFileService;
@Autowired
private EsignByTemplateService templateService;
@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<String, Object> signParams = buildSignParams(formDataVo, formDataMasterBean, true);
if (signParams == null) throw new RuntimeException("签署参数构建失败");
String esignFlowId = templateService.createBySignTemplate(signParams);
log.info("E签宝签署流程ID: " + esignFlowId);
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<String, Object> 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<String, Object> config = new HashMap<>();
config.put("signFlowTitle", contractName);
config.put("autoFinish", true);
config.put("notifyUrl", signCallBackUrl);
Map<String, Object> noticeConfig = new HashMap<>();
noticeConfig.put("noticeTypes", "1");
config.put("noticeConfig", noticeConfig);
return config;
}
private List<Signer> buildSigners(FormDataVo formDataVo, String fileId,boolean qifengSign) throws Exception {
List<Object> positions = uploadFileService.getSignPosition(fileId);
SignFieldPosition bPosition = extractPosition(positions, "乙方盖章/签字");
SignFieldPosition aPosition = extractPosition(positions, "甲方盖章/签字");
String bSignerType = formDataVo.getFieldData("乙方签署类型").getStringValue();
SignFieldPosition aQiFengposition = new SignFieldPosition();
aQiFengposition.setAcrossPageMode("ALL");
aQiFengposition.setPositionY(348f);
SignFieldPosition bQiFengposition = new SignFieldPosition();
bQiFengposition.setAcrossPageMode("ALL");
bQiFengposition.setPositionY(500f);
List<SignFieldPosition> aPos = new ArrayList<>();
aPos.add(aPosition);
aPos.add(aQiFengposition);
List<SignFieldPosition> bPos = new ArrayList<>();
bPos.add(bPosition);
bPos.add(bQiFengposition);
Signer bSigner = !"组织".equals(bSignerType) ? createPsnSigner(fileId,formDataVo.getFieldData("乙方姓名").getStringValue(),bPos,1,formDataVo.getFieldData("乙方电话").getStringValue(),false) : createOrgSigner(
fileId,
getStringField(formDataVo, B_UNIT_NAME_FIELD),
bPos, 1, formDataVo.getFieldData("乙方法人姓名").getStringValue(),
formDataVo.getFieldData("乙方法人身份证号").getStringValue(),
formDataVo.getFieldData("乙方企业社会信用代码").getStringValue(),
formDataVo.getFieldData("乙方经办人手机号").getStringValue(),
formDataVo.getFieldData("乙方经办人姓名").getStringValue(),
formDataVo.getFieldData("乙方经办人身份证号").getStringValue(),false
);
Signer aSigner = createOrgSigner(
fileId,null, aPos, 2, null, null, null, null, null, null,true
);
List<Signer> signers = new ArrayList<>();
signers.add(bSigner);
signers.add(aSigner);
return signers;
}
private Map<String, Object> buildSignParams(FormDataVo formDataVo, FormDataMasterBean formDataMasterBean, boolean byFile) throws Exception {
String fileId = null;
if (byFile) {
String attachmentId = getStringField(formDataVo, CONTRACT_ATTACHMENT_FIELD);
if (attachmentId == null) throw new RuntimeException("合同附件不能为空");
fileId = uploadFileService.uploadFileToEsign(attachmentId);
}
Map<String, Object> docMap = new HashMap<>();
docMap.put("fileId", fileId);
List<Object> docs = new ArrayList<>();
docs.add(docMap);
Map<String, Object> signFlowConfig = buildSignFlowConfig(formDataVo, formDataMasterBean);
List<Signer> signers = buildSigners(formDataVo, fileId,true);
Map<String, Object> signParams = new HashMap<>();
signParams.put("signFlowConfig", signFlowConfig);
signParams.put("signers", signers);
signParams.put("docs", docs);
return signParams;
}
private void fillFileId(String fileId,FormDataVo formDataVo,FormDataMasterBean formDataMasterBean) throws NoSuchFieldException, BusinessException {
String tableName = formDataVo.getTableName();
FormFieldBean fieldBeanByDisplay = formDataMasterBean.getFormTable().getFieldBeanByDisplay("合同文件ID");
FormDataOperator formDataOperator = new FormDataOperator();
List<FormUpdateField> updateFields = new ArrayList<>();
updateFields.add(FormUpdateField.build().fieldName(fieldBeanByDisplay.getColumnName()).value(fileId));
List<FormWhereCondition> whereConditions = new ArrayList<>();
FormWhereCondition condition = FormWhereCondition.build().value(formDataVo.getId());
condition.setFieldName("ID");
whereConditions.add(condition);
formDataOperator.updateMasterForm(updateFields,tableName,whereConditions);
}
private Map<String, Object> mapOf(Object... keyValues) {
if (keyValues.length % 2 != 0) {
throw new IllegalArgumentException("参数个数必须为偶数key 和 value 必须成对出现");
}
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < keyValues.length; i += 2) {
Object key = keyValues[i];
Object value = keyValues[i + 1];
if (!(key instanceof String)) {
throw new IllegalArgumentException("key 必须是 String 类型,当前为:" + key.getClass());
}
map.put((String) key, value);
}
return map;
}
private Signer createPsnSigner( String fileId, String psnName,List<SignFieldPosition> pos, int order, String phone,Boolean autoSign) {
Signer signer = new Signer();
signer.setSignerType(0);
signer.setSignConfig(mapOf("signOrder", order));
if(Boolean.FALSE.equals(autoSign)){
signer.setNoticeConfig(mapOf("noticeTypes", "1"));
Map<String, Object> psnInfo = mapOf("psnAccount", phone, "psnInfo", mapOf("psnName", psnName));
signer.setPsnSignerInfo(psnInfo);
}
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
fieldConfig.setSignFieldPosition(pos.get(0));
fieldConfig.setAutoSign(autoSign);
fieldConfig.setSignFieldStyle(1);
SignField field = new SignField();
field.setSignFieldType(0);
field.setNormalSignFieldConfig(fieldConfig);
field.setFileId(fileId);
NormalSignFieldConfig qiFengfieldConfig = new NormalSignFieldConfig();
qiFengfieldConfig.setSignFieldPosition(pos.get(1));
qiFengfieldConfig.setAutoSign(autoSign);
qiFengfieldConfig.setSignFieldStyle(2);
SignField qiFengfield = new SignField();
qiFengfield.setSignFieldType(0);
qiFengfield.setNormalSignFieldConfig(qiFengfieldConfig);
qiFengfield.setFileId(fileId);
signer.setSignFields(Arrays.asList(field,qiFengfield));
return signer;
}
private Signer createOrgSigner(String fileId ,String orgName, List<SignFieldPosition> pos, int order,
String legalName, String legalId, String orgCode,
String transPhone, String psnName, String psnId,Boolean autoSign) {
Signer signer = new Signer();
signer.setSignerType(1);
signer.setSignConfig(mapOf("signOrder", order));
if(Boolean.FALSE.equals(autoSign)){
signer.setNoticeConfig(mapOf("noticeTypes", "1"));
Map<String, Object> orgInfo = mapOf("orgName", orgName, "orgInfo", mapOf(
"legalRepName", legalName,
"legalRepIDCardNum", legalId,
"orgIDCardNum", orgCode,
"orgIDCardType", "CRED_ORG_USCC"
),
"transactorInfo", mapOf(
"psnAccount", transPhone,
"psnInfo", mapOf(
"psnName", psnName,
"psnIDCardNum", psnId
)
)
);
signer.setOrgSignerInfo(orgInfo);
}
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
fieldConfig.setSignFieldPosition(pos.get(0));
fieldConfig.setAutoSign(autoSign);
fieldConfig.setSignFieldStyle(1);
SignField field = new SignField();
field.setSignFieldType(0);
field.setNormalSignFieldConfig(fieldConfig);
field.setFileId(fileId);
NormalSignFieldConfig qiFengfieldConfig = new NormalSignFieldConfig();
qiFengfieldConfig.setSignFieldPosition(pos.get(1));
qiFengfieldConfig.setAutoSign(autoSign);
qiFengfieldConfig.setSignFieldStyle(2);
SignField qiFengfield = new SignField();
qiFengfield.setSignFieldType(0);
qiFengfield.setNormalSignFieldConfig(qiFengfieldConfig);
qiFengfield.setFileId(fileId);
signer.setSignFields(Arrays.asList(field,qiFengfield));
return signer;
}
private SignFieldPosition extractPosition(List<Object> positions, String keyword) {
for (Object obj : positions) {
Map<String, Object> position = (Map<String, Object>) obj;
if (Boolean.TRUE.equals(position.get("searchResult")) && keyword.equals(position.get("keyword"))) {
Object[] posArray = (Object[]) position.get("positions");
Map<String, Object> posMap = (Map<String, Object>) posArray[0];
Map<String, Object> coord = (Map<String, Object>) ((Object[])posMap.get("coordinates"))[0];
SignFieldPosition sfp = new SignFieldPosition();
sfp.setPositionPage(posMap.get("pageNum") + "");
sfp.setPositionX(toFloat(coord.get("positionX")) + 150f);
sfp.setPositionY(toFloat(coord.get("positionY")));
return sfp;
}
}
throw new RuntimeException("未找到关键字位置: " + keyword);
}
private String getStringField(FormDataVo vo, String field) throws NoSuchFieldException {
return vo.getFieldData(field) != null ? vo.getFieldData(field).getStringValue() : null;
}
private Float toFloat(Object val) {
return val instanceof Number ? ((Number) val).floatValue() : Float.parseFloat(val.toString());
}
@Override
public String getNodeId() {
return "nd_20250702";
}
@Override
public String getNodeName() {
return "E签宝签署节点";
}
}

View File

@@ -0,0 +1,38 @@
package com.seeyon.apps.esign.node;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
public class EsignOrgAuthNode extends ACommonSuperNode {
@Override
public String getPluginId() {
return "";
}
@Override
public String getFormParse() {
return "";
}
@Override
public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
//个人实名认证、企业认证处理
return null;
}
public void personAuth() {
// /v3/psn-auth-url
}
@Override
public String getNodeId() {
return "";
}
@Override
public String getNodeName() {
return "";
}
}

View File

@@ -0,0 +1,56 @@
package com.seeyon.apps.esign.node;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
import com.seeyon.apps.esign.po.AuthPsnInfo;
import com.seeyon.apps.esign.po.PsnAuthConfig;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import java.util.HashMap;
import java.util.Map;
public class EsignPersonAuthNode extends ACommonSuperNode {
@Override
public String getPluginId() {
return "";
}
@Override
public String getFormParse() {
return "";
}
@Override
public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
Map<String,Object> authParams = new HashMap<>();
PsnAuthConfig psnAuthConfig = buildPsnAuthConfig(formDataVo,formDataMasterBean);
String notifyUrl= "";
authParams.put("psnAuthConfig",psnAuthConfig);
authParams.put("notifyUrl",notifyUrl);
return null;
}
private PsnAuthConfig buildPsnAuthConfig(FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
PsnAuthConfig psnAuthConfig = new PsnAuthConfig();
psnAuthConfig.setPsnAccount(formDataVo.getFieldData("客户联系电话").getStringValue());
AuthPsnInfo authPsnInfo = new AuthPsnInfo();
authPsnInfo.setPsnName(formDataVo.getFieldData("客户联系人姓名").getStringValue());
authPsnInfo.setPsnMobile(formDataVo.getFieldData("客户联系电话").getStringValue());
authPsnInfo.setPsnIDCardType("CRED_PSN_CH_IDCARD");
authPsnInfo.setPsnIDCardNum(formDataVo.getFieldData("客户身份证号").getStringValue());
authPsnInfo.setPsnIdentityVerify(true);
return psnAuthConfig;
}
@Override
public String getNodeId() {
return "";
}
@Override
public String getNodeName() {
return "";
}
}

View File

@@ -0,0 +1,61 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class AuthPsnInfo {
private String psnName;
private String psnIDCardNum;
private String psnIDCardType;
private String psnMobile;
private String bankCardNum;
private Boolean psnIdentityVerify;
public String getPsnName() {
return psnName;
}
public void setPsnName(String psnName) {
this.psnName = psnName;
}
public String getPsnIDCardNum() {
return psnIDCardNum;
}
public void setPsnIDCardNum(String psnIDCardNum) {
this.psnIDCardNum = psnIDCardNum;
}
public String getPsnIDCardType() {
return psnIDCardType;
}
public void setPsnIDCardType(String psnIDCardType) {
this.psnIDCardType = psnIDCardType;
}
public String getPsnMobile() {
return psnMobile;
}
public void setPsnMobile(String psnMobile) {
this.psnMobile = psnMobile;
}
public String getBankCardNum() {
return bankCardNum;
}
public void setBankCardNum(String bankCardNum) {
this.bankCardNum = bankCardNum;
}
public Boolean getPsnIdentityVerify() {
return psnIdentityVerify;
}
public void setPsnIdentityVerify(Boolean psnIdentityVerify) {
this.psnIdentityVerify = psnIdentityVerify;
}
}

View File

@@ -0,0 +1,61 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ContractFile {
private String fileId;
private String fileName;
private Boolean neededPwd;
private String fileEditPwd;
private String contractBizTypeId;
private int order;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Boolean getNeededPwd() {
return neededPwd;
}
public void setNeededPwd(Boolean neededPwd) {
this.neededPwd = neededPwd;
}
public String getFileEditPwd() {
return fileEditPwd;
}
public void setFileEditPwd(String fileEditPwd) {
this.fileEditPwd = fileEditPwd;
}
public String getContractBizTypeId() {
return contractBizTypeId;
}
public void setContractBizTypeId(String contractBizTypeId) {
this.contractBizTypeId = contractBizTypeId;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}

View File

@@ -0,0 +1,220 @@
package com.seeyon.apps.esign.po;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
public class EsignApiHeader {
private String xTsignOpenAppId;
private String xTsignOpenAuthMode;
private String xTsignOpenCaSignature;
private String xTsignOpenCaTimestamp;
private String accept;
private String contentType = "application/json; charset=UTF-8";
private String contentMd5;
private String httpMethod;
private String date;
private String headers;
private String pathAndParameters;
private String token;
public String getxTsignOpenAppId() {
return xTsignOpenAppId;
}
public void setxTsignOpenAppId(String xTsignOpenAppId) {
this.xTsignOpenAppId = xTsignOpenAppId;
}
public String getX_Tsign_Open_Auth_Mode() {
return xTsignOpenAuthMode;
}
public void setX_Tsign_Open_Auth_Mode(String x_Tsign_Open_Auth_Mode) {
this.xTsignOpenAuthMode = x_Tsign_Open_Auth_Mode;
}
public String getxTsignOpenCaSignature() {
return xTsignOpenCaSignature;
}
public void setxTsignOpenCaSignature(String xTsignOpenCaSignature) {
this.xTsignOpenCaSignature = xTsignOpenCaSignature;
}
public String getxTsignOpenCaTimestamp() {
return xTsignOpenCaTimestamp;
}
public void setxTsignOpenCaTimestamp(String xTsignOpenCaTimestamp) {
this.xTsignOpenCaTimestamp = xTsignOpenCaTimestamp;
}
public String getAccept() {
return accept;
}
public void setAccept(String accept) {
this.accept = accept;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContentMd5() {
return contentMd5;
}
public void setContentMd5(String contentMd5) {
this.contentMd5 = contentMd5;
}
public static EsignApiHeader build() {
EsignApiHeader header = new EsignApiHeader();
header.setAccept("*/*");
header.setX_Tsign_Open_Auth_Mode("Signature");
return header;
}
public EsignApiHeader pathAndParameters(String pathAndParameters) {
this.pathAndParameters = pathAndParameters;
return this;
}
public EsignApiHeader appId(String appId) {
this.xTsignOpenAppId = appId;
return this;
}
public EsignApiHeader heads(String headers) {
this.headers = headers;
return this;
}
public EsignApiHeader timeStamp() {
this.xTsignOpenCaTimestamp = System.currentTimeMillis() + "";
return this;
}
public EsignApiHeader token(String token) {
this.token = token;
return this;
}
public EsignApiHeader contentMD5(String body) {
this.contentMd5 = getBodyContentMD5(body);
return this;
}
public EsignApiHeader httpMethod(String httpMethod) {
this.httpMethod = httpMethod;
return this;
}
public EsignApiHeader signature(String secret) throws Exception {
StringBuffer strBuff = new StringBuffer();
strBuff.append(httpMethod).append("\n").append(accept).append("\n").append(contentMd5).append("\n")
.append(contentType).append("\n").append("").append("\n");
if ("".equals(headers)) {
strBuff.append(headers).append(pathAndParameters);
} else {
strBuff.append(headers).append("\n").append(pathAndParameters);
}
String StringToSign = strBuff.toString();
this.setxTsignOpenCaSignature(doSignatureBase64(StringToSign, secret));
return this;
}
public String doSignatureBase64(String message, String secret) throws Exception {
String algorithm = "HmacSHA256";
Mac hmacSha256;
String digestBase64 = null;
try {
hmacSha256 = Mac.getInstance(algorithm);
byte[] keyBytes = secret.getBytes("UTF-8");
byte[] messageBytes = message.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
// 把摘要后的结果digestBytes使用Base64进行编码
digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
} catch (NoSuchAlgorithmException e) {
String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (UnsupportedEncodingException e) {
String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (InvalidKeyException e) {
String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
}
return digestBase64;
}
/***
* 计算请求Body体的Content-MD5
* @param bodyData 请求Body体数据
* @return
*/
public String getBodyContentMD5(String bodyData) {
if("".equals(bodyData)) {
return bodyData;
}
// 获取Body体的MD5的二进制数组128位
byte[] bytes = getBodyMD5Bytes128(bodyData);
// 对Body体MD5的二进制数组进行Base64编码
return new String(Base64.encodeBase64(bytes));
}
public byte[] getBodyMD5Bytes128(String bodyData) {
byte[] md5Bytes = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(bodyData.getBytes(StandardCharsets.UTF_8));
md5Bytes = md5.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5Bytes;
}
public Map<String,String> convert2Headers(){
Map<String,String> headers = new HashMap<>();
if(xTsignOpenAppId != null) {
headers.put("X-Tsign-Open-App-Id", xTsignOpenAppId);
}
if(token != null) {
headers.put("X-Tsign-Open-Token", token);
}
if(contentType != null) {
headers.put("Content-Type", contentType);
}
if(!StringUtils.isBlank(contentMd5)) {
headers.put("Content-MD5", contentMd5);
}
return headers;
}
}

View File

@@ -0,0 +1,31 @@
package com.seeyon.apps.esign.po;
public class EsignBaseResp {
private int code;
private String message;
private Object data;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@@ -0,0 +1,46 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.Serializable;
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsignCallbackParams implements Serializable {
private String signFlowId;
private String action;
private String resultDescription; //签署结果描述
private Integer signResult; //签署结果
public String getSignFlowId() {
return signFlowId;
}
public void setSignFlowId(String signFlowId) {
this.signFlowId = signFlowId;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getResultDescription() {
return resultDescription;
}
public void setResultDescription(String resultDescription) {
this.resultDescription = resultDescription;
}
public Integer getSignResult() {
return signResult;
}
public void setSignResult(Integer signResult) {
this.signResult = signResult;
}
}

View File

@@ -0,0 +1,36 @@
package com.seeyon.apps.esign.po;
/**
* description 自定义全局异常
* @author 澄泓
* datetime 2019年7月1日上午10:43:24
*/
public class EsignException extends Exception {
private static final long serialVersionUID = 4359180081622082792L;
private Exception e;
public EsignException(String msg) {
super(msg);
}
public EsignException(String msg, Throwable cause) {
super(msg,cause);
}
public EsignException(){
}
public Exception getE() {
return e;
}
public void setE(Exception e) {
this.e = e;
}
}

View File

@@ -0,0 +1,49 @@
package com.seeyon.apps.esign.po;
public class EsignFileUploadParams {
private String contentMd5;
private String contentType;
private String fileName;
private Long fileSize;
private Boolean convertToPDF = false;
public String getContentMd5() {
return contentMd5;
}
public void setContentMd5(String contentMd5) {
this.contentMd5 = contentMd5;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
public Boolean getConvertToPDF() {
return convertToPDF;
}
public void setConvertToPDF(Boolean convertToPDF) {
this.convertToPDF = convertToPDF;
}
}

View File

@@ -0,0 +1,27 @@
package com.seeyon.apps.esign.po;
/**
* 网络请求的response类
* @author 澄泓
* @date 2022/2/21 17:28
* @version
*/
public class EsignHttpResponse {
private int status;
private String body;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}

View File

@@ -0,0 +1,34 @@
package com.seeyon.apps.esign.po;
import java.io.Serializable;
public class EsignToken implements Serializable {
private String tokenStr;
private Long ttl;
private String refreshToken;
public String getTokenStr() {
return tokenStr;
}
public void setTokenStr(String tokenStr) {
this.tokenStr = tokenStr;
}
public Long getTtl() {
return ttl;
}
public void setTtl(Long ttl) {
this.ttl = ttl;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}

View File

@@ -0,0 +1,23 @@
package com.seeyon.apps.esign.po;
public class GetUploadUrlResp {
private String fileId;
private String fileUploadUrl;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getFileUploadUrl() {
return fileUploadUrl;
}
public void setFileUploadUrl(String fileUploadUrl) {
this.fileUploadUrl = fileUploadUrl;
}
}

View File

@@ -0,0 +1,31 @@
package com.seeyon.apps.esign.po;
public class NormalSignFieldConfig {
private Boolean autoSign;
private Integer signFieldStyle;
private SignFieldPosition signFieldPosition;
public Boolean getAutoSign() {
return autoSign;
}
public void setAutoSign(Boolean autoSign) {
this.autoSign = autoSign;
}
public Integer getSignFieldStyle() {
return signFieldStyle;
}
public void setSignFieldStyle(Integer signFieldStyle) {
this.signFieldStyle = signFieldStyle;
}
public SignFieldPosition getSignFieldPosition() {
return signFieldPosition;
}
public void setSignFieldPosition(SignFieldPosition signFieldPosition) {
this.signFieldPosition = signFieldPosition;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.po;
public class OrgInitiator {
private String orgId;
private Transactor transactor;
public String getOrgId() {
return orgId;
}
public void setOrgId(String orgId) {
this.orgId = orgId;
}
public Transactor getTransactor() {
return transactor;
}
public void setTransactor(Transactor transactor) {
this.transactor = transactor;
}
}

View File

@@ -0,0 +1,40 @@
package com.seeyon.apps.esign.po;
public class PsnAuthConfig {
private String psnAccount;
private String psnId;
private AuthPsnInfo psnInfo;
private PsnAuthPageConfig psnAuthPageConfig;
public String getPsnAccount() {
return psnAccount;
}
public void setPsnAccount(String psnAccount) {
this.psnAccount = psnAccount;
}
public String getPsnId() {
return psnId;
}
public void setPsnId(String psnId) {
this.psnId = psnId;
}
public AuthPsnInfo getPsnInfo() {
return psnInfo;
}
public void setPsnInfo(AuthPsnInfo psnInfo) {
this.psnInfo = psnInfo;
}
public PsnAuthPageConfig getPsnAuthPageConfig() {
return psnAuthPageConfig;
}
public void setPsnAuthPageConfig(PsnAuthPageConfig psnAuthPageConfig) {
this.psnAuthPageConfig = psnAuthPageConfig;
}
}

View File

@@ -0,0 +1,45 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class PsnAuthPageConfig {
private String psnDefaultAuthMode;
private List<String> psnAvailableAuthModes;
private List<String> advancedVersion;
private List<String> psnEditableFields;
public String getPsnDefaultAuthMode() {
return psnDefaultAuthMode;
}
public void setPsnDefaultAuthMode(String psnDefaultAuthMode) {
this.psnDefaultAuthMode = psnDefaultAuthMode;
}
public List<String> getPsnAvailableAuthModes() {
return psnAvailableAuthModes;
}
public void setPsnAvailableAuthModes(List<String> psnAvailableAuthModes) {
this.psnAvailableAuthModes = psnAvailableAuthModes;
}
public List<String> getAdvancedVersion() {
return advancedVersion;
}
public void setAdvancedVersion(List<String> advancedVersion) {
this.advancedVersion = advancedVersion;
}
public List<String> getPsnEditableFields() {
return psnEditableFields;
}
public void setPsnEditableFields(List<String> psnEditableFields) {
this.psnEditableFields = psnEditableFields;
}
}

View File

@@ -0,0 +1,13 @@
package com.seeyon.apps.esign.po;
public class PsnInitiator {
private String psnId;
public String getPsnId() {
return psnId;
}
public void setPsnId(String psnId) {
this.psnId = psnId;
}
}

View File

@@ -0,0 +1,32 @@
package com.seeyon.apps.esign.po;
public class RemarkSignFieldConfig {
private boolean freeMode = false;
private int inputType = 1;
private String remarkContent = "";
public boolean isFreeMode() {
return freeMode;
}
public void setFreeMode(boolean freeMode) {
this.freeMode = freeMode;
}
public int getInputType() {
return inputType;
}
public void setInputType(int inputType) {
this.inputType = inputType;
}
public String getRemarkContent() {
return remarkContent;
}
public void setRemarkContent(String remarkContent) {
this.remarkContent = remarkContent;
}
}

View File

@@ -0,0 +1,32 @@
package com.seeyon.apps.esign.po;
public class RestUser {
private String restName;
private String restPassword;
private String loginName;
public String getRestName() {
return restName;
}
public void setRestName(String restName) {
this.restName = restName;
}
public String getRestPassword() {
return restPassword;
}
public void setRestPassword(String restPassword) {
this.restPassword = restPassword;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
}

View File

@@ -0,0 +1,41 @@
package com.seeyon.apps.esign.po;
public class SignField {
private String fileId;
private Integer signFieldType;
private NormalSignFieldConfig normalSignFieldConfig;
private RemarkSignFieldConfig remarkSignFieldConfig;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public Integer getSignFieldType() {
return signFieldType;
}
public void setSignFieldType(Integer signFieldType) {
this.signFieldType = signFieldType;
}
public NormalSignFieldConfig getNormalSignFieldConfig() {
return normalSignFieldConfig;
}
public void setNormalSignFieldConfig(NormalSignFieldConfig normalSignFieldConfig) {
this.normalSignFieldConfig = normalSignFieldConfig;
}
public RemarkSignFieldConfig getRemarkSignFieldConfig() {
return remarkSignFieldConfig;
}
public void setRemarkSignFieldConfig(RemarkSignFieldConfig remarkSignFieldConfig) {
this.remarkSignFieldConfig = remarkSignFieldConfig;
}
}

View File

@@ -0,0 +1,41 @@
package com.seeyon.apps.esign.po;
public class SignFieldPosition {
private String acrossPageMode;
private String positionPage;
private Float positionX;
private Float positionY;
public String getAcrossPageMode() {
return acrossPageMode;
}
public void setAcrossPageMode(String acrossPageMode) {
this.acrossPageMode = acrossPageMode;
}
public String getPositionPage() {
return positionPage;
}
public void setPositionPage(String positionPage) {
this.positionPage = positionPage;
}
public Float getPositionX() {
return positionX;
}
public void setPositionX(Float positionX) {
this.positionX = positionX;
}
public Float getPositionY() {
return positionY;
}
public void setPositionY(Float positionY) {
this.positionY = positionY;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.po;
public class SignFile {
private String fileName;
private String fileId;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
}

View File

@@ -0,0 +1,127 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import java.util.Map;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SignFlowConfig {
private String signFlowTitle;
private Long signFlowExpireTime;
private Boolean autoStart;
private Boolean autoFinish;
private Boolean identifyVerify;
private String notifyUrl;
private Map<String,Object> redirectConfig;
private Map<String,Object> signConfig;
private Map<String,Object> noticeConfig;
private Map<String,Object> authConfig;
private Map<String,Object> contractConfig;
private List<String> contractGroupIds;
private Boolean docsViewLimited;
public String getSignFlowTitle() {
return signFlowTitle;
}
public void setSignFlowTitle(String signFlowTitle) {
this.signFlowTitle = signFlowTitle;
}
public Long getSignFlowExpireTime() {
return signFlowExpireTime;
}
public void setSignFlowExpireTime(Long signFlowExpireTime) {
this.signFlowExpireTime = signFlowExpireTime;
}
public Boolean getAutoStart() {
return autoStart;
}
public void setAutoStart(Boolean autoStart) {
this.autoStart = autoStart;
}
public Boolean getAutoFinish() {
return autoFinish;
}
public void setAutoFinish(Boolean autoFinish) {
this.autoFinish = autoFinish;
}
public Boolean getIdentifyVerify() {
return identifyVerify;
}
public void setIdentifyVerify(Boolean identifyVerify) {
this.identifyVerify = identifyVerify;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public Map<String, Object> getRedirectConfig() {
return redirectConfig;
}
public void setRedirectConfig(Map<String, Object> redirectConfig) {
this.redirectConfig = redirectConfig;
}
public Map<String, Object> getSignConfig() {
return signConfig;
}
public void setSignConfig(Map<String, Object> signConfig) {
this.signConfig = signConfig;
}
public Map<String, Object> getNoticeConfig() {
return noticeConfig;
}
public void setNoticeConfig(Map<String, Object> noticeConfig) {
this.noticeConfig = noticeConfig;
}
public Map<String, Object> getAuthConfig() {
return authConfig;
}
public void setAuthConfig(Map<String, Object> authConfig) {
this.authConfig = authConfig;
}
public Map<String, Object> getContractConfig() {
return contractConfig;
}
public void setContractConfig(Map<String, Object> contractConfig) {
this.contractConfig = contractConfig;
}
public List<String> getContractGroupIds() {
return contractGroupIds;
}
public void setContractGroupIds(List<String> contractGroupIds) {
this.contractGroupIds = contractGroupIds;
}
public Boolean getDocsViewLimited() {
return docsViewLimited;
}
public void setDocsViewLimited(Boolean docsViewLimited) {
this.docsViewLimited = docsViewLimited;
}
}

View File

@@ -0,0 +1,37 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SignFlowInitiator {
private OrgInitiator orgInitiator;
private PsnInitiator psnInitiator;
private List<String> initialRemarks;
public PsnInitiator getPsnInitiator() {
return psnInitiator;
}
public void setPsnInitiator(PsnInitiator psnInitiator) {
this.psnInitiator = psnInitiator;
}
public List<String> getInitialRemarks() {
return initialRemarks;
}
public void setInitialRemarks(List<String> initialRemarks) {
this.initialRemarks = initialRemarks;
}
public OrgInitiator getOrgInitiator() {
return orgInitiator;
}
public void setOrgInitiator(OrgInitiator orgInitiator) {
this.orgInitiator = orgInitiator;
}
}

View File

@@ -0,0 +1,64 @@
package com.seeyon.apps.esign.po;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import java.util.Map;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Signer {
private int signerType;
private Map<String,Object> signConfig;
private Map<String,Object> noticeConfig;
private Map<String,Object> orgSignerInfo;
private Map<String,Object> psnSignerInfo;
private List<SignField> signFields;
public int getSignerType() {
return signerType;
}
public void setSignerType(int signerType) {
this.signerType = signerType;
}
public Map<String, Object> getNoticeConfig() {
return noticeConfig;
}
public void setNoticeConfig(Map<String, Object> noticeConfig) {
this.noticeConfig = noticeConfig;
}
public Map<String, Object> getOrgSignerInfo() {
return orgSignerInfo;
}
public void setOrgSignerInfo(Map<String, Object> orgSignerInfo) {
this.orgSignerInfo = orgSignerInfo;
}
public Map<String, Object> getPsnSignerInfo() {
return psnSignerInfo;
}
public void setPsnSignerInfo(Map<String, Object> psnSignerInfo) {
this.psnSignerInfo = psnSignerInfo;
}
public List<SignField> getSignFields() {
return signFields;
}
public void setSignFields(List<SignField> signFields) {
this.signFields = signFields;
}
public Map<String, Object> getSignConfig() {
return signConfig;
}
public void setSignConfig(Map<String, Object> signConfig) {
this.signConfig = signConfig;
}
}

View File

@@ -0,0 +1,31 @@
package com.seeyon.apps.esign.po;
public class TemplateComponent {
private String componentId;
private String componentKey;
private String componentValue;
public String getComponentId() {
return componentId;
}
public void setComponentId(String componentId) {
this.componentId = componentId;
}
public String getComponentKey() {
return componentKey;
}
public void setComponentKey(String componentKey) {
this.componentKey = componentKey;
}
public String getComponentValue() {
return componentValue;
}
public void setComponentValue(String componentValue) {
this.componentValue = componentValue;
}
}

View File

@@ -0,0 +1,22 @@
package com.seeyon.apps.esign.po;
public class TemplateInfo {
private String signTemplateName;
private String signTemplateId;
public String getSignTemplateName() {
return signTemplateName;
}
public void setSignTemplateName(String signTemplateName) {
this.signTemplateName = signTemplateName;
}
public String getSignTemplateId() {
return signTemplateId;
}
public void setSignTemplateId(String signTemplateId) {
this.signTemplateId = signTemplateId;
}
}

View File

@@ -0,0 +1,13 @@
package com.seeyon.apps.esign.po;
public class Transactor {
private String psnId;
public String getPsnId() {
return psnId;
}
public void setPsnId(String psnId) {
this.psnId = psnId;
}
}

View File

@@ -0,0 +1,25 @@
package com.seeyon.apps.esign.service;
import com.seeyon.apps.esign.core.SignApiClient;
import org.springframework.stereotype.Component;
@Component
public class EsignApiClient implements SignApiClient {
public static final String providerFlag ="ESIGN";
@Override
public String signByFile() {
return "";
}
@Override
public String signByTemplate() {
return "";
}
@Override
public String downloadContract() {
return "";
}
}

View File

@@ -0,0 +1,35 @@
package com.seeyon.apps.esign.service;
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.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.utils.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class EsignAuthService {
@Autowired
private EsignConfigProvider configProvider;
public void personAuth(Map<String,Object> authParams) throws Exception {
EsignApiHeader esignApiHeader = EsignApiHeader.build();
String jsonBody = JsonUtils.toJSONString(authParams);
esignApiHeader.appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID))
.httpMethod("POST")
.heads("")
.pathAndParameters(EsignApiUrl.PERSON_AUTH_URL)
.contentMD5(jsonBody)
.signature(configProvider.getBizConfigByKey(EsignConfigConstants.APP_SECRET));
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.PERSON_AUTH_URL;
String respStr = HttpClient.httpPostRaw(url, jsonBody, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
}
}

View File

@@ -0,0 +1,57 @@
package com.seeyon.apps.esign.service;
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.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.utils.HttpClient;
import com.seeyon.apps.esign.utils.JsonCleaner;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class EsignByTemplateService {
@Autowired
private EsignConfigProvider configProvider;
@Autowired
private TokenCacheManager tokenCacheManager;
private static final Log log = LogFactory.getLog(EsignByTemplateService.class);
public void signByTemplate(Map<String,Object> params) {
}
public void startSignFlow(String flowId) throws Exception {
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SIGN_START_URL;
url.replace("{signFlowId}", flowId);
String respStr = HttpClient.httpPostRaw(url, "", null, null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
if (esignBaseResp.getCode() != 0) {
throw new Exception("签署发起失败");
}
}
public String createBySignTemplate(Map<String,Object> params) throws Exception {
EsignApiHeader esignApiHeader = EsignApiHeader.build();
String jsonBody = JsonCleaner.removeEmptyObjects(JsonUtils.toJSONString(params));
esignApiHeader.token(tokenCacheManager.getToken()).appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SIGN_BY_FILE_URL;
log.info("合同发起入参: " + jsonBody);
String respStr = HttpClient.httpPostRaw(url, jsonBody, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
if(!"0".equals(esignBaseResp.getCode() + "")) {
throw new RuntimeException("签署发起失败," + esignBaseResp.getMessage());
}
String flowId = (String) dataMap.get("signFlowId");
return flowId;
}
}

View File

@@ -0,0 +1,190 @@
package com.seeyon.apps.esign.service;
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.ContractFile;
import com.seeyon.apps.esign.po.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.po.EsignFileUploadParams;
import com.seeyon.apps.esign.po.EsignHttpResponse;
import com.seeyon.apps.esign.po.GetUploadUrlResp;
import com.seeyon.apps.esign.po.SignFlowConfig;
import com.seeyon.apps.esign.po.Signer;
import com.seeyon.apps.esign.utils.EsignHttpHelper;
import com.seeyon.apps.esign.utils.EsignRequestType;
import com.seeyon.apps.esign.utils.FileUtil;
import com.seeyon.apps.esign.utils.HttpClient;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class EsignByUploadFileService {
@Autowired
private EsignConfigProvider configProvider;
@Autowired
protected TokenCacheManager tokenCacheManager;
public Map<String,Object> getDownloadFileInfo(String flowId) throws Exception {
String reqPath = EsignApiUrl.CONTRACT_DOWNLOAD_URL.replace("{signFlowId}", flowId);
String getDownloadUrl = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + reqPath;
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID)).token(tokenCacheManager.getToken());
String respStr = HttpClient.httpGet(getDownloadUrl, esignApiHeader.convert2Headers(), null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
if(esignBaseResp.getCode() != 0 || esignBaseResp.getData() == null){
throw new RuntimeException("下载合同文件失败");
}
Map<String,Object> data = (Map<String, Object>) esignBaseResp.getData();
Object[] files = (Object[]) data.get("files");
if(files.length <= 0) {
throw new RuntimeException("下载合同文件失败");
}
Map<String,Object> fileInfo = (Map<String, Object>) files[0];
return fileInfo;
}
public GetUploadUrlResp getUploadFileUrl(String fileName,String fileMd5,Long fileSize,boolean convert2Pdf) throws Exception {
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.GET_UPLOAD_FILE_URL;
GetUploadUrlResp resp = new GetUploadUrlResp();
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
esignApiHeader.token(tokenCacheManager.getToken());
EsignFileUploadParams params = new EsignFileUploadParams();
params.setFileName(fileName);
params.setContentMd5(fileMd5);
params.setFileSize(fileSize);
params.setConvertToPDF(convert2Pdf);
params.setContentType("application/octet-stream");
String respStr = HttpClient.httpPostRaw(url, JsonUtils.toJSONString(params),esignApiHeader.convert2Headers(), null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
Object data = esignBaseResp.getData();
if (data != null) {
Map<String,Object> map = (Map<String, Object>) data;
resp.setFileUploadUrl((String) map.get("fileUploadUrl"));
resp.setFileId((String) map.get("fileId"));
}
return resp;
}
public List<Object> getSignPosition(String fileId) throws Exception {
String reqPath = EsignApiUrl.SIGN_POSITION_URL.replace("{fileId}", fileId);
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + reqPath;
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
List<String> keywords = new ArrayList<>();
keywords.add("甲方盖章/签字");
keywords.add("乙方盖章/签字");
Map<String,Object> params = new HashMap<>();
params.put("keywords",keywords);
esignApiHeader.token(tokenCacheManager.getToken());
String respStr = HttpClient.httpPostRaw(url,JsonUtils.toJSONString(params),esignApiHeader.convert2Headers(),null);
Map map = JsonUtils.parseObject(respStr, Map.class);
Map<String,Object> data = (Map<String,Object>) map.get("data");
Object[] keywordPositions = (Object[]) data.get("keywordPositions");
List<Object> resList = new ArrayList<>();
for (Object position : keywordPositions) {
resList.add(position);
}
return resList;
}
public String uploadFileToEsign(String refId) throws Exception {
String tempDir = System.getProperty("java.io.tmpdir");
File file = null;
FileUtil fileUtil = new FileUtil();
try {
List<String> paths = fileUtil.fieldFileDownload(Long.parseLong(refId), tempDir + File.separator + "oafile" + File.separator);
file = new File(paths.get(0));
String contentMD5 = EsignByUploadFileService.getFileContentMD5(paths.get(0));
GetUploadUrlResp uploadResp = getUploadFileUrl(file.getName(), contentMD5, file.length(),true);
uploadFile(uploadResp.getFileUploadUrl(), contentMD5, file.getName(), paths.get(0));
return uploadResp.getFileId();
}finally {
if(file != null) {
file.delete();
}
}
}
public static String getFileContentMD5(String filePath) throws Exception {
// 获取文件MD5的二进制数组128位
byte[] bytes = getFileMD5Bytes128(filePath);
// 对文件MD5的二进制数组进行base64编码
return new String(Base64.encodeBase64String(bytes));
}
/***
* 获取文件MD5-二进制数组128位
*
* @return
* @throws IOException
*/
public static byte[] getFileMD5Bytes128(String filePath) throws Exception {
byte[] md5Bytes = null;
File file = new File(filePath);
try (FileInputStream fis = new FileInputStream(file)) {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[1024];
int length = -1;
while ((length = fis.read(buffer, 0, 1024)) != -1) {
md5.update(buffer, 0, length);
}
md5Bytes = md5.digest();
}
return md5Bytes;
}
public String uploadFile(String uploadUrl,String contentMD5,String fileName,String filePath) throws Exception {
// EsignApiHeader esignApiHeader = EsignApiHeader.build();
// esignApiHeader.setContentType("application/octet-stream");
// esignApiHeader.setContentMd5(contentMD5);
EsignHttpResponse esignHttpResponse = EsignHttpHelper.doUploadHttp(uploadUrl, EsignRequestType.PUT, getBytes(filePath), contentMD5, "application/octet-stream", false);
// return HttpClient.uploadBinaryFile(uploadUrl,esignApiHeader.convert2Headers(),new FileInputStream(file),fileName);
return esignHttpResponse.getBody();
}
public static byte[] getBytes(String filePath) throws Exception {
File file = new File(filePath);
FileInputStream fis = null;
byte[] buffer = null;
try {
fis = new FileInputStream(file);
buffer = new byte[(int) file.length()];
fis.read(buffer);
} catch (Exception e) {
Exception ex = new Exception("获取文件字节流失败", e);
ex.initCause(e);
throw ex;
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
Exception ex = new Exception("关闭文件字节流失败", e);
ex.initCause(e);
throw ex;
}
}
}
return buffer;
}
}

View File

@@ -0,0 +1,96 @@
package com.seeyon.apps.esign.service;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.esign.config.EsignConfigProvider;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.form.EnumMapUtils;
import com.seeyon.apps.esign.form.FormDataOperator;
import com.seeyon.apps.esign.form.FormUpdateField;
import com.seeyon.apps.esign.form.FormWhereCondition;
import com.seeyon.apps.esign.utils.FileUtil;
import com.seeyon.apps.esign.utils.ProtUtil;
import com.seeyon.ctp.util.JDBCAgent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class EsignCallbackBizService {
private static final Log log = LogFactory.getLog(EsignCallbackBizService.class);
@Autowired
private ProtUtil protUtil;
@Autowired
private EsignConfigProvider configProvider;
public void handleSuccessSignCallbackBiz(String tablename,String updatefield,String statusField,String formId,String fileUrl,String fileName) throws Exception {
String[] strings = formId.split("_");
String oaFlowId = strings[0];
String tempFormId = strings[1];
String[] statusParams = statusField.split("_");
String status = statusParams[0];
String enumId = statusParams[1];
String enumItemId = EnumMapUtils.getEnumItemValueByEnumId("已签署",Long.parseLong(enumId));
//下载文件到本地
FormDataOperator formDataOperator = new FormDataOperator();
List<FormWhereCondition> conditions = new ArrayList<>();
String refId = FileUtil.uploadContractToOA(fileUrl,
fileName, getModuleId(tempFormId),
configProvider.getBizConfigByKey(EsignConfigConstants.FORMEDITLOGINNAME),
configProvider.getBizConfigByKey(EsignConfigConstants.updateAccountName));
List<FormUpdateField> updateFields = new ArrayList<>();
updateFields.add(FormUpdateField.build().fieldName(updatefield).value(refId));
updateFields.add(FormUpdateField.build().fieldName(status).value(enumItemId));
conditions.add(FormWhereCondition.build().value(tempFormId).fieldName("ID"));
formDataOperator.updateMasterForm(updateFields,tablename,conditions);
JSONObject params = new JSONObject();
params.put("message", "签署完成!!!");
params.put("returnCode", 1);
protUtil.sendPostNotification(params.toString(), configProvider.getBizConfigByKey(EsignConfigConstants.nodeTokenUrl), oaFlowId);
}
public void handleFailSignCallbackBiz(String tableName,String statusField,String formId,String failMsg) throws Exception {
String[] strings = formId.split("_");
String oaFlowId = strings[0];
String tempFormId = strings[1];
String[] statusParams = statusField.split("_");
String status = statusParams[0];
String enumId = statusParams[1];
String enumItemId = EnumMapUtils.getEnumItemValueByEnumId("签署失败",Long.parseLong(enumId));
FormDataOperator formDataOperator = new FormDataOperator();
List<FormWhereCondition> conditions = new ArrayList<>();
List<FormUpdateField> updateFields = new ArrayList<>();
updateFields.add(FormUpdateField.build().fieldName(status).value(enumItemId));
conditions.add(FormWhereCondition.build().value(tempFormId).fieldName("ID"));
formDataOperator.updateMasterForm(updateFields,tableName,conditions);
JSONObject params = new JSONObject();
params.put("message", "签署失败: " + failMsg);
params.put("returnCode", 2);
protUtil.sendPostNotification(params.toString(), configProvider.getBizConfigByKey(EsignConfigConstants.nodeTokenUrl), oaFlowId);
}
private String getModuleId(String formId) {
JDBCAgent jdbcAgent = new JDBCAgent();
try {
String sql = "SELECT MODULE_ID FROM ctp_content_all where CONTENT_DATA_ID = ?";
List<Object> params = new ArrayList<>();
params.add(formId);
jdbcAgent.execute(sql,params);
List list = jdbcAgent.resultSetToList();
if(list == null || !(list.size() > 0)) {
throw new RuntimeException("MODULE_ID获取失败");
}
Map<String,Object> map = (Map<String, Object>) list.get(0);
return map.get("module_id") +"";
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,144 @@
package com.seeyon.apps.esign.service;
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.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.po.GetUploadUrlResp;
import com.seeyon.apps.esign.po.SignFile;
import com.seeyon.apps.esign.po.TemplateComponent;
import com.seeyon.apps.esign.po.TemplateInfo;
import com.seeyon.apps.esign.utils.FileUtil;
import com.seeyon.apps.esign.utils.HttpClient;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.ctp.common.exceptions.BusinessException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
public class EsignFileTemplateService {
private static final String ORI_TEMPLATE = "原始合同模板文件";
private static final Log log = LogFactory.getLog(EsignFileTemplateService.class);
@Autowired
private EsignConfigProvider configProvider;
@Autowired
private TokenCacheManager tokenCacheManager;
@Autowired
private EsignByUploadFileService uploadFileService;
private String orgId;
private void fillOrgId() {
EsignApiHeader esignApiHeader = EsignApiHeader.build();
try {
esignApiHeader.token(tokenCacheManager.getToken()).appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
} catch (Exception e) {
e.printStackTrace();
}
//获取orgId
String queryStr = EsignApiUrl.QUERY_ORGINFO + "?orgName=" + configProvider.getBizConfigByKey(EsignConfigConstants.UNITNAME);
String reqUrl = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + queryStr;
String orgInfoRespStr = HttpClient.httpGet(reqUrl, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp orgInfoResp = JsonUtils.parseObject(orgInfoRespStr, EsignBaseResp.class);
Map<String, Object> orgData = (Map<String, Object>) orgInfoResp.getData();
orgId = (String) orgData.get("orgId");
}
//填充模板
public SignFile fillTemplate(String templateId, String fileName, Map<String,Object> params) {
//请求示例
Map<String,Object> reqParams = new HashMap<>();
reqParams.put("docTemplateId",templateId);
reqParams.put("fileName",fileName);
List<TemplateComponent> components = new ArrayList<>();
Set<String> keySets = params.keySet();
for (String key : keySets) {
TemplateComponent component = new TemplateComponent();
component.setComponentKey(key);
component.setComponentValue((String) params.get(key));
components.add(component);
}
reqParams.put("components",components);
String url = "";
String resp = HttpClient.httpPostRaw(url, JsonUtils.toJSONString(reqParams), null, null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(resp, EsignBaseResp.class);
if(esignBaseResp.getCode() != 0) {}
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
SignFile signFile = new SignFile();
signFile.setFileId((String) dataMap.get("fileId"));
signFile.setFileName(fileName);
return signFile;
}
//获取模板详细信息
public Map<String,Object> getTemplateDetail(String signTemplateId,String orgId,Boolean queryComponents) {
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + "?" + "signTemplateId=" + signTemplateId + "&orgId=" + orgId + (queryComponents != null ? "&queryComponents=" + queryComponents : "");
String resp = HttpClient.httpGet(url, null, "UTF-8");
EsignBaseResp esignBaseResp = JsonUtils.parseObject(resp, EsignBaseResp.class);
Map<String,Object> data = (Map<String, Object>) esignBaseResp.getData();
return data;
}
//获取模板详细信息
public Map<String,Object> getTemplateDetail(String signTemplateId,String orgId) {
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.QUERY_TEMPLATE_DETAIL_URL + "?" +"orgId=" + orgId + "&signTemplateId=" + signTemplateId;
EsignApiHeader apiHeader = EsignApiHeader.build().token(tokenCacheManager.getToken()).appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
String resp = HttpClient.httpGet(url, apiHeader.convert2Headers(), "UTF-8");
EsignBaseResp esignBaseResp = JsonUtils.parseObject(resp, EsignBaseResp.class);
Map<String,Object> data = (Map<String, Object>) esignBaseResp.getData();
return data;
}
public Map<String,Object> queryTemplates(Integer pageNo) throws Exception {
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
String queryStr = EsignApiUrl.QUERY_TEMPLATES_URL + "?" + "orgId=" + obtainOrgId() + "&pageNum=" + pageNo + "&pageSize=" + 20 + "&status=" + 1;
esignApiHeader.token(tokenCacheManager.getToken());
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + queryStr;
String templateListRespStr = HttpClient.httpGet(url, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp templateListResp = JsonUtils.parseObject(templateListRespStr, EsignBaseResp.class);
Map<String,Object> listData = (Map<String,Object>)templateListResp.getData();
Integer total = (Integer) listData.get("total");
Object[] templateArray = (Object[]) listData.get("signTemplates");
Map<String,Object> pageMap = new HashMap<>();
pageMap.put("total",total);
pageMap.put("templateList",templateArray);
return pageMap;
}
public String getCompareDetailUrl(String templateRefId,String contractRefId) throws Exception {
String templateFileId = uploadFileService.uploadFileToEsign(templateRefId);
String contractFileId = uploadFileService.uploadFileToEsign(contractRefId);
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.CONTRACT_COMPARE_GETURL;
Map<String,String> params = new HashMap<>();
params.put("standardFileId",templateFileId);
params.put("comparativeFileId",contractFileId);
String jsonString = JsonUtils.toJSONString(params);
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
esignApiHeader.token(tokenCacheManager.getToken());
String respStr = HttpClient.httpPostRaw(url, jsonString, esignApiHeader.convert2Headers(), null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
log.info("调用获取合同比对链接接口返回值: " + JsonUtils.toJSONString(esignBaseResp));
Map<String,String> data = (Map<String, String>) esignBaseResp.getData();
String contractCompareUrl = data.get("contractCompareUrl");
return contractCompareUrl;
}
private String obtainOrgId() {
if(orgId == null) {
fillOrgId();
}
return orgId;
}
}

View File

@@ -0,0 +1,75 @@
package com.seeyon.apps.esign.service;
import cn.hutool.json.JSONObject;
import com.cedarsoftware.util.io.JsonObject;
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.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.utils.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Component
public class SealService {
@Autowired
private EsignConfigProvider configProvider;
public void grantSeal(Map<String,Object> params) throws Exception {
JsonObject reqParams = new JsonObject();
String sealId = getSealId((String) params.get("orgId"), (String) params.get("sealName"));
reqParams.put("sealId",sealId);
List<String> authorizedPsnIds = new ArrayList<>();
authorizedPsnIds.add((String) params.get("accountId"));
reqParams.put("authorizedPsnIds",authorizedPsnIds);
reqParams.put("sealRole","SEAL_USER");
reqParams.put("transactorPsnId",params.get("managerId"));
JSONObject sealAuthScope = new JSONObject();
List<String> templateIds = new ArrayList<>();
templateIds.add("ALL");
sealAuthScope.put("templateIds",templateIds);
reqParams.put("sealAuthScope",sealAuthScope);
EsignApiHeader esignApiHeader = EsignApiHeader.build();
esignApiHeader.appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID))
.httpMethod("POST")
.heads("")
.pathAndParameters(EsignApiUrl.SEAL_GRANT_URL)
.contentMD5(reqParams.toString())
.signature(configProvider.getBizConfigByKey(EsignConfigConstants.APP_SECRET));
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SEAL_GRANT_URL;
HttpClient.httpPostRaw(url,reqParams.toString(),esignApiHeader.convert2Headers(),null);
}
private String getSealId(String orgId, String sealName) throws Exception {
String host = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST);
int pageNo = 1;
int pageSize = 20;
EsignApiHeader esignApiHeader = EsignApiHeader.build();
esignApiHeader.appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID))
.httpMethod("GET")
.heads("")
.pathAndParameters(EsignApiUrl.QUERY_SEAL_URL + "?" + HttpClient.sortQueryString("orgId=" + orgId + "&pageNo=" + pageNo + "&pageSize=" + pageSize))
.contentMD5("")
.signature(configProvider.getBizConfigByKey(EsignConfigConstants.APP_SECRET));
String url = host + EsignApiUrl.QUERY_SEAL_URL + "?orgId=" + orgId + "&pageNo=" + pageNo + "&pageSize=" + pageSize;
String respStr = HttpClient.httpGet(url, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
Map<String,Object> data = (Map<String, Object>) esignBaseResp.getData();
LinkedList<Object> seals = (LinkedList<Object>) data.get("seals");
for (Object seal : seals) {
Map<String,Object> sealMap = (Map<String, Object>) seal;
if(sealMap.get("sealName").equals(sealName)){
return (String) sealMap.get("sealId");
}
}
return null;
}
}

View File

@@ -0,0 +1,101 @@
package com.seeyon.apps.esign.service;
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.EsignApiHeader;
import com.seeyon.apps.esign.po.EsignBaseResp;
import com.seeyon.apps.esign.po.EsignToken;
import com.seeyon.apps.esign.utils.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@Component
public class TokenCacheManager {
@Autowired
private EsignConfigProvider configProvider;
private final AtomicReference<EsignToken> tokenRef = new AtomicReference<>();
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private static final long CHECK_INTERVAL = 2 * 60 * 60 * 1000; // 120分钟检查一次
public TokenCacheManager() {
// 启动定期检查任务
scheduler.scheduleAtFixedRate(this::checkTokenExpiry,
CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.MILLISECONDS);
}
private boolean checkExpired(String token) {
EsignApiHeader esignApiHeader = EsignApiHeader.build();
try {
esignApiHeader.token(token).appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
} catch (Exception e) {
e.printStackTrace();
}
//获取orgId
String queryStr = EsignApiUrl.QUERY_ORGINFO + "?orgName=" + configProvider.getBizConfigByKey(EsignConfigConstants.UNITNAME);
String reqUrl = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + queryStr;
String orgInfoRespStr = HttpClient.httpGet(reqUrl, esignApiHeader.convert2Headers(), "UTF-8");
EsignBaseResp orgInfoResp = JsonUtils.parseObject(orgInfoRespStr, EsignBaseResp.class);
if(orgInfoResp.getCode() == 401) {
return true;
}
return false;
}
public String getToken() {
EsignToken current = tokenRef.get();
if (current != null && !checkExpired(current.getTokenStr())) {
return current.getTokenStr();
}
return refreshToken();
}
private String refreshToken() {
EsignToken newToken = fetchNewToken();
tokenRef.set(newToken);
return newToken.getTokenStr();
}
private void checkTokenExpiry() {
EsignToken current = tokenRef.get();
if (current != null && isTokenExpired(current)) {
refreshToken();
}
}
private boolean isTokenExpired(EsignToken token) {
return System.currentTimeMillis() >= token.getTtl();
}
private EsignToken fetchNewToken() {
// 实际获取token的逻辑
String queryStr = "?appId=" + configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID) + "&secret=" + configProvider.getBizConfigByKey(EsignConfigConstants.APP_SECRET) + "&grantType=client_credentials";
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.TOKEN_GET_URL + queryStr;
String respStr = HttpClient.httpGet(url, null, null);
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
if(esignBaseResp.getCode() != 0) {
throw new RuntimeException("获取e签宝token失败");
}
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
String token = (String) dataMap.get("token");
Long ttl = Long.parseLong((String) dataMap.get("expiresIn")) ;
String refreshToken = (String) dataMap.get("refreshToken");
EsignToken esignToken = new EsignToken();
esignToken.setTokenStr(token);
esignToken.setTtl(ttl);
esignToken.setRefreshToken(refreshToken);
return esignToken;
}
public void shutdown() {
scheduler.shutdown();
}
}

View File

@@ -0,0 +1,26 @@
package com.seeyon.apps.esign.utils;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.form.FormDataOperator;
import com.seeyon.apps.esign.form.FormUpdateField;
import com.seeyon.apps.esign.form.FormWhereCondition;
import java.util.ArrayList;
import java.util.List;
public class AttachmentUtils {
public void fileFillBack(String url,String fileName,String loginName,String unitName,String tableName,String updateField,String formId,String formNo) throws Exception {
String refId = FileUtil.uploadContractToOA(url, fileName, formId, loginName, unitName);
if(formNo != null) {
}else {
FormDataOperator formDataOperator = new FormDataOperator();
List<FormUpdateField> updateFields = new ArrayList<>();
List<FormWhereCondition> conditions = new ArrayList<>();
updateFields.add(FormUpdateField.build().fieldName(updateField).value(refId));
conditions.add(FormWhereCondition.build().value(formId).fieldName("ID"));
formDataOperator.updateMasterForm(updateFields,tableName,conditions);
}
}
}

View File

@@ -0,0 +1,17 @@
package com.seeyon.apps.esign.utils;
import java.util.Map;
public class EnHancedMap {
private Map<String,Object> map;
public EnHancedMap of(String key, Object value) {
map.put(key, value);
return this;
}
public Map<String,Object> getMap() {
return map;
}
}

View File

@@ -0,0 +1,471 @@
package com.seeyon.apps.esign.utils;
import com.seeyon.apps.esign.po.EsignException;
import com.seeyon.apps.esign.po.EsignHttpResponse;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @description Http请求 辅助类
* @author 澄泓
* @since JDK1.7
*/
public class EsignHttpCfgHelper {
private static Logger LOGGER = LoggerFactory.getLogger(EsignHttpCfgHelper.class);
/**
* 超时时间,默认15000毫秒
*/
private static int MAX_TIMEOUT = 15000;
/**
* 请求池最大连接数,默认100个
*/
private static int MAX_TOTAL=100;
/**
* 单域名最大的连接数,默认50个
*/
private static int ROUTE_MAX_TOTAL=50;
/**
* 请求失败重试次数,默认3次
*/
private static int MAX_RETRY = 3;
/**
* 是否需要域名校验,默认不需要校验
*/
private static boolean SSL_VERIFY=false;
/**
* 正向代理IP
*/
private static String PROXY_IP;
/**
* 正向代理端口,默认8888
*/
private static int PROXY_PORT=8888;
/**
* 代理协议,默认http
*/
private static String PROXY_AGREEMENT="http";
/**
* 是否开启代理默认false
*/
private static boolean OPEN_PROXY=false;
/**
* 代理服务器用户名
*/
private static String PROXY_USERNAME="";
/**
* 代理服务器密码
*/
private static String PROXY_PASSWORD="";
private static PoolingHttpClientConnectionManager connMgr; //连接池
private static HttpRequestRetryHandler retryHandler; //重试机制
private static CloseableHttpClient httpClient=null;
public static int getMaxTimeout() {
return MAX_TIMEOUT;
}
public static void setMaxTimeout(int maxTimeout) {
MAX_TIMEOUT = maxTimeout;
}
public static int getMaxTotal() {
return MAX_TOTAL;
}
public static void setMaxTotal(int maxTotal) {
MAX_TOTAL = maxTotal;
}
public static int getRouteMaxTotal() {
return ROUTE_MAX_TOTAL;
}
public static void setRouteMaxTotal(int routeMaxTotal) {
ROUTE_MAX_TOTAL = routeMaxTotal;
}
public static int getMaxRetry() {
return MAX_RETRY;
}
public static void setMaxRetry(int maxRetry) {
MAX_RETRY = maxRetry;
}
public static boolean isSslVerify() {
return SSL_VERIFY;
}
public static void setSslVerify(boolean sslVerify) {
SSL_VERIFY = sslVerify;
}
public static String getProxyIp() {
return PROXY_IP;
}
public static void setProxyIp(String proxyIp) {
PROXY_IP = proxyIp;
}
public static int getProxyPort() {
return PROXY_PORT;
}
public static void setProxyPort(int proxyPort) {
PROXY_PORT = proxyPort;
}
public static String getProxyAgreement() {
return PROXY_AGREEMENT;
}
public static void setProxyAgreement(String proxyAgreement) {
PROXY_AGREEMENT = proxyAgreement;
}
public static boolean getOpenProxy() {
return OPEN_PROXY;
}
public static void setOpenProxy(boolean openProxy) {
OPEN_PROXY = openProxy;
}
public static String getProxyUsername() {
return PROXY_USERNAME;
}
public static void setProxyUserame(String proxyUsername) {
PROXY_USERNAME = proxyUsername;
}
public static String getProxyPassword() {
return PROXY_PASSWORD;
}
public static void setProxyPassword(String proxyPassword) {
PROXY_PASSWORD = proxyPassword;
}
/**
* 不允许外部创建实例
*/
private EsignHttpCfgHelper() {
}
//------------------------------公有方法start--------------------------------------------
/**
* @description 发起HTTP / HTTPS 请求
*
* @param reqType
* {@link EsignRequestType} 请求类型 GET、 POST 、 DELETE 、 PUT
* @param httpUrl
* {@link String} 请求目标地址
* @param headers
* {@link Map} 请求头
* @param param
* {@link Object} 参数
* @return
* @throws EsignException
* @author 澄泓
*/
public static EsignHttpResponse sendHttp(EsignRequestType reqType, String httpUrl, Map<String, String> headers, Object param, boolean debug)
throws EsignException {
HttpRequestBase reqBase=null;
if(httpUrl.startsWith("http")){
reqBase=reqType.getHttpType(httpUrl);
}else{
throw new EsignException("请求url地址格式错误");
}
if(debug){
LOGGER.info("请求头:{}",headers+"\n");
LOGGER.info("请求参数\n{}", param+"\n");
LOGGER.info("请求地址\n:{}\n请求方式\n:{}",reqBase.getURI(),reqType+"\n");
}
//请求方法不是GET或者DELETE时传入body体否则不传入。
String[] methods = {"DELETE", "GET"};
if(param instanceof String&&Arrays.binarySearch(methods, reqType.name())<0){//POST或者PUT请求
((HttpEntityEnclosingRequest) reqBase).setEntity(
new StringEntity(String.valueOf(param), ContentType.create("application/json", "UTF-8")));
}
//参数时字节流数组
else if(param instanceof byte[]) {
reqBase=reqType.getHttpType(httpUrl);
byte[] paramBytes = (byte[])param;
((HttpEntityEnclosingRequest) reqBase).setEntity(new ByteArrayEntity(paramBytes));
}
//参数是form表单时
else if(param instanceof List){
((HttpEntityEnclosingRequest) reqBase).setEntity(new UrlEncodedFormEntity((Iterable<? extends NameValuePair>) param));
}
httpClient = getHttpClient();
config(reqBase);
//设置请求头
if(headers != null &&headers.size()>0) {
for(Map.Entry<String, String> entry :headers.entrySet()) {
reqBase.setHeader(entry.getKey(), entry.getValue());
}
}
//响应对象
CloseableHttpResponse res = null;
//响应内容
String resCtx = null;
int status;
EsignHttpResponse esignHttpResponse = new EsignHttpResponse();
try {
//执行请求
res = httpClient.execute(reqBase);
status=res.getStatusLine().getStatusCode();
//获取请求响应对象和响应entity
HttpEntity httpEntity = res.getEntity();
if(httpEntity != null) {
resCtx = EntityUtils.toString(httpEntity,"utf-8");
}
if(debug) {
LOGGER.info("响应\n{}", resCtx + "\n");
LOGGER.info("----------------------------end------------------------");
}
} catch (NoHttpResponseException e) {
throw new EsignException("服务器丢失了",e);
} catch (SSLHandshakeException e){
String msg = MessageFormat.format("SSL握手异常", e);
EsignException ex = new EsignException(msg, e);
throw ex;
} catch (UnknownHostException e){
EsignException ex = new EsignException("服务器找不到", e);
ex.initCause(e);
throw ex;
} catch(ConnectTimeoutException e){
EsignException ex = new EsignException("连接超时", e);
ex.initCause(e);
throw ex;
} catch(SSLException e){
EsignException ex = new EsignException("SSL异常",e);
ex.initCause(e);
throw ex;
} catch (ClientProtocolException e) {
EsignException ex = new EsignException("请求头异常",e);
ex.initCause(e);
throw ex;
} catch (IOException e) {
EsignException ex = new EsignException("网络请求失败",e);
ex.initCause(e);
throw ex;
} finally {
if(res != null) {
try {
res.close();
} catch (IOException e) {
EsignException ex = new EsignException("--->>关闭请求响应失败",e);
ex.initCause(e);
throw ex;
}
}
}
esignHttpResponse.setStatus(status);
esignHttpResponse.setBody(resCtx);
return esignHttpResponse;
}
//------------------------------公有方法end----------------------------------------------
//------------------------------私有方法start--------------------------------------------
/**
* @description 请求头和超时时间配置
*
* @param httpReqBase
* @author 澄泓
*/
private static void config(HttpRequestBase httpReqBase) {
// 配置请求的超时设置
RequestConfig.Builder builder = RequestConfig.custom()
.setConnectionRequestTimeout(MAX_TIMEOUT)
.setConnectTimeout(MAX_TIMEOUT)
.setSocketTimeout(MAX_TIMEOUT);
if(OPEN_PROXY){
HttpHost proxy=new HttpHost(PROXY_IP,PROXY_PORT,PROXY_AGREEMENT);
builder.setProxy(proxy);
}
RequestConfig requestConfig = builder.build();
httpReqBase.setConfig(requestConfig);
}
/**
* @description 连接池配置
*
* @return
* @author 澄泓
*/
private static void cfgPoolMgr() throws EsignException {
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
if(!SSL_VERIFY){
sslsf=sslConnectionSocketFactory();
}
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainsf)
.register("https", sslsf)
.build();
//连接池管理器
connMgr = new PoolingHttpClientConnectionManager(registry);
//请求池最大连接数
connMgr.setMaxTotal(MAX_TOTAL);
//但域名最大的连接数
connMgr.setDefaultMaxPerRoute(ROUTE_MAX_TOTAL);
}
/**
* @description 设置重试机制
*
* @author 澄泓
*/
private static void cfgRetryHandler() {
retryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int excCount, HttpContext ctx) {
//超过最大重试次数,就放弃
if(excCount > MAX_RETRY) {
return false;
}
//服务器丢掉了链接,就重试
if(e instanceof NoHttpResponseException) {
return true;
}
//不重试SSL握手异常
if(e instanceof SSLHandshakeException) {
return false;
}
//中断
if(e instanceof InterruptedIOException) {
return false;
}
//目标服务器不可达
if(e instanceof UnknownHostException) {
return false;
}
//连接超时
//SSL异常
if(e instanceof SSLException) {
return false;
}
HttpClientContext clientCtx = HttpClientContext.adapt(ctx);
HttpRequest req = clientCtx.getRequest();
//如果是幂等请求,就再次尝试
if(!(req instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
};
}
/**
* 忽略域名校验
*/
private static SSLConnectionSocketFactory sslConnectionSocketFactory() throws EsignException {
try {
SSLContext ctx = SSLContext.getInstance("TLS"); // 创建一个上下文(此处指定的协议类型似乎不是重点)
X509TrustManager tm = new X509TrustManager() { // 创建一个跳过SSL证书的策略
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
};
ctx.init(null, new TrustManager[] { tm }, null); // 使用上面的策略初始化上下文
return new SSLConnectionSocketFactory(ctx, new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
}catch (Exception e){
EsignException ex = new EsignException("忽略域名校验失败",e);
ex.initCause(e);
throw ex;
}
}
/**
* @description 获取单例HttpClient
*
* @return
* @author 澄泓
*/
private static synchronized CloseableHttpClient getHttpClient() throws EsignException {
if(httpClient==null) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(PROXY_IP,PROXY_PORT),new UsernamePasswordCredentials(PROXY_USERNAME, PROXY_PASSWORD));
cfgPoolMgr();
cfgRetryHandler();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClient = httpClientBuilder.setDefaultCredentialsProvider(credsProvider).setConnectionManager(connMgr).setRetryHandler(retryHandler).build();
}
return httpClient;
}
//------------------------------私有方法end----------------------------------------------
}

View File

@@ -0,0 +1,83 @@
package com.seeyon.apps.esign.utils;
import com.seeyon.apps.esign.po.EsignException;
import com.seeyon.apps.esign.po.EsignHttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* @description Http 请求 辅助类
* @author 澄泓
* @since JDK1.7
*/
public class EsignHttpHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(EsignHttpHelper.class);
/**
* 不允许外部创建实例
*/
private EsignHttpHelper() {
}
/**
* @description 发送常规HTTP 请求
*
* @param reqType 请求方式
* @param url 请求路径
* @param paramStr 请求参数
* @return
* @throws EsignException
* @author 澄泓
*/
public static EsignHttpResponse doCommHttp(String host, String url, EsignRequestType reqType, Object paramStr , Map<String,String> httpHeader, boolean debug) throws EsignException {
return EsignHttpCfgHelper.sendHttp(reqType, host+url,httpHeader, paramStr, debug);
}
/**
* @description 发送文件流上传 HTTP 请求
*
* @param reqType 请求方式
* @param uploadUrl 请求路径
* @param param 请求参数
* @param fileContentMd5 文件fileContentMd5
* @param contentType 文件MIME类型
* @return
* @author 澄泓
*/
public static EsignHttpResponse doUploadHttp( String uploadUrl,EsignRequestType reqType,byte[] param, String fileContentMd5,
String contentType, boolean debug) throws EsignException {
Map<String, String> uploadHeader = buildUploadHeader(fileContentMd5, contentType);
if(debug){
LOGGER.info("----------------------------start------------------------");
LOGGER.info("fileContentMd5:{}",fileContentMd5);
LOGGER.info("contentType:{}",contentType);
}
return EsignHttpCfgHelper.sendHttp(reqType,uploadUrl, uploadHeader, param,debug);
}
/**
* @description 创建文件流上传 请求头
*
* @param fileContentMd5
* @param contentType
* @return
* @author 澄泓
*/
public static Map<String, String> buildUploadHeader(String fileContentMd5, String contentType) {
Map<String, String> header = new HashMap<>();
header.put("Content-MD5", fileContentMd5);
header.put("Content-Type", contentType);
return header;
}
// ------------------------------私有方法end----------------------------------------------
}

View File

@@ -0,0 +1,38 @@
package com.seeyon.apps.esign.utils;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
public enum EsignRequestType {
POST{
@Override
public HttpRequestBase getHttpType(String url) {
return new HttpPost(url);
}
},
GET{
@Override
public HttpRequestBase getHttpType(String url) {
return new HttpGet(url);
}
},
DELETE{
@Override
public HttpRequestBase getHttpType(String url) {
return new HttpDelete(url);
}
},
PUT{
@Override
public HttpRequestBase getHttpType(String url) {
return new HttpPut(url);
}
},
;
public abstract HttpRequestBase getHttpType(String url);
}

View File

@@ -0,0 +1,530 @@
package com.seeyon.apps.esign.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.filemanager.manager.AttachmentManager;
import com.seeyon.ctp.common.filemanager.manager.FileManager;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.services.FileUploadExporter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import www.seeyon.com.utils.StringUtil;
import www.seeyon.com.utils.UUIDUtil;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class FileUtil {
private static final long MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
private static final String TEMP_DIR = System.getProperty("java.io.tmpdir") + File.separator + "seeyontempfile";
private static final String DEFAULT_FILENAME_PREFIX = "没有文件名_";
private static final String CATEGORY_CODE = "66";
private FileManager fileManager;
public void setFileManager(FileManager fileManager) {
this.fileManager = fileManager;
}
public FileManager getFileManager() {
if (fileManager == null) {
fileManager = (FileManager) AppContext.getBean("fileManager");
}
return fileManager;
}
private AttachmentManager attachmentManager;
public void setAttachmentManager(AttachmentManager attachmentManager) {
this.attachmentManager = attachmentManager;
}
public AttachmentManager getAttachmentManager() {
if (attachmentManager == null) {
attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager");
}
return attachmentManager;
}
public void isFilePath(String filePath) {
File directory = new File(filePath);
if (!directory.exists()) {
directory.mkdirs();
}
}
/**
* 上传附件
*
* @param fileNames
* @throws Exception
* @throws NumberFormatException
*/
public List<Attachment> fileUpload(List<String> fileNames, String summaryId, Long memberId, Long accountId) throws NumberFormatException, Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// List<Map<String, Object>> lists = dataDao.findAttachAll(id);
FileUploadExporter fileUpload = new FileUploadExporter();
List<Attachment> attachments = new ArrayList<Attachment>();
File f = null;
long l = UUIDUtil.getUUIDLong();
for (int i = 0; i < fileNames.size(); i++) {
String fileName = fileNames.get(i);
if (StringUtils.isNotEmpty(fileName)) {
f = new File(fileName);
if (!f.exists()) {
return null;
}
if (f.length() > 102400000) {
return null;
}
}
String[] strs = new String[]{f.getAbsolutePath()};
String s = fileUpload.processUpload(strs);
// if(StringUtils.isNotEmpty(s)) {
Map<String, String> map = new HashMap();
String attachName = f.getName();
String[] suffixNames = attachName.split("\\.");
map.put("type", "0");
map.put("fileUrl", s);
map.put("mimeType", "application/" + suffixNames[suffixNames.length - 1].toLowerCase());
// if(suffixNames[suffixNames.length-1].equals("docx")) {
// map.put("mimeType", "application/docx");
// }else {
// map.put("mimeType", "image/png");
// }
map.put("size", f.length() + "");
// System.out.println(beanId);
map.put("subReference", l + "");
map.put("category", "66");
map.put("createdate", sdf.format(new Date()));
map.put("filename", f.getName());
map.put("reference", summaryId);
Attachment attachment = new Attachment(map);
attachments.add(attachment);
}
// }
String str = getAttachmentManager().create(attachments, memberId, accountId);
// attachmentManager.create(attachments);
// System.out.println(str);
return attachments;
}
public List<String> fieldFileDownload(Long refId, String path) throws BusinessException {
// 判断路径是否存在
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
List<Long> fileUrls = getAttachmentManager().getBySubReference(refId);
System.out.println(fileUrls.size());
List<String> filepaths = new ArrayList<>();
for (Long fileUrl : fileUrls) {
Attachment attachment = getAttachmentManager().getAttachmentByFileURL(fileUrl);
InputStream inputStream = getFileManager().getFileInputStream(attachment.getFileUrl());
String filepath = path + attachment.getFilename();
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filepath))) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
filepaths.add(filepath);
}
return filepaths;
}
public JSONArray getFileContent(String filePath) throws IOException {
JSONArray jsonArray = new JSONArray();
String houzhui = filePath.substring(filePath.lastIndexOf(".") + 1);
// 创建文件输入流
FileInputStream file = new FileInputStream(new File(filePath));
// 创建工作簿对象
Workbook workbook;
System.out.println("当前文件为"+houzhui+"后缀");
if ("xlsx".equals(houzhui) || "XLSX".equals(houzhui)) {
workbook = new XSSFWorkbook(file);
} else {
workbook = new HSSFWorkbook(file);
}
// 获取第一个工作表
Sheet sheet = workbook.getSheetAt(0);
// 迭代行
Iterator<Row> rowIterator = sheet.iterator();
// 根据行跳过设置
row : while (rowIterator.hasNext()) {
Row row = rowIterator.next();
if (row.getRowNum() < 2) {
continue;
}
int num = 0;
int bj = 0;
JSONObject jsonObject = new JSONObject();
JSONArray SPS = new JSONArray();
JSONObject SP = new JSONObject();
boolean isddh = false;
// 迭代单元格
Iterator<Cell> cellIterator = row.cellIterator();
cell : while (cellIterator.hasNext()) {
// 获取单元格对象
Cell cell = cellIterator.next();
// 单元格索引为1的数据订单号
if (cell.getColumnIndex() == 1) {
String ddh = "";
switch (cell.getCellType()) {
case STRING:
ddh = cell.getStringCellValue();
break;
case NUMERIC:
ddh = cell.getNumericCellValue()+"";
break;
default:
ddh = "";
}
// 如果当前订单号为空,则跳过当前行数据
// 查询当前订单号是否已经存在
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
if (ddh.equals(json.getString("DDH"))) {
// 订单号已经存在
bj = i;
isddh = true;
jsonObject = json;
SPS = jsonObject.getJSONArray("SPS");
} else {
num++;
}
}
if (num == jsonArray.size()) {
// switch (cell.getCellType()) {
// case STRING:
jsonObject.put("DDH",ddh);
// break;
// case NUMERIC:
// jsonObject.put("DDH", cell.getNumericCellValue());
// break;
// default:
// jsonObject.put("DDH", "");
// }
//// jsonObject.put("DDH", cell.getStringCellValue());
}
}
switch (cell.getColumnIndex()) {
case 3:
if (!isddh) {
switch (cell.getCellType()) {
case STRING:
jsonObject.put("GMFMC", cell.getStringCellValue());
break;
case NUMERIC:
jsonObject.put("GMFMC", cell.getNumericCellValue());
break;
default:
jsonObject.put("GMFMC", "");
}
}
break;
case 4:
if (!isddh) {
switch (cell.getCellType()) {
case STRING:
jsonObject.put("GMFNSRSBH", cell.getStringCellValue());
break;
case NUMERIC:
jsonObject.put("GMFNSRSBH", cell.getNumericCellValue());
break;
default:
jsonObject.put("GMFNSRSBH", "");
}
}
break;
case 5:
if (!isddh) {
switch (cell.getCellType()) {
case STRING:
jsonObject.put("GMFYX", cell.getStringCellValue());
break;
case NUMERIC:
jsonObject.put("GMFYX", cell.getNumericCellValue());
break;
default:
jsonObject.put("GMFYX", "");
}
}
break;
case 6:
if (!isddh) {
switch (cell.getCellType()) {
case STRING:
jsonObject.put("GMFSJ", cell.getStringCellValue());
break;
case NUMERIC:
jsonObject.put("GMFSJ", cell.getNumericCellValue());
break;
default:
jsonObject.put("GMFSJ", "");
}
}
break;
case 17:
if (!isddh) {
switch (cell.getCellType()) {
case STRING:
jsonObject.put("BZ", cell.getStringCellValue());
break;
case NUMERIC:
jsonObject.put("BZ", cell.getNumericCellValue());
break;
default:
jsonObject.put("BZ", "");
}
}
break;
case 2:
switch (cell.getCellType()) {
case STRING:
SP.put("FXHXZ", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("FXHXZ", cell.getNumericCellValue());
break;
default:
SP.put("FXHXZ", "");
}
break;
case 7:
switch (cell.getCellType()) {
case STRING:
SP.put("XMMC", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("XMMC", cell.getNumericCellValue());
break;
default:
SP.put("XMMC", "");
}
break;
case 8:
switch (cell.getCellType()) {
case STRING:
SP.put("SPBM", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("SPBM", cell.getNumericCellValue());
break;
default:
SP.put("SPBM", "");
}
break;
case 9:
switch (cell.getCellType()) {
case STRING:
SP.put("GGXH", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("GGXH", cell.getNumericCellValue());
break;
default:
SP.put("GGXH", "");
}
break;
case 10:
switch (cell.getCellType()) {
case STRING:
SP.put("DW", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("DW", cell.getNumericCellValue());
break;
default:
SP.put("DW", "");
}
break;
case 11:
switch (cell.getCellType()) {
case STRING:
SP.put("NUM", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("NUM", cell.getNumericCellValue());
break;
default:
SP.put("NUM", "");
}
break;
case 12:
switch (cell.getCellType()) {
case STRING:
SP.put("SPDJ", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("SPDJ", cell.getNumericCellValue());
break;
default:
SP.put("SPDJ", "");
}
break;
case 13:
switch (cell.getCellType()) {
case STRING:
SP.put("JE", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("JE", cell.getNumericCellValue());
break;
default:
SP.put("JE", "");
}
break;
case 14:
switch (cell.getCellType()) {
case STRING:
SP.put("SL", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("SL", cell.getNumericCellValue());
break;
default:
SP.put("SL", "");
}
break;
case 15:
switch (cell.getCellType()) {
case STRING:
SP.put("ZKJE", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("ZKJE", cell.getNumericCellValue());
break;
default:
SP.put("ZKJE", "");
}
break;
case 16:
switch (cell.getCellType()) {
case STRING:
SP.put("YHZCBS", cell.getStringCellValue());
break;
case NUMERIC:
SP.put("YHZCBS", cell.getNumericCellValue());
break;
default:
SP.put("YHZCBS", "");
}
break;
}
}
if(StringUtil.isEmpty(jsonObject.getString("DDH"))){
continue row;
}
SPS.add(SP);
jsonObject.put("SPS", SPS);
if (num == jsonArray.size()) {
jsonArray.add(jsonObject);
} else {
jsonArray.set(bj, jsonObject);
}
}
// 关闭工作簿
workbook.close();
file.close();
return jsonArray;
}
public JSONArray getFileContent(long fileId) throws IOException {
System.out.println("获取参数附件ID"+fileId);
// 附件路径
String path = SystemEnvironment.getApplicationFolder()+"/hxinvoiceFile/"+fileId+"/";
System.out.println("文件下载路径"+path);
List<Long> fileUrls = getAttachmentManager().getBySubReference(fileId);
Attachment attachment = getAttachmentManager().getAttachmentByFileURL(fileUrls.get(0));
String filePath = path+attachment.getFilename();
JSONArray jsonArray = getFileContent(filePath);
return jsonArray;
}
public static String uploadContractToOA(String url,String fileName, String formId, String loginName, String updateAccountName) throws Exception {
OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
V3xOrgMember member = orgManager.getMemberByLoginName(loginName);
V3xOrgAccount account = orgManager.getAccountByName(updateAccountName);
File tempDir = new File(TEMP_DIR);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
String savePath = TEMP_DIR + File.separator + fileName;
HttpClient.httpDownloadFile(url, null,savePath,"ITF-8");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String refId = String.valueOf(Math.abs(UUID.randomUUID().getLeastSignificantBits()));
FileUploadExporter fileUpload = new FileUploadExporter();
List<Attachment> attachments = new ArrayList<>();
File file = new File(savePath);
if (file.exists() && file.length() <= MAX_FILE_SIZE) {
String uploadedPath = fileUpload.processUpload(new String[]{file.getAbsolutePath()});
Map<String, String> attachMeta = new HashMap<>();
attachMeta.put("type", "0");
attachMeta.put("fileUrl", uploadedPath);
attachMeta.put("size", String.valueOf(file.length()));
attachMeta.put("subReference", refId);
attachMeta.put("category", CATEGORY_CODE);
attachMeta.put("createdate", sdf.format(new Date()));
attachMeta.put("filename", fileName);
attachMeta.put("reference", formId);
attachMeta.put("mimeType", "application/" + "pdf");
attachments.add(new Attachment(attachMeta));
}
if (attachments.isEmpty()) return null;
AttachmentManager attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager");
attachmentManager.create(attachments, member.getId(), account.getId());
file.delete();
return refId;
}
private static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
}

View File

@@ -0,0 +1,27 @@
package com.seeyon.apps.esign.utils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class HmacSHA256Util {
public static String encrypt(String data, String key)
throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] hash = sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}
public static void main(String[] args) throws Exception {
String data = "Hello World";
String key = "secret";
String result = encrypt(data, key);
System.out.println("HmacSHA256加密结果: " + result);
}
}

View File

@@ -0,0 +1,499 @@
package com.seeyon.apps.esign.utils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* @ClassName: HttpClient
* @Description: HTTP请求工具类
* @Author: GiikJc
* @Date: 2022/7/12 15:03
*/
/**
* 发送Get请求HttpResponse httpGet(String url,Map<String,String> headers,String encode)
*发送Post请求同表单Post提交HttpResponse httpPostForm(String url,Map<String,String> params, Map<String,String> headers,String encode)
*发送Post Raw请求HttpResponse httpPostRaw(String url,String stringJson,Map<String,String> headers, String encode)
*发送Put Raw请求HttpResponse httpPutRaw(String url,String stringJson,Map<String,String> headers, String encode)
*发送Delete请求HttpResponse httpDelete(String url,Map<String,String> headers,String encode)
*/
public class HttpClient {
/**
* 发送 HTTP GET 请求下载文件
* @param url 下载文件的 URL
* @param headers 请求头
* @param savePath 文件保存的路径
* @param encode 文件内容的编码
* @return 下载成功返回 true失败返回 false
*/
public static boolean httpDownloadFile(String url, Map<String, String> headers, String savePath, String encode) {
if (encode == null) {
encode = "utf-8"; // 默认字符编码
}
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// 创建 HttpClient 实例
httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
// 设置请求头
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
// 执行请求
httpResponse = httpClient.execute(httpGet);
HttpEntity entity = httpResponse.getEntity();
// 检查响应状态码
if (httpResponse.getStatusLine().getStatusCode() == 200) {
inputStream = entity.getContent();
// 创建输出流,将文件保存到本地
outputStream = new FileOutputStream(savePath);
// 设置缓冲区
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// 文件下载成功
return true;
} else {
System.out.println("Download failed, HTTP error code: " + httpResponse.getStatusLine().getStatusCode());
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
if (httpResponse != null) {
httpResponse.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 对queryString参数按key进行字典序升序排序
* @param queryString 原始参数字符串,如"b=2&a=1&c=3"
* @return 排序后的字符串,如"a=1&b=2&c=3"
*/
public static String sortQueryString(String queryString) {
if (queryString == null || queryString.isEmpty()) {
return queryString;
}
String[] pairs = queryString.split("&");
Map<String, String> params = new TreeMap<>();
for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv.length == 2) {
params.put(kv[0], kv[1]);
} else if (kv.length == 1) {
params.put(kv[0], "");
}
}
return params.entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
}
/**
* 发送http get请求
*/
public static String httpGet(String url,Map<String,String> headers,String encode){
if(encode == null){
encode = "utf-8";
}
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
String content = null;
//since 4.3 不再使用 DefaultHttpClient
try {
closeableHttpClient = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
//设置header
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(),entry.getValue());
}
}
httpResponse = closeableHttpClient.execute(httpGet);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try { //关闭连接、释放资源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 发送 http post 请求参数以form表单键值对的形式提交。
*/
public static String httpPostForm(String url,Map<String,String> params, Map<String,String> headers,String encode){
if(encode == null){
encode = "utf-8";
}
String content = null;
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
try {
closeableHttpClient = HttpClients.createDefault();
HttpPost httpost = new HttpPost(url);
//设置header
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpost.setHeader(entry.getKey(),entry.getValue());
}
}
//组织请求参数
List<NameValuePair> paramList = new ArrayList <NameValuePair>();
if(params != null && params.size() > 0){
Set<String> keySet = params.keySet();
for(String key : keySet) {
paramList.add(new BasicNameValuePair(key, params.get(key)));
}
}
httpost.setEntity(new UrlEncodedFormEntity(paramList, encode));
httpResponse = closeableHttpClient.execute(httpost);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try { //关闭连接、释放资源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 发送 http post 请求,参数以原生字符串进行提交
* @param url
* @param encode
* @return
*/
public static String httpPostRaw(String url,String stringJson,Map<String,String> headers, String encode){
if(encode == null){
encode = "utf-8";
}
String content = null;
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
try {
//HttpClients.createDefault()等价于 HttpClientBuilder.create().build();
closeableHttpClient = HttpClients.createDefault();
HttpPost httpost = new HttpPost(url);
//设置header
httpost.setHeader("Content-type", "application/json");
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpost.setHeader(entry.getKey(),entry.getValue());
}
}
//组织请求参数
StringEntity stringEntity = new StringEntity(stringJson, encode);
httpost.setEntity(stringEntity);
//响应信息
httpResponse = closeableHttpClient.execute(httpost);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try { //关闭连接、释放资源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 发送 http put 请求,参数以原生字符串进行提交
* @param url
* @param encode
* @return
*/
public static String httpPutRaw(String url,String stringJson,Map<String,String> headers, String encode){
if(encode == null){
encode = "utf-8";
}
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
String content = null;
//since 4.3 不再使用 DefaultHttpClient
try {
//HttpClients.createDefault()等价于 HttpClientBuilder.create().build();
closeableHttpClient = HttpClients.createDefault();
HttpPut httpput = new HttpPut(url);
//设置header
httpput.setHeader("Content-type", "application/json");
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpput.setHeader(entry.getKey(),entry.getValue());
}
}
//组织请求参数
StringEntity stringEntity = new StringEntity(stringJson, encode);
httpput.setEntity(stringEntity);
//响应信息
httpResponse = closeableHttpClient.execute(httpput);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
closeableHttpClient.close(); //关闭连接、释放资源
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 发送http delete请求
*/
public static String httpDelete(String url,Map<String,String> headers,String encode){
if(encode == null){
encode = "utf-8";
}
String content = null;
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
try {
//since 4.3 不再使用 DefaultHttpClient
closeableHttpClient = HttpClientBuilder.create().build();
HttpDelete httpdelete = new HttpDelete(url);
//设置header
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpdelete.setHeader(entry.getKey(),entry.getValue());
}
}
httpResponse = closeableHttpClient.execute(httpdelete);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try { //关闭连接、释放资源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 发送 http post 请求,支持文件上传
*/
public static String httpPostFormMultipart(String url,Map<String,String> params, List<File> files,Map<String,String> headers,String encode){
if(encode == null){
encode = "utf-8";
}
CloseableHttpResponse httpResponse = null;
CloseableHttpClient closeableHttpClient = null;
String content = null;
//since 4.3 不再使用 DefaultHttpClient
try {
closeableHttpClient = HttpClients.createDefault();
HttpPost httpost = new HttpPost(url);
//设置header
if (headers != null && headers.size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpost.setHeader(entry.getKey(),entry.getValue());
}
}
MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
mEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mEntityBuilder.setCharset(Charset.forName(encode));
// 普通参数
ContentType contentType = ContentType.create("text/plain",Charset.forName(encode));//解决中文乱码
if (params != null && params.size() > 0) {
Set<String> keySet = params.keySet();
for (String key : keySet) {
mEntityBuilder.addTextBody(key, params.get(key),contentType);
}
}
//二进制参数
if (files != null && files.size() > 0) {
for (File file : files) {
mEntityBuilder.addBinaryBody("file", file);
}
}
httpost.setEntity(mEntityBuilder.build());
httpResponse = closeableHttpClient.execute(httpost);
HttpEntity entity = httpResponse.getEntity();
content = EntityUtils.toString(entity, encode);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try { //关闭连接、释放资源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
public static String uploadBinaryFile(String url, Map<String,String> headers,
InputStream io, String fileName) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPut put = new HttpPut(url);
String responseBody = null;
try {
// 设置请求头
for (String key : headers.keySet()) {
put.addHeader(key, headers.get(key));
}
// 构建多部分实体
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.setCharset(Charset.forName("UTF-8"));
builder.addBinaryBody("file", io, ContentType.MULTIPART_FORM_DATA, fileName);
put.setEntity(builder.build());
// 执行请求
CloseableHttpResponse response = null;
try {
response = client.execute(put);
HttpEntity resEntity = response.getEntity();
responseBody = EntityUtils.toString(resEntity, "UTF-8");
// 无论状态码如何,都返回响应体
return responseBody;
} finally {
if(response != null) {
response.close();
}
}
} finally {
client.close();
io.close();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.seeyon.apps.esign.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.Iterator;
import java.util.Map;
public class JsonCleaner {
public static String removeEmptyObjects(String jsonStr) throws Exception {
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = (ObjectNode) mapper.readTree(jsonStr);
Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
while (fields.hasNext()) {
Map.Entry<String, com.fasterxml.jackson.databind.JsonNode> entry = fields.next();
if (entry.getValue().isObject() && entry.getValue().isEmpty()) {
fields.remove();
}
}
return mapper.writeValueAsString(node);
}
}

View File

@@ -0,0 +1,89 @@
package com.seeyon.apps.esign.utils;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.aicloud.common.JsonUtils;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.esign.config.EsignConfigProvider;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import www.seeyon.com.utils.StringUtil;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
@Component
public class ProtUtil {
private static final Log log = LogFactory.getLog(ProtUtil.class);
@Autowired
private EsignConfigProvider configProvider;
public String getPluginId() {return EsignConfigConstants.getPluginId();}
/**
* 获取一个token
*
* @return
* @throws IOException
* @throws FileNotFoundException
*/
private String getToken(String oatokenurl,String restName,String restPassword,String loginName) throws FileNotFoundException, IOException {
String address = oatokenurl + restName + "/" + restPassword;
if(StringUtil.isNotEmpty(loginName)){
address = address +"?loginName="+loginName;
}
DefaultHttpClient client = new DefaultHttpClient();
String result = "";
HttpGet get = new HttpGet(address);
// 添加 Headers 信息
get.addHeader(new BasicHeader("Accept", "application/json"));
try {
HttpResponse res = client.execute(get);
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
result = EntityUtils.toString(res.getEntity());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
String token = "";
if(result.contains("{")) {
JSONObject jsObj = JSONObject.parseObject(result);
token = jsObj.get("id").toString();
}else {
token = result;
}
return token;
}
/**
* 调用post接口
* @return
*/
public String sendPostNotification(String params, String urlParam, String token) throws IOException {
String host = configProvider.getBizConfigByKey(EsignConfigConstants.OA_HOST);
String tokenGetUrl = configProvider.getBizConfigByKey(EsignConfigConstants.getTokenUrl);
String restName = configProvider.getBizConfigByKey(EsignConfigConstants.restName);
String restPwd = configProvider.getBizConfigByKey(EsignConfigConstants.restPwd);
String oatoken = getToken(host + tokenGetUrl,restName,restPwd,null);
String url = host + urlParam+ token+"?token="+oatoken;
log.info("调用恢复超级节点接口请求地址为: " + url);
String respStr = HttpClient.httpPostRaw(url, params, null, null);
log.info("调用恢复超级节点接口响应结果: " + respStr);
Map map = JsonUtils.parseObject(respStr, Map.class);
if(!"0".equals(map.get("code")) || map.get("code") == null) {
throw new RuntimeException("恢复阻塞的超级节点失败: " + map.get("message"));
}
return respStr;
}
}

View File

@@ -0,0 +1,49 @@
package com.seeyon.ctp.rest.resources;
import cn.hutool.log.Log;
import com.seeyon.apps.esign.service.EsignFileTemplateService;
import com.seeyon.ctp.common.AppContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.Map;
@Path("cap4/etemplate")
public class EsignTemplateResource extends BaseResource {
private static final Log log = Log.get(EsignTemplateResource.class);
private EsignFileTemplateService esignFileTemplateService = (EsignFileTemplateService) AppContext.getBean("esignFileTemplateService");
@GET
@Produces({"application/json"})
@Consumes({"application/json"})
@Path("/querypage")
public Response queryTemplates(@QueryParam("pageNum") Integer pageNum) {
try {
Map<String, Object> map = esignFileTemplateService.queryTemplates(pageNum);
return success(map);
}catch (Exception e) {
log.error(e.getMessage(),e);
}
return fail("失败");
}
@POST
@Produces({"application/json"})
@Consumes({"application/json"})
@Path("/compareurl")
public Response compare(@QueryParam("templateRefId") String templateRefId,@QueryParam("contractRefId") String contractRefId) {
try {
String compareDetailUrl = esignFileTemplateService.getCompareDetailUrl(templateRefId, contractRefId);
return success(compareDetailUrl);
}catch (Exception e) {
log.error(e.getMessage(),e);
}
return fail("失败");
}
}

View File

@@ -0,0 +1,328 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean>
<id>/esigncallback.do</id>
<methods>
<method>callback</method>
</methods>
</bean>
<bean>
<id>/qrCodeForm.do</id>
<methods>
<method>index</method>
<method>newMain</method>
</methods>
</bean>
<bean>
<id>/sc.do</id>
<methods>
<method>qr</method>
</methods>
</bean>
<bean>
<id>/elearning.do</id>
<methods>
<method>error</method>
<method>m3Redirect</method>
<method>message</method>
<method>pcRedirect</method>
</methods>
</bean>
<bean>
<id>/phoneLogin/phoneLogin.do</id>
<methods>
<method>getMessageCode</method>
<method>validateMessageCode</method>
</methods>
</bean>
<bean>
<id>/wechat/miniprogram.do</id>
<methods>
<method>a8home</method>
<method>bind</method>
<method>bindMemberPhone</method>
<method>login</method>
<method>unbind</method>
</methods>
</bean>
<bean>
<id>/portal/spaceController.do</id>
<methods>
<method>showThemSpace</method>
</methods>
</bean>
<bean>
<id>/identification.do</id>
<methods>
<method>getSessionId</method>
</methods>
</bean>
<bean>
<id>/fileUpload.do</id>
<methods>
<method>showRTE</method>
</methods>
</bean>
<bean>
<id>/fileDownload.do</id>
<methods>
<method>showRTE</method>
</methods>
</bean>
<bean>
<id>/form/formUpgrade.do</id>
<methods>
<method>toUpgrade</method>
<method>upgrade</method>
<method>viewUpgrade</method>
</methods>
</bean>
<bean>
<id>formtalkFormMapperController.do</id>
<methods>
<method>importFormtalkData</method>
</methods>
</bean>
<bean>
<id>/thirdpartyController.do</id>
<methods>
<method>access</method>
<method>index</method>
<method>logoutNotify</method>
<method>show</method>
<method>mailAuth</method>
</methods>
</bean>
<bean>
<id>/main.do</id>
<methods>
<method>changeLocale</method>
<method>hangup</method>
<method>headerjs</method>
<method>index</method>
<method>login</method>
<method>login4Ucpc</method>
<method>login4Ucpc3</method>
<method>login4Vjoin</method>
<method>logout</method>
<method>logout4Session</method>
<method>logout4Vjoin</method>
<method>logout4ZX</method>
<method>main</method>
<method>login4QrCode</method>
<method>qrCodeHelp</method>
<method>updateLoginSeed</method>
</methods>
</bean>
<bean>
<id>/trustdo/A8/XRD.do</id>
<methods>
<method>getLoginAccount</method>
<method>getLoginAcctoken</method>
<method>webLogin</method>
</methods>
</bean>
<bean>
<id>/share.do</id>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/genericController.do</id>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/edoc/edocUpgradeControllor.do</id>
<methods>
<method>upgrade</method>
<method>download</method>
</methods>
</bean>
<bean>
<id>/uploadService.do</id>
<methods>
<method>processUploadService</method>
</methods>
</bean>
<bean>
<id>/autoinstall.do</id>
<methods>
<method>ieSetDown</method>
<method>regInstallDown</method>
<method>regInstallDown64</method>
<method>downloadAssistant</method>
</methods>
</bean>
<bean>
<id>/personalBind.do</id>
<methods>
<method>getBindTypeByLoginName</method>
<method>isCanUse</method>
<method>retrievePassword</method>
<method>sendVerificationCodeToBindEmail</method>
<method>sendVerificationCodeToBindNum</method>
<method>validateVerificationCode</method>
</methods>
</bean>
<!-- <bean>白名单清理-->
<!-- <id>/meetingPanel.do</id>-->
<!-- <methods>-->
<!-- <method>meetingPanelDisplay</method>-->
<!-- <method>meetingPanelView</method>-->
<!-- </methods>-->
<!-- </bean>-->
<bean>
<id>/commonimage.do</id>
<methods>
<method>showImage</method>
</methods>
</bean>
<bean>
<id>/individualManager.do</id>
<methods>
<method>resetPassword</method>
</methods>
</bean>
<bean>
<id>/wechat/dingding.do</id>
<methods>
<method>binding</method>
<method>index</method>
<method>main</method>
<method>newIndex</method>
<method>newMain</method>
<method>viewh5Message</method>
</methods>
</bean>
<bean>
<id>/uc/rest.do</id>
<methods>
<method>commonPierce</method>
<method>downloadImage</method>
<method>getBgTimeStamp</method>
<method>getLoginsecurityMsg</method>
<method>sendsms</method>
<method>smsrequired</method>
<method>testIp</method>
<method>isQrLogin</method>
<method>getDigitalCodeInfo</method>
</methods>
</bean>
<bean>
<id>portalManager</id>
<methods>
<method>sendSMSLoginCode</method>
<method>smsLoginEnabled</method>
</methods>
</bean>
<bean>
<id>loginUserManager</id>
<methods>
<method>getLockTime</method>
</methods>
</bean>
<bean>
<id>qrCodeLoginManager</id>
<methods>
<method>isLogin</method>
</methods>
</bean>
<bean>
<id>meetingAjaxManager</id>
<methods>
<method>meetingPanelData</method>
<method>meetingPanelDisplay</method>
</methods>
</bean>
<bean>
<id>/m3/loginController.do</id>
<methods>
<method>transLogin</method>
<method>transLogout</method>
<method>getProfile</method>
</methods>
</bean>
<bean>
<id>/m3/mClientBindController.do</id>
<methods>
<method>bindApply</method>
</methods>
</bean>
<bean>
<id>m3ProductManager</id>
<methods>
<method>productInfo</method>
<method>productStatus</method>
</methods>
</bean>
<bean>
<id>/m3/homeSkinController.do</id>
<methods>
<method>downloadImage</method>
<method>getSkinImageUrl</method>
</methods>
</bean>
<bean>
<id>/m3/transModeController.do</id>
<methods>
<method>getTransModeForMobile</method>
</methods>
</bean>
<bean>
<id>/media/media.do</id>
<methods>
<method>mediaShow</method>
</methods>
</bean>
<bean>
<id>/ocipEdoc.do</id>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/colView.do</id>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/caAccountManagerController.do</id>
<methods>
<method>findKeyNumByLoginName</method>
</methods>
</bean>
<bean>
<id>/fddCallbackController.do</id>
<methods>
<method>asynch</method>
<method>synch</method>
</methods>
</bean>
<bean>
<id>/seeyonReport/seeyonReportController.do</id>
<methods>
<method>redirectSeeyonReport</method>
</methods>
</bean>
<bean>
<id>/imc.do</id>
<methods>
<method>index</method>
<method>logout</method>
</methods>
</bean>
<bean>
<id>/cloudbuild.do</id>
<methods>
<method>download</method>
<method>getDownloadPageInfo</method>
<method>getLatestVersionInfo</method>
<method>getDownloadQrUrl</method>
</methods>
</bean>
</beans>

View File

@@ -0,0 +1,433 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean>
<id>/esigncallback.do</id>
<name>com.seeyon.apps.esign.controller.EsignCallBackController</name>
<methods>
<method>callback</method>
</methods>
</bean>
<bean>
<id>/qrCodeForm.do</id>
<name>com.seeyon.apps.qrCodeForm.controller.QrCodeFormController</name>
<methods>
<method>index</method>
<method>newMain</method>
</methods>
</bean>
<bean>
<id>/sc.do</id>
<name>com.seeyon.cap4.form.modules.smartCode.controller.SmartCodeController</name>
<methods>
<method>qr</method>
</methods>
</bean>
<bean>
<id>/media/media.do</id>
<name>com.seeyon.ctp.common.media.controller.MediaController</name>
<methods>
<method>mediaShow</method>
</methods>
</bean>
<bean>
<id>/phoneLogin/phoneLogin.do</id>
<name>com.seeyon.ctp.login.controller.PhoneLoginController</name>
<methods>
<method>getMessageCode</method>
<method>validateMessageCode</method>
</methods>
</bean>
<bean>
<id>portalManager</id>
<name>com.seeyon.ctp.portal.manager.PortalManagerImpl</name>
<methods>
<method>sendSMSLoginCode</method>
<method>smsLoginEnabled</method>
</methods>
</bean>
<bean>
<id>/fileDownload.do</id>
<name>com.seeyon.ctp.common.fileupload.FileUploadController</name>
<methods>
<method>showRTE</method>
</methods>
</bean>
<bean>
<id>loginUserManager</id>
<name>com.seeyon.ctp.login.LoginUserManagerImpl</name>
<methods>
<method>getLockTime</method>
</methods>
</bean>
<bean>
<id>/main.do</id>
<name>com.seeyon.ctp.login.controller.MainController</name>
<methods>
<method>changeLocale</method>
<method>hangup</method>
<method>headerjs</method>
<method>index</method>
<method>login</method>
<method>login4Ucpc</method>
<method>login4Ucpc3</method>
<method>login4Vjoin</method>
<method>logout</method>
<method>logout4Session</method>
<method>logout4Vjoin</method>
<method>logout4ZX</method>
<method>main</method>
<method>login4QrCode</method>
<method>qrCodeHelp</method>
<method>updateLoginSeed</method>
</methods>
</bean>
<bean>
<id>/trustdo/A8/XRD.do</id>
<name>com.seeyon.apps.trustdo.controller.XRDController</name>
<methods>
<method>getLoginAccount</method>
<method>getLoginAcctoken</method>
<method>webLogin</method>
</methods>
</bean>
<bean>
<id>/share.do</id>
<name>com.seeyon.v3x.system.share.controller.ShareController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/edoc/edocUpgradeControllor.do</id>
<name>com.seeyon.v3x.edoc.controller.EdocUpgradeControllor</name>
<methods>
<method>upgrade</method>
<method>download</method>
</methods>
</bean>
<bean>
<id>/m3/mClientBindController.do</id>
<name>com.seeyon.apps.m3.bind.controller.M3ClientBindController</name>
<methods>
<method>bindApply</method>
</methods>
</bean>
<bean>
<id>/uploadService.do</id>
<name>com.seeyon.ctp.services.FileUploadService</name>
<methods>
<method>processUploadService</method>
</methods>
</bean>
<bean>
<id>/uc/rest.do</id>
<name>com.seeyon.apps.zx.controller.ZxRestController</name>
<methods>
<method>commonPierce</method>
<method>downloadImage</method>
<method>getBgTimeStamp</method>
<method>getLoginsecurityMsg</method>
<method>sendsms</method>
<method>smsrequired</method>
<method>testIp</method>
<method>isQrLogin</method>
<method>getDigitalCodeInfo</method>
</methods>
</bean>
<bean>
<id>/m3/homeSkinController.do</id>
<name>com.seeyon.apps.m3.skin.controller.M3HomeSkinController</name>
<methods>
<method>downloadImage</method>
<method>getSkinImageUrl</method>
</methods>
</bean>
<bean>
<id>/colView.do</id>
<name>com.seeyon.apps.ocip.exchange.collaboration.controller.CollViewController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/autoinstall.do</id>
<name>com.seeyon.apps.autoinstall.controller.AutoInstallController</name>
<methods>
<method>ieSetDown</method>
<method>regInstallDown</method>
<method>regInstallDown64</method>
<method>downloadAssistant</method>
</methods>
</bean>
<!-- <bean> 白名单清理-->
<!-- <id>/meetingPanel.do</id>-->
<!-- <name>com.seeyon.apps.meeting.controller.MeetingPanelController</name>-->
<!-- <methods>-->
<!-- <method>meetingPanelDisplay</method>-->
<!-- <method>meetingPanelView</method>-->
<!-- </methods>-->
<!-- </bean>-->
<bean>
<id>/caAccountManagerController.do</id>
<name>com.seeyon.v3x.ca.caaccount.controller.CAAccountManagerController</name>
<methods>
<method>findKeyNumByLoginName</method>
</methods>
</bean>
<bean>
<id>/elearning.do</id>
<name>com.seeyon.apps.elearning.controller.ElearningController</name>
<methods>
<method>error</method>
<method>m3Redirect</method>
<method>message</method>
<method>pcRedirect</method>
</methods>
</bean>
<bean>
<id>/wechat/miniprogram.do</id>
<name>com.seeyon.apps.weixin.controller.MiniProgramController</name>
<methods>
<method>a8home</method>
<method>bind</method>
<method>bindMemberPhone</method>
<method>login</method>
<method>unbind</method>
</methods>
</bean>
<bean>
<id>/portal/spaceController.do</id>
<name>com.seeyon.ctp.portal.space.controller.SpaceController</name>
<methods>
<method>showThemSpace</method>
</methods>
</bean>
<bean>
<id>/identification.do</id>
<name>com.seeyon.v3x.identification.controller.IdentificationController</name>
<methods>
<method>getSessionId</method>
</methods>
</bean>
<bean>
<id>/fddCallbackController.do</id>
<name>com.seeyon.apps.econtract.fdd.controller.FddCallbackController</name>
<methods>
<method>asynch</method>
<method>synch</method>
</methods>
</bean>
<bean>
<id>m3ProductManager</id>
<name>com.seeyon.apps.m3.product.manager.impl.M3ProductManagerImpl</name>
<methods>
<method>productInfo</method>
<method>productStatus</method>
</methods>
</bean>
<bean>
<id>/ocipEdoc.do</id>
<name>com.seeyon.apps.ocip.exchange.edoc.OCIPEdocController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/m3/loginController.do</id>
<methods>
<method>transLogin</method>
<method>transLogout</method>
<method>getProfile</method>
</methods>
</bean>
<bean>
<id>/fileUpload.do</id>
<name>com.seeyon.ctp.common.fileupload.FileUploadController</name>
<methods>
<method>showRTE</method>
<method>processUpload</method>
</methods>
</bean>
<bean>
<id>qrCodeLoginManager</id>
<name>com.seeyon.ctp.login.manager.QrCodeLoginManagerImpl</name>
<methods>
<method>isLogin</method>
</methods>
</bean>
<bean>
<id>/form/formUpgrade.do</id>
<name>com.seeyon.ctp.form.service.FormUpgradeController</name>
<methods>
<method>toUpgrade</method>
<method>upgrade</method>
<method>viewUpgrade</method>
</methods>
</bean>
<bean>
<id>/seeyonReport/seeyonReportController.do</id>
<name>com.seeyon.apps.seeyonreport.controller.SeeyonReportController</name>
<methods>
<method>redirectSeeyonReport</method>
</methods>
</bean>
<bean>
<id>formtalkFormMapperController.do</id>
<name>com.seeyon.apps.formtalk.controller.FormtalkImportController</name>
<methods>
<method>importFormtalkData</method>
</methods>
</bean>
<bean>
<id>/thirdpartyController.do</id>
<name>com.seeyon.ctp.portal.sso.thirdpartyintegration.controller.ThirdpartyController</name>
<methods>
<method>access</method>
<method>index</method>
<method>logoutNotify</method>
<method>show</method>
<method>mailAuth</method>
</methods>
</bean>
<bean>
<id>/m3/transModeController.do</id>
<name>com.seeyon.apps.m3.transmissionmode.controller.M3TransModeController</name>
<methods>
<method>getTransModeForMobile</method>
</methods>
</bean>
<bean>
<id>/genericController.do</id>
<name>com.seeyon.v3x.common.controller.GenericController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/personalBind.do</id>
<name>com.seeyon.v3x.personalaffair.controller.PersonalBindController</name>
<methods>
<method>getBindTypeByLoginName</method>
<method>isCanUse</method>
<method>retrievePassword</method>
<method>sendVerificationCodeToBindEmail</method>
<method>sendVerificationCodeToBindNum</method>
<method>validateVerificationCode</method>
</methods>
</bean>
<bean>
<id>/commonimage.do</id>
<name>com.seeyon.apps.common.image.controller.ImageController</name>
<methods>
<method>showImage</method>
</methods>
</bean>
<bean>
<id>/individualManager.do</id>
<name>com.seeyon.v3x.personalaffair.controller.IndividualManagerController</name>
<methods>
<method>resetPassword</method>
</methods>
</bean>
<bean>
<id>meetingAjaxManager</id>
<name>com.seeyon.apps.meeting.manager.MeetingAjaxManagerImpl</name>
<methods>
<method>meetingPanelData</method>
<method>meetingPanelDisplay</method>
</methods>
</bean>
<bean>
<id>/wechat/dingding.do</id>
<name>com.seeyon.apps.weixin.controller.DingDingController</name>
<methods>
<method>binding</method>
<method>index</method>
<method>main</method>
<method>newIndex</method>
<method>newMain</method>
<method>viewh5Message</method>
</methods>
</bean>
<bean>
<id>/imc.do</id>
<name>com.seeyon.apps.imc.controller.ImcLoginController</name>
<methods>
<method>index</method>
<method>logout</method>
</methods>
</bean>
<bean>
<id>/wechat/feishu.do</id>
<name>com.seeyon.apps.weixin.controller.FeishuController</name>
<methods>
<method>newMain</method>
<method>viewh5Message</method>
</methods>
</bean>
<!-- <bean>-->
<!-- <id>/wechat/pcapp.do</id>-->
<!-- <name>com.seeyon.apps.zhifei.controller.ZhifeiPcAppController</name>-->
<!-- <methods>-->
<!-- <method>transferPageFromWxCoreServer</method>-->
<!-- <method>gotoPcApp</method>-->
<!-- <method>checkCodeTurnToRightPage</method>-->
<!-- <method>transfer</method>-->
<!-- <method>transferMsg</method>-->
<!-- </methods>-->
<!-- </bean>-->
<bean>
<id>/wechat/pcapp.do</id>
<name>com.seeyon.apps.weixin.controller.PcAppController</name>
<methods>
<method>transferPageFromWxCoreServer</method>
<method>gotoPcApp</method>
<method>checkCodeTurnToRightPage</method>
<method>transfer</method>
<method>transferMsg</method>
</methods>
</bean>
<bean>
<id>/wechat/feishu/approvalData.do</id>
<name>com.seeyon.apps.zhifei.feishu.approval.controller.ApprovalDataController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/zhifei/feishu.do</id>
<name>com.seeyon.apps.zhifei.controller.FeishuController</name>
<methods>
<method>newMain</method>
<method>viewh5Message</method>
</methods>
</bean>
<bean>
<id>/zhifei/pcapp.do</id>
<name>com.seeyon.apps.zhifei.controller.ZhifeiPcAppController</name>
<methods>
<method>transferPageFromWxCoreServer</method>
<method>gotoPcApp</method>
</methods>
</bean>
<bean>
<id>/zhifei/feishu/approvalData.do</id>
<name>com.seeyon.apps.zhifei.feishu.approval.controller.ApprovalDataController</name>
<methods>
<method>index</method>
</methods>
</bean>
<bean>
<id>/cloudbuild.do</id>
<name>com.seeyon.apps.cloudbuild.controller.CloudBuildController</name>
<methods>
<method>download</method>
<method>getDownloadPageInfo</method>
<method>getLatestVersionInfo</method>
<method>getDownloadQrUrl</method>
</methods>
</bean>
</beans>

View File

@@ -0,0 +1,7 @@
import com.seeyon.apps.esign.GtlyEsignPluginApi;
public class TestOne {
public static void main(String[] args) {
new GtlyEsignPluginApi();
}
}