Prechádzať zdrojové kódy

修复暂存,修改删除所有附件问题,新增删除服务器内文件pdf,新增pdf压缩

Administrator 11 mesiacov pred
rodič
commit
3c3752bac9

+ 5 - 4
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java

@@ -1,11 +1,13 @@
 package com.ruoyi.web.controller.common;
 
 import java.io.File;
+import java.time.temporal.TemporalUnit;
 import java.util.ArrayList;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.ruoyi.common.utils.ThumbnailUtil;
 import com.ruoyi.system.domain.vo.UploadVo;
 import net.lingala.zip4j.ZipFile;
 import net.lingala.zip4j.exception.ZipException;
@@ -78,7 +80,7 @@ public class CommonController {
             String fileName = FileUploadUtils.upload(filePath, file);
             String url = serverConfig.getUrl() + fileName;
             //服务器路径
-            String urlOnline = filePath + fileName.replace("/profile/upload","");
+            String urlOnline = filePath + fileName.replace("/profile/upload", "");
             AjaxResult ajax = AjaxResult.success();
             ajax.put("url", url);
             ajax.put("urlOnline", urlOnline);
@@ -95,9 +97,8 @@ public class CommonController {
      * 按照项目编号创建文件夹通用上传请求(单个)
      */
     @PostMapping("/uploadNew")
-    public AjaxResult uploadNewFile( @RequestParam("file") MultipartFile file,@RequestParam("loanApplicationNumber") String loanApplicationNumber,@RequestParam("fileName") String originalFilename) throws Exception {
+    public AjaxResult uploadNewFile(@RequestParam("file") MultipartFile file, @RequestParam("loanApplicationNumber") String loanApplicationNumber, @RequestParam("fileName") String originalFilename) throws Exception {
         try {
-
             // 上传文件路径
             String filePath = RuoYiConfig.getUploadPath();
             // 上传并返回新文件名称
@@ -105,7 +106,7 @@ public class CommonController {
             String url = serverConfig.getUrl() + fileName;
             AjaxResult ajax = AjaxResult.success();
             //服务器路径
-            String urlOnline = filePath + fileName.replace("/profile/upload","");
+            String urlOnline = filePath + fileName.replace("/profile/upload", "");
             ajax.put("url", url);
             ajax.put("urlOnline", urlOnline);
             ajax.put("fileName", fileName);

+ 6 - 1
ruoyi-common/pom.xml

@@ -17,7 +17,12 @@
 
 
     <dependencies>
-
+        <!--imageio-jpeg CMYK模式读取支持-->
+        <dependency>
+            <groupId>com.twelvemonkeys.imageio</groupId>
+            <artifactId>imageio-jpeg</artifactId>
+            <version>3.6</version>
+        </dependency>
         <!--   pdf文件处理包导入     -->
         <dependency>
             <groupId>org.apache.pdfbox</groupId>

+ 2 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/IdCardUtil.java

@@ -551,6 +551,8 @@ public class IdCardUtil {
                 map.put("establishData", establishData);
                 map.put("businessTerm", businessTerm);
                 map.put("businessScope", businessScope);
+            }else {
+                return AjaxResult.error("营业执照识别失败,请检查。");
             }
             return AjaxResult.success(map);
         } catch (Exception e) {

+ 553 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/ThumbnailUtil.java

@@ -0,0 +1,553 @@
+package com.ruoyi.common.utils;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/7/29 17:57
+ * @Describe:
+ */
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.multipart.MultipartFile;
+import javax.activation.MimetypesFileTypeMap;
+import javax.imageio.*;
+import javax.imageio.stream.ImageOutputStream;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.*;
+import java.util.stream.StreamSupport;
+
+
+/**
+ * @author
+ * @description 多线程图片压缩
+ * @date 2022/12/13 18:56
+ */
+public class ThumbnailUtil {
+
+    // 压缩比率, 低(原质量*0.85),中(原质量*0.7),高(原质量*0.6)
+    public static String[] ratios = new String[]{"low", "medium", "high"};
+    // 原始格式
+    public static String orgForm = "orgForm";
+    // 支持输出的图片格式
+    public static String[] imageFormats = new String[]{"bmp","jpeg","jpg","png"};
+
+    /**
+     * 多文件输入
+     * @param files
+     * @return
+     */
+    public static Builder<File> of(File... files) {
+        Iterable<File> iter = Arrays.asList(files);
+        return new Builder<>(iter);
+    }
+
+    /**
+     * 多文件Buffered流输入
+     * @param images
+     * @return
+     */
+    public static Builder<BufferedImage> of(BufferedImage... images) {
+        return new Builder<>(Arrays.asList(images));
+    }
+
+    /**
+     * 多文件输入流输入
+     * @param inputStreams
+     * @return
+     */
+    public static Builder<InputStream> of(InputStream... inputStreams) {
+        return new Builder<>(Arrays.asList(inputStreams));
+    }
+
+    /**
+     * 多文件MultipartFile流输入
+     * @param multipartFiles
+     * @return
+     */
+    public static Builder<MultipartFile> of(MultipartFile... multipartFiles) {
+        return new Builder<>(Arrays.asList(multipartFiles));
+    }
+
+    /**
+     * 识别是否是图片过滤器
+     * @return
+     */
+    public static FilenameFilter readFilter() {
+        String readFormats[] = ImageIO.getReaderFormatNames();
+        Set<String> readFormatSet = new HashSet<>(Arrays.asList(readFormats));
+        String writeFormats[] = ImageIO.getWriterFormatNames();
+        return new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                String seprator = ".";
+                if (name == null || !name.contains(seprator)) {
+                    return false;
+                }
+                String format = name.substring(name.lastIndexOf(seprator) + 1);
+                return readFormatSet.contains(format);
+            }
+        };
+    }
+
+    public static class Builder<T> {
+        // 待转换源数据
+        private final Iterable<T> sources;
+        // 输出格式
+        private String outputFormat = null;
+        // 压缩比率
+        private String compressionRatio = null;
+
+        // 缩放后宽
+        private double scaleWidth = Double.NaN;
+        // 缩放后高
+        private double scaleHeight = Double.NaN;
+        // 压缩质量系数 0-1之间
+        private double outputQuality = Double.NaN;
+
+        private Builder() {
+            sources = null;
+        }
+
+        private Builder(Iterable<T> sources) {
+            this.sources = sources;
+        }
+
+        /**
+         * 自动通过压缩比率自匹配压缩宽高比率和压缩质量系数
+         * @param compressionRatio 压缩比率, 低(原质量*0.85),中(原质量*0.7),高(原质量*0.6)
+         * @return
+         */
+        public Builder<T> identifyCompress(String compressionRatio) {
+            if (!Objects.equals(Double.NaN, scaleWidth)
+                    || !Objects.equals(Double.NaN, scaleHeight)
+                    || !Objects.equals(Double.NaN, outputQuality)
+            ) {
+                // 有设置scale和outputQuality则不使用自动压缩选项
+                return this;
+            } else if (null == compressionRatio) {
+                this.compressionRatio = ratios[1];
+                return this;
+            }
+            if (!Arrays.toString(ratios).contains(compressionRatio)) {
+                throw new IllegalArgumentException("Unsupported compressionRatio Type.");
+            }
+            this.compressionRatio = compressionRatio;
+            return this;
+        }
+
+        /**
+         * 自动根据原图尺寸以及构造器中提供的参数计算压缩长宽和压缩质量
+         * @param compressionRatio 压缩比率
+         * @param width 原图宽
+         * @param height 原图高
+         * @return 新计算的压缩宽高和压缩质量系数
+         */
+        private Builder<T> identifyCompress(String compressionRatio, int width, int height) {
+            if (width <= 0 || height <= 0) {
+                throw new IllegalArgumentException("Width (" + width + ") and height (" + height + ") cannot be <= 0");
+            }
+            // 为了支持多线程压缩, 需要将可变变量直接传入方法中,不能使用共享变量返回scaleWidth和outputQuality
+            if (!Objects.equals(Double.NaN, scaleWidth)
+                    || !Objects.equals(Double.NaN, scaleHeight)
+                    || !Objects.equals(Double.NaN, outputQuality)
+            ) {
+                // 有设置scale和outputQuality则不使用自动压缩选项
+                return this;
+            } else if (null == compressionRatio) {
+                compressionRatio = ratios[1];
+            }
+            if (!Arrays.toString(ratios).contains(compressionRatio)) {
+                throw new IllegalArgumentException("Unsupported compressionRatio Type.");
+            }
+            int min = width < height ? width : height;
+            double offset;
+            Builder builder = new Builder();
+            if (Objects.equals(ratios[0], compressionRatio)) {
+                // 最低压缩,图片保持原来尺寸,质量为原图的0.8
+                builder.scaleWidth = builder.scaleHeight = 1.0D;
+                builder.outputQuality = 0.8D;
+                return builder;
+            } else if (Objects.equals(ratios[1], compressionRatio)) {
+                offset = 0.4D;
+            } else {
+                offset = 0.3D;
+            }
+            if (min <= 1024) {
+                // 最小像素小于1024,长和宽不压缩
+                builder.scaleWidth = builder.scaleHeight = 1.0D;
+                builder.outputQuality = (builder.outputQuality = 0.3D + offset) <= 1 ? builder.outputQuality : 1;
+            } else if (min > 1024 && min <= 3 * 1024) {
+                builder.scaleHeight = (builder.scaleHeight = 0.4D + offset) <= 1 ? builder.scaleHeight : 1;
+                builder.scaleWidth = builder.scaleHeight;
+                builder.outputQuality = (builder.outputQuality = 0.3D + offset) <= 1 ? builder.outputQuality : 1;
+            } else {
+                builder.scaleHeight = (builder.scaleHeight = 2048D / min + offset) <= 1 ? builder.scaleHeight : 1;
+                builder.scaleWidth = builder.scaleHeight;
+                builder.outputQuality = builder.scaleHeight;
+            }
+            return builder;
+        }
+
+        /**
+         * 自定义设置压缩宽高比率
+         * @param scaleWidth 宽压缩比率
+         * @param scaleHeight 高压缩比率
+         * @return
+         */
+        public Builder<T> scale(double scaleWidth, double scaleHeight) {
+            if (scaleWidth <= 0.0 || scaleHeight <= 0.0) {
+                throw new IllegalArgumentException(
+                        "The scaling factor is equal to or less than 0."
+                );
+            }
+            if (Double.isNaN(scaleWidth) || Double.isNaN(scaleHeight)) {
+                throw new IllegalArgumentException(
+                        "The scaling factor is not a number."
+                );
+            }
+            if (Double.isInfinite(scaleWidth) || Double.isInfinite(scaleHeight)) {
+                throw new IllegalArgumentException(
+                        "The scaling factor cannot be infinity."
+                );
+            }
+            this.scaleWidth = scaleWidth;
+            this.scaleHeight = scaleHeight;
+            return this;
+        }
+
+        /**
+         * 自定义等比例设置压缩宽高比率
+         * @param scale 等比例宽高压缩比率
+         * @return
+         */
+        public Builder<T> scale(double scale) {
+            return scale(scale, scale);
+        }
+
+        /**
+         * 自定义设置压缩质量系数 0-1之间
+         * @param quality 压缩质量系数 0-1之间
+         *                越大,压缩越少,质量越好,一般0.8的质量和原图肉眼识别不到差异
+         * @return
+         */
+        public Builder<T> outputQuality(double quality) {
+            if (quality < 0.0f || quality > 1.0f) {
+                throw new IllegalArgumentException(
+                        "The quality setting must be in the range 0.0f and " +
+                                "1.0f, inclusive."
+                );
+            }
+            outputQuality = quality;
+            return this;
+        }
+
+        /**
+         * 自定义设置输出格式,输出格式提前使用图片工具校验
+         * @param formatName jpg jpeg png 等常用格式 见枚举imageFormats
+         * @return
+         */
+        public Builder<T> outputFormat(String formatName) {
+            if (StringUtils.isEmpty(formatName)) {
+                this.outputFormat = orgForm;
+                return this;
+            } else if (Objects.equals(orgForm, formatName)) {
+                this.outputFormat = formatName;
+                return this;
+            }
+            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
+            if (!writers.hasNext()) {
+                throw new UnsupportedOperationException(
+                        "No suitable ImageWriter found for " + formatName + "."
+                );
+            }
+            this.outputFormat = formatName;
+            return this;
+        }
+
+        /**
+         * 校验输出格式是否正确
+         * @param source 待压缩数据
+         * @param formatName 输出格式
+         * @return
+         * @throws IOException
+         */
+        private String outputFormat(T source, String formatName) throws IOException {
+            if (source == null) {
+                throw new IllegalArgumentException("The resource being processed is null.");
+            }
+            if (StringUtils.isEmpty(formatName)) {
+                formatName = orgForm;
+            } else if (!Objects.equals(orgForm, formatName)) {
+                return formatName;
+            }
+            Iterator<ImageReader> iterReader = ImageIO.getImageReaders(ImageIO.createImageInputStream(source));
+            if (null == iterReader || !iterReader.hasNext()) {
+                throw new UnsupportedOperationException("The resource being processed is not a picture.");
+            }
+            formatName = iterReader.next().getFormatName();
+            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
+            if (!writers.hasNext()) {
+                throw new UnsupportedOperationException(
+                        "No suitable ImageWriter found for " + formatName + "."
+                );
+            }
+            return formatName;
+        }
+
+        /**
+         * 压缩实现关键方法
+         * @param source 待压缩数据
+         * @param outputStream 图片输出流
+         * @throws IOException
+         */
+        private void write(T source, final ImageOutputStream outputStream) throws IOException {
+            if (StringUtils.isEmpty(outputFormat)) {
+                throw new IllegalStateException("Output format has not been set.");
+            }
+            Objects.requireNonNull(outputStream, "Could not open OutputStream.");
+            BufferedImage srcImage;
+            if (source instanceof BufferedImage) {
+                srcImage = (BufferedImage) source;
+            } else if (source instanceof File) {
+                srcImage = ImageIO.read((File) source);
+            } else if (source instanceof MultipartFile) {
+                srcImage = ImageIO.read(((MultipartFile) source).getInputStream());
+                // 将MultipartFile装换为InputStream
+                source = (T) ((MultipartFile) source).getInputStream();
+            } else if (source instanceof InputStream) {
+                srcImage = ImageIO.read((InputStream) source);
+            } else {
+                throw new IllegalArgumentException("Unsupported ImageIO Type.");
+            }
+            // 校验输出格式是否正确
+            String outputFormatName = this.outputFormat(source, outputFormat);
+            System.out.println("outputFormatName : " + outputFormatName);
+            // 原图宽
+            int width = srcImage.getWidth();
+            // 原图高
+            int height = srcImage.getHeight();
+            // 自动根据原图尺寸以及构造器中提供的参数计算压缩长宽和压缩质量
+            Builder builder = this.identifyCompress(compressionRatio, width, height);
+            double scaleWidth = builder.scaleWidth;
+            double scaleHeight = builder.scaleHeight;
+            double outputQuality = builder.outputQuality;
+            System.out.println("scaleWidth ; " + scaleWidth + " scaleHeight : " + scaleHeight + " outputQuality : " + outputQuality);
+            if (Objects.equals(outputQuality, Double.NaN)) {
+                throw new IllegalArgumentException("outputQuality is null.");
+            }
+            // 缩放后宽
+            int sclWidth = Objects.equals(Double.NaN, scaleWidth) ? width : (int) (width * scaleWidth);
+            // 缩放后高
+            int sclHeight = Objects.equals(Double.NaN, scaleHeight) ? height : (int) (height * scaleHeight);
+            System.out.println("sclWidth : " + sclWidth + " sclHeight : " + sclHeight);
+            // 输出BufferedImage流
+            long startTime = System.currentTimeMillis();
+            BufferedImage destImage =
+                    new BufferedImage(sclWidth, sclHeight, BufferedImage.TYPE_INT_RGB);
+            Graphics2D g = destImage.createGraphics();
+            // 消除锯齿
+            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+//            g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_DEFAULT);
+            g.addRenderingHints(new HashMap<>());
+            g.drawImage(srcImage, 0, 0, sclWidth, sclHeight, null);
+            System.out.println("image scale cost time : " + (System.currentTimeMillis() - startTime));
+            // 压缩后增加一点点锐化,如不需要的,以下4行代码可以干掉
+            g.dispose();
+            ImageWriter writer = null;
+            ImageTypeSpecifier type =
+                    ImageTypeSpecifier.createFromRenderedImage(destImage);
+            // formatName不生效, 所以统一使用jpg
+//            Iterator iterIO = ImageIO.getImageWriters(type, outputFormatName);
+            Iterator iterIO = ImageIO.getImageWriters(type, "jpg");
+            if (iterIO.hasNext()) {
+                writer = (ImageWriter) iterIO.next();
+            }
+            if (writer == null) {
+                throw new IllegalArgumentException("ImageWriter is null.");
+            }
+
+            IIOImage iioImage = new IIOImage(destImage, null, null);
+            ImageWriteParam param = writer.getDefaultWriteParam();
+            if (param.canWriteCompressed() && !outputFormatName.equalsIgnoreCase("bmp")) {
+                param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+                param.setCompressionQuality((float) outputQuality);    //这里可以指定压缩的程度 0-1.0
+            } else {
+//                param.setCompressionQuality(0.0f);
+                System.out.println("The outputFormat (" + outputFormatName + ") cannot be compressed");
+            }
+            writer.setOutput(outputStream);
+            writer.write(null, iioImage, param);
+            writer.dispose();
+            outputStream.close();
+        }
+
+        /**
+         * 输出单个文件到Byte流
+         * @return
+         * @throws IOException
+         */
+        public ByteArrayInputStream asByteArray() throws IOException {
+            Iterator<T> iter = sources.iterator();
+            T source = iter.next();
+            if (iter.hasNext()) {
+                throw new IllegalArgumentException("Cannot create one thumbnail from multiple original images.");
+            }
+            // 将缓存中的图片按照指定的配置输出到字节数组中
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            write(source, ImageIO.createImageOutputStream(byteArrayOutputStream));
+            // 从字节数组中读取图片
+            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+//            InputStream inputStream = new ByteArrayInputStream(byteArrayInputStream);
+//            MultipartFile file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), byteArrayInputStream);
+            return byteArrayInputStream;
+        }
+
+        /**
+         * 多文件输出MultipartFile[]流文件
+         * @return
+         */
+        public MultipartFile[] asMultipartFiles() {
+            long startTime = System.currentTimeMillis();
+            MultipartFile[] multipartFiles = StreamSupport.stream(sources.spliterator(), true).map(source -> {
+                if (!(source instanceof File)
+                        && (!(source instanceof MultipartFile))
+                ) {
+                    throw new IllegalStateException("Cannot create thumbnails to files if original images are not from files or multipartFile.");
+                }
+                String filename = "";
+                String mimeType = "";
+                if (source instanceof File) {
+                    filename = ((File) source).getName();
+                    MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
+                    mimeType = fileTypeMap.getContentType(filename);
+                } else if (source instanceof MultipartFile) {
+                    filename = ((MultipartFile) source).getOriginalFilename();
+                    mimeType = ((MultipartFile) source).getContentType();
+                }
+                // 将缓存中的图片按照指定的配置输出到字节数组中
+                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                try {
+                    System.out.println("Process the image " + filename + " start.");
+                    write(source, ImageIO.createImageOutputStream(byteArrayOutputStream));
+                } catch (IOException e) {
+                    String desc = "Failed to process the image " + filename + " .";
+                    System.out.println(desc);
+                    throw new IllegalArgumentException(desc, e);
+                }
+                // 从字节数组中读取图片
+                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+                String octetStream = "application/octet-stream";
+                MultipartFile multipartFile = null;
+                try {
+                    multipartFile =  new MockMultipartFile(octetStream, filename, mimeType, byteArrayInputStream);
+                } catch (IOException e) {
+                    String desc = "Failed to mockMultipartFile the image " + filename + " .";
+                    System.out.println(desc);
+                    throw new IllegalArgumentException(desc, e);
+                }
+                return multipartFile;
+            }).toArray(MultipartFile[]::new);
+            System.out.println("cost : " + (System.currentTimeMillis() - startTime));
+            return multipartFiles;
+        }
+
+
+        /**
+         * 单文件输出提供的文件目录中
+         * @param outFile 文件目录
+         * @throws IOException
+         */
+        public void toFile(final File outFile) throws IOException {
+            Iterator<T> iter = sources.iterator();
+            T source = iter.next();
+            if (iter.hasNext()) {
+                throw new IllegalArgumentException("Cannot create one thumbnail from multiple original images.");
+            }
+            write(source, ImageIO.createImageOutputStream(outFile));
+        }
+
+        private void toFiles(Iterable<File> iterable) throws IOException {
+            Iterator<File> filenameIter = iterable.iterator();
+            for (T source : sources) {
+                if (!filenameIter.hasNext()) {
+                    throw new IndexOutOfBoundsException(
+                            "Not enough file names provided by iterator."
+                    );
+                }
+                write(source, ImageIO.createImageOutputStream(filenameIter.next()));
+            }
+        }
+
+        /**
+         * 多文件输出提供的文件目录中
+         * @param destinationDir 文件目录
+         * @param namePrefix 文件重命名前缀
+         * @throws IOException
+         */
+        public void toFiles(File destinationDir, String namePrefix) throws IOException {
+            if (destinationDir == null && namePrefix == null) {
+                throw new NullPointerException("destinationDir and rename is null.");
+            }
+            if (destinationDir != null && !destinationDir.isDirectory()) {
+                destinationDir.mkdir();
+//                throw new IllegalArgumentException("Given destination is not a directory.");
+            }
+
+            if (destinationDir != null && !destinationDir.isDirectory()) {
+                throw new IllegalArgumentException("Given destination is not a directory.");
+            }
+            long startTime = System.currentTimeMillis();
+            Builder<T> builder = outputFormat(outputFormat);
+            StreamSupport.stream(sources.spliterator(), true).forEach(source -> {
+                if (!(source instanceof File)) {
+                    throw new IllegalStateException("Cannot create thumbnails to files if original images are not from files.");
+                }
+                File f = (File) source;
+                File actualDestDir = destinationDir == null ? f.getParentFile() : destinationDir;
+                String name = StringUtils.isEmpty(namePrefix) ? f.getName() : namePrefix + f.getName();
+                if (!Objects.equals(orgForm, builder.outputFormat)) {
+                    name = name.substring(0, name.lastIndexOf(".")) + "." + outputFormat;
+                }
+                File destinationFile = new File(actualDestDir, name);
+                try {
+                    System.out.println("Process the image " + f.getName() + " start.");
+                    write((T) source, ImageIO.createImageOutputStream(destinationFile));
+                } catch (Exception e) {
+                    System.out.println("Failed to process the image " + f.getName() + " .");
+                    e.printStackTrace();
+                }
+            });
+            System.out.println("cost : " + (System.currentTimeMillis() - startTime));
+        }
+
+        /**
+         * 单文件输出提供的输出流中
+         * @throws IOException
+         */
+        public void toOutputStream(final OutputStream outputStream) throws IOException {
+            Iterator<T> iter = sources.iterator();
+            T source = iter.next();
+            if (iter.hasNext()) {
+                throw new IllegalArgumentException("Cannot create one thumbnail from multiple original images.");
+            }
+            write(source, ImageIO.createImageOutputStream(outputStream));
+        }
+
+        /**
+         * 多文件输出提供的多个输出流中
+         * @throws IOException
+         */
+        public void toOutputStreams(Iterable<? extends OutputStream> iterable) throws IOException {
+            Iterator<? extends OutputStream> filenameIter = iterable.iterator();
+            for (T source : sources) {
+                if (!filenameIter.hasNext()) {
+                    throw new IndexOutOfBoundsException(
+                            "Not enough file names provided by iterator."
+                    );
+                }
+                write(source, ImageIO.createImageOutputStream(filenameIter.next()));
+            }
+        }
+    }
+}

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

@@ -10,6 +10,7 @@ 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.JPEGFactory;
 import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
 import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 import org.springframework.web.multipart.MultipartFile;
@@ -303,10 +304,11 @@ public class FileUploadUtils {
     public static AjaxResult createPdfFromImages(List<String> imagePaths, File outputFile) throws IOException {
         try (PDDocument document = new PDDocument()) {
             float margin = 50f; // Define the margin
-
+            // 压缩图片质量,例如设置0.5的压缩质量
+            float quality = 0.5f;
             for (String imagePath : imagePaths) {
                 // Load image
-                PDImageXObject image = LosslessFactory.createFromImage(document, ImageIO.read(new File(imagePath)));
+                PDImageXObject image = JPEGFactory.createFromImage(document, ImageIO.read(new File(imagePath)),quality);
 
                 // Calculate scaling factor to fit image within the page minus margins, maintaining aspect ratio
                 float imgWidth = image.getWidth();

+ 59 - 7
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java

@@ -16,6 +16,7 @@ import com.ruoyi.system.domain.loan.ShareholderFj;
 import com.ruoyi.system.mapper.ShareholderFjMapper;
 import com.ruoyi.system.service.loan.ILoanApplicationFjService;
 import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import com.ruoyi.common.constant.Constants;
@@ -36,7 +37,7 @@ import static com.ruoyi.common.constant.CommonConstants.*;
 
 /**
  * 异步工厂(产生任务用)
- * 
+ *
  * @author ruoyi
  */
 public class AsyncFactory
@@ -45,7 +46,7 @@ public class AsyncFactory
 
     /**
      * 记录登录信息
-     * 
+     *
      * @param username 用户名
      * @param status 状态
      * @param message 消息
@@ -100,7 +101,7 @@ public class AsyncFactory
 
     /**
      * 操作日志记录
-     * 
+     *
      * @param operLog 操作日志信息
      * @return 任务task
      */
@@ -134,8 +135,12 @@ public class AsyncFactory
                 if (bigTypeMap.size() > 0){
                     List<LoanApplicationFj> loanApplicationFjListA = bigTypeMap.get(A);
                     List<LoanApplicationFj> loanApplicationFjListB = bigTypeMap.get(B);
-                    createPdfFromImages(loanApplicationFjList,loanApplicationFjListA,loanApplicationNumber,A);
-                    createPdfFromImages(loanApplicationFjList,loanApplicationFjListB,loanApplicationNumber,B);
+                    if (loanApplicationFjListA != null && loanApplicationFjListA.size() > 0){
+                        createPdfFromImages(loanApplicationFjList,loanApplicationFjListA,loanApplicationNumber,A);
+                    }
+                    if (loanApplicationFjListB != null && loanApplicationFjListB.size() > 0){
+                        createPdfFromImages(loanApplicationFjList,loanApplicationFjListB,loanApplicationNumber,B);
+                    }
                 }
             }
         };
@@ -161,6 +166,28 @@ public class AsyncFactory
                         String replaced = typeList.get(i).replace("/profile/upload", RuoYiConfig.getUploadPath());
                         typeList.set(i, replaced);
                     }
+                    //先删除原先的pdf数据库记录
+                    List<LoanApplicationFj> pdfOne = loanApplicationFjListInsert.stream().filter(e -> ObjectUtils.isNotEmpty(e.getRemark()) && e.getRemark().equals(ONE) && ("pdf".equals(e.getName().split("\\.")[1]))).collect(Collectors.toList());
+                    if (pdfOne.size() > 0){
+                        for (LoanApplicationFj loanApplicationFj : pdfOne) {
+                            //删除数据库数据
+                            SpringUtils.getBean(ILoanApplicationFjService.class).deleteLoanApplicationFjByFjId(loanApplicationFj.getFjId());
+                            //删除服务器记录
+                            String urlPdf = loanApplicationFj.getUrl();
+                            if (StringUtils.isNotBlank(urlPdf)){
+                                String filePath = urlPdf.replace("/profile/upload", RuoYiConfig.getUploadPath());
+                                //删除服务器上对应文件
+                                File file = new File(filePath);
+                                if (file.exists()){
+                                    if (file.delete()){
+                                        System.out.println("删除:"+filePath);
+                                    }else {
+                                        System.out.println("删除:"+filePath+"失败");
+                                    }
+                                }
+                            }
+                        }
+                    }
                     createPdfFromImages(loanApplicationFjList, typeList, loanApplicationNumber, fjName+"_" + Seq.getId(Seq.uploadSeqType), type,bigType);
                 }
             }
@@ -218,6 +245,20 @@ public class AsyncFactory
                 List<String> imagePaths = new ArrayList<>();
                 //根据文件类型进行判断是否需要合成pdf
                 for (ShareholderFj shareholderFj : shareholderFjList) {
+                    //获取原先的pdf地址,去服务器上删除要替换路径
+                    String shareholderZxUrlPdf = shareholderFj.getShareholderZxUrlPdf();
+                    if (StringUtils.isNotBlank(shareholderZxUrlPdf)){
+                        String filePath = shareholderZxUrlPdf.replace("/profile/upload", RuoYiConfig.getUploadPath());
+                        //删除服务器上对应文件
+                        File file = new File(filePath);
+                        if (file.exists()){
+                            if (file.delete()){
+                                System.out.println("删除:"+filePath);
+                            }else {
+                                System.out.println("删除:"+filePath+"失败");
+                            }
+                        }
+                    }
                     String shareholderZxUrl = shareholderFj.getShareholderZxUrl();
                     if (StringUtils.isNotEmpty(shareholderZxUrl)) {
                         String[] split = shareholderZxUrl.split(",");
@@ -250,8 +291,19 @@ public class AsyncFactory
                                 FilenameUtils.getBaseName(substring), "pdf"));
                     }
                 }
-                // 插入数据
-                SpringUtils.getBean(ShareholderFjMapper.class).batchShareholderFj(shareholderFjList);
+                //判断是否有股东shareholder_fj_id
+                List<ShareholderFj> shareholderFjsInsert = shareholderFjList.stream().filter(e -> ObjectUtils.isEmpty(e.getShareholderFjId())).collect(Collectors.toList());
+                if (shareholderFjsInsert.size() > 0){
+                    // 新增股东数据
+                    SpringUtils.getBean(ShareholderFjMapper.class).batchShareholderFj(shareholderFjsInsert);
+                }
+                List<ShareholderFj> shareholderFjsUpdate = shareholderFjList.stream().filter(e -> ObjectUtils.isNotEmpty(e.getShareholderFjId())).collect(Collectors.toList());
+                if (shareholderFjsUpdate.size() > 0){
+                    for (ShareholderFj shareholderFj : shareholderFjsUpdate) {
+                        //更新股东信息
+                        SpringUtils.getBean(ShareholderFjMapper.class).updateShareholderFj(shareholderFj);
+                    }
+                }
             }
         };
     }

