增加印章同步功能
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
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";
|
||||
@@ -14,4 +13,5 @@ public class EsignApiUrl {
|
||||
public static final String QUERY_ORGINFO = "/v3/organizations/identity-info";
|
||||
public static final String CONTRACT_COMPARE_GETURL = "/v3/contract-compare-url";
|
||||
public static final String TOKEN_GET_URL = "/v1/oauth2/access_token";
|
||||
public static final String SEAL_QUERY_URL = "/v3/seals/org-own-seal-list";
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ public enum EsignConfigConstants {
|
||||
nodeTokenUrl("/seeyon/rest/flow/notification/","超级节点回调URL"),
|
||||
restName("",""),
|
||||
restPwd("",""),
|
||||
signAutoDate("","是否自动加盖签署日期"),
|
||||
eSignOrgId("61f735dd368c45a191f43a6711c3c88a","e签宝平台方组织id"),
|
||||
formLoginName("2019","表单数据录入登录名"),
|
||||
sealInfoFormCode("","印章档案编码"),
|
||||
;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
@@ -83,7 +83,36 @@ public class FormDataOperator {
|
||||
}
|
||||
}
|
||||
|
||||
public FormColumn queryOneRowFormData(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws BusinessException {
|
||||
public void deleteByCondition(String formNo, List<FormWhereCondition> conditionVos) throws Exception {
|
||||
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> fieldMap4Name = masterTableBean.getFieldMap4Name();
|
||||
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 = generateDelSql(conditionVos, tableName);
|
||||
String sql = (String) generateSql.get("sql");
|
||||
List<Object> params = (List<Object>) generateSql.get("params");
|
||||
JDBCAgent jdbcAgent = new JDBCAgent();
|
||||
try {
|
||||
jdbcAgent.execute(sql, params);
|
||||
} finally {
|
||||
jdbcAgent.close();
|
||||
}
|
||||
}
|
||||
|
||||
public FormColumn queryOneRowFormData(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws Exception {
|
||||
FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
|
||||
FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
|
||||
List<String> queryColumns = new ArrayList<>();
|
||||
@@ -138,13 +167,10 @@ public class FormDataOperator {
|
||||
}
|
||||
columns.add(column);
|
||||
}
|
||||
return columns.get(0);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return columns.size() > 0 ? columns.get(0) : null;
|
||||
} finally {
|
||||
jdbcAgent.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<FormColumn> queryFormDataCondition(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws BusinessException {
|
||||
@@ -256,6 +282,20 @@ public class FormDataOperator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Object> generateDelSql(List<FormWhereCondition> conditions, String tableName) {
|
||||
if (tableName == null) {
|
||||
throw new IllegalArgumentException("tableName cannot be null or empty");
|
||||
}
|
||||
StringBuilder sqlBuilder = new StringBuilder("DELETE ");
|
||||
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");
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.seeyon.apps.esign.job;
|
||||
|
||||
import com.seeyon.aicloud.common.JsonUtils;
|
||||
import com.seeyon.apps.esign.config.EsignConfigProvider;
|
||||
import com.seeyon.apps.esign.constants.EsignApiUrl;
|
||||
import com.seeyon.apps.esign.constants.EsignConfigConstants;
|
||||
import com.seeyon.apps.esign.po.EsignApiHeader;
|
||||
import com.seeyon.apps.esign.po.EsignBaseResp;
|
||||
import com.seeyon.apps.esign.po.SealInfoVo;
|
||||
import com.seeyon.apps.esign.service.SealService;
|
||||
import com.seeyon.apps.esign.service.TokenCacheManager;
|
||||
import com.seeyon.apps.esign.utils.HttpClient;
|
||||
import com.seeyon.apps.ext.quartz.AbstractQuartzTask;
|
||||
import 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.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class SealDocSyncJob extends AbstractQuartzTask {
|
||||
|
||||
private static final Log log = LogFactory.getLog(SealDocSyncJob.class);
|
||||
@Autowired
|
||||
private EsignConfigProvider configProvider;
|
||||
@Autowired
|
||||
private TokenCacheManager tokenCacheManager;
|
||||
@Autowired
|
||||
private SealService sealService;
|
||||
|
||||
@Override
|
||||
public String taskRun(String s) throws Exception {
|
||||
log.info("开始执行印章同步任务");
|
||||
syncSeals();
|
||||
log.info("印章同步任务完成");
|
||||
return "";
|
||||
}
|
||||
|
||||
private void syncSeals() {
|
||||
String orgId = configProvider.getBizConfigByKey(EsignConfigConstants.eSignOrgId);
|
||||
String host = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST);
|
||||
Integer pageNum = 1;
|
||||
Integer pageSize = 20;
|
||||
EsignApiHeader esignApiHeader = EsignApiHeader.build().appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID));
|
||||
esignApiHeader.token(tokenCacheManager.getToken());
|
||||
EsignBaseResp esignBaseResp = null;
|
||||
Map<String,Object> dataMap = null;
|
||||
do {
|
||||
String url = host + EsignApiUrl.SEAL_QUERY_URL + "?" + "orgId=" + orgId + "&pageNum=" + (pageNum++) + "&pageSize=" + pageSize;
|
||||
String respStr = HttpClient.httpGet(url, esignApiHeader.convert2Headers(),"UTF-8");
|
||||
esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
|
||||
if(esignBaseResp.getCode() != 0) {
|
||||
break;
|
||||
}
|
||||
dataMap = (Map<String,Object>)esignBaseResp.getData();
|
||||
Object[] sealArray = (Object[]) dataMap.get("seals");
|
||||
if(sealArray == null || sealArray.length == 0) {
|
||||
break;
|
||||
}
|
||||
for (Object o : sealArray) {
|
||||
SealInfoVo sealInfoVo = JsonUtils.parseObject(JsonUtils.toJSONString(o), SealInfoVo.class);
|
||||
sealService.upsertOaSealDoc(sealInfoVo);
|
||||
}
|
||||
}while (true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "E签宝印章信息同步任务";
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,10 @@ 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.po.NormalSignFieldConfig;
|
||||
import com.seeyon.apps.esign.po.SignField;
|
||||
import com.seeyon.apps.esign.po.SignFieldPosition;
|
||||
import com.seeyon.apps.esign.po.Signer;
|
||||
import com.seeyon.apps.esign.service.EsignByTemplateService;
|
||||
import com.seeyon.apps.esign.service.EsignByUploadFileService;
|
||||
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
|
||||
@@ -21,12 +24,15 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class EsignNode extends ACommonSuperNode {
|
||||
public class EsignMultipleSignerNode extends ACommonSuperNode {
|
||||
|
||||
private static final Log log = LogFactory.getLog(EsignNode.class);
|
||||
private static final Log log = LogFactory.getLog(EsignMultipleSignerNode.class);
|
||||
|
||||
private static final String CONTRACT_NAME_FIELD = "合同名称";
|
||||
private static final String CONTRACT_ATTACHMENT_FIELD = "合同审批附件";
|
||||
@@ -53,14 +59,14 @@ public class EsignNode extends ACommonSuperNode {
|
||||
public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) {
|
||||
SuperNodeContext context = new SuperNodeContext();
|
||||
context.setNeedSave(true);
|
||||
log.info("进入 E签宝签署集成超级节点");
|
||||
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 + " , OA超级节点ID:" + formDataVo.getToken());
|
||||
log.info("E签宝合同已发送: " + esignFlowId);
|
||||
log.info("E签宝多方签署合同已发送: " + esignFlowId);
|
||||
return context.wait("等待签署结束");
|
||||
} catch (Exception e) {
|
||||
log.error("E签宝签署失败", e);
|
||||
@@ -87,8 +93,8 @@ public class EsignNode extends ACommonSuperNode {
|
||||
|
||||
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, "甲方盖章/签字");
|
||||
List<SignFieldPosition> bPositions = extractPosition(positions, "乙方盖章/签字");
|
||||
List<SignFieldPosition> aPositions = extractPosition(positions, "甲方盖章/签字");
|
||||
String bSignerType = formDataVo.getFieldData("乙方签署类型").getStringValue();
|
||||
|
||||
SignFieldPosition aQiFengposition = new SignFieldPosition();
|
||||
@@ -98,27 +104,23 @@ public class EsignNode extends ACommonSuperNode {
|
||||
bQiFengposition.setAcrossPageMode("ALL");
|
||||
bQiFengposition.setPositionY(720f);
|
||||
|
||||
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(
|
||||
aPositions.add(aQiFengposition);
|
||||
bPositions.add(bQiFengposition);
|
||||
String sealId = formDataVo.getFieldData("甲方印章ID").getStringValue();
|
||||
Signer bSigner = !"组织".equals(bSignerType) ? createPsnSigner(fileId,formDataVo.getFieldData("乙方姓名").getStringValue(),bPositions,1,formDataVo.getFieldData("乙方电话").getStringValue(),false) : createOrgSigner(
|
||||
fileId,
|
||||
getStringField(formDataVo, B_UNIT_NAME_FIELD),
|
||||
bPos, 1, formDataVo.getFieldData("乙方法人姓名").getStringValue(),
|
||||
bPositions, 1, formDataVo.getFieldData("乙方法人姓名").getStringValue(),
|
||||
formDataVo.getFieldData("乙方法人身份证号").getStringValue(),
|
||||
formDataVo.getFieldData("乙方企业社会信用代码").getStringValue(),
|
||||
formDataVo.getFieldData("乙方经办人手机号").getStringValue(),
|
||||
formDataVo.getFieldData("乙方经办人姓名").getStringValue(),
|
||||
formDataVo.getFieldData("乙方经办人身份证号").getStringValue(),false
|
||||
);
|
||||
,null);
|
||||
|
||||
Signer aSigner = createOrgSigner(
|
||||
fileId,null, aPos, 2, null, null, null, null, null, null,true
|
||||
);
|
||||
fileId,null, aPositions, 2, null, null, null, null, null, null,true
|
||||
,sealId);
|
||||
List<Signer> signers = new ArrayList<>();
|
||||
signers.add(bSigner);
|
||||
signers.add(aSigner);
|
||||
@@ -139,7 +141,6 @@ public class EsignNode extends ACommonSuperNode {
|
||||
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);
|
||||
@@ -188,32 +189,37 @@ public class EsignNode extends ACommonSuperNode {
|
||||
signer.setPsnSignerInfo(psnInfo);
|
||||
}
|
||||
|
||||
List<SignField> signFields = new ArrayList<>();
|
||||
for (SignFieldPosition po : pos) {
|
||||
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
|
||||
fieldConfig.setSignFieldPosition(pos.get(0));
|
||||
if("ALL".equals(po.getAcrossPageMode())){
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(2);
|
||||
SignField qiFengfield = new SignField();
|
||||
qiFengfield.setSignFieldType(0);
|
||||
qiFengfield.setNormalSignFieldConfig(fieldConfig);
|
||||
qiFengfield.setFileId(fileId);
|
||||
signFields.add(qiFengfield);
|
||||
}else {
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(1);
|
||||
SignField field = new SignField();
|
||||
field.setSignFieldType(0);
|
||||
field.setNormalSignFieldConfig(fieldConfig);
|
||||
field.setSignDateConfig(new SignDateConfig());
|
||||
field.setFileId(fileId);
|
||||
signFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
signer.setSignFields(signFields);
|
||||
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) {
|
||||
String transPhone, String psnName, String psnId,Boolean autoSign,String sealId) {
|
||||
Signer signer = new Signer();
|
||||
signer.setSignerType(1);
|
||||
signer.setSignConfig(mapOf("signOrder", order));
|
||||
@@ -238,41 +244,54 @@ public class EsignNode extends ACommonSuperNode {
|
||||
signer.setOrgSignerInfo(orgInfo);
|
||||
}
|
||||
|
||||
List<SignField> signFields = new ArrayList<>();
|
||||
for (SignFieldPosition po : pos) {
|
||||
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
|
||||
fieldConfig.setSignFieldPosition(pos.get(0));
|
||||
fieldConfig.setAssignedSealId(sealId);
|
||||
if("ALL".equals(po.getAcrossPageMode())){
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(2);
|
||||
SignField qiFengfield = new SignField();
|
||||
qiFengfield.setSignFieldType(0);
|
||||
qiFengfield.setNormalSignFieldConfig(fieldConfig);
|
||||
qiFengfield.setFileId(fileId);
|
||||
signFields.add(qiFengfield);
|
||||
}else {
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(1);
|
||||
SignField field = new SignField();
|
||||
field.setSignFieldType(0);
|
||||
field.setNormalSignFieldConfig(fieldConfig);
|
||||
field.setSignDateConfig(new SignDateConfig());
|
||||
field.setFileId(fileId);
|
||||
signFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
signer.setSignFields(signFields);
|
||||
return signer;
|
||||
}
|
||||
|
||||
private SignFieldPosition extractPosition(List<Object> positions, String keyword) {
|
||||
private List<SignFieldPosition> extractPosition(List<Object> positions, String keyword) {
|
||||
List<SignFieldPosition> posList = new ArrayList<>();
|
||||
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];
|
||||
for (Object o : posArray) {
|
||||
Map<String, Object> posMap = (Map<String, Object>)o;
|
||||
Object[] coords = (Object[]) posMap.get("coordinates");
|
||||
for (Object coord : coords) {
|
||||
Map<String,Object> tempMap = (Map<String, Object>) coord;
|
||||
SignFieldPosition sfp = new SignFieldPosition();
|
||||
sfp.setPositionPage(posMap.get("pageNum") + "");
|
||||
sfp.setPositionX(toFloat(coord.get("positionX")) + 150f);
|
||||
sfp.setPositionY(toFloat(coord.get("positionY")));
|
||||
return sfp;
|
||||
sfp.setPositionX(toFloat(tempMap.get("positionX")) + 150f);
|
||||
sfp.setPositionY(toFloat(tempMap.get("positionY")));
|
||||
posList.add(sfp);
|
||||
}
|
||||
}
|
||||
return posList;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("未找到关键字位置: " + keyword);
|
||||
@@ -288,11 +307,11 @@ public class EsignNode extends ACommonSuperNode {
|
||||
|
||||
@Override
|
||||
public String getNodeId() {
|
||||
return "nd_20250702";
|
||||
return "nd_20250703";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
return "E签宝签署节点";
|
||||
return "E签宝甲乙双方签署节点";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
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 EsignOneSignerNode extends ACommonSuperNode {
|
||||
|
||||
private static final Log log = LogFactory.getLog(EsignOneSignerNode.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 + " , OA超级节点ID:" + formDataVo.getToken());
|
||||
log.info("E签宝单方签署合同已发送: " + esignFlowId);
|
||||
return context.wait("等待签署结束");
|
||||
} catch (Exception e) {
|
||||
log.error("E签宝签署失败", e);
|
||||
context.setErrMsg("E签宝签署失败: " + e.getMessage());
|
||||
return context.back("E签宝签署失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<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> buildOnlyASigner(FormDataVo formDataVo, String fileId) throws Exception {
|
||||
List<Object> positions = uploadFileService.getSignPosition(fileId);
|
||||
List<SignFieldPosition> aPositions = extractPosition(positions, "甲方盖章/签字");
|
||||
|
||||
SignFieldPosition aQiFengposition = new SignFieldPosition();
|
||||
aQiFengposition.setAcrossPageMode("ALL");
|
||||
aQiFengposition.setPositionY(520f);
|
||||
String sealId = formDataVo.getFieldData("甲方印章ID").getStringValue();
|
||||
aPositions.add(aQiFengposition);
|
||||
Signer aSigner = createOrgSigner(
|
||||
fileId,null, aPositions, 1, null, null, null, null, null, null,true
|
||||
,sealId);
|
||||
List<Signer> signers = new ArrayList<>();
|
||||
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 = buildOnlyASigner(formDataVo, fileId);
|
||||
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);
|
||||
}
|
||||
|
||||
List<SignField> signFields = new ArrayList<>();
|
||||
for (SignFieldPosition po : pos) {
|
||||
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
|
||||
if("ALL".equals(po.getAcrossPageMode())){
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(2);
|
||||
SignField qiFengfield = new SignField();
|
||||
qiFengfield.setSignFieldType(0);
|
||||
qiFengfield.setNormalSignFieldConfig(fieldConfig);
|
||||
qiFengfield.setFileId(fileId);
|
||||
signFields.add(qiFengfield);
|
||||
}else {
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(1);
|
||||
SignField field = new SignField();
|
||||
field.setSignFieldType(0);
|
||||
field.setNormalSignFieldConfig(fieldConfig);
|
||||
field.setFileId(fileId);
|
||||
signFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
signer.setSignFields(signFields);
|
||||
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,String sealId) {
|
||||
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);
|
||||
}
|
||||
|
||||
List<SignField> signFields = new ArrayList<>();
|
||||
for (SignFieldPosition po : pos) {
|
||||
NormalSignFieldConfig fieldConfig = new NormalSignFieldConfig();
|
||||
fieldConfig.setAssignedSealId(sealId);
|
||||
if("ALL".equals(po.getAcrossPageMode())){
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(2);
|
||||
SignField qiFengfield = new SignField();
|
||||
qiFengfield.setSignFieldType(0);
|
||||
qiFengfield.setNormalSignFieldConfig(fieldConfig);
|
||||
qiFengfield.setFileId(fileId);
|
||||
signFields.add(qiFengfield);
|
||||
}else {
|
||||
fieldConfig.setSignFieldPosition(po);
|
||||
fieldConfig.setAutoSign(autoSign);
|
||||
fieldConfig.setSignFieldStyle(1);
|
||||
SignField field = new SignField();
|
||||
field.setSignFieldType(0);
|
||||
field.setNormalSignFieldConfig(fieldConfig);
|
||||
field.setFileId(fileId);
|
||||
signFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
signer.setSignFields(signFields);
|
||||
return signer;
|
||||
}
|
||||
|
||||
private List<SignFieldPosition> extractPosition(List<Object> positions, String keyword) {
|
||||
List<SignFieldPosition> posList = new ArrayList<>();
|
||||
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");
|
||||
for (Object o : posArray) {
|
||||
Map<String, Object> posMap = (Map<String, Object>)o;
|
||||
Object[] coords = (Object[]) posMap.get("coordinates");
|
||||
for (Object coord : coords) {
|
||||
Map<String,Object> tempMap = (Map<String, Object>) coord;
|
||||
SignFieldPosition sfp = new SignFieldPosition();
|
||||
sfp.setPositionPage(posMap.get("pageNum") + "");
|
||||
sfp.setPositionX(toFloat(tempMap.get("positionX")) + 150f);
|
||||
sfp.setPositionY(toFloat(tempMap.get("positionY")));
|
||||
posList.add(sfp);
|
||||
}
|
||||
}
|
||||
return posList;
|
||||
}
|
||||
}
|
||||
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签宝甲方单方签署节点";
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ public class NormalSignFieldConfig {
|
||||
private Boolean autoSign;
|
||||
private Integer signFieldStyle;
|
||||
private SignFieldPosition signFieldPosition;
|
||||
private String assignedSealId; //指定签章id
|
||||
|
||||
public Boolean getAutoSign() {
|
||||
return autoSign;
|
||||
@@ -28,4 +29,12 @@ public class NormalSignFieldConfig {
|
||||
public void setSignFieldPosition(SignFieldPosition signFieldPosition) {
|
||||
this.signFieldPosition = signFieldPosition;
|
||||
}
|
||||
|
||||
public String getAssignedSealId() {
|
||||
return assignedSealId;
|
||||
}
|
||||
|
||||
public void setAssignedSealId(String assignedSealId) {
|
||||
this.assignedSealId = assignedSealId;
|
||||
}
|
||||
}
|
||||
|
||||
50
esign/src/main/java/com/seeyon/apps/esign/po/SealInfoVo.java
Normal file
50
esign/src/main/java/com/seeyon/apps/esign/po/SealInfoVo.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.seeyon.apps.esign.po;
|
||||
|
||||
public class SealInfoVo {
|
||||
|
||||
private String sealId; //印章ID
|
||||
private String sealName; //印章名称
|
||||
private String sealBizTypeDescription; //印章描述
|
||||
private String statusDescription; //印章状态描述
|
||||
private String sealImageDownloadUrl; //印章图片下载地址
|
||||
|
||||
public String getSealId() {
|
||||
return sealId;
|
||||
}
|
||||
|
||||
public void setSealId(String sealId) {
|
||||
this.sealId = sealId;
|
||||
}
|
||||
|
||||
public String getSealName() {
|
||||
return sealName;
|
||||
}
|
||||
|
||||
public void setSealName(String sealName) {
|
||||
this.sealName = sealName;
|
||||
}
|
||||
|
||||
public String getSealBizTypeDescription() {
|
||||
return sealBizTypeDescription;
|
||||
}
|
||||
|
||||
public void setSealBizTypeDescription(String sealBizTypeDescription) {
|
||||
this.sealBizTypeDescription = sealBizTypeDescription;
|
||||
}
|
||||
|
||||
public String getStatusDescription() {
|
||||
return statusDescription;
|
||||
}
|
||||
|
||||
public void setStatusDescription(String statusDescription) {
|
||||
this.statusDescription = statusDescription;
|
||||
}
|
||||
|
||||
public String getSealImageDownloadUrl() {
|
||||
return sealImageDownloadUrl;
|
||||
}
|
||||
|
||||
public void setSealImageDownloadUrl(String sealImageDownloadUrl) {
|
||||
this.sealImageDownloadUrl = sealImageDownloadUrl;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ public class SignField {
|
||||
private Integer signFieldType;
|
||||
private NormalSignFieldConfig normalSignFieldConfig;
|
||||
private RemarkSignFieldConfig remarkSignFieldConfig;
|
||||
private SignDateConfig signDateConfig;
|
||||
|
||||
public String getFileId() {
|
||||
return fileId;
|
||||
@@ -40,11 +39,4 @@ public class SignField {
|
||||
this.remarkSignFieldConfig = remarkSignFieldConfig;
|
||||
}
|
||||
|
||||
public SignDateConfig getSignDateConfig() {
|
||||
return signDateConfig;
|
||||
}
|
||||
|
||||
public void setSignDateConfig(SignDateConfig signDateConfig) {
|
||||
this.signDateConfig = signDateConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,41 @@ 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.form.FormColumn;
|
||||
import com.seeyon.apps.esign.form.FormDataOperator;
|
||||
import com.seeyon.apps.esign.form.FormExportUtil;
|
||||
import com.seeyon.apps.esign.form.FormWhereCondition;
|
||||
import com.seeyon.apps.esign.po.EsignApiHeader;
|
||||
import com.seeyon.apps.esign.po.EsignBaseResp;
|
||||
import com.seeyon.apps.esign.po.SealInfoVo;
|
||||
import com.seeyon.apps.esign.utils.HttpClient;
|
||||
import com.seeyon.ctp.common.AppContext;
|
||||
import com.seeyon.ctp.common.exceptions.BusinessException;
|
||||
import com.seeyon.ctp.services.ServiceException;
|
||||
import com.seeyon.v3x.services.form.FormFactory;
|
||||
import com.seeyon.v3x.services.form.bean.FormExport;
|
||||
import com.seeyon.v3x.services.form.bean.ValueExport;
|
||||
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.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
public class SealService {
|
||||
|
||||
private static final Log log = LogFactory.getLog(SealService.class);
|
||||
@Autowired
|
||||
private EsignConfigProvider configProvider;
|
||||
private FormFactory formFactory;
|
||||
|
||||
public FormFactory getFormFactory() {
|
||||
if (formFactory == null) {
|
||||
formFactory = (FormFactory) AppContext.getBean("formFactory");
|
||||
}
|
||||
return formFactory;
|
||||
}
|
||||
|
||||
public void grantSeal(Map<String, Object> params) throws Exception {
|
||||
JsonObject reqParams = new JsonObject();
|
||||
@@ -56,10 +75,10 @@ public class SealService {
|
||||
esignApiHeader.appId(configProvider.getBizConfigByKey(EsignConfigConstants.APP_ID))
|
||||
.httpMethod("GET")
|
||||
.heads("")
|
||||
.pathAndParameters(EsignApiUrl.QUERY_SEAL_URL + "?" + HttpClient.sortQueryString("orgId=" + orgId + "&pageNo=" + pageNo + "&pageSize=" + pageSize))
|
||||
.pathAndParameters(EsignApiUrl.SEAL_QUERY_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 url = host + EsignApiUrl.SEAL_QUERY_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();
|
||||
@@ -72,4 +91,46 @@ public class SealService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void upsertOaSealDoc(SealInfoVo vo) {
|
||||
FormDataOperator formDataOperator = new FormDataOperator();
|
||||
String formNo = configProvider.getBizConfigByKey(EsignConfigConstants.sealInfoFormCode);
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
conditions.add(FormWhereCondition.build().display("印章ID").value(vo.getSealId()));
|
||||
FormColumn formColumn = null;
|
||||
try {
|
||||
formColumn = formDataOperator.queryOneRowFormData(formNo, null, conditions);
|
||||
} catch (Exception e) {
|
||||
log.error("查询印章信息失败: " + e.getMessage(), e);
|
||||
}
|
||||
if (formColumn == null) {
|
||||
if ("已启用".equals(vo.getStatusDescription())) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("印章ID", vo.getSealId());
|
||||
params.put("印章名称", vo.getSealName());
|
||||
params.put("印章类型", vo.getSealBizTypeDescription());
|
||||
params.put("印章状态", vo.getStatusDescription());
|
||||
// params.put("印章图片地址",vo.getSealImageDownloadUrl());
|
||||
|
||||
FormExport formExport = new FormExport();
|
||||
FormExportUtil formExportUtil = new FormExportUtil();
|
||||
List<ValueExport> valueExport = formExportUtil.setFormValue(params);
|
||||
formExport.setValues(valueExport);
|
||||
try {
|
||||
getFormFactory().importBusinessFormData(configProvider.getBizConfigByKey(EsignConfigConstants.formLoginName), configProvider.getBizConfigByKey(EsignConfigConstants.sealInfoFormCode),
|
||||
formExport, new String[]{});
|
||||
} catch (ServiceException e) {
|
||||
log.error(vo.getSealName() + "信息写入OA档案失败," + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!"已启用".equals(vo.getSealBizTypeDescription())) {
|
||||
try {
|
||||
formDataOperator.deleteByCondition(formNo, conditions);
|
||||
} catch (Exception e) {
|
||||
log.error("删除停用印章失败" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user