REQ-3201: 备份

This commit is contained in:
yanglin 2025-02-12 16:22:55 +08:00
parent 31f7110d6e
commit 4b543e71d0
7 changed files with 131 additions and 8 deletions

View File

@ -7,6 +7,7 @@ import cn.axzo.nanopart.ess.api.request.AddSealPersonsRequest;
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.GetContractSignUrlRequest;
import cn.axzo.nanopart.ess.api.request.GetEmbedWebUrlRequest;
import cn.axzo.nanopart.ess.api.request.GetPersonAuthStateRequest;
import cn.axzo.nanopart.ess.api.request.GetSealsRequest;
@ -16,6 +17,7 @@ import cn.axzo.nanopart.ess.api.request.RemoveSealPersonRequest;
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.GetContractSignUrlResponse;
import cn.axzo.nanopart.ess.api.response.GetEmbedWebUrlResponse;
import cn.axzo.nanopart.ess.api.response.GetPersonAuthStateResponse;
import cn.axzo.nanopart.ess.api.response.GetUnitAuthStatesResponse;
@ -102,11 +104,18 @@ public interface EssApi {
ApiResult<CreateContractResponse> createContract(
@RequestBody @Valid CreateContractRequest request);
/**
* 获取合同签署链接
*/
@PostMapping("api/ess/getContractSignUrl")
ApiResult<GetContractSignUrlResponse> getContractSignUrl(
@RequestBody @Valid GetContractSignUrlRequest request);
/**
* 下载已签署的合同PDF, 只有合同签署完成才能下载. 下载链接有效期为5分钟
*/
@PostMapping("api/ess/getSingedContractPdfUrl")
ApiResult<DownloadSingedContractPdfResponse> getSingedContractPdfUrl(
@PostMapping("api/ess/getContractPDFUrl")
ApiResult<DownloadSingedContractPdfResponse> getContractPDFUrl(
@RequestBody @Valid DownloadSingedContractPdfRequest request);
}

View File

@ -0,0 +1,43 @@
package cn.axzo.nanopart.ess.api.request;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author yanglin
*/
@Setter @Getter
public class GetContractSignUrlRequest {
/**
* 合同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 URLType urlType;
public enum URLType {
PC, WEIXIN_APP
}
}

View File

@ -0,0 +1,17 @@
package cn.axzo.nanopart.ess.api.response;
import lombok.Getter;
import lombok.Setter;
/**
* @author yanglin
*/
@Setter @Getter
public class GetContractSignUrlResponse {
/**
* 签署地址
*/
private String signUrl;
}

View File

@ -14,7 +14,7 @@ import java.util.Optional;
@Repository("essContractDao")
public class EssContractDao extends ServiceImpl<EssContractMapper, EssContract> {
public Optional<EssContract> findByEssContractId(String essContractId) {
public Optional<EssContract> find(String essContractId) {
return lambdaQuery()
.eq(EssContract::getEssContractId, essContractId)
.oneOpt();

View File

@ -23,7 +23,7 @@ class EssBroadcaster {
void fireContractStateChanged(String essContractId) {
EssContract contract = essContractDao
.findByEssContractId(essContractId).orElse(null);
.find(essContractId).orElse(null);
if (contract == null) return;
EssContractStateChangeMessage message = new EssContractStateChangeMessage();
message.setContract(BeanMapper.copyBean(contract, EssContractInfo.class));

View File

@ -28,12 +28,16 @@ import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateEmbedWebUrlReq
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateEmbedWebUrlResponse;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateFlowByFilesRequest;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateFlowByFilesResponse;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateOrganizationBatchSignUrlRequest;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateOrganizationBatchSignUrlResponse;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelCreateSealPolicyRequest;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelDeleteSealPoliciesRequest;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelDescribeEmployeesRequest;
import com.tencentcloudapi.essbasic.v20210526.models.ChannelDescribeEmployeesResponse;
import com.tencentcloudapi.essbasic.v20210526.models.CreateConsoleLoginUrlRequest;
import com.tencentcloudapi.essbasic.v20210526.models.CreateConsoleLoginUrlResponse;
import com.tencentcloudapi.essbasic.v20210526.models.CreateSignUrlsRequest;
import com.tencentcloudapi.essbasic.v20210526.models.CreateSignUrlsResponse;
import com.tencentcloudapi.essbasic.v20210526.models.DescribeResourceUrlsByFlowsRequest;
import com.tencentcloudapi.essbasic.v20210526.models.DescribeResourceUrlsByFlowsResponse;
import com.tencentcloudapi.essbasic.v20210526.models.FlowApproverInfo;
@ -210,7 +214,7 @@ public class EssClient implements InitializingBean {
return response.getFlowId();
}
public String getSingedContractPdfUrl(EssPerson superAdmin, String essContractId) {
public String getContractPDFUrl(EssPerson superAdmin, String essContractId) {
DescribeResourceUrlsByFlowsRequest request = new DescribeResourceUrlsByFlowsRequest();
request.setAgent(agent(superAdmin));
request.setFlowIds(new String[]{essContractId});
@ -222,6 +226,32 @@ public class EssClient implements InitializingBean {
return response.getFlowResourceUrlInfos()[0].getResourceUrlInfos()[0].getUrl();
}
public String getContractSignUrlPC(EssPerson superAdmin, String essContractId, EssPerson signPerson) {
ChannelCreateOrganizationBatchSignUrlRequest request = new ChannelCreateOrganizationBatchSignUrlRequest();
request.setAgent(agent(superAdmin));
request.setFlowIds(new String[]{essContractId});
request.setOpenId(EssPersonOpenId.create(signPerson.getOuId(), signPerson.getPersonId()).toOpenId());
ChannelCreateOrganizationBatchSignUrlResponse response = exec(invocation()
.context("ChannelCreateOrganizationBatchSignUrl")
.subject(essContractId)
.request(request)
.func(() -> ess.ChannelCreateOrganizationBatchSignUrl(request)));
return response.getSignUrl();
}
public String getContractSignUrlWeixinApp(EssPerson superAdmin, String essContractId, EssPerson signPerson) {
CreateSignUrlsRequest request = new CreateSignUrlsRequest();
request.setAgent(agent(superAdmin));
request.setFlowIds(new String[]{essContractId});
request.setOpenId(EssPersonOpenId.create(signPerson.getOuId(), signPerson.getPersonId()).toOpenId());
CreateSignUrlsResponse response = exec(invocation()
.context("CreateSignUrls")
.subject(essContractId)
.request(request)
.func(() -> ess.CreateSignUrls(request)));
return response.getSignUrlInfos()[0].getSignUrl();
}
public ChannelDescribeEmployeesResponse getUsers(EssPerson superAdmin, EssOrg org, Long offset) {
ChannelDescribeEmployeesRequest request = new ChannelDescribeEmployeesRequest();
request.setAgent(agent(superAdmin));

View File

@ -9,6 +9,7 @@ import cn.axzo.nanopart.ess.api.request.AddSealPersonsRequest;
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.GetContractSignUrlRequest;
import cn.axzo.nanopart.ess.api.request.GetEmbedWebUrlRequest;
import cn.axzo.nanopart.ess.api.request.GetPersonAuthStateRequest;
import cn.axzo.nanopart.ess.api.request.GetSealsRequest;
@ -19,10 +20,12 @@ import cn.axzo.nanopart.ess.api.request.SealAndPersonRequest;
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.GetContractSignUrlResponse;
import cn.axzo.nanopart.ess.api.response.GetEmbedWebUrlResponse;
import cn.axzo.nanopart.ess.api.response.GetPersonAuthStateResponse;
import cn.axzo.nanopart.ess.api.response.GetUnitAuthStatesResponse;
import cn.axzo.nanopart.ess.server.dao.EssContractDao;
import cn.axzo.nanopart.ess.server.dao.EssPersonDao;
import cn.axzo.nanopart.ess.server.dao.EssSealDao;
import cn.axzo.nanopart.ess.server.dao.EssSealPersonDao;
import cn.axzo.nanopart.ess.server.entity.EssContract;
@ -57,6 +60,7 @@ class EssController implements EssApi {
private final EssSealDao essSealDao;
private final EssSealPersonDao essSealPersonDao;
private final EssContractDao essContractDao;
private final EssPersonDao essPersonDao;
@Override
public ApiResult<List<GetUnitAuthStatesResponse>>
@ -151,17 +155,37 @@ class EssController implements EssApi {
return ApiResult.ok(response);
}
@Override
public ApiResult<GetContractSignUrlResponse> getContractSignUrl(GetContractSignUrlRequest request) {
EssContract contract = essContractDao.find(request.getEssContractId()).orElse(null);
BizAssertions.assertNotNull(contract, "合同不存在: {}", request.getEssContractId());
EssPerson signPerson = essPersonDao.find(request.getOuId(), request.getPersonId(), false).orElse(null);
BizAssertions.assertNotNull(signPerson, "当前签署人员未加入单位, 无法签署");
//noinspection DataFlowIssue
EssPerson superAdmin = orgManager.getSuperAdminOrThrow(contract.getCreatorOuId());
String signUrl = "";
if (request.getUrlType() == GetContractSignUrlRequest.URLType.WEIXIN_APP)
//noinspection DataFlowIssue
signUrl = essClient.getContractSignUrlWeixinApp(superAdmin, request.getEssContractId(), signPerson);
else if (request.getUrlType() == GetContractSignUrlRequest.URLType.PC)
//noinspection DataFlowIssue
signUrl = essClient.getContractSignUrlPC(superAdmin, request.getEssContractId(), signPerson);
GetContractSignUrlResponse response = new GetContractSignUrlResponse();
response.setSignUrl(signUrl);
return ApiResult.ok(response);
}
@SuppressWarnings("DataFlowIssue")
@Override
public ApiResult<DownloadSingedContractPdfResponse>
getSingedContractPdfUrl(DownloadSingedContractPdfRequest request) {
getContractPDFUrl(DownloadSingedContractPdfRequest request) {
EssContract contract = essContractDao
.findByEssContractId(request.getEssContractId()).orElse(null);
.find(request.getEssContractId()).orElse(null);
BizAssertions.assertNotNull(contract, "合同不存在: {}", request.getEssContractId());
BizAssertions.assertTrue(contract.getState() == EssContractState.ALL, "合同未签署完成, 无法下载");
EssPerson superAdmin = orgManager.getSuperAdminOrThrow(contract.getCreatorOuId());
DownloadSingedContractPdfResponse response = new DownloadSingedContractPdfResponse();
response.setPdfUrl(essClient.getSingedContractPdfUrl(superAdmin, contract.getEssContractId()));
response.setPdfUrl(essClient.getContractPDFUrl(superAdmin, contract.getEssContractId()));
return ApiResult.ok(response);
}