+ 80 - 46
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/LoanApplicationServiceImpl.java

@@ -152,12 +152,12 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         List<SysRole> roles = user.getRoles();
         Boolean bl = false;
         for (SysRole role : roles) {
-            if(role.getRoleKey().equals("admin") || role.getRoleKey().equals("manager")){
+            if (role.getRoleKey().equals("admin") || role.getRoleKey().equals("manager")) {
                 bl = true;
                 break;
             }
         }
-        if(!bl){
+        if (!bl) {
             loanApplication.setUserId(user.getUserId());
         }
         List<LoanApplication> loanApplications = loanApplicationMapper.conferenceList(loanApplication);
@@ -196,6 +196,10 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
      */
     @Override
     public int insertLoanApplication(LoanApplication loanApplication) {
+        if (loanApplicationMapper.selectLoanApplicationList(loanApplication).size() > 0){
+            return 0;
+        }
+        //先去查询贷款编码是否已经存在
         //设置为audit_schedule=1 audit_type=1
         loanApplication.setAuditSchedule(ONE);
         loanApplication.setAuditType(ONE);
@@ -251,28 +255,43 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         loanApplication.setLoanApplicationType(TWO);
         loanApplication.setApplicationTime(DateUtils.getNowDate());
         Long loanApplicationId = loanApplication.getLoanApplicationId();
+
+        //需要删除的id集合
+        Long[] loanApplicationFjIdList = loanApplication.getLoanApplicationFjIdList();
+        Long[] shareholderFjIdList = loanApplication.getShareholderFjIdList();
         //相关附件先删除
-        loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationId(loanApplicationId);
+        //loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationId(loanApplicationId);
         List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
         if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
-            for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
-                loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
-                loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
+            //判断有附件id的附件进行修改,没有的进行新增
+            List<LoanApplicationFj> loanApplicationFjsInsert = loanApplicationFjList.stream().filter(e -> ObjectUtils.isEmpty(e.getFjId())).collect(Collectors.toList());
+            if (loanApplicationFjsInsert.size() > 0) {
+                for (LoanApplicationFj loanApplicationFj : loanApplicationFjsInsert) {
+                    loanApplicationFj.setLoanApplicationId(loanApplicationId);
+                    loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
+                }
+                //新增新增的附件
+                loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjsInsert);
+            }
+            if (loanApplicationFjsInsert.size() > 0 || loanApplicationFjIdList.length > 0){
+                AsyncManager.me().execute(AsyncFactory.createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber()));
             }
-            AsyncManager.me().execute(AsyncFactory.createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber()));
-
-            loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
         }
