Sfoglia il codice sorgente

feat(app): 电子签名服务功能增强

- 优化个人和企业用户签署流程
- 添加实名认证信息同步
- 修改合同模板上传逻辑
- 完善签署URL获取方法
SheepHy 4 giorni fa
parent
commit
4a3a185a13

+ 13 - 13
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/esign/sign/SignDemo.java

@@ -2,7 +2,6 @@ package org.jeecg.modules.app.esign.sign;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
-import org.jeecg.modules.app.dto.SignFlowDTO;
 import org.jeecg.modules.app.esign.comm.EsignHttpHelper;
 import org.jeecg.modules.app.esign.comm.EsignHttpResponse;
 import org.jeecg.modules.app.esign.constant.EsignDemoConfig;
@@ -30,13 +29,13 @@ public class SignDemo {
 //        System.err.println("流程id:"+signFlowId);
 
         //获取合同文件签署链接
-        EsignHttpResponse signUrl = signUrl(signFlowId);
-        JsonObject signUrlJsonObject = gson.fromJson(signUrl.getBody(), JsonObject.class);
-        JsonObject signUrlData = signUrlJsonObject.getAsJsonObject("data");
-        String shortUrl = signUrlData.get("shortUrl").getAsString();
-        String url = signUrlData.get("url").getAsString();
-        System.out.println("签署长链接:" +shortUrl);
-        System.out.println("签署短链接:"+url);
+//        EsignHttpResponse signUrl = signUrl(signFlowId);
+//        JsonObject signUrlJsonObject = gson.fromJson(signUrl.getBody(), JsonObject.class);
+//        JsonObject signUrlData = signUrlJsonObject.getAsJsonObject("data");
+//        String shortUrl = signUrlData.get("shortUrl").getAsString();
+//        String url = signUrlData.get("url").getAsString();
+//        System.out.println("签署长链接:" +shortUrl);
+//        System.out.println("签署短链接:"+url);
 
         //获取批量签页面链接(多流程)
         EsignHttpResponse batchSignUrl = batchSignUrl();
@@ -616,16 +615,16 @@ public class SignDemo {
      * @return
      * @throws EsignDemoException
      */
-    public static EsignHttpResponse signUrl(String signFlowId) throws EsignDemoException {
+    public static EsignHttpResponse signUrl(String signFlowId, String phone, String departName) throws EsignDemoException {
         String apiaddr = "/v3/sign-flow/" + signFlowId + "/sign-url";
         String jsonParm = "{\n" +
                 "    \"clientType\": \"ALL\",\n" +
                 "    \"needLogin\": true,\n" +
                 "    \"operator\": {\n" +
-                "        \"psnAccount\":\"181xxxxxx\"\n" +
+                "        \"psnAccount\":\""+phone+"\"\n" +
                 "    },\n" +
                 "    \"organization\": {\n" +
-                "        \"orgName\": \"**科技信息有限公司\"\n" +
+                "        \"orgName\": \""+departName+"\"\n" +
                 "    },\n" +
                 "    \"urlType\": 1\n" +
                 "}";
@@ -642,10 +641,11 @@ public class SignDemo {
      * @return
      * @throws EsignDemoException
      */
-    public static EsignHttpResponse createByFile(SignFlowDTO dto) throws EsignDemoException {
+    public static EsignHttpResponse createByFile(String dto) throws EsignDemoException {
         String apiaddr = "/v3/sign-flow/create-by-file";
         //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
-        String jsonParm = dto.toString();
+//        Gson gson = new Gson();
+        String jsonParm = dto;
         //请求方法
         EsignRequestType requestType = EsignRequestType.POST;
         //生成请求签名鉴权方式的Header

+ 180 - 38
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/ESignServiceImpl.java

@@ -12,7 +12,6 @@ import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.modules.app.dto.DocTemplateDTO;
 import org.jeecg.modules.app.dto.GetPsnAuthUrlDTO;
-import org.jeecg.modules.app.dto.SignFlowDTO;
 import org.jeecg.modules.app.esign.comm.EsignHttpResponse;
 import org.jeecg.modules.app.esign.exception.EsignDemoException;
 import org.jeecg.modules.app.esign.fileAndTemplate.FileDemo;
@@ -69,6 +68,10 @@ public class ESignServiceImpl implements IESignService {
         EsignHttpResponse getPsnIdentityInfo = getPsnIdentityInfo(phoneNumber);
         JsonObject getPsnIdentityInfoObject = gson.fromJson(getPsnIdentityInfo.getBody(), JsonObject.class);
         String realnameStatus =getPsnIdentityInfoObject.getAsJsonObject("data").get("realnameStatus").getAsString();//授权状态authorizeUserInfo
+        String psnId =getPsnIdentityInfoObject.getAsJsonObject("data").get("psnId").getAsString();
+        FamilyMembers familyMembers = familyMembersMapper.selectOne(Wrappers.<FamilyMembers>lambdaQuery().eq(FamilyMembers::getPhone, phoneNumber));
+        familyMembers.setPsnId(psnId);
+        familyMembersMapper.updateById(familyMembers);
         return realnameStatus.equals("1");
     }
 
@@ -99,6 +102,9 @@ public class ESignServiceImpl implements IESignService {
         }
         JsonObject dataObj = dataElement.getAsJsonObject();
         String orgRealnameStatus = dataObj.get("realnameStatus").getAsString();
+        String orgId = dataObj.get("orgId").getAsString();
+        sysDepart.setEsignOrgId(orgId);
+        sysDepartMapper.updateById(sysDepart);
         return orgRealnameStatus.equals("1");
     }
 
@@ -113,7 +119,8 @@ public class ESignServiceImpl implements IESignService {
     @Override
     public boolean uploadContractTemplate(AppContractInfoDTO appContractInfoDTO) throws EsignDemoException {
         LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        String remoteUrl = "http://127.0.0.1:8080/jeecg-boot/sys/common/static/" + appContractInfoDTO.getFilePath();
+//        String remoteUrl = "http://127.0.0.1:8080/jeecg-boot/sys/common/static/" + appContractInfoDTO.getFilePath();
+        String remoteUrl = "E:/合同模板/test-template1.pdf";
         String fileType = getFileExtension(appContractInfoDTO.getFilePath());
         if (fileType.isEmpty()) {
             throw new JeecgBootException("未指定文件类型");
@@ -156,42 +163,29 @@ public class ESignServiceImpl implements IESignService {
         AppOrder appOrder = orderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode));
         List<String> familyIds = List.of(appOrder.getFamilyIds().split(","));
         AppContractInfo appContractInfo = appAccountMapper.selectById(appOrder.getContractNo());
+        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, appOrder.getOrgCode()));
         familyIds.forEach(familyId -> {
             String generate32BitUUID = generate32BitUUID();
             FamilyMembers familyMembers = familyMembersMapper.selectById(familyId);
             EsignHttpResponse createByFile = null;
             try {
-                SignFlowDTO dto = new SignFlowDTO();
-                dto.setDocs(Arrays.asList(
-                        new SignFlowDTO.Doc().setFileId(appContractInfo.getFileId()).setFileName(appContractInfo.getContractName())
-                ));
-                dto.setSignFlowConfig(new SignFlowDTO.SignFlowConfig()
-                        .setSignFlowTitle(appContractInfo.getContractName())
-                        .setSignFlowExpireTime(System.currentTimeMillis() + 86400000L)
-                        .setAutoFinish(true)
-                        .setNotifyUrl("http://example.com/notify")
-                        .setRedirectConfig(new SignFlowDTO.RedirectConfig().setRedirectUrl(appContractInfo.getRedirectUrl())));
-                List<SignFlowDTO.Signer> signers = new  ArrayList<>();
-                //个人用户
-                SignFlowDTO.Signer signer1 = new SignFlowDTO.Signer()
-                        .setSignerType(0)
-                        .setPsnSignerInfo(new SignFlowDTO.PsnSignerInfo()
-                                .setPsnAccount(familyMembers.getPhone())
-                                .setPsnInfo(new SignFlowDTO.PsnInfo().setPsnName(familyMembers.getFullName())))
-                        .setSignFields(Collections.singletonList(
-                                new SignFlowDTO.SignField()
-                                        .setCustomBizNum(generate32BitUUID)
-                                        .setFileId(appContractInfo.getFileId())
-                                        .setNormalSignFieldConfig(new SignFlowDTO.NormalSignFieldConfig()
-                                                .setAutoSign(false)
-                                                .setSignFieldStyle(1)
-                                                .setSignFieldPosition(Collections.singletonList(new SignFlowDTO.SignFieldPosition()
-                                                        .setPositionPage("1")
-                                                        .setPositionX(100)
-                                                        .setPositionY(200))))));
-//                //企业用户
-//                SignFlowDTO.Signer signer2 = new SignFlowDTO.Signer()
-//                        .setSignerType(1)
+//                SignFlowDTO dto = new SignFlowDTO();
+//                dto.setDocs(Arrays.asList(
+//                        new SignFlowDTO.Doc().setFileId(appContractInfo.getFileId()).setFileName(appContractInfo.getContractName())
+//                ));
+//                dto.setSignFlowConfig(new SignFlowDTO.SignFlowConfig()
+//                        .setSignFlowTitle(appContractInfo.getContractName())
+//                        .setSignFlowExpireTime(System.currentTimeMillis() + 86400000L)
+//                        .setAutoFinish(true)
+//                        .setNotifyUrl("http://example.com/notify")
+//                        .setRedirectConfig(new SignFlowDTO.RedirectConfig().setRedirectUrl(appContractInfo.getRedirectUrl())));
+//                List<SignFlowDTO.Signer> signers = new  ArrayList<>();
+//                //个人用户
+//                SignFlowDTO.Signer signer1 = new SignFlowDTO.Signer()
+//                        .setSignerType(0)
+//                        .setPsnSignerInfo(new SignFlowDTO.PsnSignerInfo()
+//                                .setPsnAccount(familyMembers.getPhone())
+//                                .setPsnInfo(new SignFlowDTO.PsnInfo().setPsnName(familyMembers.getFullName())))
 //                        .setSignFields(Collections.singletonList(
 //                                new SignFlowDTO.SignField()
 //                                        .setCustomBizNum(generate32BitUUID)
@@ -203,9 +197,154 @@ public class ESignServiceImpl implements IESignService {
 //                                                        .setPositionPage("1")
 //                                                        .setPositionX(100)
 //                                                        .setPositionY(200))))));
-                signers.add(signer1);
-//                signers.add(signer2);
-                dto.setSigners(signers);
+////                //企业用户
+////                SignFlowDTO.Signer signer2 = new SignFlowDTO.Signer()
+////                        .setSignerType(1)
+////                        .setSignFields(Collections.singletonList(
+////                                new SignFlowDTO.SignField()
+////                                        .setCustomBizNum(generate32BitUUID)
+////                                        .setFileId(appContractInfo.getFileId())
+////                                        .setNormalSignFieldConfig(new SignFlowDTO.NormalSignFieldConfig()
+////                                                .setAutoSign(false)
+////                                                .setSignFieldStyle(1)
+////                                                .setSignFieldPosition(Collections.singletonList(new SignFlowDTO.SignFieldPosition()
+////                                                        .setPositionPage("1")
+////                                                        .setPositionX(100)
+////                                                        .setPositionY(200))))));
+////
+//                signers.add(signer1);
+////                signers.add(signer2);
+//                dto.setSigners(signers);
+                String dto = "{\n" +
+                        "    \"docs\": [\n" +
+                        "        {\n" +
+                        "            \"fileId\": \""+appContractInfo.getFileId()+"\",\n" +
+                        "            \"fileName\": \""+appContractInfo.getContractName()+"."+appContractInfo.getContractType()+"\"\n" +
+                        "        }\n" +
+                        "    ],\n" +
+                        "    \"attachments\": [\n" +
+                        "        {\n" +
+                        "            \"fileId\": \""+appContractInfo.getFileId()+"\",\n" +
+                        "            \"fileName\": \""+appContractInfo.getContractName()+"."+appContractInfo.getContractType()+"\"\n" +
+                        "        }\n" +
+                        "    ],\n" +
+                        "    \"signFlowConfig\": {\n" +
+                        "        \"signFlowTitle\": \""+appContractInfo.getContractName()+"\",\n" +
+                        "        \"signFlowExpireTime\": "+(System.currentTimeMillis() + 86400000L)+",\n" +
+                        "        \"autoStart\": true,\n" +
+                        "        \"autoFinish\": false,\n" +
+                        "        \"identityVerify\": true,\n" +
+                        "        \"signConfig\": {\n" +
+                        "            \"availableSignClientTypes\": \"1\",\n" +
+                        "            \"showBatchDropSealButton\": true\n" +
+                        "        },\n" +
+                        "        \"notifyUrl\": \"http://xx.xx.86.172:8081/asyn/notify\",\n" +
+                        "        \"redirectConfig\": {\n" +
+                        "            \"redirectUrl\": \"http://www.xx.cn/\"\n" +
+                        "        },\n" +
+                        "        \"authConfig\": {\n" +
+                        "            \"psnAvailableAuthModes\": [\n" +
+                        "                \"PSN_FACE\"\n" +
+                        "            ],\n" +
+                        "            \"willingnessAuthModes\": [\n" +
+                        "                \"PSN_FACE_TECENT\",\n" +
+                        "                \"PSN_FACE_ALIPAY\"\n" +
+                        "            ],\n" +
+                        "            \"orgAvailableAuthModes\": [\n" +
+                        "                \"ORG_BANK_TRANSFER\",\n" +
+                        "                \"ORG_LEGALREP\"\n" +
+                        "            ]\n" +
+                        "        }\n" +
+                        "    },\n" +
+                        "    \"signFlowInitiator\": {\n" +
+                        "        \"orgInitiator\": {\n" +
+                        "            \"orgId\": \""+sysDepart.getEsignOrgId()+"\",\n" +
+                        "            \"transactor\": {\n" +
+                        "                \"psnId\": \""+familyMembers.getPsnId()+"\"\n" +
+                        "            }\n" +
+                        "        }\n" +
+                        "    },\n" +
+                        "    \"signers\": [\n" +
+                        "        {\n" +
+                        "            \"signConfig\": {\n" +
+                        "                \"forcedReadingTime\": \"10\",\n" +
+                        "                \"signOrder\": 1\n" +
+                        "            },\n" +
+                        "            \"noticeConfig\": {\n" +
+                        "                \"noticeTypes\": \"1\"\n" +
+                        "            },\n" +
+                        "            \"signerType\": 0,\n" +
+                        "            \"psnSignerInfo\": {\n" +
+                        "                \"psnAccount\": \""+familyMembers.getPhone()+"\",\n" +
+                        "                \"psnInfo\": {\n" +
+                        "                    \"psnName\": \""+familyMembers.getFullName()+"\",\n" +
+                        "                    \"psnIDCardNum\": \""+familyMembers.getIdentityCard()+"\",\n" +
+                        "                    \"psnIDCardType\": \"CRED_PSN_CH_IDCARD\"\n" +
+                        "                }\n" +
+                        "            },"+
+                        "            \"signFields\": [\n" +
+                        "                {\n" +
+                        "                    \"fileId\": \""+appContractInfo.getFileId()+"\",\n" +
+                        "                    \"customBizNum\": \"自定义编码0001\",\n" +
+                        "                    \"signFieldType\": 0,\n" +
+                        "                    \"normalSignFieldConfig\": {\n" +
+                        "                        \"autoSign\": false,\n" +
+                        "                        \"freeMode\": false,\n" +
+                        "                        \"movableSignField\": false,\n" +
+                        "                        \"psnSealStyles\": \"0,1\",\n" +
+                        "                        \"signFieldSize\": \"96\",\n" +
+                        "                        \"signFieldStyle\": 1,\n" +
+                        "                        \"signFieldPosition\": {\n" +
+                        "                            \"positionPage\": \"1\",\n" +
+                        "                            \"positionX\": 100,\n" +
+                        "                            \"positionY\": 200\n" +
+                        "                        }\n" +
+                        "                    },\n" +
+                        "                    \"signDateConfig\": {\n" +
+                        "                        \"dateFormat\": \"yyyy-MM-dd\",\n" +
+                        "                        \"showSignDate\": 1,\n" +
+                        "                        \"signDatePositionX\": 100,\n" +
+                        "                        \"signDatePositionY\": 100\n" +
+                        "                    }\n" +
+                        "                }\n" +
+                        "            ]\n" +
+                        "        },\n" +
+                        "        {\n" +
+                        "            \"signConfig\": {\n" +
+                        "                \"forcedReadingTime\": \"10\",\n" +
+                        "                \"signOrder\": 2\n" +
+                        "            },\n" +
+                        "            \"noticeConfig\": {\n" +
+                        "                \"noticeTypes\": \"1,2\"\n" +
+                        "            },\n" +
+                        "            \"signerType\": 1,\n" +
+                        "            \"signFields\": [\n" +
+                        "                {\n" +
+                        "                    \"customBizNum\": \"自定义编码001\",\n" +
+                        "                    \"fileId\": \""+appContractInfo.getFileId()+"\",\n" +
+                        "                    \"normalSignFieldConfig\": {\n" +
+                        "                        \"autoSign\": true,\n" +
+                        "                        \"freeMode\": false,\n" +
+                        "                        \"movableSignField\": false,\n" +
+                        "                        \"signFieldSize\": \"159\",\n" +
+                        "                        \"signFieldStyle\": 1,\n" +
+                        "                        \"signFieldPosition\": {\n" +
+                        "                            \"positionPage\": \"1\",\n" +
+                        "                            \"positionX\": 300,\n" +
+                        "                            \"positionY\": 200\n" +
+                        "                        }\n" +
+                        "                    },\n" +
+                        "                    \"signDateConfig\": {\n" +
+                        "                        \"dateFormat\": \"yyyy-MM-dd\",\n" +
+                        "                        \"showSignDate\": 1,\n" +
+                        "                        \"signDatePositionX\": 300,\n" +
+                        "                        \"signDatePositionY\": 100\n" +
+                        "                    }\n" +
+                        "                }\n" +
+                        "            ]\n" +
+                        "        }\n" +
+                        "    ]\n" +
+                        "}";
                 createByFile = createByFile(dto);
             } catch (EsignDemoException e) {
                 throw new RuntimeException(e);
@@ -216,7 +355,7 @@ public class ESignServiceImpl implements IESignService {
             signFlowIds.add(signFlowId);
             appContractSignMapper.insert(new AppContractSign().setId(generate32BitUUID)
                     .setSignFlowId(signFlowId)
-                    .setOrderId(appOrder.getId())
+                    .setOrderId(appOrder.getId()).setFamilyId(familyId)
                     .setOrgCode(appOrder.getOrgCode())
                     .setCreateTime(new Date())
                     .setUpdateTime(new Date()));
@@ -231,7 +370,10 @@ public class ESignServiceImpl implements IESignService {
     }
     @Override
     public String getSignUrl(String signFlowId) throws EsignDemoException {
-        JSONObject signUrl = JSONObject.parseObject(SignDemo.signUrl(signFlowId).getBody());
+        AppContractSign appContractSign = appContractSignMapper.selectOne(Wrappers.<AppContractSign>lambdaQuery().eq(AppContractSign::getSignFlowId, signFlowId));
+        FamilyMembers familyMembers = familyMembersMapper.selectById(appContractSign.getFamilyId());
+        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, appContractSign.getOrgCode()));
+        JSONObject signUrl = JSONObject.parseObject(SignDemo.signUrl(signFlowId,familyMembers.getPhone(),sysDepart.getDepartName()).getBody());
         return signUrl.getJSONObject("data").getString("url");
     }
 

+ 1 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/entity/FamilyMembers.java

@@ -65,6 +65,7 @@ public class FamilyMembers implements Serializable {
     @Excel(name = "实名认证照片", width = 15)
     @Schema(description = "实名认证照片")
     private String realNameImg;
+    private String psnId;
 
     /**实名状态 0-未实名 ;1-已实名*/
     @Excel(name = "用户类型0-本人;1-家人", width = 15)

+ 1 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDepart.java

@@ -35,6 +35,7 @@ public class SysDepart implements Serializable {
 	/**机构/部门名称*/
 	@Excel(name="机构/部门名称",width=15)
 	private String departName;
+	private String esignOrgId;
 	/**英文名*/
 	@Excel(name="英文名",width=15)
 	private String departNameEn;