From 24182d305d731e58bd1a57e00466f42ba3a44a9e Mon Sep 17 00:00:00 2001
From: peter <14100000001@qq.com>
Date: Sun, 11 Jan 2026 01:00:14 +0800
Subject: [PATCH] 签章
---
src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java | 324 ++++++++++++++++++++++++++++++++---------------------
1 files changed, 197 insertions(+), 127 deletions(-)
diff --git a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
index f1d58e6..7a78c5c 100644
--- a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
@@ -22,6 +22,18 @@
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.rendering.ImageType;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.List;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import com.nq.pojo.ContractImage;
+import com.nq.dao.ContractImageMapper;
+import com.alibaba.fastjson.JSON;
@Service("iUserAgreementService")
public class UserAgreementServiceImpl implements IUserAgreementService {
@@ -29,6 +41,9 @@
@Autowired
private com.nq.service.IUserService iUserService;
+
+ @Autowired
+ private ContractImageMapper contractImageMapper;
@Override
@@ -41,8 +56,8 @@
return ServerResponse.createByErrorMsg("用户未登录");
}
- if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
- return ServerResponse.createByErrorMsg("用户信息不完整,请先完成实名认证");
+ if (user.getIsActive()!=2 || StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
+ return ServerResponse.createByErrorMsg("请先完成实名认证");
}
// 检查是否已生成PDF
@@ -77,7 +92,10 @@
// 从PDF模板生成新的PDF,替换占位符
generatePdfFromTemplate(pdfTemplate, pdfFile, user);
- return ServerResponse.createBySuccess(pdfUrl);
+ // 将PDF转换为图片并返回图片路径数组
+ List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
+
+ return ServerResponse.createBySuccess(imageUrls);
} catch (Exception e) {
log.error("生成用户协议PDF失败", e);
return ServerResponse.createByErrorMsg("生成PDF失败:" + e.getMessage());
@@ -102,7 +120,6 @@
// 设置中文字体
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());
@@ -224,8 +241,6 @@
@Override
public void viewAgreementPdf(HttpServletRequest request, HttpServletResponse response) {
- FileInputStream fis = null;
- OutputStream os = null;
try {
User user = iUserService.getCurrentUser(request);
if (user == null) {
@@ -237,56 +252,16 @@
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=\"" +
- 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);
-
- 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();
+ List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
+
+ response.setContentType("application/json;charset=UTF-8");
+ response.getWriter().write(JSON.toJSONString(ServerResponse.createBySuccess(imageUrls)));
+ response.getWriter().flush();
} catch (Exception e) {
log.error("查看用户协议PDF失败", e);
try {
@@ -295,21 +270,6 @@
}
} 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);
- }
}
}
}
@@ -326,7 +286,6 @@
return ServerResponse.createByErrorMsg("签名图片不能为空");
}
- // 保存签名图片到本地
String signatureDir = PropertiesUtil.getProperty("loca.pdf.dir");
File dir = new File(signatureDir);
if (!dir.exists()) {
@@ -340,20 +299,36 @@
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";
+ List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
- // 更新用户表的签合同标记(保存PDF地址)
- iUserService.updateSignedContract(user.getId(),pdfUrl);
+ String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
+ long timestamp = System.currentTimeMillis();
+
+ for (int i = 0; i < imageUrls.size(); i++) {
+ String imageName;
+ if (i == 0) {
+ imageName = "contract_" + timestamp + ".png";
+ } else {
+ imageName = "contract_" + timestamp + "_" + (i + 1) + ".png";
+ }
+ String imagePath = imagePrefix + "/" + imageName;
+
+ ContractImage contractImage = new ContractImage();
+ contractImage.setUserId(user.getId());
+ contractImage.setContractType("contract");
+ contractImage.setAddress(imagePath);
+ contractImage.setAddTime(new Date());
+ contractImageMapper.insert(contractImage);
+ }
+
+ iUserService.updateSignedContract(user.getId(), "Y");
}
return ServerResponse.createBySuccessMsg("签名保存成功");
} catch (Exception e) {
@@ -439,7 +414,10 @@
generateContractPdfFromTemplate(pdfTemplate, pdfFile, user);
- return ServerResponse.createBySuccess(pdfUrl);
+ // 将PDF转换为图片并返回图片路径数组
+ List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
+
+ return ServerResponse.createBySuccess(imageUrls);
} catch (Exception e) {
log.error("生成用户合同PDF失败", e);
return ServerResponse.createByErrorMsg("生成PDF失败:" + e.getMessage());
@@ -448,8 +426,6 @@
@Override
public void viewAgreementContractPdf(HttpServletRequest request, HttpServletResponse response) {
- FileInputStream fis = null;
- OutputStream os = null;
try {
User user = iUserService.getCurrentUser(request);
if (user == null) {
@@ -466,59 +442,19 @@
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);
- }
- os.flush();
+ List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
+
+ response.setContentType("application/json;charset=UTF-8");
+ response.getWriter().write(JSON.toJSONString(ServerResponse.createBySuccess(imageUrls)));
+ response.getWriter().flush();
} catch (Exception e) {
log.error("查看用户合同PDF失败", e);
try {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败: " + e.getMessage());
+ 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);
- }
}
}
}
@@ -555,9 +491,29 @@
if (pdfFile.exists()) {
addSignatureToContractPdf(pdfFile, signatureFileLocal, user);
- String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/contract_" + user.getId() + ".pdf";
-
- iUserService.updateSignedAgreement(user.getId(), pdfUrl);
+ List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
+
+ String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
+ long timestamp = System.currentTimeMillis();
+
+ for (int i = 0; i < imageUrls.size(); i++) {
+ String imageName;
+ if (i == 0) {
+ imageName = "agreement_" + timestamp + ".png";
+ } else {
+ imageName = "agreement_" + timestamp + "_" + (i + 1) + ".png";
+ }
+ String imagePath = imagePrefix + "/" + imageName;
+
+ ContractImage contractImage = new ContractImage();
+ contractImage.setUserId(user.getId());
+ contractImage.setContractType("agreement");
+ contractImage.setAddress(imagePath);
+ contractImage.setAddTime(new Date());
+ contractImageMapper.insert(contractImage);
+ }
+
+ iUserService.updateSignedAgreement(user.getId(), "Y");
}
return ServerResponse.createBySuccessMsg("签名保存成功");
@@ -657,4 +613,118 @@
return null;
}
}
+
+ /**
+ * 将PDF转换为图片
+ */
+ private List<String> convertPdfToImages(File pdfFile, String contractType, Integer userId) throws Exception {
+ List<String> imageUrls = new ArrayList<>();
+ String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
+ String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+
+ long timestamp = System.currentTimeMillis();
+ PDDocument document = null;
+ try {
+ document = PDDocument.load(pdfFile);
+
+ // 创建PDFRenderer,使用高质量渲染
+ PDFRenderer pdfRenderer = new PDFRenderer(document);
+
+ int pageCount = document.getNumberOfPages();
+ log.info("PDF总页数: {}", pageCount);
+
+ for (int page = 0; page < pageCount; page++) {
+ // 使用RGB模式渲染,DPI设置为300确保文字清晰
+ // ImageType.RGB可以更好地处理中文字体
+ BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
+
+ // 对图片进行优化处理,确保文字清晰
+ BufferedImage optimizedImage = optimizeImage(image);
+
+ String imageFileName = contractType + "_" + timestamp + ".png";
+ if (page > 0) {
+ imageFileName = contractType + "_" + timestamp + "_" + (page + 1) + ".png";
+ }
+ File imageFile = new File(pdfDir, imageFileName);
+
+ ImageIO.write(optimizedImage, "png", imageFile);
+
+ String imageUrl = imagePrefix + "/imgs/" + imageFileName;
+ imageUrls.add(imageUrl);
+
+ log.info("PDF第{}页已转换为图片: {}", page + 1, imageUrl);
+ }
+ } finally {
+ if (document != null) {
+ document.close();
+ }
+ }
+
+ return imageUrls;
+ }
+
+ /**
+ * 优化图片,确保文字清晰
+ */
+ private BufferedImage optimizeImage(BufferedImage originalImage) {
+ int width = originalImage.getWidth();
+ int height = originalImage.getHeight();
+
+ BufferedImage optimizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2d = optimizedImage.createGraphics();
+
+ // 设置高质量渲染
+ g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ g2d.drawImage(originalImage, 0, 0, null);
+ g2d.dispose();
+
+ return optimizedImage;
+ }
+
+ @Override
+ public ServerResponse getContractImages(HttpServletRequest request) {
+ try {
+ User user = iUserService.getCurrentUser(request);
+ if (user == null) {
+ return ServerResponse.createByErrorMsg("用户未登录");
+ }
+
+ List<ContractImage> images = contractImageMapper.selectByUserIdAndType(user.getId(), "contract");
+ List<String> imageUrls = new ArrayList<>();
+ for (ContractImage image : images) {
+ imageUrls.add(image.getAddress());
+ }
+
+ return ServerResponse.createBySuccess(imageUrls);
+ } catch (Exception e) {
+ log.error("查询合同图片列表失败", e);
+ return ServerResponse.createByErrorMsg("查询失败:" + e.getMessage());
+ }
+ }
+
+ @Override
+ public ServerResponse getAgreementImages(HttpServletRequest request) {
+ try {
+ User user = iUserService.getCurrentUser(request);
+ if (user == null) {
+ return ServerResponse.createByErrorMsg("用户未登录");
+ }
+
+ List<ContractImage> images = contractImageMapper.selectByUserIdAndType(user.getId(), "agreement");
+ List<String> imageUrls = new ArrayList<>();
+ for (ContractImage image : images) {
+ imageUrls.add(image.getAddress());
+ }
+
+ return ServerResponse.createBySuccess(imageUrls);
+ } catch (Exception e) {
+ log.error("查询保密协议图片列表失败", e);
+ return ServerResponse.createByErrorMsg("查询失败:" + e.getMessage());
+ }
+ }
}
--
Gitblit v1.9.3