Merge remote-tracking branch 'origin/master'

master
zhuliang 2 weeks ago
commit 8330c24ba3
  1. BIN
      micro-modules/micro-print/libs/esspdf-client-1.5.0-SNAPSHOT.jar
  2. BIN
      micro-modules/micro-print/libs/jackson-all-2.0.1.jar
  3. BIN
      micro-modules/micro-print/libs/jackson-module-jaxb-annotations-2.0.6.jar
  4. 21
      micro-modules/micro-print/pom.xml
  5. 30
      micro-modules/micro-print/src/main/java/com/sinosoft/print/core/files/WordToPdfConverter.java
  6. 32
      micro-modules/micro-print/src/main/java/com/sinosoft/print/core/sign/strategy/SignByCA.java
  7. 7
      micro-modules/micro-print/src/main/java/com/sinosoft/print/domain/ContPrintRequestReturn.java
  8. 15
      micro-modules/micro-print/src/main/java/com/sinosoft/print/domain/bo/BiliCard.java
  9. 8
      micro-modules/micro-print/src/main/java/com/sinosoft/print/domain/bo/ContPrintCallbackReqBo.java
  10. 30
      micro-modules/micro-print/src/main/java/com/sinosoft/print/service/impl/ContPrintCallbackServiceImpl.java
  11. 46
      micro-modules/micro-print/src/main/java/com/sinosoft/print/service/impl/FileUploadAndDownService.java
  12. 2
      micro-visual/micro-xxljob/src/main/resources/mapper/xxljob/XxlJobLogMapper.xml