-        shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
+        //需要删除附件表数据
+        if (loanApplicationFjIdList.length > 0) {
+            loanApplicationFjMapper.deleteLoanApplicationFjByFjIds(loanApplicationFjIdList);
+        }
+
+        //shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
         List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
         if (shareholderFjList != null && shareholderFjList.size() > 0) {
-            for (ShareholderFj shareholderFj : shareholderFjList) {
-                shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
-                shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
-            }
             AsyncManager.me().execute(AsyncFactory.createPdfFromImagesShareholder(shareholderFjList, loanApplication.getLoanApplicationNumber()));
             // shareholderFjMapper.batchShareholderFj(shareholderFjList);
         }
+        //需要删除股东附件表数据
+        if (shareholderFjIdList.length > 0) {
+            shareholderFjMapper.deleteShareholderFjByShareholderFjIds(shareholderFjIdList);
+        }
         return loanApplicationMapper.updateLoanApplication(loanApplication);
     }
 
@@ -288,28 +307,42 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         Long loanApplicationId = loanApplication.getLoanApplicationId();
         //走修改
         if (loanApplicationId != null) {
-            //相关附件先删除
-            loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationId(loanApplicationId);
+            //需要删除的id集合
+            Long[] loanApplicationFjIdList = loanApplication.getLoanApplicationFjIdList();
+            Long[] shareholderFjIdList = loanApplication.getShareholderFjIdList();
+
             List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
             if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
-                for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
-                    loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
-                    loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
+                //判断有附件id的附件进行修改,没有的进行新增
+                List<LoanApplicationFj> loanApplicationFjsInsert = loanApplicationFjList.stream().filter(e -> ObjectUtils.isEmpty(e.getFjId())).collect(Collectors.toList());
+                if (loanApplicationFjsInsert.size() > 0) {
+                    for (LoanApplicationFj loanApplicationFj : loanApplicationFjsInsert) {
+                        loanApplicationFj.setLoanApplicationId(loanApplicationId);
+                        loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
+                    }
+                    //新增新增的附件
+                    loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjsInsert);
                 }
