Browse Source

新增 公司章程,征信自动生成pdf

Administrator 11 months ago
parent
commit
85869b0030

+ 13 - 0
ruoyi-common/pom.xml

@@ -17,6 +17,13 @@
 
 
 
 
     <dependencies>
     <dependencies>
+        <!--   pdf文件处理包导入     -->
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>2.0.24</version>
+        </dependency>
+
         <!--二维码-->
         <!--二维码-->
         <dependency>
         <dependency>
             <groupId>com.google.zxing</groupId>
             <groupId>com.google.zxing</groupId>
@@ -187,6 +194,12 @@
             <artifactId>commons-compress</artifactId>
             <artifactId>commons-compress</artifactId>
             <version>1.19</version>
             <version>1.19</version>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-mock</artifactId>
+            <version>2.0.8</version>
+            <scope>compile</scope>
+        </dependency>
 
 
     </dependencies>
     </dependencies>
 
 

+ 56 - 2
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java

@@ -3,9 +3,15 @@ package com.ruoyi.common.utils.file;
 import java.io.File;
 import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.nio.file.Paths;
-import java.util.Objects;
-
+import java.util.*;
+import com.ruoyi.common.core.domain.AjaxResult;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.FilenameUtils;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
+import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.Constants;
@@ -15,6 +21,7 @@ import com.ruoyi.common.exception.file.InvalidExtensionException;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.uuid.Seq;
 import com.ruoyi.common.utils.uuid.Seq;
+import javax.imageio.ImageIO;
 
 
 /**
 /**
  * 文件上传工具类
  * 文件上传工具类
@@ -288,4 +295,51 @@ public class FileUploadUtils {
         return StringUtils.format("{}/{}.{}", loanApplicationNumber,
         return StringUtils.format("{}/{}.{}", loanApplicationNumber,
                 FilenameUtils.getBaseName(originalFilename), getExtension(file));
                 FilenameUtils.getBaseName(originalFilename), getExtension(file));
     }
     }
+
+    /**
+     * 合并图片生成PDF保存为文件
+     * @return
+     */
+    public static AjaxResult createPdfFromImages(List<String> imagePaths, File outputFile) throws IOException {
+        try (PDDocument document = new PDDocument()) {
+            float margin = 50f; // Define the margin
+
+            for (String imagePath : imagePaths) {
+                // Load image
+                PDImageXObject image = LosslessFactory.createFromImage(document, ImageIO.read(new File(imagePath)));
+
+                // Calculate scaling factor to fit image within the page minus margins, maintaining aspect ratio
+                float imgWidth = image.getWidth();
+                float imgHeight = image.getHeight();
+                float pageWidthForImage = PDRectangle.A4.getWidth() - 2 * margin; // Subtracting total margin from width
+                float pageHeightForImage = PDRectangle.A4.getHeight() - 2 * margin; // Subtracting total margin from height
+
+                float scaleX = pageWidthForImage / imgWidth;
+                float scaleY = pageHeightForImage / imgHeight;
+                float scale = Math.min(scaleX, scaleY);
+
+                // Resize the image dimensions with the scale
+                imgWidth *= scale;
+                imgHeight *= scale;
+
+                // Create a new page and add it to the document
+                PDPage page = new PDPage(PDRectangle.A4);
+                document.addPage(page);
+
+                // Get the content stream for the page
+                try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
+                    // Calculate the centered position considering the total margin around the page
+                    float x = (page.getMediaBox().getWidth() - imgWidth) / 2; // Centered without adding margin again
+                    float y = (page.getMediaBox().getHeight() - imgHeight) / 2; // Centered without adding margin again
+
+                    // Draw the scaled image onto the page at the correctly centered position
+                    contentStream.drawImage(image, x, y, imgWidth, imgHeight); // Apply margin here
+                }
+            }
+
+            // Save the final document
+            document.save(outputFile);
+        }
+        return null;
+    }
 }
 }

+ 123 - 11
ruoyi-system/src/main/java/com/ruoyi/system/service/loan/impl/LoanApplicationServiceImpl.java

