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/dao/ContractImageMapper.java               |   11 +
 src/main/java/com/nq/service/impl/UserBankServiceImpl.java      |    6 
 src/main/resources/application.properties                       |   15 +
 src/main/java/com/nq/service/IUserAgreementService.java         |   16 +
 src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java |  324 +++++++++++++++++++------------
 src/main/java/com/nq/pojo/ContractImage.java                    |   23 ++
 src/main/java/com/nq/controller/protol/UserController.java      |   18 +
 src/main/java/com/nq/controller/ImageController.java            |  132 +++++++++++++
 src/main/resources/mapper/ContractImageMapper.xml               |   17 +
 pom.xml                                                         |   11 +
 src/main/resources/application.yml                              |   10 
 src/main/java/com/nq/service/impl/UserServiceImpl.java          |    1 
 12 files changed, 448 insertions(+), 136 deletions(-)

diff --git a/pom.xml b/pom.xml
index 23d8072..29ac4f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -222,6 +222,17 @@
             <artifactId>itext-asian</artifactId>
             <version>5.2.0</version>
         </dependency>
+        <!-- PDFBox for PDF to Image conversion -->
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>2.0.24</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox-tools</artifactId>
+            <version>2.0.24</version>
+        </dependency>
 
     </dependencies>
 
diff --git a/src/main/java/com/nq/controller/ImageController.java b/src/main/java/com/nq/controller/ImageController.java
new file mode 100644
index 0000000..77abfaa
--- /dev/null
+++ b/src/main/java/com/nq/controller/ImageController.java
@@ -0,0 +1,132 @@
+package com.nq.controller;
+
+import com.nq.utils.PropertiesUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+@Controller
+public class ImageController {
+    private static final Logger log = LoggerFactory.getLogger(ImageController.class);
+
+    @RequestMapping({"/imgs/{filename:.+}"})
+    public void getImage(@PathVariable String filename, HttpServletResponse response) {
+        FileInputStream fis = null;
+        OutputStream os = null;
+        try {
+            String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+            File imageFile = new File(pdfDir, filename);
+
+            if (!imageFile.exists()) {
+                log.warn("图片文件不存在: {}", imageFile.getAbsolutePath());
+                response.sendError(HttpServletResponse.SC_NOT_FOUND, "图片文件不存在");
+                return;
+            }
+
+            // 设置响应头
+            response.setContentType("image/png");
+            response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
+            response.setContentLengthLong(imageFile.length());
+            response.setHeader("Cache-Control", "public, max-age=3600");
+
+            fis = new FileInputStream(imageFile);
+            os = response.getOutputStream();
+
+            byte[] buffer = new byte[8192];
+            int bytesRead;
+            while ((bytesRead = fis.read(buffer)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.flush();
+        } catch (Exception e) {
+            log.error("读取图片文件失败: {}", filename, e);
+            try {
+                if (!response.isCommitted()) {
+                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "读取图片失败");
+                }
+            } 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);
+                }
+            }
+        }
+    }
+
+    @RequestMapping({"imgs.do"})
+    public void getImageByParam(@RequestParam("file") String filename, HttpServletResponse response) {
+        FileInputStream fis = null;
+        OutputStream os = null;
+        try {
+            String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+            File imageFile = new File(pdfDir, filename);
+
+            if (!imageFile.exists()) {
+                log.warn("图片文件不存在: {}", imageFile.getAbsolutePath());
+                response.sendError(HttpServletResponse.SC_NOT_FOUND, "图片文件不存在");
+                return;
+            }
+
+            // 设置响应头
+            response.setContentType("image/png");
+            response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
+            response.setContentLengthLong(imageFile.length());
+            response.setHeader("Cache-Control", "public, max-age=3600");
+
+            fis = new FileInputStream(imageFile);
+            os = response.getOutputStream();
+
+            byte[] buffer = new byte[8192];
+            int bytesRead;
+            while ((bytesRead = fis.read(buffer)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.flush();
+        } catch (Exception e) {
+            log.error("读取图片文件失败: {}", filename, e);
+            try {
+                if (!response.isCommitted()) {
+                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "读取图片失败");
+                }
+            } 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);
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/com/nq/controller/protol/UserController.java b/src/main/java/com/nq/controller/protol/UserController.java
index 0a2ad23..5097142 100644
--- a/src/main/java/com/nq/controller/protol/UserController.java
+++ b/src/main/java/com/nq/controller/protol/UserController.java
@@ -523,4 +523,22 @@
         return this.iUserAgreementService.saveAgreementContractSignature(signatureFile, request);
     }
 
+    /**
+     * 查询合同图片列表
+     */
+    @RequestMapping({"getContractImages.do"})
+    @ResponseBody
+    public ServerResponse getContractImages(HttpServletRequest request) {
+        return this.iUserAgreementService.getContractImages(request);
+    }
+
+    /**
+     * 查询保密协议图片列表
+     */
+    @RequestMapping({"getAgreementImages.do"})
+    @ResponseBody
+    public ServerResponse getAgreementImages(HttpServletRequest request) {
+        return this.iUserAgreementService.getAgreementImages(request);
+    }
+
 }