-                AsyncManager.me().execute(AsyncFactory.createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber()));
-
-                loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
+                if (loanApplicationFjsInsert.size() > 0 || loanApplicationFjIdList.length > 0){
+                    AsyncManager.me().execute(AsyncFactory.createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber()));
+                }
+            }
+            //需要删除附件表数据
+            if (loanApplicationFjIdList.length > 0) {
+                loanApplicationFjMapper.deleteLoanApplicationFjByFjIds(loanApplicationFjIdList);
             }
-            shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
+
             List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
             if (shareholderFjList != null && shareholderFjList.size() > 0) {
                 for (ShareholderFj shareholderFj : shareholderFjList) {
-                    shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
+                    shareholderFj.setLoanApplicationId(loanApplicationId);
                     shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                 }
                 AsyncManager.me().execute(AsyncFactory.createPdfFromImagesShareholder(shareholderFjList, loanApplication.getLoanApplicationNumber()));
-
-                //shareholderFjMapper.batchShareholderFj(shareholderFjList);
+            }
+            //需要删除股东附件表数据
+            if (shareholderFjIdList.length > 0) {
+                shareholderFjMapper.deleteShareholderFjByShareholderFjIds(shareholderFjIdList);
             }
             int rows = loanApplicationMapper.updateLoanApplication(loanApplication);
             return rows > 0 ? AjaxResult.success() : AjaxResult.error();
