From 9c638d29f43035bb224996f3183a58d761cd526e Mon Sep 17 00:00:00 2001
From: peter <14100000001@qq.com>
Date: Sun, 11 Jan 2026 18:21:39 +0800
Subject: [PATCH] 1.11文档修改

---
 src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java | 1154 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 843 insertions(+), 311 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..3dbd397 100644
--- a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
@@ -15,12 +15,28 @@
 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.*;
 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 java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.GraphicsEnvironment;
+import com.nq.pojo.ContractImage;
+import com.nq.dao.ContractImageMapper;
+import com.alibaba.fastjson.JSON;
 
 @Service("iUserAgreementService")
 public class UserAgreementServiceImpl implements IUserAgreementService {
@@ -29,20 +45,535 @@
     @Autowired
     private com.nq.service.IUserService iUserService;
 
+    @Autowired
+    private ContractImageMapper contractImageMapper;
+
     @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("用户未登录");
+            }
+
+            if (user.getIsActive()!=2 || StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
+                return ServerResponse.createByErrorMsg("请先完成实名认证");
+            }
+
+            // 检查是否已生成PDF
+            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);
+
+            // 如果PDF已存在,删除后重新生成,确保数据是最新的
+            if (pdfFile.exists()) {
+                log.info("PDF文件已存在,删除后重新生成: {}", pdfFile.getAbsolutePath());
+                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模板文件不存在");
+            }
+
+            // 从PDF模板生成新的PDF,替换占位符
+            generatePdfFromTemplate(pdfTemplate, pdfFile, user);
+
+            // 将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());
+        }
+    }
+
+    /**
+     * 从PDF模板生成新的PDF,替换占位符
+     */
+    private void generatePdfFromTemplate(File templatePdf, File outputPdf, User user) throws Exception {
+        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);
+
+            // 设置中文字体,使用EMBEDDED确保字体嵌入PDF,避免转图片时乱码
+            // 使用itext-asian库提供的中文字体,必须使用EMBEDDED模式
+            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
+            Font font = new Font(baseFont, 12, Font.NORMAL);
+
+            log.info("中文字体已加载: {}", baseFont.getPostscriptFontName());
+
+            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() : "";
+
+            log.info("PDF生成数据 - 姓名: {}, 身份证: {}, 地址: {}", realName, idCard, address);
+
+            // 获取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);
+
+                // 提取PDF文本查找占位符位置
+                String pageText = PdfTextExtractor.getTextFromPage(reader, pageNum, new SimpleTextExtractionStrategy());
+
+                // 在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);
+                }
+            }
+        }
+    }
+
+    /**
+     * 在PDF上替换占位符(使用透明背景图片方式)
+     */
+    private void replacePlaceholdersInPdf(PdfContentByte canvas, Rectangle pageSize, String pageText,
+                                          String realName, String idCard, String address,
+                                          String currentDate, Font font,int pageNum) throws Exception {
+        float margin = 50;
+        float lineHeight = 14;
+        float startY = pageSize.getHeight() - 204;
+
+        if(pageNum == 1){
+            // 生成透明背景的姓名图片并插入
+            File nameImage = createTextImage(realName, font);
+            insertImageToPdf(canvas, nameImage, margin + 75, startY);
+            startY -= lineHeight;
+
+            // 生成透明背景的地址图片并插入
+            File addressImage = createTextImage(address, font);
+            insertImageToPdf(canvas, addressImage, margin + 75, startY-2);
+            startY -= lineHeight;
+
+            // 生成透明背景的身份证号图片并插入
+            File idCardImage = createTextImage(idCard, font);
+            insertImageToPdf(canvas, idCardImage, margin + 95, startY-2);
+        }
+        if(pageNum == 3){
+            // 生成透明背景的日期图片并插入
+            File dateImage1 = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage1, margin + 60, startY+32);
+            
+            File dateImage2 = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage2, margin + 60, startY);
+        }
+    }
+
+    /**
+     * 从资源文件加载字体
+     */
+    private java.awt.Font loadFontFromResource(String fontPath, int size) {
+        try {
+            InputStream fontStream = this.getClass().getClassLoader().getResourceAsStream(fontPath);
+            if (fontStream != null) {
+                java.awt.Font font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontStream);
+                font = font.deriveFont(java.awt.Font.PLAIN, size);
+                fontStream.close();
+                log.info("成功从资源文件加载字体: {}", fontPath);
+                return font;
+            }
+        } catch (Exception e) {
+            log.warn("从资源文件加载字体失败: {}, 错误: {}", fontPath, e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * 从系统字体目录加载字体文件
+     */
+    private java.awt.Font loadFontFromFile(String fontPath, int size) {
+        try {
+            File fontFile = new File(fontPath);
+            if (fontFile.exists()) {
+                java.awt.Font font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile);
+                font = font.deriveFont(java.awt.Font.PLAIN, size);
+                log.info("成功从文件加载字体: {}", fontPath);
+                return font;
+            }
+        } catch (Exception e) {
+            log.warn("从文件加载字体失败: {}, 错误: {}", fontPath, e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * 获取可用的中文字体
+     */
+    private java.awt.Font getChineseFont(int size) {
+        // 1. 优先从资源文件加载字体(如果项目中有字体文件)
+        java.awt.Font font = loadFontFromResource("fonts/simsun.ttf", size);
+        if (font != null) return font;
+        
+        font = loadFontFromResource("fonts/simhei.ttf", size);
+        if (font != null) return font;
+        
+        // 2. 从系统字体目录加载(Linux常见字体路径)
+        String[] systemFontPaths = {
+            "/usr/share/fonts/chinese/simsun.ttf",           // CentOS/RHEL
+            "/usr/share/fonts/truetype/wqy/wqy-microhei.ttf", // 文泉驿
+            "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc", // Noto字体
+            "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", // DejaVu
+            "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", // Liberation
+            "/usr/share/fonts/chinese/SimSun.ttf",
+            "/usr/share/fonts/chinese/SimHei.ttf",
+            "/usr/share/fonts/truetype/arphic/uming.ttc",    // 文鼎字体
+            "/usr/share/fonts/truetype/arphic/ukai.ttc"
+        };
+        
+        for (String fontPath : systemFontPaths) {
+            font = loadFontFromFile(fontPath, size);
+            if (font != null) return font;
+        }
+        
+        // 3. 按优先级尝试加载系统已安装的字体
+        String[] fontNames = {
+            "SimSun",           // 宋体 (Windows)
+            "SimHei",           // 黑体 (Windows)
+            "Microsoft YaHei",  // 微软雅黑 (Windows)
+            "STSong",           // 华文宋体
+            "STHeiti",          // 华文黑体
+            "WenQuanYi Micro Hei", // 文泉驿微米黑 (Linux)
+            "WenQuanYi Zen Hei",   // 文泉驿正黑 (Linux)
+            "Noto Sans CJK SC",    // Noto字体 (Linux)
+            "Droid Sans Fallback", // Android字体 (Linux)
+            "AR PL UMing CN",       // 文鼎字体 (Linux)
+            "AR PL UKai CN"         // 文鼎字体 (Linux)
+        };
+        
+        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        String[] availableFonts = ge.getAvailableFontFamilyNames();
+        
+        // 查找可用的中文字体
+        for (String fontName : fontNames) {
+            for (String availableFont : availableFonts) {
+                if (availableFont.equals(fontName)) {
+                    try {
+                        font = new java.awt.Font(fontName, java.awt.Font.PLAIN, size);
+                        log.info("成功加载系统字体: {}", fontName);
+                        return font;
+                    } catch (Exception e) {
+                        log.warn("加载字体{}失败: {}", fontName, e.getMessage());
+                    }
+                }
+            }
+        }
+        
+        // 如果找不到中文字体,尝试使用逻辑字体
+        log.warn("未找到可用的中文字体,使用SERIF逻辑字体,可能出现乱码");
+        return new java.awt.Font(java.awt.Font.SERIF, java.awt.Font.PLAIN, size);
+    }
+
+    /**
+     * 创建透明背景的文本图片
+     */
+    private File createTextImage(String text, Font font) throws Exception {
+        if (StringUtils.isBlank(text)) {
+            text = "";
+        }
+
+        // 创建临时文件
+        String tempDir = PropertiesUtil.getProperty("loca.pdf.dir");
+        File dir = new File(tempDir);
+        if (!dir.exists()) {
+            dir.mkdirs();
+        }
+        
+        String tempFileName = "text_" + System.currentTimeMillis() + "_" + Thread.currentThread().getId() + ".png";
+        File imageFile = new File(dir, tempFileName);
+
+        // 创建透明背景的BufferedImage (TYPE_INT_ARGB 默认透明)
+        BufferedImage image = new BufferedImage(500, 50, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g2d = image.createGraphics();
+        
+        // 启用透明背景支持
+        g2d.setComposite(java.awt.AlphaComposite.SrcOver);
+
+        // 设置高质量渲染
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+
+        // 使用可用的中文字体
+        java.awt.Font awtFont = getChineseFont(12);
+        g2d.setFont(awtFont);
+        
+        // 使用深黑色,RGB(0, 0, 0) 完全不透明
+        g2d.setColor(new Color(0, 0, 0, 255));
+
+        // 绘制文本
+        FontMetrics fm = g2d.getFontMetrics();
+        int textWidth = fm.stringWidth(text);
+        int textHeight = fm.getHeight();
+        
+        // 调整图片大小以适应文本
+        if (textWidth > 0 && textHeight > 0) {
+            // TYPE_INT_ARGB 类型默认透明背景,不需要清除
+            BufferedImage resizedImage = new BufferedImage(textWidth + 20, textHeight + 10, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D g2dResized = resizedImage.createGraphics();
+            
+            // 启用透明背景支持
+            g2dResized.setComposite(java.awt.AlphaComposite.SrcOver);
+            
+            // 设置高质量渲染
+            g2dResized.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g2dResized.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+            g2dResized.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+            g2dResized.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+            
+            // 使用相同的中文字体
+            g2dResized.setFont(awtFont);
+            // 使用深黑色,RGB(0, 0, 0) 完全不透明
+            g2dResized.setColor(new Color(0, 0, 0, 255));
+            
+            // 绘制文本
+            g2dResized.drawString(text, 10, textHeight);
+            g2dResized.dispose();
+            
+            // 保存图片
+            ImageIO.write(resizedImage, "PNG", imageFile);
+            image = resizedImage;
+        } else {
+            // 如果文本为空,创建一个小的透明图片
+            BufferedImage emptyImage = new BufferedImage(50, 20, BufferedImage.TYPE_INT_ARGB);
+            ImageIO.write(emptyImage, "PNG", imageFile);
+            image = emptyImage;
+        }
+
+        g2d.dispose();
+
+        log.info("已创建透明背景文本图片: {}, 文本: {}", imageFile.getAbsolutePath(), text);
+        return imageFile;
+    }
+
+    /**
+     * 将图片插入到PDF指定位置
+     */
+    private void insertImageToPdf(PdfContentByte canvas, File imageFile, float x, float y) throws Exception {
+        if (imageFile == null || !imageFile.exists()) {
+            log.warn("图片文件不存在: {}", imageFile);
+            return;
+        }
+
+        try {
+            Image image = Image.getInstance(imageFile.getAbsolutePath());
+            image.setAbsolutePosition(x, y);
+            canvas.addImage(image);
+            log.info("图片已插入到PDF,位置: ({}, {})", x, y);
+            
+            // 删除临时图片文件
+            try {
+                imageFile.delete();
+            } catch (Exception e) {
+                log.warn("删除临时图片文件失败: {}", imageFile.getAbsolutePath(), e);
+            }
+        } catch (Exception e) {
+            log.error("插入图片到PDF失败: {}", imageFile.getAbsolutePath(), e);
+            throw e;
+        }
+    }
+
+    @Override
+    public ServerResponse viewAgreementPdf(HttpServletRequest request) {
         try {
             User user = iUserService.getCurrentUser(request);
             if (user == null) {
                 return ServerResponse.createByErrorMsg("用户未登录");
             }
 
-            if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
+            // 从数据库查询已签名的图片
+            List<ContractImage> contractImages = contractImageMapper.selectByUserIdAndType(user.getId(), "contract");
+            List<String> imageUrls = new ArrayList<>();
+            
+            if (contractImages != null && !contractImages.isEmpty()) {
+                for (ContractImage image : contractImages) {
+                    imageUrls.add(image.getAddress());
+                }
+                log.info("从数据库查询到用户{}的{}张已签名合同图片", user.getId(), imageUrls.size());
+            }
+
+            return ServerResponse.createBySuccess(imageUrls);
+        } catch (Exception e) {
+            log.error("查看用户协议PDF失败", e);
+            return ServerResponse.createByErrorMsg("查看PDF失败: " + e.getMessage());
+        }
+    }
+
+    @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());
+
+            String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+            String pdfFileName = "contract_" + user.getId() + ".pdf";
+            File pdfFile = new File(pdfDir, pdfFileName);
+            //删之前的图片
+            deleteFilesWithPattern(pdfDir,"contract_" + user.getId());
+            if (pdfFile.exists()) {
+                addSignatureToPdf(pdfFile, signatureFileLocal, user);
+                List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
+                for(String imageUrl : imageUrls) {
+                    ContractImage contractImage = new ContractImage();
+                    contractImage.setUserId(user.getId());
+                    contractImage.setContractType("contract");
+                    contractImage.setAddress(imageUrl);
+                    contractImage.setAddTime(new Date());
+                    contractImageMapper.insert(contractImage);
+                }
+                iUserService.updateSignedContract(user.getId(), "Y");
+            }
+            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 (user.getIsActive()!=2 || StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()) || StringUtils.isBlank(user.getRegAddress())) {
                 return ServerResponse.createByErrorMsg("用户信息不完整,请先完成实名认证");
             }
 
-            // 检查是否已生成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,303 +581,34 @@
 
             String pdfFileName = "agreement_" + user.getId() + ".pdf";
             File pdfFile = new File(dir, pdfFileName);
+
             if (pdfFile.exists()) {
-                return ServerResponse.createBySuccess(pdfFileName);
+                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);
+            generateContractPdfFromTemplate(pdfTemplate, pdfFile, user);
 
-            return ServerResponse.createBySuccess(pdfFileName);
+            // 将PDF转换为图片并返回图片路径数组
+            List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
+
+            return ServerResponse.createBySuccess(imageUrls);
         } catch (Exception e) {
-            log.error("生成用户协议PDF失败", 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));
-
-        // 设置中文字体
-        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());
-
-        // 准备替换的数据
-        String realName = user.getRealName() != null ? user.getRealName() : "";
-        String idCard = user.getIdCard() != null ? user.getIdCard() : "";
-        String address = user.getRegAddress() != null ? user.getRegAddress() : "";
-
-        // 获取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上查找并替换占位符
-            replacePlaceholdersInPdf(canvas, pageSize, pageText, realName, idCard, address, currentDate, font,pageNum);
-        }
-
-        stamper.close();
-        reader.close();
-    }
-
-    /**
-     * 在PDF上替换占位符(使用文本覆盖方式)
-     */
-    private void replacePlaceholdersInPdf(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){
-            replacePlaceholder(canvas, "", realName, margin + 75, startY, 0, font);
-            startY -= lineHeight;
-
-            replacePlaceholder(canvas, "", address, margin + 75, startY-2, 0, font);
-            startY -= lineHeight;
-
-            replacePlaceholder(canvas, "", idCard, margin + 95, startY-2, 0, font);
-        }
-        if(pageNum == 3){
-            replacePlaceholder(canvas, "", currentDate, margin + 60, startY+32, 0, font);
-            replacePlaceholder(canvas, "", currentDate, margin + 60, startY, 0, font);
-        }
-
-    }
-
-    /**
-     * 替换单个占位符
-     */
-    private void replacePlaceholder(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);
-    }
-
     @Override
