增加日志打印,e签宝相关方法

This commit is contained in:
Jack 2025-12-05 21:34:47 +08:00
parent 97ee21b5fb
commit 992f25a224
4 changed files with 181 additions and 150 deletions

View File

@ -91,7 +91,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
@Resource
private OssService ossService;
/**
* 根据双方营业执照号码(或个人身份证)填充合同模版生成合同文件地址
* <p>
@ -109,47 +109,47 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
}
// 2. 获取平台方信息
EsignPlatformInfo esignPlatformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, "");
if (ObjectUtils.isEmpty(esignPlatformInfo)) {
EsignPlatformInfo platformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, "");
if (ObjectUtils.isEmpty(platformInfo)) {
log.error("[合同生成] 平台方(代理商方)信息缺失,请先配置平台信息");
return false;
}
if (StrUtil.isBlank(esignPlatformInfo.getDoc_template())) {
if (StrUtil.isBlank(platformInfo.getDoc_template())) {
log.error("[合同生成] 平台方合同模板信息为空,无法继续生成合同");
return false;
}
// 3. 获取入驻商家(审批通过的)的信息
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
if (shopMchEntry == null) {
ShopMchEntry mchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
if (mchEntry == null) {
log.error("[合同生成] 找不到商家入驻信息, storeId: {}", storeId);
return false;
}
// 4. 检查商家审批状态
if (!CommonConstant.MCH_APPR_STA_PASS.equals(shopMchEntry.getApproval_status())) {
log.error("[合同生成] 商家入驻审批未通过,当前状态: {}, storeId: {}", shopMchEntry.getApproval_status(), storeId);
if (!CommonConstant.MCH_APPR_STA_PASS.equals(mchEntry.getApproval_status())) {
log.error("[合同生成] 商家入驻审批未通过,当前状态: {}, storeId: {}", mchEntry.getApproval_status(), storeId);
return false;
}
ShopStoreBase shopStoreBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId);
if (ObjectUtils.isEmpty(shopStoreBase)) {
ShopStoreBase storeBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId);
if (ObjectUtils.isEmpty(storeBase)) {
log.error("[合同生成] 缺少商家店铺信息, storeId: {}", storeId);
return false;
}
BigDecimal splitRatio = shopStoreBase.getSplit_ratio();
BigDecimal splitRatio = storeBase.getSplit_ratio();
if (CheckUtil.isEmpty(splitRatio)) {
log.warn("[合同生成] 店铺分账比例为空,将使用入驻申请时设置的比例, storeId: {}", storeId);
splitRatio = shopMchEntry.getSplit_ratio();
splitRatio = mchEntry.getSplit_ratio();
}
// 5. 获取代理商信息
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMchEntry.getDistributor_id());
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(mchEntry.getDistributor_id());
// 6. 获取平台方合同模版信息
JSONArray templates = JSONUtil.parseArray(esignPlatformInfo.getDoc_template());
JSONArray templates = JSONUtil.parseArray(platformInfo.getDoc_template());
if (templates == null || templates.isEmpty()) {
log.error("[合同生成] 平台方(代理商方)合同模板信息缺失");
return false;
@ -158,27 +158,27 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 7. 准备基础数据
String today = DateUtil.format(new Date(), "yyyy年MM月dd日");
// 甲方公司名称甲方是个人的时候没有公司名直接用店铺名个人实名
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
? shopMchEntry.getBiz_license_company()
: shopMchEntry.getStore_name() + "" + shopMchEntry.getContact_name() + ")";
String platCompany = esignPlatformInfo.getLicense_company();
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
? mchEntry.getBiz_license_company()
: mchEntry.getStore_name() + "" + mchEntry.getContact_name() + ")";
String platCompany = platformInfo.getLicense_company();
// 甲方法人姓名甲方是个人的时候没有法人直接用个人实名
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
? shopMchEntry.getLegal_person_name()
: shopMchEntry.getContact_name();
String legalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
? shopMchEntry.getLegal_person_mobile()
: shopMchEntry.getLogin_mobile();
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
? mchEntry.getLegal_person_name()
: mchEntry.getContact_name();
String legalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
? mchEntry.getLegal_person_mobile()
: mchEntry.getLogin_mobile();
// 甲方法人身份证号甲方是个人的时候没有法人直接用个人身份证
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
? shopMchEntry.getLegal_person_id_number()
: shopMchEntry.getIndividual_id_number();
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
? mchEntry.getLegal_person_id_number()
: mchEntry.getIndividual_id_number();
String contractNumber = StringUtils.genLklOrderNo(4);
int successCnt = 0;
log.info("[合同生成] 开始为商家生成入驻合同文件, storeId: {}, 商家手机号: {}", storeId, shopMchEntry.getLogin_mobile());
log.info("[合同生成] 开始为商家生成入驻合同文件, storeId: {}, 商家手机号: {}", storeId, mchEntry.getLogin_mobile());
// 8. 遍历模版文件生成合同模版文件里有三份合同顺序排列的: 1.平台商户入驻服务框架协议 2.小发同城服务费结算 3.结算授权委托书
for (JSONObject template : templates.jsonIter()) {
@ -195,11 +195,11 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
fillJson.put("docTemplateId", templateId)
.put("fileName", fileName);
JSONArray list = new JSONArray();
JSONArray componentList = new JSONArray();
// 10. 填充合同组件数据
// 平台合同名称
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_contracts");
put("componentValue", "《平台商户入驻服务框架协议》和《小发同城服务费结算》");
}});
@ -207,7 +207,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 签署时间甲方
for (int i = 1; i <= 3; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_sign_date" + finalI);
put("componentValue", today);
}});
@ -216,34 +216,34 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 签署时间乙方
for (int i = 1; i <= 3; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_sign_date" + finalI);
put("componentValue", today);
}});
}
// 甲方公司名称
int mchCompanyCount = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? 17 : 16;
int mchCompanyCount = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type()) ? 17 : 16;
for (int i = 1; i <= mchCompanyCount; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_company" + finalI);
put("componentValue", mchCompany);
}});
}
// 特殊处理甲方收款账户方企业是公司名个人是个人实名
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())) {
list.add(new HashMap<String, Object>() {{
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())) {
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_company17");
put("componentValue", shopMchEntry.getContact_name());
put("componentValue", mchEntry.getContact_name());
}});
}
// 甲方法人姓名
for (int i = 1; i <= 4; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_legal_person_name" + finalI);
put("componentValue", legalPersonName);
}});
@ -252,63 +252,63 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 甲方法人手机号
for (int i = 1; i <= 3; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_legal_person_mobile" + finalI);
put("componentValue", legalPersonMobile);
}});
}
// 甲方身份证号码
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_legal_person_id_number1");
put("componentValue", legalPersonIdNumber);
}});
// 甲方店铺名称
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_store_name1");
put("componentValue", shopMchEntry.getStore_name());
put("componentValue", mchEntry.getStore_name());
}});
// 规则编号
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "rule_no");
put("componentValue", 3);
}});
// 分账比例
BigDecimal finalSplitRatio = splitRatio;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_ratio");
put("componentValue", finalSplitRatio);
}});
// 结算方式
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "settlement_method");
put("componentValue", shopMchEntry.getSettlement_method());
put("componentValue", mchEntry.getSettlement_method());
}});
// 甲方地址
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_address1");
put("componentValue", shopMchEntry.getStore_address());
put("componentValue", mchEntry.getStore_address());
}});
// 甲方银行
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_bank1");
put("componentValue", shopMchEntry.getBank_name());
put("componentValue", mchEntry.getBank_name());
}});
// 甲方账户号
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "mch_account_number1");
put("componentValue", shopMchEntry.getAccount_number());
put("componentValue", mchEntry.getAccount_number());
}});
// 乙方公司名称
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_company1");
put("componentValue", platCompany + "和代理商");
}});
@ -316,7 +316,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 其他乙方公司名称
for (int i = 2; i <= 5; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_company" + finalI);
put("componentValue", platCompany);
}});
@ -325,58 +325,58 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
// 乙方手机号
for (int i = 1; i <= 2; i++) {
int finalI = i;
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_mobile" + finalI);
put("componentValue", esignPlatformInfo.getLegal_person_mobile());
put("componentValue", platformInfo.getLegal_person_mobile());
}});
}
// 乙方邮箱重复填充但保持原逻辑
for (int i = 0; i < 6; i++) {
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_email1");
put("componentValue", esignPlatformInfo.getEmail());
put("componentValue", platformInfo.getEmail());
}});
}
// 乙方银行
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_bank1");
put("componentValue", esignPlatformInfo.getRec_acc_bank_name());
put("componentValue", platformInfo.getRec_acc_bank_name());
}});
// 乙方账户号
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "plat_account_number1");
put("componentValue", esignPlatformInfo.getRec_acc_card_no());
put("componentValue", platformInfo.getRec_acc_card_no());
}});
// 11. 处理代理商相关数据
if (distributor != null) {
// 有代理商的时候填充代理商的信息
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_company1");
put("componentValue", distributor.getLicense_company());
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_mobile1");
put("componentValue", distributor.getLegal_person_mobile());
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_company2");
put("componentValue", distributor.getLicense_company());
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_bank1");
put("componentValue", distributor.getRec_acc_bank_name());
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_account_number1");
put("componentValue", distributor.getRec_acc_card_no());
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_sign_date1");
put("componentValue", today);
}});
@ -384,24 +384,24 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
log.debug("[合同生成] 已填充代理商信息: {}", distributor.getLicense_company());
} else {
// 无代理商时填充默认值
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_company1");
put("componentValue", "");
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_mobile1");
put("componentValue", "");
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_company2");
put("componentValue", "");
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_bank1");
put("componentValue", "");
}});
list.add(new HashMap<String, Object>() {{
componentList.add(new HashMap<String, Object>() {{
put("componentKey", "distr_account_number1");
put("componentValue", "");
}});
@ -409,7 +409,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
log.debug("[合同生成] 未配置代理商信息,使用默认值");
}
fillJson.put("components", list);
fillJson.put("components", componentList);
String jsonParam = fillJson.toString();
String apiAddr = "/v3/files/create-by-doc-template";
@ -420,19 +420,19 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
appId, appSecret, jsonParam, requestType.name(), apiAddr, debug);
// 发起接口请求
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(
EsignHttpResponse response = EsignHttpHelper.doCommHttp(
serverUrl, apiAddr, requestType, jsonParam, header, debug);
log.info("[合同生成] 调用电子签约服务生成合同文件: status={}, response={}",
createByDocTemplate.getStatus(), createByDocTemplate.getBody());
response.getStatus(), response.getBody());
if (createByDocTemplate.getStatus() != 200) {
log.error("[合同生成] 调用电子签约服务生成合同文件失败, HTTP状态码: {}", createByDocTemplate.getStatus());
if (response.getStatus() != 200) {
log.error("[合同生成] 调用电子签约服务生成合同文件失败, HTTP状态码: {}", response.getStatus());
continue; // 继续处理下一个模版
}
// 13. 解析API返回结果
JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody()).getJSONObject("data");
JSONObject jsonObject = JSONUtil.parseObj(response.getBody()).getJSONObject("data");
String fileDownloadUrl = jsonObject.getStr("fileDownloadUrl");
String fileId = jsonObject.getStr("fileId");
@ -442,13 +442,13 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
}
// 14. 创建合同填充文件记录
EsignContractFillingFile esignContractFillingFile = new EsignContractFillingFile();
esignContractFillingFile.setUnsigned_contract_url(fileDownloadUrl);
esignContractFillingFile.setFile_id(fileId);
EsignContractFillingFile contractFillingFile = new EsignContractFillingFile();
contractFillingFile.setUnsigned_contract_url(fileDownloadUrl);
contractFillingFile.setFile_id(fileId);
// 15. 上传合同文件到OSS
String cosFileName = TENGXUN_DEFAULT_DIR.concat("/contract/")
.concat(shopMchEntry.getLogin_mobile()).concat("/")
.concat(mchEntry.getLogin_mobile()).concat("/")
.concat(fileId).concat(".pdf");
String localFileUrl = ossService.uploadObject4OSS(fileDownloadUrl, cosFileName);
@ -457,42 +457,42 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
continue;
}
esignContractFillingFile.setUnsigned_contract_local_url(localFileUrl);
esignContractFillingFile.setDoc_template_id(templateId);
esignContractFillingFile.setContract_number(contractNumber + seq);
esignContractFillingFile.setContract_name("商户入驻小发同城平台合同协议");
esignContractFillingFile.setStore_id(Convert.toStr(storeId));
esignContractFillingFile.setMobile(shopMchEntry.getLogin_mobile());
esignContractFillingFile.setDoc_template_filling_values(jsonParam);
esignContractFillingFile.setSeq(seq);
esignContractFillingFile.setStatus(CommonConstant.Enable);
contractFillingFile.setUnsigned_contract_local_url(localFileUrl);
contractFillingFile.setDoc_template_id(templateId);
contractFillingFile.setContract_number(contractNumber + seq);
contractFillingFile.setContract_name("商户入驻小发同城平台合同协议");
contractFillingFile.setStore_id(Convert.toStr(storeId));
contractFillingFile.setMobile(mchEntry.getLogin_mobile());
contractFillingFile.setDoc_template_filling_values(jsonParam);
contractFillingFile.setSeq(seq);
contractFillingFile.setStatus(CommonConstant.Enable);
// 16. 获取印章位置信息
Map<String, JSONArray> signPositionMap = getSignPosition(templateId, fileId);
if (signPositionMap != null) {
if (signPositionMap.get("mch") != null) {
esignContractFillingFile.setMch_sign_position(signPositionMap.get("mch").toString());
contractFillingFile.setMch_sign_position(signPositionMap.get("mch").toString());
}
if (signPositionMap.get("plat") != null) {
esignContractFillingFile.setPlat_sign_position(signPositionMap.get("plat").toString());
contractFillingFile.setPlat_sign_position(signPositionMap.get("plat").toString());
}
if (distributor != null && signPositionMap.get("distr") != null) {
// 如果有代理商则把代理商的印章位置信息写入数据库
esignContractFillingFile.setDistri_sign_position(signPositionMap.get("distr").toString());
contractFillingFile.setDistri_sign_position(signPositionMap.get("distr").toString());
}
}
// 17. 保存合同填充记录并预创建签署流程
if (esignContractFillingFileService.trySaveRecord(esignContractFillingFile)) {
if (esignContractFillingFileService.trySaveRecord(contractFillingFile)) {
successCnt += 1;
log.debug("[合同生成] 合同记录保存成功, fileId: {}", fileId);
// 预新增一个签署合同记录
boolean preCreateResult = esignContractService.preCreateSignFlow(
esignContractFillingFile.getMobile(), esignContractFillingFile.getDoc_template_id());
contractFillingFile.getMobile(), contractFillingFile.getDoc_template_id());
log.debug("[合同生成] 预创建签署流程结果: {}, 商家手机号: {}, 模板ID: {}",
preCreateResult, esignContractFillingFile.getMobile(), esignContractFillingFile.getDoc_template_id());
preCreateResult, contractFillingFile.getMobile(), contractFillingFile.getDoc_template_id());
} else {
log.error("[合同生成] 保存合同记录失败, fileId: {}", fileId);
}

View File

@ -167,61 +167,77 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
@Override
public Pair<Boolean, String> innerSignFlowCreateByFile(Integer storeId) {
// 1. 参数校验
if (CheckUtil.isEmpty(storeId)) {
return Pair.of(false, "缺少必要参数!");
}
// 组织和填充商家店铺的模版数据
// 2. 组织和填充商家店铺的模版数据
Boolean isFill = esignContractFillingFileService.fillDocTemplate(storeId);
if (!isFill) {
return Pair.of(false, "合同信息未准备好,请检查商家入驻手续是否已完成!");
}
// 3. 获取商家合同信息
EsignContract esignContract = getEsignContractByStoreId(storeId);
if (esignContract == null) {
return Pair.of(false, "未找到商家合同信息");
}
// 检查商户入驻信息是否被审核通过
// 检查店铺是否已经申请过入驻
// 4. 检查商户入驻信息是否被审核通过
Integer apprStatus = shopMchEntryService.getApprovalStatus(esignContract.getMch_mobile());
if (!CommonConstant.MCH_APPR_STA_PASS.equals(apprStatus)) {
return Pair.of(false, "请先审核商家入驻信息");
}
//"{\"docs\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"fileName\":\"小发同城平台商户合作协议.pdf\"}],\"signFlowConfig\":{\"signFlowTitle\":\"小发同城平台商户合作协议\",\"signFlowExpireTime\":1746844718000,\"autoFinish\":true,\"notifyUrl\":\"https://mall.gpxscs.cn/asyn/notify\",\"redirectConfig\":{\"redirectUrl\":\"https://mall.gpxscs.cn/\"}},\"signers\":[{\"signConfig\":{\"signOrder\":1},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":0,\"psnSignerInfo\":{\"psnAccount\":\"13128997057\",\"psnInfo\":{\"psnName\":\"潘军杰\"}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":40,\"positionX\":472.3607,\"positionY\":277.19104}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":470.58798,\"positionY\":589.14496}}}]},{\"signConfig\":{\"signOrder\":2},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":1,\"orgSignerInfo\":{\"orgName\":\"桂平发发网络有限公司\",\"orgInfo\":{\"orgIDCardNum\":\"91450881MADEQ92533\",\"orgIDCardType\":\"CRED_ORG_USCC\"},\"transactorInfo\":{\"psnAccount\":\"17777525395\",\"psnInfo\":{\"psnName\":\"谢能坤\"}}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":2,\"positionX\":479.04996,\"positionY\":357.2327}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":255.96832,\"positionY\":588.4553}}}]}]}";
// esignContractService.
// 5. 获取签署请求参数
String jsonParams = esignContract.getReq_params();
if (StrUtil.isBlank(jsonParams)) {
return Pair.of(false, "合同请求参数为空");
}
try {
//请求方法
// 6. 调用E签宝API创建签署流程
EsignRequestType requestType = EsignRequestType.POST;
String apiAddr = "/v3/sign-flow/create-by-file";
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(appId, appSecret, jsonParams, requestType.name(), apiAddr, true);
//发起接口请求
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(serverUrl, apiAddr, requestType, jsonParams, header, debug);
log.info("发起合同签署流程返回消息:{},{}", createByDocTemplate.getStatus(), createByDocTemplate.getBody());
if (createByDocTemplate.getStatus() != 200) {
if (createByDocTemplate.getBody() != null) {
JSONObject resBody = JSONUtil.parseObj(createByDocTemplate.getBody());
log.error("e签宝请求失败返回状态码{}, {}", createByDocTemplate.getStatus(), resBody.getStr("message"));
return Pair.of(false, "e签宝请求失败{}" + resBody.getStr("message"));
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(
appId, appSecret, jsonParams, requestType.name(), apiAddr, true);
EsignHttpResponse response = EsignHttpHelper.doCommHttp(
serverUrl, apiAddr, requestType, jsonParams, header, debug);
log.info("发起合同签署流程返回消息status={}, body={}", response.getStatus(), response.getBody());
// 7. 处理API响应结果
if (response.getStatus() != HttpStatus.OK.value()) {
String errorMsg = "E签宝请求失败";
if (response.getBody() != null) {
try {
JSONObject resBody = JSONUtil.parseObj(response.getBody());
errorMsg += "" + resBody.getStr("message", "未知错误");
} catch (Exception parseException) {
log.warn("解析E签宝错误响应失败{}", response.getBody());
}
}
return Pair.of(false, "e签宝请求失败!");
log.error("E签宝请求失败返回状态码{}", response.getStatus());
return Pair.of(false, errorMsg);
}
JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody());
// 8. 解析成功响应数据
JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
Integer code = jsonObject.getInt("code");
String signFlowId = (String) jsonObject.getByPath("data.signFlowId");
String signFlowId = jsonObject.getByPath("data.signFlowId", String.class);
if (code == null || code != 0 || StrUtil.isBlank(signFlowId)) {
log.error("e签宝请求失败返回status码{}", code);
return Pair.of(false, "e签宝请求失败!");
log.error("E签宝请求失败返回 code 码:{}", code);
return Pair.of(false, "E签宝请求失败!");
}
//合同签署状态-1预备数据阶段0-等待签署1-已部分签署2-已完成所有签署方完成签署3-已撤销发起方撤销签署任务5-已过期签署截止日到期后触发7-已拒签签署方拒绝签署
Boolean success = updateContractFlowIdAndFileUrl(esignContract.getId(), signFlowId, CommonConstant.CONTRACT_SIGN_STA_ING, null);
// 9. 更新合同流程状态
Boolean success = updateContractFlowIdAndFileUrl(
esignContract.getId(), signFlowId, CommonConstant.CONTRACT_SIGN_STA_ING, null);
if (!success) {
log.error("更新合同流程状态失败");
return Pair.of(false, "更新合同流程状态失败");
@ -229,12 +245,13 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
return Pair.of(true, "合同流程创建成功合同流程ID" + signFlowId);
} catch (EsignDemoException e) {
} catch (Exception e) {
log.error("发起签署电子合同请求失败:", e);
return Pair.of(false, "发起签署电子合同请求失败!");
}
}
/**
* 签署流程结束通知
*
@ -251,14 +268,14 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
String timestamp = request.getHeader("X-Tsign-Open-TIMESTAMP");
if (StrUtil.isBlank(reqAppId) || StrUtil.isBlank(signature) || StrUtil.isBlank(timestamp)) {
log.warn("e签宝异步通知缺少必要参数: reqAppId={}, signature={}, timestamp={}", reqAppId, signature, timestamp);
log.warn("E签宝异步通知缺少必要参数: reqAppId={}, signature={}, timestamp={}", reqAppId, signature, timestamp);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new JSONObject().put("code", 400).put("msg", "缺少必要参数").toString());
}
// 2. 验证AppId是否匹配
if (!reqAppId.equals(appId)) {
log.warn("e签宝异步通知AppId不匹配: 请求AppId={}, 配置AppId={}", reqAppId, appId);
log.warn("E签宝异步通知AppId不匹配: 请求AppId={}, 配置AppId={}", reqAppId, appId);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new JSONObject().put("code", 400).put("msg", "appId 有误").toString());
}
@ -278,7 +295,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
log.debug("header里面的签名值---------->>>>>> {}", signature);
if (!mySignature.equals(signature)) {
log.warn("e签宝异步通知签名校验失败: 计算签名={}, 请求签名={}", mySignature, signature);
log.warn("E签宝异步通知签名校验失败: 计算签名={}, 请求签名={}", mySignature, signature);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new JSONObject().put("code", 400).put("msg", "签名校验失败").toString());
}
@ -288,7 +305,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
try {
reqBodyJSON = JSONUtil.parseObj(requestBody);
} catch (Exception e) {
log.error("解析e签宝异步通知请求体失败: requestBody={}", requestBody, e);
log.error("解析E签宝异步通知请求体失败: requestBody={}", requestBody, e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new JSONObject().put("code", 400).put("msg", "请求体格式错误").toString());
}
@ -298,7 +315,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
Integer signResult = reqBodyJSON.getInt("signResult");
if (StrUtil.isBlank(action) || StrUtil.isBlank(signFlowId)) {
log.warn("e签宝异步通知缺少必要业务参数: action={}, signFlowId={}", action, signFlowId);
log.warn("E签宝异步通知缺少必要业务参数: action={}, signFlowId={}", action, signFlowId);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new JSONObject().put("code", 400).put("msg", "返回数据有误").toString());
}
@ -391,7 +408,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString());
}
} catch (Exception e) {
log.error("处理e签宝异步通知异常: action={}, signFlowId={}", action, signFlowId, e);
log.error("处理E签宝异步通知异常: action={}, signFlowId={}", action, signFlowId, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new JSONObject().put("code", 500).put("msg", "处理通知异常").toString());
}
@ -728,7 +745,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
}
/**
* e签宝官网根据合同流程ID获取完成签署生效的合同文件地址
* E签宝官网根据合同流程ID获取完成签署生效的合同文件地址
* <p>
* 收到异步通知签署完成之后获取合同文件地址保存并上传到 oss
*
@ -837,7 +854,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
}
// e签宝签名相关方法
// E签宝签名相关方法
/**
* 根据商家的注册手机号新增或更新签署合同记录

View File

@ -137,33 +137,47 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl<ShopNumberSeqMappe
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@DistributedLock(
key = "CREATENEXTSEQ_LOCK", // 锁的key
waitTime = 3, // 等待3秒
leaseTime = 10, // 锁持有10秒
waitTime = 3, // 等待3秒
leaseTime = 10, // 锁持有10秒
errorMsg = "生成ID繁忙请稍后重试" // 自定义错误消息
)
public synchronized Pair<Long, String> createNextSeqPair(String prefix) {
String ymd = DateUtil.format(new Date(), "yyyyMMdd");
String id = String.format("%s_%s_", prefix, ymd);
ShopNumberSeq shopNumberSeq = this.baseMapper.selectById(id);
if (shopNumberSeq == null) {
shopNumberSeq = new ShopNumberSeq();
shopNumberSeq.setPrefix(id);
shopNumberSeq.setNumber(1L);
if (!save(shopNumberSeq)) {
return null;
// 参数校验
if (prefix == null || prefix.trim().isEmpty()) {
return null;
}
try {
String ymd = DateUtil.format(new Date(), "yyyyMMdd");
String seqId = String.format("%s_%s_", prefix, ymd);
// 查询或创建序列记录
ShopNumberSeq shopNumberSeq = this.baseMapper.selectById(seqId);
if (shopNumberSeq == null) {
shopNumberSeq = new ShopNumberSeq();
shopNumberSeq.setPrefix(seqId);
shopNumberSeq.setNumber(1L);
if (!save(shopNumberSeq)) {
return null;
}
}
}
String order_id = String.format("%s_%s_%s", prefix, ymd, shopNumberSeq.getNumber());
shopNumberSeq.setPrefix(id);
boolean flag = edit(shopNumberSeq);
if (flag) {
return Pair.of(shopNumberSeq.getNumber(), order_id);
}
// 获取当前序列号
Long number = shopNumberSeq.getNumber();
String orderId = String.format("%s_%s_%s", prefix, ymd, number);
return null;
// 增加序列号并更新
// shopNumberSeq.setNumber(number + 1);
shopNumberSeq.setPrefix(seqId);
return edit(shopNumberSeq) ? Pair.of(number, orderId) : null;
} catch (Exception e) {
log.error("生成序列号失败prefix: {}", prefix, e);
return null;
}
}
/**
* 得到下一个Id
*

View File

@ -6421,7 +6421,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
type_code = StrUtil.isBlank(type_code) ? "DD" : type_code;
String xid = RootContext.getXID();
RootContext.unbind();
Pair<Long, String> seqPair = shopNumberSeqService.createNextSeqPair(type_code);// 位数的序号 DD_20251205_1 2025-12-05 1
Pair<Long, String> seqPair = shopNumberSeqService.createNextSeqPair(type_code);// 位数的序号 DD_20251205_12-> pair 12, 2025-12-05
String order_id = seqPair.getSecond();
Long seqNo = seqPair.getFirst(); // 序号 DD_20251205_1 得出 1
RootContext.bind(xid);