From d3b5fbde186a47c0dc8b0b58d5688ae5691ed9e6 Mon Sep 17 00:00:00 2001
From: peter <14100000001@qq.com>
Date: Sat, 10 Jan 2026 23:46:21 +0800
Subject: [PATCH] 签章
---
src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java | 732 ++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 501 insertions(+), 231 deletions(-)
diff --git a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
index da1149c..f1d58e6 100644
--- a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
@@ -15,6 +15,7 @@
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
+import org.springframework.web.multipart.MultipartFile;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
@@ -30,9 +31,12 @@
private com.nq.service.IUserService iUserService;
@Override
+
+// 在generateAgreementPdf方法中修改返回逻辑
public ServerResponse generateAgreementPdf(HttpServletRequest request) {
try {
User user = iUserService.getCurrentUser(request);
+ user = (User) iUserService.findByUserId(user.getId()).getData();
if (user == null) {
return ServerResponse.createByErrorMsg("用户未登录");
}
@@ -42,7 +46,8 @@
}
// 检查是否已生成PDF
- String pdfDir = PropertiesUtil.getProperty("agreement.pdf.dir", System.getProperty("user.dir") + "/agreement_pdf");
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+
File dir = new File(pdfDir);
if (!dir.exists()) {
dir.mkdirs();
@@ -50,253 +55,125 @@
String pdfFileName = "agreement_" + user.getId() + ".pdf";
File pdfFile = new File(dir, pdfFileName);
+
+ // 构建完整的PDF访问URL
+ String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/agreement_" + user.getId() + ".pdf";
+
+ // 如果PDF已存在,删除后重新生成,确保数据是最新的
if (pdfFile.exists()) {
- return ServerResponse.createBySuccess(pdfFileName);
+ log.info("PDF文件已存在,删除后重新生成: {}", pdfFile.getAbsolutePath());
+ boolean deleted = pdfFile.delete();
+ if (!deleted) {
+ log.warn("删除旧PDF文件失败: {}", pdfFile.getAbsolutePath());
+ }
}
- // 获取模板文件路径
- String templatePath = this.getClass().getResource("/templates").getPath();
- if (templatePath.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("windows")) {
- templatePath = templatePath.substring(1);
- }
- templatePath = templatePath.replaceAll("%20", " ");
- if (templatePath.contains("file:")) {
- templatePath = templatePath.substring(templatePath.indexOf("file:") + 5);
- }
- if (templatePath.contains("!")) {
- templatePath = templatePath.substring(0, templatePath.indexOf("!"));
- }
-
- // 使用PDF模板文件
- File pdfTemplate = new File(templatePath, "中原证券股票分成协议(电子正式版).pdf");
- if (!pdfTemplate.exists()) {
+ // 从资源中读取PDF模板文件
+ File pdfTemplate = getTemplateFile("中原证券股票分成协议(电子正式版).pdf");
+ if (pdfTemplate == null || !pdfTemplate.exists()) {
return ServerResponse.createByErrorMsg("PDF模板文件不存在");
}
// 从PDF模板生成新的PDF,替换占位符
generatePdfFromTemplate(pdfTemplate, pdfFile, user);
- return ServerResponse.createBySuccess(pdfFileName);
+ return ServerResponse.createBySuccess(pdfUrl);
} catch (Exception e) {
log.error("生成用户协议PDF失败", e);
return ServerResponse.createByErrorMsg("生成PDF失败:" + e.getMessage());
}
}
-
- public static void main(String[] args) {
- generateAgreementPdf11();
- }
-
- public static void generateAgreementPdf11() {
- try {
-
- // 检查是否已生成PDF
- String pdfDir = PropertiesUtil.getProperty("agreement.pdf.dir", System.getProperty("user.dir") + "/agreement_pdf");
- File dir = new File(pdfDir);
- if (!dir.exists()) {
- dir.mkdirs();
- }
-
- String pdfFileName = "agreement_111.pdf";
- File pdfFile = new File(dir, pdfFileName);
-
- // 获取模板文件路径
- String templatePath = "D:/work/A-stock/src/main/resources/templates";
- if (templatePath.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("windows")) {
- templatePath = templatePath.substring(1);
- }
- templatePath = templatePath.replaceAll("%20", " ");
- if (templatePath.contains("file:")) {
- templatePath = templatePath.substring(templatePath.indexOf("file:") + 5);
- }
- if (templatePath.contains("!")) {
- templatePath = templatePath.substring(0, templatePath.indexOf("!"));
- }
-
- // 使用PDF模板文件
- File pdfTemplate = new File(templatePath, "中原证券股票分成协议(电子正式版).pdf");
- if (!pdfTemplate.exists()) {
- System.out.println("PDF模板文件不存在");
- }
-
- // 从PDF模板生成新的PDF,替换占位符
- generatePdfFromTemplate1(pdfTemplate, pdfFile);
-
-
- } catch (Exception e) {
- log.error("生成用户协议PDF失败", e);
-
- }
- }
- public static void generatePdfFromTemplate1(File templatePdf, File outputPdf) throws Exception {
- PdfReader reader = new PdfReader(new FileInputStream(templatePdf));
- PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));
-
- // 设置中文字体
- BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
- Font font = new Font(baseFont, 12, Font.NORMAL);
-// Font boldFont = new Font(baseFont, 12, Font.BOLD);
-// BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
-// Font font = new Font(baseFont, 5, Font.BOLD);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
- String currentDate = sdf.format(new Date());
-
- // 准备替换的数据
- String realName = "陈大雷";
- String idCard = "433123198802456635";
- String address = "广东省清远市三八街道明星之城18栋2单元1506";
-
- // 获取PDF页数
- int pageCount = reader.getNumberOfPages();
-
- // 在每一页上查找并替换占位符
- for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
- PdfContentByte canvas = stamper.getOverContent(pageNum);
- Rectangle pageSize = reader.getPageSize(pageNum);
-
- // 提取PDF文本查找占位符位置
- String pageText = PdfTextExtractor.getTextFromPage(reader, pageNum, new SimpleTextExtractionStrategy());
-
- // 在PDF上查找并替换占位符
- replacePlaceholdersInPdf1(canvas, pageSize, pageText, realName, idCard, address, currentDate, font,pageNum);
- // 添加签名
- if(pageNum == 3){
- // 添加签名
- addHeaderImageToPdf(canvas, templatePdf.getParent(), pageSize);
- }
- }
-
- stamper.close();
- reader.close();
- }
-
- /**
- * 在PDF上替换占位符(使用文本覆盖方式)
- */
- public static void replacePlaceholdersInPdf1(PdfContentByte canvas, Rectangle pageSize, String pageText,
- String realName, String idCard, String address,
- String currentDate, Font font,int pageNum) throws Exception {
- // 查找占位符在文本中的位置,然后估算在PDF中的坐标
- // 由于PDF坐标系统复杂,这里使用固定位置替换
- // 实际使用时需要根据PDF模板的具体布局调整坐标
-
- float margin = 50;
- float lineHeight = 14;
- float startY = pageSize.getHeight() - 194;
-
- if(pageNum == 1){
- replacePlaceholder1(canvas, "", realName, margin + 75, startY, 0, font);
- startY -= lineHeight;
-
- replacePlaceholder1(canvas, "", address, margin + 75, startY-2, 0, font);
- startY -= lineHeight;
-
- replacePlaceholder1(canvas, "", idCard, margin + 95, startY-2, 0, font);
- }
- if(pageNum == 3){
- replacePlaceholder1(canvas, "", currentDate, margin + 60, startY+32, 0, font);
- replacePlaceholder1(canvas, "", currentDate, margin + 60, startY, 0, font);
- }
-
-// if (pageText.contains("${jcurrentDate}")) {
-// replacePlaceholder1(canvas, "${jcurrentDate}", currentDate, margin + 100, startY, 150, font);
-// startY -= lineHeight;
-// }
-//
-// if (pageText.contains("${ucurrentDate}")) {
-// replacePlaceholder1(canvas, "${ucurrentDate}", currentDate, margin + 100, startY, 300, font);
-// }
- }
-
- /**
- * 在PDF左上角添加图片
- */
- public static void addHeaderImageToPdf(PdfContentByte canvas, String templatePath, Rectangle pageSize) throws Exception {
- // 获取图片路径
- String imagePath = templatePath + File.separator + "zczq.png";
- File imageFile = new File(imagePath);
- // 如果使用相对路径找不到,尝试从resources获取
- if (!imageFile.exists()) {
- String resourcePath = "D:/work/A-stock/src/main/resources/templates";
- if (resourcePath.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("windows")) {
- resourcePath = resourcePath.substring(1);
- }
- resourcePath = resourcePath.replaceAll("%20", " ");
- if (resourcePath.contains("file:")) {
- resourcePath = resourcePath.substring(resourcePath.indexOf("file:") + 5);
- }
- if (resourcePath.contains("!")) {
- resourcePath = resourcePath.substring(0, resourcePath.indexOf("!"));
- }
- imageFile = new File(resourcePath);
- }
-
- if (imageFile.exists()) {
- Image image = Image.getInstance(imageFile.getAbsolutePath());
- // 设置图片大小
- image.scaleToFit(100, 100);
- // 设置图片位置(左上角)
- image.setAbsolutePosition(370, pageSize.getHeight() - 194);
- canvas.addImage(image);
- } else {
- log.warn("未找到图片文件: {}", imagePath);
- }
- }
- /**
- * 替换单个占位符
- */
- public static void replacePlaceholder1(PdfContentByte canvas, String placeholder, String value,
- float x, float y, float width, Font font) {
- // 添加白色背景覆盖占位符区域
- canvas.saveState();
- canvas.setColorFill(BaseColor.WHITE);
- canvas.rectangle(x - 5, y - 15, width, 20);
- canvas.fill();
- canvas.restoreState();
-
- // 添加新文本
- ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
- new Phrase(value, font), x, y, 0);
- }
-
-
/**
* 从PDF模板生成新的PDF,替换占位符
*/
private void generatePdfFromTemplate(File templatePdf, File outputPdf, User user) throws Exception {
- PdfReader reader = new PdfReader(new FileInputStream(templatePdf));
- PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));
+ log.info("开始生成PDF,模板路径: {}, 输出路径: {}, 用户: {}",
+ templatePdf.getAbsolutePath(), outputPdf.getAbsolutePath(), user.getId());
+
+ PdfReader reader = null;
+ PdfStamper stamper = null;
+ FileOutputStream fos = null;
+
+ try {
+ reader = new PdfReader(new FileInputStream(templatePdf));
+ fos = new FileOutputStream(outputPdf);
+ stamper = new PdfStamper(reader, fos);
- // 设置中文字体
- BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
- Font font = new Font(baseFont, 12, Font.NORMAL);
- Font boldFont = new Font(baseFont, 12, Font.BOLD);
+ // 设置中文字体
+ BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+ Font font = new Font(baseFont, 12, Font.NORMAL);
+ Font boldFont = new Font(baseFont, 12, Font.BOLD);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
- String currentDate = sdf.format(new Date());
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
+ String currentDate = sdf.format(new Date());
- // 准备替换的数据
- String realName = user.getRealName() != null ? user.getRealName() : "";
- String idCard = user.getIdCard() != null ? user.getIdCard() : "";
- String address = user.getRegAddress() != null ? user.getRegAddress() : "";
+ // 准备替换的数据
+ String realName = user.getRealName() != null ? user.getRealName() : "";
+ String idCard = user.getIdCard() != null ? user.getIdCard() : "";
+ String address = user.getRegAddress() != null ? user.getRegAddress() : "";
+
+ log.info("PDF生成数据 - 姓名: {}, 身份证: {}, 地址: {}", realName, idCard, address);
- // 获取PDF页数
- int pageCount = reader.getNumberOfPages();
+ // 获取PDF页数
+ int pageCount = reader.getNumberOfPages();
+ log.info("PDF模板页数: {}", pageCount);
- // 在每一页上查找并替换占位符
- for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
- PdfContentByte canvas = stamper.getOverContent(pageNum);
- Rectangle pageSize = reader.getPageSize(pageNum);
+ // 在每一页上查找并替换占位符
+ for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
+ PdfContentByte canvas = stamper.getOverContent(pageNum);
+ Rectangle pageSize = reader.getPageSize(pageNum);
- // 提取PDF文本查找占位符位置
- String pageText = PdfTextExtractor.getTextFromPage(reader, pageNum, new SimpleTextExtractionStrategy());
+ // 提取PDF文本查找占位符位置
+ String pageText = PdfTextExtractor.getTextFromPage(reader, pageNum, new SimpleTextExtractionStrategy());
- // 在PDF上查找并替换占位符
- replacePlaceholdersInPdf(canvas, pageSize, pageText, realName, idCard, address, currentDate, font,pageNum);
+ // 在PDF上查找并替换占位符
+ replacePlaceholdersInPdf(canvas, pageSize, pageText, realName, idCard, address, currentDate, font, pageNum);
+ log.info("已处理PDF第{}页", pageNum);
+ }
+
+ stamper.close();
+ stamper = null;
+ reader.close();
+ reader = null;
+ fos.close();
+ fos = null;
+
+ // 验证生成的文件
+ if (outputPdf.exists()) {
+ long fileSize = outputPdf.length();
+ log.info("PDF生成完成,文件路径: {}, 文件大小: {} 字节", outputPdf.getAbsolutePath(), fileSize);
+ if (fileSize == 0) {
+ throw new Exception("生成的PDF文件大小为0");
+ }
+ } else {
+ throw new Exception("PDF文件生成失败,文件不存在");
+ }
+ } catch (Exception e) {
+ log.error("生成PDF失败", e);
+ throw e;
+ } finally {
+ if (stamper != null) {
+ try {
+ stamper.close();
+ } catch (Exception e) {
+ log.error("关闭stamper失败", e);
+ }
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ log.error("关闭reader失败", e);
+ }
+ }
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (Exception e) {
+ log.error("关闭输出流失败", e);
+ }
+ }
}
-
- stamper.close();
- reader.close();
}
/**
@@ -347,6 +224,8 @@
@Override
public void viewAgreementPdf(HttpServletRequest request, HttpServletResponse response) {
+ FileInputStream fis = null;
+ OutputStream os = null;
try {
User user = iUserService.getCurrentUser(request);
if (user == null) {
@@ -354,37 +233,428 @@
return;
}
- String pdfDir = PropertiesUtil.getProperty("agreement.pdf.dir", System.getProperty("user.dir") + "/agreement_pdf");
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
String pdfFileName = "agreement_" + user.getId() + ".pdf";
File pdfFile = new File(pdfDir, pdfFileName);
+
+ log.info("查看PDF文件,路径: {}, 是否存在: {}, 文件大小: {}",
+ pdfFile.getAbsolutePath(), pdfFile.exists(),
+ pdfFile.exists() ? pdfFile.length() : 0);
if (!pdfFile.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "协议文件不存在,请先生成协议");
return;
}
+ long fileLength = pdfFile.length();
+ if (fileLength == 0) {
+ log.error("PDF文件大小为0: {}", pdfFile.getAbsolutePath());
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文件为空");
+ return;
+ }
+
+ // 验证PDF文件头
+ FileInputStream checkFis = new FileInputStream(pdfFile);
+ byte[] header = new byte[4];
+ checkFis.read(header);
+ checkFis.close();
+ String headerStr = new String(header);
+ if (!headerStr.startsWith("%PDF")) {
+ log.error("文件不是有效的PDF格式,文件头: {}", headerStr);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文件格式错误");
+ return;
+ }
+ log.info("PDF文件头验证通过: {}", headerStr);
+
response.setContentType("application/pdf");
- response.setHeader("Content-Disposition", "inline; filename=" + pdfFileName);
+ response.setHeader("Content-Disposition", "inline; filename=\"" +
+ new String(pdfFileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
+ response.setContentLengthLong(fileLength);
+ response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+ response.setHeader("Pragma", "no-cache");
+ response.setDateHeader("Expires", 0);
- FileInputStream fis = new FileInputStream(pdfFile);
- OutputStream os = response.getOutputStream();
+ fis = new FileInputStream(pdfFile);
+ os = response.getOutputStream();
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ long totalBytes = 0;
+ while ((bytesRead = fis.read(buffer)) != -1) {
+ os.write(buffer, 0, bytesRead);
+ totalBytes += bytesRead;
+ }
+
+ log.info("PDF文件传输完成,总字节数: {}", totalBytes);
+ os.flush();
+ } catch (Exception e) {
+ log.error("查看用户协议PDF失败", e);
+ try {
+ if (!response.isCommitted()) {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败: " + e.getMessage());
+ }
+ } catch (IOException ex) {
+ log.error("发送错误响应失败", ex);
+ }
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ log.error("关闭文件流失败", e);
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ log.error("关闭输出流失败", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public ServerResponse saveAgreementSignature(MultipartFile signatureFile, HttpServletRequest request) {
+ try {
+ User user = iUserService.getCurrentUser(request);
+ if (user == null) {
+ return ServerResponse.createByErrorMsg("用户未登录");
+ }
+
+ if (signatureFile == null || signatureFile.isEmpty()) {
+ return ServerResponse.createByErrorMsg("签名图片不能为空");
+ }
+
+ // 保存签名图片到本地
+ String signatureDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ File dir = new File(signatureDir);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ String signatureFileName = "signature_" + user.getId() + ".png";
+ File signatureFileLocal = new File(dir, signatureFileName);
+
+ signatureFile.transferTo(signatureFileLocal);
+
+ log.info("用户{}的签名图片已保存: {}", user.getId(), signatureFileLocal.getAbsolutePath());
+
+ // 重新生成PDF并插入签名图片
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ String pdfFileName = "agreement_" + user.getId() + ".pdf";
+ File pdfFile = new File(pdfDir, pdfFileName);
+
+ if (pdfFile.exists()) {
+ // 在PDF第三页插入签名图片
+ addSignatureToPdf(pdfFile, signatureFileLocal, user);
+
+ // 构建PDF访问地址
+ String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/agreement_" + user.getId() + ".pdf";
+
+ // 更新用户表的签合同标记(保存PDF地址)
+ iUserService.updateSignedContract(user.getId(),pdfUrl);
+ }
+ return ServerResponse.createBySuccessMsg("签名保存成功");
+ } catch (Exception e) {
+ log.error("保存用户协议签名失败", e);
+ return ServerResponse.createByErrorMsg("保存签名失败:" + e.getMessage());
+ }
+ }
+
+ /**
+ * 在PDF第三页插入签名图片
+ */
+ private void addSignatureToPdf(File pdfFile, File signatureImage, User user) throws Exception {
+ PdfReader reader = new PdfReader(new FileInputStream(pdfFile));
+ File tempPdf = new File(pdfFile.getParent(), "temp_" + pdfFile.getName());
+ PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));
+
+ int pageCount = reader.getNumberOfPages();
+
+ // 在第三页插入签名图片
+ if (pageCount >= 3) {
+ PdfContentByte canvas = stamper.getOverContent(3);
+ Rectangle pageSize = reader.getPageSize(3);
+
+ // 添加签名图片
+ if (signatureImage.exists()) {
+ Image image = Image.getInstance(signatureImage.getAbsolutePath());
+ // 设置图片大小(根据实际需要调整)
+ image.scaleToFit(100, 100);
+ // 设置图片位置(使用与addHeaderImageToPdf相同的坐标)
+ image.setAbsolutePosition(370, pageSize.getHeight() - 194);
+ canvas.addImage(image);
+ log.info("签名图片已插入到PDF第三页,位置: (370, {})", pageSize.getHeight() - 194);
+ }
+ }
+
+ stamper.close();
+ reader.close();
+
+ // 替换原PDF文件
+ if (tempPdf.exists()) {
+ pdfFile.delete();
+ tempPdf.renameTo(pdfFile);
+ log.info("PDF文件已更新,签名图片已插入");
+ }
+ }
+
+ @Override
+ public ServerResponse generateAgreementContractPdf(HttpServletRequest request) {
+ try {
+ User user = iUserService.getCurrentUser(request);
+ user = (User) iUserService.findByUserId(user.getId()).getData();
+ if (user == null) {
+ return ServerResponse.createByErrorMsg("用户未登录");
+ }
+
+ if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
+ return ServerResponse.createByErrorMsg("用户信息不完整,请先完成实名认证");
+ }
+
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ File dir = new File(pdfDir);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ String pdfFileName = "contract_" + user.getId() + ".pdf";
+ File pdfFile = new File(dir, pdfFileName);
+
+ String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/contract_" + user.getId() + ".pdf";
+
+ if (pdfFile.exists()) {
+ boolean deleted = pdfFile.delete();
+ if (!deleted) {
+ log.warn("删除旧PDF文件失败: {}", pdfFile.getAbsolutePath());
+ }
+ }
+
+ // 从资源中读取PDF模板文件
+ File pdfTemplate = getTemplateFile("中原证券商业核心信息保密协议.pdf");
+ if (pdfTemplate == null || !pdfTemplate.exists()) {
+ return ServerResponse.createByErrorMsg("PDF模板文件不存在");
+ }
+
+ generateContractPdfFromTemplate(pdfTemplate, pdfFile, user);
+
+ return ServerResponse.createBySuccess(pdfUrl);
+ } catch (Exception e) {
+ log.error("生成用户合同PDF失败", e);
+ return ServerResponse.createByErrorMsg("生成PDF失败:" + e.getMessage());
+ }
+ }
+
+ @Override
+ public void viewAgreementContractPdf(HttpServletRequest request, HttpServletResponse response) {
+ FileInputStream fis = null;
+ OutputStream os = null;
+ try {
+ User user = iUserService.getCurrentUser(request);
+ if (user == null) {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "用户未登录");
+ return;
+ }
+
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ String pdfFileName = "contract_" + user.getId() + ".pdf";
+ File pdfFile = new File(pdfDir, pdfFileName);
+
+ if (!pdfFile.exists()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "合同文件不存在,请先生成合同");
+ return;
+ }
+
+ long fileLength = pdfFile.length();
+ if (fileLength == 0) {
+ log.error("PDF文件大小为0: {}", pdfFile.getAbsolutePath());
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文件为空");
+ return;
+ }
+
+ FileInputStream checkFis = new FileInputStream(pdfFile);
+ byte[] header = new byte[4];
+ checkFis.read(header);
+ checkFis.close();
+ String headerStr = new String(header);
+ if (!headerStr.startsWith("%PDF")) {
+ log.error("文件不是有效的PDF格式,文件头: {}", headerStr);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "PDF文件格式错误");
+ return;
+ }
+
+ response.setContentType("application/pdf");
+ response.setHeader("Content-Disposition", "inline; filename=\"" +
+ new String(pdfFileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
+ response.setContentLengthLong(fileLength);
+ response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+
+ fis = new FileInputStream(pdfFile);
+ os = response.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
-
- fis.close();
os.flush();
- os.close();
} catch (Exception e) {
- log.error("查看用户协议PDF失败", e);
+ log.error("查看用户合同PDF失败", e);
try {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败");
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败: " + e.getMessage());
} catch (IOException ex) {
log.error("发送错误响应失败", ex);
}
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ log.error("关闭文件流失败", e);
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ log.error("关闭输出流失败", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public ServerResponse saveAgreementContractSignature(MultipartFile signatureFile, HttpServletRequest request) {
+ try {
+ User user = iUserService.getCurrentUser(request);
+ if (user == null) {
+ return ServerResponse.createByErrorMsg("用户未登录");
+ }
+
+ if (signatureFile == null || signatureFile.isEmpty()) {
+ return ServerResponse.createByErrorMsg("签名图片不能为空");
+ }
+
+ String signatureDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ File dir = new File(signatureDir);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ String signatureFileName = "contract_signature_" + user.getId() + ".png";
+ File signatureFileLocal = new File(dir, signatureFileName);
+
+ signatureFile.transferTo(signatureFileLocal);
+
+ log.info("用户{}的合同签名图片已保存: {}", user.getId(), signatureFileLocal.getAbsolutePath());
+
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+ String pdfFileName = "contract_" + user.getId() + ".pdf";
+ File pdfFile = new File(pdfDir, pdfFileName);
+
+ if (pdfFile.exists()) {
+ addSignatureToContractPdf(pdfFile, signatureFileLocal, user);
+
+ String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/contract_" + user.getId() + ".pdf";
+
+ iUserService.updateSignedAgreement(user.getId(), pdfUrl);
+ }
+
+ return ServerResponse.createBySuccessMsg("签名保存成功");
+ } catch (Exception e) {
+ log.error("保存用户合同签名失败", e);
+ return ServerResponse.createByErrorMsg("保存签名失败:" + e.getMessage());
+ }
+ }
+
+ private void generateContractPdfFromTemplate(File templatePdf, File outputPdf, User user) throws Exception {
+ PdfReader reader = new PdfReader(new FileInputStream(templatePdf));
+ PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));
+
+ BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+ Font font = new Font(baseFont, 12, Font.NORMAL);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
+ String currentDate = sdf.format(new Date());
+
+ int pageCount = reader.getNumberOfPages();
+
+ for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
+ PdfContentByte canvas = stamper.getOverContent(pageNum);
+ Rectangle pageSize = reader.getPageSize(pageNum);
+
+ replacePlaceholdersInContractPdf(canvas, pageSize, currentDate, font, pageNum);
+ }
+
+ stamper.close();
+ reader.close();
+ }
+
+ private void replacePlaceholdersInContractPdf(PdfContentByte canvas, Rectangle pageSize, String currentDate, Font font, int pageNum) throws Exception {
+ float margin = 50;
+ float startY = pageSize.getHeight() - 364;
+ if(pageNum == 2){
+ replacePlaceholder(canvas, "", currentDate, margin + 320, startY, 0, font);
+ }
+ }
+
+ private void addSignatureToContractPdf(File pdfFile, File signatureImage, User user) throws Exception {
+ PdfReader reader = new PdfReader(new FileInputStream(pdfFile));
+ File tempPdf = new File(pdfFile.getParent(), "temp_" + pdfFile.getName());
+ PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));
+
+ int pageCount = reader.getNumberOfPages();
+
+ if (pageCount >= 2) {
+ PdfContentByte canvas = stamper.getOverContent(2);
+ Rectangle pageSize = reader.getPageSize(2);
+
+ if (signatureImage.exists()) {
+ Image image = Image.getInstance(signatureImage.getAbsolutePath());
+ image.scaleToFit(100, 100);
+ image.setAbsolutePosition(435, pageSize.getHeight() - 288);
+ canvas.addImage(image);
+ log.info("签名图片已插入到合同PDF第二页");
+ }
+ }
+
+ stamper.close();
+ reader.close();
+
+ if (tempPdf.exists()) {
+ pdfFile.delete();
+ tempPdf.renameTo(pdfFile);
+ log.info("合同PDF文件已更新,签名图片已插入");
+ }
+ }
+
+ /**
+ * 从固定目录获取模板文件
+ */
+ private File getTemplateFile(String templateFileName) {
+ try {
+ String templateDir = PropertiesUtil.getProperty("pdf.template.dir");
+ if (StringUtils.isBlank(templateDir)) {
+ log.error("PDF模板目录配置不存在: pdf.template.dir");
+ return null;
+ }
+
+ File dir = new File(templateDir);
+ if (!dir.exists()) {
+ log.error("PDF模板目录不存在: {}", templateDir);
+ return null;
+ }
+
+ File templateFile = new File(dir, templateFileName);
+ if (!templateFile.exists()) {
+ log.error("PDF模板文件不存在: {}", templateFile.getAbsolutePath());
+ return null;
+ }
+
+ log.info("使用模板文件: {}", templateFile.getAbsolutePath());
+ return templateFile;
+ } catch (Exception e) {
+ log.error("获取模板文件失败: {}", templateFileName, e);
+ return null;
}
}
}
--
Gitblit v1.9.3