|  | @@ -2,50 +2,41 @@ package org.jeecg.modules.app.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
	
		
			
				|  |  | -import com.google.gson.Gson;
 | 
	
		
			
				|  |  | -import com.google.gson.JsonArray;
 | 
	
		
			
				|  |  | -import com.google.gson.JsonElement;
 | 
	
		
			
				|  |  | -import com.google.gson.JsonObject;
 | 
	
		
			
				|  |  | +import com.google.gson.*;
 | 
	
		
			
				|  |  | +import com.google.gson.reflect.TypeToken;
 | 
	
		
			
				|  |  |  import lombok.extern.log4j.Log4j2;
 | 
	
		
			
				|  |  |  import org.apache.shiro.SecurityUtils;
 | 
	
		
			
				|  |  |  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.ExternalAuthRequestDTO;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.dto.GetPsnAuthUrlDTO;
 | 
	
		
			
				|  |  | +import org.jeecg.modules.app.dto.SealInfoDTO;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.esign.comm.EsignHttpResponse;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.esign.exception.EsignDemoException;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.esign.fileAndTemplate.FileDemo;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.esign.sign.SignDemo;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.app.service.IESignService;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.system.app.dto.AppContractInfoDTO;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.entity.AppContractInfo;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.entity.AppContractSign;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.entity.AppOrder;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.entity.FamilyMembers;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.mapper.AppContractInfoMapper;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.mapper.AppContractSignMapper;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.mapper.AppOrderMapper;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.app.mapper.FamilyMembersMapper;
 | 
	
		
			
				|  |  | +import org.jeecg.modules.system.app.entity.*;
 | 
	
		
			
				|  |  | +import org.jeecg.modules.system.app.mapper.*;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.system.entity.SysDepart;
 | 
	
		
			
				|  |  | -import org.jeecg.modules.system.entity.SysUser;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.system.mapper.SysDepartMapper;
 | 
	
		
			
				|  |  |  import org.jeecg.modules.system.mapper.SysUserMapper;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  | -import java.io.File;
 | 
	
		
			
				|  |  | -import java.io.IOException;
 | 
	
		
			
				|  |  | -import java.io.InputStream;
 | 
	
		
			
				|  |  | -import java.net.URL;
 | 
	
		
			
				|  |  | -import java.nio.file.Files;
 | 
	
		
			
				|  |  | -import java.nio.file.StandardCopyOption;
 | 
	
		
			
				|  |  |  import java.util.*;
 | 
	
		
			
				|  |  | +import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static com.alibaba.dashscope.utils.JsonUtils.gson;
 | 
	
		
			
				|  |  |  import static org.jeecg.modules.app.esign.auth.ESignAuth.*;
 | 
	
		
			
				|  |  |  import static org.jeecg.modules.app.esign.fileAndTemplate.TemplateDemo.getTemplateCreateUrl;
 | 
	
		
			
				|  |  |  import static org.jeecg.modules.app.esign.fileAndTemplate.TemplateDemo.getTemplateEditUrl;
 | 
	
		
			
				|  |  | +import static org.jeecg.modules.app.esign.members.MembersDemo.administrators;
 | 
	
		
			
				|  |  | +import static org.jeecg.modules.app.esign.seal.SealDemo.orgOwnSealList;
 | 
	
		
			
				|  |  | +import static org.jeecg.modules.app.esign.seal.SealDemo.orgSealsExternalAuth;
 | 
	
		
			
				|  |  |  import static org.jeecg.modules.app.esign.sign.SignDemo.createByFile;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Service
 | 
	
	
		
			
				|  | @@ -63,6 +54,14 @@ public class ESignServiceImpl implements IESignService {
 | 
	
		
			
				|  |  |      private AppContractSignMapper appContractSignMapper;
 | 
	
		
			
				|  |  |      @Resource
 | 
	
		
			
				|  |  |      private FamilyMembersMapper familyMembersMapper;
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private AppSiteMapper appSiteMapper;
 | 
	
		
			
				|  |  | +    private static final String NOTIFY_URL = "http://xx.xx.86.172:8081/asyn/notify";
 | 
	
		
			
				|  |  | +    private static final String REDIRECT_URL = "http://www.xx.cn/";
 | 
	
		
			
				|  |  | +    private static final String[] PERSON_AUTH_MODES = {"PSN_MOBILE3"};
 | 
	
		
			
				|  |  | +    private static final String[] WILLINGNESS_MODES = {"CODE_SMS"};
 | 
	
		
			
				|  |  | +    private static final String[] ORG_AUTH_MODES = {"ORG_ALIPAY_CREDIT", "ORG_LEGALREP"};
 | 
	
		
			
				|  |  | +    private static final int DEFAULT_EXPIRE_TIME = 86400000;
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public boolean getUserIdentityInfo(String phoneNumber) throws EsignDemoException {
 | 
	
		
			
				|  |  |          EsignHttpResponse getPsnIdentityInfo = getPsnIdentityInfo(phoneNumber);
 | 
	
	
		
			
				|  | @@ -76,12 +75,9 @@ public class ESignServiceImpl implements IESignService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public String getAuthUrl() throws EsignDemoException {
 | 
	
		
			
				|  |  | -        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 | 
	
		
			
				|  |  | -        SysUser sysUser = sysUserMapper.selectById(user.getId());
 | 
	
		
			
				|  |  | -        if (null == sysUser.getPhone()) throw new JeecgBootException("请先绑定手机号");
 | 
	
		
			
				|  |  | +    public String getAuthUrl(String phoneNumber) throws EsignDemoException {
 | 
	
		
			
				|  |  |          GetPsnAuthUrlDTO getPsnAuthUrlDTO = new GetPsnAuthUrlDTO();
 | 
	
		
			
				|  |  | -        GetPsnAuthUrlDTO.PsnAuthConfig pncAuthConfig = new GetPsnAuthUrlDTO.PsnAuthConfig().setPsnAccount(sysUser.getPhone());
 | 
	
		
			
				|  |  | +        GetPsnAuthUrlDTO.PsnAuthConfig pncAuthConfig = new GetPsnAuthUrlDTO.PsnAuthConfig().setPsnAccount(phoneNumber);
 | 
	
		
			
				|  |  |          getPsnAuthUrlDTO.setPsnAuthConfig(pncAuthConfig);
 | 
	
		
			
				|  |  |          EsignHttpResponse getPsnAuthUrl = getPsnAuthUrl(getPsnAuthUrlDTO);
 | 
	
		
			
				|  |  |          JsonObject getPsnAuthUrlObject = gson.fromJson(getPsnAuthUrl.getBody(), JsonObject.class);
 | 
	
	
		
			
				|  | @@ -92,6 +88,7 @@ public class ESignServiceImpl implements IESignService {
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public boolean getOrgIdentityInfos(String orgCode) throws EsignDemoException {
 | 
	
		
			
				|  |  |          SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
 | 
	
		
			
				|  |  | +        AppSite appSite = appSiteMapper.selectOne(Wrappers.<AppSite>lambdaQuery().eq(AppSite::getOrgCode, orgCode));
 | 
	
		
			
				|  |  |          EsignHttpResponse getOrgIdentityInfo = getOrgIdentityInfo(sysDepart.getDepartName());
 | 
	
		
			
				|  |  |          JsonObject getOrgIdentityInfoObject = gson.fromJson(getOrgIdentityInfo.getBody(), JsonObject.class);
 | 
	
		
			
				|  |  |          JsonElement dataElement = getOrgIdentityInfoObject.get("data");
 | 
	
	
		
			
				|  | @@ -103,8 +100,11 @@ 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);
 | 
	
		
			
				|  |  | +        JsonObject jsonObject = dataObj.get("orgInfo").getAsJsonObject();
 | 
	
		
			
				|  |  | +        String orgIDCardNum = jsonObject.get("orgIDCardNum").getAsString();
 | 
	
		
			
				|  |  | +        appSite.setEsignOrgId(orgId);
 | 
	
		
			
				|  |  | +        appSite.setOrgIdCardNum(orgIDCardNum);
 | 
	
		
			
				|  |  | +        appSiteMapper.updateById(appSite);
 | 
	
		
			
				|  |  |          return orgRealnameStatus.equals("1");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -156,218 +156,270 @@ public class ESignServiceImpl implements IESignService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    @Transactional
 | 
	
		
			
				|  |  | -    public List<String> createSign(String orderCode) throws EsignDemoException {
 | 
	
		
			
				|  |  | -        List<String> signFlowIds = new ArrayList<>();
 | 
	
		
			
				|  |  | -        //todo
 | 
	
		
			
				|  |  | -        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)
 | 
	
		
			
				|  |  | -////                        .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);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            JSONObject createByFileJsonObject = JSONObject.parseObject(createByFile.getBody());
 | 
	
		
			
				|  |  | -            String signFlowId = createByFileJsonObject.getJSONObject("data").getString("signFlowId");
 | 
	
		
			
				|  |  | -            System.out.println("signFlowId:" + signFlowId);
 | 
	
		
			
				|  |  | +    @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | +    public List<String> createSign(String orderCode){
 | 
	
		
			
				|  |  | +    List<String> signFlowIds = new ArrayList<>();
 | 
	
		
			
				|  |  | +    AppOrder appOrder = orderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery()
 | 
	
		
			
				|  |  | +            .eq(AppOrder::getOrderCode, orderCode));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    List<String> familyIds = Arrays.asList(appOrder.getFamilyIds().split(","));
 | 
	
		
			
				|  |  | +    AppContractInfo contractInfo = appAccountMapper.selectById(appOrder.getContractNo());
 | 
	
		
			
				|  |  | +    SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery()
 | 
	
		
			
				|  |  | +            .eq(SysDepart::getOrgCode, appOrder.getOrgCode()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 预加载家庭成员信息
 | 
	
		
			
				|  |  | +    Map<String, FamilyMembers> familyMemberMap = familyIds.stream()
 | 
	
		
			
				|  |  | +            .map(familyMembersMapper::selectById)
 | 
	
		
			
				|  |  | +            .collect(Collectors.toMap(FamilyMembers::getId, fm -> fm));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 构建签署流程
 | 
	
		
			
				|  |  | +    familyIds.forEach(familyId -> {
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            FamilyMembers familyMembers = familyMemberMap.get(familyId);
 | 
	
		
			
				|  |  | +            JsonObject dto = buildSignFlowDto(contractInfo, sysDepart, familyMembers);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            EsignHttpResponse response = createByFile(dto.toString());
 | 
	
		
			
				|  |  | +            String signFlowId = extractSignFlowId(response);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            log.info("生成签署流程ID: {}", signFlowId);
 | 
	
		
			
				|  |  |              signFlowIds.add(signFlowId);
 | 
	
		
			
				|  |  | -            appContractSignMapper.insert(new AppContractSign().setId(generate32BitUUID)
 | 
	
		
			
				|  |  | -                    .setSignFlowId(signFlowId)
 | 
	
		
			
				|  |  | -                    .setOrderId(appOrder.getId()).setFamilyId(familyId)
 | 
	
		
			
				|  |  | -                    .setOrgCode(appOrder.getOrgCode())
 | 
	
		
			
				|  |  | -                    .setCreateTime(new Date())
 | 
	
		
			
				|  |  | -                    .setUpdateTime(new Date()));
 | 
	
		
			
				|  |  | +            saveSignFlowRecord(signFlowId, appOrder, familyId);
 | 
	
		
			
				|  |  | +        } catch (EsignDemoException e) {
 | 
	
		
			
				|  |  | +            log.error("签署流程创建失败,订单号: {}", orderCode, e);
 | 
	
		
			
				|  |  | +            throw new JeecgBootException(e.getMessage());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  | -        return signFlowIds;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return signFlowIds;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建签署流程请求体
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private JsonObject buildSignFlowDto(AppContractInfo contractInfo,
 | 
	
		
			
				|  |  | +                                        SysDepart sysDepart,
 | 
	
		
			
				|  |  | +                                        FamilyMembers familyMembers) {
 | 
	
		
			
				|  |  | +        JsonObject dto = new JsonObject();
 | 
	
		
			
				|  |  | +        AppSite appSite = appSiteMapper.selectOne(Wrappers.<AppSite>lambdaQuery().eq(AppSite::getOrgCode, sysDepart.getOrgCode()));
 | 
	
		
			
				|  |  | +        // 构建文档信息
 | 
	
		
			
				|  |  | +        JsonArray docs = new JsonArray();
 | 
	
		
			
				|  |  | +        JsonObject doc = new JsonObject();
 | 
	
		
			
				|  |  | +        doc.addProperty("fileId", contractInfo.getFileId());
 | 
	
		
			
				|  |  | +        doc.addProperty("fileName", contractInfo.getContractName() + "." + contractInfo.getContractType());
 | 
	
		
			
				|  |  | +        docs.add(doc);
 | 
	
		
			
				|  |  | +        dto.add("docs", docs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 构建附件信息
 | 
	
		
			
				|  |  | +        dto.add("attachments", docs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 构建签署流程配置
 | 
	
		
			
				|  |  | +        JsonObject signFlowConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("signFlowTitle", contractInfo.getContractName());
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("signFlowExpireTime", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("autoStart", true);
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("autoFinish", true);
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("identityVerify", true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 签署配置
 | 
	
		
			
				|  |  | +        JsonObject signConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        signConfig.addProperty("availableSignClientTypes", "1");
 | 
	
		
			
				|  |  | +        signConfig.addProperty("showBatchDropSealButton", true);
 | 
	
		
			
				|  |  | +        signFlowConfig.add("signConfig", signConfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 通知配置
 | 
	
		
			
				|  |  | +        signFlowConfig.addProperty("notifyUrl", NOTIFY_URL);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 重定向配置
 | 
	
		
			
				|  |  | +        JsonObject redirectConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        redirectConfig.addProperty("redirectUrl", REDIRECT_URL);
 | 
	
		
			
				|  |  | +        signFlowConfig.add("redirectConfig", redirectConfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 认证配置
 | 
	
		
			
				|  |  | +        JsonObject authConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        addStringArray(authConfig, "psnAvailableAuthModes", PERSON_AUTH_MODES);
 | 
	
		
			
				|  |  | +        addStringArray(authConfig, "willingnessAuthModes", WILLINGNESS_MODES);
 | 
	
		
			
				|  |  | +        addStringArray(authConfig, "orgAvailableAuthModes", ORG_AUTH_MODES);
 | 
	
		
			
				|  |  | +        signFlowConfig.add("authConfig", authConfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        dto.add("signFlowConfig", signFlowConfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 发起人信息
 | 
	
		
			
				|  |  | +        JsonObject signFlowInitiator = new JsonObject();
 | 
	
		
			
				|  |  | +        JsonObject orgInitiator = new JsonObject();
 | 
	
		
			
				|  |  | +        orgInitiator.addProperty("orgId", appSite.getEsignOrgId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        JsonObject transactor = new JsonObject();
 | 
	
		
			
				|  |  | +        transactor.addProperty("psnId", familyMembers.getPsnId());
 | 
	
		
			
				|  |  | +        orgInitiator.add("transactor", transactor);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        signFlowInitiator.add("orgInitiator", orgInitiator);
 | 
	
		
			
				|  |  | +        dto.add("signFlowInitiator", signFlowInitiator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 签署人信息
 | 
	
		
			
				|  |  | +        dto.add("signers", buildSigners(contractInfo, familyMembers));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return dto;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建签署人信息
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private JsonArray buildSigners(AppContractInfo contractInfo, FamilyMembers familyMembers) {
 | 
	
		
			
				|  |  | +        JsonArray signers = new JsonArray();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 个人签署人
 | 
	
		
			
				|  |  | +        JsonObject signer1 = new JsonObject();
 | 
	
		
			
				|  |  | +        signer1.add("signConfig", buildSignConfig(1, 10));
 | 
	
		
			
				|  |  | +        signer1.add("noticeConfig", buildNoticeConfig(""));
 | 
	
		
			
				|  |  | +        signer1.addProperty("signerType", 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 签署人信息
 | 
	
		
			
				|  |  | +        JsonObject psnSignerInfo = new JsonObject();
 | 
	
		
			
				|  |  | +        psnSignerInfo.addProperty("psnAccount", familyMembers.getPhone());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        JsonObject psnInfo = new JsonObject();
 | 
	
		
			
				|  |  | +        psnInfo.addProperty("psnName", familyMembers.getFullName());
 | 
	
		
			
				|  |  | +        psnInfo.addProperty("psnIDCardNum", familyMembers.getIdentityCard());
 | 
	
		
			
				|  |  | +        psnInfo.addProperty("psnIDCardType", "CRED_PSN_CH_IDCARD");
 | 
	
		
			
				|  |  | +        psnSignerInfo.add("psnInfo", psnInfo);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        signer1.add("psnSignerInfo", psnSignerInfo);
 | 
	
		
			
				|  |  | +        signer1.add("signFields", buildSignFields(contractInfo.getFileId(), 100, 200, 96, 100, 100,false));
 | 
	
		
			
				|  |  | +//        "orgSignerInfo": {
 | 
	
		
			
				|  |  | +//            "orgName": "XXXX企业名字",
 | 
	
		
			
				|  |  | +//                    "orgInfo": {
 | 
	
		
			
				|  |  | +//                "orgIDCardNum": "911*******3",
 | 
	
		
			
				|  |  | +//                        "orgIDCardType": "CRED_ORG_USCC"
 | 
	
		
			
				|  |  | +//            },
 | 
	
		
			
				|  |  | +//            "transactorInfo": {
 | 
	
		
			
				|  |  | +//                "psnAccount": "139****10",
 | 
	
		
			
				|  |  | +//                        "psnInfo": {
 | 
	
		
			
				|  |  | +//                    "psnName": "李四",
 | 
	
		
			
				|  |  | +//                            "psnIDCardNum": "3311********9",
 | 
	
		
			
				|  |  | +//                            "psnIDCardType": "CRED_PSN_CH_IDCARD"
 | 
	
		
			
				|  |  | +//                }
 | 
	
		
			
				|  |  | +//            }
 | 
	
		
			
				|  |  | +//        },
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 企业签署人
 | 
	
		
			
				|  |  | +//        JsonObject signer2 = new JsonObject();
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        JsonObject corporate = new JsonObject();
 | 
	
		
			
				|  |  | +//        // 签署人信息
 | 
	
		
			
				|  |  | +//        psnSignerInfo.addProperty("psnAccount", familyMembers.getPhone());
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        corporate.addProperty("psnName", familyMembers.getFullName());
 | 
	
		
			
				|  |  | +//        corporate.addProperty("psnIDCardNum", familyMembers.getIdentityCard());
 | 
	
		
			
				|  |  | +//        corporate.addProperty("psnIDCardType", "CRED_PSN_CH_IDCARD");
 | 
	
		
			
				|  |  | +//        psnSignerInfo.add("psnInfo", psnInfo);
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        signer1.add("orgSignerInfo", psnSignerInfo);
 | 
	
		
			
				|  |  | +//        signer2.add("signConfig", buildSignConfig(2, 10));
 | 
	
		
			
				|  |  | +//        signer2.add("noticeConfig", buildNoticeConfig(""));
 | 
	
		
			
				|  |  | +//        signer2.addProperty("signerType", 1);
 | 
	
		
			
				|  |  | +//        signer2.add("signFields", buildSignFields(contractInfo.getFileId(), 300, 200, 159, 300, 100,true));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        signers.add(signer1);
 | 
	
		
			
				|  |  | +        return signers;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建签署配置
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private JsonObject buildSignConfig(int signOrder, int readingTime) {
 | 
	
		
			
				|  |  | +        JsonObject signConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        signConfig.addProperty("forcedReadingTime", String.valueOf(readingTime));
 | 
	
		
			
				|  |  | +        signConfig.addProperty("signOrder", signOrder);
 | 
	
		
			
				|  |  | +        return signConfig;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建通知配置
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private JsonObject buildNoticeConfig(String noticeTypes) {
 | 
	
		
			
				|  |  | +        JsonObject noticeConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        noticeConfig.addProperty("noticeTypes", noticeTypes);
 | 
	
		
			
				|  |  | +        return noticeConfig;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 构建签署区域
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private JsonArray buildSignFields(String fileId,
 | 
	
		
			
				|  |  | +                                      int x, int y,
 | 
	
		
			
				|  |  | +                                      int size,
 | 
	
		
			
				|  |  | +                                      int dateX, int dateY,boolean autoSign) {
 | 
	
		
			
				|  |  | +        JsonArray signFields = new JsonArray();
 | 
	
		
			
				|  |  | +        JsonObject field = new JsonObject();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        field.addProperty("fileId", fileId);
 | 
	
		
			
				|  |  | +        field.addProperty("customBizNum", "自定义编码0001");
 | 
	
		
			
				|  |  | +        field.addProperty("signFieldType", 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 签署配置
 | 
	
		
			
				|  |  | +        JsonObject normalConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("autoSign", autoSign);
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("freeMode", false);
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("movableSignField", false);
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("psnSealStyles", "0,1");
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("signFieldSize", String.valueOf(size));
 | 
	
		
			
				|  |  | +        normalConfig.addProperty("signFieldStyle", 1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 位置配置
 | 
	
		
			
				|  |  | +        JsonObject position = new JsonObject();
 | 
	
		
			
				|  |  | +        position.addProperty("positionPage", "1");
 | 
	
		
			
				|  |  | +        position.addProperty("positionX", x);
 | 
	
		
			
				|  |  | +        position.addProperty("positionY", y);
 | 
	
		
			
				|  |  | +        normalConfig.add("signFieldPosition", position);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 日期配置
 | 
	
		
			
				|  |  | +        JsonObject dateConfig = new JsonObject();
 | 
	
		
			
				|  |  | +        dateConfig.addProperty("dateFormat", "yyyy-MM-dd");
 | 
	
		
			
				|  |  | +        dateConfig.addProperty("showSignDate", 1);
 | 
	
		
			
				|  |  | +        dateConfig.addProperty("signDatePositionX", dateX);
 | 
	
		
			
				|  |  | +        dateConfig.addProperty("signDatePositionY", dateY);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        field.add("normalSignFieldConfig", normalConfig);
 | 
	
		
			
				|  |  | +        field.add("signDateConfig", dateConfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        signFields.add(field);
 | 
	
		
			
				|  |  | +        return signFields;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 提取签署流程ID
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private String extractSignFlowId(EsignHttpResponse response) {
 | 
	
		
			
				|  |  | +        JSONObject result = JSONObject.parseObject(response.getBody());
 | 
	
		
			
				|  |  | +        return result.getJSONObject("data").getString("signFlowId");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 保存签署流程记录
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void saveSignFlowRecord(String signFlowId, AppOrder appOrder, String familyId) {
 | 
	
		
			
				|  |  | +        String id = UUID.randomUUID().toString().replace("-", "");
 | 
	
		
			
				|  |  | +        AppContractSign record = new AppContractSign()
 | 
	
		
			
				|  |  | +                .setId(id)
 | 
	
		
			
				|  |  | +                .setSignFlowId(signFlowId)
 | 
	
		
			
				|  |  | +                .setOrderId(appOrder.getId())
 | 
	
		
			
				|  |  | +                .setFamilyId(familyId)
 | 
	
		
			
				|  |  | +                .setOrgCode(appOrder.getOrgCode())
 | 
	
		
			
				|  |  | +                .setCreateTime(new Date())
 | 
	
		
			
				|  |  | +                .setUpdateTime(new Date());
 | 
	
		
			
				|  |  | +        appContractSignMapper.insert(record);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    public static String generate32BitUUID() {
 | 
	
		
			
				|  |  | -        // 生成标准 UUID(128 位)
 | 
	
		
			
				|  |  | -        UUID uuid = UUID.randomUUID();
 | 
	
		
			
				|  |  | -        // 去除连字符,得到 32 位字符串
 | 
	
		
			
				|  |  | -        return uuid.toString().replace("-", "");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 添加字符串数组到JSON对象
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void addStringArray(JsonObject parent, String key, String[] values) {
 | 
	
		
			
				|  |  | +        JsonArray array = new JsonArray();
 | 
	
		
			
				|  |  | +        for (String value : values) {
 | 
	
		
			
				|  |  | +            array.add(value);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        parent.add(key, array);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public String getSignUrl(String signFlowId) throws EsignDemoException {
 | 
	
		
			
				|  |  |          AppContractSign appContractSign = appContractSignMapper.selectOne(Wrappers.<AppContractSign>lambdaQuery().eq(AppContractSign::getSignFlowId, signFlowId));
 | 
	
	
		
			
				|  | @@ -437,43 +489,79 @@ public class ESignServiceImpl implements IESignService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 获取文件扩展名
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private String getFileExtension(String filename) {
 | 
	
		
			
				|  |  | -        if (filename == null || !filename.contains(".")) {
 | 
	
		
			
				|  |  | -            return "";
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public List<SealInfoDTO> orgOwnSeal(String orgId) {
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            // 调用API获取响应
 | 
	
		
			
				|  |  | +            EsignHttpResponse response = orgOwnSealList(orgId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 解析JSON响应
 | 
	
		
			
				|  |  | +            JsonObject result = gson.fromJson(response.getBody(), JsonObject.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 验证数据结构
 | 
	
		
			
				|  |  | +            if (!result.has("data")) {
 | 
	
		
			
				|  |  | +                throw new JeecgBootException("响应数据中缺少'data'字段");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            JsonObject data = result.getAsJsonObject("data");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (!data.has("seals")) {
 | 
	
		
			
				|  |  | +                throw new JeecgBootException("响应数据中缺少'seals'字段");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 转换数据
 | 
	
		
			
				|  |  | +            return gson.fromJson(data.getAsJsonArray("seals"),
 | 
	
		
			
				|  |  | +                    new TypeToken<List<SealInfoDTO>>(){}.getType());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } catch (JsonSyntaxException e) {
 | 
	
		
			
				|  |  | +            throw new JeecgBootException("JSON解析失败: " + e.getMessage(), e);
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            throw new JeecgBootException("获取印章列表失败: " + e.getMessage(), e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 下载远程文件
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private File downloadRemoteFile(String fileUrl) throws IOException {
 | 
	
		
			
				|  |  | -        URL url = new URL(fileUrl);
 | 
	
		
			
				|  |  | -        File tempFile = File.createTempFile("esign-", ".tmp");
 | 
	
		
			
				|  |  | -        tempFile.deleteOnExit();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        try (InputStream in = url.openStream()) {
 | 
	
		
			
				|  |  | -            Files.copy(in, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public Boolean orgSealsExternal(String orgCode, String sealId) throws EsignDemoException {
 | 
	
		
			
				|  |  | +        AppSite appSite = appSiteMapper.selectOne(Wrappers.<AppSite>lambdaQuery().eq(AppSite::getOrgCode, orgCode));
 | 
	
		
			
				|  |  | +        EsignHttpResponse administrators = administrators(appSite.getEsignOrgId());
 | 
	
		
			
				|  |  | +        JsonObject administratorsObject = gson.fromJson(administrators.getBody(), JsonObject.class);
 | 
	
		
			
				|  |  | +        JsonObject data = administratorsObject.getAsJsonObject("data");
 | 
	
		
			
				|  |  | +        String psnId = null;
 | 
	
		
			
				|  |  | +        if (data != null) {
 | 
	
		
			
				|  |  | +            JsonArray admins = data.getAsJsonArray("administrators");
 | 
	
		
			
				|  |  | +            if (admins != null && !admins.isEmpty()) {
 | 
	
		
			
				|  |  | +                JsonObject firstAdmin = admins.get(0).getAsJsonObject();
 | 
	
		
			
				|  |  | +                if (firstAdmin.has("psnId")) {
 | 
	
		
			
				|  |  | +                    psnId = firstAdmin.get("psnId").getAsString();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        ExternalAuthRequestDTO requestDTO = new ExternalAuthRequestDTO();
 | 
	
		
			
				|  |  | +        requestDTO.setOrgId(appSite.getEsignOrgId());
 | 
	
		
			
				|  |  | +        requestDTO.setTransactorPsnId(psnId);
 | 
	
		
			
				|  |  | +        requestDTO.setLongTermEffective(true);
 | 
	
		
			
				|  |  | +        requestDTO.setSealIds(Collections.singletonList(sealId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ExternalAuthRequestDTO.AuthorizedOrgInfoDTO orgInfo = new ExternalAuthRequestDTO.AuthorizedOrgInfoDTO();
 | 
	
		
			
				|  |  | +        orgInfo.setOrgName("中数未来(海南)系统集成有限公司");
 | 
	
		
			
				|  |  | +        orgInfo.setOrgIdCardNum("91460105MAA9A6L75X");
 | 
	
		
			
				|  |  | +        requestDTO.setAuthorizedOrgInfo(orgInfo);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        EsignHttpResponse orgSealsExternalAuth = orgSealsExternalAuth(requestDTO);
 | 
	
		
			
				|  |  | +        JsonObject orgSealsExternalAuthObject = gson.fromJson(orgSealsExternalAuth.getBody(), JsonObject.class);
 | 
	
		
			
				|  |  | +        System.out.println("请求返回:"+orgSealsExternalAuthObject);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        return tempFile;
 | 
	
		
			
				|  |  | +        return null;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | -     * 获取MIME类型映射
 | 
	
		
			
				|  |  | +     * 获取文件扩展名
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private String getMimeType(String ext) {
 | 
	
		
			
				|  |  | -        Map<String, String> mimeMap = new HashMap<>();
 | 
	
		
			
				|  |  | -        mimeMap.put("pdf", "application/pdf");
 | 
	
		
			
				|  |  | -        mimeMap.put("doc", "application/msword");
 | 
	
		
			
				|  |  | -        mimeMap.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
 | 
	
		
			
				|  |  | -        mimeMap.put("xls", "application/vnd.ms-excel");
 | 
	
		
			
				|  |  | -        mimeMap.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        return mimeMap.getOrDefault(ext, "application/octet-stream");
 | 
	
		
			
				|  |  | +    private String getFileExtension(String filename) {
 | 
	
		
			
				|  |  | +        if (filename == null || !filename.contains(".")) {
 | 
	
		
			
				|  |  | +            return "";
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |