Browse Source

内容库V1.0.0

kaick 1 năm trước cách đây
mục cha
commit
a0fcd2272d

+ 10 - 1
pom.xml

@@ -17,13 +17,22 @@
         <java.version>1.8</java.version>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>com.aspose</groupId>
+            <artifactId>aspose.slides</artifactId>
+            <version>15.9.0</version>
+        </dependency>
         <!-- excel工具 -->
         <dependency>
             <groupId>com.aspose</groupId>
             <artifactId>aspose-cells</artifactId>
             <version>8.5.2</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.aspose.words</groupId>
+            <artifactId>aspose-words</artifactId>
+            <version>15.8.0</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.poi</groupId>
             <artifactId>poi-ooxml</artifactId>

+ 7 - 6
src/main/java/com/caimei365/manager/config/WebConfig.java

@@ -1,5 +1,7 @@
 package com.caimei365.manager.config;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
 import org.springframework.boot.web.servlet.MultipartConfigFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -25,13 +27,12 @@ public class WebConfig {
     }
 
 
+    @Autowired
+    private MultipartProperties multipartProperties;
     @Bean
     public MultipartConfigElement multipartConfigElement() {
-        MultipartConfigFactory factory = new MultipartConfigFactory();
-        //文件最大
-        factory.setMaxFileSize(DataSize.parse("200MB"));
-        //设置总上传数据总大小
-        factory.setMaxRequestSize(DataSize.parse("200MB"));
-        return factory.createMultipartConfig();
+        multipartProperties.setMaxFileSize(DataSize.parse("200MB"));
+        multipartProperties.setMaxRequestSize(DataSize.parse("200MB"));
+        return multipartProperties.createMultipartConfig();
     }
 }

+ 21 - 4
src/main/java/com/caimei365/manager/controller/caimei/productArchive/ProductArchiveController.java

@@ -1,5 +1,6 @@
 package com.caimei365.manager.controller.caimei.productArchive;
 
+import com.caimei.utils.StringUtils;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
@@ -9,9 +10,11 @@ import com.caimei365.manager.service.caimei.productArchive.CmProductArchiveConte
 import com.caimei365.manager.service.caimei.productArchive.CmProductArchiveService;
 import com.caimei365.manager.service.caimei.providers.CmProvidersContractService;
 import com.caimei365.manager.service.caimei.providers.CmProvidersService;
+import com.caimei365.manager.utils.FFMPEG;
 import com.caimei365.manager.utils.ImageUtils;
 import com.caimei365.manager.utils.WaterMarkUtils;
 import com.github.pagehelper.PageHelper;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -27,13 +30,12 @@ import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 /**
  * 内容库管理接口
  */
+@Slf4j
 @Validated
 @RestController
 @RequestMapping("/productArchive")
