|
@@ -10,7 +10,9 @@ 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.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;
|
|
@@ -18,16 +20,28 @@ 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.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.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+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 static com.alibaba.dashscope.utils.JsonUtils.gson;
|
|
|
import static org.jeecg.modules.app.esign.auth.ESignAuth.*;
|
|
@@ -42,6 +56,14 @@ public class ESignServiceImpl implements IESignService {
|
|
|
private SysUserMapper sysUserMapper;
|
|
|
@Resource
|
|
|
private AppContractInfoMapper appAccountMapper;
|
|
|
+ @Resource
|
|
|
+ private SysDepartMapper sysDepartMapper;
|
|
|
+ @Resource
|
|
|
+ private AppOrderMapper orderMapper;
|
|
|
+ @Resource
|
|
|
+ private AppContractSignMapper appContractSignMapper;
|
|
|
+ @Resource
|
|
|
+ private FamilyMembersMapper familyMembersMapper;
|
|
|
@Override
|
|
|
public boolean getUserIdentityInfo(String phoneNumber) throws EsignDemoException {
|
|
|
EsignHttpResponse getPsnIdentityInfo = getPsnIdentityInfo(phoneNumber);
|
|
@@ -65,16 +87,25 @@ public class ESignServiceImpl implements IESignService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public boolean getOrgIdentityInfos(String orgName) throws EsignDemoException {
|
|
|
- EsignHttpResponse getOrgIdentityInfo = getOrgIdentityInfo(orgName);
|
|
|
+ public boolean getOrgIdentityInfos(String orgCode) throws EsignDemoException {
|
|
|
+ SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
|
|
|
+ EsignHttpResponse getOrgIdentityInfo = getOrgIdentityInfo(sysDepart.getDepartName());
|
|
|
JsonObject getOrgIdentityInfoObject = gson.fromJson(getOrgIdentityInfo.getBody(), JsonObject.class);
|
|
|
- String orgRealnameStatus = getOrgIdentityInfoObject.getAsJsonObject("data").get("realnameStatus").getAsString();//授权状态authorizeUserInfo
|
|
|
+ JsonElement dataElement = getOrgIdentityInfoObject.get("data");
|
|
|
+ if (dataElement == null || !dataElement.isJsonObject()) {
|
|
|
+ // 记录原始响应内容便于排查
|
|
|
+ log.error("data字段解析失败,原始响应:{}", getOrgIdentityInfo.getBody());
|
|
|
+ throw new JeecgBootException("未查询到授权信息");
|
|
|
+ }
|
|
|
+ JsonObject dataObj = dataElement.getAsJsonObject();
|
|
|
+ String orgRealnameStatus = dataObj.get("realnameStatus").getAsString();
|
|
|
return orgRealnameStatus.equals("1");
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public String getOrgAuthUrls(String orgName,String phoneNumber) throws EsignDemoException {
|
|
|
- EsignHttpResponse getOrgAuthUrl = getOrgAuthUrl(orgName,phoneNumber);
|
|
|
+ public String getOrgAuthUrls(String orgCode,String phoneNumber) throws EsignDemoException {
|
|
|
+ SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
|
|
|
+ EsignHttpResponse getOrgAuthUrl = getOrgAuthUrl(sysDepart.getDepartName(),phoneNumber);
|
|
|
JsonObject getOrgAuthUrlObject = gson.fromJson(getOrgAuthUrl.getBody(), JsonObject.class);
|
|
|
return getOrgAuthUrlObject.getAsJsonObject("data").get("authUrl").getAsString();
|
|
|
}
|
|
@@ -82,35 +113,122 @@ public class ESignServiceImpl implements IESignService {
|
|
|
@Override
|
|
|
public boolean uploadContractTemplate(AppContractInfoDTO appContractInfoDTO) throws EsignDemoException {
|
|
|
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
- EsignHttpResponse getUploadUrl = FileDemo.getUploadUrl(appContractInfoDTO.getFilePath());
|
|
|
+ String remoteUrl = "http://127.0.0.1:8080/jeecg-boot/sys/common/static/" + appContractInfoDTO.getFilePath();
|
|
|
+ String fileType = getFileExtension(appContractInfoDTO.getFilePath());
|
|
|
+ if (fileType.isEmpty()) {
|
|
|
+ throw new JeecgBootException("未指定文件类型");
|
|
|
+ }
|
|
|
+ EsignHttpResponse getUploadUrl = FileDemo.getUploadUrl(remoteUrl);
|
|
|
JsonObject getUploadUrlJsonObject = gson.fromJson(getUploadUrl.getBody(), JsonObject.class);
|
|
|
JsonObject data = getUploadUrlJsonObject.getAsJsonObject("data");
|
|
|
+ //文件id后续发起签署使用
|
|
|
+ String fileId =data.get("fileId").getAsString();
|
|
|
String fileUploadUrl =data.get("fileUploadUrl").getAsString();
|
|
|
- EsignHttpResponse uploadFileResponse = FileDemo.uploadFile(fileUploadUrl,appContractInfoDTO.getFilePath());
|
|
|
+ System.out.println("获取文件id以及文件上传地址成功,文件id:"+fileId);
|
|
|
+ System.out.println("上传链接:"+fileUploadUrl);
|
|
|
+ EsignHttpResponse uploadFileResponse = FileDemo.uploadFile(fileUploadUrl,remoteUrl);
|
|
|
JsonObject uploadFileResponseJsonObject = gson.fromJson(uploadFileResponse.getBody(), JsonObject.class);
|
|
|
int errCode = uploadFileResponseJsonObject.get("errCode").getAsInt();
|
|
|
- String fileId =data.get("fileId").getAsString();
|
|
|
- appAccountMapper.insert(new AppContractInfo()
|
|
|
- .setOrgCode(user.getOrgCode())
|
|
|
- .setFileId(fileId)
|
|
|
- .setContractName(appContractInfoDTO.getContractName())
|
|
|
- .setRemark(appContractInfoDTO.getRemark())
|
|
|
- .setCreateBy(user.getId())
|
|
|
- .setCreateTime(new java.util.Date())
|
|
|
- .setUpdateTime(new java.util.Date())
|
|
|
- .setUpdateBy(user.getId()));
|
|
|
- return errCode == 0;
|
|
|
+ System.out.println("文件上传成功,状态码:"+errCode);
|
|
|
+ if (errCode == 0) {
|
|
|
+ appAccountMapper.delete(Wrappers.<AppContractInfo>lambdaQuery()
|
|
|
+ .eq(AppContractInfo::getOrgCode, user.getOrgCode()));
|
|
|
+ appAccountMapper.insert(new AppContractInfo()
|
|
|
+ .setOrgCode(user.getOrgCode())
|
|
|
+ .setFileId(fileId)
|
|
|
+ .setContractName(appContractInfoDTO.getContractName())
|
|
|
+ .setRemark(appContractInfoDTO.getRemark())
|
|
|
+ .setCreateBy(user.getId())
|
|
|
+ .setCreateTime(new Date())
|
|
|
+ .setUpdateTime(new Date())
|
|
|
+ .setUpdateBy(user.getId())
|
|
|
+ .setContractType(fileType)); // 新增文件类型字段
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public String createSign(String fileId) throws EsignDemoException {
|
|
|
- EsignHttpResponse createByFile = createByFile();
|
|
|
- JSONObject createByFileJsonObject = JSONObject.parseObject(createByFile.getBody());
|
|
|
- String signFlowId = createByFileJsonObject.getJSONObject("data").getString("signFlowId");
|
|
|
- System.out.println("signFlowId:" + signFlowId);
|
|
|
- return signFlowId;
|
|
|
+ @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());
|
|
|
+ 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);
|
|
|
+ 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);
|
|
|
+ signFlowIds.add(signFlowId);
|
|
|
+ appContractSignMapper.insert(new AppContractSign().setId(generate32BitUUID)
|
|
|
+ .setSignFlowId(signFlowId)
|
|
|
+ .setOrderId(appOrder.getId())
|
|
|
+ .setOrgCode(appOrder.getOrgCode())
|
|
|
+ .setCreateTime(new Date())
|
|
|
+ .setUpdateTime(new Date()));
|
|
|
+ });
|
|
|
+ return signFlowIds;
|
|
|
+ }
|
|
|
+ public static String generate32BitUUID() {
|
|
|
+ // 生成标准 UUID(128 位)
|
|
|
+ UUID uuid = UUID.randomUUID();
|
|
|
+ // 去除连字符,得到 32 位字符串
|
|
|
+ return uuid.toString().replace("-", "");
|
|
|
}
|
|
|
-
|
|
|
@Override
|
|
|
public String getSignUrl(String signFlowId) throws EsignDemoException {
|
|
|
JSONObject signUrl = JSONObject.parseObject(SignDemo.signUrl(signFlowId).getBody());
|
|
@@ -119,16 +237,20 @@ public class ESignServiceImpl implements IESignService {
|
|
|
|
|
|
@Override
|
|
|
public String createTemplate(String fileId) throws EsignDemoException {
|
|
|
+ AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery().eq(AppContractInfo::getFileId, fileId));
|
|
|
+ DocTemplateDTO docTemplateDTO = new DocTemplateDTO()
|
|
|
+ .setDocTemplateName(appContractInfo.getContractName())
|
|
|
+ .setDocTemplateType(0)
|
|
|
+ .setFileId(fileId)
|
|
|
+ .setRedirectUrl(appContractInfo.getRedirectUrl());
|
|
|
/* 获取制作合同模板页面*/
|
|
|
- EsignHttpResponse getTemplateCreateUrl = getTemplateCreateUrl(fileId);
|
|
|
+ EsignHttpResponse getTemplateCreateUrl = getTemplateCreateUrl(docTemplateDTO);
|
|
|
Gson gson = new Gson();
|
|
|
JsonObject getTemplateCreateUrlObject = gson.fromJson(getTemplateCreateUrl.getBody(), JsonObject.class);
|
|
|
-
|
|
|
String docTemplateCreateUrl = getTemplateCreateUrlObject.getAsJsonObject("data").get("docTemplateCreateUrl").getAsString();
|
|
|
String docTemplateId = getTemplateCreateUrlObject.getAsJsonObject("data").get("docTemplateId").getAsString();
|
|
|
System.err.println("制作合同模板的页面链接:"+docTemplateCreateUrl);
|
|
|
System.err.println("合同模板id:"+docTemplateId);
|
|
|
- AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery().eq(AppContractInfo::getFileId, fileId));
|
|
|
appContractInfo.setDocTemplateId(docTemplateId);
|
|
|
appAccountMapper.updateById(appContractInfo);
|
|
|
return docTemplateCreateUrl;
|
|
@@ -136,8 +258,9 @@ public class ESignServiceImpl implements IESignService {
|
|
|
|
|
|
@Override
|
|
|
public String editContract(String docTemplateId) throws EsignDemoException {
|
|
|
+ AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery().eq(AppContractInfo::getDocTemplateId, docTemplateId));
|
|
|
/* 获取编辑合同模板页面*/
|
|
|
- EsignHttpResponse getTemplateEditUrl = getTemplateEditUrl();
|
|
|
+ EsignHttpResponse getTemplateEditUrl = getTemplateEditUrl(docTemplateId,appContractInfo.getRedirectUrl());
|
|
|
JsonObject getTemplateEditUrlObject = gson.fromJson(getTemplateEditUrl.getBody(), JsonObject.class);
|
|
|
String docTemplateEditUrl = getTemplateEditUrlObject.getAsJsonObject("data").get("docTemplateEditUrl").getAsString();
|
|
|
System.err.println("编辑合同模板的页面链接:"+docTemplateEditUrl);
|
|
@@ -163,7 +286,52 @@ public class ESignServiceImpl implements IESignService {
|
|
|
|
|
|
@Override
|
|
|
public List<AppContractInfo> queryContractInfo(String contractName) {
|
|
|
- return appAccountMapper.selectList(Wrappers.<AppContractInfo>lambdaQuery().like(AppContractInfo::getContractName,contractName));
|
|
|
+ LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ if(null != contractName){
|
|
|
+ return appAccountMapper.selectList(Wrappers.<AppContractInfo>lambdaQuery()
|
|
|
+ .like(AppContractInfo::getContractName,contractName).like(AppContractInfo::getOrgCode,user.getOrgCode()));
|
|
|
+ }else {
|
|
|
+ return appAccountMapper.selectList(Wrappers.<AppContractInfo>lambdaQuery().like(AppContractInfo::getOrgCode,user.getOrgCode()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文件扩展名
|
|
|
+ */
|
|
|
+ private String getFileExtension(String filename) {
|
|
|
+ if (filename == null || !filename.contains(".")) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ return tempFile;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取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");
|
|
|
}
|
|
|
}
|
|
|
|