@@ -329,10 +362,11 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         //贷款申请进度进入申报提交
         loanApplication.setLoanSchedule(ONE);
         int rows = loanApplicationMapper.insertLoanApplication(loanApplication);
+        loanApplicationId = loanApplication.getLoanApplicationId();
         List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
         if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
             for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
-                loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
+                loanApplicationFj.setLoanApplicationId(loanApplicationId);
                 loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
             }
             AsyncManager.me().execute(AsyncFactory.createPdfFromImages(loanApplicationFjList, loanApplication.getLoanApplicationNumber()));
@@ -341,7 +375,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
         if (shareholderFjList != null && shareholderFjList.size() > 0) {
             for (ShareholderFj shareholderFj : shareholderFjList) {
-                shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
+                shareholderFj.setLoanApplicationId(loanApplicationId);
                 shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
             }
             AsyncManager.me().execute(AsyncFactory.createPdfFromImagesShareholder(shareholderFjList, loanApplication.getLoanApplicationNumber()));
@@ -707,35 +741,35 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
             String key = loanApplicationId + ":ss:";
             if (Objects.equals(userId, aLong)) {
                 Object cacheObjectA = redisCache.getCacheObject(key + A);
-                if (ObjectUtils.isNotEmpty(cacheObjectA)){
+                if (ObjectUtils.isNotEmpty(cacheObjectA)) {
                     //
                     return AjaxResult.error("请勿重复放弃");
-                }else {
+                } else {
                     //A是空则查询B
                     Object cacheObjectB = redisCache.getCacheObject(key + B);
-                    if (ObjectUtils.isNotEmpty(cacheObjectB)){
+                    if (ObjectUtils.isNotEmpty(cacheObjectB)) {
                         //修改项目状态到回收站
                         loanApplication.setLoanApplicationType(THR);
                         loanApplicationMapper.updateLoanApplication(loanApplication);
-                    }else {
-                        redisCache.setCacheObject(key+A, aLong);
+                    } else {
+                        redisCache.setCacheObject(key + A, aLong);
                     }
                 }
             }
             if (Objects.equals(userId, bLong)) {
                 Object cacheObjectB = redisCache.getCacheObject(key + B);
-                if (ObjectUtils.isNotEmpty(cacheObjectB)){
+                if (ObjectUtils.isNotEmpty(cacheObjectB)) {
                     //
                     return AjaxResult.error("请勿重复放弃");
-                }else {
+                } else {
                     //B是空则查询A
                     Object cacheObjectA = redisCache.getCacheObject(key + A);
-                    if (ObjectUtils.isNotEmpty(cacheObjectA)){
+                    if (ObjectUtils.isNotEmpty(cacheObjectA)) {
                         //修改项目状态到回收站
                         loanApplication.setLoanApplicationType(THR);
                         loanApplicationMapper.updateLoanApplication(loanApplication);
-                    }else {
-                        redisCache.setCacheObject(key+B, aLong);
+                    } else {
+                        redisCache.setCacheObject(key + B, aLong);
                     }
                 }
             }
@@ -875,30 +909,30 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
             loanApplication.setAuditSchedule(String.valueOf(Integer.parseInt(auditSchedule) - 1));
         } else {
             //如果是待审核的撤销就退一步否则就是改为待审核
-            if (ONE.equals(auditType) ) {
+            if (ONE.equals(auditType)) {
                 String reviewSchedule = loanApplication.getReviewSchedule();
                 //等于6:评审会撤销
                 if (SIX.equals(loanSchedule) && !ONE.equals(reviewSchedule)) {
                     loanApplication.setReviewSchedule(ONE);
-                    if (FOR.equals(reviewSchedule)){
+                    if (FOR.equals(reviewSchedule)) {
                         //撤销到确认上会
                         loanApplication.setReviewSchedule(THR);
                         loanApplication.setReviewTime("");
                         //删掉参会人员
-                        sysUserConferenceMapper.deleteSysUserConferenceByTime(loanApplicationOld.getReviewTime(),loanApplicationOld.getLoanApplicationId());
+                        sysUserConferenceMapper.deleteSysUserConferenceByTime(loanApplicationOld.getReviewTime(), loanApplicationOld.getLoanApplicationId());
                     }
-                }else {
+                } else {
                     loanApplication.setAuditSchedule(String.valueOf(Integer.parseInt(auditSchedule) - 1));
                     loanApplication.setLoanSchedule(String.valueOf(Integer.parseInt(loanSchedule) - 1));
                 }
                 //撤销完成后是到上会评审=评审会进度到 3:同意上会
-                if (SIX.equals(loanApplication.getLoanSchedule())){
+                if (SIX.equals(loanApplication.getLoanSchedule())) {
                     loanApplication.setReviewSchedule(THR);
                     loanApplication.setReviewTime("");
                     //删掉参会人员
-                    sysUserConferenceMapper.deleteSysUserConferenceByTime(loanApplicationOld.getReviewTime(),loanApplicationOld.getLoanApplicationId());
+                    sysUserConferenceMapper.deleteSysUserConferenceByTime(loanApplicationOld.getReviewTime(), loanApplicationOld.getLoanApplicationId());
                 }
-            }else {
+            } else {
                 //进入待审核
                 loanApplication.setAuditType(ONE);
             }
@@ -948,7 +982,7 @@ public class LoanApplicationServiceImpl implements ILoanApplicationService {
         //待办信息集合
         //查询审核管理员用户id
         List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectRoleListNoDataScope();
-        if(ObjectUtils.isNotEmpty(loanApplication.getaUserId())){
+        if (ObjectUtils.isNotEmpty(loanApplication.getaUserId())) {
             WaitRemind waitRemind = new WaitRemind();
             waitRemind.setLoanApplicationId(loanApplication.getLoanApplicationId());
             waitRemind.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());

+ 24 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/loan/LoanApplication.java

@@ -326,6 +326,30 @@ public class LoanApplication extends BaseEntity
      * 其他附件
      */
     private Map<String,List<LoanApplicationFj>> otherFj;
+    /**
+     * fj删除id集合
+     */
+    private Long[] loanApplicationFjIdList;
+    /**
+     * 股东fj表股东整体删除id集合
+     */
+    private Long[] shareholderFjIdList;
+
+    public Long[] getLoanApplicationFjIdList() {
+        return loanApplicationFjIdList;
+    }
+
+    public void setLoanApplicationFjIdList(Long[] loanApplicationFjIdList) {
+        this.loanApplicationFjIdList = loanApplicationFjIdList;
+    }
+
+    public Long[] getShareholderFjIdList() {
+        return shareholderFjIdList;
+    }
+
+    public void setShareholderFjIdList(Long[] shareholderFjIdList) {
+        this.shareholderFjIdList = shareholderFjIdList;
+    }
 
     public Double getActuallyAmount() {
         return actuallyAmount;

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/LoanApplicationFjMapper.java

@@ -62,6 +62,13 @@ public interface LoanApplicationFjMapper
      */
     public int updateLoanApplicationFj(LoanApplicationFj loanApplicationFj);
 
+    /**
+     * 删除对应类型系统生成的pdf文件
+     * @param loanApplicationFj
+     * @return
+     */
+    public int deleteLoanApplicationFj(LoanApplicationFj loanApplicationFj);
+
     /**
      * 删除贷款申请_附件
      * 

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/loan/ILoanApplicationFjService.java

@@ -62,5 +62,7 @@ public interface ILoanApplicationFjService
      */
     public int deleteLoanApplicationFjByFjId(Long fjId);
 
+    public int deleteLoanApplicationFj(LoanApplicationFj loanApplicationFj);
+
     AjaxResult ewmList(LoanApplicationFj loanApplicationFj);
 }

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/loan/impl/LoanApplicationFjServiceImpl.java

@@ -105,6 +105,11 @@ public class LoanApplicationFjServiceImpl implements ILoanApplicationFjService
         return loanApplicationFjMapper.deleteLoanApplicationFjByFjId(fjId);
     }
 
+    @Override
+    public int deleteLoanApplicationFj(LoanApplicationFj loanApplicationFj) {
+        return loanApplicationFjMapper.deleteLoanApplicationFj(loanApplicationFj);
+    }
+
     @Override
     public AjaxResult ewmList(LoanApplicationFj loanApplicationFj) {
         LoanApplicationFj applicationFj = loanApplicationFjMapper.ewmList(loanApplicationFj);

+ 6 - 0
ruoyi-system/src/main/resources/mapper/system/LoanApplicationFjMapper.xml

@@ -180,4 +180,10 @@
         where loan_application_id = #{loanApplicationId}
           and big_type in ('b','c','d','e')
     </delete>
+    <delete id="deleteLoanApplicationFj" parameterType="LoanApplicationFj">
+        delete
+        from loan_application_fj
+        where loan_application_id = #{loanApplicationId}
+          and big_type = #{bigType} and type = #{type} and remark = '1'
+    </delete>
 </mapper>

+ 6 - 6
ruoyi-system/src/main/resources/mapper/system/ShareholderFjMapper.xml

@@ -110,15 +110,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="loanApplicationId != null">loan_application_id = #{loanApplicationId},</if>
             <if test="loanApplicationNumber != null and loanApplicationNumber != ''">loan_application_number = #{loanApplicationNumber},</if>
             <if test="shareholderIdCard != null and shareholderIdCard != ''">shareholder_id_card = #{shareholderIdCard},</if>
-            <if test="shareholderName != null and shareholderName != ''">shareholder_name = #{shareholderName},</if>
-            <if test="shareholderFrontName != null and shareholderFrontName != ''">shareholder_front_name = #{shareholderFrontName},</if>
-            <if test="shareholderFrontUrl != null and shareholderFrontUrl != ''">shareholder_front_url = #{shareholderFrontUrl},</if>
-            <if test="shareholderBackName != null and shareholderBackName != ''">shareholder_back_name = #{shareholderBackName},</if>
-            <if test="shareholderBackUrl != null and shareholderBackUrl != ''">shareholder_back_url = #{shareholderBackUrl},</if>
+            <if test="shareholderName != null ">shareholder_name = #{shareholderName},</if>
+            <if test="shareholderFrontName != null ">shareholder_front_name = #{shareholderFrontName},</if>
+            <if test="shareholderFrontUrl != null ">shareholder_front_url = #{shareholderFrontUrl},</if>
+            <if test="shareholderBackName != null ">shareholder_back_name = #{shareholderBackName},</if>
+            <if test="shareholderBackUrl != null ">shareholder_back_url = #{shareholderBackUrl},</if>
             <if test="shareholderZxName != null and shareholderZxName != ''">shareholder_zx_name = #{shareholderZxName},</if>
             <if test="shareholderZxUrl != null and shareholderZxUrl != ''">shareholder_zx_url = #{shareholderZxUrl},</if>
             <if test="shareholderZxUrlPdf != null and shareholderZxUrlPdf != ''">shareholder_zx_url_pdf = #{shareholderZxUrlPdf},</if>
-            <if test="shareholderBusinessUrl != null and shareholderBusinessUrl != ''">shareholder_business_url = #{shareholderBusinessUrl},</if>
+            <if test="shareholderBusinessUrl != null ">shareholder_business_url = #{shareholderBusinessUrl},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateBy != null">update_by = #{updateBy},</if>