diff --git a/src/main/java/com/nq/dao/ContractImageMapper.java b/src/main/java/com/nq/dao/ContractImageMapper.java
new file mode 100644
index 0000000..8898f2b
--- /dev/null
+++ b/src/main/java/com/nq/dao/ContractImageMapper.java
@@ -0,0 +1,11 @@
+package com.nq.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nq.pojo.ContractImage;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ContractImageMapper extends BaseMapper<ContractImage> {
+    List<ContractImage> selectByUserIdAndType(@Param("userId") Integer userId, @Param("contractType") String contractType);
+}
diff --git a/src/main/java/com/nq/pojo/ContractImage.java b/src/main/java/com/nq/pojo/ContractImage.java
new file mode 100644
index 0000000..acbba1d
--- /dev/null
+++ b/src/main/java/com/nq/pojo/ContractImage.java
@@ -0,0 +1,23 @@
+package com.nq.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+@TableName("contract_image")
+@Data
+public class ContractImage {
+    @TableId(type = IdType.AUTO, value = "id")
+    private Integer id;
+
+    private Integer userId;
+
+    private String contractType;
+
+    private String address;
+
+    private Date addTime;
+}
diff --git a/src/main/java/com/nq/service/IUserAgreementService.java b/src/main/java/com/nq/service/IUserAgreementService.java
index 2e7d064..cf55243 100644
--- a/src/main/java/com/nq/service/IUserAgreementService.java
+++ b/src/main/java/com/nq/service/IUserAgreementService.java
@@ -16,7 +16,7 @@
     ServerResponse generateAgreementPdf(HttpServletRequest request);
 
     /**
-     * 查看用户协议PDF
+     * 查看用户协议PDF(返回图片路径列表)
      * @param request
      * @param response
      * @return
@@ -53,4 +53,18 @@
      * @return
      */
     ServerResponse saveAgreementContractSignature(MultipartFile signatureFile, HttpServletRequest request);
+
+    /**
+     * 查询合同图片列表
+     * @param request
+     * @return
+     */
+    ServerResponse getContractImages(HttpServletRequest request);
+
+    /**
+     * 查询保密协议图片列表
+     * @param request
+     * @return
+     */
+    ServerResponse getAgreementImages(HttpServletRequest request);
 }
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());
+        }
+    }
 }
diff --git a/src/main/java/com/nq/service/impl/UserBankServiceImpl.java b/src/main/java/com/nq/service/impl/UserBankServiceImpl.java
index b1d7d97..413f932 100644
--- a/src/main/java/com/nq/service/impl/UserBankServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserBankServiceImpl.java
@@ -20,6 +20,7 @@
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import org.springframework.stereotype.Service;
@@ -42,6 +43,11 @@
        return ServerResponse.createBySuccessMsg("請先登錄");
      }
 