-    public void viewAgreementPdf(HttpServletRequest request, HttpServletResponse response) {
+    public void viewAgreementContractPdf(HttpServletRequest request, HttpServletResponse response) {
         try {
             User user = iUserService.getCurrentUser(request);
             if (user == null) {
@@ -354,37 +616,307 @@
                 return;
             }
 
-            String pdfDir = PropertiesUtil.getProperty("agreement.pdf.dir", System.getProperty("user.dir") + "/agreement_pdf");
-            String pdfFileName = "agreement_" + user.getId() + ".pdf";
-            File pdfFile = new File(pdfDir, pdfFileName);
-
-            if (!pdfFile.exists()) {
-                response.sendError(HttpServletResponse.SC_NOT_FOUND, "协议文件不存在,请先生成协议");
-                return;
+            // 从数据库查询已签名的图片
+            List<ContractImage> contractImages = contractImageMapper.selectByUserIdAndType(user.getId(), "agreement");
+            List<String> imageUrls = new ArrayList<>();
+            
+            if (contractImages != null && !contractImages.isEmpty()) {
+                for (ContractImage image : contractImages) {
+                    imageUrls.add(image.getAddress());
+                }
+                log.info("从数据库查询到用户{}的{}张已签名保密协议图片", user.getId(), imageUrls.size());
             }
 
-            response.setContentType("application/pdf");
-            response.setHeader("Content-Disposition", "inline; filename=" + pdfFileName);
-
-            FileInputStream fis = new FileInputStream(pdfFile);
-            OutputStream 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();
+            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);
+            log.error("查看用户合同PDF失败", e);
             try {
-                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败");
+                if (!response.isCommitted()) {
+                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查看PDF失败: " + e.getMessage());
+                }
             } catch (IOException ex) {
                 log.error("发送错误响应失败", ex);
             }
         }
     }
+
+    @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 = "agreement_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 = "agreement_" + user.getId() + ".pdf";
+            File pdfFile = new File(pdfDir, pdfFileName);
+            //删之前的图片
+            deleteFilesWithPattern(pdfDir,"agreement_" + user.getId());
+            if (pdfFile.exists()) {
+                addSignatureToContractPdf(pdfFile, signatureFileLocal, user);
+
+                List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
+                for (String imageUrl : imageUrls) {
+                    ContractImage contractImage = new ContractImage();
+                    contractImage.setUserId(user.getId());
+                    contractImage.setContractType("agreement");
+                    contractImage.setAddress(imageUrl);
+                    contractImage.setAddTime(new Date());
+                    contractImageMapper.insert(contractImage);
+                }
+                iUserService.updateSignedAgreement(user.getId(), "Y");
+            }
+
+            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));
+
+        // 设置中文字体,使用EMBEDDED确保字体嵌入PDF,避免转图片时乱码
+        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.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() - 374;
+        if(pageNum == 2){
+            // 生成透明背景的日期图片并插入
+            File dateImage = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage, margin + 320, startY);
+        }
+    }
+
+    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;
+        }
+    }
+    /**
+     * 将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 + "_" +userId +"_" + timestamp + ".png";
+                if (page > 0) {
+                    imageFileName = contractType+ "_" + userId + "_" + timestamp + "_" + (page + 1) + ".png";
+                }
+                File imageFile = new File(pdfDir, imageFileName);
+
+                ImageIO.write(optimizedImage, "png", imageFile);
+
+                String imageUrl = imagePrefix + "/" + 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());
+        }
+    }
+
+    public void deleteFilesWithPattern(String dirPath, String userId) {
+        File directory = new File(dirPath);
+        if (!directory.exists() || !directory.isDirectory()) {
+            System.out.println("目录不存在或路径错误: " + dirPath);
+            return;
+        }
+
+        File[] files = directory.listFiles((dir, name) -> name.contains(userId + "_"));
+        if (files != null) {
+            for (File file : files) {
+                if (file.delete()) {
+                    System.out.println("已删除文件: " + file.getName());
+                } else {
+                    System.out.println("删除失败: " + file.getName());
+                }
+            }
+        }
+    }
 }

--
Gitblit v1.9.3