diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/EssApi.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/EssApi.java index cca8ef17..5ee8dc93 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/EssApi.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/EssApi.java @@ -4,12 +4,12 @@ import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.ess.api.domain.EssOrgAndSealInfo; import cn.axzo.nanopart.ess.api.request.AddSealAuthorizationRequest; import cn.axzo.nanopart.ess.api.request.AddSealPersonsRequest; +import cn.axzo.nanopart.ess.api.request.AssignWeixinAppUrlByOrgRequest; import cn.axzo.nanopart.ess.api.request.CreateConsoleLoginUrlRequest; import cn.axzo.nanopart.ess.api.request.CreateContractRequest; import cn.axzo.nanopart.ess.api.request.DownloadSingedContractPdfRequest; import cn.axzo.nanopart.ess.api.request.GetContractDetailByBizCodeRequest; import cn.axzo.nanopart.ess.api.request.GetContractDetailByContractIdRequest; -import cn.axzo.nanopart.ess.api.request.GetContractSignUrlRequest; import cn.axzo.nanopart.ess.api.request.GetEmbedWebUrlRequest; import cn.axzo.nanopart.ess.api.request.GetOrgAuthStatesRequest; import cn.axzo.nanopart.ess.api.request.GetPersonAuthStateRequest; @@ -17,12 +17,12 @@ import cn.axzo.nanopart.ess.api.request.GetSealsRequest; import cn.axzo.nanopart.ess.api.request.RemoveSealAuthorizationRequest; import cn.axzo.nanopart.ess.api.request.RemoveSealPersonRequest; import cn.axzo.nanopart.ess.api.request.RevokeContractRequest; +import cn.axzo.nanopart.ess.api.response.AssignWeixinAppUrlByOrgResponse; import cn.axzo.nanopart.ess.api.response.CreateConsoleLoginUrlResponse; import cn.axzo.nanopart.ess.api.response.CreateContractResponse; import cn.axzo.nanopart.ess.api.response.DownloadSingedContractPdfResponse; import cn.axzo.nanopart.ess.api.response.GetContractDetailByBizCodeResponse; import cn.axzo.nanopart.ess.api.response.GetContractDetailByContractIdResponse; -import cn.axzo.nanopart.ess.api.response.GetContractSignUrlResponse; import cn.axzo.nanopart.ess.api.response.GetEmbedWebUrlResponse; import cn.axzo.nanopart.ess.api.response.GetOrgAuthStatesResponse; import cn.axzo.nanopart.ess.api.response.GetPersonAuthStateResponse; @@ -110,11 +110,11 @@ public interface EssApi { @RequestBody @Valid CreateContractRequest request); /** - * 获取合同签署链接, 有效期为5分钟 + * 根据单位分配微信小程序签署链接, 有效期为5分钟 */ - @PostMapping("api/ess/getContractSignUrl") - ApiResult getContractSignUrl( - @RequestBody @Valid GetContractSignUrlRequest request); + @PostMapping("api/ess/assignWeixinAppUrlByOrg") + ApiResult assignWeixinAppUrlByOrg( + @RequestBody @Valid AssignWeixinAppUrlByOrgRequest request); /** * 下载已签署的合同PDF. 下载链接有效期为5分钟 diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/enums/SignUrlType.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/enums/SignUrlType.java new file mode 100644 index 00000000..23f41a9f --- /dev/null +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/enums/SignUrlType.java @@ -0,0 +1,8 @@ +package cn.axzo.nanopart.ess.api.enums; + +/** + * @author yanglin + */ +public enum SignUrlType { + PC, WEIXIN_APP +} diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/AssignWeixinAppUrlByOrgRequest.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/AssignWeixinAppUrlByOrgRequest.java new file mode 100644 index 00000000..9f6318e4 --- /dev/null +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/AssignWeixinAppUrlByOrgRequest.java @@ -0,0 +1,48 @@ +package cn.axzo.nanopart.ess.api.request; + +import cn.axzo.nanopart.ess.api.domain.OrgPerson; +import cn.axzo.nanopart.ess.api.enums.SignUrlType; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author yanglin + */ +@Setter +@Getter +public class AssignWeixinAppUrlByOrgRequest implements OrgPerson { + + /** + * 合同id + */ + @NotBlank(message = "essContractId不能为空") + private String essContractId; + + /** + * 单位id + */ + @NotNull(message = "ouId不能为空") + private Long ouId; + + /** + * 人员id, 需要有印章权限 + */ + @NotNull(message = "personId不能为空") + private Long personId; + + /** + * PC: 电脑端, WEIXIN_APP: 小程序 + */ + @NotNull(message = "urlType不能为空") + private SignUrlType urlType; + + /** + * 签署方编号, 可以使用该编号指定动态签署方的信息 + * 该编号在创建合同的时候会返回 + */ + private String recipientId; + +} \ No newline at end of file diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/GetContractSignUrlRequest.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/GetContractSignUrlRequest.java index 704654fb..be2c3f6d 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/GetContractSignUrlRequest.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/request/GetContractSignUrlRequest.java @@ -1,6 +1,7 @@ package cn.axzo.nanopart.ess.api.request; import cn.axzo.nanopart.ess.api.domain.OrgPerson; +import cn.axzo.nanopart.ess.api.enums.SignUrlType; import lombok.Getter; import lombok.Setter; @@ -36,16 +37,6 @@ public class GetContractSignUrlRequest implements OrgPerson { * PC: 电脑端, WEIXIN_APP: 小程序 */ @NotNull(message = "urlType不能为空") - private URLType urlType; - - /** - * 签署方编号, 创建动态签署人合同时返回的签署方编号, 动态签署人的合同必传 - * 也可以不指定,将动态分配创建合同时可用(空闲)的essRecipientId - */ - private String essRecipientId; - - public enum URLType { - PC, WEIXIN_APP - } + private SignUrlType urlType; } \ No newline at end of file diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/AssignWeixinAppUrlByOrgResponse.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/AssignWeixinAppUrlByOrgResponse.java new file mode 100644 index 00000000..261ee5f3 --- /dev/null +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/AssignWeixinAppUrlByOrgResponse.java @@ -0,0 +1,20 @@ +package cn.axzo.nanopart.ess.api.response; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class AssignWeixinAppUrlByOrgResponse { + + /** + * 有效期为5分钟. + * pc: 扫码地址 + * app: 微信小程序地址 + */ + private String url; + +} diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/CreateContractResponse.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/CreateContractResponse.java index 9fc441cb..60dd2f04 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/CreateContractResponse.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/CreateContractResponse.java @@ -17,7 +17,7 @@ public class CreateContractResponse { private String essContractId; /** - * 签署方编号, 可以使用该编号指定动态签署方的信息 + * 签署方编号, 可以使用该编号指定动态签署方的信息, 顺序和请求中的approvers一致 */ private List essRecipientIds; diff --git a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/GetContractSignUrlResponse.java b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/GetContractSignUrlResponse.java index 6c46a4d4..53ff8dd6 100644 --- a/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/GetContractSignUrlResponse.java +++ b/ess/ess-api/src/main/java/cn/axzo/nanopart/ess/api/response/GetContractSignUrlResponse.java @@ -10,8 +10,10 @@ import lombok.Setter; public class GetContractSignUrlResponse { /** - * 签署地址, 有效期为5分钟 + * 签署地址或二维码地址, 有效期为5分钟 + * 如果是PC端, 才是二维码地址 + * 如果是小程序端, 则是小程序地址 */ - private String signUrl; + private String signOrQrUrl; } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssContract.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssContract.java index 3abe603c..1d356808 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssContract.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/EssContract.java @@ -6,6 +6,8 @@ import cn.axzo.nanopart.ess.api.domain.contract.Approver; import cn.axzo.nanopart.ess.api.domain.contract.EssApproveDetail; import cn.axzo.nanopart.ess.api.enums.EssContractState; import cn.axzo.nanopart.ess.api.utils.YesOrNo; +import cn.axzo.nanopart.ess.server.entity.domain.ApproverAssignType; +import cn.axzo.nanopart.ess.server.entity.domain.AssignedApprovers; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableField; @@ -81,7 +83,7 @@ public class EssContract extends BaseEntity { * 动态签署人信息 */ @TableField(typeHandler = ApproverListHandler.class) - private List assignedApprovers; + private AssignedApprovers assignedApprovers; /** * 签署方的签署情况 @@ -115,6 +117,10 @@ public class EssContract extends BaseEntity { .findFirst(); } + public ApproverAssignType getAssignType() { + return assignedApprovers == null ? null : assignedApprovers.getAssignType(); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/ApproverAssignType.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/ApproverAssignType.java new file mode 100644 index 00000000..04454d90 --- /dev/null +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/ApproverAssignType.java @@ -0,0 +1,8 @@ +package cn.axzo.nanopart.ess.server.entity.domain; + +/** + * @author yanglin + */ +public enum ApproverAssignType { + ORG_WEIXIN_APP +} \ No newline at end of file diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/AssignedApprovers.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/AssignedApprovers.java new file mode 100644 index 00000000..9983d3f7 --- /dev/null +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/AssignedApprovers.java @@ -0,0 +1,17 @@ +package cn.axzo.nanopart.ess.server.entity.domain; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class AssignedApprovers { + + private ApproverAssignType assignType; + + private SignByOrg signByOrg; + +} \ No newline at end of file diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/OrgRecipientId.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/OrgRecipientId.java new file mode 100644 index 00000000..67464de3 --- /dev/null +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/OrgRecipientId.java @@ -0,0 +1,14 @@ +package cn.axzo.nanopart.ess.server.entity.domain; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class OrgRecipientId { + private Long ouId; + private String recipientId; +} \ No newline at end of file diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/SignByOrg.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/SignByOrg.java new file mode 100644 index 00000000..48315f0e --- /dev/null +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/entity/domain/SignByOrg.java @@ -0,0 +1,64 @@ +package cn.axzo.nanopart.ess.server.entity.domain; + +import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.nanopart.ess.api.domain.contract.Approver; +import cn.axzo.nanopart.ess.server.utils.BizAssertions; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author yanglin + */ +public class SignByOrg { + + private final List recipientIds = new ArrayList<>(); + + public String assign(List approvers, Long ouId, @Nullable String recipientId) { + if (recipientId != null) { + OrgRecipientId saved = findByRecipientId(recipientId).orElse(null); + if (saved != null) + BizAssertions.assertTrue(saved.getOuId().equals(ouId), "签署编号已被其它单位占用"); + else + addRecipientId(ouId, recipientId); + return recipientId; + } else { + OrgRecipientId assigned = findByOuId(ouId).orElse(null); + if (assigned != null) + return assigned.getRecipientId(); + for (Approver approver : approvers) { + if (isRecipientIdUsed(approver.getEssRecipientId())) + continue; + addRecipientId(ouId, approver.getEssRecipientId()); + return approver.getEssRecipientId(); + } + throw new ServiceException("签署编号已经用完, 无法将指定新的单位"); + } + } + + public boolean isRecipientIdUsed(String recipientId) { + return findByRecipientId(recipientId).isPresent(); + } + + public Optional findByRecipientId(String recipientId) { + return recipientIds.stream() + .filter(r -> r.getRecipientId().equals(recipientId)) + .findFirst(); + } + + public Optional findByOuId(Long ouId) { + return recipientIds.stream() + .filter(id -> id.getOuId().equals(ouId)) + .findFirst(); + } + + public void addRecipientId(Long ouId, String recipientId) { + recipientIds.add(new OrgRecipientId() {{ + setOuId(ouId); + setRecipientId(recipientId); + }}); + } + +} \ No newline at end of file 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 133792ec..422f6170 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 @@ -2,9 +2,7 @@ package cn.axzo.nanopart.ess.server.ess; import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.exception.ServiceException; -import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; import cn.axzo.nanopart.ess.api.domain.OrgPerson; -import cn.axzo.nanopart.ess.api.domain.OrgPersons; import cn.axzo.nanopart.ess.api.domain.contract.Approver; import cn.axzo.nanopart.ess.api.domain.contract.EssApproveDetail; import cn.axzo.nanopart.ess.api.domain.contract.OrgPersonInfo; @@ -24,6 +22,7 @@ import cn.axzo.nanopart.ess.server.entity.EssOrg; import cn.axzo.nanopart.ess.server.entity.EssPerson; import cn.axzo.nanopart.ess.server.entity.EssSeal; import cn.axzo.nanopart.ess.server.entity.EssSealPerson; +import cn.axzo.nanopart.ess.server.entity.domain.AssignedApprovers; import cn.axzo.nanopart.ess.server.ess.domain.JsonObjectAsString; import cn.axzo.nanopart.ess.server.ess.domain.SealPersons; import cn.axzo.nanopart.ess.server.ess.support.EssSupport; @@ -165,28 +164,15 @@ public class ContractManager { } @Transactional - public void tryCreateDynamicApprover(String essContractId, - OrgPerson person, - String essRecipientId) { + public String assignContractRecipientId(String essContractId, Long ouId, String essRecipientId) { EssContract contract = essContractDao.find(essContractId, true).orElse(null); BizAssertions.assertNotNull(contract, "合同不存在: {}", essContractId); //noinspection DataFlowIssue - OrgPersons approvers = OrgPersons.wrap(contract.getAssignedApprovers()); - Approver approver = approvers.findByPerson(person).orElse(null); - // 已经指定过了 - if (approver != null) - return; - Approver otherApprover = approvers.findByOrgId(person.getOuId()).orElse(null); - // 该单位下已经指定过签署人了 - if (otherApprover != null) { - String message = "该合同已经由其它人签署, 同单位下无法再指定新的签署人"; - PersonProfileDto createdPerson = essSupport.findPersonProfile(otherApprover.getPersonId()).orElse(null); - if (createdPerson != null) - message = String.format("该合同已经由其 %s 签署, 同单位下无法再指定新的签署人", createdPerson.getRealName()); - throw new ServiceException(message); - } + AssignedApprovers assignedApprovers = contract.getAssignedApprovers(); + String recipientId = assignedApprovers.findRecipientId(ouId).orElse(null); + if (recipientId != null) return recipientId; EssPerson contractCreator = getContractCreatorOrThrow(contract); - Approver assignedApprover = assignApprover(contract, person, essRecipientId); + Approver assignedApprover = assignRecipientId(contract, person, essRecipientId); checkApproverSeals(assignedApprover); essClient.assignApprover(contract.getEssContractId(), contractCreator, person, assignedApprover.getEssRecipientId()); @@ -213,7 +199,8 @@ public class ContractManager { BizAssertions.assertTrue(found, "签署人员没有指定类型的印章"); } - private Approver assignApprover(EssContract contract, OrgPerson person, String essRecipientId) { + private Approver assignRecipientId(EssContract contract, OrgPerson person, String essRecipientId) { + contract.getAssignedApprovers().isRecipientIdUsed(essRecipientId); Function isRecipientIdUsed = recipientId -> contract.getAssignedApprovers().stream() .map(Approver::getEssRecipientId) 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 cae2f424..75d6e3a9 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 @@ -62,6 +62,7 @@ import com.tencentcloudapi.essbasic.v20210526.models.UserInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @@ -335,17 +336,21 @@ public class EssClient implements InitializingBean { return response.getSignUrl(); } - public String getContractSignUrlWeixinApp(String essContractId, EssPerson signPerson) { + public CreateSignUrlsResponse getContractSignUrlWeixinApp( + String essContractId, EssPerson signPerson, String recipientId) { CreateSignUrlsRequest request = new CreateSignUrlsRequest(); request.setAgent(agent(signPerson)); request.setFlowIds(new String[]{essContractId}); request.setOpenId(PersonOpenId.create(signPerson).toOpenId()); - CreateSignUrlsResponse response = exec(func() + if (StringUtils.isNotBlank(recipientId)) { + request.setRecipientIds(new String[]{recipientId}); + request.setGenerateType("RECIPIENT"); + } + return exec(func() .context("CreateSignUrls") .subject(essContractId) .request(request) .command(() -> manage.CreateSignUrls(request))); - return response.getSignUrlInfos()[0].getSignUrl(); } public void setEmployeeResigned(EssPerson superAdmin, List employees) { diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssService.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssService.java index ef1c252d..6e65408b 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssService.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/EssService.java @@ -1,10 +1,10 @@ package cn.axzo.nanopart.ess.server.ess; -import cn.axzo.nanopart.ess.api.domain.contract.Approver; import cn.axzo.nanopart.ess.api.enums.EssEmbedType.EssContext; +import cn.axzo.nanopart.ess.api.enums.SignUrlType; import cn.axzo.nanopart.ess.api.request.AddSealAuthorizationRequest; +import cn.axzo.nanopart.ess.api.request.AssignWeixinAppUrlByOrgRequest; import cn.axzo.nanopart.ess.api.request.CreateConsoleLoginUrlRequest; -import cn.axzo.nanopart.ess.api.request.GetContractSignUrlRequest; import cn.axzo.nanopart.ess.api.request.GetEmbedWebUrlRequest; import cn.axzo.nanopart.ess.api.request.RemoveSealAuthorizationRequest; import cn.axzo.nanopart.ess.api.request.SealAndPersonRequest; @@ -16,14 +16,18 @@ import cn.axzo.nanopart.ess.server.entity.EssContract; import cn.axzo.nanopart.ess.server.entity.EssPerson; import cn.axzo.nanopart.ess.server.entity.EssSeal; import cn.axzo.nanopart.ess.server.entity.EssSealPerson; +import cn.axzo.nanopart.ess.server.entity.domain.ApproverAssignType; import cn.axzo.nanopart.ess.server.ess.domain.OrgAndPerson; import cn.axzo.nanopart.ess.server.ess.domain.SealAndPerson; import cn.axzo.nanopart.ess.server.ess.support.EssProps; import cn.axzo.nanopart.ess.server.ess.support.OssService; import cn.axzo.nanopart.ess.server.utils.BizAssertions; +import com.tencentcloudapi.essbasic.v20210526.models.CreateSignUrlsResponse; +import com.tencentcloudapi.essbasic.v20210526.models.SignUrlInfo; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; /** * @author yanglin @@ -41,6 +45,7 @@ public class EssService { private final EssPersonDao essPersonDao; private final EssProps essProps; private final OssService ossService; + private final TransactionTemplate transactionTemplate; public String createConsoleLoginUrl(CreateConsoleLoginUrlRequest request) { OrgAndPerson orgAndPerson = orgManager.createConsoleLoginUrl(request); @@ -98,25 +103,27 @@ public class EssService { return new SealAndPerson(seal, sealPerson); } - public String getContractSignUrl(GetContractSignUrlRequest request) { - EssContract contract = essContractDao.getOrThrow(request.getEssContractId()); + public String assignWeixinAppUrlByOrg(AssignWeixinAppUrlByOrgRequest request) { EssPerson signPerson = essPersonDao.findOrNull(request); BizAssertions.assertNotNull(signPerson, "当前签署人员未加入单位, 无法签署"); - if (contract.getIsDynamicApprover().isYes()) { - contractManager.tryCreateDynamicApprover( - contract.getEssContractId(), request, request.getEssRecipientId()); - } else { - Approver approver = contract.findPreciseApprover(request).orElse(null); - BizAssertions.assertNotNull(approver, "当前签署人员不在合同的签署人员列表中, 无法签署"); + String recipientId = transactionTemplate.execute(unused -> { + EssContract contract = essContractDao.find(request.getEssContractId(), true).orElse(null); + BizAssertions.assertNotNull(contract, "找不到合同信息, essContractId={}", request.getEssContractId()); //noinspection DataFlowIssue - contractManager.checkApproverSeals(approver); - } - String signUrl = ""; - if (request.getUrlType() == GetContractSignUrlRequest.URLType.WEIXIN_APP) - signUrl = essClient.getContractSignUrlWeixinApp(request.getEssContractId(), signPerson); - else if (request.getUrlType() == GetContractSignUrlRequest.URLType.PC) - signUrl = essClient.getContractSignUrlPC(request.getEssContractId(), signPerson); - return signUrl; + BizAssertions.assertTrue(contract.getIsDynamicApprover().isYes(), "合同不支持动态签署"); + BizAssertions.assertEquals(ApproverAssignType.ORG_WEIXIN_APP, contract.getAssignType(), "签署方式不正确"); + String assignedRecipientId = contract.getAssignedApprovers() + .getSignByOrg() + .assign(contract.getApprovers(), request.getOuId(), request.getRecipientId()); + essContractDao.updateAssignedApprovers(contract); + return assignedRecipientId; + }); + CreateSignUrlsResponse essResponse = essClient + .getContractSignUrlWeixinApp(request.getEssContractId(), signPerson, recipientId); + SignUrlInfo signUrlInfo = essResponse.getSignUrlInfos()[0]; + return request.getUrlType() == SignUrlType.PC + ? signUrlInfo.getSignQrcodeUrl() + : signUrlInfo.getSignUrl(); } public String getContractPDFUrl(String essContractId) { @@ -134,5 +141,4 @@ public class EssService { EssPerson creator = orgManager.getSuperAdminOrThrow(contract.getCreatorOuId()); return essClient.getContractPDFUrl(creator, contract.getEssContractId()); } - } \ No newline at end of file diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/ApiController.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/ApiController.java index 529e6018..c415b29b 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/ApiController.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/controller/ApiController.java @@ -7,12 +7,12 @@ import cn.axzo.nanopart.ess.api.domain.EssOrgAndSealInfo; import cn.axzo.nanopart.ess.api.domain.contract.EssContractInfo; import cn.axzo.nanopart.ess.api.request.AddSealAuthorizationRequest; import cn.axzo.nanopart.ess.api.request.AddSealPersonsRequest; +import cn.axzo.nanopart.ess.api.request.AssignWeixinAppUrlByOrgRequest; import cn.axzo.nanopart.ess.api.request.CreateConsoleLoginUrlRequest; import cn.axzo.nanopart.ess.api.request.CreateContractRequest; import cn.axzo.nanopart.ess.api.request.DownloadSingedContractPdfRequest; import cn.axzo.nanopart.ess.api.request.GetContractDetailByBizCodeRequest; import cn.axzo.nanopart.ess.api.request.GetContractDetailByContractIdRequest; -import cn.axzo.nanopart.ess.api.request.GetContractSignUrlRequest; import cn.axzo.nanopart.ess.api.request.GetEmbedWebUrlRequest; import cn.axzo.nanopart.ess.api.request.GetOrgAuthStatesRequest; import cn.axzo.nanopart.ess.api.request.GetPersonAuthStateRequest; @@ -20,12 +20,12 @@ import cn.axzo.nanopart.ess.api.request.GetSealsRequest; import cn.axzo.nanopart.ess.api.request.RemoveSealAuthorizationRequest; import cn.axzo.nanopart.ess.api.request.RemoveSealPersonRequest; import cn.axzo.nanopart.ess.api.request.RevokeContractRequest; +import cn.axzo.nanopart.ess.api.response.AssignWeixinAppUrlByOrgResponse; import cn.axzo.nanopart.ess.api.response.CreateConsoleLoginUrlResponse; import cn.axzo.nanopart.ess.api.response.CreateContractResponse; import cn.axzo.nanopart.ess.api.response.DownloadSingedContractPdfResponse; import cn.axzo.nanopart.ess.api.response.GetContractDetailByBizCodeResponse; import cn.axzo.nanopart.ess.api.response.GetContractDetailByContractIdResponse; -import cn.axzo.nanopart.ess.api.response.GetContractSignUrlResponse; import cn.axzo.nanopart.ess.api.response.GetEmbedWebUrlResponse; import cn.axzo.nanopart.ess.api.response.GetOrgAuthStatesResponse; import cn.axzo.nanopart.ess.api.response.GetPersonAuthStateResponse; @@ -114,9 +114,9 @@ class ApiController implements EssApi { } @Override - public ApiResult getContractSignUrl(GetContractSignUrlRequest request) { - GetContractSignUrlResponse response = new GetContractSignUrlResponse(); - response.setSignUrl(essService.getContractSignUrl(request)); + public ApiResult assignWeixinAppUrlByOrg(AssignWeixinAppUrlByOrgRequest request) { + AssignWeixinAppUrlByOrgResponse response = new AssignWeixinAppUrlByOrgResponse(); + response.setUrl(essService.assignWeixinAppUrlByOrg(request)); return ApiResult.ok(response); } diff --git a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/support/EssSupport.java b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/support/EssSupport.java index bdfe6579..9973cab3 100644 --- a/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/support/EssSupport.java +++ b/ess/ess-server/src/main/java/cn/axzo/nanopart/ess/server/ess/support/EssSupport.java @@ -10,9 +10,12 @@ import cn.axzo.nanopart.ess.api.enums.EssPersonState; import cn.axzo.nanopart.ess.api.request.CreateConsoleLoginUrlRequest; import cn.axzo.nanopart.ess.api.request.CreateContractRequest; import cn.axzo.nanopart.ess.api.utils.YesOrNo; +import cn.axzo.nanopart.ess.server.entity.domain.ApproverAssignType; +import cn.axzo.nanopart.ess.server.entity.domain.AssignedApprovers; import cn.axzo.nanopart.ess.server.entity.EssContract; import cn.axzo.nanopart.ess.server.entity.EssOrg; import cn.axzo.nanopart.ess.server.entity.EssPerson; +import cn.axzo.nanopart.ess.server.entity.domain.SignByOrg; import cn.axzo.nanopart.ess.server.utils.BizAssertions; import com.tencentcloudapi.essbasic.v20210526.models.ApproverItem; import lombok.RequiredArgsConstructor; @@ -107,8 +110,12 @@ public class EssSupport { contract.setIsDynamicApprover(YesOrNo.valueOf( request.getByFile().isDynamicApprover())); contract.setApprovers(request.getByFile().getApprovers()); - contract.setAssignedApprovers(Collections.emptyList()); + AssignedApprovers assignedApprovers = new AssignedApprovers(); + assignedApprovers.setAssignType(ApproverAssignType.ORG_WEIXIN_APP); + assignedApprovers.setSignByOrg(new SignByOrg()); + contract.setAssignedApprovers(assignedApprovers); contract.setApproveDetails(Collections.emptyList()); + contract.setRecordExt(new EssContract.RecordExt()); return contract; }