+     user = (User) this.iUserService.findByUserId(user.getId()).getData();
+     if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress()) || user.getIsActive()!=2) {
+       return ServerResponse.createByErrorMsg("请先完成实名认证");
+     }
+
      UserBank dbBank = this.userBankMapper.findUserBankByUserId(user.getId());
 
      if (dbBank != null) {
diff --git a/src/main/java/com/nq/service/impl/UserServiceImpl.java b/src/main/java/com/nq/service/impl/UserServiceImpl.java
index 8130840..39759a0 100644
--- a/src/main/java/com/nq/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -385,6 +385,7 @@
         String userJson = RedisShardedPoolUtils.get(loginToken);
         User user = (User)JsonUtil.string2Obj(userJson, User.class);
         User dbuser = this.userMapper.selectByPrimaryKey(user.getId());
+        RedisShardedPoolUtils.setEx(loginToken, JsonUtil.obj2String(dbuser), 9999);
         UserInfoVO userInfoVO = assembleUserInfoVO(dbuser);
 
         return ServerResponse.createBySuccess(userInfoVO);
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 790836e..36e722f 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -10,9 +10,18 @@
 ftp.pass=ftp_red
 ftp.server.http.prefix=https://ftp.shengliankeji.top/
 loca.images.dir=/www/wwwroot/ftp.shengliankeji.top/
-pdf.server.http.prefix=https://stockapdf.shengliankeji.top
-loca.pdf.dir=/www/wwwroot/stock.A.PDF
-pdf.template.dir=/www/wwwroot/ftp.shengliankeji.top/templates
+#??
+#pdf.server.http.prefix=https://stockapdf.shengliankeji.top
+#??
+pdf.server.http.prefix=http://localhost:8099
+#??
+#loca.pdf.dir=/www/wwwroot/stock.A.PDF
+#??
+loca.pdf.dir=D:/work/A-stock/agreement_pdf
+#??
+#pdf.template.dir=/www/wwwroot/ftp.shengliankeji.top/templates
+#??
+pdf.template.dir=D:/work/A-stock/src/main/resources/templates
 #ftp.server.ip=47.56.200.145
 #ftp.user=ofsuccess
 #ftp.pass=fdymdM34HHsS8iB6
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index c7fc417..b35528f 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -104,12 +104,12 @@
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     driverClassName: com.mysql.cj.jdbc.Driver
-#    url: jdbc:mysql://127.0.0.1:3306/stock_hongta_101?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-#    username: root
-#    password: 123456
     url: jdbc:mysql://127.0.0.1:3306/stock_hongta_101?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-    username: stock_hongta_101
-    password: mFi7EZKGmnJFh8at
+    username: root
+    password: 123456
+#    url: jdbc:mysql://127.0.0.1:3306/stock_hongta_101?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+#    username: stock_hongta_101
+#    password: mFi7EZKGmnJFh8at
     druid:
       # 初始连接数
       initialSize: 5
diff --git a/src/main/resources/mapper/ContractImageMapper.xml b/src/main/resources/mapper/ContractImageMapper.xml
new file mode 100644
index 0000000..9aec2bc
--- /dev/null
+++ b/src/main/resources/mapper/ContractImageMapper.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.nq.dao.ContractImageMapper">
+    <resultMap id="BaseResultMap" type="com.nq.pojo.ContractImage">
+        <id column="id" property="id" jdbcType="INTEGER"/>
+        <result column="user_id" property="userId" jdbcType="INTEGER"/>
+        <result column="contract_type" property="contractType" jdbcType="VARCHAR"/>
+        <result column="address" property="address" jdbcType="VARCHAR"/>
+        <result column="add_time" property="addTime" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <select id="selectByUserIdAndType" resultMap="BaseResultMap">
+        select * from contract_image
+        where user_id = #{userId} and contract_type = #{contractType}
+        order by add_time asc
+    </select>
+</mapper>

--
Gitblit v1.9.3