@ -201,6 +201,27 @@
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId> <artifactId>jackson-dataformat-xml</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.esspdf</groupId>
<artifactId>esspdf-common</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/esspdf-client-1.5.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>com.jackson</groupId>
<artifactId>jackson-common</artifactId>
<version>2.0.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/jackson-all-2.0.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.jaxb</groupId>
<artifactId>jaxb-common</artifactId>
<version>2.0.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/jackson-module-jaxb-annotations-2.0.6.jar</systemPath>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -32,6 +32,7 @@ import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -152,6 +153,35 @@ public void mergeDocuments(List<InputStream> inputStreams, OutputStream outputSt
// 调用方应负责在使用完毕后清理返回的临时文件 // 调用方应负责在使用完毕后清理返回的临时文件
} }
public static void main(String[] args) throws Exception {
// ================== 1. 准备 PDF 文件 ==================
File pdf1 = new File("C:\\Users\\szy\\Desktop\\FZ接口\\a.pdf");
File pdf2 = new File("C:\\Users\\szy\\Desktop\\FZ接口\\b.pdf");
List<File> pdfFiles = Arrays.asList(pdf1, pdf2);
// ================== 2. 输出文件 ==================
File outputFile = new File("C:\\Users\\szy\\Desktop\\FZ接口\\c.pdf");
try (OutputStream os = new FileOutputStream(outputFile)) {
new WordToPdfConverter().mergePdfDocumentsWithPageNumbers(
pdfFiles,
os,
1, // startPageNumber
300 // totalPages(可写预估)
);
}
// ================== 3. 简单校验 ==================
if (!outputFile.exists()) {
throw new RuntimeException("❌ 合并失败,文件不存在");
}
System.out.println("✅ PDF 合并成功");
System.out.println("📁 输出路径:" + outputFile.getAbsolutePath());
}
public void mergePdfDocumentsWithPageNumbers( public void mergePdfDocumentsWithPageNumbers(
List<File> pdfFiles, List<File> pdfFiles,
OutputStream finalOutput, OutputStream finalOutput,

@ -1,7 +1,7 @@
package com.sinosoft.print.core.sign.strategy; package com.sinosoft.print.core.sign.strategy;
//import cn.org.bjca.seal.esspdf.client.message.ChannelMessage; import cn.org.bjca.seal.esspdf.client.message.ChannelMessage;
//import cn.org.bjca.seal.esspdf.client.tools.ESSPDFClientTool; import cn.org.bjca.seal.esspdf.client.tools.ESSPDFClientTool;
import com.sinosoft.common.core.exception.ServiceException; import com.sinosoft.common.core.exception.ServiceException;
import com.sinosoft.print.core.constant.PrintTempConstants; import com.sinosoft.print.core.constant.PrintTempConstants;
import com.sinosoft.print.domain.vo.SignServiceConfigVo; import com.sinosoft.print.domain.vo.SignServiceConfigVo;
@ -18,22 +18,22 @@ public class SignByCA implements SignInterface {
@Override @Override
public byte[] sign(byte[] signFile, String signNumber,SignServiceConfigVo configVo,String fileName, Map<String, Object> signParams) { public byte[] sign(byte[] signFile, String signNumber,SignServiceConfigVo configVo,String fileName, Map<String, Object> signParams) {
// try { try {
// ESSPDFClientTool tool = new ESSPDFClientTool(configVo.getIp(),configVo.getPort().intValue()); ESSPDFClientTool tool = new ESSPDFClientTool(configVo.getIp(),configVo.getPort().intValue());
// tool.setRespTimeout(configVo.getReadTimeout().intValue()); tool.setRespTimeout(configVo.getReadTimeout().intValue());
// tool.setTimeout(configVo.getConnectTimeout().intValue()); tool.setTimeout(configVo.getConnectTimeout().intValue());
// ChannelMessage message = tool.pdfSign(signNumber,signFile); ChannelMessage message = tool.pdfSign(signNumber,signFile);
// if(PrintTempConstants.SIGN_SUCESS_CODE.equals(message.getStatusCode())) { if(PrintTempConstants.SIGN_SUCESS_CODE.equals(message.getStatusCode())) {
// return message.getBody(); return message.getBody();
// }else { }else {
// throw new ServiceException(message.getStatusInfo()); throw new ServiceException(message.getStatusInfo());
// } }
// } catch (Exception e) { } catch (Exception e) {
// throw new ServiceException("签章失败"+e.getMessage()); throw new ServiceException("签章失败"+e.getMessage());
// } }
//去除私有包 //去除私有包
return new byte[0]; // return new byte[0];
} }
@Override @Override

@ -1,7 +1,10 @@
package com.sinosoft.print.domain; package com.sinosoft.print.domain;
import com.sinosoft.print.domain.bo.BiliCard;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* 保单打印结果回传请求体详细信息 * 保单打印结果回传请求体详细信息
*/ */
@ -20,5 +23,7 @@ public class ContPrintRequestReturn {
//打印日期 //打印日期
String printDate; String printDate;
//打印时间 //打印时间
String printTime; String printSize;
//单证信息
List<BiliCard> biliCardList;
} }

@ -0,0 +1,15 @@
package com.sinosoft.print.domain.bo;
import lombok.Data;
/**
* Description:
* Author:szy
* Create:2026/06/04
*/
@Data
public class BiliCard {
private String bilicardMain;
private String bilicardnoMain;
}

@ -2,6 +2,8 @@ package com.sinosoft.print.domain.bo;
import lombok.Data; import lombok.Data;
import java.util.List;
@Data @Data
public class ContPrintCallbackReqBo { public class ContPrintCallbackReqBo {
//文件名 //文件名
@ -13,11 +15,15 @@ public class ContPrintCallbackReqBo {
//打印日期 //打印日期
private String printDate; private String printDate;
//打印时间 //打印时间
private String printTime; private String printSize;
//打印类型 //打印类型
private String contType; private String contType;
//流水号 //流水号
String serialNo; String serialNo;
//保单号 //保单号
String grpContNo; String grpContNo;
//单证信息
List<BiliCard> biliCardList;
} }

@ -4,9 +4,12 @@ import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dtflys.forest.exceptions.ForestNetworkException; import com.dtflys.forest.exceptions.ForestNetworkException;
import com.dtflys.forest.exceptions.ForestRuntimeException; import com.dtflys.forest.exceptions.ForestRuntimeException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sinosoft.print.domain.ClientInfoReturn; import com.sinosoft.print.domain.ClientInfoReturn;
import com.sinosoft.print.domain.ContPrintRequestReturn; import com.sinosoft.print.domain.ContPrintRequestReturn;
import com.sinosoft.print.domain.InputData; import com.sinosoft.print.domain.InputData;
import com.sinosoft.print.domain.bo.BiliCard;
import com.sinosoft.print.domain.bo.ContPrintCallbackReqBo; import com.sinosoft.print.domain.bo.ContPrintCallbackReqBo;
import com.sinosoft.print.domain.bo.ContPrintCallbackReturnBo; import com.sinosoft.print.domain.bo.ContPrintCallbackReturnBo;
import com.sinosoft.print.domain.PrintConttrackLog; import com.sinosoft.print.domain.PrintConttrackLog;
@ -56,7 +59,7 @@ public class ContPrintCallbackServiceImpl implements IContPrintCallbackService {
for (Map.Entry<String, JsonNode> entry : callbackReqMap.entrySet()) { for (Map.Entry<String, JsonNode> entry : callbackReqMap.entrySet()) {
String fileName = entry.getKey(); String fileName = entry.getKey();
JsonNode jsonNode = entry.getValue(); JsonNode jsonNode = entry.getValue();
if (jsonNode == null || !jsonNode.has("PrintDate") || !jsonNode.has("PrintTime") || !jsonNode.has("PrintFlag") || !jsonNode.has("ContType")) { if (jsonNode == null) {
log.warn("文件:[{}] 数据或关键字段为空", fileName); log.warn("文件:[{}] 数据或关键字段为空", fileName);
resultList.add(new PrintResultNotifyInfoObj(ResultProcStatusEnum.EMPTY_FILE_NAME, fileName)); resultList.add(new PrintResultNotifyInfoObj(ResultProcStatusEnum.EMPTY_FILE_NAME, fileName));
continue; continue;
@ -74,11 +77,23 @@ public class ContPrintCallbackServiceImpl implements IContPrintCallbackService {
private ResultProcStatusEnum processSingleData(String fileName, JsonNode jsonNode) { private ResultProcStatusEnum processSingleData(String fileName, JsonNode jsonNode) {
ContPrintCallbackReqBo callbackReq = new ContPrintCallbackReqBo(); ContPrintCallbackReqBo callbackReq = new ContPrintCallbackReqBo();
callbackReq.setPringName(fileName); callbackReq.setPringName(fileName);
callbackReq.setPrintDate(jsonNode.get("PrintDate").asText()); callbackReq.setPrintDate(jsonNode.get("PRINT_DATE").asText());
callbackReq.setPrintTime(jsonNode.get("PrintTime").asText()); callbackReq.setPrintResult(jsonNode.get("PRINT_STATUS").asText());
callbackReq.setPrintResult(jsonNode.get("PrintFlag").asText()); callbackReq.setContType(jsonNode.get("DM").asText());
callbackReq.setContType(jsonNode.get("ContType").asText());
callbackReq.setErrorMsg(jsonNode.has("ErrorMsg") ? jsonNode.get("ErrorMsg").asText() : null); callbackReq.setErrorMsg(jsonNode.has("ErrorMsg") ? jsonNode.get("ErrorMsg").asText() : null);
callbackReq.setGrpContNo(jsonNode.get("POLICY_NO").asText());
callbackReq.setSerialNo(jsonNode.get("PRINT_ID").asText());
callbackReq.setPrintSize(jsonNode.get("PRINT_SIZE").asText());
JsonNode bilcardNode = jsonNode.get("BILCARD_LIST");
ObjectMapper objectMapper = new ObjectMapper();
List<BiliCard> biliCards = objectMapper.convertValue(
bilcardNode,
new TypeReference<List<BiliCard>>() {}
);
callbackReq.setBiliCardList(biliCards);
// 根据文件名查询数据库,获取业务流水号和保单号 // 根据文件名查询数据库,获取业务流水号和保单号
LambdaQueryWrapper<PrintConttrackLog> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<PrintConttrackLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PrintConttrackLog::getXmlfileName, fileName); queryWrapper.eq(PrintConttrackLog::getXmlfileName, fileName);
@ -88,7 +103,7 @@ public class ContPrintCallbackServiceImpl implements IContPrintCallbackService {
return ResultProcStatusEnum.ERROR; return ResultProcStatusEnum.ERROR;
} }
callbackReq.setSerialNo(printConttrackLog.getBussinessNo()); callbackReq.setSerialNo(printConttrackLog.getBussinessNo());
callbackReq.setGrpContNo(printConttrackLog.getContNo()); // callbackReq.setGrpContNo(printConttrackLog.getContNo());
log.info("文件:[{}] 查询到业务流水号:[{}],保单号:[{}]", fileName, printConttrackLog.getBussinessNo(), printConttrackLog.getContNo()); log.info("文件:[{}] 查询到业务流水号:[{}],保单号:[{}]", fileName, printConttrackLog.getBussinessNo(), printConttrackLog.getContNo());
return processCallbackReq(callbackReq); return processCallbackReq(callbackReq);
@ -108,7 +123,8 @@ public class ContPrintCallbackServiceImpl implements IContPrintCallbackService {
contPrintRequestReturn.setPrintFlag(callbackReq.getPrintResult()); contPrintRequestReturn.setPrintFlag(callbackReq.getPrintResult());
contPrintRequestReturn.setErrorMsg(callbackReq.getErrorMsg()); contPrintRequestReturn.setErrorMsg(callbackReq.getErrorMsg());
contPrintRequestReturn.setPrintDate(callbackReq.getPrintDate()); contPrintRequestReturn.setPrintDate(callbackReq.getPrintDate());
contPrintRequestReturn.setPrintTime(callbackReq.getPrintTime()); contPrintRequestReturn.setPrintSize(callbackReq.getPrintSize());
contPrintRequestReturn.setBiliCardList(callbackReq.getBiliCardList());
//保单打印请求体 //保单打印请求体
InputData inputData = new InputData(); InputData inputData = new InputData();
inputData.setResponse(List.of(contPrintRequestReturn)); inputData.setResponse(List.of(contPrintRequestReturn));

@ -55,6 +55,8 @@ import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -135,7 +137,16 @@ public class FileUploadAndDownService {
operate = "electronicUp"; operate = "electronicUp";
} }
PrintFtpConfig ftpConfig = getFtpConfig(operate); PrintFtpConfig ftpConfig = getFtpConfig(operate);
if(PrintTempConstants.FTP.equals(ftpConfig.getType())){ if(ftpConfig == null){
/*
在没有ftp或者sftp配置时将报文保存在服务器临时目录
Windows C:\Users\用户名\AppData\Local\Temp\demo.txt
Linux /tmp/demo.txt
*/
log.info(formattedXml);
System.out.println(formattedXml);
writeToTemp(fileName,formattedXml);
}else if(PrintTempConstants.FTP.equals(ftpConfig.getType())){
try { try {
log.info("开始使用FTP的方式上传xml文件"); log.info("开始使用FTP的方式上传xml文件");
FTPUtils.upload(ftpConfig.getIpAddress(),ftpConfig.getPort().intValue(),ftpConfig.getUsername(),ftpConfig.getPassword(),xmlInputStream,ftpConfig.getBasePath(),fileName); FTPUtils.upload(ftpConfig.getIpAddress(),ftpConfig.getPort().intValue(),ftpConfig.getUsername(),ftpConfig.getPassword(),xmlInputStream,ftpConfig.getBasePath(),fileName);
@ -176,6 +187,39 @@ public class FileUploadAndDownService {
return successResponse(""); return successResponse("");
} }
/**
* 将字符串写入服务器临时目录
*
* @param fileName 文件名 test.txt
* @param content 文件内容
* @return 写入后的文件对象
*/
public static Path writeToTemp(String fileName, String content) throws IOException {
// ✅ 使用系统临时目录(跨平台)
Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
// ✅ 防止路径穿越攻击
Path safeFileName = Paths.get(fileName).getFileName();
if (safeFileName == null) {
throw new IllegalArgumentException("Invalid file name");
}
Path target = tempDir.resolve(safeFileName);
// ✅ 写入文件(UTF-8)
Files.write(
target,
content.getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING
);
return target;
}
private ContPrintVo successResponse(String msg){ private ContPrintVo successResponse(String msg){
ContPrintVo contPrintVo = new ContPrintVo(); ContPrintVo contPrintVo = new ContPrintVo();
contPrintVo.setContPrintResult("Y"); contPrintVo.setContPrintResult("Y");

@ -245,7 +245,7 @@
</when> </when>
<otherwise> <otherwise>
SELECT id FROM xxl_job_log SELECT id FROM xxl_job_log
WHERE !( WHERE not(
(trigger_code in (0, 200) and handle_code = 0) (trigger_code in (0, 200) and handle_code = 0)
OR OR
(handle_code = 200) (handle_code = 200)

Loading…
Cancel
Save