@@ -79,6 +81,7 @@ public class ProductArchiveController {
     @GetMapping("/content/list")
     public ResponseJson productArchiveContentList(String title,
                                                   Integer stageStatus,
+                                                  Integer allStatus,
                                                   String labelIds,
                                                   @NotNull(message = "productArchiveId不能为空") Integer productArchiveId,
                                                   @NotBlank(message = "type不能为空") String type,
@@ -90,6 +93,7 @@ public class ProductArchiveController {
                 .setProductArchiveId(productArchiveId)
                 .setTitle(title)
                 .setStageStatus(stageStatus)
+                .setAllStatus(allStatus)
                 .setLabelIds(labelIds)
         );
         return ResponseJson.success(new PaginationVo(list));
@@ -99,7 +103,6 @@ public class ProductArchiveController {
     public ResponseJson productArchiveContentFrom(String id) {
         return ResponseJson.success(cmProductArchiveContentService.getCmProductArchiveContent(new CmProductArchiveContent().setId(id)));
     }
-
     @PostMapping("/content/add")
     public ResponseJson productArchiveContentAdd(@RequestBody CmProductArchiveContent cmProductArchiveContent
     ) {
@@ -127,5 +130,19 @@ public class ProductArchiveController {
     }
 
 
+    @GetMapping("/ffmepg")
+    public ResponseJson produc(String ffmepgPath) {
+        String s = StringUtils.isNotBlank(ffmepgPath) ? ffmepgPath : "E:\\kaick\\tools\\idmZIP\\ffmpeg-6.1-essentials_build\\bin\\ffmpeg.exe";
+        HashMap<String, String> dto = new HashMap<String, String>();
+        //ffmpeg程序路径
+        dto.put("ffmpeg_path", s);
+        log.info("ffmepg程序路径:" + s);
+        //视频输入路径
+        dto.put("input_path", "https://caimei-oss.oss-cn-shenzhen.aliyuncs.com/beta/archiveFile/9719e56b1d87413886a98e9c0ae04a5a.mp4?Expires=4845853915&OSSAccessKeyId=LTAI4GBL3o4YkWnbKYgf2Xia&Signature=otFR7YsvOJTnzOJMjFeZ5khraqA%3D");
+        // 白名单
+        dto.put("whitelist", "file,http,https,rtp,udp,tcp,tls");
+        return ResponseJson.success(new FFMPEG().getVideoSize(dto));
+    }
+
 
 }

+ 2 - 2
src/main/java/com/caimei365/manager/service/caimei/impl/AsyncService.java

@@ -25,11 +25,11 @@ public class AsyncService {
     @Async("taskExecutor")
     public void setWaterOss(CmProductArchiveFile archiveFile) {
         String ossName = archiveFile.getOssName();
-        Map<String, Object> map = WaterMarkUtils.addWaterMark(ossName.substring(ossName.lastIndexOf(".") + 1), archiveFile.getOssUrl());
+        Map<String, Object> map = WaterMarkUtils.addWaterMark(ossName.substring(ossName.lastIndexOf(".") + 1).toLowerCase(), archiveFile.getOssUrl());
         CmProductArchiveFile productArchiveFile = new CmProductArchiveFile().setId(archiveFile.getId());
         if (null == map) {
             productArchiveFile
-                    .setWaterOssName("水印文件生成失败,请稍后重试!");
+                    .setHtmlUrl("水印文件生成失败,请稍后重试!");
         } else {
             productArchiveFile
                     .setWaterOssName((String) map.get("ossName"))

+ 13 - 4
src/main/java/com/caimei365/manager/utils/CmdExecuter.java

@@ -1,5 +1,6 @@
 package com.caimei365.manager.utils;
 
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 
@@ -7,20 +8,25 @@ import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.util.LinkedList;
 import java.util.List;
-
+@Slf4j
 public class CmdExecuter {
     public static String exec(List<String> cmd) {
         String converted_time = null;
         Process proc = null;
         BufferedReader stdout = null;
         try {
-            proc = Runtime.getRuntime().exec(StringUtils.join(cmd));
+            ProcessBuilder builder = new ProcessBuilder();
+            String join = StringUtils.join(cmd, " ");
+            log.info("join:"+join);
+            builder.command(new String[]{"sh", "-c", join});
+            builder.redirectErrorStream(true);
+            proc = builder.start();
             stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
             String line;
             int lineNumber = 1;
             List<String> returnStringList = new LinkedList<String>();
             while ((line = stdout.readLine()) != null) {
-                System.out.println("第" + lineNumber + "行:" + line);
+                log.info("第" + lineNumber + "行:" + line);
                 lineNumber = lineNumber + 1;
                 returnStringList.add(FFMPEG.dealString(line));
             }
@@ -36,11 +42,14 @@ public class CmdExecuter {
             }
         } catch (IndexOutOfBoundsException ex) {
             converted_time = null;
+            log.error("CmdExecuter异常:"+ex);
         } catch (Exception e) {
             e.printStackTrace();
+            log.error("CmdExecuter异常:"+e);
         } finally {
             try {
-                proc.waitFor();
+                int resultCode = proc.waitFor();
+                log.info("resultCode:"+resultCode);
                 stdout.close();
             } catch (Exception e) {
                 e.printStackTrace();

+ 52 - 0
src/main/java/com/caimei365/manager/utils/DocUtil.java

@@ -0,0 +1,52 @@
+package com.caimei365.manager.utils;
+
+import com.aspose.words.Document;
+import com.aspose.words.License;
+import com.aspose.words.SaveFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Objects;
+
+@Slf4j
+public class DocUtil {
+
+    /**
+     * 获取 license 去除水印
+     * 若不验证则转化出的pdf文档会有水印产生
+     */
+    private static void getLicense() {
+        String licenseFilePath = "word-license.xml";
+        try {
+            InputStream is = DocUtil.class.getClassLoader().getResourceAsStream(licenseFilePath);
+            License license = new License();
+            license.setLicense(Objects.requireNonNull(is));
+        } catch (Exception e) {
+            log.error("license verify failed");
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * word 转 pdf
+     * @param wordFile word 文件路径
+     * @param pdfFile  生成的 pdf 文件路径
+     */
+    public static void word2Pdf(InputStream wordFile, String pdfFile) {
+        File file = new File(pdfFile);
+        if (!file.getParentFile().exists()) {
+            file.getParentFile().mkdir();
+        }
+        getLicense();
+        try (FileOutputStream os = new FileOutputStream(new File(pdfFile))) {
+            Document doc = new Document(wordFile);
+            doc.save(os, SaveFormat.PDF);
+        } catch (Exception e) {
+            log.error("word转pdf失败", e);
+            e.printStackTrace();
+        }
+    }
+
+}

+ 17 - 13
src/main/java/com/caimei365/manager/utils/FFMPEG.java

@@ -10,29 +10,28 @@ import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.*;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
 @Component
 public class FFMPEG {
     @Resource
     private Environment environment;
     private static String config;
-    private static String ffmepgPath = "/mnt/newdatadrive/apps/ffmpeg/ffmpeg-master/bin/ffmpeg";
-    private static String logoPath="/mnt/newdatadrive/data/runtime/jar-instance/manager-api/logo/logo.png";
+    private static String ffmepgPath = "/mnt/newdatadrive/apps/ffmpeg/ffmpeg-master/ffmpeg-resource/ffmpeg";
+    private static String logoPath = "/mnt/newdatadrive/data/runtime/jar-instance/manager-api/logo/logo.png";
 
     @PostConstruct
     public void setValue() {
         config = environment.getProperty("cm.config");
         if ("dev".equals(config)) {
-            ffmepgPath="E:\\kaick\\tools\\idmZIP\\ffmpeg-6.1-essentials_build\\bin\\ffmpeg.exe";
+            ffmepgPath = "E:\\kaick\\tools\\idmZIP\\ffmpeg-6.1-essentials_build\\bin\\ffmpeg.exe";
             logoPath = "D\\\\:logo.png";
         }
     }
+
     /**
      * 日志对象
      */
@@ -120,7 +119,7 @@ public class FFMPEG {
         }
         int markHeight= 50;
         int markWidth = 50;
-        if (!StringUtils.isEmpty(dto.get("width")) ) {
+        if (!org.springframework.util.StringUtils.isEmpty(dto.get("width"))) {
             markHeight = (int) (Integer.parseInt(dto.get("width")) * 0.1);
             markWidth = markHeight;
         }
@@ -185,7 +184,6 @@ public class FFMPEG {
         String secondsString = new FFMPEG().videoTransfer(dto);
         logger.info("转换共用:" + secondsString + "秒");
         if (StringUtils.isBlank(secondsString)) {
-            logger.error("视频添加水印异常!");
             throw new RuntimeException("视频添加水印异常!");
         }
         return OSSUtils.fileUpload(new File(filePath));
@@ -208,7 +206,9 @@ public class FFMPEG {
         String width = "";
         try {
             ProcessBuilder builder = new ProcessBuilder();
-            builder.command(cmd);
+            String join = StringUtils.join(cmd, " ");
+            logger.info("join:"+join);
+            builder.command(new String[]{"sh", "-c", join});
             final Process p = builder.start();
             //从输入流中读取视频信息
             BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
@@ -218,8 +218,9 @@ public class FFMPEG {
                 sb.append(line);
             }
             br.close();
-            System.out.println(sb.toString());
-
+            int resultCode = p.waitFor();
+            logger.info("resultCode:"+resultCode);
+            logger.info(sb.toString());
             int start = sb.indexOf("Video:");
             String substring = sb.substring(start);
             String[] split = substring.split("\\),");
@@ -238,7 +239,10 @@ public class FFMPEG {
                 width = xes[1].trim().split(" ")[0];
             }
         } catch (Exception e) {
-            e.printStackTrace();
+            StringWriter stringWriter = new StringWriter();
+            e.printStackTrace(new PrintWriter(stringWriter));
+            logger.error("出错了:[\u001B[31m {} \u001B[0m]", stringWriter);
+            logger.error("获取视频文件分辨率异常!");
         }
         map.put("height", height);
         map.put("width", width);

+ 3 - 3
src/main/java/com/caimei365/manager/utils/OSSUtils.java

@@ -48,9 +48,9 @@ public class OSSUtils {
         String url = null;
         try {
             if ("product".equals(config)) {
-                fileName = "prod/" + fileName;
+                fileName = "prod/archiveFile/" + fileName;
             } else {
-                fileName = config + "/" + fileName;
+                fileName = config + "/archiveFile/" + fileName;
             }
             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
             ObjectMetadata meta = new ObjectMetadata();
@@ -143,7 +143,7 @@ public class OSSUtils {
         if (".doc".equalsIgnoreCase(fileExtension)) {
             return "application/msword";
         }
-        if ("docx".equalsIgnoreCase(fileExtension)) {
+        if (".docx".equalsIgnoreCase(fileExtension)) {
             return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
         }
         if (".xml".equalsIgnoreCase(fileExtension)) {

+ 93 - 0
src/main/java/com/caimei365/manager/utils/Ppt2Pdf.java

@@ -0,0 +1,93 @@
+package com.caimei365.manager.utils;
+
+import com.aspose.slides.License;
+import com.aspose.slides.Presentation;
+import com.aspose.slides.SaveFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+/**
+ * 将ppt转换为pdf
+ */
+public class Ppt2Pdf {
+    private static Logger logger = LoggerFactory.getLogger(Ppt2Pdf.class);
+
+    public static boolean getLicense() {
+        boolean result = false;
+        InputStream is = null;
+        try {
+            is = Ppt2Pdf.class.getClassLoader().getResourceAsStream("license-slides.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下
+            if (is != null) {
+                License aposeLic = new License();
+                aposeLic.setLicense(is);
+                result = true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 将ppt转换为pdf
+     *
+     * @param inPath  ppt存储路径
+     * @param outPath pdf保存路径
+     */
+    public static void ppt2pdf(String inPath, String outPath) {
+        if (!getLicense() || StringUtils.isEmpty(inPath) || StringUtils.isEmpty(outPath)) { // 验证License 若不验证则转化出的pdf文档会有水印产生
+            return;
+        }
+        try {
+            long old = System.currentTimeMillis();
+            File file = new File(outPath); // 新建一个空白pdf文档
+            FileOutputStream os = new FileOutputStream(file);
+            Presentation pres = new Presentation(inPath); // Address是将要被转化的ppt文档
+            pres.save(os, SaveFormat.Pdf);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,EPUB, XPS, SWF 相互转换
+            os.flush();
+            os.close();
+            long now = System.currentTimeMillis();
+            System.out.println("Ppt转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 将ppt转为pdf
+     *
+     * @param input    需要转换的ppt
+     * @param saveFile 保存pdf文件
+     */
+    public static void ppt2pdf(InputStream input, File saveFile) {
+        if (!getLicense() || input == null || saveFile == null) { // 验证License 若不验证则转化出的pdf文档会有水印产生
+            return;
+        }
+        try {
+            long old = System.currentTimeMillis();
+            FileOutputStream os = new FileOutputStream(saveFile);
+            Presentation pres = new Presentation(input); // Address是将要被转化的excel文档
+            pres.save(os, SaveFormat.Pdf);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,EPUB, XPS, SWF 相互转换
+            os.flush();
+            os.close();
+            long now = System.currentTimeMillis();
+            System.out.println("Ppt转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 31 - 8
src/main/java/com/caimei365/manager/utils/WaterMarkUtils.java

@@ -93,9 +93,9 @@ public class WaterMarkUtils {
                 return setWaterMarkImage(fileUrl);
             } else if (videoTypes.contains(fileType)) {
                 return FFMPEG.setVideoWaterMark(fileUrl, outPath);
-            } else if (fileType.contains("ppt")) {
-                return setWaterMarkPPT(fileUrl);
-            } else if (fileType.contains("pdf") || fileType.contains("doc") || fileType.contains("xls")) {
+            // } else if (fileType.contains("ppt")) {
+            //     return setWaterMarkPPT(fileUrl);
+            } else if (fileType.contains("pdf") || fileType.contains("doc") || fileType.contains("xls")||fileType.contains("ppt")) {
                 return setWaterMarkPDF(fileUrl, fileType);
             } else {
                 throw new NullPointerException("文件格式不正确!");
@@ -126,15 +126,14 @@ public class WaterMarkUtils {
         if (fileType.contains("pdf")) {
             doc = PDDocument.load(url.openStream());
         } else if (fileType.contains("doc")) {
-            InputStream docxInputStream = url.openStream();
-            OutputStream outputStream = new FileOutputStream(filePath);
-            IConverter converter = LocalConverter.builder().build();
-            converter.convert(docxInputStream).as(fileType.contains("docx") ? DocumentType.DOCX : DocumentType.DOC).to(outputStream).as(DocumentType.PDF).execute();
-            outputStream.close();
+            DocUtil.word2Pdf(url.openStream(), filePath);
             doc = PDDocument.load(new File(filePath));
         } else if (fileType.contains("xls")) {
             PdfUtil.excel2pdf(url.openStream(), filePath, null);
             doc = PDDocument.load(new File(filePath));
+        } else if (fileType.contains("ppt")) {
+            Ppt2Pdf.ppt2pdf(url.openStream(), new File(filePath));
+            doc = PDDocument.load(new File(filePath));
         }
         PDImageXObject pdImage = PDImageXObject.createFromFile(logoPath + "logo.png", doc);
         PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
@@ -240,4 +239,28 @@ public class WaterMarkUtils {
         g2d.dispose();
         return image;
     }
+    /**
+     * 生成水印图片背景
+     *
+     * @return
+     */
+    public static File converttoPDF(String filePath,InputStream inputStream , String fileType) throws IOException {
+        PDDocument doc = null;
+        if (fileType.contains("pdf")) {
+            doc = PDDocument.load(inputStream);
+        } else if (fileType.contains("doc")) {
+            InputStream docxInputStream = inputStream;
+            OutputStream outputStream = new FileOutputStream(filePath);
+            IConverter converter = LocalConverter.builder().build();
+            converter.convert(docxInputStream).as(fileType.contains("docx") ? DocumentType.DOCX : DocumentType.DOC).to(outputStream).as(DocumentType.PDF).execute();
+            outputStream.close();
+            doc = PDDocument.load(new File(filePath));
+        } else if (fileType.contains("xls")) {
+            PdfUtil.excel2pdf(inputStream, filePath, null);
+            doc = PDDocument.load(new File(filePath));
+        }
+        doc.save(filePath);
+        doc.close();
+        return new File(filePath);
+    }
 }

+ 13 - 0
src/main/resources/license-slides.xml

@@ -0,0 +1,13 @@
+<License>
+  <Data>
+    <Products>
+      <Product>Aspose.Total for Java</Product>
+      <Product>Aspose.Words for Java</Product>
+    </Products>
+    <EditionType>Enterprise</EditionType>
+    <SubscriptionExpiry>20991231</SubscriptionExpiry>
+    <LicenseExpiry>20991231</LicenseExpiry>
+    <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
+  </Data>
+  <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
+</License>

+ 15 - 0
src/main/resources/word-license.xml

@@ -0,0 +1,15 @@
+<License>
+    <Data>
+        <Products>
+            <Product>Aspose.Total for Java</Product>
+            <Product>Aspose.Words for Java</Product>
+        </Products>
+        <EditionType>Enterprise</EditionType>
+        <SubscriptionExpiry>20991231</SubscriptionExpiry>
+        <LicenseExpiry>20991231</LicenseExpiry>
+        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
+    </Data>
+    <Signature>
+        sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
+    </Signature>
+</License>