@@ -28,6 +28,7 @@ import com.ruoyi.system.domain.review.ReviewComments;
 import com.ruoyi.system.mapper.*;
 import com.ruoyi.system.mapper.*;
 import com.ruoyi.system.service.loan.ILoanApplicationService;
 import com.ruoyi.system.service.loan.ILoanApplicationService;
 import lombok.SneakyThrows;
 import lombok.SneakyThrows;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -192,6 +193,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                 loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                 loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                 loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                 loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
             }
             }
+            createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber());
             loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
             loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
         }
         }
         List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
         List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
@@ -215,6 +217,115 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         return i;
         return i;
     }
     }
 
 
+
+    /**
+     * 合并图片生成PDF保存为文件
+     *
+     * @param loanApplicationFjList
+     * @return
+     */
+    public List<LoanApplicationFj> createPdfFromImages(List<LoanApplicationFj> loanApplicationFjList, String loanApplicationNumber) {
+        //根据文件类型进行判断是否需要合成pdf
+        //公司章程
+        List<String> gszc = loanApplicationFjList.stream().filter(e -> "gszc".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //申请企业征信报告
+        List<String> sqqyzxbg = loanApplicationFjList.stream().filter(e -> "sqqyzxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //关联企业征信报告
+        List<String> glqyzxbg = loanApplicationFjList.stream().filter(e -> "glqyzxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //企业法人征信报告
+        List<String> qyfrzxbg = loanApplicationFjList.stream().filter(e -> "qyfrzxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //实际控股人征信报告
+        List<String> sjkgrzxbg = loanApplicationFjList.stream().filter(e -> "sjkgrzxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //实际控股人配偶征信报告
+        List<String> sjkgrpozxbg = loanApplicationFjList.stream().filter(e -> "sjkgrpozxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+        //反担保人个人征信报告
+        List<String> fdbrgrzxbg = loanApplicationFjList.stream().filter(e -> "fdbrgrzxbg".equals(e.getType()) && ("png".equals(e.getName().split("\\.")[1]) || "jpg".equals(e.getName().split("\\.")[1]) || "jpeg".equals(e.getName().split("\\.")[1]))).map(LoanApplicationFj::getUrl).collect(Collectors.toList());
+
+        if (gszc.size() > 0) {
+            for (int i = 0; i < gszc.size(); i++) {
+                ///profile/upload/RZDB202405281147018884551/公司章程_20240528114820A002.png 前缀替换
+                String replaced = gszc.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                gszc.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, gszc, loanApplicationNumber, "公司章程_" + Seq.getId(Seq.uploadSeqType), "gszc");
+        }
+        if (sqqyzxbg.size() > 0) {
+            for (int i = 0; i < sqqyzxbg.size(); i++) {
+                String replaced = sqqyzxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                sqqyzxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, sqqyzxbg, loanApplicationNumber, "申请企业征信报告_" + Seq.getId(Seq.uploadSeqType), "sqqyzxbg");
+        }
+        if (glqyzxbg.size() > 0) {
+            for (int i = 0; i < glqyzxbg.size(); i++) {
+                String replaced = glqyzxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                glqyzxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, glqyzxbg, loanApplicationNumber, "关联企业征信报告_" + Seq.getId(Seq.uploadSeqType), "glqyzxbg");
+        }
+        if (qyfrzxbg.size() > 0) {
+            for (int i = 0; i < qyfrzxbg.size(); i++) {
+                String replaced = qyfrzxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                qyfrzxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, qyfrzxbg, loanApplicationNumber, "企业法人征信报告_" + Seq.getId(Seq.uploadSeqType), "qyfrzxbg");
+        }
+        if (sjkgrzxbg.size() > 0) {
+            for (int i = 0; i < sjkgrzxbg.size(); i++) {
+                String replaced = sjkgrzxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                sjkgrzxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, sjkgrzxbg, loanApplicationNumber, "实际控股人征信报告_" + Seq.getId(Seq.uploadSeqType), "sjkgrzxbg");
+        }
+        if (sjkgrpozxbg.size() > 0) {
+            for (int i = 0; i < sjkgrpozxbg.size(); i++) {
+                String replaced = sjkgrpozxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                sjkgrpozxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, sjkgrpozxbg, loanApplicationNumber, "实际控股人配偶征信报告_" + Seq.getId(Seq.uploadSeqType), "sjkgrpozxbg");
+        }
+        if (fdbrgrzxbg.size() > 0) {
+            for (int i = 0; i < fdbrgrzxbg.size(); i++) {
+                String replaced = fdbrgrzxbg.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
+                fdbrgrzxbg.set(i, replaced);
+            }
+            createPdfFromImages(loanApplicationFjList, fdbrgrzxbg, loanApplicationNumber, "反担保人个人征信报告_" + Seq.getId(Seq.uploadSeqType), "fdbrgrzxbg");
+        }
+        return loanApplicationFjList;
+    }
+
+    /**
+     * @param imagePaths            图片地址集合
+     * @param loanApplicationNumber 申请编号
+     * @param originalFilename      pdf文件名称
+     * @param type                  文件类型
+     */
+    public List<LoanApplicationFj> createPdfFromImages(List<LoanApplicationFj> loanApplicationFjList, List<String> imagePaths, String loanApplicationNumber, String originalFilename, String type) {
+        // 上传文件路径 = 根+申请编号
+        String filePath = StringUtils.format("{}/{}/{}.{}", RuoYiConfig.getUploadPath(), loanApplicationNumber,
+                FilenameUtils.getBaseName(originalFilename), "pdf");
+        //pdf保存位置
+        File outPutPdf = new File(filePath);
+        try {
+            FileUploadUtils.createPdfFromImages(imagePaths, outPutPdf);
+            //往附件信息中插入对应PDF数据
+            LoanApplicationFj applicationFj = new LoanApplicationFj();
+            applicationFj.setLoanApplicationId(loanApplicationFjList.get(0).getLoanApplicationId());
+            applicationFj.setLoanApplicationNumber(loanApplicationNumber);
+            applicationFj.setName(originalFilename + ".pdf");
+            applicationFj.setUrl(StringUtils.format("{}/{}/{}.{}", "/profile/upload", loanApplicationNumber,
+                    FilenameUtils.getBaseName(originalFilename), "pdf"));
+            applicationFj.setBigType(A);
+            applicationFj.setType(type);
+            //给前端判断是否是系统生成的pdf
+            applicationFj.setRemark(ONE);
+            loanApplicationFjList.add(applicationFj);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return loanApplicationFjList;
+    }
+
     /**
     /**
      * 修改贷款申请主
      * 修改贷款申请主
      *
      *
@@ -235,6 +346,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                 loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                 loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                 loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                 loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
             }
             }
+            createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber());
             loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
             loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
         }
         }
         shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
         shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
@@ -587,7 +699,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
             String enterpriseName = loanApplicationOld.getEnterpriseName();
             String enterpriseName = loanApplicationOld.getEnterpriseName();
             String loanApplicationNumber = loanApplicationOld.getLoanApplicationNumber();
             String loanApplicationNumber = loanApplicationOld.getLoanApplicationNumber();
             //如果退到 A角色审核 B角色审核 还需要插入待审核
             //如果退到 A角色审核 B角色审核 还需要插入待审核
-            if (loanApplication.getAuditSchedule().equals(TWO)){
+            if (loanApplication.getAuditSchedule().equals(TWO)) {
                 WaitRemind waitRemind = new WaitRemind();
                 WaitRemind waitRemind = new WaitRemind();
                 waitRemind.setLoanApplicationId(loanApplicationId);
                 waitRemind.setLoanApplicationId(loanApplicationId);
                 waitRemind.setLoanApplicationNumber(loanApplicationNumber);
                 waitRemind.setLoanApplicationNumber(loanApplicationNumber);
@@ -599,7 +711,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                 waitRemind.setRemindContent(enterpriseName + "有一条贷款申请需及时处理");
                 waitRemind.setRemindContent(enterpriseName + "有一条贷款申请需及时处理");
                 waitRemindMapper.insertWaitRemind(waitRemind);
                 waitRemindMapper.insertWaitRemind(waitRemind);
             }
             }
-            if (loanApplication.getAuditSchedule().equals(THR)){
+            if (loanApplication.getAuditSchedule().equals(THR)) {
                 WaitRemind waitRemind = new WaitRemind();
                 WaitRemind waitRemind = new WaitRemind();
                 waitRemind.setLoanApplicationId(loanApplicationId);
                 waitRemind.setLoanApplicationId(loanApplicationId);
                 waitRemind.setLoanApplicationNumber(loanApplicationNumber);
                 waitRemind.setLoanApplicationNumber(loanApplicationNumber);
@@ -795,14 +907,14 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         String fileName = "";
         String fileName = "";
         String fileNameHz = "";
         String fileNameHz = "";
         String wordPath = "";
         String wordPath = "";
-        String sheet ="";
+        String sheet = "";
         //生成二维码
         //生成二维码
-        String ewmPath = RuoYiConfig.getProfile()+"/mb/ewm";
+        String ewmPath = RuoYiConfig.getProfile() + "/mb/ewm";
         JSONObject json = new JSONObject();
         JSONObject json = new JSONObject();
-        json.put("type","2");
-        json.put("loanApplicationNumber",loanApplication.getLoanApplicationNumber());
-        json.put("bigType",bigType);
-        json.put("fileType",fileType);
+        json.put("type", "2");
+        json.put("loanApplicationNumber", loanApplication.getLoanApplicationNumber());
+        json.put("bigType", bigType);
+        json.put("fileType", fileType);
         String imagePath = QRCodeUtils.encodeNodate(json.toString(), null, ewmPath, true);
         String imagePath = QRCodeUtils.encodeNodate(json.toString(), null, ewmPath, true);
         if (StringUtils.isNotEmpty(imagePath)) {
         if (StringUtils.isNotEmpty(imagePath)) {
             PictureRenderData picture = Pictures.ofLocal(imagePath).size(70, 70).create();//本地图片地址
             PictureRenderData picture = Pictures.ofLocal(imagePath).size(70, 70).create();//本地图片地址
@@ -946,7 +1058,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                 fileName = loanApplication.getEnterpriseName() + "-项目评审意见签批表";
                 fileName = loanApplication.getEnterpriseName() + "-项目评审意见签批表";
                 fileNameHz = fileName + ".xlsx";
                 fileNameHz = fileName + ".xlsx";
                 templatePath = RuoYiConfig.getProfile() + "/mb/项目评审意见签批表.xlsx";
                 templatePath = RuoYiConfig.getProfile() + "/mb/项目评审意见签批表.xlsx";
-                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/"+fileNameHz;
+                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/" + fileNameHz;
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
 
 
                 path = sheet;
                 path = sheet;
@@ -963,7 +1075,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                     fileName = loanApplication.getEnterpriseName() + "-担保项目合法合规表个人个体户";
                     fileName = loanApplication.getEnterpriseName() + "-担保项目合法合规表个人个体户";
                 }
                 }
                 fileNameHz = fileName + ".xlsx";
                 fileNameHz = fileName + ".xlsx";
-                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/"+fileNameHz;
+                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/" + fileNameHz;
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
                 path = sheet;
                 path = sheet;
                 break;
                 break;
@@ -979,7 +1091,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
                     fileName = loanApplication.getEnterpriseName() + "-放款审批合规表个人个体户";
                     fileName = loanApplication.getEnterpriseName() + "-放款审批合规表个人个体户";
                 }
                 }
                 fileNameHz = fileName + ".xlsx";
                 fileNameHz = fileName + ".xlsx";
-                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/"+fileNameHz;
+                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber + "/" + fileNameHz;
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
                 sheet = ExcelFillUtils.fillOneSheet(templatePath, fileDir, "Sheet1", list);
                 path = sheet;
                 path = sheet;
                 break;
                 break;