diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/OperatorInfo.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/OperatorInfo.java index de7b7f73..c2daf1cf 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/OperatorInfo.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/OperatorInfo.java @@ -1,11 +1,12 @@ package cn.axzo.nanopart.ess.api.domain; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotNull; - /** * @author yanglin */ @@ -17,12 +18,14 @@ public class OperatorInfo implements OrgPerson { * 发起方单位id */ @NotNull(message = "ouId不能为空") + @Min(value = 1, message = "ouId必须大于0") private Long ouId; /** * 发起方人员id */ @NotNull(message = "personId不能为空") + @Min(value = 1, message = "personId必须大于0") private Long personId; } diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/EssApproveDetail.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/EssApproveDetail.java index f3067819..ebc15643 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/EssApproveDetail.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/EssApproveDetail.java @@ -13,7 +13,7 @@ import lombok.Setter; public class EssApproveDetail { /** - * 签署人, 动态签署人在没有签署的时候可能为null + * 签署人, 动态签署人在没有签署(state=PENDING)的时候可能为null */ private OrgPersonInfo signPerson; @@ -48,17 +48,17 @@ public class EssApproveDetail { private long approverDeadlineMs; /** - * 单位id, 动态签署人在没有签署的时候可能为空 + * 单位id, 动态签署人在没有签署(state=PENDING)的时候可能为空 */ private Long ouId; /** - * 单位名称, 动态签署人在没有签署的时候可能为空 + * 单位名称, 动态签署人在没有签署(state=PENDING)的时候可能为空 */ private String ouName; /** - * 对应签署人的手机号, 动态签署人在没有签署的时候可能为空 + * 对应签署人的手机号, 动态签署人在没有签署(state=PENDING)的时候可能为空 */ private String phoneNumber; } diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/OrgPersonInfo.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/OrgPersonInfo.java index 57b556f5..fa03534f 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/OrgPersonInfo.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/domain/contract/OrgPersonInfo.java @@ -5,6 +5,7 @@ import cn.axzo.nanopart.ess.api.domain.OrgPerson; import lombok.Getter; import lombok.Setter; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; /** @@ -18,12 +19,14 @@ public class OrgPersonInfo implements OrgPerson { * 单位id */ @NotNull(message = "ouId不能为空") + @Min(value = 1, message = "ouId必须大于0") private Long ouId; /** * 人员id */ @NotNull(message = "personId不能为空") + @Min(value = 1, message = "personId必须大于0") private Long personId; } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/dao/EssLogDao.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/dao/EssLogDao.java index 52f21e83..4bb40e78 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/dao/EssLogDao.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/dao/EssLogDao.java @@ -1,13 +1,13 @@ package cn.axzo.nanopart.ess.server.dao; -import cn.axzo.nanopart.ess.api.utils.YesOrNo; +import org.springframework.stereotype.Repository; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + import cn.axzo.nanopart.ess.server.entity.EssLog; import cn.axzo.nanopart.ess.server.mapper.EssLogMapper; import cn.axzo.nanopart.ess.server.utils.BizAssertions; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.google.common.base.Throwables; -import org.springframework.stereotype.Repository; /** * @author yanglin @@ -27,10 +27,7 @@ public class EssLogDao extends ServiceImpl { EssLog log = new EssLog(); log.setContext(context); log.setSubject(String.valueOf(subject)); - if (exception != null) { - log.setIsError(YesOrNo.YES); - log.addLogContent("exception", Throwables.getStackTraceAsString(exception)); - } + log.setError(exception); if (logContents != null && logContents.length > 0) { BizAssertions.assertTrue(logContents.length % 2 == 0, "logContents must be even"); for (int i = 0; i < logContents.length; i += 2) { diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssLog.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssLog.java index d253a1ff..4a415383 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssLog.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssLog.java @@ -1,13 +1,15 @@ package cn.axzo.nanopart.ess.server.entity; -import cn.axzo.nanopart.ess.api.utils.YesOrNo; -import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.google.common.base.Throwables; + +import cn.axzo.nanopart.ess.api.utils.YesOrNo; +import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import lombok.Getter; import lombok.Setter; @@ -51,6 +53,13 @@ public class EssLog extends BaseEntity { logContent.put(key, value); } + public void setError(Exception exception) { + if (exception == null) + return; + setIsError(YesOrNo.YES); + addLogContent("exception", Throwables.getStackTraceAsString(exception)); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/ContractManager.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/ContractManager.java index 7379c383..48bdcb0b 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/ContractManager.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/ContractManager.java @@ -14,7 +14,6 @@ import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.essbasic.v20210526.models.ApproverItem; import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateFlowByFilesResponse; -import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.nanopart.ess.api.domain.contract.EssApproveDetail; import cn.axzo.nanopart.ess.api.enums.EssContractState; import cn.axzo.nanopart.ess.api.request.CreateContractByFileRequest; @@ -42,7 +41,7 @@ public class ContractManager { public static final String CONTRACT_ID = "contractId"; - private final OrgManager orgManager; + private final OrgManager orgManager; private final EssClient essClient; private final EssContractDao essContractDao; private final EssBroadcaster essBroadcaster; @@ -62,6 +61,7 @@ public class ContractManager { return contractSupport.createDuplicateContractByFileResponse(request); } try { + orgManager.ensureOrgAuthorized(contract.getCreatorOuId(), "合同创建单位还未认证电子签"); EssPerson superAdmin = orgManager.getSuperAdminOrThrow(request.getCreator().getOuId()); List essFileIds = essClient.uploadDocument(superAdmin, request.getByFile().getBase64Files()); ChannelCreateFlowByFilesResponse essResponse = essClient.createContractByFile(superAdmin, essFileIds, @@ -79,11 +79,8 @@ public class ContractManager { response.setEssRecipientIds(essRecipientIds); return response; } - catch (TencentCloudSDKException | ServiceException e) { - log.warn("创建合同失败", e); - if (contract != null) - essContractDao.removeById(contract.getId()); - throw fail("创建合同失败: {}", e.getMessage()); + catch (TencentCloudSDKException e) { + throw fail(e, "腾讯返回: {}", e.getMessage()); } } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssClient.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssClient.java index 600a33bb..69b6164f 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssClient.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssClient.java @@ -390,7 +390,7 @@ public class EssClient implements InitializingBean { return call(builder); } catch (TencentCloudSDKException e) { - throw fail(e, String.format("腾讯返回: %s", e.getMessage())); + throw fail(e, "腾讯返回: {}", e.getMessage()); } } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/OrgManager.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/OrgManager.java index b834315e..121ea601 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/OrgManager.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/OrgManager.java @@ -1,6 +1,13 @@ package cn.axzo.nanopart.ess.server.ess; +import static cn.axzo.nanopart.ess.server.utils.IdBuilder.idbuilder; + +import java.util.Optional; + +import org.springframework.dao.DuplicateKeyException; +import org.springframework.stereotype.Component; + import cn.axzo.nanopart.ess.api.domain.OrgPerson; import cn.axzo.nanopart.ess.api.enums.EssPersonState; import cn.axzo.nanopart.ess.api.enums.EssSealState; @@ -23,12 +30,6 @@ import cn.axzo.nanopart.ess.server.utils.BizAssertions; import cn.axzo.nanopart.ess.server.utils.BizTransactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.stereotype.Component; - -import java.util.Optional; - -import static cn.axzo.nanopart.ess.server.utils.IdBuilder.idbuilder; /** * @author yanglin @@ -92,13 +93,13 @@ public class OrgManager { public EssPerson getSuperAdminOrThrow(Long ouId) { EssPerson superAdmin = findSuperAdmin(ouId).orElse(null); - BizAssertions.assertNotNull(superAdmin, "单位还未认证"); + BizAssertions.assertNotNull(superAdmin, "单位还未认证, 单位id={}", ouId); return superAdmin; } Optional findSuperAdmin(Long ouId) { EssOrg org = essOrgDao.findOrNull(ouId); - BizAssertions.assertNotNull(org, "单位不存在"); + BizAssertions.assertNotNull(org, "单位不存在, 单位id={}", ouId); if (org.getSuperAdminPersonId() <= 0L) return Optional.empty(); return Optional.ofNullable(essPersonDao.findOrNull(ouId, org.getSuperAdminPersonId())); @@ -186,4 +187,8 @@ public class OrgManager { log.info("set person resigned: {}", person); } + public void ensureOrgAuthorized(Long ouId, String message) { + EssOrg org = essOrgDao.findOrNull(ouId); + BizAssertions.assertTrue(org != null && org.isAuthorized(), message); + } } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/CallbackController.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/CallbackController.java index 4c5b034f..2620ae06 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/CallbackController.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/CallbackController.java @@ -1,6 +1,27 @@ package cn.axzo.nanopart.ess.server.ess.controller; +import static cn.axzo.nanopart.ess.api.request.CallbackRequest.ContractStateChanged; +import static cn.axzo.nanopart.ess.api.request.CallbackRequest.OrgPersonJoin; +import static cn.axzo.nanopart.ess.api.request.CallbackRequest.SealOperate; +import static cn.axzo.nanopart.ess.server.utils.IdBuilder.idbuilder; +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.fastjson.JSONObject; + import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.maokai.api.vo.response.OrganizationalUnitVO; import cn.axzo.nanopart.ess.api.EssCallbackApi; @@ -27,28 +48,9 @@ import cn.axzo.nanopart.ess.server.ess.domain.OrgOpenId; import cn.axzo.nanopart.ess.server.ess.domain.PersonOpenId; import cn.axzo.nanopart.ess.server.ess.support.EssSupport; import cn.axzo.nanopart.ess.server.ess.support.OrgProfiles; -import com.alibaba.fastjson.JSONObject; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import static cn.axzo.nanopart.ess.api.request.CallbackRequest.ContractStateChanged; -import static cn.axzo.nanopart.ess.api.request.CallbackRequest.OrgPersonJoin; -import static cn.axzo.nanopart.ess.api.request.CallbackRequest.SealOperate; -import static cn.axzo.nanopart.ess.server.utils.IdBuilder.idbuilder; -import static java.util.stream.Collectors.toList; /** * @author yanglin @@ -202,15 +204,18 @@ class CallbackController implements EssCallbackApi, InitializingBean { public ApiResult callback(CallbackRequest request) { log.info("ess callback: {}", request); Object subject = null; + CallbackType callbackType = CallbackType.parse(request.getMsgType()).orElse(null); + CallbackHandler handler = callbackType == null ? null : handlers.get(callbackType); + EssLog essLog = new EssLog(); + essLog.addLogContent("interested", handler != null); try { - CallbackType callbackType = CallbackType.parse(request.getMsgType()).orElse(null); - CallbackHandler handler = callbackType == null ? null : handlers.get(callbackType); if (handler != null) { subject = transactionTemplate.execute(unused -> { try { return handler.handle(request); } catch (Exception e) { + essLog.setError(e); log.warn("callback failed", e); // wrap exception to make it throw to yoke throw new RuntimeException(e); @@ -223,22 +228,14 @@ class CallbackController implements EssCallbackApi, InitializingBean { return ApiResult.ok("success"); } finally { - saveRequest(request, subject); + String callbackTypeStr = callbackType == null ? "" : "[" + callbackType + "]"; + essLog.setContext(String.format("ess:callback:%s%s", request.getMsgType(), callbackTypeStr)); + essLog.setSubject(subject == null ? "" : String.valueOf(subject)); + essLog.addLogContent("request", request); + essLogDao.save(essLog); } } - private void saveRequest(CallbackRequest request, Object subject) { - EssLog essLog = new EssLog(); - CallbackType callbackType = CallbackType.parse(request.getMsgType()).orElse(null); - String callbackTypeStr = callbackType == null ? "" : "[" + callbackType + "]"; - essLog.setContext(String.format("ess:callback:%s%s", request.getMsgType(), callbackTypeStr)); - essLog.setSubject(""); - if (subject != null) - essLog.setSubject(String.valueOf(subject)); - essLog.addLogContent("request", request); - essLogDao.save(essLog); - } - private void registerHandler(CallbackType callbackType, CallbackHandler handler) { handlers.put(callbackType, handler); }