|
@@ -10,6 +10,7 @@ import java.util.stream.Collectors;
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
|
import com.trade.service.contract.config.ContractConfigProperties;
|
|
|
+import com.trade.service.contract.util.SignPubUtil;
|
|
|
import com.trade.service.contract.util.esign.bizprocess.BizProcessorFactory;
|
|
|
import com.trade.service.contract.util.esign.bizprocess.SignedBizProcessor;
|
|
|
import org.jsoup.helper.StringUtil;
|
|
@@ -50,7 +51,7 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
*/
|
|
|
@Slf4j
|
|
|
@Service(ContractConstant.CONTRACT_PLATFORM_SERVICE_NAME_ESIGN)
|
|
|
-public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
+public class ESignContractServiceImpl implements SignPlatformService, SignAccountCreator {
|
|
|
|
|
|
@Resource
|
|
|
private TFileStorageService fileStorageService;
|
|
@@ -77,10 +78,12 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
public ContractSignOutput signContract(ContractSignInput signInput) {
|
|
|
log.info("进入E签宝合同签署流程,业务场景:{},签署失效时长:{}hour", signInput.getBizScene(), signInput.getSignValidTime());
|
|
|
ContractSignOutput output = new ContractSignOutput();
|
|
|
+ // 获取e签宝账号信息: 先统一创建账号,有任意创建失败则fail fast
|
|
|
+ Map<String, String> accountMap = getAccountMap(signInput.getSigneInfoList());
|
|
|
// 创建签署流程
|
|
|
String flowId = creatESignFlow(signInput);
|
|
|
// 上传签署文件
|
|
|
- output.setItems(uploadSignFileAndSetPositions(flowId, signInput));
|
|
|
+ output.setItems(uploadSignFileAndSetPositions(flowId, signInput, accountMap));
|
|
|
// 发起签署流程
|
|
|
startSignProcess(flowId);
|
|
|
output.setFlowId(flowId);
|
|
@@ -112,8 +115,7 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
|
|
|
@Override
|
|
|
public Map<String, String> getAccountMap(List<ContractSignInfo> signInfoList) {
|
|
|
- // 将e签宝在中间步骤创建的逻辑提过来
|
|
|
- return null;
|
|
|
+ return SignPubUtil.getAccountMapFromSignInfo(signInfoList, this);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -233,46 +235,6 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
log.info("e签宝签署完成文件下载完成,flowId:{}", eSignFlow.getFlowId());
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 获取本次签署所需创建的所有e签宝账号
|
|
|
- * </p>
|
|
|
- * ContractSignInfo 传值规则: </br>
|
|
|
- * 当多个签署文件只需要单方签署时,ContractSignInfo中只需设置singleSigner,sealInfoList中的signer可为空。</br>
|
|
|
- * 当多个签署文件需要多方签署时,ContractSignInfo中设置singleSigner可为空,设置sealInfoList的signer。</br>
|
|
|
- * 即:ContractSignInfo中的singleSigner为sealInfoList的signer的备选项。两者不可同时为空。</br>
|
|
|
- * sealInfoList数组中的ContractSeal对象中的sealIdType为企业证件类型时才需创建企业账号,否则为个人账号。</br>
|
|
|
- * 创建个人账号时只依赖ContractSigner信息,与ContractSeal无关。即需要加盖个人章时,只需设置ContractSigner信息即可。</br>
|
|
|
- *
|
|
|
- * @param signInfo 签署信息
|
|
|
- * @return <K 签署人证件号, V 签署人e签宝账号id>
|
|
|
- */
|
|
|
- private Map<String, String> creatESignAccount(ContractSignInfo signInfo) {
|
|
|
- // TODO check参数合法性
|
|
|
- Map<String, String> resultMap = new HashMap<>();
|
|
|
- // 单方签署
|
|
|
- ContractSigner signer = signInfo.getSingleSigner();
|
|
|
- if (null != signer) {
|
|
|
- resultMap.put(signer.getSignerIdNo(), creatPersonalAccount(signer));
|
|
|
- }
|
|
|
- signInfo.getSealInfoList().forEach(sealInfo -> {
|
|
|
- if (null == sealInfo.getSigner()) {// 签章信息中的签署人为空,则使用签署信息中的签署人
|
|
|
- if (null == signer) {
|
|
|
- throw new ServiceException("签署信息中的签署人和签章信息中的签署人不能同时为空", HttpStatus.BAD_REQUEST);
|
|
|
- }
|
|
|
- sealInfo.setSigner(signer);
|
|
|
- } else {// 签署信息中的签署人不为空,则使用签署信息中的签署人creat个人账号
|
|
|
- resultMap.computeIfAbsent(sealInfo.getSigner().getSignerIdNo(),
|
|
|
- o -> creatPersonalAccount(sealInfo.getSigner()));
|
|
|
- }
|
|
|
- // 若存在企业签章,则需创建企业账号
|
|
|
- if (ESignConstant.CRED_ORG_USCC.equals(sealInfo.getSealIdType())
|
|
|
- || ESignConstant.CRED_ORG_UNKNOWN.equals(sealInfo.getSealIdType())) {
|
|
|
- resultMap.computeIfAbsent(sealInfo.getSealIdNo(), o -> createOrgAccount(sealInfo));
|
|
|
- }
|
|
|
- });
|
|
|
- return resultMap;
|
|
|
- }
|
|
|
-
|
|
|
private String creatESignFlow(ContractSignInput signInput) {
|
|
|
if (StringUtils.isEmpty(signInput.getBizScene())) {
|
|
|
throw new ServiceException("签署任务-业务场景不能为空", HttpStatus.BAD_REQUEST);
|
|
@@ -302,7 +264,8 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
return flowId;
|
|
|
}
|
|
|
|
|
|
- private List<ContractSignOutputItem> uploadSignFileAndSetPositions(String flowId, ContractSignInput signInput) {
|
|
|
+ private List<ContractSignOutputItem> uploadSignFileAndSetPositions(String flowId, ContractSignInput signInput,
|
|
|
+ Map<String, String> accountMap) {
|
|
|
List<ContractSignInfo> signInfos = signInput.getSigneInfoList();
|
|
|
if (CollectionUtils.isEmpty(signInfos)) {
|
|
|
throw new ServiceException("签署任务-待签署信息列表不能为空", HttpStatus.BAD_REQUEST);
|
|
@@ -319,7 +282,7 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
// 上传签署文件
|
|
|
String eSignFileId = uploadSignFile(flowId, signInfo);
|
|
|
// 设置签署位置
|
|
|
- addSignField(signFieldList, flowId, signInfo, eSignFileId, willTypes);
|
|
|
+ addSignField(signFieldList, flowId, signInfo, eSignFileId, willTypes, accountMap);
|
|
|
outputItems.add(new ContractSignOutputItem(signInfo.getFileType(), signInfo.getFileId(), eSignFileId));
|
|
|
}
|
|
|
ESignRequest.addSignerHandSignArea(flowId, signFieldList);
|
|
@@ -328,51 +291,50 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
|
|
|
/**
|
|
|
* 添加签署位置
|
|
|
- *
|
|
|
+ *
|
|
|
* @param signFieldList 签署文档列表
|
|
|
* @param signInfo 签章信息
|
|
|
* @param eSignFileId e签宝文件id
|
|
|
+ * @param accountMap
|
|
|
*/
|
|
|
private void addSignField(List<ESignDoc> signFieldList, String flowId, ContractSignInfo signInfo,
|
|
|
- String eSignFileId, List<String> willTypes) {
|
|
|
+ String eSignFileId, List<String> willTypes, Map<String, String> accountMap) {
|
|
|
List<ContractSeal> sealInfoList = signInfo.getSealInfoList();
|
|
|
if (CollectionUtils.isEmpty(sealInfoList)) {
|
|
|
throw new ServiceException("签署任务-签章信息列表不能为空", HttpStatus.BAD_REQUEST);
|
|
|
}
|
|
|
- // 先统一创建账号,有任意创建失败则直接失败,不再进行后续操作
|
|
|
- Map<String, String> accountMap = creatESignAccount(signInfo);
|
|
|
- for (ContractSeal salInfo : sealInfoList) {
|
|
|
+ for (ContractSeal sealInfo : sealInfoList) {
|
|
|
// 签章里的签署人信息未传,则使用签署信息中的签署人信息
|
|
|
- ContractSigner signer = null == salInfo.getSigner() ? signInfo.getSingleSigner() : salInfo.getSigner();
|
|
|
- ESignDocPosition posBean = ESignRequest.searchWordsPosition(flowId, eSignFileId, salInfo.getKeyword());
|
|
|
- if (Boolean.TRUE.equals(salInfo.getWithTime())) {
|
|
|
+ ContractSigner signer = null == sealInfo.getSigner() ? signInfo.getSingleSigner() : sealInfo.getSigner();
|
|
|
+ ESignDocPosition posBean = ESignRequest.searchWordsPosition(flowId, eSignFileId, sealInfo.getKeyword());
|
|
|
+ if (Boolean.TRUE.equals(sealInfo.getWithTime())) {
|
|
|
posBean.setAddSignTime(true);
|
|
|
posBean.setSignTimeFormat(ESignConstant.SIGN_DATE_FORMAT);
|
|
|
}
|
|
|
ESignDoc signField = null;
|
|
|
// 企业
|
|
|
- if (ESignConstant.CRED_ORG_USCC.equals(salInfo.getSealIdType())
|
|
|
- || ESignConstant.CRED_ORG_UNKNOWN.equals(salInfo.getSealIdType())) {
|
|
|
+ if (ESignConstant.isOrgSealType(sealInfo.getSealIdType())) {
|
|
|
// 机构签约类别,当签约主体为机构时必传
|
|
|
- String actorIdentityType = "2";// 企业
|
|
|
- if (Boolean.TRUE.equals(salInfo.getSignLegal())) {
|
|
|
- actorIdentityType = "3";// 企业法人章
|
|
|
- }
|
|
|
- signField = new ESignDoc(eSignFileId, accountMap.get(signer.getSignerIdNo()), actorIdentityType,
|
|
|
- accountMap.get(salInfo.getSealIdNo()), null, 1, posBean, null, null, null);
|
|
|
- if (handleAutoSign(flowId, salInfo, signField))
|
|
|
+ String actorIdentityType = Boolean.TRUE.equals(sealInfo.getSignLegal()) ? "3" : "2";// 2企业 3法人
|
|
|
+ if (Boolean.TRUE.equals(sealInfo.getAutoSign())) {
|
|
|
+ signField = new ESignDoc(eSignFileId, accountMap.get(sealInfo.getSealIdNo()), null, posBean, null,
|
|
|
+ null);
|
|
|
+ handleAutoSign(flowId, sealInfo, signField);
|
|
|
continue;
|
|
|
- } else if (ESignConstant.CRED_PSN_CH_IDCARD.equals(signer.getSignerIdType())
|
|
|
- || ESignConstant.CRED_PSN_PASSPORT.equals(signer.getSignerIdType())) {
|
|
|
- if (Boolean.TRUE.equals(salInfo.getAutoSign())) {
|
|
|
- throw new ServiceException("签署任务-个人签章暂不支持自动签章", HttpStatus.BAD_REQUEST);
|
|
|
- }
|
|
|
- signField = new ESignDoc(eSignFileId, accountMap.get(signer.getSignerIdNo()), null, null, null,
|
|
|
- 1, posBean, "1", null, null);
|
|
|
- }
|
|
|
+ } else {
|
|
|
+ signField = new ESignDoc(eSignFileId, accountMap.get(signer.getSignerIdNo()), actorIdentityType,
|
|
|
+ accountMap.get(sealInfo.getSealIdNo()), null, 1, posBean, null, null, null);
|
|
|
+ }
|
|
|
+ } else if (ESignConstant.isIndividualSealType(signer.getSignerIdType())) {
|
|
|
+ if (Boolean.TRUE.equals(sealInfo.getAutoSign())) {
|
|
|
+ throw new ServiceException("签署任务-个人签章暂不支持自动签章", HttpStatus.BAD_REQUEST);
|
|
|
+ }
|
|
|
+ signField = new ESignDoc(eSignFileId, accountMap.get(signer.getSignerIdNo()), null, null, null, 1,
|
|
|
+ posBean, "1", null, null);
|
|
|
+ }
|
|
|
if (null == signField) {
|
|
|
log.error("签署任务-获取签章位置出错fileId:{},sealIdType:{},keyword:{}", signInfo.getFileId(),
|
|
|
- salInfo.getSealIdType(), salInfo.getKeyword());
|
|
|
+ sealInfo.getSealIdType(), sealInfo.getKeyword());
|
|
|
throw new ServiceException("签署任务-获取签章位置出错,请检查签章传参是否正确", HttpStatus.ERROR);
|
|
|
}
|
|
|
signField.setWillTypes(willTypes);
|
|
@@ -390,18 +352,14 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
* @param signField e签宝签署任务对象
|
|
|
* @return 是否自动签章
|
|
|
*/
|
|
|
- private boolean handleAutoSign(String flowId, ContractSeal sealInfo, ESignDoc signField) {
|
|
|
- if (Boolean.TRUE.equals(sealInfo.getAutoSign())) {
|
|
|
- String sealId = contractConfigProperties.getESignSealIdByIdNo(sealInfo.getSealIdNo());
|
|
|
- if (null == sealId) {
|
|
|
- throw new ServiceException("签署任务-签章信息-企业签章-自动签章-未配置签章ID", HttpStatus.BAD_REQUEST);
|
|
|
- }
|
|
|
- signField.setSealId(sealId);
|
|
|
- // 调用自动签署方法
|
|
|
- ESignRequest.addPlatformAutoSignArea(flowId, Collections.singletonList(signField));
|
|
|
- return true;
|
|
|
+ private void handleAutoSign(String flowId, ContractSeal sealInfo, ESignDoc signField) {
|
|
|
+ String sealId = contractConfigProperties.getESignSealIdByIdNo(sealInfo.getSealIdNo());
|
|
|
+ if (null == sealId) {
|
|
|
+ throw new ServiceException("签署任务-签章信息-企业签章-自动签章-未配置签章ID", HttpStatus.BAD_REQUEST);
|
|
|
}
|
|
|
- return false;
|
|
|
+ signField.setSealId(sealId);
|
|
|
+ // 调用自动签署方法
|
|
|
+ ESignRequest.addPlatformAutoSignArea(flowId, Collections.singletonList(signField));
|
|
|
}
|
|
|
|
|
|
private void saveSignFlowSigner(String flowId, Map<String, String> accountMap) {
|
|
@@ -448,7 +406,7 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
* @param signer 个人信息
|
|
|
* @return 个人账号ID
|
|
|
*/
|
|
|
- private String creatPersonalAccount(ContractSigner signer) {
|
|
|
+ public String creatPersonalAccount(ContractSigner signer) {
|
|
|
if (null == signer || StrUtil.isBlank(signer.getSigner()) || StrUtil.isBlank(signer.getSignerIdType())
|
|
|
|| StrUtil.isBlank(signer.getSignerIdNo())
|
|
|
|| (StrUtil.isBlank(signer.getMobile()) && StringUtil.isBlank(signer.getEmail()))) {
|
|
@@ -513,7 +471,7 @@ public class ESignContractServiceImpl implements SignPlatformService {
|
|
|
* @param sealInfo 签章信息
|
|
|
* @return 企业账号ID
|
|
|
*/
|
|
|
- private String createOrgAccount(ContractSeal sealInfo) {
|
|
|
+ public String createOrgAccount(ContractSeal sealInfo) {
|
|
|
if (null == sealInfo || StrUtil.isBlank(sealInfo.getSealName()) || StrUtil.isBlank(sealInfo.getSealIdNo())) {
|
|
|
log.error(JSON.toJSONString(sealInfo));
|
|
|
throw new ServiceException("机构帐号信息不全!", HttpStatus.BAD_REQUEST);
|